2019-11-11 06:49 AM
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
Solved! Go to Solution.
2019-11-15 02:26 PM
In case it helps, I've just spent the last two days debugging this issue on a STM32F030RC.
In my code (also generated by CubeIDE), MX_DMA_Init() does very little (enables the clock and interrupt handler). Later, MX_ADC_Init() calls HAL_ADC_Init() - which calls HAL_ADC_MspInit() - which calls HAL_DMA_Init().
This last function tries to set the CCR register - but it has no effect. (The register remains zero). I'm guessing this is because __HAL_RCC_DMA1_CLK_ENABLE() hasn't been called (?)
Regardless, if I move MX_DMA_Init() just before MX_ADC_Init(), everything seems to work.
Definitely a bug in CubeIDE - but at least I have a workaround.
2019-11-15 02:53 PM
One last comment: In my case, adding __HAL_RCC_DMA1_CLK_ENABLE(); to the "USER CODE BEGIN SysInit" block in main() also does the trick.
This fix has the advantage of allowing future code generation cycles without having to manually edit the results.
2020-01-12 04:03 PM
Hey @Nesrine.JLASSI
This still hasn't been fixed in CubeMX v5.5.0
I spent many hours debugging
2021-09-30 05:05 AM
Now is the end of 2021 and problem still present. Thanks to published resolution!
2021-10-06 02:43 AM
How is that possible I get the same bug with same resolution after 2 years??? Come on...!
2021-10-06 03:03 AM
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 Accept as Solution on the reply which solved your issue or answered your question.
2021-10-06 03:06 AM
Thanks for the fast confirmation! at least this is reassuring :)
good day to you
2021-10-15 11:26 AM
Hey @Nesrine.JLASSI (ST Employee),
had still the same issue in CubeMX 6.3.0-RC5 in CubeIDE 1.7.0.
Glad I found this thread!
Best regards,
Peter
2021-10-21 02:13 AM
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
2022-01-17 11:32 AM
I have this board:
NUCLEO-L452RE
I used this:
STM32CubeIDE
Version: 1.8.0
Build: 11526_20211125_0815 (UTC)
I followed this tutorial
Getting Started with STM32 - Working with ADC and DMA (digikey.com)
I only got one value in the adc_buf, never more.
I swapped the order of inits and it works, but breaks again each time I redo the IOC file.
The issue still exists, please help.