cancel
Showing results for 
Search instead for 
Did you mean: 

Practical use cases on how to configure packet memory area in STM32 USB controllers

FBL
ST Employee

Introduction

Following the previous article, this one provides STM32 developers with practical examples and guidance on configuring USB applications using the packet memory area (PMA) for different USB classes: communication device class (CDC), human interface device (HID), and mass storage class (MSC). It covers endpoint configuration, buffer allocation, and best practices for maximizing USB communication efficiency.

1. Understanding endpoint configuration

1.1 Endpoint size and buffering

Each endpoint type has specific size and buffering requirements:

  • Control, interrupt, bulk: The max packet size is 64 bytes (Full-Speed) and 64, 1024, 512 respectively in High-Speed.
  • Isochronous: The max packet size is 1023 bytes (Full-Speed) and 1024 bytes (High-Speed).

Ensure that data payloads do not exceed these sizes to prevent aborted transfers.

1.2 Endpoint addressing

Endpoints have unique addresses comprising direction and endpoint number:

  • Bits 0-3: Endpoint number (0-15).
  • Bit 7: Direction (0 for OUT, 1 for IN).
  • Bits 4-6: Reserved.

Example:         

#define EP1_OUT 0x01  // Endpoint 1, OUT direction
#define EP1_IN  0x81  // Endpoint 1, IN direction

1.3 Using the HAL_PCDEx_PMAConfig() function

The HAL_PCDEx_PMAConfig() function is used to configure the PMA for each endpoint in the application. This function is typically called in the USBD_LL_Init function in the usbd_conf.c file, which is generated by STM32CubeMX.

1.3.1 Function prototype

HAL_StatusTypeDef  HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr, uint16_t ep_kind, uint32_t pmaadress);

1.3.2 Parameters

  1. hpcd Pointer to the USB device instance.
  2. ep_addr  Endpoint address (direction + number.)
  3. ep_kind : Endpoint type (USB_SNG_BUF for single bufferUSB_DBL_BUF for double buffer.)
  • USB_SNG_BUF: single buffer used.
  • USB_DBL_BUF: double buffer used.
  1. pmaaddress : PMA address for the endpoint buffer(s.)
  • Single buffer: 16-bit PMA address.
  • Double buffer: 32-bit value combining two 16-bit PMA addresses (buffer0 in LSB, buffer1 in MSB.)

1.4 Best practice for PMA allocation

STM32 developers must not rely on STM32CubeMX code generation for PMA configuration. Instead, follow these guidelines:

  • Use HAL_PCDEx_PMAConfig() for each endpoint in your USB device configuration.
  • Allocate PMA memory based on a predefined PMA address table to avoid overlaps.
  • Use the BTABLE starting at address 0x00 to store endpoint buffer descriptors.
  • Ensure that buffer boundaries are correct to prevent conflicts with other endpoint descriptors.
  • Optimize memory usage by reducing buffer offsets and minimizing unused space.
  • To avoid any potential issue linked to overlapping or too tightly packed buffer regions, increase the initial PMA buffer START address to 0x40 (the corner-case scenario.)

2. CDC application configuration

CDC applications typically use three endpoints: Bulk IN, Bulk OUT, and Command Interrupt IN.

HAL_PCDEx_PMAConfig(&hpcd_USB_FS, EP1_IN, PCD_SNG_BUF, 0x40); //EP1 BULK IN
HAL_PCDEx_PMAConfig(&hpcd_USB_FS, EP1_OUT, PCD_SNG_BUF, 0x80); // EP1 Bulk OUT
HAL_PCDEx_PMAConfig(&hpcd_USB_FS, EP2_IN, PCD_SNG_BUF, 0xC0);              //EP2 Interrupt IN and Size of each region is 64B

3. HID application configuration

HID applications typically use an Interrupt IN endpoint to send data to the host.

HAL_PCDEx_PMAConfig(&hpcd_USB_FS, EP3_IN, PCD_SNG_BUF, 0x100); //EP3 Interrupt IN 64B

4. MSC application configuration

MSC applications use Bulk IN and Bulk OUT endpoints for data transfer.

HAL_PCDEx_PMAConfig(&hpcd_USB_FS, EP4_IN, PCD_SNG_BUF, 0x140);                          //EP4 Bulk IN 64B
HAL_PCDEx_PMAConfig(&hpcd_USB_FS, EP4_OUT, PCD_SNG_BUF, 0x180);                          // EP4 Bulk Out 64B

5. Audio application configuration

Audio speaker or headset application use isochronous OUT endpoints for data transfer.

  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, AUDIO_OUT1_EP, PCD_DBL_BUF, 0x01500090);
// EP4 ISO Out : 32-bit PMA addresses split into two 16-bit 
  • Double-buffering requires two separate buffer addresses for the same endpoint (pmaaddr0 and pmaaddr1).
  • For buffer 0 PMA start address 0x90 and for buffer 2 PMA start address 0x150

6. Debugging and testing

  • Use debugging tools to trace USB communication and identify potential mismatches in endpoint size configurations.
  • Test with different endpoint sizes (for example, 16, 32, 64 bytes) to determine the optimal configuration for your buffer.  Try adding 0x10, 0x20, or 0x40.
  • Set USB interrupt priority higher to prevent USB ISR starvation.
  • You need to be careful not to overlap one buffer with another. Otherwise, you get unexpected behavior.
  • For USBX middleware, verify if your application is configured to handle the desired endpoint sizes. This includes ensuring that the UX_SLAVE_REQUEST_DATA_MAX_LENGTH is set appropriately.
  • In case of selecting EP3 directly, you should consider allocating buffers to different descriptors of precedent in, for example, of EP1 and EP2.

Conclusion

Configuring USB applications on STM32 involves careful management of endpoints and buffer memory. By following these guidelines and examples, developers can optimize their USB applications for efficient data transfer and reliable communication.

For further detailed technical information, consult the USB section in the reference manual applicable to your specific STM32 product series. If you have further questions, feel free to ask on ST Community forums.

Related links

Version history
Last update:
‎2025-10-22 6:25 AM
Updated by: