- 修正HBI访问模型:将ESC核心CSR(0x0000-0x0FFF)改为通过ECAT_CSR_CMD/DATA 间接端口访问,解决此前直接寻址导致核心寄存器恒读0/写丢弃的问题 - 新增csrRead/csrWrite/pramRead/pramWrite接口,正确实现LAN9252访问端口操作 - 添加PDI就绪检测:等待DL_STATUS bit0置位确认EEPROM加载完成和EtherCAT核心使能 - 实现IRQ引脚输出使能:配置IRQ_CFG和INT_EN寄存器,使EtherCAT事件能到达PB1, 解决PDI_Isr未触发导致SAFEOP->OP无限挂起的问题 - 为ESC_EXMC硬件诊断添加CONFIG_ESC_EXMC_DIAG门控,默认关闭避免影响正常运行 - 修正system_gd32e50x.c中HXTAL故障诊断的寄存器偏移和位设置错
1309 lines
44 KiB
C
1309 lines
44 KiB
C
/*!
|
||
\file system_gd32e50x.c
|
||
\brief CMSIS Cortex-M33 Device Peripheral Access Layer Source File for
|
||
GD32E50x Device Series
|
||
*/
|
||
|
||
/*
|
||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||
* Copyright (c) 2023, GigaDevice Semiconductor Inc.
|
||
*
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||
* not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
*/
|
||
|
||
/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */
|
||
|
||
#include "gd32e50x.h"
|
||
|
||
/* system frequency define */
|
||
#define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */
|
||
#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */
|
||
|
||
#define VECT_TAB_OFFSET (uint32_t)0x00048000 /* vector table base offset */
|
||
|
||
/* select a system clock by uncommenting the following line */
|
||
/* use IRC8M */
|
||
//#define __SYSTEM_CLOCK_IRC8M (uint32_t)(__IRC8M)
|
||
//#define __SYSTEM_CLOCK_72M_PLL_IRC8M (uint32_t)(72000000)
|
||
//#define __SYSTEM_CLOCK_120M_PLL_IRC8M (uint32_t)(120000000)
|
||
//#define __SYSTEM_CLOCK_168M_PLL_IRC8M (uint32_t)(168000000)
|
||
//#define __SYSTEM_CLOCK_180M_PLL_IRC8M (uint32_t)(180000000)
|
||
|
||
/* use HXTAL(EPRT/HD series CK_HXTAL = 8M, CL series CK_HXTAL = 25M) */
|
||
//#define __SYSTEM_CLOCK_HXTAL (uint32_t)(__HXTAL)
|
||
//#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000)
|
||
//#define __SYSTEM_CLOCK_120M_PLL_HXTAL (uint32_t)(120000000)
|
||
//#define __SYSTEM_CLOCK_168M_PLL_HXTAL (uint32_t)(168000000)
|
||
#define __SYSTEM_CLOCK_180M_PLL_HXTAL (uint32_t)(180000000)
|
||
|
||
/* The following is to prevent Vcore fluctuations caused by frequency switching.
|
||
It is strongly recommended to include it to avoid issues caused by self-removal. */
|
||
#define RCU_MODIFY(__delay) do{ \
|
||
volatile uint32_t i,reg;; \
|
||
if(0 != __delay){ \
|
||
/* Insert a software delay */ \
|
||
for(i=0; i<__delay; i++){ \
|
||
} \
|
||
reg = RCU_CFG0; \
|
||
reg &= ~(RCU_CFG0_AHBPSC); \
|
||
reg |= RCU_AHB_CKSYS_DIV2; \
|
||
/* AHB = SYSCLK/2 */ \
|
||
RCU_CFG0 = reg; \
|
||
/* Insert a software delay */ \
|
||
for(i=0; i<__delay; i++){ \
|
||
} \
|
||
reg = RCU_CFG0; \
|
||
reg &= ~(RCU_CFG0_AHBPSC); \
|
||
reg |= RCU_AHB_CKSYS_DIV4; \
|
||
/* AHB = SYSCLK/4 */ \
|
||
RCU_CFG0 = reg; \
|
||
/* Insert a software delay */ \
|
||
for(i=0; i<__delay; i++){ \
|
||
} \
|
||
} \
|
||
}while(0)
|
||
|
||
|
||
/* The following is to prevent Vcore fluctuations caused by frequency switching.
|
||
It is strongly recommended to include it to avoid issues caused by self-removal. */
|
||
#define RCU_MODIFY_UP(__delay) do{ \
|
||
volatile uint32_t i,reg; \
|
||
if(0 != __delay){ \
|
||
for(i=0; i<__delay; i++){ \
|
||
} \
|
||
reg = RCU_CFG0; \
|
||
reg &= ~(RCU_CFG0_AHBPSC); \
|
||
reg |= RCU_AHB_CKSYS_DIV2; \
|
||
RCU_CFG0 = reg; \
|
||
for(i=0; i<__delay; i++){ \
|
||
} \
|
||
reg = RCU_CFG0; \
|
||
reg &= ~(RCU_CFG0_AHBPSC); \
|
||
reg |= RCU_AHB_CKSYS_DIV1; \
|
||
RCU_CFG0 = reg; \
|
||
} \
|
||
}while(0)
|
||
|
||
#define HXTALSTB_DELAY { \
|
||
volatile uint32_t i; \
|
||
for(i=0; i<0x1000; i++){ \
|
||
} \
|
||
}
|
||
|
||
#define SEL_IRC8M 0x00
|
||
#define SEL_HXTAL 0x01
|
||
#define SEL_PLL 0x02
|
||
|
||
/* set the system clock frequency and declare the system clock configuration function */
|
||
#ifdef __SYSTEM_CLOCK_IRC8M
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC8M;
|
||
static void system_clock_8m_irc8m(void);
|
||
#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M;
|
||
static void system_clock_72m_irc8m(void);
|
||
#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC8M)
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_IRC8M;
|
||
static void system_clock_120m_irc8m(void);
|
||
#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC8M)
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_IRC8M;
|
||
static void system_clock_168m_irc8m(void);
|
||
#elif defined (__SYSTEM_CLOCK_180M_PLL_IRC8M)
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_180M_PLL_IRC8M;
|
||
static void system_clock_180m_irc8m(void);
|
||
|
||
#elif defined (__SYSTEM_CLOCK_HXTAL)
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL;
|
||
static void system_clock_hxtal(void);
|
||
#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL;
|
||
static void system_clock_72m_hxtal(void);
|
||
#elif defined (__SYSTEM_CLOCK_120M_PLL_HXTAL)
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_120M_PLL_HXTAL;
|
||
static void system_clock_120m_hxtal(void);
|
||
#elif defined (__SYSTEM_CLOCK_168M_PLL_HXTAL)
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_168M_PLL_HXTAL;
|
||
static void system_clock_168m_hxtal(void);
|
||
#elif defined (__SYSTEM_CLOCK_180M_PLL_HXTAL)
|
||
uint32_t SystemCoreClock = __SYSTEM_CLOCK_180M_PLL_HXTAL;
|
||
static void system_clock_180m_hxtal(void);
|
||
#endif /* __SYSTEM_CLOCK_IRC8M */
|
||
|
||
/* configure the system clock */
|
||
static void system_clock_config(void);
|
||
/*!
|
||
\brief software delay to prevent the impact of Vcore fluctuations
|
||
\param[in] time delay factor
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void _soft_delay_(uint32_t time)
|
||
{
|
||
__IO uint32_t i;
|
||
for(i=0; i<time*10; i++){
|
||
}
|
||
}
|
||
/*!
|
||
\brief setup the micro-controller system, initialize the system
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
void SystemInit (void)
|
||
{
|
||
/* ===== DIAG: raw USART0 output — detect current clock for baudrate ===== */
|
||
/* Enable AFIO + GPIOA + USART0 clocks via raw register */
|
||
*((volatile uint32_t *)0x40021018U) |= (1U << 14) | (1U << 2) | (1U << 0);
|
||
/* PA9 = AF_PP, 50MHz (CTL=0b11, MD=0b11) -> CTL1 bit[4..7]=0b1011 */
|
||
{
|
||
volatile uint32_t ctl = *((volatile uint32_t *)0x40010804U);
|
||
ctl &= ~(0xFU << 4);
|
||
ctl |= (0xBU << 4); /* AF_PP 50MHz */
|
||
*((volatile uint32_t *)0x40010804U) = ctl;
|
||
}
|
||
/* Detect current system clock: if PLL is selected, assume 180MHz; otherwise IRC8M=8MHz.
|
||
* This handles both cold boot (IRC8M) and BOOT jump (PLL 180MHz). */
|
||
{
|
||
uint32_t scss = (*((volatile uint32_t *)0x40021000U) >> 2) & 0x3U; /* RCU_CFG0 SCSS bits */
|
||
uint32_t baud_div;
|
||
if (scss == 0x2U) { /* PLL selected as system clock -> 180MHz */
|
||
baud_div = 180000000U / 115200U; /* = 1562 */
|
||
} else { /* IRC8M or HXTAL -> 8MHz */
|
||
baud_div = 8000000U / 115200U; /* = 69 */
|
||
}
|
||
*((volatile uint32_t *)0x40013808U) = baud_div;
|
||
}
|
||
/* USART0 CTL0: TE + EN = bit3 + bit13 */
|
||
*((volatile uint32_t *)0x40013800U) = (1U << 3) | (1U << 13);
|
||
/* Send "APP" via USART0 DATA register */
|
||
*((volatile uint32_t *)0x40013804U) = 'A';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
*((volatile uint32_t *)0x40013804U) = 'P';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
*((volatile uint32_t *)0x40013804U) = 'P';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
*((volatile uint32_t *)0x40013804U) = '\r';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
*((volatile uint32_t *)0x40013804U) = '\n';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
/* ===== END DIAG ===== */
|
||
|
||
/* FPU settings */
|
||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
|
||
#endif
|
||
/* reset the RCU clock configuration to the default reset state */
|
||
/* Set IRC8MEN bit */
|
||
RCU_CTL |= RCU_CTL_IRC8MEN;
|
||
while(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
|
||
}
|
||
if(((RCU_CFG0 & RCU_CFG0_SCSS) == RCU_SCSS_PLL)){
|
||
RCU_MODIFY(0x100);
|
||
}
|
||
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
_soft_delay_(100);
|
||
#if (defined(GD32EPRT) || defined(GD32E50X_HD))
|
||
/* reset HXTALEN, CKMEN and PLLEN bits */
|
||
RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
|
||
/* disable all interrupts */
|
||
RCU_INT = 0x009f0000U;
|
||
#elif (defined(GD32E50X_CL) || defined(GD32E508))
|
||
/* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */
|
||
RCU_CTL &= ~(RCU_CTL_PLLEN |RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
|
||
/* disable all interrupts */
|
||
RCU_INT = 0x00ff0000U;
|
||
#endif /* GD32E50X_EPRT and GD32E50X_HD */
|
||
|
||
/* Reset CFG0 and CFG1 registers */
|
||
RCU_CFG0 = 0x00000000U;
|
||
RCU_CFG1 = 0x00000000U;
|
||
/* reset HXTALBPS bit */
|
||
RCU_CTL &= ~(RCU_CTL_HXTALBPS);
|
||
|
||
/* configure the system clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */
|
||
system_clock_config();
|
||
|
||
/* ===== DIAG: after PLL config, at 180MHz, send "CLK" ===== */
|
||
/* Re-enable USART0 at 180MHz: BAUD = 180000000/115200 = 1562.5 = 1563 */
|
||
*((volatile uint32_t *)0x40013808U) = 1563U;
|
||
*((volatile uint32_t *)0x40013800U) = (1U << 3) | (1U << 13);
|
||
*((volatile uint32_t *)0x40013804U) = 'C';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
*((volatile uint32_t *)0x40013804U) = 'L';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
*((volatile uint32_t *)0x40013804U) = 'K';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
*((volatile uint32_t *)0x40013804U) = '\r';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
*((volatile uint32_t *)0x40013804U) = '\n';
|
||
while ((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {}
|
||
/* ===== END DIAG ===== */
|
||
|
||
#ifdef VECT_TAB_SRAM
|
||
nvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET);
|
||
#else
|
||
nvic_vector_table_set(NVIC_VECTTAB_FLASH,VECT_TAB_OFFSET);
|
||
#endif
|
||
}
|
||
|
||
/*!
|
||
\brief configure the system clock
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_config(void)
|
||
{
|
||
#ifdef __SYSTEM_CLOCK_IRC8M
|
||
system_clock_8m_irc8m();
|
||
#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
|
||
system_clock_72m_irc8m();
|
||
#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC8M)
|
||
system_clock_120m_irc8m();
|
||
#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC8M)
|
||
system_clock_168m_irc8m();
|
||
#elif defined (__SYSTEM_CLOCK_180M_PLL_IRC8M)
|
||
system_clock_180m_irc8m();
|
||
|
||
#elif defined (__SYSTEM_CLOCK_HXTAL)
|
||
system_clock_hxtal();
|
||
#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
|
||
system_clock_72m_hxtal();
|
||
#elif defined (__SYSTEM_CLOCK_120M_PLL_HXTAL)
|
||
system_clock_120m_hxtal();
|
||
#elif defined (__SYSTEM_CLOCK_168M_PLL_HXTAL)
|
||
system_clock_168m_hxtal();
|
||
#elif defined (__SYSTEM_CLOCK_180M_PLL_HXTAL)
|
||
system_clock_180m_hxtal();
|
||
#endif /* __SYSTEM_CLOCK_IRC8M */
|
||
}
|
||
|
||
#ifdef __SYSTEM_CLOCK_IRC8M
|
||
/*!
|
||
\brief configure the system clock to 8M by IRC8M
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_8m_irc8m(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable IRC8M */
|
||
RCU_CTL |= RCU_CTL_IRC8MEN;
|
||
|
||
/* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
|
||
}
|
||
while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
|
||
while(1){
|
||
}
|
||
}
|
||
|
||
/* AHB = SYSCLK */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
|
||
/* APB2 = AHB/1 */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select IRC8M as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_IRC8M;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until IRC8M is selected as system clock */
|
||
while(RCU_SCSS_IRC8M != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
}
|
||
|
||
#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
|
||
/*!
|
||
\brief configure the system clock to 72M by PLL which selects IRC8M as its clock source
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_72m_irc8m(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable IRC8M */
|
||
RCU_CTL |= RCU_CTL_IRC8MEN;
|
||
|
||
/* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
|
||
}
|
||
while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
|
||
while(1){
|
||
}
|
||
}
|
||
|
||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(1);
|
||
|
||
/* LDO output voltage high mode */
|
||
RCU_APB1EN |= RCU_APB1EN_PMUEN;
|
||
|
||
/* IRC8M is stable */
|
||
/* AHB = SYSCLK/4 */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;
|
||
/* APB2 = AHB/1 */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
/* CK_PLL = (CK_IRC8M/2) * 18 = 72 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= RCU_PLL_MUL18;
|
||
|
||
/* enable PLL */
|
||
RCU_CTL |= RCU_CTL_PLLEN;
|
||
|
||
/* wait until PLL is stable */
|
||
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
|
||
}
|
||
|
||
/* enable the high-drive to extend the clock frequency to 120 MHz */
|
||
PMU_CTL0 |= PMU_CTL0_HDEN;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDRF)){
|
||
}
|
||
|
||
/* select the high-drive mode */
|
||
PMU_CTL0 |= PMU_CTL0_HDS;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDSRF)){
|
||
}
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select PLL as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_PLL;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until PLL is selected as system clock */
|
||
while(RCU_SCSS_PLL != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
RCU_MODIFY_UP(0x50);
|
||
}
|
||
|
||
#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC8M)
|
||
/*!
|
||
\brief configure the system clock to 120M by PLL which selects IRC8M as its clock source
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_120m_irc8m(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable IRC8M */
|
||
RCU_CTL |= RCU_CTL_IRC8MEN;
|
||
|
||
/* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
|
||
}while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
|
||
while(1){
|
||
}
|
||
}
|
||
|
||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(3);
|
||
|
||
/* LDO output voltage high mode */
|
||
RCU_APB1EN |= RCU_APB1EN_PMUEN;
|
||
|
||
/* IRC8M is stable */
|
||
/* AHB = SYSCLK/4 */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;
|
||
/* APB2 = AHB/1 */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
/* CK_PLL = (CK_IRC8M/2) * 30 = 120 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= RCU_PLL_MUL30;
|
||
|
||
/* enable PLL */
|
||
RCU_CTL |= RCU_CTL_PLLEN;
|
||
|
||
/* wait until PLL is stable */
|
||
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
|
||
}
|
||
|
||
/* enable the high-drive to extend the clock frequency to 120 MHz */
|
||
PMU_CTL0 |= PMU_CTL0_HDEN;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDRF)){
|
||
}
|
||
|
||
/* select the high-drive mode */
|
||
PMU_CTL0 |= PMU_CTL0_HDS;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDSRF)){
|
||
}
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select PLL as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_PLL;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until PLL is selected as system clock */
|
||
while(RCU_SCSS_PLL != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
RCU_MODIFY_UP(0x50);
|
||
}
|
||
|
||
#elif defined (__SYSTEM_CLOCK_168M_PLL_IRC8M)
|
||
/*!
|
||
\brief configure the system clock to 168M by PLL which selects IRC8M as its clock source
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_168m_irc8m(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable IRC8M */
|
||
RCU_CTL |= RCU_CTL_IRC8MEN;
|
||
|
||
/* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
|
||
}while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
|
||
while(1){
|
||
}
|
||
}
|
||
|
||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(4);
|
||
|
||
/* LDO output voltage high mode */
|
||
RCU_APB1EN |= RCU_APB1EN_PMUEN;
|
||
|
||
/* IRC8M is stable */
|
||
/* AHB = SYSCLK/4 */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;
|
||
/* APB2 = AHB/1 */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
/* CK_PLL = (CK_IRC8M/2) * 42 = 168 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= RCU_PLL_MUL42;
|
||
|
||
/* enable PLL */
|
||
RCU_CTL |= RCU_CTL_PLLEN;
|
||
|
||
/* wait until PLL is stable */
|
||
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
|
||
}
|
||
|
||
/* enable the high-drive to extend the clock frequency to 120 MHz */
|
||
PMU_CTL0 |= PMU_CTL0_HDEN;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDRF)){
|
||
}
|
||
|
||
/* select the high-drive mode */
|
||
PMU_CTL0 |= PMU_CTL0_HDS;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDSRF)){
|
||
}
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select PLL as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_PLL;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until PLL is selected as system clock */
|
||
while(RCU_SCSS_PLL != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
RCU_MODIFY_UP(0x50);
|
||
}
|
||
|
||
#elif defined (__SYSTEM_CLOCK_180M_PLL_IRC8M)
|
||
/*!
|
||
\brief configure the system clock to 180M by PLL which selects IRC8M as its clock source
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_180m_irc8m(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable IRC8M */
|
||
RCU_CTL |= RCU_CTL_IRC8MEN;
|
||
|
||
/* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
|
||
}while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
|
||
while(1){
|
||
}
|
||
}
|
||
|
||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(4);
|
||
|
||
/* LDO output voltage high mode */
|
||
RCU_APB1EN |= RCU_APB1EN_PMUEN;
|
||
|
||
/* IRC8M is stable */
|
||
/* AHB = SYSCLK/4 */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;
|
||
/* APB2 = AHB/1 */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
/* CK_PLL = (CK_IRC8M/2) * 45 = 180 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= RCU_PLL_MUL45;
|
||
|
||
/* enable PLL */
|
||
RCU_CTL |= RCU_CTL_PLLEN;
|
||
|
||
/* wait until PLL is stable */
|
||
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
|
||
}
|
||
|
||
/* enable the high-drive to extend the clock frequency to 120 MHz */
|
||
PMU_CTL0 |= PMU_CTL0_HDEN;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDRF)){
|
||
}
|
||
|
||
/* select the high-drive mode */
|
||
PMU_CTL0 |= PMU_CTL0_HDS;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDSRF)){
|
||
}
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select PLL as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_PLL;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until PLL is selected as system clock */
|
||
while(RCU_SCSS_PLL != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
RCU_MODIFY_UP(0x50);
|
||
}
|
||
|
||
#elif defined (__SYSTEM_CLOCK_HXTAL)
|
||
/*!
|
||
\brief configure the system clock to HXTAL
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_hxtal(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable HXTAL */
|
||
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
HXTALSTB_DELAY
|
||
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
|
||
}while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||
/* HXTAL failed: output diagnostic via USART0 at IRC8M.
|
||
* 修正(1.5.34):原段把 CTL0 写到 STAT0 偏移(0x40013800)且漏开 USART0EN(APB2EN bit14),
|
||
* 该诊断从未真正发出;正确布局:CTL0 @ USART0+0x0C,APB2EN bit14|bit2|bit0。 */
|
||
*((volatile uint32_t *)0x40021018U) |= (1U << 14) | (1U << 2) | (1U << 0);
|
||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||
*((volatile uint32_t *)0x4001380CU) = (1U << 3) | (1U << 13);
|
||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||
for(int i=0; _msg[i]; i++){
|
||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||
while(1){ }
|
||
}
|
||
|
||
/* AHB = SYSCLK */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
|
||
/* APB2 = AHB/1 */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select HXTAL as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_HXTAL;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until HXTAL is selected as system clock */
|
||
while(RCU_SCSS_HXTAL != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
}
|
||
|
||
#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
|
||
/*!
|
||
\brief configure the system clock to 72M by PLL which selects HXTAL as its clock source
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_72m_hxtal(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable HXTAL */
|
||
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
HXTALSTB_DELAY
|
||
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
|
||
}while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||
/* HXTAL failed: output diagnostic via USART0 at IRC8M.
|
||
* 修正(1.5.34):原段把 CTL0 写到 STAT0 偏移(0x40013800)且漏开 USART0EN(APB2EN bit14),
|
||
* 该诊断从未真正发出;正确布局:CTL0 @ USART0+0x0C,APB2EN bit14|bit2|bit0。 */
|
||
*((volatile uint32_t *)0x40021018U) |= (1U << 14) | (1U << 2) | (1U << 0);
|
||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||
*((volatile uint32_t *)0x4001380CU) = (1U << 3) | (1U << 13);
|
||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||
for(int i=0; _msg[i]; i++){
|
||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||
while(1){ }
|
||
}
|
||
|
||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(1);
|
||
|
||
RCU_APB1EN |= RCU_APB1EN_PMUEN;
|
||
|
||
/* HXTAL is stable */
|
||
/* AHB = SYSCLK/4 */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;
|
||
/* APB2 = AHB/1 */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
#if defined(GD32E50X_HD)
|
||
/* select HXTAL/2 as clock source */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0);
|
||
|
||
/* CK_PLL = (CK_HXTAL/2) * 18 = 72 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= RCU_PLL_MUL18;
|
||
|
||
#elif (defined(GD32E50X_CL) || defined(GD32E508))
|
||
/* CK_PLL = (CK_PREDIV0) * 18 = 72 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL18);
|
||
|
||
/* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
|
||
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
|
||
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
|
||
|
||
/* enable PLL1 */
|
||
RCU_CTL |= RCU_CTL_PLL1EN;
|
||
/* wait till PLL1 is ready */
|
||
while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
|
||
}
|
||
|
||
#elif defined(GD32EPRT)
|
||
/* CK_PLL = (CK_PREDIV0) * 18 = 72 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL18);
|
||
|
||
/* CK_PREDIV0 = (CK_HXTAL)/2 *8 /8 = 4 MHz */
|
||
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
|
||
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV8);
|
||
|
||
/* enable PLL1 */
|
||
RCU_CTL |= RCU_CTL_PLL1EN;
|
||
/* wait till PLL1 is ready */
|
||
while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
|
||
}
|
||
#endif /* GD32E50X_HD */
|
||
|
||
/* enable PLL */
|
||
RCU_CTL |= RCU_CTL_PLLEN;
|
||
|
||
/* wait until PLL is stable */
|
||
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
|
||
}
|
||
|
||
/* enable the high-drive to extend the clock frequency to 180 MHz */
|
||
PMU_CTL0 |= PMU_CTL0_HDEN;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDRF)){
|
||
}
|
||
|
||
/* select the high-drive mode */
|
||
PMU_CTL0 |= PMU_CTL0_HDS;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDSRF)){
|
||
}
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select PLL as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_PLL;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until PLL is selected as system clock */
|
||
while(RCU_SCSS_PLL != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
RCU_MODIFY_UP(0x50);
|
||
}
|
||
#elif defined (__SYSTEM_CLOCK_120M_PLL_HXTAL)
|
||
/*!
|
||
\brief configure the system clock to 72M by PLL which selects HXTAL as its clock source
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_120m_hxtal(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable HXTAL */
|
||
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
HXTALSTB_DELAY
|
||
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
|
||
}while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||
/* HXTAL failed: output diagnostic via USART0 at IRC8M.
|
||
* 修正(1.5.34):原段把 CTL0 写到 STAT0 偏移(0x40013800)且漏开 USART0EN(APB2EN bit14),
|
||
* 该诊断从未真正发出;正确布局:CTL0 @ USART0+0x0C,APB2EN bit14|bit2|bit0。 */
|
||
*((volatile uint32_t *)0x40021018U) |= (1U << 14) | (1U << 2) | (1U << 0);
|
||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||
*((volatile uint32_t *)0x4001380CU) = (1U << 3) | (1U << 13);
|
||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||
for(int i=0; _msg[i]; i++){
|
||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||
while(1){ }
|
||
}
|
||
|
||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(3);
|
||
|
||
RCU_APB1EN |= RCU_APB1EN_PMUEN;
|
||
|
||
/* HXTAL is stable */
|
||
/* AHB = SYSCLK/2 (60 MHz) */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
|
||
/* APB2 = AHB/1 (60 MHz) */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 (30 MHz) */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
#if defined(GD32E50X_HD)
|
||
/* select HXTAL/2 as clock source */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0);
|
||
|
||
/* CK_PLL = (CK_HXTAL/2) * 30 = 120 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= RCU_PLL_MUL30;
|
||
|
||
#elif (defined(GD32E50X_CL) || defined(GD32E508))
|
||
/* CK_PLL = (CK_PREDIV0) * 30 = 120 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL30);
|
||
|
||
/* CK_PREDIV0 = (CK_HXTAL)/2 *8 /8 = 4 MHz */
|
||
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
|
||
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV8);
|
||
|
||
/* enable PLL1 */
|
||
RCU_CTL |= RCU_CTL_PLL1EN;
|
||
/* wait till PLL1 is ready */
|
||
while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
|
||
}
|
||
|
||
#elif defined(GD32EPRT)
|
||
/* CK_PLL = (CK_PREDIV0) * 30 = 120 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL30);
|
||
|
||
/* CK_PREDIV0 = (CK_HXTAL)/2 *8 /8 = 4 MHz */
|
||
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
|
||
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV8);
|
||
|
||
/* enable PLL1 */
|
||
RCU_CTL |= RCU_CTL_PLL1EN;
|
||
/* wait till PLL1 is ready */
|
||
while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
|
||
}
|
||
#endif /* GD32F50X_HD */
|
||
|
||
/* enable PLL */
|
||
RCU_CTL |= RCU_CTL_PLLEN;
|
||
|
||
/* wait until PLL is stable */
|
||
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
|
||
}
|
||
|
||
/* enable the high-drive to extend the clock frequency to 180 MHz */
|
||
PMU_CTL0 |= PMU_CTL0_HDEN;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDRF)){
|
||
}
|
||
|
||
/* select the high-drive mode */
|
||
PMU_CTL0 |= PMU_CTL0_HDS;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDSRF)){
|
||
}
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select PLL as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_PLL;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until PLL is selected as system clock */
|
||
while(RCU_SCSS_PLL != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
RCU_MODIFY_UP(0x50);
|
||
}
|
||
|
||
#elif defined (__SYSTEM_CLOCK_168M_PLL_HXTAL)
|
||
/*!
|
||
\brief configure the system clock to 108M by PLL which selects HXTAL as its clock source
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_168m_hxtal(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable HXTAL */
|
||
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
HXTALSTB_DELAY
|
||
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
|
||
}while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||
/* HXTAL failed: output diagnostic via USART0 at IRC8M.
|
||
* 修正(1.5.34):原段把 CTL0 写到 STAT0 偏移(0x40013800)且漏开 USART0EN(APB2EN bit14),
|
||
* 该诊断从未真正发出;正确布局:CTL0 @ USART0+0x0C,APB2EN bit14|bit2|bit0。 */
|
||
*((volatile uint32_t *)0x40021018U) |= (1U << 14) | (1U << 2) | (1U << 0);
|
||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||
*((volatile uint32_t *)0x4001380CU) = (1U << 3) | (1U << 13);
|
||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||
for(int i=0; _msg[i]; i++){
|
||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||
while(1){ }
|
||
}
|
||
|
||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(4);
|
||
|
||
RCU_APB1EN |= RCU_APB1EN_PMUEN;
|
||
|
||
/* HXTAL is stable */
|
||
/* AHB = SYSCLK/4 */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;
|
||
/* APB2 = AHB/1 */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
#if defined(GD32E50X_HD)
|
||
/* select HXTAL/2 as clock source */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0);
|
||
|
||
/* CK_PLL = (CK_HXTAL/2) * 42 = 168 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= RCU_PLL_MUL42;
|
||
|
||
#elif (defined(GD32E50X_CL) || defined(GD32E508))
|
||
/* CK_PLL = (CK_PREDIV0) * 42 = 168 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL42);
|
||
|
||
/* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
|
||
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
|
||
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
|
||
|
||
/* enable PLL1 */
|
||
RCU_CTL |= RCU_CTL_PLL1EN;
|
||
/* wait till PLL1 is ready */
|
||
while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
|
||
}
|
||
|
||
#elif defined(GD32EPRT)
|
||
/* CK_PLL = (CK_PREDIV0) * 42 = 168 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL42);
|
||
|
||
/* CK_PREDIV0 = (CK_HXTAL)/2 *8 /8 = 4 MHz */
|
||
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
|
||
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV8);
|
||
|
||
/* enable PLL1 */
|
||
RCU_CTL |= RCU_CTL_PLL1EN;
|
||
/* wait till PLL1 is ready */
|
||
while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
|
||
}
|
||
#endif /* GD32F50X_HD */
|
||
|
||
/* enable PLL */
|
||
RCU_CTL |= RCU_CTL_PLLEN;
|
||
|
||
/* wait until PLL is stable */
|
||
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
|
||
}
|
||
|
||
/* enable the high-drive to extend the clock frequency to 180 MHz */
|
||
PMU_CTL0 |= PMU_CTL0_HDEN;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDRF)){
|
||
}
|
||
|
||
/* select the high-drive mode */
|
||
PMU_CTL0 |= PMU_CTL0_HDS;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDSRF)){
|
||
}
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select PLL as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_PLL;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until PLL is selected as system clock */
|
||
while(RCU_SCSS_PLL != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
RCU_MODIFY_UP(0x50);
|
||
}
|
||
|
||
#elif defined (__SYSTEM_CLOCK_180M_PLL_HXTAL)
|
||
/*!
|
||
\brief configure the system clock to 180M by PLL which selects HXTAL as its clock source
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
static void system_clock_180m_hxtal(void)
|
||
{
|
||
uint32_t timeout = 0U;
|
||
uint32_t stab_flag = 0U;
|
||
__IO uint32_t reg_temp;
|
||
|
||
/* enable HXTAL */
|
||
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
HXTALSTB_DELAY
|
||
/* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
|
||
do{
|
||
timeout++;
|
||
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
|
||
}while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
|
||
|
||
/* if fail */
|
||
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
|
||
/* HXTAL failed: output diagnostic via USART0 at IRC8M.
|
||
* 修正(1.5.34):原段把 CTL0 写到 STAT0 偏移(0x40013800)且漏开 USART0EN(APB2EN bit14),
|
||
* 该诊断从未真正发出;正确布局:CTL0 @ USART0+0x0C,APB2EN bit14|bit2|bit0。 */
|
||
*((volatile uint32_t *)0x40021018U) |= (1U << 14) | (1U << 2) | (1U << 0);
|
||
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U);
|
||
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
|
||
*((volatile uint32_t *)0x40010804U) = _ctl; }
|
||
*((volatile uint32_t *)0x40013808U) = 69U; /* 8MHz/115200 */
|
||
*((volatile uint32_t *)0x4001380CU) = (1U << 3) | (1U << 13);
|
||
{ const char *_msg = "HXTAL FAIL\r\n";
|
||
for(int i=0; _msg[i]; i++){
|
||
*((volatile uint32_t *)0x40013804U) = _msg[i];
|
||
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } }
|
||
while(1){ }
|
||
}
|
||
|
||
FMC_WS = (FMC_WS & (~FMC_WS_WSCNT)) | WS_WSCNT(4);
|
||
|
||
RCU_APB1EN |= RCU_APB1EN_PMUEN;
|
||
|
||
/* HXTAL is stable */
|
||
/* AHB = SYSCLK/4 */
|
||
RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;
|
||
/* APB2 = AHB/1 */
|
||
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
/* APB1 = AHB/2 */
|
||
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
||
#if defined(GD32E50X_HD)
|
||
/* select HXTAL/2 as clock source */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0);
|
||
|
||
/* CK_PLL = (CK_HXTAL/2) * 45 = 180 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= RCU_PLL_MUL45;
|
||
|
||
#elif defined(GD32E508)
|
||
/* GD32E508 + 8MHz HXTAL:
|
||
CK_PREDIV0 = (CK_HXTAL)/2 *8 /8 = 4 MHz
|
||
CK_PLL = CK_PREDIV0 * 45 = 180 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL45);
|
||
|
||
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
|
||
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV8);
|
||
|
||
/* enable PLL1 */
|
||
RCU_CTL |= RCU_CTL_PLL1EN;
|
||
/* wait till PLL1 is ready */
|
||
while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
|
||
}
|
||
|
||
#elif defined(GD32E50X_CL)
|
||
/* CK_PLL = (CK_PREDIV0) * 45 = 180 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL45);
|
||
|
||
/* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
|
||
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
|
||
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10) ;
|
||
|
||
/* enable PLL1 */
|
||
RCU_CTL |= RCU_CTL_PLL1EN;
|
||
/* wait till PLL1 is ready */
|
||
while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
|
||
}
|
||
|
||
#elif defined(GD32EPRT)
|
||
/* CK_PLL = (CK_PREDIV0) * 45 = 180 MHz */
|
||
RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
|
||
RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL45);
|
||
|
||
/* CK_PREDIV0 = (CK_HXTAL)/2 *8 /8 = 4 MHz */
|
||
RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
|
||
RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV2 | RCU_PREDV0_DIV8);
|
||
|
||
/* enable PLL1 */
|
||
RCU_CTL |= RCU_CTL_PLL1EN;
|
||
/* wait till PLL1 is ready */
|
||
while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
|
||
}
|
||
#endif /* GD32F50X_HD */
|
||
|
||
/* enable PLL */
|
||
RCU_CTL |= RCU_CTL_PLLEN;
|
||
|
||
/* wait until PLL is stable */
|
||
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
|
||
}
|
||
|
||
/* enable the high-drive to extend the clock frequency to 180 MHz */
|
||
PMU_CTL0 |= PMU_CTL0_HDEN;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDRF)){
|
||
}
|
||
|
||
/* select the high-drive mode */
|
||
PMU_CTL0 |= PMU_CTL0_HDS;
|
||
while(0U == (PMU_CS0 & PMU_CS0_HDSRF)){
|
||
}
|
||
|
||
reg_temp = RCU_CFG0;
|
||
/* select PLL as system clock */
|
||
reg_temp &= ~RCU_CFG0_SCS;
|
||
reg_temp |= RCU_CKSYSSRC_PLL;
|
||
RCU_CFG0 = reg_temp;
|
||
|
||
/* wait until PLL is selected as system clock */
|
||
while(RCU_SCSS_PLL != (RCU_CFG0 & RCU_CFG0_SCSS)){
|
||
}
|
||
RCU_MODIFY_UP(0x50);
|
||
}
|
||
#endif /* __SYSTEM_CLOCK_IRC8M */
|
||
|
||
/*!
|
||
\brief update the SystemCoreClock with current core clock retrieved from CPU registers
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval none
|
||
*/
|
||
void SystemCoreClockUpdate (void)
|
||
{
|
||
uint32_t sws;
|
||
uint32_t pllsel, pllpresel, predv0sel, pllmf, ck_src, idx, clk_exp;
|
||
#if (defined(GD32E50X_CL) || defined(GD32EPRT) || defined(GD32E508))
|
||
uint32_t predv0, predv1, pll1mf;
|
||
#endif /* GD32E50X_CL and GD32EPRT*/
|
||
|
||
/* exponent of AHB, APB1 and APB2 clock divider */
|
||
uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||
|
||
sws = GET_BITS(RCU_CFG0, 2, 3);
|
||
switch(sws){
|
||
/* IRC8M is selected as CK_SYS */
|
||
case SEL_IRC8M:
|
||
SystemCoreClock = IRC8M_VALUE;
|
||
break;
|
||
/* HXTAL is selected as CK_SYS */
|
||
case SEL_HXTAL:
|
||
SystemCoreClock = HXTAL_VALUE;
|
||
break;
|
||
/* PLL is selected as CK_SYS */
|
||
case SEL_PLL:
|
||
/* PLL clock source selection, HXTAL, IRC48M or IRC8M/2 */
|
||
pllsel = (RCU_CFG0 & RCU_CFG0_PLLSEL);
|
||
|
||
if(RCU_PLLSRC_HXTAL_IRC48M == pllsel) {
|
||
/* PLL clock source is HXTAL or IRC48M */
|
||
pllpresel = (RCU_CFG1 & RCU_CFG1_PLLPRESEL);
|
||
|
||
if(RCU_PLLPRESRC_HXTAL == pllpresel){
|
||
/* PLL clock source is HXTAL */
|
||
ck_src = HXTAL_VALUE;
|
||
}else{
|
||
/* PLL clock source is IRC48 */
|
||
ck_src = IRC48M_VALUE;
|
||
}
|
||
|
||
#if defined(GD32E50X_HD)
|
||
predv0sel = (RCU_CFG0 & RCU_CFG0_PREDV0);
|
||
/* PREDV0 input source clock divided by 2 */
|
||
if(RCU_CFG0_PREDV0 == predv0sel){
|
||
ck_src = ck_src/2U;
|
||
}
|
||
#elif (defined(GD32E50X_CL) || defined(GD32EPRT) || defined(GD32E508))
|
||
predv0sel = (RCU_CFG1 & RCU_CFG1_PREDV0SEL);
|
||
/* source clock use PLL1 */
|
||
if(RCU_PREDV0SRC_CKPLL1 == predv0sel){
|
||
predv1 = ((RCU_CFG1 & RCU_CFG1_PREDV1) >> ((uint32_t)4U)) + 1U;
|
||
pll1mf = (uint32_t)((RCU_CFG1 & RCU_CFG1_PLL1MF) >> ((uint32_t)8U)) + 2U;
|
||
if(17U == pll1mf){
|
||
pll1mf = 20U;
|
||
}
|
||
ck_src = (ck_src/predv1)*pll1mf;
|
||
}
|
||
predv0 = (RCU_CFG1 & RCU_CFG1_PREDV0) + 1U;
|
||
ck_src /= predv0;
|
||
#endif /* GD32E50X_HD */
|
||
}else{
|
||
/* PLL clock source is IRC8M/2 */
|
||
ck_src = IRC8M_VALUE/2U;
|
||
}
|
||
|
||
/* PLL multiplication factor */
|
||
pllmf = GET_BITS(RCU_CFG0, 18, 21);
|
||
if((RCU_CFG0 & RCU_CFG0_PLLMF_4)){
|
||
pllmf |= 0x10U;
|
||
}
|
||
if((RCU_CFG0 & RCU_CFG0_PLLMF_5)){
|
||
pllmf |= 0x20U;
|
||
}
|
||
if(pllmf < 15U){
|
||
pllmf += 2U;
|
||
}else if((pllmf >= 15U) && (pllmf <= 64U)){
|
||
pllmf += 1U;
|
||
}else{
|
||
}
|
||
SystemCoreClock = ck_src*pllmf;
|
||
#if (defined(GD32E50X_CL) || defined(GD32EPRT) || defined(GD32E508))
|
||
if(15U == pllmf){
|
||
SystemCoreClock = ck_src*6U + ck_src/2U;
|
||
}
|
||
#endif /* GD32E50X_CL and GD32EPRT and GD32E508 */
|
||
|
||
break;
|
||
/* IRC8M is selected as CK_SYS */
|
||
default:
|
||
SystemCoreClock = IRC8M_VALUE;
|
||
break;
|
||
}
|
||
|
||
/* calculate AHB clock frequency */
|
||
idx = GET_BITS(RCU_CFG0, 4, 7);
|
||
clk_exp = ahb_exp[idx];
|
||
SystemCoreClock >>= clk_exp;
|
||
}
|
||
|
||
#ifdef __FIRMWARE_VERSION_DEFINE
|
||
/*!
|
||
\brief get firmware version
|
||
\param[in] none
|
||
\param[out] none
|
||
\retval firmware version
|
||
*/
|
||
uint32_t gd32e50x_firmware_version_get(void)
|
||
{
|
||
return __GD32E50X_STDPERIPH_VERSION;
|
||
}
|
||
#endif /* __FIRMWARE_VERSION_DEFINE */
|