cancel
Showing results for 
Search instead for 
Did you mean: 

How to configure USB FIFO over USB OTG controller on STM32 in device mode

FBL
ST Employee

Introduction

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:

  • STM32F4 series (STM32F427/39 F437/39 F469/79 and F446 series)
  • STM32F7 series
  • STM32L4 series
  • STM32H7 series
  • STM32U5 series (STM32U575 / U585 / U9x / Ax / Gx / Fx series)
  • STM32N6 series

1. USB SPRAM  on STM32 OTG controllers

STM32 USB OTG controllers include dedicated RAM (SPRAM) with FIFO control, whose size depends on the STM32 MCU product line. Key features include:

  • Configurable partitioning of RAM space into different FIFOs for flexible and efficient use of RAM
  • Each FIFO can hold multiple packets
  • Dynamic memory allocation
  • Configurable FIFO sizes that are not powers of two to allow the use of contiguous memory locations.

In the scope of this article, we address device mode applications.

2. FIFO memory organization

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. 

fifo memory organization.png

 

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.

2.1 FIFO memory organization

  • IN endpoints: Each active IN endpoint has its own dedicated Tx FIFO buffer.
  • OUT endpoints: All OUT endpoints share a single Rx FIFO buffer.

2.2 FIFO memory characteristics

  • FIFO memory is like a dedicated memory, separate from system RAMs.
  • Data transfer to/from endpoints involve explicit read/write operations to these FIFO memory addresses.
  • The device writes data to these TxFIFOs, which the host subsequently reads.
  • The Rx FIFO stores both received data and status information (for example, number of bytes received, setup packets etc.)
  • Status information is pushed into the Rx FIFO ahead of actual data packets to maintain synchronization.

2.3 FIFO configuration requirements

  • Tx FIFOs: Both size and start address must be configured individually for each Tx FIFO.
  • Rx FIFO: The start address is fixed and shared among all OUT endpoints; only the size is configurable.
  • FIFO sizes are expressed in 32-bit words (4 bytes per word).
  • FIFO start addresses must be aligned to 32-bit boundaries (multiples of 4 bytes).

For better details, you can refer to the dedicated reference manual.

Caution: Avoid overlapping FIFO regions to prevent undefined behavior and data corruption.

2.4 USB OTG controller operating modes

STM32 USB OTG controllers operate in different default modes depending on the controller type:

  • USB OTG_FS controller is configured in slave mode by default.
  • USB OTG_HS controller is configured in buffer DMA mode by default, but it can also be configured in FS and operate in slave mode.

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.

3. FIFO size calculation

3.1 Rx FIFO size calculation

For RxFIFO, the developer should allocate 

  • 13 locations also called words (52 bytes) for SETUP packets (for the control endpoint).
  • Largest packet size in words
  • Additional one word for status information
  • Two words for each OUT endpoint 
  • One word for global OUT NAK

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:

  • Six endpoints in the Full-Speed USB OTG controller (five EPs + one control EP)
  • Nine endpoints in the High-Speed USB OTG controller (eight EPs + one control EP)

3.1.1 Examples

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.

3.1.2 USB buffer DMA

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

3.2 Tx FIFO size calculation

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

  • If a Tx FIFO with a higher index number (n) is not used, and a Tx FIFO with a lower index number (m) is used (where n > m), the memory allocated for the unused higher-index FIFO (n) can be reassigned to the lower-index FIFO (m).

This allows more efficient use of the FIFO memory by reclaiming space from unused FIFOs at higher indices.

  • If a Tx FIFO with a lower index number (n) is not used, and a Tx FIFO with a higher index number (m) is used (where n < m), the unused lower-index FIFO (n) must still be configured with the minimum size of 16 words. This is necessary to maintain the correct memory layout and prevent memory overlapping or corruption.

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.

3.3 Recommendations on FIFO size

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)

 Conclusion

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:

  • The application can preload large amounts of data into the Tx FIFO before it needs to be sent over USB.
  • Buffering of incoming data in the single Rx FIFO, reducing CPU intervention.
  • The core can operate in FS continuously without waiting for the CPU to intervene frequently.
  • It has a large reserve of data ready to send, enabling smooth transmission.
  • The receive buffer has enough space to autonomously accept incoming data from the USB host without overflow.

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.

Related links

Version history
Last update:
‎2025-09-23 6:15 AM
Updated by:
Contributors