diff --git a/examples/platforms/nrf52840/radio.c b/examples/platforms/nrf52840/radio.c index c40cd137a..78ed76541 100644 --- a/examples/platforms/nrf52840/radio.c +++ b/examples/platforms/nrf52840/radio.c @@ -63,6 +63,7 @@ #define SHORT_ADDRESS_SIZE 2 #define EXTENDED_ADDRESS_SIZE 8 +#define PENDING_BIT 0x10 enum { @@ -75,7 +76,7 @@ static RadioPacket sReceivedFrames[RADIO_RX_BUFFERS]; static RadioPacket sTransmitFrame; static uint8_t sTransmitPsdu[kMaxPHYPacketSize + 1] __attribute__((section("nrf_radio_buffer.sTransmiPsdu"))); -static bool sTransmitPendingBit; +static uint8_t *sAckPsdu; static uint32_t sEnergyDetectionTime; static uint8_t sEnergyDetectionChannel; @@ -102,6 +103,8 @@ static void dataInit(void) { sReceivedFrames[i].mPsdu = NULL; } + + sAckPsdu = NULL; } static void convertShortAddress(uint8_t *aTo, uint16_t aFrom) @@ -515,16 +518,24 @@ void nrf5RadioProcess(otInstance *aInstance) if (isPendingEventSet(kPendingEventFrameTransmitted)) { + bool pendingBit = ((sAckPsdu != NULL) && (sAckPsdu[1] & PENDING_BIT)) ? true : false; + #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) { - otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, sTransmitPendingBit, OT_ERROR_NONE); + otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, pendingBit, OT_ERROR_NONE); } else #endif { - otPlatRadioTransmitDone(aInstance, &sTransmitFrame, sTransmitPendingBit, OT_ERROR_NONE); + otPlatRadioTransmitDone(aInstance, &sTransmitFrame, pendingBit, OT_ERROR_NONE); + } + + if (sAckPsdu != NULL) + { + nrf_drv_radio802154_buffer_free(sAckPsdu); + sAckPsdu = NULL; } resetPendingEvent(kPendingEventFrameTransmitted); @@ -595,9 +606,9 @@ void nrf_drv_radio802154_received(uint8_t *p_data, int8_t power, int8_t lqi) receivedFrame->mChannel = nrf_drv_radio802154_channel_get(); } -void nrf_drv_radio802154_transmitted(bool pending_bit) +void nrf_drv_radio802154_transmitted(uint8_t *aAckPsdu) { - sTransmitPendingBit = pending_bit; + sAckPsdu = aAckPsdu; setPendingEvent(kPendingEventFrameTransmitted); } diff --git a/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.c b/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.c index dbced96cb..ef7d90192 100644 --- a/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.c +++ b/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.c @@ -1439,7 +1439,7 @@ void RADIO_IRQHandler(void) if (!ack_is_requested(mp_tx_data)) { - nrf_drv_radio802154_transmitted(false); + nrf_drv_radio802154_transmitted(NULL); state_set(RADIO_STATE_WAITING_RX_FRAME); } @@ -1463,8 +1463,8 @@ void RADIO_IRQHandler(void) if ((nrf_radio_event_get(NRF_RADIO_EVENT_MHRMATCH)) && (nrf_radio_crc_status_get() == NRF_RADIO_CRC_STATUS_OK)) { - nrf_drv_radio802154_transmitted( - (mp_current_rx_buffer->psdu[FRAME_PENDING_OFFSET] & FRAME_PENDING_BIT) != 0); + mp_current_rx_buffer->free = false; + nrf_drv_radio802154_transmitted(mp_current_rx_buffer->psdu); nrf_radio_mhmu_search_pattern_set(0); nrf_radio_event_clear(NRF_RADIO_EVENT_MHRMATCH); @@ -1679,9 +1679,9 @@ void __attribute__((weak)) nrf_drv_radio802154_received(uint8_t * p_data, int8_t (void) lqi; } -void __attribute__((weak)) nrf_drv_radio802154_transmitted(bool pending_bit) +void __attribute__((weak)) nrf_drv_radio802154_transmitted(uint8_t * p_ack) { - (void) pending_bit; + (void) p_ack; } void __attribute__((weak)) nrf_drv_radio802154_busy_channel(void) diff --git a/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.h b/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.h index 8e0ec86b6..6282ca7ae 100644 --- a/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.h +++ b/third_party/NordicSemiconductor/drivers/nrf_drv_radio802154.h @@ -224,12 +224,17 @@ void nrf_drv_radio802154_received(uint8_t * p_data, int8_t power, int8_t lqi); * @brief Notify that frame was transmitted. * * @note If ACK was requested for transmitted frame this function is called after proper ACK is - * received. If ACK was not requested this function is called just after transmission is - * ended. + * received. If ACK was not requested this function is called just after transmission ends. + * @note Buffer pointed by the p_ack pointer is not modified by the radio driver (and can't + * be used to receive a frame) until nrf_drv_radio802154_buffer_free() function is called. + * @note Buffer pointed by the p_ack pointer may be modified by the function handler (and other + * modules) until nrf_drv_radio802154_buffer_free() function is called. * - * @param[in] pending_bit Value of pending bit in received ACK or false if ACK was not requested. + * @param[in] p_ack Pointer to received ACK buffer. The first byte in the buffer is length of the + * frame and following bytes are the ACK frame itself (after PHR). + * If ACK was not requested @p p_ack is set to NULL. */ -void nrf_drv_radio802154_transmitted(bool pending_bit); +void nrf_drv_radio802154_transmitted(uint8_t * p_ack); /** * @brief Notify that frame was not transmitted due to busy channel.