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