Fix up the incomplete Webserver project so that it integrates with the uIP stack...
[pub/USBasp.git] / Projects / XPLAINBridge / XPLAINBridge.c
index 68cca54..2de545f 100644 (file)
@@ -1,22 +1,21 @@
 /*\r
              LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
+     Copyright (C) Dean Camera, 2010.\r
               \r
   dean [at] fourwalledcubicle [dot] com\r
       www.fourwalledcubicle.com\r
 */\r
 \r
 /*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-  Copyright 2009  John Steggall (steggall.j@gmail.com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
+  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, distribute, and sell this \r
+  software and its documentation for any purpose is hereby granted\r
+  without fee, provided that the above copyright notice appear in \r
+  all copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting \r
+  documentation, and that the name of the author not be used in \r
+  advertising or publicity pertaining to distribution of the \r
   software without specific, written prior permission.\r
 \r
   The author disclaim all warranties with regard to this\r
 \r
 #include "XPLAINBridge.h"\r
 \r
-/** Circular buffer to hold data from the host before it is sent to the device via the serial port. */\r
-RingBuff_t USBtoUART_Buffer;\r
-\r
-/** Circular buffer to hold data from the serial port before it is sent to the host. */\r
-RingBuff_t UARTtoUSB_Buffer;\r
+/* Current firmware mode, making the device behave as either a programmer or a USART bridge */\r
+bool CurrentFirmwareMode = MODE_PDI_PROGRAMMER;\r
 \r
 /** LUFA CDC Class driver interface configuration and state information. This structure is\r
  *  passed to all CDC Class driver functions, so that multiple instances of the same class\r
@@ -66,6 +62,13 @@ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
                                .NotificationEndpointDoubleBank = false,\r
                        },\r
        };\r
+       \r
+/** Circular buffer to hold data from the host before it is sent to the device via the serial port. */\r
+RingBuff_t USBtoUART_Buffer;\r
+\r
+/** Circular buffer to hold data from the serial port before it is sent to the host. */\r
+RingBuff_t UARTtoUSB_Buffer;\r
+\r
 \r
 /** Main program entry point. This routine contains the overall program flow, including initial\r
  *  setup of all components and the main program loop.\r
@@ -79,32 +82,60 @@ int main(void)
 \r
        for (;;)\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
+               if (USB_DeviceState == DEVICE_STATE_Configured)\r
                {\r
-                       if (!(BUFF_STATICSIZE - USBtoUART_Buffer.Elements))\r
-                         break;\r
-                         \r
-                       Buffer_StoreElement(&USBtoUART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface));\r
+                       if (CurrentFirmwareMode == MODE_USART_BRIDGE)\r
+                         USARTBridge_Task();\r
+                       else\r
+                         AVRISP_Task();\r
                }\r
                \r
-               /* Read bytes from the UART receive buffer into the USB IN endpoint */\r
-               if (UARTtoUSB_Buffer.Elements)\r
-                 CDC_Device_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&UARTtoUSB_Buffer));\r
-               \r
-               /* Load bytes from the UART transmit buffer into the UART */\r
-               if ((USBtoUART_Buffer.Elements) && SoftUART_IsReady())\r
-                 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
-\r
-               CDC_Device_USBTask(&VirtualSerial_CDC_Interface);\r
                USB_USBTask();\r
        }\r
 }\r
 \r
+void AVRISP_Task(void)\r
+{\r
+       Endpoint_SelectEndpoint(AVRISP_DATA_EPNUM);\r
+       \r
+       /* Check to see if a V2 Protocol command has been received */\r
+       if (Endpoint_IsOUTReceived())\r
+       {\r
+               LEDs_SetAllLEDs(LEDMASK_BUSY);\r
+\r
+               /* Pass off processing of the V2 Protocol command to the V2 Protocol handler */\r
+               V2Protocol_ProcessCommand();\r
+\r
+               LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
+       }\r
+}\r
+\r
+void USARTBridge_Task(void)\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
+               if (!(BUFF_STATICSIZE - USBtoUART_Buffer.Elements))\r
+                 break;\r
+                 \r
+               Buffer_StoreElement(&USBtoUART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface));\r
+       }\r
+       \r
+       /* Read bytes from the UART receive buffer into the USB IN endpoint */\r
+       if (UARTtoUSB_Buffer.Elements)\r
+         CDC_Device_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&UARTtoUSB_Buffer));\r
+       \r
+       /* Load bytes from the UART transmit buffer into the UART */\r
+       if ((USBtoUART_Buffer.Elements) && SoftUART_IsReady())\r
+         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
+\r
+       CDC_Device_USBTask(&VirtualSerial_CDC_Interface);\r
+}\r
+\r
 /** Configures the board hardware and chip peripherals for the demo's functionality. */\r
 void SetupHardware(void)\r
 {\r
@@ -117,17 +148,61 @@ void SetupHardware(void)
 \r
        /* Hardware Initialization */\r
        SoftUART_Init();\r
+       LEDs_Init();\r
        USB_Init();\r
+       V2Protocol_Init();\r
+       \r
+       /* Disable JTAG debugging */\r
+       MCUCR |= (1 << JTD);\r
+       MCUCR |= (1 << JTD);\r
+\r
+       /* Enable pullup on the JTAG TDI pin so we can use it to select the mode */\r
+       PORTF |= (1 << 7);\r
+       _delay_ms(10);\r
+\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
 \r
 /** Event handler for the library USB Configuration Changed event. */\r
 void EVENT_USB_Device_ConfigurationChanged(void)\r
 {\r
-       CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);\r
+       bool EndpointConfigSuccess;\r
+\r
+       if (CurrentFirmwareMode == MODE_USART_BRIDGE)\r
+       {\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
+       }\r
+\r
+       if (EndpointConfigSuccess)\r
+         LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
+       else\r
+         LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
 }\r
 \r
 /** Event handler for the library USB Unhandled Control Request event. */\r
 void EVENT_USB_Device_UnhandledControlRequest(void)\r
 {\r
-       CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);\r
+       if (CurrentFirmwareMode == MODE_USART_BRIDGE)\r
+         CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);\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
+ *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the\r
+ *  USB host.\r
+ */\r
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)\r
+{\r
+       if (CurrentFirmwareMode == MODE_USART_BRIDGE)\r
+         return USART_GetDescriptor(wValue, wIndex, DescriptorAddress);\r
+       else\r
+         return AVRISP_GetDescriptor(wValue, wIndex, DescriptorAddress);\r
 }\r