1 /******************************************************************************
2 * Filename: prcm.c
3 *
4 * Description: Driver for the PRCM.
5 *
6 * Copyright (c) 2015 - 2022, Texas Instruments Incorporated
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * 1) Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * 2) Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 ******************************************************************************/
36
37 #include "prcm.h"
38
39 //*****************************************************************************
40 //
41 // Handle support for DriverLib in ROM:
42 // This section will undo prototype renaming made in the header file
43 //
44 //*****************************************************************************
45 #if !defined(DOXYGEN)
46 #undef PRCMInfClockConfigureSet
47 #define PRCMInfClockConfigureSet NOROM_PRCMInfClockConfigureSet
48 #undef PRCMInfClockConfigureGet
49 #define PRCMInfClockConfigureGet NOROM_PRCMInfClockConfigureGet
50 #undef PRCMAudioClockConfigSet
51 #define PRCMAudioClockConfigSet NOROM_PRCMAudioClockConfigSet
52 #undef PRCMAudioClockConfigSetOverride
53 #define PRCMAudioClockConfigSetOverride NOROM_PRCMAudioClockConfigSetOverride
54 #undef PRCMAudioClockInternalSource
55 #define PRCMAudioClockInternalSource NOROM_PRCMAudioClockInternalSource
56 #undef PRCMAudioClockExternalSource
57 #define PRCMAudioClockExternalSource NOROM_PRCMAudioClockExternalSource
58 #undef PRCMPowerDomainOn
59 #define PRCMPowerDomainOn NOROM_PRCMPowerDomainOn
60 #undef PRCMPowerDomainOff
61 #define PRCMPowerDomainOff NOROM_PRCMPowerDomainOff
62 #undef PRCMPeripheralRunEnable
63 #define PRCMPeripheralRunEnable NOROM_PRCMPeripheralRunEnable
64 #undef PRCMPeripheralRunDisable
65 #define PRCMPeripheralRunDisable NOROM_PRCMPeripheralRunDisable
66 #undef PRCMPeripheralSleepEnable
67 #define PRCMPeripheralSleepEnable NOROM_PRCMPeripheralSleepEnable
68 #undef PRCMPeripheralSleepDisable
69 #define PRCMPeripheralSleepDisable NOROM_PRCMPeripheralSleepDisable
70 #undef PRCMPeripheralDeepSleepEnable
71 #define PRCMPeripheralDeepSleepEnable NOROM_PRCMPeripheralDeepSleepEnable
72 #undef PRCMPeripheralDeepSleepDisable
73 #define PRCMPeripheralDeepSleepDisable NOROM_PRCMPeripheralDeepSleepDisable
74 #undef PRCMPowerDomainsAllOff
75 #define PRCMPowerDomainsAllOff NOROM_PRCMPowerDomainsAllOff
76 #undef PRCMPowerDomainsAllOn
77 #define PRCMPowerDomainsAllOn NOROM_PRCMPowerDomainsAllOn
78 #undef PRCMDeepSleep
79 #define PRCMDeepSleep NOROM_PRCMDeepSleep
80 #endif
81
82
83 //*****************************************************************************
84 //
85 // Arrays that maps the "peripheral set" number (which is stored in
86 // bits[11:8] of the PRCM_PERIPH_* defines) to the PRCM register that
87 // contains the relevant bit for that peripheral.
88 //
89 //*****************************************************************************
90
91 // Run mode registers
92 static const uint32_t g_pui32RCGCRegs[] =
93 {
94 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_GPTCLKGR), // Index 0
95 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_SSICLKGR), // Index 1
96 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_UARTCLKGR), // Index 2
97 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2CCLKGR), // Index 3
98 (PRCM_BASE + PRCM_O_SECDMACLKGR), // Index 4
99 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_GPIOCLKGR), // Index 5
100 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SCLKGR) // Index 6
101 };
102
103 // Sleep mode registers
104 static const uint32_t g_pui32SCGCRegs[] =
105 {
106 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_GPTCLKGS), // Index 0
107 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_SSICLKGS), // Index 1
108 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_UARTCLKGS), // Index 2
109 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2CCLKGS), // Index 3
110 (PRCM_BASE + PRCM_O_SECDMACLKGS), // Index 4
111 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_GPIOCLKGS), // Index 5
112 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SCLKGS) // Index 6
113 };
114
115 // Deep sleep mode registers
116 static const uint32_t g_pui32DCGCRegs[] =
117 {
118 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_GPTCLKGDS), // Index 0
119 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_SSICLKGDS), // Index 1
120 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_UARTCLKGDS), // Index 2
121 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2CCLKGDS), // Index 3
122 (PRCM_BASE + PRCM_O_SECDMACLKGDS), // Index 4
123 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_GPIOCLKGDS), // Index 5
124 (PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SCLKGDS) // Index 6
125 };
126
127 //*****************************************************************************
128 //
129 // This macro extracts the array index out of the peripheral number
130 //
131 //*****************************************************************************
132 #define PRCM_PERIPH_INDEX(a) (((a) >> 8) & 0xf)
133
134 //*****************************************************************************
135 //
136 // This macro extracts the peripheral instance number and generates bit mask
137 //
138 //*****************************************************************************
139 #define PRCM_PERIPH_MASKBIT(a) (0x00000001 << ((a) & 0x1f))
140
141
142 //*****************************************************************************
143 //
144 // Configure the infrastructure clock.
145 //
146 //*****************************************************************************
147 void
PRCMInfClockConfigureSet(uint32_t ui32ClkDiv,uint32_t ui32PowerMode)148 PRCMInfClockConfigureSet(uint32_t ui32ClkDiv, uint32_t ui32PowerMode)
149 {
150 uint32_t ui32Divisor;
151
152 // Check the arguments.
153 ASSERT((ui32ClkDiv == PRCM_CLOCK_DIV_1) ||
154 (ui32ClkDiv == PRCM_CLOCK_DIV_2) ||
155 (ui32ClkDiv == PRCM_CLOCK_DIV_8) ||
156 (ui32ClkDiv == PRCM_CLOCK_DIV_32));
157 ASSERT((ui32PowerMode == PRCM_RUN_MODE) ||
158 (ui32PowerMode == PRCM_SLEEP_MODE) ||
159 (ui32PowerMode == PRCM_DEEP_SLEEP_MODE));
160
161 ui32Divisor = 0;
162
163 // Find the correct division factor.
164 if(ui32ClkDiv == PRCM_CLOCK_DIV_1)
165 {
166 ui32Divisor = 0x0;
167 }
168 else if(ui32ClkDiv == PRCM_CLOCK_DIV_2)
169 {
170 ui32Divisor = 0x1;
171 }
172 else if(ui32ClkDiv == PRCM_CLOCK_DIV_8)
173 {
174 ui32Divisor = 0x2;
175 }
176 else if(ui32ClkDiv == PRCM_CLOCK_DIV_32)
177 {
178 ui32Divisor = 0x3;
179 }
180
181 // Determine the correct power mode set the division factor accordingly.
182 if(ui32PowerMode == PRCM_RUN_MODE)
183 {
184 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_INFRCLKDIVR) = ui32Divisor;
185 }
186 else if(ui32PowerMode == PRCM_SLEEP_MODE)
187 {
188 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_INFRCLKDIVS) = ui32Divisor;
189 }
190 else if(ui32PowerMode == PRCM_DEEP_SLEEP_MODE)
191 {
192 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_INFRCLKDIVDS) = ui32Divisor;
193 }
194 }
195
196 //*****************************************************************************
197 //
198 // Use this function to get the infrastructure clock configuration
199 //
200 //*****************************************************************************
201 uint32_t
PRCMInfClockConfigureGet(uint32_t ui32PowerMode)202 PRCMInfClockConfigureGet(uint32_t ui32PowerMode)
203 {
204 uint32_t ui32ClkDiv;
205 uint32_t ui32Divisor;
206
207 // Check the arguments.
208 ASSERT((ui32PowerMode == PRCM_RUN_MODE) ||
209 (ui32PowerMode == PRCM_SLEEP_MODE) ||
210 (ui32PowerMode == PRCM_DEEP_SLEEP_MODE));
211
212 ui32ClkDiv = 0;
213 ui32Divisor = 0;
214
215 // Determine the correct power mode.
216 if(ui32PowerMode == PRCM_RUN_MODE)
217 {
218 ui32ClkDiv = HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_INFRCLKDIVR);
219 }
220 else if(ui32PowerMode == PRCM_SLEEP_MODE)
221 {
222 ui32ClkDiv = HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_INFRCLKDIVS);
223 }
224 else if(ui32PowerMode == PRCM_DEEP_SLEEP_MODE)
225 {
226 ui32ClkDiv = HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_INFRCLKDIVDS);
227 }
228
229 // Find the correct division factor.
230 if(ui32ClkDiv == 0x0)
231 {
232 ui32Divisor = PRCM_CLOCK_DIV_1;
233 }
234 else if(ui32ClkDiv == 0x1)
235 {
236 ui32Divisor = PRCM_CLOCK_DIV_2;
237 }
238 else if(ui32ClkDiv == 0x2)
239 {
240 ui32Divisor = PRCM_CLOCK_DIV_8;
241 }
242 else if(ui32ClkDiv == 0x3)
243 {
244 ui32Divisor = PRCM_CLOCK_DIV_32;
245 }
246
247 // Return the clock division factor.
248 return ui32Divisor;
249 }
250
251
252 //*****************************************************************************
253 //
254 // Configure the audio clock generation
255 //
256 //*****************************************************************************
257 void
PRCMAudioClockConfigSet(uint32_t ui32ClkConfig,uint32_t ui32SampleRate)258 PRCMAudioClockConfigSet(uint32_t ui32ClkConfig, uint32_t ui32SampleRate)
259 {
260 uint32_t ui32Reg;
261 uint32_t ui32MstDiv;
262 uint32_t ui32BitDiv;
263 uint32_t ui32WordDiv;
264
265 // Check the arguments.
266 ASSERT(!(ui32ClkConfig & (PRCM_I2SCLKCTL_WCLK_PHASE_M | PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M)));
267 ASSERT((ui32SampleRate == I2S_SAMPLE_RATE_16K) ||
268 (ui32SampleRate == I2S_SAMPLE_RATE_24K) ||
269 (ui32SampleRate == I2S_SAMPLE_RATE_32K) ||
270 (ui32SampleRate == I2S_SAMPLE_RATE_48K));
271
272 ui32MstDiv = 0;
273 ui32BitDiv = 0;
274 ui32WordDiv = 0;
275
276 // Make sure the audio clock generation is disabled before reconfiguring.
277 PRCMAudioClockDisable();
278
279 // Define the clock division factors for the audio interface.
280 switch(ui32SampleRate)
281 {
282 case I2S_SAMPLE_RATE_16K :
283 ui32MstDiv = 6;
284 ui32BitDiv = 60;
285 ui32WordDiv = 25;
286 break;
287 case I2S_SAMPLE_RATE_24K :
288 ui32MstDiv = 4;
289 ui32BitDiv = 40;
290 ui32WordDiv = 25;
291 break;
292 case I2S_SAMPLE_RATE_32K :
293 ui32MstDiv = 3;
294 ui32BitDiv = 30;
295 ui32WordDiv = 25;
296 break;
297 case I2S_SAMPLE_RATE_48K :
298 ui32MstDiv = 2;
299 ui32BitDiv = 20;
300 ui32WordDiv = 25;
301 break;
302 }
303
304 // Make sure to compensate the Frame clock division factor if using single
305 // phase format.
306 if((ui32ClkConfig & PRCM_I2SCLKCTL_WCLK_PHASE_M) == PRCM_WCLK_SINGLE_PHASE)
307 {
308 ui32WordDiv -= 1;
309 }
310
311 // Write the clock division factors.
312 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SMCLKDIV) = ui32MstDiv;
313 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SBCLKDIV) = ui32BitDiv;
314 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SWCLKDIV) = ui32WordDiv;
315
316 // Configure the Word clock format and polarity.
317 ui32Reg = HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SCLKCTL) & ~(PRCM_I2SCLKCTL_WCLK_PHASE_M |
318 PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M);
319 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SCLKCTL) = ui32Reg | ui32ClkConfig;
320 }
321
322 //*****************************************************************************
323 //
324 // Configure the audio clock generation with manual setting of clock divider.
325 //
326 //*****************************************************************************
327 void
PRCMAudioClockConfigSetOverride(uint32_t ui32ClkConfig,uint32_t ui32MstDiv,uint32_t ui32BitDiv,uint32_t ui32WordDiv)328 PRCMAudioClockConfigSetOverride(uint32_t ui32ClkConfig, uint32_t ui32MstDiv,
329 uint32_t ui32BitDiv, uint32_t ui32WordDiv)
330 {
331 uint32_t ui32Reg;
332
333 // Check the arguments.
334 ASSERT(!(ui32ClkConfig & (PRCM_I2SCLKCTL_WCLK_PHASE_M | PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M)));
335
336 // Make sure the audio clock generation is disabled before reconfiguring.
337 PRCMAudioClockDisable();
338
339 // Make sure to compensate the Frame clock division factor if using single
340 // phase format.
341 if((ui32ClkConfig & PRCM_I2SCLKCTL_WCLK_PHASE_M) == PRCM_WCLK_SINGLE_PHASE)
342 {
343 ui32WordDiv -= 1;
344 }
345
346 // Write the clock division factors.
347 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SMCLKDIV) = ui32MstDiv;
348 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SBCLKDIV) = ui32BitDiv;
349 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SWCLKDIV) = ui32WordDiv;
350
351 // Configure the Word clock format and polarity.
352 ui32Reg = HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SCLKCTL) & ~(PRCM_I2SCLKCTL_WCLK_PHASE_M |
353 PRCM_I2SCLKCTL_SMPL_ON_POSEDGE_M);
354 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SCLKCTL) = ui32Reg | ui32ClkConfig;
355 }
356
357 //*****************************************************************************
358 //
359 // Configure the audio clocks for I2S module
360 //
361 //*****************************************************************************
362 void
PRCMAudioClockConfigOverride(uint8_t ui8SamplingEdge,uint8_t ui8WCLKPhase,uint32_t ui32MstDiv,uint32_t ui32BitDiv,uint32_t ui32WordDiv)363 PRCMAudioClockConfigOverride(uint8_t ui8SamplingEdge,
364 uint8_t ui8WCLKPhase,
365 uint32_t ui32MstDiv,
366 uint32_t ui32BitDiv,
367 uint32_t ui32WordDiv)
368 {
369 // Check the arguments.
370 ASSERT(ui8SamplingEdge == PRCM_I2S_WCLK_NEG_EDGE ||
371 ui8SamplingEdge == PRCM_I2S_WCLK_POS_EDGE);
372 ASSERT(ui8WCLKPhase == PRCM_WCLK_SINGLE_PHASE ||
373 ui8WCLKPhase == PRCM_WCLK_DUAL_PHASE ||
374 ui8WCLKPhase == 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 + NONSECURE_OFFSET + PRCM_O_I2SMCLKDIV) = ui32MstDiv;
388 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SBCLKDIV) = ui32BitDiv;
389 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_I2SWCLKDIV) = ui32WordDiv;
390
391 // Configure the Word clock format and polarity and enable it.
392 HWREG(PRCM_BASE + NONSECURE_OFFSET + 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 + NONSECURE_OFFSET + 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 + NONSECURE_OFFSET + 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 + NONSECURE_OFFSET + PRCM_O_PDCTL0RFC ) = 1;
436 }
437 if(ui32Domains & PRCM_DOMAIN_SERIAL)
438 {
439 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_PDCTL0SERIAL) = 1;
440 }
441 if(ui32Domains & PRCM_DOMAIN_PERIPH)
442 {
443 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_PDCTL0PERIPH) = 1;
444 }
445 if(ui32Domains & PRCM_DOMAIN_VIMS)
446 {
447 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_PDCTL1VIMS ) = 1;
448 }
449 if(ui32Domains & PRCM_DOMAIN_CPU)
450 {
451 HWREG(PRCM_BASE + NONSECURE_OFFSET + 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 + NONSECURE_OFFSET + PRCM_O_PDCTL0RFC ) = 0;
474 }
475 if(ui32Domains & PRCM_DOMAIN_SERIAL)
476 {
477 HWREG(PRCM_BASE + NONSECURE_OFFSET + PRCM_O_PDCTL0SERIAL) = 0;
478 }
479 if(ui32Domains & PRCM_DOMAIN_PERIPH)
480 {
481 HWREG(PRCM_BASE + NONSECURE_OFFSET + 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 + NONSECURE_OFFSET + PRCM_O_PDCTL1VIMS ) = ( ui32Domains >> 16 ) & 3;
489 }
490 if(ui32Domains & PRCM_DOMAIN_CPU)
491 {
492 HWREG(PRCM_BASE + NONSECURE_OFFSET + 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(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(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(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(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(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(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 + NONSECURE_OFFSET + PRCM_O_PDSTAT0);
611 ui32StatusRegister1 = HWREG(PRCM_BASE + NONSECURE_OFFSET + 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 + NONSECURE_OFFSET + PRCM_O_PDSTAT0);
652 ui32StatusRegister1 = HWREG(PRCM_BASE + NONSECURE_OFFSET + 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