1 /******************************************************************************
\r
2 * @file system_XMC4500.c
\r
3 * @brief Device specific initialization for the XMC4500-Series according to CMSIS
\r
5 * @date 20. January 2012
\r
8 * Copyright (C) 2011 Infineon Technologies AG. All rights reserved.
\r
12 * Infineon Technologies AG (Infineon) is supplying this software for use with Infineon
\92s microcontrollers.
\r
13 * This file can be freely distributed within development tools that are supporting such microcontrollers.
\r
17 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
\r
18 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
\r
20 * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
\r
21 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
\r
24 ******************************************************************************/
\r
26 #include "System_XMC4500.h"
\r
27 #include <XMC4500.h>
\r
29 /*----------------------------------------------------------------------------
\r
30 Define clocks is located in System_XMC4500.h
\r
31 *----------------------------------------------------------------------------*/
\r
33 /*----------------------------------------------------------------------------
\r
34 Clock Variable definitions
\r
35 *----------------------------------------------------------------------------*/
\r
36 /*!< System Clock Frequency (Core Clock)*/
\r
37 uint32_t SystemCoreClock = CLOCK_OSC_HP;
\r
40 //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
\r
45 /*--------------------- Watchdog Configuration -------------------------------
\r
47 // <e> Watchdog Configuration
\r
48 // <o1.0> Disable Watchdog
\r
53 #define WDTENB_nVal 0x00000001
\r
55 /*--------------------- CLOCK Configuration -------------------------------
\r
57 // <e> Main Clock Configuration
\r
58 // <o1.0..1> CPU clock divider
\r
59 // <0=> fCPU = fSYS
\r
60 // <1=> fCPU = fSYS / 2
\r
61 // <o2.0..1> Peripheral Bus clock divider
\r
63 // <1=> fPB = fCPU / 2
\r
64 // <o3.0..1> CCU Bus clock divider
\r
66 // <1=> fCCU = fCPU / 2
\r
72 #define SCU_CLOCK_SETUP 1
\r
73 #define SCU_CPUCLKCR_DIV 0x00000000
\r
74 #define SCU_PBCLKCR_DIV 0x00000000
\r
75 #define SCU_CCUCLKCR_DIV 0x00000000
\r
79 /*--------------------- USB CLOCK Configuration ---------------------------
\r
81 // <e> USB Clock Configuration
\r
87 #define SCU_USB_CLOCK_SETUP 0
\r
90 /*--------------------- CLOCKOUT Configuration -------------------------------
\r
92 // <e> Clock OUT Configuration
\r
93 // <o1.0..1> Clockout Source Selection
\r
94 // <0=> System Clock
\r
96 // <3=> Divided value of PLL Clock
\r
97 // <o2.0..1> Clockout Pin Selection
\r
106 #define SCU_CLOCKOUT_SETUP 0 // recommended to keep disabled
\r
107 #define SCU_CLOCKOUT_SOURCE 0x00000000
\r
108 #define SCU_CLOCKOUT_PIN 0x00000000
\r
110 /*----------------------------------------------------------------------------
\r
111 static functions declarations
\r
112 *----------------------------------------------------------------------------*/
\r
113 #if (SCU_CLOCK_SETUP == 1)
\r
114 static int SystemClockSetup(void);
\r
117 #if (SCU_USB_CLOCK_SETUP == 1)
\r
118 static void USBClockSetup(void);
\r
122 * @brief Setup the microcontroller system.
\r
123 * Initialize the PLL and update the
\r
124 * SystemCoreClock variable.
\r
128 void SystemInit(void)
\r
130 /* Setup the WDT */
\r
131 #if (WDT_SETUP == 1)
\r
132 WDT->CTR &= ~WDTENB_nVal;
\r
135 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
\r
136 SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
\r
137 (3UL << 11*2) ); /* set CP11 Full Access */
\r
140 /* Disable branch prediction - PCON.PBS = 1 */
\r
141 PREF->PCON |= (PREF_PCON_PBS_Msk);
\r
143 /* Enable unaligned memory access - SCB_CCR.UNALIGN_TRP = 0 */
\r
144 SCB->CCR &= ~(SCB_CCR_UNALIGN_TRP_Msk);
\r
146 /* Setup the clockout */
\r
147 /* README README README README README README README README README README */
\r
149 * Please use the CLOCKOUT feature with diligence. Use this only if you know
\r
150 * what you are doing.
\r
152 * You must be aware that the settings below can potentially be in conflict
\r
153 * with DAVE code generation engine preferences.
\r
155 * Even worse, the setting below configures the ports as output ports while in
\r
156 * reality, the board on which this chip is mounted may have a source driving
\r
159 * So use this feature only when you are absolutely sure that the port must
\r
160 * indeed be configured as an output AND you are NOT linking this startup code
\r
161 * with code that was generated by DAVE code engine.
\r
163 #if (SCU_CLOCKOUT_SETUP == 1)
\r
164 SCU_CLK->EXTCLKCR |= SCU_CLOCKOUT_SOURCE;
\r
166 if (SCU_CLOCKOUT_PIN) {
\r
167 PORT0->IOCR8 = 0x00000088; /*P0.8 --> ALT1 select + HWSEL */
\r
168 PORT0->HWSEL &= (~PORT0_HWSEL_HW8_Msk);
\r
170 else PORT1->IOCR12 = 0x88000000; /*P1.15--> ALT1 select */
\r
173 /* Setup the System clock */
\r
174 #if (SCU_CLOCK_SETUP == 1)
\r
175 SystemClockSetup();
\r
178 /* Setup the USB PL */
\r
179 #if (SCU_USB_CLOCK_SETUP == 1)
\r
187 * @brief Update SystemCoreClock according to Clock Register Values
\r
192 void SystemCoreClockUpdate(void)
\r
195 /*----------------------------------------------------------------------------
\r
196 Clock Variable definitions
\r
197 *----------------------------------------------------------------------------*/
\r
198 SystemCoreClock = SYSTEM_FREQUENCY;/*!< System Clock Frequency (Core Clock)*/
\r
209 #if (SCU_CLOCK_SETUP == 1)
\r
210 static int SystemClockSetup(void)
\r
212 /* enable PLL first */
\r
213 SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk |
\r
214 SCU_PLL_PLLCON0_PLLPWD_Msk);
\r
216 /* Enable OSC_HP */
\r
217 if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL)
\r
219 /* Enable the OSC_HP*/
\r
220 SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4);
\r
221 /* Setup OSC WDG devider */
\r
222 SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16);
\r
223 /* Select external OSC as PLL input */
\r
224 SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk;
\r
225 /* Restart OSC Watchdog */
\r
226 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk;
\r
230 ; /* here a timeout need to be added */
\r
231 }while(!( (SCU_PLL->PLLSTAT) &
\r
232 (SCU_PLL_PLLSTAT_PLLHV_Msk | SCU_PLL_PLLSTAT_PLLLV_Msk |
\r
233 SCU_PLL_PLLSTAT_PLLSP_Msk)
\r
239 /* Setup Main PLL */
\r
240 /* Select FOFI as system clock */
\r
241 if(SCU_CLK->SYSCLKCR != 0X000000)
\r
242 SCU_CLK->SYSCLKCR = 0x00000000; /*Select FOFI*/
\r
244 /* Go to bypass the Main PLL */
\r
245 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_VCOBYP_Msk;
\r
247 /* disconnect OSC_HP to PLL */
\r
248 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FINDIS_Msk;
\r
250 /* Setup devider settings for main PLL */
\r
251 SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) |
\r
252 (PLL_K2DIV_STEP_1<<16) | (PLL_PDIV<<24));
\r
254 /* we may have to set OSCDISCDIS */
\r
255 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_OSCDISCDIS_Msk;
\r
257 /* connect OSC_HP to PLL */
\r
258 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FINDIS_Msk;
\r
260 /* restart PLL Lock detection */
\r
261 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_RESLD_Msk;
\r
263 /* wait for PLL Lock */
\r
264 while (!(SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk));
\r
266 /* Go back to the Main PLL */
\r
267 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_VCOBYP_Msk;
\r
269 /*********************************************************
\r
270 here we need to setup the system clock divider
\r
271 *********************************************************/
\r
273 SCU_CLK->CPUCLKCR = SCU_CPUCLKCR_DIV;
\r
274 SCU_CLK->PBCLKCR = SCU_PBCLKCR_DIV;
\r
275 SCU_CLK->CCUCLKCR = SCU_CCUCLKCR_DIV;
\r
277 /* Switch system clock to PLL */
\r
278 SCU_CLK->SYSCLKCR |= 0x00010000;
\r
280 /*********************************************************
\r
281 here the ramp up of the system clock starts
\r
282 *********************************************************/
\r
283 /* Delay for next K2 step ~50µs */
\r
284 /********************************/
\r
285 /* Set reload register */
\r
286 SysTick->LOAD = ((1250+100) & SysTick_LOAD_RELOAD_Msk) - 1;
\r
288 /* Load the SysTick Counter Value */
\r
291 /* Enable SysTick IRQ and SysTick Timer */
\r
292 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
\r
293 SysTick_CTRL_ENABLE_Msk;
\r
295 /* wait for ~50µs */
\r
296 while (SysTick->VAL >= 100);
\r
298 /* Stop SysTick Timer */
\r
299 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
\r
300 /********************************/
\r
302 /* Setup devider settings for main PLL */
\r
303 SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) |
\r
304 (PLL_K2DIV_STEP_2<<16) | (PLL_PDIV<<24));
\r
306 /* Delay for next K2 step ~50µs */
\r
307 /********************************/
\r
308 SysTick->LOAD = ((3000+100) & SysTick_LOAD_RELOAD_Msk) - 1;
\r
310 /* Load the SysTick Counter Value */
\r
313 /* Enable SysTick IRQ and SysTick Timer */
\r
314 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
\r
316 /* Wait for ~50µs */
\r
317 while (SysTick->VAL >= 100);
\r
319 /* Stop SysTick Timer */
\r
320 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
\r
321 /********************************/
\r
323 /* Setup devider settings for main PLL */
\r
324 SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) |
\r
325 (PLL_K2DIV_STEP_3<<16) | (PLL_PDIV<<24));
\r
327 /* Delay for next K2 step ~50µs */
\r
328 /********************************/
\r
329 SysTick->LOAD = ((4800+100) & SysTick_LOAD_RELOAD_Msk) - 1;
\r
331 /* Load the SysTick Counter Value */
\r
334 /* Enable SysTick IRQ and SysTick Timer */
\r
335 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
\r
337 /* Wait for ~50µs */
\r
338 while (SysTick->VAL >= 100);
\r
340 /* Stop SysTick Timer */
\r
341 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
\r
342 /********************************/
\r
344 /* Setup devider settings for main PLL */
\r
345 SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | (PLL_K2DIV<<16) |
\r
348 /* clear request for System OCS Watchdog Trap and System VCO Lock Trap */
\r
349 SCU_TRAP->TRAPCLR = SCU_TRAP_TRAPCLR_SOSCWDGT_Msk |
\r
350 SCU_TRAP_TRAPCLR_SVCOLCKT_Msk;
\r
363 #if(SCU_USB_CLOCK_SETUP == 1)
\r
364 static void USBClockSetup(void)
\r
366 /* enable PLL first */
\r
367 SCU_PLL->USBPLLCON &= ~(SCU_PLL_USBPLLCON_VCOPWD_Msk |
\r
368 SCU_PLL_USBPLLCON_PLLPWD_Msk);
\r
370 /* check and if not already running enable OSC_HP */
\r
371 if(!((SCU_PLL->PLLSTAT) &
\r
372 (SCU_PLL_PLLSTAT_PLLHV_Msk |
\r
373 SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk)))
\r
375 if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL)
\r
378 SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4); /*enable the OSC_HP*/
\r
379 /* setup OSC WDG devider */
\r
380 SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16);
\r
381 /* select external OSC as PLL input */
\r
382 SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk;
\r
383 /* restart OSC Watchdog */
\r
384 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk;
\r
388 ; /* here a timeout need to be added */
\r
389 }while(!((SCU_PLL->PLLSTAT) & (SCU_PLL_PLLSTAT_PLLHV_Msk |
\r
390 SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk)));
\r
396 /* Setup USB PLL */
\r
397 /* Go to bypass the Main PLL */
\r
398 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_VCOBYP_Msk;
\r
399 /* disconnect OSC_FI to PLL */
\r
400 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_FINDIS_Msk;
\r
401 /* Setup devider settings for main PLL */
\r
402 SCU_PLL->USBPLLCON = ((USBPLL_NDIV<<8) | (USBPLL_PDIV<<24));
\r
403 /* we may have to set OSCDISCDIS */
\r
404 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_OSCDISCDIS_Msk;
\r
405 /* connect OSC_FI to PLL */
\r
406 SCU_PLL->USBPLLCON &= ~SCU_PLL_USBPLLCON_FINDIS_Msk;
\r
407 /* restart PLL Lock detection */
\r
408 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_RESLD_Msk;
\r
409 /* wait for PLL Lock */
\r
410 while (!(SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOLOCK_Msk));
\r