/*================================================================================================= * @fn txComplete * * @brief Transmit has completed. Perform needed maintenance and return status of * the transmit via callback function. * * @param status - status of the transmit that just went out * * @return none *================================================================================================= */ static void txComplete(uint8 status) { /* reset the retransmit flag */ txRetransmitFlag = 0; /* update tx state; turn off receiver if nothing is keeping it on */ macTxActive = MAC_TX_ACTIVE_NO_ACTIVITY; /* If no ACK is pending go to sleep sooner than wait for high level mac * to clear MAC_RX_POLL bit and then go to sleep */ if (status != MAC_ACK_PENDING) { macRxEnableFlags &= ~MAC_RX_POLL; } /* turn off receive if allowed */ macRxOffRequest(); /* update transmit power in case there was a change */ macRadioUpdateTxPower(); /* * Channel cannot change during transmit so update it here. (Channel *can* change during * a receive. The update function resets receive logic and any partially received * frame is purged.) */ macRadioUpdateChannel(); /* return status of transmit via callback function */ macTxCompleteCallback(status); }
/*================================================================================================= * @fn txComplete * * @brief Transmit has completed. Perform needed maintenance and return status of * the transmit via callback function. * * @param status - status of the transmit that just went out * * @return none *================================================================================================= */ static void txComplete(uint8 status) { /* * Unless receive is active, update power here. Power is *always* updated at end of receive. */ if (!macRxActive) { macRadioUpdateTxPower(); } /* * Channel cannot change during transmit so update it here. (Channel *can* change during * a receive. The update function resets receive logic and any partially received * frame is purged.) */ macRadioUpdateChannel(); /* reset the retransmit flag */ txRetransmitFlag = FALSE; /* update tx state; turn off receiver if nothing is keeping it on */ macTxActive = FALSE; /* turn off receive if allowed */ macRxOffRequest(); /* return status of transmit via callback function */ macTxCompleteCallback(status); }
/*================================================================================================= * @fn rxPostRxUpdates * * @brief Updates that need to be performed once receive is complete. * * It is not fatal to execute this function if somehow receive is active. Under * certain timing/interrupt conditions a new receive may have started before this * function executes. This should happen very rarely (if it happens at all) and * would cause no problems. * * @param none * * @return none *================================================================================================= */ static void rxPostRxUpdates(void) { /* turn off receiver if permitted */ macRxOffRequest(); /* update the transmit power, update may have been blocked by transmit of outgoing ACK */ macRadioUpdateTxPower(); /* initiate and transmit that was queued during receive */ macTxStartQueuedFrame(); }
/************************************************************************************************** * @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 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 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(); } }
/*================================================================================================= * @fn txComplete * * @brief Transmit has completed. Perform needed maintenance and return status of * the transmit via callback function. * * @param status - status of the transmit that just went out * * @return none *================================================================================================= */ static void txComplete(uint8 status) { /* reset the retransmit flag */ txRetransmitFlag = 0; /* update tx state; turn off receiver if nothing is keeping it on */ macTxActive = MAC_TX_ACTIVE_NO_ACTIVITY; if(pMacPib->rf4cepowerSavings) { /* mark receive as inactive */ macRxActive = MAC_RX_ACTIVE_NO_ACTIVITY; } /* In general, the MAC_RX_POLL is controlled by high level MAC. The flag is * cleared here when no ACK is pending to allow the RX to be turned off sooner * in order to save power. */ if (status != MAC_ACK_PENDING) { macRxEnableFlags &= ~MAC_RX_POLL; } /* turn off receive if allowed */ macRxOffRequest(); /* update transmit power in case there was a change */ macRadioUpdateTxPower(); /* * Channel cannot change during transmit so update it here. (Channel *can* change during * a receive. The update function resets receive logic and any partially received * frame is purged.) */ macRadioUpdateChannel(); /* return status of transmit via callback function */ macTxCompleteCallback(status); }
/*================================================================================================= * @fn txComplete * * @brief Transmit has completed. Perform needed maintenance and return status of * the transmit via callback function. * * @param status - status of the transmit that just went out * * @return none *================================================================================================= */ static void txComplete(uint8 status) { /* reset the retransmit flag */ txRetransmitFlag = 0; /* update tx state; turn off receiver if nothing is keeping it on */ macTxActive = MAC_TX_ACTIVE_NO_ACTIVITY; /* turn off receive if allowed */ macRxOffRequest(); /* update transmit power in case there was a change */ macRadioUpdateTxPower(); /* * Channel cannot change during transmit so update it here. (Channel *can* change during * a receive. The update function resets receive logic and any partially received * frame is purged.) */ macRadioUpdateChannel(); /* return status of transmit via callback function */ macTxCompleteCallback(status); }
/*================================================================================================= * @fn rxFcsIsr * * @brief Receive ISR state for handling the FCS. * * @param none * * @return none *================================================================================================= */ static void rxFcsIsr(void) { uint8 crcOK; uint8 ackWithPending = 0; /* read FCS, rxBuf is now available storage */ MAC_RADIO_READ_RX_FIFO(rxBuf, MAC_FCS_FIELD_LEN); /* * The FCS has actually been replaced within the radio by a proprietary version of the FCS. * This proprietary FCS is two bytes (same length as the real FCS) and contains: * 1) the RSSI value * 2) the average correlation value (used for LQI) * 3) a CRC passed bit */ /* save the "CRC-is-OK" status */ crcOK = PROPRIETARY_FCS_CRC_OK(rxBuf); /* * See if the frame should be passed up to high-level MAC. If the CRC is OK, the * the frame is always passed up. Frames with a bad CRC are also passed up *if* * a special variant of promiscuous mode is active. */ if (crcOK || (rxPromiscuousMode == MAC_PROMISCUOUS_MODE_WITH_BAD_CRC)) { int8 rssiDbm; uint8 corr; #ifdef FEATURE_SYSTEM_STATS /* Increment diagnostic CRC success counter */ macLowLevelDiags( MAC_DIAGS_RX_CRC_PASS ); #endif /* FEATURE_SYSTEM_STATS */ /* * As power saving optimization, set state variable to indicate physical receive * has completed and then request turning of the receiver. This means the receiver * can be off (if other conditions permit) during execution of the callback function. * * The receiver will be requested to turn off once again at the end of the receive * logic. There is no harm in doing this. */ macRxActive = MAC_RX_ACTIVE_DONE; macRxOffRequest(); /* decode RSSI and correlation values */ rssiDbm = PROPRIETARY_FCS_RSSI(rxBuf) + MAC_RADIO_RSSI_OFFSET; MAC_RADIO_RSSI_LNA_OFFSET(rssiDbm); corr = PROPRIETARY_FCS_CORRELATION_VALUE(rxBuf); /* record parameters that get passed up to high-level */ pRxBuf->mac.mpduLinkQuality = macRadioComputeLQI(rssiDbm, corr); pRxBuf->mac.rssi = rssiDbm; pRxBuf->mac.correlation = corr; /* set the MSDU pointer to point at start of data */ pRxBuf->mhr.p = (uint8 *) (pRxBuf + 1); pRxBuf->msdu.p += (pRxBuf->mhr.len - pRxBuf->msdu.len); if ((pRxBuf->internal.flags & MAC_RX_FLAG_ACK_PENDING) && (*pRxBuf->msdu.p != MAC_DATA_REQ_FRAME)) { /* For non-data request commands, cancel the pending bit in the ACK. */ MAC_RADIO_TX_ACK(); } /* Read the source matching result back */ if( macSrcMatchIsEnabled && MAC_RADIO_SRC_MATCH_RESULT() ) { /* This result will not overwrite the previously determined pRxBuf->internal.flags */ ackWithPending = MAC_RX_FLAG_ACK_PENDING; } pRxBuf->internal.flags |= ( crcOK | ackWithPending ); /* finally... execute callback function */ macRxCompleteCallback(pRxBuf); pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */ } else { #ifdef FEATURE_SYSTEM_STATS /* Increment diagnostic CRC failure counter */ macLowLevelDiags( MAC_DIAGS_RX_CRC_FAIL ); #endif /* FEATURE_SYSTEM_STATS */ /* * The CRC is bad so no ACK was sent. Cancel any callback and clear the flag. * (It's OK to cancel the outgoing ACK even if an ACK was not requested. It's * slightly more efficient to do so.) */ MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK(); macRxOutgoingAckFlag = 0; /* the CRC failed so the packet must be discarded */ MEM_FREE((uint8 **)&pRxBuf); pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */ } /* reset threshold level, reset receive state, and complete receive logic */ MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN); pFuncRxState = &rxStartIsr; rxDone(); }
/*================================================================================================= * @fn rxFcsIsr * * @brief Receive ISR state for handling the FCS. * * @param none * * @return none *================================================================================================= */ static void rxFcsIsr(void) { uint8 crcOK; /* read FCS, rxBuf is now available storage */ MAC_RADIO_READ_RX_FIFO(rxBuf, MAC_FCS_FIELD_LEN); /* * The FCS has actually been replaced within the radio by a proprietary version of the FCS. * This proprietary FCS is two bytes (same length as the real FCS) and contains: * 1) the RSSI value * 2) the average correlation value (used for LQI) * 3) a CRC passed bit */ /* save the "CRC-is-OK" status */ crcOK = PROPRIETARY_FCS_CRC_OK(rxBuf); /* * See if the frame should be passed up to high-level MAC. If the CRC is OK, the * the frame is always passed up. Frames with a bad CRC are also passed up *if* * a special variant of promiscuous mode is active. */ if (crcOK || (rxPromiscuousMode == MAC_PROMISCUOUS_MODE_WITH_BAD_CRC)) { int8 rssiDbm; uint8 corr; /* * As power saving optimization, set state variable to indicate physical receive * has completed and then request turning of the receiver. This means the receiver * can be off (if other conditions permit) during execution of the callback function. * * The receiver will be requested to turn off once again at the end of the receive * logic. There is no harm in doing this. */ macRxActive = MAC_RX_ACTIVE_DONE; macRxOffRequest(); /* decode RSSI and correlation values */ rssiDbm = PROPRIETARY_FCS_RSSI(rxBuf) + MAC_RADIO_RSSI_OFFSET; corr = PROPRIETARY_FCS_CORRELATION_VALUE(rxBuf); /* record parameters that get passed up to high-level */ pRxBuf->internal.flags |= crcOK; pRxBuf->mac.mpduLinkQuality = macRadioComputeLQI(rssiDbm, corr); pRxBuf->mac.rssi = rssiDbm; pRxBuf->mac.correlation = corr; /* set the MSDU pointer to point at start of data */ pRxBuf->msdu.p = (uint8 *) (pRxBuf + 1); /* finally... execute callback function */ macRxCompleteCallback(pRxBuf); pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */ } else { /* * The CRC is bad so no ACK was sent. Cancel any callback and clear the flag. * (It's OK to cancel the outgoing ACK even if an ACK was not requested. It's * slightly more efficient to do so.) */ MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK(); macRxOutgoingAckFlag = 0; /* the CRC failed so the packet must be discarded */ MEM_FREE((uint8 *) pRxBuf); pRxBuf = NULL; /* needed to indicate buffer is no longer allocated */ } /* reset threshold level, reset receive state, and complete receive logic */ MAC_RADIO_SET_RX_THRESHOLD(RX_THRESHOLD_START_LEN); pFuncRxState = &rxStartIsr; rxDone(); }