Skip to main content
filipxsikora
Associate II
January 5, 2025
Solved

STM32N6 HPDMA not copying data

  • January 5, 2025
  • 6 replies
  • 2061 views

Hello,

another day, another N6 "issue" :)

I want to do RAM to RAM copy by HPDMA, but the data never get copied from Src to Dest, Dest always stays unmodified. I have checked the 'DMA_RAMToRAM' example for N6 and went from there, but with no success.

DMA Init:

__HAL_RCC_HPDMA1_CLK_ENABLE();

HAL_NVIC_SetPriority(HPDMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(HPDMA1_Channel1_IRQn);

handle_HPDMA1.Instance = HPDMA1_Channel1;
handle_HPDMA1.Init.Request = DMA_REQUEST_SW;
handle_HPDMA1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_HPDMA1.Init.Direction = DMA_MEMORY_TO_MEMORY;
handle_HPDMA1.Init.SrcInc = DMA_SINC_INCREMENTED;
handle_HPDMA1.Init.DestInc = DMA_DINC_INCREMENTED;
handle_HPDMA1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD;
handle_HPDMA1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD;
handle_HPDMA1.Init.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
handle_HPDMA1.Init.SrcBurstLength = 2;
handle_HPDMA1.Init.DestBurstLength = 2;
handle_HPDMA1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0 | DMA_DEST_ALLOCATED_PORT0;
handle_HPDMA1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_HPDMA1.Init.Mode = DMA_NORMAL;

if (HAL_DMA_Init(&handle_HPDMA1) != HAL_OK)
{
 Error_Handler();
}

if (HAL_DMA_ConfigChannelAttributes(&handle_HPDMA1,
 DMA_CHANNEL_PRIV | DMA_CHANNEL_SEC | DMA_CHANNEL_SRC_SEC | DMA_CHANNEL_DEST_SEC) != HAL_OK)
{
 Error_Handler();
}

And code:

__attribute((aligned(32))) uint16_t _dataSrc[128];
__attribute((aligned(32))) uint16_t _dataDst[128];

...

if (HAL_DMA_Start_IT(&handle_HPDMA1, (uint32_t)&_dataSrc[0], (uint32_t)&_dataDst[0], 256) != HAL_OK)
{
 Error_Handler();
}

if (HAL_DMA_PollForTransfer(&handle_HPDMA1, HAL_DMA_FULL_TRANSFER, 10) != HAL_OK)
{
 Error_Handler();
}

_dataSrc and _dataDst are global variables at 0x3400xxxx region (FLEXRAM).

_dataSrc contains data, checked.

 

When I use memcpy, that works. When I use GPDMA1 with exactly the same parameters, that also works. But HPDMA doesn't. No error I can see happened, not stuck in Error_Handler, no HardFault.. The code just executes normally and continues after that, so the transfer completed correctly. Yet the _dataDst stays unmodified.

 

L1 D-cache was off for these tests.

 

What am I missing?

Thank you.

Best answer by ANJS

Hello!
you need to configure the Resource isolation slave unit for address space protection in order to let the HPDMA1 master to have access to SRAM2 or SRAM1

 

  /*RISAF2 => SRAM1_AXI */
  /*RISAF3 => SRAM2_AXI */


RISAF3->REG[0].CFGR = 0x00000000;

RISAF3->REG[1].CFGR = 0x00000000;

RISAF3->REG[0].CIDCFGR = 0x000F000F; /* RW for everyone */

RISAF3->REG[0].ENDR = 0xFFFFFFFF; /* all-encompassing */

RISAF3->REG[0].CFGR = 0x00000101; /* enabled, secure, unprivileged for everyone */

RISAF3->REG[1].CIDCFGR = 0x00FF00FF; /* RW for everyone */

RISAF3->REG[1].ENDR = 0xFFFFFFFF; /* all-encompassing */

RISAF3->REG[1].CFGR = 0x00000001; /* enabled, non-secure, unprivileged*/

For further information see the chapter 7. Resource isolation slave unit for address space
protection of the reference manual RM0486.
Best regards



6 replies

AScha.3
Super User
January 5, 2025

Hi,

> What am I missing?

Look at the registers of HPDMA before and after the "transfer"  (in debug).

Should show, what HPDMA doing - or not.

"If you feel a post has answered your question, please click ""Accept as Solution""."
filipxsikora
Associate II
January 6, 2025

Hello,

Checked the registers, I didn't see any error flags being set, or anything weird, just Transfer Complete flag.

I've also registered the callbacks

HAL_DMA_RegisterCallback(&handle_HPDMA1, HAL_DMA_XFER_CPLT_CB_ID, TransferCompleteHPDMA);
HAL_DMA_RegisterCallback(&handle_HPDMA1, HAL_DMA_XFER_ERROR_CB_ID, TransferErrorHPDMA);

 And I've got the TransferComplete CB every time, never the TransferError.

But result is still the same, data at the destination not being modified.

ANJSBest answer
ST Employee
January 10, 2025

Hello!
you need to configure the Resource isolation slave unit for address space protection in order to let the HPDMA1 master to have access to SRAM2 or SRAM1

 

  /*RISAF2 => SRAM1_AXI */
  /*RISAF3 => SRAM2_AXI */


RISAF3->REG[0].CFGR = 0x00000000;

RISAF3->REG[1].CFGR = 0x00000000;

RISAF3->REG[0].CIDCFGR = 0x000F000F; /* RW for everyone */

RISAF3->REG[0].ENDR = 0xFFFFFFFF; /* all-encompassing */

RISAF3->REG[0].CFGR = 0x00000101; /* enabled, secure, unprivileged for everyone */

RISAF3->REG[1].CIDCFGR = 0x00FF00FF; /* RW for everyone */

RISAF3->REG[1].ENDR = 0xFFFFFFFF; /* all-encompassing */

RISAF3->REG[1].CFGR = 0x00000001; /* enabled, non-secure, unprivileged*/

For further information see the chapter 7. Resource isolation slave unit for address space
protection of the reference manual RM0486.
Best regards



Explorer
May 27, 2025

KUDOS! This fixes my problem!

filipxsikora
Associate II
January 10, 2025

Hello @ANJS,

Thank you! That worked.

 

Since I don't care about that security/isolation stuff one bit, is there a way to disable it altogether?

filipxsikora_0-1736538417171.png

Can I iterate through all of these RISAF regions, configure them the same way as you suggested and forget about it?

Associate III
November 7, 2025

Hi, 

Is above HPDMA issue regarding camera interface in DCMIPP CSI interface. I have been trying to implement camera interface from STM32cubeMX for STM32N6 board. Please provide me proper configurations of camera DCMIPP CSI or parallel configuration from STM32cubeMX. ThankYou.

Visitor
July 23, 2026

Thanks to the author for the tip! It helped me too.
  Note that my DMA buffers were allocated in a separate area around these addresses 0x38000000
  (I disabled the DMA cache). Accordingly, I used RISAF21 instead of RISAF3.

The program still refused to work. Then I used a wonderful tool and recommend it to you.

  Run your code in debug mode, stop it somewhere in the middle of the process, and when you realize that what you're trying to do isn't working, open the SFRs tab and find the register block for the IAC.
  Look for which IAF flag is set to 1 and find it in Datasheet RM0486, Section 8. There are tables there. Then you'll know exactly which device was blocked. You can see my case on IAC_Reg.jpg and piece of table from Datasheet - RISAF.jpg
In my case, this was my own DMA buffer in AHBSRAM1 - IAF155 and, as I later discovered, my own DMA handlers located in the main memory of AXISRAM2 - IAF141.
So, following the author's example, I placed two groups of register operations (for RISAF3 and RISAF21) inside the SystemIsolation_Config() function. It all worked!
Thanks again for the tip.