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 */ 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 */ 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