1 /******************************************************************************
2 * @file system_msp432p4111.c
3 * @brief CMSIS Cortex-M4F Device Peripheral Access Layer Source File for
4 * MSP432P4111
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 <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;
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 // Enable all SRAM banks
280 while(!(SYSCTL_A->SRAM_STAT & SYSCTL_A_SRAM_STAT_BNKEN_RDY));
281 if (SYSCTL_A->SRAM_NUMBANKS == 4)
282 {
283 SYSCTL_A->SRAM_BANKEN_CTL0 = SYSCTL_A_SRAM_BANKEN_CTL0_BNK3_EN;
284 }
285 else
286 {
287 SYSCTL_A->SRAM_BANKEN_CTL0 = SYSCTL_A_SRAM_BANKEN_CTL0_BNK1_EN;
288 }
289
290
291 #if (__SYSTEM_CLOCK == 1500000) // 1.5 MHz
292 // Default VCORE is LDO VCORE0 so no change necessary
293
294 // Switches LDO VCORE0 to DCDC VCORE0 if requested
295 #if __REGULATOR
296 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
297 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
298 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
299 #endif
300
301 // No flash wait states necessary
302
303 // DCO = 1.5 MHz; MCLK = source
304 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
305 CS->CTL0 = CS_CTL0_DCORSEL_0; // Set DCO to 1.5MHz
306 CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK; // Select MCLK as DCO source
307 CS->KEY = 0;
308
309 // Set Flash Bank read buffering
310 FLCTL_A->BANK0_RDCTL &= ~(FLCTL_A_BANK0_RDCTL_BUFD | FLCTL_A_BANK0_RDCTL_BUFI);
311 FLCTL_A->BANK1_RDCTL &= ~(FLCTL_A_BANK0_RDCTL_BUFD | FLCTL_A_BANK0_RDCTL_BUFI);
312
313 #elif (__SYSTEM_CLOCK == 3000000) // 3 MHz
314 // Default VCORE is LDO VCORE0 so no change necessary
315
316 // Switches LDO VCORE0 to DCDC VCORE0 if requested
317 #if __REGULATOR
318 while(PCM->CTL1 & PCM_CTL1_PMR_BUSY);
319 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
320 while(PCM->CTL1 & PCM_CTL1_PMR_BUSY);
321 #endif
322
323 // No flash wait states necessary
324
325 // DCO = 3 MHz; MCLK = source
326 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
327 CS->CTL0 = CS_CTL0_DCORSEL_1; // Set DCO to 1.5MHz
328 CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK; // Select MCLK as DCO source
329 CS->KEY = 0;
330
331 // Set Flash Bank read buffering
332 FLCTL_A->BANK0_RDCTL &= ~(FLCTL_A_BANK0_RDCTL_BUFD | FLCTL_A_BANK0_RDCTL_BUFI);
333 FLCTL_A->BANK1_RDCTL &= ~(FLCTL_A_BANK0_RDCTL_BUFD | FLCTL_A_BANK0_RDCTL_BUFI);
334
335 #elif (__SYSTEM_CLOCK == 12000000) // 12 MHz
336 // Default VCORE is LDO VCORE0 so no change necessary
337
338 // Switches LDO VCORE0 to DCDC VCORE0 if requested
339 #if __REGULATOR
340 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
341 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
342 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
343 #endif
344
345 // No flash wait states necessary
346
347 // DCO = 12 MHz; MCLK = source
348 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
349 CS->CTL0 = CS_CTL0_DCORSEL_3; // Set DCO to 12MHz
350 CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK; // Select MCLK as DCO source
351 CS->KEY = 0;
352
353 // Set Flash Bank read buffering
354 FLCTL_A->BANK0_RDCTL &= ~(FLCTL_A_BANK0_RDCTL_BUFD | FLCTL_A_BANK0_RDCTL_BUFI);
355 FLCTL_A->BANK1_RDCTL &= ~(FLCTL_A_BANK0_RDCTL_BUFD | FLCTL_A_BANK0_RDCTL_BUFI);
356
357 #elif (__SYSTEM_CLOCK == 24000000) // 24 MHz
358 // Default VCORE is LDO VCORE0 so no change necessary
359
360 // Switches LDO VCORE0 to DCDC VCORE0 if requested
361 #if __REGULATOR
362 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
363 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
364 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
365 #endif
366
367 // 2 flash wait state (BANK0 VCORE0 max is 24 MHz)
368 FLCTL_A->BANK0_RDCTL &= ~FLCTL_A_BANK0_RDCTL_WAIT_MASK | FLCTL_A_BANK0_RDCTL_WAIT_2;
369 FLCTL_A->BANK1_RDCTL &= ~FLCTL_A_BANK0_RDCTL_WAIT_MASK | FLCTL_A_BANK0_RDCTL_WAIT_2;
370
371 // DCO = 24 MHz; MCLK = source
372 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
373 CS->CTL0 = CS_CTL0_DCORSEL_4; // Set DCO to 24MHz
374 CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK; // Select MCLK as DCO source
375 CS->KEY = 0;
376
377 // Set Flash Bank read buffering
378 FLCTL_A->BANK0_RDCTL |= (FLCTL_A_BANK0_RDCTL_BUFD | FLCTL_A_BANK0_RDCTL_BUFI);
379 FLCTL_A->BANK1_RDCTL &= ~(FLCTL_A_BANK0_RDCTL_BUFD | FLCTL_A_BANK0_RDCTL_BUFI);
380
381 #elif (__SYSTEM_CLOCK == 48000000) // 48 MHz
382 // Switches LDO VCORE0 to LDO VCORE1; mandatory for 48 MHz setting
383 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
384 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1;
385 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
386
387 // Switches LDO VCORE1 to DCDC VCORE1 if requested
388 #if __REGULATOR
389 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
390 PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5;
391 while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
392 #endif
393
394 // 3 flash wait states (BANK0 VCORE1 max is 16 MHz, BANK1 VCORE1 max is 32 MHz)
395 FLCTL_A->BANK0_RDCTL &= ~FLCTL_A_BANK0_RDCTL_WAIT_MASK | FLCTL_A_BANK0_RDCTL_WAIT_3;
396 FLCTL_A->BANK1_RDCTL &= ~FLCTL_A_BANK1_RDCTL_WAIT_MASK | FLCTL_A_BANK1_RDCTL_WAIT_3;
397
398 // DCO = 48 MHz; MCLK = source
399 CS->KEY = CS_KEY_VAL; // Unlock CS module for register access
400 CS->CTL0 = CS_CTL0_DCORSEL_5; // Set DCO to 48MHz
401 CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK; // Select MCLK as DCO source
402 CS->KEY = 0;
403
404 // Set Flash Bank read buffering
405 FLCTL_A->BANK0_RDCTL |= (FLCTL_A_BANK0_RDCTL_BUFD | FLCTL_A_BANK0_RDCTL_BUFI);
406 FLCTL_A->BANK1_RDCTL |= (FLCTL_A_BANK1_RDCTL_BUFD | FLCTL_A_BANK1_RDCTL_BUFI);
407 #endif
408
409 }
410
411