[nRF52840] update radio driver (#2212)

This commit is contained in:
Hubert Miś
2017-09-21 08:44:34 -07:00
committed by Jonathan Hui
parent b9ac11e741
commit aa811d0aac
9 changed files with 235 additions and 45 deletions
+32 -2
View File
@@ -99,6 +99,7 @@ typedef enum
kPendingEventTransmit, // Frame is queued for transmission.
kPendingEventFrameTransmitted, // Transmitted frame and received ACK (if requested).
kPendingEventChannelAccessFailure, // Failed to transmit frame (channel busy).
kPendingEventInvalidAck, // Failed to transmit frame (received invalid ACK).
kPendingEventEnergyDetectionStart, // Requested to start Energy Detection procedure.
kPendingEventEnergyDetected, // Energy Detection finished.
} RadioPendingEvents;
@@ -166,6 +167,7 @@ static inline void clearPendingEvents(void)
bitsToRemain &= ~(1UL << kPendingEventFrameTransmitted);
bitsToRemain &= ~(1UL << kPendingEventChannelAccessFailure);
bitsToRemain &= ~(1UL << kPendingEventInvalidAck);
bitsToRemain &= ~(1UL << kPendingEventSleep);
@@ -592,6 +594,23 @@ void nrf5RadioProcess(otInstance *aInstance)
resetPendingEvent(kPendingEventChannelAccessFailure);
}
if (isPendingEventSet(kPendingEventInvalidAck))
{
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
{
otPlatDiagRadioTransmitDone(aInstance, &sTransmitFrame, OT_ERROR_NO_ACK);
}
else
#endif
{
otPlatRadioTxDone(aInstance, &sTransmitFrame, NULL, OT_ERROR_NO_ACK);
}
resetPendingEvent(kPendingEventInvalidAck);
}
if (isPendingEventSet(kPendingEventEnergyDetected))
{
otPlatRadioEnergyScanDone(aInstance, sEnergyDetected);
@@ -665,9 +684,20 @@ void nrf_drv_radio802154_transmitted_raw(uint8_t *aAckPsdu, int8_t aPower, int8_
setPendingEvent(kPendingEventFrameTransmitted);
}
void nrf_drv_radio802154_busy_channel(void)
void nrf_drv_radio802154_transmit_failed(nrf_drv_radio802154_tx_error_t error)
{
setPendingEvent(kPendingEventChannelAccessFailure);
switch (error)
{
case NRF_DRV_RADIO802154_TX_ERROR_BUSY_CHANNEL:
case NRF_DRV_RADIO802154_TX_ERROR_TIMESLOT_ENDED:
setPendingEvent(kPendingEventChannelAccessFailure);
break;
case NRF_DRV_RADIO802154_TX_ERROR_INVALID_ACK:
case NRF_DRV_RADIO802154_TX_ERROR_NO_MEM:
setPendingEvent(kPendingEventInvalidAck);
break;
}
}
void nrf_drv_radio802154_energy_detected(uint8_t result)
@@ -407,6 +407,11 @@ __WEAK void nrf_drv_radio802154_rx_started(void)
// Intentionally empty
}
__WEAK void nrf_drv_radio802154_tx_ack_started(void)
{
// Intentionally empty
}
__WEAK void nrf_drv_radio802154_received(uint8_t * p_data, uint8_t length, int8_t power, int8_t lqi)
{
(void) length;
@@ -424,11 +429,21 @@ __WEAK void nrf_drv_radio802154_received_raw(uint8_t * p_data, int8_t power, int
lqi);
}
__WEAK void nrf_drv_radio802154_receive_failed(nrf_drv_radio802154_rx_error_t error)
{
(void) error;
}
__WEAK void nrf_drv_radio802154_tx_started(void)
{
// Intentionally empty
}
__WEAK void nrf_drv_radio802154_rx_ack_started(void)
{
// Intentionally empty
}
__WEAK void nrf_drv_radio802154_transmitted(uint8_t * p_ack, uint8_t length, int8_t power, int8_t lqi)
{
(void) length;
@@ -449,9 +464,9 @@ __WEAK void nrf_drv_radio802154_transmitted_raw(uint8_t * p_ack, int8_t power, i
lqi);
}
__WEAK void nrf_drv_radio802154_busy_channel(void)
__WEAK void nrf_drv_radio802154_transmit_failed(nrf_drv_radio802154_tx_error_t error)
{
// Intentionally empty
(void) error;
}
__WEAK void nrf_drv_radio802154_energy_detected(uint8_t result)
@@ -64,15 +64,38 @@ typedef enum
NRF_DRV_RADIO802154_STATE_CONTINUOUS_CARRIER,
} nrf_drv_radio802154_state_t;
/**
* Errors reported during frame transmission.
*/
typedef enum
{
NRF_DRV_RADIO802154_TX_ERROR_BUSY_CHANNEL, /**< CCA reported busy channel prior to transmission. */
NRF_DRV_RADIO802154_TX_ERROR_INVALID_ACK, /**< Received ACK frame is other than expected. */
NRF_DRV_RADIO802154_TX_ERROR_NO_MEM, /**< No receive buffer are available to receive an ACK. */
NRF_DRV_RADIO802154_TX_ERROR_TIMESLOT_ENDED, /**< Radio timeslot ended during transmission procedure. */
} nrf_drv_radio802154_tx_error_t;
/**
* @brief Possible errors during frame reception.
*/
typedef enum
{
NRF_DRV_RADIO802154_RX_ERROR_INVALID_FRAME, /**< Received a malformed frame */
NRF_DRV_RADIO802154_RX_ERROR_INVALID_FCS, /**< Received a frame with invalid checksum. */
NRF_DRV_RADIO802154_RX_ERROR_INVALID_DEST_ADDR, /**< Received a frame with mismatched destination address. */
NRF_DRV_RADIO802154_RX_ERROR_RUNTIME, /**< A runtime error occured (e.g. CPU was hold for too long.) */
NRF_DRV_RADIO802154_RX_ERROR_TIMESLOT_ENDED, /**< Radio timeslot ended during frame reception. */
} nrf_drv_radio802154_rx_error_t;
/**
* @brief Structure for configuring CCA.
*/
typedef struct
{
nrf_radio_cca_mode_t mode; ///< CCA mode.
uint8_t ed_threshold; ///< CCA Energy Busy Threshold. Not used in NRF_RADIO_CCA_MODE_CARRIER.
uint8_t corr_threshold; ///< CCA Correlator Busy Threshold. Not used in NRF_RADIO_CCA_MODE_ED.
uint8_t corr_limit; ///< Limit of occurrences above CCA Correlator Busy Threshold. Not used in NRF_RADIO_CCA_MODE_ED.
nrf_radio_cca_mode_t mode; /**< CCA mode. */
uint8_t ed_threshold; /**< CCA Energy Busy Threshold. Not used in NRF_RADIO_CCA_MODE_CARRIER. */
uint8_t corr_threshold; /**< CCA Correlator Busy Threshold. Not used in NRF_RADIO_CCA_MODE_ED. */
uint8_t corr_limit; /**< Limit of occurrences above CCA Correlator Busy Threshold. Not used in NRF_RADIO_CCA_MODE_ED. */
} nrf_drv_radio802154_cca_cfg_t;
/**
@@ -262,7 +285,7 @@ void nrf_drv_radio802154_receive(void);
* @note This function should be called in Receive state. In other states transmission will not be
* scheduled.
* @note If the CPU was halted or interrupted during performing this function
* @sa nrf_drv_radio802154_transmitted() or @sa nrf_drv_radio802154_busy_channel() may be
* @sa nrf_drv_radio802154_transmitted() or @sa nrf_drv_radio802154_transmit_failed() may be
* called before nrf_drv_radio802154_transmit_raw() returns result.
* @note This function is implemented in zero-copy fashion. It passes given buffer pointer to
* the RADIO peripheral.
@@ -271,7 +294,7 @@ void nrf_drv_radio802154_receive(void);
* Radio driver waits infinitely for ACK frame. Higher layer is responsible to call
* @sa nrf_radio802154_receive() after ACK timeout.
* Transmission result is reported to higher layer by @sa nrf_radio802154_transmitted() or
* @sa nrf_radio802154_busy_channel() calls.
* @sa nrf_radio802154_transmit_failed() calls.
*
* p_data
* v
@@ -298,7 +321,7 @@ bool nrf_drv_radio802154_transmit_raw(const uint8_t *p_data, bool cca);
* @note This function should be called in Receive state. In other states transmission will not be
* scheduled.
* @note If the CPU was halted or interrupted during performing this function
* @sa nrf_drv_radio802154_transmitted() or @sa nrf_drv_radio802154_busy_channel() may be
* @sa nrf_drv_radio802154_transmitted() or @sa nrf_drv_radio802154_transmit_failed() may be
* called before nrf_drv_radio802154_transmit() returns result.
* @note This function makes copy of given buffer. There is an internal buffer maintained by this
* function. It is used to make a frame copy. To prevent unnecessary memory consumption and
@@ -309,7 +332,7 @@ bool nrf_drv_radio802154_transmit_raw(const uint8_t *p_data, bool cca);
* Radio driver waits infinitely for ACK frame. Higher layer is responsible to call
* @sa nrf_radio802154_receive() after ACK timeout.
* Transmission result is reported to higher layer by @sa nrf_radio802154_transmitted() or
* @sa nrf_radio802154_busy_channel() calls.
* @sa nrf_radio802154_transmit_failed() calls.
*
* p_data
* v
@@ -390,6 +413,13 @@ bool nrf_drv_radio802154_continuous_carrier(void);
*/
extern void nrf_drv_radio802154_rx_started(void);
/**
* @brief Notify that transmitting ACK frame has started.
*
* @note This function should be very short to prevent dropping frames by the driver.
*/
extern void nrf_drv_radio802154_tx_ack_started(void);
/**
* @brief Notify that frame was received.
*
@@ -442,6 +472,13 @@ extern void nrf_drv_radio802154_received_raw(uint8_t * p_data, int8_t power, int
*/
extern void nrf_drv_radio802154_received(uint8_t * p_data, uint8_t length, int8_t power, int8_t lqi);
/**
* @brief Notify that reception of a frame failed.
*
* @param[in] error An error code that indicates reason of the failure.
*/
extern void nrf_drv_radio802154_receive_failed(nrf_drv_radio802154_rx_error_t error);
/**
* @brief Notify that transmitting frame has started.
*
@@ -451,6 +488,15 @@ extern void nrf_drv_radio802154_received(uint8_t * p_data, uint8_t length, int8_
*/
extern void nrf_drv_radio802154_tx_started(void);
/**
* @brief Notify that receiving ACK frame has started.
*
* @note It is possible that the frame being received is not expected ACK and
* @sa nrf_drv_radio802154_transmitted won't be called.
* @note This function should be very short to prevent dropping frames by the driver.
*/
extern void nrf_drv_radio802154_rx_ack_started(void);
/**
* @brief Notify that frame was transmitted.
*
@@ -501,9 +547,11 @@ extern void nrf_drv_radio802154_transmitted(uint8_t * p_ack, uint8_t length, int
/**
* @brief Notify that frame was not transmitted due to busy channel.
*
* This function is called if CCA procedure (performed just before transmission) fails.
* This function is called if transmission procedure fails.
*
* @param[in] error Reason of the failure.
*/
extern void nrf_drv_radio802154_busy_channel(void);
extern void nrf_drv_radio802154_transmit_failed(nrf_drv_radio802154_tx_error_t error);
/**
* @brief Notify that Energy Detection procedure finished.
@@ -633,7 +633,13 @@ void nrf_raal_timeslot_ended(void)
case RADIO_STATE_CCA_BEFORE_TX:
case RADIO_STATE_TX_FRAME:
case RADIO_STATE_RX_ACK:
nrf_drv_radio802154_notify_busy_channel();
nrf_drv_radio802154_notify_transmit_failed(NRF_DRV_RADIO802154_TX_ERROR_TIMESLOT_ENDED);
break;
case RADIO_STATE_RX_HEADER:
case RADIO_STATE_RX_FRAME:
case RADIO_STATE_TX_ACK:
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_TIMESLOT_ENDED);
break;
default:
@@ -689,6 +695,7 @@ static inline void irq_framestart_state_waiting_rx_frame(void)
nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH);
nrf_radio_event_clear(NRF_RADIO_EVENT_END);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_FRAME);
}
else
{
@@ -718,6 +725,7 @@ static inline void irq_framestart_state_waiting_rx_frame(void)
nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH);
nrf_radio_event_clear(NRF_RADIO_EVENT_END);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_RUNTIME);
break;
default:
@@ -733,7 +741,7 @@ static inline void irq_framestart_state_rx_ack(void)
if ((mp_current_rx_buffer->psdu[0] < ACK_LENGTH) ||
(mp_current_rx_buffer->psdu[0] > MAX_PACKET_SIZE))
{
nrf_drv_radio802154_notify_busy_channel();
nrf_drv_radio802154_notify_transmit_failed(NRF_DRV_RADIO802154_TX_ERROR_INVALID_ACK);
frame_rx_start_after_ack_rx();
nrf_radio_event_clear(NRF_RADIO_EVENT_END); // In case frame ended before task DISABLE
@@ -741,6 +749,8 @@ static inline void irq_framestart_state_rx_ack(void)
else
{
nrf_radio_task_trigger(NRF_RADIO_TASK_RSSISTART);
nrf_drv_radio802154_rx_ack_started();
}
}
@@ -750,6 +760,12 @@ static inline void irq_framestart_state_tx_frame(void)
nrf_drv_radio802154_tx_started();
}
/// This event is handled when the radio starts transmitting an ACK frame.
static inline void irq_framestart_state_tx_ack(void)
{
nrf_drv_radio802154_tx_ack_started();
}
/// This event is handled when MHR is received
static inline void irq_bcmatch_mhr(void)
{
@@ -758,8 +774,10 @@ static inline void irq_bcmatch_mhr(void)
mp_current_rx_buffer->psdu[0],
ack_is_requested(mp_current_rx_buffer->psdu))))
{
uint8_t frame_type = mp_current_rx_buffer->psdu[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK;
// Check Frame Control field.
switch (mp_current_rx_buffer->psdu[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK)
switch (frame_type)
{
case FRAME_TYPE_BEACON:
// Beacon is broadcast frame.
@@ -786,6 +804,7 @@ static inline void irq_bcmatch_mhr(void)
auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME);
nrf_radio_event_clear(NRF_RADIO_EVENT_END);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_FRAME);
}
break;
@@ -804,6 +823,11 @@ static inline void irq_bcmatch_mhr(void)
auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME);
nrf_radio_event_clear(NRF_RADIO_EVENT_END);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
// Do not count received ACK as an error.
if (frame_type != FRAME_TYPE_ACK)
{
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_FRAME);
}
}
}
}
@@ -813,6 +837,8 @@ static inline void irq_bcmatch_mhr(void)
nrf_radio_reset();
state_set(RADIO_STATE_WAITING_TIMESLOT);
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_TIMESLOT_ENDED);
}
}
@@ -836,6 +862,7 @@ static inline void irq_bcmatch_address(void)
auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME);
nrf_radio_event_clear(NRF_RADIO_EVENT_END);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_DEST_ADDR);
}
}
}
@@ -878,6 +905,7 @@ static inline void irq_bcmatch_state_rx_header(void)
auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME);
nrf_radio_event_clear(NRF_RADIO_EVENT_END);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_RUNTIME);
break;
default:
@@ -913,6 +941,7 @@ static inline void irq_end_state_rx_header(void)
// Frame ended before header was received.
auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_FRAME);
}
/// This event is generated when radio peripheral ends receiving of a complete frame.
@@ -947,6 +976,7 @@ static inline void irq_end_state_rx_frame(void)
{
auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_INVALID_FCS);
}
break;
@@ -955,6 +985,7 @@ static inline void irq_end_state_rx_frame(void)
// CPU was hold too long.
auto_ack_abort(RADIO_STATE_WAITING_RX_FRAME);
nrf_radio_event_clear(NRF_RADIO_EVENT_READY);
nrf_drv_radio802154_notify_receive_failed(NRF_DRV_RADIO802154_RX_ERROR_RUNTIME);
break;
default:
@@ -1026,7 +1057,7 @@ static inline void irq_end_state_rx_ack(void)
}
else
{
nrf_drv_radio802154_notify_busy_channel();
nrf_drv_radio802154_notify_transmit_failed(NRF_DRV_RADIO802154_TX_ERROR_INVALID_ACK);
}
frame_rx_start_after_ack_rx();
@@ -1255,7 +1286,7 @@ static inline void irq_ready_state_rx_ack(void)
if (mp_current_rx_buffer == NULL || (!mp_current_rx_buffer->free))
{
nrf_drv_radio802154_notify_busy_channel();
nrf_drv_radio802154_notify_transmit_failed(NRF_DRV_RADIO802154_TX_ERROR_NO_MEM);
frame_rx_start_after_ack_rx();
}
else
@@ -1317,7 +1348,7 @@ static inline void irq_ccabusy_state_tx_frame(void)
shorts_disable();
nrf_drv_radio802154_notify_busy_channel();
nrf_drv_radio802154_notify_transmit_failed(NRF_DRV_RADIO802154_TX_ERROR_BUSY_CHANNEL);
state_set(RADIO_STATE_WAITING_RX_FRAME);
nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE);
@@ -1387,11 +1418,14 @@ static inline void irq_handler(void)
break;
case RADIO_STATE_TX_FRAME:
case RADIO_STATE_CCA_BEFORE_TX: // This could happen at the beginning of transmission procedure.
irq_framestart_state_tx_frame();
break;
case RADIO_STATE_TX_ACK:
case RADIO_STATE_CCA_BEFORE_TX: // This could happen at the beginning of transmission procedure.
irq_framestart_state_tx_ack();
break;
case RADIO_STATE_WAITING_TIMESLOT:
break;
@@ -34,6 +34,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -59,6 +61,13 @@ void nrf_drv_radio802154_notification_init(void);
*/
void nrf_drv_radio802154_notify_received(uint8_t * p_data, int8_t power, int8_t lqi);
/**
* @brief Notify next higher layer that reception of a frame failed.
*
* @param[in] error An error code that indicates reason of the failure.
*/
void nrf_drv_radio802154_notify_receive_failed(nrf_drv_radio802154_rx_error_t error);
/**
* @brief Notify next higher layer that a frame was transmitted.
*
@@ -70,8 +79,10 @@ void nrf_drv_radio802154_notify_transmitted(uint8_t * p_ack, int8_t power, int8_
/**
* @brief Notify next higher layer that a frame was not transmitted.
*
* @param[in] error An error code indicating reason of the failure.
*/
void nrf_drv_radio802154_notify_busy_channel(void);
void nrf_drv_radio802154_notify_transmit_failed(nrf_drv_radio802154_tx_error_t error);
/**
* @brief Notify next higher layer that energy detection procedure ended.
@@ -51,14 +51,19 @@ void nrf_drv_radio802154_notify_received(uint8_t * p_data, int8_t power, int8_t
nrf_drv_radio802154_received_raw(p_data, power, lqi);
}
void nrf_drv_radio802154_notify_receive_failed(nrf_drv_radio802154_rx_error_t error)
{
nrf_drv_radio802154_receive_failed(error);
}
void nrf_drv_radio802154_notify_transmitted(uint8_t * p_ack, int8_t power, int8_t lqi)
{
nrf_drv_radio802154_transmitted_raw(p_ack, power, lqi);
}
void nrf_drv_radio802154_notify_busy_channel(void)
void nrf_drv_radio802154_notify_transmit_failed(nrf_drv_radio802154_tx_error_t error)
{
nrf_drv_radio802154_busy_channel();
nrf_drv_radio802154_transmit_failed(error);
}
void nrf_drv_radio802154_notify_energy_detected(uint8_t result)
@@ -39,6 +39,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154.h"
#include "nrf_drv_radio802154_swi.h"
#include "raal/nrf_raal_api.h"
@@ -52,14 +53,19 @@ void nrf_drv_radio802154_notify_received(uint8_t * p_data, int8_t power, int8_t
nrf_drv_radio802154_swi_notify_received(p_data, power, lqi);
}
void nrf_drv_radio802154_notify_receive_failed(nrf_drv_radio802154_rx_error_t error)
{
nrf_drv_radio802154_swi_notify_receive_failed(error);
}
void nrf_drv_radio802154_notify_transmitted(uint8_t * p_ack, int8_t power, int8_t lqi)
{
nrf_drv_radio802154_swi_notify_transmitted(p_ack, power, lqi);
}
void nrf_drv_radio802154_notify_busy_channel(void)
void nrf_drv_radio802154_notify_transmit_failed(nrf_drv_radio802154_tx_error_t error)
{
nrf_drv_radio802154_swi_notify_busy_channel();
nrf_drv_radio802154_swi_notify_transmit_failed(error);
}
void nrf_drv_radio802154_notify_energy_detected(uint8_t result)
@@ -82,8 +82,9 @@
typedef enum
{
NTF_TYPE_RECEIVED, ///< Frame received
NTF_TYPE_RECEIVE_FAILED, ///< Frame reception failed
NTF_TYPE_TRANSMITTED, ///< Frame transmitted
NTF_TYPE_CHANNEL_BUSY, ///< Frame transmission failure
NTF_TYPE_TRANSMIT_FAILED, ///< Frame transmission failure
NTF_TYPE_ENERGY_DETECTED, ///< Energy detection procedure ended
NTF_TYPE_CCA, ///< CCA procedure ended
} nrf_drv_radio802154_ntf_type_t;
@@ -96,28 +97,38 @@ typedef struct
{
struct
{
uint8_t * p_psdu; ///< Pointer to received frame PSDU.
int8_t power; ///< RSSI of received frame.
int8_t lqi; ///< LQI of received frame.
} received; ///< Received frame details.
uint8_t * p_psdu; ///< Pointer to received frame PSDU.
int8_t power; ///< RSSI of received frame.
int8_t lqi; ///< LQI of received frame.
} received; ///< Received frame details.
struct
{
uint8_t * p_psdu; ///< Pointer to received ACK PSDU or NULL.
int8_t power; ///< RSSI of received ACK or 0.
int8_t lqi; ///< LQI of received ACK or 0.
} transmitted; ///< Transmitted frame details.
uint8_t * p_psdu; ///< Pointer to received ACK PSDU or NULL.
int8_t power; ///< RSSI of received ACK or 0.
int8_t lqi; ///< LQI of received ACK or 0.
} transmitted; ///< Transmitted frame details.
struct
{
int8_t result; ///< Energy detection result.
} energy_detected; ///< Energy detection details.
nrf_drv_radio802154_tx_error_t error; ///< An error code that indicates reason of the failure.
} transmit_failed;
struct
{
bool result; ///< CCA result.
} cca; ///< CCA details.
} data; ///< Notification data depending on it's type.
nrf_drv_radio802154_rx_error_t error; ///< An error code that indicates reason of the failure.
} receive_failed;
struct
{
int8_t result; ///< Energy detection result.
} energy_detected; ///< Energy detection details.
struct
{
bool result; ///< CCA result.
} cca; ///< CCA details.
} data; ///< Notification data depending on it's type.
} nrf_drv_radio802154_ntf_data_t;
/// Type of requests in request queue.
@@ -372,6 +383,20 @@ void nrf_drv_radio802154_swi_notify_received(uint8_t * p_data, int8_t power, int
nrf_egu_task_trigger(SWI_EGU, NTF_TASK);
}
void nrf_drv_radio802154_swi_notify_receive_failed(nrf_drv_radio802154_rx_error_t error)
{
assert(!ntf_queue_is_full());
nrf_drv_radio802154_ntf_data_t * p_slot = &m_ntf_queue[m_ntf_w_ptr];
p_slot->type = NTF_TYPE_RECEIVE_FAILED;
p_slot->data.receive_failed.error = error;
ntf_queue_ptr_increment(&m_ntf_w_ptr);
nrf_egu_task_trigger(SWI_EGU, NTF_TASK);
}
void nrf_drv_radio802154_swi_notify_transmitted(uint8_t * p_data, int8_t power, int8_t lqi)
{
assert(!ntf_queue_is_full());
@@ -388,13 +413,14 @@ void nrf_drv_radio802154_swi_notify_transmitted(uint8_t * p_data, int8_t power,
nrf_egu_task_trigger(SWI_EGU, NTF_TASK);
}
void nrf_drv_radio802154_swi_notify_busy_channel(void)
void nrf_drv_radio802154_swi_notify_transmit_failed(nrf_drv_radio802154_tx_error_t error)
{
assert(!ntf_queue_is_full());
nrf_drv_radio802154_ntf_data_t * p_slot = &m_ntf_queue[m_ntf_w_ptr];
p_slot->type = NTF_TYPE_CHANNEL_BUSY;
p_slot->type = NTF_TYPE_TRANSMIT_FAILED;
p_slot->data.transmit_failed.error = error;
ntf_queue_ptr_increment(&m_ntf_w_ptr);
@@ -545,14 +571,18 @@ void SWI_IRQHandler(void)
p_slot->data.received.lqi);
break;
case NTF_TYPE_RECEIVE_FAILED:
nrf_drv_radio802154_receive_failed(p_slot->data.receive_failed.error);
break;
case NTF_TYPE_TRANSMITTED:
nrf_drv_radio802154_transmitted_raw(p_slot->data.transmitted.p_psdu,
p_slot->data.transmitted.power,
p_slot->data.transmitted.lqi);
break;
case NTF_TYPE_CHANNEL_BUSY:
nrf_drv_radio802154_busy_channel();
case NTF_TYPE_TRANSMIT_FAILED:
nrf_drv_radio802154_transmit_failed(p_slot->data.transmit_failed.error);
break;
case NTF_TYPE_ENERGY_DETECTED:
@@ -34,6 +34,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_radio802154.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -59,6 +61,13 @@ void nrf_drv_radio802154_swi_init(void);
*/
void nrf_drv_radio802154_swi_notify_received(uint8_t * p_data, int8_t power, int8_t lqi);
/**
* @brief Notify next higher layer that reception of a frame failed.
*
* @param[in] error An error code that indicates reason of the failure.
*/
void nrf_drv_radio802154_swi_notify_receive_failed(nrf_drv_radio802154_rx_error_t error);
/**
* @brief Notify next higher layer that a frame was transmitted from SWI priority level.
*
@@ -70,8 +79,10 @@ void nrf_drv_radio802154_swi_notify_transmitted(uint8_t * p_data, int8_t power,
/**
* @brief Notify next higher layer that a frame was not transmitted from SWI priority level.
*
* @param[in] error Reason of the transmission failure.
*/
void nrf_drv_radio802154_swi_notify_busy_channel(void);
void nrf_drv_radio802154_swi_notify_transmit_failed(nrf_drv_radio802154_tx_error_t error);
/**
* @brief Notify next higher layer that energy detection procedure ended from SWI priority level.