Commit of new class abstraction APIs for all device demos other than the MIDI demo - not documented yet.

Removed scheduler and memory allocation libraries.

Added new EVENT_USB_StartOfFrame event in the library to indicate the start of each USB frame (when generated).

Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt.
This commit is contained in:
Dean Camera 2009-06-01 11:03:39 +00:00
parent 2440ca268a
commit d1e5266036
106 changed files with 3072 additions and 5760 deletions

View file

@ -37,26 +37,12 @@
#define _DESCRIPTORS_H_
/* Includes: */
#include <LUFA/Drivers/USB/USB.h>
#include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/Device/CDC.h>
/* Macros: */
/** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a
* uniform structure but variable sized data payloads, thus cannot be represented accurately by
* a single typedef struct. A macro is used instead so that functional descriptors can be created
* easily by specifying the size of the payload. This allows sizeof() to work correctly.
*
* \param DataSize Size in bytes of the CDC functional descriptor's data payload
*/
#define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \
struct \
{ \
USB_Descriptor_Header_t Header; \
uint8_t SubType; \
uint8_t Data[DataSize]; \
}
/** Endpoint number of the CDC device-to-host notification IN endpoint. */
#define CDC_NOTIFICATION_EPNUM 2

View file

@ -30,37 +30,54 @@
#include "USBtoSerial.h"
/* Scheduler Task List */
TASK_LIST
{
{ .Task = USB_USBTask , .TaskStatus = TASK_STOP },
{ .Task = CDC_Task , .TaskStatus = TASK_STOP },
};
/* Globals: */
/** Contains the current baud rate and other settings of the virtual serial port.
*
* These values are set by the host via a class-specific request, and the physical USART should be reconfigured to match the
* new settings each time they are changed by the host.
*/
CDC_Line_Coding_t LineCoding = { .BaudRateBPS = 9600,
.CharFormat = OneStopBit,
.ParityType = Parity_None,
.DataBits = 8 };
/** Ring (circular) buffer to hold the RX data - data from the host to the attached device on the serial port. */
RingBuff_t Rx_Buffer;
/** Ring (circular) buffer to hold the TX data - data from the attached device on the serial port to the host. */
RingBuff_t Tx_Buffer;
/** Flag to indicate if the USART is currently transmitting data from the Rx_Buffer circular buffer. */
volatile bool Transmitting = false;
USB_ClassInfo_CDC_t VirtualSerial_CDC_Interface =
{
.ControlInterfaceNumber = 0,
.DataINEndpointNumber = CDC_TX_EPNUM,
.DataINEndpointSize = CDC_TXRX_EPSIZE,
.DataOUTEndpointNumber = CDC_RX_EPNUM,
.DataOUTEndpointSize = CDC_TXRX_EPSIZE,
.NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
.NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
};
/** Main program entry point. This routine configures the hardware required by the application, then
* starts the scheduler to run the application tasks.
*/
int main(void)
{
SetupHardware();
Buffer_Initialize(&Rx_Buffer);
Buffer_Initialize(&Tx_Buffer);
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
for (;;)
{
for (uint8_t DataBytesRem = USB_CDC_BytesReceived(&VirtualSerial_CDC_Interface); DataBytesRem != 0; DataBytesRem--)
{
if (!(BUFF_STATICSIZE - Rx_Buffer.Elements))
break;
Buffer_StoreElement(&Rx_Buffer, USB_CDC_ReceiveByte(&VirtualSerial_CDC_Interface));
}
if (Tx_Buffer.Elements)
USB_CDC_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&Rx_Buffer));
if (Rx_Buffer.Elements)
Serial_TxByte(Buffer_GetElement(&Rx_Buffer));
USB_CDC_USBTask(&VirtualSerial_CDC_Interface);
USB_USBTask();
}
}
void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
@ -70,304 +87,61 @@ int main(void)
clock_prescale_set(clock_div_1);
/* Hardware Initialization */
Joystick_Init();
LEDs_Init();
ReconfigureUSART();
/* Ring buffer Initialization */
Buffer_Initialize(&Rx_Buffer);
Buffer_Initialize(&Tx_Buffer);
/* Indicate USB not ready */
UpdateStatus(Status_USBNotReady);
/* Initialize Scheduler so that it can be used */
Scheduler_Init();
/* Initialize USB Subsystem */
USB_Init();
/* Scheduling - routine never returns, so put this last in the main function */
Scheduler_Start();
}
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and
* starts the library USB task to begin the enumeration and USB management process.
*/
void EVENT_USB_Connect(void)
{
/* Start USB management task */
Scheduler_SetTaskMode(USB_USBTask, TASK_RUN);
/* Indicate USB enumerating */
UpdateStatus(Status_USBEnumerating);
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
* the status LEDs and stops the USB management and CDC management tasks.
*/
void EVENT_USB_Disconnect(void)
{
/* Stop running CDC and USB management tasks */
Scheduler_SetTaskMode(CDC_Task, TASK_STOP);
Scheduler_SetTaskMode(USB_USBTask, TASK_STOP);
/* Reset Tx and Rx buffers, device disconnected */
Buffer_Initialize(&Rx_Buffer);
Buffer_Initialize(&Tx_Buffer);
/* Indicate USB not ready */
UpdateStatus(Status_USBNotReady);
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
}
/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
* of the USB device after enumeration - the device endpoints are configured and the CDC management task started.
*/
void EVENT_USB_ConfigurationChanged(void)
{
/* Setup CDC Notification, Rx and Tx Endpoints */
Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,
ENDPOINT_DIR_IN, CDC_NOTIFICATION_EPSIZE,
ENDPOINT_BANK_SINGLE);
LEDs_SetAllLEDs(LEDMASK_USB_READY);
Endpoint_ConfigureEndpoint(CDC_TX_EPNUM, EP_TYPE_BULK,
ENDPOINT_DIR_IN, CDC_TXRX_EPSIZE,
ENDPOINT_BANK_SINGLE);
Endpoint_ConfigureEndpoint(CDC_RX_EPNUM, EP_TYPE_BULK,
ENDPOINT_DIR_OUT, CDC_TXRX_EPSIZE,
ENDPOINT_BANK_SINGLE);
/* Indicate USB connected and ready */
UpdateStatus(Status_USBReady);
/* Start CDC task */
Scheduler_SetTaskMode(CDC_Task, TASK_RUN);
if (!(USB_CDC_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
}
/** Event handler for the USB_UnhandledControlPacket event. This is used to catch standard and class specific
* control requests that are not handled internally by the USB library (including the CDC control commands,
* which are all issued via the control endpoint), so that they can be handled appropriately for the application.
*/
void EVENT_USB_UnhandledControlPacket(void)
{
uint8_t* LineCodingData = (uint8_t*)&LineCoding;
/* Process CDC specific control requests */
switch (USB_ControlRequest.bRequest)
{
case REQ_GetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP();
/* Write the line coding data to the control endpoint */
Endpoint_Write_Control_Stream_LE(LineCodingData, sizeof(LineCoding));
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT();
}
break;
case REQ_SetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP();
/* Read the line coding data in from the host into the global struct */
Endpoint_Read_Control_Stream_LE(LineCodingData, sizeof(LineCoding));
/* Finalize the stream transfer to clear the last packet from the host */
Endpoint_ClearIN();
/* Reconfigure the USART with the new settings */
ReconfigureUSART();
}
break;
case REQ_SetControlLineState:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP();
/* NOTE: Here you can read in the line state mask from the host, to get the current state of the output handshake
lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the
CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:
*/
/* Acknowledge status stage */
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN();
}
break;
}
USB_CDC_ProcessControlPacket(&VirtualSerial_CDC_Interface);
}
/** Task to manage CDC data transmission and reception to and from the host, from and to the physical USART. */
TASK(CDC_Task)
{
if (USB_IsConnected)
{
#if 0
/* NOTE: Here you can use the notification endpoint to send back line state changes to the host, for the special RS-232
handshake signal lines (and some error states), via the CONTROL_LINE_IN_* masks and the following code:
*/
USB_Notification_Header_t Notification = (USB_Notification_Header_t)
{
.NotificationType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.Notification = NOTIF_SerialState,
.wValue = 0,
.wIndex = 0,
.wLength = sizeof(uint16_t),
};
uint16_t LineStateMask;
// Set LineStateMask here to a mask of CONTROL_LINE_IN_* masks to set the input handshake line states to send to the host
Endpoint_SelectEndpoint(CDC_NOTIFICATION_EPNUM);
Endpoint_Write_Stream_LE(&Notification, sizeof(Notification));
Endpoint_Write_Stream_LE(&LineStateMask, sizeof(LineStateMask));
Endpoint_ClearIN();
#endif
/* Select the Serial Rx Endpoint */
Endpoint_SelectEndpoint(CDC_RX_EPNUM);
/* Check to see if a packet has been received from the host */
if (Endpoint_IsOUTReceived())
{
/* Read the bytes in from the endpoint into the buffer while space is available */
while (Endpoint_BytesInEndpoint() && (BUFF_STATICSIZE - Rx_Buffer.Elements))
{
/* Store each character from the endpoint */
Buffer_StoreElement(&Rx_Buffer, Endpoint_Read_Byte());
}
/* Check to see if all bytes in the current packet have been read */
if (!(Endpoint_BytesInEndpoint()))
{
/* Clear the endpoint buffer */
Endpoint_ClearOUT();
}
}
/* Check if Rx buffer contains data - if so, send it */
if (Rx_Buffer.Elements)
Serial_TxByte(Buffer_GetElement(&Rx_Buffer));
/* Select the Serial Tx Endpoint */
Endpoint_SelectEndpoint(CDC_TX_EPNUM);
/* Check if the Tx buffer contains anything to be sent to the host */
if (Tx_Buffer.Elements)
{
/* Wait until Serial Tx Endpoint Ready for Read/Write */
while (!(Endpoint_IsReadWriteAllowed()));
/* Write the bytes from the buffer to the endpoint while space is available */
while (Tx_Buffer.Elements && (Endpoint_BytesInEndpoint() < CDC_TXRX_EPSIZE))
{
/* Write each byte retreived from the buffer to the endpoint */
Endpoint_Write_Byte(Buffer_GetElement(&Tx_Buffer));
}
/* Remember if the packet to send completely fills the endpoint */
bool IsFull = (Endpoint_BytesInEndpoint() == CDC_TXRX_EPSIZE);
/* Send the data */
Endpoint_ClearIN();
/* If no more data to send and the last packet filled the endpoint, send an empty packet to release
* the buffer on the receiver (otherwise all data will be cached until a non-full packet is received) */
if (IsFull && !(Tx_Buffer.Elements))
{
/* Wait until Serial Tx Endpoint Ready for Read/Write */
while (!(Endpoint_IsReadWriteAllowed()));
/* Send an empty packet to terminate the transfer */
Endpoint_ClearIN();
}
}
}
}
/** ISR to handle the USART receive complete interrupt, fired each time the USART has received a character. This stores the received
* character into the Tx_Buffer circular buffer for later transmission to the host.
*/
ISR(USART1_RX_vect, ISR_BLOCK)
{
/* Only store received characters if the USB interface is connected */
if (USB_IsConnected)
{
/* Character received, store it into the buffer */
Buffer_StoreElement(&Tx_Buffer, UDR1);
}
Buffer_StoreElement(&Tx_Buffer, UDR1);
}
/** Function to manage status updates to the user. This is done via LEDs on the given board, if available, but may be changed to
* log to a serial port, or anything else that is suitable for status updates.
*
* \param CurrentStatus Current status of the system, from the USBtoSerial_StatusCodes_t enum
*/
void UpdateStatus(uint8_t CurrentStatus)
{
uint8_t LEDMask = LEDS_NO_LEDS;
/* Set the LED mask to the appropriate LED mask based on the given status code */
switch (CurrentStatus)
{
case Status_USBNotReady:
LEDMask = (LEDS_LED1);
break;
case Status_USBEnumerating:
LEDMask = (LEDS_LED1 | LEDS_LED2);
break;
case Status_USBReady:
LEDMask = (LEDS_LED2 | LEDS_LED4);
break;
}
/* Set the board LEDs to the new LED mask */
LEDs_SetAllLEDs(LEDMask);
}
/** Reconfigures the USART to match the current serial port settings issued by the host as closely as possible. */
void ReconfigureUSART(void)
void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo)
{
uint8_t ConfigMask = 0;
/* Determine parity - non odd/even parity mode defaults to no parity */
if (LineCoding.ParityType == Parity_Odd)
if (CDCInterfaceInfo->LineEncoding.ParityType == Parity_Odd)
ConfigMask = ((1 << UPM11) | (1 << UPM10));
else if (LineCoding.ParityType == Parity_Even)
else if (CDCInterfaceInfo->LineEncoding.ParityType == Parity_Even)
ConfigMask = (1 << UPM11);
/* Determine stop bits - 1.5 stop bits is set as 1 stop bit due to hardware limitations */
if (LineCoding.CharFormat == TwoStopBits)
if (CDCInterfaceInfo->LineEncoding.CharFormat == TwoStopBits)
ConfigMask |= (1 << USBS1);
/* Determine data size - 5, 6, 7, or 8 bits are supported */
if (LineCoding.DataBits == 6)
if (CDCInterfaceInfo->LineEncoding.DataBits == 6)
ConfigMask |= (1 << UCSZ10);
else if (LineCoding.DataBits == 7)
else if (CDCInterfaceInfo->LineEncoding.DataBits == 7)
ConfigMask |= (1 << UCSZ11);
else if (LineCoding.DataBits == 8)
else if (CDCInterfaceInfo->LineEncoding.DataBits == 8)
ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
/* Enable double speed, gives better error percentages at 8MHz */
UCSR1A = (1 << U2X1);
/* Enable transmit and receive modules and interrupts */
UCSR1A = (1 << U2X1);
UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
/* Set the USART mode to the mask generated by the Line Coding options */
UCSR1C = ConfigMask;
/* Set the USART baud rate register to the desired baud rate value */
UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)LineCoding.BaudRateBPS);
UCSR1C = ConfigMask;
UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)CDCInterfaceInfo->LineEncoding.BaudRateBPS);
}

View file

@ -46,140 +46,28 @@
#include "Lib/RingBuff.h"
#include <LUFA/Version.h> // Library Version Information
#include <LUFA/Drivers/USB/USB.h> // USB Functionality
#include <LUFA/Drivers/Peripheral/Serial.h> // USART driver
#include <LUFA/Drivers/Board/LEDs.h> // LEDs driver
#include <LUFA/Scheduler/Scheduler.h> // Simple scheduler for task management
#include <LUFA/Version.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Drivers/Board/Joystick.h>
#include <LUFA/Drivers/Peripheral/Serial.h>
#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/USB/Class/Device/CDC.h>
/* Macros: */
/** CDC Class specific request to get the current virtual serial port configuration settings. */
#define REQ_GetLineEncoding 0x21
/** CDC Class specific request to set the current virtual serial port configuration settings. */
#define REQ_SetLineEncoding 0x20
/** CDC Class specific request to set the current virtual serial port handshake line states. */
#define REQ_SetControlLineState 0x22
#define LEDMASK_USB_NOTREADY LEDS_LED1
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/** Notification type constant for a change in the virtual serial port handshake line states, for
* use with a USB_Notification_Header_t notification structure when sent to the host via the CDC
* notification endpoint.
*/
#define NOTIF_SerialState 0x20
/** Mask for the DTR handshake line for use with the REQ_SetControlLineState class specific request
* from the host, to indicate that the DTR line state should be high.
*/
#define CONTROL_LINE_OUT_DTR (1 << 0)
/** Mask for the RTS handshake line for use with the REQ_SetControlLineState class specific request
* from the host, to indicate that theRTS line state should be high.
*/
#define CONTROL_LINE_OUT_RTS (1 << 1)
/** Mask for the DCD handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the DCD line state is currently high.
*/
#define CONTROL_LINE_IN_DCD (1 << 0)
/** Mask for the DSR handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the DSR line state is currently high.
*/
#define CONTROL_LINE_IN_DSR (1 << 1)
/** Mask for the BREAK handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the BREAK line state is currently high.
*/
#define CONTROL_LINE_IN_BREAK (1 << 2)
/** Mask for the RING handshake line for use with the a NOTIF_SerialState class specific notification
* from the device to the host, to indicate that the RING line state is currently high.
*/
#define CONTROL_LINE_IN_RING (1 << 3)
/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
* to indicate that a framing error has occurred on the virtual serial port.
*/
#define CONTROL_LINE_IN_FRAMEERROR (1 << 4)
/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
* to indicate that a parity error has occurred on the virtual serial port.
*/
#define CONTROL_LINE_IN_PARITYERROR (1 << 5)
/** Mask for use with the a NOTIF_SerialState class specific notification from the device to the host,
* to indicate that a data overrun error has occurred on the virtual serial port.
*/
#define CONTROL_LINE_IN_OVERRUNERROR (1 << 6)
/* Type Defines: */
/** Type define for the virtual serial port line encoding settings, for storing the current USART configuration
* as set by the host via a class specific request.
*/
typedef struct
{
uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second */
uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the
* CDCDevice_CDC_LineCodingFormats_t enum
*/
uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the
* CDCDevice_LineCodingParity_t enum
*/
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
} CDC_Line_Coding_t;
/** Type define for a CDC notification, sent to the host via the CDC notification endpoint to indicate a
* change in the device state asynchronously.
*/
typedef struct
{
uint8_t NotificationType; /**< Notification type, a mask of REQDIR_*, REQTYPE_* and REQREC_* constants
* from the library StdRequestType.h header
*/
uint8_t Notification; /**< Notification value, a NOTIF_* constant */
uint16_t wValue; /**< Notification wValue, notification-specific */
uint16_t wIndex; /**< Notification wIndex, notification-specific */
uint16_t wLength; /**< Notification wLength, notification-specific */
} USB_Notification_Header_t;
/* Enums: */
/** Enum for the possible line encoding formats of a virtual serial port. */
enum CDCDevice_CDC_LineCodingFormats_t
{
OneStopBit = 0, /**< Each frame contains one stop bit */
OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits */
TwoStopBits = 2, /**< Each frame contains two stop bits */
};
/** Enum for the possible line encoding parity settings of a virtual serial port. */
enum CDCDevice_LineCodingParity_t
{
Parity_None = 0, /**< No parity bit mode on each frame */
Parity_Odd = 1, /**< Odd parity bit mode on each frame */
Parity_Even = 2, /**< Even parity bit mode on each frame */
Parity_Mark = 3, /**< Mark parity bit mode on each frame */
Parity_Space = 4, /**< Space parity bit mode on each frame */
};
/** Enum for the possible status codes for passing to the UpdateStatus() function. */
enum USBtoSerial_StatusCodes_t
{
Status_USBNotReady = 0, /**< USB is not ready (disconnected from a USB host) */
Status_USBEnumerating = 1, /**< USB interface is enumerating */
Status_USBReady = 2, /**< USB interface is connected and ready */
};
/* Tasks: */
TASK(CDC_Task);
/* Function Prototypes: */
void SetupHardware(void);
void EVENT_USB_Connect(void);
void EVENT_USB_Disconnect(void);
void EVENT_USB_ConfigurationChanged(void);
void EVENT_USB_UnhandledControlPacket(void);
void ReconfigureUSART(void);
void UpdateStatus(uint8_t CurrentStatus);
void EVENT_USB_StartOfFrame(void);
void EVENT_USB_CDC_LineEncodingChanged(USB_ClassInfo_CDC_t* CDCInterfaceInfo);
#endif

View file

@ -126,7 +126,6 @@ LUFA_PATH = ../../..
SRC = $(TARGET).c \
Descriptors.c \
Lib/RingBuff.c \
$(LUFA_PATH)/LUFA/Scheduler/Scheduler.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \
@ -137,7 +136,7 @@ SRC = $(TARGET).c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBInterrupt.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/USBTask.c \
$(LUFA_PATH)/LUFA/Drivers/USB/HighLevel/ConfigDescriptor.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/HIDParser.c \
$(LUFA_PATH)/LUFA/Drivers/USB/Class/Device/CDC.c \
# List C++ source files here. (C dependencies are automatically generated.)
@ -184,7 +183,7 @@ CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD)
CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DNO_STREAM_CALLBACKS -DUSB_DEVICE_ONLY
CDEFS += -DUSE_NONSTANDARD_DESCRIPTOR_NAMES -DUSB_DEVICE_ONLY
CDEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=8 -DUSE_SINGLE_DEVICE_CONFIGURATION
CDEFS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"