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:
parent
2746154652
commit
60fd0ff418
14 changed files with 205 additions and 112 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue