\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
\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
.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
Buffer_Initialize(&USBtoUART_Buffer);\r
Buffer_Initialize(&UARTtoUSB_Buffer);\r
\r
+ LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
+ sei();\r
+\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
- {\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
+ 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
+ /* 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
+ {\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
+ /* 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
+ 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
SoftUART_Init();\r
LEDs_Init();\r
USB_Init();\r
+ V2Protocol_Init();\r
\r
- PORTD |= (1 << 5); // PD5 is connected to the XMEGA /RESET, enable pullup\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
+ /* 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
- LEDs_SetAllLEDs(LEDS_LED1);\r
+ bool EndpointConfigSuccess = true;\r
\r
- if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))\r
- LEDs_SetAllLEDs(LEDS_NO_LEDS);\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
+ }\r
+ else\r
+ {\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
+ 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
+/** 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
+ * 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
+ /* 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
+ return AVRISP_GetDescriptor(wValue, wIndex, DescriptorAddress);\r
}\r