4dcf1da7c5d9e3dd373828ddb176da5ee929cb59
[i3-mote/i3-mote.git] / Basic-Test-Package / MSP432 / Test_MSP432_Blink_SysTick / system_msp432p401r.c
1 /*
3 /**************************************************************************//**
4 * @file     system_msp432p401r.c
5 * @brief    CMSIS Cortex-M4F Device Peripheral Access Layer Source File for
6 *           MSP432P401R
7 * @version  V1.00
8 * @date     20-Oct-2015
9 *
10 * @note     View configuration instructions embedded in comments
11 *
12 ******************************************************************************/
14 //*****************************************************************************
16 #include <stdint.h>
17 #include "msp.h"
19 /*--------------------- Configuration Instructions ----------------------------
20    1. If you prefer to halt the Watchdog Timer, set __HALT_WDT to 1:
21    #define __HALT_WDT       1
22    2. Insert your desired CPU frequency in Hz at:
23    #define __SYSTEM_CLOCK   3000000
24    3. If you prefer the DC-DC power regulator (more efficient at higher
25        frequencies), set the __REGULATOR to 1:
26    #define __REGULATOR      1
27  *---------------------------------------------------------------------------*/
29 /*--------------------- Watchdog Timer Configuration ------------------------*/
30 //  Halt the Watchdog Timer
31 //     <0> Do not halt the WDT
32 //     <1> Halt the WDT
33 #define __HALT_WDT         1
35 /*--------------------- CPU Frequency Configuration -------------------------*/
36 //  CPU Frequency
37 //     <1500000> 1.5 MHz
38 //     <3000000> 3 MHz
39 //     <12000000> 12 MHz
40 //     <24000000> 24 MHz
41 //     <48000000> 48 MHz
42 #define  __SYSTEM_CLOCK  12000000
44 /*--------------------- Power Regulator Configuration -----------------------*/
45 //  Power Regulator Mode
46 //     <0> LDO
47 //     <1> DC-DC
48 #define __REGULATOR      1
50 /*----------------------------------------------------------------------------
51    Define clocks, used for SystemCoreClockUpdate()
52  *---------------------------------------------------------------------------*/
53 #define __VLOCLK           10000
54 #define __MODCLK           24000000
55 #define __LFXT             32768
56 #define __HFXT             48000000
58 /*----------------------------------------------------------------------------
59    Clock Variable definitions
60  *---------------------------------------------------------------------------*/
61 uint32_t SystemCoreClock = __SYSTEM_CLOCK;  /*!< System Clock Frequency (Core Clock)*/
63 /**
64  * Update SystemCoreClock variable
65  *
66  * @param  none
67  * @return none
68  *
69  * @brief  Updates the SystemCoreClock with current core Clock
70  *         retrieved from cpu registers.
71  */
72 void SystemCoreClockUpdate(void)
73 {
74     uint32_t source, divider;
75     uint8_t dividerValue;
77     float dcoConst;
78     int32_t calVal;
79     uint32_t centeredFreq;
80     int16_t dcoTune;
82     divider = (CS->CTL1 & CS_CTL1_DIVM_MASK) >> CS_CTL1_DIVM_OFS;
83     dividerValue = 1 << divider;
84     source = CS->CTL1 & CS_CTL1_SELM_MASK;
86     switch(source)
87     {
88     case CS_CTL1_SELM__LFXTCLK:
89         if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
90         {
91             // Clear interrupt flag
92             CS->KEY = CS_KEY_VAL;
93             CS->CLRIFG |= CS_CLRIFG_CLR_LFXTIFG;
94             CS->KEY = 1;
96             if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
97             {
98                 if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
99                 {
100                     SystemCoreClock = (128000 / dividerValue);
101                 }
102                 else
103                 {
104                     SystemCoreClock = (32000 / dividerValue);
105                 }
106             }
107             else
108             {
109                 SystemCoreClock = __LFXT / dividerValue;
110             }
111         }
112         else
113         {
114             SystemCoreClock = __LFXT / dividerValue;
115         }
116         break;
117     case CS_CTL1_SELM__VLOCLK:
118         SystemCoreClock = __VLOCLK / dividerValue;
119         break;
120     case CS_CTL1_SELM__REFOCLK:
121         if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
122         {
123             SystemCoreClock = (128000 / dividerValue);
124         }
125         else
126         {
127             SystemCoreClock = (32000 / dividerValue);
128         }
129         break;
130     case CS_CTL1_SELM__DCOCLK:
131         dcoTune = (CS->CTL0 & CS_CTL0_DCOTUNE_MASK) >> CS_CTL0_DCOTUNE_OFS;
132     
133         switch(CS->CTL0 & CS_CTL0_DCORSEL_MASK)
134         {
135         case CS_CTL0_DCORSEL_0:
136             centeredFreq = 1500000;
137             break;
138         case CS_CTL0_DCORSEL_1:
139             centeredFreq = 3000000;
140             break;
141         case CS_CTL0_DCORSEL_2:
142             centeredFreq = 6000000;
143             break;
144         case CS_CTL0_DCORSEL_3:
145             centeredFreq = 12000000;
146             break;
147         case CS_CTL0_DCORSEL_4:
148             centeredFreq = 24000000;
149             break;
150         case CS_CTL0_DCORSEL_5:
151             centeredFreq = 48000000;
152             break;
153         }
155         if(dcoTune == 0)
156         {
157             SystemCoreClock = centeredFreq;
158         }
159         else
160         {
162             if(dcoTune & 0x1000)
163             {
164                 dcoTune = dcoTune | 0xF000;
165             }
167             if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
168             {
169                 dcoConst = *((float *) &TLV->DCOER_CONSTK_RSEL04);
170                 calVal = TLV->DCOER_FCAL_RSEL04;
171             }
172             /* Internal Resistor */
173             else
174             {
175                 dcoConst = *((float *) &TLV->DCOIR_CONSTK_RSEL04);
176                 calVal = TLV->DCOIR_FCAL_RSEL04;
177             }
179             SystemCoreClock = (uint32_t) ((centeredFreq)
180                                / (1
181                                     - ((dcoConst * dcoTune)
182                                             / (8 * (1 + dcoConst * (768 - calVal))))));
183         }
184         break;
185     case CS_CTL1_SELM__MODOSC:
186         SystemCoreClock = __MODCLK / dividerValue;
187         break;
188     case CS_CTL1_SELM__HFXTCLK:
189         if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
190         {
191             // Clear interrupt flag
192             CS->KEY = CS_KEY_VAL;
193             CS->CLRIFG |= CS_CLRIFG_CLR_HFXTIFG;
194             CS->KEY = 1;
196             if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
197             {
198                 if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS))
199                 {
200                     SystemCoreClock = (128000 / dividerValue);
201                 }
202                 else
203                 {
204                     SystemCoreClock = (32000 / dividerValue);
205                 }
206             }
207             else
208             {
209                 SystemCoreClock = __HFXT / dividerValue;
210             }
211         }
212         else
213         {
214             SystemCoreClock = __HFXT / dividerValue;
215         }
216         break;
217     }
220 /**
221  * Initialize the system
222  *
223  * @param  none
224  * @return none
225  *
226  * @brief  Setup the microcontroller system.
227  *
228  * Performs the following initialization steps:
229  *     1. Enables the FPU
230  *     2. Halts the WDT if requested
231  *     3. Enables all SRAM banks
232  *     4. Sets up power regulator and VCORE
233  *     5. Enable Flash wait states if needed
234  *     6. Change MCLK to desired frequency
235  *     7. Enable Flash read buffering
236  */
237 void SystemInit(void)
239     // Enable FPU if used
240     #if (__FPU_USED == 1)                              /* __FPU_USED is defined in core_cm4.h */
241     SCB->CPACR |= ((3UL << 10 * 2) |                   /* Set CP10 Full Access */
242                    (3UL << 11 * 2));                   /* Set CP11 Full Access */
243     #endif
245     #if (__HALT_WDT == 1)
246     WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD;         // Halt the WDT
247     #endif
249     SYSCTL->SRAM_BANKEN = SYSCTL_SRAM_BANKEN_BNK7_EN;   // Enable all SRAM banks
251     #if (__SYSTEM_CLOCK == 1500000)                                  // 1.5 MHz
252     // Default VCORE is LDO VCORE0 so no change necessary
254     // Switches LDO VCORE0 to DCDC VCORE0 if requested
255     #if __REGULATOR
256     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
257     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
258     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
259     #endif
261     // No flash wait states necessary
263     // DCO = 1.5 MHz; MCLK = source
264     CS->KEY = CS_KEY_VAL;                                 // Unlock CS module for register access
265     CS->CTL0 = CS_CTL0_DCORSEL_0;                                // Set DCO to 1.5MHz
266     CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK;  // Select MCLK as DCO source
267     CS->KEY = 0;
269     // Set Flash Bank read buffering
270     FLCTL->BANK0_RDCTL &= ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
271     FLCTL->BANK1_RDCTL &= ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
273     #elif (__SYSTEM_CLOCK == 3000000)                                  // 3 MHz
274     // Default VCORE is LDO VCORE0 so no change necessary
276     // Switches LDO VCORE0 to DCDC VCORE0 if requested
277     #if __REGULATOR
278     while(PCM->CTL1 & PCM_CTL1_PMR_BUSY);
279     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
280     while(PCM->CTL1 & PCM_CTL1_PMR_BUSY);
281     #endif
283     // No flash wait states necessary
285     // DCO = 3 MHz; MCLK = source
286     CS->KEY = CS_KEY_VAL;                                                         // Unlock CS module for register access
287     CS->CTL0 = CS_CTL0_DCORSEL_1;                                                  // Set DCO to 1.5MHz
288     CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK;  // Select MCLK as DCO source
289     CS->KEY = 0;
291     // Set Flash Bank read buffering
292     FLCTL->BANK0_RDCTL &= ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
293     FLCTL->BANK1_RDCTL &= ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
295     #elif (__SYSTEM_CLOCK == 12000000)                                // 12 MHz
296     // Default VCORE is LDO VCORE0 so no change necessary
298     // Switches LDO VCORE0 to DCDC VCORE0 if requested
299     #if __REGULATOR
300     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
301     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
302     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
303     #endif
305     // No flash wait states necessary
307     // DCO = 12 MHz; MCLK = source
308     CS->KEY = CS_KEY_VAL;                                                         // Unlock CS module for register access
309     CS->CTL0 = CS_CTL0_DCORSEL_3;                                                  // Set DCO to 12MHz
310     CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK;  // Select MCLK as DCO source
311     CS->KEY = 0;
313     // Set Flash Bank read buffering
314     FLCTL->BANK0_RDCTL &= ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
315     FLCTL->BANK1_RDCTL &= ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
317     #elif (__SYSTEM_CLOCK == 24000000)                                // 24 MHz
318     // Default VCORE is LDO VCORE0 so no change necessary
320     // Switches LDO VCORE0 to DCDC VCORE0 if requested
321     #if __REGULATOR
322     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
323     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4;
324     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
325     #endif
327     // 1 flash wait state (BANK0 VCORE0 max is 12 MHz)
328     FLCTL->BANK0_RDCTL &= ~FLCTL_BANK0_RDCTL_WAIT_MASK | FLCTL_BANK0_RDCTL_WAIT_1;
329     FLCTL->BANK1_RDCTL &= ~FLCTL_BANK0_RDCTL_WAIT_MASK | FLCTL_BANK0_RDCTL_WAIT_1;
331     // DCO = 24 MHz; MCLK = source
332     CS->KEY = CS_KEY_VAL;                                                         // Unlock CS module for register access
333     CS->CTL0 = CS_CTL0_DCORSEL_4;                                                  // Set DCO to 24MHz
334     CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK;  // Select MCLK as DCO source
335     CS->KEY = 0;
337     // Set Flash Bank read buffering
338     FLCTL->BANK0_RDCTL |= (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
339     FLCTL->BANK1_RDCTL &= ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
341     #elif (__SYSTEM_CLOCK == 48000000)                                // 48 MHz
342     // Switches LDO VCORE0 to LDO VCORE1; mandatory for 48 MHz setting
343     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
344     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1;
345     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
347     // Switches LDO VCORE1 to DCDC VCORE1 if requested
348     #if __REGULATOR
349     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
350     PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5;
351     while((PCM->CTL1 & PCM_CTL1_PMR_BUSY));
352     #endif
354     // 2 flash wait states (BANK0 VCORE1 max is 16 MHz, BANK1 VCORE1 max is 32 MHz)
355     FLCTL->BANK0_RDCTL &= ~FLCTL_BANK0_RDCTL_WAIT_MASK | FLCTL_BANK0_RDCTL_WAIT_2;
356     FLCTL->BANK1_RDCTL &= ~FLCTL_BANK1_RDCTL_WAIT_MASK | FLCTL_BANK1_RDCTL_WAIT_2;
358     // DCO = 48 MHz; MCLK = source
359     CS->KEY = CS_KEY_VAL;                                                         // Unlock CS module for register access
360     CS->CTL0 = CS_CTL0_DCORSEL_5;                                                  // Set DCO to 48MHz
361     CS->CTL1 &= ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK) | CS_CTL1_SELM__DCOCLK;  // Select MCLK as DCO source
362     CS->KEY = 0;
364     // Set Flash Bank read buffering
365     FLCTL->BANK0_RDCTL |= (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI);
366     FLCTL->BANK1_RDCTL |= (FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI);
367     #endif