On this article, you find application examples, document references, tips and tricks and so on related to STM32 USB
1. What is the Universal Serial Bus (USB)?
The large diversity of ports (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.
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:
For more complex USB system, the device can be attached to the host through one or more hub(s).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
7. References
- ↑ STM32 STMicroelectronics webpage
- ↑ ST-MCU-FINDER
- ↑ 3.0 3.1 STM32Cube ecosystem webpage
- ↑ Universal Serial Bus Mass Storage Class Bulk-Only Transport specification
- ↑ Universal Serial Bus Mass Storage Specification for Bootability document
- ↑ Universal Serial Bus Device Class Definition for Audio Devices specification