xref: /btstack/port/msp432p401lp-cc256x/system_msp432p401r.c (revision 142ae15a423624edf2dd1e70e2cd0a47dd644b3e)
1 /******************************************************************************
2 * @file     system_msp432p401r.c
3 * @brief    CMSIS Cortex-M4F Device Peripheral Access Layer Source File for
4 *           MSP432P401R
5 * @version  3.231
6 * @date     01/26/18
7 *
8 * @note     View configuration instructions embedded in comments
9 *
10 ******************************************************************************/
11 //*****************************************************************************
12 //
13 // Copyright (C) 2015 - 2018 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 
48 /*--------------------- Configuration Instructions ----------------------------
49    1. If you prefer to halt the Watchdog Timer, set __HALT_WDT to 1:
50    #define __HALT_WDT       1
51    2. Insert your desired CPU frequency in Hz at:
52    #define __SYSTEM_CLOCK   12000000
53    3. If you prefer the DC-DC power regulator (more efficient at higher
54        frequencies), set the __REGULATOR to 1:
55    #define __REGULATOR      1
56  *---------------------------------------------------------------------------*/
57 
58 /*--------------------- Watchdog Timer Configuration ------------------------*/
59 //  Halt the Watchdog Timer
60 //     <0> Do not halt the WDT
61 //     <1> Halt the WDT
62 #define __HALT_WDT         1
63 
64 /*--------------------- CPU Frequency Configuration -------------------------*/
65 //  CPU Frequency
66 //     <1500000> 1.5 MHz
67 //     <3000000> 3 MHz
68 //     <12000000> 12 MHz
69 //     <24000000> 24 MHz
70 //     <48000000> 48 MHz
71 #define  __SYSTEM_CLOCK    48000000
72 
73 /*--------------------- Power Regulator Configuration -----------------------*/
74 //  Power Regulator Mode
75 //     <0> LDO
76 //     <1> DC-DC
77 #define __REGULATOR        0
78 
79 /*----------------------------------------------------------------------------
80    Define clocks, used for SystemCoreClockUpdate()
81  *---------------------------------------------------------------------------*/
82 #define __VLOCLK           10000
83 #define __MODCLK           24000000
84 #define __LFXT             32768
85 #define __HFXT             48000000
86 
87 /*----------------------------------------------------------------------------
88    Clock Variable definitions
89  *---------------------------------------------------------------------------*/
90 uint32_t SystemCoreClock = __SYSTEM_CLOCK;  /*!< System Clock Frequency (Core Clock)*/
91 
92 /**
93  * Update SystemCoreClock variable
94  *
95  * @param  none
96  * @return none
97  *
98  * @brief  Updates the SystemCoreClock with current core Clock
99  *         retrieved from cpu registers.
100  */
SystemCoreClockUpdate(void)101 void SystemCoreClockUpdate(void)
102 {
103     uint32_t source = 0, divider = 0, dividerValue = 0, centeredFreq = 0, calVal = 0;
104     int16_t dcoTune = 0;
105     float dcoConst = 0.0;
106 
107     divider = (CS->CTL1 & CS_CTL1_DIVM_MASK) >> CS_CTL1_DIVM_OFS;
108     dividerValue = 1 << divider;
109     source = CS->CTL1 & CS_CTL1_SELM_MASK;
110 
111     switch(source)
112     {
113     case CS_CTL1_SELM__LFXTCLK:
114         if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
115         {
116             // Clear interrupt flag
117             CS->KEY = CS_KEY_VAL;
118             CS->CLRIFG |= CS_CLRIFG_CLR_LFXTIFG;
119             CS->KEY = 1;
120 
121             if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
122             {
123                 if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
124                 {
125                     SystemCoreClock = (128000 / dividerValue);
126                 }
127                 else
128                 {
129                     SystemCoreClock = (32000 / dividerValue);
130                 }
131             }
132             else
133             {
134                 SystemCoreClock = __LFXT / dividerValue;
135             }
136         }
137         else
138         {
139             SystemCoreClock = __LFXT / dividerValue;
140         }
141         break;
142     case CS_CTL1_SELM__VLOCLK:
143         SystemCoreClock = __VLOCLK / dividerValue;
144         break;
145     case CS_CTL1_SELM__REFOCLK:
146         if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
147         {
148             SystemCoreClock = (128000 / dividerValue);
149         }
150         else
151         {
152             SystemCoreClock = (32000 / dividerValue);
153         }
154         break;
155     case CS_CTL1_SELM__DCOCLK:
156         dcoTune = (CS->CTL0 & CS_CTL0_DCOTUNE_MASK) >> CS_CTL0_DCOTUNE_OFS;
157 
158         switch(CS->CTL0 & CS_CTL0_DCORSEL_MASK)
159         {
160         case CS_CTL0_DCORSEL_0:
161             centeredFreq = 1500000;
162             break;
163         case CS_CTL0_DCORSEL_1:
164             centeredFreq = 3000000;
165             break;
166         case CS_CTL0_DCORSEL_2:
167             centeredFreq = 6000000;
168             break;
169         case CS_CTL0_DCORSEL_3:
170             centeredFreq = 12000000;
171             break;
172         case CS_CTL0_DCORSEL_4:
173             centeredFreq = 24000000;
174             break;
175         case CS_CTL0_DCORSEL_5:
176             centeredFreq = 48000000;
177             break;
178         }
179 
180         if(dcoTune == 0)
181         {
182             SystemCoreClock = centeredFreq;
183         }
184         else
185         {
186 
187             if(dcoTune & 0x1000)
188             {
189                 dcoTune = dcoTune | 0xF000;
190             }
191 
192             if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
193             {
194                 dcoConst = *((volatile const float *) &TLV->DCOER_CONSTK_RSEL04);
195                 calVal = TLV->DCOER_FCAL_RSEL04;
196             }
197             /* Internal Resistor */
198             else
199             {
200                 dcoConst = *((volatile const float *) &TLV->DCOIR_CONSTK_RSEL04);
201                 calVal = TLV->DCOIR_FCAL_RSEL04;
202             }
203 
204             SystemCoreClock = (uint32_t) ((centeredFreq)
205                                / (1
206                                     - ((dcoConst * dcoTune)
207                                             / (8 * (1 + dcoConst * (768 - calVal))))));
208         }
209         break;
210     case CS_CTL1_SELM__MODOSC:
211         SystemCoreClock = __MODCLK / dividerValue;
212         break;
213     case CS_CTL1_SELM__HFXTCLK:
214         if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
215         {
216             // Clear interrupt flag
217             CS->KEY = CS_KEY_VAL;
218             CS->CLRIFG |= CS_CLRIFG_CLR_HFXTIFG;
219             CS->KEY = 1;
220 
221             if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
222             {
223                 if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
224                 {
225                     SystemCoreClock = (128000 / dividerValue);
226                 }
227                 else
228                 {
229                     SystemCoreClock = (32000 / dividerValue);
230                 }
231             }
232             else
233             {
234                 SystemCoreClock = __HFXT / dividerValue;
235             }
236         }
237         else
238         {
239             SystemCoreClock = __HFXT / dividerValue;
240         }
241         break;
242     }
243 }
244 
245 /**
246  * Initialize the system
247  *
248  * @param  none
249  * @return none
250  *
251  * @brief  Setup the microcontroller system.
252  *
253  * Performs the following initialization steps:
254  *     1. Enables the FPU
255  *     2. Halts the WDT if requested
256  *     3. Enables all SRAM banks
257  *     4. Sets up power regulator and VCORE
258  *     5. Enable Flash wait states if needed
259  *     6. Change MCLK to desired frequency
260  *     7. Enable Flash read buffering
261  */
SystemInit(void)262 void SystemInit(void)
263 {
264     // Enable FPU if used
265     #if (__FPU_USED == 1)                                  // __FPU_USED is defined in core_cm4.h
266     SCB->CPACR |= ((3UL << 10 * 2) |                       // Set CP10 Full Access
267                    (3UL << 11 * 2));                       // Set CP11 Full Access
268     #endif
269 
270     #if (__HALT_WDT == 1)
271     WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD;            // Halt the WDT
272     #endif
273 
274     SYSCTL->SRAM_BANKEN = SYSCTL_SRAM_BANKEN_BNK7_EN;      // Enable all SRAM banks
275 
276     #if (__SYSTEM_CLOCK == 1500000)                        // 1.5 MHz
277     // Default VCORE is LDO VCORE0 so no change necessary
278 
279     // Switches LDO VCORE0 to DCDC VCORE0 if requested
280     #if __REGULATOR
281     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
282     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
283     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
284     #endif
285 
286     // No flash wait states necessary
287 
288     // DCO = 1.5 MHz; MCLK = source
289     CS->KEY = CS_KEY_VAL;                                  // Unlock CS module for register access
290     CS->CTL0 = CS_CTL0_DCORSEL_0;                          // Set DCO to 1.5MHz
291     CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
292 	                                                       // Select MCLK as DCO source
293     CS->KEY = 0;
294 
295     // Set Flash Bank read buffering
296     FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
297     FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
298 
299     #elif (__SYSTEM_CLOCK == 3000000)                      // 3 MHz
300     // Default VCORE is LDO VCORE0 so no change necessary
301 
302     // Switches LDO VCORE0 to DCDC VCORE0 if requested
303     #if __REGULATOR
304     while(PCM->CTL1 & PCM_CTL1_PMR_BUSY);
305     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
306     while(PCM->CTL1 & PCM_CTL1_PMR_BUSY);
307     #endif
308 
309     // No flash wait states necessary
310 
311     // DCO = 3 MHz; MCLK = source
312     CS->KEY = CS_KEY_VAL;                                  // Unlock CS module for register access
313     CS->CTL0 = CS_CTL0_DCORSEL_1;                          // Set DCO to 1.5MHz
314     CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
315 	                                                       // Select MCLK as DCO source
316     CS->KEY = 0;
317 
318     // Set Flash Bank read buffering
319     FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
320     FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
321 
322     #elif (__SYSTEM_CLOCK == 12000000)                     // 12 MHz
323     // Default VCORE is LDO VCORE0 so no change necessary
324 
325     // Switches LDO VCORE0 to DCDC VCORE0 if requested
326     #if __REGULATOR
327     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
328     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
329     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
330     #endif
331 
332     // No flash wait states necessary
333 
334     // DCO = 12 MHz; MCLK = source
335     CS->KEY = CS_KEY_VAL;                                  // Unlock CS module for register access
336     CS->CTL0 = CS_CTL0_DCORSEL_3;                          // Set DCO to 12MHz
337     CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
338 	                                                       // Select MCLK as DCO source
339     CS->KEY = 0;
340 
341     // Set Flash Bank read buffering
342     FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
343     FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
344 
345     #elif (__SYSTEM_CLOCK == 24000000)                     // 24 MHz
346     // Default VCORE is LDO VCORE0 so no change necessary
347 
348     // Switches LDO VCORE0 to DCDC VCORE0 if requested
349     #if __REGULATOR
350     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
351     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
352     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
353     #endif
354 
355     // 1 flash wait state (BANK0 VCORE0 max is 12 MHz)
356     FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1;
357     FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1;
358 
359     // DCO = 24 MHz; MCLK = source
360     CS->KEY = CS_KEY_VAL;                                  // Unlock CS module for register access
361     CS->CTL0 = CS_CTL0_DCORSEL_4;                          // Set DCO to 24MHz
362     CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
363 	                                                       // Select MCLK as DCO source
364     CS->KEY = 0;
365 
366     // Set Flash Bank read buffering
367     FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
368     FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
369 
370     #elif (__SYSTEM_CLOCK == 48000000)                     // 48 MHz
371     // Switches LDO VCORE0 to LDO VCORE1; mandatory for 48 MHz setting
372     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
373     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1;
374     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
375 
376     // Switches LDO VCORE1 to DCDC VCORE1 if requested
377     #if __REGULATOR
378     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
379     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5;
380     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
381     #endif
382 
383     // 1 flash wait states (BANK0 VCORE1 max is 16 MHz, BANK1 VCORE1 max is 32 MHz)
384     FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1;
385     FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1;
386 
387     // DCO = 48 MHz; MCLK = source
388     CS->KEY = CS_KEY_VAL;                                  // Unlock CS module for register access
389     CS->CTL0 = CS_CTL0_DCORSEL_5;                          // Set DCO to 48MHz
390 //    CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK;
391 //	                                                       // Select MCLK as DCO source
392     CS->CTL1 = 0x00000033;   // reset value (SMCLK, HSMCLK, MCLK source DCO)
393     CS->KEY = 0;
394 
395     // Set Flash Bank read buffering
396     FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
397     FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL | (FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
398     #endif
399 
400 }
401 
402 
403