Skip to main content
Graduate
December 31, 2024
Question

CubeIDE how to configure USB HS with internal FS Phy for DMA transfer on STM32F4

  • December 31, 2024
  • 1 reply
  • 1605 views

Following on from this question USB FS speed vs USB HS with internal FS Phy with DMA  it seems that USB HS has access to DMA but there is no information on how this is configured. I do not see any additional DMA options appear in Cube IDE when I have enabled the above options.

exlabs_0-1735628133657.png

Note I have enabled the option: Enable internal IP DMA 

exlabs_0-1735628740988.png

I would like to setup the following pipeline:

  1. Peripheral to Memory (see above I2S3_EXT_RX): receive sensor data and buffer small number of bytes to memory
  2. Memory to USB DMA transfer: send the data immediately out of the MCU over USB connection 

I cannot see how to configure the number 2: the Memory to USB DMA transfer

Is this configurable in CubeIDE or perhaps only in software? Given the crucial role this plays in the board's operation, I want to confirm its feasibility before proceeding. If not, I would change to a STM32 that would allow this scheme.

Regards,

    This topic has been closed for replies.

    1 reply

    Super User
    December 31, 2024

    The OTG_HS module's DMA is internal to that module, i.e. it is not related to the general-purpose DMA modules.

    That's why OTG_HS is a busmaster on the bus matrix.

    waclawekjan_0-1735632785081.png

    The OTG_HS's DMA has no option to avoid increment of address, so you can't fetch data from a single address. Also there's no provision to trigger it from external trigger source like some peripheral's (such as I2S) signal.

    In other words, you cannot achieve complete automatism as you've outlined. You need to use the general-purpose DMA to transfer data to RAM, and then use the OTG_HS's DMA to transfer that through USB with periodic software intervention restarting that DMA.

    JW

    Visitor II
    December 31, 2024

    USB has its own DMA (inside the USB block). This USB DMA cannot be used for any other peripheral.

    Bring the USB stack alive, with DMA. So, you can now send and receive data via USB. But if you want to send data from peripherals (e.g. I2S3 or SPI3) - they might need their own DMA. So, these peripherals put/get data to/from DMA buffer and USB DMA uses another DMA buffer.

    The FW needs now a "trigger", e.g. Callback, that USB has transferred into USB DMA buffer. Now you have to copy the data fo/from USB buffer to peripheral buffers. Or: you map the USB DMA buffer to the peripheral buffers (with a smart buffer management in SW).

    USB with DMA is like an engine running in background, transferring data to/from a USB buffer. You have to move the data from other buffers into/from their location into the USB buffers. The trigger is SW code, e.g. checking in which USB Callback you are (in order to know which next half-buffer to fill with data for USB).

    exlabsAuthor
    Graduate
    January 1, 2025

    Thanks @waclawek.jan and @tjaekel for the helpful comments. Yes, the bus matrix really helps understand these capabilities—thanks for pointing that out—I am learning!

    So it seems this is well within the capabilities of the MCU using double buffering and half-complete callback to trigger to USB OTG HS DMA. Maybe something like this?

    Create three buffers:

    DMA1.png

    When the buffer is half full, use a callback to trigger the USB OTG HS DMA 

    DMA2.png

    When the buffer is full, use a callback to trigger the USB OTG HS DMA to read from the buffer at an offset:

    DMA3.png

    I will use circular buffers and let this run until I have collected enough samples.

    Do you see any potential issues or pitfalls with the approach? As long as all the incoming data is received and sent out without any missed bytes, this should work.

    Regards,