2025-04-26 16:03:23 +08:00

345 lines
9.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** ##########################################################################
** Filename :
** Project :
** Module :
** Processor :
** Version :
** Compiler :
** Date/Time :
** Abstract :
** Contents :
** Note :
**
** (c) Copyright dmdz Co.,Ltd
** --------------------------------------------------------------------------
** R E V I S I O N H I S T O R Y
** --------------------------------------------------------------------------
** Date Ver Author Description
** -20230602- --V1.0-- --mingyea--- --修改--
** #########################################################################*/
/*---------------------------------------------------------------------------
- I N C L U D E F I L E S
----------------------------------------------------------------------------*/
#include "clk.h"
#include "mf_config.h"
#include "nvic.h"
/*---------------------------------------------------------------------------
- D E F I N E S / M A C R O S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- T Y P E D E F I N I T I O N S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- S T A T I C V A R I A B L E S
----------------------------------------------------------------------------*/
//static clk_work_mode_e g_clk_work_mode;
static clk_clocks_freq_s g_clk_info;
/*---------------------------------------------------------------------------
* G L O B A L V A R I A B L E S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- C O N S T A N T S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- F U N C T I O N P R O T O T Y P E
----------------------------------------------------------------------------*/
extern void SystemInit_hsi(void);
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :初始化
----------------------------------------------------------------------------*/
void clk_init(void)
{
FL_Init();
MF_Clock_Init();
#ifdef CLK_HSE_EN
/* XTHF 8M倍频至48M */
SelXTHFToPLL(FL_CMU_PLL_PSC_DIV8, 48 - 1);
#else
SystemInit_hsi();
#endif
FL_CMU_RCLP_Enable(); //其实默认己开
//SystemCoreClockUpdate();
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void SystemDeInit (void)
{
#if 0
CKGEN_SetSysclkSrc(SYSCLK_SRC_INTERNAL_OSC); ///<set internal 8M RC as sysclk first
SPM_EnablePLL(DISABLE); ///<Disable PLL next
SPM_EnableXOSC(DISABLE); ///<Disable XOSC final
CKGEN_SetPLLReference(PLL_REF_INTERAL_OSC);
//SPM_EnableLVD(DISABLE); //disable LVD if need
#endif
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : Source 锁相环输入参考时钟选择
PLL_REFPSC:
@arg @ref FL_CMU_PLL_CLK_SOURCE_RCHF
* @arg @ref FL_CMU_PLL_CLK_SOURCE_XTHF
* PLL_DB : FL_CMU_PLL_PSC_DIV1
* PLL_OSEL:FL_CMU_PLL_OUTPUT_X1
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void CMU_PLL_ConfigDomain_SYSTEM(uint32_t Source, uint32_t PLL_REFPSC, uint32_t PLL_DB, uint32_t PLL_OSEL)
{
MODIFY_REG(CMU->PLLCR, CMU_PLLCR_DB_Msk | CMU_PLLCR_REFPRSC_Msk | CMU_PLLCR_OSEL_Msk | CMU_PLLCR_INSEL_Msk,
(PLL_DB << CMU_PLLCR_DB_Pos) | PLL_REFPSC | PLL_OSEL | Source);
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : RCHF振荡频率值
|Output parameters :
|Return value :
|Description : RCHF初始化配置
----------------------------------------------------------------------------*/
void RCHFInit(uint32_t clock)
{
switch(clock)
{
case FL_CMU_RCHF_FREQUENCY_8MHZ:
FL_CMU_RCHF_WriteTrimValue(RCHF8M_TRIM);
break;
case FL_CMU_RCHF_FREQUENCY_16MHZ:
FL_CMU_RCHF_WriteTrimValue(RCHF16M_TRIM);
break;
case FL_CMU_RCHF_FREQUENCY_24MHZ:
FL_CMU_RCHF_WriteTrimValue(RCHF24M_TRIM);
break;
case FL_CMU_RCHF_FREQUENCY_32MHZ:
FL_CMU_RCHF_WriteTrimValue(RCHF32M_TRIM);
break;
default:
FL_CMU_RCHF_WriteTrimValue(RCHF8M_TRIM);
break;
}
FL_CMU_RCHF_SetFrequency(clock);
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : rchf FL_CMU_RCHF_FREQUENCY_8MHZ
clock PLL倍频输出频率
|Output parameters :
|Return value :
|Description : RCHF初始化配置
----------------------------------------------------------------------------*/
void SelRCHFToPLL(uint32_t rchf, uint32_t clock)
{
FL_NVIC_ConfigTypeDef InterruptConfigStruct;
uint32_t counter = 0;
uint32_t readystatus = 0;
uint32_t div = FL_CMU_PLL_PSC_DIV8;
if(clock > 63) { return; }
RCHFInit(rchf);
FL_CMU_ClearFlag_SYSCLKSELError(); //清除时钟选择错误标志
FL_CMU_EnableIT_SYSCLKSELError(); //使能时钟选择错误中断
InterruptConfigStruct.preemptPriority = NVIC_PRIORITY_CLK;
FL_NVIC_Init(&InterruptConfigStruct, FDET_IRQn); //系统时钟选择错误中断
switch(rchf)
{
case FL_CMU_RCHF_FREQUENCY_16MHZ:
div = FL_CMU_PLL_PSC_DIV16;
break;
case FL_CMU_RCHF_FREQUENCY_24MHZ:
div = FL_CMU_PLL_PSC_DIV24;
break;
case FL_CMU_RCHF_FREQUENCY_32MHZ:
div = FL_CMU_PLL_PSC_DIV32;
break;
default:
break;
}
if(clock <= 23)
{
FL_FLASH_SetReadWait(FLASH, FL_FLASH_READ_WAIT_0CYCLE);
}
else
if((clock > 23) && (clock <= 47))
{
FL_FLASH_SetReadWait(FLASH, FL_FLASH_READ_WAIT_1CYCLE);
}
else
{
FL_FLASH_SetReadWait(FLASH, FL_FLASH_READ_WAIT_2CYCLE);
}
CMU_PLL_ConfigDomain_SYSTEM(FL_CMU_PLL_CLK_SOURCE_RCHF, div, clock, FL_CMU_PLL_OUTPUT_X1);
FL_CMU_PLL_Enable();
do
{
readystatus = FL_CMU_IsActiveFlag_PLLReady();
counter++;
} while((readystatus != 0x1U) && (counter != PLL_TIMEOUT));
FL_CDIF_SetPrescaler(CDIF, FL_CDIF_PSC_DIV8); //CDIF接口访问的最高频率建议不超过8M
FL_CMU_SetSystemClockSource(FL_CMU_SYSTEM_CLK_SOURCE_PLL); //系统时钟源选择PLL
FL_CMU_SetAHBPrescaler(FL_CMU_AHBCLK_PSC_DIV1);
FL_CMU_SetAPBPrescaler(FL_CMU_APBCLK_PSC_DIV1);
SystemCoreClockUpdate();
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description : XTHF初始化配置
----------------------------------------------------------------------------*/
void XTHFInit(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct = {0};
FL_NVIC_ConfigTypeDef InterruptConfigStruct;
//PC2.3配置成模拟功能外接XTHF
GPIO_InitStruct.pin = FL_GPIO_PIN_2 | FL_GPIO_PIN_3;
GPIO_InitStruct.mode = FL_GPIO_MODE_ANALOG;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
GPIO_InitStruct.analogSwitch = FL_DISABLE;
(void)FL_GPIO_Init(GPIOC, &GPIO_InitStruct);
//使能XTHF
FL_CMU_XTHF_Enable();
FL_CMU_XTHF_WriteDriverStrength(0x02); //振荡强度---05 可能合适 10PF
FL_DelayMs(2);
#if 1 //晶振停振检测,要开启
FL_CMU_ClearFlag_XTHFFail();
FL_CMU_EnableIT_XTHFFail(); //开启XTHF停振检测中断
InterruptConfigStruct.preemptPriority = NVIC_PRIORITY_CLK;
FL_NVIC_Init(&InterruptConfigStruct, FDET_IRQn);
#endif
SystemCoreClockUpdate();
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : div 对XTHF参考时钟的分频目标分频到1M; clock PLL倍频输出频率
|Output parameters :
|Return value :
|Description : 选择外部XTHF作为锁相环的参考时钟
----------------------------------------------------------------------------*/
void SelXTHFToPLL(uint32_t div, uint32_t clock)
{
FL_NVIC_ConfigTypeDef InterruptConfigStruct;
uint32_t counter = 0;
uint32_t readystatus = 0;
if(clock > 63) { return; }
XTHFInit();
FL_CMU_ClearFlag_SYSCLKSELError(); //清除时钟选择错误标志
FL_CMU_EnableIT_SYSCLKSELError(); //使能时钟选择错误中断
InterruptConfigStruct.preemptPriority = 0x00;
FL_NVIC_Init(&InterruptConfigStruct, FDET_IRQn); //系统时钟选择错误中断
if(clock <= 23)
{
FL_FLASH_SetReadWait(FLASH, FL_FLASH_READ_WAIT_0CYCLE);
}
else
if((clock > 23) && (clock <= 47))
{
FL_FLASH_SetReadWait(FLASH, FL_FLASH_READ_WAIT_1CYCLE);
}
else
{
FL_FLASH_SetReadWait(FLASH, FL_FLASH_READ_WAIT_2CYCLE);
}
CMU_PLL_ConfigDomain_SYSTEM(FL_CMU_PLL_CLK_SOURCE_XTHF, div, clock, FL_CMU_PLL_OUTPUT_X1);
FL_CMU_PLL_Enable();
do
{
readystatus = FL_CMU_IsActiveFlag_PLLReady();
counter++;
} while((readystatus != 0x1U) && (counter != PLL_TIMEOUT));
FL_CDIF_SetPrescaler(CDIF, FL_CDIF_PSC_DIV8); //CDIF接口访问的最高频率建议不超过8M
FL_CMU_SetSystemClockSource(FL_CMU_SYSTEM_CLK_SOURCE_PLL);
FL_CMU_SetAHBPrescaler(FL_CMU_AHBCLK_PSC_DIV1);
FL_CMU_SetAPBPrescaler(FL_CMU_APBCLK_PSC_DIV1);
SystemCoreClockUpdate();
}