1 /* --COPYRIGHT--,BSD 2 * Copyright (c) 2017, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * --/COPYRIGHT--*/ 32 /* Standard Includes */ 33 #include <stdint.h> 34 35 /* DriverLib Includes */ 36 #include <ti/devices/msp432p4xx/driverlib/cs.h> 37 #include <ti/devices/msp432p4xx/driverlib/interrupt.h> 38 #include <ti/devices/msp432p4xx/driverlib/debug.h> 39 40 #ifdef __MCU_HAS_SYSCTL_A__ 41 #include <ti/devices/msp432p4xx/driverlib/sysctl_a.h> 42 #else 43 #include <ti/devices/msp432p4xx/driverlib/sysctl.h> 44 #endif 45 46 /* Statics */ 47 static uint32_t hfxtFreq; 48 static uint32_t lfxtFreq; 49 50 #ifdef DEBUG 51 52 bool _CSIsClockDividerValid(uint8_t divider) 53 { 54 return ((divider == CS_CLOCK_DIVIDER_1) || (divider == CS_CLOCK_DIVIDER_2) 55 || (divider == CS_CLOCK_DIVIDER_4) || (divider == CS_CLOCK_DIVIDER_8) 56 || (divider == CS_CLOCK_DIVIDER_16) || (divider == CS_CLOCK_DIVIDER_32) 57 || (divider == CS_CLOCK_DIVIDER_64) || (divider == CS_CLOCK_DIVIDER_128)); 58 } 59 60 #endif 61 62 static uint32_t _CSGetHFXTFrequency() 63 { 64 if (hfxtFreq >= CS_1MHZ && hfxtFreq <= CS_4MHZ) 65 return CS_CTL2_HFXTFREQ_0; 66 else if (hfxtFreq > CS_4MHZ && hfxtFreq <= CS_8MHZ) 67 return CS_CTL2_HFXTFREQ_1; 68 else if (hfxtFreq > CS_8MHZ && hfxtFreq <= CS_16MHZ) 69 return CS_CTL2_HFXTFREQ_2; 70 else if (hfxtFreq > CS_16MHZ && hfxtFreq <= CS_24MHZ) 71 return CS_CTL2_HFXTFREQ_3; 72 else if (hfxtFreq > CS_24MHZ && hfxtFreq <= CS_32MHZ) 73 return CS_CTL2_HFXTFREQ_4; 74 else if (hfxtFreq > CS_32MHZ && hfxtFreq <= CS_40MHZ) 75 return CS_CTL2_HFXTFREQ_5; 76 else if (hfxtFreq > CS_40MHZ && hfxtFreq <= CS_48MHZ) 77 return CS_CTL2_HFXTFREQ_6; 78 else 79 { 80 ASSERT(false); 81 return 0; 82 } 83 84 } 85 86 static uint32_t _CSGetDividerValue(uint32_t wDivider) 87 { 88 switch (wDivider) 89 { 90 case CS_CLOCK_DIVIDER_1: 91 return 1; 92 case CS_CLOCK_DIVIDER_2: 93 return 2; 94 case CS_CLOCK_DIVIDER_4: 95 return 4; 96 case CS_CLOCK_DIVIDER_8: 97 return 8; 98 case CS_CLOCK_DIVIDER_16: 99 return 16; 100 case CS_CLOCK_DIVIDER_32: 101 return 32; 102 case CS_CLOCK_DIVIDER_64: 103 return 64; 104 case CS_CLOCK_DIVIDER_128: 105 return 128; 106 default: 107 ASSERT(false); 108 return 1; 109 } 110 } 111 112 static uint32_t _CSComputeCLKFrequency(uint32_t wClockSource, uint32_t wDivider) 113 { 114 uint_fast8_t bDivider; 115 116 bDivider = _CSGetDividerValue(wDivider); 117 118 switch (wClockSource) 119 { 120 case CS_LFXTCLK_SELECT: 121 { 122 if (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) 123 { 124 CS_clearInterruptFlag(CS_LFXT_FAULT); 125 126 if (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) 127 { 128 if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) 129 return (128000 / bDivider); 130 else 131 return (32768 / bDivider); 132 } 133 } 134 return lfxtFreq / bDivider; 135 } 136 case CS_HFXTCLK_SELECT: 137 { 138 if (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) 139 { 140 CS_clearInterruptFlag(CS_HFXT_FAULT); 141 142 if (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) 143 { 144 if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) 145 return (128000 / bDivider); 146 else 147 return (32768 / bDivider); 148 } 149 } 150 return hfxtFreq / bDivider; 151 } 152 case CS_VLOCLK_SELECT: 153 return CS_VLOCLK_FREQUENCY / bDivider; 154 case CS_REFOCLK_SELECT: 155 { 156 if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) 157 return (128000 / bDivider); 158 else 159 return (32768 / bDivider); 160 } 161 case CS_DCOCLK_SELECT: 162 return (CS_getDCOFrequency() / bDivider); 163 case CS_MODOSC_SELECT: 164 return CS_MODCLK_FREQUENCY / bDivider; 165 default: 166 ASSERT(false); 167 return 0; 168 } 169 } 170 171 //****************************************************************************** 172 // Internal function for getting DCO nominal frequency 173 //****************************************************************************** 174 static uint32_t _CSGetDOCFrequency(void) 175 { 176 uint32_t dcoFreq; 177 178 switch (CS->CTL0 & CS_CTL0_DCORSEL_MASK) 179 { 180 case CS_CTL0_DCORSEL_0: 181 dcoFreq = 1500000; 182 break; 183 case CS_CTL0_DCORSEL_1: 184 dcoFreq = 3000000; 185 break; 186 case CS_CTL0_DCORSEL_2: 187 dcoFreq = 6000000; 188 break; 189 case CS_CTL0_DCORSEL_3: 190 dcoFreq = 12000000; 191 break; 192 case CS_CTL0_DCORSEL_4: 193 dcoFreq = 24000000; 194 break; 195 case CS_CTL0_DCORSEL_5: 196 dcoFreq = 48000000; 197 break; 198 default: 199 dcoFreq = 0; 200 } 201 202 return (dcoFreq); 203 } 204 205 void CS_setExternalClockSourceFrequency(uint32_t lfxt_XT_CLK_frequency, 206 uint32_t hfxt_XT_CLK_frequency) 207 { 208 hfxtFreq = hfxt_XT_CLK_frequency; 209 lfxtFreq = lfxt_XT_CLK_frequency; 210 } 211 212 void CS_initClockSignal(uint32_t selectedClockSignal, uint32_t clockSource, 213 uint32_t clockSourceDivider) 214 { 215 ASSERT(_CSIsClockDividerValid(clockSourceDivider)); 216 217 /* Unlocking the CS Module */ 218 CS->KEY = CS_KEY; 219 220 switch (selectedClockSignal) 221 { 222 case CS_ACLK: 223 { 224 /* Making sure that the clock signal for ACLK isn't set to anything 225 * invalid 226 */ 227 ASSERT( 228 (selectedClockSignal != CS_DCOCLK_SELECT) 229 && (selectedClockSignal != CS_MODOSC_SELECT) 230 && (selectedClockSignal != CS_HFXTCLK_SELECT)); 231 232 /* Waiting for the clock source ready bit to be valid before 233 * changing */ 234 while (!BITBAND_PERI(CS->STAT, CS_STAT_ACLK_READY_OFS)) 235 ; 236 237 /* Setting the divider and source */ 238 CS->CTL1 = ((clockSourceDivider >> CS_ACLK_DIV_BITPOS) 239 | (clockSource << CS_ACLK_SRC_BITPOS)) 240 | (CS->CTL1 & ~(CS_CTL1_SELA_MASK | CS_CTL1_DIVA_MASK)); 241 242 /* Waiting for ACLK to be ready again */ 243 while (!BITBAND_PERI(CS->STAT, CS_STAT_ACLK_READY_OFS)) 244 ; 245 246 break; 247 } 248 case CS_MCLK: 249 { 250 251 /* Waiting for the clock source ready bit to be valid before 252 * changing */ 253 while (!BITBAND_PERI(CS->STAT, CS_STAT_MCLK_READY_OFS)) 254 ; 255 256 CS->CTL1 = ((clockSourceDivider >> CS_MCLK_DIV_BITPOS) 257 | (clockSource << CS_MCLK_SRC_BITPOS)) 258 | (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)); 259 260 /* Waiting for MCLK to be ready */ 261 while (!BITBAND_PERI(CS->STAT, CS_STAT_MCLK_READY_OFS)) 262 ; 263 264 break; 265 } 266 case CS_SMCLK: 267 { 268 /* Waiting for the clock source ready bit to be valid before 269 * changing */ 270 while (!BITBAND_PERI(CS->STAT, CS_STAT_SMCLK_READY_OFS)) 271 ; 272 273 CS->CTL1 = ((clockSourceDivider >> CS_SMCLK_DIV_BITPOS) 274 | (clockSource << CS_HSMCLK_SRC_BITPOS)) 275 | (CS->CTL1 & ~(CS_CTL1_DIVS_MASK | CS_CTL1_SELS_MASK)); 276 277 /* Waiting for SMCLK to be ready */ 278 while (!BITBAND_PERI(CS->STAT, CS_STAT_SMCLK_READY_OFS)) 279 ; 280 281 break; 282 } 283 case CS_HSMCLK: 284 { 285 /* Waiting for the clock source ready bit to be valid before 286 * changing */ 287 while (!BITBAND_PERI(CS->STAT, CS_STAT_HSMCLK_READY_OFS)) 288 ; 289 290 CS->CTL1 = ((clockSourceDivider >> CS_HSMCLK_DIV_BITPOS) 291 | (clockSource << CS_HSMCLK_SRC_BITPOS)) 292 | (CS->CTL1 & ~(CS_CTL1_DIVHS_MASK | CS_CTL1_SELS_MASK)); 293 294 /* Waiting for HSMCLK to be ready */ 295 while (!BITBAND_PERI(CS->STAT, CS_STAT_HSMCLK_READY_OFS)) 296 ; 297 298 break; 299 } 300 case CS_BCLK: 301 { 302 303 /* Waiting for the clock source ready bit to be valid before 304 * changing */ 305 while (!BITBAND_PERI(CS->STAT, CS_STAT_BCLK_READY_OFS)) 306 ; 307 308 /* Setting the clock source and then returning 309 * (cannot divide CLK) 310 */ 311 if (clockSource == CS_LFXTCLK_SELECT) 312 BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS) = 0; 313 else if (clockSource == CS_REFOCLK_SELECT) 314 BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS) = 1; 315 else 316 ASSERT(false); 317 318 /* Waiting for BCLK to be ready */ 319 while (!BITBAND_PERI(CS->STAT, CS_STAT_BCLK_READY_OFS)) 320 ; 321 322 break; 323 } 324 default: 325 { 326 /* Should never get here */ 327 ASSERT(false); 328 } 329 } 330 331 /* Locking the module */ 332 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 333 } 334 335 bool CS_startHFXT(bool bypassMode) 336 { 337 return CS_startHFXTWithTimeout(bypassMode, 0); 338 } 339 340 bool CS_startHFXTWithTimeout(bool bypassMode, uint32_t timeout) 341 { 342 uint32_t wHFFreqRange; 343 uint_fast8_t bNMIStatus; 344 bool boolTimeout; 345 346 /* Unlocking the CS Module */ 347 CS->KEY = CS_KEY; 348 349 /* Saving status and temporarily disabling NMIs for UCS faults */ 350 #ifdef __MCU_HAS_SYSCTL_A__ 351 bNMIStatus = SysCtl_A_getNMISourceStatus() & SYSCTL_A_CS_SRC; 352 SysCtl_A_disableNMISource(SYSCTL_A_CS_SRC); 353 #else 354 bNMIStatus = SysCtl_getNMISourceStatus() & SYSCTL_CS_SRC; 355 SysCtl_disableNMISource(SYSCTL_CS_SRC); 356 #endif 357 358 /* Determining which frequency range to use */ 359 wHFFreqRange = _CSGetHFXTFrequency(); 360 boolTimeout = (timeout == 0) ? false : true; 361 362 /* Setting to maximum drive strength */ 363 BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 1; 364 CS->CTL2 = (CS->CTL2 & (~CS_CTL2_HFXTFREQ_MASK)) | (wHFFreqRange); 365 366 if (bypassMode) 367 { 368 BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTBYPASS_OFS) = 1; 369 } else 370 { 371 BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTBYPASS_OFS) = 0; 372 } 373 374 /* Starting and Waiting for frequency stabilization */ 375 BITBAND_PERI(CS->CTL2, CS_CTL2_HFXT_EN_OFS) = 1; 376 while (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) 377 { 378 if (boolTimeout && ((--timeout) == 0)) 379 break; 380 381 BITBAND_PERI(CS->CLRIFG,CS_CLRIFG_CLR_HFXTIFG_OFS) = 1; 382 } 383 384 /* Setting the drive strength */ 385 if (!bypassMode) 386 { 387 if (wHFFreqRange != CS_CTL2_HFXTFREQ_0) 388 BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 1; 389 else 390 BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 0; 391 } 392 393 /* Locking the module */ 394 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 395 396 /* Enabling the NMI state */ 397 #ifdef __MCU_HAS_SYSCTL_A__ 398 SysCtl_A_enableNMISource(bNMIStatus); 399 #else 400 SysCtl_enableNMISource(bNMIStatus); 401 #endif 402 403 if (boolTimeout && timeout == 0) 404 return false; 405 406 return true; 407 } 408 409 bool CS_startLFXT(uint32_t xtDrive) 410 { 411 return CS_startLFXTWithTimeout(xtDrive, 0); 412 } 413 414 bool CS_startLFXTWithTimeout(uint32_t xtDrive, uint32_t timeout) 415 { 416 uint8_t bNMIStatus; 417 bool boolBypassMode, boolTimeout; 418 419 ASSERT(lfxtFreq != 0) 420 ASSERT( 421 (xtDrive == CS_LFXT_DRIVE0) || (xtDrive == CS_LFXT_DRIVE1) 422 || (xtDrive == CS_LFXT_DRIVE2) 423 || (xtDrive == CS_LFXT_DRIVE3) 424 || (xtDrive == CS_LFXT_BYPASS)); 425 426 /* Unlocking the CS Module */ 427 CS->KEY = CS_KEY; 428 429 /* Saving status and temporarily disabling NMIs for UCS faults */ 430 #ifdef __MCU_HAS_SYSCTL_A__ 431 bNMIStatus = SysCtl_A_getNMISourceStatus() & SYSCTL_A_CS_SRC; 432 SysCtl_A_disableNMISource(SYSCTL_A_CS_SRC); 433 #else 434 bNMIStatus = SysCtl_getNMISourceStatus() & SYSCTL_CS_SRC; 435 SysCtl_disableNMISource(SYSCTL_CS_SRC); 436 #endif 437 boolBypassMode = (xtDrive == CS_LFXT_BYPASS) ? true : false; 438 boolTimeout = (timeout == 0) ? false : true; 439 440 /* Setting to maximum drive strength */ 441 if (boolBypassMode) 442 { 443 BITBAND_PERI(CS->CTL2, CS_CTL2_LFXTBYPASS_OFS) = 1; 444 } else 445 { 446 CS->CTL2 |= (CS_LFXT_DRIVE3); 447 BITBAND_PERI(CS->CTL2, CS_CTL2_LFXTBYPASS_OFS) = 0; 448 } 449 450 /* Waiting for frequency stabilization */ 451 BITBAND_PERI(CS->CTL2, CS_CTL2_LFXT_EN_OFS) = 1; 452 453 while (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) 454 { 455 if (boolTimeout && ((--timeout) == 0)) 456 break; 457 458 BITBAND_PERI(CS->CLRIFG,CS_CLRIFG_CLR_LFXTIFG_OFS) = 1; 459 } 460 461 /* Setting the drive strength */ 462 if (!boolBypassMode) 463 { 464 CS->CTL2 = ((CS->CTL2 & ~CS_LFXT_DRIVE3) | xtDrive); 465 } 466 467 /* Locking the module */ 468 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 469 470 /* Enabling the NMI state */ 471 #ifdef __MCU_HAS_SYSCTL_A__ 472 SysCtl_A_enableNMISource(bNMIStatus); 473 #else 474 SysCtl_enableNMISource(bNMIStatus); 475 #endif 476 477 if (boolTimeout && timeout == 0) 478 return false; 479 480 return true; 481 } 482 483 void CS_enableClockRequest(uint32_t selectClock) 484 { 485 ASSERT( 486 selectClock == CS_ACLK || selectClock == CS_HSMCLK 487 || selectClock == CS_SMCLK || selectClock == CS_MCLK); 488 489 /* Unlocking the module */ 490 CS->KEY = CS_KEY; 491 492 CS->CLKEN |= selectClock; 493 494 /* Locking the module */ 495 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 496 } 497 498 void CS_disableClockRequest(uint32_t selectClock) 499 { 500 ASSERT( 501 selectClock == CS_ACLK || selectClock == CS_HSMCLK 502 || selectClock == CS_SMCLK || selectClock == CS_MCLK); 503 504 /* Unlocking the module */ 505 CS->KEY = CS_KEY; 506 507 CS->CLKEN &= ~selectClock; 508 509 /* Locking the module */ 510 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 511 } 512 513 void CS_setReferenceOscillatorFrequency(uint8_t referenceFrequency) 514 { 515 ASSERT( 516 referenceFrequency == CS_REFO_32KHZ 517 || referenceFrequency == CS_REFO_128KHZ); 518 519 /* Unlocking the module */ 520 CS->KEY = CS_KEY; 521 522 BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS) = referenceFrequency; 523 524 /* Locking the module */ 525 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 526 } 527 528 void CS_enableDCOExternalResistor(void) 529 { 530 /* Unlocking the module */ 531 CS->KEY = CS_KEY; 532 533 BITBAND_PERI(CS->CTL0,CS_CTL0_DCORES_OFS) = 1; 534 535 /* Locking the module */ 536 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 537 } 538 539 void CS_setDCOExternalResistorCalibration(uint_fast8_t calData, 540 uint_fast8_t freqRange) 541 { 542 uint_fast8_t rselVal; 543 544 /* Unlocking the module */ 545 CS->KEY = CS_KEY; 546 547 rselVal = (CS->CTL0 | CS_CTL0_DCORSEL_MASK) >> CS_CTL0_DCORSEL_OFS; 548 549 CS->CTL0 &= ~CS_CTL0_DCORSEL_MASK; 550 551 if ((freqRange == CS_OVER32MHZ)) 552 { 553 CS->DCOERCAL1 &= ~CS_DCOERCAL1_DCO_FCAL_RSEL5_MASK; 554 CS->DCOERCAL1 |= (calData); 555 } else 556 { 557 CS->DCOERCAL0 &= ~CS_DCOERCAL0_DCO_FCAL_RSEL04_MASK; 558 CS->DCOERCAL0 |= (calData) << CS_DCOERCAL0_DCO_FCAL_RSEL04_OFS; 559 } 560 561 CS->CTL0 |= (rselVal) << CS_CTL0_DCORSEL_OFS; 562 563 /* Locking the module */ 564 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 565 566 } 567 568 void CS_disableDCOExternalResistor(void) 569 { 570 /* Unlocking the module */ 571 CS->KEY = CS_KEY; 572 573 BITBAND_PERI(CS->CTL0,CS_CTL0_DCORES_OFS) = 0; 574 575 /* Locking the module */ 576 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 577 } 578 579 void CS_setDCOCenteredFrequency(uint32_t dcoFreq) 580 { 581 ASSERT( 582 dcoFreq == CS_DCO_FREQUENCY_1_5 || dcoFreq == CS_DCO_FREQUENCY_3 583 || dcoFreq == CS_DCO_FREQUENCY_6 584 || dcoFreq == CS_DCO_FREQUENCY_12 585 || dcoFreq == CS_DCO_FREQUENCY_24 586 || dcoFreq == CS_DCO_FREQUENCY_48); 587 588 /* Unlocking the CS Module */ 589 CS->KEY = CS_KEY; 590 591 /* Resetting Tuning Parameters and Setting the frequency */ 592 CS->CTL0 = ((CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dcoFreq); 593 594 /* Locking the CS Module */ 595 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 596 } 597 598 void CS_tuneDCOFrequency(int16_t tuneParameter) 599 { 600 CS->KEY = CS_KEY; 601 602 uint16_t dcoTuneMask = 0x1FFF; 603 uint16_t dcoTuneSigned = 0x1000; 604 605 dcoTuneMask = 0x3FF; 606 dcoTuneSigned = 0x200; 607 608 if (tuneParameter < 0) 609 { 610 CS->CTL0 = ((CS->CTL0 & ~dcoTuneMask) | (tuneParameter & dcoTuneMask) 611 | dcoTuneSigned); 612 } else 613 { 614 CS->CTL0 = ((CS->CTL0 & ~dcoTuneMask) | (tuneParameter & dcoTuneMask)); 615 } 616 617 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 618 } 619 620 uint32_t CS_getDCOFrequency(void) 621 { 622 float dcoConst; 623 int32_t calVal; 624 uint32_t centeredFreq; 625 int16_t dcoTune; 626 uint_fast8_t tlvLength; 627 uint32_t retVal; 628 629 #ifdef __MCU_HAS_SYSCTL_A__ 630 SysCtl_A_CSCalTLV_Info *csInfo; 631 632 /* Parsing the TLV and getting the trim information */ 633 SysCtl_A_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**) &csInfo); 634 #else 635 SysCtl_CSCalTLV_Info *csInfo; 636 637 /* Parsing the TLV and getting the trim information */ 638 SysCtl_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**) &csInfo); 639 #endif 640 641 centeredFreq = _CSGetDOCFrequency(); 642 643 if (tlvLength == 0) 644 { 645 return centeredFreq; 646 } 647 648 dcoTune = CS->CTL0 & 0x3FF; 649 if (dcoTune & 0x200) 650 { 651 dcoTune = dcoTune | 0xFE00; 652 } 653 654 if (dcoTune == 0) 655 return (uint32_t) centeredFreq; 656 657 /* DCORSEL = 5 */ 658 if ((centeredFreq == 48000000)) 659 { 660 /* External Resistor */ 661 if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) 662 { 663 dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL5); 664 calVal = csInfo->rDCOER_FCAL_RSEL5; 665 } 666 /* Internal Resistor */ 667 else 668 { 669 dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL5); 670 calVal = csInfo->rDCOIR_FCAL_RSEL5; 671 } 672 } 673 /* DCORSEL = 4 */ 674 else 675 { 676 /* External Resistor */ 677 if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) 678 { 679 dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL04); 680 calVal = csInfo->rDCOER_FCAL_RSEL04; 681 } 682 /* Internal Resistor */ 683 else 684 { 685 dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL04); 686 calVal = csInfo->rDCOIR_FCAL_RSEL04; 687 } 688 } 689 retVal = (uint32_t) ((centeredFreq) 690 / (1 - ((dcoConst * dcoTune) / ((1 + dcoConst * (768 - calVal)))))); 691 692 return retVal; 693 } 694 695 void CS_setDCOFrequency(uint32_t dcoFrequency) 696 { 697 int32_t nomFreq, calVal, dcoSigned; 698 int16_t dcoTune; 699 float dcoConst; 700 bool rsel5 = false; 701 dcoSigned = (int32_t) dcoFrequency; 702 uint_fast8_t tlvLength; 703 704 #ifdef __MCU_HAS_SYSCTL_A__ 705 SysCtl_A_CSCalTLV_Info *csInfo; 706 707 /* Parsing the TLV and getting the trim information */ 708 SysCtl_A_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**) &csInfo); 709 #else 710 SysCtl_CSCalTLV_Info *csInfo; 711 712 /* Parsing the TLV and getting the trim information */ 713 SysCtl_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**) &csInfo); 714 #endif 715 716 717 if (dcoFrequency < 2000000) 718 { 719 nomFreq = CS_15MHZ; 720 CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_1_5); 721 } else if (dcoFrequency < 4000000) 722 { 723 nomFreq = CS_3MHZ; 724 CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_3); 725 } else if (dcoFrequency < 8000000) 726 { 727 nomFreq = CS_6MHZ; 728 CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_6); 729 } else if (dcoFrequency < 16000000) 730 { 731 nomFreq = CS_12MHZ; 732 CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12); 733 } else if (dcoFrequency < 32000000) 734 { 735 nomFreq = CS_24MHZ; 736 CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_24); 737 } else if (dcoFrequency < 640000001) 738 { 739 nomFreq = CS_48MHZ; 740 CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48); 741 rsel5 = true; 742 } else 743 { 744 ASSERT(false); 745 return; 746 } 747 748 if (dcoFrequency == nomFreq || tlvLength == 0) 749 { 750 CS_tuneDCOFrequency(0); 751 return; 752 } 753 754 if (rsel5) 755 { 756 /* External Resistor*/ 757 if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) 758 { 759 dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL5); 760 calVal = csInfo->rDCOER_FCAL_RSEL5; 761 } 762 /* Internal Resistor */ 763 else 764 { 765 dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL5); 766 calVal = csInfo->rDCOIR_FCAL_RSEL5; 767 } 768 } 769 /* DCORSEL = 4 */ 770 else 771 { 772 /* External Resistor */ 773 if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) 774 { 775 dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL04); 776 calVal = csInfo->rDCOER_FCAL_RSEL04; 777 } 778 /* Internal Resistor */ 779 else 780 { 781 dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL04); 782 calVal = csInfo->rDCOIR_FCAL_RSEL04; 783 } 784 } 785 786 dcoTune = (int16_t) (((dcoSigned - nomFreq) 787 * (1.0f + dcoConst * (768.0f - calVal))) / (dcoSigned * dcoConst)); 788 789 CS_tuneDCOFrequency(dcoTune); 790 791 } 792 793 uint32_t CS_getBCLK(void) 794 { 795 if (BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS)) 796 return _CSComputeCLKFrequency(CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); 797 else 798 return _CSComputeCLKFrequency(CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1); 799 } 800 801 uint32_t CS_getHSMCLK(void) 802 { 803 uint32_t wSource, wDivider; 804 805 wSource = (CS->CTL1 & CS_CTL1_SELS_MASK) >> CS_HSMCLK_SRC_BITPOS; 806 wDivider = ((CS->CTL1 & CS_CTL1_DIVHS_MASK) << CS_HSMCLK_DIV_BITPOS); 807 808 return _CSComputeCLKFrequency(wSource, wDivider); 809 } 810 811 uint32_t CS_getACLK(void) 812 { 813 uint32_t wSource, wDivider; 814 815 wSource = (CS->CTL1 & CS_CTL1_SELA_MASK) >> CS_ACLK_SRC_BITPOS; 816 wDivider = ((CS->CTL1 & CS_CTL1_DIVA_MASK) << CS_ACLK_DIV_BITPOS); 817 818 return _CSComputeCLKFrequency(wSource, wDivider); 819 } 820 821 uint32_t CS_getSMCLK(void) 822 { 823 uint32_t wDivider, wSource; 824 825 wSource = (CS->CTL1 & CS_CTL1_SELS_MASK) >> CS_HSMCLK_SRC_BITPOS; 826 wDivider = ((CS->CTL1 & CS_CTL1_DIVS_MASK)); 827 828 return _CSComputeCLKFrequency(wSource, wDivider); 829 830 } 831 832 uint32_t CS_getMCLK(void) 833 { 834 uint32_t wSource, wDivider; 835 836 wSource = (CS->CTL1 & CS_CTL1_SELM_MASK) << CS_MCLK_SRC_BITPOS; 837 wDivider = ((CS->CTL1 & CS_CTL1_DIVM_MASK) << CS_MCLK_DIV_BITPOS); 838 839 return _CSComputeCLKFrequency(wSource, wDivider); 840 } 841 842 void CS_enableFaultCounter(uint_fast8_t counterSelect) 843 { 844 ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER || 845 counterSelect == CS_HFXT_FAULT_COUNTER); 846 847 /* Unlocking the module */ 848 CS->KEY = CS_KEY; 849 850 if (counterSelect == CS_HFXT_FAULT_COUNTER) 851 { 852 BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTHF_EN_OFS) = 1; 853 } else 854 { 855 BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTLF_EN_OFS) = 1; 856 } 857 858 /* Locking the module */ 859 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 860 } 861 862 void CS_disableFaultCounter(uint_fast8_t counterSelect) 863 { 864 ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER || 865 counterSelect == CS_HFXT_FAULT_COUNTER); 866 867 /* Unlocking the module */ 868 CS->KEY = CS_KEY; 869 870 if (counterSelect == CS_HFXT_FAULT_COUNTER) 871 { 872 BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTHF_EN_OFS) = 0; 873 } else 874 { 875 BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTLF_EN_OFS) = 0; 876 } 877 878 /* Locking the module */ 879 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 880 } 881 882 void CS_resetFaultCounter(uint_fast8_t counterSelect) 883 { 884 ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER || 885 counterSelect == CS_HFXT_FAULT_COUNTER); 886 887 /* Unlocking the module */ 888 CS->KEY = CS_KEY; 889 890 if (counterSelect == CS_HFXT_FAULT_COUNTER) 891 { 892 BITBAND_PERI(CS->CTL3, CS_CTL3_RFCNTHF_OFS) = 1; 893 } else 894 { 895 BITBAND_PERI(CS->CTL3, CS_CTL3_RFCNTLF_OFS) = 1; 896 } 897 898 /* Locking the module */ 899 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 900 } 901 902 void CS_startFaultCounter(uint_fast8_t counterSelect, uint_fast8_t countValue) 903 { 904 ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER || 905 counterSelect == CS_HFXT_FAULT_COUNTER); 906 907 ASSERT(countValue == CS_FAULT_COUNTER_4096_CYCLES || 908 countValue == CS_FAULT_COUNTER_8192_CYCLES || 909 countValue == CS_FAULT_COUNTER_16384_CYCLES || 910 countValue == CS_FAULT_COUNTER_32768_CYCLES); 911 912 /* Unlocking the module */ 913 CS->KEY = CS_KEY; 914 915 if (counterSelect == CS_HFXT_FAULT_COUNTER) 916 { 917 CS->CTL3 = ((CS->CTL3 & ~CS_CTL3_FCNTHF_MASK) | (countValue << 4)); 918 } else 919 { 920 CS->CTL3 = ((CS->CTL3 & ~CS_CTL3_FCNTLF_MASK) | (countValue)); 921 } 922 923 /* Locking the module */ 924 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 925 } 926 927 void CS_enableInterrupt(uint32_t flags) 928 { 929 /* Unlocking the module */ 930 CS->KEY = CS_KEY; 931 932 CS->IE |= flags; 933 934 /* Locking the module */ 935 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 936 } 937 938 void CS_disableInterrupt(uint32_t flags) 939 { 940 /* Unlocking the module */ 941 CS->KEY = CS_KEY; 942 943 CS->IE &= ~flags; 944 945 /* Locking the module */ 946 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 947 } 948 949 uint32_t CS_getInterruptStatus(void) 950 { 951 return CS->IFG; 952 } 953 954 uint32_t CS_getEnabledInterruptStatus(void) 955 { 956 return CS_getInterruptStatus() & CS->IE; 957 } 958 959 void CS_clearInterruptFlag(uint32_t flags) 960 { 961 /* Unlocking the module */ 962 CS->KEY = CS_KEY; 963 964 CS->CLRIFG |= flags; 965 966 /* Locking the module */ 967 BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; 968 } 969 970 void CS_registerInterrupt(void (*intHandler)(void)) 971 { 972 // 973 // Register the interrupt handler, returning an error if an error occurs. 974 // 975 Interrupt_registerInterrupt(INT_CS, intHandler); 976 977 // 978 // Enable the system control interrupt. 979 // 980 Interrupt_enableInterrupt(INT_CS); 981 } 982 983 void CS_unregisterInterrupt(void) 984 { 985 // 986 // Disable the interrupt. 987 // 988 Interrupt_disableInterrupt(INT_CS); 989 990 // 991 // Unregister the interrupt handler. 992 // 993 Interrupt_unregisterInterrupt(INT_CS); 994 } 995 996