Thanks for this, It's been applied in 4b16af6e Thanks for the clear examples of where the values were wrong. Bright side, it's even smaller code than original buggy code :)
FWIW, it's easier for me to work with patches from github, though feel welcome to keep sending patches via mail. Cheers, Karl P Filip Moc <d...@moc6.cz> wrote: > This fixes problems when values such as 512..639 or 1024..1151 > or ... or 32768..32895 are passed to iwdg_set_period_ms. > > Signed-off-by: Filip Moc <d...@moc6.cz> > --- > lib/stm32/common/iwdg_common_all.c | 54 > +++++++++++++++++++------------------- > 1 file changed, 27 insertions(+), 27 deletions(-) > > diff --git a/lib/stm32/common/iwdg_common_all.c > b/lib/stm32/common/iwdg_common_all.c index f2b1c1d8..1e299893 > 100644 > --- a/lib/stm32/common/iwdg_common_all.c > +++ b/lib/stm32/common/iwdg_common_all.c > @@ -42,6 +42,7 @@ relevant bit is not set, the IWDG timer must be enabled by > software. > #define LSI_FREQUENCY 32000 > #define COUNT_LENGTH 12 > #define COUNT_MASK ((1 << COUNT_LENGTH)-1) > +#define PRESCALER_MAX 6 > > > /*---------------------------------------------------------------------------*/ > /** @brief IWDG Enable Watchdog Timer > @@ -73,42 +74,41 @@ 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_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); > - } > + uint8_t prescale = 0; > + > + /* Set the count to represent ticks of 8kHz clock (the 32kHz LSI clock > + * divided by 4 = lowest prescaler setting) > + */ > + uint32_t count = period << 3; > > - /* 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; > } > > > /*---------------------------------------------------------------------------*/ > -- > 2.11.0 > > > > _______________________________________________ > libopencm3-devel mailing list > libopencm3-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/libopencm3-devel
signature.html
Description: OpenPGP Digital Signature
_______________________________________________ libopencm3-devel mailing list libopencm3-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libopencm3-devel