-               
-               /* 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));
-               
-               /* Load bytes from the USART transmit buffer into the USART */
-               while (USBtoUSART_Buffer.Count)
-                 Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer));
-               
+
+               /* Check if the UART receive buffer flush timer has expired or the buffer is nearly full */
+               uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
+               if (BufferCount)
+               {
+                       Endpoint_SelectEndpoint(VirtualSerial_CDC_Interface.Config.DataINEndpoint.Address);
+
+                       /* Check if a packet is already enqueued to the host - if so, we shouldn't try to send more data
+                        * until it completes as there is a chance nothing is listening and a lengthy timeout could occur */
+                       if (Endpoint_IsINReady())
+                       {
+                               /* Never send more than one bank size less one byte to the host at a time, so that we don't block
+                                * while a Zero Length Packet (ZLP) to terminate the transfer is sent if the host isn't listening */
+                               uint8_t BytesToSend = MIN(BufferCount, (CDC_TXRX_EPSIZE - 1));
+
+                               /* Read bytes from the USART receive buffer into the USB IN endpoint */
+                               while (BytesToSend--)
+                               {
+                                       /* 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(&USARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
+                                       {
+                                               break;
+                                       }
+
+                                       /* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
+                                       RingBuffer_Remove(&USARTtoUSB_Buffer);
+                               }
+                       }
+               }
+
+               /* Load the next byte from the USART transmit buffer into the USART */
+               if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer)))
+                 Serial_SendByte(RingBuffer_Remove(&USBtoUSART_Buffer));
+