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 
_CSIsClockDividerValid(uint8_t divider)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 
_CSGetHFXTFrequency()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 
_CSGetDividerValue(uint32_t wDivider)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 
_CSComputeCLKFrequency(uint32_t wClockSource,uint32_t wDivider)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 //******************************************************************************
_CSGetDOCFrequency(void)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 
CS_setExternalClockSourceFrequency(uint32_t lfxt_XT_CLK_frequency,uint32_t hfxt_XT_CLK_frequency)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 
CS_initClockSignal(uint32_t selectedClockSignal,uint32_t clockSource,uint32_t clockSourceDivider)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 
CS_startHFXT(bool bypassMode)335 bool CS_startHFXT(bool bypassMode)
336 {
337     return CS_startHFXTWithTimeout(bypassMode, 0);
338 }
339 
CS_startHFXTWithTimeout(bool bypassMode,uint32_t timeout)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 
CS_startLFXT(uint32_t xtDrive)409 bool CS_startLFXT(uint32_t xtDrive)
410 {
411     return CS_startLFXTWithTimeout(xtDrive, 0);
412 }
413 
CS_startLFXTWithTimeout(uint32_t xtDrive,uint32_t timeout)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 
CS_enableClockRequest(uint32_t selectClock)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 
CS_disableClockRequest(uint32_t selectClock)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 
CS_setReferenceOscillatorFrequency(uint8_t referenceFrequency)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 
CS_enableDCOExternalResistor(void)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 
CS_setDCOExternalResistorCalibration(uint_fast8_t calData,uint_fast8_t freqRange)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 
CS_disableDCOExternalResistor(void)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 
CS_setDCOCenteredFrequency(uint32_t dcoFreq)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 
CS_tuneDCOFrequency(int16_t tuneParameter)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 
CS_getDCOFrequency(void)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 
CS_setDCOFrequency(uint32_t dcoFrequency)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 
CS_getBCLK(void)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 
CS_getHSMCLK(void)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 
CS_getACLK(void)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 
CS_getSMCLK(void)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 
CS_getMCLK(void)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 
CS_enableFaultCounter(uint_fast8_t counterSelect)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 
CS_disableFaultCounter(uint_fast8_t counterSelect)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 
CS_resetFaultCounter(uint_fast8_t counterSelect)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 
CS_startFaultCounter(uint_fast8_t counterSelect,uint_fast8_t countValue)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 
CS_enableInterrupt(uint32_t flags)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 
CS_disableInterrupt(uint32_t flags)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 
CS_getInterruptStatus(void)949 uint32_t CS_getInterruptStatus(void)
950 {
951     return CS->IFG;
952 }
953 
CS_getEnabledInterruptStatus(void)954 uint32_t CS_getEnabledInterruptStatus(void)
955 {
956     return CS_getInterruptStatus() & CS->IE;
957 }
958 
CS_clearInterruptFlag(uint32_t flags)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 
CS_registerInterrupt(void (* intHandler)(void))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 
CS_unregisterInterrupt(void)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