X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=FreeRTOS%2FDemo%2FCORTEX_M4F_Infineon_XMC4000_Tasking%2FStartup%2FInfineon%2FXMC4500%2Fsystem_XMC4500.c;h=74ecf74d32bc995bfc0779f908bf225ee1a13063;hb=c8de997b68d477fce45cb6f98499981407103b95;hp=fc9b4840e9379500fc6d2e343d77a7f6faa0caaa;hpb=971f762b8c059cc4fe7e9b30ef08442c158bf992;p=freertos diff --git a/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Tasking/Startup/Infineon/XMC4500/system_XMC4500.c b/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Tasking/Startup/Infineon/XMC4500/system_XMC4500.c index fc9b4840e..74ecf74d3 100644 --- a/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Tasking/Startup/Infineon/XMC4500/system_XMC4500.c +++ b/FreeRTOS/Demo/CORTEX_M4F_Infineon_XMC4000_Tasking/Startup/Infineon/XMC4500/system_XMC4500.c @@ -1,47 +1,47 @@ -/****************************************************************************** +/**************************************************************************//** * @file system_XMC4500.c - * @brief Device specific initialization for the XMC4500-Series according to CMSIS - * @version V2.2 - * @date 20. January 2012 + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File + * for the Infineon XMC4500 Device Series + * @version V3.0.1 Alpha + * @date 17. September 2012 * * @note - * Copyright (C) 2011 Infineon Technologies AG. All rights reserved. - + * Copyright (C) 2011 ARM Limited. All rights reserved. * * @par - * Infineon Technologies AG (Infineon) is supplying this software for use with Infineon’s microcontrollers. - * This file can be freely distributed within development tools that are supporting such microcontrollers. - + * ARM Limited (ARM) is supplying this software for use with Cortex-M + * processor based microcontrollers. This file can be freely distributed + * within development tools that are supporting such ARM based processors. * * @par * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. - * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * - * ******************************************************************************/ #include "system_XMC4500.h" #include -/*---------------------------------------------------------------------------- - Define clocks is located in System_XMC4500.h - *----------------------------------------------------------------------------*/ - /*---------------------------------------------------------------------------- Clock Variable definitions *----------------------------------------------------------------------------*/ /*!< System Clock Frequency (Core Clock)*/ -uint32_t SystemCoreClock = CLOCK_OSC_HP; +uint32_t SystemCoreClock; + +/* clock definitions, do not modify! */ +#define SCU_CLOCK_CRYSTAL 1 +#define SCU_CLOCK_BACK_UP_FACTORY 2 +#define SCU_CLOCK_BACK_UP_AUTOMATIC 3 + + +#define HIB_CLOCK_FOSI 1 +#define HIB_CLOCK_OSCULP 2 + + -/*---------------------------------------------------------------------------- - Keil pragma to prevent warnings - *----------------------------------------------------------------------------*/ -#if defined(__ARMCC_VERSION) -#pragma diag_suppress 177 -#endif /* //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ @@ -80,8 +80,57 @@ uint32_t SystemCoreClock = CLOCK_OSC_HP; #define SCU_CPUCLKCR_DIV 0x00000000 #define SCU_PBCLKCR_DIV 0x00000000 #define SCU_CCUCLKCR_DIV 0x00000000 - - +/* not avalible in config wizzard*/ +/* +* mandatory clock parameters ************************************************** +* +* source for clock generation +* range: SCU_CLOCK_CRYSTAL (crystal or external clock at crystal input) +* +**************************************************************************************/ +// Selection of imput lock for PLL +/*************************************************************************************/ +#define SCU_PLL_CLOCK_INPUT SCU_CLOCK_CRYSTAL +//#define SCU_PLL_CLOCK_INPUT SCU_CLOCK_BACK_UP_FACTORY +//#define SCU_PLL_CLOCK_INPUT SCU_CLOCK_BACK_UP_AUTOMATIC + +/*************************************************************************************/ +// Standby clock selection for Backup clock source trimming +/*************************************************************************************/ +#define SCU_STANDBY_CLOCK HIB_CLOCK_OSCULP +//#define SCU_STANDBY_CLOCK HIB_CLOCK_FOSI + +/*************************************************************************************/ +// Global clock parameters +/*************************************************************************************/ +#define CLOCK_FSYS 120000000 +#define CLOCK_CRYSTAL_FREQUENCY 12000000 +#define CLOCK_BACK_UP 24000000 + +/*************************************************************************************/ +/* OSC_HP setup parameters */ +/*************************************************************************************/ +#define SCU_OSC_HP_MODE 0xF0 +#define SCU_OSCHPWDGDIV 2 + +/*************************************************************************************/ +/* MAIN PLL setup parameters */ +/*************************************************************************************/ +//Divider settings for external crystal @ 12 MHz +/*************************************************************************************/ +#define SCU_PLL_K1DIV 1 +#define SCU_PLL_K2DIV 3 +#define SCU_PLL_PDIV 1 +#define SCU_PLL_NDIV 79 + +/*************************************************************************************/ +//Divider settings for use of backup clock source trimmed +/*************************************************************************************/ +//#define SCU_PLL_K1DIV 1 +//#define SCU_PLL_K2DIV 3 +//#define SCU_PLL_PDIV 3 +//#define SCU_PLL_NDIV 79 +/*************************************************************************************/ /*--------------------- USB CLOCK Configuration --------------------------- // @@ -92,6 +141,25 @@ uint32_t SystemCoreClock = CLOCK_OSC_HP; */ #define SCU_USB_CLOCK_SETUP 0 +/* not avalible in config wizzard*/ +#define SCU_USBPLL_PDIV 0 +#define SCU_USBPLL_NDIV 31 +#define SCU_USBDIV 3 + +/*--------------------- Flash Wait State Configuration ------------------------------- +// +// Flash Wait State Configuration +// Flash Wait State +// <0=> 3 WS +// <1=> 4 WS +// <2=> 5 WS +// <3=> 6 WS +// +// +*/ + +#define PMU_FLASH 1 +#define PMU_FLASH_WS 0x00000000 /*--------------------- CLOCKOUT Configuration ------------------------------- @@ -99,9 +167,10 @@ uint32_t SystemCoreClock = CLOCK_OSC_HP; // Clock OUT Configuration // Clockout Source Selection // <0=> System Clock -// <2=> USB Clock +// <2=> Divided value of USB PLL output // <3=> Divided value of PLL Clock -// Clockout Pin Selection +// Clockout divider <1-10><#-1> +// Clockout Pin Selection // <0=> P1.15 // <1=> P0.8 // @@ -110,9 +179,20 @@ uint32_t SystemCoreClock = CLOCK_OSC_HP; // */ -#define SCU_CLOCKOUT_SETUP 0 // recommended to keep disabled -#define SCU_CLOCKOUT_SOURCE 0x00000000 -#define SCU_CLOCKOUT_PIN 0x00000000 +#define SCU_CLOCKOUT_SETUP 0 +#define SCU_CLOCKOUT_SOURCE 0x00000003 +#define SCU_CLOCKOUT_DIV 0x00000009 +#define SCU_CLOCKOUT_PIN 0x00000001 + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *----------------------------------------------------------------------------*/ +/*!< System Clock Frequency (Core Clock)*/ +#if SCU_CLOCK_SETUP +uint32_t SystemCoreClock = CLOCK_FSYS; +#else +uint32_t SystemCoreClock = CLOCK_BACK_UP; +#endif /*---------------------------------------------------------------------------- static functions declarations @@ -122,9 +202,10 @@ static int SystemClockSetup(void); #endif #if (SCU_USB_CLOCK_SETUP == 1) -static void USBClockSetup(void); +static int USBClockSetup(void); #endif + /** * @brief Setup the microcontroller system. * Initialize the PLL and update the @@ -134,59 +215,70 @@ static void USBClockSetup(void); */ void SystemInit(void) { -/* Setup the WDT */ -#if (WDT_SETUP == 1) -WDT->CTR &= ~WDTENB_nVal; -#endif - +int temp; + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */ (3UL << 11*2) ); /* set CP11 Full Access */ #endif -/* Disable branch prediction - PCON.PBS = 1 */ -PREF->PCON |= (PREF_PCON_PBS_Msk); - /* Enable unaligned memory access - SCB_CCR.UNALIGN_TRP = 0 */ SCB->CCR &= ~(SCB_CCR_UNALIGN_TRP_Msk); + +/* Setup the WDT */ +#if WDT_SETUP +WDT->CTR &= ~WDTENB_nVal; + +#endif + +/* Setup the Flash Wait State */ +#if PMU_FLASH +temp = FLASH0->FCON; +temp &= ~FLASH_FCON_WSPFLASH_Msk; +temp |= PMU_FLASH_WS+3; +FLASH0->FCON = temp; +#endif + + /* Setup the clockout */ -/* README README README README README README README README README README */ -/* - * Please use the CLOCKOUT feature with diligence. Use this only if you know - * what you are doing. - * - * You must be aware that the settings below can potentially be in conflict - * with DAVE code generation engine preferences. - * - * Even worse, the setting below configures the ports as output ports while in - * reality, the board on which this chip is mounted may have a source driving - * the ports. - * - * So use this feature only when you are absolutely sure that the port must - * indeed be configured as an output AND you are NOT linking this startup code - * with code that was generated by DAVE code engine. - */ -#if (SCU_CLOCKOUT_SETUP == 1) +#if SCU_CLOCKOUT_SETUP + SCU_CLK->EXTCLKCR |= SCU_CLOCKOUT_SOURCE; +/*set PLL div for clkout */ +SCU_CLK->EXTCLKCR |= SCU_CLOCKOUT_DIV<<16; if (SCU_CLOCKOUT_PIN) { - PORT0->IOCR8 = 0x00000088; /*P0.8 --> ALT1 select + HWSEL */ - PORT0->HWSEL &= (~PORT0_HWSEL_HW8_Msk); - } -else PORT1->IOCR12 = 0x88000000; /*P1.15--> ALT1 select */ + PORT0->IOCR8 = 0x00000088; /*P0.8 --> ALT1 select + HWSEL */ + PORT0->HWSEL &= (~PORT0_HWSEL_HW8_Msk); + //PORT0->PDR1 &= (~PORT0_PDR1_PD8_Msk); /*set to strong driver */ + } +else { + PORT1->IOCR12 = 0x88000000; /*P1.15--> ALT1 select */ + //PORT1->PDR1 &= (~PORT1_PDR1_PD15_Msk); /*set to strong driver */ + } + #endif + /* Setup the System clock */ -#if (SCU_CLOCK_SETUP == 1) +#if SCU_CLOCK_SETUP SystemClockSetup(); #endif +/*---------------------------------------------------------------------------- + Clock Variable definitions + *----------------------------------------------------------------------------*/ +SystemCoreClockUpdate();/*!< System Clock Frequency (Core Clock)*/ + + /* Setup the USB PL */ -#if (SCU_USB_CLOCK_SETUP == 1) +#if SCU_USB_CLOCK_SETUP USBClockSetup(); #endif + + } @@ -198,11 +290,49 @@ USBClockSetup(); */ void SystemCoreClockUpdate(void) { +unsigned int PDIV; +unsigned int NDIV; +unsigned int K2DIV; +unsigned int long VCO; + /*---------------------------------------------------------------------------- Clock Variable definitions *----------------------------------------------------------------------------*/ -SystemCoreClock = SYSTEM_FREQUENCY;/*!< System Clock Frequency (Core Clock)*/ +if (SCU_CLK->SYSCLKCR == 0x00010000) +{ + if (SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk){ + /* check if PLL is locked */ + /* read back divider settings */ + PDIV = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_PDIV_Msk)>>24)+1; + NDIV = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_NDIV_Msk)>>8)+1; + K2DIV = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_K2DIV_Msk)>>16)+1; + + if(SCU_PLL->PLLCON2 & SCU_PLL_PLLCON2_PINSEL_Msk){ + /* the selected clock is the Backup clock fofi */ + VCO = (CLOCK_BACK_UP/PDIV)*NDIV; + SystemCoreClock = VCO/K2DIV; + /* in case the sysclock div is used */ + SystemCoreClock = SystemCoreClock/((SCU_CLK->SYSCLKCR & SCU_CLK_SYSCLKCR_SYSDIV_Msk)+1); + + } + else + { + /* the selected clock is the PLL external oscillator */ + VCO = (CLOCK_CRYSTAL_FREQUENCY/PDIV)*NDIV; + SystemCoreClock = VCO/K2DIV; + /* in case the sysclock div is used */ + SystemCoreClock = SystemCoreClock/((SCU_CLK->SYSCLKCR & SCU_CLK_SYSCLKCR_SYSDIV_Msk)+1); + } + + + } +} +else +{ +SystemCoreClock = CLOCK_BACK_UP; +} + } @@ -216,146 +346,285 @@ SystemCoreClock = SYSTEM_FREQUENCY;/*!< System Clock Frequency (Core Clock)*/ #if (SCU_CLOCK_SETUP == 1) static int SystemClockSetup(void) { +int temp; +unsigned int long VCO; +int stepping_K2DIV; + +/* this weak function enables DAVE3 clock App usage */ +if(AllowPLLInitByStartup()){ + +/* check if PLL is switched on */ +if ((SCU_PLL->PLLCON0 &(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk)) != 0){ /* enable PLL first */ - SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk | - SCU_PLL_PLLCON0_PLLPWD_Msk); + SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk); -/* Enable OSC_HP */ +} + +/* Enable OSC_HP if not already on*/ if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL) { - /* Enable the OSC_HP*/ - SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4); - /* Setup OSC WDG devider */ - SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16); - /* Select external OSC as PLL input */ - SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk; - /* Restart OSC Watchdog */ - SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk; - - do - { - ; /* here a timeout need to be added */ - }while(!( (SCU_PLL->PLLSTAT) & - (SCU_PLL_PLLSTAT_PLLHV_Msk | SCU_PLL_PLLSTAT_PLLLV_Msk | - SCU_PLL_PLLSTAT_PLLSP_Msk) - ) - ); - - } - -/* Setup Main PLL */ - /* Select FOFI as system clock */ - if(SCU_CLK->SYSCLKCR != 0X000000) - SCU_CLK->SYSCLKCR = 0x00000000; /*Select FOFI*/ + /********************************************************************************************************************/ + /* Use external crystal for PLL clock input */ + /********************************************************************************************************************/ - /* Go to bypass the Main PLL */ - SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_VCOBYP_Msk; - - /* disconnect OSC_HP to PLL */ - SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FINDIS_Msk; - - /* Setup devider settings for main PLL */ - SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | - (PLL_K2DIV_STEP_1<<16) | (PLL_PDIV<<24)); - - /* we may have to set OSCDISCDIS */ - SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_OSCDISCDIS_Msk; - - /* connect OSC_HP to PLL */ - SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FINDIS_Msk; - - /* restart PLL Lock detection */ - SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_RESLD_Msk; + if (SCU_OSC->OSCHPCTRL & SCU_OSC_OSCHPCTRL_MODE_Msk){ + SCU_OSC->OSCHPCTRL &= ~(SCU_OSC_HP_MODE); /*enable the OSC_HP*/ + /* setup OSC WDG devider */ + SCU_OSC->OSCHPCTRL |= (SCU_OSCHPWDGDIV<<16); + /* select external OSC as PLL input */ + SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk; + /* restart OSC Watchdog */ + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk; - /* wait for PLL Lock */ - while (!(SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk)); + /* Timeout for wait loop ~150ms */ + /********************************/ + SysTick->LOAD = ((5000000+100) & SysTick_LOAD_RELOAD_Msk) - 1;/* set reload register */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + do + { + ;/* wait for ~150ms */ + }while((((SCU_PLL->PLLSTAT) & (SCU_PLL_PLLSTAT_PLLHV_Msk | SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk)) != 0x380)&&(SysTick->VAL >= 500)); - /* Go back to the Main PLL */ - SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_VCOBYP_Msk; + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; /* Stop SysTick Timer */ + if (((SCU_PLL->PLLSTAT) & (SCU_PLL_PLLSTAT_PLLHV_Msk | SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk)) != 0x380) + return(0);/* Return Error */ - /********************************************************* - here we need to setup the system clock divider - *********************************************************/ + } + } + else if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_BACK_UP_FACTORY) + { + /********************************************************************************************************************/ + /* Use factory trimming Back-up clock for PLL clock input */ + /********************************************************************************************************************/ + /* PLL Back up clock selected */ + SCU_PLL->PLLCON2 |= SCU_PLL_PLLCON2_PINSEL_Msk; + + } + else if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_BACK_UP_AUTOMATIC) + { + /********************************************************************************************************************/ + /* Use automatic trimming Back-up clock for PLL clock input */ + /********************************************************************************************************************/ + /* check for HIB Domain enabled */ + if((SCU_POWER->PWRSTAT & SCU_POWER_PWRSTAT_HIBEN_Msk) == 0) + SCU_POWER->PWRSET |= SCU_POWER_PWRSET_HIB_Msk; /*enable Hibernate domain*/ + + /* check for HIB Domain is not in reset state */ + if ((SCU_RESET->RSTSTAT & SCU_RESET_RSTSTAT_HIBRS_Msk)== 1) + SCU_RESET->RSTCLR |= SCU_RESET_RSTCLR_HIBRS_Msk; /*de-assert hibernate reset*/ + + /* PLL Back up clock selected */ + SCU_PLL->PLLCON2 |= SCU_PLL_PLLCON2_PINSEL_Msk; + + if (SCU_STANDBY_CLOCK == HIB_CLOCK_FOSI) + { + /****************************************************************************************************************/ + /* Use fOSI as source of the standby clock */ + /****************************************************************************************************************/ + SCU_HIBERNATE->HDCR &= ~SCU_HIBERNATE_HDCR_STDBYSEL_Msk; + + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FOTR_Msk; + for(temp=0;temp<=0xFFFF;temp++); + + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_AOTREN_Msk; + } + else if (SCU_STANDBY_CLOCK == HIB_CLOCK_OSCULP) + { + /****************************************************************************************************************/ + /* Use fULP as source of the standby clock */ + /****************************************************************************************************************/ + /*check OSCUL if running correct*/ + if ((SCU_HIBERNATE->OSCULCTRL & SCU_HIBERNATE_OSCULCTRL_MODE_Msk)!= 0) + { + while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_OSCULCTRL_Msk); + + SCU_HIBERNATE->OSCULCTRL &= ~SCU_HIBERNATE_OSCULCTRL_MODE_Msk; /*enable OSCUL*/ + /*now ceck if the clock is OK using OSCULP Oscillator Watchdog (ULPWDG)*/ + /* select OSCUL clock for RTC*/ + SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_RCS_Msk; + while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCR_Msk); + /*enable OSCULP WDG Alarm Enable*/ + SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_ULPWDGEN_Msk; + while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCR_Msk); + /*wait now for clock is stable */ + do + { + SCU_HIBERNATE->HDCLR |= SCU_HIBERNATE_HDCLR_ULPWDG_Msk; + while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCLR_Msk); + for(temp=0;temp<=0xFFFF;temp++); + } + while ((SCU_HIBERNATE->HDSTAT & SCU_HIBERNATE_HDSTAT_ULPWDG_Msk)==SCU_HIBERNATE_HDSTAT_ULPWDG_Msk); + + SCU_HIBERNATE->HDCLR |= SCU_HIBERNATE_HDCLR_ULPWDG_Msk; + while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCLR_Msk); + } + // now OSCULP is running and can be used + SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_STDBYSEL_Msk; + while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCR_Msk); + + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FOTR_Msk; + /*TRIAL for delay loop*/ + for(temp=0;temp<=0xFFFF;temp++); + + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_AOTREN_Msk; + /*TRIAL for delay loop*/ + for(temp=0;temp<=0xFFFF;temp++); + + } + } - SCU_CLK->CPUCLKCR = SCU_CPUCLKCR_DIV; - SCU_CLK->PBCLKCR = SCU_PBCLKCR_DIV; - SCU_CLK->CCUCLKCR = SCU_CCUCLKCR_DIV; + /********************************************************************************************************************/ + /* Setup and look the main PLL */ + /********************************************************************************************************************/ + +if (!(SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk)){ + /* Systen is still running from internal clock */ + /* select FOFI as system clock */ + if((SCU_CLK->SYSCLKCR & SCU_CLK_SYSCLKCR_SYSSEL_Msk) != 0x0)SCU_CLK->SYSCLKCR &= ~SCU_CLK_SYSCLKCR_SYSSEL_Msk; /*Select FOFI*/ + + + /*calulation for stepping*/ + if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL)VCO = (CLOCK_CRYSTAL_FREQUENCY/(SCU_PLL_PDIV+1))*(SCU_PLL_NDIV+1); + if ((SCU_PLL_CLOCK_INPUT == SCU_CLOCK_BACK_UP_AUTOMATIC) ||(SCU_PLL_CLOCK_INPUT == SCU_CLOCK_BACK_UP_FACTORY)) + VCO = (CLOCK_BACK_UP/(SCU_PLL_PDIV+1))*(SCU_PLL_NDIV+1); + + stepping_K2DIV = (VCO/24000000)-1; + /* Go to bypass the Main PLL */ + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_VCOBYP_Msk; + /* disconnect OSC_HP to PLL */ + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FINDIS_Msk; + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((SCU_PLL_K1DIV) | (SCU_PLL_NDIV<<8) | (stepping_K2DIV<<16) | (SCU_PLL_PDIV<<24)); + /* we may have to set OSCDISCDIS */ + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_OSCDISCDIS_Msk; + /* connect OSC_HP to PLL */ + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FINDIS_Msk; + /* restart PLL Lock detection */ + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_RESLD_Msk; + /* wait for PLL Lock */ + /* setup time out loop */ + /* Timeout for wait loo ~150ms */ + /********************************/ + SysTick->LOAD = ((5000000+100) & SysTick_LOAD_RELOAD_Msk) - 1;/* set reload register */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + + while ((!(SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk))&&(SysTick->VAL >= 500)); + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; /* Stop SysTick Timer */ + + if ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk)==SCU_PLL_PLLSTAT_VCOLOCK_Msk) + { + /* Go back to the Main PLL */ + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_VCOBYP_Msk; + } + else return(0); + + + /********************************************************* + here we need to setup the system clock divider + *********************************************************/ + + SCU_CLK->CPUCLKCR = SCU_CPUCLKCR_DIV; + SCU_CLK->PBCLKCR = SCU_PBCLKCR_DIV; + SCU_CLK->CCUCLKCR = SCU_CCUCLKCR_DIV; + - /* Switch system clock to PLL */ - SCU_CLK->SYSCLKCR |= 0x00010000; - + /* Switch system clock to PLL */ + SCU_CLK->SYSCLKCR |= 0x00010000; + + /* we may have to reset OSCDISCDIS */ + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCDISCDIS_Msk; + + + /*********************************************************/ + /* Delay for next K2 step ~50µs */ + /*********************************************************/ + SysTick->LOAD = ((1250+100) & SysTick_LOAD_RELOAD_Msk) - 1;/* set reload register */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + + while (SysTick->VAL >= 100); /* wait for ~50µs */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; /* Stop SysTick Timer */ + /*********************************************************/ + + /********************************************************* + here the ramp up of the system clock starts FSys < 60MHz + *********************************************************/ + if (CLOCK_FSYS > 60000000){ + /*calulation for stepping*/ + if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL)VCO = (CLOCK_CRYSTAL_FREQUENCY/(SCU_PLL_PDIV+1))*(SCU_PLL_NDIV+1); + if ((SCU_PLL_CLOCK_INPUT == SCU_CLOCK_BACK_UP_AUTOMATIC) ||(SCU_PLL_CLOCK_INPUT == SCU_CLOCK_BACK_UP_FACTORY)) + VCO = (CLOCK_BACK_UP/(SCU_PLL_PDIV+1))*(SCU_PLL_NDIV+1); + + stepping_K2DIV = (VCO/60000000)-1; + + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((SCU_PLL_K1DIV) | (SCU_PLL_NDIV<<8) | (stepping_K2DIV<<16) | (SCU_PLL_PDIV<<24)); + } + else + { + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((SCU_PLL_K1DIV) | (SCU_PLL_NDIV<<8) | (SCU_PLL_K2DIV<<16) | (SCU_PLL_PDIV<<24)); + SCU_TRAP->TRAPCLR = SCU_TRAP_TRAPCLR_SOSCWDGT_Msk | SCU_TRAP_TRAPCLR_SVCOLCKT_Msk; /* clear request for System OCS Watchdog Trap and System VCO Lock Trap */ + return(1); + } + + /*********************************************************/ + /* Delay for next K2 step ~50µs */ + /*********************************************************/ + SysTick->LOAD = ((3000+100) & SysTick_LOAD_RELOAD_Msk) - 1; + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + + while (SysTick->VAL >= 100); /* wait for ~50µs */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; /* Stop SysTick Timer */ + /********************************/ + /********************************************************* - here the ramp up of the system clock starts - *********************************************************/ - /* Delay for next K2 step ~50µs */ - /********************************/ - /* Set reload register */ - SysTick->LOAD = ((1250+100) & SysTick_LOAD_RELOAD_Msk) - 1; - - /* Load the SysTick Counter Value */ - SysTick->VAL = 0; - - /* Enable SysTick IRQ and SysTick Timer */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_ENABLE_Msk; - - /* wait for ~50µs */ - while (SysTick->VAL >= 100); - - /* Stop SysTick Timer */ - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; - /********************************/ - - /* Setup devider settings for main PLL */ - SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | - (PLL_K2DIV_STEP_2<<16) | (PLL_PDIV<<24)); - - /* Delay for next K2 step ~50µs */ - /********************************/ - SysTick->LOAD = ((3000+100) & SysTick_LOAD_RELOAD_Msk) - 1; - - /* Load the SysTick Counter Value */ - SysTick->VAL = 0; - - /* Enable SysTick IRQ and SysTick Timer */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; - - /* Wait for ~50µs */ - while (SysTick->VAL >= 100); - - /* Stop SysTick Timer */ - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; - /********************************/ - - /* Setup devider settings for main PLL */ - SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | - (PLL_K2DIV_STEP_3<<16) | (PLL_PDIV<<24)); - - /* Delay for next K2 step ~50µs */ - /********************************/ - SysTick->LOAD = ((4800+100) & SysTick_LOAD_RELOAD_Msk) - 1; - - /* Load the SysTick Counter Value */ - SysTick->VAL = 0; - - /* Enable SysTick IRQ and SysTick Timer */ - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; - - /* Wait for ~50µs */ - while (SysTick->VAL >= 100); - - /* Stop SysTick Timer */ - SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; - /********************************/ - - /* Setup devider settings for main PLL */ - SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | (PLL_K2DIV<<16) | - (PLL_PDIV<<24)); - - /* clear request for System OCS Watchdog Trap and System VCO Lock Trap */ - SCU_TRAP->TRAPCLR = SCU_TRAP_TRAPCLR_SOSCWDGT_Msk | - SCU_TRAP_TRAPCLR_SVCOLCKT_Msk; - + here the ramp up of the system clock starts FSys < 90MHz + *********************************************************/ + if (CLOCK_FSYS > 90000000){ + /*calulation for stepping*/ + if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL)VCO = (CLOCK_CRYSTAL_FREQUENCY/(SCU_PLL_PDIV+1))*(SCU_PLL_NDIV+1); + if ((SCU_PLL_CLOCK_INPUT == SCU_CLOCK_BACK_UP_AUTOMATIC) ||(SCU_PLL_CLOCK_INPUT == SCU_CLOCK_BACK_UP_FACTORY)) + VCO = (CLOCK_BACK_UP/(SCU_PLL_PDIV+1))*(SCU_PLL_NDIV+1); + + stepping_K2DIV = (VCO/90000000)-1; + + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((SCU_PLL_K1DIV) | (SCU_PLL_NDIV<<8) | (stepping_K2DIV<<16) | (SCU_PLL_PDIV<<24)); + } + else + { + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((SCU_PLL_K1DIV) | (SCU_PLL_NDIV<<8) | (SCU_PLL_K2DIV<<16) | (SCU_PLL_PDIV<<24)); + SCU_TRAP->TRAPCLR = SCU_TRAP_TRAPCLR_SOSCWDGT_Msk | SCU_TRAP_TRAPCLR_SVCOLCKT_Msk; /* clear request for System OCS Watchdog Trap and System VCO Lock Trap */ + return(1); + } + + /*********************************************************/ + /* Delay for next K2 step ~50µs */ + /*********************************************************/ + SysTick->LOAD = ((4800+100) & SysTick_LOAD_RELOAD_Msk) - 1; + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + + while (SysTick->VAL >= 100); /* wait for ~50µs */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; /* Stop SysTick Timer */ + /********************************/ + + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((SCU_PLL_K1DIV) | (SCU_PLL_NDIV<<8) | (SCU_PLL_K2DIV<<16) | (SCU_PLL_PDIV<<24)); + + SCU_TRAP->TRAPCLR = SCU_TRAP_TRAPCLR_SOSCWDGT_Msk | SCU_TRAP_TRAPCLR_SVCOLCKT_Msk; /* clear request for System OCS Watchdog Trap and System VCO Lock Trap */ + } + }/* end this weak function enables DAVE3 clock App usage */ return(1); } @@ -367,36 +636,46 @@ static int SystemClockSetup(void) * @param None * @retval None */ -#if(SCU_USB_CLOCK_SETUP == 1) -static void USBClockSetup(void) +#if (SCU_USB_CLOCK_SETUP == 1) +static int USBClockSetup(void) { -/* enable PLL first */ - SCU_PLL->USBPLLCON &= ~(SCU_PLL_USBPLLCON_VCOPWD_Msk | - SCU_PLL_USBPLLCON_PLLPWD_Msk); +/* this weak function enables DAVE3 clock App usage */ +if(AllowPLLInitByStartup()){ + + /* check if PLL is switched on */ +if ((SCU_PLL->USBPLLCON &(SCU_PLL_USBPLLCON_VCOPWD_Msk | SCU_PLL_USBPLLCON_PLLPWD_Msk)) != 0){ + /* enable PLL first */ + SCU_PLL->USBPLLCON &= ~(SCU_PLL_USBPLLCON_VCOPWD_Msk | SCU_PLL_USBPLLCON_PLLPWD_Msk); +} /* check and if not already running enable OSC_HP */ - if(!((SCU_PLL->PLLSTAT) & - (SCU_PLL_PLLSTAT_PLLHV_Msk | - SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk))) - { - if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL) - { - - SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4); /*enable the OSC_HP*/ + if (SCU_OSC->OSCHPCTRL & SCU_OSC_OSCHPCTRL_MODE_Msk){ + /* check if Main PLL is switched on for OSC WD*/ + if ((SCU_PLL->PLLCON0 &(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk)) != 0){ + /* enable PLL first */ + SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk); + } + SCU_OSC->OSCHPCTRL &= ~(SCU_OSC_HP_MODE); /*enable the OSC_HP*/ /* setup OSC WDG devider */ - SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16); - /* select external OSC as PLL input */ - SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk; + SCU_OSC->OSCHPCTRL |= (SCU_OSCHPWDGDIV<<16); /* restart OSC Watchdog */ SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk; + /* Timeout for wait loop ~150ms */ + /********************************/ + SysTick->LOAD = ((5000000+100) & SysTick_LOAD_RELOAD_Msk) - 1;/* set reload register */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ do { - ; /* here a timeout need to be added */ - }while(!((SCU_PLL->PLLSTAT) & (SCU_PLL_PLLSTAT_PLLHV_Msk | - SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk))); + ;/* wait for ~150ms */ + }while((((SCU_PLL->PLLSTAT) & (SCU_PLL_PLLSTAT_PLLHV_Msk | SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk)) != 0x380)&&(SysTick->VAL >= 500)); + + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; /* Stop SysTick Timer */ + if (((SCU_PLL->PLLSTAT) & (SCU_PLL_PLLSTAT_PLLHV_Msk | SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk)) != 0x380) + return(0);/* Return Error */ - } } @@ -406,7 +685,9 @@ static void USBClockSetup(void) /* disconnect OSC_FI to PLL */ SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_FINDIS_Msk; /* Setup devider settings for main PLL */ - SCU_PLL->USBPLLCON = ((USBPLL_NDIV<<8) | (USBPLL_PDIV<<24)); + SCU_PLL->USBPLLCON = ((SCU_USBPLL_NDIV<<8) | (SCU_USBPLL_PDIV<<24)); + /* Setup USBDIV settings USB clock */ + SCU_CLK->USBCLKCR = SCU_USBDIV; /* we may have to set OSCDISCDIS */ SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_OSCDISCDIS_Msk; /* connect OSC_FI to PLL */ @@ -415,5 +696,10 @@ static void USBClockSetup(void) SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_RESLD_Msk; /* wait for PLL Lock */ while (!(SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOLOCK_Msk)); - } + + }/* end this weak function enables DAVE3 clock App usage */ + return(1); + +} #endif +