/********************************************************************************************************************* * @file system_XMC4700.c * @brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File for the Infineon XMC4700 Device Series * @version V1.0.3 * @date 09. Feb 2017 * * @cond ********************************************************************************************************************* * Copyright (c) 2015-2017, Infineon Technologies AG * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the * following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following * disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided with the distribution. * * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with * Infineon Technologies AG dave@infineon.com). ********************************************************************************************************************* * ********************** Version History *************************************** * V1.0.0, 03. Sep 2015, Initial version * V1.0.1, 26. Jan 2016, Disable trap generation from clock unit * V1.0.2, 01. Jun 2016, Fix masking of OSCHPCTRL value * V1.0.3, 09. Feb 2017, Fix activation of USBPLL when SDMMC clock is enabled ****************************************************************************** * @endcond */ /******************************************************************************* * Default clock initialization * fPLL = 288MHz => fSYS = 144MHz => fCPU = 144MHz * => fPB = 144MHz * => fCCU = 144MHz * => fETH = 72MHz * => fUSB = 48MHz * => fEBU = 72MHz * * fUSBPLL Disabled, only enabled if SCU_CLK_USBCLKCR_USBSEL_USBPLL is selected * * fOFI = 24MHz => fWDT = 24MHz *******************************************************************************/ /******************************************************************************* * HEADER FILES *******************************************************************************/ #include #include #include "system_XMC4700.h" /******************************************************************************* * MACROS *******************************************************************************/ #define CHIPID_LOC ((uint8_t *)0x20000000UL) /* Define WEAK attribute */ #if !defined(__WEAK) #if defined ( __CC_ARM ) #define __WEAK __attribute__ ((weak)) #elif defined ( __ICCARM__ ) #define __WEAK __weak #elif defined ( __GNUC__ ) #define __WEAK __attribute__ ((weak)) #elif defined ( __TASKING__ ) #define __WEAK __attribute__ ((weak)) #endif #endif #define PMU_FLASH_WS (0x4U) #define FOSCREF (2500000U) #define DELAY_CNT_50US_50MHZ (2500UL) #define DELAY_CNT_150US_50MHZ (7500UL) #define DELAY_CNT_50US_48MHZ (2400UL) #define DELAY_CNT_50US_72MHZ (3600UL) #define DELAY_CNT_50US_96MHZ (4800UL) #define DELAY_CNT_50US_120MHZ (6000UL) #define DELAY_CNT_50US_144MHZ (7200UL) #define SCU_PLL_PLLSTAT_OSC_USABLE (SCU_PLL_PLLSTAT_PLLHV_Msk | \ SCU_PLL_PLLSTAT_PLLLV_Msk | \ SCU_PLL_PLLSTAT_PLLSP_Msk) /* //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ */ /* // Clock configuration */ /* // External crystal frequency [Hz] // <8000000=> 8MHz // <12000000=> 12MHz // <16000000=> 16MHz // Defines external crystal frequency // Default: 8MHz */ #define OSCHP_FREQUENCY (12000000U) /* USB PLL settings, fUSBPLL = 48MHz and fUSBPLLVCO = 384 MHz */ /* Note: Implicit divider of 2 and fUSBPLLVCO >= 260 MHz and fUSBPLLVCO <= 520 MHz*/ #if OSCHP_FREQUENCY == 8000000U #define USB_PDIV (1U) #define USB_NDIV (95U) #elif OSCHP_FREQUENCY == 12000000U #define USB_PDIV (1U) #define USB_NDIV (63U) #elif OSCHP_FREQUENCY == 16000000U #define USB_PDIV (1U) #define USB_NDIV (47U) #else #error "External crystal frequency not supported" #endif /* // Backup clock calibration mode // <0=> Factory calibration // <1=> Automatic calibration // Default: Automatic calibration */ #define FOFI_CALIBRATION_MODE 1 #define FOFI_CALIBRATION_MODE_FACTORY 0 #define FOFI_CALIBRATION_MODE_AUTOMATIC 1 /* // Standby clock (fSTDBY) source selection // <0=> Internal slow oscillator (32768Hz) // <1=> External crystal (32768Hz) // Default: Internal slow oscillator (32768Hz) */ #define STDBY_CLOCK_SRC 0 #define STDBY_CLOCK_SRC_OSI 0 #define STDBY_CLOCK_SRC_OSCULP 1 /* // PLL clock source selection // <0=> External crystal // <1=> Internal fast oscillator // Default: External crystal */ #define PLL_CLOCK_SRC 0 #define PLL_CLOCK_SRC_EXT_XTAL 0 #define PLL_CLOCK_SRC_OFI 1 /* PLL settings, fPLL = 288MHz */ #if PLL_CLOCK_SRC == PLL_CLOCK_SRC_EXT_XTAL #if OSCHP_FREQUENCY == 8000000U #define PLL_PDIV (1U) #define PLL_NDIV (71U) #define PLL_K2DIV (0U) #elif OSCHP_FREQUENCY == 12000000U #define PLL_PDIV (1U) #define PLL_NDIV (47U) #define PLL_K2DIV (0U) #elif OSCHP_FREQUENCY == 16000000U #define PLL_PDIV (1U) #define PLL_NDIV (35U) #define PLL_K2DIV (0U) #else #error "External crystal frequency not supported" #endif #define VCO ((OSCHP_FREQUENCY / (PLL_PDIV + 1UL)) * (PLL_NDIV + 1UL)) #else /* PLL_CLOCK_SRC == PLL_CLOCK_SRC_EXT_XTAL */ #define PLL_PDIV (1U) #define PLL_NDIV (23U) #define PLL_K2DIV (0U) #define VCO ((OFI_FREQUENCY / (PLL_PDIV + 1UL)) * (PLL_NDIV + 1UL)) #endif /* PLL_CLOCK_SRC == PLL_CLOCK_SRC_OFI */ #define PLL_K2DIV_24MHZ ((VCO / OFI_FREQUENCY) - 1UL) #define PLL_K2DIV_48MHZ ((VCO / 48000000U) - 1UL) #define PLL_K2DIV_72MHZ ((VCO / 72000000U) - 1UL) #define PLL_K2DIV_96MHZ ((VCO / 96000000U) - 1UL) #define PLL_K2DIV_120MHZ ((VCO / 120000000U) - 1UL) #define SCU_CLK_CLKCLR_ENABLE_USBCLK SCU_CLK_CLKCLR_USBCDI_Msk #define SCU_CLK_CLKCLR_ENABLE_MMCCLK SCU_CLK_CLKCLR_MMCCDI_Msk #define SCU_CLK_CLKCLR_ENABLE_ETHCLK SCU_CLK_CLKCLR_ETH0CDI_Msk #define SCU_CLK_CLKCLR_ENABLE_EBUCLK SCU_CLK_CLKCLR_EBUCDI_Msk #define SCU_CLK_CLKCLR_ENABLE_CCUCLK SCU_CLK_CLKCLR_CCUCDI_Msk #define SCU_CLK_CLKCLR_ENABLE_WDTCLK SCU_CLK_CLKCLR_WDTCDI_Msk #define SCU_CLK_SYSCLKCR_SYSSEL_OFI (0U << SCU_CLK_SYSCLKCR_SYSSEL_Pos) #define SCU_CLK_SYSCLKCR_SYSSEL_PLL (1U << SCU_CLK_SYSCLKCR_SYSSEL_Pos) #define SCU_CLK_USBCLKCR_USBSEL_USBPLL (0U << SCU_CLK_USBCLKCR_USBSEL_Pos) #define SCU_CLK_USBCLKCR_USBSEL_PLL (1U << SCU_CLK_USBCLKCR_USBSEL_Pos) #define SCU_CLK_WDTCLKCR_WDTSEL_OFI (0U << SCU_CLK_WDTCLKCR_WDTSEL_Pos) #define SCU_CLK_WDTCLKCR_WDTSEL_STANDBY (1U << SCU_CLK_WDTCLKCR_WDTSEL_Pos) #define SCU_CLK_WDTCLKCR_WDTSEL_PLL (2U << SCU_CLK_WDTCLKCR_WDTSEL_Pos) #define SCU_CLK_EXTCLKCR_ECKSEL_SYS (0U << SCU_CLK_EXTCLKCR_ECKSEL_Pos) #define SCU_CLK_EXTCLKCR_ECKSEL_USBPLL (2U << SCU_CLK_EXTCLKCR_ECKSEL_Pos) #define SCU_CLK_EXTCLKCR_ECKSEL_PLL (3U << SCU_CLK_EXTCLKCR_ECKSEL_Pos) #define EXTCLK_PIN_P0_8 (1) #define EXTCLK_PIN_P1_15 (2) /* // Clock tree // System clock source selection // <0=> fOFI // <1=> fPLL // Default: fPLL // System clock divider <1-256><#-1> // Default: 2 // CPU clock divider // <0=> fCPU = fSYS // <1=> fCPU = fSYS / 2 // Default: fCPU = fSYS // Peripheral clock divider // <0=> fPB = fCPU // <1=> fPB = fCPU / 2 // Default: fPB = fCPU // CCU clock divider // <0=> fCCU = fCPU // <1=> fCCU = fCPU / 2 // Default: fCCU = fCPU // Enable WDT clock // WDT clock source <0=> fOFI // <1=> fSTDBY // <2=> fPLL // Default: fOFI // WDT clock divider <1-256><#-1> // Default: 1 // // Enable EBU clock // EBU clock divider <1-64><#-1> // Default: 4 // // Enable ETH clock // // Enable MMC clock // // Enable USB clock // USB clock source <0=> fUSBPLL // <1=> fPLL // Default: fPLL // // Enable external clock // External Clock Source Selection // <0=> fSYS // <2=> fUSB // <3=> fPLL // Default: fPLL // External Clock divider <1-512><#-1> // Default: 288 // Only valid for USB PLL and PLL clocks // External Clock Pin Selection // <0=> Disabled // <1=> P0.8 // <2=> P1.15 // Default: Disabled // // */ #define __CLKSET (0x00000000UL) #define __SYSCLKCR (0x00010001UL) #define __CPUCLKCR (0x00000000UL) #define __PBCLKCR (0x00000000UL) #define __CCUCLKCR (0x00000000UL) #define __WDTCLKCR (0x00000000UL) #define __EBUCLKCR (0x00000003UL) #define __USBCLKCR (0x00010000UL) #define __EXTCLKCR (0x01200003UL) #define __EXTCLKPIN (0U) /* // */ /* //-------- <<< end of configuration section >>> ------------------ */ #define ENABLE_PLL \ (((__SYSCLKCR & SCU_CLK_SYSCLKCR_SYSSEL_Msk) == SCU_CLK_SYSCLKCR_SYSSEL_PLL) || \ ((__CLKSET & SCU_CLK_CLKSET_EBUCEN_Msk) != 0) || \ (((__CLKSET & SCU_CLK_CLKSET_USBCEN_Msk) != 0) && ((__USBCLKCR & SCU_CLK_USBCLKCR_USBSEL_Msk) == SCU_CLK_USBCLKCR_USBSEL_PLL)) || \ (((__CLKSET & SCU_CLK_CLKSET_WDTCEN_Msk) != 0) && ((__WDTCLKCR & SCU_CLK_WDTCLKCR_WDTSEL_Msk) == SCU_CLK_WDTCLKCR_WDTSEL_PLL))) #define ENABLE_USBPLL \ ((((__CLKSET & SCU_CLK_CLKSET_USBCEN_Msk) != 0) && ((__USBCLKCR & SCU_CLK_USBCLKCR_USBSEL_Msk) == SCU_CLK_USBCLKCR_USBSEL_USBPLL)) || \ (((__CLKSET & SCU_CLK_CLKSET_MMCCEN_Msk) != 0) && ((__USBCLKCR & SCU_CLK_USBCLKCR_USBSEL_Msk) == SCU_CLK_USBCLKCR_USBSEL_USBPLL))) #if ((__USBCLKCR & SCU_CLK_USBCLKCR_USBSEL_Msk) == SCU_CLK_USBCLKCR_USBSEL_USBPLL) #define USB_DIV (3U) #else #define USB_DIV (5U) #endif /******************************************************************************* * GLOBAL VARIABLES *******************************************************************************/ #if defined ( __CC_ARM ) #if defined(XMC4700_E196x2048) || defined(XMC4700_F144x2048) || defined(XMC4700_F100x2048) uint32_t SystemCoreClock __attribute__((at(0x2003FFC0))); uint8_t g_chipid[16] __attribute__((at(0x2003FFC4))); #elif defined(XMC4700_E196x1536) || defined(XMC4700_F144x1536) || defined(XMC4700_F100x1536) uint32_t SystemCoreClock __attribute__((at(0x2002CFC0))); uint8_t g_chipid[16] __attribute__((at(0x2002CFC4))); #else #error "system_XMC4700.c: device not supported" #endif #elif defined ( __ICCARM__ ) #if defined(XMC4700_E196x2048) || defined(XMC4700_F144x2048) || defined(XMC4700_F100x2048) || \ defined(XMC4700_E196x1536) || defined(XMC4700_F144x1536) || defined(XMC4700_F100x1536) __no_init uint32_t SystemCoreClock; __no_init uint8_t g_chipid[16]; #else #error "system_XMC4700.c: device not supported" #endif #elif defined ( __GNUC__ ) #if defined(XMC4700_E196x2048) || defined(XMC4700_F144x2048) || defined(XMC4700_F100x2048) || \ defined(XMC4700_E196x1536) || defined(XMC4700_F144x1536) || defined(XMC4700_F100x1536) uint32_t SystemCoreClock __attribute__((section(".no_init"))); uint8_t g_chipid[16] __attribute__((section(".no_init"))); #else #error "system_XMC4700.c: device not supported" #endif #elif defined ( __TASKING__ ) #if defined(XMC4700_E196x2048) || defined(XMC4700_F144x2048) || defined(XMC4700_F100x2048) uint32_t SystemCoreClock __at( 0x2003FFC0 ); uint8_t g_chipid[16] __at( 0x2003FFC4 ); #elif defined(XMC4700_E196x1536) || defined(XMC4700_F144x1536) || defined(XMC4700_F100x1536) uint32_t SystemCoreClock __at( 0x2002CFC0 ); uint8_t g_chipid[16] __at( 0x2002CFC4 ); #else #error "system_XMC4700.c: device not supported" #endif #else #error "system_XMC4700.c: compiler not supported" #endif extern uint32_t __Vectors; /******************************************************************************* * LOCAL FUNCTIONS *******************************************************************************/ static void delay(uint32_t cycles) { volatile uint32_t i; for(i = 0UL; i < cycles ;++i) { __NOP(); } } /******************************************************************************* * API IMPLEMENTATION *******************************************************************************/ __WEAK void SystemInit(void) { memcpy(g_chipid, CHIPID_LOC, 16); SystemCoreSetup(); SystemCoreClockSetup(); } __WEAK void SystemCoreSetup(void) { uint32_t temp; /* relocate vector table */ __disable_irq(); SCB->VTOR = (uint32_t)(&__Vectors); __DSB(); __enable_irq(); #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */ (3UL << 11*2) ); /* set CP11 Full Access */ #endif /* Enable unaligned memory access - SCB_CCR.UNALIGN_TRP = 0 */ SCB->CCR &= ~(SCB_CCR_UNALIGN_TRP_Msk); temp = FLASH0->FCON; temp &= ~FLASH_FCON_WSPFLASH_Msk; temp |= PMU_FLASH_WS; FLASH0->FCON = temp; } __WEAK void SystemCoreClockSetup(void) { #if FOFI_CALIBRATION_MODE == FOFI_CALIBRATION_MODE_FACTORY /* Enable factory calibration */ SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FOTR_Msk; #else /* Automatic calibration uses the fSTDBY */ /* Enable HIB domain */ /* Power up HIB domain if and only if it is currently powered down */ if((SCU_POWER->PWRSTAT & SCU_POWER_PWRSTAT_HIBEN_Msk) == 0) { SCU_POWER->PWRSET |= SCU_POWER_PWRSET_HIB_Msk; while((SCU_POWER->PWRSTAT & SCU_POWER_PWRSTAT_HIBEN_Msk) == 0) { /* wait until HIB domain is enabled */ } } /* Remove the reset only if HIB domain were in a state of reset */ if((SCU_RESET->RSTSTAT) & SCU_RESET_RSTSTAT_HIBRS_Msk) { SCU_RESET->RSTCLR |= SCU_RESET_RSTCLR_HIBRS_Msk; delay(DELAY_CNT_150US_50MHZ); } #if STDBY_CLOCK_SRC == STDBY_CLOCK_SRC_OSCULP /* Enable OSC_ULP */ if ((SCU_HIBERNATE->OSCULCTRL & SCU_HIBERNATE_OSCULCTRL_MODE_Msk) != 0UL) { /*enable OSC_ULP*/ while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_OSCULCTRL_Msk) { /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */ } SCU_HIBERNATE->OSCULCTRL &= ~SCU_HIBERNATE_OSCULCTRL_MODE_Msk; /* Check if the clock is OK using OSCULP Oscillator Watchdog*/ while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCR_Msk) { /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */ } SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_ULPWDGEN_Msk; /* wait till clock is stable */ do { while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCLR_Msk) { /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */ } SCU_HIBERNATE->HDCLR |= SCU_HIBERNATE_HDCLR_ULPWDG_Msk; delay(DELAY_CNT_50US_50MHZ); } while ((SCU_HIBERNATE->HDSTAT & SCU_HIBERNATE_HDSTAT_ULPWDG_Msk) != 0UL); } /* now OSC_ULP is running and can be used*/ /* Select OSC_ULP as the clock source for RTC and STDBY*/ while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCR_Msk) { /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */ } SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_RCS_Msk | SCU_HIBERNATE_HDCR_STDBYSEL_Msk; #endif /* STDBY_CLOCK_SRC == STDBY_CLOCK_SRC_OSCULP */ /* Enable automatic calibration of internal fast oscillator */ SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_AOTREN_Msk; #endif /* FOFI_CALIBRATION_MODE == FOFI_CALIBRATION_MODE_AUTOMATIC */ delay(DELAY_CNT_50US_50MHZ); #if ENABLE_PLL /* enable PLL */ SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk); #if PLL_CLOCK_SRC != PLL_CLOCK_SRC_OFI /* enable OSC_HP */ if ((SCU_OSC->OSCHPCTRL & SCU_OSC_OSCHPCTRL_MODE_Msk) != 0U) { SCU_OSC->OSCHPCTRL &= ~(SCU_OSC_OSCHPCTRL_MODE_Msk | SCU_OSC_OSCHPCTRL_OSCVAL_Msk); SCU_OSC->OSCHPCTRL |= ((OSCHP_GetFrequency() / FOSCREF) - 1UL) << SCU_OSC_OSCHPCTRL_OSCVAL_Pos; /* select OSC_HP clock as PLL input */ SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk; /* restart OSC Watchdog */ SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk; while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_OSC_USABLE) != SCU_PLL_PLLSTAT_OSC_USABLE) { /* wait till OSC_HP output frequency is usable */ } } #else /* PLL_CLOCK_SRC != PLL_CLOCK_SRC_OFI */ /* select backup clock as PLL input */ SCU_PLL->PLLCON2 |= SCU_PLL_PLLCON2_PINSEL_Msk; #endif /* Go to bypass the Main PLL */ SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_VCOBYP_Msk; /* disconnect Oscillator from PLL */ SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FINDIS_Msk; /* Setup divider settings for main PLL */ SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) | (PLL_K2DIV_24MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) | (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos)); /* Set OSCDISCDIS */ SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_OSCDISCDIS_Msk; /* connect Oscillator to PLL */ SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FINDIS_Msk; /* restart PLL Lock detection */ SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_RESLD_Msk; while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk) == 0U) { /* wait for PLL Lock at 24MHz*/ } /* Disable bypass- put PLL clock back */ SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_VCOBYP_Msk; while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOBYST_Msk) != 0U) { /* wait for normal mode */ } #endif /* ENABLE_PLL */ /* Before scaling to final frequency we need to setup the clock dividers */ SCU_CLK->SYSCLKCR = __SYSCLKCR; SCU_CLK->PBCLKCR = __PBCLKCR; SCU_CLK->CPUCLKCR = __CPUCLKCR; SCU_CLK->CCUCLKCR = __CCUCLKCR; SCU_CLK->WDTCLKCR = __WDTCLKCR; SCU_CLK->EBUCLKCR = __EBUCLKCR; SCU_CLK->USBCLKCR = __USBCLKCR | USB_DIV; SCU_CLK->EXTCLKCR = __EXTCLKCR; #if ENABLE_PLL /* PLL frequency stepping...*/ /* Reset OSCDISCDIS */ SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCDISCDIS_Msk; SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) | (PLL_K2DIV_48MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) | (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos)); delay(DELAY_CNT_50US_48MHZ); SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) | (PLL_K2DIV_72MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) | (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos)); delay(DELAY_CNT_50US_72MHZ); SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) | (PLL_K2DIV_96MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) | (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos)); delay(DELAY_CNT_50US_96MHZ); SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) | (PLL_K2DIV_120MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) | (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos)); delay(DELAY_CNT_50US_120MHZ); SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) | (PLL_K2DIV << SCU_PLL_PLLCON1_K2DIV_Pos) | (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos)); delay(DELAY_CNT_50US_144MHZ); #endif /* ENABLE_PLL */ #if ENABLE_USBPLL /* enable USB PLL first */ SCU_PLL->USBPLLCON &= ~(SCU_PLL_USBPLLCON_VCOPWD_Msk | SCU_PLL_USBPLLCON_PLLPWD_Msk); /* USB PLL uses as clock input the OSC_HP */ /* check and if not already running enable OSC_HP */ if ((SCU_OSC->OSCHPCTRL & SCU_OSC_OSCHPCTRL_MODE_Msk) != 0U) { /* check if Main PLL is switched on for OSC WDG*/ if ((SCU_PLL->PLLCON0 &(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk)) != 0UL) { /* enable PLL first */ SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk); } SCU_OSC->OSCHPCTRL &= ~(SCU_OSC_OSCHPCTRL_MODE_Msk | SCU_OSC_OSCHPCTRL_OSCVAL_Msk); SCU_OSC->OSCHPCTRL |= ((OSCHP_GetFrequency() / FOSCREF) - 1UL) << SCU_OSC_OSCHPCTRL_OSCVAL_Pos; /* restart OSC Watchdog */ SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk; while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_OSC_USABLE) != SCU_PLL_PLLSTAT_OSC_USABLE) { /* wait till OSC_HP output frequency is usable */ } } /* Setup USB PLL */ /* Go to bypass the USB PLL */ SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_VCOBYP_Msk; /* disconnect Oscillator from USB PLL */ SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_FINDIS_Msk; /* Setup Divider settings for USB PLL */ SCU_PLL->USBPLLCON = ((USB_NDIV << SCU_PLL_USBPLLCON_NDIV_Pos) | (USB_PDIV << SCU_PLL_USBPLLCON_PDIV_Pos)); /* Set OSCDISCDIS */ SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_OSCDISCDIS_Msk; /* connect Oscillator to USB PLL */ SCU_PLL->USBPLLCON &= ~SCU_PLL_USBPLLCON_FINDIS_Msk; /* restart PLL Lock detection */ SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_RESLD_Msk; while ((SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOLOCK_Msk) == 0U) { /* wait for PLL Lock */ } #endif /* Enable selected clocks */ SCU_CLK->CLKSET = __CLKSET; #if __EXTCLKPIN != 0 #if __EXTCLKPIN == EXTCLK_PIN_P1_15 /* P1.15 */ PORT1->PDR1 &= ~PORT1_PDR1_PD15_Msk; PORT1->IOCR12 = (PORT1->IOCR12 & ~PORT0_IOCR12_PC15_Msk) | (0x11U << PORT0_IOCR12_PC15_Pos); #else /* P0.8 */ PORT0->HWSEL &= ~PORT0_HWSEL_HW8_Msk; PORT0->PDR1 &= ~PORT0_PDR1_PD8_Msk; PORT0->IOCR8 = (PORT0->IOCR8 & ~PORT0_IOCR8_PC8_Msk) | (0x11U << PORT0_IOCR8_PC8_Pos); #endif #endif /* ENABLE_EXTCLK == 1 */ SystemCoreClockUpdate(); } __WEAK void SystemCoreClockUpdate(void) { uint32_t pdiv; uint32_t ndiv; uint32_t kdiv; uint32_t temp; if (SCU_CLK->SYSCLKCR & SCU_CLK_SYSCLKCR_SYSSEL_Msk) { /* fPLL is clock source for fSYS */ if(SCU_PLL->PLLCON2 & SCU_PLL_PLLCON2_PINSEL_Msk) { /* PLL input clock is the backup clock (fOFI) */ temp = OFI_FREQUENCY; } else { /* PLL input clock is the high performance osicllator (fOSCHP) */ temp = OSCHP_GetFrequency(); } /* check if PLL is locked */ if (SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk) { /* PLL normal mode */ /* read back divider settings */ pdiv = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_PDIV_Msk) >> SCU_PLL_PLLCON1_PDIV_Pos) + 1; ndiv = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_NDIV_Msk) >> SCU_PLL_PLLCON1_NDIV_Pos) + 1; kdiv = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_K2DIV_Msk) >> SCU_PLL_PLLCON1_K2DIV_Pos) + 1; temp = (temp / (pdiv * kdiv)) * ndiv; } else { /* PLL prescalar mode */ /* read back divider settings */ kdiv = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_K1DIV_Msk) >> SCU_PLL_PLLCON1_K1DIV_Pos) + 1; temp = (temp / kdiv); } } else { /* fOFI is clock source for fSYS */ temp = OFI_FREQUENCY; } temp = temp / ((SCU_CLK->SYSCLKCR & SCU_CLK_SYSCLKCR_SYSDIV_Msk) + 1); temp = temp / ((SCU_CLK->CPUCLKCR & SCU_CLK_CPUCLKCR_CPUDIV_Msk) + 1); SystemCoreClock = temp; } __WEAK uint32_t OSCHP_GetFrequency(void) { return OSCHP_FREQUENCY; }