/** * @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; }