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