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