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