1 /*********************************************************************************************************************
2 * @file system_XMC4700.c
3 * @brief CMSIS Cortex-M4 Device Peripheral Access Layer Header File for the Infineon XMC4700 Device Series
4 * @version V1.0.6
5 * @date 29. Oct 2018
6 *
7 * @cond
8 *********************************************************************************************************************
9 * Copyright (c) 2015-2018, Infineon Technologies AG
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the
13 * following conditions are met:
14 *
15 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
19 * disclaimer in the documentation and/or other materials provided with the distribution.
20 *
21 * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
22 * products derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with
33 * Infineon Technologies AG dave@infineon.com).
34 *********************************************************************************************************************
35 *
36 ********************** Version History ***************************************
37 * V1.0.0, 03. Sep 2015, Initial version
38 * V1.0.1, 26. Jan 2016, Disable trap generation from clock unit
39 * V1.0.2, 01. Jun 2016, Fix masking of OSCHPCTRL value
40 * V1.0.3, 09. Feb 2017, Fix activation of USBPLL when SDMMC clock is enabled
41 * V1.0.4, 19. Jun 2017, Rely on cmsis_compiler.h instead of defining __WEAK
42 * Added support for ARM Compiler 6 (armclang)
43 * V1.0.5, 26. Sep 2017, Disable FPU if FPU_USED is zero
44 * V1.0.6, 29. Oct 2018, Fix variable location of SystemCoreClock and g_chipid for ARMCC compiler
45 ******************************************************************************
46 * @endcond
47 */
48
49 /*******************************************************************************
50 * Default clock initialization
51 * fPLL = 288MHz => fSYS = 144MHz => fCPU = 144MHz
52 * => fPB = 144MHz
53 * => fCCU = 144MHz
54 * => fETH = 72MHz
55 * => fUSB = 48MHz
56 * => fEBU = 72MHz
57 *
58 * fUSBPLL Disabled, only enabled if SCU_CLK_USBCLKCR_USBSEL_USBPLL is selected
59 *
60 * fOFI = 24MHz => fWDT = 24MHz
61 *******************************************************************************/
62
63 /*******************************************************************************
64 * HEADER FILES
65 *******************************************************************************/
66 #include <string.h>
67
68 #include <XMC4700.h>
69 #include "system_XMC4700.h"
70
71 /*******************************************************************************
72 * MACROS
73 *******************************************************************************/
74 #define CHIPID_LOC ((uint8_t *)0x20000000UL)
75
76 #define PMU_FLASH_WS (0x4U)
77
78 #define FOSCREF (2500000U)
79
80 #define DELAY_CNT_50US_50MHZ (2500UL)
81 #define DELAY_CNT_150US_50MHZ (7500UL)
82 #define DELAY_CNT_50US_48MHZ (2400UL)
83 #define DELAY_CNT_50US_72MHZ (3600UL)
84 #define DELAY_CNT_50US_96MHZ (4800UL)
85 #define DELAY_CNT_50US_120MHZ (6000UL)
86 #define DELAY_CNT_50US_144MHZ (7200UL)
87
88 #define SCU_PLL_PLLSTAT_OSC_USABLE (SCU_PLL_PLLSTAT_PLLHV_Msk | \
89 SCU_PLL_PLLSTAT_PLLLV_Msk | \
90 SCU_PLL_PLLSTAT_PLLSP_Msk)
91
92 /*
93 //-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
94 */
95
96 /*
97 // <h> Clock configuration
98 */
99
100 /*
101 // <o> External crystal frequency [Hz]
102 // <8000000=> 8MHz
103 // <12000000=> 12MHz
104 // <16000000=> 16MHz
105 // <i> Defines external crystal frequency
106 // <i> Default: 8MHz
107 */
108 #define OSCHP_FREQUENCY (12000000U)
109
110 /* USB PLL settings, fUSBPLL = 48MHz and fUSBPLLVCO = 384 MHz */
111 /* Note: Implicit divider of 2 and fUSBPLLVCO >= 260 MHz and fUSBPLLVCO <= 520 MHz*/
112 #if OSCHP_FREQUENCY == 8000000U
113 #define USB_PDIV (1U)
114 #define USB_NDIV (95U)
115
116 #elif OSCHP_FREQUENCY == 12000000U
117 #define USB_PDIV (1U)
118 #define USB_NDIV (63U)
119
120 #elif OSCHP_FREQUENCY == 16000000U
121 #define USB_PDIV (1U)
122 #define USB_NDIV (47U)
123
124 #else
125 #error "External crystal frequency not supported"
126
127 #endif
128
129 /*
130 // <o> Backup clock calibration mode
131 // <0=> Factory calibration
132 // <1=> Automatic calibration
133 // <i> Default: Automatic calibration
134 */
135 #define FOFI_CALIBRATION_MODE 1
136 #define FOFI_CALIBRATION_MODE_FACTORY 0
137 #define FOFI_CALIBRATION_MODE_AUTOMATIC 1
138
139 /*
140 // <o> Standby clock (fSTDBY) source selection
141 // <0=> Internal slow oscillator (32768Hz)
142 // <1=> External crystal (32768Hz)
143 // <i> Default: Internal slow oscillator (32768Hz)
144 */
145 #define STDBY_CLOCK_SRC 0
146 #define STDBY_CLOCK_SRC_OSI 0
147 #define STDBY_CLOCK_SRC_OSCULP 1
148
149 /*
150 // <o> PLL clock source selection
151 // <0=> External crystal
152 // <1=> Internal fast oscillator
153 // <i> Default: External crystal
154 */
155 #define PLL_CLOCK_SRC 0
156 #define PLL_CLOCK_SRC_EXT_XTAL 0
157 #define PLL_CLOCK_SRC_OFI 1
158
159 /* PLL settings, fPLL = 288MHz */
160 #if PLL_CLOCK_SRC == PLL_CLOCK_SRC_EXT_XTAL
161 #if OSCHP_FREQUENCY == 8000000U
162 #define PLL_PDIV (1U)
163 #define PLL_NDIV (71U)
164 #define PLL_K2DIV (0U)
165
166 #elif OSCHP_FREQUENCY == 12000000U
167 #define PLL_PDIV (1U)
168 #define PLL_NDIV (47U)
169 #define PLL_K2DIV (0U)
170
171 #elif OSCHP_FREQUENCY == 16000000U
172 #define PLL_PDIV (1U)
173 #define PLL_NDIV (35U)
174 #define PLL_K2DIV (0U)
175
176 #else
177 #error "External crystal frequency not supported"
178
179 #endif
180
181 #define VCO ((OSCHP_FREQUENCY / (PLL_PDIV + 1UL)) * (PLL_NDIV + 1UL))
182
183 #else /* PLL_CLOCK_SRC == PLL_CLOCK_SRC_EXT_XTAL */
184 #define PLL_PDIV (1U)
185 #define PLL_NDIV (23U)
186 #define PLL_K2DIV (0U)
187
188 #define VCO ((OFI_FREQUENCY / (PLL_PDIV + 1UL)) * (PLL_NDIV + 1UL))
189
190 #endif /* PLL_CLOCK_SRC == PLL_CLOCK_SRC_OFI */
191
192 #define PLL_K2DIV_24MHZ ((VCO / OFI_FREQUENCY) - 1UL)
193 #define PLL_K2DIV_48MHZ ((VCO / 48000000U) - 1UL)
194 #define PLL_K2DIV_72MHZ ((VCO / 72000000U) - 1UL)
195 #define PLL_K2DIV_96MHZ ((VCO / 96000000U) - 1UL)
196 #define PLL_K2DIV_120MHZ ((VCO / 120000000U) - 1UL)
197
198 #define SCU_CLK_CLKCLR_ENABLE_USBCLK SCU_CLK_CLKCLR_USBCDI_Msk
199 #define SCU_CLK_CLKCLR_ENABLE_MMCCLK SCU_CLK_CLKCLR_MMCCDI_Msk
200 #define SCU_CLK_CLKCLR_ENABLE_ETHCLK SCU_CLK_CLKCLR_ETH0CDI_Msk
201 #define SCU_CLK_CLKCLR_ENABLE_EBUCLK SCU_CLK_CLKCLR_EBUCDI_Msk
202 #define SCU_CLK_CLKCLR_ENABLE_CCUCLK SCU_CLK_CLKCLR_CCUCDI_Msk
203 #define SCU_CLK_CLKCLR_ENABLE_WDTCLK SCU_CLK_CLKCLR_WDTCDI_Msk
204
205 #define SCU_CLK_SYSCLKCR_SYSSEL_OFI (0U << SCU_CLK_SYSCLKCR_SYSSEL_Pos)
206 #define SCU_CLK_SYSCLKCR_SYSSEL_PLL (1U << SCU_CLK_SYSCLKCR_SYSSEL_Pos)
207
208 #define SCU_CLK_USBCLKCR_USBSEL_USBPLL (0U << SCU_CLK_USBCLKCR_USBSEL_Pos)
209 #define SCU_CLK_USBCLKCR_USBSEL_PLL (1U << SCU_CLK_USBCLKCR_USBSEL_Pos)
210
211 #define SCU_CLK_WDTCLKCR_WDTSEL_OFI (0U << SCU_CLK_WDTCLKCR_WDTSEL_Pos)
212 #define SCU_CLK_WDTCLKCR_WDTSEL_STANDBY (1U << SCU_CLK_WDTCLKCR_WDTSEL_Pos)
213 #define SCU_CLK_WDTCLKCR_WDTSEL_PLL (2U << SCU_CLK_WDTCLKCR_WDTSEL_Pos)
214
215 #define SCU_CLK_EXTCLKCR_ECKSEL_SYS (0U << SCU_CLK_EXTCLKCR_ECKSEL_Pos)
216 #define SCU_CLK_EXTCLKCR_ECKSEL_USBPLL (2U << SCU_CLK_EXTCLKCR_ECKSEL_Pos)
217 #define SCU_CLK_EXTCLKCR_ECKSEL_PLL (3U << SCU_CLK_EXTCLKCR_ECKSEL_Pos)
218
219 #define EXTCLK_PIN_P0_8 (1)
220 #define EXTCLK_PIN_P1_15 (2)
221
222 /*
223 // <h> Clock tree
224 // <o1.16> System clock source selection
225 // <0=> fOFI
226 // <1=> fPLL
227 // <i> Default: fPLL
228 // <o1.0..7> System clock divider <1-256><#-1>
229 // <i> Default: 2
230 // <o2.0> CPU clock divider
231 // <0=> fCPU = fSYS
232 // <1=> fCPU = fSYS / 2
233 // <i> Default: fCPU = fSYS
234 // <o3.0> Peripheral clock divider
235 // <0=> fPB = fCPU
236 // <1=> fPB = fCPU / 2
237 // <i> Default: fPB = fCPU
238 // <o4.0> CCU clock divider
239 // <0=> fCCU = fCPU
240 // <1=> fCCU = fCPU / 2
241 // <i> Default: fCCU = fCPU
242 // <e.5> Enable WDT clock
243 // <o5.16..17> WDT clock source <0=> fOFI
244 // <1=> fSTDBY
245 // <2=> fPLL
246 // <i> Default: fOFI
247 // <o5.0..7> WDT clock divider <1-256><#-1>
248 // <i> Default: 1
249 // </e>
250 // <e.3> Enable EBU clock
251 // <o6.0..5> EBU clock divider <1-64><#-1>
252 // <i> Default: 4
253 // </e>
254 // <e.2> Enable ETH clock
255 // </e>
256 // <e.1> Enable MMC clock
257 // </e>
258 // <e.0> Enable USB clock
259 // <o7.16> USB clock source <0=> fUSBPLL
260 // <1=> fPLL
261 // <i> Default: fPLL
262 // </e>
263 // <e8> Enable external clock
264 // <o8.0..1> External Clock Source Selection
265 // <0=> fSYS
266 // <2=> fUSB
267 // <3=> fPLL
268 // <i> Default: fPLL
269 // <o8.16..24> External Clock divider <1-512><#-1>
270 // <i> Default: 288
271 // <i> Only valid for USB PLL and PLL clocks
272 // <o9.0> External Clock Pin Selection
273 // <0=> Disabled
274 // <1=> P0.8
275 // <2=> P1.15
276 // <i> Default: Disabled
277 // </e>
278 // </h>
279 */
280 #define __CLKSET (0x00000000UL)
281 #define __SYSCLKCR (0x00010001UL)
282 #define __CPUCLKCR (0x00000000UL)
283 #define __PBCLKCR (0x00000000UL)
284 #define __CCUCLKCR (0x00000000UL)
285 #define __WDTCLKCR (0x00000000UL)
286 #define __EBUCLKCR (0x00000003UL)
287 #define __USBCLKCR (0x00010000UL)
288
289 #define __EXTCLKCR (0x01200003UL)
290 #define __EXTCLKPIN (0U)
291
292 /*
293 // </h>
294 */
295
296 /*
297 //-------- <<< end of configuration section >>> ------------------
298 */
299
300 #define ENABLE_PLL \
301 (((__SYSCLKCR & SCU_CLK_SYSCLKCR_SYSSEL_Msk) == SCU_CLK_SYSCLKCR_SYSSEL_PLL) || \
302 ((__CLKSET & SCU_CLK_CLKSET_EBUCEN_Msk) != 0) || \
303 (((__CLKSET & SCU_CLK_CLKSET_USBCEN_Msk) != 0) && ((__USBCLKCR & SCU_CLK_USBCLKCR_USBSEL_Msk) == SCU_CLK_USBCLKCR_USBSEL_PLL)) || \
304 (((__CLKSET & SCU_CLK_CLKSET_WDTCEN_Msk) != 0) && ((__WDTCLKCR & SCU_CLK_WDTCLKCR_WDTSEL_Msk) == SCU_CLK_WDTCLKCR_WDTSEL_PLL)))
305
306 #define ENABLE_USBPLL \
307 ((((__CLKSET & SCU_CLK_CLKSET_USBCEN_Msk) != 0) && ((__USBCLKCR & SCU_CLK_USBCLKCR_USBSEL_Msk) == SCU_CLK_USBCLKCR_USBSEL_USBPLL)) || \
308 (((__CLKSET & SCU_CLK_CLKSET_MMCCEN_Msk) != 0) && ((__USBCLKCR & SCU_CLK_USBCLKCR_USBSEL_Msk) == SCU_CLK_USBCLKCR_USBSEL_USBPLL)))
309
310 #if ((__USBCLKCR & SCU_CLK_USBCLKCR_USBSEL_Msk) == SCU_CLK_USBCLKCR_USBSEL_USBPLL)
311 #define USB_DIV (3U)
312 #else
313 #define USB_DIV (5U)
314 #endif
315
316 /*******************************************************************************
317 * GLOBAL VARIABLES
318 *******************************************************************************/
319 #if defined ( __CC_ARM )
320 #if defined(XMC4700_E196x2048) || defined(XMC4700_F144x2048) || defined(XMC4700_F100x2048)
321 uint32_t SystemCoreClock __attribute__((at(0x2003FFC0)));
322 uint8_t g_chipid[16] __attribute__((at(0x2003FFC4)));
323 #elif defined(XMC4700_E196x1536) || defined(XMC4700_F144x1536) || defined(XMC4700_F100x1536)
324 uint32_t SystemCoreClock __attribute__((at(0x2002CFC0)));
325 uint8_t g_chipid[16] __attribute__((at(0x2002CFC4)));
326 #else
327 #error "system_XMC4700.c: device not supported"
328 #endif
329 #elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
330 #if defined(XMC4700_E196x2048) || defined(XMC4700_F144x2048) || defined(XMC4700_F100x2048)
331 uint32_t SystemCoreClock __attribute__((section(".bss.ARM.__at_0x2003FFC0")));
332 uint8_t g_chipid[16] __attribute__((section(".bss.ARM.__at_0x2003FFC4")));
333 #elif defined(XMC4700_E196x1536) || defined(XMC4700_F144x1536) || defined(XMC4700_F100x1536)
334 uint32_t SystemCoreClock __attribute__((section(".bss.ARM.__at_0x2002CFC0")));
335 uint8_t g_chipid[16] __attribute__((section(".bss.ARM.__at_0x2002CFC4")));
336 #else
337 #error "system_XMC4700.c: device not supported"
338 #endif
339 #elif defined ( __ICCARM__ )
340 #if defined(XMC4700_E196x2048) || defined(XMC4700_F144x2048) || defined(XMC4700_F100x2048) || \
341 defined(XMC4700_E196x1536) || defined(XMC4700_F144x1536) || defined(XMC4700_F100x1536)
342 __no_init uint32_t SystemCoreClock;
343 __no_init uint8_t g_chipid[16];
344 #else
345 #error "system_XMC4700.c: device not supported"
346 #endif
347 #elif defined ( __GNUC__ )
348 #if defined(XMC4700_E196x2048) || defined(XMC4700_F144x2048) || defined(XMC4700_F100x2048) || \
349 defined(XMC4700_E196x1536) || defined(XMC4700_F144x1536) || defined(XMC4700_F100x1536)
350 uint32_t SystemCoreClock __attribute__((section(".noinit")));
351 uint8_t g_chipid[16] __attribute__((section(".noinit")));
352 #else
353 #error "system_XMC4700.c: device not supported"
354 #endif
355 #elif defined ( __TASKING__ )
356 #if defined(XMC4700_E196x2048) || defined(XMC4700_F144x2048) || defined(XMC4700_F100x2048)
357 uint32_t SystemCoreClock __at( 0x2003FFC0 );
358 uint8_t g_chipid[16] __at( 0x2003FFC4 );
359 #elif defined(XMC4700_E196x1536) || defined(XMC4700_F144x1536) || defined(XMC4700_F100x1536)
360 uint32_t SystemCoreClock __at( 0x2002CFC0 );
361 uint8_t g_chipid[16] __at( 0x2002CFC4 );
362 #else
363 #error "system_XMC4700.c: device not supported"
364 #endif
365 #else
366 #error "system_XMC4700.c: compiler not supported"
367 #endif
368
369 extern uint32_t __Vectors;
370
371 /*******************************************************************************
372 * LOCAL FUNCTIONS
373 *******************************************************************************/
delay(uint32_t cycles)374 static void delay(uint32_t cycles)
375 {
376 volatile uint32_t i;
377
378 for(i = 0UL; i < cycles ;++i)
379 {
380 __NOP();
381 }
382 }
383
384 /*******************************************************************************
385 * API IMPLEMENTATION
386 *******************************************************************************/
387
SystemInit(void)388 __WEAK void SystemInit(void)
389 {
390 memcpy(g_chipid, CHIPID_LOC, 16);
391
392 SystemCoreSetup();
393 SystemCoreClockSetup();
394 }
395
SystemCoreSetup(void)396 __WEAK void SystemCoreSetup(void)
397 {
398 uint32_t temp;
399
400 /* relocate vector table */
401 __disable_irq();
402 SCB->VTOR = (uint32_t)(&__Vectors);
403 __DSB();
404 __enable_irq();
405
406 /* __FPU_PRESENT = 1 defined in device header file */
407 /* __FPU_USED value depends on compiler/linker options. */
408 /* __FPU_USED = 0 if -mfloat-abi=soft is selected */
409 /* __FPU_USED = 1 if -mfloat-abi=softfp or –mfloat-abi=hard */
410
411 #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
412 SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
413 (3UL << 11*2) ); /* set CP11 Full Access */
414 #else
415 SCB->CPACR = 0;
416 #endif
417
418 /* Enable unaligned memory access - SCB_CCR.UNALIGN_TRP = 0 */
419 SCB->CCR &= ~(SCB_CCR_UNALIGN_TRP_Msk);
420
421 temp = FLASH0->FCON;
422 temp &= ~FLASH_FCON_WSPFLASH_Msk;
423 temp |= PMU_FLASH_WS;
424 FLASH0->FCON = temp;
425 }
426
SystemCoreClockSetup(void)427 __WEAK void SystemCoreClockSetup(void)
428 {
429 #if FOFI_CALIBRATION_MODE == FOFI_CALIBRATION_MODE_FACTORY
430 /* Enable factory calibration */
431 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FOTR_Msk;
432 #else
433 /* Automatic calibration uses the fSTDBY */
434
435 /* Enable HIB domain */
436 /* Power up HIB domain if and only if it is currently powered down */
437 if((SCU_POWER->PWRSTAT & SCU_POWER_PWRSTAT_HIBEN_Msk) == 0)
438 {
439 SCU_POWER->PWRSET |= SCU_POWER_PWRSET_HIB_Msk;
440
441 while((SCU_POWER->PWRSTAT & SCU_POWER_PWRSTAT_HIBEN_Msk) == 0)
442 {
443 /* wait until HIB domain is enabled */
444 }
445 }
446
447 /* Remove the reset only if HIB domain were in a state of reset */
448 if((SCU_RESET->RSTSTAT) & SCU_RESET_RSTSTAT_HIBRS_Msk)
449 {
450 SCU_RESET->RSTCLR |= SCU_RESET_RSTCLR_HIBRS_Msk;
451 delay(DELAY_CNT_150US_50MHZ);
452 }
453
454 #if STDBY_CLOCK_SRC == STDBY_CLOCK_SRC_OSCULP
455 /* Enable OSC_ULP */
456 if ((SCU_HIBERNATE->OSCULCTRL & SCU_HIBERNATE_OSCULCTRL_MODE_Msk) != 0UL)
457 {
458 /*enable OSC_ULP*/
459 while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_OSCULCTRL_Msk)
460 {
461 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
462 }
463 SCU_HIBERNATE->OSCULCTRL &= ~SCU_HIBERNATE_OSCULCTRL_MODE_Msk;
464
465 /* Check if the clock is OK using OSCULP Oscillator Watchdog*/
466 while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCR_Msk)
467 {
468 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
469 }
470 SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_ULPWDGEN_Msk;
471
472 /* wait till clock is stable */
473 do
474 {
475 while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCLR_Msk)
476 {
477 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
478 }
479 SCU_HIBERNATE->HDCLR |= SCU_HIBERNATE_HDCLR_ULPWDG_Msk;
480
481 delay(DELAY_CNT_50US_50MHZ);
482
483 } while ((SCU_HIBERNATE->HDSTAT & SCU_HIBERNATE_HDSTAT_ULPWDG_Msk) != 0UL);
484
485 }
486
487 /* now OSC_ULP is running and can be used*/
488 /* Select OSC_ULP as the clock source for RTC and STDBY*/
489 while (SCU_GENERAL->MIRRSTS & SCU_GENERAL_MIRRSTS_HDCR_Msk)
490 {
491 /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
492 }
493 SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_RCS_Msk | SCU_HIBERNATE_HDCR_STDBYSEL_Msk;
494 #endif /* STDBY_CLOCK_SRC == STDBY_CLOCK_SRC_OSCULP */
495
496 /* Enable automatic calibration of internal fast oscillator */
497 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_AOTREN_Msk;
498 #endif /* FOFI_CALIBRATION_MODE == FOFI_CALIBRATION_MODE_AUTOMATIC */
499
500 delay(DELAY_CNT_50US_50MHZ);
501
502 #if ENABLE_PLL
503
504 /* enable PLL */
505 SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk);
506
507 #if PLL_CLOCK_SRC != PLL_CLOCK_SRC_OFI
508 /* enable OSC_HP */
509 if ((SCU_OSC->OSCHPCTRL & SCU_OSC_OSCHPCTRL_MODE_Msk) != 0U)
510 {
511 SCU_OSC->OSCHPCTRL &= ~(SCU_OSC_OSCHPCTRL_MODE_Msk | SCU_OSC_OSCHPCTRL_OSCVAL_Msk);
512 SCU_OSC->OSCHPCTRL |= ((OSCHP_GetFrequency() / FOSCREF) - 1UL) << SCU_OSC_OSCHPCTRL_OSCVAL_Pos;
513
514 /* select OSC_HP clock as PLL input */
515 SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk;
516
517 /* restart OSC Watchdog */
518 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk;
519
520 while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_OSC_USABLE) != SCU_PLL_PLLSTAT_OSC_USABLE)
521 {
522 /* wait till OSC_HP output frequency is usable */
523 }
524 }
525 #else /* PLL_CLOCK_SRC != PLL_CLOCK_SRC_OFI */
526
527 /* select backup clock as PLL input */
528 SCU_PLL->PLLCON2 |= SCU_PLL_PLLCON2_PINSEL_Msk;
529 #endif
530
531 /* Go to bypass the Main PLL */
532 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_VCOBYP_Msk;
533
534 /* disconnect Oscillator from PLL */
535 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FINDIS_Msk;
536
537 /* Setup divider settings for main PLL */
538 SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) |
539 (PLL_K2DIV_24MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) |
540 (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos));
541
542 /* Set OSCDISCDIS */
543 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_OSCDISCDIS_Msk;
544
545 /* connect Oscillator to PLL */
546 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FINDIS_Msk;
547
548 /* restart PLL Lock detection */
549 SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_RESLD_Msk;
550
551 while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk) == 0U)
552 {
553 /* wait for PLL Lock at 24MHz*/
554 }
555
556 /* Disable bypass- put PLL clock back */
557 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_VCOBYP_Msk;
558 while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOBYST_Msk) != 0U)
559 {
560 /* wait for normal mode */
561 }
562 #endif /* ENABLE_PLL */
563
564 /* Before scaling to final frequency we need to setup the clock dividers */
565 SCU_CLK->SYSCLKCR = __SYSCLKCR;
566 SCU_CLK->PBCLKCR = __PBCLKCR;
567 SCU_CLK->CPUCLKCR = __CPUCLKCR;
568 SCU_CLK->CCUCLKCR = __CCUCLKCR;
569 SCU_CLK->WDTCLKCR = __WDTCLKCR;
570 SCU_CLK->EBUCLKCR = __EBUCLKCR;
571 SCU_CLK->USBCLKCR = __USBCLKCR | USB_DIV;
572 SCU_CLK->EXTCLKCR = __EXTCLKCR;
573
574 #if ENABLE_PLL
575 /* PLL frequency stepping...*/
576 /* Reset OSCDISCDIS */
577 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCDISCDIS_Msk;
578
579 SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) |
580 (PLL_K2DIV_48MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) |
581 (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos));
582
583 delay(DELAY_CNT_50US_48MHZ);
584
585 SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) |
586 (PLL_K2DIV_72MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) |
587 (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos));
588
589 delay(DELAY_CNT_50US_72MHZ);
590
591 SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) |
592 (PLL_K2DIV_96MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) |
593 (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos));
594
595 delay(DELAY_CNT_50US_96MHZ);
596
597 SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) |
598 (PLL_K2DIV_120MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) |
599 (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos));
600
601 delay(DELAY_CNT_50US_120MHZ);
602
603 SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) |
604 (PLL_K2DIV << SCU_PLL_PLLCON1_K2DIV_Pos) |
605 (PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos));
606
607 delay(DELAY_CNT_50US_144MHZ);
608
609 #endif /* ENABLE_PLL */
610
611 #if ENABLE_USBPLL
612 /* enable USB PLL first */
613 SCU_PLL->USBPLLCON &= ~(SCU_PLL_USBPLLCON_VCOPWD_Msk | SCU_PLL_USBPLLCON_PLLPWD_Msk);
614
615 /* USB PLL uses as clock input the OSC_HP */
616 /* check and if not already running enable OSC_HP */
617 if ((SCU_OSC->OSCHPCTRL & SCU_OSC_OSCHPCTRL_MODE_Msk) != 0U)
618 {
619 /* check if Main PLL is switched on for OSC WDG*/
620 if ((SCU_PLL->PLLCON0 &(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk)) != 0UL)
621 {
622 /* enable PLL first */
623 SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk);
624 }
625
626 SCU_OSC->OSCHPCTRL &= ~(SCU_OSC_OSCHPCTRL_MODE_Msk | SCU_OSC_OSCHPCTRL_OSCVAL_Msk);
627 SCU_OSC->OSCHPCTRL |= ((OSCHP_GetFrequency() / FOSCREF) - 1UL) << SCU_OSC_OSCHPCTRL_OSCVAL_Pos;
628
629 /* restart OSC Watchdog */
630 SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk;
631
632 while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_OSC_USABLE) != SCU_PLL_PLLSTAT_OSC_USABLE)
633 {
634 /* wait till OSC_HP output frequency is usable */
635 }
636 }
637
638
639 /* Setup USB PLL */
640 /* Go to bypass the USB PLL */
641 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_VCOBYP_Msk;
642
643 /* disconnect Oscillator from USB PLL */
644 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_FINDIS_Msk;
645
646 /* Setup Divider settings for USB PLL */
647 SCU_PLL->USBPLLCON = ((USB_NDIV << SCU_PLL_USBPLLCON_NDIV_Pos) |
648 (USB_PDIV << SCU_PLL_USBPLLCON_PDIV_Pos));
649
650 /* Set OSCDISCDIS */
651 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_OSCDISCDIS_Msk;
652
653 /* connect Oscillator to USB PLL */
654 SCU_PLL->USBPLLCON &= ~SCU_PLL_USBPLLCON_FINDIS_Msk;
655
656 /* restart PLL Lock detection */
657 SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_RESLD_Msk;
658
659 while ((SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOLOCK_Msk) == 0U)
660 {
661 /* wait for PLL Lock */
662 }
663 #endif
664
665
666 /* Enable selected clocks */
667 SCU_CLK->CLKSET = __CLKSET;
668
669 #if __EXTCLKPIN != 0
670 #if __EXTCLKPIN == EXTCLK_PIN_P1_15
671 /* P1.15 */
672 PORT1->PDR1 &= ~PORT1_PDR1_PD15_Msk;
673 PORT1->IOCR12 = (PORT1->IOCR12 & ~PORT0_IOCR12_PC15_Msk) | (0x11U << PORT0_IOCR12_PC15_Pos);
674 #else
675 /* P0.8 */
676 PORT0->HWSEL &= ~PORT0_HWSEL_HW8_Msk;
677 PORT0->PDR1 &= ~PORT0_PDR1_PD8_Msk;
678 PORT0->IOCR8 = (PORT0->IOCR8 & ~PORT0_IOCR8_PC8_Msk) | (0x11U << PORT0_IOCR8_PC8_Pos);
679 #endif
680 #endif /* ENABLE_EXTCLK == 1 */
681
682 SystemCoreClockUpdate();
683 }
684
SystemCoreClockUpdate(void)685 __WEAK void SystemCoreClockUpdate(void)
686 {
687 uint32_t pdiv;
688 uint32_t ndiv;
689 uint32_t kdiv;
690 uint32_t temp;
691
692 if (SCU_CLK->SYSCLKCR & SCU_CLK_SYSCLKCR_SYSSEL_Msk)
693 {
694 /* fPLL is clock source for fSYS */
695 if(SCU_PLL->PLLCON2 & SCU_PLL_PLLCON2_PINSEL_Msk)
696 {
697 /* PLL input clock is the backup clock (fOFI) */
698 temp = OFI_FREQUENCY;
699 }
700 else
701 {
702 /* PLL input clock is the high performance osicllator (fOSCHP) */
703 temp = OSCHP_GetFrequency();
704 }
705
706 /* check if PLL is locked */
707 if (SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk)
708 {
709 /* PLL normal mode */
710 /* read back divider settings */
711 pdiv = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_PDIV_Msk) >> SCU_PLL_PLLCON1_PDIV_Pos) + 1;
712 ndiv = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_NDIV_Msk) >> SCU_PLL_PLLCON1_NDIV_Pos) + 1;
713 kdiv = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_K2DIV_Msk) >> SCU_PLL_PLLCON1_K2DIV_Pos) + 1;
714
715 temp = (temp / (pdiv * kdiv)) * ndiv;
716 }
717 else
718 {
719 /* PLL prescalar mode */
720 /* read back divider settings */
721 kdiv = ((SCU_PLL->PLLCON1 & SCU_PLL_PLLCON1_K1DIV_Msk) >> SCU_PLL_PLLCON1_K1DIV_Pos) + 1;
722
723 temp = (temp / kdiv);
724 }
725 }
726 else
727 {
728 /* fOFI is clock source for fSYS */
729 temp = OFI_FREQUENCY;
730 }
731
732 temp = temp / ((SCU_CLK->SYSCLKCR & SCU_CLK_SYSCLKCR_SYSDIV_Msk) + 1);
733 temp = temp / ((SCU_CLK->CPUCLKCR & SCU_CLK_CPUCLKCR_CPUDIV_Msk) + 1);
734
735 SystemCoreClock = temp;
736 }
737
OSCHP_GetFrequency(void)738 __WEAK uint32_t OSCHP_GetFrequency(void)
739 {
740 return OSCHP_FREQUENCY;
741 }
742