Old / new BT module communication:
The old / new BT module do have a sligthly different command set. To keep them compatible a function has been added which returns, based on the HW identification, the command string which matches to the module. In case a command is not supported the value 0 is returned and the calling function may react. E.g. with skipping of configuration steps like it is done now for the new module.
line source
/**+ −
******************************************************************************+ −
* @file stm32f4xx_hal_rcc_ex.c+ −
* @author MCD Application Team+ −
* @brief Extension RCC HAL module driver.+ −
* This file provides firmware functions to manage the following+ −
* functionalities RCC extension peripheral:+ −
* + Extended Peripheral Control functions+ −
*+ −
******************************************************************************+ −
* @attention+ −
*+ −
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>+ −
*+ −
* Redistribution and use in source and binary forms, with or without modification,+ −
* are permitted provided that the following conditions are met:+ −
* 1. Redistributions of source code must retain the above copyright notice,+ −
* this list of conditions and the following disclaimer.+ −
* 2. Redistributions in binary form must reproduce the above copyright notice,+ −
* this list of conditions and the following disclaimer in the documentation+ −
* and/or other materials provided with the distribution.+ −
* 3. Neither the name of STMicroelectronics nor the names of its contributors+ −
* may be used to endorse or promote products derived from this software+ −
* without specific prior written permission.+ −
*+ −
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+ −
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ −
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+ −
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+ −
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ −
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+ −
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+ −
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+ −
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+ −
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ −
*+ −
******************************************************************************+ −
*/+ −
+ −
/* Includes ------------------------------------------------------------------*/+ −
#include "stm32f4xx_hal.h"+ −
+ −
/** @addtogroup STM32F4xx_HAL_Driver+ −
* @{+ −
*/+ −
+ −
/** @defgroup RCCEx RCCEx+ −
* @brief RCCEx HAL module driver+ −
* @{+ −
*/+ −
+ −
#ifdef HAL_RCC_MODULE_ENABLED+ −
+ −
/* Private typedef -----------------------------------------------------------*/+ −
/* Private define ------------------------------------------------------------*/+ −
/** @addtogroup RCCEx_Private_Constants+ −
* @{+ −
*/+ −
/**+ −
* @}+ −
*/+ −
/* Private macro -------------------------------------------------------------*/+ −
/* Private variables ---------------------------------------------------------*/+ −
/* Private function prototypes -----------------------------------------------*/+ −
/* Private functions ---------------------------------------------------------*/+ −
/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions+ −
* @{+ −
*/+ −
+ −
/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions+ −
* @brief Extended Peripheral Control functions+ −
*+ −
@verbatim+ −
===============================================================================+ −
##### Extended Peripheral Control functions #####+ −
===============================================================================+ −
[..]+ −
This subsection provides a set of functions allowing to control the RCC Clocks+ −
frequencies.+ −
[..]+ −
(@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to+ −
select the RTC clock source; in this case the Backup domain will be reset in+ −
order to modify the RTC Clock source, as consequence RTC registers (including+ −
the backup registers) and RCC_BDCR register are set to their reset values.+ −
+ −
@endverbatim+ −
* @{+ −
*/+ −
+ −
#if defined(STM32F446xx)+ −
/**+ −
* @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, SAI, LTDC RTC and TIM).+ −
*+ −
* @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select+ −
* the RTC clock source; in this case the Backup domain will be reset in+ −
* order to modify the RTC Clock source, as consequence RTC registers (including+ −
* the backup registers) and RCC_BDCR register are set to their reset values.+ −
*+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tickstart = 0U;+ −
uint32_t tmpreg1 = 0U;+ −
uint32_t plli2sp = 0U;+ −
uint32_t plli2sq = 0U;+ −
uint32_t plli2sr = 0U;+ −
uint32_t pllsaip = 0U;+ −
uint32_t pllsaiq = 0U;+ −
uint32_t plli2sused = 0U;+ −
uint32_t pllsaiused = 0U;+ −
+ −
/* Check the peripheral clock selection parameters */+ −
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));+ −
+ −
/*------------------------ I2S APB1 configuration --------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1))+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection));+ −
+ −
/* Configure I2S Clock source */+ −
__HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection);+ −
/* Enable the PLLI2S when it's used as clock source for I2S */+ −
if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)+ −
{+ −
plli2sused = 1U;+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- I2S APB2 configuration ----------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2))+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection));+ −
+ −
/* Configure I2S Clock source */+ −
__HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection);+ −
/* Enable the PLLI2S when it's used as clock source for I2S */+ −
if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)+ −
{+ −
plli2sused = 1U;+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*--------------------------- SAI1 configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));+ −
+ −
/* Configure SAI1 Clock source */+ −
__HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);+ −
/* Enable the PLLI2S when it's used as clock source for SAI */+ −
if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)+ −
{+ −
plli2sused = 1U;+ −
}+ −
/* Enable the PLLSAI when it's used as clock source for SAI */+ −
if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)+ −
{+ −
pllsaiused = 1U;+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*-------------------------- SAI2 configuration ----------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));+ −
+ −
/* Configure SAI2 Clock source */+ −
__HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);+ −
+ −
/* Enable the PLLI2S when it's used as clock source for SAI */+ −
if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)+ −
{+ −
plli2sused = 1U;+ −
}+ −
/* Enable the PLLSAI when it's used as clock source for SAI */+ −
if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)+ −
{+ −
pllsaiused = 1U;+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*----------------------------- RTC configuration --------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))+ −
{+ −
/* Check for RTC Parameters used to output RTCCLK */+ −
assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));+ −
+ −
/* 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 from reset value */+ −
tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);+ −
if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (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 LSE reactivation if LSE was enable prior to Backup Domain reset */+ −
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))+ −
{+ −
/* 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);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- TIM configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))+ −
{+ −
/* Configure Timer Prescaler */+ −
__HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- FMPI2C1 Configuration -----------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));+ −
+ −
/* Configure the FMPI2C1 clock source */+ −
__HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*------------------------------ CEC Configuration -------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));+ −
+ −
/* Configure the CEC clock source */+ −
__HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*----------------------------- CLK48 Configuration ------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));+ −
+ −
/* Configure the CLK48 clock source */+ −
__HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);+ −
+ −
/* Enable the PLLSAI when it's used as clock source for CLK48 */+ −
if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)+ −
{+ −
pllsaiused = 1U;+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*----------------------------- SDIO Configuration -------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));+ −
+ −
/* Configure the SDIO clock source */+ −
__HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*------------------------------ SPDIFRX Configuration ---------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_SPDIFRXCLKSOURCE(PeriphClkInit->SpdifClockSelection));+ −
+ −
/* Configure the SPDIFRX clock source */+ −
__HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifClockSelection);+ −
/* Enable the PLLI2S when it's used as clock source for SPDIFRX */+ −
if(PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP)+ −
{+ −
plli2sused = 1U;+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- PLLI2S Configuration ------------------------*/+ −
/* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S on APB1,+ −
I2S on APB2 or SPDIFRX */+ −
if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))+ −
{+ −
/* 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;+ −
}+ −
}+ −
+ −
/* check for common PLLI2S Parameters */+ −
assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));+ −
assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));+ −
+ −
/*------ In Case of PLLI2S is selected as source clock for I2S -----------*/+ −
if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) ||+ −
((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)))+ −
{+ −
/* check for Parameters */+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));+ −
+ −
/* Read PLLI2SP/PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */+ −
plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);+ −
plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */+ −
/* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */+ −
__HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR);+ −
}+ −
+ −
/*------- In Case of PLLI2S is selected as source clock for SAI ----------*/+ −
if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||+ −
((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)))+ −
{+ −
/* Check for PLLI2S Parameters */+ −
assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));+ −
/* Check for PLLI2S/DIVQ parameters */+ −
assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));+ −
+ −
/* Read PLLI2SP/PLLI2SR value from PLLI2SCFGR register (this value is not needed for SAI configuration) */+ −
plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);+ −
plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
/* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */+ −
__HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, PeriphClkInit->PLLI2S.PLLI2SQ, plli2sr);+ −
+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */+ −
__HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);+ −
}+ −
+ −
/*------ In Case of PLLI2S is selected as source clock for SPDIFRX -------*/+ −
if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) && (PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP))+ −
{+ −
/* check for Parameters */+ −
assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));+ −
/* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */+ −
plli2sq = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);+ −
plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */+ −
/* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */+ −
__HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, plli2sq, plli2sr);+ −
}+ −
+ −
/*----------------- In Case of PLLI2S is just selected -----------------*/+ −
if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)+ −
{+ −
/* Check for Parameters */+ −
assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));+ −
assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));+ −
+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */+ −
__HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, PeriphClkInit->PLLI2S.PLLI2SQ, 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;+ −
}+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*----------------------------- PLLSAI Configuration -----------------------*/+ −
/* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, CLK48 or SDIO */+ −
if(pllsaiused == 1U)+ −
{+ −
/* Disable PLLSAI Clock */+ −
__HAL_RCC_PLLSAI_DISABLE();+ −
/* Get tick */+ −
tickstart = HAL_GetTick();+ −
/* Wait till PLLSAI is disabled */+ −
while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
/* Check the PLLSAI division factors */+ −
assert_param(IS_RCC_PLLSAIM_VALUE(PeriphClkInit->PLLSAI.PLLSAIM));+ −
assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));+ −
+ −
/*------ In Case of PLLSAI is selected as source clock for SAI -----------*/+ −
if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||+ −
((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))+ −
{+ −
/* check for PLLSAIQ Parameter */+ −
assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));+ −
/* check for PLLSAI/DIVQ Parameter */+ −
assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));+ −
+ −
/* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */+ −
pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);+ −
/* PLLSAI_VCO Input = PLL_SOURCE/PLLM */+ −
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */+ −
/* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */+ −
__HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, 0U);+ −
+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */+ −
__HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);+ −
}+ −
+ −
/*------ In Case of PLLSAI is selected as source clock for CLK48 ---------*/+ −
/* In Case of PLLI2S is selected as source clock for CLK48 */+ −
if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))+ −
{+ −
/* check for Parameters */+ −
assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));+ −
/* Read PLLSAIQ value from PLLI2SCFGR register (this value is not need for SAI configuration) */+ −
pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);+ −
/* Configure the PLLSAI division factors */+ −
/* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLI2SN/PLLSAIM) */+ −
/* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */+ −
__HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, 0U);+ −
}+ −
+ −
/* Enable PLLSAI Clock */+ −
__HAL_RCC_PLLSAI_ENABLE();+ −
/* Get tick */+ −
tickstart = HAL_GetTick();+ −
/* Wait till PLLSAI is ready */+ −
while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
return HAL_OK;+ −
}+ −
+ −
/**+ −
* @brief Get the RCC_PeriphCLKInitTypeDef according to the internal+ −
* RCC configuration registers.+ −
* @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that+ −
* will be configured.+ −
* @retval None+ −
*/+ −
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tempreg;+ −
+ −
/* Set all possible values for the extended clock type parameter------------*/+ −
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\+ −
RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\+ −
RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\+ −
RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_FMPI2C1 |\+ −
RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO |\+ −
RCC_PERIPHCLK_SPDIFRX;+ −
+ −
/* Get the PLLI2S Clock configuration --------------------------------------*/+ −
PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);+ −
PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);+ −
/* Get the PLLSAI Clock configuration --------------------------------------*/+ −
PeriphClkInit->PLLSAI.PLLSAIM = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM) >> RCC_PLLSAICFGR_PLLSAIM_Pos);+ −
PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);+ −
PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);+ −
PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);+ −
/* Get the PLLSAI/PLLI2S division factors ----------------------------------*/+ −
PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);+ −
PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);+ −
+ −
/* Get the SAI1 clock configuration ----------------------------------------*/+ −
PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();+ −
+ −
/* Get the SAI2 clock configuration ----------------------------------------*/+ −
PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();+ −
+ −
/* Get the I2S APB1 clock configuration ------------------------------------*/+ −
PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE();+ −
+ −
/* Get the I2S APB2 clock configuration ------------------------------------*/+ −
PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE();+ −
+ −
/* Get the RTC Clock configuration -----------------------------------------*/+ −
tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);+ −
PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));+ −
+ −
/* Get the CEC clock configuration -----------------------------------------*/+ −
PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();+ −
+ −
/* Get the FMPI2C1 clock configuration -------------------------------------*/+ −
PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();+ −
+ −
/* Get the CLK48 clock configuration ----------------------------------------*/+ −
PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();+ −
+ −
/* Get the SDIO clock configuration ----------------------------------------*/+ −
PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();+ −
+ −
/* Get the SPDIFRX clock configuration -------------------------------------*/+ −
PeriphClkInit->SpdifClockSelection = __HAL_RCC_GET_SPDIFRX_SOURCE();+ −
+ −
/* Get the TIM Prescaler configuration -------------------------------------*/+ −
if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;+ −
}+ −
else+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;+ −
}+ −
}+ −
+ −
/**+ −
* @brief Return the peripheral clock frequency for a given peripheral(SAI..)+ −
* @note Return 0 if peripheral clock identifier not managed by this API+ −
* @param PeriphClk Peripheral clock identifier+ −
* This parameter can be one of the following values:+ −
* @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock+ −
* @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock+ −
* @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock+ −
* @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock+ −
* @retval Frequency in KHz+ −
*/+ −
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)+ −
{+ −
uint32_t tmpreg1 = 0U;+ −
/* This variable used to store the SAI clock frequency (value in Hz) */+ −
uint32_t frequency = 0U;+ −
/* This variable used to store the VCO Input (value in Hz) */+ −
uint32_t vcoinput = 0U;+ −
/* This variable used to store the SAI clock source */+ −
uint32_t saiclocksource = 0U;+ −
uint32_t srcclk = 0U;+ −
/* This variable used to store the VCO Output (value in Hz) */+ −
uint32_t vcooutput = 0U;+ −
switch (PeriphClk)+ −
{+ −
case RCC_PERIPHCLK_SAI1:+ −
case RCC_PERIPHCLK_SAI2:+ −
{+ −
saiclocksource = RCC->DCKCFGR;+ −
saiclocksource &= (RCC_DCKCFGR_SAI1SRC | RCC_DCKCFGR_SAI2SRC);+ −
switch (saiclocksource)+ −
{+ −
case 0U: /* PLLSAI is the clock source for SAI*/+ −
{+ −
/* Configure the PLLSAI division factor */+ −
/* PLLSAI_VCO Input = PLL_SOURCE/PLLSAIM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)+ −
{+ −
/* In Case the PLL Source is HSI (Internal Clock) */+ −
vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM));+ −
}+ −
else+ −
{+ −
/* In Case the PLL Source is HSE (External Clock) */+ −
vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM)));+ −
}+ −
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */+ −
/* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */+ −
tmpreg1 = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24U;+ −
frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6U))/(tmpreg1);+ −
+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */+ −
tmpreg1 = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8U) + 1U);+ −
frequency = frequency/(tmpreg1);+ −
break;+ −
}+ −
case RCC_DCKCFGR_SAI1SRC_0: /* PLLI2S is the clock source for SAI*/+ −
case RCC_DCKCFGR_SAI2SRC_0: /* PLLI2S is the clock source for SAI*/+ −
{+ −
/* Configure the PLLI2S division factor */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)+ −
{+ −
/* In Case the PLL Source is HSI (Internal Clock) */+ −
vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
else+ −
{+ −
/* In Case the PLL Source is HSE (External Clock) */+ −
vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)));+ −
}+ −
+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
/* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */+ −
tmpreg1 = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24U;+ −
frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U))/(tmpreg1);+ −
+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */+ −
tmpreg1 = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1U);+ −
frequency = frequency/(tmpreg1);+ −
break;+ −
}+ −
case RCC_DCKCFGR_SAI1SRC_1: /* PLLR is the clock source for SAI*/+ −
case RCC_DCKCFGR_SAI2SRC_1: /* PLLR is the clock source for SAI*/+ −
{+ −
/* Configure the PLLI2S division factor */+ −
/* PLL_VCO Input = PLL_SOURCE/PLLM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)+ −
{+ −
/* In Case the PLL Source is HSI (Internal Clock) */+ −
vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
else+ −
{+ −
/* In Case the PLL Source is HSE (External Clock) */+ −
vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));+ −
}+ −
+ −
/* PLL_VCO Output = PLL_VCO Input * PLLN */+ −
/* SAI_CLK_x = PLL_VCO Output/PLLR */+ −
tmpreg1 = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U;+ −
frequency = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U))/(tmpreg1);+ −
break;+ −
}+ −
case RCC_DCKCFGR_SAI1SRC: /* External clock is the clock source for SAI*/+ −
{+ −
frequency = EXTERNAL_CLOCK_VALUE;+ −
break;+ −
}+ −
case RCC_DCKCFGR_SAI2SRC: /* PLLSRC(HSE or HSI) is the clock source for SAI*/+ −
{+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)+ −
{+ −
/* In Case the PLL Source is HSI (Internal Clock) */+ −
frequency = (uint32_t)(HSI_VALUE);+ −
}+ −
else+ −
{+ −
/* In Case the PLL Source is HSE (External Clock) */+ −
frequency = (uint32_t)(HSE_VALUE);+ −
}+ −
break;+ −
}+ −
default :+ −
{+ −
break;+ −
}+ −
}+ −
break;+ −
}+ −
case RCC_PERIPHCLK_I2S_APB1:+ −
{+ −
/* Get the current I2S source */+ −
srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE();+ −
switch (srcclk)+ −
{+ −
/* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */+ −
case RCC_I2SAPB1CLKSOURCE_EXT:+ −
{+ −
/* Set the I2S clock to the external clock value */+ −
frequency = EXTERNAL_CLOCK_VALUE;+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */+ −
case RCC_I2SAPB1CLKSOURCE_PLLI2S:+ −
{+ −
/* Configure the PLLI2S division factor */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));+ −
/* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */+ −
case RCC_I2SAPB1CLKSOURCE_PLLR:+ −
{+ −
/* Configure the PLL division factor R */+ −
/* PLL_VCO Input = PLL_SOURCE/PLLM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
+ −
/* PLL_VCO Output = PLL_VCO Input * PLLN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));+ −
/* I2S_CLK = PLL_VCO Output/PLLR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));+ −
break;+ −
}+ −
/* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */+ −
case RCC_I2SAPB1CLKSOURCE_PLLSRC:+ −
{+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
frequency = HSE_VALUE;+ −
}+ −
else+ −
{+ −
frequency = HSI_VALUE;+ −
}+ −
break;+ −
}+ −
/* Clock not enabled for I2S*/+ −
default:+ −
{+ −
frequency = 0U;+ −
break;+ −
}+ −
}+ −
break;+ −
}+ −
case RCC_PERIPHCLK_I2S_APB2:+ −
{+ −
/* Get the current I2S source */+ −
srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE();+ −
switch (srcclk)+ −
{+ −
/* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */+ −
case RCC_I2SAPB2CLKSOURCE_EXT:+ −
{+ −
/* Set the I2S clock to the external clock value */+ −
frequency = EXTERNAL_CLOCK_VALUE;+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */+ −
case RCC_I2SAPB2CLKSOURCE_PLLI2S:+ −
{+ −
/* Configure the PLLI2S division factor */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));+ −
/* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */+ −
case RCC_I2SAPB2CLKSOURCE_PLLR:+ −
{+ −
/* Configure the PLL division factor R */+ −
/* PLL_VCO Input = PLL_SOURCE/PLLM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
+ −
/* PLL_VCO Output = PLL_VCO Input * PLLN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));+ −
/* I2S_CLK = PLL_VCO Output/PLLR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));+ −
break;+ −
}+ −
/* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */+ −
case RCC_I2SAPB2CLKSOURCE_PLLSRC:+ −
{+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
frequency = HSE_VALUE;+ −
}+ −
else+ −
{+ −
frequency = HSI_VALUE;+ −
}+ −
break;+ −
}+ −
/* Clock not enabled for I2S*/+ −
default:+ −
{+ −
frequency = 0U;+ −
break;+ −
}+ −
}+ −
break;+ −
}+ −
}+ −
return frequency;+ −
}+ −
#endif /* STM32F446xx */+ −
+ −
#if defined(STM32F469xx) || defined(STM32F479xx)+ −
/**+ −
* @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, SAI, LTDC, RTC and TIM).+ −
*+ −
* @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select+ −
* the RTC clock source; in this case the Backup domain will be reset in+ −
* order to modify the RTC Clock source, as consequence RTC registers (including+ −
* the backup registers) and RCC_BDCR register are set to their reset values.+ −
*+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tickstart = 0U;+ −
uint32_t tmpreg1 = 0U;+ −
uint32_t pllsaip = 0U;+ −
uint32_t pllsaiq = 0U;+ −
uint32_t pllsair = 0U;+ −
+ −
/* Check the parameters */+ −
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));+ −
+ −
/*--------------------------- CLK48 Configuration --------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));+ −
+ −
/* Configure the CLK48 clock source */+ −
__HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*------------------------------ SDIO Configuration ------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));+ −
+ −
/* Configure the SDIO clock source */+ −
__HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/+ −
/*------------------- Common configuration SAI/I2S -------------------------*/+ −
/* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division+ −
factor is common parameters for both peripherals */+ −
if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||+ −
(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S) ||+ −
(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))+ −
{+ −
/* check for Parameters */+ −
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;+ −
}+ −
}+ −
+ −
/*---------------------- I2S configuration -------------------------------*/+ −
/* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added+ −
only for I2S configuration */+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))+ −
{+ −
/* check for Parameters */+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */+ −
/* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */+ −
__HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);+ −
}+ −
+ −
/*---------------------------- SAI configuration -------------------------*/+ −
/* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must+ −
be added only for SAI configuration */+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))+ −
{+ −
/* Check the PLLI2S division factors */+ −
assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));+ −
assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));+ −
+ −
/* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */+ −
tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLM */+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
/* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */+ −
__HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1);+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */+ −
__HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);+ −
}+ −
+ −
/*----------------- In Case of PLLI2S is just selected -----------------*/+ −
if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)+ −
{+ −
/* Check for Parameters */+ −
assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));+ −
+ −
/* Configure the PLLI2S multiplication and division factors */+ −
__HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, 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;+ −
}+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/+ −
/*----------------------- Common configuration SAI/LTDC --------------------*/+ −
/* In Case of SAI, LTDC or CLK48 Clock Configuration through PLLSAI, PLLSAIN division+ −
factor is common parameters for these peripherals */+ −
if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||+ −
(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC) ||+ −
((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) &&+ −
(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)))+ −
{+ −
/* Check the PLLSAI division factors */+ −
assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));+ −
+ −
/* Disable PLLSAI Clock */+ −
__HAL_RCC_PLLSAI_DISABLE();+ −
/* Get tick */+ −
tickstart = HAL_GetTick();+ −
/* Wait till PLLSAI is disabled */+ −
while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
/*---------------------------- SAI configuration -------------------------*/+ −
/* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must+ −
be added only for SAI configuration */+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))+ −
{+ −
assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));+ −
assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));+ −
+ −
/* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */+ −
pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);+ −
/* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */+ −
pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);+ −
/* PLLSAI_VCO Input = PLL_SOURCE/PLLM */+ −
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */+ −
/* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */+ −
__HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, pllsair);+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */+ −
__HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);+ −
}+ −
+ −
/*---------------------------- LTDC configuration ------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))+ −
{+ −
assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));+ −
assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));+ −
+ −
/* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */+ −
pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);+ −
/* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */+ −
pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);+ −
/* PLLSAI_VCO Input = PLL_SOURCE/PLLM */+ −
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */+ −
/* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */+ −
__HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, pllsaiq, PeriphClkInit->PLLSAI.PLLSAIR);+ −
/* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */+ −
__HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);+ −
}+ −
+ −
/*---------------------------- CLK48 configuration ------------------------*/+ −
/* Configure the PLLSAI when it is used as clock source for CLK48 */+ −
if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == (RCC_PERIPHCLK_CLK48)) &&+ −
(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))+ −
{+ −
assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));+ −
+ −
/* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */+ −
pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);+ −
/* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */+ −
pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);+ −
/* PLLSAI_VCO Input = PLL_SOURCE/PLLM */+ −
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */+ −
/* CLK48_CLK(first level) = PLLSAI_VCO Output/PLLSAIP */+ −
__HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, pllsair);+ −
}+ −
+ −
/* Enable PLLSAI Clock */+ −
__HAL_RCC_PLLSAI_ENABLE();+ −
/* Get tick */+ −
tickstart = HAL_GetTick();+ −
/* Wait till PLLSAI is ready */+ −
while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- RTC configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))+ −
{+ −
/* Check for RTC Parameters used to output RTCCLK */+ −
assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));+ −
+ −
/* 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 from reset value */+ −
tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);+ −
if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (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 LSE reactivation if LSE was enable prior to Backup Domain reset */+ −
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))+ −
{+ −
/* 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);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- TIM configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))+ −
{+ −
__HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);+ −
}+ −
return HAL_OK;+ −
}+ −
+ −
/**+ −
* @brief Configures the RCC_PeriphCLKInitTypeDef according to the internal+ −
* RCC configuration registers.+ −
* @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that+ −
* will be configured.+ −
* @retval None+ −
*/+ −
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tempreg;+ −
+ −
/* Set all possible values for the extended clock type parameter------------*/+ −
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI |\+ −
RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC |\+ −
RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\+ −
RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO;+ −
+ −
/* Get the PLLI2S Clock configuration --------------------------------------*/+ −
PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);+ −
/* Get the PLLSAI Clock configuration --------------------------------------*/+ −
PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);+ −
PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);+ −
PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);+ −
/* Get the PLLSAI/PLLI2S division factors ----------------------------------*/+ −
PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);+ −
PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);+ −
PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);+ −
/* Get the RTC Clock configuration -----------------------------------------*/+ −
tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);+ −
PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));+ −
+ −
/* Get the CLK48 clock configuration -------------------------------------*/+ −
PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();+ −
+ −
/* Get the SDIO clock configuration ----------------------------------------*/+ −
PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();+ −
+ −
if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;+ −
}+ −
else+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;+ −
}+ −
}+ −
+ −
/**+ −
* @brief Return the peripheral clock frequency for a given peripheral(SAI..)+ −
* @note Return 0 if peripheral clock identifier not managed by this API+ −
* @param PeriphClk Peripheral clock identifier+ −
* This parameter can be one of the following values:+ −
* @arg RCC_PERIPHCLK_I2S: I2S peripheral clock+ −
* @retval Frequency in KHz+ −
*/+ −
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)+ −
{+ −
/* This variable used to store the I2S clock frequency (value in Hz) */+ −
uint32_t frequency = 0U;+ −
/* This variable used to store the VCO Input (value in Hz) */+ −
uint32_t vcoinput = 0U;+ −
uint32_t srcclk = 0U;+ −
/* This variable used to store the VCO Output (value in Hz) */+ −
uint32_t vcooutput = 0U;+ −
switch (PeriphClk)+ −
{+ −
case RCC_PERIPHCLK_I2S:+ −
{+ −
/* Get the current I2S source */+ −
srcclk = __HAL_RCC_GET_I2S_SOURCE();+ −
switch (srcclk)+ −
{+ −
/* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */+ −
case RCC_I2SCLKSOURCE_EXT:+ −
{+ −
/* Set the I2S clock to the external clock value */+ −
frequency = EXTERNAL_CLOCK_VALUE;+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */+ −
case RCC_I2SCLKSOURCE_PLLI2S:+ −
{+ −
/* Configure the PLLI2S division factor */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));+ −
/* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));+ −
break;+ −
}+ −
/* Clock not enabled for I2S*/+ −
default:+ −
{+ −
frequency = 0U;+ −
break;+ −
}+ −
}+ −
break;+ −
}+ −
}+ −
return frequency;+ −
}+ −
#endif /* STM32F469xx || STM32F479xx */+ −
+ −
#if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)+ −
/**+ −
* @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, LTDC RTC and TIM).+ −
*+ −
* @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select+ −
* the RTC clock source; in this case the Backup domain will be reset in+ −
* order to modify the RTC Clock source, as consequence RTC registers (including+ −
* the backup registers) and RCC_BDCR register are set to their reset values.+ −
*+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tickstart = 0U;+ −
uint32_t tmpreg1 = 0U;+ −
#if defined(STM32F413xx) || defined(STM32F423xx)+ −
uint32_t plli2sq = 0U;+ −
#endif /* STM32F413xx || STM32F423xx */+ −
uint32_t plli2sused = 0U;+ −
+ −
/* Check the peripheral clock selection parameters */+ −
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));+ −
+ −
/*----------------------------------- I2S APB1 configuration ---------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1))+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection));+ −
+ −
/* Configure I2S Clock source */+ −
__HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection);+ −
/* Enable the PLLI2S when it's used as clock source for I2S */+ −
if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)+ −
{+ −
plli2sused = 1U;+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*----------------------------------- I2S APB2 configuration ---------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2))+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection));+ −
+ −
/* Configure I2S Clock source */+ −
__HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection);+ −
/* Enable the PLLI2S when it's used as clock source for I2S */+ −
if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)+ −
{+ −
plli2sused = 1U;+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
#if defined(STM32F413xx) || defined(STM32F423xx)+ −
/*----------------------- SAI1 Block A configuration -----------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == (RCC_PERIPHCLK_SAIA))+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_SAIACLKSOURCE(PeriphClkInit->SaiAClockSelection));+ −
+ −
/* Configure SAI1 Clock source */+ −
__HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(PeriphClkInit->SaiAClockSelection);+ −
/* Enable the PLLI2S when it's used as clock source for SAI */+ −
if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)+ −
{+ −
plli2sused = 1U;+ −
}+ −
/* Enable the PLLSAI when it's used as clock source for SAI */+ −
if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLR)+ −
{+ −
/* Check for PLL/DIVR parameters */+ −
assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR));+ −
+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */+ −
__HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR);+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------- SAI1 Block B configuration ------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == (RCC_PERIPHCLK_SAIB))+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_SAIBCLKSOURCE(PeriphClkInit->SaiBClockSelection));+ −
+ −
/* Configure SAI1 Clock source */+ −
__HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG(PeriphClkInit->SaiBClockSelection);+ −
/* Enable the PLLI2S when it's used as clock source for SAI */+ −
if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR)+ −
{+ −
plli2sused = 1U;+ −
}+ −
/* Enable the PLLSAI when it's used as clock source for SAI */+ −
if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLR)+ −
{+ −
/* Check for PLL/DIVR parameters */+ −
assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR));+ −
+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */+ −
__HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR);+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
#endif /* STM32F413xx || STM32F423xx */+ −
+ −
/*------------------------------------ RTC configuration -------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))+ −
{+ −
/* Check for RTC Parameters used to output RTCCLK */+ −
assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));+ −
+ −
/* 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 from reset value */+ −
tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);+ −
if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (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 LSE reactivation if LSE was enable prior to Backup Domain reset */+ −
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))+ −
{+ −
/* 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);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*------------------------------------ TIM configuration -------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))+ −
{+ −
/* Configure Timer Prescaler */+ −
__HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*------------------------------------- FMPI2C1 Configuration --------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));+ −
+ −
/* Configure the FMPI2C1 clock source */+ −
__HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*------------------------------------- CLK48 Configuration ----------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));+ −
+ −
/* Configure the SDIO clock source */+ −
__HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);+ −
+ −
/* Enable the PLLI2S when it's used as clock source for CLK48 */+ −
if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)+ −
{+ −
plli2sused = 1U;+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*------------------------------------- SDIO Configuration -----------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));+ −
+ −
/* Configure the SDIO clock source */+ −
__HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*-------------------------------------- PLLI2S Configuration --------------*/+ −
/* PLLI2S is configured when a peripheral will use it as source clock : I2S on APB1 or+ −
I2S on APB2*/+ −
if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))+ −
{+ −
/* 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;+ −
}+ −
}+ −
+ −
/* check for common PLLI2S Parameters */+ −
assert_param(IS_RCC_PLLI2SCLKSOURCE(PeriphClkInit->PLLI2SSelection));+ −
assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));+ −
assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));+ −
/*-------------------- Set the PLL I2S clock -----------------------------*/+ −
__HAL_RCC_PLL_I2S_CONFIG(PeriphClkInit->PLLI2SSelection);+ −
+ −
/*------- In Case of PLLI2S is selected as source clock for I2S ----------*/+ −
if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) ||+ −
((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)) ||+ −
((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)) ||+ −
((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) && (PeriphClkInit->SdioClockSelection == RCC_SDIOCLKSOURCE_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)))+ −
{+ −
/* check for Parameters */+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));+ −
assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));+ −
+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/+ −
/* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */+ −
__HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);+ −
}+ −
+ −
#if defined(STM32F413xx) || defined(STM32F423xx)+ −
/*------- In Case of PLLI2S is selected as source clock for SAI ----------*/+ −
if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == RCC_PERIPHCLK_SAIA) && (PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)) ||+ −
((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == RCC_PERIPHCLK_SAIB) && (PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR)))+ −
{+ −
/* Check for PLLI2S Parameters */+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));+ −
/* Check for PLLI2S/DIVR parameters */+ −
assert_param(IS_RCC_PLLI2S_DIVR_VALUE(PeriphClkInit->PLLI2SDivR));+ −
+ −
/* Read PLLI2SQ value from PLLI2SCFGR register (this value is not needed for SAI configuration) */+ −
plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
/* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */+ −
__HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR);+ −
+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVR */+ −
__HAL_RCC_PLLI2S_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLI2SDivR);+ −
}+ −
#endif /* STM32F413xx || STM32F423xx */+ −
+ −
/*----------------- In Case of PLLI2S is just selected ------------------*/+ −
if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)+ −
{+ −
/* Check for Parameters */+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));+ −
assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));+ −
+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/+ −
/* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */+ −
__HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, 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;+ −
}+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*-------------------- DFSDM1 clock source configuration -------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));+ −
+ −
/* Configure the DFSDM1 interface clock source */+ −
__HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*-------------------- DFSDM1 Audio clock source configuration -------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1_AUDIO) == RCC_PERIPHCLK_DFSDM1_AUDIO)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection));+ −
+ −
/* Configure the DFSDM1 Audio interface clock source */+ −
__HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
#if defined(STM32F413xx) || defined(STM32F423xx)+ −
/*-------------------- DFSDM2 clock source configuration -------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2) == RCC_PERIPHCLK_DFSDM2)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_DFSDM2CLKSOURCE(PeriphClkInit->Dfsdm2ClockSelection));+ −
+ −
/* Configure the DFSDM1 interface clock source */+ −
__HAL_RCC_DFSDM2_CONFIG(PeriphClkInit->Dfsdm2ClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*-------------------- DFSDM2 Audio clock source configuration -------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2_AUDIO) == RCC_PERIPHCLK_DFSDM2_AUDIO)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_DFSDM2AUDIOCLKSOURCE(PeriphClkInit->Dfsdm2AudioClockSelection));+ −
+ −
/* Configure the DFSDM1 Audio interface clock source */+ −
__HAL_RCC_DFSDM2AUDIO_CONFIG(PeriphClkInit->Dfsdm2AudioClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- LPTIM1 Configuration ------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));+ −
+ −
/* Configure the LPTIM1 clock source */+ −
__HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
#endif /* STM32F413xx || STM32F423xx */+ −
+ −
return HAL_OK;+ −
}+ −
+ −
/**+ −
* @brief Get the RCC_PeriphCLKInitTypeDef according to the internal+ −
* RCC configuration registers.+ −
* @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that+ −
* will be configured.+ −
* @retval None+ −
*/+ −
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tempreg;+ −
+ −
/* Set all possible values for the extended clock type parameter------------*/+ −
#if defined(STM32F413xx) || defined(STM32F423xx)+ −
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\+ −
RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\+ −
RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 |\+ −
RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 |\+ −
RCC_PERIPHCLK_DFSDM1_AUDIO | RCC_PERIPHCLK_DFSDM2 |\+ −
RCC_PERIPHCLK_DFSDM2_AUDIO | RCC_PERIPHCLK_LPTIM1 |\+ −
RCC_PERIPHCLK_SAIA | RCC_PERIPHCLK_SAIB;+ −
#else /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx */+ −
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\+ −
RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\+ −
RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 |\+ −
RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 |\+ −
RCC_PERIPHCLK_DFSDM1_AUDIO;+ −
#endif /* STM32F413xx || STM32F423xx */+ −
+ −
+ −
+ −
/* Get the PLLI2S Clock configuration --------------------------------------*/+ −
PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);+ −
#if defined(STM32F413xx) || defined(STM32F423xx)+ −
/* Get the PLL/PLLI2S division factors -------------------------------------*/+ −
PeriphClkInit->PLLI2SDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVR) >> RCC_DCKCFGR_PLLI2SDIVR_Pos);+ −
PeriphClkInit->PLLDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLDIVR) >> RCC_DCKCFGR_PLLDIVR_Pos);+ −
#endif /* STM32F413xx || STM32F423xx */+ −
+ −
/* Get the I2S APB1 clock configuration ------------------------------------*/+ −
PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE();+ −
+ −
/* Get the I2S APB2 clock configuration ------------------------------------*/+ −
PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE();+ −
+ −
/* Get the RTC Clock configuration -----------------------------------------*/+ −
tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);+ −
PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));+ −
+ −
/* Get the FMPI2C1 clock configuration -------------------------------------*/+ −
PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();+ −
+ −
/* Get the CLK48 clock configuration ---------------------------------------*/+ −
PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();+ −
+ −
/* Get the SDIO clock configuration ----------------------------------------*/+ −
PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();+ −
+ −
/* Get the DFSDM1 clock configuration --------------------------------------*/+ −
PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE();+ −
+ −
/* Get the DFSDM1 Audio clock configuration --------------------------------*/+ −
PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();+ −
+ −
#if defined(STM32F413xx) || defined(STM32F423xx)+ −
/* Get the DFSDM2 clock configuration --------------------------------------*/+ −
PeriphClkInit->Dfsdm2ClockSelection = __HAL_RCC_GET_DFSDM2_SOURCE();+ −
+ −
/* Get the DFSDM2 Audio clock configuration --------------------------------*/+ −
PeriphClkInit->Dfsdm2AudioClockSelection = __HAL_RCC_GET_DFSDM2AUDIO_SOURCE();+ −
+ −
/* Get the LPTIM1 clock configuration --------------------------------------*/+ −
PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();+ −
+ −
/* Get the SAI1 Block Aclock configuration ---------------------------------*/+ −
PeriphClkInit->SaiAClockSelection = __HAL_RCC_GET_SAI_BLOCKA_SOURCE();+ −
+ −
/* Get the SAI1 Block B clock configuration --------------------------------*/+ −
PeriphClkInit->SaiBClockSelection = __HAL_RCC_GET_SAI_BLOCKB_SOURCE();+ −
#endif /* STM32F413xx || STM32F423xx */+ −
+ −
/* Get the TIM Prescaler configuration -------------------------------------*/+ −
if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;+ −
}+ −
else+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;+ −
}+ −
}+ −
+ −
/**+ −
* @brief Return the peripheral clock frequency for a given peripheral(I2S..)+ −
* @note Return 0 if peripheral clock identifier not managed by this API+ −
* @param PeriphClk Peripheral clock identifier+ −
* This parameter can be one of the following values:+ −
* @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock+ −
* @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock+ −
* @retval Frequency in KHz+ −
*/+ −
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)+ −
{+ −
/* This variable used to store the I2S clock frequency (value in Hz) */+ −
uint32_t frequency = 0U;+ −
/* This variable used to store the VCO Input (value in Hz) */+ −
uint32_t vcoinput = 0U;+ −
uint32_t srcclk = 0U;+ −
/* This variable used to store the VCO Output (value in Hz) */+ −
uint32_t vcooutput = 0U;+ −
switch (PeriphClk)+ −
{+ −
case RCC_PERIPHCLK_I2S_APB1:+ −
{+ −
/* Get the current I2S source */+ −
srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE();+ −
switch (srcclk)+ −
{+ −
/* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */+ −
case RCC_I2SAPB1CLKSOURCE_EXT:+ −
{+ −
/* Set the I2S clock to the external clock value */+ −
frequency = EXTERNAL_CLOCK_VALUE;+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */+ −
case RCC_I2SAPB1CLKSOURCE_PLLI2S:+ −
{+ −
if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
else+ −
{+ −
/* Configure the PLLI2S division factor */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
}+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));+ −
/* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */+ −
case RCC_I2SAPB1CLKSOURCE_PLLR:+ −
{+ −
/* Configure the PLL division factor R */+ −
/* PLL_VCO Input = PLL_SOURCE/PLLM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
+ −
/* PLL_VCO Output = PLL_VCO Input * PLLN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));+ −
/* I2S_CLK = PLL_VCO Output/PLLR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));+ −
break;+ −
}+ −
/* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */+ −
case RCC_I2SAPB1CLKSOURCE_PLLSRC:+ −
{+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
frequency = HSE_VALUE;+ −
}+ −
else+ −
{+ −
frequency = HSI_VALUE;+ −
}+ −
break;+ −
}+ −
/* Clock not enabled for I2S*/+ −
default:+ −
{+ −
frequency = 0U;+ −
break;+ −
}+ −
}+ −
break;+ −
}+ −
case RCC_PERIPHCLK_I2S_APB2:+ −
{+ −
/* Get the current I2S source */+ −
srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE();+ −
switch (srcclk)+ −
{+ −
/* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */+ −
case RCC_I2SAPB2CLKSOURCE_EXT:+ −
{+ −
/* Set the I2S clock to the external clock value */+ −
frequency = EXTERNAL_CLOCK_VALUE;+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */+ −
case RCC_I2SAPB2CLKSOURCE_PLLI2S:+ −
{+ −
if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
else+ −
{+ −
/* Configure the PLLI2S division factor */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
}+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));+ −
/* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */+ −
case RCC_I2SAPB2CLKSOURCE_PLLR:+ −
{+ −
/* Configure the PLL division factor R */+ −
/* PLL_VCO Input = PLL_SOURCE/PLLM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
+ −
/* PLL_VCO Output = PLL_VCO Input * PLLN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));+ −
/* I2S_CLK = PLL_VCO Output/PLLR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));+ −
break;+ −
}+ −
/* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */+ −
case RCC_I2SAPB2CLKSOURCE_PLLSRC:+ −
{+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
frequency = HSE_VALUE;+ −
}+ −
else+ −
{+ −
frequency = HSI_VALUE;+ −
}+ −
break;+ −
}+ −
/* Clock not enabled for I2S*/+ −
default:+ −
{+ −
frequency = 0U;+ −
break;+ −
}+ −
}+ −
break;+ −
}+ −
}+ −
return frequency;+ −
}+ −
#endif /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */+ −
+ −
#if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)+ −
/**+ −
* @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 = 0U;+ −
uint32_t tmpreg1 = 0U;+ −
+ −
/* Check the parameters */+ −
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));+ −
+ −
/*---------------------------- RTC configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))+ −
{+ −
/* Check for RTC Parameters used to output RTCCLK */+ −
assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));+ −
+ −
/* 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 from reset value */+ −
tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);+ −
if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (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 LSE reactivation if LSE was enable prior to Backup Domain reset */+ −
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))+ −
{+ −
/* 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);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- TIM configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))+ −
{+ −
__HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- FMPI2C1 Configuration -----------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));+ −
+ −
/* Configure the FMPI2C1 clock source */+ −
__HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- LPTIM1 Configuration ------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));+ −
+ −
/* Configure the LPTIM1 clock source */+ −
__HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);+ −
}+ −
+ −
/*---------------------------- I2S Configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_I2SAPBCLKSOURCE(PeriphClkInit->I2SClockSelection));+ −
+ −
/* Configure the I2S clock source */+ −
__HAL_RCC_I2S_CONFIG(PeriphClkInit->I2SClockSelection);+ −
}+ −
+ −
return HAL_OK;+ −
}+ −
+ −
/**+ −
* @brief Configures the RCC_OscInitStruct according to the internal+ −
* RCC configuration registers.+ −
* @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that+ −
* will be configured.+ −
* @retval None+ −
*/+ −
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tempreg;+ −
+ −
/* Set all possible values for the extended clock type parameter------------*/+ −
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;+ −
+ −
tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);+ −
PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));+ −
+ −
if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;+ −
}+ −
else+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;+ −
}+ −
/* Get the FMPI2C1 clock configuration -------------------------------------*/+ −
PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();+ −
+ −
/* Get the I2S clock configuration -----------------------------------------*/+ −
PeriphClkInit->I2SClockSelection = __HAL_RCC_GET_I2S_SOURCE();+ −
+ −
+ −
}+ −
/**+ −
* @brief Return the peripheral clock frequency for a given peripheral(SAI..)+ −
* @note Return 0 if peripheral clock identifier not managed by this API+ −
* @param PeriphClk Peripheral clock identifier+ −
* This parameter can be one of the following values:+ −
* @arg RCC_PERIPHCLK_I2S: I2S peripheral clock+ −
* @retval Frequency in KHz+ −
*/+ −
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)+ −
{+ −
/* This variable used to store the I2S clock frequency (value in Hz) */+ −
uint32_t frequency = 0U;+ −
/* This variable used to store the VCO Input (value in Hz) */+ −
uint32_t vcoinput = 0U;+ −
uint32_t srcclk = 0U;+ −
/* This variable used to store the VCO Output (value in Hz) */+ −
uint32_t vcooutput = 0U;+ −
switch (PeriphClk)+ −
{+ −
case RCC_PERIPHCLK_I2S:+ −
{+ −
/* Get the current I2S source */+ −
srcclk = __HAL_RCC_GET_I2S_SOURCE();+ −
switch (srcclk)+ −
{+ −
/* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */+ −
case RCC_I2SAPBCLKSOURCE_EXT:+ −
{+ −
/* Set the I2S clock to the external clock value */+ −
frequency = EXTERNAL_CLOCK_VALUE;+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */+ −
case RCC_I2SAPBCLKSOURCE_PLLR:+ −
{+ −
/* Configure the PLL division factor R */+ −
/* PLL_VCO Input = PLL_SOURCE/PLLM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
+ −
/* PLL_VCO Output = PLL_VCO Input * PLLN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));+ −
/* I2S_CLK = PLL_VCO Output/PLLR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));+ −
break;+ −
}+ −
/* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */+ −
case RCC_I2SAPBCLKSOURCE_PLLSRC:+ −
{+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
frequency = HSE_VALUE;+ −
}+ −
else+ −
{+ −
frequency = HSI_VALUE;+ −
}+ −
break;+ −
}+ −
/* Clock not enabled for I2S*/+ −
default:+ −
{+ −
frequency = 0U;+ −
break;+ −
}+ −
}+ −
break;+ −
}+ −
}+ −
return frequency;+ −
}+ −
#endif /* STM32F410Tx || STM32F410Cx || STM32F410Rx */+ −
+ −
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)+ −
/**+ −
* @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, SAI, LTDC RTC and TIM).+ −
*+ −
* @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select+ −
* the RTC clock source; in this case the Backup domain will be reset in+ −
* order to modify the RTC Clock source, as consequence RTC registers (including+ −
* the backup registers) and RCC_BDCR register are set to their reset values.+ −
*+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tickstart = 0U;+ −
uint32_t tmpreg1 = 0U;+ −
+ −
/* Check the parameters */+ −
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));+ −
+ −
/*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/+ −
/*----------------------- Common configuration SAI/I2S ---------------------*/+ −
/* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division+ −
factor is common parameters for both peripherals */+ −
if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||+ −
(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S))+ −
{+ −
/* check for Parameters */+ −
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;+ −
}+ −
}+ −
+ −
/*---------------------------- I2S configuration -------------------------*/+ −
/* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added+ −
only for I2S configuration */+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))+ −
{+ −
/* check for Parameters */+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));+ −
/* 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);+ −
}+ −
+ −
/*---------------------------- SAI configuration -------------------------*/+ −
/* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must+ −
be added only for SAI configuration */+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))+ −
{+ −
/* Check the PLLI2S division factors */+ −
assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));+ −
assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));+ −
+ −
/* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */+ −
tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLM */+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
/* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */+ −
__HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1);+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */+ −
__HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);+ −
}+ −
+ −
/* 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;+ −
}+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/+ −
/*----------------------- Common configuration SAI/LTDC --------------------*/+ −
/* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division+ −
factor is common parameters for both peripherals */+ −
if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||+ −
(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC))+ −
{+ −
/* Check the PLLSAI division factors */+ −
assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));+ −
+ −
/* Disable PLLSAI Clock */+ −
__HAL_RCC_PLLSAI_DISABLE();+ −
/* Get tick */+ −
tickstart = HAL_GetTick();+ −
/* Wait till PLLSAI is disabled */+ −
while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
/*---------------------------- SAI configuration -------------------------*/+ −
/* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must+ −
be added only for SAI configuration */+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))+ −
{+ −
assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));+ −
assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));+ −
+ −
/* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */+ −
tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);+ −
/* PLLSAI_VCO Input = PLL_SOURCE/PLLM */+ −
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */+ −
/* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */+ −
__HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1);+ −
/* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */+ −
__HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);+ −
}+ −
+ −
/*---------------------------- LTDC configuration ------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))+ −
{+ −
assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));+ −
assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));+ −
+ −
/* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */+ −
tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);+ −
/* PLLSAI_VCO Input = PLL_SOURCE/PLLM */+ −
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */+ −
/* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */+ −
__HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, PeriphClkInit->PLLSAI.PLLSAIR);+ −
/* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */+ −
__HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);+ −
}+ −
/* Enable PLLSAI Clock */+ −
__HAL_RCC_PLLSAI_ENABLE();+ −
/* Get tick */+ −
tickstart = HAL_GetTick();+ −
/* Wait till PLLSAI is ready */+ −
while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- RTC configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))+ −
{+ −
/* Check for RTC Parameters used to output RTCCLK */+ −
assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));+ −
+ −
/* 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 from reset value */+ −
tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);+ −
if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (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 LSE reactivation if LSE was enable prior to Backup Domain reset */+ −
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))+ −
{+ −
/* 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);+ −
}+ −
/*--------------------------------------------------------------------------*/+ −
+ −
/*---------------------------- TIM configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))+ −
{+ −
__HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);+ −
}+ −
return HAL_OK;+ −
}+ −
+ −
/**+ −
* @brief Configures the PeriphClkInit according to the internal+ −
* RCC configuration registers.+ −
* @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that+ −
* will be configured.+ −
* @retval None+ −
*/+ −
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tempreg;+ −
+ −
/* Set all possible values for the extended clock type parameter------------*/+ −
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;+ −
+ −
/* Get the PLLI2S Clock configuration -----------------------------------------------*/+ −
PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);+ −
/* Get the PLLSAI Clock configuration -----------------------------------------------*/+ −
PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);+ −
PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);+ −
PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);+ −
/* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/+ −
PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);+ −
PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);+ −
PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);+ −
/* Get the RTC Clock configuration -----------------------------------------------*/+ −
tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);+ −
PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));+ −
+ −
if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;+ −
}+ −
else+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;+ −
}+ −
}+ −
+ −
/**+ −
* @brief Return the peripheral clock frequency for a given peripheral(SAI..)+ −
* @note Return 0 if peripheral clock identifier not managed by this API+ −
* @param PeriphClk Peripheral clock identifier+ −
* This parameter can be one of the following values:+ −
* @arg RCC_PERIPHCLK_I2S: I2S peripheral clock+ −
* @retval Frequency in KHz+ −
*/+ −
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)+ −
{+ −
/* This variable used to store the I2S clock frequency (value in Hz) */+ −
uint32_t frequency = 0U;+ −
/* This variable used to store the VCO Input (value in Hz) */+ −
uint32_t vcoinput = 0U;+ −
uint32_t srcclk = 0U;+ −
/* This variable used to store the VCO Output (value in Hz) */+ −
uint32_t vcooutput = 0U;+ −
switch (PeriphClk)+ −
{+ −
case RCC_PERIPHCLK_I2S:+ −
{+ −
/* Get the current I2S source */+ −
srcclk = __HAL_RCC_GET_I2S_SOURCE();+ −
switch (srcclk)+ −
{+ −
/* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */+ −
case RCC_I2SCLKSOURCE_EXT:+ −
{+ −
/* Set the I2S clock to the external clock value */+ −
frequency = EXTERNAL_CLOCK_VALUE;+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */+ −
case RCC_I2SCLKSOURCE_PLLI2S:+ −
{+ −
/* Configure the PLLI2S division factor */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));+ −
/* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));+ −
break;+ −
}+ −
/* Clock not enabled for I2S */+ −
default:+ −
{+ −
frequency = 0U;+ −
break;+ −
}+ −
}+ −
break;+ −
}+ −
}+ −
return frequency;+ −
}+ −
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */+ −
+ −
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\+ −
defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)+ −
/**+ −
* @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 = 0U;+ −
uint32_t tmpreg1 = 0U;+ −
+ −
/* 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) == RCC_PERIPHCLK_PLLI2S))+ −
{+ −
/* check for Parameters */+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));+ −
assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));+ −
#if defined(STM32F411xE)+ −
assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));+ −
#endif /* STM32F411xE */+ −
/* 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;+ −
}+ −
}+ −
+ −
#if defined(STM32F411xE)+ −
/* Configure the PLLI2S division factors */+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */+ −
/* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */+ −
__HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR);+ −
#else+ −
/* 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);+ −
#endif /* STM32F411xE */+ −
+ −
/* 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))+ −
{+ −
/* Check for RTC Parameters used to output RTCCLK */+ −
assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));+ −
+ −
/* 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 from reset value */+ −
tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);+ −
if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (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 LSE reactivation if LSE was enable prior to Backup Domain reset */+ −
if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))+ −
{+ −
/* 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);+ −
}+ −
#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)+ −
/*---------------------------- TIM configuration ---------------------------*/+ −
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))+ −
{+ −
__HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);+ −
}+ −
#endif /* STM32F401xC || STM32F401xE || STM32F411xE */+ −
return HAL_OK;+ −
}+ −
+ −
/**+ −
* @brief Configures the RCC_OscInitStruct according to the internal+ −
* RCC configuration registers.+ −
* @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that+ −
* will be configured.+ −
* @retval None+ −
*/+ −
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)+ −
{+ −
uint32_t tempreg;+ −
+ −
/* Set all possible values for the extended clock type parameter------------*/+ −
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC;+ −
+ −
/* Get the PLLI2S Clock configuration --------------------------------------*/+ −
PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);+ −
PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);+ −
#if defined(STM32F411xE)+ −
PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM);+ −
#endif /* STM32F411xE */+ −
/* Get the RTC Clock configuration -----------------------------------------*/+ −
tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);+ −
PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));+ −
+ −
#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)+ −
/* Get the TIM Prescaler configuration -------------------------------------*/+ −
if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;+ −
}+ −
else+ −
{+ −
PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;+ −
}+ −
#endif /* STM32F401xC || STM32F401xE || STM32F411xE */+ −
}+ −
+ −
/**+ −
* @brief Return the peripheral clock frequency for a given peripheral(SAI..)+ −
* @note Return 0 if peripheral clock identifier not managed by this API+ −
* @param PeriphClk Peripheral clock identifier+ −
* This parameter can be one of the following values:+ −
* @arg RCC_PERIPHCLK_I2S: I2S peripheral clock+ −
* @retval Frequency in KHz+ −
*/+ −
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)+ −
{+ −
/* This variable used to store the I2S clock frequency (value in Hz) */+ −
uint32_t frequency = 0U;+ −
/* This variable used to store the VCO Input (value in Hz) */+ −
uint32_t vcoinput = 0U;+ −
uint32_t srcclk = 0U;+ −
/* This variable used to store the VCO Output (value in Hz) */+ −
uint32_t vcooutput = 0U;+ −
switch (PeriphClk)+ −
{+ −
case RCC_PERIPHCLK_I2S:+ −
{+ −
/* Get the current I2S source */+ −
srcclk = __HAL_RCC_GET_I2S_SOURCE();+ −
switch (srcclk)+ −
{+ −
/* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */+ −
case RCC_I2SCLKSOURCE_EXT:+ −
{+ −
/* Set the I2S clock to the external clock value */+ −
frequency = EXTERNAL_CLOCK_VALUE;+ −
break;+ −
}+ −
/* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */+ −
case RCC_I2SCLKSOURCE_PLLI2S:+ −
{+ −
#if defined(STM32F411xE)+ −
/* Configure the PLLI2S division factor */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));+ −
}+ −
#else+ −
/* Configure the PLLI2S division factor */+ −
/* PLLI2S_VCO Input = PLL_SOURCE/PLLM */+ −
if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
else+ −
{+ −
/* Get the I2S source clock value */+ −
vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));+ −
}+ −
#endif /* STM32F411xE */+ −
/* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */+ −
vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));+ −
/* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */+ −
frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));+ −
break;+ −
}+ −
/* Clock not enabled for I2S*/+ −
default:+ −
{+ −
frequency = 0U;+ −
break;+ −
}+ −
}+ −
break;+ −
}+ −
}+ −
return frequency;+ −
}+ −
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */+ −
+ −
#if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\+ −
defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)+ −
/**+ −
* @brief Select LSE mode+ −
*+ −
* @note This mode is only available for STM32F410xx/STM32F411xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices.+ −
*+ −
* @param Mode specifies the LSE mode.+ −
* This parameter can be one of the following values:+ −
* @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode selection+ −
* @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection+ −
* @retval None+ −
*/+ −
void HAL_RCCEx_SelectLSEMode(uint8_t Mode)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_LSE_MODE(Mode));+ −
if(Mode == RCC_LSE_HIGHDRIVE_MODE)+ −
{+ −
SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);+ −
}+ −
else+ −
{+ −
CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);+ −
}+ −
}+ −
+ −
#endif /* STM32F410xx || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */+ −
+ −
/** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions+ −
* @brief Extended Clock management functions+ −
*+ −
@verbatim + −
===============================================================================+ −
##### Extended clock management functions #####+ −
===============================================================================+ −
[..]+ −
This subsection provides a set of functions allowing to control the + −
activation or deactivation of PLLI2S, PLLSAI.+ −
@endverbatim+ −
* @{+ −
*/+ −
+ −
#if defined(RCC_PLLI2S_SUPPORT)+ −
/**+ −
* @brief Enable PLLI2S.+ −
* @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that+ −
* contains the configuration information for the PLLI2S+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit)+ −
{+ −
uint32_t tickstart;+ −
+ −
/* Check for parameters */+ −
assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SInit->PLLI2SN));+ −
assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SInit->PLLI2SR));+ −
#if defined(RCC_PLLI2SCFGR_PLLI2SM)+ −
assert_param(IS_RCC_PLLI2SM_VALUE(PLLI2SInit->PLLI2SM));+ −
#endif /* RCC_PLLI2SCFGR_PLLI2SM */+ −
#if defined(RCC_PLLI2SCFGR_PLLI2SP)+ −
assert_param(IS_RCC_PLLI2SP_VALUE(PLLI2SInit->PLLI2SP));+ −
#endif /* RCC_PLLI2SCFGR_PLLI2SP */+ −
#if defined(RCC_PLLI2SCFGR_PLLI2SQ)+ −
assert_param(IS_RCC_PLLI2SQ_VALUE(PLLI2SInit->PLLI2SQ));+ −
#endif /* RCC_PLLI2SCFGR_PLLI2SQ */+ −
+ −
/* Disable the PLLI2S */+ −
__HAL_RCC_PLLI2S_DISABLE();+ −
+ −
/* Wait till PLLI2S is disabled */+ −
tickstart = HAL_GetTick();+ −
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 */+ −
#if defined(STM32F446xx)+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */+ −
/* I2SPCLK = PLLI2S_VCO / PLLI2SP */+ −
/* I2SQCLK = PLLI2S_VCO / PLLI2SQ */+ −
/* I2SRCLK = PLLI2S_VCO / PLLI2SR */+ −
__HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \+ −
PLLI2SInit->PLLI2SP, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);+ −
#elif defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\+ −
defined(STM32F413xx) || defined(STM32F423xx)+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/+ −
/* I2SQCLK = PLLI2S_VCO / PLLI2SQ */+ −
/* I2SRCLK = PLLI2S_VCO / PLLI2SR */+ −
__HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \+ −
PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);+ −
#elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\+ −
defined(STM32F469xx) || defined(STM32F479xx)+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * PLLI2SN */+ −
/* I2SQCLK = PLLI2S_VCO / PLLI2SQ */+ −
/* I2SRCLK = PLLI2S_VCO / PLLI2SR */+ −
__HAL_RCC_PLLI2S_SAICLK_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);+ −
#elif defined(STM32F411xE)+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */+ −
/* I2SRCLK = PLLI2S_VCO / PLLI2SR */+ −
__HAL_RCC_PLLI2S_I2SCLK_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR);+ −
#else+ −
/* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x PLLI2SN */+ −
/* I2SRCLK = PLLI2S_VCO / PLLI2SR */+ −
__HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR);+ −
#endif /* STM32F446xx */+ −
+ −
/* Enable the PLLI2S */+ −
__HAL_RCC_PLLI2S_ENABLE();+ −
+ −
/* Wait till PLLI2S is ready */+ −
tickstart = HAL_GetTick();+ −
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;+ −
}+ −
}+ −
+ −
return HAL_OK;+ −
}+ −
+ −
/**+ −
* @brief Disable PLLI2S.+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)+ −
{+ −
uint32_t tickstart;+ −
+ −
/* Disable the PLLI2S */+ −
__HAL_RCC_PLLI2S_DISABLE();+ −
+ −
/* Wait till PLLI2S is disabled */+ −
tickstart = HAL_GetTick();+ −
while(READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
return HAL_OK;+ −
}+ −
+ −
#endif /* RCC_PLLI2S_SUPPORT */+ −
+ −
#if defined(RCC_PLLSAI_SUPPORT)+ −
/**+ −
* @brief Enable PLLSAI.+ −
* @param PLLSAIInit pointer to an RCC_PLLSAIInitTypeDef structure that+ −
* contains the configuration information for the PLLSAI+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI(RCC_PLLSAIInitTypeDef *PLLSAIInit)+ −
{+ −
uint32_t tickstart;+ −
+ −
/* Check for parameters */+ −
assert_param(IS_RCC_PLLSAIN_VALUE(PLLSAIInit->PLLSAIN));+ −
assert_param(IS_RCC_PLLSAIQ_VALUE(PLLSAIInit->PLLSAIQ));+ −
#if defined(RCC_PLLSAICFGR_PLLSAIM)+ −
assert_param(IS_RCC_PLLSAIM_VALUE(PLLSAIInit->PLLSAIM));+ −
#endif /* RCC_PLLSAICFGR_PLLSAIM */+ −
#if defined(RCC_PLLSAICFGR_PLLSAIP)+ −
assert_param(IS_RCC_PLLSAIP_VALUE(PLLSAIInit->PLLSAIP));+ −
#endif /* RCC_PLLSAICFGR_PLLSAIP */+ −
#if defined(RCC_PLLSAICFGR_PLLSAIR)+ −
assert_param(IS_RCC_PLLSAIR_VALUE(PLLSAIInit->PLLSAIR));+ −
#endif /* RCC_PLLSAICFGR_PLLSAIR */+ −
+ −
/* Disable the PLLSAI */+ −
__HAL_RCC_PLLSAI_DISABLE();+ −
+ −
/* Wait till PLLSAI is disabled */+ −
tickstart = HAL_GetTick();+ −
while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
/* Configure the PLLSAI division factors */+ −
#if defined(STM32F446xx)+ −
/* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLSAIN/PLLSAIM) */+ −
/* SAIPCLK = PLLSAI_VCO / PLLSAIP */+ −
/* SAIQCLK = PLLSAI_VCO / PLLSAIQ */+ −
/* SAIRCLK = PLLSAI_VCO / PLLSAIR */+ −
__HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIM, PLLSAIInit->PLLSAIN, \+ −
PLLSAIInit->PLLSAIP, PLLSAIInit->PLLSAIQ, 0U);+ −
#elif defined(STM32F469xx) || defined(STM32F479xx)+ −
/* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * PLLSAIN */+ −
/* SAIPCLK = PLLSAI_VCO / PLLSAIP */+ −
/* SAIQCLK = PLLSAI_VCO / PLLSAIQ */+ −
/* SAIRCLK = PLLSAI_VCO / PLLSAIR */+ −
__HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIP, \+ −
PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR);+ −
#else+ −
/* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x PLLSAIN */+ −
/* SAIQCLK = PLLSAI_VCO / PLLSAIQ */+ −
/* SAIRCLK = PLLSAI_VCO / PLLSAIR */+ −
__HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR);+ −
#endif /* STM32F446xx */+ −
+ −
/* Enable the PLLSAI */+ −
__HAL_RCC_PLLSAI_ENABLE();+ −
+ −
/* Wait till PLLSAI is ready */+ −
tickstart = HAL_GetTick();+ −
while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
return HAL_OK;+ −
}+ −
+ −
/**+ −
* @brief Disable PLLSAI.+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI(void)+ −
{+ −
uint32_t tickstart;+ −
+ −
/* Disable the PLLSAI */+ −
__HAL_RCC_PLLSAI_DISABLE();+ −
+ −
/* Wait till PLLSAI is disabled */+ −
tickstart = HAL_GetTick();+ −
while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
/* return in case of Timeout detected */+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
return HAL_OK;+ −
}+ −
+ −
#endif /* RCC_PLLSAI_SUPPORT */+ −
+ −
/**+ −
* @}+ −
*/+ −
+ −
#if defined(STM32F446xx)+ −
/**+ −
* @brief Returns the SYSCLK frequency+ −
*+ −
* @note This function implementation is valid only for STM32F446xx devices.+ −
* @note This function add the PLL/PLLR System clock source+ −
*+ −
* @note The system frequency computed by this function is not the real+ −
* frequency in the chip. It is calculated based on the predefined+ −
* constant and the selected clock source:+ −
* @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)+ −
* @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)+ −
* @note If SYSCLK source is PLL or PLLR, function returns values based on HSE_VALUE(**)+ −
* or HSI_VALUE(*) multiplied/divided by the PLL factors.+ −
* @note (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value+ −
* 16 MHz) but the real value may vary depending on the variations+ −
* in voltage and temperature.+ −
* @note (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value+ −
* 25 MHz), user has to ensure that HSE_VALUE is same as the real+ −
* frequency of the crystal used. Otherwise, this function may+ −
* have wrong result.+ −
*+ −
* @note The result of this function could be not correct when using fractional+ −
* value for HSE crystal.+ −
*+ −
* @note This function can be used by the user application to compute the+ −
* baudrate for the communication peripherals or configure other parameters.+ −
*+ −
* @note Each time SYSCLK changes, this function must be called to update the+ −
* right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.+ −
*+ −
*+ −
* @retval SYSCLK frequency+ −
*/+ −
uint32_t HAL_RCC_GetSysClockFreq(void)+ −
{+ −
uint32_t pllm = 0U;+ −
uint32_t pllvco = 0U;+ −
uint32_t pllp = 0U;+ −
uint32_t pllr = 0U;+ −
uint32_t sysclockfreq = 0U;+ −
+ −
/* Get SYSCLK source -------------------------------------------------------*/+ −
switch (RCC->CFGR & RCC_CFGR_SWS)+ −
{+ −
case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */+ −
{+ −
sysclockfreq = HSI_VALUE;+ −
break;+ −
}+ −
case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */+ −
{+ −
sysclockfreq = HSE_VALUE;+ −
break;+ −
}+ −
case RCC_CFGR_SWS_PLL: /* PLL/PLLP used as system clock source */+ −
{+ −
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN+ −
SYSCLK = PLL_VCO / PLLP */+ −
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;+ −
if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)+ −
{+ −
/* HSE used as PLL clock source */+ −
pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);+ −
}+ −
else+ −
{+ −
/* HSI used as PLL clock source */+ −
pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);+ −
}+ −
pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U) *2U);+ −
+ −
sysclockfreq = pllvco/pllp;+ −
break;+ −
}+ −
case RCC_CFGR_SWS_PLLR: /* PLL/PLLR used as system clock source */+ −
{+ −
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN+ −
SYSCLK = PLL_VCO / PLLR */+ −
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;+ −
if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)+ −
{+ −
/* HSE used as PLL clock source */+ −
pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);+ −
}+ −
else+ −
{+ −
/* HSI used as PLL clock source */+ −
pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);+ −
}+ −
pllr = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos);+ −
+ −
sysclockfreq = pllvco/pllr;+ −
break;+ −
}+ −
default:+ −
{+ −
sysclockfreq = HSI_VALUE;+ −
break;+ −
}+ −
}+ −
return sysclockfreq;+ −
}+ −
#endif /* STM32F446xx */+ −
+ −
/**+ −
* @}+ −
*/+ −
+ −
/**+ −
* @}+ −
*/+ −
+ −
/**+ −
* @brief Resets the RCC clock configuration to the default reset state.+ −
* @note The default reset state of the clock configuration is given below:+ −
* - HSI ON and used as system clock source+ −
* - HSE, PLL, PLLI2S and PLLSAI OFF+ −
* - AHB, APB1 and APB2 prescaler set to 1.+ −
* - CSS, MCO1 and MCO2 OFF+ −
* - All interrupts disabled+ −
* @note This function doesn't modify the configuration of the+ −
* - Peripheral clocks+ −
* - LSI, LSE and RTC clocks+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCC_DeInit(void)+ −
{+ −
uint32_t tickstart;+ −
+ −
/* Get Start Tick */+ −
tickstart = HAL_GetTick();+ −
+ −
/* Set HSION bit to the reset value */+ −
SET_BIT(RCC->CR, RCC_CR_HSION);+ −
+ −
/* Wait till HSI is ready */+ −
while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)+ −
{+ −
if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
/* Set HSITRIM[4:0] bits to the reset value */+ −
SET_BIT(RCC->CR, RCC_CR_HSITRIM_4);+ −
+ −
/* Get Start Tick */+ −
tickstart = HAL_GetTick();+ −
+ −
/* Reset CFGR register */+ −
CLEAR_REG(RCC->CFGR);+ −
+ −
/* Wait till clock switch is ready */+ −
while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET)+ −
{+ −
if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
/* Get Start Tick */+ −
tickstart = HAL_GetTick();+ −
+ −
/* Clear HSEON, HSEBYP and CSSON bits */+ −
CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_CSSON);+ −
+ −
/* Wait till HSE is disabled */+ −
while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET)+ −
{+ −
if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
/* Get Start Tick */+ −
tickstart = HAL_GetTick();+ −
+ −
/* Clear PLLON bit */+ −
CLEAR_BIT(RCC->CR, RCC_CR_PLLON);+ −
+ −
/* Wait till PLL is disabled */+ −
while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)+ −
{+ −
if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
#if defined(RCC_PLLI2S_SUPPORT)+ −
/* Get Start Tick */+ −
tickstart = HAL_GetTick();+ −
+ −
/* Reset PLLI2SON bit */+ −
CLEAR_BIT(RCC->CR, RCC_CR_PLLI2SON);+ −
+ −
/* Wait till PLLI2S is disabled */+ −
while (READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET)+ −
{+ −
if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
#endif /* RCC_PLLI2S_SUPPORT */+ −
+ −
#if defined(RCC_PLLSAI_SUPPORT)+ −
/* Get Start Tick */+ −
tickstart = HAL_GetTick();+ −
+ −
/* Reset PLLSAI bit */+ −
CLEAR_BIT(RCC->CR, RCC_CR_PLLSAION);+ −
+ −
/* Wait till PLLSAI is disabled */+ −
while (READ_BIT(RCC->CR, RCC_CR_PLLSAIRDY) != RESET)+ −
{+ −
if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
#endif /* RCC_PLLSAI_SUPPORT */+ −
+ −
/* Once PLL, PLLI2S and PLLSAI are OFF, reset PLLCFGR register to default value */+ −
#if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \+ −
defined(STM32F423xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)+ −
RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLR_1;+ −
#elif defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)+ −
RCC->PLLCFGR = RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLR_1 | RCC_PLLCFGR_PLLR_2 | RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLQ_1 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLQ_3;+ −
#else+ −
RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2;+ −
#endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx || STM32F469xx || STM32F479xx */+ −
+ −
/* Reset PLLI2SCFGR register to default value */+ −
#if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \+ −
defined(STM32F423xx) || defined(STM32F446xx)+ −
RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1;+ −
#elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)+ −
RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1;+ −
#elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)+ −
RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1;+ −
#elif defined(STM32F411xE)+ −
RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1;+ −
#endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx */+ −
+ −
/* Reset PLLSAICFGR register */+ −
#if defined(STM32F427xx) || defined(STM32F429xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)+ −
RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2 | RCC_PLLSAICFGR_PLLSAIR_1;+ −
#elif defined(STM32F446xx)+ −
RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIM_4 | RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2;+ −
#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F469xx || STM32F479xx */+ −
+ −
/* Disable all interrupts */+ −
CLEAR_BIT(RCC->CIR, RCC_CIR_LSIRDYIE | RCC_CIR_LSERDYIE | RCC_CIR_HSIRDYIE | RCC_CIR_HSERDYIE | RCC_CIR_PLLRDYIE);+ −
+ −
#if defined(RCC_CIR_PLLI2SRDYIE)+ −
CLEAR_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYIE);+ −
#endif /* RCC_CIR_PLLI2SRDYIE */+ −
+ −
#if defined(RCC_CIR_PLLSAIRDYIE)+ −
CLEAR_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYIE);+ −
#endif /* RCC_CIR_PLLSAIRDYIE */+ −
+ −
/* Clear all interrupt flags */+ −
SET_BIT(RCC->CIR, RCC_CIR_LSIRDYC | RCC_CIR_LSERDYC | RCC_CIR_HSIRDYC | RCC_CIR_HSERDYC | RCC_CIR_PLLRDYC | RCC_CIR_CSSC);+ −
+ −
#if defined(RCC_CIR_PLLI2SRDYC)+ −
SET_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYC);+ −
#endif /* RCC_CIR_PLLI2SRDYC */+ −
+ −
#if defined(RCC_CIR_PLLSAIRDYC)+ −
SET_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYC);+ −
#endif /* RCC_CIR_PLLSAIRDYC */+ −
+ −
/* Clear LSION bit */+ −
CLEAR_BIT(RCC->CSR, RCC_CSR_LSION);+ −
+ −
/* Reset all CSR flags */+ −
SET_BIT(RCC->CSR, RCC_CSR_RMVF);+ −
+ −
/* Update the SystemCoreClock global variable */+ −
SystemCoreClock = HSI_VALUE;+ −
+ −
/* Adapt Systick interrupt period */+ −
if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)+ −
{+ −
return HAL_ERROR;+ −
}+ −
else+ −
{+ −
return HAL_OK;+ −
}+ −
}+ −
+ −
#if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\+ −
defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)+ −
/**+ −
* @brief Initializes the RCC Oscillators according to the specified parameters in the+ −
* RCC_OscInitTypeDef.+ −
* @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that+ −
* contains the configuration information for the RCC Oscillators.+ −
* @note The PLL is not disabled when used as system clock.+ −
* @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not+ −
* supported by this API. User should request a transition to LSE Off+ −
* first and then LSE On or LSE Bypass.+ −
* @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not+ −
* supported by this API. User should request a transition to HSE Off+ −
* first and then HSE On or HSE Bypass.+ −
* @note This function add the PLL/PLLR factor management during PLL configuration this feature+ −
* is only available in STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices+ −
* @retval HAL status+ −
*/+ −
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)+ −
{+ −
uint32_t tickstart = 0U;+ −
+ −
/* Check the parameters */+ −
assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));+ −
/*------------------------------- HSE Configuration ------------------------*/+ −
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));+ −
/* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */+ −
#if defined(STM32F446xx)+ −
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\+ −
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)) ||\+ −
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))+ −
#else+ −
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\+ −
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))+ −
#endif /* STM32F446xx */+ −
{+ −
if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))+ −
{+ −
return HAL_ERROR;+ −
}+ −
}+ −
else+ −
{+ −
/* Set the new HSE configuration ---------------------------------------*/+ −
__HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);+ −
+ −
/* Check the HSE State */+ −
if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF)+ −
{+ −
/* Get Start Tick*/+ −
tickstart = HAL_GetTick();+ −
+ −
/* Wait till HSE is ready */+ −
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
else+ −
{+ −
/* Get Start Tick*/+ −
tickstart = HAL_GetTick();+ −
+ −
/* Wait till HSE is bypassed or disabled */+ −
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
}+ −
}+ −
/*----------------------------- HSI Configuration --------------------------*/+ −
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));+ −
assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));+ −
+ −
/* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */+ −
#if defined(STM32F446xx)+ −
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\+ −
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)) ||\+ −
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))+ −
#else+ −
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\+ −
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))+ −
#endif /* STM32F446xx */+ −
{+ −
/* When HSI is used as system clock it will not disabled */+ −
if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))+ −
{+ −
return HAL_ERROR;+ −
}+ −
/* Otherwise, just the calibration is allowed */+ −
else+ −
{+ −
/* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/+ −
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);+ −
}+ −
}+ −
else+ −
{+ −
/* Check the HSI State */+ −
if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF)+ −
{+ −
/* Enable the Internal High Speed oscillator (HSI). */+ −
__HAL_RCC_HSI_ENABLE();+ −
+ −
/* Get Start Tick*/+ −
tickstart = HAL_GetTick();+ −
+ −
/* Wait till HSI is ready */+ −
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
/* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/+ −
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);+ −
}+ −
else+ −
{+ −
/* Disable the Internal High Speed oscillator (HSI). */+ −
__HAL_RCC_HSI_DISABLE();+ −
+ −
/* Get Start Tick*/+ −
tickstart = HAL_GetTick();+ −
+ −
/* Wait till HSI is ready */+ −
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
}+ −
}+ −
/*------------------------------ LSI Configuration -------------------------*/+ −
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));+ −
+ −
/* Check the LSI State */+ −
if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF)+ −
{+ −
/* Enable the Internal Low Speed oscillator (LSI). */+ −
__HAL_RCC_LSI_ENABLE();+ −
+ −
/* Get Start Tick*/+ −
tickstart = HAL_GetTick();+ −
+ −
/* Wait till LSI is ready */+ −
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
else+ −
{+ −
/* Disable the Internal Low Speed oscillator (LSI). */+ −
__HAL_RCC_LSI_DISABLE();+ −
+ −
/* Get Start Tick*/+ −
tickstart = HAL_GetTick();+ −
+ −
/* Wait till LSI is ready */+ −
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
}+ −
/*------------------------------ LSE Configuration -------------------------*/+ −
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)+ −
{+ −
FlagStatus pwrclkchanged = RESET;+ −
+ −
/* Check the parameters */+ −
assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));+ −
+ −
/* Update LSE configuration in Backup Domain control register */+ −
/* Requires to enable write access to Backup Domain of necessary */+ −
if(__HAL_RCC_PWR_IS_CLK_DISABLED())+ −
{+ −
__HAL_RCC_PWR_CLK_ENABLE();+ −
pwrclkchanged = SET;+ −
}+ −
+ −
if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))+ −
{+ −
/* Enable write access to Backup domain */+ −
SET_BIT(PWR->CR, PWR_CR_DBP);+ −
+ −
/* Wait for Backup domain Write protection disable */+ −
tickstart = HAL_GetTick();+ −
+ −
while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))+ −
{+ −
if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
+ −
/* Set the new LSE configuration -----------------------------------------*/+ −
__HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);+ −
/* Check the LSE State */+ −
if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF)+ −
{+ −
/* 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;+ −
}+ −
}+ −
}+ −
else+ −
{+ −
/* 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;+ −
}+ −
}+ −
}+ −
+ −
/* Restore clock configuration if changed */+ −
if(pwrclkchanged == SET)+ −
{+ −
__HAL_RCC_PWR_CLK_DISABLE();+ −
}+ −
}+ −
/*-------------------------------- PLL Configuration -----------------------*/+ −
/* Check the parameters */+ −
assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));+ −
if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)+ −
{+ −
/* Check if the PLL is used as system clock or not */+ −
if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)+ −
{+ −
if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)+ −
{+ −
/* Check the parameters */+ −
assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));+ −
assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));+ −
assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));+ −
assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));+ −
assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));+ −
assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));+ −
+ −
/* Disable the main PLL. */+ −
__HAL_RCC_PLL_DISABLE();+ −
+ −
/* Get Start Tick*/+ −
tickstart = HAL_GetTick();+ −
+ −
/* Wait till PLL is ready */+ −
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
+ −
/* Configure the main PLL clock source, multiplication and division factors. */+ −
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,+ −
RCC_OscInitStruct->PLL.PLLM,+ −
RCC_OscInitStruct->PLL.PLLN,+ −
RCC_OscInitStruct->PLL.PLLP,+ −
RCC_OscInitStruct->PLL.PLLQ,+ −
RCC_OscInitStruct->PLL.PLLR);+ −
+ −
/* Enable the main PLL. */+ −
__HAL_RCC_PLL_ENABLE();+ −
+ −
/* Get Start Tick*/+ −
tickstart = HAL_GetTick();+ −
+ −
/* Wait till PLL is ready */+ −
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
else+ −
{+ −
/* Disable the main PLL. */+ −
__HAL_RCC_PLL_DISABLE();+ −
+ −
/* Get Start Tick*/+ −
tickstart = HAL_GetTick();+ −
+ −
/* Wait till PLL is ready */+ −
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)+ −
{+ −
if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)+ −
{+ −
return HAL_TIMEOUT;+ −
}+ −
}+ −
}+ −
}+ −
else+ −
{+ −
return HAL_ERROR;+ −
}+ −
}+ −
return HAL_OK;+ −
}+ −
+ −
/**+ −
* @brief Configures the RCC_OscInitStruct according to the internal+ −
* RCC configuration registers.+ −
* @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that will be configured.+ −
*+ −
* @note This function is only available in case of STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices.+ −
* @note This function add the PLL/PLLR factor management+ −
* @retval None+ −
*/+ −
void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)+ −
{+ −
/* Set all possible values for the Oscillator type parameter ---------------*/+ −
RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;+ −
+ −
/* Get the HSE configuration -----------------------------------------------*/+ −
if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)+ −
{+ −
RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;+ −
}+ −
else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)+ −
{+ −
RCC_OscInitStruct->HSEState = RCC_HSE_ON;+ −
}+ −
else+ −
{+ −
RCC_OscInitStruct->HSEState = RCC_HSE_OFF;+ −
}+ −
+ −
/* Get the HSI configuration -----------------------------------------------*/+ −
if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)+ −
{+ −
RCC_OscInitStruct->HSIState = RCC_HSI_ON;+ −
}+ −
else+ −
{+ −
RCC_OscInitStruct->HSIState = RCC_HSI_OFF;+ −
}+ −
+ −
RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);+ −
+ −
/* Get the LSE configuration -----------------------------------------------*/+ −
if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)+ −
{+ −
RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;+ −
}+ −
else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON)+ −
{+ −
RCC_OscInitStruct->LSEState = RCC_LSE_ON;+ −
}+ −
else+ −
{+ −
RCC_OscInitStruct->LSEState = RCC_LSE_OFF;+ −
}+ −
+ −
/* Get the LSI configuration -----------------------------------------------*/+ −
if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)+ −
{+ −
RCC_OscInitStruct->LSIState = RCC_LSI_ON;+ −
}+ −
else+ −
{+ −
RCC_OscInitStruct->LSIState = RCC_LSI_OFF;+ −
}+ −
+ −
/* Get the PLL configuration -----------------------------------------------*/+ −
if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)+ −
{+ −
RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;+ −
}+ −
else+ −
{+ −
RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;+ −
}+ −
RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);+ −
RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM);+ −
RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);+ −
RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1U) >> RCC_PLLCFGR_PLLP_Pos);+ −
RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos);+ −
RCC_OscInitStruct->PLL.PLLR = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos);+ −
}+ −
#endif /* STM32F410xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */+ −
+ −
#endif /* HAL_RCC_MODULE_ENABLED */+ −
/**+ −
* @}+ −
*/+ −
+ −
/**+ −
* @}+ −
*/+ −
+ −
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/+ −