/***************************************************************************** * Copyright (c) 2019, Nations Technologies Inc. * * All rights reserved. * **************************************************************************** * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * * Nations' name may not be used to endorse or promote products derived from * this software without specific prior written permission. * * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * DISCLAIMED. IN NO EVENT SHALL NATIONS 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. * ****************************************************************************/ /** * @file n32g45x_rcc.c * @author Nations * @version v1.0.2 * * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved. */ #include "n32g45x_rcc.h" /** @addtogroup N32G45X_StdPeriph_Driver * @{ */ /** @addtogroup RCC * @brief RCC driver modules * @{ */ /** @addtogroup RCC_Private_TypesDefinitions * @{ */ /** * @} */ /** @addtogroup RCC_Private_Defines * @{ */ /* ------------ RCC registers bit address in the alias region ----------- */ #define RCC_OFFSET (RCC_BASE - PERIPH_BASE) /* --- CTRL Register ---*/ /* Alias word address of HSIEN bit */ #define CTRL_OFFSET (RCC_OFFSET + 0x00) #define HSIEN_BITN 0x00 #define CTRL_HSIEN_BB (PERIPH_BB_BASE + (CTRL_OFFSET * 32) + (HSIEN_BITN * 4)) /* Alias word address of PLLEN bit */ #define PLLEN_BITN 0x18 #define CTRL_PLLEN_BB (PERIPH_BB_BASE + (CTRL_OFFSET * 32) + (PLLEN_BITN * 4)) /* Alias word address of CLKSSEN bit */ #define CLKSSEN_BITN 0x13 #define CTRL_CLKSSEN_BB (PERIPH_BB_BASE + (CTRL_OFFSET * 32) + (CLKSSEN_BITN * 4)) /* --- CFG Register ---*/ /* Alias word address of USBPRES bit */ #define CFG_OFFSET (RCC_OFFSET + 0x04) #define USBPRES_BITN 0x16 #define CFG_USBPRES_BB (PERIPH_BB_BASE + (CFG_OFFSET * 32) + (USBPRES_BITN * 4)) #define USBPRE_Bit1Number 0x17 #define CFGR_USBPRE_BB_BIT1 (PERIPH_BB_BASE + (CFG_OFFSET * 32) + (USBPRE_Bit1Number * 4)) /* --- BDCTRL Register ---*/ /* Alias word address of RTCEN bit */ #define BDCTRL_OFFSET (RCC_OFFSET + 0x20) #define RTCEN_BITN 0x0F #define BDCTRL_RTCEN_BB (PERIPH_BB_BASE + (BDCTRL_OFFSET * 32) + (RTCEN_BITN * 4)) /* Alias word address of BDSFTRST bit */ #define BDSFTRST_BITN 0x10 #define BDCTRL_BDSFTRST_BB (PERIPH_BB_BASE + (BDCTRL_OFFSET * 32) + (BDSFTRST_BITN * 4)) /* --- CTRLSTS Register ---*/ /* Alias word address of LSIEN bit */ #define CTRLSTS_OFFSET (RCC_OFFSET + 0x24) #define LSIEN_BITNUMBER 0x00 #define CTRLSTS_LSIEN_BB (PERIPH_BB_BASE + (CTRLSTS_OFFSET * 32) + (LSIEN_BITNUMBER * 4)) /* ---------------------- RCC registers bit mask ------------------------ */ /* CTRL register bit mask */ #define CTRL_HSEBP_RESET ((uint32_t)0xFFFBFFFF) #define CTRL_HSEBP_SET ((uint32_t)0x00040000) #define CTRL_HSEEN_RESET ((uint32_t)0xFFFEFFFF) #define CTRL_HSEEN_SET ((uint32_t)0x00010000) #define CTRL_HSITRIM_MASK ((uint32_t)0xFFFFFF07) /* CFG register bit mask */ #define CFG_PLL_MASK ((uint32_t)0xF7C0FFFF) #define CFG_PLLMULFCT_MASK ((uint32_t)0x083C0000) #define CFG_PLLSRC_MASK ((uint32_t)0x00010000) #define CFG_PLLHSEPRES_MASK ((uint32_t)0x00020000) #define CFG_SCLKSTS_MASK ((uint32_t)0x0000000C) #define CFG_SCLKSW_MASK ((uint32_t)0xFFFFFFFC) #define CFG_AHBPRES_RESET_MASK ((uint32_t)0xFFFFFF0F) #define CFG_AHBPRES_SET_MASK ((uint32_t)0x000000F0) #define CFG_APB1PRES_RESET_MASK ((uint32_t)0xFFFFF8FF) #define CFG_APB1PRES_SET_MASK ((uint32_t)0x00000700) #define CFG_APB2PRES_RESET_MASK ((uint32_t)0xFFFFC7FF) #define CFG_APB2PRES_SET_MASK ((uint32_t)0x00003800) /* CFG2 register bit mask */ #define CFG2_TIM18CLKSEL_SET_MASK ((uint32_t)0x20000000) #define CFG2_TIM18CLKSEL_RESET_MASK ((uint32_t)0xDFFFFFFF) #define CFG2_RNGCPRES_SET_MASK ((uint32_t)0x1F000000) #define CFG2_RNGCPRES_RESET_MASK ((uint32_t)0xE0FFFFFF) #define CFG2_ADC1MSEL_SET_MASK ((uint32_t)0x00000400) #define CFG2_ADC1MSEL_RESET_MASK ((uint32_t)0xFFFFFBFF) #define CFG2_ADC1MPRES_SET_MASK ((uint32_t)0x0000F800) #define CFG2_ADC1MPRES_RESET_MASK ((uint32_t)0xFFFF07FF) #define CFG2_ADCPLLPRES_SET_MASK ((uint32_t)0x000001F0) #define CFG2_ADCPLLPRES_RESET_MASK ((uint32_t)0xFFFFFE0F) #define CFG2_ADCHPRES_SET_MASK ((uint32_t)0x0000000F) #define CFG2_ADCHPRES_RESET_MASK ((uint32_t)0xFFFFFFF0) /* CFG3 register bit mask */ #define CFGR3_TRNG1MSEL_SET_MASK ((uint32_t)0x00020000) #define CFGR3_TRNG1MSEL_RESET_MASK ((uint32_t)0xFFFDFFFF) #define CFGR3_TRNG1MPRES_SET_MASK ((uint32_t)0x0000F800) #define CFGR3_TRNG1MPRES_RESET_MASK ((uint32_t)0xFFFF07FF) /* CTRLSTS register bit mask */ #define CSR_RMRSTF_SET ((uint32_t)0x01000000) #define CSR_RMVF_Reset ((uint32_t)0xfeffffff) /* RCC Flag Mask */ #define FLAG_MASK ((uint8_t)0x1F) /* CLKINT register byte 2 (Bits[15:8]) base address */ #define CLKINT_BYTE2_ADDR ((uint32_t)0x40021009) /* CLKINT register byte 3 (Bits[23:16]) base address */ #define CLKINT_BYTE3_ADDR ((uint32_t)0x4002100A) /* CFG register byte 4 (Bits[31:24]) base address */ #define CFG_BYTE4_ADDR ((uint32_t)0x40021007) /* BDCTRL register base address */ #define BDCTRL_ADDR (PERIPH_BASE + BDCTRL_OFFSET) /** * @} */ /** @addtogroup RCC_Private_Macros * @{ */ /** * @} */ /** @addtogroup RCC_Private_Variables * @{ */ static const uint8_t s_ApbAhbPresTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; static const uint8_t s_AdcHclkPresTable[16] = {1, 2, 4, 6, 8, 10, 12, 16, 32, 32, 32, 32, 32, 32, 32, 32}; static const uint16_t s_AdcPllClkPresTable[16] = {1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256, 256, 256, 256, 256}; /** * @} */ /** @addtogroup RCC_Private_FunctionPrototypes * @{ */ /** * @} */ /** @addtogroup RCC_Private_Functions * @{ */ /** * @brief Resets the RCC clock configuration to the default reset state. */ void RCC_DeInit(void) { /* Set HSIEN bit */ RCC->CTRL |= (uint32_t)0x00000001; /* Reset SW, HPRE, PPRE1, PPRE2 and MCO bits */ RCC->CFG &= (uint32_t)0xF8FFC000; /* Reset HSEON, CLKSSEN and PLLEN bits */ RCC->CTRL &= (uint32_t)0xFEF6FFFF; /* Reset HSEBYP bit */ RCC->CTRL &= (uint32_t)0xFFFBFFFF; /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRES/OTGFSPRE bits */ RCC->CFG &= (uint32_t)0xF700FFFF; /* Reset CFG2 register */ RCC->CFG2 = 0x00003800; /* Reset CFG3 register */ RCC->CFG3 = 0x00003840; /* Disable all interrupts and clear pending bits */ RCC->CLKINT = 0x009F0000; } /** * @brief Configures the External High Speed oscillator (HSE). * @note HSE can not be stopped if it is used directly or through the PLL as system clock. * @param RCC_HSE specifies the new state of the HSE. * This parameter can be one of the following values: * @arg RCC_HSE_DISABLE HSE oscillator OFF * @arg RCC_HSE_ENABLE HSE oscillator ON * @arg RCC_HSE_BYPASS HSE oscillator bypassed with external clock */ void RCC_ConfigHse(uint32_t RCC_HSE) { /* Check the parameters */ assert_param(IS_RCC_HSE(RCC_HSE)); /* Reset HSEON and HSEBYP bits before configuring the HSE ------------------*/ /* Reset HSEON bit */ RCC->CTRL &= CTRL_HSEEN_RESET; /* Reset HSEBYP bit */ RCC->CTRL &= CTRL_HSEBP_RESET; /* Configure HSE (RC_HSE_DISABLE is already covered by the code section above) */ switch (RCC_HSE) { case RCC_HSE_ENABLE: /* Set HSEON bit */ RCC->CTRL |= CTRL_HSEEN_SET; break; case RCC_HSE_BYPASS: /* Set HSEBYP and HSEON bits */ RCC->CTRL |= CTRL_HSEBP_SET | CTRL_HSEEN_SET; break; default: break; } } /** * @brief Waits for HSE start-up. * @return An ErrorStatus enumuration value: * - SUCCESS: HSE oscillator is stable and ready to use * - ERROR: HSE oscillator not yet ready */ ErrorStatus RCC_WaitHseStable(void) { __IO uint32_t StartUpCounter = 0; ErrorStatus status = ERROR; FlagStatus HSEStatus = RESET; /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC_GetFlagStatus(RCC_FLAG_HSERD); StartUpCounter++; } while ((StartUpCounter != HSE_STARTUP_TIMEOUT) && (HSEStatus == RESET)); if (RCC_GetFlagStatus(RCC_FLAG_HSERD) != RESET) { status = SUCCESS; } else { status = ERROR; } return (status); } /** * @brief Adjusts the Internal High Speed oscillator (HSI) calibration value. * @param HSICalibrationValue specifies the calibration trimming value. * This parameter must be a number between 0 and 0x1F. */ void RCC_SetHsiCalibValue(uint8_t HSICalibrationValue) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_CALIB_VALUE(HSICalibrationValue)); tmpregister = RCC->CTRL; /* Clear HSITRIM[4:0] bits */ tmpregister &= CTRL_HSITRIM_MASK; /* Set the HSITRIM[4:0] bits according to HSICalibrationValue value */ tmpregister |= (uint32_t)HSICalibrationValue << 3; /* Store the new value */ RCC->CTRL = tmpregister; } /** * @brief Enables or disables the Internal High Speed oscillator (HSI). * @note HSI can not be stopped if it is used directly or through the PLL as system clock. * @param Cmd new state of the HSI. This parameter can be: ENABLE or DISABLE. */ void RCC_EnableHsi(FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(Cmd)); *(__IO uint32_t*)CTRL_HSIEN_BB = (uint32_t)Cmd; } /** * @brief Configures the PLL clock source and multiplication factor. * @note This function must be used only when the PLL is disabled. * @param RCC_PLLSource specifies the PLL entry clock source. * this parameter can be one of the following values: * @arg RCC_PLL_SRC_HSI_DIV2 HSI oscillator clock divided by 2 selected as PLL clock entry * @arg RCC_PLL_SRC_HSE_DIV1 HSE oscillator clock selected as PLL clock entry * @arg RCC_PLL_SRC_HSE_DIV2 HSE oscillator clock divided by 2 selected as PLL clock entry * @param RCC_PLLMul specifies the PLL multiplication factor. * this parameter can be RCC_PLLMul_x where x:[2,32] */ void RCC_ConfigPll(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_PLL_SRC(RCC_PLLSource)); assert_param(IS_RCC_PLL_MUL(RCC_PLLMul)); tmpregister = RCC->CFG; /* Clear PLLSRC, PLLXTPRE and PLLMUL[4:0] bits */ tmpregister &= CFG_PLL_MASK; /* Set the PLL configuration bits */ tmpregister |= RCC_PLLSource | RCC_PLLMul; /* Store the new value */ RCC->CFG = tmpregister; } /** * @brief Enables or disables the PLL. * @note The PLL can not be disabled if it is used as system clock. * @param Cmd new state of the PLL. This parameter can be: ENABLE or DISABLE. */ void RCC_EnablePll(FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(Cmd)); *(__IO uint32_t*)CTRL_PLLEN_BB = (uint32_t)Cmd; } /** * @brief Configures the system clock (SYSCLK). * @param RCC_SYSCLKSource specifies the clock source used as system clock. * This parameter can be one of the following values: * @arg RCC_SYSCLK_SRC_HSI HSI selected as system clock * @arg RCC_SYSCLK_SRC_HSE HSE selected as system clock * @arg RCC_SYSCLK_SRC_PLLCLK PLL selected as system clock */ void RCC_ConfigSysclk(uint32_t RCC_SYSCLKSource) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_SYSCLK_SRC(RCC_SYSCLKSource)); tmpregister = RCC->CFG; /* Clear SW[1:0] bits */ tmpregister &= CFG_SCLKSW_MASK; /* Set SW[1:0] bits according to RCC_SYSCLKSource value */ tmpregister |= RCC_SYSCLKSource; /* Store the new value */ RCC->CFG = tmpregister; } /** * @brief Returns the clock source used as system clock. * @return The clock source used as system clock. The returned value can * be one of the following: * - 0x00: HSI used as system clock * - 0x04: HSE used as system clock * - 0x08: PLL used as system clock */ uint8_t RCC_GetSysclkSrc(void) { return ((uint8_t)(RCC->CFG & CFG_SCLKSTS_MASK)); } /** * @brief Configures the AHB clock (HCLK). * @param RCC_SYSCLK defines the AHB clock divider. This clock is derived from * the system clock (SYSCLK). * This parameter can be one of the following values: * @arg RCC_SYSCLK_DIV1 AHB clock = SYSCLK * @arg RCC_SYSCLK_DIV2 AHB clock = SYSCLK/2 * @arg RCC_SYSCLK_DIV4 AHB clock = SYSCLK/4 * @arg RCC_SYSCLK_DIV8 AHB clock = SYSCLK/8 * @arg RCC_SYSCLK_DIV16 AHB clock = SYSCLK/16 * @arg RCC_SYSCLK_DIV64 AHB clock = SYSCLK/64 * @arg RCC_SYSCLK_DIV128 AHB clock = SYSCLK/128 * @arg RCC_SYSCLK_DIV256 AHB clock = SYSCLK/256 * @arg RCC_SYSCLK_DIV512 AHB clock = SYSCLK/512 */ void RCC_ConfigHclk(uint32_t RCC_SYSCLK) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_SYSCLK_DIV(RCC_SYSCLK)); tmpregister = RCC->CFG; /* Clear HPRE[3:0] bits */ tmpregister &= CFG_AHBPRES_RESET_MASK; /* Set HPRE[3:0] bits according to RCC_SYSCLK value */ tmpregister |= RCC_SYSCLK; /* Store the new value */ RCC->CFG = tmpregister; } /** * @brief Configures the Low Speed APB clock (PCLK1). * @param RCC_HCLK defines the APB1 clock divider. This clock is derived from * the AHB clock (HCLK). * This parameter can be one of the following values: * @arg RCC_HCLK_DIV1 APB1 clock = HCLK * @arg RCC_HCLK_DIV2 APB1 clock = HCLK/2 * @arg RCC_HCLK_DIV4 APB1 clock = HCLK/4 * @arg RCC_HCLK_DIV8 APB1 clock = HCLK/8 * @arg RCC_HCLK_DIV16 APB1 clock = HCLK/16 */ void RCC_ConfigPclk1(uint32_t RCC_HCLK) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_HCLK_DIV(RCC_HCLK)); tmpregister = RCC->CFG; /* Clear PPRE1[2:0] bits */ tmpregister &= CFG_APB1PRES_RESET_MASK; /* Set PPRE1[2:0] bits according to RCC_HCLK value */ tmpregister |= RCC_HCLK; /* Store the new value */ RCC->CFG = tmpregister; } /** * @brief Configures the High Speed APB clock (PCLK2). * @param RCC_HCLK defines the APB2 clock divider. This clock is derived from * the AHB clock (HCLK). * This parameter can be one of the following values: * @arg RCC_HCLK_DIV1 APB2 clock = HCLK * @arg RCC_HCLK_DIV2 APB2 clock = HCLK/2 * @arg RCC_HCLK_DIV4 APB2 clock = HCLK/4 * @arg RCC_HCLK_DIV8 APB2 clock = HCLK/8 * @arg RCC_HCLK_DIV16 APB2 clock = HCLK/16 */ void RCC_ConfigPclk2(uint32_t RCC_HCLK) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_HCLK_DIV(RCC_HCLK)); tmpregister = RCC->CFG; /* Clear PPRE2[2:0] bits */ tmpregister &= CFG_APB2PRES_RESET_MASK; /* Set PPRE2[2:0] bits according to RCC_HCLK value */ tmpregister |= RCC_HCLK << 3; /* Store the new value */ RCC->CFG = tmpregister; } /** * @brief Enables or disables the specified RCC interrupts. * @param RccInt specifies the RCC interrupt sources to be enabled or disabled. * * this parameter can be any combination of the following values * @arg RCC_INT_LSIRDIF LSI ready interrupt * @arg RCC_INT_LSERDIF LSE ready interrupt * @arg RCC_INT_HSIRDIF HSI ready interrupt * @arg RCC_INT_HSERDIF HSE ready interrupt * @arg RCC_INT_PLLRDIF PLL ready interrupt * * @param Cmd new state of the specified RCC interrupts. * This parameter can be: ENABLE or DISABLE. */ void RCC_ConfigInt(uint8_t RccInt, FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_RCC_INT(RccInt)); assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { /* Perform Byte access to RCC_CLKINT bits to enable the selected interrupts */ *(__IO uint8_t*)CLKINT_BYTE2_ADDR |= RccInt; } else { /* Perform Byte access to RCC_CLKINT bits to disable the selected interrupts */ *(__IO uint8_t*)CLKINT_BYTE2_ADDR &= (uint8_t)~RccInt; } } /** * @brief Configures the USB clock (USBCLK). * @param RCC_USBCLKSource specifies the USB clock source. This clock is * derived from the PLL output. * This parameter can be one of the following values: * @arg RCC_USBCLK_SRC_PLLCLK_DIV1_5 PLL clock divided by 1,5 selected as USB clock source * @arg RCC_USBCLK_SRC_PLLCLK_DIV1 PLL clock selected as USB clock source * @arg RCC_USBCLK_SRC_PLLCLK_DIV2 PLL clock divided by 2 selected as USB clock source * @arg RCC_USBCLK_SRC_PLLCLK_DIV3 PLL clock divided by 3 selected as USB clock source */ void RCC_ConfigUsbClk(uint32_t RCC_USBCLKSource) { /* Check the parameters */ assert_param(IS_RCC_USBCLK_SRC(RCC_USBCLKSource)); *(__IO uint32_t*)CFG_USBPRES_BB = RCC_USBCLKSource; *(__IO uint32_t*)CFGR_USBPRE_BB_BIT1 = RCC_USBCLKSource >> 1; } /** * @brief Configures the TIM1/8 clock (TIM1/8CLK). * @param RCC_TIM18CLKSource specifies the TIM1/8 clock source. * This parameter can be one of the following values: * @arg RCC_TIM18CLK_SRC_TIM18CLK * @arg RCC_TIM18CLKSource_AHBCLK */ void RCC_ConfigTim18Clk(uint32_t RCC_TIM18CLKSource) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_TIM18CLKSRC(RCC_TIM18CLKSource)); tmpregister = RCC->CFG2; /* Clear TIMCLK_SEL bits */ tmpregister &= CFG2_TIM18CLKSEL_RESET_MASK; /* Set TIMCLK_SEL bits according to RCC_TIM18CLKSource value */ tmpregister |= RCC_TIM18CLKSource; /* Store the new value */ RCC->CFG2 = tmpregister; } /** * @brief Configures the RNGCCLK prescaler. * @param RCC_RNGCCLKPrescaler specifies the RNGCCLK prescaler. * This parameter can be one of the following values: * @arg RCC_RNGCCLK_SYSCLK_DIV1 RNGCPRE[24:28] = 00000, SYSCLK Divided By 1 * @arg RCC_RNGCCLK_SYSCLK_DIV2 RNGCPRE[24:28] = 00001, SYSCLK Divided By 2 * @arg RCC_RNGCCLK_SYSCLK_DIV3 RNGCPRE[24:28] = 00002, SYSCLK Divided By 3 * ... * @arg RCC_RNGCCLK_SYSCLK_DIV31 RNGCPRE[24:28] = 11110, SYSCLK Divided By 31 * @arg RCC_RNGCCLK_SYSCLK_DIV32 RNGCPRE[24:28] = 11111, SYSCLK Divided By 32 */ void RCC_ConfigRngcClk(uint32_t RCC_RNGCCLKPrescaler) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_RNGCCLKPRE(RCC_RNGCCLKPrescaler)); tmpregister = RCC->CFG2; /* Clear RNGCPRE[3:0] bits */ tmpregister &= CFG2_RNGCPRES_RESET_MASK; /* Set RNGCPRE[3:0] bits according to RCC_RNGCCLKPrescaler value */ tmpregister |= RCC_RNGCCLKPrescaler; /* Store the new value */ RCC->CFG2 = tmpregister; } /** * @brief Configures the ADCx 1M clock (ADC1MCLK). * @param RCC_ADC1MCLKSource specifies the ADC1M clock source. * This parameter can be on of the following values: * @arg RCC_ADC1MCLK_SRC_HSI * @arg RCC_ADC1MCLK_SRC_HSE * * @param RCC_ADC1MPrescaler specifies the ADC1M clock prescaler. * This parameter can be on of the following values: * @arg RCC_ADC1MCLK_DIV1 ADC1M clock = RCC_ADC1MCLKSource_xxx/1 * @arg RCC_ADC1MCLK_DIV2 ADC1M clock = RCC_ADC1MCLKSource_xxx/2 * @arg RCC_ADC1MCLK_DIV3 ADC1M clock = RCC_ADC1MCLKSource_xxx/3 * ... * @arg RCC_ADC1MCLK_DIV31 ADC1M clock = RCC_ADC1MCLKSource_xxx/31 * @arg RCC_ADC1MCLK_DIV32 ADC1M clock = RCC_ADC1MCLKSource_xxx/32 */ void RCC_ConfigAdc1mClk(uint32_t RCC_ADC1MCLKSource, uint32_t RCC_ADC1MPrescaler) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_ADC1MCLKSRC(RCC_ADC1MCLKSource)); assert_param(IS_RCC_ADC1MCLKPRE(RCC_ADC1MPrescaler)); tmpregister = RCC->CFG2; /* Clear ADC1MSEL and ADC1MPRE[4:0] bits */ tmpregister &= CFG2_ADC1MSEL_RESET_MASK; tmpregister &= CFG2_ADC1MPRES_RESET_MASK; /* Set ADC1MSEL bits according to RCC_ADC1MCLKSource value */ tmpregister |= RCC_ADC1MCLKSource; /* Set ADC1MPRE[4:0] bits according to RCC_ADC1MPrescaler value */ tmpregister |= RCC_ADC1MPrescaler; /* Store the new value */ RCC->CFG2 = tmpregister; } /** * @brief Configures the ADCPLLCLK prescaler, and enable/disable ADCPLLCLK. * @param RCC_ADCPLLCLKPrescaler specifies the ADCPLLCLK prescaler. * This parameter can be on of the following values: * @arg RCC_ADCPLLCLK_DISABLE ADCPLLCLKPRES[4:0] = 0xxxx, ADC Pll Clock Disable * @arg RCC_ADCPLLCLK_DIV1 ADCPLLCLKPRES[4:0] = 10000, Pll Clock Divided By 1 * @arg RCC_ADCPLLCLK_DIV2 ADCPLLCLKPRES[4:0] = 10001, Pll Clock Divided By 2 * @arg RCC_ADCPLLCLK_DIV4 ADCPLLCLKPRES[4:0] = 10010, Pll Clock Divided By 4 * @arg RCC_ADCPLLCLK_DIV6 ADCPLLCLKPRES[4:0] = 10011, Pll Clock Divided By 6 * @arg RCC_ADCPLLCLK_DIV8 ADCPLLCLKPRES[4:0] = 10100, Pll Clock Divided By 8 * @arg RCC_ADCPLLCLK_DIV10 ADCPLLCLKPRES[4:0] = 10101, Pll Clock Divided By 10 * @arg RCC_ADCPLLCLK_DIV12 ADCPLLCLKPRES[4:0] = 10110, Pll Clock Divided By 12 * @arg RCC_ADCPLLCLK_DIV16 ADCPLLCLKPRES[4:0] = 10111, Pll Clock Divided By 16 * @arg RCC_ADCPLLCLK_DIV32 ADCPLLCLKPRES[4:0] = 11000, Pll Clock Divided By 32 * @arg RCC_ADCPLLCLK_DIV64 ADCPLLCLKPRES[4:0] = 11001, Pll Clock Divided By 64 * @arg RCC_ADCPLLCLK_DIV128 ADCPLLCLKPRES[4:0] = 11010, Pll Clock Divided By 128 * @arg RCC_ADCPLLCLK_DIV256 ADCPLLCLKPRES[4:0] = 11011, Pll Clock Divided By 256 * @arg RCC_ADCPLLCLK_DIV256 ADCPLLCLKPRES[4:0] = others, Pll Clock Divided By 256 * * @param Cmd specifies the ADCPLLCLK enable/disable selection. * This parameter can be on of the following values: * @arg ENABLE enable ADCPLLCLK * @arg DISABLE disable ADCPLLCLK */ void RCC_ConfigAdcPllClk(uint32_t RCC_ADCPLLCLKPrescaler, FunctionalState Cmd) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_ADCPLLCLKPRE(RCC_ADCPLLCLKPrescaler)); assert_param(IS_FUNCTIONAL_STATE(Cmd)); tmpregister = RCC->CFG2; /* Clear ADCPLLPRES[4:0] bits */ tmpregister &= CFG2_ADCPLLPRES_RESET_MASK; if (Cmd != DISABLE) { tmpregister |= RCC_ADCPLLCLKPrescaler; } else { tmpregister |= RCC_ADCPLLCLKPrescaler; tmpregister &= RCC_ADCPLLCLK_DISABLE; } /* Store the new value */ RCC->CFG2 = tmpregister; } /** * @brief Configures the ADCHCLK prescaler. * @param RCC_ADCHCLKPrescaler specifies the ADCHCLK prescaler. * This parameter can be on of the following values: * @arg RCC_ADCHCLK_DIV1 ADCHCLKPRE[3:0] = 0000, HCLK Clock Divided By 1 * @arg RCC_ADCHCLK_DIV2 ADCHCLKPRE[3:0] = 0001, HCLK Clock Divided By 2 * @arg RCC_ADCHCLK_DIV4 ADCHCLKPRE[3:0] = 0010, HCLK Clock Divided By 4 * @arg RCC_ADCHCLK_DIV6 ADCHCLKPRE[3:0] = 0011, HCLK Clock Divided By 6 * @arg RCC_ADCHCLK_DIV8 ADCHCLKPRE[3:0] = 0100, HCLK Clock Divided By 8 * @arg RCC_ADCHCLK_DIV10 ADCHCLKPRE[3:0] = 0101, HCLK Clock Divided By 10 * @arg RCC_ADCHCLK_DIV12 ADCHCLKPRE[3:0] = 0110, HCLK Clock Divided By 12 * @arg RCC_ADCHCLK_DIV16 ADCHCLKPRE[3:0] = 0111, HCLK Clock Divided By 16 * @arg RCC_ADCHCLK_DIV32 ADCHCLKPRE[3:0] = 1000, HCLK Clock Divided By 32 * @arg RCC_ADCHCLK_DIV32 ADCHCLKPRE[3:0] = others, HCLK Clock Divided By 32 */ void RCC_ConfigAdcHclk(uint32_t RCC_ADCHCLKPrescaler) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_ADCHCLKPRE(RCC_ADCHCLKPrescaler)); tmpregister = RCC->CFG2; /* Clear ADCHPRE[3:0] bits */ tmpregister &= CFG2_ADCHPRES_RESET_MASK; /* Set ADCHPRE[3:0] bits according to RCC_ADCHCLKPrescaler value */ tmpregister |= RCC_ADCHCLKPrescaler; /* Store the new value */ RCC->CFG2 = tmpregister; } /** * @brief Configures the TRNG 1M clock (TRNG1MCLK). * @param RCC_TRNG1MCLKSource specifies the TRNG1M clock source. * This parameter can be on of the following values: * @arg RCC_TRNG1MCLK_SRC_HSI * @arg RCC_TRNG1MCLK_SRC_HSE * * @param RCC_TRNG1MPrescaler specifies the TRNG1M prescaler. * This parameter can be on of the following values: * @arg RCC_TRNG1MCLKDiv_2 TRNG1M clock = RCC_TRNG1MCLKSource_xxx/2 * @arg RCC_TRNG1MCLKDiv_4 TRNG1M clock = RCC_TRNG1MCLKSource_xxx/4 * @arg RCC_TRNG1MCLKDiv_6 TRNG1M clock = RCC_TRNG1MCLKSource_xxx/6 * ... * @arg RCC_TRNG1MCLKDiv_30 TRNG1M clock = RCC_TRNG1MCLKSource_xxx/30 * @arg RCC_TRNG1MCLKDiv_32 TRNG1M clock = RCC_TRNG1MCLKSource_xxx/32 */ void RCC_ConfigTrng1mClk(uint32_t RCC_TRNG1MCLKSource, uint32_t RCC_TRNG1MPrescaler) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_TRNG1MCLK_SRC(RCC_TRNG1MCLKSource)); assert_param(IS_RCC_TRNG1MCLKPRE(RCC_TRNG1MPrescaler)); tmpregister = RCC->CFG3; /* Clear TRNG1MSEL and TRNG1MPRE[4:0] bits */ tmpregister &= CFGR3_TRNG1MSEL_RESET_MASK; tmpregister &= CFGR3_TRNG1MPRES_RESET_MASK; /* Set TRNG1MSEL bits according to RCC_TRNG1MCLKSource value */ tmpregister |= RCC_TRNG1MCLKSource; /* Set TRNG1MPRE[4:0] bits according to RCC_TRNG1MPrescaler value */ tmpregister |= RCC_TRNG1MPrescaler; /* Store the new value */ RCC->CFG3 = tmpregister; } /** * @brief Enable/disable TRNG clock (TRNGCLK). * @param Cmd specifies the TRNGCLK enable/disable selection. * This parameter can be on of the following values: * @arg ENABLE enable TRNGCLK * @arg DISABLE disable TRNGCLK */ void RCC_EnableTrng1mClk(FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { RCC->CFG3 |= RCC_TRNG1MCLK_ENABLE; } else { RCC->CFG3 &= RCC_TRNG1MCLK_DISABLE; } } /** * @brief Configures the External Low Speed oscillator (LSE). * @param RCC_LSE specifies the new state of the LSE. * This parameter can be one of the following values: * @arg RCC_LSE_DISABLE LSE oscillator OFF * @arg RCC_LSE_ENABLE LSE oscillator ON * @arg RCC_LSE_BYPASS LSE oscillator bypassed with external clock */ void RCC_ConfigLse(uint8_t RCC_LSE) { /* Check the parameters */ assert_param(IS_RCC_LSE(RCC_LSE)); /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/ /* Reset LSEON bit */ *(__IO uint8_t*)BDCTRL_ADDR = RCC_LSE_DISABLE; /* Reset LSEBYP bit */ *(__IO uint8_t*)BDCTRL_ADDR = RCC_LSE_DISABLE; /* Configure LSE (RCC_LSE_DISABLE is already covered by the code section above) */ switch (RCC_LSE) { case RCC_LSE_ENABLE: /* Set LSEON bit */ *(__IO uint8_t*)BDCTRL_ADDR = RCC_LSE_ENABLE; break; case RCC_LSE_BYPASS: /* Set LSEBYP and LSEON bits */ *(__IO uint8_t*)BDCTRL_ADDR = RCC_LSE_BYPASS | RCC_LSE_ENABLE; break; default: break; } } /** * @brief Enables or disables the Internal Low Speed oscillator (LSI). * @note LSI can not be disabled if the IWDG is running. * @param Cmd new state of the LSI. This parameter can be: ENABLE or DISABLE. */ void RCC_EnableLsi(FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(Cmd)); *(__IO uint32_t*)CTRLSTS_LSIEN_BB = (uint32_t)Cmd; } /** * @brief Configures the RTC clock (RTCCLK). * @note Once the RTC clock is selected it can't be changed unless the Backup domain is reset. * @param RCC_RTCCLKSource specifies the RTC clock source. * This parameter can be one of the following values: * @arg RCC_RTCCLK_SRC_LSE LSE selected as RTC clock * @arg RCC_RTCCLK_SRC_LSI LSI selected as RTC clock * @arg RCC_RTCCLK_SRC_HSE_DIV128 HSE clock divided by 128 selected as RTC clock */ void RCC_ConfigRtcClk(uint32_t RCC_RTCCLKSource) { /* Check the parameters */ assert_param(IS_RCC_RTCCLK_SRC(RCC_RTCCLKSource)); /* Clear the RTC clock source */ RCC->BDCTRL &= (~0x00000300); /* Select the RTC clock source */ RCC->BDCTRL |= RCC_RTCCLKSource; } /** * @brief Enables or disables the RTC clock. * @note This function must be used only after the RTC clock was selected using the RCC_ConfigRtcClk function. * @param Cmd new state of the RTC clock. This parameter can be: ENABLE or DISABLE. */ void RCC_EnableRtcClk(FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(Cmd)); *(__IO uint32_t*)BDCTRL_RTCEN_BB = (uint32_t)Cmd; } /** * @brief Returns the frequencies of different on chip clocks. * @param RCC_Clocks pointer to a RCC_ClocksType structure which will hold * the clocks frequencies. * @note The result of this function could be not correct when using * fractional value for HSE crystal. */ void RCC_GetClocksFreqValue(RCC_ClocksType* RCC_Clocks) { uint32_t tmp = 0, pllclk = 0, pllmull = 0, pllsource = 0, presc = 0; /* Get PLL clock source and multiplication factor ----------------------*/ pllmull = RCC->CFG & CFG_PLLMULFCT_MASK; pllsource = RCC->CFG & CFG_PLLSRC_MASK; if ((pllmull & RCC_CFG_PLLMULFCT_4) == 0) { pllmull = (pllmull >> 18) + 2; // PLLMUL[4]=0 } else { pllmull = ((pllmull >> 18) - 496) + 1; // PLLMUL[4]=1 } if (pllsource == 0x00) { /* HSI oscillator clock divided by 2 selected as PLL clock entry */ pllclk = (HSI_VALUE >> 1) * pllmull; } else { /* HSE selected as PLL clock entry */ if ((RCC->CFG & CFG_PLLHSEPRES_MASK) != (uint32_t)RESET) { /* HSE oscillator clock divided by 2 */ pllclk = (HSE_VALUE >> 1) * pllmull; } else { pllclk = HSE_VALUE * pllmull; } } /* Get SYSCLK source -------------------------------------------------------*/ tmp = RCC->CFG & CFG_SCLKSTS_MASK; switch (tmp) { case 0x00: /* HSI used as system clock */ RCC_Clocks->SysclkFreq = HSI_VALUE; break; case 0x04: /* HSE used as system clock */ RCC_Clocks->SysclkFreq = HSE_VALUE; break; case 0x08: /* PLL used as system clock */ RCC_Clocks->SysclkFreq = pllclk; break; default: RCC_Clocks->SysclkFreq = HSI_VALUE; break; } /* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/ /* Get HCLK prescaler */ tmp = RCC->CFG & CFG_AHBPRES_SET_MASK; tmp = tmp >> 4; presc = s_ApbAhbPresTable[tmp]; /* HCLK clock frequency */ RCC_Clocks->HclkFreq = RCC_Clocks->SysclkFreq >> presc; /* Get PCLK1 prescaler */ tmp = RCC->CFG & CFG_APB1PRES_SET_MASK; tmp = tmp >> 8; presc = s_ApbAhbPresTable[tmp]; /* PCLK1 clock frequency */ RCC_Clocks->Pclk1Freq = RCC_Clocks->HclkFreq >> presc; /* Get PCLK2 prescaler */ tmp = RCC->CFG & CFG_APB2PRES_SET_MASK; tmp = tmp >> 11; presc = s_ApbAhbPresTable[tmp]; /* PCLK2 clock frequency */ RCC_Clocks->Pclk2Freq = RCC_Clocks->HclkFreq >> presc; /* Get ADCHCLK prescaler */ tmp = RCC->CFG2 & CFG2_ADCHPRES_SET_MASK; presc = s_AdcHclkPresTable[tmp]; /* ADCHCLK clock frequency */ RCC_Clocks->AdcHclkFreq = RCC_Clocks->HclkFreq / presc; /* Get ADCPLLCLK prescaler */ tmp = RCC->CFG2 & CFG2_ADCPLLPRES_SET_MASK; tmp = tmp >> 4; presc = s_AdcPllClkPresTable[(tmp & 0xF)]; // ignore BIT5 /* ADCPLLCLK clock frequency */ RCC_Clocks->AdcPllClkFreq = pllclk / presc; } /** * @brief Enables or disables the AHB peripheral clock. * @param RCC_AHBPeriph specifies the AHB peripheral to gates its clock. * * this parameter can be any combination of the following values: * @arg RCC_AHB_PERIPH_DMA1 * @arg RCC_AHB_PERIPH_DMA2 * @arg RCC_AHB_PERIPH_SRAM * @arg RCC_AHB_PERIPH_FLITF * @arg RCC_AHB_PERIPH_CRC * @arg RCC_AHB_PERIPH_RNGC * @arg RCC_AHB_PERIPH_SDIO * @arg RCC_AHB_PERIPH_SAC * @arg RCC_AHB_PERIPH_ADC1 * @arg RCC_AHB_PERIPH_ADC2 * @arg RCC_AHB_PERIPH_ADC3 * @arg RCC_AHB_PERIPH_ADC4 * @arg RCC_AHB_PERIPH_ETHMAC * @arg RCC_AHB_PERIPH_QSPI * * @note SRAM and FLITF clock can be disabled only during sleep mode. * @param Cmd new state of the specified peripheral clock. * This parameter can be: ENABLE or DISABLE. */ void RCC_EnableAHBPeriphClk(uint32_t RCC_AHBPeriph, FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph)); assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { RCC->AHBPCLKEN |= RCC_AHBPeriph; } else { RCC->AHBPCLKEN &= ~RCC_AHBPeriph; } } /** * @brief Enables or disables the High Speed APB (APB2) peripheral clock. * @param RCC_APB2Periph specifies the APB2 peripheral to gates its clock. * This parameter can be any combination of the following values: * @arg RCC_APB2_PERIPH_AFIO, RCC_APB2_PERIPH_GPIOA, RCC_APB2_PERIPH_GPIOB, * RCC_APB2_PERIPH_GPIOC, RCC_APB2_PERIPH_GPIOD, RCC_APB2_PERIPH_GPIOE, * RCC_APB2_PERIPH_GPIOF, RCC_APB2_PERIPH_GPIOG, RCC_APB2_PERIPH_TIM1, * RCC_APB2_PERIPH_SPI1, RCC_APB2_PERIPH_TIM8, RCC_APB2_PERIPH_USART1, * RCC_APB2_PERIPH_DVP, RCC_APB2_PERIPH_UART6, RCC_APB2_PERIPH_UART7, * RCC_APB2_PERIPH_I2C3, RCC_APB2_PERIPH_I2C4 * @param Cmd new state of the specified peripheral clock. * This parameter can be: ENABLE or DISABLE. */ void RCC_EnableAPB2PeriphClk(uint32_t RCC_APB2Periph, FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { RCC->APB2PCLKEN |= RCC_APB2Periph; } else { RCC->APB2PCLKEN &= ~RCC_APB2Periph; } } /** * @brief Enables or disables the Low Speed APB (APB1) peripheral clock. * @param RCC_APB1Periph specifies the APB1 peripheral to gates its clock. * This parameter can be any combination of the following values: * @arg RCC_APB1_PERIPH_TIM2, RCC_APB1_PERIPH_TIM3, RCC_APB1_PERIPH_TIM4, * RCC_APB1_PERIPH_TIM5, RCC_APB1_PERIPH_TIM6, RCC_APB1_PERIPH_TIM7, * RCC_APB1_PERIPH_COMP, RCC_APB1_PERIPH_COMP_FILT, RCC_APB1_PERIPH_TSC, * RCC_APB1_PERIPH_WWDG, RCC_APB1_PERIPH_SPI2, RCC_APB1_PERIPH_SPI3, * RCC_APB1_PERIPH_USART2, RCC_APB1_PERIPH_USART3, RCC_APB1_PERIPH_UART4, * RCC_APB1_PERIPH_UART5, RCC_APB1_PERIPH_I2C1, RCC_APB1_PERIPH_I2C2, * RCC_APB1_PERIPH_USB, RCC_APB1_PERIPH_CAN1, RCC_APB1_PERIPH_CAN2, RCC_APB1_PERIPH_BKP, * RCC_APB1_PERIPH_PWR, RCC_APB1_PERIPH_DAC, RCC_APB1_PERIPH_OPAMP * * @param Cmd new state of the specified peripheral clock. * This parameter can be: ENABLE or DISABLE. */ void RCC_EnableAPB1PeriphClk(uint32_t RCC_APB1Periph, FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { RCC->APB1PCLKEN |= RCC_APB1Periph; } else { RCC->APB1PCLKEN &= ~RCC_APB1Periph; } } /** * @brief Forces or releases AHB peripheral reset. * @param RCC_AHBPeriph specifies the AHB peripheral to reset. * This parameter can be any combination of the following values: * @arg RCC_AHB_PERIPH_QSPI. * RCC_AHB_PERIPH_ETHMAC. * RCC_AHB_PERIPH_ADC4. * RCC_AHB_PERIPH_ADC3. * RCC_AHB_PERIPH_ADC2. * RCC_AHB_PERIPH_ADC1. * RCC_AHB_PERIPH_SAC. * RCC_AHB_PERIPH_RNGC. * @param Cmd new state of the specified peripheral reset. This parameter can be ENABLE or DISABLE. */ void RCC_EnableAHBPeriphReset(uint32_t RCC_AHBPeriph, FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph)); assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { RCC->AHBPRST |= RCC_AHBPeriph; } else { RCC->AHBPRST &= ~RCC_AHBPeriph; } } /** * @brief Forces or releases High Speed APB (APB2) peripheral reset. * @param RCC_APB2Periph specifies the APB2 peripheral to reset. * This parameter can be any combination of the following values: * @arg RCC_APB2_PERIPH_AFIO, RCC_APB2_PERIPH_GPIOA, RCC_APB2_PERIPH_GPIOB, * RCC_APB2_PERIPH_GPIOC, RCC_APB2_PERIPH_GPIOD, RCC_APB2_PERIPH_GPIOE, * RCC_APB2_PERIPH_GPIOF, RCC_APB2_PERIPH_GPIOG, RCC_APB2_PERIPH_TIM1, * RCC_APB2_PERIPH_SPI1, RCC_APB2_PERIPH_TIM8, RCC_APB2_PERIPH_USART1, * RCC_APB2_PERIPH_DVP, RCC_APB2_PERIPH_UART6, RCC_APB2_PERIPH_UART7, * RCC_APB2_PERIPH_I2C3, RCC_APB2_PERIPH_I2C4 * @param Cmd new state of the specified peripheral reset. * This parameter can be: ENABLE or DISABLE. */ void RCC_EnableAPB2PeriphReset(uint32_t RCC_APB2Periph, FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { RCC->APB2PRST |= RCC_APB2Periph; } else { RCC->APB2PRST &= ~RCC_APB2Periph; } } /** * @brief Forces or releases Low Speed APB (APB1) peripheral reset. * @param RCC_APB1Periph specifies the APB1 peripheral to reset. * This parameter can be any combination of the following values: * @arg RCC_APB1_PERIPH_TIM2, RCC_APB1_PERIPH_TIM3, RCC_APB1_PERIPH_TIM4, * RCC_APB1_PERIPH_TIM5, RCC_APB1_PERIPH_TIM6, RCC_APB1_PERIPH_TIM7, * RCC_APB1_PERIPH_TSC, RCC_APB1_PERIPH_WWDG, RCC_APB1_PERIPH_SPI2, * RCC_APB1_PERIPH_SPI3, RCC_APB1_PERIPH_USART2, RCC_APB1_PERIPH_USART3, * RCC_APB1_PERIPH_UART4, RCC_APB1_PERIPH_UART5, RCC_APB1_PERIPH_I2C1, * RCC_APB1_PERIPH_I2C2, RCC_APB1_PERIPH_USB, RCC_APB1_PERIPH_CAN1, * RCC_APB1_PERIPH_CAN2, RCC_APB1_PERIPH_BKP, RCC_APB1_PERIPH_PWR, * RCC_APB1_PERIPH_DAC * @param Cmd new state of the specified peripheral clock. * This parameter can be: ENABLE or DISABLE. */ void RCC_EnableAPB1PeriphReset(uint32_t RCC_APB1Periph, FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph)); assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { RCC->APB1PRST |= RCC_APB1Periph; } else { RCC->APB1PRST &= ~RCC_APB1Periph; } } /** * @brief BOR reset enable. * @param Cmd new state of the BOR reset. * This parameter can be: ENABLE or DISABLE. */ void RCC_EnableBORReset(FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(Cmd)); if (Cmd != DISABLE) { RCC->CFG3 |= RCC_BOR_RST_ENABLE; } else { RCC->CFG3 &= ~RCC_BOR_RST_ENABLE; } } /** * @brief Forces or releases the Backup domain reset. * @param Cmd new state of the Backup domain reset. * This parameter can be: ENABLE or DISABLE. */ void RCC_EnableBackupReset(FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(Cmd)); *(__IO uint32_t*)BDCTRL_BDSFTRST_BB = (uint32_t)Cmd; } /** * @brief Enables or disables the Clock Security System. * @param Cmd new state of the Clock Security System.. * This parameter can be: ENABLE or DISABLE. */ void RCC_EnableClockSecuritySystem(FunctionalState Cmd) { /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(Cmd)); *(__IO uint32_t*)CTRL_CLKSSEN_BB = (uint32_t)Cmd; } /** * @brief Configures the MCO PLL clock prescaler. * @param RCC_MCOPLLCLKPrescaler specifies the MCO PLL clock prescaler. * This parameter can be on of the following values: * @arg RCC_MCO_PLLCLK_DIV2 MCOPRE[3:0] = 0010, PLL Clock Divided By 2 * @arg RCC_MCO_PLLCLK_DIV3 MCOPRE[3:0] = 0011, PLL Clock Divided By 3 * @arg RCC_MCO_PLLCLK_DIV4 MCOPRE[3:0] = 0100, PLL Clock Divided By 4 * @arg RCC_MCO_PLLCLK_DIV5 MCOPRE[3:0] = 0101, PLL Clock Divided By 5 * ... * @arg RCC_MCO_PLLCLK_DIV13 MCOPRE[3:0] = 1101, PLL Clock Divided By 13 * @arg RCC_MCO_PLLCLK_DIV14 MCOPRE[3:0] = 1110, PLL Clock Divided By 14 * @arg RCC_MCO_PLLCLK_DIV15 MCOPRE[3:0] = 1111, PLL Clock Divided By 15 */ void RCC_ConfigMcoPllClk(uint32_t RCC_MCOPLLCLKPrescaler) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_MCOPLLCLKPRE(RCC_MCOPLLCLKPrescaler)); tmpregister = RCC->CFG; /* Clear MCOPRE[3:0] bits */ tmpregister &= ((uint32_t)0x0FFFFFFF); /* Set MCOPRE[3:0] bits according to RCC_ADCHCLKPrescaler value */ tmpregister |= RCC_MCOPLLCLKPrescaler; /* Store the new value */ RCC->CFG = tmpregister; } /** * @brief Selects the clock source to output on MCO pin. * @param RCC_MCO specifies the clock source to output. * * this parameter can be one of the following values: * @arg RCC_MCO_NOCLK No clock selected * @arg RCC_MCO_SYSCLK System clock selected * @arg RCC_MCO_HSI HSI oscillator clock selected * @arg RCC_MCO_HSE HSE oscillator clock selected * @arg RCC_MCO_PLLCLK PLL clock divided by xx selected * */ void RCC_ConfigMco(uint8_t RCC_MCO) { uint32_t tmpregister = 0; /* Check the parameters */ assert_param(IS_RCC_MCO(RCC_MCO)); tmpregister = RCC->CFG; /* Clear MCO[2:0] bits */ tmpregister &= ((uint32_t)0xF8FFFFFF); /* Set MCO[2:0] bits according to RCC_MCO value */ tmpregister |= ((uint32_t)(RCC_MCO << 24)); /* Store the new value */ RCC->CFG = tmpregister; } /** * @brief Checks whether the specified RCC flag is set or not. * @param RCC_FLAG specifies the flag to check. * * this parameter can be one of the following values: * @arg RCC_FLAG_HSIRD HSI oscillator clock ready * @arg RCC_FLAG_HSERD HSE oscillator clock ready * @arg RCC_FLAG_PLLRD PLL clock ready * @arg RCC_FLAG_LSERD LSE oscillator clock ready * @arg RCC_FLAG_LSIRD LSI oscillator clock ready * @arg RCC_FLAG_BORRST BOR reset flag * @arg RCC_FLAG_RETEMC Retention EMC reset flag * @arg RCC_FLAG_BKPEMC BackUp EMC reset flag * @arg RCC_FLAG_RAMRST RAM reset flag * @arg RCC_FLAG_MMURST Mmu reset flag * @arg RCC_FLAG_PINRST Pin reset * @arg RCC_FLAG_PORRST POR/PDR reset * @arg RCC_FLAG_SFTRST Software reset * @arg RCC_FLAG_IWDGRST Independent Watchdog reset * @arg RCC_FLAG_WWDGRST Window Watchdog reset * @arg RCC_FLAG_LPWRRST Low Power reset * * @return The new state of RCC_FLAG (SET or RESET). */ FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) { uint32_t tmp = 0; uint32_t statusreg = 0; FlagStatus bitstatus = RESET; /* Check the parameters */ assert_param(IS_RCC_FLAG(RCC_FLAG)); /* Get the RCC register index */ tmp = RCC_FLAG >> 5; if (tmp == 1) /* The flag to check is in CTRL register */ { statusreg = RCC->CTRL; } else if (tmp == 2) /* The flag to check is in BDCTRL register */ { statusreg = RCC->BDCTRL; } else /* The flag to check is in CTRLSTS register */ { statusreg = RCC->CTRLSTS; } /* Get the flag position */ tmp = RCC_FLAG & FLAG_MASK; if ((statusreg & ((uint32_t)1 << tmp)) != (uint32_t)RESET) { bitstatus = SET; } else { bitstatus = RESET; } /* Return the flag status */ return bitstatus; } /** * @brief Clears the RCC reset flags. * @note The reset flags are: RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST, * RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST */ void RCC_ClrFlag(void) { /* Set RMVF bit to clear the reset flags */ RCC->CTRLSTS |= CSR_RMRSTF_SET; /* RMVF bit should be reset */ RCC->CTRLSTS &= CSR_RMVF_Reset; } /** * @brief Checks whether the specified RCC interrupt has occurred or not. * @param RccInt specifies the RCC interrupt source to check. * * this parameter can be one of the following values: * @arg RCC_INT_LSIRDIF LSI ready interrupt * @arg RCC_INT_LSERDIF LSE ready interrupt * @arg RCC_INT_HSIRDIF HSI ready interrupt * @arg RCC_INT_HSERDIF HSE ready interrupt * @arg RCC_INT_PLLRDIF PLL ready interrupt * * @arg RCC_INT_CLKSSIF Clock Security System interrupt * * @return The new state of RccInt (SET or RESET). */ INTStatus RCC_GetIntStatus(uint8_t RccInt) { INTStatus bitstatus = RESET; /* Check the parameters */ assert_param(IS_RCC_GET_INT(RccInt)); /* Check the status of the specified RCC interrupt */ if ((RCC->CLKINT & RccInt) != (uint32_t)RESET) { bitstatus = SET; } else { bitstatus = RESET; } /* Return the RccInt status */ return bitstatus; } /** * @brief Clears the RCC's interrupt pending bits. * @param RccInt specifies the interrupt pending bit to clear. * * this parameter can be any combination of the * following values: * @arg RCC_INT_LSIRDIF LSI ready interrupt * @arg RCC_INT_LSERDIF LSE ready interrupt * @arg RCC_INT_HSIRDIF HSI ready interrupt * @arg RCC_INT_HSERDIF HSE ready interrupt * @arg RCC_INT_PLLRDIF PLL ready interrupt * * @arg RCC_INT_CLKSSIF Clock Security System interrupt */ void RCC_ClrIntPendingBit(uint8_t RccInt) { /* Check the parameters */ assert_param(IS_RCC_CLR_INT(RccInt)); /* Perform Byte access to RCC_CLKINT[23:16] bits to clear the selected interrupt pending bits */ *(__IO uint8_t*)CLKINT_BYTE3_ADDR = RccInt; } /** * @} */ /** * @} */ /** * @} */