/**
******************************************************************************
* @file py32f002b_ll_rcc.c
* @author MCU Application Team
* @brief RCC LL module driver.
******************************************************************************
* @attention
*
*
© Copyright (c) 2023 Puya Semiconductor Co.
* All rights reserved.
*
* This software component is licensed by Puya under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
* @attention
*
* © Copyright (c) 2016 STMicroelectronics.
* All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
#if defined(USE_FULL_LL_DRIVER)
/* Includes ------------------------------------------------------------------*/
#include "py32f002b_ll_rcc.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif
/** @addtogroup PY32F002B_LL_Driver
* @{
*/
#if defined(RCC)
/** @addtogroup RCC_LL
* @{
*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/** @addtogroup RCC_LL_Private_Macros
* @{
*/
#define IS_LL_RCC_MCO_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_MCO1_CLKSOURCE))
#if (defined(RCC_CCIPR_COMP1SEL) && defined(RCC_CCIPR_COMP2SEL))
#define IS_LL_RCC_COMP_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_COMP1_CLKSOURCE) \
|| ((__VALUE__) == LL_RCC_COMP2_CLKSOURCE))
#endif
#if defined(RCC_CCIPR_LPTIMSEL)
#define IS_LL_RCC_LPTIM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPTIM1_CLKSOURCE))
#endif /* LPTIM1 */
/**
* @}
*/
/* Private function prototypes -----------------------------------------------*/
/** @defgroup RCC_LL_Private_Functions RCC Private functions
* @{
*/
uint32_t RCC_GetSystemClockFreq(void);
uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup RCC_LL_Exported_Functions
* @{
*/
/** @addtogroup RCC_LL_EF_Init
* @{
*/
/**
* @brief Reset 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
* - AHB and APB1 prescaler set to 1.
* - CSS, MCO OFF
* - All interrupts disabled
* @note This function does not modify the configuration of the
* - Peripheral clocks
* - LSI and LSE clocks
* @retval An ErrorStatus enumeration value:
* - SUCCESS: RCC registers are de-initialized
* - ERROR: not applicable
*/
ErrorStatus LL_RCC_DeInit(void)
{
/* Set HSI_FS, HSITRIM bits to default value*/
LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_24MHz);
/* Set HSION bit and wait for HSI READY bit */
LL_RCC_HSI_Enable();
while (LL_RCC_HSI_IsReady() != 1U)
{}
/* Reset CFGR register */
LL_RCC_WriteReg(CFGR, 0x00000000U);
/* Wait till SYSCLK is HSISYS */
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSISYS)
{}
/* Reset whole CR register but HSI in 2 steps in case HSEBYP is set */
LL_RCC_WriteReg(CR, RCC_CR_HSION);
/* Disable all interrupts */
LL_RCC_WriteReg(CIER, 0x00000000U);
/* Clear all interrupts flags */
LL_RCC_WriteReg(CICR, 0xFFFFFFFFU);
return SUCCESS;
}
/**
* @}
*/
/** @addtogroup RCC_LL_EF_Get_Freq
* @brief Return the frequencies of different on chip clocks; System, AHB and APB1 buses clocks
* and different peripheral clocks available on the device.
* @note If SYSCLK source is HSI, function returns values based on HSI_VALUE divided by HSI division factor(**)
* @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
* or HSI_VALUE(**) multiplied/divided by the PLL factors.
* @note (**) HSI_VALUE is a constant defined in this file (default value
* 8 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
* @note The result of this function could be incorrect when using fractional
* value for HSE crystal.
* @note This function can be used by the user application to compute the
* baud-rate for the communication peripherals or configure other parameters.
* @{
*/
/**
* @brief Return the frequencies of different on chip clocks; System, AHB and APB1 buses clocks
* @note Each time SYSCLK, HCLK and/or PCLK1 clock changes, this function
* must be called to update structure fields. Otherwise, any
* configuration based on this function will be incorrect.
* @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
* @retval None
*/
void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
{
/* Get SYSCLK frequency */
RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
/* HCLK clock frequency */
RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
/* PCLK1 clock frequency */
RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
}
/**
* @brief Return MCO clock frequency
* @param MCOx This parameter can be one of the following values:
* @arg @ref LL_RCC_MCO1_CLKSOURCE
* @retval MCO clock frequency (in Hz)
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSE, LSI or LSE) is not ready
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
*/
uint32_t LL_RCC_GetMCOClockFreq(uint32_t MCOx)
{
uint32_t mco_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
/* Check parameter */
assert_param(IS_LL_RCC_MCO_CLKSOURCE(MCOx));
switch (LL_RCC_GetMCOClockSource(MCOx))
{
case LL_RCC_MCO1SOURCE_SYSCLK: /* MCO Clock is SYSCLK */
mco_frequency = SystemCoreClock;
break;
case LL_RCC_MCO1SOURCE_HSI: /* MCO Clock is HSI */
mco_frequency = LL_RCC_HSI_GetFreq();
break;
case LL_RCC_MCO1SOURCE_HSE: /* MCO Clock is HSE */
if (LL_RCC_HSE_IsBypass() == 1U)
{
mco_frequency = HSE_VALUE;
}
break;
case LL_RCC_MCO1SOURCE_LSI: /* MCO Clock is LSI */
if (LL_RCC_LSI_IsReady() == 1U)
{
mco_frequency = LL_RCC_LSI_GetFreq();
}
break;
#if defined(RCC_LSE_SUPPORT)
case LL_RCC_MCO1SOURCE_LSE: /* MCO Clock is LSE */
if (LL_RCC_LSE_IsReady() == 1U)
{
mco_frequency = LSE_VALUE;
}
break;
#endif
case LL_RCC_MCO1SOURCE_NOCLOCK: /* No clock used as MCO clock source */
default:
mco_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
return mco_frequency;
}
mco_frequency = mco_frequency / (1U << (LL_RCC_GetMCODiv(MCOx) >> RCC_CFGR_MCOPRE_Pos));
return mco_frequency;
}
#if defined(RCC_BDCR_LSCOEN)
/**
* @brief Return LSC clock frequency
* @retval LSC clock frequency (in Hz)
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (LSI or LSE) is not ready
*/
uint32_t LL_RCC_GetLSCClockFreq(void)
{
#if defined(RCC_LSE_SUPPORT)
uint32_t lsc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
switch (LL_RCC_LSCO_GetSource())
{
case LL_RCC_LSCO_CLKSOURCE_LSE: /* LSC Clock is LSE Osc. */
if (LL_RCC_LSE_IsReady() == 1U)
{
lsc_frequency = LSE_VALUE;
}
break;
case LL_RCC_LSCO_CLKSOURCE_LSI: /* LSC Clock is LSI Osc. */
default:
if (LL_RCC_LSI_IsReady() == 1U)
{
lsc_frequency = LL_RCC_LSI_GetFreq();
}
break;
}
return lsc_frequency;
#else
return LL_RCC_LSI_GetFreq();
#endif
}
#endif
#if defined(COMP1)
/**
* @brief Return COMP clock frequency
* @param COMPx This parameter can be one of the following values:
* @arg @ref LL_RCC_COMP1_CLKSOURCE
* @arg @ref LL_RCC_COMP2_CLKSOURCE
* @retval COMP clock frequency (in Hz)
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (PCLK1, LSI or LSE) is not ready
*/
uint32_t LL_RCC_GetCOMPClockFreq(uint32_t COMPx)
{
uint32_t comp_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
/* Check parameter */
assert_param(IS_LL_RCC_COMP_CLKSOURCE(COMPx));
if (COMPx == LL_RCC_COMP1_CLKSOURCE)
{
/* COMP1CLK clock frequency */
switch (LL_RCC_GetCOMPClockSource(COMPx))
{
case LL_RCC_COMP1_CLKSOURCE_LSC: /* COMP1 Clock is LSC */
comp_frequency = LL_RCC_GetLSCClockFreq();
break;
case LL_RCC_COMP1_CLKSOURCE_PCLK1: /* COMP1 Clock is PCLK1 */
default:
comp_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
break;
}
}
#if defined(COMP2)
else
{
/* COMP2CLK clock frequency */
switch (LL_RCC_GetCOMPClockSource(COMPx))
{
case LL_RCC_COMP2_CLKSOURCE_LSC: /* COMP2 Clock is LSC */
comp_frequency = LL_RCC_GetLSCClockFreq();
break;
case LL_RCC_COMP2_CLKSOURCE_PCLK1: /* COMP2 Clock is PCLK1 */
default:
comp_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
break;
}
}
#endif
return comp_frequency;
}
#endif
/**
* @brief Return LPTIMx clock frequency
* @param LPTIMx This parameter can be one of the following values:
* @arg @ref LL_RCC_LPTIM1_CLKSOURCE
* @retval LPTIM clock frequency (in Hz)
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (PCLK1, LSI or LSE) is not ready
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
*/
uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMx)
{
uint32_t lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
/* Check parameter */
assert_param(IS_LL_RCC_LPTIM_CLKSOURCE(LPTIMx));
if (LPTIMx == LL_RCC_LPTIM1_CLKSOURCE)
{
/* LPTIM1CLK clock frequency */
switch (LL_RCC_GetLPTIMClockSource(LPTIMx))
{
case LL_RCC_LPTIM1_CLKSOURCE_LSI: /* LPTIM1 Clock is LSI Osc. */
if (LL_RCC_LSI_IsReady() == 1U)
{
lptim_frequency = LL_RCC_LSI_GetFreq();
}
break;
case LL_RCC_LPTIM1_CLKSOURCE_NONE: /* No clock used as LPTIM1 clock source */
lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
break;
#if defined(RCC_LSE_SUPPORT)
case LL_RCC_LPTIM1_CLKSOURCE_LSE: /* LPTIM1 Clock is LSE Osc. */
if (LL_RCC_LSE_IsReady() == 1U)
{
lptim_frequency = LSE_VALUE;
}
break;
#endif
case LL_RCC_LPTIM1_CLKSOURCE_PCLK1: /* LPTIM1 Clock is PCLK1 */
default:
lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
break;
}
}
return lptim_frequency;
}
/**
* @}
*/
/**
* @}
*/
/** @addtogroup RCC_LL_Private_Functions
* @{
*/
/**
* @brief Return SYSTEM clock frequency
* @retval SYSTEM clock frequency (in Hz)
*/
uint32_t RCC_GetSystemClockFreq(void)
{
uint32_t frequency;
/* Get SYSCLK source -------------------------------------------------------*/
switch (LL_RCC_GetSysClkSource())
{
case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
frequency = HSE_VALUE;
break;
case LL_RCC_SYS_CLKSOURCE_STATUS_LSI:
frequency = LL_RCC_LSI_GetFreq();
break;
#if defined(RCC_LSE_SUPPORT)
case LL_RCC_SYS_CLKSOURCE_STATUS_LSE:
frequency = LSE_VALUE;
break;
#endif
case LL_RCC_SYS_CLKSOURCE_STATUS_HSISYS: /* HSISYS used as system clock source */
default:
frequency = __LL_RCC_CALC_HSI_FREQ(LL_RCC_GetHSIDiv());
break;
}
return frequency;
}
/**
* @brief Return HCLK clock frequency
* @param SYSCLK_Frequency SYSCLK clock frequency
* @retval HCLK clock frequency (in Hz)
*/
uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
{
/* HCLK clock frequency */
return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
}
/**
* @brief Return PCLK1 clock frequency
* @param HCLK_Frequency HCLK clock frequency
* @retval PCLK1 clock frequency (in Hz)
*/
uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
{
/* PCLK1 clock frequency */
return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
}
/**
* @}
*/
/**
* @}
*/
#endif /* defined(RCC) */
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */
/************************ (C) COPYRIGHT Puya*****END OF FILE****/