예제 #1
0
/*********************************************************************
 * @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);
  }
}
예제 #2
0
/*
 *  ======== 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());
    }
}
예제 #3
0
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;
}
예제 #4
0
/*********************************************************************
 * @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);
}
예제 #5
0
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();
    }
}