/********************************************************************************
 * @file    RCC_SystemClockConfig.c
 * @author  SOC AE Team
 * @version V1.1
 * @date    2025-06-27
 * @brief   系统时钟源配置，滴答定时器定时1ms，若PA10 1ms翻转一次则配置成功。
 *          通过宏定义RCC_SYSCLKSource选择系统时钟源：
 *          0：HIRC  1：LRC 2：LXT  3：64M  4：HXT
 *******************************************************************************/

#include "sc32_conf.h"
#include "Function_Init.h"
#include "stdio.h"

/* 系统时钟源配置 */
//HIRC:RCC_SYSCLKSource=0  LIRC:RCC_SYSCLKSource=1   LXT:2      64M/72M:RCC_SYSCLKSource=3  HXT:RCC_SYSCLKSource=4
#define RCC_SYSCLKSource 3

void RCC_SystemClockConfig_Function(void)
{  
  GPIO_InitTypeDef GPIO_InitStruct; //定义GPIO初始化结构体变量
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT_PP;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
  
  RCC_DeInit();
  RCC_Unlock(0xFF);//寄存器解锁
  
#if(RCC_SYSCLKSource == 0)
  /* RCC_SYSCLKSource: HIRC*/
  RCC_HIRCCmd(ENABLE);
#if defined(SC32f10xx)
  RCC_SYSCLKConfig(RCC_SYSCLKSource_HIRC);//SYSCLK=32MHz
#elif defined(SC32f12xx)
  RCC_SYSCLKConfig( RCC_SYSCLKSource_HIRC_2);//SYSCLK=32MHz/36M
#endif   
	RCC_HCLKConfig(RCC_SYSCLK_Div1);//HCLK=SYSCLK/1
  /* 滴答定时器配置 */
  RCC_SystickCLKConfig(RCC_SysTickSource_HCLK);//SystickCLK=HCLK=32MHz
#if defined(SC32f10xx)||defined(SC32f12xx)
  RCC_SystickSetCounter(32000000/1000); //1ms中断一次(SystickCLK/1000)

#endif
#elif	(RCC_SYSCLKSource == 1)

  /* RCC_SYSCLKSource:LIRC	*/
  RCC_LIRCCmd(ENABLE);

  RCC_SYSCLKConfig(RCC_SYSCLKSource_LIRC);//SYSCLK=32KHz
  RCC_HCLKConfig(RCC_SYSCLK_Div1);//HCLK=SYSCLK/1
  /* 滴答定时器配置 */
  RCC_SystickCLKConfig(RCC_SysTickSource_HCLK);//SystickCLK=HCLK=32KHz 
  RCC_SystickSetCounter(32000/1000);//1ms中断一次(SystickCLK/1000)
  
#elif	(RCC_SYSCLKSource == 2)
  /* RCC_SYSCLKSource:LXT （需要起振时间） */
  RCC_LXTCmd(ENABLE);
  {
    uint32_t text = 5000000;
    while(text--);
  }
  RCC_Unlock(0xFF);
  RCC_SYSCLKConfig(RCC_SYSCLKSource_LXT);//SYSCLK=32.768KHz
  RCC_HCLKConfig(RCC_SYSCLK_Div1);//HCLK=SYSCLK/1

  /**/
  RCC_SystickCLKConfig(RCC_SysTickSource_HCLK);//SystickCLK=HCLK
  RCC_SystickSetCounter(32768/1000);//1ms中断一次(SystickCLK/1000)
#endif
#if defined(SC32f10xx)
#if	(RCC_SYSCLKSource == 3)

  /* RCC_SYSCLKSource:PLL */
	RCC_Unlock(0xFF);
	RLL_Factor_TypeDef RLL_Factor_Struct;
	RLL_Factor_Struct.PLLM = 16; //PLLM=HIRC/16=32/16=2MHz
	RLL_Factor_Struct.PLLN = 128; //PLLN=PLLM*144=2*128=256MHz
	RLL_Factor_Struct.PLLP = 1;	//PLLP=PLLN/2^(1+1)=256/4=64MHz
	RCC_PLLConfig(RCC_PLLCLKSource_HIRC,&RLL_Factor_Struct);
	RCC_PLLCmd(ENABLE);
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
	{
		uint32_t waiting = 1500;
		while(waiting--);
		RCC_Unlock(0xFF);
		RCC_PLLRCmd(ENABLE);
	}
	RCC_PLLRCmd(ENABLE);
	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLRCLK);//SYSCLK=64M
	RCC_HCLKConfig(RCC_SYSCLK_Div1);
  /**/
  RCC_SystickCLKConfig(RCC_SysTickSource_HCLK);//SystickCLK=HCLK
  RCC_SystickSetCounter(64000000/1000);//1ms中断一次(SystickCLK/1000)
#endif
#elif	defined(SC32f12xx)
#if	(RCC_SYSCLKSource == 3)

  RCC_HIRCDIV1Cmd(ENABLE);
  RCC_SYSCLKConfig(RCC_SYSCLKSource_HIRC);//SYSCLK=32.768KHz
  RCC_HCLKConfig(RCC_SYSCLK_Div1);//HCLK=SYSCLK/1
  /**/
  RCC_SystickCLKConfig(RCC_SysTickSource_HCLK);//SystickCLK=HCLK
  RCC_SystickSetCounter(64000000/1000);//1ms中断一次(SystickCLK/1000)
#endif
#endif
#if defined(SC32f10xx) ||defined(SC32f12xx)
#if	(RCC_SYSCLKSource == 4)
  /* RCC_SYSCLKSource:HXT */
  RCC_HXTCmd(ENABLE);
  RCC_SYSCLKConfig(RCC_SYSCLKSource_HXT);
  RCC_HCLKConfig(RCC_SYSCLK_Div1);//HCLK=SYSCLK/1
 
  /* 滴答定时器配置 */
  RCC_SystickCLKConfig(RCC_SysTickSource_HXT_DIV2);//SystickCLK=HXT/2(如果 SysTick时钟源不是来自HCLK，SysTick时钟源必须小于或等于HCLK/2)
  RCC_SystickSetCounter(8000000/1000);//1ms中断一次(SystickCLK/1000)
#endif
#endif

  
  /*使能滴答定时器中断*/	
  NVIC_EnableIRQ(SysTick_IRQn);
  RCC_SystickCmd(ENABLE);
  
  /*时钟分频设置*/
  RCC_APB0Config(RCC_HCLK_Div2);//PCLK0=HCLK/2
  RCC_APB1Config(RCC_HCLK_Div4);//PCLK1=HCLK/4
  RCC_APB2Config(RCC_HCLK_Div2);//PCLK2=HCLK/2
  
  /*获取每个时钟的频率*/
  RCC_ClocksTypeDef RCC_Clocks;//定义结构体，存储各个时钟频率
  RCC_GetClocksFreq(&RCC_Clocks);//函数内HXT_VALUE可以根据实际外接晶振大小在芯片头文件中修改
  
  while(1)
  {
  }
}

void SYSTICK_SystemClockConfig_SYSTICKHandler(void)
{
  PA_OT(10);   //PA10翻转
}
