You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

82 lines
2.4 KiB

#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();
}