/** * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the * RCC_PeriphCLKInitTypeDef. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks). * * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset * * @retval HAL status */ HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) { uint32_t tickstart = 0; uint32_t tmpreg1 = 0; /* Check the parameters */ assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); /*---------------------------- I2S configuration ---------------------------*/ if(((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))|| \ (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S)) { /* check for Parameters */ assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); /* Disable the PLLI2S */ __HAL_RCC_PLLI2S_DISABLE(); /* Get tick */ tickstart = HAL_GetTick(); /* Wait till PLLI2S is disabled */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) { if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) { /* return in case of Timeout detected */ return HAL_TIMEOUT; } } /* Configure the PLLI2S division factors */ /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */ /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); /* Enable the PLLI2S */ __HAL_RCC_PLLI2S_ENABLE(); /* Get tick */ tickstart = HAL_GetTick(); /* Wait till PLLI2S is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) { if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) { /* return in case of Timeout detected */ return HAL_TIMEOUT; } } } /*--------------------------------------------------------------------------*/ /*----------------------------- RTC configuration --------------------------*/ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) { /* Enable Power Clock*/ __HAL_RCC_PWR_CLK_ENABLE(); /* Enable write access to Backup domain */ PWR->CR |= PWR_CR_DBP; /* Get tick */ tickstart = HAL_GetTick(); while((PWR->CR & PWR_CR_DBP) == RESET) { if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } /* Reset the Backup domain only if the RTC Clock source selection is modified */ if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)) { /* Store the content of BDCR register before the reset of Backup Domain */ tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); /* RTC Clock selection can be changed only if the Backup Domain is reset */ __HAL_RCC_BACKUPRESET_FORCE(); __HAL_RCC_BACKUPRESET_RELEASE(); /* Restore the Content of BDCR register */ RCC->BDCR = tmpreg1; /* Wait for LSERDY if LSE was enabled */ if(HAL_IS_BIT_SET(tmpreg1, RCC_BDCR_LSERDY)) { /* Get tick */ tickstart = HAL_GetTick(); /* Wait till LSE is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) { if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } } __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); } } /*--------------------------------------------------------------------------*/ return HAL_OK; }
/** * @brief Returns the peripheral clock frequency * @note Returns 0 if peripheral clock is unknown * @param PeriphClk Peripheral clock identifier * This parameter can be one of the following values: * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock * @arg @ref RCC_PERIPHCLK_LCD LCD peripheral clock (depends on devices) * @retval Frequency in Hz (0: means that no available frequency for the peripheral) */ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) { uint32_t temp_reg = 0, clkprediv = 0, frequency = 0; uint32_t srcclk = 0; /* Check the parameters */ assert_param(IS_RCC_PERIPHCLOCK(PeriphClk)); switch (PeriphClk) { case RCC_PERIPHCLK_RTC: #if defined(LCD) case RCC_PERIPHCLK_LCD: #endif /* LCD */ { /* Get RCC CSR configuration ------------------------------------------------------*/ temp_reg = RCC->CSR; /* Get the current RTC source */ srcclk = __HAL_RCC_GET_RTC_SOURCE(); /* Check if LSE is ready if RTC clock selection is LSE */ if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSERDY))) { frequency = LSE_VALUE; } /* Check if LSI is ready if RTC clock selection is LSI */ else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSIRDY))) { frequency = LSI_VALUE; } /* Check if HSE is ready and if RTC clock selection is HSE */ else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIVX) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))) { /* Get the current HSE clock divider */ clkprediv = __HAL_RCC_GET_RTC_HSE_PRESCALER(); switch (clkprediv) { case RCC_RTC_HSE_DIV_16: /* HSE DIV16 has been selected */ { frequency = HSE_VALUE / 16; break; } case RCC_RTC_HSE_DIV_8: /* HSE DIV8 has been selected */ { frequency = HSE_VALUE / 8; break; } case RCC_RTC_HSE_DIV_4: /* HSE DIV4 has been selected */ { frequency = HSE_VALUE / 4; break; } default: /* HSE DIV2 has been selected */ { frequency = HSE_VALUE / 2; break; } } } /* Clock not enabled for RTC */ else { frequency = 0; } break; } default: { break; } } return(frequency); }
/** * @brief Returns the peripheral clock frequency * @note Returns 0 if peripheral clock is unknown * @param PeriphClk Peripheral clock identifier * This parameter can be one of the following values: * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock * @arg @ref RCC_PERIPHCLK_LCD LCD peripheral clock (depends on devices) * @retval Frequency in Hz (0: means that no available frequency for the peripheral) */ uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) { uint32_t temp_reg = 0, frequency = 0; uint32_t srcclk = 0; /* Check the parameters */ assert_param(IS_RCC_PERIPHCLOCK(PeriphClk)); switch (PeriphClk) { case RCC_PERIPHCLK_RTC: #if defined(STM32L100xB) || defined(STM32L100xBA) || defined(STM32L100xC)\ || defined(STM32L152xB) || defined(STM32L152xBA) || defined(STM32L152xC)\ || defined(STM32L162xC) || defined(STM32L152xCA) || defined(STM32L152xD)\ || defined(STM32L162xCA) || defined(STM32L162xD) || defined(STM32L152xE) || defined(STM32L152xDX)\ || defined(STM32L162xE) || defined(STM32L162xDX) case RCC_PERIPHCLK_LCD: #endif /* STM32L100xB || STM32L152xBA || ... || STM32L152xE || STM32L152xDX || STM32L162xE || STM32L162xDX */ { /* Get RCC CSR configuration ------------------------------------------------------*/ temp_reg = RCC->CSR; /* Get the current RTC source */ srcclk = __HAL_RCC_GET_RTC_SOURCE(); /* Check if LSE is ready if RTC clock selection is LSE */ if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSERDY))) { frequency = LSE_VALUE; } /* Check if LSI is ready if RTC clock selection is LSI */ else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSIRDY))) { frequency = LSI_VALUE; } /* Check if HSE is ready */ else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) { switch (READ_BIT(RCC->CR, RCC_CR_RTCPRE)) { case RCC_CR_RTCPRE: /* HSE DIV16 has been selected */ { frequency = HSE_VALUE / 16; break; } case RCC_CR_RTCPRE_1: /* HSE DIV8 has been selected */ { frequency = HSE_VALUE / 8; break; } case RCC_CR_RTCPRE_0: /* HSE DIV4 has been selected */ { frequency = HSE_VALUE / 4; break; } default: { frequency = HSE_VALUE / 2; break; } } } /* Clock not enabled for RTC*/ else { frequency = 0; } break; } default: { break; } } return(frequency); }
/** * @brief Initializes the RCC extended peripherals clocks according to the specified * parameters in the RCC_PeriphCLKInitTypeDef. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that * contains the configuration information for the Extended Peripherals clocks(RTC/LCD clock). * @retval HAL status * @note If HAL_ERROR returned, first switch-OFF HSE clock oscillator with @ref HAL_RCC_OscConfig() * to possibly update HSE divider. */ HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) { uint32_t tickstart = 0; uint32_t temp_reg = 0; /* Check the parameters */ assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); /*------------------------------- RTC/LCD Configuration ------------------------*/ if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) #if defined(LCD) || (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD) #endif /* LCD */ ) { /* check for RTC Parameters used to output RTCCLK */ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) { assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); } #if defined(LCD) if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD) { assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->LCDClockSelection)); } #endif /* LCD */ /* As soon as function is called to change RTC clock source, activation of the power domain is done. */ /* Enable Power Clock*/ __HAL_RCC_PWR_CLK_ENABLE(); /* Enable write access to Backup domain */ SET_BIT(PWR->CR, PWR_CR_DBP); /* Wait for Backup domain Write protection disable */ tickstart = HAL_GetTick(); while((PWR->CR & PWR_CR_DBP) == RESET) { if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } /* Check if user wants to change HSE RTC prescaler whereas HSE is enabled */ temp_reg = (RCC->CR & RCC_CR_RTCPRE); if ((temp_reg != (PeriphClkInit->RTCClockSelection & RCC_CR_RTCPRE)) #if defined (LCD) || (temp_reg != (PeriphClkInit->LCDClockSelection & RCC_CR_RTCPRE)) #endif /* LCD */ ) { /* Check HSE State */ if (((PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL) == RCC_CSR_RTCSEL_HSE) && HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) { /* To update HSE divider, first switch-OFF HSE clock oscillator*/ return HAL_ERROR; } } /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ temp_reg = (RCC->CSR & RCC_CSR_RTCSEL); if((temp_reg != 0x00000000U) && (((temp_reg != (PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL)) \ && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)) #if defined(LCD) || ((temp_reg != (PeriphClkInit->LCDClockSelection & RCC_CSR_RTCSEL)) \ && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD)) #endif /* LCD */ )) { /* Store the content of CSR register before the reset of Backup Domain */ temp_reg = (RCC->CSR & ~(RCC_CSR_RTCSEL)); /* RTC Clock selection can be changed only if the Backup Domain is reset */ __HAL_RCC_BACKUPRESET_FORCE(); __HAL_RCC_BACKUPRESET_RELEASE(); /* Restore the Content of CSR register */ RCC->CSR = temp_reg; /* Wait for LSERDY if LSE was enabled */ if (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSERDY)) { /* Get Start Tick */ tickstart = HAL_GetTick(); /* Wait till LSE is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) { if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } } } __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); } return HAL_OK; }
/** * @brief Initializes the RCC extended peripherals clocks according to the specified * parameters in the RCC_PeriphCLKInitTypeDef. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that * contains the configuration information for the Extended Peripherals clocks(RTC/LCD clock). * @retval HAL status */ HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) { uint32_t tickstart = 0; uint32_t temp_reg = 0; /* Check the parameters */ assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); /*------------------------------- RTC/LCD Configuration ------------------------*/ if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) #if defined(STM32L100xB) || defined(STM32L100xBA) || defined(STM32L100xC)\ || defined(STM32L152xB) || defined(STM32L152xBA) || defined(STM32L152xC)\ || defined(STM32L162xC) || defined(STM32L152xCA) || defined(STM32L152xD)\ || defined(STM32L162xCA) || defined(STM32L162xD) || defined(STM32L152xE) || defined(STM32L152xDX)\ || defined(STM32L162xE) || defined(STM32L162xDX) || (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD) #endif /* STM32L100xB || STM32L152xBA || ... || STM32L152xE || STM32L152xDX || STM32L162xE || STM32L162xDX */ ) { /* check for RTC Parameters used to output RTCCLK */ if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) { assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); } #if defined(STM32L100xB) || defined(STM32L100xBA) || defined(STM32L100xC)\ || defined(STM32L152xB) || defined(STM32L152xBA) || defined(STM32L152xC)\ || defined(STM32L162xC) || defined(STM32L152xCA) || defined(STM32L152xD)\ || defined(STM32L162xCA) || defined(STM32L162xD) || defined(STM32L152xE) || defined(STM32L152xDX)\ || defined(STM32L162xE) || defined(STM32L162xDX) if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD) { assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->LCDClockSelection)); } #endif /* STM32L100xB || STM32L152xBA || ... || STM32L152xE || STM32L152xDX || STM32L162xE || STM32L162xDX */ /* Enable Power Clock*/ __HAL_RCC_PWR_CLK_ENABLE(); /* Enable write access to Backup domain */ SET_BIT(PWR->CR, PWR_CR_DBP); /* Wait for Backup domain Write protection disable */ tickstart = HAL_GetTick(); while((PWR->CR & PWR_CR_DBP) == RESET) { if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } /* Reset the Backup domain only if the RTC Clock source selection is modified */ temp_reg = (RCC->CSR & RCC_CSR_RTCSEL); if(((temp_reg != (PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL)) \ && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)) #if defined(STM32L100xB) || defined(STM32L100xBA) || defined(STM32L100xC)\ || defined(STM32L152xB) || defined(STM32L152xBA) || defined(STM32L152xC)\ || defined(STM32L162xC) || defined(STM32L152xCA) || defined(STM32L152xD)\ || defined(STM32L162xCA) || defined(STM32L162xD) || defined(STM32L152xE) || defined(STM32L152xDX)\ || defined(STM32L162xE) || defined(STM32L162xDX) || ((temp_reg != (PeriphClkInit->LCDClockSelection & RCC_CSR_RTCSEL)) \ && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD)) #endif /* STM32L100xB || STM32L152xBA || ... || STM32L152xE || STM32L152xDX || STM32L162xE || STM32L162xDX */ ) { /* Store the content of CSR register before the reset of Backup Domain */ temp_reg = (RCC->CSR & ~(RCC_CSR_RTCSEL)); /* RTC Clock selection can be changed only if the Backup Domain is reset */ __HAL_RCC_BACKUPRESET_FORCE(); __HAL_RCC_BACKUPRESET_RELEASE(); /* Restore the Content of CSR register */ RCC->CSR = temp_reg; /* Wait for LSERDY if LSE was enabled */ if (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSERDY)) { /* Get Start Tick */ tickstart = HAL_GetTick(); /* Wait till LSE is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) { if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } } __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); } } return HAL_OK; }