diff --git a/src/Descriptors.c b/src/Descriptors.c index 23e7725..adf1d84 100644 --- a/src/Descriptors.c +++ b/src/Descriptors.c @@ -37,6 +37,49 @@ #include "Descriptors.h" + + + + +/** Endpoint address for the CDC control interface event notification endpoint. */ +#define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM) + +/** Endpoint address for the CDC data interface TX (data IN) endpoint. */ +#define CDC_TX_EPADDR (ENDPOINT_DIR_IN | CDC_TX_EPNUM) + +/** Endpoint address for the CDC data interface RX (data OUT) endpoint. */ +#define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | CDC_RX_EPNUM) + +/** 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 + * within a device can be differentiated from one another. + */ +USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = { + .Config = { + .ControlInterfaceNumber = INTERFACE_ID_CDC_CCI, + .DataINEndpoint = + { + .Address = CDC_TX_EPADDR, + .Size = CDC_TXRX_EPSIZE, + .Banks = 1, + }, + .DataOUTEndpoint = + { + .Address = CDC_RX_EPADDR, + .Size = CDC_TXRX_EPSIZE, + .Banks = 1, + }, + .NotificationEndpoint = + { + .Address = CDC_NOTIFICATION_EPADDR, + .Size = CDC_NOTIFICATION_EPSIZE, + .Banks = 1, + }, + }, +}; + + + /** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall * device characteristics, including the supported USB version, control endpoint size and the * number of device configurations. The descriptor is read out by the USB host when the enumeration diff --git a/src/Descriptors.h b/src/Descriptors.h index 0ec0ada..37e3cfc 100644 --- a/src/Descriptors.h +++ b/src/Descriptors.h @@ -39,6 +39,12 @@ /* Includes: */ #include + + + extern USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface; + + + /* Macros: */ #if defined(__AVR_AT90USB1287__) #define AVR_SIGNATURE_1 0x1E @@ -107,6 +113,8 @@ /** Size of the CDC control interface notification endpoint bank, in bytes. */ #define CDC_NOTIFICATION_EPSIZE 8 + #define INTERFACE_ID_CDC_CCI 0 + /* Type Defines: */ /** Type define for the device configuration descriptor structure. This must be defined in the * application code, as the configuration descriptor contains several sub-descriptors which diff --git a/src/main.c b/src/main.c index b4db2b4..4722b46 100644 --- a/src/main.c +++ b/src/main.c @@ -1,92 +1,19 @@ #include #include +#include +#include - #include +#include "Descriptors.h" +// Pro Micro LEDs are: B0, D5 - #include "Descriptors.h" - - #define LED_SETUP() DDRB |= (1<<0); DDRD |= (1<<5); - #define L_LED_OFF() PORTD |= (1<<5) - #define L_LED_ON() PORTD &= ~(1<<5) - #define L_LED_TOGGLE() PORTD ^= (1<<5) - #define DATA_LED_OFF() PORTB |= (1<<0) - #define DATA_LED_ON() PORTB &= ~(1<<0) - - - - /** Endpoint address for the CDC control interface event notification endpoint. */ - #define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM) - - /** Endpoint address for the CDC data interface TX (data IN) endpoint. */ - #define CDC_TX_EPADDR (ENDPOINT_DIR_IN | CDC_TX_EPNUM) - - /** Endpoint address for the CDC data interface RX (data OUT) endpoint. */ - #define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | CDC_RX_EPNUM) - - -/** Retrieves the next byte from the host in the CDC data OUT endpoint, and clears the endpoint bank if needed - * to allow reception of the next data packet from the host. - * - * \return Next received byte from the host in the CDC data OUT endpoint - */ -static uint8_t FetchNextCommandByte(void) -{ - /* Select the OUT endpoint so that the next data byte can be read */ - Endpoint_SelectEndpoint(CDC_RX_EPADDR); - - /* If OUT endpoint empty, clear it and wait for the next packet from the host */ - while (!(Endpoint_IsReadWriteAllowed())) - { - Endpoint_ClearOUT(); - - while (!(Endpoint_IsOUTReceived())) - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return 0; - } - } - - /* Fetch the next byte from the OUT endpoint */ - return Endpoint_Read_8(); -} - - - - -/** Writes the next response byte to the CDC data IN endpoint, and sends the endpoint back if needed to free up the - * bank when full ready for the next byte in the packet to the host. - * - * \param[in] Response Next response byte to send to the host - */ -static void WriteNextResponseByte(const uint8_t Response) -{ - /* Select the IN endpoint so that the next data byte can be written */ - Endpoint_SelectEndpoint(CDC_TX_EPADDR); - - /* If IN endpoint full, clear it and wait until ready for the next packet to the host */ - if (!(Endpoint_IsReadWriteAllowed())) - { - Endpoint_ClearIN(); - - while (!(Endpoint_IsINReady())) - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return; - } - } - - /* Write the next byte to the IN endpoint */ - Endpoint_Write_8(Response); -} - - - - - - - void CDC_Task(void); +#define LED_SETUP() DDRB |= (1<<0); DDRD |= (1<<5); +#define L_LED_OFF() PORTD |= (1<<5) +#define L_LED_ON() PORTD &= ~(1<<5) +#define L_LED_TOGGLE() PORTD ^= (1<<5) +#define DATA_LED_OFF() PORTB |= (1<<0) +#define DATA_LED_ON() PORTB &= ~(1<<0) /* Pulse generation counters to keep track of the time remaining for each pulse type */ #define DATA_LED_PULSE_PERIOD 100 @@ -107,6 +34,26 @@ void LEDPulse(void) } +static int16_t UsbReceiveByte() { + return CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); +} + +static int8_t UsbSendData(const uint8_t* const bytes, uint16_t len) { + return CDC_Device_SendData(&VirtualSerial_CDC_Interface, bytes, len); +} + +static int8_t UsbSendData_P(const uint8_t* const bytes, uint16_t len) { + return CDC_Device_SendData_P(&VirtualSerial_CDC_Interface, bytes, len); +} + +static int8_t UsbSendString(const char* const str) { + return CDC_Device_SendString(&VirtualSerial_CDC_Interface, str); +} + +static int8_t UsbSendString_P(const char* const str) { + return CDC_Device_SendString_P(&VirtualSerial_CDC_Interface, str); +} + void main () { LED_SETUP(); @@ -117,126 +64,73 @@ void main () { /* Enable global interrupts so that the USB stack can function */ sei(); - for(;;) { - CDC_Task(); - USB_USBTask(); + // keep the indicator on for a while + int light_cnt = 0; + for (;;) + { LEDPulse(); - } -} + int16_t ch = UsbReceiveByte(); + if (ch > 0) { + light_cnt = 10; -/* - * some parts of this code are from LUFA. - * - * - Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - The author disclaim all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -// /* -// -// /** Retrieves the next byte from the host in the CDC data OUT endpoint, and clears the endpoint bank if needed -// * to allow reception of the next data packet from the host. -// * -// * \return Next received byte from the host in the CDC data OUT endpoint -// */ -// static uint8_t FetchNextCommandByte(void) -// { -// /* Select the OUT endpoint so that the next data byte can be read */ -// Endpoint_SelectEndpoint(CDC_RX_EPNUM); -// -// /* If OUT endpoint empty, clear it and wait for the next packet from the host */ -// while (!(Endpoint_IsReadWriteAllowed())) -// { -// Endpoint_ClearOUT(); -// -// while (!(Endpoint_IsOUTReceived())) -// { -// if (USB_DeviceState == DEVICE_STATE_Unattached) -// return 0; -// } -// } -// -// /* Fetch the next byte from the OUT endpoint */ -// return Endpoint_Read_8(); -// } -// */ - - -/** Task to read in AVR910 commands from the CDC data OUT endpoint, process them, perform the required actions - * and send the appropriate response back to the host. - */ -void CDC_Task(void) -{ - /* Select the OUT endpoint */ - Endpoint_SelectEndpoint(CDC_RX_EPNUM); - - /* Check if endpoint has a command in it sent from the host */ - if (!(Endpoint_IsOUTReceived())) - return; - - DATA_LED_ON(); - DataLEDPulse = DATA_LED_PULSE_PERIOD; + if (ch == 'a') { + UsbSendString_P(PSTR("OFF\r\n")); + } else if (ch == 'A') { + UsbSendString_P(PSTR("ON\r\n")); + } + } - /* Read in the bootloader command (first byte sent from host) */ - uint8_t Command = FetchNextCommandByte(); + if (light_cnt > 0) { + light_cnt--; + } else { + DATA_LED_OFF(); + } - // COMMAND PROCESSING - if (Command == 'a') - { - WriteNextResponseByte('b'); - WriteNextResponseByte('\r'); - WriteNextResponseByte('\n'); + CDC_Device_USBTask(&VirtualSerial_CDC_Interface); + USB_USBTask(); } +} - /* Select the IN endpoint */ - Endpoint_SelectEndpoint(CDC_TX_EPNUM); - /* Remember if the endpoint is completely full before clearing it */ - bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed()); - /* Send the endpoint data to the host */ - Endpoint_ClearIN(); - /* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */ - if (IsEndpointFull) - { - while (!(Endpoint_IsINReady())) - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return; - } +/** Event handler for the library USB Connection event. */ +void EVENT_USB_Device_Connect(void) +{ + // +} - Endpoint_ClearIN(); - } +/** Event handler for the library USB Disconnection event. */ +void EVENT_USB_Device_Disconnect(void) +{ + // +} - /* Wait until the data has been sent to the host */ - while (!(Endpoint_IsINReady())) - { - if (USB_DeviceState == DEVICE_STATE_Unattached) - return; - } +/** Event handler for the library USB Configuration Changed event. */ +void EVENT_USB_Device_ConfigurationChanged(void) +{ + bool ConfigSuccess = true; + ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface); +} - /* Select the OUT endpoint */ - Endpoint_SelectEndpoint(CDC_RX_EPNUM); +/** Event handler for the library USB Control Request reception event. */ +void EVENT_USB_Device_ControlRequest(void) +{ + CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface); +} - /* Acknowledge the command from the host */ - Endpoint_ClearOUT(); + +/** Event handler for the CDC Class driver Line Encoding Changed event. + * + * \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced + */ +void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + // } + + +