Introduction to USB with STM32

Under construction.png Coming soon

On this article, you will find application examples, document references, tips and tricks and so on related to STM32 USB

1. What is the Universal Serial Bus (USB)

The large diversity of ports (parallel, serial, midi, joystick, etc) with their specific requirements and the lack of plug-and-play feature were almost the main reasons that pushed the most known companies in the technology domain to seek for a substitution. These companies developed the USB standard and formed the USB Implementers Forum.
The USB provided the most successful serial interface having the following characteristics:

  • simplicity and flexibility (plug-and-play)
  • bi-directionality
  • increasing speeds
  • low cost

Since developed, the USB has been continuously ameliorated always keeping compatibility with the new technologies evolution and requirements.
The STM32 USB hardware and software are compliant with USB1.1 and USB2.0 specifications and all the following sections will speak about these standard devices.
This section focuses on the USB2.0 standard and provides a general overview about the rich characteristics of this standard.

1.1. Speed

The USB2.0 supports three speeds:

  • Low speed (LS): supports the transfer rate of 1.5 Mb/s. This speed is mainly dedicated to interactive devices (mouse, keyboard, etc)
  • Full speed (FS): supports the transfer rate of 12 Mb/s. This speed is mainly dedicated to phone and audio devices (microphone, speaker, etc)
  • High speed (HS): supports the transfer rate of 480 Mb/s. This speed is mainly dedicated to video and storage devices (printer, camera, etc)

At protocol level, the USB grants a very high compatibility, so users can not see big differences between dealing with different speeds

1.2. USB interconnect components

The USB interconnect has three main components:

  • Host or Root Hub: it is unique for every USB system. It is responsible of initiating all transactions.
  • Function or Device: the final point in the interconnect ensuring the user's required roles (keyboard, mouse, microphone, etc)
  • Hub: a bridge ensuring the communication between the host and many devices. It has one upstream port to be connected directly (point to point connection through USB cable) or indirectly (connection through another hub) to the host and many downstream ports to be connected directly or indirectly to the USB Functions.

The previous components can be connected to each other through USB cables with a maximum length of 5 meters.
The maximum number of hubs connected in series allowed by the USB specification is 5. Thus, a function or device can be connected to the host through one or more hub(s).
In every USB system, there is a host that can communicate with up to 127 devices and hubs. The following figure provides an example of USB system components connection.

File:typical USB system topology.png
USB system topology example

1.3. USB interconnect topology

The USB physical interconnect is characterized by a tired star topology. Each star has a hub at the center with one upstream connection directly or indirectly with the host and one or more downstream connection(s) with function or other hub.
A maximum of 127 devices (functions or hubs) can be connected to one host (root hub) with a maximum of 5 hubs connected in series.

1.4. Power

Generally, the host (root hub) provides power for functions direct connection. Some hubs may supply power for directly connected downstream functions. For the functions, there are two types:

  • Bus powered functions: these devices rely totally on the bus power coming from the upstream hub.
  • Self powered functions: these devices are capable of providing their own power independently from the bus.

1.5. System configuration

The USB system has an intelligent mechanism to detect the device attachment and detachment at any time.

  • Device attachment: the host can detect at any time the detachment of a device by continuously querying a bit for all the connected hub ports. Once a device is attached, the host enables the port and gives the device a unique address then establish a communication with this newly connected device to conclude if it is a function or a hub.
  • Device detachment: once a device is detached, the corresponding port will be disabled. If a hub is detached, all the downstream devices' ports that were attached to the removed hub will be disabled and the detached hub's upstream port will be disabled.
  • Bus enumeration: it is a set of hardware and software events allowing the host to continuously detect and address and recognize the newly connected device. It includes also the set of events ensuring the removal of a device.

1.6. Class

Depending on the required USB device functionality and application, the device and the host features very. The USB IF defines a variety of classes ensuring the classification according to the required functionality. Every class defines an association of:

  • Data including characteristics that must be stored within the device and given to the host when requested
  • Software drivers stored within the host and loaded after negotiation with the device and after discovery of its characteristics.

An overview of all the defined USB classes and codes is provided by the USB IF at this link.

1.7. USB Data transfers

USB communication is based on four main transfer types:

  • Control transfer: mainly used for the configuration data of the newly attached device.
  • Bulk transfer: used for large amounts of data transmission or reception.
  • Interrupt transfer: used for limited data transmission with minimal latency.
  • Isochronous transfer: used for data transfer with real-time requirements.

More detailed explanations of the USB characteristics and data flow will be explained with code examples in the following pages.

1.8. Data direction

As it was outlined in the previous section, the USB supports only 4 transfer types. For all the transfers, it is always the host who initiates the communication with the device. In fact, the USB can transfer data in two directions where the reference is always the host:

  • data out is the data that will be transferred from the host to the device
  • data in is the data that will be transferred from the device into the host

1.9. Transactions

Each transfer independently from its type is based on one or more transaction to ensure the information exchange between a host and a device. Each transaction itself consists of up to three phases or packets:

  • Token: it is always required to start every transaction. It is USB packet sent from the host to the device providing some information about the transaction (type, destination, data phase direction, etc.)
  • Data: this phase is optional. Its existence, direction and size are indicated within the token packet. During this phase, the source of data will send the specified data if it exists.
  • Handshake: this phase is optional. Its existence and direction can be inferred from the token packet. In fact, depending on the direction of data specified in the token packet, the data destination will send this packet to acknowledge the data reception status.

1.10. Requests

As mentioned previously, the host always initiates the communication with the device by sending request. All USB requests have common fields. Each field size, value and signification is known by the device and the host. It is always the host who is responsible of filling a request fields and sending it and, on the other side, the device receives the request and decodes it to be prepared for the next communication phase.

1.11. Descriptor

It is a set of data blocks stocked within the device and organized in a defined manner known by the device and the host. Some descriptors are required for all the devices and the host cannot continue the communication with any device missing a required descriptor. Some descriptors are optional and can differ from a device to another depending on its functionalities. Every descriptor includes some information about the device and will be send to the host as answer to a defined request.

1.12. Endpoint

It is a source or destination data buffer that must be implemented on the device side. Each amount of data that will be received from or sent to the host will be placed into an endpoint. Each endpoint is uniquely characterized by a number and direction which means that for a given number, there is a unique pair of endpoints of the same type and number but each one deals with the data of only one direction:

  • Endpoint in for data that will be transferred into the host.
  • Endpoint out for data that will be transferred from the host.

A device has always more than one endpoint identified by their numbers:

  • Endpoint zero: it is a pair of out and in endpoints dedicated for control data transfers which means it is a control endpoint. It is required to establish the first communication transfers between the host and the device while the other endpoints are not yet configured.
  • Other endpoints: will be configured after negotiation between the host and the device. Each endpoint is independent from the other and can handle a different transfer type.

1.13. Address

A unique value assigned by the host and it varies from 1 to 127. Address 0 is always given to the newly attached device before being addressed by the host.

1.14. Enumeration

It is the procedure ensuring the control of the device status changes and the real time management of any device attachment and detachment. During this step, there is a combination of hardware and software negotiation allowing the host to decode the device nature. At device software level, this procedure ensures the correct reception and decoding of the host request and then device state modification accordingly.

1.15. Device status

From being completely detached until being completely recognized by the USB Host and ensuring its function, the USB device goes through consecutive stages:

  • Attached: it is the stage when the device is physically connected to the USB host but not yet powered. This stage is transparent at the device software level.
  • Powered: it is the second stage and is corresponding to a device that was attached to USB Host and just powered. This stage is transparent at the device software level.
  • Default: this stage is reached when the attached device has been powered then reset by the host. This stage is assigned to the device by its software each time the device is newly attached then powered then reset or an old attached device received a reset. At this stage, The USB Device operates with convenient speed (selected by hardware during reset) and has the default address which is the address number 0.
  • Addressed: after going through all the previous stages, the USB device reaches this state by receiving its unique address (different from 0) from the host. This stage is reached after correct process of the host request by the device software.
  • Configured: the device reaches this stage after receiving the convenient request from the host with a non-zero configuration number. This stage is reached after correct process of the host request by the device software.
  • Suspended: the device must enter this stage if there is no data on the traffic for a known period that depends on the speed. In fact, the host forces the device to enter this state electrically depending on the speed. When detecting this electrical indication, the USB device software must change its state into suspended.

2. Getting started with STM32 and USB

This section provides answers that can be asked when starting the use of the STM32 MCU's USB.

2.1. What does the STM32 support?

All the STM32 families (not all products) include the USB IP. Depending on the hardware, each STM32 MCU including the USB can support:

  • Device in FS speed only.
  • OTG ( dual role: device and host) in FS speed.
  • OTG in HS speed.

Some STM32 MCUs include two USB peripherals and support both OTG in FS and HS speeds.
An overview of the USB hardware over the STM32 MCUs will be provided in the next pages.

2.2. What role can the STM32 MCU play within a USB system?

A basic USB system can be established by a host and a device attached with a USB cable. The following figure shows the possible roles that can keep the STM32 MCU's USB:

STM32 USB role within a basic USB system

For more complex USB system, the device can be attached to the host through one or more hub(s). For such system, currently, the STM32 USB can play the role of the device as shown in the figure below.

STM32 USB role within a complex USB system

2.3. How can I select one STM32 MCU for my USB application?

For every USB application, it is important to select the correct STM32 with required USB role (Host or Device) and speed (LS or FS or HS). But there are many STM32 MCUs having the same USB hardware implementation, how to choose? Besides the USB features, the STM32 MCUs offer a large set of peripherals with large features portfolio. The diversity of peripherals and features guarantees the flexibility and ease of the required application's implementation. In fact, the convenient MCU selection is one of the most secrets of a successful USB application.
To select the convenient MCU, the following features must be taken into consideration depending on the application requirements:

  • The MCU performance have a direct impact on data transfer and processing in the STM32 system.
  • The memories (RAM and ROM) availability and sizes are very important for applications processing large amounts of data.
  • the required peripherals availability and features must be checked when selecting the STM32 MCU because peripherals versions and combinations can largely differ from one MCU to another.
  • The power consumption is a very important requirement for some applications

The STM32 compliant with USB section provides an overview of all the STM32 MCUs including USB, it also includes some of the most important features for USB applications requirements.

2.4. Where can I find more detailed information about the USB for the selected STM32 MCU?

For every STM32 MCU, there is a set of documents providing information about all the integrated peripherals and among others the USB. All the STM32 MCUs have a page providing a generic overview with a direct link to the MCU's datasheet. In fact, all the STM32 MCU's USB peripheral information are integrated mainly in the datasheet (specially the electrical characterization) and the reference manual (includes all the MCU's peripherals information thus it provides a detailed information about the integrated USB peripheral(s)).
All the STM32 MCUs technical documents can be found using this link.

2.5. Is there any provided STM32 USB code examples?

Every STM32 Family has a package that includes the MCU's drivers and peripherals examples called the STM32Cube Firmware package. This package includes the USB Device and Host (if supported by the MCU) drivers and code examples for all the supported speeds.
To access the USB code, the STM32Cube Firmware package must be installed. When opening the installed folder, the following steps must be followed:

  • Open "Projects" sub-folder.
  • Open the folder having the name of the convenient board including the selected MCU.
  • Open "Applications" sub-folder
  • Select the USB convenient sub-folder ("USB_Device" for device applications and USB_Host for host applications if supported by the MCU)
  • Select the convenient application
  • Select the convenient IDE (IAR, STM32CubeIDE, KEIL)

At this level, the application's code can be debugged and can be loaded into the STM32 t check the results as mentioned in the readme.txt file which is provided within the application sub-folder. All the STM32 MCUs tools and software can be accessed using this link.
A detailed explanation of all the STM32 USB code parts will be explained in the following pages.

3. Video related to STM32 USB

Special STM32 USB training videos were published to facilitate the understanding of the USB concepts and the STM32 USB supported features. It provides also an explanation of the STM32 USB host and device provided libraries. These videos cover many Hardware and Software concepts that target different USB knowledge levels.

pc videol.png

MOOC - STM32 USB training

In the following pages, some parts of the videos will be explained in more details with some code examples extracted from the STM32Cube firmware.

4. STM32 compliant with USB

The following table provides an overview about the USB hardware implementation through STM32 series. Some part numbers may not include same USB hardware compared to other part numbers in the same family include as shown in the table below:

STM32 series USB Device only USB OTG FS USB OTG HS USB OTG FS&HS
STM32F0
STM32F1
STM32F2
STM32F3
STM32F4
STM32F7
STM32G4
STM32H7
STM32L0
STM32L1
STM32L4
STM32L4+
STM32L5
STM32WB


More detailed information about every STM32 MCU and Board features and peripherals can be found using the ST-MCU-FINDER.

5. USB Device Library Overview

With the STM32 MCUs and boards, a full and free development environment called the STM32Cube is offered including two main parts:

  • Graphical software tools.
  • Embedded software packages (STM32Cube firmware).

More details about the STM32Cube offer can be found here. Each STM32Cube firmware provides full set of drivers and examples ensuring the ease of use of the different peripherals supported by one stm32 MCUs Family. The STM32Cube firmware covers the different levels by offering:

  • Low layer and optimized drivers.
  • Hardware abstraction layer and portable drivers.
  • Middleware libraries.
  • Examples and applications.

As almost of middleware components, the STM32 USB device offer is based mainly on STMicroelectronics Device library but also on some low and hardware abstraction layers drivers besides many applications.

5.1. USB Device library folders architecture within STM32Cube firmware

Within every STM32Cube firmware package, there is “Middlewares” folder including all ST and third party’s middleware libraries. The STM32 USB device library is part of the “Middlewares/ST” offer. The “STM32_USB_Device_Library” includes the “Core” module for the USB device standard peripheral control APIs and “Classes” model for the commonly supported classes APIs. The following figures shows the folders structure of the STM32 USB device library.

File:STM32 Device Library Folders Architecture.png
USB Device library folders architecture

5.2. USB Device Applications folders architecture within STM32Cube firmware

Within every STM32Cube firmware package, a dedicated folder for applications is offered including a list of all the middlewares that are supported by the selected STM32 board and, among others, the USB device Applications will be found. These applications code can be run, debugged, and tested directly on the convenient STM32 by following the steps described in the readme.txt provided within every application’s folder. Generally, to guarantee more flexibility, every application is offered with the support of three IDEs. The following figure shows an example of USB Device applications supported by one STM32 board. The applications number differs from one STM32 Board to another.

File:STM32 Device Applications Folders Architecture.png
STM32 Device Applications Folders Architecture.png

5.3. STM32 USB Device Library description

As mentioned previously, the STM32 USB Device Library includes the Core and the Classes folders.

5.3.1. Core

this folder includes the files ensuring USB 2.0 standard code implementation. These files’ APIs will be called within every USB device application regardless of the desired functionality. It includes five main modules that are:

  • usbd_core (.c, .h): this file includes all the functions ensuring the control of the USB core state machine and the different events processing.
Function Description
USBD_Init Initializes the Device Handler and state machine
USBD_DeInit De-initializes the Device Handler
USBD_RegisterClass Links the device handler to the class handler
USBD_Start Starts the device core
USBD_Stop Stops the device core and class
USBD_SetClassConfig Initializes the device’s class with the input configuration
USBD_ClrClassConfig Clears a device’s class configuration
USBD_LL_SetupStage Handles the setup stage requests
USBD_LL_DataOutStage Handles the data reception from the host on the convenient endpoint
USBD_LL_DataInStage Handles the data sending to the host on the convenient endpoint
USBD_LL_Reset Reinitializes the Device’s handler
USBD_LL_SetSpeed Sets the device’s speed
USBD_LL_Suspend Modifies the device status into suspended
USBD_LL_Resume Resumes the device old status before being suspended
USBD_LL_SOF Handles the Start Of Frame event
USBD_LL_IsoINIncomplete Handles the Iso In Incomplete event
USBD_LL_IsoOUTIncomplete Handles the Iso Out Incomplete event
USBD_LL_DevConnected Handles the Device connected event
USBD_LL_DevDisconnected Handles the Device disconnected event


  • usbd_ioreq (.c, .h): this file includes functions ensuring the data sending and reception on the endpoint 0.
Function Description
USBD_CtlSendData Starts data sending on the Endpoint 0
USBD_CtlContinueSendData Sends the remaining data on the endpoint 0
USBD_CtlPrepareRx Prepares the endpoint 0 for receiving data
USBD_CtlContinueRx Continues the reception of data on endpoint 0
USBD_CtlSendStatus Sends zero length packet on the endpoint 0
USBD_CtlReceiveStatus Receives zero length packet on the endpoint 0
USBD_GetRxCount Returns the received data length


  • usbd_conf_template (.c, .h): template for implementing USB device configuration and interrupts callbacks when developing a new application.
  • usbd_desc_template (.c, .h): template for implementing USB device descriptors when developing a new application.
  • usbd_def.h: includes all common USB device constants and structures definitions.

5.3.2. Classes

This folder includes the files including different USB device classes. All STM32 USB classes are implemented according to the USB 2.0 and every class’s specifications. These files’ APIs will be called within USB device applications according to the desired functionality.

5.3.2.1. HID Class

this class code was implemented according to the “Device Class Definition for Human Interface Devices (HID) version 1.11”. This class folder includes:

  • usbd_hid (.c, .h): these files include all the HID class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBD_HID_Init Initializes the HID class’ handler and required endpoints
USBD_HID_DeInit De-initializes the HID class’ handler and required endpoints
USBD_HID_Setup Handles the HID specific requests
USBD_HID_SendReport Handles data sending to the host on non-control IN endpoint
USBD_HID_GetPollingInterval Returns polling interval from endpoint descriptor
USBD_HID_GetFSCfgDesc Returns FS configuration descriptor
USBD_HID_GetHSCfgDesc Returns HS configuration descriptor
USBD_HID_GetOtherSpeedCfgDesc Returns other speed configuration descriptor


5.3.2.2. CustomHID Class

This class code was implemented according to the “Device Class Definition for Human Interface Devices (HID) version 1.11”. This class folder includes:

  • usbd_customhid (.c, .h): these files include all the CustomHID class’ variables and specific requests and APIs implementation. The following table shows the main functions.
Function Description
USBD_CUSTOM_HID_Init Initializes the CustomHID class’ handler and required endpoints
USBD_CUSTOM_HID_DeInit De-initializes the CustomHID class’ handler and required endpoints
USBD_CUSTOM_HID_Setup Handles the CustomHID specific requests
USBD_CUSTOM_HID_SendReport Handles data sending to the host on non-control IN endpoint
USBD_CUSTOM_HID_GetFSCfgDesc Returns FS configuration descriptor
USBD_CUSTOM_HID_GetHSCfgDesc Returns HS configuration descriptor
USBD_CUSTOM_HID_GetOtherSpeedCfgDesc Returns other speed configuration descriptor
USBD_CUSTOM_HID_DataIn Handles DATA IN event
USBD_CUSTOM_HID_DataOut Handles DATA OUT event
USBD_CUSTOM_HID_ReceivePacket Prepares OUT Endpoint for reception
USBD_CUSTOM_HID_EP0_RxReady Handles the reception ready event on endpoint 0
USBD_CUSTOM_HID_GetDeviceQualifierDesc Returns Device Qualifier descriptor
USBD_CUSTOM_HID_RegisterInterface Links the CustomHID interface to the device handler


5.3.2.3. MSC Class

This class code was implemented according to the “Universal Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0”. This class folder includes:

  • usbd_msc (.c, .h):these files include all the MSC class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBD_MSC_Init Initializes the MSC class’ handler and required endpoints
USBD_MSC_DeInit De-initializes the MSC class’ handler and required endpoints
USBD_MSC_Setup Handles the MSC specific requests
USBD_MSC_DataIn Handles data sending to the host on non-control IN endpoint
USBD_MSC_DataOut Handles data reception from the host on non-control OUT endpoint
USBD_MSC_GetFSCfgDesc Returns FS configuration descriptor
USBD_MSC_GetHSCfgDesc Returns HS configuration descriptor
USBD_MSC_GetOtherSpeedCfgDesc Returns other speed configuration descriptor
USBD_MSC_GetDeviceQualifierDescriptor Returns Device Qualifier descriptor
USBD_MSC_RegisterStorage Links the class handler to the device handler


  • usbd_msc_scsi (.c, .h): these files include different required SCSI commands processing functions.
  • usbd_msc_bot (.c, .h): these files include different bulk only transfers processing functions.
  • usbd_msc_data (.c, .h): these files include different mass storage devices’ inquiry pages and sense data.
  • usbd_msc_storage_template (.c, .h): these files are templates allowing to add further features and abilities to the mass storage devices.
5.3.2.4. CDC Class

This class code was implemented according to the “Universal Serial Bus Class Definitions for Communications Devices Revision 1.2”. This class folder includes:

  • usbd_cdc (.c, .h): these files include all the CDC class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBD_CDC_Init Initializes the CDC class’ handler and required endpoints
USBD_CDC_DeInit De-initializes the CDC class’ handler and required endpoints
USBD_CDC_Setup Handles the CDC specific requests
USBD_CDC_DataIn Handles data sending to the host on non-control IN endpoint
USBD_CDC_DataOut Handles data reception from the host on non-control OUT endpoint
USBD_CDC_EP0_RxReady Handles the reception ready event on endpoint 0
USBD_CDC_GetFSCfgDesc Returns FS configuration descriptor
USBD_CDC_GetHSCfgDesc Returns HS configuration descriptor
USBD_CDC_GetDeviceQualifierDescriptor Returns Device Qualifier descriptor
USBD_CDC_RegisterInterface Links the CDC interface class to the device handler
USBD_CDC_SetTxBuffer Prepares the Tx buffer for transferring data
USBD_CDC_SetRxBuffer Prepares the Rx buffer for receiving data
USBD_CDC_TransmitPacket Transmits one packet on IN endpoint
USBD_CDC_ReceivePacket Prepares OUT Endpoint for reception


  • usbd_cdc_if_template (.c, .h): these files are templates that can be filled and added to the application to ensure the interfacing between the USB and other peripheral.
5.3.2.5. CDC ECM Class

This class code was implemented according to the “Universal Serial Bus Communications Class Subclass Specification for Ethernet Control Model Devices Revision 1.2”. This class folder includes:

  • usbd_cdc_ecm (.c, .h): these files include all the CDC-ECM subclass’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBD_CDC_ECM_Init Initializes the CDC-ECM subclass’ handler and required endpoints
USBD_CDC_ECM_DeInit De-initializes the CDC-ECM subclass’ handler and required endpoints
USBD_CDC_ECM_Setup Handles the CDC-ECM specific requests
USBD_CDC_ECM_DataIn Handles data sending to the host on non-control IN endpoint
USBD_CDC_ECM_DataOut Handles data reception from the host on non-control OUT endpoint
USBD_CDC_ECM_EP0_RxReady Handles the reception ready event on endpoint 0
USBD_CDC_ECM_GetFSCfgDesc Returns FS configuration descriptor
USBD_CDC_ECM_GetHSCfgDesc Returns HS configuration descriptor
USBD_CDC_ECM_GetOtherSpeedCfgDesc Returns other speed configuration descriptor
USBD_CDC_ECM_GetDeviceQualifierDescriptor Returns Device Qualifier descriptor
USBD_CDC_ECM_RegisterInterface Links the CDC-ECM interface to the device handler
USBD_CDC_ECM_USRStringDescriptor Manages the transfer of user string descriptors when this feature is enabled by user
USBD_CDC_ECM_SetTxBuffer Prepares the Tx buffer for transferring data
USBD_CDC_ECM_SetRxBuffer Prepares the Rx buffer for receiving data
USBD_CDC_ECM_TransmitPacket Transmits one packet on IN endpoint
USBD_CDC_ECM_ReceivePacket Prepares OUT Endpoint for reception
USBD_CDC_ECM_SendNotification Transmits Notification packet on IN interrupt endpoint


  • usbd_cdc_ecm_if_template (.c, .h): these files are templates that can be filled and added to the application to ensure the interfacing between the USB and ethernet.
5.3.2.6. CDC RNDIS Class

This class code was implemented according to the “Remote Network Driver Interface Specification (RNDIS) Protocol Revision 5.0”. This class folder includes:

  • usbd_cdc_rndis (.c, .h): these files include all the CDC-ECM subclass’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBD_CDC_RNDIS_Init Initializes the CDC-RNDIS subclass’ handler and required endpoints
USBD_CDC_RNDIS_DeInit De-initializes the CDC- RNDIS subclass’ handler and required endpoints
USBD_CDC_RNDIS_Setup Handles the CDC- RNDIS specific requests
USBD_CDC_RNDIS_DataIn Handles data sending to the host on non-control IN endpoint
USBD_CDC_RNDIS_DataOut Handles data reception from the host on non-control OUT endpoint
USBD_CDC_RNDIS_EP0_RxReady Handles the reception ready event on endpoint 0
USBD_CDC_RNDIS_GetFSCfgDesc Returns FS configuration descriptor
USBD_CDC_RNDIS_GetHSCfgDesc Returns HS configuration descriptor
USBD_CDC_RNDIS_GetOtherSpeedCfgDesc Returns other speed configuration descriptor
USBD_CDC_RNDIS_GetDeviceQualifierDescriptor Returns Device Qualifier descriptor
USBD_CDC_RNDIS_RegisterInterface Links the CDC-RNDIS interface to the device handler
USBD_CDC_RNDIS_USRStringDescriptor Manages the transfer of user string descriptors when this feature is enabled by user
USBD_CDC_RNDIS_SetTxBuffer Prepares the Tx buffer for transferring data
USBD_CDC_RNDIS_SetRxBuffer Prepares the Rx buffer for receiving data
USBD_CDC_RNDIS_TransmitPacket Transmits one packet on IN endpoint
USBD_CDC_RNDIS_ReceivePacket Prepares OUT Endpoint for reception
USBD_CDC_RNDIS_SendNotification Transmits Notification packet on IN interrupt endpoint
USBD_CDC_RNDIS_MsgParsing Parses received message and process it depending on its nature
USBD_CDC_RNDIS_ProcessInitMsg Parses, extracts data and checks correctness of CDC_RNDIS INIT_MSG command


  • usbd_cdc_rndis_if_template (.c, .h): these files are templates that can be filled and added to the application to ensure the interfacing between the USB and ethernet.
5.3.2.7. AUDIO Class

This class code was implemented according to the “USB Device Class Definition for Audio Devices V1.0”. This class folder includes:

  • usbd_audio (.c, .h): these files include all the AUDIO class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBD_AUDIO_Init Initializes the AUDIO class’ handler and required endpoints
USBD_AUDIO_DeInit De-initializes the AUDIO class’ handler and required endpoints
USBD_AUDIO_Setup Handles the AUDIO class’ specific requests
USBD_AUDIO_DataIn Handles data sending to the host on non-control IN endpoint
USBD_AUDIO_DataOut Handles data reception from the host on non-control OUT endpoint
USBD_AUDIO_EP0_RxReady Handles the endpoint 0 Rx ready event
USBD_AUDIO_EP0_TxReady Handles the endpoint 0 Tx ready event
USBD_AUDIO_SOF Handles the Start Of Frame event
USBD_AUDIO_Sync Synchronizes pointers for data sending or reception
USBD_AUDIO_IsoINIncomplete Handles the ISO IN Incomplete event
USBD_AUDIO_IsoOutIncomplete Handles the ISO OUT Incomplete event
AUDIO_REQ_GetCurrent Handles the Get Current request.
AUDIO_REQ_SetCurrent Handles the Set Current request.
USBD_AUDIO_GetDeviceQualifierDesc Returns Device Qualifier descriptor
USBD_AUDIO_RegisterInterface Links the AUDIO interface class to the device handler


  • usbd_audio_if_template (.c, .h): these files are templates that can be filled and added to the application to ensure the interfacing between the USB and the audio peripheral.
5.3.2.8. BILLBOARD Class

This class code was implemented according to the “Universal Serial Bus Device Class Definition for Billboard Devices Revision 1.21”. This class folder includes:

  • usbd_billboard (.c, .h): these files include all the Billboard class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBD_BB_Init Initializes the Billboard class’ handler and required endpoints
USBD_BB_DeInit De-initializes the Billboard class’ handler and required endpoints
USBD_BB_Setup Handles the Billboard class’ specific requests
USBD_BB_DataIn Handles data sending to the host on non-control IN endpoint
USBD_BB_DataOut Handles data reception from the host on non-control OUT endpoint
USBD_BB_EP0_RxReady Handles the endpoint 0 Rx ready event
USBD_BB_GetCfgDesc Returns the configuration descriptor
USBD_BB_GetOtherSpeedCfgDesc Returns other speed configuration descriptor
USBD_BB_GetDeviceQualifierDesc Returns Device Qualifier descriptor
USBD_BB_GetNextDesc Returns the next descriptor header
USBD_BB_GetCapDesc Returns the Billboard Capability descriptor
USBD_BB_GetAltModeDesc Returns the Billboard Alternate Mode descriptor


5.3.2.9. DFU Class

This class code was implemented according to the “Device Class Specification for Device Firmware Upgrade Version 1.1”. This class folder includes:

  • usbd_dfu (.c, .h): these files include all the DFU class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBD_DFU_Init Initializes the DFU class’ handler and required endpoints
USBD_DFU_DeInit De-initializes the DFU class handler and required endpoints
USBD_DFU_Setup Handles the DFU specific requests
USBD_DFU_DataIn Handles data sending to the host on non-control IN endpoint
USBD_DFU_DataOut Handles data reception from the host on non-control OUT endpoint
USBD_DFU_GetCfgDesc Returns the configuration descriptor
USBD_DFU_EP0_RxReady Prepares the Rx buffer for receiving data
USBD_DFU_EP0_TxReady Prepares the Tx buffer for transferring data
USBD_DFU_SOF Handles the Start Of Frame event
USBD_DFU_IsoINIncomplete Handles data ISO IN Incomplete event
USBD_DFU_IsoOutIncomplete Handle data ISO OUT Incomplete event
USBD_DFU_GetDeviceQualifierDesc Returns Device Qualifier descriptor
USBD_DFU_RegisterMedia Links the DFU interface to the device handler
DFU_Detach Handles the DFU DETACH request
DFU_Download Handles the DFU DOWNLOAD request
DFU_Upload Handles the DFU UPLOAD request
DFU_GetStatus Handles the DFU GET STATUS request
DFU_GetState Handles the DFU GET STATE request
DFU_ClearStatus Handles the DFU CLEAR STATUS request
DFU_Abort Handles the DFU ABORT requestt
DFU_Leave Handles the DFU leave DFU mode request (After this request, the application leaves DFU mode and resets device to jump to user loaded code)


  • usbd_dfu_media_template (.c, .h): these files are templates that can be used to interface with different memories.
5.3.2.10. Template Class

This folder provides the ability to implement a custom class respecting the STM32 USB Device class’ architecture. It includes the usbd_template (.c & .h) files to define the different required class’ descriptors, implement the class’ handler initialization and deinitialization, handle the class’ specific requests, data exchange with the host on the different endpoints… etc.

5.3.3. STM32 USB Device Library main variables

The STM32 USB Device library offers common structures to manage the different USB device data. These structures can be filled according to the class, the peripheral hardware type and application requirements.

5.3.3.1. Setup request structure

When a request is received from the host, it will be decoded and put in the following structure to ease its processing:
typedef struct usb_setup_req
{
uint8_t bmRequest; ➔ this field includes information about the data transfer direction (if data exchange is required in the next communication phase), the request type and the precise destination that can be the device or the interface or the endpoint.
uint8_t bRequest; ➔ this field specifies the request. Mainly, there are the standard requests that are required by the host from any connected device and there are optional requests that depend on the device functionality.
uint16_t wValue; ➔ this field includes the request parameter that the device need to know to proceed correctly. For some requests, there is no required parameter and thus this field includes a zero.
uint16_t wIndex; ➔ this field includes the request parameter that the device need to know to proceed correctly. For some requests, there is no required parameter and thus this field includes a zero.
uint16_t wLength; ➔ this field specifies the data length to be transferred in the next transfer phase in the direction specified in the bmRequest field. If no data transfer is required, this field includes zero.
}

5.3.3.2. USB Device descriptors structure

To ease the different device descriptors processing, a dedicated structure was implemented to include all the common required descriptors. This structures can be filled according to the class requirements. Please refer to every class table in the previous section to know the convenient required descriptors.
typedef struct
{
uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); ➔ response to get descriptor request when the descriptor type is of device type.
uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); ➔ response to get descriptor request when the descriptor type (according to the wValue) is of string type when the descriptor index designs the langId string desc.
uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); ➔ response to string descriptor request when the descriptor index designs the manufacturer string desc.
uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);➔ response to string descriptor request when the descriptor index designs the product string desc.
uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); ➔ response to string descriptor request when the descriptor index designs the serial string desc.
uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); ➔ response to string descriptor request when the descriptor index designs the configuration string desc.
uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); ➔ response to string descriptor request when the descriptor index designs the interface string desc.
uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); ➔ response to
the get user string descriptor if supported.
uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); ➔ response to get descriptor request when the descriptor type is of BOS type if supported.
}
USBD_DescriptorsTypeDef;

5.3.3.3. USB Device handler structure

This structure includes the different USB Device data and information. This structures can be filled according to the class requirements.
typedef struct _USBD_HandleTypeDef
{
uint8_t id;➔ Low level core index (FS or HS) assigned bu USBD_Init defined in core.c and It is defined only for device software requirements.
uint32_t dev_config; ➔ The lower byte of the wValue field specifies the desired configuration. It is assigned in set_config() that is defined in ctlreq.c.
uint32_t dev_default_config; ➔ the default configuration is always 0, it is called by the get_cofig when the device is not yet configured and it is in addressed state assigned in get status when the device is in configured state.
uint32_t dev_config_status; ➔ it contains 2 informations if the device is self-powered and if it supports the remote wake up.
USBD_SpeedTypeDef dev_speed; ➔ it is assigned in usbd_ll_set_speed in the core.c and includes the device speed.
USBD_EndpointTypeDef ep_in[15]; ➔ total endpoints in number depending on the device hardware. It can reach 16.
USBD_EndpointTypeDef ep_out[15]; ➔ total endpoints out number depending on the device hardware. It can reach 16.
uint32_t ep0_state; ➔ it includes the ep0 status depending on the transfer stage. It takes:

  • USBD_EP0_SETUP when USBD_LL_SetupStage is called.
  • USBD_EP0_IDLE when status in or out phase is completed or after reset.
  • USBD_EP0_DATA_IN or USBD_EP0_DATA_OUT status when it sends or receives data.
  • USBD_EP0_STATUS_IN or USBD_EP0_STATUS_OUT status when it sends or receives status.

uint32_t ep0_data_len; ➔ This field specifies the length of the data transferred during the second phase of the control transfer specified in USBD_LL_SetupStage().
uint8_t dev_state; ➔ it includes the device state that can be:

  • USBD_STATE_DEFAULT when initializing the device by calling USBD_Init(), deinitializing the device by calling USBD_DeInit(), resetting the device by calling USBD_LL_Reset() and when the deice is disconnected by calling USBD_LL_DevDisconnected().
  • USBD_STATE_SUSPENDED when the device will be suspended by callig USBD_LL_Suspend ().
  • USBD_STATE_ADDRESSED in set_address when the received address is valid.
  • USBD_STATE_CONFIGURED in set config if the device is addressed.

uint8_t dev_old_state; ➔ the previous state of the device before switching to the current state.
uint8_t dev_address; ➔ modified in USBD_SetAddress() when the Set Address is received.
uint8_t dev_connection_status; ➔ includes the device connection status.
uint8_t dev_test_mode; ➔ for the software when it is set to 1 it will run the test mode function uint32_t dev_remote_wakeup; ➔ it is set to 1 when USBD_SetFeature() is called and it is set to 0 after reset when the USBD_LL_Reset() is called and when USBD_ClrFeature() is called.
USBD_SetupReqTypedef request; ➔ it is a pointer to the request structure. The USBD_ParseSetupRequest is called to fill the request class parts with the received data in the ll_setup_stage. Depending on the bmRequest, one of the following functions will be called:

  • USBD_StdDevReq to handle standard device request.
  • USBD_StdItfReq to handle standard interface request.
  • USBD_StdEPReq to handle standard endpoint request.

USBD_DescriptorsTypeDef *pDesc; ➔ pointer to a structure that includes all the USB descriptors. It is defined in the usbd_def.h and fulled by variables the usbd_desc.c when calling the usbd_int(). It depends on the class. Please refer to "USB Device descriptors structure" section.
USBD_ClassTypeDef *pClass; ➔ USBD_RegisterClass() is used to fill the structure defined in usbd_def.h and the variable values are defined in the class files. Please refer to "USB Device class structure" section.
void *pClassData; ➔ it is the allocation of the size of USBD_class_Handle_Typedef
void *pUserData; ➔ it is a pointer to the interface structure that is required by some classes and it is not used by other classes.
void *pData; initiated in the usbd_ll_init() and it is a pointer to the low layer stack structure ( PCD_HandleTypeDef )
void *pBosDesc; ➔ pointer to the BOS descriptor if required by the class.
void *pConfDesc; ➔ pointer to the configuration descriptor.
}
USBD_HandleTypeDef;

5.3.3.4. USB Device class structure

To ease the different device's class processing, a dedicated structure was implemented to include all the common required functions. This structures can be filled according to the class requirements. Please refer to every class table in the previous section to know the convenient required functions.
typedef struct _Device_cb
{
uint8_t (*Init) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); ➔ pointer to the function allowing the initialization of the class
uint8_t (*DeInit) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); ➔ pointer to the function allowing the deinitialization of the class
uint8_t (*Setup) (struct _USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req); ➔ pointer to the function allowing to handle the class specific requests
uint8_t (*EP0_TxSent) (struct _USBD_HandleTypeDef *pdev ); ➔ pointer to the function allowing to handle the endpoint zero Tx Ready event. This pointer can be null for classes that does not need to do this event.
uint8_t (*EP0_RxReady) (struct _USBD_HandleTypeDef *pdev ); ➔ pointer to the function allowing to handle the endpoint zero Rx Ready data event. This pointer can be null for classes that does not need to do this event.
uint8_t (*DataIn) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); ➔ pointer to the function allowing to handle the data sending through a non-control IN endpoint. This pointer can be null for classes that does not need to send data through a non-control IN endpoint.
uint8_t (*DataOut) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); ➔ pointer to the function allowing to handle the data reception through a non-control OUT endpoint. This pointer can be null for classes that does not need to send data through a non-control OUT endpoint.
uint8_t (*SOF) (struct _USBD_HandleTypeDef *pdev); ➔ pointer to the function allowing to handle handle SOF event. This pointer can be null for classes that does not need to handle this event.
uint8_t (*IsoINIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); ➔ pointer to the function allowing to handle data ISO IN Incomplete event. This pointer can be null for classes that does not need to handle this event.
uint8_t (*IsoOUTIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); ➔ pointer to the function allowing to handle data ISO OUT Incomplete event. This pointer can be null for classes that does not need to handle this event.
uint8_t *(*GetHSConfigDescriptor)(uint16_t *length); ➔ pointer to the function allowing to provide the convenient configuration descriptor for HS speed. This pointer can be null for devices that does not support HS speed.
uint8_t *(*GetFSConfigDescriptor)(uint16_t *length); ➔ pointer to the function allowing to provide the convenient configuration descriptor for FS speed.
uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length); ➔ pointer to the function allowing to provide the convenient other speed configuration descriptor.
uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length); ➔ pointer to the function allowing to provide the Device Qualifier descriptor.
uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev ,uint8_t index, uint16_t *length); ➔ pointer to the function allowing to provide the user string descriptor.
}
USBD_ClassTypeDef;

5.3.3.5. Low layer USB peripheral control driver handler structure

To ease the different low layer peripheral data processing, a dedicated structure was implemented to include all the common required variables. This structures can be filled according to the peripheral hardware.
{
PCD_TypeDef *Instance; ➔ Register base address.
PCD_InitTypeDef Init; ➔ PCD required parameters.
__IO uint8_t USB_Address; ➔ USB assigned Address.
PCD_EPTypeDef IN_ep[n]; ➔ IN endpoint parameters, n is the number of endpoints supported by the product up to 16.
PCD_EPTypeDef OUT_ep[n]; ➔ OUT endpoint parameters, n is the number of endpoints supported by the product up to 16.
HAL_LockTypeDef Lock; ➔ PCD peripheral status.
__IO PCD_StateTypeDef State; ➔ PCD communication state.
__IO uint32_t ErrorCode; ➔ PCD Error code.
uint32_t Setup[12]; ➔ Setup packet buffer.
PCD_LPM_StateTypeDef LPM_State; ➔ LPM State.
uint32_t BESL; uint32_t lpm_active; ➔ Enable or disable the Link Power Management . This parameter can be set to ENABLE or DISABLE.
uint32_t battery_charging_active; ➔ Enable or disable Battery charging. This parameter can be set to ENABLE or DISABLE;
void *pData; ➔ Pointer to upper stack Handler.
}
PCD_HandleTypeDef;

5.4. STM32 USB Hardware Abstraction Layer

Unlike the USB device library that is common for all STM32 microcontrollers, the HAL layer differs from one STM32 device to another. But the different layers can be easily linked to each other and work successfully. For every family, there are:

  • stm32XXxx_hal_pcd (.c, .h): XX refers to the STM32 device series that can be f4, f7, h7, wb, g4…etc. These files include the different callbacks registration and un-registration besides a set of variables and functions allowing to manage the peripheral controller driver initialization, deinitialization and data transfers.
  • stm32XXxx_hal_pcd_ex (.c, .h): XX refers to the STM32 device series that can be f4, f7, h7, wb, g4…etc. These files include the variables and functions allowing the update of the endpoints data buffers, the activation and deactivation of some features (LPM, BCD).

5.5. STM32 USB Low layer

This layer depends highly on the STM32 USB hardware peripheral type since it ensures the different registers access required to allow the higher layers (HAL, USB Device library & application) to communicate with the hardware peripheral and control its status accordingly. For every family, there are:

  • stm32XXxx_ll_usb (.c, .h): XX refers to the STM32 device series that can be f4, f7, h7, wb, g4…etc These files includes different variables and functions ensuring the access to the USB peripheral hardware registers.

5.6. USB Device application implementation

For every STM32 USB Device application there are a set of files that must be updated accordingly to interface correctly with the STM32 USB Device libray, Hardware abstraction layer and low layer:

  • main (.c, .h): include the main applications functions and variables required for the application.
  • usb_device (.c, .h): exists only for the advanced applications architecture. It contains all the USB initialization functions and variables.For the basic application architecture, the initialization will be done in main(.c, .h).
  • stm32XXxx_it (.c, .h): XX refers to the STM32 device that can be f4, f7, h7, wb, g4, l5...etc. It includes the USB and other system interrpts IRQ handler.
  • usb_desc (.c, .h): include the descriptors definitions and related functions. It depends on the selected class.
  • usbd_conf (.c, .h): include the GPIOs and low layer handler initialization and the USB callbacks definitions. It depends on the hardware.

In the application file that can be the main.c or usb_device.c, the initialization of the USB Device is ensured mainly through three main functions that are:

  • USBD_Init (): initializes the device stack and loads the class driver.
  • USBD_RegisterClass(): links the class driver to the device core.
  • USBD_Start(): allows user to start the USB device core.

The following figure provides an overview about some functions that will be called to ensure the initialization. For more details about all the functions calls and different variables assignment, please refer to an STM32 USB Device application.

USB Device initialization main functions call graph

5.7. STM32 USB Device Components organization

As most of the other middleware in the STM32Cube firmware, the USB application implementation requires the interaction between different drivers’ levels:

  • The application level includes the files that are related to the desired functionality of the USB device and differ from one application to another. It includes one part that is depend only on the class and the other part includes the configuration files that depend on the STM32 USB hardware.
  • The STM32 USB Device Library contains the "Core" including the APIs that are common for all the STM32 USB classes and applications and the "Classes" that including all the APIs related to all the USB device supported classes.
  • The Hardware abstraction layer and the low layer drivers ensure the interaction with the USB hardware peripheral. These drivers are classes-independent and depend only on the USB hardware peripheral type.
File:STM32 Device Library components organization.png
STM32 Device Library components organization

6. USB Host Library Overview

With the STM32 MCUs and boards, a full and free development environment called the STM32Cube is offered including two main parts:

  • Graphical software tools.
  • Embedded software packages (STM32Cube firmware).

More details about the STM32Cube offer can be found here. Each STM32Cube firmware provides full set of drivers and examples ensuring the ease of use of the different peripherals supported by one stm32 MCUs Family. The STM32Cube firmware covers the different levels by offering:

  • Low layer and optimized drivers.
  • Hardware abstraction layer and portable drivers.
  • Middleware libraries.
  • Examples and applications.

As almost of middleware components, the STM32 USB Host offer is based mainly on STMicroelectronics Host library but also on some low and hardware abstraction layers drivers besides many applications.

6.1. USB Host library folders architecture within STM32Cube firmware

Within every STM32Cube firmware package, there is “Middlewares” folder including all ST and third party’s middleware libraries. The STM32 USB host library is part of the “Middlewares/ST” offer. The “STM32_USB_Host_Library” includes the “Core” module for the USB host standard peripheral control APIs and “Classes” model for the commonly supported classes APIs. The following figures shows the folders structure of the STM32 USB Host library.

STM32 USB Host Library Folders Architecture

6.2. USB Host Applications folders architecture within STM32Cube firmware

Within every STM32Cube firmware package, a dedicated folder for applications is offered including a list of all the middlewares that are supported by the selected STM32 board and, among others, the USB Host Applications will be found. These applications code can be run, debugged, and tested directly on the convenient STM32 by following the steps described in the readme.txt provided within every application’s folder. Generally, to guarantee more flexibility, every application is offered with the support of three IDEs. The following figure shows an example of USB Host applications supported by one STM32 board. For the Host, the applications can work with FreeRTOS. The applications number differs from one STM32 Board to another.

STM32 Host Applications Folder Architecture

7. Specific tools

Links and explanations for the tech domain dedicated tools

8. STMicroelectronics Resources

The place for AN, UM... direct links

9. Examples

The area where FAE's, collab... can put examples (linked to Github)




[[Category:]]