- /* Read bytes from the UART receive buffer into the USB IN endpoint */
- if (UARTtoUSB_Buffer.Elements)
- CDC_Device_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&UARTtoUSB_Buffer));
-
- /* Load bytes from the UART transmit buffer into the UART */
- if ((USBtoUART_Buffer.Elements) && SoftUART_IsReady())
- SoftUART_TxByte(Buffer_GetElement(&USBtoUART_Buffer));
-
- /* Load bytes from the UART into the UART receive buffer */
- if (SoftUART_IsReceived())
- Buffer_StoreElement(&UARTtoUSB_Buffer, SoftUART_RxByte());
+ /* Check if the UART receive buffer flush timer has expired or buffer is nearly full */
+ uint16_t BufferCount = RingBuffer_GetCount(&UARTtoUSB_Buffer);
+ if ((TIFR0 & (1 << TOV0)) || (BufferCount > 200))
+ {
+ /* Clear flush timer expiry flag */
+ TIFR0 |= (1 << TOV0);
+
+ /* Read bytes from the USART receive buffer into the USB IN endpoint */
+ while (BufferCount--)
+ {
+ /* Try to send the next byte of data to the host, abort if there is an error without dequeuing */
+ if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface,
+ RingBuffer_Peek(&UARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
+ {
+ break;
+ }
+
+ /* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
+ RingBuffer_Remove(&UARTtoUSB_Buffer);
+ }
+ }