Changed XPLAINBridge project to be both a USB to USART bridge and a PDI programmer, based on the state of a mode select pin.

This commit is contained in:
Dean Camera 2010-01-19 05:27:58 +00:00
parent 2746154652
commit 60fd0ff418
14 changed files with 205 additions and 112 deletions

View file

@ -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 (!(CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
LEDs_SetAllLEDs(LEDS_NO_LEDS);
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 (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);
}