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