/********************************************************************* * @fn Util_rescheduleClock * * @brief Reschedule a clock by changing the timeout and period values. * * @param pClock - pointer to clock struct * @param clockPeriod - longevity of clock timer in milliseconds * @return none */ void Util_rescheduleClock(Clock_Struct *pClock, uint32_t clockPeriod) { bool running; uint32_t clockTicks; Clock_Handle handle; handle = Clock_handle(pClock); running = Clock_isActive(handle); if (running) { Clock_stop(handle); } // Convert period in milliseconds to ticks. clockTicks = clockPeriod * (1000 / Clock_tickPeriod); Clock_setTimeout(handle, clockTicks); Clock_setPeriod(handle, clockTicks); if (running) { Clock_start(handle); } }
/* * ======== Power_LF_clockFunc ======== */ Void Power_LF_clockFunc(UArg arg) { UInt32 sourceLF; /* query LF clock source */ sourceLF = OSCClockSourceGet(OSC_SRC_CLK_LF); /* is LF source either RCOSC_LF or XOSC_LF yet? */ if ((sourceLF == OSC_RCOSC_LF) || (sourceLF == OSC_XOSC_LF)) { /* yes, disable the LF clock qualifiers */ DDI16BitfieldWrite( AUX_DDI0_OSC_BASE, DDI_0_OSC_O_CTL0, DDI_0_OSC_CTL0_BYPASS_XOSC_LF_CLK_QUAL_M| DDI_0_OSC_CTL0_BYPASS_RCOSC_LF_CLK_QUAL_M, DDI_0_OSC_CTL0_BYPASS_RCOSC_LF_CLK_QUAL_S, 0x3 ); /* now finish by releasing the standby disallow constraint */ Power_releaseConstraint(Power_SB_DISALLOW); } /* not yet, LF still derived from HF, restart clock to check back later */ else { /* retrigger LF Clock to fire in 100 msec */ Clock_setTimeout( ti_sysbios_family_arm_cc26xx_Power_Module_State_lfClockObj(), (100000 / Clock_tickPeriod)); Clock_start( ti_sysbios_family_arm_cc26xx_Power_Module_State_lfClockObj()); } }
static Int32 IpcFramesInLink_reconfigPrdObj(IpcFramesInLink_Obj * pObj, UInt period) { UTILS_assert(pObj->prd.clkHandle != NULL); if (TRUE == pObj->prd.clkStarted) { Clock_stop(pObj->prd.clkHandle); } Clock_setPeriod(pObj->prd.clkHandle, 0); Clock_setTimeout(pObj->prd.clkHandle, period); Clock_start(pObj->prd.clkHandle); return IPC_FRAMES_IN_LINK_S_SUCCESS; }
/********************************************************************* * @fn Util_restartClock * * @brief Restart a clock by changing the timeout. * * @param pClock - pointer to clock struct * @param clockTimeout - longevity of clock timer in milliseconds * * @return none */ void Util_restartClock(Clock_Struct *pClock, uint32_t clockTimeout) { uint32_t clockTicks; Clock_Handle handle; handle = Clock_handle(pClock); if (Clock_isActive(handle)) { // Stop clock first Clock_stop(handle); } // Convert timeout in milliseconds to ticks. clockTicks = clockTimeout * (1000 / Clock_tickPeriod); // Set the initial timeout Clock_setTimeout(handle, clockTicks); // Start clock instance Clock_start(handle); }
static Int32 IpcFramesInLink_startPrdObj(IpcFramesInLink_Obj * pObj, UInt period, Bool oneShotMode) { UTILS_assert(pObj->prd.clkHandle != NULL); if (FALSE == pObj->prd.clkStarted) { if (TRUE == oneShotMode) { Clock_setPeriod(pObj->prd.clkHandle, 0); } else { Clock_setPeriod(pObj->prd.clkHandle, period); } Clock_setTimeout(pObj->prd.clkHandle, period); Clock_start(pObj->prd.clkHandle); pObj->prd.clkStarted = TRUE; } return IPC_FRAMES_IN_LINK_S_SUCCESS; }
/************************************************************************************************** * @fn macBackoffTimerUpdateWakeup * * @brief Recomputes and provides weakup timing hint to power module. * This function does not read timing variables in a critical * section. The caller must call this function within a critical * section where the timing variable is modified in order * to have more accurate notification. * * @param none * * @return none ************************************************************************************************** */ static void macBackoffTimerUpdateWakeup(void) { int_fast64_t ticks; /* Replicate the timer in order to inform power module to wake up properly * in case the device enters sleep state in the future. */ /* First find out which RAT channel between backoffTimerTrigger and * macBackoffTimerRollover is supposed to expire next. */ ticks = MAC_RADIO_BACKOFF_COUNT(); if (backoffTimerTrigger > ticks && backoffTimerTrigger < macBackoffTimerRollover) { ticks = backoffTimerTrigger - ticks; } else if (macBackoffTimerRollover > ticks) { ticks = macBackoffTimerRollover - ticks; } else { /* Note that current count might have exceeded already set thresholds, * as the code is executed while interrupt is flagged. * In such a case, this function shall be called again anyways and * hence this condition can be ignored. */ return; } /* TODO: For subG, backoff timer unit is not necessarily backoff period * but fixed 320us and hence the following constant * (MAC_SPEC_USECS_PER_BACKOFF) should be replaced with backoff * timer unit period in usecs. */ /* Convert backoff timer unit to RTOS tick unit */ ticks *= MAC_SPEC_USECS_PER_BACKOFF; #ifdef USE_ICALL ticks -= (MAC_BACKOFF_TIMER_ADDITIONAL_WAKEUP_LATENCY + ICall_pwrGetXOSCStartupTime(ticks/1000)); #elif defined OSAL_PORT2TIRTOS ticks -= MAC_BACKOFF_TIMER_ADDITIONAL_WAKEUP_LATENCY + Power_getXoscStartupTime(ticks/1000); #endif /* defined OSAL_PORT2TIRTOS */ if (ticks > 0) { #ifdef USE_ICALL ticks /= osal_tickperiod; #elif defined OSAL_PORT2TIRTOS ticks /= Clock_tickPeriod; #endif /* defined OSAL_PORT2TIRTOS */ } if (ticks > 0) { #ifdef USE_ICALL ICall_setTimer((uint_fast32_t) ticks, macBackoffTimerICallTimerCback, NULL, &macBackoffTimerICallTimerID); #endif /* USE_ICALL */ #ifdef OSAL_PORT2TIRTOS Clock_stop(macBackoffWakeupClock); Clock_setTimeout(macBackoffWakeupClock, (UInt32) ticks); Clock_start(macBackoffWakeupClock); #endif /* OSAL_PORT2TIRTOS */ /* Allow entering sleep state */ macBackoffTimerImpending = FALSE; #ifdef DEBUG_SW_TRACE DBG_PRINTL1(DBGSYS, "BO %u", ticks); #endif /* DEBUG_SW_TRACE */ } else { /* Timing is too close. Suppress sleep. */ macBackoffTimerImpending = TRUE; } macPwrVote(); }
/* * ======== 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(); } }