CC26XX睡眠

低功耗模式分为两种: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”

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dear_Wally

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值