📄 mac_backoff_timer.c
字号:
* @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 + -