]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4F_MSP432_LaunchPad_IAR_CCS_Keil/driverlib/cs.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / CORTEX_M4F_MSP432_LaunchPad_IAR_CCS_Keil / driverlib / cs.c
1 /*
2  * -------------------------------------------
3  *    MSP432 DriverLib - v3_10_00_09 
4  * -------------------------------------------
5  *
6  * --COPYRIGHT--,BSD,BSD
7  * Copyright (c) 2014, Texas Instruments Incorporated
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * *  Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  *
17  * *  Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * *  Neither the name of Texas Instruments Incorporated nor the names of
22  *    its contributors may be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  * --/COPYRIGHT--*/
37 /* Standard Includes */
38 #include <stdint.h>
39
40 /* DriverLib Includes */
41 #include <cs.h>
42 #include <debug.h>
43 #include <sysctl.h>
44 #include <interrupt.h>
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_5;
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     bNMIStatus = SysCtl_getNMISourceStatus() & SYSCTL_CS_SRC;
351     SysCtl_disableNMISource(SYSCTL_CS_SRC);
352
353     /* Determining which frequency range to use */
354     wHFFreqRange = _CSGetHFXTFrequency();
355     boolTimeout = (timeout == 0) ? false : true;
356
357     /* Setting to maximum drive strength  */
358     BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 1;
359     CS->CTL2 = (CS->CTL2 & (~CS_CTL2_HFXTFREQ_MASK)) | (wHFFreqRange);
360
361     if (bypassMode)
362     {
363         BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTBYPASS_OFS) = 1;
364     } else
365     {
366         BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTBYPASS_OFS) = 0;
367     }
368
369     /* Starting and Waiting for frequency stabilization */
370     BITBAND_PERI(CS->CTL2, CS_CTL2_HFXT_EN_OFS) = 1;
371     while (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS))
372     {
373         if (boolTimeout && ((--timeout) == 0))
374             break;
375
376         BITBAND_PERI(CS->CLRIFG,CS_CLRIFG_CLR_HFXTIFG_OFS) = 1;
377     }
378     
379     /* Setting the drive strength */
380     if (!bypassMode)
381     {
382         if (wHFFreqRange != CS_CTL2_HFXTFREQ_0)
383             BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 1;
384         else
385             BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 0;
386     }
387
388     /* Locking the module */
389     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
390
391     /* Enabling the NMI state */
392     SysCtl_enableNMISource(bNMIStatus);
393     
394     if(boolTimeout && timeout == 0)
395         return false;
396
397     return true;
398 }
399
400 bool CS_startLFXT(uint32_t xtDrive)
401 {
402     return CS_startLFXTWithTimeout(xtDrive, 0);
403 }
404
405 bool CS_startLFXTWithTimeout(uint32_t xtDrive, uint32_t timeout)
406 {
407     uint8_t bNMIStatus;
408     bool boolBypassMode, boolTimeout;
409
410     ASSERT(lfxtFreq != 0)
411     ASSERT(
412             (xtDrive == CS_LFXT_DRIVE0) || (xtDrive == CS_LFXT_DRIVE1)
413             || (xtDrive == CS_LFXT_DRIVE2)
414             || (xtDrive == CS_LFXT_DRIVE3)
415             || (xtDrive == CS_LFXT_BYPASS));
416
417     /* Unlocking the CS Module */
418     CS->KEY = CS_KEY;
419
420     /* Saving status and temporarily disabling NMIs for UCS faults */
421     bNMIStatus = SysCtl_getNMISourceStatus() & SYSCTL_CS_SRC;
422     SysCtl_disableNMISource(SYSCTL_CS_SRC);
423     boolBypassMode = (xtDrive == CS_LFXT_BYPASS) ? true : false;
424     boolTimeout = (timeout == 0) ? false : true;
425
426     /* Setting to maximum drive strength  */
427     if (boolBypassMode)
428     {
429         BITBAND_PERI(CS->CTL2, CS_CTL2_LFXTBYPASS_OFS) = 1;
430     } else
431     {
432         CS->CTL2 |= (CS_LFXT_DRIVE3);
433         BITBAND_PERI(CS->CTL2, CS_CTL2_LFXTBYPASS_OFS) = 0;
434     }
435
436     /* Waiting for frequency stabilization */
437     BITBAND_PERI(CS->CTL2, CS_CTL2_LFXT_EN_OFS) = 1;
438
439     while (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS))
440     {
441         if (boolTimeout && ((--timeout) == 0))
442             break;
443
444         BITBAND_PERI(CS->CLRIFG,CS_CLRIFG_CLR_LFXTIFG_OFS) = 1;
445     }
446
447     /* Setting the drive strength */
448     if (!boolBypassMode)
449     {
450         CS->CTL2 = ((CS->CTL2 & ~CS_LFXT_DRIVE3) | xtDrive);
451     }
452
453     /* Locking the module */
454     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
455
456     /* Enabling the NMI state */
457     SysCtl_enableNMISource(bNMIStatus);
458     
459     if(boolTimeout && timeout == 0)
460         return false;
461
462     return true;
463 }
464
465 void CS_enableClockRequest(uint32_t selectClock)
466 {
467     ASSERT(
468             selectClock == CS_ACLK || selectClock == CS_HSMCLK
469             || selectClock == CS_SMCLK || selectClock == CS_MCLK);
470
471     /* Unlocking the module */
472     CS->KEY = CS_KEY;
473
474     CS->CLKEN |= selectClock;
475
476     /* Locking the module */
477     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
478 }
479
480 void CS_disableClockRequest(uint32_t selectClock)
481 {
482     ASSERT(
483             selectClock == CS_ACLK || selectClock == CS_HSMCLK
484             || selectClock == CS_SMCLK || selectClock == CS_MCLK);
485
486     /* Unlocking the module */
487     CS->KEY = CS_KEY;
488
489     CS->CLKEN &= ~selectClock;
490
491     /* Locking the module */
492     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
493 }
494
495 void CS_setReferenceOscillatorFrequency(uint8_t referenceFrequency)
496 {
497     ASSERT(
498             referenceFrequency == CS_REFO_32KHZ
499             || referenceFrequency == CS_REFO_128KHZ);
500
501     /* Unlocking the module */
502     CS->KEY = CS_KEY;
503
504     BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS) = referenceFrequency;
505
506     /* Locking the module */
507     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
508 }
509
510 void CS_enableDCOExternalResistor(void)
511 {
512     /* Unlocking the module */
513     CS->KEY = CS_KEY;
514
515     BITBAND_PERI(CS->CTL0,CS_CTL0_DCORES_OFS) = 1;
516
517     /* Locking the module */
518     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
519 }
520
521 void CS_setDCOExternalResistorCalibration(uint_fast8_t calData, 
522                                             uint_fast8_t freqRange)
523 {
524     uint_fast8_t rselVal;
525
526     /* Unlocking the module */
527     CS->KEY = CS_KEY;
528
529     rselVal = (CS->CTL0 | CS_CTL0_DCORSEL_MASK)>>CS_CTL0_DCORSEL_OFS;
530
531     CS->CTL0 &= ~CS_CTL0_DCORSEL_MASK;
532
533     if( (freqRange == CS_OVER32MHZ) && ( TLV->HWREV > DEVICE_PG1_1))
534     {
535         CS->DCOERCAL1 &= ~CS_DCOERCAL1_DCO_FCAL_RSEL5_MASK;
536         CS->DCOERCAL1 |= (calData);
537     }
538     else
539     {
540         CS->DCOERCAL0 &= ~CS_DCOERCAL0_DCO_FCAL_RSEL04_MASK;
541         CS->DCOERCAL0 |= (calData)<<CS_DCOERCAL0_DCO_FCAL_RSEL04_OFS;
542     }
543
544     CS->CTL0 |= (rselVal)<<CS_CTL0_DCORSEL_OFS;
545
546     /* Locking the module */
547     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
548
549 }
550
551 void CS_disableDCOExternalResistor(void)
552 {
553     /* Unlocking the module */
554     CS->KEY = CS_KEY;
555
556     BITBAND_PERI(CS->CTL0,CS_CTL0_DCORES_OFS) = 0;
557
558     /* Locking the module */
559     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
560 }
561
562 void CS_setDCOCenteredFrequency(uint32_t dcoFreq)
563 {
564     ASSERT(
565             dcoFreq == CS_DCO_FREQUENCY_1_5 || dcoFreq == CS_DCO_FREQUENCY_3
566             || dcoFreq == CS_DCO_FREQUENCY_6
567             || dcoFreq == CS_DCO_FREQUENCY_12
568             || dcoFreq == CS_DCO_FREQUENCY_24
569             || dcoFreq == CS_DCO_FREQUENCY_48);
570
571     /* Unlocking the CS Module */
572     CS->KEY = CS_KEY;
573
574     /* Resetting Tuning Parameters and Setting the frequency */
575     CS->CTL0 = ((CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dcoFreq);
576
577     /* Locking the CS Module */
578     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
579 }
580
581 void CS_tuneDCOFrequency(int16_t tuneParameter)
582 {
583     CS->KEY = CS_KEY;
584
585     uint16_t dcoTuneMask = 0x1FFF;
586     uint16_t dcoTuneSigned = 0x1000;
587
588     if (TLV->HWREV > DEVICE_PG1_1) {
589         dcoTuneMask = 0x3FF;
590         dcoTuneSigned = 0x200;
591     }
592
593     if (tuneParameter < 0)
594     {
595         CS->CTL0 = ((CS->CTL0 & ~dcoTuneMask) | (tuneParameter
596                         & dcoTuneMask) | dcoTuneSigned);
597     } 
598     else
599     {
600                 CS->CTL0 = ((CS->CTL0 & ~dcoTuneMask) | (tuneParameter
601                                         & dcoTuneMask));
602     }
603      
604      BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
605 }
606
607 uint32_t CS_getDCOFrequency(void)
608 {
609     float dcoConst;
610     int32_t calVal;
611     uint32_t centeredFreq;
612     int16_t dcoTune;
613     uint_fast8_t tlvLength;
614     SysCtl_CSCalTLV_Info *csInfo;
615     uint32_t retVal;
616
617     centeredFreq = _CSGetDOCFrequency();
618
619     /* Parsing the TLV and getting the maximum erase pulses */
620     SysCtl_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**)&csInfo);
621
622     if(tlvLength == 0)
623     {
624         return centeredFreq;
625     }
626
627     /* Checking to see if we need to do signed conversion */
628     if ( TLV->HWREV > DEVICE_PG1_1)
629     {
630         dcoTune = CS->CTL0 & 0x3FF;
631         if (dcoTune & 0x200)
632         {
633             dcoTune = dcoTune | 0xFE00;
634         }
635     }
636     else
637     {
638         dcoTune = CS->CTL0 & 0x1FFF;
639         if (dcoTune & 0x1000)
640         {
641             dcoTune = dcoTune | 0xF000;
642         }
643     }
644     
645     if (dcoTune == 0)
646         return (uint32_t) centeredFreq;
647
648     /* DCORSEL = 5  */
649     if ((centeredFreq == 48000000) && ( TLV->HWREV > DEVICE_PG1_1))
650     {
651          /* External Resistor */
652         if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
653         {
654             dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL5);
655             calVal = csInfo->rDCOER_FCAL_RSEL5;
656         }
657         /* Internal Resistor */
658         else
659         {
660             dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL5);
661             calVal = csInfo->rDCOIR_FCAL_RSEL5;
662         }
663     }
664     /* DCORSEL = 4 */
665     else
666     {
667         /* External Resistor */
668         if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
669         {
670             dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL04);
671             calVal = csInfo->rDCOER_FCAL_RSEL04;
672         }
673         /* Internal Resistor */
674         else
675         {
676             dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL04);
677             calVal = csInfo->rDCOIR_FCAL_RSEL04;
678         }
679     }
680
681     if( TLV->HWREV > DEVICE_PG1_1 )
682     {
683         retVal = (uint32_t) (centeredFreq)
684             / (1 - ((dcoConst * dcoTune)
685                             / ((1 + dcoConst * (768 - calVal)))));
686     }
687     else
688     {
689         retVal = (uint32_t) (centeredFreq)
690             / (1 - ((dcoConst * dcoTune)
691                             / (8 * (1 + dcoConst * (768 - calVal)))));
692     }    
693     return retVal;
694 }
695
696 void CS_setDCOFrequency(uint32_t dcoFrequency)
697 {
698     int32_t nomFreq, calVal, dcoSigned;
699     int16_t dcoTune;
700     float dcoConst;
701     bool rsel5 = false;
702     dcoSigned = (int32_t) dcoFrequency;
703     uint_fast8_t tlvLength;
704      SysCtl_CSCalTLV_Info *csInfo;
705
706     if (dcoFrequency < 2000000)
707     {
708         nomFreq = CS_15MHZ;
709         CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_1_5);
710     } else if (dcoFrequency < 4000000)
711     {
712         nomFreq = CS_3MHZ;
713         CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_3);
714     } else if (dcoFrequency < 8000000)
715     {
716         nomFreq = CS_6MHZ;
717         CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_6);
718     } else if (dcoFrequency < 16000000)
719     {
720         nomFreq = CS_12MHZ;
721         CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
722     } else if (dcoFrequency < 32000000)
723     {
724         nomFreq = CS_24MHZ;
725         CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_24);
726     } else if (dcoFrequency < 640000001)
727     {
728         nomFreq = CS_48MHZ;
729         CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
730         rsel5 = true;
731     } else
732     {
733         ASSERT(false);
734         return;
735     }
736     
737     /* Parsing the TLV and getting the maximum erase pulses */
738     SysCtl_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**)&csInfo);
739
740     if(dcoFrequency == nomFreq || tlvLength == 0)
741     {
742        CS_tuneDCOFrequency(0);
743        return;
744     }
745
746     if ((rsel5) && ( TLV->HWREV > DEVICE_PG1_1))
747     {
748         /* External Resistor*/
749         if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
750         {
751             dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL5);
752             calVal = csInfo->rDCOER_FCAL_RSEL5;
753         }
754         /* Internal Resistor */
755         else
756         {
757             dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL5);
758             calVal = csInfo->rDCOIR_FCAL_RSEL5;
759         }
760     }
761     /* DCORSEL = 4 */
762     else
763     {
764         /* External Resistor */
765         if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS))
766         {
767             dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL04);
768             calVal = csInfo->rDCOER_FCAL_RSEL04;
769         }
770         /* Internal Resistor */
771         else
772         {
773             dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL04);
774             calVal = csInfo->rDCOIR_FCAL_RSEL04;
775         }
776     }
777
778     if ( TLV->HWREV > DEVICE_PG1_1)
779         dcoTune = (int16_t) (((dcoSigned - nomFreq)
780                 * (1.0f + dcoConst * (768.0f - calVal)))
781                 / (dcoSigned * dcoConst));
782     else
783         dcoTune = (int16_t) (((dcoSigned - nomFreq)
784                 * (1.0f + dcoConst * (768.0f - calVal)) * 8.0f)
785                 / (dcoSigned * dcoConst));
786
787     CS_tuneDCOFrequency(dcoTune);
788
789 }
790
791 uint32_t CS_getBCLK(void)
792 {
793     if (BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS))
794         return _CSComputeCLKFrequency(CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
795     else
796         return _CSComputeCLKFrequency(CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
797 }
798
799 uint32_t CS_getHSMCLK(void)
800 {
801     uint32_t wSource, wDivider;
802
803     wSource = (CS->CTL1 & CS_CTL1_SELS_MASK) >> CS_HSMCLK_SRC_BITPOS;
804     wDivider = ((CS->CTL1 & CS_CTL1_DIVHS_MASK) << CS_HSMCLK_DIV_BITPOS);
805
806     return _CSComputeCLKFrequency(wSource, wDivider);
807 }
808
809 uint32_t CS_getACLK(void)
810 {
811     uint32_t wSource, wDivider;
812
813     wSource = (CS->CTL1 & CS_CTL1_SELA_MASK) >> CS_ACLK_SRC_BITPOS;
814     wDivider = ((CS->CTL1 & CS_CTL1_DIVA_MASK) << CS_ACLK_DIV_BITPOS);
815
816     return _CSComputeCLKFrequency(wSource, wDivider);
817 }
818
819 uint32_t CS_getSMCLK(void)
820 {
821     uint32_t wDivider, wSource;
822
823     wSource = (CS->CTL1 & CS_CTL1_SELS_MASK) >> CS_HSMCLK_SRC_BITPOS;
824     wDivider = ((CS->CTL1 & CS_CTL1_DIVS_MASK));
825
826     return _CSComputeCLKFrequency(wSource, wDivider);
827
828 }
829
830 uint32_t CS_getMCLK(void)
831 {
832     uint32_t wSource, wDivider;
833
834     wSource = (CS->CTL1 & CS_CTL1_SELM_MASK) << CS_MCLK_SRC_BITPOS;
835     wDivider = ((CS->CTL1 & CS_CTL1_DIVM_MASK) << CS_MCLK_DIV_BITPOS);
836
837     return _CSComputeCLKFrequency(wSource, wDivider);
838 }
839
840 void CS_enableFaultCounter(uint_fast8_t counterSelect)
841 {
842     ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER ||
843             counterSelect == CS_HFXT_FAULT_COUNTER);
844
845     /* Unlocking the module */
846     CS->KEY = CS_KEY;
847
848     if (counterSelect == CS_HFXT_FAULT_COUNTER)
849     {
850         BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTHF_EN_OFS) = 1;
851     } else
852     {
853         BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTLF_EN_OFS) = 1;
854     }
855
856     /* Locking the module */
857     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
858 }
859
860 void CS_disableFaultCounter(uint_fast8_t counterSelect)
861 {
862     ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER ||
863             counterSelect == CS_HFXT_FAULT_COUNTER);
864
865     /* Unlocking the module */
866     CS->KEY = CS_KEY;
867
868     if (counterSelect == CS_HFXT_FAULT_COUNTER)
869     {
870         BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTHF_EN_OFS) = 0;
871     } else
872     {
873         BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTLF_EN_OFS) = 0;
874     }
875
876     /* Locking the module */
877     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
878 }
879
880 void CS_resetFaultCounter(uint_fast8_t counterSelect)
881 {
882     ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER ||
883             counterSelect == CS_HFXT_FAULT_COUNTER);
884
885     /* Unlocking the module */
886     CS->KEY = CS_KEY;
887
888     if (counterSelect == CS_HFXT_FAULT_COUNTER)
889     {
890         BITBAND_PERI(CS->CTL3, CS_CTL3_RFCNTHF_OFS) = 1;
891     } else
892     {
893         BITBAND_PERI(CS->CTL3, CS_CTL3_RFCNTLF_OFS) = 1;
894     }
895
896     /* Locking the module */
897     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
898 }
899
900 void CS_startFaultCounter(uint_fast8_t counterSelect, uint_fast8_t countValue)
901 {
902     ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER ||
903             counterSelect == CS_HFXT_FAULT_COUNTER);
904
905     ASSERT(countValue == CS_FAULT_COUNTER_4096_CYCLES ||
906             countValue == CS_FAULT_COUNTER_8192_CYCLES ||
907             countValue == CS_FAULT_COUNTER_16384_CYCLES ||
908             countValue == CS_FAULT_COUNTER_32768_CYCLES);
909
910     /* Unlocking the module */
911     CS->KEY = CS_KEY;
912
913     if (counterSelect == CS_HFXT_FAULT_COUNTER)
914     {
915         CS->CTL3 = ((CS->CTL3 & ~CS_CTL3_FCNTHF_MASK) | (countValue << 4));
916     } else
917     {
918         CS->CTL3 = ((CS->CTL3 & ~CS_CTL3_FCNTLF_MASK) | (countValue));
919     }
920
921     /* Locking the module */
922     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
923 }
924
925 void CS_enableInterrupt(uint32_t flags)
926 {
927     /* Unlocking the module */
928     CS->KEY = CS_KEY;
929
930     CS->IE |= flags;
931
932     /* Locking the module */
933     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
934 }
935
936 void CS_disableInterrupt(uint32_t flags)
937 {
938     /* Unlocking the module */
939     CS->KEY = CS_KEY;
940
941     CS->IE &= ~flags;
942
943     /* Locking the module */
944     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
945 }
946
947 uint32_t CS_getInterruptStatus(void)
948 {
949     return CS->IFG;
950 }
951
952 uint32_t CS_getEnabledInterruptStatus(void)
953 {
954     return CS_getInterruptStatus() & CS->IE;
955 }
956
957 void CS_clearInterruptFlag(uint32_t flags)
958 {
959     /* Unlocking the module */
960     CS->KEY = CS_KEY;
961
962     CS->CLRIFG |= flags;
963
964     /* Locking the module */
965     BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1;
966 }
967
968 void CS_registerInterrupt(void (*intHandler)(void))
969 {
970     //
971     // Register the interrupt handler, returning an error if an error occurs.
972     //
973     Interrupt_registerInterrupt(INT_CS, intHandler);
974
975     //
976     // Enable the system control interrupt.
977     //
978     Interrupt_enableInterrupt(INT_CS);
979 }
980
981 void CS_unregisterInterrupt(void)
982 {
983     //
984     // Disable the interrupt.
985     //
986     Interrupt_disableInterrupt(INT_CS);
987
988     //
989     // Unregister the interrupt handler.
990     //
991     Interrupt_unregisterInterrupt(INT_CS);
992 }
993