2018-09-30 05: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 08: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.