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/pcm.h>
37 #include <ti/devices/msp432p4xx/driverlib/debug.h>
38 #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
39 #include <ti/devices/msp432p4xx/driverlib/wdt_a.h>
40 #include <ti/devices/msp432p4xx/driverlib/rtc_c.h>
41 #include <ti/devices/msp432p4xx/driverlib/cpu.h>
42
__PCM_setCoreVoltageLevelAdvanced(uint_fast8_t voltageLevel,uint32_t timeOut,bool blocking)43 static bool __PCM_setCoreVoltageLevelAdvanced(uint_fast8_t voltageLevel,
44 uint32_t timeOut, bool blocking)
45 {
46 uint8_t powerMode, bCurrentVoltageLevel;
47 uint32_t regValue;
48 bool boolTimeout;
49
50 ASSERT(voltageLevel == PCM_VCORE0 || voltageLevel == PCM_VCORE1);
51
52 /* Getting current power mode and level */
53 powerMode = PCM_getPowerMode();
54 bCurrentVoltageLevel = PCM_getCoreVoltageLevel();
55
56 boolTimeout = timeOut > 0 ? true : false;
57
58 /* If we are already at the power mode they requested, return */
59 if (bCurrentVoltageLevel == voltageLevel)
60 return true;
61
62 while (bCurrentVoltageLevel != voltageLevel)
63 {
64 regValue = PCM->CTL0;
65
66 switch (PCM_getPowerState())
67 {
68 case PCM_AM_LF_VCORE1:
69 case PCM_AM_DCDC_VCORE1:
70 case PCM_AM_LDO_VCORE0:
71 PCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE1)
72 | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
73 break;
74 case PCM_AM_LF_VCORE0:
75 case PCM_AM_DCDC_VCORE0:
76 case PCM_AM_LDO_VCORE1:
77 PCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE0)
78 | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
79 break;
80 default:
81 ASSERT(false);
82 }
83
84 if(blocking)
85 {
86 while (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
87 {
88 if (boolTimeout && !(--timeOut))
89 return false;
90
91 }
92 }
93 else
94 {
95 return true;
96 }
97
98 bCurrentVoltageLevel = PCM_getCoreVoltageLevel();
99 }
100
101 /* Changing the power mode if we are stuck in LDO mode */
102 if (powerMode != PCM_getPowerMode())
103 {
104 if (powerMode == PCM_DCDC_MODE)
105 return PCM_setPowerMode(PCM_DCDC_MODE);
106 else
107 return PCM_setPowerMode(PCM_LF_MODE);
108 }
109
110 return true;
111
112 }
113
114
PCM_setCoreVoltageLevel(uint_fast8_t voltageLevel)115 bool PCM_setCoreVoltageLevel(uint_fast8_t voltageLevel)
116 {
117 return __PCM_setCoreVoltageLevelAdvanced(voltageLevel, 0, true);
118 }
119
PCM_setCoreVoltageLevelWithTimeout(uint_fast8_t voltageLevel,uint32_t timeOut)120 bool PCM_setCoreVoltageLevelWithTimeout(uint_fast8_t voltageLevel,
121 uint32_t timeOut)
122 {
123 return __PCM_setCoreVoltageLevelAdvanced(voltageLevel, timeOut, true);
124 }
125
PCM_setCoreVoltageLevelNonBlocking(uint_fast8_t voltageLevel)126 bool PCM_setCoreVoltageLevelNonBlocking(uint_fast8_t voltageLevel)
127 {
128 return __PCM_setCoreVoltageLevelAdvanced(voltageLevel, 0, false);
129 }
130
PCM_getPowerMode(void)131 uint8_t PCM_getPowerMode(void)
132 {
133 uint8_t currentPowerState;
134
135 currentPowerState = PCM_getPowerState();
136
137 switch (currentPowerState)
138 {
139 case PCM_AM_LDO_VCORE0:
140 case PCM_AM_LDO_VCORE1:
141 case PCM_LPM0_LDO_VCORE0:
142 case PCM_LPM0_LDO_VCORE1:
143 return PCM_LDO_MODE;
144 case PCM_AM_DCDC_VCORE0:
145 case PCM_AM_DCDC_VCORE1:
146 case PCM_LPM0_DCDC_VCORE0:
147 case PCM_LPM0_DCDC_VCORE1:
148 return PCM_DCDC_MODE;
149 case PCM_LPM0_LF_VCORE0:
150 case PCM_LPM0_LF_VCORE1:
151 case PCM_AM_LF_VCORE1:
152 case PCM_AM_LF_VCORE0:
153 return PCM_LF_MODE;
154 default:
155 ASSERT(false);
156 return false;
157
158 }
159 }
160
PCM_getCoreVoltageLevel(void)161 uint8_t PCM_getCoreVoltageLevel(void)
162 {
163 uint8_t currentPowerState = PCM_getPowerState();
164
165 switch (currentPowerState)
166 {
167 case PCM_AM_LDO_VCORE0:
168 case PCM_AM_DCDC_VCORE0:
169 case PCM_AM_LF_VCORE0:
170 case PCM_LPM0_LDO_VCORE0:
171 case PCM_LPM0_DCDC_VCORE0:
172 case PCM_LPM0_LF_VCORE0:
173 return PCM_VCORE0;
174 case PCM_AM_LDO_VCORE1:
175 case PCM_AM_DCDC_VCORE1:
176 case PCM_AM_LF_VCORE1:
177 case PCM_LPM0_LDO_VCORE1:
178 case PCM_LPM0_DCDC_VCORE1:
179 case PCM_LPM0_LF_VCORE1:
180 return PCM_VCORE1;
181 case PCM_LPM3:
182 return PCM_VCORELPM3;
183 default:
184 ASSERT(false);
185 return false;
186
187 }
188 }
189
__PCM_setPowerModeAdvanced(uint_fast8_t powerMode,uint32_t timeOut,bool blocking)190 static bool __PCM_setPowerModeAdvanced(uint_fast8_t powerMode, uint32_t timeOut,
191 bool blocking)
192 {
193 uint8_t bCurrentPowerMode, bCurrentPowerState;
194 uint32_t regValue;
195 bool boolTimeout;
196
197 ASSERT(
198 powerMode == PCM_LDO_MODE || powerMode == PCM_DCDC_MODE
199 || powerMode == PCM_LF_MODE);
200
201 /* Getting Current Power Mode */
202 bCurrentPowerMode = PCM_getPowerMode();
203
204 /* If the power mode being set it the same as the current mode, return */
205 if (powerMode == bCurrentPowerMode)
206 return true;
207
208 bCurrentPowerState = PCM_getPowerState();
209
210 boolTimeout = timeOut > 0 ? true : false;
211
212 /* Go through the while loop while we haven't achieved the power mode */
213 while (bCurrentPowerMode != powerMode)
214 {
215 regValue = PCM->CTL0;
216
217 switch (bCurrentPowerState)
218 {
219 case PCM_AM_DCDC_VCORE0:
220 case PCM_AM_LF_VCORE0:
221 PCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE0
222 | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
223 break;
224 case PCM_AM_LF_VCORE1:
225 case PCM_AM_DCDC_VCORE1:
226 PCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE1
227 | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
228 break;
229 case PCM_AM_LDO_VCORE1:
230 {
231 if (powerMode == PCM_DCDC_MODE)
232 {
233 PCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE1
234 | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
235 } else if (powerMode == PCM_LF_MODE)
236 {
237 PCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE1
238 | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
239 } else
240 ASSERT(false);
241
242 break;
243 }
244 case PCM_AM_LDO_VCORE0:
245 {
246 if (powerMode == PCM_DCDC_MODE)
247 {
248 PCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE0
249 | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
250 } else if (powerMode == PCM_LF_MODE)
251 {
252 PCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE0
253 | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
254 } else
255 ASSERT(false);
256
257 break;
258 }
259 default:
260 ASSERT(false);
261 }
262
263 if (blocking)
264 {
265 while (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
266 {
267 if (boolTimeout && !(--timeOut))
268 return false;
269
270 }
271 } else
272 return true;
273
274 bCurrentPowerMode = PCM_getPowerMode();
275 bCurrentPowerState = PCM_getPowerState();
276 }
277
278 return true;
279
280 }
281
PCM_setPowerMode(uint_fast8_t powerMode)282 bool PCM_setPowerMode(uint_fast8_t powerMode)
283 {
284 return __PCM_setPowerModeAdvanced(powerMode, 0, true);
285 }
286
PCM_setPowerModeNonBlocking(uint_fast8_t powerMode)287 bool PCM_setPowerModeNonBlocking(uint_fast8_t powerMode)
288 {
289 return __PCM_setPowerModeAdvanced(powerMode, 0, false);
290 }
291
PCM_setPowerModeWithTimeout(uint_fast8_t powerMode,uint32_t timeOut)292 bool PCM_setPowerModeWithTimeout(uint_fast8_t powerMode, uint32_t timeOut)
293 {
294 return __PCM_setPowerModeAdvanced(powerMode, timeOut, true);
295 }
296
__PCM_setPowerStateAdvanced(uint_fast8_t powerState,uint32_t timeout,bool blocking)297 static bool __PCM_setPowerStateAdvanced(uint_fast8_t powerState,
298 uint32_t timeout,
299 bool blocking)
300 {
301 uint8_t bCurrentPowerState;
302 bCurrentPowerState = PCM_getPowerState();
303
304 ASSERT(
305 powerState == PCM_AM_LDO_VCORE0 || powerState == PCM_AM_LDO_VCORE1
306 || powerState == PCM_AM_DCDC_VCORE0 || powerState == PCM_AM_DCDC_VCORE1
307 || powerState == PCM_AM_LF_VCORE0 || powerState == PCM_AM_LF_VCORE1
308 || powerState == PCM_LPM0_LDO_VCORE0 || powerState == PCM_LPM0_LDO_VCORE1
309 || powerState == PCM_LPM0_DCDC_VCORE0 || powerState == PCM_LPM0_DCDC_VCORE1
310 || powerState == PCM_LPM3 || powerState == PCM_LPM35_VCORE0
311 || powerState == PCM_LPM45 || powerState == PCM_LPM4);
312
313 if (bCurrentPowerState == powerState)
314 return true;
315
316 switch (powerState)
317 {
318 case PCM_AM_LDO_VCORE0:
319 return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
320 && __PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking));
321 case PCM_AM_LDO_VCORE1:
322 return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
323 && __PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking));
324 case PCM_AM_DCDC_VCORE0:
325 return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
326 && __PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout, blocking));
327 case PCM_AM_DCDC_VCORE1:
328 return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
329 && __PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout, blocking));
330 case PCM_AM_LF_VCORE0:
331 return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
332 && __PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking));
333 case PCM_AM_LF_VCORE1:
334 return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
335 && __PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking));
336 case PCM_LPM0_LDO_VCORE0:
337 if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
338 || !__PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking))
339 break;
340 return PCM_gotoLPM0();
341 case PCM_LPM0_LDO_VCORE1:
342 if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
343 || !__PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking))
344 break;
345 return PCM_gotoLPM0();
346 case PCM_LPM0_DCDC_VCORE0:
347 if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
348 || !__PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout,
349 blocking))
350 break;
351 return PCM_gotoLPM0();
352 case PCM_LPM0_DCDC_VCORE1:
353 if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
354 || !__PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout,
355 blocking))
356 break;
357 return PCM_gotoLPM0();
358 case PCM_LPM0_LF_VCORE0:
359 if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
360 || !__PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking))
361 break;
362 return PCM_gotoLPM0();
363 case PCM_LPM0_LF_VCORE1:
364 if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
365 || !__PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking))
366 break;
367 return PCM_gotoLPM0();
368 case PCM_LPM3:
369 return PCM_gotoLPM3();
370 case PCM_LPM4:
371 return PCM_gotoLPM4();
372 case PCM_LPM45:
373 return PCM_shutdownDevice(PCM_LPM45);
374 case PCM_LPM35_VCORE0:
375 return PCM_shutdownDevice(PCM_LPM35_VCORE0);
376 default:
377 ASSERT(false);
378 return false;
379 }
380
381 return false;
382
383 }
384
PCM_setPowerState(uint_fast8_t powerState)385 bool PCM_setPowerState(uint_fast8_t powerState)
386 {
387 return __PCM_setPowerStateAdvanced(powerState, 0, true);
388 }
389
PCM_setPowerStateWithTimeout(uint_fast8_t powerState,uint32_t timeout)390 bool PCM_setPowerStateWithTimeout(uint_fast8_t powerState, uint32_t timeout)
391 {
392 return __PCM_setPowerStateAdvanced(powerState, timeout, true);
393 }
394
PCM_setPowerStateNonBlocking(uint_fast8_t powerState)395 bool PCM_setPowerStateNonBlocking(uint_fast8_t powerState)
396 {
397 return __PCM_setPowerStateAdvanced(powerState, 0, false);
398 }
399
PCM_shutdownDevice(uint32_t shutdownMode)400 bool PCM_shutdownDevice(uint32_t shutdownMode)
401 {
402 uint32_t shutdownModeBits = (shutdownMode == PCM_LPM45) ?
403 PCM_CTL0_LPMR_12 : PCM_CTL0_LPMR_10;
404
405 ASSERT(
406 shutdownMode == PCM_SHUTDOWN_PARTIAL
407 || shutdownMode == PCM_SHUTDOWN_COMPLETE);
408
409 /* If a power transition is occuring, return false */
410 if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
411 return false;
412
413 /* Initiating the shutdown */
414 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
415
416 PCM->CTL0 = (PCM_KEY | shutdownModeBits
417 | (PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK)));
418
419 CPU_wfi();
420
421 return true;
422 }
423
PCM_gotoLPM4(void)424 bool PCM_gotoLPM4(void)
425 {
426 /* Disabling RTC_C and WDT_A */
427 WDT_A_holdTimer();
428 RTC_C_holdClock();
429
430 /* LPM4 is just LPM3 with WDT_A/RTC_C disabled... */
431 return PCM_gotoLPM3();
432 }
433
PCM_gotoLPM4InterruptSafe(void)434 bool PCM_gotoLPM4InterruptSafe(void)
435 {
436 bool slHappenedCorrect;
437
438 /* Disabling master interrupts. In Cortex M, if an interrupt is enabled but
439 master interrupts are disabled and a WFI happens the WFI will
440 immediately exit. */
441 Interrupt_disableMaster();
442
443 slHappenedCorrect = PCM_gotoLPM4();
444
445 /* Enabling and Disabling Interrupts very quickly so that the
446 processor catches any pending interrupts */
447 Interrupt_enableMaster();
448 Interrupt_disableMaster();
449
450 return slHappenedCorrect;
451 }
452
PCM_gotoLPM0(void)453 bool PCM_gotoLPM0(void)
454 {
455 /* If we are in the middle of a state transition, return false */
456 if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
457 return false;
458
459 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
460
461 CPU_wfi();
462
463 return true;
464 }
465
PCM_gotoLPM0InterruptSafe(void)466 bool PCM_gotoLPM0InterruptSafe(void)
467 {
468 bool slHappenedCorrect;
469
470 /* Disabling master interrupts. In Cortex M, if an interrupt is enabled but
471 master interrupts are disabled and a WFI happens the WFI will
472 immediately exit. */
473 Interrupt_disableMaster();
474
475 slHappenedCorrect = PCM_gotoLPM0();
476
477 /* Enabling and Disabling Interrupts very quickly so that the
478 processor catches any pending interrupts */
479 Interrupt_enableMaster();
480 Interrupt_disableMaster();
481
482 return slHappenedCorrect;
483 }
484
PCM_gotoLPM3(void)485 bool PCM_gotoLPM3(void)
486 {
487 uint_fast8_t bCurrentPowerState;
488 uint_fast8_t currentPowerMode;
489
490 /* If we are in the middle of a state transition, return false */
491 if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
492 return false;
493
494 /* If we are in the middle of a shutdown, return false */
495 if ((PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_10
496 || (PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_12)
497 return false;
498
499 currentPowerMode = PCM_getPowerMode();
500 bCurrentPowerState = PCM_getPowerState();
501
502 if (currentPowerMode == PCM_DCDC_MODE)
503 PCM_setPowerMode(PCM_LDO_MODE);
504
505 /* Clearing the SDR */
506 PCM->CTL0 = (PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK)) | PCM_KEY;
507
508 /* Setting the sleep deep bit */
509 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
510
511 CPU_wfi();
512
513 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
514
515 return PCM_setPowerState(bCurrentPowerState);
516 }
517
PCM_gotoLPM3InterruptSafe(void)518 bool PCM_gotoLPM3InterruptSafe(void)
519 {
520 bool lpmHappenedCorrect;
521
522 /* Disabling master interrupts. In Cortex M, if an interrupt is enabled but
523 master interrupts are disabled and a WFI happens the WFI will
524 immediately exit. */
525 Interrupt_disableMaster();
526
527 lpmHappenedCorrect = PCM_gotoLPM3();
528
529 /* Enabling and Disabling Interrupts very quickly so that the
530 processor catches any pending interrupts */
531 Interrupt_enableMaster();
532 Interrupt_disableMaster();
533
534 return lpmHappenedCorrect;
535 }
536
PCM_getPowerState(void)537 uint8_t PCM_getPowerState(void)
538 {
539 return (PCM->CTL0 & PCM_CTL0_CPM_MASK) >> PCM_CTL0_CPM_OFS;
540 }
541
PCM_enableRudeMode(void)542 void PCM_enableRudeMode(void)
543 {
544
545 PCM->CTL1 = (PCM->CTL1 & ~(PCM_CTL0_KEY_MASK)) | PCM_KEY
546 | PCM_CTL1_FORCE_LPM_ENTRY;
547 }
548
PCM_disableRudeMode(void)549 void PCM_disableRudeMode(void)
550 {
551 PCM->CTL1 = (PCM->CTL1 & ~(PCM_CTL0_KEY_MASK | PCM_CTL1_FORCE_LPM_ENTRY))
552 | PCM_KEY;
553 }
554
PCM_enableInterrupt(uint32_t flags)555 void PCM_enableInterrupt(uint32_t flags)
556 {
557 PCM->IE |= flags;
558 }
559
PCM_disableInterrupt(uint32_t flags)560 void PCM_disableInterrupt(uint32_t flags)
561 {
562 PCM->IE &= ~flags;
563 }
564
PCM_getInterruptStatus(void)565 uint32_t PCM_getInterruptStatus(void)
566 {
567 return PCM->IFG;
568 }
569
PCM_getEnabledInterruptStatus(void)570 uint32_t PCM_getEnabledInterruptStatus(void)
571 {
572 return PCM_getInterruptStatus() & PCM->IE;
573 }
574
PCM_clearInterruptFlag(uint32_t flags)575 void PCM_clearInterruptFlag(uint32_t flags)
576 {
577 PCM->CLRIFG |= flags;
578 }
579
PCM_registerInterrupt(void (* intHandler)(void))580 void PCM_registerInterrupt(void (*intHandler)(void))
581 {
582 //
583 // Register the interrupt handler, returning an error if an error occurs.
584 //
585 Interrupt_registerInterrupt(INT_PCM, intHandler);
586
587 //
588 // Enable the system control interrupt.
589 //
590 Interrupt_enableInterrupt(INT_PCM);
591 }
592
PCM_unregisterInterrupt(void)593 void PCM_unregisterInterrupt(void)
594 {
595 //
596 // Disable the interrupt.
597 //
598 Interrupt_disableInterrupt(INT_PCM);
599
600 //
601 // Unregister the interrupt handler.
602 //
603 Interrupt_unregisterInterrupt(INT_PCM);
604 }
605