cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO H7S3L8 ADC continous conv mode + DMA; DMA stays idle

Vidar
Associate II

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();



0 REPLIES 0