Skip to main content
Tesla DeLorean
Guru
October 1, 2018
Question

Fixing poor math in the library code

  • October 1, 2018
  • 1 reply
  • 599 views

I've pointed this out before, but still spreading throughout the code base.

STM32Cube_FW_F4_V1.19.0\Projects\STM32F429I-Discovery\Demonstrations\STemWin\Core\Src\k_rtc.c

/**
 * @brief Configures TIM5 to measure the LSI oscillator frequency.
 * @param None
 * @retval LSI Frequency
 */
static uint32_t GetLSIFrequency(void)
{
 uint32_t pclk1 = 0;
 TIM_IC_InitTypeDef timinputconfig;
 
 
 /* Configure the TIM peripheral */
 /* Set TIM5 instance */
 TimInputCaptureHandle.Instance = TIM5;
 
 /* TIM5 configuration: Input Capture mode ---------------------
 The LSI oscillator is connected to TIM5 CH4.
 The Rising edge is used as active edge.
 The TIM5 CCR4 is used to compute the frequency value.
 ------------------------------------------------------------ */
 TimInputCaptureHandle.Init.Prescaler = 0;
 TimInputCaptureHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
 TimInputCaptureHandle.Init.Period = 0xFFFF;
 TimInputCaptureHandle.Init.ClockDivision = 0;
 TimInputCaptureHandle.Init.RepetitionCounter = 0;
 
 if(HAL_TIM_IC_Init(&TimInputCaptureHandle) != HAL_OK)
 {}
 /* Connect internally the TIM5_CH4 Input Capture to the LSI clock output */
 HAL_TIMEx_RemapConfig(&TimInputCaptureHandle, TIM_TIM5_LSI);
 
 /* Configure the Input Capture of channel 4 */
 timinputconfig.ICPolarity = TIM_ICPOLARITY_RISING;
 timinputconfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
 timinputconfig.ICPrescaler = TIM_ICPSC_DIV8;
 timinputconfig.ICFilter = 0;
 
 if(HAL_TIM_IC_ConfigChannel(&TimInputCaptureHandle, &timinputconfig, TIM_CHANNEL_4) != HAL_OK)
 {}
 /* Reset the flags */
 TimInputCaptureHandle.Instance->SR = 0;
 
 /* Start the TIM Input Capture measurement in interrupt mode */
 if(HAL_TIM_IC_Start_IT(&TimInputCaptureHandle, TIM_CHANNEL_4) != HAL_OK)
 {
 }
 
 
 
 /* Wait until the TIM5 get 2 LSI edges (refer to TIM5_IRQHandler() in
 stm32f4xx_it.c file) */
 while(uwMeasurementDone == 0)
 {
 }
 uwCaptureNumber = 0;
 
 /* Deinitialize the TIM5 peripheral registers to their default reset values */
 HAL_TIM_IC_DeInit(&TimInputCaptureHandle);
 
 /* Compute the LSI frequency, depending on TIM5 input clock frequency (PCLK1)*/
 /* Get PCLK1 frequency */
 pclk1 = HAL_RCC_GetPCLK1Freq();
 
 /* Get PCLK1 prescaler */
 if((RCC->CFGR & RCC_CFGR_PPRE1) == 0)
 {
 /* PCLK1 prescaler equal to 1 => TIMCLK = PCLK1 */
 return ((pclk1 / uwPeriodValue) * 8); // BAD
 }
 else
 {
 /* PCLK1 prescaler different from 1 => TIMCLK = 2 * PCLK1 */
 return (((2 * pclk1) / uwPeriodValue) * 8); // BAD
 }
}

Do the math like this so you maintain precision, and don't get multiples of EIGHT all the time.

   /* PCLK1 prescaler different from 1 => TIMCLK = 2 * PCLK1 */

   return ((2 * pclk1 * 8) / uwPeriodValue); // MULTIPLY BEFORE DIVISION

This topic has been closed for replies.

1 reply

Amel NASRI
ST Technical Moderator
October 2, 2018

Proposal reported internally. Thanks Clive.

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.