cancel
Showing results for 
Search instead for 
Did you mean: 

WWDG watchdog resets system when being refreshed

SKled.1
Senior II

--------

EDIT: I added a minimal example project, 2 posts below.

--------

Using the WWDG on STM32L07, because I need the EWI interrupt it offers to prevent the reset in certain situatons.

(Edit: orig. config code + some obsolete explanation removed. The minimal example 2 posts below is more readable)

APB1 is at full 32MHz, which should, using max prescaler and WWDG:CR:T bits, yield a timeout of ca. 65ms.

I am setting the window low value same as refresh - according to the manual, figure 192, that should make the "refresh allowed" part the largest possible. I don't need/want a lower bound.

Refreshing the counter regularly in much less than that time.

Now, yet, I see a constantly resetting MCU.

1 ACCEPTED SOLUTION

Accepted Solutions
SKled.1
Senior II

OK I just saw that in the CFR:W, the highest bit was missing, that I added to CR:T with ORing WWDG_CR_T6, so actually the window was lower than the T value - I was somehow fixated on the bare values.

I added a readback of the APB1ENR after enabling the clock - seeing the HAL does this, commenting that it wants to wait somewhat after enabling the clock. Haven't looked yet why that's supposedly necessary.

This seems to work now.

View solution in original post

2 REPLIES 2
SKled.1
Senior II

I have made a minimal example project, for the Nucleo-L073RZ board. See attached zip file.

There, in the .ioc file / CubeIDE, I only configured RCC and RTC, generating LL code (not HAL).

The Watchdog is not touched in the .ioc file, but rather configured "by hand", in OurCode/App.cpp, so it is no mistake - it replicates my real project, where this was added as an afterthought and re-generating the code would create a mess.

EDIT: Within my minimal project, I now also tried CubeIDE generated, LL based code for setting up WWDG with NVIC and the same settings (63,63, div 8).

That also shows this problem. I.e. after the WWDG gets enabled, my breakpoint in the ISR is hit. (I have not re-uploaded the project for this CubeIDE-generated test)

The CubeIDE-generated main.c calls App_Run() from that file, which then configures the WWDG and runs the endless loop.

The WWDG interrupt will be raised soon after configuration.

Does anyone see anything wrong with the overall setup? Why does the IRQ / watchdog trigger?

Omitting the CubeIDE-generated RCC init code, here for convenience, the content of App.cpp:

#include "App.hpp"
#include "stm32l0xx.h" 
 
static void watchdog_init()
{
    DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_WWDG_STOP; // Make Watchdog stop when debugger halt!
    RCC->APB1ENR |= RCC_APB1ENR_WWDGEN; // Enable the clock for the thing, before giving it commands
 
    WWDG->SR &= ~ WWDG_SR_EWIF;
    NVIC_SetPriority(WWDG_IRQn, 0);
    NVIC_ClearPendingIRQ(WWDG_IRQn);
    NVIC_EnableIRQ(WWDG_IRQn);
    // Window is configured same as T, to effectively disable the lower bound
    WWDG->CFR = WWDG_CFR_EWI | (63u << WWDG_CFR_W_Pos) | (3u << WWDG_CFR_WDGTB_Pos);
    WWDG->CR  = WWDG_CR_WDGA | (63u << WWDG_CR_T_Pos)  | WWDG_CR_T6 ;
}
 
static void watchdog_refresh()
{
    WWDG->CR = WWDG_CR_T6 | (63u << WWDG_CR_T_Pos);
}
 
extern "C" void WWDG_IRQHandler()
{
    WWDG->SR &= ~ WWDG_SR_EWIF;
}
 
void App_Run()
{   watchdog_init();
 
    while (1)
    {   static constexpr unsigned N = 2000;//8000; // I tried different waiting times
        for (unsigned i=0; i<N;  ++i)
        {   __NOP();
        }
        watchdog_refresh();
    }
}

SKled.1
Senior II

OK I just saw that in the CFR:W, the highest bit was missing, that I added to CR:T with ORing WWDG_CR_T6, so actually the window was lower than the T value - I was somehow fixated on the bare values.

I added a readback of the APB1ENR after enabling the clock - seeing the HAL does this, commenting that it wants to wait somewhat after enabling the clock. Haven't looked yet why that's supposedly necessary.

This seems to work now.