5.22 WWDG Guide
This chapter describes the file composition and the 8 public functions of the WWDG driver in the N32G41x standard peripheral library: prescaler and window value configuration, counter loading and watchdog start, and early wakeup interrupt and flag handling, together with the WWDG_Reset example. Read the refresh window, count-time table and register bit definitions together with the “Window watchdog (WWDG)” chapter of the user manual, and take the errata sheet as the authority on known chip issues.
5.22.1 Related files
| Relative path | Purpose |
|---|---|
firmware/n32g41x_std_periph_driver/inc/n32g41x_wwdg.h |
Defines the prescaler division macros and the bit masks of WWDG_CFG, WWDG_CTRL and WWDG_STS, and declares 8 public functions in the reset, configuration, enable and interrupt/flag sections |
firmware/n32g41x_std_periph_driver/src/n32g41x_wwdg.c |
Implements those 8 functions: read-modify-write of WWDG_CFG, counter loading and start through WWDG_CTRL, and access to the early wakeup interrupt and flag |
projects/n32g41x_EVAL/examples/WWDG/ |
WWDG example root directory, containing the single example WWDG_Reset |
projects/n32g41x_EVAL/examples/WWDG/WWDG_Reset/ |
Directory composition of that example: MDK-ARM/, EWARM/, inc/, src/, readme.txt |
projects/n32g41x_EVAL/bsp/ |
Board support files used by the example: evaluation-board LED definitions, the millisecond delay function and the log output interface |
5.22.2 API reference
The following 8 public functions are listed in the declaration order of n32g41x_wwdg.h in 4 groups; each entry gives a summary and the original comment above the function in n32g41x_wwdg.c.
Reset
WWDG_Reset
Configuration
WWDG_SetPrescalerDiv, WWDG_SetWValue, WWDG_SetCnt
Enable
WWDG_EnableInt, WWDG_Enable
Interrupt and flags
WWDG_GetEWINTF, WWDG_ClrEWINTF
void WWDG_Reset(void)Resets the WWDG peripheral registers to their default reset values.
name WWDG_Reset.
fun Resets the WWDG peripheral registers to their default reset values.
return none
Use note: The implementation restores the WWDG registers to their default reset values through the RCC APB1 peripheral reset.
void WWDG_SetPrescalerDiv(uint32_t WWDG_Prescaler)Set the WWDG Prescaler Division Value.
name WWDG_SetPrescalerDiv.
fun Set the WWDG Prescaler Division Value.
param WWDG_Prescaler :
- WWDG_PRESCALER_DIV1 WWDG Counter Clock (PCLK1 / 4096) / 1
- WWDG_PRESCALER_DIV2 WWDG Counter Clock (PCLK1 / 4096) / 2
- WWDG_PRESCALER_DIV4 WWDG Counter Clock (PCLK1 / 4096) / 4
- WWDG_PRESCALER_DIV8 WWDG Counter Clock (PCLK1 / 4096) / 8
return none
Use note: The implementation rewrites only the TIMERB[1:0] bits of WWDG_CFG and keeps the other bits, so it can be called again to change the division without affecting the window value.
void WWDG_SetWValue(uint16_t WindowValue)Set the WWDG Window Value.
name WWDG_SetWValue.
fun Set the WWDG Window Value.
param WindowValue : WWDG Window Value
The value range of this parameter :
- 0x0040 ~ 0x3FFF
return none
Use note: The implementation ANDs WindowValue with 0x3FFF and writes it to W[13:0] of WWDG_CFG, leaving the EWINT and TIMERB[1:0] bits unchanged.
void WWDG_SetCnt(uint16_t Counter)Set the WWDG Counter Value.
name WWDG_SetCnt.
fun Set the WWDG Counter Value.
param Counter : WWDG Counter value
The value range of this parameter :
- 0x40 ~ 0x3FFF
return none
Use note: The implementation ANDs Counter with 0x3FFF and writes the result directly to WWDG_CTRL, with no read-modify-write; writing 0 to the ACTB bit does not change whether the watchdog is enabled.
void WWDG_EnableInt(void)Enable WWDG Early Wakeup interrupt(EWINT).
name WWDG_EnableInt.
fun Enable WWDG Early Wakeup interrupt(EWINT).
return none
Use note: The implementation sets the EWINT bit of WWDG_CFG and leaves the division and window value in the same register unchanged.
void WWDG_Enable(uint16_t Counter)Set the WWDG Counter Value and Enable WWDG.
name WWDG_Enable.
fun Set the WWDG Counter Value and Enable WWDG.
param Counter : WWDG Counter value
The value range of this parameter :
- 0x40 ~ 0x3FFF
return none
Use note: The implementation writes the ACTB bit together with the masked Counter into WWDG_CTRL, loading the counter and enabling the watchdog in one step.
FlagStatus WWDG_GetEWINTF(void)Get WWDG Early Wakeup Interrupt Flag.
name WWDG_GetEWINTF.
fun Get WWDG Early Wakeup Interrupt Flag.
return SET or RESET
Use note: The implementation reads the EWINTF bit of WWDG_STS and returns SET when it is set, otherwise RESET.
void WWDG_ClrEWINTF(void)Clear WWDG Early Wake-up Interrupt Flag.
name WWDG_ClrEWINTF.
fun Clear WWDG Early Wake-up Interrupt Flag.
return none
Use note: The implementation writes 0 to WWDG_STS, that is, it clears the EWINTF bit by writing 0 to it.
5.22.3 Demo descriptions
This section describes the single WWDG example: WWDG_Reset refreshes the counter inside the window so that LED3 keeps flashing, and lights LED1 when a refresh falls outside the window and resets the system.
5.22.3.1 WWDG_Reset window watchdog reset
Example directory: projects/n32g41x_EVAL/examples/WWDG/WWDG_Reset/
Enable the WWDG and GPIO clocks and print the example banner→configure LED1 and LED3 as push-pull outputs→check whether the previous reset came from WWDG and light LED1→set the division and window value and start the watchdog with 127→toggle LED3 every 45 ms and reload the counter inside the window
| Item | Source analysis |
|---|---|
| Function | Configures the WWDG prescaler, window value and counter and refreshes it periodically inside the window, so that LED3 keeps flashing while the program runs normally; it lights LED1 when the previous reset was caused by WWDG. When a refresh falls outside the window the system keeps resetting and LED3 no longer flashes normally. |
| Source files | src/main.c: main plus LedInit, LedOn, LedOff and LedBlink;inc/main.h: includes the WWDG, GPIO, RCC and log headers;src/n32g41x_it.c, inc/n32g41x_it.h: interrupt service routines;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects.The LED pin macros come from bsp/inc/n32g41x_stb.h and SysTick_Delay_Ms from bsp/src/delay.c. |
| Key configuration | Clock source HSE+PLL, 80 MHz for N32G412 and 96 MHz for N32G415;WWDG_SetPrescalerDiv(WWDG_PRESCALER_DIV8) sets the counter clock to (PCLK1/4096)/8, WWDG_SetWValue(80) sets the window value and WWDG_Enable(127) starts the watchdog with an initial counter of 127.LED1 is PA1 and LED3 is PB1, both configured as push-pull outputs. |
| Program and data path | main: log_init prints --- WWDG demo reset ---;WWDG_ClrEWINTF clears the early wakeup flag;LedInit initialises LED1 and LED3 and turns them off;RCC_CTRLSTS_FLAG_WWDGRSTF is read to find the reset source, and on a hit LedOn lights LED1 and RCC_ClearResetFlag clears it;after a 1 s delay it enables the WWDG clock and configures the watchdog; in while(1) LedBlink toggles LED3, 45 ms (N32G412) or 35 ms (N32G415) elapse, and WWDG_SetCnt(127) reloads the counter inside the window. |
| Main APIs | WWDG_ClrEWINTF, WWDG_SetPrescalerDiv, WWDG_SetWValue, WWDG_Enable, WWDG_SetCnt, RCC_EnableAPB1PeriphClk, RCC_GetFlagStatus, RCC_ClearResetFlag, GPIO_InitStruct, GPIO_InitPeripheral, GPIO_SetBits, GPIO_ResetBits, GPIO_TogglePin |
| Verification | After power-up the serial port prints --- WWDG demo reset --- and LED3 keeps flashing, which shows that the window value is refreshed normally;after the SysTick_Delay_Ms argument is changed to fall outside the window time the system keeps resetting, and after each reset LED1 is lit and the serial port prints reset by WWDG. |
| Use note | A small window value puts the system into a frequent reset state that can prevent normal program download; the example adds a 1 s delay before enabling the WWDG, and raising the BOOT0 pin is an alternative. The supported chips are N32G412x8L7, N32G412xBL7, N32G415x8L7 and N32G415xBL7; the development environments are KEIL MDK-ARM V5.34 or IAR EWARM 8.50.1. |
Core-code walkthrough and porting
The example first checks the source of the previous reset and lights LED1 as an indicator, then configures the window watchdog and finally feeds it periodically in the main loop.
Data path: main → WWDG_ClrEWINTF clears the early wakeup flag → LedInit initialises LED1 and LED3 → RCC_GetFlagStatus checks the WWDG reset flag → RCC_EnableAPB1PeriphClk opens the WWDG clock → WWDG_SetPrescalerDiv, WWDG_SetWValue and WWDG_Enable configure and start the watchdog → WWDG_SetCnt reloads the counter inside the window → LED3 flashes and LED1 indicates the reset
1. Board macros give the port, pin and clock of the two LEDs. The evaluation-board LED definitions live in the BSP header, and the example references them through LEDx_PORT and LEDx_PIN, so only these macros change when the board changes.
#define LED1_STB
#define LED1_PORT GPIOA
#define LED1_PIN GPIO_PIN_1
#define LED1_CLOCK RCC_AHB_PERIPH_GPIO
#define LED1_CLOCK_ENABLE RCC_EnableAHBPeriphClk(LED1_CLOCK, ENABLE)
#define LED1_ON_STATE Bit_SET
#define LED3_STB
#define LED3_PORT GPIOB
#define LED3_PIN GPIO_PIN_1
#define LED3_CLOCK RCC_AHB_PERIPH_GPIO
#define LED3_CLOCK_ENABLE RCC_EnableAHBPeriphClk(LED3_CLOCK, ENABLE)
#define LED3_ON_STATE Bit_SET
When the LED pins change, update LED1_PORT, LED1_PIN, LED3_PORT and LED3_PIN together; the example code itself needs no change.
2. LedInit opens the port clock and configures the pin as a push-pull output. It starts from the structure defaults, sets the pin and output mode, and finally writes the result with GPIO_InitPeripheral.
void LedInit(GPIO_Module* GPIOx, uint16_t Pin)
{
GPIO_InitType GPIO_InitStructure;
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_GPIO, ENABLE);
GPIO_InitStruct(&GPIO_InitStructure);
GPIO_InitStructure.Pin = Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);
Moving to another port or output type means changing the GPIO_Module, Pin and GPIO_Mode values together.
3. After reset the example clears the early wakeup flag and checks the source of the previous reset. It first clears WWDG_STS.EWINTF, then reads the RCC WWDG reset flag; on a hit it lights LED1 to mark that the watchdog caused the last reset and clears that flag.
/* Clear WWDG early wakeup interrupt flag */
WWDG_ClrEWINTF();
/* Initialize LED1 and LED3 */
LedInit(LED1_PORT, LED1_PIN);
LedInit(LED3_PORT, LED3_PIN);
LedOff(LED1_PORT, LED1_PIN);
LedOff(LED3_PORT, LED3_PIN);
/* Check if the system has resumed from WWDG reset */
if (RCC_GetFlagStatus(RCC_CTRLSTS_FLAG_WWDGRSTF) != RESET)
{
/* WWDG reset flag set */
LedOn(LED1_PORT, LED1_PIN);
log_info("reset by WWDG\n");
RCC_ClearResetFlag();
}
else
{
LedOff(LED1_PORT, LED1_PIN);
}
When the indicator LED changes, update the pin arguments passed to LedOn and LedOff after the reset-source check.
4. The watchdog is configured and started one second later. The APB1 WWDG clock is enabled first, then the division by 8 and the window value 80 are set and the watchdog is started with an initial counter of 127; the two branches compile only under their own macro.
SysTick_Delay_Ms(1000);
/* WWDG configuration */
/* Enable WWDG clock */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_WWDG, ENABLE);
#ifdef N32G412
/*********************** For N32G412 ***********************/
/* WWDG clock counter = (PCLK1(40MHz)/4096)/8 = 1220Hz (~0.82ms per count)
WWDG timeout = ~0.82ms * (127-63) = ~52ms
WWDG window = ~0.82ms * (127-80) = ~38ms
Allowed feed window: counter 80~63 (38ms~52ms after last feed) */
WWDG_SetPrescalerDiv(WWDG_PRESCALER_DIV8);
WWDG_SetWValue(80);
WWDG_Enable(127);
#endif /* N32G412 */
#ifdef N32G415
/*********************** For N32G415 ***********************/
/* WWDG clock counter = (PCLK1(48MHz)/4096)/8 = 1464.8Hz (~683us per count)
WWDG timeout = ~683us * (127-63) = ~43.7ms
WWDG window = ~683us * (127-80) = ~32.1ms
Allowed feed window: counter 80~63 (32.1ms~43.7ms after last feed) */
WWDG_SetPrescalerDiv(WWDG_PRESCALER_DIV8);
WWDG_SetWValue(80);
WWDG_Enable(127);
#endif /* N32G412 */
When porting to another PCLK1 frequency, follow the timeout formula to change the division, window value and initial counter together so that the refresh interval still falls inside the window.
5. The main loop toggles LED3 and reloads the counter inside the window. Each pass toggles LED3, waits 45 ms or 35 ms depending on the model, and then reloads the counter to 127, keeping the refresh inside the window.
while (1)
{
/* Feed the watchdog within the window */
LedBlink(LED3_PORT, LED3_PIN);
#ifdef N32G412
SysTick_Delay_Ms(45);
#endif /* N32G412 */
#ifdef N32G415
SysTick_Delay_Ms(35);
#endif /* N32G415 */
WWDG_SetCnt(127);
}
When the feed interval changes, change the SysTick_Delay_Ms argument and the WWDG_SetCnt value together so that a refresh never leaves the window.
Corresponding source files: src/main.c, projects/n32g41x_EVAL/bsp/inc/n32g41x_stb.h
5.22.4 Notes and troubleshooting
| Scenario | Check & action | Source |
|---|---|---|
| The watchdog resets immediately after it is enabled | Before the WWDG is enabled at least one bit of the high 8 bits T[13:6] of the counter value WWDG_CTRL.T[13:0] must be 1, otherwise the watchdog resets immediately after it is enabled;the counter argument passed to WWDG_Enable must therefore be greater than 0x40. |
User manual |
| A refresh outside the window causes a reset | The system is reset when the down-counter is refreshed before it reaches the window value W[13:0], or after T6 becomes 0;refresh must fall between W[13:0] and 0x3F. |
User manual |
| Clearing the early wakeup interrupt flag | WWDG_STS.EWINTF is set by hardware when the counter reaches 0x40 and must be cleared by software writing 0, while writing 1 has no effect;the flag is set even when the interrupt is not enabled and can be cleared with WWDG_ClrEWINTF. |
User manual |
| The watchdog cannot be turned off again | WWDG_CTRL.ACTB is set by software and cleared only by a reset;once enabled the watchdog stays enabled until a reset occurs, so it cannot be disabled by software. |
User manual |
| Counter behaviour when the core is halted | While the Cortex-M4 core is halted the WWDG counter either keeps counting or stops according to DBG_CTRL.WWDG_STOP: the counter stops when the bit is 1 and runs normally when it is 0. |
User manual |
| Timeout calculation | The timeout is T_WWDG = T_PCLK1 x 4096 x 2^TIMERB x (T[13:0] - 0x3F + 1);for N32G412 at PCLK1 = 40 MHz with TIMERB = 0 the maximum timeout is 1671.270 ms and the minimum 102.4 us, and for N32G415 at PCLK1 = 48 MHz they are 1392.725 ms and 85.3 us. |
User manual |
| Reserved bits and reset values | WWDG_CFG and WWDG_CTRL have a reset value of 0x00003FFF and WWDG_STS of 0x0000;the reserved bits of all three registers must keep their reset values. |
User manual |
The N32G412 and N32G415 series errata sheet V1.0.0 (2026.6.30) lists a single row for revision A chips with an empty errata link column, and lists no WWDG related entries.