/* * ======== Power_Module_startup ======== */ Int ti_sysbios_family_arm_cc26xx_Power_Module_startup(Int status) { DRIVERLIB_ASSERT_CURR_RELEASE(); /* enable cache (in case boot ROM doesn't because of HIB) */ HWREG(VIMS_BASE + VIMS_O_CTL) = ((HWREG(VIMS_BASE + VIMS_O_CTL) & ~VIMS_CTL_MODE_M ) | VIMS_CTL_MODE_CACHE ); /* force AUX on and enable OSC clock */ OSCInterfaceEnable(); /* source the HF clock from RC_OSC */ OSCHF_SwitchToRcOscTurnOffXosc(); /* when in sleep, power off JTAG */ AONWUCJtagPowerOff(); /* allow AUX to power down */ AUXWUCPowerCtrl(AUX_WUC_POWER_DOWN); /* clear PDCTL1.VIMS_MODE to power VIMS only when CPU domain is powered */ HWREG(PRCM_BASE + PRCM_O_PDCTL1VIMS) &= ~PRCM_PDCTL1VIMS_ON; /* sync with AON */ SysCtrlAonSync(); /* set standby disallow constraint pending LF clock quailifier disabling */ Power_setConstraint(Power_SB_DISALLOW); return (Startup_DONE); }
/* * ======== SENSORTAG_CC2650_initGeneral ======== */ Void SENSORTAG_CC2650_initGeneral(Void) { /* force power on AUX - this will be released when entering sleep mode */ AONWUCAuxWakeupEvent(AONWUC_AUX_WAKEUP); /* enable the AUX oscillator clock */ AUXWUCClockEnable(AUX_WUC_OSCCTRL_CLOCK); while(AUXWUCClockStatus(AUX_WUC_OSCCTRL_CLOCK) != AUX_WUC_CLOCK_READY) { } /* This application will not be using the AUX domain out of boot * and we will leave out clock for optimal power conservation */ AONWUCAuxPowerDownConfig(AONWUC_NO_CLOCK); /* * Source the LF clock from the low frequency XTAL_OSC. * HF and MF are sourced from the high frequency RC_OSC. */ OSCClockSourceSet(OSC_SRC_CLK_LF, OSC_XOSC_LF); OSCClockSourceSet(OSC_SRC_CLK_MF | OSC_SRC_CLK_HF, OSC_RCOSC_HF); /* * Check if already sourcing the HF clock from RC_OSC. * If a switch of the clock source is not required, then the call to ROM * will loop forever. */ if(OSCClockSourceGet(OSC_SRC_CLK_HF) != OSC_RCOSC_HF) { OSCHfSourceSwitch(); } /* enable DCDC */ PowerCtrlSourceSet(PWRCTRL_PWRSRC_DCDC); /* make sure AON accesses are in sync and enable powerdown on AUX */ SysCtrlAonSync(); AUXWUCPowerCtrl(AUX_WUC_POWER_DOWN); }
/* * ======== Power_shutdown ======== */ Power_Status Power_shutdown(UArg arg) { Power_Status status = Power_EFAIL; Bool exitNow = FALSE; UInt32 constraints; UInt hwiKey; /* make sure shutdown request doesn't violate a constraint */ constraints = Power_getConstraintInfo(); if ((constraints & (Power_SD_DISALLOW)) != 0) { status = Power_ECHANGE_NOT_ALLOWED; } if (status == Power_EFAIL) { /* make sure Power is not still busy with a previous transition */ hwiKey = Hwi_disable(); if (Power_module->state == Power_ACTIVE) { /* set new transition state to entering shutdown */ Power_module->state = Power_SHUTDOWN; } else { exitNow = TRUE; } Hwi_restore(hwiKey); if (exitNow == TRUE) { status = Power_EBUSY; } else { /* disable interrupts as start the shutdown sequence */ Hwi_disable(); /* signal all clients registered for pre-shutdown notification */ status = Power_notify(Power_ENTERING_SHUTDOWN); /* check for any error */ if (status != Power_SOK) { Power_module->state = Power_ACTIVE; CPUcpsie(); return (status); } /* proceed with shutdown sequence ... */ /* switch to RCOSC_HF and RCOSC_LF */ OSCInterfaceEnable(); if(OSCClockSourceGet(OSC_SRC_CLK_HF) != OSC_RCOSC_HF) { OSCClockSourceSet(OSC_SRC_CLK_HF | OSC_SRC_CLK_MF, OSC_RCOSC_HF); while(!OSCHfSourceReady()); OSCHfSourceSwitch(); } OSCClockSourceSet(OSC_SRC_CLK_LF,OSC_RCOSC_LF); while(OSCClockSourceGet(OSC_SRC_CLK_LF) != OSC_RCOSC_LF); OSCInterfaceDisable(); /* make sure DMA and CRYTO clocks are off in deep-sleep */ PRCMPeripheralDeepSleepDisable(PRCM_PERIPH_CRYPTO); PRCMPeripheralDeepSleepDisable(PRCM_PERIPH_UDMA); PRCMLoadSet(); while(!PRCMLoadGet()){}; /* power OFF AUX and disconnect from bus */ AUXWUCPowerCtrl(AUX_WUC_POWER_OFF); /* remove AUX force ON */ HWREG(AON_WUC_BASE + AON_WUC_O_AUXCTL) &= ~AON_WUC_AUXCTL_AUX_FORCE_ON; /* * reset AON event source IDs to avoid pending events powering * on MCU/AUX */ HWREG(AON_EVENT_BASE + AON_EVENT_O_MCUWUSEL) = 0x3F3F3F3F; HWREG(AON_EVENT_BASE + AON_EVENT_O_AUXWUSEL) = 0x003F3F3F; /* sync AON */ HWREG(AON_RTC_BASE + AON_RTC_O_SYNC); /* * enable shutdown - this latches the IOs, so configuration of * IOCFGx registers must be done prior to this */ AONWUCShutDownEnable(); /* sync AON */ HWREG(AON_RTC_BASE + AON_RTC_O_SYNC); /* wait until AUX powered off */ while (AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON); /* request to power off MCU when go to deep sleep */ PRCMMcuPowerOff(); /* turn off power domains inside MCU VD (BUS, FL_BUS, RFC, CPU) */ PRCMPowerDomainOff(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH | PRCM_DOMAIN_CPU | PRCM_DOMAIN_VIMS); /* deep sleep to activate shutdown */ PRCMDeepSleep(); } } Power_module->state = Power_ACTIVE; /* if get here failed to shutdown, return failure code */ return (Power_EFAIL); }
//***************************************************************************** // // Force the system in to low power modes. // //***************************************************************************** void PowerCtrlStateSet(uint32_t ui32Powerstate) { // // Check the arguments. // ASSERT((ui32Powerstate == PWRCTRL_STANDBY) || (ui32Powerstate == PWRCTRL_POWER_DOWN) || (ui32Powerstate == PWRCTRL_SHUTDOWN)); // // Configure the desired power state. // if(ui32Powerstate == PWRCTRL_STANDBY) { // // // Turn of all power domains in the MCU voltage domain. This is // necessary to conserve power before switching to the uLDO. // PRCMPowerDomainOff(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH | PRCM_DOMAIN_CPU | PRCM_DOMAIN_VIMS); // // Make sure to request power off of the JTAG domain. // AONWUCJtagPowerOff(); // // Configuration of clock source for MCU and AUX in standby mode. // AONWUCMcuPowerDownConfig(AONWUC_CLOCK_SRC_LF); AONWUCAuxPowerDownConfig(AONWUC_CLOCK_SRC_LF); // // Configure the recharge controller and request the uLDO as power // source. // AONWUCRechargeCtrlConfigSet(true, 34, 2500, 5000); // // Enable AUX power down // This will tell the system that no HF source is needed and will // allow the system to use the low-leakage/effect power supply. // NB. This does not allow co-existence of an independent // Sensor Controller. // AUXWUCPowerCtrl(AUX_WUC_POWER_DOWN); while(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON); // // Request the uLDO for standby power consumption. // PowerCtrlSourceSet(PWRCTRL_PWRSRC_ULDO); // // Sync the AON interface to ensure all writes have gone through // HWREG(AON_RTC_BASE + AON_RTC_O_SYNC); // // Enable transition to standby. // PRCMDeepSleep(); } else if(ui32Powerstate == PWRCTRL_POWER_DOWN) { // // Latch the current IO configuration before going to sleep to ensure // the IOs retain their value even after boot and reset of the // configuration. // AONIOCFreezeEnable(); // // Make sure retention on MCU SRAM is on - on pr. default. // AONWUCMcuSRamConfig(MCU_RAM0_RETENTION | MCU_RAM1_RETENTION | MCU_RAM2_RETENTION | MCU_RAM3_RETENTION); // // Allow power off on all domains in the MCU voltage domain. // This is necessary to conserve power before switching to the uLDO. // PRCMPowerDomainOff(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH | PRCM_DOMAIN_CPU | PRCM_DOMAIN_VIMS); // // Turn off the MCU voltage domain. This will not take effect until System CPU // is in deep sleep. // PRCMMcuPowerOff(); // // Set the wake up mode - default value coming out of reset // AONWUCMcuWakeUpConfig(MCU_IMM_WAKE_UP); // // VIRTUAL POWER OFF DISABLE is the default value coming out of reset // AONWUCMcuPowerOffConfig(MCU_VIRT_PWOFF_DISABLE); // // Configure the recharge controller and request the uLDO as power // source. // Recommended maximum numbers for lowest power consumption // AdaptRate = 96 // MaxPeriod = 21440 // InitPeriod = 14816 // AONWUCRechargeCtrlConfigSet(true, 75, 5000, 7500); // // Enable AUX power down with LF clock source // Turn off JTAG domain and enable powerdown - values are default. // AONWUCAuxPowerDownConfig(AONWUC_CLOCK_SRC_LF); AUXWUCPowerCtrl(AUX_WUC_POWER_DOWN); AONWUCDomainPowerDownEnable(); while(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON); // // Sync the AON interface to ensure all writes have gone through // HWREG(AON_RTC_BASE + AON_RTC_O_SYNC); // // Enable transition to power down. // PRCMDeepSleep(); } else { // // Latch the current IO configuration before going to sleep to ensure // the IOs retain their value even after boot and reset of the // configuration. // AONIOCFreezeEnable(); // // Turn of all power domains in the MCU voltage domain. // PRCMPowerDomainOff(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH | PRCM_DOMAIN_CPU | PRCM_DOMAIN_VIMS); // // Turn off the MCU voltage domain. This will not take effect until System CPU // is in deep sleep. // PRCMMcuPowerOff(); // // Set the wake up mode of MCU to immediate // AONWUCMcuWakeUpConfig(MCU_IMM_WAKE_UP); AONWUCMcuPowerOffConfig(MCU_VIRT_PWOFF_DISABLE); // // Turn off the AUX domain and wait for power to be off. // // Is this required for shutdown mode? or will AUX automatically // power off. AUXWUCPowerCtrl(AUX_WUC_POWER_OFF); while(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON) { } // // Latch the IOs in the padring before going to sleep to retain their // value even after boot and reset of the configuration. // PowerCtrlIOFreezeEnable(); // // Enable shutdown and make sure the AON interface is in sync on the // 32kHz clock. // AONWUCShutDownEnable(); // // Sync the AON interface to ensure all writes have gone through // HWREG(AON_RTC_BASE + AON_RTC_O_SYNC); // // Enable transition to shutdown. // PRCMDeepSleep(); } }