2026-01-03 2:56 AM
Hello,
I am looking for help debugging an issue with both ADCs running in continuous conversion mode with multiple channels, using DMA on an STM32H7 device.
Hardware / Tools
Board: NUCLEO-H7S3L8
MCU family: STM32H7RS
Peripherals: ADC1 and ADC2
Mode: Continuous conversion, multi-channel (scan mode)
Data transfer: DMA
Configuration Overview
Both ADCs are configured in continuous conversion mode
Each ADC scans multiple channels
DMA is used to transfer conversion results into memory buffers
DMA buffers are statically allocated and placed in DMA-accessible memory
D-Cache is enabled on the H7
Problem Description
Both ADCs are running and DMA transfers are occurring, but the sampled data in the buffer is always 0
In the SFR it shows that the ADC is working, but the DMA is idle/not set up correctly. Also the DMA buffers are in a non-cacheble region protercted by my MPU.
static void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/* Disables all MPU regions */
for(uint8_t i=0; i<__MPU_REGIONCOUNT; i++)
{
HAL_MPU_DisableRegion(i);
}
/** Initializes and configures the Region and the memory to be protected
*/
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);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x30000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; /* TEX = 000 */
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; /* C = 0 */
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; /* B = 0 */
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; /* S = 1 */
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0x70000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB;
MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RO;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);The DMA buffers themselves are located correctly, and there are no hard faults or DMA errors reported. The issue appears to be related to the interaction between:
Continuous conversion + scan mode
DMA buffer handling
What I Have Checked / Tried
Verified that DMA buffers are not located in Flash
Confirmed DMA streams are enabled and running
Checked ADC channel ranks and scan configuration
Ensured continuous mode is enabled only where intended
Tested with different buffer sizes
Reviewed reference manual sections on ADC + DMA operation
Reviewed cache configuration (D-Cache enabled)
Despite this, the DMA is misbehaiving, can someone help?
Best regards.
PS: I applied additionally the ADC config as well as 2 SFRs. Also this is how i start the DMA+ADC:
if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc1_dma_buf, 7) != HAL_OK)
tb_fatal();
if (HAL_ADC_Start_DMA(&hadc2, (uint32_t *)adc2_dma_buf, 7) != HAL_OK)
tb_fatal();