Imagine this scenario:

You are using a timer driven ADC in DMA mode, nothing special. Now, because you are interested in having a Watchdog, you also enable the ADC Global Interrupt in CubeIDE (enabling this is necessary so the watchdog triggers the interrupt).

Now imagine the DMA finishes transfering: the DMA will call "HAL_ADC_ConvCpltCallback", BUT since we also enabled global interrupts for the watchdog, HAL_ADC_IRQHandler will also be called, and this function will also call "HAL_ADC_ConvCpltCallback".

So, do you end up having "HAL_ADC_ConvCpltCallback" called twice? One by the DMA and another one by the IRQ handler?

Things get more confusing when DMA fails and an overrun happens in the ADC. The DMA will by itself call "HAL_ADC_ErrorCallback" due to transfer error, BUT because we also have an overrun, HAL_ADC_IRQHandler will also call "HAL_ADC_ErrorCallback" due to overrun error.

So, you end up having "HAL_ADC_ErrorCallback" called twice? One by the DMA transfer error and another one by the IRQ handler due to overrun?

I have tried to find the answer for this in the STM32 manual, also the HAL manual and by directly looking at HAL code but could not figure it out.

  • \$\begingroup\$ How likely scenario that is? Who would use it and for what? Have you tried it yourself? \$\endgroup\$
    – Justme
    Dec 20, 2020 at 22:01
  • \$\begingroup\$ Justme: I would say this is extremely likely to happen. For example, if the ADC is configured in continuous conversion mode and the DMA fails: the DMA will call HAL_ADC_ErrorCallback, but because the ADC is still active and the DMA is stopped, an overrun will happen and the IRQ handler will also call HAL_ADC_ErrorCallback, so the callback is called twice. My question is more "what would happen if you have DMA and interrupts taking into account that both handlers call the same callbacks" \$\endgroup\$
    – sauz
    Dec 20, 2020 at 22:12
  • 1
    \$\begingroup\$ but why would the DMA fail to begin with? What would cause it to fail all of a sudden if it has been working for seconds, hours or days? If it does not work then there is a bug in the software that must be fixed. What prevents you from testing what happens by manually causing a DMA failure (how can a DMA transfer even fail?). \$\endgroup\$
    – Justme
    Dec 21, 2020 at 10:04
  • \$\begingroup\$ The HAL implements code in case the DMA fails, so ST wrote that code because the DMA can fail. Also, according to the book Mastering STM32, the DMA channel can fail in non reproducible scenarios when the DMA channel is heavily used by other periferials, so the DMA request done by the ADC is not served in time. I would like to simulate a DMA transfer error to debug and see what happens but don't know how to force an error. Also forget about error, what about the conversion complete callback? Is it called twice? \$\endgroup\$
    – sauz
    Dec 21, 2020 at 11:49

1 Answer 1


I managed to simulate a DMA transfer error, with the ADC configured in continuous conversion mode and indeed, HAL_ADC_ErrorCallback is called twice: one by the DMA because of the transfer error and another one because just after the DMA auto-deactivation due to that error, an overrun happens in the ADC that is captured by the IRQ handler.

As for the other callbacks, half conversion complete and conversion complete do not seem to be called twice, just once, by the DMA handler.

  • \$\begingroup\$ I am curious to know how you simulated a DMA transfer error?. I am having an intermittent issue with adc DMA it runs fine in circular mode for days and then the HAL_Adc_Err... callback gets called and DMA interrupts stops firing for good. Not sure if you came across such issue and recovered ?. Thanks \$\endgroup\$
    – alzughoul
    May 11, 2021 at 9:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.