on 2025-10-22 8:00 AM
This guide explains the basic structure and organization of the packet memory area (PMA) in STM32 USB controllers operating in full speed. It covers how buffers are allocated and configured to support data transfers between the device and host. By understanding these concepts and following best practices, developers can improve the efficiency and reliability of USB communication in their applications.
Applicable STM32 products:
Note: This guide is not applicable for products embedding USB OTG controllers.
The packet memory area (PMA) is a dedicated memory region within STM32 microcontrollers designed to buffer USB data packets during communication between the USB peripheral and the host. It enables efficient management of both incoming (OUT) and outgoing (IN) data to the STM32 USB device by organizing memory through a buffer description table. This table tracks buffer locations and sizes for each endpoint and direction.
The buffer description table is a critical component that maps the packet memory area. Each entry in the table corresponds to a specific endpoint and direction (IN or OUT) and contains the following information:
Example reference: See figure 674 in the RM0440 G4 reference manual for examples of buffer description table locations.
The buffer descriptor table is located within the USB SRAM and acts as a configuration map for packet buffers. It defines the location and size of each buffer, enabling the USB peripheral to handle data packets effectively.
The USB SRAM register map consists of several registers; each associated with a specific channel or endpoint. These registers are used to configure packet buffers for data transmission and reception.
We have 2 versions of USB controllers,
First version of USB controller:
Applicable to STM32F102/F103, STM32L1, STM32F3, STM32F0, STM32L0x2/x3, STM32L4x2/x3, STM32L5, STM32G4, STM32WB55/35.
Second version of USB controller:
Applicable to STM32G0, STM32C071, STM32U535/545, STM32U3, STM32U073/83, STM32H503/23/33/63/73.
We can find differences in the mapping of two versions of controllers:
Registers in this version are 16-bit wide and include the following fields:
Each register contains multiple bits, crucial for configuring the packet memory:
Below is a table showing the memory allocation for buffer sizes based on the values of NUM_BLOCK and BLSIZE. Ensure buffers are allocated correctly to avoid conflicts.
|
Value of NUM_BLOCK [4:0] |
Memory allocated when BLSIZE = 0 |
Memory allocated when BLSIZE = 1 |
|
0 |
Not allowed |
32 bytes |
|
1 |
2 bytes |
64 bytes |
|
2 |
4 bytes |
96 bytes |
|
3 |
6 bytes |
128 bytes |
|
.. |
.. |
.. |
|
14 |
28 bytes |
480 bytes |
|
15 |
30 bytes |
|
|
16 |
32 bytes |
|
|
|
.. |
|
|
29 |
58 bytes |
|
|
30 |
60 bytes |
992 bytes |
|
31 |
62 bytes |
1023 bytes |
For USB version 1 devices, we distinguish between two types of access scheme:
For 2 x 16 bits/word access scheme devices (PMA_ACCESS=1) we recommend that buffer addresses are aligned to 1 byte (8 bit) boundaries for optimal performance. Or half-word (16-bit) accesses. Word (32-bit) access is not allowed.
For 1 x 16 bits/word access scheme devices (PMA_ACCESS = 2): To obtain the correct memory address value to be used in the application software while accessing the packet memory, the actual memory location address must be multiplied by two. So, every valid 16-bit data word is followed by a padding 16-bit word that is unused or reserved.
To configure a transmission buffer:
Note: In case of double-buffered or isochronous endpoints in the OUT/IN direction, this address location is referred to as USB_ADDRn_RX_0/USB_ADDRn_TX_0.
To configure a reception buffer:
Note: In case of double-buffered or isochronous endpoints in the OUT/IN direction, this address location is referred to as USB_ADDRn_RX_1/USB_ADDRn_TX_1.
Registers in this version are 32-bit wide and include:
Note: CHEP stands for Channel for host mode and EP for device mode.
The following figures illustrate packet buffer areas with examples of buffer description table locations for two versions of USB controllers with minor changes.
Figure 1 is extracted from Figure 674 in RM0440 and Figure 2 from Figure 790 in RM0481.
0x40 is the worst case allocation.
|
Version 1: register |
Version 1: field |
Version 2: register |
Version 2: field |
|
USB_ADDRn_TX |
ADDRn_TX[15:1] |
CHEPn_ TXRXBD |
ADDRn_TX[15:1] |
|
USB_COUNTn_RX |
BLSIZE |
BLSIZE |
|
|
NUM_BLOCK [4:0] |
NUM_BLOCK [4:0] |
||
|
COUNTn_RX[9:0] |
COUNTn_RX[9:0] |
||
|
USB_ADDRn_RX |
ADDRn_RX[15:1] |
CHEPn_ RXTXBD |
ADDRn_RX[15:1] |
|
USB_COUNTn_TX |
COUNTn_TX[9:0] |
COUNTn_TX[9:0] |
Single-buffered endpoints can be used for control, bulk, isochronous, and interrupt transfers, where data is transferred in smaller, predictable amounts with lower performance requirements.
Double-buffering is a technique used to enhance data transfer efficiency by allowing simultaneous read and write operations. It involves toggling between two buffers, reducing wait times and increasing throughput. To implement double-buffering:
Toggle Bits (DTOG and SW_BUF) Manage buffer swapping. The USB peripheral toggles the DTOG bit upon completing a transaction, while the application software toggles the SW_BUF bit after processing the buffer.
The BLSIZE bit in the USB controller's buffer configuration register serves as an important indicator for buffer block sizing. When set to 1, it configures the buffer allocation in 32-byte blocks. This enables efficient handling of large USB packets up to the maximum packet size defined by the USB specification (for example, 1024 bytes). Conversely, when BLSIZE is cleared, the buffer is allocated in 2-byte blocks, optimizing memory usage for smaller packet transfers. This design allows the USB peripheral and software stack to dynamically balance memory efficiency and transfer capability by selecting the appropriate block size granularity based on the expected packet size.
For more details, refer to Table 424: Bulk double-buffering memory buffers usage and Table 425: Isochronous memory buffers usage in RM0440.
To initialize packet buffers, configure the buffer description table by setting the appropriate address and count registers. Ensure that the buffer addresses are aligned to 8-byte boundaries to optimize access speed and avoid conflicts.
Understanding and managing the packet memory area is essential for efficient USB communication in STM32 microcontrollers. By following best practices and leveraging features like double-buffering, developers can significantly optimize data transfers and enhance the performance of their USB applications. Building on this foundation, the following article provides practical examples and detailed guidance on configuring USB applications for various USB classes, including CDC, HID, MSC, and audio. This next step will help developers apply PMA concepts effectively in real-world scenarios to maximize USB communication efficiency.
1. A simple but important piece of information is missing from the article: Which microcontrollers have PMA_ACCESS=1 option and which ones PMA_ACCESS=2? The information may be (not always easily) found in RefMan but it clearly is missing from this text.
2. I am too dumb to understand this; compare these 2 paragraphs from the above article:
"For 2 x 16 bits/word access scheme devices (PMA_ACCESS=1) we recommend that buffer addresses are aligned to 1 byte (8 bit) boundaries for optimal performance. Or half-word (16-bit) accesses. Word (32-bit) access is not allowed."
"For USB controller V1, buffer addresses should be half-word (2 byte) aligned. In some cases (2 x 16 bits/word access scheme), 1-byte alignment may be optimal. Refer to the specific controller documentation."
So, the PMA addresses should be aligned to 2 but alignment to 1 may be needed for "optimal performance". Huh?!
Any location aligned to boundary of 2 or 4 is also aligned to a boundary of 1. So, alignment to 2 or 4 is also "alignment to 1 byte". This has nothing to do with the fact that no 32-bit access is allowed. The buffer address may still be aligned to 4. I believe that for OUT EPs, the buffer size must be the same as EP size, so why not to align it to 4? To save 2 bytes on IN EP buffer?
Why would anyone align the packet buffer to a boundary of 1 B instead of 2 B? Any rationale for that?
Hi @gbm
Thank you for your feedback and questions. I appreciate the opportunity to clarify these important points regarding PMA access schemes and buffer alignment in first version of STM32 USB controllers.
I hope it's clear!