STM32 Explored: Window Watchdog

A look at the embedded software supervisor

Kunal Salvi
3 min readFeb 15, 2020

No one can predict what will happen to an embedded device when deployed on the field. MCUs are not perfect and they tend to get locked up while executing code which can lead to problematic situations depending upon the application.

To counter this, windowed watchdog (WWDG) timers are used. WWDG keeps track of the time of code execution and generates an MCU reset. Software faults are usually generated by external interference or unplanned logical conditions. These can cause the application to abandon its normal sequence. STM32F103 provides an embedded window watchdog timer to supervise the code execution. Below is the block diagram of the embedded window watchdog timer:

Fig 1: Watchdog Block diagram

WWDG has a programmable free-running down-counter, a conditional reset mechanism that resets the timer if the counter value becomes less than 0x40 or if the counter is reloaded outside of the window, and an early wake-up interrupt. WWDG is activated by setting the WDGA bit in the WWDG_CR register. When the down-counter falls from 0x40 to 0x3F, a system reset is generated. The software should reload the counter before it reaches 0x40 and when it is greater than the value stored in the window register, this is shown in Fig. 2 below.

Fig 2: Watchdog Timing Diagram

The WWDG_CR register must be written at regular intervals during normal operations to avoid MCU reset and this should be done only when the counter value is less than WWDG_CR value and more than 0x40. As the WWDG_CR register is a 7-bit register, the input values for WWDG_CR will range from 64 to 127. The 6th bit of WWDG_CR should always be written 1 while updating WWDG_CR to avoid generating an immediate interrupt.

The WWDGA of STM32F103C8T6 is clocked by APB1 which runs at 36 MHz and is divided by prescaler. The clock is divided even more by WDGTB prescaler and its value is selected by WDGTB bits in the WWDG_CR register. This clock then operates the counter. The WWDG timeout value can be calculated by the formula given below :

Fig 3: Watchdog timeout formula

Refer to the reference manual for a proper example.

Driver

This driver takes the value in milliseconds after which it generates a reset.

 int timeout;
void Window_Watchdog_Init(float milli_seconds)
{
RCC -> APB1ENR |= RCC_APB1ENR_WWDGEN;
if(milliseconds < 8.0)
{
WWDG -> CFR &= ~WWDG_CFR_WDGTB;
timeout = (uint8_t)((( milli_second * 36000.0 )/(4096.0))-1.0);
WWDG -> CR |= (1 << 6) | timeout;
WWDG -> CFR |= (timeout - 20);
}
else if(milli_second < 15.0 && milli_second > 8.0)
{
WWDG -> CFR |= WWDG_CFR_WDGTB_0;
timeout = (uint8_t)((( milli_second * 36000.0 )/(4096 * 2))-1);
WWDG -> CR |= (1 << 6) | timeout;
WWDG -> CFR |= (timeout - 20);
}
else if(milli_second >15.0 && milli_second <30.0)
{
WWDG -> CFR |= WWDG_CFR_WDGTB_1;
timeout = (uint8_t)((( milli_second * 36000.0 )/(4096 * 4))-1);
WWDG -> CR |= (1 << 6) | timeout;
WWDG -> CFR |= (timeout - 20);
}
else if(milli_second >29.0 && milli_second < 59.0)
{
WWDG -> CFR |= WWDG_CFR_WDGTB_1 | WWDG_CFR_WDGTB_0;
timeout = (uint8_t)((( milli_second * 36000.0 )/(4096 * 8))-1);
WWDG -> CR |= (1 << 6) | timeout;
WWDG -> CFR |= (timeout - 20);
}
WWDG -> CR |= WWDG_CR_WDGA;
}
void Window_Watchdog_Reload(void)
{
int time1 = ( WWDG -> CFR ) & (0x7F);
int counter = (WWDG -> CR) & (0x3F);
if(counter < time 1 && counter > 63)
{
WWDG -> CR |= (1 << 6) | timeout;
}
}

Link to GitHub: https://github.com/embeddedalpha

STM32F1 Reference Manual: https://bit.ly/2Ss7jmE

Note: Corrections will be made in future if necessary.

--

--

Kunal Salvi
Kunal Salvi

Written by Kunal Salvi

Embedded Systems Engineer | Roboticist | Researcher | Innovator

No responses yet