低功耗模式分为两种:1、掉电模式(shutdown),2、睡眠模式(sleep 或者 standby)
1、睡眠模式
即规格书中说的 Standby 模式,电流功耗 1.1uA,只有 RTC,RAM/CPU 保持运行
int_fast16_t Power_sleep(uint_fast16_t sleepState)
参数说明
sleepState 目前只支持 PowerCC26XX_STANDBY
示例:
Power_sleep(PowerCC26XX_STANDBY);
2、掉电模式
只能通过外部中断唤醒,电流功耗 100nA
int_fast16_t Power_shutdown(uint_fast16_t shutdownState, uint_fast32_t shutdownTime)
参数说明
shutdownState:没有使用
shutdownTime:没有使用
注意:
调用该 API 时需要先禁用所有中断
睡眠之前,需要调用函数PINCC26XX_setWakeup配置管脚唤醒
示例:
- PIN_Config ButtonTableWakeUp[] = {
-
- CONFIG_PIN_BUTTON_0 | PIN_INPUT_EN | PIN_PULLUP | PINCC26XX_WAKEUP_NEGEDGE,
-
- PIN_TERMINATE /* Terminate list */
-
- };
-
-
-
- /* Configure DIO for wake up from shutdown */
-
- PINCC26XX_setWakeup(ButtonTableWakeUp);
-
-
-
- /* Go to shutdown */
-
- Power_shutdown(0, 0);
3、注册监听电源状态
int_fast16_t Power_registerNotify(Power_NotifyObj * pNotifyObj, uint_fast16_t eventTypes, Power_NotifyFxn notifyFxn, uintptr_t clientArg)
参数说明
pNotifyObj: 通知对象结构体
eventTypes: 需要注册的事件类型

notifyFxn: 回调函数
clientArg: 回调函数的参数
4、TIRTOS睡眠
使能睡眠功能,通过TI图形化配置工具,选中Enable Policy,或者通过代码调用Power_enablePolicy/Power_disablePolicy来使能/禁止
a、配置完成后系统自动生成以下代码
- const PowerCC26X2_Config PowerCC26X2_config = {
- .enablePolicy = true,
- .policyInitFxn = NULL,
- .policyFxn = PowerCC26XX_standbyPolicy,
- .calibrateFxn = PowerCC26XX_calibrate,
- .calibrateRCOSC_LF = true,
- .calibrateRCOSC_HF = true,
- .enableTCXOFxn = NULL
- };
b、待机策略函数是 PowerCC26XX_standbyPolicy 也可以通过代码调用Power_setPolicy设置
c、在Power_idleFunc函数会调用 PowerCC26XX_standbyPolicy (在Power_init函数已经把PowerCC26X2_config.policyFxn赋值给PowerCC26X2_module.policyFxn,而PowerCC26X2_config.policyFxn初始化时就赋值为PowerCC26XX_standbyPolicy)
- void Power_idleFunc()
- {
- if (PowerCC26X2_module.enablePolicy) {
- if (PowerCC26X2_module.policyFxn != NULL) {
- (*(PowerCC26X2_module.policyFxn))();
- }
- }
- }
d、Power_idleFunc函数在空闲任务中被调用
- #pragma location = ".const_ti_sysbios_knl_Idle_funcList__A"
- const __T1_ti_sysbios_knl_Idle_funcList ti_sysbios_knl_Idle_funcList__A[1] = {
- ((xdc_Void(*)(xdc_Void))(Power_idleFunc)), /* [0] */
- };
e、睡眠策略函数 PowerCC26XX_standbyPolicy
- void PowerCC26XX_standbyPolicy(void)
- {
- bool justIdle = TRUE;
- uint32_t constraints;
- uint32_t ticks, time;
-
- /* disable interrupts */
- CPUcpsid();
-
- /* check operating conditions, optimally choose DCDC versus GLDO */
- SysCtrl_DCDC_VoltageConditionalControl();
-
- /* query the declared constraints */
- constraints = Power_getConstraintMask();
-
- /* do quick check to see if only WFI allowed; if yes, do it now */
- if ((constraints &
- ((1 << PowerCC26XX_DISALLOW_STANDBY) | (1 << PowerCC26XX_DISALLOW_IDLE))) ==
- ((1 << PowerCC26XX_DISALLOW_STANDBY) | (1 << PowerCC26XX_DISALLOW_IDLE))) {
-
- /* Flush any remaining log messages in the ITM */
- ITM_flush();
- PRCMSleep();
- /* Restore ITM settings */
- ITM_restore();
- }
- /*
- * check if any sleep modes are allowed for automatic activation
- */
- else {
- /* check if we are allowed to go to standby */
- if ((constraints & (1 << PowerCC26XX_DISALLOW_STANDBY)) == 0) {
- /*
- * Check how many ticks until the next scheduled wakeup. A value of
- * zero indicates a wakeup will occur as the current Clock tick
- * period expires; a very large value indicates a very large number
- * of Clock tick periods will occur before the next scheduled
- * wakeup.
- */
- ticks = Clock_getTicksUntilInterrupt();
-
- /* convert ticks to usec */
- time = ticks * Clock_tickPeriod;
-
- /* check if can go to STANDBY */
- if (time > Power_getTransitionLatency(PowerCC26XX_STANDBY,
- Power_TOTAL)) {
-
- /* schedule the wakeup event */
- ticks -= PowerCC26X2_WAKEDELAYSTANDBY / Clock_tickPeriod;
- Clock_setTimeout(Clock_handle((Clock_Struct *)&PowerCC26X2_module.clockObj), ticks);
- Clock_start(Clock_handle((Clock_Struct *)&PowerCC26X2_module.clockObj));
-
- /* Flush any remaining log messages in the ITM */
- ITM_flush();
-
- /* go to standby mode */
- Power_sleep(PowerCC26XX_STANDBY);
-
- /* Restore ITM settings */
- ITM_restore();
-
- Clock_stop(Clock_handle((Clock_Struct *)&PowerCC26X2_module.clockObj));
- justIdle = FALSE;
- }
- }
-
- /* idle if allowed */
- if (justIdle) {
-
- /* Flush any remaining log messages in the ITM */
- ITM_flush();
-
- /*
- * Power off the CPU domain; VIMS will power down if SYSBUS is
- * powered down, and SYSBUS will power down if there are no
- * dependencies
- * NOTE: if radio driver is active it must force SYSBUS enable to
- * allow access to the bus and SRAM
- */
- if ((constraints & (1 << PowerCC26XX_DISALLOW_IDLE)) == 0) {
- uint32_t modeVIMS;
- /* 1. Get the current VIMS mode */
- do {
- modeVIMS = VIMSModeGet(VIMS_BASE);
- } while (modeVIMS == VIMS_MODE_CHANGING);
-
- /* 2. Configure flash to remain on in IDLE or not and keep
- * VIMS powered on if it is configured as GPRAM
- * 3. Always keep cache retention ON in IDLE
- * 4. Turn off the CPU power domain
- * 5. Ensure any possible outstanding AON writes complete
- * 6. Enter IDLE
- */
- if ((constraints & (1 << PowerCC26XX_NEED_FLASH_IN_IDLE)) ||
- (modeVIMS == VIMS_MODE_DISABLED)) {
- SysCtrlIdle(VIMS_ON_BUS_ON_MODE);
- }
- else {
- SysCtrlIdle(VIMS_ON_CPU_ON_MODE);
- }
-
- /* 7. Make sure MCU and AON are in sync after wakeup */
- SysCtrlAonUpdate();
- }
- else {
- PRCMSleep();
- }
-
- /* Restore ITM settings */
- ITM_restore();
- }
- }
-
- /* re-enable interrupts */
- CPUcpsie();
- }
任务空闲时,程序会调用PowerCC26XX_standbyPolicy,根据当前系统的状态进入不同的睡眠模式,并根据最短的那个任务调度时间设置定时唤醒。
参考官方文档“Power_Management.pdf”