on 2025-09-23 6:30 AM
This article provides an in-depth explanation of the FIFO (First-In First-Out) architecture implemented in USB OTG controllers operating in device mode on STM32 microcontrollers. The USB system features up to 4 Kbytes of dedicated RAM with a sophisticated FIFO control mechanism.
Applicable STM32 microcontrollers:
STM32 USB OTG controllers include dedicated RAM (SPRAM) with FIFO control, whose size depends on the STM32 MCU product line. Key features include:
In the scope of this article, we address device mode applications.
The USB OTG controller module in STM32 devices organizes dedicated RAM into multiple Tx FIFOs for transmitting data and a shared Rx FIFO for receiving data.
Receive FIFO (RxFIFO) is used to store data received from the host. The size of the RxFIFO can be configured to optimize performance.
Transmit FIFO (TxFIFO) is used to store data that needs to be sent to the host. Each endpoint can have its own TxFIFO, and the size should be adjusted based on the type of data transfer (for example, bulk, interrupt, isochronous). The application pushes the data to be temporarily stored into this FIFO (in blue) before the USB transmission.
For better details, you can refer to the dedicated reference manual.
Caution: Avoid overlapping FIFO regions to prevent undefined behavior and data corruption.
STM32 USB OTG controllers operate in different default modes depending on the controller type:
These modes impact FIFO memory usage and configuration requirements, especially regarding additional FIFO space needed for DMA operations. This distinction is important when calculating FIFO sizes and setting up memory partitions.
For RxFIFO, the developer should allocate
Minimum Rx FIFO size formula (in 32-bit words):
Device RxFIFO = 13 + ((largest USB packet size)/4 + 1) + (2 × number of OUT EP) + 1
The number of OUT endpoints is:
For the USB FS controller, the MPS is 64 bytes for a periodic USB packet and 64 bytes for a nonperiodic USB packet. There are five OUT endpoints, five IN endpoints, and one control endpoint.
Device RxFIFO = 13 + ((64 / 4) +1) + (2 * 6) + 1 = 43 words
For the USB HS controller, the MPS is 1024 bytes for a periodic USB packet and 512 bytes for a nonperiodic USB packet. There are eight OUT endpoints, eight IN endpoints, and one control endpoint.
Device RxFIFO = 13 + ((1,024 / 4) +1) + (2 * 9) + 1 = 289 words
Note: Pay attention to the calculations and additional requirements in your MCU’s reference manual.
When USB buffer DMA mode is used, the formula is as follows:
Device RxFIFO = 13 + ((largest USB packet size)/4+1) + (2 × number of OUT EP) + 1 + 18
Additional, 18 words are needed for slave and buffer DMA mode and 4x 18 = 72 words are needed for scatter gather mode (may be discussed in another KB).
The minimum TxFIFO size for each IN endpoint is the maximum packet size in words for each EP. More space allocated in the transmit IN endpoint FIFO results in better performance on the USB. Tx FIFOs do not store metadata, only payload data.
So, the minimum Tx FIFO size for each control EP to transmit FIFO to TxFIFO is 16 words (64 bytes).
When configuring multiple Tx FIFOs, it is important to understand how unused FIFOs affect memory allocation:
When a TxFIFO is not used, the configuration must follow these rules based on the FIFO index numbers (n and m):
This allows more efficient use of the FIFO memory by reclaiming space from unused FIFOs at higher indices.
For optimal memory usage and performance, it is recommended to assign Tx FIFOs to IN endpoints with consecutive, starting with the lower FIFO index. For example, using IN endpoints 1 and 2 is more efficient than using endpoints 1 and 3, as this avoids gaps and fragmentation in FIFO memory.
More space allocated in the transmission IN endpoint FIFO results in better performance over the USB
For multiple isochronous OUT endpoints typically, two (largest packet size / 4) + 1 spaces are recommended. This is so that when the previous packet is being transferred to AHB, the USB can receive the subsequent packet. If AHB latency is high, you must allocate enough space to receive multiple packets. This is critical to prevent dropping of any isochronous packets. This is also applicable if Tx or Rx threshold is configured in OTG_DTHRCTL, So, the formula becomes:
Device RxFIFO = 13 + 2 × ((largest USB packet size)/4 + 1) + (2 × number of OUT EP) + 1
For each transmit FIFO
Device TxFIFO = 2 × MPS (for each EP)
High-speed applications require more space than Full-speed applications. Generally, the minimum RxFIFO in HS mode we allocate 512 words (0x200) and in FS mode we allocate 128 words (0x80)
The USB OTG controller module in STM32 devices organizes dedicated RAM into multiple Tx FIFOs for transmitting data and a shared Rx FIFO for receiving data. The application pushes the data to be temporarily stored into this FIFO before the USB transmission. Here are some key takeaways:
For more detailed information, always refer to the STM32 reference manual specific to your MCU series. If you need further assistance or examples, feel free to ask or consult the ST Community forum.