#include "stm32f4xx_iwdg.h" #include "iwdg.h" #define LSI_FREQUENCY 32000 #define COUNT_LENGTH 12 #define COUNT_MASK ((1 << COUNT_LENGTH)-1) /** @brief IWDG Enable Watchdog Timer * The watchdog timer is started. * The timeout period defaults to 512 milliseconds * unless it has been previously defined. */ void iwdg_start(void) { IWDG_Enable(); } /** @brief IWDG Set Period in Milliseconds * * The countdown period is converted into count and prescale values. The maximum * period is 32.76 seconds; values above this are truncated. Periods less than 1ms * are not supported by this library. * * A delay of up to 5 clock cycles of the LSI clock (about 156 microseconds) * can occasionally occur if the prescale or preload registers are currently busy * loading a previous value. * * @param[in] period uint32_t Period in milliseconds (< 32760) from a watchdog * reset until a system reset is issued. */ void iwdg_set_period_ms(uint32_t period) { uint32_t count, prescale, reload, exponent; /* Set the count to represent ticks of the 32kHz LSI clock */ count = (period << 5); /* Strip off the first 12 bits to get the prescale value required */ prescale = (count >> 12); if (prescale > 256) { exponent = IWDG_Prescaler_256; reload = COUNT_MASK; } else if (prescale > 128) { exponent = IWDG_Prescaler_256; reload = (count >> 8); } else if (prescale > 64) { exponent = IWDG_Prescaler_128; reload = (count >> 7); } else if (prescale > 32) { exponent = IWDG_Prescaler_64; reload = (count >> 6); } else if (prescale > 16) { exponent = IWDG_Prescaler_32; reload = (count >> 5); } else if (prescale > 8) { exponent = IWDG_Prescaler_16; reload = (count >> 4); } else if (prescale > 4) { exponent = IWDG_Prescaler_8; reload = (count >> 3); } else { exponent = IWDG_Prescaler_4; reload = (count >> 2); } /* Avoid the undefined situation of a zero count */ if (count == 0) { count = 1; } while (IWDG_GetFlagStatus(IWDG_FLAG_PVU) != RESET) ; IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(exponent); while (IWDG_GetFlagStatus(IWDG_FLAG_RVU) != RESET) ; IWDG_SetReload(reload & COUNT_MASK); } /** @brief IWDG reset Watchdog Timer * * The watchdog timer is reset. The counter restarts from the value in the reload * register. */ void iwdg_reset(void) { IWDG_ReloadCounter(); }