STMicroelectronics / STM32CubeF7

STM32Cube MCU Full Package for the STM32F7 series - (HAL + LL Drivers, CMSIS Core, CMSIS Device, MW libraries plus a set of Projects running on all boards provided by ST (Nucleo, Evaluation and Discovery Kits))
Other
331 stars 194 forks source link

__LL_TIM_CALC_PSC rounding #57

Closed phryniszak closed 2 years ago

phryniszak commented 2 years ago

Describe the set-up

/**
  * @brief  HELPER macro calculating the prescaler value to achieve the required counter clock frequency.
  * @note ex: @ref __LL_TIM_CALC_PSC (80000000, 1000000);
  * @param  __TIMCLK__ timer input clock frequency (in Hz)
  * @param  __CNTCLK__ counter clock frequency (in Hz)
  * @retval Prescaler value  (between Min_Data=0 and Max_Data=65535)
  */
#define __LL_TIM_CALC_PSC(__TIMCLK__, __CNTCLK__)   \
  (((__TIMCLK__) >= (__CNTCLK__)) ? (uint32_t)(((__TIMCLK__)/(__CNTCLK__)) - 1U) : 0U)

Works as expected when the result of division is integer, but in the other case result is truncated, not round.

So in my case when I call it with values: __LL_TIM_CALC_PSC(108*1e6, 10*1e6); function returns precaller value 9 which gives counter frequency 10.8*1e6 (8% error). Better value is 10 with counter frequency equal 9.8*1e6 (2% error).

I didn't check but it looks like this macro is present in most of stm32cube packages in the same form.

Additional context

https://www.google.com/search?q=Rounding+integer+division

ASELSTM commented 2 years ago

Hi @phryniszak,

Thank you for your report. Indeed, the issue is confirmed. To fix it you can use the patch below :

/**
  * @brief  HELPER macro calculating the prescaler value to achieve the required counter clock frequency.
  * @note ex: @ref __LL_TIM_CALC_PSC (80000000, 1000000);
  * @param  __TIMCLK__ timer input clock frequency (in Hz)
  * @param  __CNTCLK__ counter clock frequency (in Hz)
  * @retval Prescaler value  (between Min_Data=0 and Max_Data=65535)
  */
#define __LL_TIM_CALC_PSC(__TIMCLK__, __CNTCLK__)   \
- (((__TIMCLK__) >= (__CNTCLK__)) ? (uint32_t)(((__TIMCLK__)/(__CNTCLK__)) - 1U) : 0U)
+ (((__TIMCLK__) >= (__CNTCLK__)) ? (uint32_t)((((__TIMCLK__) + (__CNTCLK__)/2U)/(__CNTCLK__)) - 1U) : 0U)

The fix will be made available in the frame of a future release.

With regards,

ASELSTM commented 2 years ago

ST Internal Reference: 118234

ASELSTM commented 2 years ago

Hi @phryniszak,

Thank you for your contribution. This issue has been fixed in the frame of version v1.17.0 of the STM32CubeF7. Please allow me then to close this thread.

Thank you again for your contribution.

With regards,