aboutsummaryrefslogtreecommitdiffstats
path: root/Projects/XPLAINBridge/XPLAINBridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'Projects/XPLAINBridge/XPLAINBridge.c')
-rw-r--r--Projects/XPLAINBridge/XPLAINBridge.c128
1 files changed, 99 insertions, 29 deletions
diff --git a/Projects/XPLAINBridge/XPLAINBridge.c b/Projects/XPLAINBridge/XPLAINBridge.c
index 37509a981..2de545f95 100644
--- a/Projects/XPLAINBridge/XPLAINBridge.c
+++ b/Projects/XPLAINBridge/XPLAINBridge.c
@@ -36,11 +36,8 @@
#include "XPLAINBridge.h"
-/** Circular buffer to hold data from the host before it is sent to the device via the serial port. */
-RingBuff_t USBtoUART_Buffer;
-
-/** Circular buffer to hold data from the serial port before it is sent to the host. */
-RingBuff_t UARTtoUSB_Buffer;
+/* Current firmware mode, making the device behave as either a programmer or a USART bridge */
+bool CurrentFirmwareMode = MODE_PDI_PROGRAMMER;
/** LUFA CDC Class driver interface configuration and state information. This structure is
* passed to all CDC Class driver functions, so that multiple instances of the same class
@@ -65,6 +62,13 @@ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
.NotificationEndpointDoubleBank = false,
},
};
+
+/** Circular buffer to hold data from the host before it is sent to the device via the serial port. */
+RingBuff_t USBtoUART_Buffer;
+
+/** Circular buffer to hold data from the serial port before it is sent to the host. */
+RingBuff_t UARTtoUSB_Buffer;
+
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.
@@ -78,32 +82,60 @@ int main(void)
for (;;)
{
- /* Read bytes from the USB OUT endpoint into the UART transmit buffer */
- for (uint8_t DataBytesRem = CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface); DataBytesRem != 0; DataBytesRem--)
+ if (USB_DeviceState == DEVICE_STATE_Configured)
{
- if (!(BUFF_STATICSIZE - USBtoUART_Buffer.Elements))
- break;
-
- Buffer_StoreElement(&USBtoUART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface));
+ if (CurrentFirmwareMode == MODE_USART_BRIDGE)
+ USARTBridge_Task();
+ else
+ AVRISP_Task();
}
- /* Read bytes from the UART receive buffer into the USB IN endpoint */
- if (UARTtoUSB_Buffer.Elements)
- CDC_Device_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&UARTtoUSB_Buffer));
-
- /* Load bytes from the UART transmit buffer into the UART */
- if ((USBtoUART_Buffer.Elements) && SoftUART_IsReady())
- SoftUART_TxByte(Buffer_GetElement(&USBtoUART_Buffer));
-
- /* Load bytes from the UART into the UART receive buffer */
- if(SoftUART_IsReceived())
- Buffer_StoreElement(&UARTtoUSB_Buffer, SoftUART_RxByte());
-
- CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
USB_USBTask();
}
}
+void AVRISP_Task(void)
+{
+ Endpoint_SelectEndpoint(AVRISP_DATA_EPNUM);
+
+ /* Check to see if a V2 Protocol command has been received */
+ if (Endpoint_IsOUTReceived())
+ {
+ LEDs_SetAllLEDs(LEDMASK_BUSY);
+
+ /* Pass off processing of the V2 Protocol command to the V2 Protocol handler */
+ V2Protocol_ProcessCommand();
+
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
+ }
+}
+
+void USARTBridge_Task(void)
+{
+ /* Read bytes from the USB OUT endpoint into the UART transmit buffer */
+ for (uint8_t DataBytesRem = CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface); DataBytesRem != 0; DataBytesRem--)
+ {
+ if (!(BUFF_STATICSIZE - USBtoUART_Buffer.Elements))
+ break;
+
+ Buffer_StoreElement(&USBtoUART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface));
+ }
+
+ /* Read bytes from the UART receive buffer into the USB IN endpoint */
+ if (UARTtoUSB_Buffer.Elements)
+ CDC_Device_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&UARTtoUSB_Buffer));
+
+ /* Load bytes from the UART transmit buffer into the UART */
+ if ((USBtoUART_Buffer.Elements) && SoftUART_IsReady())
+ SoftUART_TxByte(Buffer_GetElement(&USBtoUART_Buffer));
+
+ /* Load bytes from the UART into the UART receive buffer */
+ if(SoftUART_IsReceived())
+ Buffer_StoreElement(&UARTtoUSB_Buffer, SoftUART_RxByte());
+
+ CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
+}
+
/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
{
@@ -118,21 +150,59 @@ void SetupHardware(void)
SoftUART_Init();
LEDs_Init();
USB_Init();
+ V2Protocol_Init();
- PORTD |= (1 << 5); // PD5 is connected to the XMEGA /RESET, enable pullup
+ /* Disable JTAG debugging */
+ MCUCR |= (1 << JTD);
+ MCUCR |= (1 << JTD);
+
+ /* Enable pullup on the JTAG TDI pin so we can use it to select the mode */
+ PORTF |= (1 << 7);
+ _delay_ms(10);
+
+ /* Select the firmware mode based on the JTD pin's value */
+ CurrentFirmwareMode = (PINF & (1 << 7)) ? MODE_USART_BRIDGE : MODE_PDI_PROGRAMMER;
}
/** Event handler for the library USB Configuration Changed event. */
void EVENT_USB_Device_ConfigurationChanged(void)
{
- LEDs_SetAllLEDs(LEDS_LED1);
+ bool EndpointConfigSuccess;
+
+ if (CurrentFirmwareMode == MODE_USART_BRIDGE)
+ {
+ EndpointConfigSuccess = CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
+ }
+ else
+ {
+ EndpointConfigSuccess = Endpoint_ConfigureEndpoint(AVRISP_DATA_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, AVRISP_DATA_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+ }
- if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
- LEDs_SetAllLEDs(LEDS_NO_LEDS);
+ if (EndpointConfigSuccess)
+ LEDs_SetAllLEDs(LEDMASK_USB_READY);
+ else
+ LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Event handler for the library USB Unhandled Control Request event. */
void EVENT_USB_Device_UnhandledControlRequest(void)
{
- CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
+ if (CurrentFirmwareMode == MODE_USART_BRIDGE)
+ CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
+}
+
+/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
+ * documentation) by the application code so that the address and size of a requested descriptor can be given
+ * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ * USB host.
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, const uint8_t wIndex, void** const DescriptorAddress)
+{
+ if (CurrentFirmwareMode == MODE_USART_BRIDGE)
+ return USART_GetDescriptor(wValue, wIndex, DescriptorAddress);
+ else
+ return AVRISP_GetDescriptor(wValue, wIndex, DescriptorAddress);
}