1 /******************************************************************************
2 *  Filename:       prcm.c
3 *  Revised:        2020-08-19 12:18:33 +0200 (Wed, 19 Aug 2020)
4 *  Revision:       58172
5 *
6 *  Description:    Driver for the PRCM.
7 *
8 *  Copyright (c) 2015 - 2020, Texas Instruments Incorporated
9 *  All rights reserved.
10 *
11 *  Redistribution and use in source and binary forms, with or without
12 *  modification, are permitted provided that the following conditions are met:
13 *
14 *  1) Redistributions of source code must retain the above copyright notice,
15 *     this list of conditions and the following disclaimer.
16 *
17 *  2) Redistributions in binary form must reproduce the above copyright notice,
18 *     this list of conditions and the following disclaimer in the documentation
19 *     and/or other materials provided with the distribution.
20 *
21 *  3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 *     be used to endorse or promote products derived from this software without
23 *     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, THE
27 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 *  POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38 
39 #include "prcm.h"
40 
41 //*****************************************************************************
42 //
43 // Handle support for DriverLib in ROM:
44 // This section will undo prototype renaming made in the header file
45 //
46 //*****************************************************************************
47 #if !defined(DOXYGEN)
48     #undef  PRCMInfClockConfigureSet
49     #define PRCMInfClockConfigureSet        NOROM_PRCMInfClockConfigureSet
50     #undef  PRCMInfClockConfigureGet
51     #define PRCMInfClockConfigureGet        NOROM_PRCMInfClockConfigureGet
52     #undef  PRCMAudioClockConfigSet
53     #define PRCMAudioClockConfigSet         NOROM_PRCMAudioClockConfigSet
54     #undef  PRCMAudioClockConfigSetOverride
55     #define PRCMAudioClockConfigSetOverride NOROM_PRCMAudioClockConfigSetOverride
56     #undef  PRCMAudioClockInternalSource
57     #define PRCMAudioClockInternalSource    NOROM_PRCMAudioClockInternalSource
58     #undef  PRCMAudioClockExternalSource
59     #define PRCMAudioClockExternalSource    NOROM_PRCMAudioClockExternalSource
60     #undef  PRCMPowerDomainOn
61     #define PRCMPowerDomainOn               NOROM_PRCMPowerDomainOn
62     #undef  PRCMPowerDomainOff
63     #define PRCMPowerDomainOff              NOROM_PRCMPowerDomainOff
64     #undef  PRCMPeripheralRunEnable
65     #define PRCMPeripheralRunEnable         NOROM_PRCMPeripheralRunEnable
66     #undef  PRCMPeripheralRunDisable
67     #define PRCMPeripheralRunDisable        NOROM_PRCMPeripheralRunDisable
68     #undef  PRCMPeripheralSleepEnable
69     #define PRCMPeripheralSleepEnable       NOROM_PRCMPeripheralSleepEnable
70     #undef  PRCMPeripheralSleepDisable
71     #define PRCMPeripheralSleepDisable      NOROM_PRCMPeripheralSleepDisable
72     #undef  PRCMPeripheralDeepSleepEnable
73     #define PRCMPeripheralDeepSleepEnable   NOROM_PRCMPeripheralDeepSleepEnable
74     #undef  PRCMPeripheralDeepSleepDisable
75     #define PRCMPeripheralDeepSleepDisable  NOROM_PRCMPeripheralDeepSleepDisable
76     #undef  PRCMPowerDomainsAllOff
77     #define PRCMPowerDomainsAllOff          NOROM_PRCMPowerDomainsAllOff
78     #undef  PRCMPowerDomainsAllOn
79     #define PRCMPowerDomainsAllOn           NOROM_PRCMPowerDomainsAllOn
80     #undef  PRCMDeepSleep
81     #define PRCMDeepSleep                   NOROM_PRCMDeepSleep
82 #endif
83 
84 
85 //*****************************************************************************
86 //
87 // Arrays that maps the "peripheral set" number (which is stored in
88 // bits[11:8] of the PRCM_PERIPH_* defines) to the PRCM register that
89 // contains the relevant bit for that peripheral.
90 //
91 //*****************************************************************************
92 
93 // Run mode registers
94 static const uint32_t g_pui32RCGCRegs[] =
95 {
96     PRCM_O_GPTCLKGR     , // Index 0
97     PRCM_O_SSICLKGR     , // Index 1
98     PRCM_O_UARTCLKGR    , // Index 2
99     PRCM_O_I2CCLKGR     , // Index 3
100     PRCM_O_SECDMACLKGR  , // Index 4
101     PRCM_O_GPIOCLKGR    , // Index 5
102     PRCM_O_I2SCLKGR       // Index 6
103 };
104 
105 // Sleep mode registers
106 static const uint32_t g_pui32SCGCRegs[] =
107 {
108     PRCM_O_GPTCLKGS     , // Index 0
109     PRCM_O_SSICLKGS     , // Index 1
110     PRCM_O_UARTCLKGS    , // Index 2
111     PRCM_O_I2CCLKGS     , // Index 3
112     PRCM_O_SECDMACLKGS  , // Index 4
113     PRCM_O_GPIOCLKGS    , // Index 5
114     PRCM_O_I2SCLKGS       // Index 6
115 };
116 
117 // Deep sleep mode registers
118 static const uint32_t g_pui32DCGCRegs[] =
119 {
120     PRCM_O_GPTCLKGDS    , // Index 0
121     PRCM_O_SSICLKGDS    , // Index 1
122     PRCM_O_UARTCLKGDS   , // Index 2
123     PRCM_O_I2CCLKGDS    , // Index 3
124     PRCM_O_SECDMACLKGDS , // Index 4
125     PRCM_O_GPIOCLKGDS   , // Index 5
126     PRCM_O_I2SCLKGDS      // Index 6
127 };
128 
129 //*****************************************************************************
130 //
131 // This macro extracts the array index out of the peripheral number
132 //
133 //*****************************************************************************
134 #define PRCM_PERIPH_INDEX(a)  (((a) >> 8) & 0xf)
135 
136 //*****************************************************************************
137 //
138 // This macro extracts the peripheral instance number and generates bit mask
139 //
140 //*****************************************************************************
141 #define PRCM_PERIPH_MASKBIT(a) (0x00000001 << ((a) & 0x1f))
142 
143 
144 //*****************************************************************************
145 //
146 // Configure the infrastructure clock.
147 //
148 //*****************************************************************************
149 void
PRCMInfClockConfigureSet(uint32_t ui32ClkDiv,uint32_t ui32PowerMode)150 PRCMInfClockConfigureSet(uint32_t ui32ClkDiv, uint32_t ui32PowerMode)
151 {
152     uint32_t ui32Divisor;
153 
154     // Check the arguments.
155     ASSERT((ui32ClkDiv == PRCM_CLOCK_DIV_1) ||
156            (ui32ClkDiv == PRCM_CLOCK_DIV_2) ||
157            (ui32ClkDiv == PRCM_CLOCK_DIV_8) ||
158            (ui32ClkDiv == PRCM_CLOCK_DIV_32));
159     ASSERT((ui32PowerMode == PRCM_RUN_MODE) ||
160            (ui32PowerMode == PRCM_SLEEP_MODE) ||
161            (ui32PowerMode == PRCM_DEEP_SLEEP_MODE));
162 
163     ui32Divisor = 0;
164 
165     // Find the correct division factor.
166     if(ui32ClkDiv == PRCM_CLOCK_DIV_1)
167     {
168         ui32Divisor = 0x0;
169     }
170     else if(ui32ClkDiv == PRCM_CLOCK_DIV_2)
171     {
172         ui32Divisor = 0x1;
173     }
174     else if(ui32ClkDiv == PRCM_CLOCK_DIV_8)
175     {
176         ui32Divisor = 0x2;
177     }
178     else if(ui32ClkDiv == PRCM_CLOCK_DIV_32)
179     {
180         ui32Divisor = 0x3;
181     }
182 
183     // Determine the correct power mode set the division factor accordingly.
184     if(ui32PowerMode == PRCM_RUN_MODE)
185     {
186         HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVR) = ui32Divisor;
187     }
188     else if(ui32PowerMode == PRCM_SLEEP_MODE)
189     {
190         HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVS) = ui32Divisor;
191     }
192     else if(ui32PowerMode == PRCM_DEEP_SLEEP_MODE)
193     {
194         HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVDS) = ui32Divisor;
195     }
196 }
197 
198 //*****************************************************************************
199 //
200 // Use this function to get the infrastructure clock configuration
201 //
202 //*****************************************************************************
203 uint32_t
PRCMInfClockConfigureGet(uint32_t ui32PowerMode)204 PRCMInfClockConfigureGet(uint32_t ui32PowerMode)
205 {
206     uint32_t ui32ClkDiv;
207     uint32_t ui32Divisor;
208 
209     // Check the arguments.
210     ASSERT((ui32PowerMode == PRCM_RUN_MODE) ||
211            (ui32PowerMode == PRCM_SLEEP_MODE) ||
212            (ui32PowerMode == PRCM_DEEP_SLEEP_MODE));
213 
214     ui32ClkDiv = 0;
215     ui32Divisor = 0;
216 
217     // Determine the correct power mode.
218     if(ui32PowerMode == PRCM_RUN_MODE)
219     {
220         ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVR);
221     }
222     else if(ui32PowerMode == PRCM_SLEEP_MODE)
223     {
224         ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVS);
225     }
226     else if(ui32PowerMode == PRCM_DEEP_SLEEP_MODE)
227     {
228         ui32ClkDiv = HWREG(PRCM_BASE + PRCM_O_INFRCLKDIVDS);
229     }
230 
231     // Find the correct division factor.
232     if(ui32ClkDiv == 0x0)
233     {
234         ui32Divisor = PRCM_CLOCK_DIV_1;
235     }
236     else if(ui32ClkDiv == 0x1)
237     {
238         ui32Divisor = PRCM_CLOCK_DIV_2;
239     }
240     else if(ui32ClkDiv == 0x2)
241     {
242         ui32Divisor = PRCM_CLOCK_DIV_8;
243     }
244     else if(ui32ClkDiv == 0x3)
245     {
246         ui32Divisor = PRCM_CLOCK_DIV_32;
247     }
248 
249     // Return the clock division factor.
250     return ui32Divisor;
251 }
252 
253 
254 //*****************************************************************************
255 //
256 // Configure the audio clock generation
257 //
258 //*****************************************************************************
259 void
PRCMAudioClockConfigSet(uint32_t ui32ClkConfig,uint32_t ui32SampleRate)260 PRCMAudioClockConfigSet(uint32_t ui32ClkConfig, uint32_t ui32SampleRate)
261 {
262     uint32_t ui32Reg;
263     uint32_t ui32MstDiv;
264     uint32_t ui32BitDiv;
265     uint32_t ui32WordDiv;
266 
267     // Check the arguments.
268     ASSERT(!(ui32ClkConfig & (PRCM_I2SCLKCTL_WCLK_PHASE_M | PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M)));
269     ASSERT((ui32SampleRate == I2S_SAMPLE_RATE_16K) ||
270            (ui32SampleRate == I2S_SAMPLE_RATE_24K) ||
271            (ui32SampleRate == I2S_SAMPLE_RATE_32K) ||
272            (ui32SampleRate == I2S_SAMPLE_RATE_48K));
273 
274     ui32MstDiv = 0;
275     ui32BitDiv = 0;
276     ui32WordDiv = 0;
277 
278     // Make sure the audio clock generation is disabled before reconfiguring.
279     PRCMAudioClockDisable();
280 
281     // Define the clock division factors for the audio interface.
282     switch(ui32SampleRate)
283     {
284     case I2S_SAMPLE_RATE_16K :
285         ui32MstDiv = 6;
286         ui32BitDiv = 60;
287         ui32WordDiv = 25;
288         break;
289     case I2S_SAMPLE_RATE_24K :
290         ui32MstDiv = 4;
291         ui32BitDiv = 40;
292         ui32WordDiv = 25;
293         break;
294     case I2S_SAMPLE_RATE_32K :
295         ui32MstDiv = 3;
296         ui32BitDiv = 30;
297         ui32WordDiv = 25;
298         break;
299     case I2S_SAMPLE_RATE_48K :
300         ui32MstDiv = 2;
301         ui32BitDiv = 20;
302         ui32WordDiv = 25;
303         break;
304     }
305 
306     // Make sure to compensate the Frame clock division factor if using single
307     // phase format.
308     if((ui32ClkConfig & PRCM_I2SCLKCTL_WCLK_PHASE_M) == PRCM_WCLK_SINGLE_PHASE)
309     {
310         ui32WordDiv -= 1;
311     }
312 
313     // Write the clock division factors.
314     HWREG(PRCM_BASE + PRCM_O_I2SMCLKDIV) = ui32MstDiv;
315     HWREG(PRCM_BASE + PRCM_O_I2SBCLKDIV) = ui32BitDiv;
316     HWREG(PRCM_BASE + PRCM_O_I2SWCLKDIV) = ui32WordDiv;
317 
318     // Configure the Word clock format and polarity.
319     ui32Reg = HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) & ~(PRCM_I2SCLKCTL_WCLK_PHASE_M |
320               PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M);
321     HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) = ui32Reg | ui32ClkConfig;
322 }
323 
324 //*****************************************************************************
325 //
326 // Configure the audio clock generation with manual setting of clock divider.
327 //
328 //*****************************************************************************
329 void
PRCMAudioClockConfigSetOverride(uint32_t ui32ClkConfig,uint32_t ui32MstDiv,uint32_t ui32BitDiv,uint32_t ui32WordDiv)330 PRCMAudioClockConfigSetOverride(uint32_t ui32ClkConfig, uint32_t ui32MstDiv,
331                         uint32_t ui32BitDiv, uint32_t ui32WordDiv)
332 {
333     uint32_t ui32Reg;
334 
335     // Check the arguments.
336     ASSERT(!(ui32ClkConfig & (PRCM_I2SCLKCTL_WCLK_PHASE_M | PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M)));
337 
338     // Make sure the audio clock generation is disabled before reconfiguring.
339     PRCMAudioClockDisable();
340 
341     // Make sure to compensate the Frame clock division factor if using single
342     // phase format.
343     if((ui32ClkConfig & PRCM_I2SCLKCTL_WCLK_PHASE_M) == PRCM_WCLK_SINGLE_PHASE)
344     {
345         ui32WordDiv -= 1;
346     }
347 
348     // Write the clock division factors.
349     HWREG(PRCM_BASE + PRCM_O_I2SMCLKDIV) = ui32MstDiv;
350     HWREG(PRCM_BASE + PRCM_O_I2SBCLKDIV) = ui32BitDiv;
351     HWREG(PRCM_BASE + PRCM_O_I2SWCLKDIV) = ui32WordDiv;
352 
353     // Configure the Word clock format and polarity.
354     ui32Reg = HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) & ~(PRCM_I2SCLKCTL_WCLK_PHASE_M |
355               PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M);
356     HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) = ui32Reg | ui32ClkConfig;
357 }
358 
359 //*****************************************************************************
360 //
361 // Configure the audio clocks for I2S module
362 //
363 //*****************************************************************************
364 void
PRCMAudioClockConfigOverride(uint8_t ui8SamplingEdge,uint8_t ui8WCLKPhase,uint32_t ui32MstDiv,uint32_t ui32BitDiv,uint32_t ui32WordDiv)365 PRCMAudioClockConfigOverride(uint8_t  ui8SamplingEdge,
366                              uint8_t  ui8WCLKPhase,
367                              uint32_t ui32MstDiv,
368                              uint32_t ui32BitDiv,
369                              uint32_t ui32WordDiv)
370 {
371     // Check the arguments.
372     ASSERT(    ui8BitsPerSample == PRCM_WCLK_SINGLE_PHASE
373             || ui8BitsPerSample == PRCM_WCLK_DUAL_PHASE
374             || ui8BitsPerSample == PRCM_WCLK_USER_DEF);
375 
376     // Make sure the audio clock generation is disabled before reconfiguring.
377     PRCMAudioClockDisable();
378 
379     // Make sure to compensate the Frame clock division factor if using single
380     // phase format.
381     if((ui8WCLKPhase) == PRCM_WCLK_SINGLE_PHASE)
382     {
383         ui32WordDiv -= 1;
384     }
385 
386     // Write the clock division factors.
387     HWREG(PRCM_BASE + PRCM_O_I2SMCLKDIV) = ui32MstDiv;
388     HWREG(PRCM_BASE + PRCM_O_I2SBCLKDIV) = ui32BitDiv;
389     HWREG(PRCM_BASE + PRCM_O_I2SWCLKDIV) = ui32WordDiv;
390 
391     // Configure the Word clock format and polarity and enable it.
392     HWREG(PRCM_BASE + PRCM_O_I2SCLKCTL) =  (ui8SamplingEdge  << PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_S) |
393                                            (ui8WCLKPhase     << PRCM_I2SCLKCTL_WCLK_PHASE_S     ) |
394                                            (1                << PRCM_I2SCLKCTL_EN_S             );
395 }
396 
397 //*****************************************************************************
398 //
399 // Configure the clocks as "internally generated".
400 //
401 //*****************************************************************************
PRCMAudioClockInternalSource(void)402 void PRCMAudioClockInternalSource(void)
403 {
404     HWREG(PRCM_BASE + PRCM_O_I2SBCLKSEL) = PRCM_I2SBCLKSEL_SRC;
405 }
406 
407 //*****************************************************************************
408 //
409 // Configure the clocks as "externally generated".
410 //
411 //*****************************************************************************
PRCMAudioClockExternalSource(void)412 void PRCMAudioClockExternalSource(void)
413 {
414     HWREG(PRCM_BASE + PRCM_O_I2SBCLKSEL) = 0;
415 }
416 
417 //*****************************************************************************
418 //
419 // Turn power on in power domains in the MCU domain
420 //
421 //*****************************************************************************
422 void
PRCMPowerDomainOn(uint32_t ui32Domains)423 PRCMPowerDomainOn(uint32_t ui32Domains)
424 {
425     // Check the arguments.
426     ASSERT((ui32Domains & PRCM_DOMAIN_RFCORE) ||
427            (ui32Domains & PRCM_DOMAIN_SERIAL) ||
428            (ui32Domains & PRCM_DOMAIN_PERIPH) ||
429            (ui32Domains & PRCM_DOMAIN_CPU) ||
430            (ui32Domains & PRCM_DOMAIN_VIMS));
431 
432     // Assert the request to power on the right domains.
433     if(ui32Domains & PRCM_DOMAIN_RFCORE)
434     {
435         HWREG(PRCM_BASE + PRCM_O_PDCTL0RFC   ) = 1;
436     }
437     if(ui32Domains & PRCM_DOMAIN_SERIAL)
438     {
439         HWREG(PRCM_BASE + PRCM_O_PDCTL0SERIAL) = 1;
440     }
441     if(ui32Domains & PRCM_DOMAIN_PERIPH)
442     {
443         HWREG(PRCM_BASE + PRCM_O_PDCTL0PERIPH) = 1;
444     }
445     if(ui32Domains & PRCM_DOMAIN_VIMS)
446     {
447         HWREG(PRCM_BASE + PRCM_O_PDCTL1VIMS  ) = 1;
448     }
449     if(ui32Domains & PRCM_DOMAIN_CPU)
450     {
451         HWREG(PRCM_BASE + PRCM_O_PDCTL1CPU   ) = 1;
452     }
453 }
454 
455 //*****************************************************************************
456 //
457 // Turn off a specific power domain
458 //
459 //*****************************************************************************
460 void
PRCMPowerDomainOff(uint32_t ui32Domains)461 PRCMPowerDomainOff(uint32_t ui32Domains)
462 {
463     // Check the arguments.
464     ASSERT((ui32Domains & PRCM_DOMAIN_RFCORE) ||
465            (ui32Domains & PRCM_DOMAIN_SERIAL) ||
466            (ui32Domains & PRCM_DOMAIN_PERIPH) ||
467            (ui32Domains & PRCM_DOMAIN_CPU) ||
468            (ui32Domains & PRCM_DOMAIN_VIMS));
469 
470     // Assert the request to power off the right domains.
471     if(ui32Domains & PRCM_DOMAIN_RFCORE)
472     {
473         HWREG(PRCM_BASE + PRCM_O_PDCTL0RFC   ) = 0;
474     }
475     if(ui32Domains & PRCM_DOMAIN_SERIAL)
476     {
477         HWREG(PRCM_BASE + PRCM_O_PDCTL0SERIAL) = 0;
478     }
479     if(ui32Domains & PRCM_DOMAIN_PERIPH)
480     {
481         HWREG(PRCM_BASE + PRCM_O_PDCTL0PERIPH) = 0;
482     }
483     if(ui32Domains & PRCM_DOMAIN_VIMS)
484     {
485         // Write bits ui32Domains[17:16] to the VIMS_MODE alias register.
486         // PRCM_DOMAIN_VIMS sets VIMS_MODE=0b00, PRCM_DOMAIN_VIMS_OFF_NO_WAKEUP sets VIMS_MODE=0b10.
487         ASSERT(!(ui32Domains & 0x00010000));
488         HWREG(PRCM_BASE + PRCM_O_PDCTL1VIMS  ) = ( ui32Domains >> 16 ) & 3;
489     }
490     if(ui32Domains & PRCM_DOMAIN_CPU)
491     {
492         HWREG(PRCM_BASE + PRCM_O_PDCTL1CPU   ) = 0;
493     }
494 }
495 
496 //*****************************************************************************
497 //
498 // Enables a peripheral in Run mode
499 //
500 //*****************************************************************************
501 void
PRCMPeripheralRunEnable(uint32_t ui32Peripheral)502 PRCMPeripheralRunEnable(uint32_t ui32Peripheral)
503 {
504     // Check the arguments.
505     ASSERT(PRCMPeripheralValid(ui32Peripheral));
506 
507     // Enable module in Run Mode.
508     HWREG(PRCM_BASE + g_pui32RCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) |=
509         PRCM_PERIPH_MASKBIT(ui32Peripheral);
510 }
511 
512 //*****************************************************************************
513 //
514 // Disables a peripheral in Run mode
515 //
516 //*****************************************************************************
517 void
PRCMPeripheralRunDisable(uint32_t ui32Peripheral)518 PRCMPeripheralRunDisable(uint32_t ui32Peripheral)
519 {
520     // Check the arguments.
521     ASSERT(PRCMPeripheralValid(ui32Peripheral));
522 
523     // Disable module in Run Mode.
524     HWREG(PRCM_BASE + g_pui32RCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) &=
525         ~PRCM_PERIPH_MASKBIT(ui32Peripheral);
526 }
527 
528 //*****************************************************************************
529 //
530 // Enables a peripheral in sleep mode
531 //
532 //*****************************************************************************
533 void
PRCMPeripheralSleepEnable(uint32_t ui32Peripheral)534 PRCMPeripheralSleepEnable(uint32_t ui32Peripheral)
535 {
536     // Check the arguments.
537     ASSERT(PRCMPeripheralValid(ui32Peripheral));
538 
539     // Enable this peripheral in sleep mode.
540     HWREG(PRCM_BASE + g_pui32SCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) |=
541         PRCM_PERIPH_MASKBIT(ui32Peripheral);
542 }
543 
544 //*****************************************************************************
545 //
546 // Disables a peripheral in sleep mode
547 //
548 //*****************************************************************************
549 void
PRCMPeripheralSleepDisable(uint32_t ui32Peripheral)550 PRCMPeripheralSleepDisable(uint32_t ui32Peripheral)
551 {
552     // Check the arguments.
553     ASSERT(PRCMPeripheralValid(ui32Peripheral));
554 
555     // Disable this peripheral in sleep mode
556     HWREG(PRCM_BASE + g_pui32SCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) &=
557         ~PRCM_PERIPH_MASKBIT(ui32Peripheral);
558 }
559 
560 //*****************************************************************************
561 //
562 // Enables a peripheral in deep-sleep mode
563 //
564 //*****************************************************************************
565 void
PRCMPeripheralDeepSleepEnable(uint32_t ui32Peripheral)566 PRCMPeripheralDeepSleepEnable(uint32_t ui32Peripheral)
567 {
568     // Check the arguments.
569     ASSERT(PRCMPeripheralValid(ui32Peripheral));
570 
571     // Enable this peripheral in deep-sleep mode.
572     HWREG(PRCM_BASE + g_pui32DCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) |=
573         PRCM_PERIPH_MASKBIT(ui32Peripheral);
574 }
575 
576 //*****************************************************************************
577 //
578 // Disables a peripheral in deep-sleep mode
579 //
580 //*****************************************************************************
581 void
PRCMPeripheralDeepSleepDisable(uint32_t ui32Peripheral)582 PRCMPeripheralDeepSleepDisable(uint32_t ui32Peripheral)
583 {
584     // Check the arguments.
585     ASSERT(PRCMPeripheralValid(ui32Peripheral));
586 
587     // Disable this peripheral in Deep Sleep mode.
588     HWREG(PRCM_BASE + g_pui32DCGCRegs[PRCM_PERIPH_INDEX(ui32Peripheral)]) &=
589         ~PRCM_PERIPH_MASKBIT(ui32Peripheral);
590 }
591 
592 //*****************************************************************************
593 //
594 // Return PRCM_DOMAIN_POWER_OFF if all power domains are off
595 //
596 //*****************************************************************************
597 uint32_t
PRCMPowerDomainsAllOff(uint32_t ui32Domains)598 PRCMPowerDomainsAllOff(uint32_t ui32Domains)
599 {
600     bool bStatus;
601     uint32_t ui32StatusRegister0;
602     uint32_t ui32StatusRegister1;
603 
604     // Check the arguments.
605     ASSERT((ui32Domains & (PRCM_DOMAIN_RFCORE |
606                            PRCM_DOMAIN_SERIAL |
607                            PRCM_DOMAIN_PERIPH)));
608 
609     bStatus = false;
610     ui32StatusRegister0 = HWREG(PRCM_BASE + PRCM_O_PDSTAT0);
611     ui32StatusRegister1 = HWREG(PRCM_BASE + PRCM_O_PDSTAT1);
612 
613     // Return the correct power status.
614     if(ui32Domains & PRCM_DOMAIN_RFCORE)
615     {
616        bStatus = bStatus ||
617                  ((ui32StatusRegister0 & PRCM_PDSTAT0_RFC_ON) ||
618                   (ui32StatusRegister1 & PRCM_PDSTAT1_RFC_ON));
619     }
620     if(ui32Domains & PRCM_DOMAIN_SERIAL)
621     {
622         bStatus = bStatus || (ui32StatusRegister0 & PRCM_PDSTAT0_SERIAL_ON);
623     }
624     if(ui32Domains & PRCM_DOMAIN_PERIPH)
625     {
626         bStatus = bStatus || (ui32StatusRegister0 & PRCM_PDSTAT0_PERIPH_ON);
627     }
628 
629     // Return the status.
630     return (bStatus ? PRCM_DOMAIN_POWER_ON : PRCM_DOMAIN_POWER_OFF);
631 }
632 
633 //*****************************************************************************
634 //
635 // Return PRCM_DOMAIN_POWER_ON if all power domains are on
636 //
637 //*****************************************************************************
638 uint32_t
PRCMPowerDomainsAllOn(uint32_t ui32Domains)639 PRCMPowerDomainsAllOn(uint32_t ui32Domains)
640 {
641     bool bStatus;
642     uint32_t ui32StatusRegister0;
643     uint32_t ui32StatusRegister1;
644 
645     // Check the arguments.
646     ASSERT((ui32Domains & (PRCM_DOMAIN_RFCORE |
647                            PRCM_DOMAIN_SERIAL |
648                            PRCM_DOMAIN_PERIPH)));
649 
650     bStatus = true;
651     ui32StatusRegister0 = HWREG(PRCM_BASE + PRCM_O_PDSTAT0);
652     ui32StatusRegister1 = HWREG(PRCM_BASE + PRCM_O_PDSTAT1);
653 
654     // Return the correct power status.
655     if(ui32Domains & PRCM_DOMAIN_RFCORE)
656     {
657        bStatus = bStatus &&
658                  ((ui32StatusRegister0 & PRCM_PDSTAT0_RFC_ON) ||
659                   (ui32StatusRegister1 & PRCM_PDSTAT1_RFC_ON));
660     }
661     if(ui32Domains & PRCM_DOMAIN_SERIAL)
662     {
663         bStatus = bStatus && (ui32StatusRegister0 & PRCM_PDSTAT0_SERIAL_ON);
664     }
665     if(ui32Domains & PRCM_DOMAIN_PERIPH)
666     {
667         bStatus = bStatus && (ui32StatusRegister0 & PRCM_PDSTAT0_PERIPH_ON);
668     }
669 
670     // Return the status.
671     return (bStatus ? PRCM_DOMAIN_POWER_ON : PRCM_DOMAIN_POWER_OFF);
672 }
673 
674 //*****************************************************************************
675 //
676 // Put the processor into deep-sleep mode
677 //
678 //*****************************************************************************
679 void
PRCMDeepSleep(void)680 PRCMDeepSleep(void)
681 {
682     // Enable deep-sleep.
683     HWREG(NVIC_SYS_CTRL) |= NVIC_SYS_CTRL_SLEEPDEEP;
684 
685     // Wait for an interrupt.
686     CPUwfi();
687 
688     // Disable deep-sleep so that a future sleep will work correctly.
689     HWREG(NVIC_SYS_CTRL) &= ~(NVIC_SYS_CTRL_SLEEPDEEP);
690 }
691