aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S16/system_LPC55S16.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S16/system_LPC55S16.c')
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S16/system_LPC55S16.c401
1 files changed, 401 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S16/system_LPC55S16.c b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S16/system_LPC55S16.c
new file mode 100644
index 000000000..6e00b0883
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S16/system_LPC55S16.c
@@ -0,0 +1,401 @@
1/*
2** ###################################################################
3** Processors: LPC55S16JBD100
4** LPC55S16JBD64
5** LPC55S16JEV98
6**
7** Compilers: GNU C Compiler
8** IAR ANSI C/C++ Compiler for ARM
9** Keil ARM C/C++ Compiler
10** MCUXpresso Compiler
11**
12** Reference manual: LPC55S1x/LPC551x User manual Rev.0.6 15 November 2019
13** Version: rev. 1.1, 2019-12-03
14** Build: b201015
15**
16** Abstract:
17** Provides a system configuration function and a global variable that
18** contains the system frequency. It configures the device and initializes
19** the oscillator (PLL) that is part of the microcontroller device.
20**
21** Copyright 2016 Freescale Semiconductor, Inc.
22** Copyright 2016-2020 NXP
23** All rights reserved.
24**
25** SPDX-License-Identifier: BSD-3-Clause
26**
27** http: www.nxp.com
28** mail: [email protected]
29**
30** Revisions:
31** - rev. 1.0 (2018-08-22)
32** Initial version based on v0.2UM
33** - rev. 1.1 (2019-12-03)
34** Initial version based on v0.6UM
35**
36** ###################################################################
37*/
38
39/*!
40 * @file LPC55S16
41 * @version 1.1
42 * @date 2019-12-03
43 * @brief Device specific configuration file for LPC55S16 (implementation file)
44 *
45 * Provides a system configuration function and a global variable that contains
46 * the system frequency. It configures the device and initializes the oscillator
47 * (PLL) that is part of the microcontroller device.
48 */
49
50#include <stdint.h>
51#include "fsl_device_registers.h"
52
53/* PLL0 SSCG control1 */
54#define PLL_SSCG_MD_FRACT_P 0U
55#define PLL_SSCG_MD_INT_P 25U
56#define PLL_SSCG_MD_FRACT_M (0x1FFFFFFUL << PLL_SSCG_MD_FRACT_P)
57#define PLL_SSCG_MD_INT_M ((uint64_t)0xFFUL << PLL_SSCG_MD_INT_P)
58
59/* Get predivider (N) from PLL0 NDEC setting */
60static uint32_t findPll0PreDiv(void)
61{
62 uint32_t preDiv = 1UL;
63
64 /* Direct input is not used? */
65 if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPREDIV_MASK) == 0UL)
66 {
67 preDiv = SYSCON->PLL0NDEC & SYSCON_PLL0NDEC_NDIV_MASK;
68 if (preDiv == 0UL)
69 {
70 preDiv = 1UL;
71 }
72 }
73 return preDiv;
74}
75
76/* Get postdivider (P) from PLL0 PDEC setting */
77static uint32_t findPll0PostDiv(void)
78{
79 uint32_t postDiv = 1;
80
81 if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPOSTDIV_MASK) == 0UL)
82 {
83 if ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPOSTDIV2_MASK) != 0UL)
84 {
85 postDiv = SYSCON->PLL0PDEC & SYSCON_PLL0PDEC_PDIV_MASK;
86 }
87 else
88 {
89 postDiv = 2UL * (SYSCON->PLL0PDEC & SYSCON_PLL0PDEC_PDIV_MASK);
90 }
91 if (postDiv == 0UL)
92 {
93 postDiv = 2UL;
94 }
95 }
96 return postDiv;
97}
98
99/* Get multiplier (M) from PLL0 SSCG and SEL_EXT settings */
100static float findPll0MMult(void)
101{
102 float mMult = 1.0F;
103 float mMult_fract;
104 uint32_t mMult_int;
105
106 if ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_SEL_EXT_MASK) != 0UL)
107 {
108 mMult =
109 (float)(uint32_t)((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MDIV_EXT_MASK) >> SYSCON_PLL0SSCG1_MDIV_EXT_SHIFT);
110 }
111 else
112 {
113 mMult_int = ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MD_MBS_MASK) << 7U);
114 mMult_int = mMult_int | ((SYSCON->PLL0SSCG0) >> PLL_SSCG_MD_INT_P);
115 mMult_fract = ((float)(uint32_t)((SYSCON->PLL0SSCG0) & PLL_SSCG_MD_FRACT_M) /
116 (float)(uint32_t)(1UL << PLL_SSCG_MD_INT_P));
117 mMult = (float)mMult_int + mMult_fract;
118 }
119 if (mMult == 0.0F)
120 {
121 mMult = 1.0F;
122 }
123 return mMult;
124}
125
126/* Get predivider (N) from PLL1 NDEC setting */
127static uint32_t findPll1PreDiv(void)
128{
129 uint32_t preDiv = 1UL;
130
131 /* Direct input is not used? */
132 if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPREDIV_MASK) == 0UL)
133 {
134 preDiv = SYSCON->PLL1NDEC & SYSCON_PLL1NDEC_NDIV_MASK;
135 if (preDiv == 0UL)
136 {
137 preDiv = 1UL;
138 }
139 }
140 return preDiv;
141}
142
143/* Get postdivider (P) from PLL1 PDEC setting */
144static uint32_t findPll1PostDiv(void)
145{
146 uint32_t postDiv = 1UL;
147
148 if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPOSTDIV_MASK) == 0UL)
149 {
150 if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPOSTDIV2_MASK) != 0UL)
151 {
152 postDiv = SYSCON->PLL1PDEC & SYSCON_PLL1PDEC_PDIV_MASK;
153 }
154 else
155 {
156 postDiv = 2UL * (SYSCON->PLL1PDEC & SYSCON_PLL1PDEC_PDIV_MASK);
157 }
158 if (postDiv == 0UL)
159 {
160 postDiv = 2UL;
161 }
162 }
163 return postDiv;
164}
165
166/* Get multiplier (M) from PLL1 MDEC settings */
167static uint32_t findPll1MMult(void)
168{
169 uint32_t mMult = 1UL;
170
171 mMult = SYSCON->PLL1MDEC & SYSCON_PLL1MDEC_MDIV_MASK;
172
173 if (mMult == 0UL)
174 {
175 mMult = 1UL;
176 }
177 return mMult;
178}
179
180/* Get FRO 12M Clk */
181/*! brief Return Frequency of FRO 12MHz
182 * return Frequency of FRO 12MHz
183 */
184static uint32_t GetFro12MFreq(void)
185{
186 return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK) != 0UL) ? 12000000U : 0U;
187}
188
189/* Get FRO 1M Clk */
190/*! brief Return Frequency of FRO 1MHz
191 * return Frequency of FRO 1MHz
192 */
193static uint32_t GetFro1MFreq(void)
194{
195 return ((SYSCON->CLOCK_CTRL & SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK) != 0UL) ? 1000000U : 0U;
196}
197
198/* Get EXT OSC Clk */
199/*! brief Return Frequency of External Clock
200 * return Frequency of External Clock. If no external clock is used returns 0.
201 */
202static uint32_t GetExtClkFreq(void)
203{
204 return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK) != 0UL) ? CLK_CLK_IN : 0U;
205}
206
207/* Get HF FRO Clk */
208/*! brief Return Frequency of High-Freq output of FRO
209 * return Frequency of High-Freq output of FRO
210 */
211static uint32_t GetFroHfFreq(void)
212{
213 return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK) != 0UL) ? 96000000U : 0U;
214}
215
216/* Get RTC OSC Clk */
217/*! brief Return Frequency of 32kHz osc
218 * return Frequency of 32kHz osc
219 */
220static uint32_t GetOsc32KFreq(void)
221{
222 return ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_FRO32K_MASK)) &&
223 (0UL == (PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK))) ?
224 CLK_RTC_32K_CLK :
225 ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_XTAL32K_MASK)) &&
226 ((PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK) != 0UL)) ?
227 CLK_RTC_32K_CLK :
228 0U;
229}
230
231/* ----------------------------------------------------------------------------
232 -- Core clock
233 ---------------------------------------------------------------------------- */
234
235uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
236
237/* ----------------------------------------------------------------------------
238 -- SystemInit()
239 ---------------------------------------------------------------------------- */
240
241__attribute__((weak)) void SystemInit(void)
242{
243#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
244 SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access in Secure mode */
245#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
246 SCB_NS->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access in Non-secure mode */
247#endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
248#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
249
250 SCB->CPACR |= ((3UL << 0 * 2) | (3UL << 1 * 2)); /* set CP0, CP1 Full Access in Secure mode (enable PowerQuad) */
251#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
252 SCB_NS->CPACR |= ((3UL << 0 * 2) | (3UL << 1 * 2)); /* set CP0, CP1 Full Access in Normal mode (enable PowerQuad) */
253#endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
254
255 SCB->NSACR |= ((3UL << 0) | (3UL << 10)); /* enable CP0, CP1, CP10, CP11 Non-secure Access */
256
257#if defined(__MCUXPRESSO)
258 extern void (*const g_pfnVectors[])(void);
259 SCB->VTOR = (uint32_t)&g_pfnVectors;
260#else
261 extern void *__Vectors;
262 SCB->VTOR = (uint32_t)&__Vectors;
263#endif
264 SYSCON->TRACECLKDIV = 0;
265/* Optionally enable RAM banks that may be off by default at reset */
266#if !defined(DONT_ENABLE_DISABLED_RAMBANKS)
267 SYSCON->AHBCLKCTRLSET[0] = SYSCON_AHBCLKCTRL0_SRAM_CTRL1_MASK | SYSCON_AHBCLKCTRL0_SRAM_CTRL2_MASK;
268#endif
269 /* Following code is to reset PUF to remove over consumption */
270 /* Enable PUF register clock to access register */
271 SYSCON->AHBCLKCTRLSET[2] = SYSCON_AHBCLKCTRL2_PUF_MASK;
272 /* Release PUF reset */
273 SYSCON->PRESETCTRLCLR[2] = SYSCON_PRESETCTRL2_PUF_RST_MASK;
274 /* Enable PUF SRAM */
275 PUF_SRAM_CTRL->CFG |= PUF_SRAM_CTRL_CFG_ENABLE_MASK | PUF_SRAM_CTRL_CFG_CKGATING_MASK;
276 /* Disable PUF register clock. */
277 // Delaying the line of code below until the PUF State Machine execution is completed:
278 // Shutting down the clock to early will prevent the state machine from reaching the end.
279 // => Wait for status bit in PUF Controller Registers before stop PUF clock.
280 while ((PUF_SRAM_CTRL->INT_STATUS & PUF_SRAM_CTRL_INT_STATUS_READY_MASK) == 0UL)
281 {
282 }
283 SYSCON->AHBCLKCTRLCLR[2] = SYSCON_AHBCLKCTRL2_PUF_MASK;
284 SystemInitHook();
285}
286
287/* ----------------------------------------------------------------------------
288 -- SystemCoreClockUpdate()
289 ---------------------------------------------------------------------------- */
290
291void SystemCoreClockUpdate(void)
292{
293 uint32_t clkRate = 0;
294 uint32_t prediv, postdiv;
295 uint64_t workRate;
296 uint64_t workRate1;
297
298 switch (SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK)
299 {
300 case 0x00: /* MAINCLKSELA clock (main_clk_a)*/
301 switch (SYSCON->MAINCLKSELA & SYSCON_MAINCLKSELA_SEL_MASK)
302 {
303 case 0x00: /* FRO 12 MHz (fro_12m) */
304 clkRate = GetFro12MFreq();
305 break;
306 case 0x01: /* CLKIN (clk_in) */
307 clkRate = GetExtClkFreq();
308 break;
309 case 0x02: /* Fro 1MHz (fro_1m) */
310 clkRate = GetFro1MFreq();
311 break;
312 default: /* = 0x03 = FRO 96 MHz (fro_hf) */
313 clkRate = GetFroHfFreq();
314 break;
315 }
316 break;
317 case 0x01: /* PLL0 clock (pll0_clk)*/
318 switch (SYSCON->PLL0CLKSEL & SYSCON_PLL0CLKSEL_SEL_MASK)
319 {
320 case 0x00: /* FRO 12 MHz (fro_12m) */
321 clkRate = GetFro12MFreq();
322 break;
323 case 0x01: /* CLKIN (clk_in) */
324 clkRate = GetExtClkFreq();
325 break;
326 case 0x02: /* Fro 1MHz (fro_1m) */
327 clkRate = GetFro1MFreq();
328 break;
329 case 0x03: /* RTC oscillator 32 kHz output (32k_clk) */
330 clkRate = GetOsc32KFreq();
331 break;
332 default:
333 clkRate = 0UL;
334 break;
335 }
336 if (((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPLL_MASK) == 0UL) &&
337 ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_CLKEN_MASK) != 0UL) &&
338 ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_MASK) == 0UL) &&
339 ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_SSCG_MASK) == 0UL))
340 {
341 prediv = findPll0PreDiv();
342 postdiv = findPll0PostDiv();
343 /* Adjust input clock */
344 clkRate = clkRate / prediv;
345 /* MDEC used for rate */
346 workRate = (uint64_t)clkRate * (uint64_t)findPll0MMult();
347 clkRate = (uint32_t)(workRate / ((uint64_t)postdiv));
348 }
349 break;
350 case 0x02: /* PLL1 clock (pll1_clk)*/
351 switch (SYSCON->PLL1CLKSEL & SYSCON_PLL1CLKSEL_SEL_MASK)
352 {
353 case 0x00: /* FRO 12 MHz (fro_12m) */
354 clkRate = GetFro12MFreq();
355 break;
356 case 0x01: /* CLKIN (clk_in) */
357 clkRate = GetExtClkFreq();
358 break;
359 case 0x02: /* Fro 1MHz (fro_1m) */
360 clkRate = GetFro1MFreq();
361 break;
362 case 0x03: /* RTC oscillator 32 kHz output (32k_clk) */
363 clkRate = GetOsc32KFreq();
364 break;
365 default:
366 clkRate = 0UL;
367 break;
368 }
369 if (((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPLL_MASK) == 0UL) &&
370 ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_CLKEN_MASK) != 0UL) &&
371 ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL1_MASK) == 0UL))
372 {
373 /* PLL is not in bypass mode, get pre-divider, post-divider, and M divider */
374 prediv = findPll1PreDiv();
375 postdiv = findPll1PostDiv();
376 /* Adjust input clock */
377 clkRate = clkRate / prediv;
378
379 /* MDEC used for rate */
380 workRate1 = (uint64_t)clkRate * (uint64_t)findPll1MMult();
381 clkRate = (uint32_t)(workRate1 / ((uint64_t)postdiv));
382 }
383 break;
384 case 0x03: /* RTC oscillator 32 kHz output (32k_clk) */
385 clkRate = GetOsc32KFreq();
386 break;
387 default:
388 clkRate = 0UL;
389 break;
390 }
391 SystemCoreClock = clkRate / ((SYSCON->AHBCLKDIV & 0xFFUL) + 1UL);
392}
393
394/* ----------------------------------------------------------------------------
395 -- SystemInitHook()
396 ---------------------------------------------------------------------------- */
397
398__attribute__((weak)) void SystemInitHook(void)
399{
400 /* Void implementation of the weak function. */
401}