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
|
@param[in] period uint32_t Period in milliseconds (< 32760) from a watchdog
|
||||||
reset until a system reset is issued.
|
reset until a system reset is issued.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void iwdg_set_period_ms(uint32_t period)
|
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 */
|
/* Set the count to represent ticks of 8kHz clock (the 32kHz LSI clock
|
||||||
count = (period << 5);
|
* divided by 4 = lowest prescaler setting)
|
||||||
|
*/
|
||||||
|
uint32_t count = period << 3;
|
||||||
|
|
||||||
/* Strip off the first 12 bits to get the prescale value required */
|
/* Prevent underflow */
|
||||||
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 */
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
count = 1;
|
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());
|
while (iwdg_prescaler_busy());
|
||||||
IWDG_KR = IWDG_KR_UNLOCK;
|
IWDG_KR = IWDG_KR_UNLOCK;
|
||||||
IWDG_PR = exponent;
|
IWDG_PR = prescale;
|
||||||
while (iwdg_reload_busy());
|
while (iwdg_reload_busy());
|
||||||
IWDG_KR = IWDG_KR_UNLOCK;
|
IWDG_KR = IWDG_KR_UNLOCK;
|
||||||
IWDG_RLR = (reload & COUNT_MASK);
|
IWDG_RLR = count & COUNT_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user