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:
Filip Moc 2018-10-05 23:30:41 +00:00 committed by Karl Palsson
parent 239b4a4704
commit 4b16af6e24

View File

@ -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;
}
/*---------------------------------------------------------------------------*/