cancel
Showing results for 
Search instead for 
Did you mean: 

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

ETX
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions
waclawek.jan
Super User

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

View solution in original post

4 REPLIES 4
waclawek.jan
Super User

> 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

ETX
Associate II
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
Super User

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

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