/** * @brief Configures TIM21 to measure the LSI oscillator frequency. * @param None * @retval LSI Frequency */ static uint32_t GetLSIFrequency(void) { TIM_IC_InitTypeDef TIMInput_Config; /* Configure the TIM peripheral *********************************************/ /* Set TIMx instance */ Input_Handle.Instance = TIM21; /* TIM21 configuration: Input Capture mode --------------------- The LSI oscillator is connected to TIM21 CH1. The Rising edge is used as active edge. The TIM21 CCR1 is used to compute the frequency value. ------------------------------------------------------------ */ Input_Handle.Init.Prescaler = 0; Input_Handle.Init.CounterMode = TIM_COUNTERMODE_UP; Input_Handle.Init.Period = 0xFFFF; Input_Handle.Init.ClockDivision = 0; if(HAL_TIM_IC_Init(&Input_Handle) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /* Connect internally the TIM21_CH1 Input Capture to the LSI clock output */ HAL_TIMEx_RemapConfig(&Input_Handle, TIM21_TI1_LSI); /* Configure the Input Capture of channel 1 */ TIMInput_Config.ICPolarity = TIM_ICPOLARITY_RISING; TIMInput_Config.ICSelection = TIM_ICSELECTION_DIRECTTI; TIMInput_Config.ICPrescaler = TIM_ICPSC_DIV8; TIMInput_Config.ICFilter = 0; if(HAL_TIM_IC_ConfigChannel(&Input_Handle, &TIMInput_Config, TIM_CHANNEL_1) != HAL_OK) { /* Initialization Error */ Error_Handler(); } /* Start the TIM Input Capture measurement in interrupt mode */ if(HAL_TIM_IC_Start_IT(&Input_Handle, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } /* Wait until the TIM21 get 2 LSI edges */ while(uwCaptureNumber != 2) { } /* Disable TIM21 CC1 Interrupt Request */ HAL_TIM_IC_Stop_IT(&Input_Handle, TIM_CHANNEL_1); /* Deinitialize the TIM21 peripheral registers to their default reset values */ HAL_TIM_IC_DeInit(&Input_Handle); return uwLsiFreq; }
/** * @brief Configures TIM2 channel 4 in input capture mode * @param None * @retval None */ static void TIM_Config(void) { /*##-1- Configure the TIM peripheral #######################################*/ /* Set TIMx instance */ TimHandle.Instance = TIMx; /* Initialize TIMx peripheral as follow: + Period = 0xFFFF + Prescaler = 0 + ClockDivision = 0 + Counter direction = Up */ TimHandle.Init.Period = 0xFFFF; TimHandle.Init.Prescaler = 0; TimHandle.Init.ClockDivision = 0; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; if(HAL_TIM_IC_Init(&TimHandle) != HAL_OK) { /* Error */ ErrorHandler(); } HAL_TIMEx_RemapConfig(&TimHandle, TIM2_TI4_COMP1); /*##-2- Configure the Input Capture channel ################################*/ /* Configure the Input Capture of channel 4 */ sICConfig.ICPolarity = TIM_ICPOLARITY_BOTHEDGE; sICConfig.ICSelection = TIM_ICSELECTION_DIRECTTI; sICConfig.ICPrescaler = TIM_ICPSC_DIV1; sICConfig.ICFilter = 0; if(HAL_TIM_IC_ConfigChannel(&TimHandle, &sICConfig, TIM_CHANNEL_4) != HAL_OK) { /* Configuration Error */ ErrorHandler(); } /*##-3- Start the Input Capture in interrupt mode ##########################*/ if(HAL_TIM_IC_Start_IT(&TimHandle, TIM_CHANNEL_4) != HAL_OK) { /* Starting Error */ ErrorHandler(); } }
/** * @brief Configures TIM5 to measure the LSI oscillator frequency. * @param None * @retval LSI Frequency */ static uint32_t GetLSIFrequency(void) { uint32_t pclk1 = 0, latency = 0; TIM_IC_InitTypeDef timinputconfig = {0}; RCC_OscInitTypeDef oscinit = {0}; RCC_ClkInitTypeDef clkinit = {0}; /* Enable LSI Oscillator */ oscinit.OscillatorType = RCC_OSCILLATORTYPE_LSI; oscinit.LSIState = RCC_LSI_ON; oscinit.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&oscinit)!= HAL_OK) { Error_Handler(); } /* Configure the TIM peripheral */ /* Set TIMx instance */ TimInputCaptureHandle.Instance = TIMx; /* TIMx configuration: Input Capture mode --------------------- The LSI clock 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) { /* Initialization Error */ Error_Handler(); } /* Connect internally the TIM5 CH4 Input Capture to the LSI clock output */ HAL_TIMEx_RemapConfig(&TimInputCaptureHandle, TIMx_REMAP); /* 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) { /* Initialization Error */ Error_Handler(); } /* 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) { /* Starting Error */ Error_Handler(); } /* 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(); HAL_RCC_GetClockConfig(&clkinit, &latency); /* Get PCLK1 prescaler */ if ((clkinit.APB1CLKDivider) == RCC_HCLK_DIV1) { /* PCLK1 prescaler equal to 1 => TIMCLK = PCLK1 */ return ((pclk1 / uwPeriodValue) * 8); } else { /* PCLK1 prescaler different from 1 => TIMCLK = 2 * PCLK1 */ return (((2 * pclk1) / uwPeriodValue) * 8) ; } }
/** * @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; /* Enable the LSI oscillator */ __HAL_RCC_LSI_ENABLE(); /* Wait till LSI is ready */ while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) { } /* Configure the TIM peripheral */ /* Set TIMx 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) { /* Initialization Error */ Error_Handler(); } /* 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) { /* Initialization Error */ Error_Handler(); } /* 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) { Error_Handler(); } /* 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); } else { /* PCLK1 prescaler different from 1 => TIMCLK = 2 * PCLK1 */ return (((2 * pclk1) / uwPeriodValue) * 8); } }