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
39 /*----------------------------------------------------------------------------
\r
40 Keil pragma to prevent warnings
\r
41 *----------------------------------------------------------------------------*/
\r
42 #if defined(__ARMCC_VERSION)
\r
43 #pragma diag_suppress 177
\r
47 //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
\r
52 /*--------------------- Watchdog Configuration -------------------------------
\r
54 // <e> Watchdog Configuration
\r
55 // <o1.0> Disable Watchdog
\r
60 #define WDTENB_nVal 0x00000001
\r
62 /*--------------------- CLOCK Configuration -------------------------------
\r
64 // <e> Main Clock Configuration
\r
65 // <o1.0..1> CPU clock divider
\r
66 // <0=> fCPU = fSYS
\r
67 // <1=> fCPU = fSYS / 2
\r
68 // <o2.0..1> Peripheral Bus clock divider
\r
70 // <1=> fPB = fCPU / 2
\r
71 // <o3.0..1> CCU Bus clock divider
\r
73 // <1=> fCCU = fCPU / 2
\r
79 #define SCU_CLOCK_SETUP 1
\r
80 #define SCU_CPUCLKCR_DIV 0x00000000
\r
81 #define SCU_PBCLKCR_DIV 0x00000000
\r
82 #define SCU_CCUCLKCR_DIV 0x00000000
\r
86 /*--------------------- USB CLOCK Configuration ---------------------------
\r
88 // <e> USB Clock Configuration
\r
94 #define SCU_USB_CLOCK_SETUP 0
\r
97 /*--------------------- CLOCKOUT Configuration -------------------------------
\r
99 // <e> Clock OUT Configuration
\r
100 // <o1.0..1> Clockout Source Selection
\r
101 // <0=> System Clock
\r
103 // <3=> Divided value of PLL Clock
\r
104 // <o2.0..1> Clockout Pin Selection
\r
113 #define SCU_CLOCKOUT_SETUP 0 // recommended to keep disabled
\r
114 #define SCU_CLOCKOUT_SOURCE 0x00000000
\r
115 #define SCU_CLOCKOUT_PIN 0x00000000
\r
117 /*----------------------------------------------------------------------------
\r
118 static functions declarations
\r
119 *----------------------------------------------------------------------------*/
\r
120 #if (SCU_CLOCK_SETUP == 1)
\r
121 static int SystemClockSetup(void);
\r
124 #if (SCU_USB_CLOCK_SETUP == 1)
\r
125 static void USBClockSetup(void);
\r
129 * @brief Setup the microcontroller system.
\r
130 * Initialize the PLL and update the
\r
131 * SystemCoreClock variable.
\r
135 void SystemInit(void)
\r
137 /* Setup the WDT */
\r
138 #if (WDT_SETUP == 1)
\r
139 WDT->CTR &= ~WDTENB_nVal;
\r
142 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
\r
143 SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
\r
144 (3UL << 11*2) ); /* set CP11 Full Access */
\r
147 /* Disable branch prediction - PCON.PBS = 1 */
\r
148 PREF->PCON |= (PREF_PCON_PBS_Msk);
\r
150 /* Enable unaligned memory access - SCB_CCR.UNALIGN_TRP = 0 */
\r
151 SCB->CCR &= ~(SCB_CCR_UNALIGN_TRP_Msk);
\r
153 /* Setup the clockout */
\r
154 /* README README README README README README README README README README */
\r
156 * Please use the CLOCKOUT feature with diligence. Use this only if you know
\r
157 * what you are doing.
\r
159 * You must be aware that the settings below can potentially be in conflict
\r
160 * with DAVE code generation engine preferences.
\r
162 * Even worse, the setting below configures the ports as output ports while in
\r
163 * reality, the board on which this chip is mounted may have a source driving
\r
166 * So use this feature only when you are absolutely sure that the port must
\r
167 * indeed be configured as an output AND you are NOT linking this startup code
\r
168 * with code that was generated by DAVE code engine.
\r
170 #if (SCU_CLOCKOUT_SETUP == 1)
\r
171 SCU_CLK->EXTCLKCR |= SCU_CLOCKOUT_SOURCE;
\r
173 if (SCU_CLOCKOUT_PIN) {
\r
174 PORT0->IOCR8 = 0x00000088; /*P0.8 --> ALT1 select + HWSEL */
\r
175 PORT0->HWSEL &= (~PORT0_HWSEL_HW8_Msk);
\r
177 else PORT1->IOCR12 = 0x88000000; /*P1.15--> ALT1 select */
\r
180 /* Setup the System clock */
\r
181 #if (SCU_CLOCK_SETUP == 1)
\r
182 SystemClockSetup();
\r
185 /* Setup the USB PL */
\r
186 #if (SCU_USB_CLOCK_SETUP == 1)
\r
194 * @brief Update SystemCoreClock according to Clock Register Values
\r
199 void SystemCoreClockUpdate(void)
\r
202 /*----------------------------------------------------------------------------
\r
203 Clock Variable definitions
\r
204 *----------------------------------------------------------------------------*/
\r
205 SystemCoreClock = SYSTEM_FREQUENCY;/*!< System Clock Frequency (Core Clock)*/
\r
216 #if (SCU_CLOCK_SETUP == 1)
\r
217 static int SystemClockSetup(void)
\r
219 /* enable PLL first */
\r
220 SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk |
\r
221 SCU_PLL_PLLCON0_PLLPWD_Msk);
\r
223 /* Enable OSC_HP */
\r
224 if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL)
\r
226 /* Enable the OSC_HP*/
\r
227 SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4);
\r
228 /* Setup OSC WDG devider */
\r
229 SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16);
\r
230 /* Select external OSC as PLL input */
\r
231 SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk;
\r
232 /* Restart OSC Watchdog */
\r
233 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk;
\r
237 ; /* here a timeout need to be added */
\r
238 }while(!( (SCU_PLL->PLLSTAT) &
\r
239 (SCU_PLL_PLLSTAT_PLLHV_Msk | SCU_PLL_PLLSTAT_PLLLV_Msk |
\r
240 SCU_PLL_PLLSTAT_PLLSP_Msk)
\r
246 /* Setup Main PLL */
\r
247 /* Select FOFI as system clock */
\r
248 if(SCU_CLK->SYSCLKCR != 0X000000)
\r
249 SCU_CLK->SYSCLKCR = 0x00000000; /*Select FOFI*/
\r
251 /* Go to bypass the Main PLL */
\r
252 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_VCOBYP_Msk;
\r
254 /* disconnect OSC_HP to PLL */
\r
255 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FINDIS_Msk;
\r
257 /* Setup devider settings for main PLL */
\r
258 SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) |
\r
259 (PLL_K2DIV_STEP_1<<16) | (PLL_PDIV<<24));
\r
261 /* we may have to set OSCDISCDIS */
\r
262 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_OSCDISCDIS_Msk;
\r
264 /* connect OSC_HP to PLL */
\r
265 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FINDIS_Msk;
\r
267 /* restart PLL Lock detection */
\r
268 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_RESLD_Msk;
\r
270 /* wait for PLL Lock */
\r
271 while (!(SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk));
\r
273 /* Go back to the Main PLL */
\r
274 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_VCOBYP_Msk;
\r
276 /*********************************************************
\r
277 here we need to setup the system clock divider
\r
278 *********************************************************/
\r
280 SCU_CLK->CPUCLKCR = SCU_CPUCLKCR_DIV;
\r
281 SCU_CLK->PBCLKCR = SCU_PBCLKCR_DIV;
\r
282 SCU_CLK->CCUCLKCR = SCU_CCUCLKCR_DIV;
\r
284 /* Switch system clock to PLL */
\r
285 SCU_CLK->SYSCLKCR |= 0x00010000;
\r
287 /*********************************************************
\r
288 here the ramp up of the system clock starts
\r
289 *********************************************************/
\r
290 /* Delay for next K2 step ~50µs */
\r
291 /********************************/
\r
292 /* Set reload register */
\r
293 SysTick->LOAD = ((1250+100) & SysTick_LOAD_RELOAD_Msk) - 1;
\r
295 /* Load the SysTick Counter Value */
\r
298 /* Enable SysTick IRQ and SysTick Timer */
\r
299 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
\r
300 SysTick_CTRL_ENABLE_Msk;
\r
302 /* wait for ~50µs */
\r
303 while (SysTick->VAL >= 100);
\r
305 /* Stop SysTick Timer */
\r
306 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
\r
307 /********************************/
\r
309 /* Setup devider settings for main PLL */
\r
310 SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) |
\r
311 (PLL_K2DIV_STEP_2<<16) | (PLL_PDIV<<24));
\r
313 /* Delay for next K2 step ~50µs */
\r
314 /********************************/
\r
315 SysTick->LOAD = ((3000+100) & SysTick_LOAD_RELOAD_Msk) - 1;
\r
317 /* Load the SysTick Counter Value */
\r
320 /* Enable SysTick IRQ and SysTick Timer */
\r
321 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
\r
323 /* Wait for ~50µs */
\r
324 while (SysTick->VAL >= 100);
\r
326 /* Stop SysTick Timer */
\r
327 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
\r
328 /********************************/
\r
330 /* Setup devider settings for main PLL */
\r
331 SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) |
\r
332 (PLL_K2DIV_STEP_3<<16) | (PLL_PDIV<<24));
\r
334 /* Delay for next K2 step ~50µs */
\r
335 /********************************/
\r
336 SysTick->LOAD = ((4800+100) & SysTick_LOAD_RELOAD_Msk) - 1;
\r
338 /* Load the SysTick Counter Value */
\r
341 /* Enable SysTick IRQ and SysTick Timer */
\r
342 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
\r
344 /* Wait for ~50µs */
\r
345 while (SysTick->VAL >= 100);
\r
347 /* Stop SysTick Timer */
\r
348 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
\r
349 /********************************/
\r
351 /* Setup devider settings for main PLL */
\r
352 SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | (PLL_K2DIV<<16) |
\r
355 /* clear request for System OCS Watchdog Trap and System VCO Lock Trap */
\r
356 SCU_TRAP->TRAPCLR = SCU_TRAP_TRAPCLR_SOSCWDGT_Msk |
\r
357 SCU_TRAP_TRAPCLR_SVCOLCKT_Msk;
\r
370 #if(SCU_USB_CLOCK_SETUP == 1)
\r
371 static void USBClockSetup(void)
\r
373 /* enable PLL first */
\r
374 SCU_PLL->USBPLLCON &= ~(SCU_PLL_USBPLLCON_VCOPWD_Msk |
\r
375 SCU_PLL_USBPLLCON_PLLPWD_Msk);
\r
377 /* check and if not already running enable OSC_HP */
\r
378 if(!((SCU_PLL->PLLSTAT) &
\r
379 (SCU_PLL_PLLSTAT_PLLHV_Msk |
\r
380 SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk)))
\r
382 if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL)
\r
385 SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4); /*enable the OSC_HP*/
\r
386 /* setup OSC WDG devider */
\r
387 SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16);
\r
388 /* select external OSC as PLL input */
\r
389 SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk;
\r
390 /* restart OSC Watchdog */
\r
391 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk;
\r
395 ; /* here a timeout need to be added */
\r
396 }while(!((SCU_PLL->PLLSTAT) & (SCU_PLL_PLLSTAT_PLLHV_Msk |
\r
397 SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk)));
\r
403 /* Setup USB PLL */
\r
404 /* Go to bypass the Main PLL */
\r
405 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_VCOBYP_Msk;
\r
406 /* disconnect OSC_FI to PLL */
\r
407 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_FINDIS_Msk;
\r
408 /* Setup devider settings for main PLL */
\r
409 SCU_PLL->USBPLLCON = ((USBPLL_NDIV<<8) | (USBPLL_PDIV<<24));
\r
410 /* we may have to set OSCDISCDIS */
\r
411 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_OSCDISCDIS_Msk;
\r
412 /* connect OSC_FI to PLL */
\r
413 SCU_PLL->USBPLLCON &= ~SCU_PLL_USBPLLCON_FINDIS_Msk;
\r
414 /* restart PLL Lock detection */
\r
415 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_RESLD_Msk;
\r
416 /* wait for PLL Lock */
\r
417 while (!(SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOLOCK_Msk));
\r