cancel
Showing results for 
Search instead for 
Did you mean: 

ADC reads on STM32F030 not restarting reliably - weird timing issue?

Jim Seymour
Senior

NOTE: I have built a test project in STM32CubeIDE to demonstrate this issue (see attached). (Change "POSITION" from 1 to 2 to demonstrate the bug - see line 164 in main.c).

I am reading multiple ADC channels on a custom board with a STM32F030RCT6TR. I have 8 channels defined in my Cube project and am using DMA and the callback function to know when it's finished.

At startup, I call HAL_ADC_Start_DMA() to get things going. Then, in my main loop I look for completion by examining a variable set by the callback function. If the readings are complete, I dump their values out a serial port and then start another conversion with HAL_ADC_Start_DMA().

The weirdness is that if I run these reads as fast as possible, they work OK. However, if I only check them every 500 milliseconds, I see only one read - and the subsequent read never completes.

Any thoughts?

12 REPLIES 12
Jim Seymour
Senior

I think I have an answer to this...

I had some old debug code left in my serial routines. This code pulsed two GPIO pins during the interrupt handler - both of which happened to be defined as ADC channels. Once I deleted that debug code, my test code started working.

So... Nevermind...

I don't understand how would this result in the described behaviour.

If the said two pins are set as Analog in GPIO_MODER, the output driver should be disconnected, i.e. writing to the respective ODR or BSRRR/BRR bits should do literally nothing.

JW

mckenney
Senior

On the F4 series, I observed that the ADC won't start if the Overrun bit is set. You might want to check if this is true of the F0 series as well.

I'm no longer convinced that this was the issue - and I'm having trouble duplicating the original problem.

Jim Seymour
Senior

I don't have a good explanation of what changed, but I'm no longer getting stalled ADC reads. However, I'm only seeing results in the first field of my buffer.

I've tried every combination of options that makes sense. Some give me stalled restarts. Others seem to work repeatedly. But none give me data other than the first channel (or at least the first 16-bit field).

Does anyone have a STM32CubeIDE project example that does multichannel ADC reads on the STM32F030 family? (I don't really care if it's Polled, IT, or DMA - though I've been trying DMA exclusively so far).

I know that ST provides an ADC example - but it's only one channel and isn't built using their new IDE.

Thanks.

Jim Seymour
Senior

I gave up on using the HAL functions to do ADC readings with DMA and implemented a crude polling method. I got it to work - but it's ugly. (I have to disable other interrupts or else I get ADC overruns).

And while I have a solution that *could* be considered "good enough", I'd really like to get the DMA method working.

What I'm seeing is that the calls to the various HAL_ADC_* functions return success - but I only get the first completion callback. (And even then, the data in my buffer is incorrect).

Here's the full sequence:

  1. During startup, I call HAL_ADC_Init() and HAL_ADC_ConfigChannel() for each of my channels - this code is generated by the CubeIDE
  2. My init code then calls HAL_ADCEx_Calibration_Start() and HAL_ADC_Start_DMA() - with a small delay between them
  3. I receive two DMA interrupts. Shortly after the second, my HAL_ADC_ConvCpltCallback() is called
  4. My completion callback routine calls HAL_ADC_Stop_DMA() and then sets a flag variable
  5. In my main loop, when I see the completion flag is set, I report the values read and then call HAL_ADC_Start_DMA() again
  6. I receive two more DMA interrupts - but my HAL_ADC_ConvCpltCallback() is NOT called

I'm at a loss...

Ah... I'm getting an error callback. (HAL_ADC_ErrorCallback)

Anyone know what causes DMA errors?

DMA transfer request, when already at the end of a non-circular buffer?

Well, that might be something. But I would expect the call to HAL_ADC_StartDMA() would reset the pointer.