Fix flip-ee DFU build target accidentally erasing the target FLASH memory space.
[pub/USBasp.git] / Projects / USBtoSerial / USBtoSerial.c
index e073425..fb9ac87 100644 (file)
@@ -7,7 +7,7 @@
 */
 
 /*
-  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+  Copyright 2012  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
@@ -57,18 +57,24 @@ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
                .Config =
                        {
                                .ControlInterfaceNumber         = 0,
-
-                               .DataINEndpointNumber           = CDC_TX_EPNUM,
-                               .DataINEndpointSize             = CDC_TXRX_EPSIZE,
-                               .DataINEndpointDoubleBank       = false,
-
-                               .DataOUTEndpointNumber          = CDC_RX_EPNUM,
-                               .DataOUTEndpointSize            = CDC_TXRX_EPSIZE,
-                               .DataOUTEndpointDoubleBank      = false,
-
-                               .NotificationEndpointNumber     = CDC_NOTIFICATION_EPNUM,
-                               .NotificationEndpointSize       = CDC_NOTIFICATION_EPSIZE,
-                               .NotificationEndpointDoubleBank = false,
+                               .DataINEndpoint                 =
+                                       {
+                                               .Address                = CDC_TX_EPADDR,
+                                               .Size                   = CDC_TXRX_EPSIZE,
+                                               .Banks                  = 1,
+                                       },
+                               .DataOUTEndpoint                =
+                                       {
+                                               .Address                = CDC_RX_EPADDR,
+                                               .Size                   = CDC_TXRX_EPSIZE,
+                                               .Banks                  = 1,
+                                       },
+                               .NotificationEndpoint           =
+                                       {
+                                               .Address                = CDC_NOTIFICATION_EPADDR,
+                                               .Size                   = CDC_NOTIFICATION_EPSIZE,
+                                               .Banks                  = 1,
+                                       },
                        },
        };
 
@@ -84,7 +90,7 @@ int main(void)
        RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data));
 
        LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
-       sei();
+       GlobalInterruptEnable();
 
        for (;;)
        {
@@ -102,21 +108,32 @@ int main(void)
                uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
                if ((TIFR0 & (1 << TOV0)) || (BufferCount > (uint8_t)(sizeof(USARTtoUSB_Buffer_Data) * .75)))
                {
-                       /* Clear flush timer expiry flag */
-                       TIFR0 |= (1 << TOV0);
-
-                       /* Read bytes from the USART receive buffer into the USB IN endpoint */
-                       while (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())
                        {
-                               /* 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)
+                               /* Clear flush timer expiry flag */
+                               TIFR0 |= (1 << TOV0);
+                       
+                               /* 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--)
                                {
-                                       break;
+                                       /* 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);
                                }
-
-                               /* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
-                               RingBuffer_Remove(&USARTtoUSB_Buffer);
                        }
                }