NOTICE: The Processors Wiki will End-of-Life in December of 2020. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
HALCoGen USB Device - driver & CDC Class
- 1 Introduction
- 2 Features
- 3 Limitations
- 4 Requirements
- 5 Software Architecture
- 6 CDC Device Class
- 7 Creating a new CDC Device Application using HALCoGen
- 7.1 Step 1: Enable USBD Driver
- 7.2 Step 2: Enable PINMUX for USBDevice peripheral
- 7.3 Step 3: Setup 48MHz clock on VCLKA3_S for USBD.
- 7.4 Step 4: Setup PLL2 as clock source for VCLKA3_S
- 7.5 Step 5: Update stack sizes
- 7.6 Step 6: Configure USB descriptors
- 7.7 Step 7: Enable the USBD Interrupts on ‘VIM Channel 63-94’ tab
- 7.8 Step 8: Setup the interrupt service routines for USBD on ‘VIM RAM’ tab
- 7.9 Step 9: Generate the code
- 7.10 Step 10: Integrating the CDC Example application
- 7.11 Step 11: Create a CCS Project
- 7.12 Step 13: Compiler setting changes
- 7.13 Step 14: Update build settings
- 7.14 Step 15: Miscellaneous changes to project.
- 7.15 Step 16: Changes to HDK Jumper settings
- 7.16 Step 17: Build, Flash & Execute the binary
- 7.17 Step 18: Windows (Win32) Drivers
- 7.18 Worked Example Files
The Hercules USB stack is an OS-independent USB solution that is migrated from the StellarisWare USB solution.
- Supports USB Device
- Interrupt driver IO Transfers (DMA Transfers are not supported)
- Support for CDC ACM
- DMA Transfers are not supported
- Requires CCS v5.1 with CGTools 4.12.0A12016 and later version
- HALCoGen 3.01.00 Release
- RM48L950 HDK
The following diagram shows the architecture of the USB stack.
Hardware Abstraction Layer
Hardware Abstraction Layer (HAL) is the lower most layer of the stack and is the only layer that directly communicates with the USB Device controller. This layer abstracts all the functionalities and services used by upper layers to configure and control the USB device controllers. The HAL is implemented in a single file (USB.C).
Device Core Layer
The device core layer is responsible for device enumeration and handling all of the control transfers. Interrupt service routines are part of this layer. Typical tasks handled by device core layers are as follows:
- Device Controller Initialization via HAL
- USB Device Enumeration
- Interrupt handling (EP0 & EPn)
- Standard request handling & forwarding to class specific handlers
- Terminate the device controller driver
The initialization APIs are called by the class driver in order to start the enumeration process. Once the enumeration has started, all of the standard request routines are called from the ISR in response to the appropriate interrupt event. For any class-specific request, the application or class driver must register the callback handler with the core so that the ISR can branch when necessary.
The device core layer is implemented by a single source file USBDENUM.C.
USB Configuration Layer
This layer contains all of the parameters required to configure the USB device. These parameters include VID, PID, Descriptors, event handlers, buffers, and more. These parameters are specified by the application writer. Once all the information is fed in to this layer, the configuration layer can give a device instance structure to the other layers within the USB stack. This device instance contains all of the information regarding the device, and the required information is extracted when necessary.
This layer is considered to be part of application, and most of the data is specified by the application programmer. This layer is implemented by the source file USB_SERIAL_STRUCTS.C. The following parameters are configurable by the application programmer:
- Global instance for the USB device structure
- Rx and Tx Buffers
- Vendor ID
- Product ID
- Power configuration parameters
- Control event call backs
- Application event call backs
- String descriptors
- Language descriptor
CDC Device Class
The USB Communication Device Class (CDC) class driver supports the CDC Abstract Control Model (ACM) variant and allows a client application to be seen as a virtual serial port to the USB host system. The driver provides two channels: one transmit and one receive. The channels may be used in conjunction with USB buffers to provide a simple read/write interface for data transfer to and from the host. Additional APIs and events are used to support serial link-specific operations such as notification of UART errors, sending break conditions, and setting communication line parameters. The data transmission capabilities of this device class driver are very similar to the generic bulk class, but (because this is a standard device class) the host operating system should be able to access the device without the need for any host-side drivers. On Windows, a simple INF file is all that is required to make the USB device appear as a COM port that can be accessed by any serial terminal application. This device class uses three endpoints in addition to endpoint zero. Two bulk endpoints carry data to and from the host and an interrupt IN endpoint is used to signal any serial errors such as break, framing error, or parity error detected by the device. Endpoint zero carries standard USB requests and also CDC-specific requests which translate to events passed to the application via the control channel callback. This layer is implemented in the source file USBDCDC.C.
CDC Device Enumeration
The Application main must perform the following steps:
- Configure the system interrupts
- Register the interrupt handler (i.e. ISR)
- Initialize the buffers
- Call USBDCDCInit() with the device instance structure as a parameter
With this call, control is given to the CDC device class layer. The device class layer must perform the following steps:
- Assign endpoints to the device instance structure
- Apply the configuration descriptor to the device instance structure
- Call USBDCDInit() and pass the device instance structure to the core
With this call, control is passed to the core layer. The core layer must perform the following steps in order to complete enumeration:
- Reset the USB module
- Switch on the USB PHY
- Clear all pending interrupts
- Enable the required interrupts
- Set the configuration parameters
- Disconnect the device
- Reconnect the device
Now the device will start receiving interrupts from the host. The interrupt handler in the core layer will identify all of the EP0 interrupts and call the appropriate handler. If all the standard requests are serviced by the device, then enumeration is complete and the device is ready for communication. Now control return to the application and wait for data interrupts.
CDC Application Data Flow
Data out Flow (From Host to Device)
When data arrives from the host, the device will receive an interrupt from the host. The interrupt handler must perform the following steps on reception:
- Read the interrupt status register
- Identify the interrupt
- Call the appropriate handler (i.e. Read Data handler)
- Read handler checks whether the RX Packet Ready bit is set
- Check the number of byte available in the buffer
- Read the data to buffer
- Clear the RX Packet Ready bit
- Give the read data to the application
Data in Flow (From Device to Host)
When the device side application needs to send data to the host, the device must follow the below steps.
- Application calls the write data API and passes the data buffer to the CDC layer
- Write data API checks the amount of data to be sent
- Copy data the TX buffer
- Set the TX Packet Ready bit
- After the transmit operation completes, the host sends a TX completion interrupt
- TX Packet Ready bit will be cleared automatically
- After receiving the TX Complete Interrupt, the ISR sends an event to the application indicating the completion of data transfer
Creating a new CDC Device Application using HALCoGen
HALCoGen GUI can be used to create the required descriptors & configurations for USBD CDC Application. Following are details steps to create & configure a new CDC application using HALCoGen.
Step 1: Enable USBD Driver
Step 2: Enable PINMUX for USBDevice peripheral
Step 3: Setup 48MHz clock on VCLKA3_S for USBD.
Following screen shots demonstrate usage of PLL2 for VLCKA3 clock source ( on PLL tab).
Step 4: Setup PLL2 as clock source for VCLKA3_S
Since majority of the USBD stack executes in interrupt context, the stack size has to be increased as shown below
Step 6: Configure USB descriptors
Configure USB descriptors and other items specific to USBD CDC Stack. These options are available under the ‘USB’ tab.
Note: Since the string descriptors are in Unicode, one must manually convert the ASCII test to Unicode (Eg., 'ABC' should be entered as 'A','0','B','0','C','0'). The character count for each string must be manually updated for size of the Unicode string (eg., Size of A','0','B','0','C','0' shall be 4).
<u>'''NOTE: The INF file in the example folder uses 0x0451 VID. So use 0x0451 VID, instead of 0x1CBE, in HALCoGen configuration window.'''</u>
Step 7: Enable the USBD Interrupts on ‘VIM Channel 63-94’ tab
Step 8: Setup the interrupt service routines for USBD on ‘VIM RAM’ tab
Step 10: Integrating the CDC Example application
An example CDC application is provided HALCoGen release and is present in <install folder>\examples\RM48x\example_usbd_cdc\example_usbd_cdc.c. This file needs to be copied & replaced in <code generation folder\Source\sys_main.c
Step 11: Create a CCS Project
Following is a screenshot of the project settings used during creation. Note that USB device is available only on RM48xx devices (Little Endian).
Step 13: Compiler setting changes
USBD CDC Stack uses packed structures for the descriptors. Hence appropriate options should be enalbled in the compiler settings. Following two screenshots indicate the settings to be enabled.
Step 14: Update build settings
Update the project build settings to include the 'include' folder generated by HALCoGen.
Step 15: Miscellaneous changes to project.
Since the main() function is part of the example application, from Step# 10, delete the main.c that is generated during CCS project creation.
Step 16: Changes to HDK Jumper settings
Before executing the binary file ensure that the USBD switch is ON (HDK S2 Switch3 must be in ON position)
Step 17: Build, Flash & Execute the binary
Step 18: Windows (Win32) Drivers
Windows Driver INF file for Windows7 is present in examples\RM48x\example_usbd_cdc folder.
Make sure that your project is loaded on the HDK and *running* (not halted at a breakpoint) when you plug in the USB B cable.
Windows will initially fail to detect the device driver. See File:How to use the inf file hcg usb cdc example rm48.pdf if you need help instructing windows to use the .inf file that is included in the example folder.
Worked Example Files
Here is a project built with HalCoGen 4.02.00 and tested on an RM48 HDK. DIP switches in S2 were OFF, OFF, ON, OFF (only USBD ON was on). File:Halcogen usb cdc example worked.zip