diff options
Diffstat (limited to 'Projects/USBtoSerial')
-rw-r--r-- | Projects/USBtoSerial/Lib/LightweightRingBuff.h | 41 | ||||
-rw-r--r-- | Projects/USBtoSerial/USBtoSerial.c | 23 |
2 files changed, 53 insertions, 11 deletions
diff --git a/Projects/USBtoSerial/Lib/LightweightRingBuff.h b/Projects/USBtoSerial/Lib/LightweightRingBuff.h index 1dc05935c..9c25707b4 100644 --- a/Projects/USBtoSerial/Lib/LightweightRingBuff.h +++ b/Projects/USBtoSerial/Lib/LightweightRingBuff.h @@ -75,12 +75,12 @@ Buffer->Count = 0; } - /** Inserts an element into the ring buffer. + /** Atomically inserts an element into the ring buffer. * * \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, RingBuff_Data_t Data) + static inline void RingBuffer_AtomicInsert(RingBuff_t* const Buffer, RingBuff_Data_t Data) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { @@ -93,13 +93,13 @@ } } - /** Retrieves an element from the ring buffer. + /** Atomically retrieves an element from the ring buffer. * * \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) + static inline RingBuff_Data_t RingBuffer_AtomicRemove(RingBuff_t* const Buffer) { RingBuff_Data_t Data; @@ -116,5 +116,38 @@ return Data; } + /** Inserts an element into the ring buffer. + * + * \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, RingBuff_Data_t Data) + { + *Buffer->In = Data; + + if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE]) + Buffer->In = Buffer->Buffer; + + Buffer->Count++; + } + + /** Retrieves an element from the ring buffer. + * + * \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; + + Buffer->Count--; + + return Data; + } + #endif
\ No newline at end of file diff --git a/Projects/USBtoSerial/USBtoSerial.c b/Projects/USBtoSerial/USBtoSerial.c index 7a0f6866a..918986883 100644 --- a/Projects/USBtoSerial/USBtoSerial.c +++ b/Projects/USBtoSerial/USBtoSerial.c @@ -87,16 +87,22 @@ int main(void) if (!(BUFFER_SIZE - USBtoUSART_Buffer.Count)) break; - RingBuffer_Insert(&USBtoUSART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface)); + RingBuffer_AtomicInsert(&USBtoUSART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface)); } - /* Read bytes from the USART receive buffer into the USB IN endpoint */ - while (USARTtoUSB_Buffer.Count) - CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer)); + /* Check if the software USART flush timer has expired */ + if (TIFR0 & (1 << TOV0)) + { + TIFR0 |= (1 << TOV0); + + /* Read bytes from the USART receive buffer into the USB IN endpoint */ + while (USARTtoUSB_Buffer.Count) + CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_AtomicRemove(&USARTtoUSB_Buffer)); + } - /* Load bytes from the USART transmit buffer into the USART */ - while (USBtoUSART_Buffer.Count) - Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer)); + /* Load the next byte from the USART transmit buffer into the USART */ + if (USBtoUSART_Buffer.Count) + Serial_TxByte(RingBuffer_AtomicRemove(&USBtoUSART_Buffer)); CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); @@ -117,6 +123,9 @@ void SetupHardware(void) Serial_Init(9600, false); LEDs_Init(); USB_Init(); + + /* Configure the UART flush timer - run at Fcpu/1024 for maximum interval before overflow */ + TCCR0B = ((1 << CS02) | (1 << CS00)); } /** Event handler for the library USB Connection event. */ |