Skip to main content
Associate II
September 1, 2025
Solved

ADC Analog Watchdog (AWD) Interrupt-Disable and Enable again at Runtime

  • September 1, 2025
  • 3 replies
  • 935 views

I'm using the AWD (STM32G0B0CE) with the HAL_ADC_LevelOutOfWindowCallback(), which works fine.
For not blocking the MCU completely, I'm disabeling the AWD-IT inside the Callback when fired for about 500ms:
LL_ADC_DisableIT_AWD1 (ADC1);
After the 500ms elapsed the AWD-IT is enabled again:
LL_ADC_EnableIT_AWD1 (ADC1);

This only works fine for about 2 times:
Start -> Fire IT -> DisableIT
-> 500ms
-> EnableIT -> Fire IT -> DisableIT
-> 500ms
-> IT stays completely disabled, though enabled again.

Any idea what I'm missing?
Thanks.

Best answer by waclawek.jan

ADC_CR.ADSTART can't be cleared by writing 0 to it; you stop conversions by setting ADC_CR.ADSTP and that in hardware clears ADC_CR.ADSTART. This is not immediate, you are supposed to read back ADC_CR.ADSTP until it autoclears.

But I personally wouldn't do that. I would try to avoid triggering the interrupt by setting the watchdog thresholds so that no ADC result triggers it.

JW

3 replies

waclawek.jan
Super User
September 2, 2025

> IT stays completely disabled,

How do you know? Have you observed the respective control flags in ADC? A generic "interrupt does not fire" guide here. As you appear to use Cube/HAL, the problem may be also in Cube/HAL's fabric, I don't use it but it's open source so you can check yoruself.

JW

ETXAuthor
Associate II
September 7, 2025
Thanks for your answer!
Reading the reference manual (rm0454-stm32g0x0) about the ADC interrupt enable register (ADC_IER), it says AWD1IE (Analog watchdog 1 interrupt enable) can only be set, when ADSTART bit is cleared.
The ADSTART bit is part of the ADC control register (ADC_CR) and is cleared by hardware after each conversion.
As I'm running in continous conversion mode, I suppose ADSTART is never cleared by hardware.
So tried to clear it manually while enabling AWD1IE again.
ADC1->CR &= ~ADC_CR_ADSTART; // Clear ADSTART in ADC control register (ADC_CR)
ADC1->IER|=ADC_IER_AWD1IE; // Enable AWD-interrupt in ADC IR enable register (ADC_IER)
 // LL_ADC_EnableIT_AWD1 (ADC1); // also doesn't work
ADC1->CR |= ADC_CR_ADSTART; // Set ADSTART in ADC control register (ADC_CR)
But unfortunately this does'nt also work, as clearing the ADSTART bit doesn't seem to work.
As I'm just new to STM32 MCUs, maybe someone could give some more advice.
Thanks!
waclawek.jan
waclawek.janBest answer
Super User
September 7, 2025

ADC_CR.ADSTART can't be cleared by writing 0 to it; you stop conversions by setting ADC_CR.ADSTP and that in hardware clears ADC_CR.ADSTART. This is not immediate, you are supposed to read back ADC_CR.ADSTP until it autoclears.

But I personally wouldn't do that. I would try to avoid triggering the interrupt by setting the watchdog thresholds so that no ADC result triggers it.

JW

ETXAuthor
Associate II
September 7, 2025

Thanks for your idea!
This really sounds a better solution....