uint16_t calc_frame_transmit_duration(uint8_t *phy_frame) { uint8_t transaction_duration_octets; uint16_t transaction_duration_sym; /* number of octets */ transaction_duration_octets = (*phy_frame) + PHY_OVERHEAD; /* Add interframe spacing - independent on ACK transmission. */ if (*phy_frame > aMaxSIFSFrameSize) { transaction_duration_sym = macMinLIFSPeriod_def; /* symbols */ } else { transaction_duration_sym = macMinSIFSPeriod_def; /* symbols */ } /* If the frame requested an ACK, add ACK handling time. */ if (phy_frame[PL_POS_FCF_1] & FCF_ACK_REQUEST) { /* Ensure there is room for the ACK. */ transaction_duration_octets += ACK_FRAME_LEN + PHY_OVERHEAD; /** * *octets **/ /* Space is needed until the ACK is sent. */ transaction_duration_sym += aTurnaroundTime + aUnitBackoffPeriod; /** * *symbols **/ } transaction_duration_sym += transaction_duration_octets * SYMBOLS_PER_OCTET; transaction_duration_sym = TAL_PSDU_US_PER_OCTET( transaction_duration_sym); return transaction_duration_sym; }
/* * \brief Implements the handling of the transmission end. * * This function handles the callback for the transmission end. */ void tx_done_handling(void) { tal_state = TAL_IDLE; #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) /* * The entire timestamp calculation is only required for beaconing *networks * or if timestamping is explicitly enabled. */ /* Calculate negative offset of timestamp */ uint16_t offset; /* Calculate the tx time */ offset = TAL_CONVERT_SYMBOLS_TO_US( (PHY_OVERHEAD + LENGTH_FIELD_LEN) * SYMBOLS_PER_OCTET) + TAL_PSDU_US_PER_OCTET(*tal_frame_to_tx + FCS_LEN) + IRQ_PROCESSING_DLY_US; if (mac_frame_ptr->mpdu[PL_POS_FCF_1] & FCF_ACK_REQUEST) { /* Tx timestamp needs to be reduced by ACK duration etc. */ offset += TAL_CONVERT_SYMBOLS_TO_US( (PHY_OVERHEAD + LENGTH_FIELD_LEN) * SYMBOLS_PER_OCTET) + TAL_PSDU_US_PER_OCTET(ACK_PAYLOAD_LEN + FCS_LEN); #ifdef HIGH_DATA_RATE_SUPPORT if (tal_pib.CurrentPage == 0) { offset += TAL_CONVERT_SYMBOLS_TO_US(aTurnaroundTime); } else { offset += 32; } #else offset += TAL_CONVERT_SYMBOLS_TO_US(aTurnaroundTime); #endif /* #ifdef HIGH_DATA_RATE_SUPPORT */ } mac_frame_ptr->time_stamp -= offset; #endif /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */ retval_t status; switch (trx_trac_status) { case TRAC_SUCCESS: status = MAC_SUCCESS; break; case TRAC_SUCCESS_DATA_PENDING: status = TAL_FRAME_PENDING; break; case TRAC_CHANNEL_ACCESS_FAILURE: status = MAC_CHANNEL_ACCESS_FAILURE; break; case TRAC_NO_ACK: status = MAC_NO_ACK; break; case TRAC_INVALID: status = FAILURE; break; default: Assert("Unexpected tal_tx_state" == 0); status = FAILURE; break; } tal_tx_frame_done_cb(status, mac_frame_ptr); } /* tx_done_handling() */
/* * \brief Implements the handling of the transmission end. * * This function handles the callback for the transmission end. */ void tx_done_handling(void) { tal_state = TAL_IDLE; #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) #if (DISABLE_TSTAMP_IRQ == 0) /* * The Tx timestamp IRQ is enabled and provided via DIG2. * The actual value is stored within trx_irq_timestamp_handler_cb(); * see file "tal_irq_handler.c". * The value gets stored into the mac_frame_ptr structure during the * tx end interrupt; see handle_tx_end_irq(). * So, here is nothing left to do. */ #else /* (DISABLE_TSTAMP_IRQ == 1) */ /* * The entire timestamp calculation is only required for beaconing networks * or if timestamping is explicitly enabled. */ /* Calculate negative offset of timestamp */ uint16_t offset; /* Calculate the tx time */ offset = TAL_CONVERT_SYMBOLS_TO_US((PHY_OVERHEAD + LENGTH_FIELD_LEN) * SYMBOLS_PER_OCTET) + TAL_PSDU_US_PER_OCTET(*tal_frame_to_tx + FCS_LEN) + TRX_IRQ_DELAY_US; if (mac_frame_ptr->mpdu[PL_POS_FCF_1] & FCF_ACK_REQUEST) { /* Tx timestamp needs to be reduced by ACK duration etc. */ offset += TAL_CONVERT_SYMBOLS_TO_US((PHY_OVERHEAD + LENGTH_FIELD_LEN) * SYMBOLS_PER_OCTET) + TAL_PSDU_US_PER_OCTET(ACK_PAYLOAD_LEN + FCS_LEN); offset += TAL_CONVERT_SYMBOLS_TO_US(aTurnaroundTime); } mac_frame_ptr->time_stamp -= offset; #endif /* #if (DISABLE_TSTAMP_IRQ == 0) */ #endif /* #if (defined BEACON_SUPPORT) || (defined ENABLE_TSTAMP) */ retval_t status; switch (trx_trac_status) { case TRAC_SUCCESS: status = MAC_SUCCESS; break; case TRAC_SUCCESS_DATA_PENDING: status = TAL_FRAME_PENDING; break; case TRAC_CHANNEL_ACCESS_FAILURE: status = MAC_CHANNEL_ACCESS_FAILURE; break; case TRAC_NO_ACK: status = MAC_NO_ACK; break; case TRAC_INVALID: status = FAILURE; break; default: Assert("Unexpected tal_tx_state" == 0); status = FAILURE; break; } tal_tx_frame_done_cb(status, mac_frame_ptr); } /* tx_done_handling() */