⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac_backoff_timer.c

📁 Zigbee2006入门源代码,包括了Zigbee的入门介绍,和源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 * @param       none
 *
 * @return      last backoff count that was captured
 **************************************************************************************************
 */
uint32 macBackoffTimerCapture(void)
{
  halIntState_t  s;
  uint32 backoffCapture;

  HAL_ENTER_CRITICAL_SECTION(s);
  backoffCapture = MAC_RADIO_BACKOFF_CAPTURE();
  HAL_EXIT_CRITICAL_SECTION(s);

#ifdef MAC_RADIO_FEATURE_HARDWARE_OVERFLOW_NO_ROLLOVER
  /*
   *  See other instance of this #ifdef for detailed comments.
   *  Those comments apply to the backoff capture value too.
   */
  if (backoffCapture >= backoffTimerRollover)
  {
    return(0);
  }
#endif
  
  return(backoffCapture);
}


/**************************************************************************************************
 * @fn          macBackoffTimerGetTrigger
 *
 * @brief       Returns the trigger set for the backoff timer.
 *
 * @param       none
 *
 * @return      backoff count of trigger
 **************************************************************************************************
 */
uint32 macBackoffTimerGetTrigger(void)
{
  return(backoffTimerTrigger);
}


/**************************************************************************************************
 * @fn          macBackoffTimerSetTrigger
 *
 * @brief       Sets the trigger count for the backoff counter.  A callback is exectuted when
 *              the backoff count reaches the trigger
 *
 * @param       triggerBackoff - backoff count for new trigger
 *
 * @return      none
 **************************************************************************************************
 */
void macBackoffTimerSetTrigger(uint32 triggerBackoff)
{
  halIntState_t  s;

  MAC_ASSERT(triggerBackoff < backoffTimerRollover); /* trigger backoff must be less than rollover backoff */

  HAL_ENTER_CRITICAL_SECTION(s);
  backoffTimerTrigger = triggerBackoff;
  if (triggerBackoff > MAC_RADIO_BACKOFF_COUNT())
  {
    compareState = COMPARE_STATE_TRIGGER;
    MAC_RADIO_BACKOFF_SET_COMPARE(triggerBackoff);
  }
  else
  {
    if (triggerBackoff == 0)
    {
      compareState = COMPARE_STATE_ROLLOVER_AND_TRIGGER;
    }
    else
    {
      compareState = COMPARE_STATE_ROLLOVER_AND_ARM_TRIGGER;
    }
    MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerRollover);
  }
  HAL_EXIT_CRITICAL_SECTION(s);
}


/**************************************************************************************************
 * @fn          macBackoffTimerCancelTrigger
 *
 * @brief       Cancels the trigger for the backoff counter.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macBackoffTimerCancelTrigger(void)
{
  halIntState_t  s;

  HAL_ENTER_CRITICAL_SECTION(s);
  compareState = COMPARE_STATE_ROLLOVER;
  MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerRollover);
  HAL_EXIT_CRITICAL_SECTION(s);
}


/**************************************************************************************************
 * @fn          macBackoffTimerRealign
 *
 * @brief       
 *
 *  Realignment is accomplished by adjusting the internal time base to align with the expected
 *  reception time of an incoming frame.  The difference between the expected reception time and
 *  the actual reception time is computed and this difference is used to adjust the hardware
 *  timer count and backoff count.
 *
 *  The realignment is based on the SFD signal for the incoming frame.  The timer is aligned
 *  by adjusting it with the difference between the expected SFD time and the actual SFD time.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
int32 macBackoffTimerRealign(macRx_t *pMsg)
{
  uint16 timerDelayTicks;
  int32 backoffDelta;
  int32 backoffCount;

  MAC_ASSERT_STATEMENT( MAC_RADIO_FORCE_TX_DONE_IF_PENDING(); ); /* force TX to complete if just pending */
  MAC_ASSERT(!MAC_TX_IS_PHYSICALLY_ACTIVE()); /* realignment during actual transmit corrupts timing */

  /*-------------------------------------------------------------------------------
   *  Calculate the delta backoff difference between expected backoff count,
   *  which is zero, and the backoff count of the received frame.
   */

  /* since expected receive time is zero, the delta is simply the receive time */
  backoffDelta = pMsg->mac.timestamp;

  /* if the frame was received more than halfway to the rollover count, use a negative delta value */
  if (((uint32) backoffDelta) > (backoffTimerRollover / 2))
  {
    backoffDelta = backoffDelta - backoffTimerRollover;    /* result will be negative */
  }

  /*-------------------------------------------------------------------------------
   *  Calculate the number of timer ticks to delay that will align the internal
   *  time base with the received frame.
   */

  /* retrieve the timer count when frame was received */
  timerDelayTicks = pMsg->mac.timestamp2;

  /*
   *  Subtract the expected SFD time from the actual SFD time to find the needed
   *  timer adjustment. If subtracting the offset would result in a negative value,
   *  the tick delay must wrap around.
   */
  if (timerDelayTicks >= TIMER_TICKS_EXPECTED_AT_SFD)
  {
    /* since delay count is greater than or equal to offset, subtract it directly */
    timerDelayTicks = timerDelayTicks - TIMER_TICKS_EXPECTED_AT_SFD;
  }
  else
  {
    /*
     *  The expected time is greater that actualy time so it cannot be subtracted directly.
     *  The tick count per backoff is added to wrap around within the backoff.
     *  Since a wrap around did happen, the backoff delta is adjusted by one.
     */
    timerDelayTicks = timerDelayTicks - TIMER_TICKS_EXPECTED_AT_SFD + MAC_RADIO_TIMER_TICKS_PER_BACKOFF();
    backoffDelta--;
  }

  /*-------------------------------------------------------------------------------
   *  Calculate the new backoff count.
   */

  backoffCount = MAC_RADIO_BACKOFF_COUNT() - backoffDelta;

  if (backoffCount >= ((int32) backoffTimerRollover))
  {
    backoffCount -= backoffTimerRollover;
  }
  else if (backoffCount < 0)
  {
    backoffCount += backoffTimerRollover;
  }

  MAC_RADIO_TIMER_FORCE_DELAY(timerDelayTicks);
  MAC_RADIO_BACKOFF_SET_COUNT(backoffCount);

  return(backoffDelta);
}


/**************************************************************************************************
 * @fn          macBackoffTimerCompareIsr
 *
 * @brief       Interrupt service routine that fires when the backoff count is equal
 *              to the trigger count.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void macBackoffTimerCompareIsr(void)
{
  uint8 oldState;
  halIntState_t  s;

  HAL_ENTER_CRITICAL_SECTION(s);
  oldState = compareState;

  /* if compare is a rollover, set count to zero */
  if (oldState & COMPARE_STATE_ROLLOVER_BV)
  {
    MAC_RADIO_BACKOFF_SET_COUNT(0);
    macBackoffTimerRolloverCallback();
  }

  /* if compare is a trigger, reset for rollover and run the trigger callback */
  if (oldState & COMPARE_STATE_TRIGGER_BV)
  {
    compareState = COMPARE_STATE_ROLLOVER;
    MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerRollover);
    HAL_EXIT_CRITICAL_SECTION(s);
    macBackoffTimerTriggerCallback();
  }
  else if (oldState == COMPARE_STATE_ROLLOVER_AND_ARM_TRIGGER)
  {
    compareState = COMPARE_STATE_TRIGGER;
    MAC_RADIO_BACKOFF_SET_COMPARE(backoffTimerTrigger);
    HAL_EXIT_CRITICAL_SECTION(s);
  }
  else
  {
    HAL_EXIT_CRITICAL_SECTION(s);
  }
}


/**************************************************************************************************
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -