2018-09-30 5:00 PM
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
2018-10-02 8:07 AM
Proposal reported internally. Thanks Clive.
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
We’re moving the ST Community to a new platform to give you a better and more reliable community experience.