LUFA – First Steps Part 2

Device Descriptors

Now that the overall project configuration has been configured we need to supply information about the device itself. Descriptors are data structures a USB device passes to the host computer during initialisation and are the key to ‘plug and play’ operation. An excellent introduction to the various kinds of descriptor can be found here.

The monitor project is in essence a Serial to USB converter so I decided to copy the descriptors from the Serial to USB example project. The relevant files are Descriptors.h and Descriptors.c. I copied these into my project root. You also need to ‘Add’ them to the project using the Solution Explorer window.

The Descriptors.h file needs to be edited and the function prototype for CALLBACK_USB_GetDescriptor deleted. The version below has been edited to remove comments for clarity:
LUFA Library
Copyright (C) Dean Camera, 2014.

dean [at] fourwalledcubicle [dot] com


#include <avr/pgmspace.h>
#include <LUFA/Drivers/USB/USB.h>

#define CDC_TXRX_EPSIZE 32

typedef struct
USB_Descriptor_Configuration_Header_t Config;

// CDC Command Interface
USB_Descriptor_Interface_t CDC_CCI_Interface;
USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;

// CDC Data Interface
USB_Descriptor_Interface_t CDC_DCI_Interface;
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
} USB_Descriptor_Configuration_t;

enum InterfaceDescriptors_t
INTERFACE_ID_CDC_CCI = 0, /**< CDC CCI interface descriptor ID */
INTERFACE_ID_CDC_DCI = 1, /**< CDC DCI interface descriptor ID */

enum StringDescriptors_t
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
STRING_ID_Product = 2, /**< Product string ID */


This entry was posted in AVR, Microcontroller, USB. Bookmark the permalink.

5 Responses to LUFA – First Steps Part 2

  1. Lefteris says:

    Hi there, the tutorial is great so far. IBut how do you send or receive data in the main code


  2. sjdavies2 says:

    Hi Lefteris,
    I’m on holiday right now. My code only works in one direction, receiving UART characters and sending them to the PC via USB. The mainline has a while(true) loop executing the following steps:
    1) Endpoint_SelectEndpoint(VirtualSerial_CDC_Interface.Config.DataINEndpoint.Address);
    2) if (Endpoint_IsINReady())
    3) if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface, nextChar) != ENDPOINT_READYWAIT_NoError)
    4) CDC_Device_USBTask(&VirtualSerial_CDC_Interface)

    The UART is interrupt driven, characters queue into a buffer. I’ve poached most of it from the USBtoSerial example. The send logic is this:
    1) select the IN endpoint
    2) check that it can actually transmit data
    3) start queuing bytes int0 the USB buffer
    4) transfers control to the USB framework. Not sure if this is actually needed and have no means to test right now.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s