Skip to main content
Explorer
November 16, 2024
Solved

HPDMA does not seem to work with FMC memory-to-memory?

  • November 16, 2024
  • 2 replies
  • 886 views

I've got an STM32H7RS, and am attempting to use HPDMA to do a memory-to-memory transfer where one side is the FMC.

The transfer works perfectly if I use GPDMA.

With the exact same code (just replacing the GPDMA handle with an HPDMA one) does not work (it returns an error from HAL_DMA_PollForTransfer) and reports:
State: HAL_DMA_STATE_READY
Error: HAL_DMA_ERROR_DTE

I've initialized HPDMA with the exact same parameters (and I've made sure to enable the HPDMA clock with __HAL_RCC_HPDMA1_CLK_ENABLE() at the top of MX_HPDMA1_Init()). 

My MX_HPDMA1_Init():

 

 /* USER CODE BEGIN HPDMA1_Init 0 */
 __HAL_RCC_HPDMA1_CLK_ENABLE();
 HAL_NVIC_SetPriority(HPDMA1_Channel12_IRQn, 8, 0);
 HAL_NVIC_EnableIRQ(HPDMA1_Channel12_IRQn);

 /* USER CODE END HPDMA1_Init 0 */

 /* USER CODE BEGIN HPDMA1_Init 1 */

 /* USER CODE END HPDMA1_Init 1 */
 handle_HPDMA1_Channel12.Instance = HPDMA1_Channel12;
 handle_HPDMA1_Channel12.Init.Request = DMA_REQUEST_SW;
 handle_HPDMA1_Channel12.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
 handle_HPDMA1_Channel12.Init.Direction = DMA_MEMORY_TO_MEMORY;
 handle_HPDMA1_Channel12.Init.SrcInc = DMA_SINC_INCREMENTED;
 handle_HPDMA1_Channel12.Init.DestInc = DMA_DINC_INCREMENTED;
 handle_HPDMA1_Channel12.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
 handle_HPDMA1_Channel12.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
 handle_HPDMA1_Channel12.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
 handle_HPDMA1_Channel12.Init.SrcBurstLength = 8;
 handle_HPDMA1_Channel12.Init.DestBurstLength = 8;
 handle_HPDMA1_Channel12.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT1|DMA_DEST_ALLOCATED_PORT1;
 handle_HPDMA1_Channel12.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
 handle_HPDMA1_Channel12.Init.Mode = DMA_NORMAL;
 if (HAL_DMA_Init(&handle_HPDMA1_Channel12) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_DMA_ConfigChannelAttributes(&handle_HPDMA1_Channel12, DMA_CHANNEL_NPRIV) != HAL_OK)
 {
 Error_Handler();
 }

 

 My DMA code is:

 

uint8_t __attribute__((aligned(32))) local_dma_buf[8192 * 4];
#define DMA_HANDLE (&handle_GPDMA1_Channel12)
...
main()
{
...
 uint32_t src_addr = (uint32_t)&FpgaMem.fifo;
 uint32_t dst_addr = (uint32_t)&local_dma_buf[0];

 if (HAL_DMA_Start(DMA_HANDLE, src_addr, dst_addr, 1024) != HAL_OK) {
 ERROR("Could not start DMA");
 } else {
 if (HAL_DMA_PollForTransfer(DMA_HANDLE, HAL_DMA_FULL_TRANSFER, 1000) != HAL_OK) {
 ERROR("Could not poll for transfer error dmaErr: 0x%lx dmaState: 0x%x",
 HAL_DMA_GetError(DMA_HANDLE), HAL_DMA_GetState(DMA_HANDLE));
 }
...

 

With DMA_HANDLE as shown, all works great. With DMA_HANDLE as &handle_HPDMA1_Channel12, it reports the state/error.

If it matters the FpgaMem is mapped at 0x60000000 in a MPU_TEX_LEVEL2 region (device).

Any suggestions would be greatly appreciated. Thanks!

    This topic has been closed for replies.
    Best answer by BRAHIM_SALH

    Hello @FA1234 ,

    Unfortunately, FMC cannot be accessed by HPDMA via PORT1 (interconnect restriction), only PORT0 is supported.

    (FMC can be accessed by GPDMA vi both PORT0 and PORT1)

    Please refer to "Table 2. Bus-master-to-bus-slave interconnect" in reference manual of STM32H7RS.

    HPDMA _AXI   : PORT0.
    HPDMA _AHB : PORT1.

    There is also a table of supported/non supported configuration in hal_dma.c top file (unfortunately FMC is not mentioned, it can be added in the next release).

    So you can update your code above to :

    handle_HPDMA1_Channel12.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
     
    Only FMC side is required to use PORT0 but I used it in both source and destination. Please check with Reference Manual if there is no other restriction with the memory you are reading from / writing to.

    If your question is answered, please close this topic by clicking "Accept as Solution".

    Best regards,
    Brahim

    2 replies

    Technical Moderator
    November 18, 2024

    Hello @FA1234 

    Please refer to the DMA examples available on STM32CubeH7RS.

    ST Employee
    November 18, 2024

    Hello @FA1234 ,

    Unfortunately, FMC cannot be accessed by HPDMA via PORT1 (interconnect restriction), only PORT0 is supported.

    (FMC can be accessed by GPDMA vi both PORT0 and PORT1)

    Please refer to "Table 2. Bus-master-to-bus-slave interconnect" in reference manual of STM32H7RS.

    HPDMA _AXI   : PORT0.
    HPDMA _AHB : PORT1.

    There is also a table of supported/non supported configuration in hal_dma.c top file (unfortunately FMC is not mentioned, it can be added in the next release).

    So you can update your code above to :

    handle_HPDMA1_Channel12.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
     
    Only FMC side is required to use PORT0 but I used it in both source and destination. Please check with Reference Manual if there is no other restriction with the memory you are reading from / writing to.

    If your question is answered, please close this topic by clicking "Accept as Solution".

    Best regards,
    Brahim
    FA1234Author
    Explorer
    November 18, 2024

    This is exactly the information that I had missed, and fixed the problem immediately. Thank you so much!