/*! \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 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 */ *((volatile uint32_t *)0x40021018U) |= (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 *)0x40013800U) = (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 */ *((volatile uint32_t *)0x40021018U) |= (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 *)0x40013800U) = (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 */ *((volatile uint32_t *)0x40021018U) |= (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 *)0x40013800U) = (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/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) * 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)/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) * 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 */ *((volatile uint32_t *)0x40021018U) |= (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 *)0x40013800U) = (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 */ *((volatile uint32_t *)0x40021018U) |= (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 *)0x40013800U) = (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 */