1 /******************************************************************************
2 * @file system_msp432p401r.c
3 * @brief CMSIS Cortex-M4F Device Peripheral Access Layer Source File for
4 * MSP432P401R
5 * @version 3.202
6 * @date 08/03/17
7 *
8 * @note View configuration instructions embedded in comments
9 *
10 ******************************************************************************/
11 //*****************************************************************************
12 //
13 // Copyright (C) 2015 - 2017 Texas Instruments Incorporated - http://www.ti.com/
14 //
15 // Redistribution and use in source and binary forms, with or without
16 // modification, are permitted provided that the following conditions
17 // are met:
18 //
19 // Redistributions of source code must retain the above copyright
20 // notice, this list of conditions and the following disclaimer.
21 //
22 // Redistributions in binary form must reproduce the above copyright
23 // notice, this list of conditions and the following disclaimer in the
24 // documentation and/or other materials provided with the
25 // distribution.
26 //
27 // Neither the name of Texas Instruments Incorporated nor the names of
28 // its contributors may be used to endorse or promote products derived
29 // from this software without specific prior written permission.
30 //
31 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 //
43 //*****************************************************************************
44
45 #include <stdint.h>
46 #include <ti/devices/msp432p4xx/inc/msp.h>
47 #include <zephyr/devicetree.h>
48
49 /*--------------------- Configuration Instructions ----------------------------
50 1. If you prefer to halt the Watchdog Timer, set __HALT_WDT to 1:
51 #define __HALT_WDT 1
52 2. Insert your desired CPU frequency in Hz at:
53 #define __SYSTEM_CLOCK 12000000
54 3. If you prefer the DC-DC power regulator (more efficient at higher
55 frequencies), set the __REGULATOR to 1:
56 #define __REGULATOR 1
57 *---------------------------------------------------------------------------*/
58
59 /*--------------------- Watchdog Timer Configuration ------------------------*/
60 // Halt the Watchdog Timer
61 // <0> Do not halt the WDT
62 // <1> Halt the WDT
63 #define __HALT_WDT 1
64
65 /*--------------------- CPU Frequency Configuration -------------------------*/
66 // CPU Frequency
67 // <1500000> 1.5 MHz
68 // <3000000> 3 MHz
69 // <12000000> 12 MHz
70 // <24000000> 24 MHz
71 // <48000000> 48 MHz
72 #define __SYSTEM_CLOCK DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency)
73
74 /*--------------------- Power Regulator Configuration -----------------------*/
75 // Power Regulator Mode
76 // <0> LDO
77 // <1> DC-DC
78 #define __REGULATOR 0
79
80 /*----------------------------------------------------------------------------
81 Define clocks, used for SystemCoreClockUpdate()
82 *---------------------------------------------------------------------------*/
83 #define __VLOCLK 10000
84 #define __MODCLK 24000000
85 #define __LFXT 32768
86 #define __HFXT 48000000
87
88 /*----------------------------------------------------------------------------
89 Clock Variable definitions
90 *---------------------------------------------------------------------------*/
91 uint32_t SystemCoreClock = __SYSTEM_CLOCK; /*!< System Clock Frequency (Core Clock)*/
92
93 /**
94 * Update SystemCoreClock variable
95 *
96 * @param none
97 * @return none
98 *
99 * @brief Updates the SystemCoreClock with current core Clock
100 * retrieved from cpu registers.
101 */
SystemCoreClockUpdate(void)102 void SystemCoreClockUpdate(void)
103 {
104 uint32_t source, divider;
105 uint8_t dividerValue;
106
107 float dcoConst;
108 int32_t calVal;
109 uint32_t centeredFreq = 1500000; // Default center freq
110 int16_t dcoTune;
111
112 divider = (CS->CTL1 & CS_CTL1_DIVM_MASK) >> CS_CTL1_DIVM_OFS;
113 dividerValue = 1 << divider;
114 source = CS->CTL1 & CS_CTL1_SELM_MASK;
115
116 switch(source)
117 {
118 case CS_CTL1_SELM__LFXTCLK:
119 if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
120 {
121 // Clear interrupt flag
122 CS->KEY = CS_KEY_VAL;
123 CS->CLRIFG |= CS_CLRIFG_CLR_LFXTIFG;
124 CS->KEY = 1;
125
126 if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
127 {
128 if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
129 {
130 SystemCoreClock = (128000 / dividerValue);
131 }
132 else
133 {
134 SystemCoreClock = (32000 / dividerValue);
135 }
136 }
137 else
138 {
139 SystemCoreClock = __LFXT / dividerValue;
140 }
141 }
142 else
143 {
144 SystemCoreClock = __LFXT / dividerValue;
145 }
146 break;
147 case CS_CTL1_SELM__VLOCLK:
148 SystemCoreClock = __VLOCLK / dividerValue;
149 break;
150 case CS_CTL1_SELM__REFOCLK:
151 if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
152 {
153 SystemCoreClock = (128000 / dividerValue);
154 }
155 else
156 {
157 SystemCoreClock = (32000 / dividerValue);
158 }
159 break;
160 case CS_CTL1_SELM__DCOCLK:
161 dcoTune = (CS->CTL0 & CS_CTL0_DCOTUNE_MASK) >> CS_CTL0_DCOTUNE_OFS;
162
163 switch(CS->CTL0 & CS_CTL0_DCORSEL_MASK)
164 {
165 case CS_CTL0_DCORSEL_0:
166 centeredFreq = 1500000;
167 break;
168 case CS_CTL0_DCORSEL_1:
169 centeredFreq = 3000000;
170 break;
171 case CS_CTL0_DCORSEL_2:
172 centeredFreq = 6000000;
173 break;
174 case CS_CTL0_DCORSEL_3:
175 centeredFreq = 12000000;
176 break;
177 case CS_CTL0_DCORSEL_4:
178 centeredFreq = 24000000;
179 break;
180 case CS_CTL0_DCORSEL_5:
181 centeredFreq = 48000000;
182 break;
183 }
184
185 if(dcoTune == 0)
186 {
187 SystemCoreClock = centeredFreq;
188 }
189 else
190 {
191
192 if(dcoTune & 0x1000)
193 {
194 dcoTune = dcoTune | 0xF000;
195 }
196
197 if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
198 {
199 dcoConst = *((float *) &TLV->DCOER_CONSTK_RSEL04);
200 calVal = TLV->DCOER_FCAL_RSEL04;
201 }
202 /* Internal Resistor */
203 else
204 {
205 dcoConst = *((float *) &TLV->DCOIR_CONSTK_RSEL04);
206 calVal = TLV->DCOIR_FCAL_RSEL04;
207 }
208
209 SystemCoreClock = (uint32_t) ((centeredFreq)
210 / (1
211 - ((dcoConst * dcoTune)
212 / (8 * (1 + dcoConst * (768 - calVal))))));
213 }
214 break;
215 case CS_CTL1_SELM__MODOSC:
216 SystemCoreClock = __MODCLK / dividerValue;
217 break;
218 case CS_CTL1_SELM__HFXTCLK:
219 if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
220 {
221 // Clear interrupt flag
222 CS->KEY = CS_KEY_VAL;
223 CS->CLRIFG |= CS_CLRIFG_CLR_HFXTIFG;
224 CS->KEY = 1;
225
226 if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
227 {
228 if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
229 {
230 SystemCoreClock = (128000 / dividerValue);
231 }
232 else
233 {
234 SystemCoreClock = (32000 / dividerValue);
235 }
236 }
237 else
238 {
239 SystemCoreClock = __HFXT / dividerValue;
240 }
241 }
242 else
243 {
244 SystemCoreClock = __HFXT / dividerValue;
245 }
246 break;
247 }
248 }
249
250 /**
251 * Initialize the system
252 *
253 * @param none
254 * @return none
255 *
256 * @brief Setup the microcontroller system.
257 *
258 * Performs the following initialization steps:
259 * 1. Enables the FPU
260 * 2. Halts the WDT if requested
261 * 3. Enables all SRAM banks
262 * 4. Sets up power regulator and VCORE
263 * 5. Enable Flash wait states if needed
264 * 6. Change MCLK to desired frequency
265 * 7. Enable Flash read buffering
266 */
SystemInit(void)267 void SystemInit(void)
268 {
269 // Enable FPU if used
270 #if (__FPU_USED == 1) // __FPU_USED is defined in core_cm4.h
271 SCB->CPACR |= ((3UL << 10 * 2) | // Set CP10 Full Access
272 (3UL << 11 * 2)); // Set CP11 Full Access
273 #endif
274
275 #if (__HALT_WDT == 1)
276 WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // Halt the WDT
277 #endif
278
279 SYSCTL->SRAM_BANKEN = SYSCTL_SRAM_BANKEN_BNK7_EN; // Enable all SRAM banks
280
281 #if (__SYSTEM_CLOCK == 1500000) // 1.5 MHz
282 // Default VCORE is LDO VCORE0 so no change necessary
283
284 // Switches LDO VCORE0 to DCDC VCORE0 if requested
285 #if __REGULATOR
286 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
287 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
288 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
289 #endif
290
291 // No flash wait states necessary
292
293 // DCO = 1.5 MHz; MCLK = source
294 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
295 CS->CTL0 = CS_CTL0_DCORSEL_0; // Set DCO to 1.5MHz
296 CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
297 // Select MCLK as DCO source
298 CS->KEY = 0;
299
300 // Set Flash Bank read buffering
301 FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
302 FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
303
304 #elif (__SYSTEM_CLOCK == 3000000) // 3 MHz
305 // Default VCORE is LDO VCORE0 so no change necessary
306
307 // Switches LDO VCORE0 to DCDC VCORE0 if requested
308 #if __REGULATOR
309 while(PCM->CTL1 & PCM_CTL1_PMR_BUSY);
310 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
311 while(PCM->CTL1 & PCM_CTL1_PMR_BUSY);
312 #endif
313
314 // No flash wait states necessary
315
316 // DCO = 3 MHz; MCLK = source
317 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
318 CS->CTL0 = CS_CTL0_DCORSEL_1; // Set DCO to 1.5MHz
319 CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
320 // Select MCLK as DCO source
321 CS->KEY = 0;
322
323 // Set Flash Bank read buffering
324 FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
325 FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
326
327 #elif (__SYSTEM_CLOCK == 12000000) // 12 MHz
328 // Default VCORE is LDO VCORE0 so no change necessary
329
330 // Switches LDO VCORE0 to DCDC VCORE0 if requested
331 #if __REGULATOR
332 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
333 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
334 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
335 #endif
336
337 // No flash wait states necessary
338
339 // DCO = 12 MHz; MCLK = source
340 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
341 CS->CTL0 = CS_CTL0_DCORSEL_3; // Set DCO to 12MHz
342 CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
343 // Select MCLK as DCO source
344 CS->KEY = 0;
345
346 // Set Flash Bank read buffering
347 FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
348 FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
349
350 #elif (__SYSTEM_CLOCK == 24000000) // 24 MHz
351 // Default VCORE is LDO VCORE0 so no change necessary
352
353 // Switches LDO VCORE0 to DCDC VCORE0 if requested
354 #if __REGULATOR
355 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
356 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
357 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
358 #endif
359
360 // 1 flash wait state (BANK0 VCORE0 max is 12 MHz)
361 FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1;
362 FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1;
363
364 // DCO = 24 MHz; MCLK = source
365 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
366 CS->CTL0 = CS_CTL0_DCORSEL_4; // Set DCO to 24MHz
367 CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
368 // Select MCLK as DCO source
369 CS->KEY = 0;
370
371 // Set Flash Bank read buffering
372 FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
373 FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
374
375 #elif (__SYSTEM_CLOCK == 48000000) // 48 MHz
376 // Switches LDO VCORE0 to LDO VCORE1; mandatory for 48 MHz setting
377 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
378 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1;
379 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
380
381 // Switches LDO VCORE1 to DCDC VCORE1 if requested
382 #if __REGULATOR
383 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
384 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5;
385 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
386 #endif
387
388 // 1 flash wait states (BANK0 VCORE1 max is 16 MHz, BANK1 VCORE1 max is 32 MHz)
389 FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1;
390 FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1;
391
392 // DCO = 48 MHz; MCLK = source
393 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
394 CS->CTL0 = CS_CTL0_DCORSEL_5; // Set DCO to 48MHz
395 CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
396 // Select MCLK as DCO source
397 CS->KEY = 0;
398
399 // Set Flash Bank read buffering
400 FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
401 FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL | (FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
402 #endif
403
404 }
405
406
407