diff --git a/LUFA.pnproj b/LUFA.pnproj index dc70a188d1..4df28cbb3f 100644 --- a/LUFA.pnproj +++ b/LUFA.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/LUFA/Common/Common.h b/LUFA/Common/Common.h index 3860eff678..f2e5e313dc 100644 --- a/LUFA/Common/Common.h +++ b/LUFA/Common/Common.h @@ -85,14 +85,14 @@ * * \ingroup Group_Debugging */ - #define JTAG_DEBUG_POINT() __asm__ volatile ("NOP" ::) + #define JTAG_DEBUG_POINT() __asm__ __volatile__ ("NOP" ::) /** Defines an explicit JTAG break point in the resulting binary via the ASM BREAK statement. When * a JTAG is used, this causes the program execution to halt when reached until manually resumed. * * \ingroup Group_Debugging */ - #define JTAG_DEBUG_BREAK() __asm__ volatile ("BREAK" ::) + #define JTAG_DEBUG_BREAK() __asm__ __volatile__ ("BREAK" ::) /** Macro for testing condition "x" and breaking via JTAG_DEBUG_BREAK() if the condition is false. * @@ -111,6 +111,16 @@ #define STDOUT_ASSERT(x) MACROS{ if (!(x)) { printf_P(PSTR("%s: Function \"%s\", Line %d: " \ "Assertion \"%s\" failed.\r\n"), \ __FILE__, __func__, __LINE__, #x); } }MACROE + + /** Forces GCC to use pointer indirection (via the AVR's pointer register pairs) when accessing the given + * struct pointer. In some cases GCC will emit non-optimal assembly code when accessing a structure through + * a pointer, resulting in a larger binary. When this macro is used on a (non-const) structure pointer before + * use, it will force GCC to use pointer indirection on the elements rather than direct store and load + * instructions. + * + * \param[in, out] StructPtr Pointer to a structure which is to be forced into indirect access mode. + */ + #define GCC_FORCE_POINTER_ACCESS(StructPtr) __asm__ __volatile__("" : "=b" (StructPtr) : "0" (StructPtr)) #if !defined(pgm_read_ptr) || defined(__DOXYGEN__) /** Reads a pointer out of PROGMEM space. This is currently a wrapper for the avr-libc pgm_read_ptr() diff --git a/Projects/Benito/Lib/LightweightRingBuff.h b/LUFA/Drivers/Misc/RingBuffer.h similarity index 59% rename from Projects/Benito/Lib/LightweightRingBuff.h rename to LUFA/Drivers/Misc/RingBuffer.h index cddf97f6ae..30493e33aa 100644 --- a/Projects/Benito/Lib/LightweightRingBuff.h +++ b/LUFA/Drivers/Misc/RingBuffer.h @@ -1,211 +1,254 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2010. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaim all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -/** \file - * - * Ultra lightweight ring buffer, for fast insertion/deletion. This uses inlined functions - * for maximum speed. All buffers created with this library must be of the same size, however - * multiple independant buffers can be created. - * - * Note that for each buffer, insertion and removal operations may occur at the same time (via - * a multithreaded ISR based system) however the same kind of operation (two or more insertions - * or deletions) must not overlap. If there is possibility of two or more of the same kind of - * operating occuring at the same point in time, atomic (mutex) locking should be used. - */ - -#ifndef _ULW_RING_BUFF_H_ -#define _ULW_RING_BUFF_H_ - - /* Includes: */ - #include - - #include - #include - - /* Defines: */ - /** Size of each ring buffer, in data elements - must be between 1 and 255. */ - #define BUFFER_SIZE 128 - - /** Type of data to store into the buffer. */ - #define RingBuff_Data_t uint8_t - - /** Datatype which may be used to store the count of data stored in a buffer, retrieved - * via a call to \ref RingBuffer_GetCount(). - */ - #if (BUFFER_SIZE <= 0xFF) - #define RingBuff_Count_t uint8_t - #else - #define RingBuff_Count_t uint16_t - #endif - - /* Type Defines: */ - /** Type define for a new ring buffer object. Buffers should be initialized via a call to - * \ref RingBuffer_InitBuffer() before use. - */ - typedef struct - { - RingBuff_Data_t Buffer[BUFFER_SIZE]; /**< Internal ring buffer data, referenced by the buffer pointers. */ - RingBuff_Data_t* In; /**< Current storage location in the circular buffer */ - RingBuff_Data_t* Out; /**< Current retrieval location in the circular buffer */ - RingBuff_Count_t Count; - } RingBuff_t; - - /* Inline Functions: */ - /** Initializes a ring buffer ready for use. Buffers must be initialized via this function - * before any operations are called upon them. Already initialized buffers may be reset - * by re-initializing them using this function. - * - * \param[out] Buffer Pointer to a ring buffer structure to initialize - */ - static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer) - { - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Buffer->In = Buffer->Buffer; - Buffer->Out = Buffer->Buffer; - } - } - - /** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed - * by entering an atomic lock on the buffer while the IN and OUT locations are fetched, so that - * the buffer cannot be modified while the computation takes place. This value should be cached - * when reading out the contents of the buffer, so that as small a time as possible is spent - * in an atomic lock. - * - * \note The value returned by this function is guaranteed to only be the minimum number of bytes - * stored in the given buffer; this value may change as other threads write new data and so - * the returned number should be used only to determine how many successive reads may safely - * be performed on the buffer. - * - * \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed - */ - static inline RingBuff_Count_t RingBuffer_GetCount(RingBuff_t* const Buffer) - { - RingBuff_Count_t Count; - - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Count = Buffer->Count; - } - - return Count; - } - - /** Atomically determines if the specified ring buffer contains any free space. This should - * be tested before storing data to the buffer, to ensure that no data is lost due to a - * buffer overrun. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to insert into - * - * \return Boolean true if the buffer contains no free space, false otherwise - */ - static inline bool RingBuffer_IsFull(RingBuff_t* const Buffer) - { - return (RingBuffer_GetCount(Buffer) == BUFFER_SIZE); - } - - /** Atomically determines if the specified ring buffer contains any data. This should - * be tested before removing data from the buffer, to ensure that the buffer does not - * underflow. - * - * If the data is to be removed in a loop, store the total number of bytes stored in the - * buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable - * to reduce the time spent in atomicity locks. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to insert into - * - * \return Boolean true if the buffer contains no free space, false otherwise - */ - static inline bool RingBuffer_IsEmpty(RingBuff_t* const Buffer) - { - return (RingBuffer_GetCount(Buffer) == 0); - } - - /** Inserts an element into the ring buffer. - * - * \note Only one execution thread (main program thread or an ISR) may insert into a single buffer - * otherwise data corruption may occur. Insertion and removal may occur from different execution - * threads. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to insert into - * \param[in] Data Data element to insert into the buffer - */ - static inline void RingBuffer_Insert(RingBuff_t* const Buffer, - const RingBuff_Data_t Data) - { - *Buffer->In = Data; - - if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE]) - Buffer->In = Buffer->Buffer; - - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Buffer->Count++; - } - } - - /** Removes an element from the ring buffer. - * - * \note Only one execution thread (main program thread or an ISR) may remove from a single buffer - * otherwise data corruption may occur. Insertion and removal may occur from different execution - * threads. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from - * - * \return Next data element stored in the buffer - */ - static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer) - { - RingBuff_Data_t Data = *Buffer->Out; - - if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE]) - Buffer->Out = Buffer->Buffer; - - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Buffer->Count--; - } - - return Data; - } - - /** Returns the next element stored in the ring buffer, without removing it. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from - * - * \return Next data element stored in the buffer - */ - static inline RingBuff_Data_t RingBuffer_Peek(RingBuff_t* const Buffer) - { - return *Buffer->Out; - } - -#endif - +/* + LUFA Library + Copyright (C) Dean Camera, 2010. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Lightweight ring buffer, for fast insertion/deletion. + * + * Lightweight ring buffer, for fast insertion/deletion. Multiple buffers can be created of + * different sizes to suit different needs. + * + * Note that for each buffer, insertion and removal operations may occur at the same time (via + * a multithreaded ISR based system) however the same kind of operation (two or more insertions + * or deletions) must not overlap. If there is possibility of two or more of the same kind of + * operating occuring at the same point in time, atomic (mutex) locking should be used. + */ + +/** \ingroup Group_MiscDrivers + * @defgroup Group_RingBuff Generic Byte Ring Buffer - LUFA/Drivers/Misc/RingBuffer.h + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Module Description + * Lightweight ring buffer, for fast insertion/deletion. Multiple buffers can be created of + * different sizes to suit different needs. + * + * Note that for each buffer, insertion and removal operations may occur at the same time (via + * a multithreaded ISR based system) however the same kind of operation (two or more insertions + * or deletions) must not overlap. If there is possibility of two or more of the same kind of + * operating occuring at the same point in time, atomic (mutex) locking should be used. + * + * Example Usage: + * \code + * // Create the buffer structure and its underlying storage array + * RingBuff_t Buffer; + * uint8_t BufferData[128]; + * + * // Initialise the buffer with the created storage array + * RingBuffer_InitBuffer(&Buffer, BufferData, sizeof(BufferData)); + * + * // Insert some data into the buffer + * RingBuffer_Insert(Buffer, 'H'); + * RingBuffer_Insert(Buffer, 'E'); + * RingBuffer_Insert(Buffer, 'L'); + * RingBuffer_Insert(Buffer, 'L'); + * RingBuffer_Insert(Buffer, 'O'); + * + * // Cache the number of stored bytes in the buffer + * uint16_t BufferCount = RingBuffer_GetCount(&Buffer); + * + * // Printer stored data length + * printf("Buffer Length: %d, Buffer Data:\r\n", BufferCount); + * + * // Print contents of the buffer one character at a time + * while (BufferCount--) + * putc(RingBuffer_Remove(&Buffer)); + * \endcode + * + * @{ + */ + +#ifndef __RING_BUFF_H__ +#define __RING_BUFF_H__ + + /* Includes: */ + #include + #include + #include + + #include + + /* Type Defines: */ + /** Type define for a new ring buffer object. Buffers should be initialized via a call to + * \ref RingBuffer_InitBuffer() before use. + */ + typedef struct + { + uint8_t* In; /**< Current storage location in the circular buffer */ + uint8_t* Out; /**< Current retrieval location in the circular buffer */ + uint8_t* Start; /** Pointer to the start of the buffer's underlying storage array */ + uint8_t* End; /** Pointer to the end of the buffer's underlying storage array */ + uint8_t Size; /** Size of the buffer's underlying storage array */ + uint16_t Count; /** Number of bytes currently stored in the buffer */ + } RingBuff_t; + + /* Inline Functions: */ + /** Initializes a ring buffer ready for use. Buffers must be initialized via this function + * before any operations are called upon them. Already initialized buffers may be reset + * by re-initializing them using this function. + * + * \param[out] Buffer Pointer to a ring buffer structure to initialize + * \param[out] DataPtr Pointer to a global array that will hold the data stored into the ring buffer + * \param[out] Size Maximum number of bytes that can be stored in the underlying data array + */ + static inline void RingBuffer_InitBuffer(RingBuff_t* Buffer, uint8_t* const DataPtr, const uint16_t Size) + { + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + GCC_FORCE_POINTER_ACCESS(Buffer); + + Buffer->In = DataPtr; + Buffer->Out = DataPtr; + Buffer->Start = &DataPtr[0]; + Buffer->End = &DataPtr[Size]; + Buffer->Size = Size; + Buffer->Count = 0; + } + } + + /** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed + * by entering an atomic lock on the buffer while the IN and OUT locations are fetched, so that + * the buffer cannot be modified while the computation takes place. This value should be cached + * when reading out the contents of the buffer, so that as small a time as possible is spent + * in an atomic lock. + * + * \note The value returned by this function is guaranteed to only be the minimum number of bytes + * stored in the given buffer; this value may change as other threads write new data and so + * the returned number should be used only to determine how many successive reads may safely + * be performed on the buffer. + * + * \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed + */ + static inline uint16_t RingBuffer_GetCount(RingBuff_t* const Buffer) + { + uint16_t Count; + + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + Count = Buffer->Count; + } + + return Count; + } + + /** Atomically determines if the specified ring buffer contains any free space. This should + * be tested before storing data to the buffer, to ensure that no data is lost due to a + * buffer overrun. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to insert into + * + * \return Boolean true if the buffer contains no free space, false otherwise + */ + static inline bool RingBuffer_IsFull(RingBuff_t* const Buffer) + { + return (RingBuffer_GetCount(Buffer) == Buffer->Size); + } + + /** Atomically determines if the specified ring buffer contains any data. This should + * be tested before removing data from the buffer, to ensure that the buffer does not + * underflow. + * + * If the data is to be removed in a loop, store the total number of bytes stored in the + * buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable + * to reduce the time spent in atomicity locks. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to insert into + * + * \return Boolean true if the buffer contains no free space, false otherwise + */ + static inline bool RingBuffer_IsEmpty(RingBuff_t* const Buffer) + { + return (RingBuffer_GetCount(Buffer) == 0); + } + + /** Inserts an element into the ring buffer. + * + * \note Only one execution thread (main program thread or an ISR) may insert into a single buffer + * otherwise data corruption may occur. Insertion and removal may occur from different execution + * threads. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to insert into + * \param[in] Data Data element to insert into the buffer + */ + static inline void RingBuffer_Insert(RingBuff_t* const Buffer, + const uint8_t Data) + { + *Buffer->In = Data; + + if (++Buffer->In == Buffer->End) + Buffer->In = Buffer->Start; + + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + Buffer->Count++; + } + } + + /** Removes an element from the ring buffer. + * + * \note Only one execution thread (main program thread or an ISR) may remove from a single buffer + * otherwise data corruption may occur. Insertion and removal may occur from different execution + * threads. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from + * + * \return Next data element stored in the buffer + */ + static inline uint8_t RingBuffer_Remove(RingBuff_t* const Buffer) + { + uint8_t Data = *Buffer->Out; + + if (++Buffer->Out == Buffer->End) + Buffer->Out = Buffer->Start; + + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + Buffer->Count--; + } + + return Data; + } + + /** Returns the next element stored in the ring buffer, without removing it. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from + * + * \return Next data element stored in the buffer + */ + static inline uint8_t RingBuffer_Peek(RingBuff_t* const Buffer) + { + return *Buffer->Out; + } + +#endif + +/** @} */ + diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 496bd8d433..382e0ed4d3 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -12,6 +12,8 @@ * - Added new MIDIToneGenerator project * - Added new ORDERED_EP_CONFIG compile time option to restrict endpoint/pipe configuration to ascending order * in exchange for a smaller compiled program binary size + * - Added a new general RingBuff.h miscellaneous ring buffer library driver header + * - Added new GCC_FORCE_POINTER_ACCESS() macro to correct GCC's mishandling of struct pointer accesses * - Library Applications: * - Added new incomplete MIDIToneGenerator project * - Added ability to write protect Mass Storage disk write operations from the host OS @@ -27,6 +29,7 @@ * via the Input Capture register, to reduce user confusion * - Combined page and word ISP programming mode code in the AVRISP-MKII clone project to reduce compiled size and * increase maintainability of the code + * - Changed over library projects to use the new general ring buffer library driver module * * Fixed: * - Core: diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt index 2197cb5d3b..319c4c9910 100644 --- a/LUFA/ManPages/FutureChanges.txt +++ b/LUFA/ManPages/FutureChanges.txt @@ -21,7 +21,6 @@ * -# Add HID report macros to make HID report editing easier * -# Investigate dynamically created device descriptors * - Known Bugs - * -# Errors with AVRISP-MKII program with full EEPROM programming on the ATMEGA8 (and others?) * -# No wakeup when plugged into hub, and hub plugged into host * -# Incomplete TMC class demo errors * - Documentation/Support diff --git a/Projects/Benito/Benito.c b/Projects/Benito/Benito.c index c6cbf02b34..e666c245c3 100644 --- a/Projects/Benito/Benito.c +++ b/Projects/Benito/Benito.c @@ -39,6 +39,9 @@ /** Circular buffer to hold data from the serial port before it is sent to the host. */ RingBuff_t USARTtoUSB_Buffer; +/** Underlying data buffer for \ref USARTtoUSB_Buffer, where the stored bytes are located. */ +uint8_t USARTtoUSB_Buffer_Data[128]; + /** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ volatile struct { @@ -85,7 +88,7 @@ int main(void) { SetupHardware(); - RingBuffer_InitBuffer(&USARTtoUSB_Buffer); + RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data)); sei(); @@ -126,7 +129,7 @@ int main(void) LEDs_TurnOffLEDs(LEDMASK_RX); /* Check if the receive buffer flush period has expired */ - RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); + uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); if (!(--FlushPeriodRemaining) || (BufferCount > 200)) { /* Echo bytes from the target to the host via the virtual serial port */ diff --git a/Projects/Benito/Benito.h b/Projects/Benito/Benito.h index 7883ec87b1..55d1b6d634 100644 --- a/Projects/Benito/Benito.h +++ b/Projects/Benito/Benito.h @@ -42,11 +42,11 @@ #include #include "Descriptors.h" - #include "Lib/LightweightRingBuff.h" #include #include #include + #include #include /* Macros: */ diff --git a/Projects/Benito/makefile b/Projects/Benito/makefile index 9cbc1d6fb1..839b7d731c 100644 --- a/Projects/Benito/makefile +++ b/Projects/Benito/makefile @@ -118,6 +118,7 @@ LUFA_PATH = ../.. # LUFA library compile-time options and predefined tokens LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 +LUFA_OPTS += -D ORDERED_EP_CONFIG LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D USE_FLASH_DESCRIPTORS diff --git a/Projects/Incomplete/StandaloneProgrammer/makefile b/Projects/Incomplete/StandaloneProgrammer/makefile index e7f0b315ed..e90586e36d 100644 --- a/Projects/Incomplete/StandaloneProgrammer/makefile +++ b/Projects/Incomplete/StandaloneProgrammer/makefile @@ -117,6 +117,8 @@ LUFA_PATH = ../../.. # LUFA library compile-time options and predefined tokens LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 +LUFA_OPTS += -D HOST_STATE_AS_GPIOR=1 +LUFA_OPTS += -D ORDERED_EP_CONFIG LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D USE_FLASH_DESCRIPTORS diff --git a/Projects/LEDNotifier/makefile b/Projects/LEDNotifier/makefile index 653c051a95..017a3fa4c7 100644 --- a/Projects/LEDNotifier/makefile +++ b/Projects/LEDNotifier/makefile @@ -118,6 +118,7 @@ LUFA_PATH = ../.. # LUFA library compile-time options and predefined tokens LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 +LUFA_OPTS += -D ORDERED_EP_CONFIG LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D USE_FLASH_DESCRIPTORS diff --git a/Projects/MIDIToneGenerator/makefile b/Projects/MIDIToneGenerator/makefile index 815f4a7b6c..7aee785d8f 100644 --- a/Projects/MIDIToneGenerator/makefile +++ b/Projects/MIDIToneGenerator/makefile @@ -118,6 +118,7 @@ LUFA_PATH = ../../ # LUFA library compile-time options and predefined tokens LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 +LUFA_OPTS += -D ORDERED_EP_CONFIG LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D USE_FLASH_DESCRIPTORS diff --git a/Projects/Magstripe/makefile b/Projects/Magstripe/makefile index 110d20dd45..597736dce6 100644 --- a/Projects/Magstripe/makefile +++ b/Projects/Magstripe/makefile @@ -118,6 +118,7 @@ LUFA_PATH = ../.. # LUFA library compile-time options and predefined tokens LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 +LUFA_OPTS += -D ORDERED_EP_CONFIG LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D USE_FLASH_DESCRIPTORS diff --git a/Projects/MissileLauncher/makefile b/Projects/MissileLauncher/makefile index 5c074de750..f18c7a7ed3 100644 --- a/Projects/MissileLauncher/makefile +++ b/Projects/MissileLauncher/makefile @@ -118,6 +118,7 @@ LUFA_PATH = ../.. # LUFA library compile-time options and predefined tokens LUFA_OPTS = -D USB_HOST_ONLY LUFA_OPTS += -D HOST_STATE_AS_GPIOR=0 +LUFA_OPTS += -D ORDERED_EP_CONFIG LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" LUFA_OPTS += -D NO_STREAM_CALLBACKS diff --git a/Projects/RelayBoard/makefile b/Projects/RelayBoard/makefile index d572f59394..baad4a74b3 100644 --- a/Projects/RelayBoard/makefile +++ b/Projects/RelayBoard/makefile @@ -118,6 +118,7 @@ LUFA_PATH = ../.. # LUFA library compile-time options and predefined tokens LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 +LUFA_OPTS += -D ORDERED_EP_CONFIG LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D CONTROL_ONLY_DEVICE diff --git a/Projects/USBtoSerial/Lib/LightweightRingBuff.h b/Projects/USBtoSerial/Lib/LightweightRingBuff.h deleted file mode 100644 index cddf97f6ae..0000000000 --- a/Projects/USBtoSerial/Lib/LightweightRingBuff.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2010. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaim all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -/** \file - * - * Ultra lightweight ring buffer, for fast insertion/deletion. This uses inlined functions - * for maximum speed. All buffers created with this library must be of the same size, however - * multiple independant buffers can be created. - * - * Note that for each buffer, insertion and removal operations may occur at the same time (via - * a multithreaded ISR based system) however the same kind of operation (two or more insertions - * or deletions) must not overlap. If there is possibility of two or more of the same kind of - * operating occuring at the same point in time, atomic (mutex) locking should be used. - */ - -#ifndef _ULW_RING_BUFF_H_ -#define _ULW_RING_BUFF_H_ - - /* Includes: */ - #include - - #include - #include - - /* Defines: */ - /** Size of each ring buffer, in data elements - must be between 1 and 255. */ - #define BUFFER_SIZE 128 - - /** Type of data to store into the buffer. */ - #define RingBuff_Data_t uint8_t - - /** Datatype which may be used to store the count of data stored in a buffer, retrieved - * via a call to \ref RingBuffer_GetCount(). - */ - #if (BUFFER_SIZE <= 0xFF) - #define RingBuff_Count_t uint8_t - #else - #define RingBuff_Count_t uint16_t - #endif - - /* Type Defines: */ - /** Type define for a new ring buffer object. Buffers should be initialized via a call to - * \ref RingBuffer_InitBuffer() before use. - */ - typedef struct - { - RingBuff_Data_t Buffer[BUFFER_SIZE]; /**< Internal ring buffer data, referenced by the buffer pointers. */ - RingBuff_Data_t* In; /**< Current storage location in the circular buffer */ - RingBuff_Data_t* Out; /**< Current retrieval location in the circular buffer */ - RingBuff_Count_t Count; - } RingBuff_t; - - /* Inline Functions: */ - /** Initializes a ring buffer ready for use. Buffers must be initialized via this function - * before any operations are called upon them. Already initialized buffers may be reset - * by re-initializing them using this function. - * - * \param[out] Buffer Pointer to a ring buffer structure to initialize - */ - static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer) - { - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Buffer->In = Buffer->Buffer; - Buffer->Out = Buffer->Buffer; - } - } - - /** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed - * by entering an atomic lock on the buffer while the IN and OUT locations are fetched, so that - * the buffer cannot be modified while the computation takes place. This value should be cached - * when reading out the contents of the buffer, so that as small a time as possible is spent - * in an atomic lock. - * - * \note The value returned by this function is guaranteed to only be the minimum number of bytes - * stored in the given buffer; this value may change as other threads write new data and so - * the returned number should be used only to determine how many successive reads may safely - * be performed on the buffer. - * - * \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed - */ - static inline RingBuff_Count_t RingBuffer_GetCount(RingBuff_t* const Buffer) - { - RingBuff_Count_t Count; - - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Count = Buffer->Count; - } - - return Count; - } - - /** Atomically determines if the specified ring buffer contains any free space. This should - * be tested before storing data to the buffer, to ensure that no data is lost due to a - * buffer overrun. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to insert into - * - * \return Boolean true if the buffer contains no free space, false otherwise - */ - static inline bool RingBuffer_IsFull(RingBuff_t* const Buffer) - { - return (RingBuffer_GetCount(Buffer) == BUFFER_SIZE); - } - - /** Atomically determines if the specified ring buffer contains any data. This should - * be tested before removing data from the buffer, to ensure that the buffer does not - * underflow. - * - * If the data is to be removed in a loop, store the total number of bytes stored in the - * buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable - * to reduce the time spent in atomicity locks. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to insert into - * - * \return Boolean true if the buffer contains no free space, false otherwise - */ - static inline bool RingBuffer_IsEmpty(RingBuff_t* const Buffer) - { - return (RingBuffer_GetCount(Buffer) == 0); - } - - /** Inserts an element into the ring buffer. - * - * \note Only one execution thread (main program thread or an ISR) may insert into a single buffer - * otherwise data corruption may occur. Insertion and removal may occur from different execution - * threads. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to insert into - * \param[in] Data Data element to insert into the buffer - */ - static inline void RingBuffer_Insert(RingBuff_t* const Buffer, - const RingBuff_Data_t Data) - { - *Buffer->In = Data; - - if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE]) - Buffer->In = Buffer->Buffer; - - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Buffer->Count++; - } - } - - /** Removes an element from the ring buffer. - * - * \note Only one execution thread (main program thread or an ISR) may remove from a single buffer - * otherwise data corruption may occur. Insertion and removal may occur from different execution - * threads. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from - * - * \return Next data element stored in the buffer - */ - static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer) - { - RingBuff_Data_t Data = *Buffer->Out; - - if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE]) - Buffer->Out = Buffer->Buffer; - - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Buffer->Count--; - } - - return Data; - } - - /** Returns the next element stored in the ring buffer, without removing it. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from - * - * \return Next data element stored in the buffer - */ - static inline RingBuff_Data_t RingBuffer_Peek(RingBuff_t* const Buffer) - { - return *Buffer->Out; - } - -#endif - diff --git a/Projects/USBtoSerial/USBtoSerial.c b/Projects/USBtoSerial/USBtoSerial.c index 477dd44f5a..e775541fda 100644 --- a/Projects/USBtoSerial/USBtoSerial.c +++ b/Projects/USBtoSerial/USBtoSerial.c @@ -39,9 +39,16 @@ /** Circular buffer to hold data from the host before it is sent to the device via the serial port. */ RingBuff_t USBtoUSART_Buffer; +/** Underlying data buffer for \ref USBtoUSART_Buffer, where the stored bytes are located. */ +uint8_t USBtoUSART_Buffer_Data[128]; + /** Circular buffer to hold data from the serial port before it is sent to the host. */ RingBuff_t USARTtoUSB_Buffer; +/** Underlying data buffer for \ref USARTtoUSB_Buffer, where the stored bytes are located. */ +uint8_t USARTtoUSB_Buffer_Data[128]; + + /** LUFA CDC Class driver interface configuration and state information. This structure is * passed to all CDC Class driver functions, so that multiple instances of the same class * within a device can be differentiated from one another. @@ -73,8 +80,8 @@ int main(void) { SetupHardware(); - RingBuffer_InitBuffer(&USBtoUSART_Buffer); - RingBuffer_InitBuffer(&USARTtoUSB_Buffer); + RingBuffer_InitBuffer(&USBtoUSART_Buffer, USBtoUSART_Buffer_Data, sizeof(USBtoUSART_Buffer_Data)); + RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); @@ -92,7 +99,7 @@ int main(void) } /* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */ - RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); + uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer); if ((TIFR0 & (1 << TOV0)) || (BufferCount > 200)) { /* Clear flush timer expiry flag */ diff --git a/Projects/USBtoSerial/USBtoSerial.h b/Projects/USBtoSerial/USBtoSerial.h index 5276b041ff..0d42480f9c 100644 --- a/Projects/USBtoSerial/USBtoSerial.h +++ b/Projects/USBtoSerial/USBtoSerial.h @@ -44,11 +44,10 @@ #include "Descriptors.h" - #include "Lib/LightweightRingBuff.h" - #include #include #include + #include #include /* Macros: */ diff --git a/Projects/USBtoSerial/makefile b/Projects/USBtoSerial/makefile index dfe114ce16..f495af6899 100644 --- a/Projects/USBtoSerial/makefile +++ b/Projects/USBtoSerial/makefile @@ -118,6 +118,7 @@ LUFA_PATH = ../.. # LUFA library compile-time options and predefined tokens LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 +LUFA_OPTS += -D ORDERED_EP_CONFIG LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D USE_FLASH_DESCRIPTORS diff --git a/Projects/XPLAINBridge/Lib/LightweightRingBuff.h b/Projects/XPLAINBridge/Lib/LightweightRingBuff.h deleted file mode 100644 index b19291cafe..0000000000 --- a/Projects/XPLAINBridge/Lib/LightweightRingBuff.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2010. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaim all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -/** \file - * - * Ultra lightweight ring buffer, for fast insertion/deletion. This uses inlined functions - * for maximum speed. All buffers created with this library must be of the same size, however - * multiple independant buffers can be created. - * - * Note that for each buffer, insertion and removal operations may occur at the same time (via - * a multithreaded ISR based system) however the same kind of operation (two or more insertions - * or deletions) must not overlap. If there is possibility of two or more of the same kind of - * operating occuring at the same point in time, atomic (mutex) locking should be used. - */ - -#ifndef _ULW_RING_BUFF_H_ -#define _ULW_RING_BUFF_H_ - - /* Includes: */ - #include - - #include - #include - - /* Defines: */ - /** Size of each ring buffer, in data elements - must be between 1 and 255. */ - #define BUFFER_SIZE 255 - - /** Type of data to store into the buffer. */ - #define RingBuff_Data_t uint8_t - - /** Datatype which may be used to store the count of data stored in a buffer, retrieved - * via a call to \ref RingBuffer_GetCount(). - */ - #if (BUFFER_SIZE <= 0xFF) - #define RingBuff_Count_t uint8_t - #else - #define RingBuff_Count_t uint16_t - #endif - - /* Type Defines: */ - /** Type define for a new ring buffer object. Buffers should be initialized via a call to - * \ref RingBuffer_InitBuffer() before use. - */ - typedef struct - { - RingBuff_Data_t Buffer[BUFFER_SIZE]; /**< Internal ring buffer data, referenced by the buffer pointers. */ - RingBuff_Data_t* In; /**< Current storage location in the circular buffer */ - RingBuff_Data_t* Out; /**< Current retrieval location in the circular buffer */ - RingBuff_Count_t Count; - } RingBuff_t; - - /* Inline Functions: */ - /** Initializes a ring buffer ready for use. Buffers must be initialized via this function - * before any operations are called upon them. Already initialized buffers may be reset - * by re-initializing them using this function. - * - * \param[out] Buffer Pointer to a ring buffer structure to initialize - */ - static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer) - { - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Buffer->In = Buffer->Buffer; - Buffer->Out = Buffer->Buffer; - } - } - - /** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed - * by entering an atomic lock on the buffer while the IN and OUT locations are fetched, so that - * the buffer cannot be modified while the computation takes place. This value should be cached - * when reading out the contents of the buffer, so that as small a time as possible is spent - * in an atomic lock. - * - * \note The value returned by this function is guaranteed to only be the minimum number of bytes - * stored in the given buffer; this value may change as other threads write new data and so - * the returned number should be used only to determine how many successive reads may safely - * be performed on the buffer. - * - * \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed - */ - static inline RingBuff_Count_t RingBuffer_GetCount(RingBuff_t* const Buffer) - { - RingBuff_Count_t Count; - - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Count = Buffer->Count; - } - - return Count; - } - - /** Atomically determines if the specified ring buffer contains any free space. This should - * be tested before storing data to the buffer, to ensure that no data is lost due to a - * buffer overrun. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to insert into - * - * \return Boolean true if the buffer contains no free space, false otherwise - */ - static inline bool RingBuffer_IsFull(RingBuff_t* const Buffer) - { - return (RingBuffer_GetCount(Buffer) == BUFFER_SIZE); - } - - /** Atomically determines if the specified ring buffer contains any data. This should - * be tested before removing data from the buffer, to ensure that the buffer does not - * underflow. - * - * If the data is to be removed in a loop, store the total number of bytes stored in the - * buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable - * to reduce the time spent in atomicity locks. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to insert into - * - * \return Boolean true if the buffer contains no free space, false otherwise - */ - static inline bool RingBuffer_IsEmpty(RingBuff_t* const Buffer) - { - return (RingBuffer_GetCount(Buffer) == 0); - } - - /** Inserts an element into the ring buffer. - * - * \note Only one execution thread (main program thread or an ISR) may insert into a single buffer - * otherwise data corruption may occur. Insertion and removal may occur from different execution - * threads. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to insert into - * \param[in] Data Data element to insert into the buffer - */ - static inline void RingBuffer_Insert(RingBuff_t* const Buffer, - const RingBuff_Data_t Data) - { - *Buffer->In = Data; - - if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE]) - Buffer->In = Buffer->Buffer; - - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Buffer->Count++; - } - } - - /** Removes an element from the ring buffer. - * - * \note Only one execution thread (main program thread or an ISR) may remove from a single buffer - * otherwise data corruption may occur. Insertion and removal may occur from different execution - * threads. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from - * - * \return Next data element stored in the buffer - */ - static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer) - { - RingBuff_Data_t Data = *Buffer->Out; - - if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE]) - Buffer->Out = Buffer->Buffer; - - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) - { - Buffer->Count--; - } - - return Data; - } - - /** Returns the next element stored in the ring buffer, without removing it. - * - * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from - * - * \return Next data element stored in the buffer - */ - static inline RingBuff_Data_t RingBuffer_Peek(RingBuff_t* const Buffer) - { - return *Buffer->Out; - } - -#endif - diff --git a/Projects/XPLAINBridge/Lib/SoftUART.h b/Projects/XPLAINBridge/Lib/SoftUART.h index 803e1e5a6b..f9426237e4 100644 --- a/Projects/XPLAINBridge/Lib/SoftUART.h +++ b/Projects/XPLAINBridge/Lib/SoftUART.h @@ -44,7 +44,6 @@ #include #include "../XPLAINBridge.h" - #include "LightweightRingBuff.h" /* Macros: */ #define SRX PD0 diff --git a/Projects/XPLAINBridge/XPLAINBridge.c b/Projects/XPLAINBridge/XPLAINBridge.c index 912e68367f..c71a42103e 100644 --- a/Projects/XPLAINBridge/XPLAINBridge.c +++ b/Projects/XPLAINBridge/XPLAINBridge.c @@ -66,9 +66,15 @@ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = /** Circular buffer to hold data from the host before it is sent to the device via the serial port. */ RingBuff_t USBtoUART_Buffer; +/** Underlying data buffer for \ref USBtoUART_Buffer, where the stored bytes are located. */ +uint8_t USBtoUART_Buffer_Data[128]; + /** Circular buffer to hold data from the serial port before it is sent to the host. */ RingBuff_t UARTtoUSB_Buffer; +/** Underlying data buffer for \ref UARTtoUSB_Buffer, where the stored bytes are located. */ +uint8_t UARTtoUSB_Buffer_Data[128]; + /** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. @@ -130,7 +136,7 @@ void UARTBridge_Task(void) } /* Check if the UART receive buffer flush timer has expired or buffer is nearly full */ - RingBuff_Count_t BufferCount = RingBuffer_GetCount(&UARTtoUSB_Buffer); + uint16_t BufferCount = RingBuffer_GetCount(&UARTtoUSB_Buffer); if ((TIFR0 & (1 << TOV0)) || (BufferCount > 200)) { /* Clear flush timer expiry flag */ @@ -199,8 +205,8 @@ void EVENT_USB_Device_ConfigurationChanged(void) TCCR0B = ((1 << CS02) | (1 << CS00)); /* Initialize ring buffers used to hold serial data between USB and software UART interfaces */ - RingBuffer_InitBuffer(&USBtoUART_Buffer); - RingBuffer_InitBuffer(&UARTtoUSB_Buffer); + RingBuffer_InitBuffer(&USBtoUART_Buffer, USBtoUART_Buffer_Data, sizeof(USBtoUART_Buffer_Data)); + RingBuffer_InitBuffer(&UARTtoUSB_Buffer, UARTtoUSB_Buffer_Data, sizeof(UARTtoUSB_Buffer_Data)); /* Start the software USART */ SoftUART_Init(); diff --git a/Projects/XPLAINBridge/XPLAINBridge.h b/Projects/XPLAINBridge/XPLAINBridge.h index 4492575021..38fc2007f3 100644 --- a/Projects/XPLAINBridge/XPLAINBridge.h +++ b/Projects/XPLAINBridge/XPLAINBridge.h @@ -46,12 +46,12 @@ #include "AVRISPDescriptors.h" #include "USARTDescriptors.h" - #include "Lib/LightweightRingBuff.h" #include "Lib/SoftUART.h" #include "Lib/V2Protocol.h" #include #include + #include #include /* Macros: */ diff --git a/Projects/XPLAINBridge/makefile b/Projects/XPLAINBridge/makefile index 946a371f48..ee466dde3a 100644 --- a/Projects/XPLAINBridge/makefile +++ b/Projects/XPLAINBridge/makefile @@ -122,6 +122,7 @@ AVRISP_PATH = ../AVRISP-MKII # LUFA library compile-time options and predefined tokens LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 +LUFA_OPTS += -D ORDERED_EP_CONFIG LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D USE_FLASH_DESCRIPTORS