diff options
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S26/system_LPC55S26.c')
-rw-r--r-- | lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S26/system_LPC55S26.c | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S26/system_LPC55S26.c b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S26/system_LPC55S26.c new file mode 100644 index 000000000..c0281f134 --- /dev/null +++ b/lib/chibios-contrib/ext/mcux-sdk/devices/LPC55S26/system_LPC55S26.c | |||
@@ -0,0 +1,378 @@ | |||
1 | /* | ||
2 | ** ################################################################### | ||
3 | ** Processors: LPC55S26JBD100 | ||
4 | ** LPC55S26JBD64 | ||
5 | ** LPC55S26JEV98 | ||
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: LPC55S6x/LPC55S2x/LPC552x User manual(UM11126) Rev.1.3 16 May 2019 | ||
13 | ** Version: rev. 1.1, 2019-05-16 | ||
14 | ** Build: b200418 | ||
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-05-16) | ||
34 | ** Initial A1 version based on v1.3UM | ||
35 | ** | ||
36 | ** ################################################################### | ||
37 | */ | ||
38 | |||
39 | /*! | ||
40 | * @file LPC55S26 | ||
41 | * @version 1.1 | ||
42 | * @date 2019-05-16 | ||
43 | * @brief Device specific configuration file for LPC55S26 (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 */ | ||
60 | static 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 */ | ||
77 | static 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 */ | ||
100 | static 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 = (float)(uint32_t)((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MDIV_EXT_MASK) >> SYSCON_PLL0SSCG1_MDIV_EXT_SHIFT); | ||
109 | } | ||
110 | else | ||
111 | { | ||
112 | mMult_int = ((SYSCON->PLL0SSCG1 & SYSCON_PLL0SSCG1_MD_MBS_MASK) << 7U); | ||
113 | mMult_int = mMult_int | ((SYSCON->PLL0SSCG0) >> PLL_SSCG_MD_INT_P); | ||
114 | mMult_fract = ((float)(uint32_t)((SYSCON->PLL0SSCG0) & PLL_SSCG_MD_FRACT_M) / | ||
115 | (float)(uint32_t)(1UL << PLL_SSCG_MD_INT_P)); | ||
116 | mMult = (float)mMult_int + mMult_fract; | ||
117 | } | ||
118 | if (mMult == 0.0F) | ||
119 | { | ||
120 | mMult = 1.0F; | ||
121 | } | ||
122 | return mMult; | ||
123 | } | ||
124 | |||
125 | /* Get predivider (N) from PLL1 NDEC setting */ | ||
126 | static uint32_t findPll1PreDiv(void) | ||
127 | { | ||
128 | uint32_t preDiv = 1UL; | ||
129 | |||
130 | /* Direct input is not used? */ | ||
131 | if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPREDIV_MASK) == 0UL) | ||
132 | { | ||
133 | preDiv = SYSCON->PLL1NDEC & SYSCON_PLL1NDEC_NDIV_MASK; | ||
134 | if (preDiv == 0UL) | ||
135 | { | ||
136 | preDiv = 1UL; | ||
137 | } | ||
138 | } | ||
139 | return preDiv; | ||
140 | } | ||
141 | |||
142 | /* Get postdivider (P) from PLL1 PDEC setting */ | ||
143 | static uint32_t findPll1PostDiv(void) | ||
144 | { | ||
145 | uint32_t postDiv = 1UL; | ||
146 | |||
147 | if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPOSTDIV_MASK) == 0UL) | ||
148 | { | ||
149 | if ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPOSTDIV2_MASK) != 0UL) | ||
150 | { | ||
151 | postDiv = SYSCON->PLL1PDEC & SYSCON_PLL1PDEC_PDIV_MASK; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | postDiv = 2UL * (SYSCON->PLL1PDEC & SYSCON_PLL1PDEC_PDIV_MASK); | ||
156 | } | ||
157 | if (postDiv == 0UL) | ||
158 | { | ||
159 | postDiv = 2UL; | ||
160 | } | ||
161 | } | ||
162 | return postDiv; | ||
163 | } | ||
164 | |||
165 | /* Get multiplier (M) from PLL1 MDEC settings */ | ||
166 | static uint32_t findPll1MMult(void) | ||
167 | { | ||
168 | uint32_t mMult = 1UL; | ||
169 | |||
170 | mMult = SYSCON->PLL1MDEC & SYSCON_PLL1MDEC_MDIV_MASK; | ||
171 | |||
172 | if (mMult == 0UL) | ||
173 | { | ||
174 | mMult = 1UL; | ||
175 | } | ||
176 | return mMult; | ||
177 | } | ||
178 | |||
179 | /* Get FRO 12M Clk */ | ||
180 | /*! brief Return Frequency of FRO 12MHz | ||
181 | * return Frequency of FRO 12MHz | ||
182 | */ | ||
183 | static uint32_t GetFro12MFreq(void) | ||
184 | { | ||
185 | return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_12MHZCLK_MASK) != 0UL) ? 12000000U : 0U; | ||
186 | } | ||
187 | |||
188 | /* Get FRO 1M Clk */ | ||
189 | /*! brief Return Frequency of FRO 1MHz | ||
190 | * return Frequency of FRO 1MHz | ||
191 | */ | ||
192 | static uint32_t GetFro1MFreq(void) | ||
193 | { | ||
194 | return ((SYSCON->CLOCK_CTRL & SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK) != 0UL) ? 1000000U : 0U; | ||
195 | } | ||
196 | |||
197 | /* Get EXT OSC Clk */ | ||
198 | /*! brief Return Frequency of External Clock | ||
199 | * return Frequency of External Clock. If no external clock is used returns 0. | ||
200 | */ | ||
201 | static uint32_t GetExtClkFreq(void) | ||
202 | { | ||
203 | return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK) != 0UL) ? CLK_CLK_IN : 0U; | ||
204 | } | ||
205 | |||
206 | /* Get HF FRO Clk */ | ||
207 | /*! brief Return Frequency of High-Freq output of FRO | ||
208 | * return Frequency of High-Freq output of FRO | ||
209 | */ | ||
210 | static uint32_t GetFroHfFreq(void) | ||
211 | { | ||
212 | return ((ANACTRL->FRO192M_CTRL & ANACTRL_FRO192M_CTRL_ENA_96MHZCLK_MASK) != 0UL) ? 96000000U : 0U; | ||
213 | } | ||
214 | |||
215 | /* Get RTC OSC Clk */ | ||
216 | /*! brief Return Frequency of 32kHz osc | ||
217 | * return Frequency of 32kHz osc | ||
218 | */ | ||
219 | static uint32_t GetOsc32KFreq(void) | ||
220 | { | ||
221 | return ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_FRO32K_MASK)) && (0UL == (PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK))) ? | ||
222 | CLK_RTC_32K_CLK : | ||
223 | ((0UL == (PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_XTAL32K_MASK)) && ((PMC->RTCOSC32K & PMC_RTCOSC32K_SEL_MASK) != 0UL)) ? | ||
224 | CLK_RTC_32K_CLK : | ||
225 | 0U; | ||
226 | } | ||
227 | |||
228 | |||
229 | |||
230 | /* ---------------------------------------------------------------------------- | ||
231 | -- Core clock | ||
232 | ---------------------------------------------------------------------------- */ | ||
233 | |||
234 | uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK; | ||
235 | |||
236 | /* ---------------------------------------------------------------------------- | ||
237 | -- SystemInit() | ||
238 | ---------------------------------------------------------------------------- */ | ||
239 | |||
240 | __attribute__((weak)) void SystemInit (void) { | ||
241 | #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) | ||
242 | SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access in Secure mode */ | ||
243 | #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) | ||
244 | SCB_NS->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access in Non-secure mode */ | ||
245 | #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ | ||
246 | #endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */ | ||
247 | |||
248 | SCB->CPACR |= ((3UL << 0*2) | (3UL << 1*2)); /* set CP0, CP1 Full Access in Secure mode (enable PowerQuad) */ | ||
249 | #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) | ||
250 | SCB_NS->CPACR |= ((3UL << 0*2) | (3UL << 1*2)); /* set CP0, CP1 Full Access in Normal mode (enable PowerQuad) */ | ||
251 | #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ | ||
252 | |||
253 | SCB->NSACR |= ((3UL << 0) | (3UL << 10)); /* enable CP0, CP1, CP10, CP11 Non-secure Access */ | ||
254 | |||
255 | #if defined(__MCUXPRESSO) | ||
256 | extern void(*const g_pfnVectors[]) (void); | ||
257 | SCB->VTOR = (uint32_t) &g_pfnVectors; | ||
258 | #else | ||
259 | extern void *__Vectors; | ||
260 | SCB->VTOR = (uint32_t) &__Vectors; | ||
261 | #endif | ||
262 | SYSCON->TRACECLKDIV = 0; | ||
263 | /* Optionally enable RAM banks that may be off by default at reset */ | ||
264 | #if !defined(DONT_ENABLE_DISABLED_RAMBANKS) | ||
265 | SYSCON->AHBCLKCTRLSET[0] = SYSCON_AHBCLKCTRL0_SRAM_CTRL1_MASK | SYSCON_AHBCLKCTRL0_SRAM_CTRL2_MASK | ||
266 | | SYSCON_AHBCLKCTRL0_SRAM_CTRL3_MASK | SYSCON_AHBCLKCTRL0_SRAM_CTRL4_MASK; | ||
267 | #endif | ||
268 | SystemInitHook(); | ||
269 | } | ||
270 | |||
271 | /* ---------------------------------------------------------------------------- | ||
272 | -- SystemCoreClockUpdate() | ||
273 | ---------------------------------------------------------------------------- */ | ||
274 | |||
275 | void SystemCoreClockUpdate (void) { | ||
276 | uint32_t clkRate = 0; | ||
277 | uint32_t prediv, postdiv; | ||
278 | uint64_t workRate; | ||
279 | uint64_t workRate1; | ||
280 | |||
281 | switch (SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK) | ||
282 | { | ||
283 | case 0x00: /* MAINCLKSELA clock (main_clk_a)*/ | ||
284 | switch (SYSCON->MAINCLKSELA & SYSCON_MAINCLKSELA_SEL_MASK) | ||
285 | { | ||
286 | case 0x00: /* FRO 12 MHz (fro_12m) */ | ||
287 | clkRate = GetFro12MFreq(); | ||
288 | break; | ||
289 | case 0x01: /* CLKIN (clk_in) */ | ||
290 | clkRate = GetExtClkFreq(); | ||
291 | break; | ||
292 | case 0x02: /* Fro 1MHz (fro_1m) */ | ||
293 | clkRate = GetFro1MFreq(); | ||
294 | break; | ||
295 | default: /* = 0x03 = FRO 96 MHz (fro_hf) */ | ||
296 | clkRate = GetFroHfFreq(); | ||
297 | break; | ||
298 | } | ||
299 | break; | ||
300 | case 0x01: /* PLL0 clock (pll0_clk)*/ | ||
301 | switch (SYSCON->PLL0CLKSEL & SYSCON_PLL0CLKSEL_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 | case 0x03: /* RTC oscillator 32 kHz output (32k_clk) */ | ||
313 | clkRate = GetOsc32KFreq(); | ||
314 | break; | ||
315 | default: | ||
316 | clkRate = 0UL; | ||
317 | break; | ||
318 | } | ||
319 | if (((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_BYPASSPLL_MASK) == 0UL) && ((SYSCON->PLL0CTRL & SYSCON_PLL0CTRL_CLKEN_MASK) != 0UL) && ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_MASK) == 0UL) && ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL0_SSCG_MASK) == 0UL)) | ||
320 | { | ||
321 | prediv = findPll0PreDiv(); | ||
322 | postdiv = findPll0PostDiv(); | ||
323 | /* Adjust input clock */ | ||
324 | clkRate = clkRate / prediv; | ||
325 | /* MDEC used for rate */ | ||
326 | workRate = (uint64_t)clkRate * (uint64_t)findPll0MMult(); | ||
327 | clkRate = (uint32_t)(workRate / ((uint64_t)postdiv)); | ||
328 | } | ||
329 | break; | ||
330 | case 0x02: /* PLL1 clock (pll1_clk)*/ | ||
331 | switch (SYSCON->PLL1CLKSEL & SYSCON_PLL1CLKSEL_SEL_MASK) | ||
332 | { | ||
333 | case 0x00: /* FRO 12 MHz (fro_12m) */ | ||
334 | clkRate = GetFro12MFreq(); | ||
335 | break; | ||
336 | case 0x01: /* CLKIN (clk_in) */ | ||
337 | clkRate = GetExtClkFreq(); | ||
338 | break; | ||
339 | case 0x02: /* Fro 1MHz (fro_1m) */ | ||
340 | clkRate = GetFro1MFreq(); | ||
341 | break; | ||
342 | case 0x03: /* RTC oscillator 32 kHz output (32k_clk) */ | ||
343 | clkRate = GetOsc32KFreq(); | ||
344 | break; | ||
345 | default: | ||
346 | clkRate = 0UL; | ||
347 | break; | ||
348 | } | ||
349 | if (((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_BYPASSPLL_MASK) == 0UL) && ((SYSCON->PLL1CTRL & SYSCON_PLL1CTRL_CLKEN_MASK) != 0UL) && ((PMC->PDRUNCFG0 & PMC_PDRUNCFG0_PDEN_PLL1_MASK) == 0UL)) | ||
350 | { | ||
351 | /* PLL is not in bypass mode, get pre-divider, post-divider, and M divider */ | ||
352 | prediv = findPll1PreDiv(); | ||
353 | postdiv = findPll1PostDiv(); | ||
354 | /* Adjust input clock */ | ||
355 | clkRate = clkRate / prediv; | ||
356 | |||
357 | /* MDEC used for rate */ | ||
358 | workRate1 = (uint64_t)clkRate * (uint64_t)findPll1MMult(); | ||
359 | clkRate = (uint32_t)(workRate1 / ((uint64_t)postdiv)); | ||
360 | } | ||
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 | SystemCoreClock = clkRate / ((SYSCON->AHBCLKDIV & 0xFFUL) + 1UL); | ||
370 | } | ||
371 | |||
372 | /* ---------------------------------------------------------------------------- | ||
373 | -- SystemInitHook() | ||
374 | ---------------------------------------------------------------------------- */ | ||
375 | |||
376 | __attribute__ ((weak)) void SystemInitHook (void) { | ||
377 | /* Void implementation of the weak function. */ | ||
378 | } | ||