/**
  ******************************************************************************
  * @file    lcm32f06x_rcc.c
  * @author  System R&D Team
  * @version V2.0.2
  * @date    10-April-2025
  * @brief   This file provides all the rcc firmware functions.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) Hangzhou Lingxin Microelectronics Co.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "lcm32f06x_rcc.h"

/**
  * @Description:
  *   APB0����ʱ��Ƶ�����֧��48MHz��Ĭ��APB0����ʱ��Ƶ�ʣ���ϵͳʱ��Ƶ�ʵ�1/2��
  *   �û���ͨ��RCC_PCLK0Config(uint32_t RCC_HCLK)���˺�������APB0���ߵ�ʱ�ӷ�Ƶ��
  *     �ر�ע�⣺���ĳ�����蹤��Ƶ����Ҫ48MHz,ϵͳʱ��Ƶ��Ҳ��48MHz����ô����ͨ�����Ϻ������޸�ABP0���ߵ�ʱ��Ϊϵͳʱ��Ƶ���Ҳ���Ƶ��
  *     �ڵ���ϵͳʱ��Ƶ��ʱ��Ҫ���Ǹ�������Ĺ���ʱ���Ƿ񳬹�����߹���ʱ��Ƶ�ʡ�
  *   FLASH����̽ӿ�ʱ��ʼ�ղ����ڲ�RCH�Ķ���Ƶʱ�ӡ�
  *   ADC������ʱ��Ƶ�����32MHz����ͨ��ADC_InitTypeDef->ADC_ClkMode��ʼ���ṹ����з�Ƶ��
  *   TIM��ʱ��Դ��ѡ��ϵͳʱ�ӻ���APB0ʱ�ӡ�RCC_TIMxCLKConfig(uint32_t RCC_TIMxCLK_Source);(x = 1,2,15,16,17)ѡ������ʱ��Դ��Ҳ���ٴ�2��Ƶ�򲻷�Ƶ��
  *   I2C������ʱ��Ƶ�����48MHz����ͨ��RCC_I2C0CLKConfig(uint32_t RCC_I2C0CLK_Source, uint32_t RCC_I2C0CLK_Div);ѡ������ʱ��Դ��Ҳ���ٴ�2��Ƶ�򲻷�Ƶ��
  *   SPI������ʱ��Ƶ�����48MHz����ͨ��RCC_SPI0CLKConfig(uint32_t RCC_SPI0CLK_Source, uint32_t RCC_SPI0CLK_Div);ѡ������ʱ��Դ��Ҳ���ٴ�2��Ƶ�򲻷�Ƶ��
  *   USART/LIN������ʱ��Ƶ�����48MHz����ͨ��RCC_USARTxCLKConfig(uint32_t RCC_USARTxCLK_Source, uint32_t RCC_USARTxCLK_Div);(x = 0,1)ѡ��ʱ��Դ��Ҳ���ٴ�2��Ƶ�򲻷�Ƶ��
  *   WT������ʱ�ӿ���ͨ��RCC_WTCLKConfig(uint32_t RCC_WTCLKSource)�˺�����ѡ���ڲ���Ƶʱ��RCL���ⲿ��Ƶʱ��OSCL����RCH�Ĺ̶���Ƶʱ�ӡ�
  */

/**
  * @name  delay10us
  * @brief EN: 10us precise delay.
  *        CN: 10us��ȷ��ʱ��
  * @param u32Cnt: 
  *        EN: Delay Time.
  *        CN: ��ʱʱ�䡣
  * @ retval None
  */

void delay10us(uint32_t u32Cnt)
{
  uint32_t TempLoad;
  uint32_t TempVal;
  uint32_t TempCtrl;
  TempLoad = SysTick->LOAD;
  TempVal = SysTick->VAL;
  TempCtrl = SysTick->CTRL;

  SysTick->CTRL = 0;
  SysTick->LOAD = 0xFFFFFF;
  SysTick->VAL = 0;
  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;

  while (u32Cnt-- > 0)
  {
      SysTick->VAL = 0;
      while (SysTick->VAL > DELAY_10US_COUNT)
      {
          __NOP(); __NOP(); __NOP();
      }
  }
  
  SysTick->LOAD = TempLoad;
  SysTick->VAL = TempVal;
  SysTick->CTRL = TempCtrl;
}

/**
  * @name  FLASH_LATENCY
  * @brief EN: Setting the flash latency.
  *        CN: FLASH ȡָ�ӳ����á�
  * @param clkrank: 
  *        EN: FLASH read delay.
  *        CN: FLASH ��ȡ�ӳ١�
  * @ retval None
  */
void FLASH_LATENCY(uint8_t clkrank)
{
  switch (clkrank)
  {
    case 0x00:
      FLASH->ACR = 0x00000010;
      break;
    case 0x01:
      FLASH->ACR = 0x00000011;
      break;
    case 0x02:
      FLASH->ACR = 0x00000012;
      break;
    case 0x03:
      FLASH->ACR = 0x00000013;
      break;
    case 0x04:
      FLASH->ACR = 0x00000014;
      break;
    default:
        break;
  }
}

/**
  * @name   Sysclk_ResetRch
  * @brief  EN: System clock reset to RCH.
  *         CN: ϵͳʱ�Ӹ�λ��RCH��
  * @retval None
  */
void Sysclk_ResetRch(void)
{
  chipctrl_access();
  CHIPCTRL->CLK_CFG &= 0xFFCFFFFF; // RCH
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00080000;  // RCH
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
  FLASH_LATENCY(0);
}

/**
  * @name   HSI_SetSysClockTo8
  * @brief  EN: Configure the system clock to 8M
  *         CN: ����ϵͳʱ��Ϊ 8M 
  * @retval None
  */
void HSI_SetSysClockTo8(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_50uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(0);                    // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_RCH_STB_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00000040; 
  __dekey();
}

/**
  * @name   HSI_SetSysClockTo16
  * @brief  EN: Configure the system clock to 16M
  *         CN: ����ϵͳʱ��Ϊ 16M 
  * @retval None
  */
void HSI_SetSysClockTo16(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_50uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(0);                    // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();
}

/**
  * @name   HSI_SetSysClockTo24
  * @brief  EN: Configure the system clock to 24M
  *         CN: ����ϵͳʱ��Ϊ 24M 
  * @retval None
  */
void HSI_SetSysClockTo24(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_50uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(0);                    // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();

  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x0000012C;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}


/**
  * @name   HSI_SetSysClockTo28
  * @brief  EN: Configure the system clock to 24M
  *         CN: ����ϵͳʱ��Ϊ 24M 
  * @retval None
  */
void HSI_SetSysClockTo28(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_50uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(1);                    // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();

  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x00000134;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   HSI_SetSysClockTo32
  * @brief  EN: Configure the system clock to 32M
  *         CN: ����ϵͳʱ��Ϊ 32M 
  * @retval None
  */
void HSI_SetSysClockTo32(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_50uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(1);                    // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();

  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x0000013C;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
}

/**
  * @name   HSI_SetSysClockTo40
  * @brief  EN: Configure the system clock to 40M
  *         CN: ����ϵͳʱ��Ϊ 40M 
  * @retval None
  */
void HSI_SetSysClockTo40(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_50uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(1);                    // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();

  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x0000014C;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  delay10us(1000);
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   HSI_SetSysClockTo48
  * @brief  EN: Configure the system clock to 48M
  *         CN: ����ϵͳʱ��Ϊ 48M 
  * @retval None
  */
void HSI_SetSysClockTo48(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_50uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(1);                    // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();

  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x0000015C;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
}

/**
  * @name   HSI_SetSysClockTo56
  * @brief  EN: Configure the system clock to 56M
  *         CN: ����ϵͳʱ��Ϊ 56M 
  * @retval None
  */
void HSI_SetSysClockTo56(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(2);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();

  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x00000934;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   HSI_SetSysClockTo64
  * @brief  EN: Configure the system clock to 64M
  *         CN: ����ϵͳʱ��Ϊ 64M 
  * @retval None
  */
void HSI_SetSysClockTo64(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(2);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();
  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x00000D3C;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   HSI_SetSysClockTo72
  * @brief  EN: Configure the system clock to 72M
  *         CN: ����ϵͳʱ��Ϊ 72M 
  * @retval None
  */
void HSI_SetSysClockTo72(void)
{
  #if defined(LCM32F067) || defined(LCM32F063)
    #ifdef LOW_POWER_EFFICIENCY_GEAR
    PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
    FLASH_LATENCY(2);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
    #elif defined(HIGH_ENERGY_EFFICIENCY_GEAR)
    PWR_LDODriverLevel(PWR_LDODRV_200uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
    FLASH_LATENCY(2);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
    #endif
  #elif defined(LCM32F062) || defined(LCM32CF6990)
    PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
    FLASH_LATENCY(2);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  #endif
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();
  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x00000D44;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   HSI_SetSysClockTo84
  * @brief  EN: Configure the system clock to 84M
  *         CN: ����ϵͳʱ��Ϊ 84M 
  * @retval None
  */
void HSI_SetSysClockTo84(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(3);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();
  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x00000D50;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   HSI_SetSysClockTo88
  * @brief  EN: Configure the system clock to 88M
  *         CN: ����ϵͳʱ��Ϊ 88M 
  * @retval None
  */
void HSI_SetSysClockTo88(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(3);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();
  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x00000D54;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   HSI_SetSysClockTo92
  * @brief  EN: Configure the system clock to 92M
  *         CN: ����ϵͳʱ��Ϊ 92M 
  * @retval None
  */
void HSI_SetSysClockTo92(void)
{
  PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(3);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000;  // RCH
  __dekey();
  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x00000D58;
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   HSI_SetSysClockTo96
  * @brief  EN: Configure the system clock to 96M
  *         CN: ����ϵͳʱ��Ϊ 96M 
  * @retval None
  */
void HSI_SetSysClockTo96(void)
{
  #if defined(LCM32F067) || defined(LCM32F063)
    #ifdef LOW_POWER_EFFICIENCY_GEAR
    PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
    FLASH_LATENCY(4);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
    #elif defined(HIGH_ENERGY_EFFICIENCY_GEAR)
    PWR_LDODriverLevel(PWR_LDODRV_200uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
    FLASH_LATENCY(3);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
    #endif
  #elif defined(LCM32F062)
    PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
    FLASH_LATENCY(4);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  #endif
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();
  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x00000D5C; //96mHZ
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   HSI_SetSysClockTo108
  * @brief  EN: Configure the system clock to 108M
  *         CN: ����ϵͳʱ��Ϊ 108M 
  * @retval None
  */
void HSI_SetSysClockTo108(void)
{
  #ifdef LOW_POWER_EFFICIENCY_GEAR
  PWR_LDODriverLevel(PWR_LDODRV_150uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(4);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  #elif defined(HIGH_ENERGY_EFFICIENCY_GEAR)
  PWR_LDODriverLevel(PWR_LDODRV_200uA); // �ں� LDO ����ģʽ����,0:10uA; 1:50uA; 2:150uA; 3:200uA; �Ժĵ�������ģʽ
  FLASH_LATENCY(3);                     // 0:sysclk <= 24 MHz 1:24Mhz<sysclk<=48Mhz  2:48Mhz<sysclk<=72MHz  3:72Mhz<sysclk<=96MHz  4:96Mhz<sysclk
  #endif
  chipctrl_access();
  CHIPCTRL->CLK_CFG = 0x00081000; // RCH
  __dekey();
  chipctrl_access();
  CHIPCTRL->PLL_CFG = 0x00000D68; //108MHz
  __dekey();
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00090000; // PLL
  __dekey();
  while(1)
  {
    if(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk)
    {
      delay10us(1000);
    }
    while (!(CHIPCTRL->STS & CHIPCTRL_STS_PLL_LOCK_Msk))
    {
      __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
    }
    break;
  }
  chipctrl_access();
  CHIPCTRL->CLK_CFG |= 0x00290000;
  __dekey();
  while (!(CHIPCTRL->STS & CHIPCTRL_STS_SYS_CLK_LOCK_Msk))
  {
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
  }
}

/**
  * @name   SetSysClock
  * @brief  EN: set System clock.
  *         CN: ����ϵͳʱ�ӡ�
  * @retval None
  */
void SetSysClock(void)
{
  #if (SYSTEM_CORE_CLOCK == 8000000)
    HSI_SetSysClockTo8();
  #elif (SYSTEM_CORE_CLOCK == 16000000)
    HSI_SetSysClockTo16();
  #elif (SYSTEM_CORE_CLOCK == 24000000)
    HSI_SetSysClockTo24();
  #elif (SYSTEM_CORE_CLOCK == 28000000)
    HSI_SetSysClockTo28();
  #elif (SYSTEM_CORE_CLOCK == 32000000)
    HSI_SetSysClockTo32();
  #elif (SYSTEM_CORE_CLOCK == 40000000)
    HSI_SetSysClockTo40();
  #elif (SYSTEM_CORE_CLOCK == 48000000)
    HSI_SetSysClockTo48();
  #elif (SYSTEM_CORE_CLOCK == 56000000)
    HSI_SetSysClockTo56();
  #elif (SYSTEM_CORE_CLOCK == 64000000)
    HSI_SetSysClockTo64();
  #elif (SYSTEM_CORE_CLOCK == 72000000)
    HSI_SetSysClockTo72();
  #elif (SYSTEM_CORE_CLOCK == 84000000)
    HSI_SetSysClockTo84();
  #elif (SYSTEM_CORE_CLOCK == 88000000)
    HSI_SetSysClockTo88();
  #elif (SYSTEM_CORE_CLOCK == 92000000)
    HSI_SetSysClockTo92();
  #elif (SYSTEM_CORE_CLOCK == 96000000)
    HSI_SetSysClockTo96();
  #elif (SYSTEM_CORE_CLOCK == 108000000)
    HSI_SetSysClockTo108();
  #else
    #error "Unsupported srsCLK config(check lem32f06x conf.h)"
  #endif
}

/**
  * @name   RCC_DeInit
  * @brief  EN: Open crystal oscillator multiplexing pin: PA11 PA12.
  *         CN: ��OSCL�����ùܽţ� PA11 PA12��
  * @retval None
  */
void OSCL_GPIO_INIT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    GPIO_StructInit(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_2;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_2);
}

/**
  * @name   RCC_AdjustHSICalibrationValue
  * @brief  EN: Adjusts the Internal High Speed oscillator (HSI) calibration value.
  *         CN: �����ڲ�����������HSI��У׼ֵ��
  * @param  HSICalibrationValue: 
  *         EN: specifies the HSI calibration trimming value(This parameter must be a number between 0 and 0xFFF).
  *         CN: ָ��HSIУ׼΢��ֵ���˲���������0��0xFFF֮������֣���
  * @retval None
  */
void RCC_AdjustHSICalibrationValue(uint32_t HSICalibrationValue)
{
  chipctrl_access();
  CHIPCTRL->RCH_CFG = HSICalibrationValue; /* ���޸� */
  __dekey();
}

/**
  * @name   RCC_HSICmd
  * @brief  EN: Enables or disables the Internal High Speed oscillator (HSI).
  *         CN: ���û�����ڲ�����������HSI����
  * @param  NewState: 
  *         EN: new state of the HSI.
  *         CN: HSI ����״̬��
  *             @arg ENABLE
  *             @arg DISABLE
  * @retval None
  */
void RCC_HSICmd(FunctionalState NewState)  //@zhang rch
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {

    chipctrl_access();
    CHIPCTRL->CLK_CFG_b.RCH_EN = 0;
    __dekey();
  }
  else
  {
    chipctrl_access();
    CHIPCTRL->CLK_CFG_b.RCH_EN = 1;
    __dekey();
  }
}

/**
  * @name   RCC_LSEConfig
  * @brief  EN: Configures the External Low Speed oscillator (LSE).
  *         CN: �����ⲿ����������LSE����
  * @param  RCC_LSE: 
  *         EN: specifies the new state of the LSE.
  *         CN: ָ��LSE����״̬��
  *             @arg RCC_LSE_OFF
  *             @arg RCC_LSE_ON
  *             @arg RCC_LSE_Bypass
  * @retval None
  */
void RCC_LSEConfig(uint32_t RCC_LSE) //@zhang oscl
{
  /* Check the parameters */
  assert_param(IS_RCC_LSE(RCC_LSE));

  /* Reset LSEON and LSEBYP bits before configuring the LSE ------------------*/
  /* Reset LSEON bit */

  chipctrl_access();
  CHIPCTRL->BDCR_b.OSCL_EN = 0;
  __dekey();

  /* Reset LSEBYP bit */
  chipctrl_access();
  CHIPCTRL->BDCR_b.OSCL_BYP = 0;
  __dekey();

  /* Configure LSE */

  if (RCC_LSE == RCC_LSE_ON)
  {
    chipctrl_access();
    CHIPCTRL->BDCR_b.OSCL_EN = 1;
    __dekey();
  }
  if (RCC_LSE == RCC_LSE_Bypass)
  {
    chipctrl_access();
    CHIPCTRL->BDCR_b.OSCL_BYP = 1;
    __dekey();

    chipctrl_access();
    CHIPCTRL->BDCR_b.OSCL_EN = 1;
    __dekey();
  }
  else //(RCC_LSE==RCC_LSE_OFF)
  {
    chipctrl_access();
    CHIPCTRL->BDCR_b.OSCL_EN = 0;
    __dekey();
  }
}

/**
  * @name   RCC_LSICmd
  * @brief  EN: Enables or disables the Internal Low Speed oscillator (LSI).
  *         CN: ���û�����ڲ�����������LSI����
  * @param  NewState: 
  *         EN: specifies the new state of the LSI.
  *         CN: ָ��LSI����״̬��
  *             @arg ENABLE
  *             @arg DISABLE
  * @retval None
  */
void RCC_LSICmd(FunctionalState NewState) 
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
      chipctrl_access();
      CHIPCTRL->RCL_CFG_b.RCL_EN = 1;
      __dekey();
  }
  else
  {
      chipctrl_access();
      CHIPCTRL->RCL_CFG_b.RCL_EN = 0;
      __dekey();
  }
}

/**
  * @name   RCC_MCOConfig
  * @brief  EN: Selects the clock source to output on MCO pin (PA8) and the corresponding prescsaler.
  *         CN: ѡ��Ҫ��MCO���ţ�PA8������Ӧ��Ԥ��Ƶ���������ʱ��Դ��
  * @param  RCC_MCOSource: 
  *         EN: specifies the clock source to output.
  *         CN: ָ��Ҫ�����ʱ��Դ��
  *             @arg RCC_MCOSource_NoClock
  *             @arg RCC_MCOSource_PLL
  *             @arg RCC_MCOSource_PLL_CLK_IN
  *             @arg RCC_MCOSource_SYSCLK
  *             @arg RCC_MCOSource_LSI
  *             @arg RCC_MCOSource_LSE
  *             @arg RCC_MCOSource_HSI
  * @param  RCC_MCOPrescaler:
  *         EN: specifies the prescaler on MCO pin.
  *         CN: ָ��MCO�����ϵ�Ԥ��Ƶ����
  *             @arg RCC_MCOPrescaler_1
  *             @arg RCC_MCOPrescaler_2
  *             @arg RCC_MCOPrescaler_4
  *             @arg RCC_MCOPrescaler_8
  *             @arg RCC_MCOPrescaler_16
  *             @arg RCC_MCOPrescaler_32
  *             @arg RCC_MCOPrescaler_64
  *             @arg RCC_MCOPrescaler_128
  * @retval None
  */
void RCC_MCOConfig(uint8_t RCC_MCOSource, uint32_t RCC_MCOPrescaler)
{
  /* Check the parameters */
  assert_param(IS_RCC_MCO_SOURCE(RCC_MCOSource));
  assert_param(IS_RCC_MCO_PRESCALER(RCC_MCOPrescaler));

  sysctrl_access();
  SYSCTRL->ClkEnR1_b.MCO_SEL = RCC_MCOSource;
  __dekey();

  sysctrl_access();
  SYSCTRL->ClkEnR1_b.MCO_DIV = RCC_MCOPrescaler;
  __dekey();
}

/**
  * @name   RCC_SYSCLKConfig
  * @brief  EN: Configures the system clock Source (SYSCLK).
  *         CN: ����ϵͳʱ��Դ��SYSCLK ����
  * @param  RCC_SYSCLKSource: 
  *         EN:specifies the clock source used as system clock source.
  *         CN:ָ������ϵͳʱ��Դ��ʱ��Դ��
  *             @arg RCC_SYSCLKSource_HSI
  *             @arg RCC_SYSCLKSource_PLLCLK
  *             @arg RCC_SYSCLKSource_LSI
  * @retval None
  */
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
{
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_RCC_SYSCLK_SOURCE(RCC_SYSCLKSource));

  tmpreg = CHIPCTRL->CLK_CFG;

  tmpreg &= ~CHIPCTRL_CLK_CFG_SYS_SRC_SEL_Msk;

  tmpreg |= RCC_SYSCLKSource;

  /* Store the new value */
  chipctrl_access();
  CHIPCTRL->CLK_CFG = tmpreg;
  __dekey();
}

/**
  * @name   RCC_GetSYSCLKSource
  * @brief  EN: Returns the clock source used as system clock.
  *         CN: ��������ϵͳʱ�ӵ�ʱ��Դ��
  * @retval EN: The clock source used as system clock.
  *         CN: ����ϵͳʱ�ӵ�ʱ��Դ��
  */
uint32_t RCC_GetSYSCLKSource(void)
{
  return (CHIPCTRL->CLK_CFG & CHIPCTRL_CLK_CFG_SYS_SRC_SEL_Msk);
}

/**
  * @name   RCC_SYSCLKConfig
  * @brief  EN: Configures the AHB clock (HCLK).
  *         CN: ����AHBʱ�ӣ�HCLK����
  * @param  RCC_SYSCLK: 
  *         EN: defines the AHB clock divider. This clock is derived from the system clock (SYSCLK).
  *         CN: ����AHBʱ�ӷ�Ƶ������ʱ��Դ��ϵͳʱ�ӣ�SYSCLK����
  *             @arg RCC_SYSCLK_Div1
  *             @arg RCC_SYSCLK_Div2
  *             @arg RCC_SYSCLK_Div3
  *             @arg RCC_SYSCLK_Div4
  *             @arg RCC_SYSCLK_Div5
  *             @arg RCC_SYSCLK_Div3
  *             @arg RCC_SYSCLK_Div6
  *             @arg RCC_SYSCLK_Div8
  *             @arg ...
  *             @arg RCC_SYSCLK_Div126
  *             @arg RCC_SYSCLK_Div128
  * @retval None
  */
void RCC_HCLKConfig(uint32_t RCC_SYSCLK) //@zhang
{
  // 00xx_xxxx: SYS_CLK = SYS_CLK_IN
  // 01xx_xxxx: SYS_CLK = SYS_CLK_IN / (2 * (SYS_CLK_SEL[5:0]+1))
  // 10xx_xxxx: SYS_CLK = SYS_CLK_IN / 3
  // 11xx_xxxx: SYS_CLK = SYS_CLK_IN / 5
  chipctrl_access();
  CHIPCTRL->CLK_CFG_b.SYS_CLK_SEL = RCC_SYSCLK;
  __dekey();
}

/**
  * @name   RCC_PCLK0Config
  * @brief  EN: Configures the APB clock (PCLK).
  *         CN: ����APBʱ�ӣ�PCLK����
  * @param  RCC_HCLK: 
  *         EN: defines the APB clock divider. This clock is derived from the AHB clock (HCLK).
  *         CN: ������APBʱ�ӷ�Ƶ������ʱ��Դ��AHBʱ�ӣ�HCLK����
  *             @arg RCC_HCLK_Div1
  *             @arg RCC_HCLK_Div2
  *             @arg RCC_HCLK_Div3
  *             @arg RCC_HCLK_Div4
  *             @arg RCC_HCLK_Div5
  *             @arg RCC_HCLK_Div6
  *             @arg RCC_HCLK_Div7
  *             @arg RCC_HCLK_Div8
  *             @arg RCC_HCLK_Div9
  *             @arg RCC_HCLK_Div10
  *             @arg RCC_HCLK_Div11
  *             @arg RCC_HCLK_Div12
  *             @arg RCC_HCLK_Div13
  *             @arg RCC_HCLK_Div14
  *             @arg RCC_HCLK_Div15
  *             @arg RCC_HCLK_Div16
  * @retval None
  */
void RCC_PCLK0Config(uint32_t RCC_HCLK)
{
  assert_param(IS_RCC_PCLK(RCC_HCLK));
  chipctrl_access();
  CHIPCTRL->CLK_CFG_b.APB0_DIV = RCC_HCLK;
  __dekey();
}

/**
  * @name   RCC_TIM17CLKConfig
  * @brief  EN: Configures the TIM17 clock.
  *         CN: ����TIM17ʱ�ӡ�
  * @param  RCC_TIM17CLK_Source: 
  *         EN: Configure TIM17 clock source.
  *         CN: ����TIM17ʱ��Դ��
  *             @arg RCC_TIM17CLK_SYS_CLK
  *             @arg RCC_TIM17CLK_APB0
  * @retval None
  */
void RCC_TIM17CLKConfig(uint32_t RCC_TIM17CLK_Source)
{
    /* Check the parameters */
    assert_param(IS_RCC_TIM17CLK_SOURCE(RCC_TIM17CLK_Source));
    sysctrl_access();
    SYSCTRL->ClkEnR1_b.TIM17_CLKSEL = RCC_TIM17CLK_Source;
    __dekey();
}

/**
  * @name   RCC_TIM16CLKConfig
  * @brief  EN: Configures the TIM16 clock.
  *         CN: ����TIM16ʱ�ӡ�
  * @param  RCC_TIM16CLK_Source: 
  *         EN: Configure TIM16 clock source.
  *         CN: ����TIM16ʱ��Դ��
  *             @arg RCC_TIM16CLK_SYS_CLK
  *             @arg RCC_TIM16CLK_APB0
  * @retval None
  */
void RCC_TIM16CLKConfig(uint32_t RCC_TIM16CLK_Source)
{
  /* Check the parameters */
  assert_param(IS_RCC_TIM16CLK_SOURCE(RCC_TIM16CLK_Source));
  sysctrl_access();
  SYSCTRL->ClkEnR1_b.TIM16_CLKSEL = RCC_TIM16CLK_Source;
  __dekey();
}

/**
  * @name   RCC_TIM15CLKConfig
  * @brief  EN: Configures the TIM15 clock.
  *         CN: ����TIM15ʱ�ӡ�
  * @param  RCC_TIM15CLK_Source: 
  *         EN: Configure TIM15 clock source.
  *         CN: ����TIM15ʱ��Դ��
  *             @arg RCC_TIM15CLK_SYS_CLK
  *             @arg RCC_TIM15CLK_APB0
  * @retval None
  */
void RCC_TIM15CLKConfig(uint32_t RCC_TIM15CLK_Source)
{
  /* Check the parameters */
  assert_param(IS_RCC_TIM15CLK_SOURCE(RCC_TIM15CLK_Source));
  sysctrl_access();
  SYSCTRL->ClkEnR1_b.TIM15_CLKSEL = RCC_TIM15CLK_Source;
  __dekey();
}

/**
  * @name   RCC_TIM2CLKConfig
  * @brief  EN: Configures the TIM2 clock.
  *         CN: ����TIM2ʱ�ӡ�
  * @param  RCC_TIM2CLK_Source: 
  *         EN: Configure TIM2 clock source.
  *         CN: ����TIM2ʱ��Դ��
  *             @arg RCC_TIM2CLK_SYS_CLK
  *             @arg RCC_TIM2CLK_APB0
  * @retval None
  */
void RCC_TIM2CLKConfig(uint32_t RCC_TIM2CLK_Source)
{
  /* Check the parameters */
  assert_param(IS_RCC_TIM2CLK_SOURCE(RCC_TIM2CLK_Source));
  sysctrl_access();
  SYSCTRL->ClkEnR1_b.TIM2_CLKSEL = RCC_TIM2CLK_Source;
  __dekey();
}

/**
  * @name   RCC_TIM1CLKConfig
  * @brief  EN: Configures the TIM1 clock.
  *         CN: ����TIM1ʱ�ӡ�
  * @param  RCC_TIM1CLK_Source: 
  *         EN: Configure TIM1 clock source.
  *         CN: ����TIM1ʱ��Դ��
  *             @arg RCC_TIM1CLK_SYS_CLK
  *             @arg RCC_TIM1CLK_APB0
  * @retval None
  */
void RCC_TIM1CLKConfig(uint32_t RCC_TIM1CLK_Source)
{
  /* Check the parameters */
  assert_param(IS_RCC_TIM1CLK_SOURCE(RCC_TIM1CLK_Source));
  sysctrl_access();
  SYSCTRL->ClkEnR1_b.TIM1_CLKSEL = RCC_TIM1CLK_Source;
  __dekey();
}

/**
  * @name   RCC_SPI0CLKConfig
  * @brief  EN: Configures the SPI0 clock.
  *         CN: ����SPI0ʱ�ӡ�
  * @param  RCC_SPI0CLK_Source: 
  *         EN: Configure SPI0 clock source.
  *         CN: ����SPI0ʱ��Դ��
  *             @arg RCC_SPI0CLK_APB0
  *             @arg RCC_SPI0CLK_SYS_CLK_IN
  *             @arg RCC_SPI0CLK_RCH
  *             @arg RCC_SPI0CLK_OSCL
  * @param  RCC_SPI0CLK_Div: 
  *         EN: Configure SPI0 clock division.
  *         CN: ����SPI0ʱ�ӷ�Ƶ��
  *             @arg RCC_SPI0CLK_DIV_1
  *             @arg RCC_SPI0CLK_DIV_2
  * @retval None
  */
void RCC_SPI0CLKConfig(uint32_t RCC_SPI0CLK_Source, uint32_t RCC_SPI0CLK_Div)
{
  /* Check the parameters */
  assert_param(IS_RCC_SPI0CLK_SOURCE(RCC_SPI0CLK_Source));
  assert_param(IS_RCC_SPI0CLK_DIV(RCC_SPI0CLK_Div));
  sysctrl_access();
  SYSCTRL->ClkEnR1_b.SPI0_CLKSEL = RCC_SPI0CLK_Source;
  SYSCTRL->ClkEnR1_b.SPI0_CLKDIV = RCC_SPI0CLK_Div;
  __dekey();
}

/**
  * @name   RCC_I2C0CLKConfig
  * @brief  EN: Configures the I2C0 clock.
  *         CN: ����I2C0ʱ�ӡ�
  * @param  RCC_I2C0CLK_Source: 
  *         EN: Configure I2C0 clock source.
  *         CN: ����I2C0ʱ��Դ��
  *             @arg RCC_I2C0CLK_APB0
  *             @arg RCC_I2C0CLK_SYS_CLK_IN
  *             @arg RCC_I2C0CLK_RCH
  *             @arg RCC_I2C0CLK_OSCL
  * @param  RCC_I2C0CLK_Div: 
  *         EN: Configure I2C0 clock division.
  *         CN: ����I2C0ʱ�ӷ�Ƶ��
  *             @arg RCC_I2C0CLK_DIV_1
  *             @arg RCC_I2C0CLK_DIV_2
  * @retval None
  */
void RCC_I2C0CLKConfig(uint32_t RCC_I2C0CLK_Source, uint32_t RCC_I2C0CLK_Div)
{
  /* Check the parameters */
  assert_param(IS_RCC_I2C0CLK_SOURCE(RCC_I2C0CLK_Source));
  assert_param(IS_RCC_I2C0CLK_DIV(RCC_I2C0CLK_Div));
  sysctrl_access();
  SYSCTRL->ClkEnR1_b.I2C0_CLKSEL = RCC_I2C0CLK_Source;
  SYSCTRL->ClkEnR1_b.I2C0_CLKDIV = RCC_I2C0CLK_Div;
  __dekey();
}

/**
  * @name   RCC_USART1CLKConfig
  * @brief  EN: Configures the USART1 clock.
  *         CN: ����USART1ʱ�ӡ�
  * @param  RCC_USART1CLK_Source: 
  *         EN: Configure USART1 clock source.
  *         CN: ����USART1ʱ��Դ��
  *             @arg RCC_USART1CLK_APB0
  *             @arg RCC_USART1CLK_SYS_CLK_IN
  *             @arg RCC_USART1CLK_RCH
  *             @arg RCC_USART1CLK_OSCL
  * @param  RCC_USART1CLK_Div: 
  *         EN: Configure USART1 clock division.
  *         CN: ����USART1ʱ�ӷ�Ƶ��
  *             @arg RCC_USART1CLK_DIV_1
  *             @arg RCC_USART1CLK_DIV_2
  * @retval None
  */
void RCC_USART1CLKConfig(uint32_t RCC_USART1CLK_Source, uint32_t RCC_USART1CLK_Div)
{
  /* Check the parameters */
  assert_param(IS_RCC_USART1CLK_SOURCE(RCC_USART1CLK_Source));
  assert_param(IS_RCC_USART1CLK_DIV(RCC_USART1CLK_Div));

  sysctrl_access();
  SYSCTRL->ClkEnR1_b.USART1_CLKSEL = RCC_USART1CLK_Source;
  SYSCTRL->ClkEnR1_b.USART1_CLKDIV = RCC_USART1CLK_Div;
  __dekey();
}

/**
  * @name   RCC_USART0CLKConfig
  * @brief  EN: Configures the USART0 clock.
  *         CN: ����USART0ʱ�ӡ�
  * @param  RCC_USART0CLK_Source: 
  *         EN: Configure USART0 clock source.
  *         CN: ����USART0ʱ��Դ��
  *             @arg RCC_USART0CLK_APB0
  *             @arg RCC_USART0CLK_SYS_CLK_IN
  *             @arg RCC_USART0CLK_RCH
  *             @arg RCC_USART0CLK_OSCL
  * @param  RCC_USART0CLK_Div: 
  *         EN: Configure USART1 clock division.
  *         CN: ����USART1ʱ�ӷ�Ƶ��
  *             @arg RCC_USART0CLK_DIV_1
  *             @arg RCC_USART0CLK_DIV_2
  * @retval None
  */
void RCC_USART0CLKConfig(uint32_t RCC_USART0CLK_Source, uint32_t RCC_USART0CLK_Div)
{
  /* Check the parameters */
  assert_param(IS_RCC_USART0CLK_SOURCE(RCC_USART0CLK_Source));
  assert_param(IS_RCC_USART0CLK_DIV(RCC_USART0CLK_Div));

  sysctrl_access();
  SYSCTRL->ClkEnR1_b.USART0_CLKSEL = RCC_USART0CLK_Source;
  SYSCTRL->ClkEnR1_b.USART0_CLKDIV = RCC_USART0CLK_Div;
  __dekey();
}

/**
  * @name   RCC_WTCLKConfig
  * @brief  EN: Configures the WT clock.
  *         CN: ����WTʱ�ӡ�
  * @param  RCC_WTCLKSource: 
  *         EN: Configure WT clock source.
  *         CN: ����WTʱ��Դ��
  *             @arg RCC_WTCLKSource_NONE
  *             @arg RCC_WTCLKSource_LSE
  *             @arg RCC_WTCLKSource_LSI
  * @retval None
  */
void RCC_WTCLKConfig(uint32_t RCC_WTCLKSource)
{
  /* Check the parameters */
  assert_param(IS_RCC_WTCLK_SOURCE(RCC_WTCLKSource));
  /* Select the WT clock source */
  chipctrl_access();
  CHIPCTRL->BDCR_b.WT_SEL = RCC_WTCLKSource;
  __dekey();
}

/**
  * @name  RCC_WTCLKCmd
  * @brief  EN: Enables or disables the RTC clock.
  *         CN: ���û���� WT ʱ�ӡ�
  * @param  NewState:
  *         EN: WT state.
  *         CN: WT ״̬��
  *             @arg ENBALE
  *             @arg DISABLE
  * @return None
  */
void RCC_WTCLKCmd(FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    chipctrl_access();
    CHIPCTRL->BDCR_b.WT_EN = 1;
  }
  else
  {
    chipctrl_access();
    CHIPCTRL->BDCR_b.WT_EN = 0;
  }
  __dekey();
}

/**
  * @name   RCC_BackupResetCmd
  * @brief  EN: Software reset of the entire WT domain and external low-frequency 
  *             oscillation OSCL configuration
  *         CN: ������λ���� WT ����ⲿ��Ƶ�� OSCL ������
  * @param  NewState: 
  *         EN: WT New Status
  *         CN: WT ��״̬
  *             @arg ENBALE
  *             @arg DISABLE
  * @retval None
  */
void RCC_BackupResetCmd(FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    chipctrl_access();
    CHIPCTRL->BDCR_b.BDRST = 1;
    __dekey();
  }
  else
  {
    chipctrl_access();
    CHIPCTRL->BDCR_b.BDRST = 0;
    __dekey();
  }
}

/**
  * @name   RCC_AHBPeriphClockCmd
  * @brief  EN: Enables or disables the AHB peripheral clock.
  *         CN: ���û����AHB��Χʱ�ӡ�
  * @param  RCC_AHBPeriph: 
  *         EN: specifies the AHB peripheral to gates its clock.
  *         CN: ָ��AHB��Χ�豸ѡͨ��ʱ�ӡ�
  *             @arg RCC_AHBPeriph_RAM1
  *             @arg RCC_AHBPeriph_RAM0
  *             @arg RCC_AHBPeriph_EFLS
  *             @arg RCC_AHBPeriph_GPIOA
  *             @arg RCC_AHBPeriph_GPIOB
  *             @arg RCC_AHBPeriph_CRC
  *             @arg RCC_AHBPeriph_DMA
  *             @arg RCC_AHBPeriph_DIV
  * @param  NewState: 
  *         EN: new state of the specified peripheral clock.
  *         CN: ָ������Χʱ�ӵ���״̬��
  *             @arg ENBALE
  *             @arg DISABLE
  * @retval None
  */
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if(RCC_AHBPeriph == RCC_AHBPeriph_DIV)
  {
    if (NewState != DISABLE)
    {
      sysctrl_access();
      SYSCTRL->ClkEnR2 |= RCC_AHBPeriph;
      __dekey();
    }
    else
    {
      sysctrl_access();
      SYSCTRL->ClkEnR2 &= ~RCC_AHBPeriph;
      __dekey();
    }
  }
  else
  {
    if (NewState != DISABLE)
    {
      sysctrl_access();
      SYSCTRL->ClkEnR0 |= RCC_AHBPeriph;
      __dekey();
    }
    else
    {
      sysctrl_access();
      SYSCTRL->ClkEnR0 &= ~RCC_AHBPeriph;
      __dekey();
    }
  }
}

/**
  * @name   RCC_AHBPeriphResetCmd
  * @brief  EN: Forces or releases AHB peripheral reset.
  *         CN: ǿ�ƻ��ͷ�AHB��Χ�豸���á�
  * @param  RCC_AHBPeriph: 
  *         EN: specifies the AHB peripheral to reset.
  *         CN: ָ��Ҫ���õ�AHB��Χ�豸��
  *             @arg RCC_AHBPeriph_RAM1
  *             @arg RCC_AHBPeriph_RAM0
  *             @arg RCC_AHBPeriph_EFLS
  *             @arg RCC_AHBPeriph_GPIOA
  *             @arg RCC_AHBPeriph_GPIOB
  *             @arg RCC_AHBPeriph_CRC
  *             @arg RCC_AHBPeriph_DMA
  *             @arg RCC_AHBPeriph_DIV
  * @param  NewState: 
  *         EN: new state of the specified peripheral reset.
  *         CN: ָ���������õ���״̬��
  *             @arg ENBALE
  *             @arg DISABLE
  * @retval None
  */
void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_RCC_AHB_RST_PERIPH(RCC_AHBPeriph));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if(RCC_AHBPeriph == RCC_AHBPeriph_DIV)
  {
    if (NewState != DISABLE)
    {
      sysctrl_access();
      SYSCTRL->RST1 &= ~RCC_AHBPeriph;
      __dekey();
    }
    else
    {
      sysctrl_access();
      SYSCTRL->RST1 |= RCC_AHBPeriph;
      __dekey();
    }
  }
  else
  {
    if (NewState != DISABLE)
    {
      sysctrl_access();
      SYSCTRL->RST0 &= ~RCC_AHBPeriph;
      __dekey();
    }
    else
    {
      sysctrl_access();
      SYSCTRL->RST0 |= RCC_AHBPeriph;
      __dekey();
    }
  }
}

/**
  * @name   RCC_APB0PeriphClockCmd
  * @brief  EN: Enables or disables the APB0 peripheral clock.
  *         CN: ���û����APB0��Χʱ�ӡ�
  * @param  RCC_APB0Periph:
  *         EN: specifies the APB0 peripheral to gates its clock.
  *         CN: ָ��APB0��Χ�豸ѡͨ��ʱ�ӡ�
  *             @arg RCC_APB0Periph_TIM2
  *             @arg RCC_APB0Periph_TIM17
  *             @arg RCC_APB0Periph_TIM16
  *             @arg RCC_APB0Periph_TIM15
  *             @arg RCC_APB0Periph_TIM1
  *             @arg RCC_APB0Periph_USART1
  *             @arg RCC_APB0Periph_USART0
  *             @arg RCC_APB0Periph_SPI0
  *             @arg RCC_APB0Periph_IIC0
  *             @arg RCC_APB0Periph_ADC
  *             @arg RCC_APB0Periph_ANACTRL
  *             @arg RCC_APB0Periph_EXTI
  *             @arg RCC_APB0Periph_CORDIC
  * @param  NewState: 
  *         EN: new state of the specified peripheral clock.
  *         CN: ָ������Χʱ�ӵ���״̬��
  *             @arg ENBALE
  *             @arg DISABLE
  * @retval None
  */
void RCC_APB0PeriphClockCmd(uint32_t RCC_APB0Periph, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_RCC_APB0_PERIPH(RCC_APB0Periph));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (RCC_APB0Periph == RCC_APB0Periph_EXTI || RCC_APB0Periph == RCC_APB0Periph_ANACTRL)
  {
    if (NewState != DISABLE)
    {
      sysctrl_access();
      SYSCTRL->ClkEnR2 |= RCC_APB0Periph;
      __dekey();
    }
    else
    {
      sysctrl_access();
      SYSCTRL->ClkEnR2 &= ~RCC_APB0Periph;
      __dekey();
    }
  }
  else
  {
    if (NewState != DISABLE)
    {
      sysctrl_access();
      SYSCTRL->ClkEnR0 |= RCC_APB0Periph;
      __dekey();
    }
    else
    {
      sysctrl_access();
      SYSCTRL->ClkEnR0 &= ~RCC_APB0Periph;
      __dekey();
    }
  }
}
/**
  * @name   RCC_APB0PeriphResetCmd
  * @brief  EN: Forces or releases APB0 peripheral reset.
  *         CN: ǿ�ƻ��ͷ�APB0��Χ�豸���á�
  * @param  RCC_APB0Periph: 
  *         EN: specifies the APB0 peripheral to reset.
  *         CN: ָ��Ҫ���õ�APB0��Χ�豸��
  *             @arg RCC_APB0Periph_TIM2
  *             @arg RCC_APB0Periph_TIM17
  *             @arg RCC_APB0Periph_TIM16
  *             @arg RCC_APB0Periph_TIM15
  *             @arg RCC_APB0Periph_TIM1
  *             @arg RCC_APB0Periph_USART1
  *             @arg RCC_APB0Periph_USART0
  *             @arg RCC_APB0Periph_SPI0
  *             @arg RCC_APB0Periph_IIC0
  *             @arg RCC_APB0Periph_ADC
  *             @arg RCC_APB0Periph_ANACTRL
  *             @arg RCC_APB0Periph_EXTI
  *             @arg RCC_APB0Periph_CORDIC
  * @param  NewState: 
  *         EN: new state of the specified peripheral reset.
  *         CN: ָ���������õ���״̬��
  *             @arg ENBALE
  *             @arg DISABLE
  * @retval None
  */
void RCC_APB0PeriphResetCmd(uint32_t RCC_APB0Periph, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_RCC_APB0_PERIPH(RCC_APB0Periph));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (RCC_APB0Periph == RCC_APB0Periph_EXTI || RCC_APB0Periph == RCC_APB0Periph_ANACTRL)
  {
    if (NewState != DISABLE)
    {
      sysctrl_access();
      SYSCTRL->RST1 &= ~RCC_APB0Periph;
      __dekey();
    }
    else
    {
      sysctrl_access();
      SYSCTRL->RST1 |= RCC_APB0Periph;
      __dekey();
    }
  }
  else
  {
    if (NewState != DISABLE)
    {
      sysctrl_access();
      SYSCTRL->RST0 &= ~RCC_APB0Periph;
      __dekey();
    }
    else
    {
      sysctrl_access();
      SYSCTRL->RST0 |= RCC_APB0Periph;
      __dekey();
    }
  }
}

/**
  * @name   RCC_ITConfig
  * @brief  EN: Enables or disables the specified RCC interrupts.
  *         CN: ���û����ָ����RCC�жϡ�
  * @param  RCC_IT: 
  *         EN: specifies the RCC interrupt sources to be enabled or disabled.
  *         CN: ָ��Ҫ���û���õ�RCC�ж�Դ��
  *             @arg RCC_IT_CLXMUXERR
  *             @arg RCC_IT_CLKENERR
  *             @arg RCC_IT_PLL
  *             @arg RCC_IT_LSE
  *             @arg RCC_IT_HSI
  *             @arg RCC_IT_LSI
  * @param  NewState: 
  *         EN: new state of the specified RCC interrupts.
  *         CN: ָ��RCC�жϵ���״̬��
  *             @arg ENBALE
  *             @arg DISABLE
  * @retval None
  */
void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_RCC_IT(RCC_IT));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    chipctrl_access();
    CHIPCTRL->CTRL |= RCC_IT;
    __dekey();
  }
  else
  {
    chipctrl_access();
    CHIPCTRL->CTRL &= ~RCC_IT;
    __dekey();
  }
}

/**
  * @name   RCC_ClearITPendingBit
  * @brief  EN: Enables or disables the specified RCC interrupts.
  *         CN: ���û����ָ����RCC�жϡ�
  * @param  RCC_IT: 
  *         EN: specifies the RCC interrupt sources to be enabled or disabled.
  *         CN: ָ��Ҫ���û���õ�RCC�ж�Դ��
  *             @arg RCC_IT_CLXMUXERR
  *             @arg RCC_IT_CLKENERR
  *             @arg RCC_IT_PLL
  *             @arg RCC_IT_LSE
  *             @arg RCC_IT_HSI
  *             @arg RCC_IT_LSI
  * @retval None
  */
void RCC_ClearITPendingBit(uint8_t RCC_IT)
{
  /* Check the parameters */
  assert_param(IS_RCC_CLEAR_IT(RCC_IT));

  chipctrl_access();
  CHIPCTRL->STS |= RCC_IT;
  __dekey();
}

/**
  * @name   RCC_GetFlagStatus
  * @brief  EN: Checks whether the specified RCC flag is set or not.
  *         CN: ����Ƿ�������ָ����RCC��־��
  * @param  RCC_FLAG:
  *         EN: specifies the flag to check.
  *         CN: ָ��Ҫ���ı�־��
  *             @arg RCC_FLAG_LVD
  *             @arg RCC_FLAG_CLKMUX_LOCK
  *             @arg RCC_FLAG_SYS_CLK_LOCK
  *             @arg RCC_FLAG_PLL_LOCK
  *             @arg RCC_FLAG_HSERDY
  *             @arg RCC_FLAG_HSIRDY
  *             @arg RCC_FLAG_LSERDY
  *             @arg RCC_FLAG_LSIRDY
  * @retval FlagStatus
  */
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
{
  /* Check the parameters */
  assert_param(IS_RCC_FLAG(RCC_FLAG));

  if ((CHIPCTRL->STS >> RCC_FLAG) & 0x01)
  {
      return SET;
  }
  return RESET;
}

/**
  * @name   RCC_GetITStatus
  * @brief  EN: Checks whether the specified RCC interrupt has occurred or not.
  *         CN: ���ָ����RCC�ж��Ƿ��ѷ�����
  * @param  RCC_IT: 
  *         EN: specifies the RCC interrupt source to check.
  *         CN: ָ��Ҫ����RCC�ж�Դ��
  *             @arg RCC_IT_CLXMUXERR
  *             @arg RCC_IT_CLKENERR
  *             @arg RCC_IT_PLL
  *             @arg RCC_IT_LSE
  *             @arg RCC_IT_HSI
  *             @arg RCC_IT_LSI
  * @retval ITStatus
  */
ITStatus RCC_GetITStatus(uint8_t RCC_IT)
{
  ITStatus bitstatus = RESET;

  /* Check the parameters */
  assert_param(IS_RCC_GET_IT(RCC_IT));

  /* Check the status of the specified RCC interrupt */
  if ((CHIPCTRL->STS & RCC_IT) != (uint32_t)RESET)
  {
    bitstatus = SET;
  }
  else
  {
    bitstatus = RESET;
  }
  /* Return the RCC_IT status */
  return bitstatus;
}

/**
  * @name   RCC_GetClockFreq
  * @brief  EN: Obtain clock frequency.
  *         CN: ��ȡʱ��Ƶ�ʡ�
  * @param  RCC_Clocks: 
  *         EN: Clock to be obtained.
  *         CN: ��Ҫ��ȡ��ʱ�ӡ�
  * @retval ITStatus
  */
void RCC_GetClockFreq(RCC_ClocksTypeDef *RCC_Clocks)
{
    uint32_t v_clk_src_sel;
    uint32_t v_pll_str;
    uint32_t v_sys_clk_sel;
    uint32_t v_sys_clk_sel76;
    uint32_t v_sys_clk_sel50;
    uint32_t v_regtmp;

    v_clk_src_sel = CHIPCTRL->CLK_CFG_b.SYS_SRC_SEL;

    RCC_Clocks->HSI_Frequency = _LCM32_GBL_HSI_nHZ;
    RCC_Clocks->LSI_Frequency = _LCM32_GBL_LSI_nHZ;
    RCC_Clocks->LSE_Frequency = _LCM32_GBL_LSE_nHZ;

    if (v_clk_src_sel == 0) // RCH as sysclk
    {
        RCC_Clocks->SYSCLK_IN_Frequency = RCC_Clocks->HSI_Frequency;
    }
    else if (v_clk_src_sel == 2) // PLL as sysclk
    {
        v_pll_str = RCC_Clocks->HSI_Frequency;
        RCC_Clocks->PLL_Frequency = (v_pll_str *(CHIPCTRL->PLL_CFG_b.PLL_SEL + 1) * (CHIPCTRL->PLL_CFG_b.PLL_DN + 1)) / ((CHIPCTRL->PLL_CFG_b.PLL_DM + 1) * (CHIPCTRL->PLL_CFG_b.PLL_OD + 1) * 4);
        RCC_Clocks->SYSCLK_IN_Frequency = RCC_Clocks->PLL_Frequency;
    }
    else // LSE as sysclk
    {
        RCC_Clocks->SYSCLK_IN_Frequency = RCC_Clocks->LSI_Frequency;
    }

    /*sys_clk after prescale*/
    v_sys_clk_sel = CHIPCTRL->CLK_CFG_b.SYS_CLK_SEL;
    v_sys_clk_sel76 = (v_sys_clk_sel >> 6) & (0x03);
    v_sys_clk_sel50 = (v_sys_clk_sel >> 0) & (0x3f);
    switch (v_sys_clk_sel76)
    {
      case 0x00:
        RCC_Clocks->SYSCLK_Frequency = RCC_Clocks->SYSCLK_IN_Frequency;
        break;
      case 0x01:
        RCC_Clocks->SYSCLK_Frequency = (RCC_Clocks->SYSCLK_IN_Frequency) / (2 * (v_sys_clk_sel50 + 1));
        break;
      case 0x02:
        RCC_Clocks->SYSCLK_Frequency = (RCC_Clocks->SYSCLK_IN_Frequency) / 3;
        break;
      case 0x03:
        RCC_Clocks->SYSCLK_Frequency = (RCC_Clocks->SYSCLK_IN_Frequency) / 5;
        break;
      default:
        break;
    }
    RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency;
    v_regtmp = CHIPCTRL->CLK_CFG_b.APB0_DIV;
    RCC_Clocks->PCLK0_Frequency = RCC_Clocks->SYSCLK_Frequency / (v_regtmp + 1);
    /*USART0 clk*/
    switch (SYSCTRL->ClkEnR1_b.USART0_CLKSEL)
    {
      case 0x00:
        RCC_Clocks->USART0_Frequency = RCC_Clocks->PCLK0_Frequency;
        break;
      case 0x01:
        RCC_Clocks->USART0_Frequency = RCC_Clocks->SYSCLK_IN_Frequency;
        break;
      case 0x02:
        RCC_Clocks->USART0_Frequency = RCC_Clocks->HSI_Frequency;
        break;
      case 0x03:
        RCC_Clocks->USART0_Frequency = RCC_Clocks->LSE_Frequency;
        break;
      default:
        break;
    }
    if(SYSCTRL->ClkEnR1_b.USART0_CLKDIV == RCC_USART0CLK_DIV_2)
    {
      RCC_Clocks->USART0_Frequency = RCC_Clocks->USART0_Frequency / 2;
    }
    /*USART1 clk*/
    switch (SYSCTRL->ClkEnR1_b.USART1_CLKSEL)
    {
      case 0x00:
        RCC_Clocks->USART1_Frequency = RCC_Clocks->PCLK0_Frequency;
        break;
      case 0x01:
        RCC_Clocks->USART1_Frequency = RCC_Clocks->SYSCLK_IN_Frequency;
        break;
      case 0x02:
        RCC_Clocks->USART1_Frequency = RCC_Clocks->HSI_Frequency;
        break;
      case 0x03:
        RCC_Clocks->USART1_Frequency = RCC_Clocks->LSE_Frequency;
        break;
      default:
        break;
    }
    if(SYSCTRL->ClkEnR1_b.USART1_CLKDIV == RCC_USART1CLK_DIV_2)
    {
      RCC_Clocks->USART1_Frequency = RCC_Clocks->USART1_Frequency / 2;
    }
    /*I2C0 clk*/
    switch (SYSCTRL->ClkEnR1_b.I2C0_CLKSEL)
    {
      case 0x00:
        RCC_Clocks->I2C0_Frequency = RCC_Clocks->PCLK0_Frequency;
        break;
      case 0x01:
        RCC_Clocks->I2C0_Frequency = RCC_Clocks->SYSCLK_IN_Frequency;
        break;
      case 0x02:
        RCC_Clocks->I2C0_Frequency = RCC_Clocks->HSI_Frequency;
        break;
      case 0x03:
        RCC_Clocks->I2C0_Frequency = RCC_Clocks->LSE_Frequency;
        break;
      default:
        break;
    }
    if(SYSCTRL->ClkEnR1_b.I2C0_CLKDIV == RCC_I2C0CLK_DIV_2)
    {
      RCC_Clocks->I2C0_Frequency = RCC_Clocks->I2C0_Frequency / 2;
    }
    /*SPI0 clk*/
    switch (SYSCTRL->ClkEnR1_b.SPI0_CLKSEL)
    {
      case 0x00:
        RCC_Clocks->SPI0_Frequency = RCC_Clocks->PCLK0_Frequency;
        break;
      case 0x01:
        RCC_Clocks->SPI0_Frequency = RCC_Clocks->SYSCLK_IN_Frequency;
        break;
      case 0x02:
        RCC_Clocks->SPI0_Frequency = RCC_Clocks->HSI_Frequency;
        break;
      case 0x03:
        RCC_Clocks->SPI0_Frequency = RCC_Clocks->LSE_Frequency;
        break;
      default:
        break;
    }
    if(SYSCTRL->ClkEnR1_b.SPI0_CLKDIV == RCC_SPI0CLK_DIV_2)
    {
      RCC_Clocks->SPI0_Frequency = RCC_Clocks->SPI0_Frequency / 2;
    }
}

/**
  * @name   RCC_FrequrencyJitter_Config
  * @brief  EN: Jitter frequency function configuration.
  *         CN: ����Ƶ�ʹ������á�
  * @param  FjRange: 
  *         EN: Range of jitter frequency variation.
  *         CN: ��Ƶ�仯��Χ��
  *         @arg RCC_FJRANGE_0 
  *         @arg RCC_FJRANGE_1 
  *         @arg RCC_FJRANGE_2 
  *         @arg RCC_FJRANGE_3 
  * @param  FjInterval: 
  *         EN: The time interval between each frequency change in jitter frequency.
  *         CN: ��Ƶ��ÿ��Ƶ�ʱ仯��ʱ������
  *         @arg RCC_FJINTERVAL_64   
  *         @arg RCC_FJINTERVAL_128  
  *         @arg RCC_FJINTERVAL_256  
  *         @arg RCC_FJINTERVAL_512  
  *         @arg RCC_FJINTERVAL_1024 
  *         @arg RCC_FJINTERVAL_2048 
  *         @arg RCC_FJINTERVAL_4096 
  *         @arg RCC_FJINTERVAL_8192 
  * @param  NewState: 
  *         EN: Specify the new state of the Douyin function.
  *         CN: ָ����Ƶ���ܵ���״̬��
  * @retval ITStatus
  */
void RCC_FrequrencyJitter_Config(uint32_t FjRange, uint32_t FjInterval, FunctionalState NewState)
{ 
  if (NewState != DISABLE)
  {
    chipctrl_access();
    CHIPCTRL->RCH_CFG &= ~(CHIPCTRL_RCH_CFG_RCH_FJ_INV_Msk | CHIPCTRL_RCH_CFG_RCH_FJ_RANGE_Msk);
    CHIPCTRL->RCH_CFG |= FjRange | FjInterval | CHIPCTRL_RCH_CFG_RCH_FJ_EN_Msk;
    __dekey();
  }
  else
  {
    chipctrl_access();
    CHIPCTRL->RCH_CFG &= ~CHIPCTRL_RCH_CFG_RCH_FJ_EN_Msk;
    __dekey();
  }
}
