Make a new general RingBuffer.h misc library driver, instead of the per-application LightweightRingBuff.h ring buffers. Change over projects to use the new driver.

Add ORDERED_EP_CONFIG to the device Projects (only) that use only a single class driver, or where the endpoint ordering is fixed, to save on compiled binary size.

Added new GCC_FORCE_POINTER_ACCESS() macro to correct GCC's mishandling of struct pointers.
pull/1469/head
Dean Camera 14 years ago
parent 12418e6eaf
commit 39ac72f2d1

File diff suppressed because one or more lines are too long

@ -85,14 +85,14 @@
* *
* \ingroup Group_Debugging * \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 /** 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. * a JTAG is used, this causes the program execution to halt when reached until manually resumed.
* *
* \ingroup Group_Debugging * \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. /** 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: " \ #define STDOUT_ASSERT(x) MACROS{ if (!(x)) { printf_P(PSTR("%s: Function \"%s\", Line %d: " \
"Assertion \"%s\" failed.\r\n"), \ "Assertion \"%s\" failed.\r\n"), \
__FILE__, __func__, __LINE__, #x); } }MACROE __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__) #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() /** Reads a pointer out of PROGMEM space. This is currently a wrapper for the avr-libc pgm_read_ptr()

@ -1,211 +1,254 @@
/* /*
LUFA Library LUFA Library
Copyright (C) Dean Camera, 2010. Copyright (C) Dean Camera, 2010.
dean [at] fourwalledcubicle [dot] com dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org www.lufa-lib.org
*/ */
/* /*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com) Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the advertising or publicity pertaining to distribution of the
software without specific, written prior permission. software without specific, written prior permission.
The author disclaim all warranties with regard to this The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action, in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of arising out of or in connection with the use or performance of
this software. this software.
*/ */
/** \file /** \file
* * \brief Lightweight ring buffer, for fast insertion/deletion.
* 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 * Lightweight ring buffer, for fast insertion/deletion. Multiple buffers can be created of
* multiple independant buffers can be created. * different sizes to suit different needs.
* *
* Note that for each buffer, insertion and removal operations may occur at the same time (via * 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 * 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 * 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. * operating occuring at the same point in time, atomic (mutex) locking should be used.
*/ */
#ifndef _ULW_RING_BUFF_H_ /** \ingroup Group_MiscDrivers
#define _ULW_RING_BUFF_H_ * @defgroup Group_RingBuff Generic Byte Ring Buffer - LUFA/Drivers/Misc/RingBuffer.h
*
/* Includes: */ * \section Sec_Dependencies Module Source Dependencies
#include <util/atomic.h> * The following files must be built with any user project that uses this module:
* - None
#include <stdint.h> *
#include <stdbool.h> * \section Module Description
* Lightweight ring buffer, for fast insertion/deletion. Multiple buffers can be created of
/* Defines: */ * different sizes to suit different needs.
/** Size of each ring buffer, in data elements - must be between 1 and 255. */ *
#define BUFFER_SIZE 128 * 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
/** Type of data to store into the buffer. */ * or deletions) must not overlap. If there is possibility of two or more of the same kind of
#define RingBuff_Data_t uint8_t * operating occuring at the same point in time, atomic (mutex) locking should be used.
*
/** Datatype which may be used to store the count of data stored in a buffer, retrieved * Example Usage:
* via a call to \ref RingBuffer_GetCount(). * \code
*/ * // Create the buffer structure and its underlying storage array
#if (BUFFER_SIZE <= 0xFF) * RingBuff_t Buffer;
#define RingBuff_Count_t uint8_t * uint8_t BufferData[128];
#else *
#define RingBuff_Count_t uint16_t * // Initialise the buffer with the created storage array
#endif * RingBuffer_InitBuffer(&Buffer, BufferData, sizeof(BufferData));
*
/* Type Defines: */ * // Insert some data into the buffer
/** Type define for a new ring buffer object. Buffers should be initialized via a call to * RingBuffer_Insert(Buffer, 'H');
* \ref RingBuffer_InitBuffer() before use. * RingBuffer_Insert(Buffer, 'E');
*/ * RingBuffer_Insert(Buffer, 'L');
typedef struct * RingBuffer_Insert(Buffer, 'L');
{ * RingBuffer_Insert(Buffer, 'O');
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 */ * // Cache the number of stored bytes in the buffer
RingBuff_Data_t* Out; /**< Current retrieval location in the circular buffer */ * uint16_t BufferCount = RingBuffer_GetCount(&Buffer);
RingBuff_Count_t Count; *
} RingBuff_t; * // Printer stored data length
* printf("Buffer Length: %d, Buffer Data:\r\n", BufferCount);
/* Inline Functions: */ *
/** Initializes a ring buffer ready for use. Buffers must be initialized via this function * // Print contents of the buffer one character at a time
* before any operations are called upon them. Already initialized buffers may be reset * while (BufferCount--)
* by re-initializing them using this function. * putc(RingBuffer_Remove(&Buffer));
* * \endcode
* \param[out] Buffer Pointer to a ring buffer structure to initialize *
*/ * @{
static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer) */
{
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) #ifndef __RING_BUFF_H__
{ #define __RING_BUFF_H__
Buffer->In = Buffer->Buffer;
Buffer->Out = Buffer->Buffer; /* Includes: */
} #include <util/atomic.h>
} #include <stdint.h>
#include <stdbool.h>
/** 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 #include <LUFA/Common/Common.h>
* 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 /* Type Defines: */
* in an atomic lock. /** Type define for a new ring buffer object. Buffers should be initialized via a call to
* * \ref RingBuffer_InitBuffer() before use.
* \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 typedef struct
* the returned number should be used only to determine how many successive reads may safely {
* be performed on the buffer. uint8_t* In; /**< Current storage location in the circular buffer */
* uint8_t* Out; /**< Current retrieval location in the circular buffer */
* \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed 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 */
static inline RingBuff_Count_t RingBuffer_GetCount(RingBuff_t* const Buffer) uint8_t Size; /** Size of the buffer's underlying storage array */
{ uint16_t Count; /** Number of bytes currently stored in the buffer */
RingBuff_Count_t Count; } RingBuff_t;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) /* Inline Functions: */
{ /** Initializes a ring buffer ready for use. Buffers must be initialized via this function
Count = Buffer->Count; * before any operations are called upon them. Already initialized buffers may be reset
} * by re-initializing them using this function.
*
return Count; * \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
/** 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 static inline void RingBuffer_InitBuffer(RingBuff_t* Buffer, uint8_t* const DataPtr, const uint16_t Size)
* buffer overrun. {
* ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into {
* GCC_FORCE_POINTER_ACCESS(Buffer);
* \return Boolean true if the buffer contains no free space, false otherwise
*/ Buffer->In = DataPtr;
static inline bool RingBuffer_IsFull(RingBuff_t* const Buffer) Buffer->Out = DataPtr;
{ Buffer->Start = &DataPtr[0];
return (RingBuffer_GetCount(Buffer) == BUFFER_SIZE); Buffer->End = &DataPtr[Size];
} Buffer->Size = Size;
Buffer->Count = 0;
/** 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.
* /** Retrieves the minimum number of bytes stored in a particular buffer. This value is computed
* If the data is to be removed in a loop, store the total number of bytes stored in the * by entering an atomic lock on the buffer while the IN and OUT locations are fetched, so that
* buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable * the buffer cannot be modified while the computation takes place. This value should be cached
* to reduce the time spent in atomicity locks. * when reading out the contents of the buffer, so that as small a time as possible is spent
* * in an atomic lock.
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into *
* * \note The value returned by this function is guaranteed to only be the minimum number of bytes
* \return Boolean true if the buffer contains no free space, false otherwise * 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
static inline bool RingBuffer_IsEmpty(RingBuff_t* const Buffer) * be performed on the buffer.
{ *
return (RingBuffer_GetCount(Buffer) == 0); * \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)
/** Inserts an element into the ring buffer. {
* uint16_t Count;
* \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 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
* threads. {
* Count = Buffer->Count;
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into }
* \param[in] Data Data element to insert into the buffer
*/ return Count;
static inline void RingBuffer_Insert(RingBuff_t* const Buffer, }
const RingBuff_Data_t Data)
{ /** Atomically determines if the specified ring buffer contains any free space. This should
*Buffer->In = Data; * be tested before storing data to the buffer, to ensure that no data is lost due to a
* buffer overrun.
if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE]) *
Buffer->In = Buffer->Buffer; * \param[in,out] Buffer Pointer to a ring buffer structure to insert into
*
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) * \return Boolean true if the buffer contains no free space, false otherwise
{ */
Buffer->Count++; static inline bool RingBuffer_IsFull(RingBuff_t* const Buffer)
} {
} return (RingBuffer_GetCount(Buffer) == Buffer->Size);
}
/** Removes an element from the ring buffer.
* /** Atomically determines if the specified ring buffer contains any data. This should
* \note Only one execution thread (main program thread or an ISR) may remove from a single buffer * be tested before removing data from the buffer, to ensure that the buffer does not
* otherwise data corruption may occur. Insertion and removal may occur from different execution * underflow.
* threads. *
* * If the data is to be removed in a loop, store the total number of bytes stored in the
* \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from * buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable
* * to reduce the time spent in atomicity locks.
* \return Next data element stored in the buffer *
*/ * \param[in,out] Buffer Pointer to a ring buffer structure to insert into
static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer) *
{ * \return Boolean true if the buffer contains no free space, false otherwise
RingBuff_Data_t Data = *Buffer->Out; */
static inline bool RingBuffer_IsEmpty(RingBuff_t* const Buffer)
if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE]) {
Buffer->Out = Buffer->Buffer; return (RingBuffer_GetCount(Buffer) == 0);
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{ /** Inserts an element into the ring buffer.
Buffer->Count--; *
} * \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
return Data; * threads.
} *
* \param[in,out] Buffer Pointer to a ring buffer structure to insert into
/** Returns the next element stored in the ring buffer, without removing it. * \param[in] Data Data element to insert into the buffer
* */
* \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from static inline void RingBuffer_Insert(RingBuff_t* const Buffer,
* const uint8_t Data)
* \return Next data element stored in the buffer {
*/ *Buffer->In = Data;
static inline RingBuff_Data_t RingBuffer_Peek(RingBuff_t* const Buffer)
{ if (++Buffer->In == Buffer->End)
return *Buffer->Out; Buffer->In = Buffer->Start;
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
#endif {
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
/** @} */

@ -12,6 +12,8 @@
* - Added new MIDIToneGenerator project * - Added new MIDIToneGenerator project
* - Added new ORDERED_EP_CONFIG compile time option to restrict endpoint/pipe configuration to ascending order * - 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 * 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: * - Library Applications:
* - Added new incomplete MIDIToneGenerator project * - Added new incomplete MIDIToneGenerator project
* - Added ability to write protect Mass Storage disk write operations from the host OS * - 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 * 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 * - Combined page and word ISP programming mode code in the AVRISP-MKII clone project to reduce compiled size and
* increase maintainability of the code * increase maintainability of the code
* - Changed over library projects to use the new general ring buffer library driver module
* *
* <b>Fixed:</b> * <b>Fixed:</b>
* - Core: * - Core:

@ -21,7 +21,6 @@
* -# Add HID report macros to make HID report editing easier * -# Add HID report macros to make HID report editing easier
* -# Investigate dynamically created device descriptors * -# Investigate dynamically created device descriptors
* - Known Bugs * - 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 * -# No wakeup when plugged into hub, and hub plugged into host
* -# Incomplete TMC class demo errors * -# Incomplete TMC class demo errors
* - Documentation/Support * - Documentation/Support

@ -39,6 +39,9 @@
/** Circular buffer to hold data from the serial port before it is sent to the host. */ /** Circular buffer to hold data from the serial port before it is sent to the host. */
RingBuff_t USARTtoUSB_Buffer; 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 */ /** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
volatile struct volatile struct
{ {
@ -85,7 +88,7 @@ int main(void)
{ {
SetupHardware(); SetupHardware();
RingBuffer_InitBuffer(&USARTtoUSB_Buffer); RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data));
sei(); sei();
@ -126,7 +129,7 @@ int main(void)
LEDs_TurnOffLEDs(LEDMASK_RX); LEDs_TurnOffLEDs(LEDMASK_RX);
/* Check if the receive buffer flush period has expired */ /* 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)) if (!(--FlushPeriodRemaining) || (BufferCount > 200))
{ {
/* Echo bytes from the target to the host via the virtual serial port */ /* Echo bytes from the target to the host via the virtual serial port */

@ -42,11 +42,11 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "Descriptors.h" #include "Descriptors.h"
#include "Lib/LightweightRingBuff.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Peripheral/Serial.h> #include <LUFA/Drivers/Peripheral/Serial.h>
#include <LUFA/Drivers/Misc/RingBuffer.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Macros: */ /* Macros: */

@ -118,6 +118,7 @@ LUFA_PATH = ../..
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 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_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS LUFA_OPTS += -D USE_FLASH_DESCRIPTORS

@ -117,6 +117,8 @@ LUFA_PATH = ../../..
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 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_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS LUFA_OPTS += -D USE_FLASH_DESCRIPTORS

@ -118,6 +118,7 @@ LUFA_PATH = ../..
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 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_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS LUFA_OPTS += -D USE_FLASH_DESCRIPTORS

@ -118,6 +118,7 @@ LUFA_PATH = ../../
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 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_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS LUFA_OPTS += -D USE_FLASH_DESCRIPTORS

@ -118,6 +118,7 @@ LUFA_PATH = ../..
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 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_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS LUFA_OPTS += -D USE_FLASH_DESCRIPTORS

@ -118,6 +118,7 @@ LUFA_PATH = ../..
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_HOST_ONLY LUFA_OPTS = -D USB_HOST_ONLY
LUFA_OPTS += -D HOST_STATE_AS_GPIOR=0 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 USE_STATIC_OPTIONS="(USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
LUFA_OPTS += -D NO_STREAM_CALLBACKS LUFA_OPTS += -D NO_STREAM_CALLBACKS

@ -118,6 +118,7 @@ LUFA_PATH = ../..
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 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_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D CONTROL_ONLY_DEVICE LUFA_OPTS += -D CONTROL_ONLY_DEVICE

@ -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 <util/atomic.h>
#include <stdint.h>
#include <stdbool.h>
/* 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

@ -39,9 +39,16 @@
/** Circular buffer to hold data from the host before it is sent to the device via the serial port. */ /** Circular buffer to hold data from the host before it is sent to the device via the serial port. */
RingBuff_t USBtoUSART_Buffer; 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. */ /** Circular buffer to hold data from the serial port before it is sent to the host. */
RingBuff_t USARTtoUSB_Buffer; 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 /** 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 * passed to all CDC Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another. * within a device can be differentiated from one another.
@ -73,8 +80,8 @@ int main(void)
{ {
SetupHardware(); SetupHardware();
RingBuffer_InitBuffer(&USBtoUSART_Buffer); RingBuffer_InitBuffer(&USBtoUSART_Buffer, USBtoUSART_Buffer_Data, sizeof(USBtoUSART_Buffer_Data));
RingBuffer_InitBuffer(&USARTtoUSB_Buffer); RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data));
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei(); sei();
@ -92,7 +99,7 @@ int main(void)
} }
/* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */ /* 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)) if ((TIFR0 & (1 << TOV0)) || (BufferCount > 200))
{ {
/* Clear flush timer expiry flag */ /* Clear flush timer expiry flag */

@ -44,11 +44,10 @@
#include "Descriptors.h" #include "Descriptors.h"
#include "Lib/LightweightRingBuff.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Peripheral/Serial.h> #include <LUFA/Drivers/Peripheral/Serial.h>
#include <LUFA/Drivers/Misc/RingBuffer.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Macros: */ /* Macros: */

@ -118,6 +118,7 @@ LUFA_PATH = ../..
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 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_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS LUFA_OPTS += -D USE_FLASH_DESCRIPTORS

@ -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 <util/atomic.h>
#include <stdint.h>
#include <stdbool.h>
/* 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

@ -44,7 +44,6 @@
#include <stdbool.h> #include <stdbool.h>
#include "../XPLAINBridge.h" #include "../XPLAINBridge.h"
#include "LightweightRingBuff.h"
/* Macros: */ /* Macros: */
#define SRX PD0 #define SRX PD0

@ -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. */ /** Circular buffer to hold data from the host before it is sent to the device via the serial port. */
RingBuff_t USBtoUART_Buffer; 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. */ /** Circular buffer to hold data from the serial port before it is sent to the host. */
RingBuff_t UARTtoUSB_Buffer; 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 /** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop. * 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 */ /* 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)) if ((TIFR0 & (1 << TOV0)) || (BufferCount > 200))
{ {
/* Clear flush timer expiry flag */ /* Clear flush timer expiry flag */
@ -199,8 +205,8 @@ void EVENT_USB_Device_ConfigurationChanged(void)
TCCR0B = ((1 << CS02) | (1 << CS00)); TCCR0B = ((1 << CS02) | (1 << CS00));
/* Initialize ring buffers used to hold serial data between USB and software UART interfaces */ /* Initialize ring buffers used to hold serial data between USB and software UART interfaces */
RingBuffer_InitBuffer(&USBtoUART_Buffer); RingBuffer_InitBuffer(&USBtoUART_Buffer, USBtoUART_Buffer_Data, sizeof(USBtoUART_Buffer_Data));
RingBuffer_InitBuffer(&UARTtoUSB_Buffer); RingBuffer_InitBuffer(&UARTtoUSB_Buffer, UARTtoUSB_Buffer_Data, sizeof(UARTtoUSB_Buffer_Data));
/* Start the software USART */ /* Start the software USART */
SoftUART_Init(); SoftUART_Init();

@ -46,12 +46,12 @@
#include "AVRISPDescriptors.h" #include "AVRISPDescriptors.h"
#include "USARTDescriptors.h" #include "USARTDescriptors.h"
#include "Lib/LightweightRingBuff.h"
#include "Lib/SoftUART.h" #include "Lib/SoftUART.h"
#include "Lib/V2Protocol.h" #include "Lib/V2Protocol.h"
#include <LUFA/Version.h> #include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h> #include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Misc/RingBuffer.h>
#include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/USB/USB.h>
/* Macros: */ /* Macros: */

@ -122,6 +122,7 @@ AVRISP_PATH = ../AVRISP-MKII
# LUFA library compile-time options and predefined tokens # LUFA library compile-time options and predefined tokens
LUFA_OPTS = -D USB_DEVICE_ONLY LUFA_OPTS = -D USB_DEVICE_ONLY
LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0 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_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
LUFA_OPTS += -D USE_FLASH_DESCRIPTORS LUFA_OPTS += -D USE_FLASH_DESCRIPTORS

Loading…
Cancel
Save