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