/* * ======== Seconds_get ======== */ UInt32 Seconds_get(Void) { UInt32 curSeconds; UInt key; /* * Disable scheduling. We use Swi_disable() instead of * Hwi_disable() because of the large times for accessing * these registers. */ key = Swi_disable(); /* * The CC3200 timer has a frequency of 32768 (2 ** 15), so * to get seconds, drop the lower 15 bits. */ curSeconds = (UInt32)(Seconds_getCount() >> 15); curSeconds = curSeconds - Seconds_module->refSeconds + Seconds_module->setSeconds; /* Re-enable scheduling */ Swi_restore(key); return (curSeconds); }
/* * ======== Power_updateConstraints ======== */ Void Power_updateConstraints(Power_Constraint type, UArg value) { UInt key; /* stop threading */ key = Swi_disable(); /* update the disallowed CPU domain setpoints mask(?) */ if (type == Power_DISALLOWED_CPU_SETPOINT_MASK) { Power_module->disallowedSetpointsCPU |= (UInt) value; } /* or, update disallowed PER domain setpoints mask(?) */ else if (type == Power_DISALLOWED_PER_SETPOINT_MASK) { Power_module->disallowedSetpointsPER |= (UInt) value; } /* or, update disallowed sleep modes mask(?) */ else if (type == Power_DISALLOWEDSLEEPSTATE_MASK) { Power_module->disallowedSleepModes |= (UInt) value; } /* resume threading */ Swi_restore(key); }
/* * ======== tsk0Fxn ======= */ Void tsk0Fxn(UArg arg0, UArg arg1) { UInt key; /* wait for swis to be posted from Clock function */ Semaphore_pend(sem0, BIOS_WAIT_FOREVER); System_printf("Running tsk0Fxn\n"); key = Swi_disable(); /* swis are disabled */ Swi_inc(swi0); /* swi0 trigger = 1 */ Swi_inc(swi0); /* swi0 trigger = 2 */ Swi_restore(key); /* swi0 runs */ Swi_or(swi1, 0x100); /* swi1 runs with trigger = 0x111 */ Swi_andn(swi1, 0x1); /* swi1 trigger = 0x10 */ Swi_andn(swi1, 0x2); /* swi1 runs with trigger = 0x00 */ Swi_dec(swi1); /* swi1 trigger = 2 */ Swi_dec(swi1); /* swi1 trigger = 1 */ Swi_dec(swi1); /* swi1 runs with trigger = 0 */ System_printf("Calling BIOS_exit\n"); BIOS_exit(0); }
/* * ======== GateAll_leave ======== */ Void GateAll_leave(GateAll_Object *gate, IArg key) { if (key == 0) { gate->entered = FALSE; Swi_restore(gate->swiKey); Hwi_restore(gate->hwiKey); } }
/* * ======== Swi_restorePri ======== */ Void Swi_restorePri(UInt priority) { UInt swiKey; swiKey = Swi_disable(); Swi_module->curQ = Queue_Object_get(Swi_module->readyQ, priority); Swi_restore(swiKey); }
/* * ======== Power_rebuildConstraint ======== */ Void Power_rebuildConstraint(Power_Constraint type) { Queue_Handle constraintsQ; Queue_Elem * elem; UInt value; UInt key; /* disable scheduling */ key = Swi_disable(); /* first, re-initialize the aggregate constraint */ if (type == Power_DISALLOWED_CPU_SETPOINT_MASK) { Power_module->disallowedSetpointsCPU = 0; } else if (type == Power_DISALLOWED_PER_SETPOINT_MASK) { Power_module->disallowedSetpointsPER = 0; } else if (type == Power_DISALLOWEDSLEEPSTATE_MASK) { Power_module->disallowedSleepModes = 0; } constraintsQ = Power_Module_State_constraintsQ(); if (!Queue_empty(constraintsQ)) { elem = Queue_head(constraintsQ); do { /* only if constraint 'type' matches... */ if (((Power_ConstraintObj *)elem)->type == type) { /* get the constraint value */ value = (UInt) ((Power_ConstraintObj *)elem)->value; /* update the agregate constraint */ if (type == Power_DISALLOWED_CPU_SETPOINT_MASK) { Power_module->disallowedSetpointsCPU |= value; } else if (type == Power_DISALLOWED_PER_SETPOINT_MASK) { Power_module->disallowedSetpointsPER |= value; } else if (type == Power_DISALLOWEDSLEEPSTATE_MASK) { Power_module->disallowedSleepModes |= value; } } elem = Queue_next(elem); } while (elem != (Queue_Elem *) constraintsQ); } /* re-enable scheduling */ Swi_restore(key); }
/* * ======== IpcPower_hibernateLock ======== */ UInt IpcPower_hibernateLock() { IArg hwiKey, swiKey; hwiKey = Hwi_disable(); swiKey = Swi_disable(); IpcPower_hibLock++; Swi_restore(swiKey); Hwi_restore(hwiKey); return (IpcPower_hibLock); }
/* * ======== IpcPower_hibernateUnlock ======== */ UInt IpcPower_hibernateUnlock() { IArg hwiKey, swiKey; hwiKey = Hwi_disable(); swiKey = Swi_disable(); if (IpcPower_hibLock > 0) { IpcPower_hibLock--; } Swi_restore(swiKey); Hwi_restore(hwiKey); return (IpcPower_hibLock); }
/* * ======== Seconds_set ======== */ Void Seconds_set(UInt32 seconds) { UInt64 curCount; UInt key; /* * Disable scheduling. We use Swi_disable() instead of * Hwi_disable() because of the large times for accessing * these registers. */ key = Swi_disable(); /* * Start the RTC counter the first time Seconds_set() is called, if * it is not already running. */ if (Seconds_module->refSeconds == 0xffffffff) { /* * Only start the RTC if it is not already running. */ if (!(HWREG(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_ENABLE) & 0x1)) { /* Enable the timer */ HWREG(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_ENABLE) = 0x1; } } curCount = Seconds_getCount(); /* * The CC3200 timer has a frequency of 32768 (2 ** 15), so * to get seconds, drop the lower 15 bits. */ Seconds_module->refSeconds = (UInt32)(curCount >> 15); Seconds_module->setSeconds = seconds; /* Re-enable scheduling */ Swi_restore(key); }
/* * ======== Seconds_getTime ======== */ UInt32 Seconds_getTime(Seconds_Time *ts) { UInt64 curCount; UInt key; /* * Disable scheduling. We use Swi_disable() instead of * Hwi_disable() because of the large times for accessing * these registers. */ key = Swi_disable(); curCount = Seconds_getCount(); ts->secs = (UInt32)(curCount >> 15) - Seconds_module->refSeconds + Seconds_module->setSeconds; ts->nsecs = (UInt32)(1000000000 * (curCount & 0x7FFF) / 32768); /* Re-enable scheduling */ Swi_restore(key); return (0); }
/* * ======== Power_releaseDependency ======== * Release a dependency that has been previously declared by * Power_setDependency. * */ Power_Status Power_releaseDependency(Power_Resource resourceID) { Power_Status status = Power_SOK; PMI_Status pmi = PMI_BUSY; Bool callStatus; UInt checks = 0; UInt state = 0; UInt refCount; UInt key; /* make sure RT has been configured ON */ if (!ti_sysbios_family_c674_Power_trackResources) { status = Power_ENOTSUPPORTED; } /* validate resource ID is within range of pre-defined resources */ else if (resourceID >= Power_RSRC_END) { status = Power_EOUTOFRANGE; } /* make sure this resource is 'valid' for DSP control */ else if ((ti_sysbios_family_c674_Power_database[resourceID].flags & VALID) == 0) { status = Power_EINVALIDVALUE; } /* else, check reference count, de-activate resource */ else { /* disable scheduling */ key = Swi_disable(); /* read reference count */ refCount = ti_sysbios_family_c674_Power_database[resourceID].count; /* if reference count already zero return an error code */ if (refCount == 0) { status = Power_ETOOMANYCALLS; } /* else, if dependencies remain simply decrement count */ else if (refCount > 1) { ti_sysbios_family_c674_Power_database[resourceID].count = refCount - 1; } /* else, one remaining dependency, and it is being released... */ else { /* if resource has special handler - call it now */ if (ti_sysbios_family_c674_Power_database[resourceID].specialHandler != NULL) { callStatus = (*ti_sysbios_family_c674_Power_database[resourceID].specialHandler) (resourceID, Power_RELEASE); } /* else, call to PMI to deactivate the resource */ else { state = ti_sysbios_family_c674_Power_database[resourceID].inactiveState; /* optionally assert force for the transition */ if ((ti_sysbios_family_c674_Power_database[resourceID].flags & FORCE_MODE) != 0) { state = state | FORCE_BIT; } /* initiate transition to inactive state */ PMI_setModuleState(0, (UInt)ti_sysbios_family_c674_Power_database[resourceID].pscNum, (UInt)ti_sysbios_family_c674_Power_database[resourceID].lpscNum, state); /* now wait for the PSC transition to complete */ while ((pmi == PMI_BUSY) && (checks++ < PSCWAITTHRESHOLD)) { pmi = PMI_getModuleState(0, (UInt)ti_sysbios_family_c674_Power_database[resourceID].pscNum, (UInt)ti_sysbios_family_c674_Power_database[resourceID].lpscNum, &state); } /* check that transitioned to inactive state */ if ((pmi == PMI_OK) && (state == (UInt)ti_sysbios_family_c674_Power_database[resourceID].inactiveState)) { callStatus = TRUE; } else { callStatus = FALSE; } } /* if returned status is good, set reference count to 0 */ if (callStatus == TRUE) { ti_sysbios_family_c674_Power_database[resourceID].count = 0; } /* else, don't modify reference count, return failure code */ else { status = Power_EFAIL; } } /* re-enable scheduling */ Swi_restore(key); } return (status); }
/* * ======== PowerCC3200_sleepPolicy ======== */ void PowerCC3200_sleepPolicy() { bool returnFromSleep = FALSE; uint32_t constraintMask; uint32_t ticks; uint64_t time; uint64_t match; uint64_t curr; uint64_t remain; uint32_t taskKey; uint32_t swiKey; /* disable interrupts */ CPUcpsid(); /* disable Swi and Task scheduling */ swiKey = Swi_disable(); taskKey = Task_disable(); /* query the declared constraints */ constraintMask = Power_getConstraintMask(); /* * Do not go into LPDS if not allowed into DEEPSLEEP. * Check to see if we can go into LPDS (lowest level sleep). * If not allowed, then attempt to go into DEEPSLEEP. * If not allowed in DEEPSLEEP then just SLEEP. */ /* check if we are allowed to go to LPDS */ if ((constraintMask & ((1 << PowerCC3200_DISALLOW_LPDS) | (1 << PowerCC3200_DISALLOW_DEEPSLEEP))) == 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. */ /* Get the time remaining for the RTC timer to expire */ ticks = Clock_getTicksUntilInterrupt(); /* convert ticks to microseconds */ time = ticks * Clock_tickPeriod; /* check if can go to LPDS */ if (time > Power_getTransitionLatency(PowerCC3200_LPDS, Power_TOTAL)) { /* get the current and match values for RTC */ match = MAP_PRCMSlowClkCtrMatchGet(); curr = MAP_PRCMSlowClkCtrGet(); remain = match - curr - (((uint64_t)PowerCC3200_TOTALTIMELPDS * 32768) / 1000000); /* set the LPDS wakeup time interval */ MAP_PRCMLPDSIntervalSet(remain); /* enable the wake source to be timer */ MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_TIMER); /* go to LPDS mode */ Power_sleep(PowerCC3200_LPDS); /* set 'returnFromSleep' to TRUE*/ returnFromSleep = TRUE; } } /* check if we are allowed to go to DEEPSLEEP */ if ((constraintMask & (1 << PowerCC3200_DISALLOW_DEEPSLEEP) == 0) && (!returnFromSleep)) { /* * 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 microseconds */ time = ticks * Clock_tickPeriod; /* check if can go to DEEPSLEEP */ if (time > Power_getTransitionLatency(PowerCC3200_DEEPSLEEP, Power_TOTAL)) { /* schedule the wakeup event */ ticks -= PowerCC3200_RESUMETIMEDEEPSLEEP / Clock_tickPeriod; Clock_setTimeout(Clock_handle(&clockObj), ticks); Clock_start(Clock_handle(&clockObj)); /* go to DEEPSLEEP mode */ Power_sleep(PowerCC3200_DEEPSLEEP); Clock_stop(Clock_handle(&clockObj)); /* set 'returnFromSleep' to TRUE so we don't go to sleep (below) */ returnFromSleep = TRUE; } } /* re-enable interrupts */ CPUcpsie(); /* restore Swi scheduling */ Swi_restore(swiKey); /* restore Task scheduling */ Task_restore(taskKey); /* sleep only if we are not returning from one of the sleep modes above */ if (!(returnFromSleep)) { MAP_PRCMSleepEnter(); } }
/* * ======== Swi_startup ======== */ Void Swi_startup() { Swi_restore(FALSE); }
/* * ======== Power_changeSetpoint ======== * Initiate a change to the F/V setpoint of the CPU, or the peripheral domain. * */ Power_Status Power_changeSetpoint(Power_Domain domain, UInt newSetpoint, UInt notifyTimeout) { PSCL_Status statusPSCL = PSCL_CANNOT_CHANGE_SETPOINT; Power_Status status = Power_SOK; Power_Status statusNotifyCPU = Power_SOK; Power_Status statusNotifyPER = Power_SOK; Bool notifyCPU = FALSE; Bool notifyPER = FALSE; UInt willChange = FALSE; Bool proceed = FALSE; Types_FreqHz cpuFreq; UInt previousSPPER; UInt previousSP; UInt disallowed; PSCL_ClkID clk; UInt frequency; UInt voltage; UInt maskSP; UInt taskKey; UInt swiKey; UInt key; /* make sure V/F scaling is supported */ if (!ti_sysbios_family_c674_Power_enableScaling) { status = Power_ENOTIMPLEMENTED; } /* check to make sure V/F scaling initialized OK */ else if (Power_module->PSCLinitOK == FALSE) { status = Power_EINITFAILURE; } /* check that domain ID is valid */ else if ((domain != Power_CPU) && (domain != Power_PER)) { status = Power_EINVALIDVALUE; } /* check if setpoint ID is out of range for the specified domain ID */ else if (((domain == Power_CPU) && (newSetpoint > (Power_module->numSPCPU - 1))) || ((domain == Power_PER) && (newSetpoint > (Power_module->numSPPER - 1)))) { status = Power_EOUTOFRANGE; } else { /* convert requested setpoint into a mask bit */ maskSP = 1 << newSetpoint; /* go atomic */ key = Hwi_disable(); /* now check the requested SP against disallowed SP constraints */ if (domain == Power_CPU) { disallowed = maskSP & Power_module->disallowedSetpointsCPU; } else { disallowed = maskSP & Power_module->disallowedSetpointsPER; } /* if the SP is *not* disallowed, check and set the 'busy' flag */ if (disallowed == 0) { if (Power_module->busy == FALSE) { Power_module->busy = TRUE; proceed = TRUE; } else { status = Power_EBUSY; } } else { status = Power_ENOTSUPPORTED; } /* end ATOMIC */ Hwi_restore(key); if (proceed == TRUE) { /* determine PSCL clock ID */ clk = (PSCL_ClkID) domain == Power_CPU ? PSCL_CPU_CLK : PSCL_PER_CLK; /* disable Task scheduling; allow Swi & Hwi for completion */ taskKey = Task_disable(); /* set flag for domain to be notified for SP change */ if (domain == Power_CPU) { notifyCPU = TRUE; } else { notifyPER = TRUE; } /* if voltage scaling enabled, call to PSCL to see if this setpoint change will result in a voltage change; if yes, then must notify for other clk domain too, as there will be a voltage scale even though that clk frequency isn't changing */ if (Power_module->currentConfig.scaleVoltage == TRUE) { PSCL_queryWillChangeVoltage(clk, newSetpoint, &willChange); if (willChange == TRUE) { if (domain == Power_CPU) { notifyPER = TRUE; } else { notifyCPU = TRUE; } } } /* now send any pre-notifications for CPU domain */ if (notifyCPU == TRUE) { /* set nextSP to indicate the pending setpoint */ if (domain == Power_CPU) { Power_module->nextSP = newSetpoint; /* yes, new setpoint */ previousSP = Power_module->currentSetpointCPU; } else { /* not new CPU setpoint */ Power_module->nextSP = Power_module->currentSetpointCPU; previousSP = Power_module->currentSetpointCPU; } /* notify clients registered for pre CPU SP notification */ statusNotifyCPU = Power_notify(Power_PENDING_CPU_SETPOINTCHANGE, notifyTimeout, Power_SigType_INTERNAL, NULL, NULL); } /* now send any pre-notifications for PER domain */ if ((statusNotifyCPU == Power_SOK) && (notifyPER == TRUE)) { /* set nextSPPER to indicate the pending setpoint */ if (domain == Power_CPU) { /* not new PER SP */ Power_module->nextSPPER = Power_module->currentSetpointPER; previousSPPER = Power_module->currentSetpointPER; } else { Power_module->nextSPPER = newSetpoint; /* yes, new PER SP */ previousSPPER = Power_module->currentSetpointPER; } /* notify clients registered for pre PER SP notification */ statusNotifyPER = Power_notify(Power_PENDING_PER_SETPOINTCHANGE, notifyTimeout, Power_SigType_INTERNAL, NULL, NULL); } /* if all 'pre' notifications succeeded... do the scaling op */ if ((statusNotifyCPU == Power_SOK) && (statusNotifyPER == Power_SOK)) { swiKey = Swi_disable(); /* call to PSCL to change the setpoint */ statusPSCL = PSCL_changeSetpoint(clk, newSetpoint, Power_module->currentConfig.scaleVoltage, Power_module->currentConfig.waitForVoltageScale,NULL,NULL); Swi_restore(swiKey); } /* if scaling operation successful... */ if (statusPSCL == PSCL_OK) { /* update previous and current SP globals */ if (notifyCPU == TRUE) { Power_module->currentSetpointCPU = Power_module->nextSP; Power_module->previousSP = previousSP; } if (notifyPER == TRUE) { Power_module->currentSetpointPER = Power_module->nextSPPER; Power_module->previousSPPER = previousSPPER; } /* if scaled the CPU frequency... tell BIOS about it */ if (domain == Power_CPU) { Power_getSetpointInfo(Power_CPU, newSetpoint, &frequency, &voltage); cpuFreq.lo = frequency * 1000; /* convert kHz to Hz */ cpuFreq.hi = 0; BIOS_setCpuFreq(&cpuFreq); } /* now notify post-notification clients */ if (notifyCPU == TRUE) { /* notify clients registered of post CPU SP change */ statusNotifyCPU = Power_notify(Power_DONE_CPU_SETPOINTCHANGE, notifyTimeout, Power_SigType_INTERNAL, NULL, NULL); } if ((statusNotifyCPU == Power_SOK) && (notifyPER == TRUE)) { /* notify clients registered of post PER SP change */ statusNotifyPER = Power_notify(Power_DONE_PER_SETPOINTCHANGE, notifyTimeout, Power_SigType_INTERNAL, NULL, NULL); } } /* done, so clear Power busy flag */ Power_module->busy = FALSE; /* resume Tasking */ Task_restore(taskKey); /* figure out return code */ if (statusPSCL == PSCL_INVALID_SETPOINT) { status = Power_EOUTOFRANGE; /* invalid SP according to PSCL */ } else if ((statusNotifyCPU == Power_ETIMEOUT) || (statusNotifyPER == Power_ETIMEOUT) ) { status = Power_ETIMEOUT; /* notification timeout */ } else if ((status != Power_SOK) || (statusPSCL != PSCL_OK)) { status = Power_EFAIL; /* convert to 'general failure' */ } } } return (status); }
/* * ======== Power_sleepDSP ======== */ Power_Status Power_sleepDSP(UInt sleepCode, UInt sleepArg, UInt notifyTimeout) { Power_Status status = Power_SOK; Bool exitNow = FALSE; Power_Event preEvent; Power_Event postEvent; PMI_Sleep sleepMode; UInt taskKey; UInt swiKey; UInt hwiKey; /* first validate the sleep code */ if ( (sleepCode != Power_STANDBY) && (sleepCode != Power_SLEEP) && (sleepCode != Power_DEEPSLEEP) ) { status = Power_ENOTIMPLEMENTED; } /* make sure sleep request doesn't violate a registered constraint */ else if ( ( (sleepCode == Power_STANDBY) && ((Power_module->disallowedSleepModes & Power_STANDBY) != 0) ) || ( (sleepCode == Power_SLEEP) && ((Power_module->disallowedSleepModes & Power_SLEEP) != 0) ) || ( (sleepCode == Power_DEEPSLEEP) && ((Power_module->disallowedSleepModes & Power_DEEPSLEEP) != 0))) { status = Power_ENOTSUPPORTED; } /* check for valid sleepArg */ else if (sleepCode == Power_DEEPSLEEP) { if ((sleepArg != Power_EXTERNAL) && (sleepArg != Power_RTC_ALARM)) { status = Power_EINVALIDVALUE; } } if (status == Power_SOK) { /* make sure Power is not still busy with a previous transition */ hwiKey = Hwi_disable(); if (Power_module->busy == FALSE) { Power_module->busy = TRUE; } else { exitNow = TRUE; } Hwi_restore(hwiKey); if (exitNow == TRUE) { status = Power_EBUSY; } else { /* setup sleep vars */ if (sleepCode == Power_STANDBY) { preEvent = Power_GOINGTOSTANDBY; postEvent = Power_AWAKEFROMSTANDBY; sleepMode = PMI_STANDBY; } else if (sleepCode == Power_SLEEP) { preEvent = Power_GOINGTOSLEEP; postEvent = Power_AWAKEFROMSLEEP; sleepMode = PMI_SLEEP; } else { preEvent = Power_GOINGTODEEPSLEEP; postEvent = Power_AWAKEFROMDEEPSLEEP; sleepMode = PMI_DEEPSLEEP; } /* disable Task scheduling; allow Swis and Hwis for notifications */ taskKey = Task_disable(); /* signal all clients registered for pre-sleep notification */ status = Power_notify(preEvent, notifyTimeout, Power_SigType_INTERNAL, NULL, NULL); /* check for timeout or any other error */ if (status != Power_SOK) { Power_module->busy = FALSE; /* clear busy */ Task_restore(taskKey); /* re-enable scheduler */ return (status); } /* now disable Swi scheduling */ swiKey = Swi_disable(); /* start the sleep sequence */ hwiKey = Hwi_disable(); /* call to PMI to go to and wake from sleep... */ PMI_sleepCPU(sleepMode, Power_module->currentConfig.scaleVoltage, (UInt) sleepArg); /* when get here CPU has already processed the wakeup interrupt */ /* restore the previous interrupt enable state */ Hwi_restore(hwiKey); /* re-enable Swi scheduling */ Swi_restore(swiKey); /* signal all clients registered for post-sleep notification */ status = Power_notify(postEvent, notifyTimeout, Power_SigType_INTERNAL, NULL, NULL); /* now clear the busy flag before re-enabling scheduler */ Power_module->busy = FALSE; /* re-enable Task scheduling */ Task_restore(taskKey); /* check for timeout or other notification error */ if (status != Power_SOK) { return (status); } } } return (status); }
/* * ======== Power_suspend ======== */ UInt Power_suspend(Power_Suspend level) { Bool l1CacheEnabled; Bool l2CacheEnabled; UInt32 *wordPtr; UInt32 taskKey; UInt32 swiKey; UInt32 hwiKey; UInt32 reset; UInt32 tmp1; UInt32 tmp2; UInt32 i; /* disable interrupts */ hwiKey = Hwi_disable(); /* disable scheduling */ taskKey = Task_disable(); swiKey = Swi_disable(); /* check Unicache state; set 'enabled' flags */ l1CacheEnabled = Cache_cache.L1_CONFIG & 0x2; l2CacheEnabled = Cache_cache.L2_CONFIG & 0x2; #if _VERBOSE_ System_printf("Power_suspend\n"); System_printf(" suspend level = 0x%x\n", level); System_printf(" subsystem context = 0x%x\n", &ssContext); System_printf(" CPU context = 0x%x\n", &ti_sysbios_family_c64p_tesla_Power_cpuRegs); System_printf(" CPU sys regs = 0x%x\n", &ssContext.cpuSysRegs); System_printf(" INTC context = 0x%x\n", &ssContext.configINTC); System_printf(" SYSC context = 0x%x\n", &ssContext.configSYSC); System_printf(" AMMU context = 0x%x\n", &ssContext.configAMMU); System_printf(" EDMA context = 0x%x\n", &ssContext.configEDMA); System_printf(" TSC flag = 0x%x\n", &ssContext.tscRunning); System_printf(" L1 context = 0x%x\n", &ssContext.configL1); System_printf(" L1 enabled = 0x%x\n", l1CacheEnabled); System_printf(" L2 context = 0x%x\n", &ssContext.configL2); System_printf(" L2 enabled = 0x%x\n", l2CacheEnabled); #endif /* = = = = = = = = */ /* if HIBERNATE: save Tesla subsystem context ... */ if (level == Power_Suspend_HIBERNATE) { /* save Unicache config context */ ssContext.configL1.CONFIG = (UInt32) Cache_cache.L1_CONFIG; ssContext.configL1.OCP = (UInt32) Cache_cache.L1_OCP; ssContext.configL2.CONFIG = (UInt32) Cache_cache.L2_CONFIG; ssContext.configL2.OCP = (UInt32) Cache_cache.L2_OCP; /* = = = = = = = = */ /* save AMMU context */ for (i = 0; i < AMMU_numLargePages; i++) { ssContext.configAMMU.largeAddr[i] = (UInt32) AMMU_mmu.LARGE_ADDR[i]; ssContext.configAMMU.largePolicy[i] = (UInt32) AMMU_mmu.LARGE_POLICY[i]; } for (i = 0; i < AMMU_numMediumPages; i++) { ssContext.configAMMU.medAddr[i] = (UInt32) AMMU_mmu.MEDIUM_ADDR[i]; ssContext.configAMMU.medPolicy[i] = (UInt32) AMMU_mmu.MEDIUM_POLICY[i]; } for (i = 0; i < AMMU_numSmallPages; i++) { ssContext.configAMMU.smallAddr[i] = (UInt32) AMMU_mmu.SMALL_ADDR[i]; ssContext.configAMMU.smallPolicy[i] = (UInt32) AMMU_mmu.SMALL_POLICY[i]; } /* = = = = = = = = */ /* save SYSC context */ ssContext.configSYSC.SYSCONFIG = REG((UInt32)Power_syscRegs + SYSCONFIG_REG_OFFSET); ssContext.configSYSC.VBUSM2OCP = REG((UInt32)Power_syscRegs + VBUSM2OCP_REG_OFFSET); ssContext.configSYSC.EDMA = REG((UInt32)Power_syscRegs + EDMA_REG_OFFSET); ssContext.configSYSC.CORE = REG((UInt32)Power_syscRegs + CORE_REG_OFFSET); ssContext.configSYSC.IVA_ICTRL = REG((UInt32)Power_syscRegs + IVA_ICTRL_REG_OFFSET); ssContext.configSYSC.IDLEDLY = REG((UInt32)Power_syscRegs + IDLEDLY_REG_OFFSET); /* = = = = = = = = */ /* save INTC context */ ssContext.configINTC.EVTMASK0 = REG(EVTMASK0_REG); ssContext.configINTC.EVTMASK1 = REG(EVTMASK1_REG); ssContext.configINTC.EVTMASK2 = REG(EVTMASK2_REG); ssContext.configINTC.EVTMASK3 = REG(EVTMASK3_REG); ssContext.configINTC.EXPMASK0 = REG(EXPMASK0_REG); ssContext.configINTC.EXPMASK1 = REG(EXPMASK1_REG); ssContext.configINTC.EXPMASK2 = REG(EXPMASK2_REG); ssContext.configINTC.EXPMASK3 = REG(EXPMASK3_REG); ssContext.configINTC.INTMUX1 = REG(INTMUX1_REG); ssContext.configINTC.INTMUX2 = REG(INTMUX2_REG); ssContext.configINTC.INTMUX3 = REG(INTMUX3_REG); ssContext.configINTC.AEGMUX0 = REG(AEGMUX0_REG); ssContext.configINTC.AEGMUX1 = REG(AEGMUX1_REG); ssContext.configINTC.INTDMASK = REG(INTDMASK_REG); /* = = = = = = = = */ /* save EDMA context */ ssContext.configEDMA.CLKGDIS = REG((UInt32)Power_tpccRegs + CLKGDIS_REG_OFFSET); /* save DMA chan to PARAM mapping registers */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + DCHMAP0_REG_OFFSET); for (i = 0; i < 64; i++) { ssContext.configEDMA.DCHMAP[i] = *wordPtr++; } /* save QDMA chan to PARAM mapping registers */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + QCHMAP0_REG_OFFSET); for (i = 0; i < 8; i++) { ssContext.configEDMA.QCHMAP[i] = *wordPtr++; } /* save DMA queue mapping registers */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + DMAQNUM0_REG_OFFSET); for (i = 0; i < 8; i++) { ssContext.configEDMA.DMAQNUM[i] = *wordPtr++; } ssContext.configEDMA.QDMAQNUM = REG((UInt32)Power_tpccRegs + QDMAQNUM_REG_OFFSET); ssContext.configEDMA.QUETCMAP = REG((UInt32)Power_tpccRegs + QUETCMAP_REG_OFFSET); ssContext.configEDMA.QUEPRI = REG((UInt32)Power_tpccRegs + QUEPRI_REG_OFFSET); /* save DMA and QDMA region access enable bits */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + DRAEM0_REG_OFFSET); for (i = 0; i < (8 * 3); i++) { ssContext.configEDMA.regionAccessBits[i] = *wordPtr++; } ssContext.configEDMA.QWMTHRA = REG((UInt32)Power_tpccRegs + QWMTHRA_REG_OFFSET); ssContext.configEDMA.AETCTL = REG((UInt32)Power_tpccRegs + AETCTL_REG_OFFSET); ssContext.configEDMA.IER = REG((UInt32)Power_tpccRegs + IER_REG_OFFSET); ssContext.configEDMA.IERH = REG((UInt32)Power_tpccRegs + IERH_REG_OFFSET); ssContext.configEDMA.QEER = REG((UInt32)Power_tpccRegs + QEER_REG_OFFSET); /* bulk save of all PaRAMs (8 regs * 128 PaRAMs */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + OPT0_REG_OFFSET); for (i = 0; i < (8 * 128); i++) { ssContext.configEDMA.PaRAMs[i] = *wordPtr++; } /* = = = = = = = = */ /* save CPU control registers */ ssContext.cpuSysRegs.AMR = AMR; ssContext.cpuSysRegs.CSR = CSR; ssContext.cpuSysRegs.IER = IER; ssContext.cpuSysRegs.ISTP = ISTP; ssContext.cpuSysRegs.IRP = IRP; ssContext.cpuSysRegs.SSR = SSR; ssContext.cpuSysRegs.GPLYB = GPLYB; ssContext.cpuSysRegs.GFPGFR = GFPGFR; ssContext.cpuSysRegs.TSR = TSR; ssContext.cpuSysRegs.ITSR = ITSR; ssContext.cpuSysRegs.IERR = IERR; } /* sample and set the 'TSC is running' state flag */ tmp1 = TSCL; tmp2 = TSCL; if (tmp1 == tmp2) { ssContext.tscRunning = 0; } else { ssContext.tscRunning = 1; } /* if Unicache enabled, prepare for standby ... */ if (l1CacheEnabled || l2CacheEnabled) { /* if HIBERNATE: write back all for L1 and L2 */ if (level == Power_Suspend_HIBERNATE) { Cache_wbAll(); } /* else, retention, just clean the write buffers */ else { Cache_wb(0, 0, Cache_Type_ALL, TRUE);/* start=end=0 -> clean bufs */ } /* now bypass the caches... */ if (l1CacheEnabled) { Cache_disable(Cache_Type_L1); } if (l2CacheEnabled) { Cache_disable(Cache_Type_L2); } } /* set reset-function-sampled 'doing a resume' flag */ ti_sysbios_family_c64p_tesla_Power_doResume = 1; /* set the ready-to-standby flag (an FYI for the MPU) */ ti_sysbios_family_c64p_tesla_Power_readyIdle = 1; /* setup PDC to put GEM into standby when execute IDLE */ REG(PDCCMD_REG) = PDCCMD_STANDBY; REG(PDCCMD_REG); /* make function call to save child-preserved CPU regs and do standby ... */ reset = ti_sysbios_family_c64p_tesla_Power_standby( &ti_sysbios_family_c64p_tesla_Power_cpuRegs); /* = = = = = = = = */ /* NOTE: return here both when woke from IDLE, or resumed after reset */ /* = = = = = = = = */ /* note: this symbol is not used, but is defined for debug purposes only */ asm(" .global ti_sysbios_family_c64p_tesla_Power_suspend_RESUME"); asm("ti_sysbios_family_c64p_tesla_Power_suspend_RESUME:"); /* if HIBERNATE and *did* reset: restore all context ... */ if ((reset != 0) && (level == Power_Suspend_HIBERNATE)) { /* restore CPU control registers */ AMR = ssContext.cpuSysRegs.AMR; CSR = ssContext.cpuSysRegs.CSR; IER = ssContext.cpuSysRegs.IER; ISTP = ssContext.cpuSysRegs.ISTP; IRP = ssContext.cpuSysRegs.IRP; SSR = ssContext.cpuSysRegs.SSR; GPLYB = ssContext.cpuSysRegs.GPLYB; GFPGFR = ssContext.cpuSysRegs.GFPGFR; TSR = ssContext.cpuSysRegs.TSR; ITSR = ssContext.cpuSysRegs.ITSR; IERR = ssContext.cpuSysRegs.IERR; /* = = = = = = = = */ /* restore AMMU configuration */ for (i = 0; i < AMMU_numLargePages; i++) { AMMU_mmu.LARGE_ADDR[i] = (Char *) ssContext.configAMMU.largeAddr[i]; AMMU_mmu.LARGE_POLICY[i] = ssContext.configAMMU.largePolicy[i]; } for (i = 0; i < AMMU_numMediumPages; i++) { AMMU_mmu.MEDIUM_ADDR[i] = (Char *) ssContext.configAMMU.medAddr[i]; AMMU_mmu.MEDIUM_POLICY[i] = ssContext.configAMMU.medPolicy[i]; } for (i = 0; i < AMMU_numSmallPages; i++) { AMMU_mmu.SMALL_ADDR[i] = (Char *) ssContext.configAMMU.smallAddr[i]; AMMU_mmu.SMALL_POLICY[i] = ssContext.configAMMU.smallPolicy[i]; } /* = = = = = = = = */ /* restore Unicache config */ Cache_cache.L1_OCP = ssContext.configL1.OCP; tmp1 = Cache_cache.L1_OCP; /* read to ensure posted write done */ Cache_cache.L1_CONFIG = ssContext.configL1.CONFIG; tmp1 = Cache_cache.L1_CONFIG; /* read to ensure posted write done */ Cache_cache.L2_OCP = ssContext.configL2.OCP; tmp1 = Cache_cache.L2_OCP; /* read to ensure posted write done */ Cache_cache.L2_CONFIG = ssContext.configL2.CONFIG; tmp1 = Cache_cache.L2_CONFIG; /* read to ensure posted write done */ /* = = = = = = = = */ /* restore SYSC context */ REG((UInt32)Power_syscRegs + SYSCONFIG_REG_OFFSET) = ssContext.configSYSC.SYSCONFIG; REG((UInt32)Power_syscRegs + VBUSM2OCP_REG_OFFSET) = ssContext.configSYSC.VBUSM2OCP; REG((UInt32)Power_syscRegs + EDMA_REG_OFFSET) = ssContext.configSYSC.EDMA; REG((UInt32)Power_syscRegs + CORE_REG_OFFSET) = ssContext.configSYSC.CORE; REG((UInt32)Power_syscRegs + IVA_ICTRL_REG_OFFSET) = ssContext.configSYSC.IVA_ICTRL; REG((UInt32)Power_syscRegs + IDLEDLY_REG_OFFSET) = ssContext.configSYSC.IDLEDLY; /* = = = = = = = = */ /* restore INTC context */ REG(EVTMASK0_REG) = ssContext.configINTC.EVTMASK0; REG(EVTMASK1_REG) = ssContext.configINTC.EVTMASK1; REG(EVTMASK2_REG) = ssContext.configINTC.EVTMASK2; REG(EVTMASK3_REG) = ssContext.configINTC.EVTMASK3; REG(EXPMASK0_REG) = ssContext.configINTC.EXPMASK0; REG(EXPMASK1_REG) = ssContext.configINTC.EXPMASK1; REG(EXPMASK2_REG) = ssContext.configINTC.EXPMASK2; REG(EXPMASK3_REG) = ssContext.configINTC.EXPMASK3; REG(INTMUX1_REG) = ssContext.configINTC.INTMUX1; REG(INTMUX2_REG) = ssContext.configINTC.INTMUX2; REG(INTMUX3_REG) = ssContext.configINTC.INTMUX3; REG(AEGMUX0_REG) = ssContext.configINTC.AEGMUX0; REG(AEGMUX1_REG) = ssContext.configINTC.AEGMUX1; REG(INTDMASK_REG) = ssContext.configINTC.INTDMASK; /* = = = = = = = = */ /* restore EDMA context */ REG((UInt32)Power_tpccRegs + CLKGDIS_REG_OFFSET) = ssContext.configEDMA.CLKGDIS; /* restore DMA chan to PARAM mapping registers */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + DCHMAP0_REG_OFFSET); for (i = 0; i < 64; i++) { *wordPtr++ = ssContext.configEDMA.DCHMAP[i]; } /* restore QDMA chan to PARAM mapping registers */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + QCHMAP0_REG_OFFSET); for (i = 0; i < 8; i++) { *wordPtr++ = ssContext.configEDMA.QCHMAP[i]; } /* restore DMA queue mapping registers */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + DMAQNUM0_REG_OFFSET); for (i = 0; i < 8; i++) { *wordPtr++ = ssContext.configEDMA.DMAQNUM[i]; } REG((UInt32)Power_tpccRegs + QDMAQNUM_REG_OFFSET) = ssContext.configEDMA.QDMAQNUM; REG((UInt32)Power_tpccRegs + QUETCMAP_REG_OFFSET) = ssContext.configEDMA.QUETCMAP; REG((UInt32)Power_tpccRegs + QUEPRI_REG_OFFSET) = ssContext.configEDMA.QUEPRI; /* restore DMA and QDMA region access enable bits */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + DRAEM0_REG_OFFSET); for (i = 0; i < (8 * 3); i++) { *wordPtr++ = ssContext.configEDMA.regionAccessBits[i]; } REG((UInt32)Power_tpccRegs + QWMTHRA_REG_OFFSET) = ssContext.configEDMA.QWMTHRA; REG((UInt32)Power_tpccRegs + AETCTL_REG_OFFSET) = ssContext.configEDMA.AETCTL; /* restore interrupt enable registers (using IESR and IESRH) */ REG((UInt32)Power_tpccRegs + IESR_REG_OFFSET) = ssContext.configEDMA.IER; REG((UInt32)Power_tpccRegs + IESRH_REG_OFFSET) = ssContext.configEDMA.IERH; /* restore QDMA event enable register (using QEESR) */ REG((UInt32)Power_tpccRegs + QEESR_REG_OFFSET) = ssContext.configEDMA.QEER; /* restore all PaRAMs (8 regs * 128 PaRAMs */ wordPtr = (UInt32 *)((UInt32)Power_tpccRegs + OPT0_REG_OFFSET); for (i = 0; i < (8 * 128); i++) { *wordPtr++ = ssContext.configEDMA.PaRAMs[i]; } #if _VERBOSE_ System_printf("hibernate: restored context\n"); #endif } /* Else: Restore caches to their pre-standby enable state. * Note: When come out of retention reset caches will always be enabled, * even if they weren't enabled before standby. So, need to disable * them now, if they weren't enabled when suspend was invoked. */ else { /* restore the enabled state of the caches ... */ if (l1CacheEnabled) { Cache_enable(Cache_Type_L1); } else { Cache_disable(Cache_Type_L1); } if (l2CacheEnabled) { Cache_enable(Cache_Type_L2); } else { Cache_disable(Cache_Type_L2); } } #if _VERBOSE_ System_printf("reset flag = %d\n", reset); #endif /* if TSC was enabled on entry: start it again */ if (ssContext.tscRunning == 1) { TSCL = 1; /* write any value to TSC to kick start it */ } /* clear the ready-to-standby flag */ ti_sysbios_family_c64p_tesla_Power_readyIdle = 0; /* clear the reset-sampled 'do resume' flag */ ti_sysbios_family_c64p_tesla_Power_doResume = 0; /* re-enable scheduling */ Task_restore(taskKey); Swi_restore(swiKey); /* re-enable interrupts */ Hwi_restore(hwiKey); return (reset); }
/* * ======== Power_sleep ======== */ Power_Status Power_sleep(Power_SleepState sleepState, UArg arg0, UArg arg1) { Power_Status status = Power_SOK; UInt xosc_hf_active = FALSE; Power_Event postEventLate; UInt32 poweredDomains = 0; Bool exitNow = FALSE; Power_Event preEvent; Power_Event postEvent; UInt32 constraints; Bool retainCache = FALSE; UInt32 modeVIMS; UInt taskKey; UInt swiKey; UInt hwiKey; /* first validate the sleep code */ if ( sleepState != Power_STANDBY) { status = Power_EFAIL; } if (status == Power_SOK) { /* make sure Power is not still busy with a previous transition */ hwiKey = Hwi_disable(); if (Power_module->state == Power_ACTIVE) { /* set transition state to entering sleep */ Power_module->state = Power_ENTERING_SLEEP; } else { exitNow = TRUE; } Hwi_restore(hwiKey); if (exitNow == TRUE) { status = Power_EBUSY; } else { /* setup sleep vars */ if (sleepState == Power_STANDBY) { preEvent = Power_ENTERING_STANDBY; postEvent = Power_AWAKE_STANDBY; postEventLate = Power_AWAKE_STANDBY_LATE; } /* disable Task scheduling; allow Swis and Hwis for notifications */ taskKey = Task_disable(); /* signal all clients registered for pre-sleep notification */ status = Power_notify(preEvent); /* check for any error */ if (status != Power_SOK) { Power_module->state = Power_ACTIVE; Task_restore(taskKey); /* re-enable scheduler */ return (status); } /* now disable Swi scheduling */ swiKey = Swi_disable(); /* freeze the IOs on the boundary between MCU and AON */ AONIOCFreezeEnable(); /* if XOSC_HF is active, force it off */ if(OSCClockSourceGet(OSC_SRC_CLK_HF) == OSC_XOSC_HF) { xosc_hf_active = TRUE; ti_sysbios_family_arm_cc26xx_Power_XOSC_HF(DISABLE); } /* allow AUX to power down */ AONWUCAuxWakeupEvent(AONWUC_AUX_ALLOW_SLEEP); /* make sure writes take effect */ SysCtrlAonSync(); /* invoke specific sequences to activate sleep states... */ if (sleepState == Power_STANDBY) { /* query and save domain states before powering them off */ if (Power_getDependencyCount(DOMAIN_RFCORE)) { poweredDomains |= PRCM_DOMAIN_RFCORE; } if (Power_getDependencyCount(DOMAIN_SERIAL)){ poweredDomains |= PRCM_DOMAIN_SERIAL; } if (Power_getDependencyCount(DOMAIN_PERIPH)) { poweredDomains |= PRCM_DOMAIN_PERIPH; } /* gate running deep sleep clocks for Crypto and DMA */ if (Power_getDependencyCount(PERIPH_CRYPTO)) { PRCMPeripheralDeepSleepDisable( ti_sysbios_family_arm_cc26xx_Power_db[ PERIPH_CRYPTO].driverlibID); } if (Power_getDependencyCount(PERIPH_UDMA)) { PRCMPeripheralDeepSleepDisable( ti_sysbios_family_arm_cc26xx_Power_db[ PERIPH_UDMA].driverlibID); } /* make sure clock settings take effect */ PRCMLoadSet(); /* request power off of domains in the MCU voltage domain */ PRCMPowerDomainOff(poweredDomains | PRCM_DOMAIN_CPU); /* request uLDO during standby */ PRCMMcuUldoConfigure(true); /* query constraints to determine if cache should be retained */ constraints = Power_getConstraintInfo(); if ((constraints & Power_SB_VIMS_CACHE_RETAIN) != 0) { retainCache = TRUE; } /* if don't want retention in standby, disable it now ... */ if (retainCache == FALSE) { modeVIMS = VIMSModeGet(VIMS_BASE); /* wait if invalidate in progress... */ while (modeVIMS == VIMS_MODE_CHANGING) { modeVIMS = VIMSModeGet(VIMS_BASE); } PRCMCacheRetentionDisable(); VIMSModeSet(VIMS_BASE, VIMS_MODE_OFF); } /* setup recharge parameters */ SysCtrlSetRechargeBeforePowerDown(XoscInHighPowerMode); /* make sure all writes have taken effect */ SysCtrlAonSync(); /* invoke deep sleep to go to STANDBY */ PRCMDeepSleep(); /* if didn't retain cache in standby, re-enable retention now */ if (retainCache == FALSE) { VIMSModeSet(VIMS_BASE, modeVIMS); PRCMCacheRetentionEnable(); } /* force power on of AUX to keep it on when system is not * sleeping; this also counts as a write to the AON interface * ensuring that a following sync of the AON interface will * force an update of all registers */ AONWUCAuxWakeupEvent(AONWUC_AUX_WAKEUP); while(!(AONWUCPowerStatusGet() & AONWUC_AUX_POWER_ON)) {}; /* if XOSC_HF was forced off above, initiate switch back */ if (xosc_hf_active == TRUE) { ti_sysbios_family_arm_cc26xx_Power_XOSC_HF(ENABLE); } /* restore power domain states in effect before standby */ PRCMPowerDomainOn(poweredDomains); while (PRCMPowerDomainStatus(poweredDomains) != PRCM_DOMAIN_POWER_ON){}; /* restore deep sleep clocks of Crypto and DMA */ if (Power_getDependencyCount(PERIPH_CRYPTO)) { PRCMPeripheralDeepSleepEnable( ti_sysbios_family_arm_cc26xx_Power_db[ PERIPH_CRYPTO].driverlibID); } if (Power_getDependencyCount(PERIPH_UDMA)) { PRCMPeripheralDeepSleepEnable( ti_sysbios_family_arm_cc26xx_Power_db[ PERIPH_UDMA].driverlibID); } /* make sure clock settings take effect */ PRCMLoadSet(); } /* release request for uLDO */ PRCMMcuUldoConfigure(false); /* set transition state to EXITING_SLEEP */ Power_module->state = Power_EXITING_SLEEP; /* * signal clients registered for early post-sleep notification; * this should be used to initialize any timing critical or IO * dependent hardware */ status = Power_notify(postEvent); /* disable IO freeze and ensure RTC shadow value is updated */ AONIOCFreezeDisable(); SysCtrlAonSync(); /* re-enable interrupts */ CPUcpsie(); /* signal all clients registered for late post-sleep notification */ status = Power_notify(postEventLate); /* now clear the transition state before re-enabling scheduler */ Power_module->state = Power_ACTIVE; /* re-enable Swi scheduling */ Swi_restore(swiKey); /* adjust recharge parameters */ SysCtrlAdjustRechargeAfterPowerDown(); /* re-enable Task scheduling */ Task_restore(taskKey); /* check for any notification error */ if (status != Power_SOK) { return (status); } } } return (status); }
/* * ======== PowerMSP432_policyFxn ======== */ void PowerMSP432_policyFxn() { UInt constraints; Bool slept = false; UInt taskKey; UInt swiKey; /* disable interrupts */ CPU_cpsid(); /* disable Swi and Task scheduling */ swiKey = Swi_disable(); taskKey = Task_disable(); /* query the declared constraints */ constraints = Power_getConstraintMask(); /* * Check if can go to a sleep state, starting with the deepest level. * Do not go to a sleep state if a lesser sleep state is disallowed. */ /* check if can go to DEEPSLEEP_1 */ if ((constraints & ((1 << PowerMSP432_DISALLOW_SLEEP) | (1 << PowerMSP432_DISALLOW_DEEPSLEEP_0) | (1 << PowerMSP432_DISALLOW_DEEPSLEEP_1))) == 0) { /* go to DEEPSLEEP_1 */ Power_sleep(PowerMSP432_DEEPSLEEP_1); /* set 'slept' to true*/ slept = true; } /* if didn't sleep yet, now check if can go to DEEPSLEEP_0 */ if (!slept && ((constraints & ((1 << PowerMSP432_DISALLOW_SLEEP) | (1 << PowerMSP432_DISALLOW_DEEPSLEEP_0))) == 0)) { /* go to DEEPSLEEP_0 */ Power_sleep(PowerMSP432_DEEPSLEEP_0); /* set 'slept' to true*/ slept = true; } /* if didn't sleep yet, now check if can go to SLEEP */ if (!slept && ((constraints & (1 << PowerMSP432_DISALLOW_SLEEP)) == 0)) { /* go to SLEEP */ Power_sleep(PowerMSP432_SLEEP); /* set 'slept' to true*/ slept = true; } /* re-enable interrupts */ CPU_cpsie(); /* restore Swi scheduling */ Swi_restore(swiKey); /* restore Task scheduling */ Task_restore(taskKey); /* if didn't sleep yet, just do WFI */ if (!slept) { __asm(" wfi"); } }
/* * ======== PowerMSP432_schedulerRestore ======== */ void PowerMSP432_schedulerRestore() { Swi_restore(PowerMSP432_swiKey); Task_restore(PowerMSP432_taskKey); }
/* * ======== Swi_enable ======== */ Void Swi_enable() { Swi_restore(FALSE); }