1 /*
2 ** ###################################################################
3 ** Processors: MCIMX7U5CVP06
4 ** MCIMX7U5DVK07
5 ** MCIMX7U5DVP07
6 **
7 ** Compilers: GNU C Compiler
8 ** IAR ANSI C/C++ Compiler for ARM
9 ** Keil ARM C/C++ Compiler
10 **
11 ** Reference manual: IMX7ULPRM, Rev. 0, Nov. 2018
12 ** Version: rev. 7.0, 2018-11-05
13 ** Build: b200408
14 **
15 ** Abstract:
16 ** Provides a system configuration function and a global variable that
17 ** contains the system frequency. It configures the device and initializes
18 ** the oscillator (PLL) that is part of the microcontroller device.
19 **
20 ** Copyright 2016 Freescale Semiconductor, Inc.
21 ** Copyright 2016-2020 NXP
22 ** All rights reserved.
23 **
24 ** SPDX-License-Identifier: BSD-3-Clause
25 **
26 ** http: www.nxp.com
27 ** mail: support@nxp.com
28 **
29 ** Revisions:
30 ** - rev. 1.0 (2016-04-13)
31 ** Initial version.
32 ** - rev. 2.0 (2016-07-19)
33 ** RevC Header ER
34 ** - rev. 3.0 (2017-02-28)
35 ** RevD Header ER
36 ** - rev. 4.0 (2017-05-02)
37 ** RevE Header ER
38 ** - rev. 5.0 (2017-12-22)
39 ** RevA(B0) Header GA
40 ** - rev. 6.0 (2018-02-01)
41 ** RevB(B0) Header GA
42 ** - rev. 7.0 (2018-11-05)
43 ** RevA(B1) Header
44 **
45 ** ###################################################################
46 */
47
48 /*!
49 * @file MCIMX7U5_cm4
50 * @version 7.0
51 * @date 2018-11-05
52 * @brief Device specific configuration file for MCIMX7U5_cm4 (implementation
53 * file)
54 *
55 * Provides a system configuration function and a global variable that contains
56 * the system frequency. It configures the device and initializes the oscillator
57 * (PLL) that is part of the microcontroller device.
58 */
59
60 #include <stdint.h>
61 #include "fsl_device_registers.h"
62
63
64
65 typedef void (*WdogFuncPtr)(WDOG_Type *wdog);
66
67
68
69 /* ----------------------------------------------------------------------------
70 -- Core clock
71 ---------------------------------------------------------------------------- */
72
73 uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
74
75 /* ----------------------------------------------------------------------------
76 -- SystemInit()
77 ---------------------------------------------------------------------------- */
78
SystemInit(void)79 void SystemInit (void) {
80 #if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
81 SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access */
82 #endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
83
84
85 /* i.MX7ULP systemInit */
86 WdogFuncPtr WdogDisable;
87 uint16_t WdogDisable32[] = {
88 0xF64D, /* MOV R1, #0xD928 */
89 0x1128,
90 0xF24C, /* MOV R2, #0xC520 */
91 0x5220,
92 0xEA4F, /* LSL R1, R1, #16 */
93 0x4101,
94 0x4411, /* ADD R1, R1, R2 */
95 0x6041, /* STR R1, [R0, #4] */
96 0xF64F, /* MOV R1, #0xFFFF */
97 0x71FF,
98 0x6081, /* STR R1, [R0, #8] */
99 0x6801, /* LDR R1, [R0, #0] */
100 0xF031, /* BICS R1, R1, #0x80 */
101 0x0180,
102 0xF051, /* ORRS R1, R1, #0x20 */
103 0x0120,
104 0x6001, /* STR R1, [R0] */
105 0x4770 /* BX LR */
106 };
107 uint16_t WdogDisable16[] = {
108 0xF24C, /* MOV R1, #0xC520 */
109 0x5120,
110 0x6041, /* STR R1, [R0, #4] */
111 0xF64D, /* MOV R1, #0xD928 */
112 0x1128,
113 0x6041, /* STR R1, [R0, #4] */
114 0xF64F, /* MOV R1, #0xFFFF */
115 0x71FF,
116 0x6081, /* STR R1, [R0, #8] */
117 0x6801, /* LDR R1, [R0, #0] */
118 0xF031, /* BICS R1, R1, #0x80 */
119 0x0180,
120 0xF051, /* ORRS R1, R1, #0x20 */
121 0x0120,
122 0x6001, /* STR R1, [R0] */
123 0x4770 /* BX LR */
124 };
125 #if (DISABLE_WDOG)
126 if ((WDOG0->CS & WDOG_CS_EN_MASK) != 0U)
127 {
128 /* WDOG has timing requirement to unlock the operation window.
129 When running in QSPI flash, it's possible to violate that timing
130 requirement. So we put the WDOG operation in RAM */
131 /* Is WDOG 32bit access enabled? */
132 if ((WDOG0->CS & WDOG_CS_CMD32EN_MASK) != 0U)
133 {
134 WdogDisable = (WdogFuncPtr)(((uint32_t)WdogDisable32) | 1U); /* thumb code */
135 }
136 else
137 {
138 WdogDisable = (WdogFuncPtr)(((uint32_t)WdogDisable16) | 1U); /* thumb code */
139 }
140 WdogDisable(WDOG0);
141 }
142 #endif /* (DISABLE_WDOG) */
143 /* set command to invalidate all ways and write GO bit
144 to initiate command */
145 LMEM->PCCCR = LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK;
146 LMEM->PCCCR |= LMEM_PCCCR_GO_MASK;
147 /* Wait until the command completes */
148 while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U)
149 {}
150 /* Enable code bus cache, enable write buffer */
151 LMEM->PCCCR = (LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
152 __ISB();
153 __DSB();
154
155 SystemInitHook();
156 }
157
158 /* ----------------------------------------------------------------------------
159 -- SystemCoreClockUpdate()
160 ---------------------------------------------------------------------------- */
161
SystemCoreClockUpdate(void)162 void SystemCoreClockUpdate (void) {
163
164
165 /* i.MX7ULP systemCoreClockUpdate */
166 uint8_t spllMulti[] = {0U, 15U, 16U, 20U, 22U, 25U, 30U, 0U};
167 uint32_t SCGOUTClock, apllNum, apllDenom, apllTmp;
168 /* Identify current system clock source. */
169 switch (SCG0->CSR & SCG_CSR_SCS_MASK)
170 {
171 /* System OSC */
172 case SCG_CSR_SCS(1):
173 SCGOUTClock = CPU_XTAL_SOSC_CLK_HZ;
174 break;
175 /* Slow IRC */
176 case SCG_CSR_SCS(2):
177 SCGOUTClock = ((0u == (SCG0->SIRCCFG & SCG_SIRCCFG_RANGE_MASK)) ? 4000000u : 16000000u);
178 break;
179 /* Fast IRC */
180 case SCG_CSR_SCS(3):
181 SCGOUTClock = 48000000u + ((SCG0->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT) * 4000000u;
182 break;
183 /* RTC OSC */
184 case SCG_CSR_SCS(4):
185 SCGOUTClock = 32768u;
186 break;
187 /* System PLL */
188 case SCG_CSR_SCS(6):
189 /* System clock from SPLL. */
190 SCGOUTClock = (0u == (SCG0->SPLLCFG & SCG_SPLLCFG_SOURCE_MASK)) ? CPU_XTAL_SOSC_CLK_HZ :
191 (48000000u + ((SCG0->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT) * 4000000u);
192 SCGOUTClock /= ((SCG0->SPLLCFG & SCG_SPLLCFG_PREDIV_MASK) >> SCG_SPLLCFG_PREDIV_SHIFT) + 1u;
193 SCGOUTClock *= spllMulti[((SCG0->SPLLCFG & SCG_SPLLCFG_MULT_MASK) >> SCG_SPLLCFG_MULT_SHIFT)];
194 /* Is Core clock from PLL PFD? */
195 if (0u != (SCG0->SPLLCFG & SCG_SPLLCFG_PLLS_MASK))
196 {
197 /* System clock from SPLL PFD. */
198 switch (SCG0->SPLLCFG & SCG_SPLLCFG_PFDSEL_MASK)
199 {
200 case SCG_SPLLCFG_PFDSEL(0):
201 SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
202 ((SCG0->SPLLPFD & SCG_SPLLPFD_PFD0_MASK) >> SCG_SPLLPFD_PFD0_SHIFT));
203 break;
204 case SCG_SPLLCFG_PFDSEL(1):
205 SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
206 ((SCG0->SPLLPFD & SCG_SPLLPFD_PFD1_MASK) >> SCG_SPLLPFD_PFD1_SHIFT));
207 break;
208 case SCG_SPLLCFG_PFDSEL(2):
209 SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
210 ((SCG0->SPLLPFD & SCG_SPLLPFD_PFD2_MASK) >> SCG_SPLLPFD_PFD2_SHIFT));
211 break;
212 case SCG_SPLLCFG_PFDSEL(3):
213 SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
214 ((SCG0->SPLLPFD & SCG_SPLLPFD_PFD3_MASK) >> SCG_SPLLPFD_PFD3_SHIFT));
215 break;
216 default:
217 SCGOUTClock = 0u;
218 break;
219 }
220 }
221 break;
222 /* Auxiliary PLL */
223 case SCG_CSR_SCS(5):
224 /* System clock from APLL. */
225 SCGOUTClock = (0u == (SCG0->APLLCFG & SCG_APLLCFG_SOURCE_MASK)) ? CPU_XTAL_SOSC_CLK_HZ :
226 (48000000u + ((SCG0->FIRCCFG & SCG_FIRCCFG_RANGE_MASK) >> SCG_FIRCCFG_RANGE_SHIFT) * 4000000u);
227 SCGOUTClock /= ((SCG0->APLLCFG & SCG_APLLCFG_PREDIV_MASK) >> SCG_APLLCFG_PREDIV_SHIFT) + 1u;
228 apllNum = SCG0->APLLNUM;
229 apllDenom = SCG0->APLLDENOM;
230 apllTmp = (uint32_t)((uint64_t)SCGOUTClock * ((uint64_t)apllNum) / ((uint64_t)apllDenom));
231 SCGOUTClock = SCGOUTClock * ((SCG0->APLLCFG & SCG_APLLCFG_MULT_MASK) >> SCG_APLLCFG_MULT_SHIFT) + apllTmp;
232 /* Is Core clock from PLL directly? */
233 if (0u == (SCG0->APLLCFG & SCG_APLLCFG_PLLS_MASK))
234 {
235 /* System clock from APLL directly. */
236 SCGOUTClock /= (((SCG0->APLLCFG & SCG_APLLCFG_PLLPOSTDIV1_MASK) >> SCG_APLLCFG_PLLPOSTDIV1_SHIFT) + 1u);
237 SCGOUTClock /= (((SCG0->APLLCFG & SCG_APLLCFG_PLLPOSTDIV2_MASK) >> SCG_APLLCFG_PLLPOSTDIV2_SHIFT) + 1u);
238 }
239 else
240 {
241 /* System clock from APLL PFD. */
242 switch (SCG0->APLLCFG & SCG_APLLCFG_PFDSEL_MASK)
243 {
244 case SCG_APLLCFG_PFDSEL(0):
245 SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
246 ((SCG0->APLLPFD & SCG_APLLPFD_PFD0_MASK) >> SCG_APLLPFD_PFD0_SHIFT));
247 break;
248 case SCG_APLLCFG_PFDSEL(1):
249 SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
250 ((SCG0->APLLPFD & SCG_APLLPFD_PFD1_MASK) >> SCG_APLLPFD_PFD1_SHIFT));
251 break;
252 case SCG_APLLCFG_PFDSEL(2):
253 SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
254 ((SCG0->APLLPFD & SCG_APLLPFD_PFD2_MASK) >> SCG_APLLPFD_PFD2_SHIFT));
255 break;
256 case SCG_APLLCFG_PFDSEL(3):
257 SCGOUTClock = (uint32_t)(((uint64_t)SCGOUTClock * 18u) /
258 ((SCG0->APLLPFD & SCG_APLLPFD_PFD3_MASK) >> SCG_APLLPFD_PFD3_SHIFT));
259 break;
260 default:
261 SCGOUTClock = 0u;
262 break;
263 }
264 }
265 break;
266 /* Can not identify core clock source. */
267 default:
268 SCGOUTClock = 0u;
269 break;
270 }
271 /* Divide the SCG output clock to get the M4 Core clock. */
272 SCGOUTClock /= ((SCG0->CSR & SCG_CSR_DIVCORE_MASK) >> SCG_CSR_DIVCORE_SHIFT) + 1u;
273 /* Update System Core Clock. */
274 SystemCoreClock = SCGOUTClock;
275
276 }
277
278 /* ----------------------------------------------------------------------------
279 -- SystemInitHook()
280 ---------------------------------------------------------------------------- */
281
SystemInitHook(void)282 __attribute__ ((weak)) void SystemInitHook (void) {
283 /* Void implementation of the weak function. */
284 }
285