#include #include #include void watchdog_refresh(void) { /* set to the maximum a 7-bit counter supports */ WWDG_CR = 0x7f; } #ifdef DEBUG_WATCHDOG void WWDG_IRQHandler(void) { WWDG_ClearFlag(); /* instead of triggering a reset, we hang in this endless loop to wait * for openocd/gdb attach and investigation of the stack */ watchdog_fini(); printf("WWDG\r\n"); while(1) {} } #endif void watchdog_fini(void) { /* documentation claims we cannot stop it. lol. */ watchdog_refresh(); rcc_periph_clock_disable(RCC_WWDG); } int watchdog_init(void) { #ifdef RCC_DBGMCU /* make sure the watchdog stops during JTAG stop */ rcc_periph_clock_enable(RCC_DBGMCU); DBGMCU_CR |= DBGMCU_CR_WWDG_STOP #endif rcc_periph_clock_enable(RCC_WWDG); /* Set WWDG clock to (PCLK1/4096)/8 */ /* At 8 MHz PCLK1 this is 244.14 Hz */ WWDG_CFR = (WWDG_CFR & ~WWDG_CFR_WDGTB_LSB) | WWDG_CFR_WDGTB_CK_DIV8; #ifdef DEBUG_WATCHDOG NVIC_InitTypeDef nvic_init = { .NVIC_IRQChannelPriority = 0, .NVIC_IRQChannel = WWDG_IRQn, .NVIC_IRQChannelCmd = ENABLE, }; WWDG_EnableIT(); NVIC_Init(&nvic_init); #endif /* highest possible window value */ WWDG_CFR = (WWDG_CFR & WWDG_CFR_WDGTB_LSB) | 0x7f; /* this means, that we have 0x80-0x40= 64 cycles of the 214.14Hz * watchdog clock tore-fresh the counter, before it reaches * 0x3F, at which point a reset will be issued to the CPU. If my * calculations are correct, this is 0.262 seconds, i.e. * refreshing every time the systick timer fires (and we return * to the main loop) should be sufficient. */ WWDG_CR = WWDG_CR_WDGA | 0x7f; return 0; }