Re-add in old Endpoint/Pipe workaround for unordered pipes - add new ORDERED_EP_CONFI...
[pub/USBasp.git] / Projects / XPLAINBridge / XPLAINBridge.c
index 8cd1b2d..912e683 100644 (file)
@@ -31,7 +31,7 @@
 /** \file
  *
  *  Main source file for the XPLAINBridge project. This file contains the main tasks of
- *  the demo and is responsible for the initial application hardware configuration.
+ *  the project and is responsible for the initial application hardware configuration.
  */
 
 #include "XPLAINBridge.h"
@@ -119,20 +119,36 @@ void UARTBridge_Task(void)
        if (USB_DeviceState != DEVICE_STATE_Configured)
          return;
 
-       /* Read bytes from the USB OUT endpoint into the UART transmit buffer */
-       int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
-       if (!(ReceivedByte < 0) && !(RingBuffer_IsFull(&USBtoUART_Buffer)))
-         RingBuffer_Insert(&USBtoUART_Buffer, ReceivedByte);
+       /* Only try to read in bytes from the CDC interface if the transmit buffer is not full */
+       if (!(RingBuffer_IsFull(&USBtoUART_Buffer)))
+       {
+               int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
 
+               /* Read bytes from the USB OUT endpoint into the UART transmit buffer */
+               if (!(ReceivedByte < 0))
+                 RingBuffer_Insert(&USBtoUART_Buffer, ReceivedByte);
+       }
+       
        /* Check if the UART receive buffer flush timer has expired or buffer is nearly full */
        RingBuff_Count_t BufferCount = RingBuffer_GetCount(&UARTtoUSB_Buffer);
        if ((TIFR0 & (1 << TOV0)) || (BufferCount > 200))
        {
+               /* Clear flush timer expiry flag */
                TIFR0 |= (1 << TOV0);
 
-               /* Read bytes from the UART receive buffer into the USB IN endpoint */
+               /* Read bytes from the USART receive buffer into the USB IN endpoint */
                while (BufferCount--)
-                 CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&UARTtoUSB_Buffer));
+               {
+                       /* 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);
+               }
        }
 
        CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
@@ -206,8 +222,8 @@ void EVENT_USB_Device_ConfigurationChanged(void)
        LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
 }
 
-/** Event handler for the library USB Unhandled Control Request event. */
-void EVENT_USB_Device_UnhandledControlRequest(void)
+/** Event handler for the library USB Control Request reception event. */
+void EVENT_USB_Device_ControlRequest(void)
 {
        if (CurrentFirmwareMode == MODE_USART_BRIDGE)
          CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);