osmo-opencm3-projects/libcommon/src/watchdog.c

71 lines
1.6 KiB
C

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/wwdg.h>
#include <libcommon/watchdog.h>
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;
}