1 /******************************************************************************
2 * Filename: sys_ctrl.c
3 * Revised: 2015-09-25 11:16:31 +0200 (Fri, 25 Sep 2015)
4 * Revision: 44664
5 *
6 * Description: Driver for the System Control.
7 *
8 * Copyright (c) 2015, 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 // Hardware headers
40 #include <inc/hw_types.h>
41 #include <inc/hw_ccfg.h>
42 // Driverlib headers
43 #include <driverlib/aon_batmon.h>
44 #include <driverlib/sys_ctrl.h>
45
46 // Prototype from setup.c
47 int32_t SignExtendVddrTrimValue( uint32_t ui32VddrTrimVal );
48
49 //*****************************************************************************
50 //
51 // Handle support for DriverLib in ROM:
52 // This section will undo prototype renaming made in the header file
53 //
54 //*****************************************************************************
55 #if !defined(DOXYGEN)
56 #undef SysCtrlPowerEverything
57 #define SysCtrlPowerEverything NOROM_SysCtrlPowerEverything
58 #undef SysCtrlStandby
59 #define SysCtrlStandby NOROM_SysCtrlStandby
60 #undef SysCtrlPowerdown
61 #define SysCtrlPowerdown NOROM_SysCtrlPowerdown
62 #undef SysCtrlShutdown
63 #define SysCtrlShutdown NOROM_SysCtrlShutdown
64 #undef SysCtrlResetSourceGet
65 #define SysCtrlResetSourceGet NOROM_SysCtrlResetSourceGet
66 #endif
67
68 //*****************************************************************************
69 //
70 // Recharge calculator defines and globals
71 //
72 //*****************************************************************************
73
74 #define PD_STATE_CACHE_RET 1
75 #define PD_STATE_RFMEM_RET 2
76 #define PD_STATE_XOSC_LPM 4
77 #define PD_STATE_EXT_REG_MODE 8
78
79 typedef struct {
80 uint32_t pdTime ;
81 uint16_t pdRechargePeriod ;
82 uint8_t pdState ;
83 int8_t pdTemp ;
84 } PowerQualGlobals_t;
85
86 static PowerQualGlobals_t powerQualGlobals;
87
88
89 //*****************************************************************************
90 //
91 // Arrays that maps the "peripheral set" number (which is stored in the
92 // third nibble of the PRCM_PERIPH_* defines) to the PRCM register that
93 // contains the relevant bit for that peripheral.
94 //
95 //*****************************************************************************
96
97 // Run mode registers
98 static const uint32_t g_pui32ModuleCG[] =
99 {
100 PRCM_PERIPH_TIMER0,
101 PRCM_PERIPH_TIMER1,
102 PRCM_PERIPH_TIMER2,
103 PRCM_PERIPH_TIMER3,
104 PRCM_PERIPH_SSI0,
105 PRCM_PERIPH_SSI1,
106 PRCM_PERIPH_UART0,
107 PRCM_PERIPH_I2C0,
108 PRCM_PERIPH_UDMA,
109 PRCM_PERIPH_TRNG,
110 PRCM_PERIPH_CRYPTO,
111 PRCM_PERIPH_GPIO,
112 PRCM_PERIPH_I2S
113 };
114
115 //*****************************************************************************
116 //
117 // Power up everything
118 //
119 //*****************************************************************************
120 void
SysCtrlPowerEverything(void)121 SysCtrlPowerEverything(void)
122 {
123 uint32_t ui32Idx;
124 uint32_t ui32AuxClocks;
125
126 //
127 // Force power on AUX
128 //
129 AONWUCAuxWakeupEvent(AONWUC_AUX_WAKEUP);
130 while(!(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON))
131 { }
132
133 //
134 // Enable all the AUX domain clocks and wait for them to be ready
135 //
136 ui32AuxClocks = AUX_WUC_ADI_CLOCK | AUX_WUC_OSCCTRL_CLOCK |
137 AUX_WUC_TDCIF_CLOCK | AUX_WUC_ANAIF_CLOCK |
138 AUX_WUC_TIMER_CLOCK | AUX_WUC_AIODIO0_CLOCK |
139 AUX_WUC_AIODIO1_CLOCK | AUX_WUC_SMPH_CLOCK |
140 AUX_WUC_TDC_CLOCK | AUX_WUC_ADC_CLOCK |
141 AUX_WUC_REF_CLOCK;
142 AUXWUCClockEnable(ui32AuxClocks);
143 while(AUXWUCClockStatus(ui32AuxClocks) != AUX_WUC_CLOCK_READY)
144 { }
145
146 //
147 // Request to switch to the crystal to enable radio operation.
148 // It takes a while for the XTAL to be ready so it is possible to
149 // perform other tasks while waiting.
150 OSCClockSourceSet(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_XOSC_HF);
151 OSCClockSourceSet(OSC_SRC_CLK_LF, OSC_XOSC_LF);
152
153 //
154 // Switch the HF source to XTAL - must be performed safely out of ROM to
155 // avoid flash issues when switching the clock.
156 //
157 // NB. If already running XTAL on HF clock source the ROM will wait forever
158 // on a flag that will never be set - need to check.
159 //
160 if(OSCClockSourceGet(OSC_SRC_CLK_HF) != OSC_XOSC_HF) {
161 OSCHfSourceSwitch();
162 }
163
164 //
165 // Turn on all the MCU power domains
166 // If the CPU is running and executing code the SYSBUS, VIMS and CPU are
167 // automatically on as well.
168 //
169 PRCMPowerDomainOn(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL |
170 PRCM_DOMAIN_PERIPH);
171 //
172 // Wait for power to be on
173 //
174 while(PRCMPowerDomainStatus(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL |
175 PRCM_DOMAIN_PERIPH) != PRCM_DOMAIN_POWER_ON);
176
177 PRCMLoadSet();
178 while(!PRCMLoadGet());
179
180 //
181 // Ensure the domain clocks are running and wait for the clock settings to
182 // take effect
183 //
184 PRCMDomainEnable(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_VIMS);
185 PRCMLoadSet();
186 while(!PRCMLoadGet())
187 { }
188
189 //
190 // Enable all the RF Core clocks
191 //
192 // Do not read back to check, for two reasons:
193 // 1. CPE will update the PWMCLKENABLE register right after boot
194 // 2. The PWMCLKENABLE register always reads back what is written
195 HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = 0x7FF;
196
197 //
198 // Enable all peripheral clocks in System CPU run/sleep/deep-sleep mode.
199 //
200 for(ui32Idx = 0; ui32Idx < sizeof(g_pui32ModuleCG) / sizeof(uint32_t);
201 ui32Idx++)
202 {
203 PRCMPeripheralRunEnable(g_pui32ModuleCG[ui32Idx]);
204 PRCMPeripheralSleepEnable(g_pui32ModuleCG[ui32Idx]);
205 PRCMPeripheralDeepSleepEnable(g_pui32ModuleCG[ui32Idx]);
206 }
207 PRCMLoadSet();
208 while(!PRCMLoadGet())
209 { }
210 }
211
212 //*****************************************************************************
213 //
214 //! Force the system in to standby mode
215 //
216 //*****************************************************************************
SysCtrlStandby(void)217 void SysCtrlStandby(void)
218 {
219 //
220 // Enable the oscillator configuration interface
221 //
222 OSCInterfaceEnable();
223
224 //
225 // Ensure the low frequency clock source is sourced from a low frequency
226 // oscillator. The XTAL will provide the most accurate real time clock.
227 //
228 OSCClockSourceSet(OSC_SRC_CLK_LF,OSC_XOSC_LF);
229
230 //
231 // Enable the oscillator configuration interface
232 //
233 OSCInterfaceDisable();
234
235 //
236 // Execute the transition to standby
237 //
238 PowerCtrlStateSet(PWRCTRL_STANDBY);
239 }
240
241 //*****************************************************************************
242 //
243 //! Force the system in to power down.
244 //
245 //*****************************************************************************
246 void
SysCtrlPowerdown(void)247 SysCtrlPowerdown(void)
248 {
249 //
250 // Make sure the oscillator interface is enabled
251 //
252 OSCInterfaceEnable();
253
254 //
255 // Source the LF clock from the low frequency XTAL_OSC.
256 // HF and MF are sourced from the high frequency RC_OSC.
257 //
258 OSCClockSourceSet(OSC_SRC_CLK_LF, OSC_XOSC_LF);
259 OSCClockSourceSet(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_RCOSC_HF);
260
261 //
262 // Check if already sourcing the HF clock from RC_OSC.
263 // If a switch of the clock source is not required, then the call to ROM
264 // will loop forever.
265 //
266 if(OSCClockSourceGet(OSC_SRC_CLK_HF) != OSC_RCOSC_HF)
267 {
268 OSCHfSourceSwitch();
269 }
270
271 //
272 // Disable the oscillator interface
273 //
274 OSCInterfaceDisable();
275
276 //
277 // Execute the transition to power down.
278 //
279 PowerCtrlStateSet(PWRCTRL_POWER_DOWN);
280 }
281
282 //*****************************************************************************
283 //
284 //! Force the system in to shutdown.
285 //
286 //*****************************************************************************
287 void
SysCtrlShutdown(void)288 SysCtrlShutdown(void)
289 {
290 //
291 // Make sure the oscillator interface is enabled
292 //
293 OSCInterfaceEnable();
294
295 //
296 // Source the LF clock from the low frequency RC_OSC.
297 // HF and MF are sourced from the high frequency RC_OSC.
298 //
299 OSCClockSourceSet(OSC_SRC_CLK_LF, OSC_RCOSC_LF);
300 OSCClockSourceSet(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_RCOSC_HF);
301
302 //
303 // Check if already sourcing the HF clock from RC_OSC.
304 // If a switch of the clock source is not required, then the call to ROM
305 // will loop forever.
306 //
307 if(OSCClockSourceGet(OSC_SRC_CLK_HF) != OSC_RCOSC_HF)
308 {
309 OSCHfSourceSwitch();
310 }
311
312 //
313 // Disable the oscillator interface
314 //
315 OSCInterfaceDisable();
316
317 //
318 // Execute transition to shutdown.
319 //
320 PowerCtrlStateSet(PWRCTRL_SHUTDOWN);
321 }
322
323
324 //*****************************************************************************
325 // Need to know the CCFG:MODE_CONF.VDDR_TRIM_SLEEP_DELTA fild width in order
326 // to sign extend correctly but this is however not defined in the hardware
327 // description fields and are therefore defined separately here.
328 //*****************************************************************************
329 #define CCFG_MODE_CONF_VDDR_TRIM_SLEEP_DELTA_WIDTH 4
330
331 //*****************************************************************************
332 //
333 // SysCtrlSetRechargeBeforePowerDown( xoscPowerMode )
334 //
335 //*****************************************************************************
336 void
SysCtrlSetRechargeBeforePowerDown(uint32_t xoscPowerMode)337 SysCtrlSetRechargeBeforePowerDown( uint32_t xoscPowerMode )
338 {
339 int32_t curTemp ;
340 int32_t shiftedTemp ;
341 int32_t deltaVddrSleepTrim ;
342 int32_t vddrTrimSleep ;
343 int32_t vddrTrimActve ;
344 int32_t diffVddrActiveSleep ;
345 uint32_t ccfg_ModeConfReg ;
346 uint32_t curState ;
347 uint32_t prcmRamRetention ;
348 uint32_t di ;
349 uint32_t dii ;
350 uint32_t ti ;
351 uint32_t cd ;
352 uint32_t cl ;
353 uint32_t load ;
354 uint32_t k ;
355 uint32_t vddrCap ;
356 uint32_t newRechargePeriod ;
357 uint32_t perE ;
358 uint32_t perM ;
359 const uint32_t * pLookupTable ;
360
361 //
362 // If external regulator mode we shall:
363 // - Disable adaptive recharge (bit[31]=0) in AON_WUC_O_RECHARGECFG
364 // - Set recharge period to approximately 500 mS (perM=31, perE=5 => 0xFD)
365 // - Make sure you get a recalculation if leaving external regulator mode by setting powerQualGlobals.pdState accordingly
366 //
367 if ( HWREG( AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL ) & AON_SYSCTL_PWRCTL_EXT_REG_MODE ) {
368 powerQualGlobals.pdState = PD_STATE_EXT_REG_MODE;
369 HWREG( AON_WUC_BASE + AON_WUC_O_RECHARGECFG ) = 0x00A4FDFD;
370 return;
371 }
372
373 //--- Spec. point 1 ---
374 curTemp = AONBatMonTemperatureGetDegC();
375 curState = 0;
376
377 // read the MODE_CONF register in CCFG
378 ccfg_ModeConfReg = HWREG( CCFG_BASE + CCFG_O_MODE_CONF );
379 // Get VDDR_TRIM_SLEEP_DELTA + 1 (sign extended)
380 deltaVddrSleepTrim = ((((int32_t) ccfg_ModeConfReg )
381 << ( 32 - CCFG_MODE_CONF_VDDR_TRIM_SLEEP_DELTA_WIDTH - CCFG_MODE_CONF_VDDR_TRIM_SLEEP_DELTA_S ))
382 >> ( 32 - CCFG_MODE_CONF_VDDR_TRIM_SLEEP_DELTA_WIDTH )) + 1;
383 // Do temperature compensation if enabled
384 if (( ccfg_ModeConfReg & CCFG_MODE_CONF_VDDR_TRIM_SLEEP_TC ) == 0 ) {
385 int32_t tcDelta = ( 62 - curTemp ) >> 3;
386 if ( tcDelta > 8 ) tcDelta = 8;
387 if ( tcDelta > deltaVddrSleepTrim ) deltaVddrSleepTrim = tcDelta;
388 }
389 if ((( ccfg_ModeConfReg & CCFG_MODE_CONF_VDDR_EXT_LOAD ) == 0 ) &&
390 (( ccfg_ModeConfReg & CCFG_MODE_CONF_VDDS_BOD_LEVEL ) != 0 ) )
391 {
392 vddrTrimSleep = SignExtendVddrTrimValue((
393 HWREG( FCFG1_BASE + FCFG1_O_VOLT_TRIM ) &
394 FCFG1_VOLT_TRIM_VDDR_TRIM_SLEEP_H_M ) >>
395 FCFG1_VOLT_TRIM_VDDR_TRIM_SLEEP_H_S ) ;
396 vddrTrimActve = SignExtendVddrTrimValue((
397 HWREG( FCFG1_BASE + FCFG1_O_VOLT_TRIM ) &
398 FCFG1_VOLT_TRIM_VDDR_TRIM_HH_M ) >>
399 FCFG1_VOLT_TRIM_VDDR_TRIM_HH_S ) ;
400 } else
401 {
402 vddrTrimSleep = SignExtendVddrTrimValue((
403 HWREG( FCFG1_BASE + FCFG1_O_LDO_TRIM ) &
404 FCFG1_LDO_TRIM_VDDR_TRIM_SLEEP_M ) >>
405 FCFG1_LDO_TRIM_VDDR_TRIM_SLEEP_S ) ;
406 vddrTrimActve = SignExtendVddrTrimValue((
407 HWREG( FCFG1_BASE + FCFG1_O_SHDW_ANA_TRIM ) &
408 FCFG1_SHDW_ANA_TRIM_VDDR_TRIM_M ) >>
409 FCFG1_SHDW_ANA_TRIM_VDDR_TRIM_S ) ;
410 }
411 vddrTrimSleep += deltaVddrSleepTrim;
412 if ( vddrTrimSleep > 21 ) vddrTrimSleep = 21;
413 if ( vddrTrimSleep < -10 ) vddrTrimSleep = -10;
414 // Write adjusted value using MASKED write (MASK8)
415 HWREGH( ADI3_BASE + ADI_O_MASK8B + ( ADI_3_REFSYS_O_DCDCCTL1 * 2 )) = (( ADI_3_REFSYS_DCDCCTL1_VDDR_TRIM_SLEEP_M << 8 ) |
416 (( vddrTrimSleep << ADI_3_REFSYS_DCDCCTL1_VDDR_TRIM_SLEEP_S ) & ADI_3_REFSYS_DCDCCTL1_VDDR_TRIM_SLEEP_M ));
417
418 prcmRamRetention = HWREG( PRCM_BASE + PRCM_O_RAMRETEN );
419 if ( prcmRamRetention & PRCM_RAMRETEN_VIMS_M ) {
420 curState |= PD_STATE_CACHE_RET;
421 }
422 if ( prcmRamRetention & PRCM_RAMRETEN_RFC ) {
423 curState |= PD_STATE_RFMEM_RET;
424 }
425 if ( xoscPowerMode != XOSC_IN_HIGH_POWER_MODE ) {
426 curState |= PD_STATE_XOSC_LPM;
427 }
428
429 //--- Spec. point 2 ---
430 if ((( curTemp - powerQualGlobals.pdTemp ) >= 5 ) || ( curState != powerQualGlobals.pdState )) {
431 //--- Spec. point 3 ---
432 shiftedTemp = curTemp - 15;
433
434 //--- Spec point 4 ---
435 //4. Check for external VDDR load option (may not be supported): ext_load = (VDDR_EXT_LOAD=0 in CCFG)
436 // Currently not implementing external load handling
437 // if ( __ccfg.ulModeConfig & MODE_CONF_VDDR_EXT_LOAD ) {
438 // }
439
440 pLookupTable = (uint32_t *)( FCFG1_BASE + FCFG1_O_PWD_CURR_20C );
441
442 //--- Spec point 5 ---
443 di = 0;
444 ti = 0;
445 if ( shiftedTemp >= 0 ) {
446 //--- Spec point 5.a ---
447 shiftedTemp += ( shiftedTemp << 4 );
448
449 //--- Spec point 5.b ---
450 ti = ( shiftedTemp >> 8 );
451 if ( ti > 7 ) {
452 ti = 7;
453 }
454 dii = ti;
455 if ( dii > 6 ) {
456 dii = 6;
457 }
458
459 //--- Spec point 5.c ---
460 cd = pLookupTable[ dii + 1 ] - pLookupTable[ dii ];
461
462 //--- Spec point 5.d ---
463 di = cd & 0xFF;
464
465 //--- Spec point 5.e ---
466 if ( curState & PD_STATE_XOSC_LPM ) {
467 di += (( cd >> 8 ) & 0xFF );
468 }
469 if ( curState & PD_STATE_RFMEM_RET ) {
470 di += (( cd >> 16 ) & 0xFF );
471 }
472 if ( curState & PD_STATE_CACHE_RET ) {
473 di += (( cd >> 24 ) & 0xFF );
474 }
475
476 //--- Spec point 5.f ---
477 // Currently not implementing external load handling
478 }
479
480 //--- Spec. point 6 ---
481 cl = pLookupTable[ ti ];
482
483 //--- Spec. point 7 ---
484 load = cl & 0xFF;
485
486 //--- Spec. point 8 ---
487 if ( curState & PD_STATE_XOSC_LPM ) {
488 load += (( cl >> 8 ) & 0xFF );
489 }
490 if ( curState & PD_STATE_RFMEM_RET ) {
491 load += (( cl >> 16 ) & 0xFF );
492 }
493 if ( curState & PD_STATE_CACHE_RET ) {
494 load += (( cl >> 24 ) & 0xFF );
495 }
496
497 //--- Spec. point 9 ---
498 load += ((( di * ( shiftedTemp - ( ti << 8 ))) + 128 ) >> 8 );
499
500 // Currently not implementing external load handling
501 // if ( __ccfg.ulModeConfig & MODE_CONF_VDDR_EXT_LOAD ) {
502 //--- Spec. point 10 ---
503 // } else {
504 //--- Spec. point 11 ---
505 diffVddrActiveSleep = ( vddrTrimActve - vddrTrimSleep );
506 if ( diffVddrActiveSleep < 1 ) diffVddrActiveSleep = 1;
507 k = ( diffVddrActiveSleep * 52 );
508 // }
509
510 //--- Spec. point 12 ---
511
512 vddrCap = ( ccfg_ModeConfReg & CCFG_MODE_CONF_VDDR_CAP_M ) >> CCFG_MODE_CONF_VDDR_CAP_S;
513 newRechargePeriod = ( vddrCap * k ) / load;
514 if ( newRechargePeriod > 0xFFFF ) {
515 newRechargePeriod = 0xFFFF;
516 }
517 powerQualGlobals.pdRechargePeriod = newRechargePeriod;
518
519 //--- Spec. point 13 ---
520 if ( curTemp > 127 ) curTemp = 127;
521 if ( curTemp < -128 ) curTemp = -128;
522 powerQualGlobals.pdTemp = curTemp;
523 powerQualGlobals.pdState = curState;
524 }
525
526 powerQualGlobals.pdTime = HWREG( AON_RTC_BASE + AON_RTC_O_SEC );
527
528 // Calculate PER_E and PER_M (based on powerQualGlobals.pdRechargePeriod)
529 // Round downwards but make sure PER_E=0 and PER_M=1 is the minimum possible setting.
530 // (assuming that powerQualGlobals.pdRechargePeriod always are <= 0xFFFF)
531 perE = 0;
532 perM = powerQualGlobals.pdRechargePeriod;
533 if ( perM < 31 ) {
534 perM = 31;
535 powerQualGlobals.pdRechargePeriod = 31;
536 }
537 while ( perM > 511 ) {
538 perM >>= 1;
539 perE += 1;
540 }
541 perM = ( perM - 15 ) >> 4;
542
543 HWREG( AON_WUC_BASE + AON_WUC_O_RECHARGECFG ) =
544 ( 0x80A4E700 ) |
545 ( perM << AON_WUC_RECHARGECFG_PER_M_S ) |
546 ( perE << AON_WUC_RECHARGECFG_PER_E_S ) ;
547 HWREG( AON_WUC_BASE + AON_WUC_O_RECHARGESTAT ) = 0;
548 }
549
550
551 //*****************************************************************************
552 //
553 // SysCtrlAdjustRechargeAfterPowerDown()
554 //
555 //*****************************************************************************
556 void
SysCtrlAdjustRechargeAfterPowerDown(void)557 SysCtrlAdjustRechargeAfterPowerDown( void )
558 {
559 int32_t curTemp ;
560 uint32_t longestRechargePeriod ;
561 uint32_t deltaTime ;
562 uint32_t newRechargePeriod ;
563
564 //--- Spec. point 2 ---
565 longestRechargePeriod = ( HWREG( AON_WUC_BASE + AON_WUC_O_RECHARGESTAT ) &
566 AON_WUC_RECHARGESTAT_MAX_USED_PER_M ) >>
567 AON_WUC_RECHARGESTAT_MAX_USED_PER_S ;
568
569 if ( longestRechargePeriod != 0 ) {
570 //--- Spec. changed (originaly point 1) ---
571 curTemp = AONBatMonTemperatureGetDegC();
572 if ( curTemp < powerQualGlobals.pdTemp ) {
573 if ( curTemp < -128 ) {
574 curTemp = -128;
575 }
576 powerQualGlobals.pdTemp = curTemp;
577 }
578
579 //--- Spec. point 4 ---
580 if ( longestRechargePeriod < powerQualGlobals.pdRechargePeriod ) {
581 powerQualGlobals.pdRechargePeriod = longestRechargePeriod;
582 } else {
583 //--- Spec. point 5 ---
584 deltaTime = HWREG( AON_RTC_BASE + AON_RTC_O_SEC ) - powerQualGlobals.pdTime + 2;
585 if ( deltaTime > 31 ) {
586 deltaTime = 31;
587 }
588 newRechargePeriod = powerQualGlobals.pdRechargePeriod + (( longestRechargePeriod - powerQualGlobals.pdRechargePeriod ) >> (deltaTime>>1));
589 if ( newRechargePeriod > 0xFFFF ) {
590 newRechargePeriod = 0xFFFF;
591 }
592 powerQualGlobals.pdRechargePeriod = newRechargePeriod;
593 }
594 }
595 }
596
597
598 //*****************************************************************************
599 //
600 // SysCtrl_DCDC_VoltageConditionalControl()
601 //
602 //*****************************************************************************
603 void
SysCtrl_DCDC_VoltageConditionalControl(void)604 SysCtrl_DCDC_VoltageConditionalControl( void )
605 {
606 uint32_t batThreshold ; // Fractional format with 8 fractional bits.
607 uint32_t aonBatmonBat ; // Fractional format with 8 fractional bits.
608 uint32_t ccfg_ModeConfReg ; // Holds a copy of the CCFG_O_MODE_CONF register.
609 uint32_t aonSysctlPwrctl ; // Reflect whats read/written to the AON_SYSCTL_O_PWRCTL register.
610
611 //
612 // We could potentially call this function before any battery voltage measurement
613 // is made/available. In that case we must make sure that we do not turn off the DCDC.
614 // This can be done by doing nothing as long as the battery voltage is 0 (Since the
615 // reset value of the battery voltage register is 0).
616 //
617 aonBatmonBat = HWREG( AON_BATMON_BASE + AON_BATMON_O_BAT );
618 if ( aonBatmonBat != 0 ) {
619 //
620 // Check if Voltage Conditional Control is enabled
621 // It is enabled if both:
622 // - DCDC in use (either in active or recharge mode), (in use if one of the corresponding CCFG bits are zero).
623 // - Alternative DCDC settings are enabled ( DIS_ALT_DCDC_SETTING == 0 )
624 //
625 ccfg_ModeConfReg = HWREG( CCFG_BASE + CCFG_O_MODE_CONF );
626
627 if (((( ccfg_ModeConfReg & CCFG_MODE_CONF_DCDC_RECHARGE_M ) == 0 ) ||
628 (( ccfg_ModeConfReg & CCFG_MODE_CONF_DCDC_ACTIVE_M ) == 0 ) ) &&
629 (( HWREG( CCFG_BASE + CCFG_O_SIZE_AND_DIS_FLAGS ) & CCFG_SIZE_AND_DIS_FLAGS_DIS_ALT_DCDC_SETTING ) == 0 ) )
630 {
631 aonSysctlPwrctl = HWREG( AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL );
632 batThreshold = (((( HWREG( CCFG_BASE + CCFG_O_MODE_CONF_1 ) &
633 CCFG_MODE_CONF_1_ALT_DCDC_VMIN_M ) >>
634 CCFG_MODE_CONF_1_ALT_DCDC_VMIN_S ) + 28 ) << 4 );
635
636 if ( aonSysctlPwrctl & ( AON_SYSCTL_PWRCTL_DCDC_EN_M | AON_SYSCTL_PWRCTL_DCDC_ACTIVE_M )) {
637 //
638 // DCDC is ON, check if it should be switched off
639 //
640 if ( aonBatmonBat < batThreshold ) {
641 aonSysctlPwrctl &= ~( AON_SYSCTL_PWRCTL_DCDC_EN_M | AON_SYSCTL_PWRCTL_DCDC_ACTIVE_M );
642
643 HWREG( AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL ) = aonSysctlPwrctl;
644 }
645 } else {
646 //
647 // DCDC is OFF, check if it should be switched on
648 //
649 if ( aonBatmonBat > batThreshold ) {
650 if (( ccfg_ModeConfReg & CCFG_MODE_CONF_DCDC_RECHARGE_M ) == 0 ) aonSysctlPwrctl |= AON_SYSCTL_PWRCTL_DCDC_EN_M ;
651 if (( ccfg_ModeConfReg & CCFG_MODE_CONF_DCDC_ACTIVE_M ) == 0 ) aonSysctlPwrctl |= AON_SYSCTL_PWRCTL_DCDC_ACTIVE_M ;
652
653 HWREG( AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL ) = aonSysctlPwrctl;
654 }
655 }
656 }
657 }
658 }
659
660
661 //*****************************************************************************
662 //
663 // SysCtrlResetSourceGet()
664 //
665 //*****************************************************************************
666 uint32_t
SysCtrlResetSourceGet(void)667 SysCtrlResetSourceGet( void )
668 {
669 if ( HWREG( AON_SYSCTL_BASE + AON_SYSCTL_O_RESETCTL ) & AON_SYSCTL_RESETCTL_WU_FROM_SD_M ) {
670 return ( RSTSRC_WAKEUP_FROM_SHUTDOWN );
671 } else {
672 return (( HWREG( AON_SYSCTL_BASE + AON_SYSCTL_O_RESETCTL ) &
673 AON_SYSCTL_RESETCTL_RESET_SRC_M ) >>
674 AON_SYSCTL_RESETCTL_RESET_SRC_S ) ;
675 }
676 }
677