stm32: iwdg: correct calculation for all ranges.
The original calculations miscalculated ranges such as 512..639 or 1024..1151 or ... or 32768..32895 Reviewed-by: Karl Palsson <karlp@tweak.net.au>
This commit is contained in:
parent
239b4a4704
commit
4b16af6e24
@ -70,45 +70,44 @@ 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;
|
||||
const int PRESCALER_MAX = 6;
|
||||
uint8_t prescale = 0;
|
||||
|
||||
/* Set the count to represent ticks of the 32kHz LSI clock */
|
||||
count = (period << 5);
|
||||
/* Set the count to represent ticks of 8kHz clock (the 32kHz LSI clock
|
||||
* divided by 4 = lowest prescaler setting)
|
||||
*/
|
||||
uint32_t count = period << 3;
|
||||
|
||||
/* Strip off the first 12 bits to get the prescale value required */
|
||||
prescale = (count >> 12);
|
||||
if (prescale > 256) {
|
||||
exponent = IWDG_PR_DIV256; reload = COUNT_MASK;
|
||||
} else if (prescale > 128) {
|
||||
exponent = IWDG_PR_DIV256; reload = (count >> 8);
|
||||
} else if (prescale > 64) {
|
||||
exponent = IWDG_PR_DIV128; reload = (count >> 7);
|
||||
} else if (prescale > 32) {
|
||||
exponent = IWDG_PR_DIV64; reload = (count >> 6);
|
||||
} else if (prescale > 16) {
|
||||
exponent = IWDG_PR_DIV32; reload = (count >> 5);
|
||||
} else if (prescale > 8) {
|
||||
exponent = IWDG_PR_DIV16; reload = (count >> 4);
|
||||
} else if (prescale > 4) {
|
||||
exponent = IWDG_PR_DIV8; reload = (count >> 3);
|
||||
} else {
|
||||
exponent = IWDG_PR_DIV4; reload = (count >> 2);
|
||||
}
|
||||
|
||||
/* Avoid the undefined situation of a zero count */
|
||||
/* Prevent underflow */
|
||||
if (count == 0) {
|
||||
count = 1;
|
||||
}
|
||||
|
||||
/* Shift count while increasing prescaler as many times as needed to
|
||||
* fit into IWDG_RLR
|
||||
*/
|
||||
while ((count - 1) >> COUNT_LENGTH) {
|
||||
count >>= 1;
|
||||
prescale++;
|
||||
}
|
||||
|
||||
/* IWDG_RLR actually holds count - 1 */
|
||||
count--;
|
||||
|
||||
/* Clamp to max possible period */
|
||||
if (prescale > PRESCALER_MAX) {
|
||||
count = COUNT_MASK;
|
||||
prescale = PRESCALER_MAX;
|
||||
}
|
||||
|
||||
while (iwdg_prescaler_busy());
|
||||
IWDG_KR = IWDG_KR_UNLOCK;
|
||||
IWDG_PR = exponent;
|
||||
IWDG_PR = prescale;
|
||||
while (iwdg_reload_busy());
|
||||
IWDG_KR = IWDG_KR_UNLOCK;
|
||||
IWDG_RLR = (reload & COUNT_MASK);
|
||||
IWDG_RLR = count & COUNT_MASK;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user