Can HPDMA on the the STM32H7S3L8 access DTCM memory?
Hello,
I'm trying out both the DMAs on the STM32H7S3L8. I am trying to keep it as simple as possible, so I am not using linked list mode (I think. CxLLR is 0). When using HPDMA, I get a Data Transfer Error when trying to copy from SRAM1 to DTCM. The datasheet says the following:

Specifically, note that it seems to suggest it is possible for HPDMA to access CPU TCM, which I assume to be/include DTCM.
My code is mostly baremetal and difficult for me to condense into a simple example (though I will try to do so needed). The following are the highlights which might be useful :
- I am using HPDMA1 Channel 0 in privileged mode in the Boot domain. I do not have an application domain
- I am attempting to copy 0x100 bytes from SRAM (at 0x240002b4) to DTCM (at 0x2000002c)
- I am using a burst length of 8 on both the src and dest, with width of 1 word (0b10) on both. Both SINC and DINC are enabled.
- No repeats configured, no offsets configured, none of the increments are set to negative.
- No linked list is used.
- No trigger is used.
- I'm using the software request (setting EN on the CxCR register)
- The same code works fine if the destination is in SRAM instead of being in DTCM
No interrupts are used. I just request the transfer soon after reset and halt using the debugger to see if the memory is properly written. I am also polling the error flags and halting the CPU if an error is detected, and I find there is a Data Transfer Error (DTEF is high).
Any insight into why this is breaking would be much appreciated.
The following code is what I use to configure the MPU at startup. This is based on an ST Application note. It allows my application to read and write to DTCM from the Cortex without any issue. Also, ICache and DCache are both disabled on the CPU.
__weak void mpu_init(void){
MPU_Region_InitTypeDef MPU_InitStruct = {0};
HAL_MPU_Disable();
// Background protection for preventing speculative execution
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x0;
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
MPU_InitStruct.SubRegionDisable = 0x87;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
MPU_InitStruct = (MPU_Region_InitTypeDef){0};
// Read Access for ID
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x08fff000;
MPU_InitStruct.Size = MPU_REGION_SIZE_4KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
__weak void configure_memory_layout(void){
FLASH_OBProgramInitTypeDef pOBInit = {0};
if (HAL_FLASH_Unlock() != HAL_OK) { die(); }
if (HAL_FLASH_OB_Unlock() != HAL_OK) { die(); }
pOBInit.OptionType = OPTIONBYTE_USER;
pOBInit.USERType = OB_USER_SRAM_ECC
| OB_USER_I2C_NI3C
| OB_USER_DTCM_AXI_SHARE
| OB_USER_ITCM_AXI_SHARE;
pOBInit.USERConfig2 = OB_I2C_NI3C_I2C
|OB_DTCM_AXI_SHARE_1
|OB_ITCM_AXI_SHARE_0
|OB_AXISRAM_ECC_DISABLE;
if (HAL_FLASHEx_OBProgram(&pOBInit) != HAL_OK) { die(); }
if (HAL_FLASH_OB_Lock() != HAL_OK) { die(); }
if (HAL_FLASH_Lock() != HAL_OK) { die(); }
prepare_tcm_memory();
}


