Introduction to USB with STM32

(Redirected from USB overview)

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

Contents

1 What is the Universal Serial Bus (USB)?

The large diversity of ports (such as parallel, serial, midi, joystick) 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 speak about these standard compliant devices and hosts.

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 (such as mouse, keyboard)
  • Full speed (FS): supports the transfer rate of 12 Mb/s. This speed is mainly dedicated to phone and audio devices (such as microphone, speaker)
  • High speed (HS): supports the transfer rate of 480 Mb/s. This speed is mainly dedicated to video and storage devices (such as printer, camera)

At protocol level, the USB grants a very high compatibility, so the users cannot 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 (such as keyboard, mouse, microphone)
  • 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).
The following figure provides an example of USB system components connection.

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 is disabled. If a hub is detached, all the downstream devices' ports that were attached to the removed hub are disabled and the detached hub's upstream port is disabled.
  • Bus enumeration: it is a set of hardware and software events allowing the host to continuously manage the process of events of the newly connected or disconnected devices. 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 vary. 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.
For more details about the STM32 USB device classes, please refer to The USB Device Classes section.
For more details about the STM32 USB Host classes, please refer to The USB Host Classes section.

1.7 USB data transfers

The 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 are explained with code examples in the following pages.

1.8 Data direction

As it is 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 is transferred from the host to the device
  • data in is the data that is transferred from the device into the host

1.9 Transactions

Each transfer independently from its type is based on one or more transaction(s) 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 (such as type, destination, data phase direction)
  • Data: this phase is optional. Its existence, direction and size are indicated within the token packet. During this phase, the source of data sends 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 sends 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 field 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's memory 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 a defined set of information about the device and will be sent 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 is 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:

  • IN Endpoint for data that will be transferred into the host.
  • OUT Endpoint for data that will be transferred from the host.

A device has always more than one endpoint pair 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 mainly ensured by hardware.
  • Powered: it is the second stage and is corresponding to a device that was attached to USB Host and just powered. This stage is mainly ensured by hardware.
  • Default: this stage is reached when the attached device is 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 its 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.

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).

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 has 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 the 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 STM32 STMicroelectronics webpage [1].

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 then run to check the functionality as described 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 can be found in USB Device Library Overview and USB Host Library Overview sections.

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

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 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[2].

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 in STM32Cube ecosystem webpage[3]. 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 STMicroelectronics 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 figure shows the folders structure of the STM32 USB device library.

STM32 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.

STM32 Device Applications Folders' Architecture

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 USB device core

This folder includes the files ensuring USB 2.0 standard code implementation for an USB device. 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): these files include the implementation of the control of the USB core state machine and the different events processing. The following table shows the main functions' description.
Function Description
USBD_Init Initializes the Device Handler and state machine
USBD_DeInit De-initializes the Device Handler
USBD_RegisterClass Links the device structure handler to the class structure 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_ctlreq (.c, .h): these files include variables and functions ensuring the processing of all requests of the chapter 9 in the USB 2.0 specification.
Function Description
USBD_StdDevReq Handles all the requests that are addressed to a USB device
USBD_StdItfReq Handles all the requests that are addressed to an interface
USBD_StdEPReq Handles all the requests that are addressed to an endpoint
USBD_GetDescriptor Handles the different types of Get Descriptor request
USBD_SetAddress Handles the Set Address request
USBD_GetConfig Handles the Get Configuration request
USBD_SetConfig Handles the Get Configuration request
USBD_GetStatus Handles the Get Status request
USBD_SetFeature Handles the Set Feature request
USBD_ClrFeature Handles the Clear Feature request
USBD_ParseSetupRequest Organizes the received data buffer into setup request structure
USBD_CtlError Handles USB low level Error
USBD_GetString Converts Ascii string into Unicode one
USBD_GetLen Returns the string length


  • usbd_ioreq (.c, .h): these files include the implementation of data sending and reception on the endpoint 0. The following table shows the main functions' description.
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 USB Device 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 Human Interface Devices (HID) Class

This class allows the implementation of Human Interface devices allowing the interaction between a human and a machine such as game controllers, mouses, keyboards. This class code is 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 is 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 Mass Storage Class (MSC)

This class allows the implementation of mass storage devices ensuring data storage and exchange via USB. This class code is 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 Communications Devices Class (CDC)

This class allows the implementation of virtual COM ports and modems. This class' code is 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 Ethernet Control Model (ECM) Subclass

This class code is 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 the 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 Remote Network Driver Interface Specification (RNDIS) Sublass

This class code is 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 the 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 (AC)

This class allows the implementation of audio devices such as headphones and microphones. This class' code is 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 is 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 Device Firmware Upgrade (DFU) Class

This class code is 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 the 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 endpoint, 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 handler structure

When a request is received from the host, it is 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 needs 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 needs 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.
} USBD_SetupReqTypedef;
5.3.3.2 USB device descriptor handler structure

To ease the different device descriptors processing, a dedicated structure is implemented to include all the common required descriptors. This structure 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); // pointer to the function that answers "Get Descriptor" request when the descriptor type is device descriptor.
uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); // pointer to the function that answers "Get Descriptor" request when the descriptor type (according to the wValue) is of string type and when the descriptor index designs the langId string desc.
uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); // pointer to the function that answers "Get String Descriptor" request when the descriptor's index designs the manufacturer string descriptor.
uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); // pointer to the function that answers "Get String Descriptor" request when the descriptor index designs the product  string descriptor.
uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); // pointer to the function that answers "Get String Descriptor" request when the descriptor index designs the serial  string desc.
uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);  // pointer to the function that answers "Get String Descriptor" request when the descriptor index designs the configuration string descriptor.
uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);  // pointer to the function that answers "Get String Descriptor" request when the descriptor index designs the interface  string descriptor.
uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);  // pointer to the function that answers "Get User String Descriptor" if supported.
uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); // pointer to the function that answers "Get Descriptor" request when the descriptor type is  BOS descriptor if supported.
}  USBD_DescriptorsTypeDef;
5.3.3.3 USB device handler structure

This structure includes the different USB device data and information. This structure can be filled according to the class requirements.

typedef struct _USBD_HandleTypeDef
{
uint8_t                 id; // Low level core index (FS or HS) and It is defined only for device software requirements.
uint32_t                dev_config; // The lower byte of the wValue field specifies the desired configuration. 
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]; // This field specifies the total endpoints in number depending on the device hardware. It can reach 16.
USBD_EndpointTypeDef    ep_out[15]; // This field specifies the total endpoints out number depending on the device hardware. It  can reach 16.
uint32_t                ep0_state; // This field specifies the endpoint 0 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; // This field specifies 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 is 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; // This field specifies the previous state of the device before switching to the current state.
uint8_t                 dev_address; // This field specifies the address that must be modified in USBD_SetAddress() when the Set Address command is received.
uint8_t                 dev_connection_status; // This field specifies the device connection status.
uint8_t                 dev_test_mode; // This field specifies the test mode. For the software when it is set to 1 it will run the test mode function 
uint32_t                dev_remote_wakeup; // This field specifies the remote wake up support status. 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 or when  USBD_ClrFeature() is called.
USBD_SetupReqTypedef    request; // This field specifies the 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 is 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 depends on the class. For more details about this structure, please refer to "USB Device descriptor handler structure" section.
USBD_ClassTypeDef       *pClass; // pointer to a structure that includes all the USB class parameters. USBD_RegisterClass() is used to fill the structure defined in usbd_def.h and the variable values are defined in the class files. For more details about this structure, 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; // it is a pointer to the low layer stack structure ( PCD_HandleTypeDef ) and initiated in the usbd_ll_init().
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 is implemented to include all the common required functions. This structure 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 de-initialization 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 handle 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 handle 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 (PCD) structure

To ease the different low layer peripheral data processing, a dedicated structure is implemented to include all the common required variables. This structure can be filled according to the peripheral hardware.

{
PCD_TypeDef             *Instance; // this field includes the register base address.               
PCD_InitTypeDef         Init; // structure including the Peripheral Controller Driver initialization required parameters.           
__IO uint8_t            USB_Address; // this field includes the USB assigned Address.                        
PCD_EPTypeDef           IN_ep[n]; // buffer of IN endpoint structures, n is the number of endpoints supported by the product up to 16.         
PCD_EPTypeDef           OUT_ep[n]; // buffer of OUT endpoint structures, n is the number of endpoints supported by the product up to 16.               
HAL_LockTypeDef         Lock; // HAL lock status (used for synchronization).              
__IO PCD_StateTypeDef   State; // Pereipheral Controller Driver (PCD) communication state that can be:\
* HAL_PCD_STATE_RESET when deinitializing the PCD.  \
* HAL_PCD_STATE_READY when initializing the PCD.   \
* HAL_PCD_STATE_ERROR when an error occurs during the device or the core initialization.   \
* HAL_PCD_STATE_BUSY for when dealing with some transient events.   \
* HAL_PCD_STATE_TIMEOUT when a timeout occurs \           
__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; // LPM active state:  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 Device 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 Device 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 and 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 include 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 library, Hardware abstraction layer and low layer:

  • main (.c, .h): includes the main functions and variables required for the application.
  • usb_device (.c, .h): exists only for the advanced applications architecture. It contains all the USB device initialization functions and variables. For the basic application architecture, the initialization is 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 interrupts IRQ handler.
  • usb_desc (.c, .h): includes the descriptors definitions and related functions. It depends on the selected class.
  • usbd_conf (.c, .h): includes 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 the user to start the USB device core.

For some classes where the USB needs to interface with other peripheral, USBD_CLASS_RegisterInterface(...) (where CLASS can be AUDIO or DFU or CDC or MSC) to add interface callbacks.
The following figure provides an overview about some functions that are 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 device application's 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 differs from one application to another. It includes one part that depends only on the class and the other part includes the configuration files that depend on the STM32 USB hardware peripheral.
  • 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" 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.
STM32 Device Library files organization.png

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 STMicroelectronics webpage[3]. 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 STMicroelectronics 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 figure 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 are 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, some applications are offered with FreeRTOS. The applications number differs from one STM32 board to another.

STM32 Host Applications Folder Architecture

6.3 STM32 USB Host library description

As mentioned previously, the STM32 USB Host library includes the Core and the Classes folders.

6.3.1 USB Host Core

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

  • usbh_core (.c, .h): these files include the implementation of the core state machine process and the enumeration and the control transfers processing. The following table shows the main functions' description.
Function Description
USBH_Init Initializes the Host Handler and state machine
USBH_DeInit De-initializes the Host state machine and restores the default state
DeInitStateMachine De-initializes the host state machine
USBH_RegisterClass Links the host structure handler to the class structure handler
USBH_SelectInterface Switches the interface to the selected one
USBH_GetActiveClass Returns the current selected class
USBH_FindInterface Returns the interface index for a specific class
USBH_FindInterfaceIndex Returns the interface index for a specific class interface and alternate setting number
USBH_Start Starts the USB low level driver and activates VBUS on the port
USBH_Stop Deactivates VBUS on the port, stops and cleans the low level driver and frees control pipes
USBH_ReEnumerate Performs a new enumeration phase
USBH_Process Performs the processing of the USB core depending on the Host and device state
USBH_HandleEnum Performs all the enumeration phase steps
USBH_LL_SetTimer Performs all the enumeration phase steps
USBH_LL_IncTimer Increments Host Timer tick
USBH_HandleSof Handles the Start Of Frame process
USBH_LL_PortEnabled Enables the device port
USBH_LL_PortDisabled disables the device port
USBH_IsPortEnabled Checks whether the port is enabled or not
USBH_LL_Connect Handles the connection of a device event
USBH_LL_Disconnect Handles the disconnection of a device event
USBH_Process_OS USB Host Thread task process if the FreeRTOS is used
USBH_LL_NotifyURBChange Notify that URB state Changed


  • usbh_ctlreq(.c, .h): these files include the implementation of the processing of the control requests required for the device enumeration. The following table shows the main functions' description.
Function Description
USBH_Get_DevDesc Sends the Get Device Descriptor command to the connected device. If the command is successfully sent and the response received, it parses the Descriptor and updates the status accordingly
USBH_Get_CfgDesc Sends the Get Configuration Descriptor command to the connected device. If the command is successfully sent and the response received, it parses the Descriptor and updates the status accordingly
USBH_Get_StringDesc Sends the Get String Descriptor command to the connected device. If the command is successfully sent and the response received, it parses the Descriptor and updates the status accordingly
USBH_GetDescriptor Sends the Get Descriptor command to the connected device. If the command is successfully sent and the response received, it parses the Descriptor and updates the status accordingly
USBH_SetAddress Prepares the Set Address command's parameters and issues it to the connected device
USBH_SetCfg Prepares the Set Configuration command's parameters and issues it to the connected device
USBH_SetInterface Prepares the Set Interface command's parameters and issues it to the connected device
USBH_SetFeature Prepares the Set Feature command's parameters and issues it to the connected device
USBH_ClrFeature Prepares the Clear Feature command's parameters and issues it to the connected device.
USBH_ParseDevDesc Ensures the parsing of a device descriptor's parameters
USBH_ParseCfgDesc Ensures the parsing of a configuration descriptor's parameters
USBH_ParseInterfaceDesc Ensures the parsing of an interface descriptor's parameters
USBH_ParseEPDesc Ensures the parsing of an endpoint descriptor's parameters
USBH_ParseStringDesc Ensures the parsing of a string descriptor's parameters
USBH_GetNextDesc Finds and returns the next descriptor header
USBH_CtlReq sends a control request and provide the status after completion of the request transaction
USBH_HandleControl Handles the USB control transfer state machine


  • usbh_ioreq(.c, .h): These files include the implementation of different USB transactions process. The following table shows the main functions' description.
Function Description
USBH_CtlSendSetup Sends Setup Packet to the connected device
USBH_CtlSendData Sends Data Packet to the connected device
USBH_CtlReceiveData Receives the Setup Packet's response from the connected device
USBH_BulkSendData Sends OUT Bulk Packet to the connected device
USBH_BulkReceiveData Receives IN Bulk Packet from the connected device
USBH_InterruptReceiveData Receives an Interrupt IN token's response from the connected device
USBH_InterruptSendData Sends the data to the device on an Interrupt OUT Endpoint
USBH_IsocReceiveData Receives an Isochronous IN token's answer from the device
USBH_IsocSendData Sends the data to the device on Isochronous OUT Endpoint


  • usbh_pipes(.c, .h): these files include the implementation of Pipes process ( opening, closing, allocating... etc).
Function Description
USBH_OpenPipe Opens a pipe
USBH_ClosePipe Closes a pipe
USBH_AllocPipe Allocates a new Pipe
USBH_FreePipe Frees the USB Pipe
USBH_GetFreePipe Gets a free Pipe number for allocation to a device endpoint


  • usbh_conf_template (.c, .h): these files are templates for interfacing between the low level and the application level. It depends highly on the application and must be customized before being added to any application's file.
  • usbh_def (.c, .h): includes all common USB host constants and structures definitions.

6.3.2 USB Host Classes

This folder includes the files including different USB host 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.

6.3.2.1 Human Interface Devices (HID) Class

This class code is implemented to access and communicate with mouses and keyboards but can be easily customized to access other Human Interface Devices. This class folder includes:

  • usbh_hid (.c, .h): these files include the common the HID class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBH_HID_InterfaceInit Finds and selects an interface, allocates memory for HID Handle and initiates it by decoding the device nature to know if it is a keyboard or a mouse and initiating endpoints and pipes
USBH_HID_InterfaceDeInit De-initializes the HID class’ interface by closing and resetting all the pipes and un-linking the class
USBH_HID_ClassRequest Handles the different HID standard requests
USBH_HID_Process Handles the state machine for HID data transfers
USBH_HID_SOFProcess Manages Start Of Frame process
USBH_HID_GetHIDReportDescriptor Sends the Get HID Report Descriptor command to the connected device. If the command is successfully sent and the response received, it parses the Report Descriptor and updates the status accordingly
USBH_HID_SetIdle Sends Set Idle control request and provides the status after completion of the request
USBH_HID_SetReport Sends Set Report control request and provides the status after completion of the request
USBH_HID_GetReport Sends Get Report control request and provides the status after completion of the request
USBH_HID_SetProtocol Sends Set Report control request and provides the status after completion of the request
USBH_HID_ParseHIDDesc Ensures the parsing of a HID descriptor's parameters
USBH_HID_GetDeviceType Finds and returns the device function whether a mouse or keyboard
USBH_HID_GetPollInterval Gets HID polling period
USBH_HID_FifoInit Initializes the FIFO
USBH_HID_FifoRead Reads data from FIFO
USBH_HID_EventCallback Callback about HID Data events that should be overloaded within application files


  • usbh_hid_keybd(.c, .h): these files include all the HID keyboard’s variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBH_HID_KeybdInit Initializes the HID keyboard
USBH_HID_GetKeybdInfo Allows to get the Keyboard's information
USBH_HID_KeybdDecode Decodes the keyboard's data from the FIFO
USBH_HID_GetASCIICode Decodes the keyboard key data and converts it into ASCII code


  • usbh_hid_mouse(.c, .h): these files include all the HID mouse’s variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBH_HID_MouseInit Initializes the HID mouse
USBH_HID_GetMouseInfo Allows to get the mouse's information
USBH_HID_MouseDecode Decodes the mouse's data from the FIFO


  • usbh_hid_parser(.c, .h): these files include the USB Host HID reports parser implementation. The following table shows the main functions.
Function Description
HID_ReadItem Allows to read a HID report item
HID_WriteItem Allows to write a HID report item


  • usbh_hid_usage.h: this file includes the USB Host HID defines.
6.3.2.2 Mass Storage Class (MSC)

This class code is implemented to access and communicate with USB Mass Storage devices based on the “Bulk-Only Transport” (BOT) protocol and the SCSI command set. This class folder includes:

  • usbh_msc (.c, .h): these files include the common MSC class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBH_MSC_InterfaceInit Finds and selects an interface, allocates memory for MSC Handle and initiates it by initiating the endpoints and pipes
USBH_MSC_InterfaceDeInit De-initializes the MSC class’ interface by closing and resetting all the pipes and un-linking the class
USBH_MSC_ClassRequest Handles the different MSC standard requests
USBH_MSC_Process Handles the state machine for MSC data transfers
USBH_MSC_SOFProcess Manages Start Of Frame process
USBH_MSC_RdWrProcess Ensures the MSC class' reading and writing process
USBH_MSC_IsReady Checks if the MSC function is ready
USBH_MSC_GetMaxLUN Allows to get the max Logical Unit Number supported
USBH_MSC_UnitIsReady Checks whether a Logical Unit Number is ready
USBH_MSC_GetLUNInfo Allows to get a Logical Unit Number information
USBH_MSC_Read Performs a Read operation to the connected device
USBH_MSC_Write Performs a Read operation to the connected device


  • usbh_msc_bot(.c, .h): these files include the USB “Bulk-Only Transport” BOT protocol implementation. The following table shows the main functions.
Function Description
USBH_MSC_BOT_REQ_Reset Sends MSC BOT Reset control request and provides the status after completion of the request
USBH_MSC_BOT_REQ_GetMaxLUN Sends MSC BOT Get Max LUN control request and provides the status after completion of the request
USBH_MSC_BOT_Init Initializes the BOT protocol
USBH_MSC_BOT_Process Ensures the different BOT states process
USBH_MSC_BOT_Abort Handles the BOT Abort process
USBH_MSC_DecodeCSW decodes the "Command Status Wrapper" (CSW) sent to the device and updates the upper layer accordingly.


For more details about the Universal Serial Bus Mass Storage Class Bulk-Only Transport, please refer to the specification[4].

  • usbh_msc_scsi(.c, .h): these files include the SCSI commands implementation. The following table shows the main functions.
Function Description
USBH_MSC_SCSI_TestUnitReady Sends the SCSI's Test Unit Ready command
USBH_MSC_SCSI_ReadCapacity Sends the SCSI's Read Capacity command
USBH_MSC_SCSI_Inquiry Sends the SCSI's Inquiry command
USBH_MSC_SCSI_RequestSense Sends the SCSI's Request Sense command
USBH_MSC_SCSI_Write Sends the SCSI's write10 command
USBH_MSC_SCSI_Read Sends the SCSI's Read10 command


For more details about the different commands, please refer to the USB.org document[5].

6.3.2.3 Communications Devices Class (CDC)

This class code is implemented to access and communicate with the CDC virtual comport devices that are compliant with the Abstract Control Model (ACM) subclass. This class folder includes:

  • usbh_cdc(.c, .h): these files include the common CDC class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBH_CDC_InterfaceInit Finds and selects an interface, allocates memory for CDC Handle and initiates it by initiating the endpoints and pipes
USBH_CDC_InterfaceDeInit De-initializes the CDC class’ interface by closing and resetting all the pipes and un-linking the class
USBH_CDC_ClassRequest Handles the different CDC standard requests
USBH_CDC_Process Handles the state machine for CDC data transfers
USBH_CDC_SOFProcess Manages Start Of Frame process
USBH_CDC_Stop Stops current CDC Transmission by closing the pipes
GetLineCoding Allows the host to find out the currently configured line coding by sending the Get Line Coding control request
SetLineCoding Allows the host to specify typical asynchronous line-character formatting properties by sending the Set Line Coding request
USBH_CDC_SetLineCoding Prepares the state before sending the class specific commands to the connected device
USBH_CDC_GetLineCoding prepares the state before sending the class specific commands to the connected device
USBH_CDC_GetLastReceivedDataSize Allows to find the last received data size
USBH_CDC_Transmit Prepares the state and the data buffers to send data to the device
USBH_CDC_Receive Prepares the state and the data buffers to receive data from the device
CDC_ProcessTransmission Ensures the data sending to the device
CDC_ProcessReception Ensures the data reception from the device
USBH_CDC_TransmitCallback Callback indicating data transmit complete. It should be overloaded within application files if required
USBH_CDC_ReceiveCallback Callback indicating data reception complete. It should be overloaded within application files if required
USBH_CDC_LineCodingChanged Callback indicating setting modification. It should be overloaded within application files if required


6.3.2.4 AUDIO Class (AC)

This class code is implemented to access and communicate with the USB speaker device that is compliant with the USB Audio class 1.0 specification. This class folder includes:

  • usbh_audio (.c, .h): these files include the common CDC class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBH_AUDIO_InterfaceInit Finds and selects the convenient interface interface with largest endpoint size, allocates memory for AUDIO Handle and initiates it by initiating the endpoints and pipes
USBH_AUDIO_InterfaceDeInit De-initializes the AUDIO class’ interface by closing and resetting all the pipes and un-linking the class
USBH_AUDIO_ClassRequest Handles the different AUDIO standard requests
USBH_AUDIO_CSRequest Handles the different AUDIO specific requests for only one specified feature and channel
USBH_AUDIO_HandleCSRequest Handles the different AUDIO specific requests for all features and channels
USBH_AUDIO_Process Handles the state machine for AUDIO data transfers
USBH_AUDIO_SOFProcess Manages Start Of Frame process
USBH_AUDIO_FindAudioStreamingIN Allows to find IN Audio Streaming interfaces
USBH_AUDIO_FindAudioStreamingOUT Allows to find OUT Audio Streaming interfaces
USBH_AUDIO_FindHIDControl Allows to find Human Interface Device control interfaces
USBH_AUDIO_ParseCSDescriptors Allows to parse the class and class specific interfaces descriptors
ParseCSDescriptors Allows to parse a specific interface descriptors
USBH_AUDIO_FindLinkedUnit Finds and Links a Unit to next associated one
USBH_AUDIO_BuildMicrophonePath Builds full path for Microphone device
USBH_AUDIO_BuildHeadphonePath Builds full path for Headphone device
USBH_AC_SetCur Sends "Set Cur" control request to modify the current setting attribute and provides the status after completion of the request
USBH_AC_GetCur Sends "Get Cur" control request to get current setting attribute and provides the status after completion of the request
USBH_AC_GetMax Sends "Get Max" control request to get the mximum setting attribute and provides the status after completion of the request
USBH_AC_GetRes Sends "Get Res" control request to get the resolution setting attribute and provides the status after completion of the request
USBH_AC_GetMin Sends "Get Min" control request to get the minimum setting attribute and provides the status after completion of the request
USBH_AUDIO_SetEndpointControls Sends "Set Endpoint Controls" control request and provides the status after completion of the request
USBH_AUDIO_InputStream Manages the input stream process
USBH_AUDIO_Control Manages HID Control process
USBH_AUDIO_OutputStream Manages Output stream process
USBH_AUDIO_Transmit Manages Transmission process
USBH_AUDIO_SetFrequency Sets Audio sampling parameters
USBH_AUDIO_Play Starts playback process
USBH_AUDIO_Stop Stops the playback process
USBH_AUDIO_Suspend Suspends the playback process
USBH_AUDIO_Resume Resumes the playback process
USBH_AUDIO_GetOutOffset Allows to get the current buffer pointer for OUT process
USBH_AUDIO_ChangeOutBuffer Allows to change audio data buffer address
USBH_AUDIO_SetControlAttribute Allows to set Control Attribute
USBH_AUDIO_SetVolume Allows to increase or decrease the volume
AUDIO_SetVolume Sets a new volume value by sending control request to the device
USBH_AUDIO_FrequencySet Callback allowing to inform the user that the frequency is set. It must be overloaded within application files if required.
USBH_AUDIO_BufferEmptyCallback Callback allowing to inform the user that the user data are processed. It must be overloaded within application files if required.


For more details about this class requirements please refer to the specification [6].

6.3.2.5 Multimedia Transfer Protocol (MTP) Class

This class code is implemented to access the multimedia mobile devices (smartphone, camera, audio player...) that are compliant with the Media Transfer Protocol v.1.1 Specification. This class protocol is based on Picture Transfer Protocol (PTP) that is defined in ISO 15740 specification. This class folder includes:

  • usbh_mtp(.c, .h): these files include the common MTP class’ variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBH_MTP_InterfaceInit Finds and selects the convenient interface interface with largest endpoint size, allocates memory for MTP Handle and initiates it by initiating the endpoints and pipes
USBH_MTP_InterfaceDeInit De-initializes the MTP class’ interface by closing and resetting all the pipes and un-linking the class
MTP_FindCtlEndpoint Finds MTP control endpoint
MTP_FindDataOutEndpoint Finds Data Out Endpoint
MTP_FindDataInEndpoint Finds Data In Endpoint
USBH_MTP_ClassRequest Handles the MTP class standard requests
USBH_MTP_Process Manages state machine for MTP data transfers
USBH_MTP_SOFProcess Manages Start Of Frame process
USBH_MTP_IsReady Checks if the MSC function is ready
USBH_MTP_GetNumStorage Allows to find storage number
USBH_MTP_SelectStorage Allows to select one storage unit
USBH_MTP_GetStorageInfo Allows to get the storage Unit information
USBH_MTP_GetNumObjects Allows to get the objects number
USBH_MTP_GetObjectHandles Allows to get one object handle
USBH_MTP_GetObjectInfo Allows to get one object information
USBH_MTP_DeleteObject Allows to delete one object
USBH_MTP_GetObject Allows to get one object
USBH_MTP_GetPartialObject Allows to get one object partially
USBH_MTP_GetObjectPropsSupported Allows to get object supported properties
USBH_MTP_GetObjectPropDesc Allows to get object description
USBH_MTP_GetObjectPropList Allows to get object properties list
USBH_MTP_SendObject Allows to send an object
USBH_MTP_Events Allows to handle MTP events
MTP_DecodeEvent Decode device event sent by responder
USBH_MTP_GetDevicePropDesc Allows to get device properties description
USBH_MTP_EventsCallback Callback to inform the user that an MTP event occured. It must be overloaded within application files if required.


  • usbh_mtp_ptp(.c, .h): these files include the common PTP protocol’s variables and specific APIs implementation. The following table shows the main functions.
Function Description
USBH_PTP_Init Initializes the PTP protocol
USBH_PTP_Process Allows to handle the PTP state machine
USBH_PTP_SendRequest Allows to send a PTP request to the connected device
USBH_PTP_GetResponse Allows to parse and decode a received response parameters
PTP_BufferFullCallback Callback to inform the user that the data buffer is full
PTP_DecodeDeviceInfo Allows to parse and decode a received Device information parameters
PTP_GetStorageIDs Manages state machine for MTP data transfers
PTP_GetStorageIDs Gets Storage Ids
PTP_GetStorageInfo Gets Storage Information and decodes its different parameters
PTP_GetObjectInfo Gets Object Information and decodes its different parameters
PTP_GetObjectPropDesc Gets Object properties description
PTP_GetDevicePropValue Gets Device property value
PTP_GetObjectPropList Gets Object properties list
PTP_GetString Gets a String
PTP_GetArray16 Allows to get an array of 16-bit data
PTP_GetArray32 Allows to get an array of 32-bit data
USBH_PTP_OpenSession Allows to send "Open Session" request
USBH_PTP_GetDevicePropDesc Allows to send "Get Device Properties Description" request
USBH_PTP_GetDeviceInfo Allows to send "Get Device Information" request
USBH_PTP_GetStorageIds Allows to send "Get Storage Ids" request
USBH_PTP_GetStorageInfo Allows to send "Get Storage Information" request
USBH_PTP_GetNumObjects Allows to send "Get Number of Objects" request
USBH_PTP_GetObjectHandles Allows to send "Get Object Handles" request
USBH_PTP_GetObjectInfo Allows to send "Get Object Information" request
USBH_PTP_DeleteObject Allows to send "Delete Object" request
USBH_PTP_GetObject Allows to send "Get Object" request
USBH_PTP_GetPartialObject Allows to send "Get Partial Object" request
USBH_PTP_GetObjectPropsSupported Allows to send "Get Object Props Supported" request
USBH_PTP_GetObjectPropDesc Allows to send "Get Object Prop Desc" request
USBH_PTP_GetObjectPropList Allows to send "Get Object Properties List" request
USBH_PTP_SendObject Allows to send "Send Object" request


6.3.2.6 Template

This folder provides the ability to implement a custom class respecting the STM32 USB Host class’ architecture. It includes the usbh_template (.c & .h) files to define the different required class’ variables and PIs, implement the class’ handlers initialization and de-initialization, handle the class’ specific requests, data exchange with the device on the different endpoints… etc.

6.3.3 STM32 USB Host library main variables

The STM32 USB Host library offers common structures to manage the different USB device data. These structures can be filled according to the class and application requirements.

6.3.3.1 Setup request handler structure

Before being sent to the device, a setup request's parameters is organized in a USB_Setup_TypeDef structure to ease its reception and decoding by the device.

typedef union _USB_Setup
{
uint32_t d8[2]; // allows to see this packet structure as two-words buffer if required

struct _SetupPkt_Struc
{
uint8_t           bmRequestType; // 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_uint8_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_uint8_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_uint8_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.
} b;
}USB_Setup_TypeDef;
6.3.3.2 Descriptor header handler structure

To ease the descriptors manipulation, a dedicated structure is implemented to include just the header of the descriptor.

typedef  struct  _DescHeader
{
uint8_t  bLength; // this field includes the length of the descriptor
uint8_t  bDescriptorType; // this field includes the descriptor type that can take one of the following defined values depending on the class: \
*  USB_DESC_TYPE_DEVICE \
*  USB_DESC_TYPE_CONFIGURATION \
*  USB_DESC_TYPE_STRING \
*  USB_DESC_TYPE_INTERFACE \
*  USB_DESC_TYPE_ENDPOINT \
*  USB_DESC_TYPE_DEVICE_QUALIFIER \
*  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION \
*  USB_DESC_TYPE_INTERFACE_POWER \
*  USB_DESC_TYPE_HID \
*  USB_DESC_TYPE_HID_REPORT
} USBH_DescHeader_t;
6.3.3.3 USB device descriptor handler structure

To ease the device descriptors processing and exchange with the device, a dedicated structure is implemented to include all the common required Standard Device descriptor's parameters according to the USB 2.0 specification. This structure can be filled according to the connected device functionality.

typedef struct _DeviceDescriptor
{
uint8_t   bLength; // this field includes the length of the descriptor
uint8_t   bDescriptorType; // this field includes the descriptor type that can take one of the following defined values depending on the class:
*  USB_DESC_TYPE_DEVICE \
*  USB_DESC_TYPE_CONFIGURATION \
*  USB_DESC_TYPE_STRING \
*  USB_DESC_TYPE_INTERFACE \
*  USB_DESC_TYPE_ENDPOINT \
*   USB_DESC_TYPE_DEVICE_QUALIFIER \
*  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION \
*  USB_DESC_TYPE_INTERFACE_POWER \
*  USB_DESC_TYPE_HID \
*  USB_DESC_TYPE_HID_REPORT 
uint16_t  bcdUSB; // includes the USB Specification Number which device complies to, for version 2.0 this field includes the value of 0x0200.
uint8_t   bDeviceClass; // includes the connected device class code that is defined by the USB-IF
uint8_t   bDeviceSubClass; // includes the connected device subclass code that is defined by the USB-IF. 
uint8_t   bDeviceProtocol; // includes the protocol code that is defined by the USB-IF and that depends on the class and subclass code. This code identifies the protocols that the device uses according the the device's class specification. 
uint8_t   bMaxPacketSize; // includes the maximum packet size for endpoint zero that can be 8 or 16 or 32 or 64. 
uint16_t  idVendor; // includes the Vendor ID that is assigned by the USB-IF 
uint16_t  idProduct; // includes the Product ID that is assigned by Manufacturer ( STMicroelectronics ) 
uint16_t  bcdDevice; // includes the Device Release Number,  for version 2.0 this field includes the value of 0x0200 
uint8_t   iManufacturer; // includes the Index of Manufacturer String Descriptor  
uint8_t   iProduct; //  includes the Index of Product String Descriptor  
uint8_t   iSerialNumber; // includes the Index of Serial Number String Descriptor 
uint8_t   bNumConfigurations; //  includes the Number of Possible Configurations 
} USBH_DevDescTypeDef;
6.3.3.4 Endpoint Descriptor handler structure

To ease the different Endpoints Descriptors processing and exchange with the device , a dedicated structure is implemented to include all the common required Standard Endpoint Descriptor's parameters according to the USB 2.0 specification. This structure can be filled according to the connected device functionality.

typedef struct _EndpointDescriptor
{
uint8_t   bLength; // this field includes the length of the descriptor. 
uint8_t   bDescriptorType; // this field includes the descriptor type.
uint8_t   bEndpointAddress; // includes what endpoint address this descriptor is describing. Every endpoint is characterized by a number and direction (IN or OUT).
uint8_t   bmAttributes; // includes the transfer type. 
uint16_t  wMaxPacketSize; // includes the Maximum Packet Size this endpoint is capable of sending or receiving.
uint8_t   bInterval; // includes the polling interval of certain transfers.
} USBH_EpDescTypeDef;
6.3.3.5 Interface Descriptor handler structure

To ease the different Interfaces Descriptors processing and exchange with the device, a dedicated structure is implemented to include all the common required Standard Interface Descriptor's parameters according to the USB 2.0 specification. This structure can be filled according to the connected device functionality.

typedef struct _InterfaceDescriptor
{
uint8_t bLength; // this field includes the length of the descriptor. 
uint8_t bDescriptorType; // this field includes the descriptor type.  
uint8_t bInterfaceNumber; // includes Number of the interface described by this descriptor. It identifies the index in the array of concurrent interfaces supported by this configuration. 
uint8_t bAlternateSetting; // includes the value that is used to select alternative setting  
uint8_t bNumEndpoints; // includes the Number of Endpoints used for this interface   
uint8_t bInterfaceClass; // includes the Class Code that is assigned by USB-IF 
uint8_t bInterfaceSubClass; // includes the Subclass Code that is assigned by USB-IF
uint8_t bInterfaceProtocol; // includes the  Protocol Code 
uint8_t iInterface; // includes the Index of String Descriptor Describing this interface  
USBH_EpDescTypeDef   Ep_Desc[USBH_MAX_NUM_ENDPOINTS]; // It is a table of Endpoints descriptors that are used for this interface.            
} USBH_InterfaceDescTypeDef;
6.3.3.6 Configuration descriptor handler structure

To ease the different configuration descriptors processing and exchange with the device, a dedicated structure is implemented to include all the common required Standard Configuration Descriptor's parameters according to the USB 2.0 specification. This structure can be filled according to the connected device functionality.

typedef struct _ConfigurationDescriptor
{
uint8_t   bLength; // this field includes the length of the descriptor. 
uint8_t   bDescriptorType; // this field includes the descriptor type.  
uint16_t  wTotalLength; // contains the Total Length of Returned Data  
uint8_t   bNumInterfaces; // contains the Number of Interfaces supported by this configuration  
uint8_t   bConfigurationValue; // contains the Value to use as an argument to select this configuration  
uint8_t   iConfiguration; // contains the Index of String Descriptor Describing this configuration    
uint8_t   bmAttributes; // Contains information about power source (Bus Powered or Self Powered) and Remote wakeup support by the device.  
uint8_t   bMaxPower; // includes the value of Maximum Power Consumption  
USBH_InterfaceDescTypeDef        Itf_Desc[USBH_MAX_NUM_INTERFACES]; // It is a table of Interfaces descriptors that are used for this configuration.
} USBH_CfgDescTypeDef;
6.3.3.7 Control request handler structure

To ease the control transfers processing and exchange with the attached device a dedicated structure is implemented.

typedef struct
{
uint8_t               pipe_in; // includes the pipe IN number  
uint8_t               pipe_out; // includes the pipe OUT number 
uint8_t               pipe_size; // includes the pipe size 
uint8_t               *buff; // includes pointer to the data buffer  
uint16_t              length; //  includes the request data length
uint16_t              timer; //  includes the polling interval value 
USB_Setup_TypeDef     setup; // includes the Setup request structure 
CTRL_StateTypeDef     state; // includes the control request state the can be one of the following defined values: \
*   CTRL_IDLE \
*   CTRL_SETUP \
*   CTRL_SETUP_WAIT \
*   CTRL_DATA_IN \
*   CTRL_DATA_IN_WAIT \
*   CTRL_DATA_OUT \
*   CTRL_DATA_OUT_WAIT \
*   CTRL_STATUS_IN \
*   CTRL_STATUS_IN_WAIT \
*   CTRL_STATUS_OUT \
*   CTRL_STATUS_OUT_WAIT \
*   CTRL_ERROR \
*   CTRL_STALLED \
*   CTRL_COMPLETE
uint8_t               errorcount; // includes the errors counter 
} USBH_CtrlTypeDef;
6.3.3.8 USB connected device handler structure

To ease the data process and the control of the connected device, a dedicated Device handler structure is implemented to include all the device's information and data.

typedef struct
{
uint8_t                           CfgDesc_Raw[USBH_MAX_SIZE_CONFIGURATION]; // it is the Configuration Descriptor raw data buffer. 
uint8_t                           Data[USBH_MAX_DATA_BUFFER]; //  it is the Descriptor raw data buffer.  
uint8_t                           address; // It includes the device address value. 
uint8_t                           speed; // It includes the device speed. 
uint8_t                           EnumCnt; // includes the enumeration number counter.  
uint8_t                           RstCnt; // includes the reset number counter.      
__IO uint8_t                      is_connected; // includes information about the device connection state. 
__IO uint8_t                      is_disconnected; // includes information about the device disconnection state.   
__IO uint8_t                      is_ReEnumerated; // includes information about the device re-enumeration state.  
uint8_t                           PortEnabled; // includes information about the port whether it is enabled.   
uint8_t                           current_interface; //  includes the current interface number.     
USBH_DevDescTypeDef               DevDesc; // includes the Device Descriptor handler structure.   
USBH_CfgDescTypeDef               CfgDesc; // includes the Configuration Descriptor handler structure.    
} USBH_DeviceTypeDef;
6.3.3.9 USB Host Class handler structure

To ease the Classes processing and data exchange with the device, a dedicated structure is implemented to include all the common required parameters and functions. This structure can be filled according to the connected device functionality.

typedef struct
{
const char          *Name; // the class name.     
uint8_t              ClassCode; //  the class code.
USBH_StatusTypeDef(*Init)(struct _USBH_HandleTypeDef *phost); //  pointer to the function allowing the initialization of the class. 
USBH_StatusTypeDef(*DeInit)(struct _USBH_HandleTypeDef *phost); //  pointer to the function allowing the de-initialization of the class.
USBH_StatusTypeDef(*Requests)(struct _USBH_HandleTypeDef *phost); //  pointer to the function allowing the process of the class' standard requests.  
USBH_StatusTypeDef(*BgndProcess)(struct _USBH_HandleTypeDef *phost); //  pointer to the function ensuring the Class' state machine process. 
USBH_StatusTypeDef(*SOFProcess)(struct _USBH_HandleTypeDef *phost); //  pointer to the function allowing the Start Of Frame process.    
void                *pData; //  pointer to the class data.
} USBH_ClassTypeDef

For more details about every class' functions, please refer to the Classes section.

6.3.3.10 USB Host Class handler structure

To ease the Host data processing and exchange with the connected device, a dedicated structure is implemented to include all the common required parameters and information. This structure can be filled according to the connected device functionality.

typedef struct _USBH_HandleTypeDef
{
__IO HOST_StateTypeDef     gState; // Host State Machine Value that can be one of the following defined values: \
 *  HOST_IDLE \
 *  HOST_DEV_WAIT_FOR_ATTACHMENT \
 *  HOST_DEV_ATTACHED \
 *  HOST_DEV_DISCONNECTED \
 *  HOST_DETECT_DEVICE_SPEED \
 *  HOST_ENUMERATION \
 *  HOST_CLASS_REQUEST \
 *  HOST_INPUT \
 *  HOST_SET_CONFIGURATION \
 *  HOST_SET_WAKEUP_FEATURE \
 *  HOST_CHECK_CLASS \
 *  HOST_CLASS \
 *  HOST_SUSPENDED \
 *  HOST_ABORT_STATE
ENUM_StateTypeDef     EnumState; // Enumeration State Machine Value that can be one of the following defined values:      \
 *  ENUM_IDLE  \
 *  ENUM_GET_FULL_DEV_DESC \
 *  ENUM_SET_ADDR \
 *  ENUM_GET_CFG_DESC \
 *  ENUM_GET_FULL_CFG_DESC \
 *  ENUM_GET_MFC_STRING_DESC \
 *  ENUM_GET_PRODUCT_STRING_DESC \
 *  ENUM_GET_SERIALNUM_STRING_DESC 
CMD_StateTypeDef      RequestState; // Request State Machine Value that can be one of the following defined values: \
 *  CMD_IDLE  \
 *  CMD_SEND \
*  CMD_WAIT 
USBH_CtrlTypeDef      Control; // control request handler structure.          
USBH_DeviceTypeDef    device; // connected device handler structure.       
USBH_ClassTypeDef    *pClass[USBH_MAX_NUM_SUPPORTED_CLASS]; // table of all the supported classes structures. 
USBH_ClassTypeDef    *pActiveClass; // currently active class handler structure.   
uint32_t              ClassNumber; // the class number.       
uint32_t              Pipes[16]; // USBH supported pipes table.    
__IO uint32_t         Timer; // Timer counter.         
uint32_t              Timeout; // Timeout value.         
uint8_t               id; // driver ID        
void                 *pData; // low layer handler structure.     
void (* pUser)(struct _USBH_HandleTypeDef *pHandle, uint8_t id); // pointer to the user process function.       
#if (USBH_USE_OS == 1U)         
#if osCMSIS < 0x20000       
osMessageQId          os_event;              
osThreadId            thread;     
#else          
osMessageQueueId_t    os_event;        
osThreadId_t          thread;
#endif
uint32_t              os_msg;
#endif  // FreeRTOS event and thread and message that will be used in case the application will be implemented with FreeRTOS.   
} USBH_HandleTypeDef;

6.4 STM32 USB Host Hardware Abstraction Layer

Unlike the USB Host 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_hcd (.c, .h): XX refers to the STM32 device series that can be f4, f7, h7, L4, …etc. These files include some common callbacks process besides a set of variables and functions allowing to manage the peripheral controller driver initialization and deinitialization and Host channels and data exchange control.

6.5 STM32 USB Host 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 Host library and 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, l4, …etc These files includes different variables and functions ensuring the access to the USB peripheral hardware registers.

6.6 USB Host application implementation

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

  • main (.c, .h): includes the main functions and variables required for the application.
  • usb_host (.c, .h): exists only for the advanced applications architecture. It contains all the USB Host initialization functions and variables. For the basic application architecture, the initialization is done in main(.c, .h).
  • stm32XXxx_it (.c, .h): XX refers to the STM32 device that can be f4, f7, h7, l4...etc. It includes the USB and other system interrupts IRQ handlers.
  • usbh_conf (.c, .h): includes 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_host.c, the initialization of the USB Host is ensured mainly through three main functions that are:

  • USBH_Init(): initializes the host library and loads the class driver.
  • USBH_RegisterClass(): links the class driver to the host core.
  • USBH_Start(): allows the user to start the USB host core.

Unlike the device, for the Host, the user has to call a function called USBH_Process() in a blocking mode to ensure the background process of the USB Core.
The following figure provides an overview about some functions that are called to ensure the initialization. For more details about all the functions calls and different variables assignment, please refer to an STM32 USB Host application.

USB Host initialization main functions

6.7 STM32 USB Host components organization

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

  • The application level includes the files that are related to the desired functionality of the connected USB device and differs from one application to another. It includes one part that depends only on the class and the other part includes the configuration files that depend on the STM32 USB hardware peripheral.
  • The STM32 USB Host Library contains the "Core" including the APIs that are common for all the STM32 USB classes and applications and the "Classes" including all the APIs related to all the USB Host 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.
STM32 Host Library components organization

7 References