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

Attachment: signature.html
Description: OpenPGP Digital Signature

_______________________________________________
libopencm3-devel mailing list
libopencm3-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libopencm3-devel

Reply via email to