Device mode class driver callbacks are now fired before the control request status...
[pub/USBasp.git] / Projects / XPLAINBridge / XPLAINBridge.c
index 2de545f..5457a22 100644 (file)
@@ -51,11 +51,11 @@ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
 \r
                                .DataINEndpointNumber           = CDC_TX_EPNUM,\r
                                .DataINEndpointSize             = CDC_TXRX_EPSIZE,\r
-                               .DataINEndpointDoubleBank       = false,\r
+                               .DataINEndpointDoubleBank       = true,\r
 \r
                                .DataOUTEndpointNumber          = CDC_RX_EPNUM,\r
                                .DataOUTEndpointSize            = CDC_TXRX_EPSIZE,\r
-                               .DataOUTEndpointDoubleBank      = false,\r
+                               .DataOUTEndpointDoubleBank      = true,\r
 \r
                                .NotificationEndpointNumber     = CDC_NOTIFICATION_EPNUM,\r
                                .NotificationEndpointSize       = CDC_NOTIFICATION_EPSIZE,\r
@@ -80,23 +80,27 @@ int main(void)
        Buffer_Initialize(&USBtoUART_Buffer);\r
        Buffer_Initialize(&UARTtoUSB_Buffer);\r
 \r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+       sei();\r
+\r
        for (;;)\r
        {\r
-               if (USB_DeviceState == DEVICE_STATE_Configured)\r
-               {\r
-                       if (CurrentFirmwareMode == MODE_USART_BRIDGE)\r
-                         USARTBridge_Task();\r
-                       else\r
-                         AVRISP_Task();\r
-               }\r
-               \r
+               if (CurrentFirmwareMode == MODE_USART_BRIDGE)\r
+                 USARTBridge_Task();\r
+               else\r
+                 AVRISP_Task();\r
+\r
                USB_USBTask();\r
        }\r
 }\r
 \r
 void AVRISP_Task(void)\r
 {\r
-       Endpoint_SelectEndpoint(AVRISP_DATA_EPNUM);\r
+       /* Must be in the configured state for the AVRISP code to process data */\r
+       if (USB_DeviceState != DEVICE_STATE_Configured)\r
+         return;\r
+\r
+       Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPNUM);\r
        \r
        /* Check to see if a V2 Protocol command has been received */\r
        if (Endpoint_IsOUTReceived())\r
@@ -112,6 +116,10 @@ void AVRISP_Task(void)
 \r
 void USARTBridge_Task(void)\r
 {\r
+       /* Must be in the configured state for the USART Bridge code to process data */\r
+       if (USB_DeviceState != DEVICE_STATE_Configured)\r
+         return;\r
+\r
        /* Read bytes from the USB OUT endpoint into the UART transmit buffer */\r
        for (uint8_t DataBytesRem = CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface); DataBytesRem != 0; DataBytesRem--)\r
        {\r
@@ -130,8 +138,8 @@ void USARTBridge_Task(void)
          SoftUART_TxByte(Buffer_GetElement(&USBtoUART_Buffer));\r
        \r
        /* Load bytes from the UART into the UART receive buffer */\r
-       if(SoftUART_IsReceived())\r
-               Buffer_StoreElement(&UARTtoUSB_Buffer, SoftUART_RxByte());\r
+       if (SoftUART_IsReceived())\r
+         Buffer_StoreElement(&UARTtoUSB_Buffer, SoftUART_RxByte());\r
 \r
        CDC_Device_USBTask(&VirtualSerial_CDC_Interface);\r
 }\r
@@ -162,22 +170,33 @@ void SetupHardware(void)
 \r
        /* Select the firmware mode based on the JTD pin's value */\r
        CurrentFirmwareMode = (PINF & (1 << 7)) ? MODE_USART_BRIDGE : MODE_PDI_PROGRAMMER;\r
+\r
+       /* Re-enable JTAG debugging */\r
+       MCUCR &= ~(1 << JTD);\r
+       MCUCR &= ~(1 << JTD);\r
 }\r
 \r
 /** Event handler for the library USB Configuration Changed event. */\r
 void EVENT_USB_Device_ConfigurationChanged(void)\r
 {\r
-       bool EndpointConfigSuccess;\r
+       bool EndpointConfigSuccess = true;\r
 \r
+       /* Configure the device endpoints according to the selected mode */\r
        if (CurrentFirmwareMode == MODE_USART_BRIDGE)\r
        {\r
-               EndpointConfigSuccess = CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);\r
+               EndpointConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);\r
        }\r
        else\r
        {\r
-               EndpointConfigSuccess = Endpoint_ConfigureEndpoint(AVRISP_DATA_EPNUM, EP_TYPE_BULK,\r
-                                                                                                  ENDPOINT_DIR_OUT, AVRISP_DATA_EPSIZE,\r
-                                                                                                  ENDPOINT_BANK_SINGLE);\r
+               EndpointConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_OUT_EPNUM, EP_TYPE_BULK,\r
+                                                                                                   ENDPOINT_DIR_OUT, AVRISP_DATA_EPSIZE,\r
+                                                                                                   ENDPOINT_BANK_SINGLE);\r
+\r
+               #if defined(LIBUSB_FILTERDRV_COMPAT)\r
+               EndpointConfigSuccess &= Endpoint_ConfigureEndpoint(AVRISP_DATA_IN_EPNUM, EP_TYPE_BULK,\r
+                                                                   ENDPOINT_DIR_IN, AVRISP_DATA_EPSIZE,\r
+                                                                   ENDPOINT_BANK_SINGLE);\r
+               #endif\r
        }\r
 \r
        if (EndpointConfigSuccess)\r
@@ -193,6 +212,18 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
          CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);\r
 }\r
 \r
+/** Event handler for the library USB Connection event. */\r
+void EVENT_USB_Device_Connect(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
+}\r
+\r
+/** Event handler for the library USB Disconnection event. */\r
+void EVENT_USB_Device_Disconnect(void)\r
+{\r
+       LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+}\r
+\r
 /** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"\r
  *  documentation) by the application code so that the address and size of a requested descriptor can be given\r
  *  to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function\r
@@ -201,6 +232,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
  */\r
 uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)\r
 {\r
+       /* Return the correct descriptors based on the selected mode */\r
        if (CurrentFirmwareMode == MODE_USART_BRIDGE)\r
          return USART_GetDescriptor(wValue, wIndex, DescriptorAddress);\r
        else\r