on 2024-10-23 06:16 AM
The article provides a comprehensive guide on selecting suitable endpoints for USB applications using STM32 microcontrollers. This involves understanding the types of data transfers required by the application and determining suitable endpoints. The article aims to assist in choosing the appropriate STM32 MCU and determining the necessary endpoints.
USB endpoints are virtual communication channels between the host and the device. There are four primary types of endpoints.
Used for configuration, command, and status operations. Every USB device must have at least one control endpoint (endpoint 0).
Used for large, non-time-critical data transfers. Commonly used for data that can tolerate delays, such as file transfers.
Used for small, time-sensitive data transfers. Ideal for devices that need to send small amounts of data at regular intervals, like keyboards and mice.
Used for time-sensitive data transfers that require consistent data flow, such as audio and video streaming.
To determine the number of endpoints required for your application, consider the following general guidelines based on the types of data transfers your application needs:
Here’s an example of endpoints that might be declared for an HID class:
1 x control endpoint (endpoint 0): Used for standard USB control transfers, such as configuration and enumeration.
1 x interrupt IN endpoint: For sending HID reports from the device to the host (for example, mouse movements, keyboard presses). This endpoint is used to send periodic data to the host with minimal latency. The HID descriptor defines the polling interval for this endpoint.
1 x interrupt OUT endpoint: For receiving HID reports from the host to the device (for example, LED status for keyboards, feature reports). This endpoint is used to receive data from the host that needs to be processed by the device.
Here’s an example of endpoints that might be declared for a CDC ACM class implementation (PSTN subclass):
1 x bulk IN endpoint: For sending data from the STM32 device to the PC host. Data received over UART is saved in a buffer to be sent. Periodically, a timer callback checks the buffer state. If data is available, it’s transmitted in response to an IN token; otherwise, it’s NAKed.
1 x bulk OUT endpoint: For receiving data from the PC host to the STM32 device. Data received through this endpoint is saved in a receive buffer and then transmitted over UART using interrupt mode. Meanwhile, the OUT endpoint is NAKed. Once the transmission is complete, the OUT endpoint is prepared to receive the next packet in the UART transmit callback.
1 x interrupt IN endpoint: For setting and getting serial-port parameters. In this example, two requests can be implemented:
Here’s an example of endpoints that might be declared for an audio class:
To learn about the number of endpoints available, refer to the associated STM32 datasheet or section 2.1 "USB implementation on STM32 products" in application note 4879.
Consider the maximum packet size and buffering requirements for each endpoint:
Control | Interrupt | Bulk | Isochronous | |
Max packet size in bytes in full speed | 64 | 64 | 64 | 1023 |
Max packet size in bytes in high speed | 64 | 1024 | 512 | 1024 |
Data payloads must be less than or equal to the endpoint’s max packet size. If a larger than expected data payload is received, the control transfer is aborted.
Each endpoint has a unique address composed of a direction (IN or OUT) and an endpoint number to be defined in each endpoint descriptor. The endpoint address is an 8-bit value that contains both the endpoint number and the direction of data transfer. The format is as follows:
Endpoint numbers typically range from 1 to 15 (0 is reserved for control endpoints). The definition of endpoint numbers must respect the order of classes instantiation. Here’s an example to initialize the endpoint address:
// Define endpoint addresses
#define EP1_OUT 0x01 // Endpoint 1, OUT direction
#define EP1_IN 0x81 // Endpoint 1, IN direction
#define EP2_OUT 0x02 // Endpoint 2, OUT direction
#define EP2_IN 0x82 // Endpoint 2, IN direction
// Initialize endpoint descriptors
USBD_EpDescTypedef ep1_out_descriptor = {
.bLength = 7, // Descriptor size
.bDescriptorType = 0x05, // Endpoint descriptor type
.bEndpointAddress = EP1_OUT,// Endpoint address
.bmAttributes = 0x02, // Bulk transfer type
.wMaxPacketSize = 64, // Maximum packet size (64 bytes)
.bInterval = 0 // Polling interval (ignored for bulk)
};
Generally, FIFO sizes can be adjusted to optimize performance and reduce CPU overhead. For example, to handle more data and reduce the frequency of FIFO overflows, FIFO sizes should be larger in high speed mode. Also, bulk endpoints might require larger FIFOs to handle large data transfers efficiently compared to different types of endpoints.
Refer to the appropriate STM32 datasheet to check the size of dedicated FIFO SRAM. Furthermore, check if double buffer mode is supported, which would reduce the number of available endpoints. Here’s how USB FIFO is managed:
Proper management of FIFO sizes ensures efficient data transmission and reception without overflow. By configuring FIFO sizes appropriately, you can enhance the performance and reliability of your USB communication.
When selecting an STM32 MCU for a USB application, it is crucial to ensure that the chosen MCU meets all the requirements of your project. Here are some key considerations:
By understanding the types of data transfers your USB application requires, you can determine the suitable endpoints and associated configuration. This ensures efficient and reliable communication between the USB device and the host. Always refer to the USB specification and the STM32 MCU’s datasheet for detailed information on endpoint capabilities and limitations.