Skip to main content
Stecklo
Senior
November 11, 2019
Solved

DMA + ADC doesn't work

  • November 11, 2019
  • 25 replies
  • 15528 views

CubeIDE 1.1.0

STM32Cube_FW_WB_V1.3.0

Trying to make DMA transfer ADC results.

I'm putting code in main() after MX_..._Init() and before while(1) {}

HAL_ADC_Start_IT(&hadc1); works fine

HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel2, (uint32_t) src, (uint32_t) dest, 40); works fine too

but

HAL_ADC_Start_DMA(&hadc1, dest, 10) doesn't work as it should

ADC is activated and keeps throwing Overrun_Error

But DMA doesn't transfer anything

static void MX_ADC1_Init(void)
{
 
 /* USER CODE BEGIN ADC1_Init 0 */
 
 /* USER CODE END ADC1_Init 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_DIV8;
 hadc1.Init.Resolution = ADC_RESOLUTION_12B;
 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
 hadc1.Init.LowPowerAutoWait = DISABLE;
 hadc1.Init.ContinuousConvMode = ENABLE;
 hadc1.Init.NbrOfConversion = 1;
 hadc1.Init.DiscontinuousConvMode = DISABLE;
 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
 hadc1.Init.DMAContinuousRequests = ENABLE;
 hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
 hadc1.Init.OversamplingMode = ENABLE;
 hadc1.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_16;
 hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_NONE;
 hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
 hadc1.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
 if (HAL_ADC_Init(&hadc1) != HAL_OK)
 {
 Error_Handler();
 }
 /** Configure Regular Channel 
 */
 sConfig.Channel = ADC_CHANNEL_5;
 sConfig.Rank = ADC_REGULAR_RANK_1;
 sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
 sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED;
 sConfig.OffsetNumber = ADC_OFFSET_NONE;
 sConfig.Offset = 0;
 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN ADC1_Init 2 */
 
 /* USER CODE END ADC1_Init 2 */
 
}
static void MX_DMA_Init(void) 
{
 
 /* DMA controller clock enable */
 __HAL_RCC_DMAMUX1_CLK_ENABLE();
 __HAL_RCC_DMA1_CLK_ENABLE();
 
 /* Configure DMA request hdma_memtomem_dma1_channel2 on DMA1_Channel2 */
 hdma_memtomem_dma1_channel2.Instance = DMA1_Channel2;
 hdma_memtomem_dma1_channel2.Init.Request = DMA_REQUEST_MEM2MEM;
 hdma_memtomem_dma1_channel2.Init.Direction = DMA_MEMORY_TO_MEMORY;
 hdma_memtomem_dma1_channel2.Init.PeriphInc = DMA_PINC_ENABLE;
 hdma_memtomem_dma1_channel2.Init.MemInc = DMA_MINC_ENABLE;
 hdma_memtomem_dma1_channel2.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 hdma_memtomem_dma1_channel2.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_memtomem_dma1_channel2.Init.Mode = DMA_NORMAL;
 hdma_memtomem_dma1_channel2.Init.Priority = DMA_PRIORITY_LOW;
 if (HAL_DMA_Init(&hdma_memtomem_dma1_channel2) != HAL_OK)
 {
 Error_Handler( );
 }
 
 /* DMA interrupt init */
 /* DMA1_Channel1_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 15, 0);
 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 if(hadc->Instance==ADC1)
 {
 /* USER CODE BEGIN ADC1_MspInit 0 */
 
 /* USER CODE END ADC1_MspInit 0 */
 /* Peripheral clock enable */
 __HAL_RCC_ADC_CLK_ENABLE();
 
 __HAL_RCC_GPIOA_CLK_ENABLE();
 /**ADC1 GPIO Configuration 
 PA0 ------> ADC1_IN5
 PA1 ------> ADC1_IN6 
 */
 GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
 /* ADC1 DMA Init */
 /* ADC1 Init */
 hdma_adc1.Instance = DMA1_Channel1;
 hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
 hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
 hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
 hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
 hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
 hdma_adc1.Init.Mode = DMA_NORMAL;
 hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
 if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
 {
 Error_Handler();
 }
 
 __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
 
 /* USER CODE BEGIN ADC1_MspInit 1 */
 
 /* USER CODE END ADC1_MspInit 1 */
 }
 
}

I've tried this confuguration on PNUCLEO-WB55 Dongle in far more complex code and it worked. Now I'm using custom board and just main() body. But I think the board should not matter as DMA is totally internal thing

This topic has been closed for replies.
Best answer by Stecklo

The answer is to put

MX_DMA_Init();

before

MX_ADC1_Init();

As the first one calls

__HAL_RCC_DMAMUX1_CLK_ENABLE();

 __HAL_RCC_DMA1_CLK_ENABLE();

25 replies

gretis
Visitor II
September 30, 2021

Now is the end of 2021 and problem still present. Thanks to published resolution!

ad ho
Associate II
October 6, 2021

How is that possible I get the same bug with same resolution after 2 years??? Come on...!

Amel NASRI
ST Technical Moderator
October 6, 2021

Hi @gretis​  & @Community member​ ,

Problem was fixed, but unfortunately appeared again as a regression with latest STM32CubeMX version (6.3.0).

I assume that it will be fixed in coming version of the tool. @Khouloud OTHMAN​  can confirm about this.

Sorry for such inconvenience.

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
ad ho
Associate II
October 6, 2021

Thanks for the fast confirmation! at least this is reassuring :)

good day to you

eg7963
Associate III
October 21, 2021

This is still true at this time.

Lost a couple hours figuring out why a previous program was working ( where i already applied the correction and already lost couple hours a few months ago figuring out why the SPI wasn't working) and not the last one i generated with nearly same code but differnet MCU. Luckily i came accros that thread that reminded me the fix I made in the previous program.

Used the latest STM32CubeMX V6.3.0 and latest definition for STM32H7 MCUs.

The easiest way to avoid that to happen when knowing the problem is by sorting the init function in STM32CubeMX>ProjectManager> Advanced Settings

Otherwise the problem reappears by each new regeneration of the project

Javier1
Principal
January 18, 2022

thanks for the tip, this bug is also present in stm32wb and stm32f2xx packages that i know of

hit me up in https://www.linkedin.com/in/javiermuñoz/
Amel NASRI
ST Technical Moderator
January 18, 2022

Dear @eg7963​ & @Javier Muñoz​ ,

A pinned post is published some time ago under STM32CubeMX topic in order to describe the permanent solution for this regression issue.

Please have a look to MX_DMA_Init order in the main.c file generated by STM32CubeMX, How to fix?.

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.