/************************************************************************************************** * @fn macSleep * * @brief Puts radio into the selected sleep mode. * * @param sleepState - selected sleep level, see #defines in .h file * * @return TRUE if radio was successfully put into selected sleep mode. * FALSE if it was not safe for radio to go to sleep. ************************************************************************************************** */ uint8 macSleep(uint8 sleepState) { MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_AWAKE); /* radio must be awake to put it to sleep */ MAC_ASSERT(macRxFilter == RX_FILTER_OFF); /* do not sleep when scanning or in promiscuous mode */ MAC_ASSERT(!HAL_INTERRUPTS_ARE_ENABLED()); /* interrupts should be disabled to call this function */ /* check to see if anything would prevent sleep */ if (macRxActive || macTxActive || macRxEnableFlags) { /* sleep is not allowed */ return(FALSE); } /* put MAC timer to sleep */ MAC_RADIO_TIMER_SLEEP(); /* update sleep state variable */ macSleepState = sleepState; /* put radio in selected sleep mode */ if (sleepState == MAC_SLEEP_STATE_OSC_OFF) { MAC_RADIO_TURN_OFF_OSC(); } else { MAC_ASSERT(sleepState == MAC_SLEEP_STATE_CHIP_OFF); MAC_RADIO_TURN_OFF_VREG(); } /* radio successfully put to sleep */ return(TRUE); }
/************************************************************************************************** * @fn macRadioStartScan * * @brief Puts radio into selected scan mode. * * @param scanMode - scan mode, see #defines in .h file * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRadioStartScan(uint8 scanMode) { MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_AWAKE); /* radio must be awake */ MAC_ASSERT(macRxFilter == RX_FILTER_OFF); /* all filtering must be off to start scan */ /* set the receive filter based on the selected scan mode */ if (scanMode == MAC_SCAN_ED) { macRxFilter = RX_FILTER_ALL; } else if (scanMode == MAC_SCAN_ORPHAN) { macRxFilter = RX_FILTER_NON_COMMAND_FRAMES; } else { #ifdef FEATURE_ENHANCED_BEACON MAC_ASSERT((scanMode == MAC_SCAN_ACTIVE_ENHANCED) || (scanMode == MAC_SCAN_ACTIVE) || (scanMode == MAC_SCAN_PASSIVE)); /* invalid scan type */ #else MAC_ASSERT((scanMode == MAC_SCAN_ACTIVE) || (scanMode == MAC_SCAN_PASSIVE)); /* invalid scan type */ #endif macRxFilter = RX_FILTER_NON_BEACON_FRAMES; /* for active and passive scans, per spec the pan ID must be 0xFFFF */ MAC_RADIO_SET_PAN_ID(0xFFFF); } }
/************************************************************************************************** * @fn macBackoffTimerSetCount * * @brief Sets the count of the backoff timer. * * @param backoff - new count * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffTimerSetCount(uint32 backoff) { halIntState_t s; MAC_ASSERT(backoff < backoffTimerRollover); /* count must be less than rollover value */ MAC_ASSERT(!(backoff & 0x80000000)); /* count must not represent negative value for int32 */ HAL_ENTER_CRITICAL_SECTION(s); MAC_RADIO_BACKOFF_SET_COUNT(backoff); HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macBackoffTimerSetCount * * @brief Sets the count of the backoff timer. * * @param backoff - new count * * @return none ************************************************************************************************** */ void macBackoffTimerSetCount(uint32 backoff) { halIntState_t s; MAC_ASSERT(compareState == COMPARE_STATE_ROLLOVER); /* trigger cannot be active if changing count */ MAC_ASSERT(backoff < backoffTimerRollover); /* count must be less than rollover value */ MAC_ASSERT(!(backoff & 0x80000000)); /* count must not represent negative value for int32 */ HAL_ENTER_CRITICAL_SECTION(s); MAC_RADIO_BACKOFF_SET_COUNT(backoff); HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macBackoffTimerSetCount * * @brief Sets the count of the backoff timer. * * @param backoff - new count * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffTimerSetCount(uint32 backoff) { #if defined( FEATURE_BEACON_MODE ) halIntState_t s; MAC_ASSERT(backoff < macBackoffTimerRollover); /* count must be less than rollover value */ MAC_ASSERT(!(backoff & 0x80000000)); /* count must not represent negative value for int32 */ DBG_PRINT2(DBGSYS, "MAC_RADIO_BACKOFF_SET_COUNT(%u), RAT BACKOFF = %u", backoff, MAC_RADIO_BACKOFF_COUNT()); HAL_ENTER_CRITICAL_SECTION(s); MAC_RADIO_BACKOFF_SET_COUNT(backoff); MAC_BACKOFF_TIMER_UPDATE_WAKEUP(); HAL_EXIT_CRITICAL_SECTION(s); #endif /* FEATURE_BEACON_MODE */ }
/************************************************************************************************** * @fn macTxTimestampCallback * * @brief This callback function records the timestamp into the receive data structure. * It should be called as soon as possible after there is a valid timestamp. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macTxTimestampCallback(void) { MAC_ASSERT(pMacDataTx != NULL); /* transmit structure must be there */ pMacDataTx->internal.timestamp = macBackoffTimerCapture(); pMacDataTx->internal.timestamp2 = MAC_RADIO_TIMER_CAPTURE(); }
/************************************************************************************************** * @fn macTxTimestampCallback * * @brief - * * @param none * * @return none ************************************************************************************************** */ void macTxTimestampCallback(void) { MAC_ASSERT(pMacDataTx != NULL); /* must have data to transmit */ pMacDataTx->internal.timestamp = MAC_RADIO_BACKOFF_CAPTURE(); pMacDataTx->internal.timestamp2 = MAC_RADIO_TIMER_CAPTURE(); }
/************************************************************************************************** * @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 macSleepWakeUp * * @brief Wake up the radio from sleep mode. * * @param none * * @return none ************************************************************************************************** */ void macSleepWakeUp(void) { /* don't wake up radio if it's already awake */ if (macSleepState == MAC_SLEEP_STATE_AWAKE) { return; } /* wake up MAC timer */ MAC_RADIO_TIMER_WAKE_UP(); /* if radio was completely off, restore from that state first */ if (macSleepState == MAC_SLEEP_STATE_RADIO_OFF) { /* turn on radio power (turns on oscillator too) */ MAC_RADIO_TURN_ON_POWER(); /* power-up initialization of receive logic */ macRxRadioPowerUpInit(); } else { MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_OSC_OFF); /* turn on the oscillator */ MAC_RADIO_TURN_ON_OSC(); } /* update sleep state here before requesting to turn on receiver */ macSleepState = MAC_SLEEP_STATE_AWAKE; /* turn on the receiver if enabled */ macRxOnRequest(); }
/************************************************************************************************** * @fn macRadioUpdateChannel * * @brief Update the radio channel if a new channel has been requested. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRadioUpdateChannel(void) { halIntState_t s; MAC_ASSERT(!macTxActive); /* cannot change channel during a transmit */ /* if the channel has changed, set the radio to the new channel */ HAL_ENTER_CRITICAL_SECTION(s); if (reqChannel != macPhyChannel) { macPhyChannel = reqChannel; HAL_EXIT_CRITICAL_SECTION(s); /* changing the channel stops any receive in progress */ macRxOff(); MAC_RADIO_SET_CHANNEL(macPhyChannel); /* If the channel is updated in the middle of receiving a frame, we must * clean up the Rx logic. */ macRxHaltCleanup(); macRxOnRequest(); } else { HAL_EXIT_CRITICAL_SECTION(s); } }
/************************************************************************************************** * @fn macBackoffTimerPeriodIsr * * @brief Interrupt service routine that fires when the backoff count rolls over on * overflow period. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffTimerPeriodIsr(void) { halIntState_t s; uint32 macRatCount = MAC_RAT_COUNT; uint32 backoffRolloverRat = macBackoffTimerRollover * MAC_BACKOFF_TO_RAT_RATIO; uint32 ratCompensation = (macRatCount - macPrevPeriodRatCount) % MAC_BACKOFF_TO_RAT_RATIO; MAC_ASSERT( macBackoffTimerRollover <= MAC_BACKOFF_MAXIMUM_ROLLOVER ); if (macRatCount < backoffRolloverRat) { /* RAT wraparound has occurred. This would occur once in a blue moon (1073.74 seconds). */ DBG_PRINTL1(DBGSYS, "!!! RAT wraparound !!! RAT = %u", macRatCount); } DBG_PRINTL2(DBGSYS, "macRatChanA Period ISR, Rollover Period = %u, RAT Compensation = %u", macBackoffTimerRollover, ratCompensation); /* Convert count to RAT count and set MAC Channel A Compare. The modulus calculation will * compensate the math or interrupt latency error and prevent it from being accumulated. * Note that MAC_BACKOFF_TO_RAT_RATIO is used as part of compensation. This means the * maximum error that can be compensated is 320us. If the interrupt latency is greater * than 320us, more elaborated compensation scheme must be used for Beacon mode. * Non-beacon mode does not require absolute timing. Longer interrupt latency can be * tolerated. */ macPrevPeriodRatCount = macRatCount - ratCompensation; macSetupRATChanCompare( macRatChanA, backoffRolloverRat + macPrevPeriodRatCount ); macBackoffTimerRolloverCallback(); HAL_ENTER_CRITICAL_SECTION(s); MAC_BACKOFF_TIMER_UPDATE_WAKEUP(); HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macTxDoneCallback * * @brief - * * @param - * * @return none ************************************************************************************************** */ void macTxDoneCallback(uint8 status) { if (status == MAC_TXDONE_SUCCESS) { /* see if ACK was requested */ if (!txAckReq) { /* ACK was not requested, transmit is complete */ txComplete(MAC_SUCCESS); } else { /* * ACK was requested - must wait to receive it. A timer is set * to expire after the timeout duration for waiting for an ACK. * If an ACK is received, the function macTxAckReceived() is called. * If an ACK is not received within the timeout period, * the function macTxAckTimeoutCallback() is called. */ macTxListenForAck = TRUE; MAC_RADIO_TX_REQUEST_ACK_TIMEOUT_CALLBACK(); } } else if (status == MAC_TXDONE_CHANNEL_BUSY) { MAC_ASSERT((macTxType == MAC_TX_TYPE_SLOTTED_CSMA) || (macTxType == MAC_TX_TYPE_UNSLOTTED_CSMA)); /* clear channel assement failed, follow through with CSMA algorithm */ nb++; if (nb > macPib.maxCsmaBackoffs) { txComplete(MAC_CHANNEL_ACCESS_FAILURE); } else { macTxBe = MIN(macTxBe+1, macPib.maxBe); txCsmaPrep(); txCsmaGo(); } } else { MAC_ASSERT(status == MAC_TXDONE_INSUFFICIENT_TIME); txComplete(MAC_NO_TIME); } }
/*================================================================================================= * @fn rxAddrIsr * * @brief Receive ISR state for decoding address. Reads and stores the address information * from the incoming packet. * * @param none * * @return none *================================================================================================= */ static void rxAddrIsr(void) { uint8 buf[MAX_ADDR_FIELDS_LEN]; uint8 dstAddrMode; uint8 srcAddrMode; uint8 * p; MAC_ASSERT(rxNextLen != 0); /* logic assumes at least one address byte in buffer */ /* read out address fields into local buffer in one shot */ MAC_RADIO_READ_RX_FIFO(buf, rxNextLen); /* set pointer to buffer with addressing fields */ p = buf; /* destination address */ dstAddrMode = MAC_DEST_ADDR_MODE(&rxBuf[1]); if (dstAddrMode != SADDR_MODE_NONE) { pRxBuf->mac.srcPanId = pRxBuf->mac.dstPanId = BUILD_UINT16(p[0], p[1]); p += MAC_PAN_ID_FIELD_LEN; if (dstAddrMode == SADDR_MODE_EXT) { sAddrExtCpy(pRxBuf->mac.dstAddr.addr.extAddr, p); p += MAC_EXT_ADDR_FIELD_LEN; } else { pRxBuf->mac.dstAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]); p += MAC_SHORT_ADDR_FIELD_LEN; } } /* sources address */ srcAddrMode = MAC_SRC_ADDR_MODE(&rxBuf[1]); if (srcAddrMode != SADDR_MODE_NONE) { if (!(pRxBuf->internal.flags & MAC_RX_FLAG_INTRA_PAN)) { pRxBuf->mac.srcPanId = BUILD_UINT16(p[0], p[1]); p += MAC_PAN_ID_FIELD_LEN; } if (srcAddrMode == SADDR_MODE_EXT) { sAddrExtCpy(pRxBuf->mac.srcAddr.addr.extAddr, p); } else { pRxBuf->mac.srcAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]); } } /*------------------------------------------------------------------------------- * Prepare for payload interrupts. */ pFuncRxState = &rxPayloadIsr; rxPrepPayload(); }
/************************************************************************************************** * @fn macSleep * * @brief Puts radio into the selected sleep mode. * * @param sleepState - selected sleep level, see #defines in .h file * * @return TRUE if radio was successfully put into selected sleep mode. * FALSE if it was not safe for radio to go to sleep. ************************************************************************************************** */ uint8 macSleep(uint8 sleepState) { halIntState_t s; /* disable interrupts until macSleepState can be set */ HAL_ENTER_CRITICAL_SECTION(s); /* assert checks */ MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_AWAKE); /* radio must be awake to put it to sleep */ MAC_ASSERT(macRxFilter == RX_FILTER_OFF); /* do not sleep when scanning or in promiscuous mode */ /* if either RX or TX is active or any RX enable flags are set, it's not OK to sleep */ if (macRxActive || macRxOutgoingAckFlag || macTxActive || macRxEnableFlags) { HAL_EXIT_CRITICAL_SECTION(s); return(FALSE); } /* turn off the receiver */ macRxOff(); /* update sleep state variable */ macSleepState = sleepState; /* macSleepState is now set, re-enable interrupts */ HAL_EXIT_CRITICAL_SECTION(s); /* put MAC timer to sleep */ MAC_RADIO_TIMER_SLEEP(); /* put radio in selected sleep mode */ if (sleepState == MAC_SLEEP_STATE_OSC_OFF) { MAC_RADIO_TURN_OFF_OSC(); } else { MAC_ASSERT(sleepState == MAC_SLEEP_STATE_RADIO_OFF); /* unknown sleep state */ MAC_RADIO_TURN_OFF_POWER(); } /* radio successfully entered sleep mode */ return(TRUE); }
/************************************************************************************************** * @fn macBackoffTimerSetRollover * * @brief Set rollover count of backoff timer. * * @param rolloverBackoff - backoff count where count is reset to zero * * @return none ************************************************************************************************** */ void macBackoffTimerSetRollover(uint32 rolloverBackoff) { halIntState_t s; MAC_ASSERT(rolloverBackoff > MAC_RADIO_BACKOFF_COUNT()); /* rollover value must be greater than count */ HAL_ENTER_CRITICAL_SECTION(s); backoffTimerRollover = rolloverBackoff; MAC_RADIO_BACKOFF_SET_COMPARE(rolloverBackoff); HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRxSoftEnable * * @brief Set enable flags but don't turn on the receiver. Useful to leave the receiver * on after a transmit, but without turning it on immediately. * * @param flags - byte containing rx enable flags to set * * @return none ************************************************************************************************** */ void macRxSoftEnable(uint8 flags) { halIntState_t s; MAC_ASSERT(flags != 0); /* rx flags not affected */ /* set the enable flags but do not turn on the receiver */ HAL_ENTER_CRITICAL_SECTION(s); macRxEnableFlags |= flags; HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRxEnable * * @brief Set enable flags and then turn on receiver. * * @param flags - byte containing rx enable flags to set * * @return none ************************************************************************************************** */ void macRxEnable(uint8 flags) { halIntState_t s; MAC_ASSERT(flags != 0); /* rx flags not affected */ /* set enable flags and then turn on receiver */ HAL_ENTER_CRITICAL_SECTION(s); macRxEnableFlags |= flags; macRxOn(); HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macMemReadRxFifo * * @brief Read multiple bytes from receive FIFO. * * @param pData - pointer to location to store read data * @param len - number of bytes to read from RX FIFO * * @return none ************************************************************************************************** */ void macMemReadRxFifo(uint8 * pData, uint8 len) { MAC_ASSERT(len != 0); /* pointless to read zero bytes */ do { *pData = RFD; pData++; len--; } while (len); }
/************************************************************************************************** * @fn macMemWriteTxFifo * * @brief Write multiple bytes to the transmit FIFO. * * @param pData - pointer to bytes to be written to TX FIFO * @param len - number of bytes to write * * @return none ************************************************************************************************** */ void macMemWriteTxFifo(uint8 * pData, uint8 len) { MAC_ASSERT(len != 0); /* pointless to write zero bytes */ do { RFD = *pData; pData++; len--; } while (len); }
/************************************************************************************************** * @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 ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffTimerSetTrigger(uint32 triggerBackoff) { halIntState_t s; MAC_ASSERT(triggerBackoff < macBackoffTimerRollover); /* trigger backoff must be less than rollover backoff */ DBG_PRINT1(DBGSYS, "MAC_RADIO_BACKOFF_SET_COMPARE(%u)", triggerBackoff); HAL_ENTER_CRITICAL_SECTION(s); backoffTimerTrigger = triggerBackoff; MAC_RADIO_BACKOFF_SET_COMPARE(triggerBackoff); MAC_BACKOFF_TIMER_UPDATE_WAKEUP(); HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macBackoffTimerSetRollover * * @brief Set rollover count of backoff timer. * * @param rolloverBackoff - backoff count where count is reset to zero * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffTimerSetRollover(uint32 rolloverBackoff) { halIntState_t s; /* Normally called on initialization but timer realign also calls this. */ MAC_ASSERT(rolloverBackoff > MAC_RADIO_BACKOFF_COUNT()); /* rollover value must be greater than count */ DBG_PRINTL1(DBGSYS, "MAC_RADIO_BACKOFF_SET_PERIOD(%u)", rolloverBackoff); HAL_ENTER_CRITICAL_SECTION(s); macBackoffTimerRollover = rolloverBackoff; MAC_RADIO_BACKOFF_SET_PERIOD(rolloverBackoff); MAC_BACKOFF_TIMER_UPDATE_WAKEUP(); HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macRxDisable * * @brief Clear indicated rx enable flags. If all flags are clear, turn off receiver * unless there is an active receive or transmit. * * @param flags - byte containg rx enable flags to clear * * @return none ************************************************************************************************** */ void macRxDisable(uint8 flags) { halIntState_t s; MAC_ASSERT(flags != 0); /* rx flags not affected */ /* clear the indicated flags */ HAL_ENTER_CRITICAL_SECTION(s); macRxEnableFlags &= (0xff ^ flags); HAL_EXIT_CRITICAL_SECTION(s); /* turn off the radio if it is allowed */ macRxOffRequest(); }
/*================================================================================================= * @fn rxDiscardFrame * * @brief Initializes for discarding a packet. Must be called before ACK is strobed. * * @param none * * @return none *================================================================================================= */ static void rxDiscardFrame(void) { MAC_ASSERT(pFuncRxState == &rxStartIsr); /* illegal state for calling discard frame function */ if (rxUnreadLen == 0) { rxDone(); } else { rxNextLen = MIN(rxUnreadLen, MAX_PAYLOAD_BYTES_READ_PER_INTERRUPT); MAC_RADIO_SET_RX_THRESHOLD(rxNextLen); pFuncRxState = &rxDiscardIsr; } }
/************************************************************************************************** * @fn macRxSoftEnable * * @brief Set enable flags but don't turn on the receiver. Useful to leave the receiver * on after a transmit, but without turning it on immediately. * * @param flags - byte containing rx enable flags to set * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxSoftEnable(uint8 flags) { halIntState_t s; MAC_ASSERT(flags != 0); /* rx flags not affected */ DBG_PRINT1(DBGSYS, "macRxSoftEnable(0x%X)", flags); /* set the enable flags but do not turn on the receiver */ HAL_ENTER_CRITICAL_SECTION(s); macRxEnableFlags |= flags; HAL_EXIT_CRITICAL_SECTION(s); /* Power management state may change. Hence, vote. */ macPwrVote(); }
/************************************************************************************************** * @fn macRxPromiscuousMode * * @brief Sets promiscuous mode - enabling or disabling it. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxPromiscuousMode(uint8 mode) { rxPromiscuousMode = mode; if (rxPromiscuousMode == MAC_PROMISCUOUS_MODE_OFF) { MAC_RADIO_TURN_ON_RX_FRAME_FILTERING(); } else { MAC_ASSERT((mode == MAC_PROMISCUOUS_MODE_WITH_BAD_CRC) || (mode == MAC_PROMISCUOUS_MODE_COMPLIANT)); /* invalid mode */ MAC_RADIO_TURN_OFF_RX_FRAME_FILTERING(); } }
/************************************************************************************************** * @fn macLowLevelReset * * @brief Reset low-level MAC. * * @param none * * @return none ************************************************************************************************** */ void macLowLevelReset(void) { MAC_ASSERT(!HAL_INTERRUPTS_ARE_ENABLED()); /* interrupts must be disabled */ /* reset radio modules; if not awake, skip this */ if (macSleepState == MAC_SLEEP_STATE_AWAKE) { macRxTxReset(); macRadioReset(); } /* reset timer */ macBackoffTimerReset(); /* power up the radio */ macSleepWakeUp(); }
/************************************************************************************************** * @fn macRxDisable * * @brief Clear indicated rx enable flags. If all flags are clear, turn off receiver * unless there is an active receive or transmit. * * @param flags - byte containg rx enable flags to clear * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxDisable(uint8 flags) { halIntState_t s; MAC_ASSERT(flags != 0); /* rx flags not affected */ DBG_PRINT1(DBGSYS, "macRxDisable(0x%X)", flags); /* clear the indicated flags */ HAL_ENTER_CRITICAL_SECTION(s); macRxEnableFlags &= (flags ^ 0xFF); HAL_EXIT_CRITICAL_SECTION(s); /* turn off the radio if it is allowed */ macRxOffRequest(); /* Power management state may change. Hence, vote. */ macPwrVote(); }
/************************************************************************************************** * @fn macBackoffSetupPwrMgmt * * @brief Intializes backoff timer power management logic. * Note that this function must be called only once. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macBackoffSetupPwrMgmt(void) { #ifdef USE_ICALL /* Register power transition notification */ if (ICall_pwrRegisterNotify(macBackoffTimerICallPwrNotify, &macBackoffTimerICallPwrNotifyData) != ICALL_ERRNO_SUCCESS) { MAC_ASSERT(0); } #endif /* USE_ICALL */ #ifdef OSAL_PORT2TIRTOS /* Register power transition notification */ Power_registerNotify(&macBackoffPwrNotifyObj, (Power_ENTERING_STANDBY | Power_ENTERING_SHUTDOWN | Power_AWAKE_STANDBY), (xdc_Fxn) macBackoffTimerPwrNotify, (UArg) NULL, 0); #endif /* OSAL_PORT2TIRTOS */ }
/************************************************************************************************** * @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 ************************************************************************************************** */ MAC_INTERNAL_API 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; MAC_RADIO_BACKOFF_SET_COMPARE(triggerBackoff); if (triggerBackoff == MAC_RADIO_BACKOFF_COUNT()) { /* Clear the interrupt and fire it manually */ MAC_RADIO_BACKOFF_COMPARE_CLEAR_INTERRUPT(); HAL_EXIT_CRITICAL_SECTION(s); macBackoffTimerTriggerCallback(); } else { HAL_EXIT_CRITICAL_SECTION(s); } }
/************************************************************************************************** * @fn macTxChannelBusyCallback * * @brief This callback is executed if a CSMA transmit was attempted but the channel * was busy. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macTxChannelBusyCallback(void) { MAC_ASSERT((macTxType == MAC_TX_TYPE_SLOTTED_CSMA) || (macTxType == MAC_TX_TYPE_UNSLOTTED_CSMA)); /* turn off receiver if allowed */ macTxActive = MAC_TX_ACTIVE_CHANNEL_BUSY; macRxOffRequest(); /* clear channel assement failed, follow through with CSMA algorithm */ nb++; if (nb > pMacPib->maxCsmaBackoffs) { txComplete(MAC_CHANNEL_ACCESS_FAILURE); } else { macTxBe = MIN(macTxBe+1, pMacPib->maxBe); txCsmaPrep(); macTxActive = MAC_TX_ACTIVE_GO; txCsmaGo(); } }