cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 ADC with DMA not working, Cache disabled

DCajigal
Associate III

Hi,

I am trying to use the ADC with DMA but the values on the buffer are not being updated.

Next i detail the steps that i have done:

  • Disabled the ICache and DCache.
  • Place the DMA buffer in a separate section in RAM_D2 with the address 0x30000000, so there souldnt be problems related to alignment.
  • Configure MPU in order to make the previous section not cacheable:
void MPU_Config(void)
{
	  MPU_Region_InitTypeDef MPU_InitStruct;
 
	  /* Disable the MPU */
	  HAL_MPU_Disable();
	  MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
	  MPU_InitStruct.BaseAddress      = 0x30000000;
	  MPU_InitStruct.Size             = MPU_REGION_SIZE_128KB;
	  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
	  MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
	  MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;
	  MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
	  MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
	  MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
	  MPU_InitStruct.SubRegionDisable = 0x00;
	  MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
	  HAL_MPU_ConfigRegion(&MPU_InitStruct);
	  /* Enable the MPU */
	  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
  • Place all the data sections, apart from the previous one, in RAM_D1.
  • Set DMA as circular and memory size as Half Word.
  • Enable the DMA and ADC global interruptions.

While running the ADC handler does not show any error, but the buffer remains empty, only updating the first index with trash values.

ADC Config:

static void MX_ADC1_Init(void)
{
 
  /* USER CODE BEGIN ADC1_Init 0 */
 
  /* USER CODE END ADC1_Init 0 */
 
  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC1_Init 1 */
 
  /* USER CODE END ADC1_Init 1 */
  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_16B;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 3;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_16;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_32CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_17;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_18;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
 
  /* USER CODE END ADC1_Init 2 */
 
}

ADC functions:

#define NADC_CH				((uint32_t)  3) 
#define NADC_SAMPLES		30 
#define ADC_VUSB_CH		0
#define ADC_5V_CH		        1
#define ADC_AUX_CH		        2
 
#if defined( __ICCARM__ )
  #define DMA_BUFFER \
      _Pragma("location=\".dma_buffer\"")
#else
  #define DMA_BUFFER \
      __attribute__((section(".dma_buffer")))
#endif
 
DMA_BUFFER uint16_t aADCxConvertedData[NADC_CH]; 
 
void adc_TimInt(TIM_HandleTypeDef *htim) {
	if (htim->Instance == _TIMER_ADC.Instance)
	{
		if (HAL_ADC_GetState(&_ADC) & HAL_ADC_STATE_READY) {
			if (HAL_ADC_Start_DMA(&_ADC, (uint32_t *)aADCxConvertedData, NADC_CH) != HAL_OK)
			{
			/* ADC conversion start error */
				Error_Hand();
			}
		}
 
	}
}
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *AdcHandle)
{
 
	/* Invalidate Data Cache to get the updated content of the SRAM on the second half of the ADC converted data buffer: 32 bytes */
//	SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[NADC_CH/2], NADC_CH);
 
	ubDmaTransferStatus = 1;
	adc_samples[ADC_VUSB_CH][ptr_adc_sample] = aADCxConvertedData[0];
	adc_samples[ADC_5V_CH][ptr_adc_sample] = aADCxConvertedData[1];
	adc_samples[ADC_AUX_CH][ptr_adc_sample] = aADCxConvertedData[2];
 
}

Any help would be really appreciated!

5 REPLIES 5
A.Caliskan
Associate II

YOU CAN ALSO USE ADC WITHOUT MPU,why did you use mpu

I have also tried wihtout MPU but it did not work

MHaji.1
Senior

Hi, Change MPU access in D2 RAM to sharable ...

BR

finally i changed it in order not to work with DMA... thanks for the help anyway

PAkRad
Associate III

Hello all.

We have developed in the past some devices using the STM32F4 and F7 families, with no issues using ADC+DMA+Timer Triggering with no effort (mostly tweaking the examples provided by ST and using the ioc Cube files).

However, we are trying to do the same, but we are finding big issues with the H7 family, in specific when we use more than one ADC (to my knowledge this example is not provided by ST yet). There are also problems with the DMA (we have reader and moved the data buffers to RAM D2 area) and we do not see the triggering of the DMA interrupt with the Timer trigger.

Maybe somebody in the forum knows one repository or is able to share a simple example of this structure (if it is based on STM32Cubemx ioc file the better, since for it will be easier to add things).

Thank you in advance.