You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
878 lines
28 KiB
878 lines
28 KiB
|
5 months ago
|
/*!
|
||
|
|
\file system_gd32h75e.c
|
||
|
|
\brief CMSIS Cortex-M7 Device Peripheral Access Layer Source File for
|
||
|
|
gd32h75e Device Series
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
|
||
|
|
* Copyright (c) 2025, 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 "gd32h75e.h"
|
||
|
|
|
||
|
|
/* system frequency define */
|
||
|
|
#define __IRC64M (IRC64M_VALUE) /* internal 64 MHz RC oscillator frequency */
|
||
|
|
#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */
|
||
|
|
#define __LPIRC4M (LPIRC4M_VALUE) /* low power internal 4 MHz RC oscillator frequency */
|
||
|
|
#define __SYS_OSC_CLK (__IRC64M) /* main oscillator frequency */
|
||
|
|
|
||
|
|
#define VECT_TAB_OFFSET (uint32_t)0x00 /* vector table base offset */
|
||
|
|
#define RCU_APB4EN_SYSCFG (uint32_t)0x01 /* enable SYSCFG clk */
|
||
|
|
|
||
|
|
/* select a system clock by uncommenting the following line */
|
||
|
|
/* use IRC64M */
|
||
|
|
//#define __SYSTEM_CLOCK_IRC64M (__IRC64M)
|
||
|
|
//#define __SYSTEM_CLOCK_480M_PLL0_IRC64M (uint32_t)(480000000)
|
||
|
|
//#define __SYSTEM_CLOCK_600M_PLL0_IRC64M (uint32_t)(600000000)
|
||
|
|
|
||
|
|
/* use LPIRC4M */
|
||
|
|
//#define __SYSTEM_CLOCK_LPIRC4M (__LPIRC4M)
|
||
|
|
|
||
|
|
/* use HXTAL(CK_HXTAL = 25M) */
|
||
|
|
//#define __SYSTEM_CLOCK_HXTAL (__HXTAL)
|
||
|
|
//#define __SYSTEM_CLOCK_200M_PLL0_HXTAL (uint32_t)(200000000)
|
||
|
|
//#define __SYSTEM_CLOCK_400M_PLL0_HXTAL (uint32_t)(400000000)
|
||
|
|
//#define __SYSTEM_CLOCK_480M_PLL0_HXTAL (uint32_t)(480000000)
|
||
|
|
#define __SYSTEM_CLOCK_600M_PLL0_HXTAL (uint32_t)(600000000)
|
||
|
|
|
||
|
|
/*
|
||
|
|
Note: the power mode need to match the mcu selection and external power supply circuit.
|
||
|
|
|
||
|
|
according to the selected mcu and external power supply circuit to uncomment
|
||
|
|
the following macro SEL_PMU_SMPS_MODE.
|
||
|
|
*/
|
||
|
|
//#define SEL_PMU_SMPS_MODE PMU_LDO_SUPPLY
|
||
|
|
//#define SEL_PMU_SMPS_MODE PMU_DIRECT_SMPS_SUPPLY
|
||
|
|
//#define SEL_PMU_SMPS_MODE PMU_BYPASS
|
||
|
|
|
||
|
|
#define SEL_IRC64MDIV 0x00U
|
||
|
|
#define SEL_HXTAL 0x01U
|
||
|
|
#define SEL_LPIRC4M 0x02U
|
||
|
|
#define SEL_PLL0P 0x03U
|
||
|
|
|
||
|
|
#define PLL0PSC_REG_OFFSET 0U
|
||
|
|
#define PLL0N_REG_OFFSET 6U
|
||
|
|
#define PLL0P_REG_OFFSET 16U
|
||
|
|
#define PLL0Q_REG_OFFSET 0U
|
||
|
|
#define PLL0R_REG_OFFSET 24U
|
||
|
|
|
||
|
|
/* set the system clock frequency and declare the system clock configuration function */
|
||
|
|
#ifdef __SYSTEM_CLOCK_IRC64M
|
||
|
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_IRC64M;
|
||
|
|
static void system_clock_64m_irc64m(void);
|
||
|
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_IRC64M)
|
||
|
|
#define PLL0PSC 16U
|
||
|
|
#define PLL0N (120U - 1U)
|
||
|
|
#define PLL0P (1U - 1U)
|
||
|
|
#define PLL0Q (2U - 1U)
|
||
|
|
#define PLL0R (2U - 1U)
|
||
|
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_480M_PLL0_IRC64M;
|
||
|
|
static void system_clock_480m_irc64m(void);
|
||
|
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M)
|
||
|
|
#define PLL0PSC 16U
|
||
|
|
#define PLL0N (150U - 1U)
|
||
|
|
#define PLL0P (1U - 1U)
|
||
|
|
#define PLL0Q (2U - 1U)
|
||
|
|
#define PLL0R (2U - 1U)
|
||
|
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_600M_PLL0_IRC64M;
|
||
|
|
static void system_clock_600m_irc64m(void);
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_LPIRC4M)
|
||
|
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_LPIRC4M;
|
||
|
|
static void system_clock_4m_lpirc4m(void);
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_HXTAL)
|
||
|
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_HXTAL;
|
||
|
|
static void system_clock_hxtal(void);
|
||
|
|
#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL)
|
||
|
|
#define PLL0PSC 5U
|
||
|
|
#define PLL0N (40U - 1U)
|
||
|
|
#define PLL0P (1U - 1U)
|
||
|
|
#define PLL0Q (2U - 1U)
|
||
|
|
#define PLL0R (2U - 1U)
|
||
|
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_200M_PLL0_HXTAL;
|
||
|
|
static void system_clock_200m_hxtal(void);
|
||
|
|
#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL)
|
||
|
|
#define PLL0PSC 5U
|
||
|
|
#define PLL0N (80U - 1U)
|
||
|
|
#define PLL0P (1U - 1U)
|
||
|
|
#define PLL0Q (2U - 1U)
|
||
|
|
#define PLL0R (2U - 1U)
|
||
|
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_400M_PLL0_HXTAL;
|
||
|
|
static void system_clock_400m_hxtal(void);
|
||
|
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_HXTAL)
|
||
|
|
#define PLL0PSC 5U
|
||
|
|
#define PLL0N (96U - 1U)
|
||
|
|
#define PLL0P (1U - 1U)
|
||
|
|
#define PLL0Q (2U - 1U)
|
||
|
|
#define PLL0R (2U - 1U)
|
||
|
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_480M_PLL0_HXTAL;
|
||
|
|
static void system_clock_480m_hxtal(void);
|
||
|
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL)
|
||
|
|
#define PLL0PSC 5U
|
||
|
|
#define PLL0N (120U - 1U)
|
||
|
|
#define PLL0P (1U - 1U)
|
||
|
|
#define PLL0Q (2U - 1U)
|
||
|
|
#define PLL0R (2U - 1U)
|
||
|
|
uint32_t SystemCoreClock = __SYSTEM_CLOCK_600M_PLL0_HXTAL;
|
||
|
|
static void system_clock_600m_hxtal(void);
|
||
|
|
#endif /* __SYSTEM_CLOCK_IRC64M */
|
||
|
|
|
||
|
|
/* configure the system clock */
|
||
|
|
static void system_clock_config(void);
|
||
|
|
|
||
|
|
/*!
|
||
|
|
\brief setup the microcontroller system, initialize the system
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval none
|
||
|
|
*/
|
||
|
|
void SystemInit(void)
|
||
|
|
{
|
||
|
|
/* FPU settings */
|
||
|
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1U)
|
||
|
|
/* set CP10 and CP11 Full Access */
|
||
|
|
SCB->CPACR |= (uint32_t)((0x03U << 10U * 2U) | (0x03U << 11U * 2U));
|
||
|
|
#endif
|
||
|
|
/* enable IRC64M */
|
||
|
|
RCU_CTL |= RCU_CTL_IRC64MEN;
|
||
|
|
while(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/* no TCM wait state */
|
||
|
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
|
||
|
|
SYSCFG_SRAMCFG1 &= ~SYSCFG_SRAMCFG1_TCM_WAITSTATE;
|
||
|
|
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
|
||
|
|
/* reset RCU */
|
||
|
|
/* reset HXTALEN, CKMEN, PLL0EN, PLL1EN, PLL2EN, PLLUSB0 and PLLUSB1 bits */
|
||
|
|
RCU_CTL &= ~(RCU_CTL_HXTALEN | RCU_CTL_CKMEN | RCU_CTL_PLL0EN | RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_HXTALBPS);
|
||
|
|
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_PLLUSBHS0EN | RCU_ADDCTL1_PLLUSBHS1EN | RCU_ADDCTL1_LPIRC4MEN);
|
||
|
|
/* reset CFG0, CFG1, CFG2, CFG3 registers */
|
||
|
|
RCU_CFG0 &= ~(RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC | RCU_CFG0_APB3PSC | RCU_CFG0_APB4PSC | RCU_CFG0_AHBPSC |
|
||
|
|
RCU_CFG0_I2C0SEL | RCU_CFG0_SCS | RCU_CFG0_RTCDIV);
|
||
|
|
RCU_CFG1 &= ~(RCU_CFG1_HPDFSEL | RCU_CFG1_TIMERSEL | RCU_CFG1_PERSEL |
|
||
|
|
RCU_CFG1_USART0SEL | RCU_CFG1_USART1SEL | RCU_CFG1_USART2SEL | RCU_CFG1_USART5SEL | RCU_CFG1_PLL2RDIV);
|
||
|
|
RCU_CFG2 &= ~(RCU_CFG2_HPDFASEL | RCU_CFG2_CKOUT0SEL | RCU_CFG2_CKOUT1SEL | RCU_CFG2_CKOUT0DIV | RCU_CFG2_CKOUT1DIV);
|
||
|
|
RCU_CFG3 &= ~(RCU_CFG3_ADC01SEL | RCU_CFG3_ADC2SEL
|
||
|
|
| RCU_CFG3_I2C3SEL | RCU_CFG3_I2C2SEL | RCU_CFG3_I2C1SEL);
|
||
|
|
RCU_CFG4 &= ~(RCU_CFG4_EXMCSEL);
|
||
|
|
RCU_CFG5 &= ~(RCU_CFG5_SPI0SEL | RCU_CFG5_SPI1SEL | RCU_CFG5_SPI2SEL |
|
||
|
|
RCU_CFG5_SPI3SEL | RCU_CFG5_SPI4SEL | RCU_CFG5_SPI5SEL);
|
||
|
|
/* disable all interrupts */
|
||
|
|
RCU_INT = 0x14FF0000U;
|
||
|
|
RCU_ADDINT = 0x00700000U;
|
||
|
|
/* reset all PLL0 parameter */
|
||
|
|
RCU_PLL0 = 0x01002020U;
|
||
|
|
RCU_PLL1 = 0x01012020U;
|
||
|
|
RCU_PLL2 = 0x01012020U;
|
||
|
|
RCU_PLLALL = 0x00000000U;
|
||
|
|
RCU_PLLADDCTL = 0x00010101U;
|
||
|
|
RCU_PLLUSBCFG = 0x00000000U;
|
||
|
|
RCU_PLL0FRA = 0x00000000U;
|
||
|
|
RCU_PLL1FRA = 0x00000000U;
|
||
|
|
RCU_PLL2FRA = 0x00000000U;
|
||
|
|
|
||
|
|
#if defined (SEL_PMU_SMPS_MODE)
|
||
|
|
/* power supply config */
|
||
|
|
pmu_smps_ldo_supply_config(SEL_PMU_SMPS_MODE);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* configure system clock */
|
||
|
|
system_clock_config();
|
||
|
|
|
||
|
|
#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_IRC64M
|
||
|
|
system_clock_64m_irc64m();
|
||
|
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_IRC64M)
|
||
|
|
system_clock_480m_irc64m();
|
||
|
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M)
|
||
|
|
system_clock_600m_irc64m();
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_LPIRC4M)
|
||
|
|
system_clock_4m_lpirc4m();
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_HXTAL)
|
||
|
|
system_clock_hxtal();
|
||
|
|
#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL)
|
||
|
|
system_clock_200m_hxtal();
|
||
|
|
#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL)
|
||
|
|
system_clock_400m_hxtal();
|
||
|
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_HXTAL)
|
||
|
|
system_clock_480m_hxtal();
|
||
|
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL)
|
||
|
|
system_clock_600m_hxtal();
|
||
|
|
#endif /* __SYSTEM_CLOCK_IRC64M */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef __SYSTEM_CLOCK_IRC64M
|
||
|
|
/*!
|
||
|
|
\brief configure the system clock to 64M by IRC64M
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval none
|
||
|
|
*/
|
||
|
|
static void system_clock_64m_irc64m(void)
|
||
|
|
{
|
||
|
|
uint32_t timeout = 0U;
|
||
|
|
uint32_t stab_flag = 0U;
|
||
|
|
|
||
|
|
/* enable IRC64M */
|
||
|
|
RCU_CTL |= RCU_CTL_IRC64MEN;
|
||
|
|
|
||
|
|
/* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */
|
||
|
|
do {
|
||
|
|
timeout++;
|
||
|
|
stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB);
|
||
|
|
} while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout));
|
||
|
|
|
||
|
|
/* if fail */
|
||
|
|
if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) {
|
||
|
|
while(1) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* AHB = SYSCLK / 1 */
|
||
|
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
|
||
|
|
/* APB4 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV1;
|
||
|
|
/* APB3 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV1;
|
||
|
|
/* APB2 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
|
|
/* APB1 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
|
||
|
|
|
||
|
|
/* configure IRC64M div */
|
||
|
|
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV);
|
||
|
|
RCU_ADDCTL1 |= RCU_IRC64M_DIV1;
|
||
|
|
|
||
|
|
/* select IRC64M as system clock */
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
RCU_CFG0 |= RCU_CKSYSSRC_IRC64MDIV;
|
||
|
|
|
||
|
|
/* wait until IRC64M is selected as system clock */
|
||
|
|
while(RCU_SCSS_IRC64MDIV != (RCU_CFG0 & RCU_CFG0_SCSS)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_IRC64M)
|
||
|
|
/*!
|
||
|
|
\brief configure the system clock to 480M by PLL0 which selects IRC64M as its clock source
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval none
|
||
|
|
*/
|
||
|
|
static void system_clock_480m_irc64m(void)
|
||
|
|
{
|
||
|
|
uint32_t timeout = 0U;
|
||
|
|
uint32_t stab_flag = 0U;
|
||
|
|
|
||
|
|
/* enable IRC64M */
|
||
|
|
RCU_CTL |= RCU_CTL_IRC64MEN;
|
||
|
|
|
||
|
|
/* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */
|
||
|
|
do {
|
||
|
|
timeout++;
|
||
|
|
stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB);
|
||
|
|
} while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout));
|
||
|
|
|
||
|
|
/* if fail */
|
||
|
|
if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) {
|
||
|
|
while(1) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* insert TCM wait state at 480MHz */
|
||
|
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
|
||
|
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
|
||
|
|
|
||
|
|
/* IRC64M is already stable */
|
||
|
|
/* AHB = SYSCLK / 2 */
|
||
|
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
|
||
|
|
/* APB4 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
|
||
|
|
/* APB3 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
|
||
|
|
/* APB2 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
|
|
/* APB1 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
|
|
||
|
|
/* PLL0 select IRC64MDIV, config IRC64MDIV as IRC64M, PLL0 input and output range */
|
||
|
|
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV);
|
||
|
|
RCU_ADDCTL1 |= RCU_IRC64M_DIV1;
|
||
|
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
|
||
|
|
RCU_PLLALL |= (RCU_PLLSRC_IRC64MDIV | RCU_PLL0RNG_4M_8M);
|
||
|
|
|
||
|
|
/* PLL0P = IRC64MDIV / 16 * 120 / 1 = 480 MHz */
|
||
|
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
|
||
|
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
|
||
|
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
|
||
|
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
|
||
|
|
|
||
|
|
/* enable PLL0P, PLL0Q, PLL0R */
|
||
|
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
|
||
|
|
|
||
|
|
/* enable PLL0 */
|
||
|
|
RCU_CTL |= RCU_CTL_PLL0EN;
|
||
|
|
|
||
|
|
/* wait until PLL0 is stable */
|
||
|
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/* select PLL0 as system clock */
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
|
||
|
|
|
||
|
|
/* wait until PLL0 is selected as system clock */
|
||
|
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_IRC64M)
|
||
|
|
/*!
|
||
|
|
\brief configure the system clock to 600M by PLL0 which selects IRC64M as its clock source
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval none
|
||
|
|
*/
|
||
|
|
static void system_clock_600m_irc64m(void)
|
||
|
|
{
|
||
|
|
uint32_t timeout = 0U;
|
||
|
|
uint32_t stab_flag = 0U;
|
||
|
|
|
||
|
|
/* enable IRC64M */
|
||
|
|
RCU_CTL |= RCU_CTL_IRC64MEN;
|
||
|
|
|
||
|
|
/* wait until IRC64M is stable or the startup time is longer than IRC64M_STARTUP_TIMEOUT */
|
||
|
|
do {
|
||
|
|
timeout++;
|
||
|
|
stab_flag = (RCU_CTL & RCU_CTL_IRC64MSTB);
|
||
|
|
} while((0U == stab_flag) && (IRC64M_STARTUP_TIMEOUT != timeout));
|
||
|
|
|
||
|
|
/* if fail */
|
||
|
|
if(0U == (RCU_CTL & RCU_CTL_IRC64MSTB)) {
|
||
|
|
while(1) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* insert TCM wait state at 600MHz */
|
||
|
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
|
||
|
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
|
||
|
|
|
||
|
|
/* IRC64M is already stable */
|
||
|
|
/* AHB = SYSCLK / 2 */
|
||
|
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
|
||
|
|
/* APB4 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
|
||
|
|
/* APB3 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
|
||
|
|
/* APB2 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
|
|
/* APB1 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
|
|
||
|
|
/* PLL0 select IRC64MDIV, config IRC64MDIV as IRC64M, PLL0 input and output range */
|
||
|
|
RCU_ADDCTL1 &= ~(RCU_ADDCTL1_IRC64MDIV);
|
||
|
|
RCU_ADDCTL1 |= RCU_IRC64M_DIV1;
|
||
|
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
|
||
|
|
RCU_PLLALL |= (RCU_PLLSRC_IRC64MDIV | RCU_PLL0RNG_4M_8M);
|
||
|
|
|
||
|
|
/* PLL0P = IRC64MDIV / 16 * 150 / 1 = 600 MHz */
|
||
|
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
|
||
|
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
|
||
|
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
|
||
|
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
|
||
|
|
|
||
|
|
/* enable PLL0P, PLL0Q, PLL0R */
|
||
|
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
|
||
|
|
|
||
|
|
/* enable PLL0 */
|
||
|
|
RCU_CTL |= RCU_CTL_PLL0EN;
|
||
|
|
|
||
|
|
/* wait until PLL0 is stable */
|
||
|
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/* select PLL0 as system clock */
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
|
||
|
|
|
||
|
|
/* wait until PLL0 is selected as system clock */
|
||
|
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_LPIRC4M)
|
||
|
|
/*!
|
||
|
|
\brief configure the system clock to LPIRC4M
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval none
|
||
|
|
*/
|
||
|
|
static void system_clock_4m_lpirc4m(void)
|
||
|
|
{
|
||
|
|
uint32_t timeout = 0U;
|
||
|
|
uint32_t stab_flag = 0U;
|
||
|
|
|
||
|
|
/* enable LPIRC4M */
|
||
|
|
RCU_ADDCTL1 |= RCU_ADDCTL1_LPIRC4MEN;
|
||
|
|
|
||
|
|
/* wait until LPIRC4M is stable or the startup time is longer than LPIRC4M_STARTUP_TIMEOUT */
|
||
|
|
do {
|
||
|
|
timeout++;
|
||
|
|
stab_flag = (RCU_ADDCTL1 & RCU_ADDCTL1_LPIRC4MSTB);
|
||
|
|
} while((0U == stab_flag) && (LPIRC4M_STARTUP_TIMEOUT != timeout));
|
||
|
|
/* if fail */
|
||
|
|
if(0U == (RCU_ADDCTL1 & RCU_ADDCTL1_LPIRC4MSTB)) {
|
||
|
|
while(1) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* LPIRC4M is stable */
|
||
|
|
/* AHB = SYSCLK / 1*/
|
||
|
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
|
||
|
|
/* APB4 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV1;
|
||
|
|
/* APB3 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV1;
|
||
|
|
/* APB2 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
|
|
/* APB1 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
|
||
|
|
|
||
|
|
/* select LPIRC4M as system clock */
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
RCU_CFG0 |= RCU_CKSYSSRC_LPIRC4M;
|
||
|
|
|
||
|
|
/* wait until LPIRC4M is selected as system clock */
|
||
|
|
while(RCU_SCSS_LPIRC4M != (RCU_CFG0 & RCU_CFG0_SCSS)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#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;
|
||
|
|
|
||
|
|
/* enable HXTAL */
|
||
|
|
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
|
|
|
||
|
|
/* 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)) {
|
||
|
|
while(1) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* HXTAL is stable */
|
||
|
|
/* AHB = SYSCLK / 1*/
|
||
|
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
|
||
|
|
/* APB4 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV1;
|
||
|
|
/* APB3 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV1;
|
||
|
|
/* APB2 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
|
|
/* APB1 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV1;
|
||
|
|
|
||
|
|
/* select HXTAL as system clock */
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
RCU_CFG0 |= RCU_CKSYSSRC_HXTAL;
|
||
|
|
|
||
|
|
/* wait until HXTAL is selected as system clock */
|
||
|
|
while(RCU_SCSS_HXTAL != (RCU_CFG0 & RCU_CFG0_SCSS)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_200M_PLL0_HXTAL)
|
||
|
|
/*!
|
||
|
|
\brief configure the system clock to 200M by PLL0 which selects HXTAL as its clock source
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval none
|
||
|
|
*/
|
||
|
|
static void system_clock_200m_hxtal(void)
|
||
|
|
{
|
||
|
|
uint32_t timeout = 0U;
|
||
|
|
uint32_t stab_flag = 0U;
|
||
|
|
|
||
|
|
/* enable HXTAL */
|
||
|
|
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
|
|
|
||
|
|
/* 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)) {
|
||
|
|
while(1) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* HXTAL is stable */
|
||
|
|
/* AHB = SYSCLK / 1 */
|
||
|
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
|
||
|
|
/* APB4 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
|
||
|
|
/* APB3 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
|
||
|
|
/* APB2 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
|
|
/* APB1 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
|
|
||
|
|
/* PLL0 select HXTAL, configure PLL0 input and output range */
|
||
|
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
|
||
|
|
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLLALL_PLL0VCOSEL | RCU_PLL0RNG_4M_8M);
|
||
|
|
|
||
|
|
/* PLL0P = HXTAL / 5 * 40 = 200 MHz */
|
||
|
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
|
||
|
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
|
||
|
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
|
||
|
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
|
||
|
|
|
||
|
|
/* enable PLL0P, PLL0Q, PLL0R */
|
||
|
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
|
||
|
|
|
||
|
|
/* enable PLL0 */
|
||
|
|
RCU_CTL |= RCU_CTL_PLL0EN;
|
||
|
|
|
||
|
|
/* wait until PLL0 is stable */
|
||
|
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/* select PLL0 as system clock */
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
|
||
|
|
|
||
|
|
/* wait until PLL0 is selected as system clock */
|
||
|
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_400M_PLL0_HXTAL)
|
||
|
|
/*!
|
||
|
|
\brief configure the system clock to 400M by PLL0 which selects HXTAL as its clock source
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval none
|
||
|
|
*/
|
||
|
|
static void system_clock_400m_hxtal(void)
|
||
|
|
{
|
||
|
|
uint32_t timeout = 0U;
|
||
|
|
uint32_t stab_flag = 0U;
|
||
|
|
|
||
|
|
/* enable HXTAL */
|
||
|
|
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
|
|
|
||
|
|
/* 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)) {
|
||
|
|
while(1) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* insert TCM wait state at 400MHz */
|
||
|
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
|
||
|
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
|
||
|
|
|
||
|
|
/* HXTAL is stable */
|
||
|
|
/* AHB = SYSCLK / 1 */
|
||
|
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
|
||
|
|
/* APB4 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
|
||
|
|
/* APB3 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
|
||
|
|
/* APB2 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
|
|
/* APB1 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
|
|
||
|
|
/* PLL0 select HXTAL, configure PLL0 input and output range */
|
||
|
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
|
||
|
|
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLLALL_PLL0VCOSEL | RCU_PLL0RNG_4M_8M);
|
||
|
|
|
||
|
|
/* PLL0P = HXTAL / 5 * 80 = 400 MHz */
|
||
|
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
|
||
|
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
|
||
|
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
|
||
|
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
|
||
|
|
|
||
|
|
/* enable PLL0P, PLL0Q, PLL0R */
|
||
|
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
|
||
|
|
|
||
|
|
/* enable PLL */
|
||
|
|
RCU_CTL |= RCU_CTL_PLL0EN;
|
||
|
|
|
||
|
|
/* wait until PLL0 is stable */
|
||
|
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/* select PLL0 as system clock */
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
|
||
|
|
|
||
|
|
/* wait until PLL0 is selected as system clock */
|
||
|
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_480M_PLL0_HXTAL)
|
||
|
|
/*!
|
||
|
|
\brief configure the system clock to 480M by PLL0 which selects HXTAL as its clock source
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval none
|
||
|
|
*/
|
||
|
|
static void system_clock_480m_hxtal(void)
|
||
|
|
{
|
||
|
|
uint32_t timeout = 0U;
|
||
|
|
uint32_t stab_flag = 0U;
|
||
|
|
|
||
|
|
/* enable HXTAL */
|
||
|
|
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
|
|
|
||
|
|
/* 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)) {
|
||
|
|
while(1) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* insert TCM wait state at 480MHz */
|
||
|
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
|
||
|
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
|
||
|
|
|
||
|
|
/* HXTAL is stable */
|
||
|
|
/* AHB = SYSCLK / 2 */
|
||
|
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
|
||
|
|
/* APB4 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
|
||
|
|
/* APB3 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
|
||
|
|
/* APB2 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
|
|
/* APB1 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
|
|
||
|
|
/* PLL select HXTAL, configure PLL input and output range */
|
||
|
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
|
||
|
|
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLL0RNG_4M_8M);
|
||
|
|
|
||
|
|
/* PLL0P = HXTAL / 5 * 96 = 480 MHz */
|
||
|
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
|
||
|
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
|
||
|
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
|
||
|
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
|
||
|
|
|
||
|
|
/* enable PLL0P, PLL0Q, PLL0R */
|
||
|
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
|
||
|
|
|
||
|
|
/* enable PLL0 */
|
||
|
|
RCU_CTL |= RCU_CTL_PLL0EN;
|
||
|
|
|
||
|
|
/* wait until PLL0 is stable */
|
||
|
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/* select PLL0 as system clock */
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
|
||
|
|
|
||
|
|
/* wait until PLL0 is selected as system clock */
|
||
|
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#elif defined (__SYSTEM_CLOCK_600M_PLL0_HXTAL)
|
||
|
|
/*!
|
||
|
|
\brief configure the system clock to 600M by PLL0 which selects HXTAL as its clock source
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval none
|
||
|
|
*/
|
||
|
|
static void system_clock_600m_hxtal(void)
|
||
|
|
{
|
||
|
|
uint32_t timeout = 0U;
|
||
|
|
uint32_t stab_flag = 0U;
|
||
|
|
|
||
|
|
/* enable HXTAL */
|
||
|
|
RCU_CTL |= RCU_CTL_HXTALEN;
|
||
|
|
|
||
|
|
/* 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)) {
|
||
|
|
while(1) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* insert TCM wait state at 600MHz */
|
||
|
|
RCU_APB4EN |= RCU_APB4EN_SYSCFG;
|
||
|
|
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
|
||
|
|
|
||
|
|
/* HXTAL is stable */
|
||
|
|
/* AHB = SYSCLK / 2 */
|
||
|
|
RCU_CFG0 |= RCU_AHB_CKSYS_DIV2;
|
||
|
|
/* APB4 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB4_CKAHB_DIV2;
|
||
|
|
/* APB3 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB3_CKAHB_DIV2;
|
||
|
|
/* APB2 = AHB / 1 */
|
||
|
|
RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
|
||
|
|
/* APB1 = AHB / 2 */
|
||
|
|
RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
|
||
|
|
|
||
|
|
/* PLL select HXTAL, configure PLL input and output range */
|
||
|
|
RCU_PLLALL &= ~(RCU_PLLALL_PLLSEL | RCU_PLLALL_PLL0VCOSEL | RCU_PLLALL_PLL0RNG);
|
||
|
|
RCU_PLLALL |= (RCU_PLLSRC_HXTAL | RCU_PLL0RNG_4M_8M);
|
||
|
|
|
||
|
|
/* PLL0P = HXTAL / 5 * 120 = 600 MHz */
|
||
|
|
RCU_PLL0 &= ~(RCU_PLL0_PLL0N | RCU_PLL0_PLL0PSC | RCU_PLL0_PLL0P | RCU_PLL0_PLL0R | RCU_PLL0_PLLSTBSRC);
|
||
|
|
RCU_PLL0 |= ((PLL0N << PLL0N_REG_OFFSET) | (PLL0PSC << PLL0PSC_REG_OFFSET) | (PLL0P << PLL0P_REG_OFFSET) | (PLL0R << PLL0R_REG_OFFSET));
|
||
|
|
RCU_PLLADDCTL &= ~(RCU_PLLADDCTL_PLL0Q);
|
||
|
|
RCU_PLLADDCTL |= (PLL0Q << PLL0Q_REG_OFFSET);
|
||
|
|
|
||
|
|
/* enable PLL0P, PLL0Q, PLL0R */
|
||
|
|
RCU_PLLADDCTL |= RCU_PLLADDCTL_PLL0PEN | RCU_PLLADDCTL_PLL0QEN | RCU_PLLADDCTL_PLL0REN;
|
||
|
|
|
||
|
|
/* enable PLL0 */
|
||
|
|
RCU_CTL |= RCU_CTL_PLL0EN;
|
||
|
|
|
||
|
|
/* wait until PLL0 is stable */
|
||
|
|
while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/* select PLL0 as system clock */
|
||
|
|
RCU_CFG0 &= ~RCU_CFG0_SCS;
|
||
|
|
RCU_CFG0 |= RCU_CKSYSSRC_PLL0P;
|
||
|
|
|
||
|
|
/* wait until PLL0 is selected as system clock */
|
||
|
|
while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif /* __SYSTEM_CLOCK_IRC64M */
|
||
|
|
|
||
|
|
/*!
|
||
|
|
\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 = 0U;
|
||
|
|
uint32_t irc64div = 0U;
|
||
|
|
uint32_t pllpsc = 0U, plln = 0U, pllp = 0U, pllsel = 0U;
|
||
|
|
|
||
|
|
sws = GET_BITS(RCU_CFG0, 2, 3);
|
||
|
|
switch(sws) {
|
||
|
|
/* IRC64M is selected as CK_SYS */
|
||
|
|
case SEL_IRC64MDIV:
|
||
|
|
irc64div = (1U << GET_BITS(RCU_ADDCTL1, 16, 17));
|
||
|
|
SystemCoreClock = IRC64M_VALUE / irc64div;
|
||
|
|
break;
|
||
|
|
/* HXTAL is selected as CK_SYS */
|
||
|
|
case SEL_LPIRC4M:
|
||
|
|
SystemCoreClock = LPIRC4M_VALUE;
|
||
|
|
break;
|
||
|
|
/* HXTAL is selected as CK_SYS */
|
||
|
|
case SEL_HXTAL:
|
||
|
|
SystemCoreClock = HXTAL_VALUE;
|
||
|
|
break;
|
||
|
|
/* PLL0P is selected as CK_SYS */
|
||
|
|
case SEL_PLL0P:
|
||
|
|
/* get the value of PLL0PSC[0,5], PLL0N[6,14], PLL0P[16,22] */
|
||
|
|
pllpsc = GET_BITS(RCU_PLL0, 0, 5);
|
||
|
|
plln = GET_BITS(RCU_PLL0, 6, 14) + 1U;
|
||
|
|
pllp = GET_BITS(RCU_PLL0, 16, 22) + 1U;
|
||
|
|
|
||
|
|
/* PLL clock source selection, HXTAL or IRC64M_VALUE or LPIRC4M_VALUE */
|
||
|
|
pllsel = GET_BITS(RCU_PLLALL, 16, 17);
|
||
|
|
if(0U == pllsel) {
|
||
|
|
irc64div = (1U << GET_BITS(RCU_ADDCTL1, 16, 17));
|
||
|
|
SystemCoreClock = (IRC64M_VALUE / irc64div / pllpsc) * plln / pllp;
|
||
|
|
} else if(1U == pllsel) {
|
||
|
|
SystemCoreClock = (LPIRC4M_VALUE / pllpsc) * plln / pllp;
|
||
|
|
} else {
|
||
|
|
SystemCoreClock = (HXTAL_VALUE / pllpsc) * plln / pllp;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
/* should not be here */
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifdef __FIRMWARE_VERSION_DEFINE
|
||
|
|
/*!
|
||
|
|
\brief get firmware version
|
||
|
|
\param[in] none
|
||
|
|
\param[out] none
|
||
|
|
\retval firmware version
|
||
|
|
*/
|
||
|
|
uint32_t gd32h75e_firmware_version_get(void)
|
||
|
|
{
|
||
|
|
return __GD32H75E_STDPERIPH_VERSION;
|
||
|
|
}
|
||
|
|
#endif /* __FIRMWARE_VERSION_DEFINE */
|