cancel
Showing results for 
Search instead for 
Did you mean: 

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

FA1234
Associate III

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!

1 ACCEPTED SOLUTION

Accepted Solutions
BRAHIM_SALH
ST Employee

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

View solution in original post

3 REPLIES 3
Saket_Om
ST Employee

Hello @FA1234 

Please refer to the DMA examples available on STM32CubeH7RS.

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

Thanks
Omar
BRAHIM_SALH
ST Employee

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

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