/*================================================================================================= * @fn txGo * * @brief Start a transmit going. * * @param none * * @return none *================================================================================================= */ static void txGo(void) { /* * If execution has reached this point, any transmitted ACK has long since completed. It is * possible though that there is still a pending callback. If so, it is irrelevant and needs to * be canceled at this point. */ MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK(); macRxOutgoingAckFlag = 0; /* based on type of transmit, call the correct "go" functionality */ if (macTxType == MAC_TX_TYPE_SLOTTED) { MAC_RADIO_TX_GO_SLOTTED(); } #ifdef FEATURE_GREEN_POWER else if (macTxType == MAC_TX_TYPE_GREEN_POWER) { MAC_RADIO_TX_GO_GREEN_POWER(); } #endif /* #ifdef FEATURE_GREEN_POWER */ else { txCsmaGo(); } }
/************************************************************************************************** * @fn macTxStartQueuedFrame * * @brief - * * @param none * * @return none ************************************************************************************************** */ void macTxStartQueuedFrame(void) { halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); if (macTxFrameInQueueFlag) { macTxFrameInQueueFlag = FALSE; HAL_EXIT_CRITICAL_SECTION(s); if (macTxType == MAC_TX_TYPE_SLOTTED) { MAC_RADIO_TX_GO_SLOTTED(); } else { txCsmaGo(); } } HAL_EXIT_CRITICAL_SECTION(s); }
/************************************************************************************************** * @fn macTxFrame * * @brief Transmit the frame pointed to by pMacDataTx with unslotted CSMA. * NOTE! It is not legal to call this function from interrupt context. * * @param none * * @return none ************************************************************************************************** */ void macTxFrame(uint8 txType) { MAC_ASSERT(!macTxActive); /* transmit on top of transmit */ MAC_ASSERT(!macTxFrameInQueueFlag); /* already a queued transmit */ MAC_ASSERT(macSleepState == MAC_SLEEP_STATE_AWAKE); /* radio must be awake */ /* initialize */ macTxActive = TRUE; macTxType = txType; /*------------------------------------------------------------------------------- * Prepare for transmit. */ if (macTxType == MAC_TX_TYPE_SLOTTED) { MAC_RADIO_TX_PREP_SLOTTED(); } else { MAC_ASSERT((macTxType == MAC_TX_TYPE_SLOTTED_CSMA) || (macTxType == MAC_TX_TYPE_UNSLOTTED_CSMA)); nb = 0; macTxBe = (pMacDataTx->internal.txOptions & MAC_TXOPTION_ALT_BE) ? macPib.altBe : macPib.minBe; if ((macTxType == MAC_TX_TYPE_SLOTTED_CSMA) && (macPib.battLifeExt)) { macTxBe = MIN(2, macTxBe); } txCsmaPrep(); } /*------------------------------------------------------------------------------- * Load transmit FIFO unless this is a retransmit. No need to write * the FIFO again in that case. */ if (!txRetransmitFlag) { uint8 * p; uint8 lenMhrMsdu; MAC_ASSERT(pMacDataTx != NULL); /* must have data to transmit */ /* save needed parameters */ txAckReq = MAC_ACK_REQUEST(pMacDataTx->msdu.p); txSeqn = MAC_SEQ_NUMBER(pMacDataTx->msdu.p); /* set length of frame (note: use of term msdu is a misnomer, here it's actually mhr + msdu) */ lenMhrMsdu = pMacDataTx->msdu.len; /* calling code guarantees an unused prepended byte */ p = pMacDataTx->msdu.p - PREPENDED_BYTE_LEN; /* first byte of buffer is length of MPDU */ *p = lenMhrMsdu + MFR_LEN; /* * Flush the TX FIFO. This is necessary in case the previous transmit was never * actually sent (e.g. CSMA failed without strobing TXON). If bytes are written to * the FIFO but not transmitted, they remain in the FIFO to be transmitted whenever * a strobe of TXON does happen. */ MAC_RADIO_FLUSH_TX_FIFO(); /* write bytes to FIFO, prepended byte is included, MFR is not (it's generated by hardware) */ MAC_RADIO_WRITE_TX_FIFO(p, PREPENDED_BYTE_LEN + lenMhrMsdu); } /*------------------------------------------------------------------------------- * If not receiving, start the transmit. If receive is active * queue up the transmit. */ { halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); if (!macRxActive) { HAL_EXIT_CRITICAL_SECTION(s); if (macTxType == MAC_TX_TYPE_SLOTTED) { MAC_RADIO_TX_GO_SLOTTED(); } else { txCsmaGo(); } } else { macTxFrameInQueueFlag = TRUE; HAL_EXIT_CRITICAL_SECTION(s); } } }