drivers: nrf_802154: Update the IEEE 802.15.4 component

This commit updates the nRF 802.15.4 radio driver to feature
the latest changes.

sdk-nrf-802154 commit: 453044a0e97ec2c8fa2d6d0135a093cbc5362eb2

Signed-off-by: Andrzej Kuros <andrzej.kuros@nordicsemi.no>
This commit is contained in:
Andrzej Kuros 2021-12-21 18:11:29 +01:00 committed by Marti Bolivar
parent b1db86f188
commit c081c7be7c
78 changed files with 5331 additions and 912 deletions

View File

@ -52,6 +52,7 @@ target_sources(nrf-802154-driver
src/nrf_802154_debug_assert.c
src/nrf_802154_encrypt.c
src/nrf_802154_pib.c
src/nrf_802154_peripherals_alloc.c
src/nrf_802154_queue.c
src/nrf_802154_rssi.c
src/nrf_802154_rx_buffer.c
@ -91,7 +92,7 @@ else ()
)
endif ()
if (SL_OPENSOURCE OR NRF53_SERIES)
if (SL_OPENSOURCE)
target_compile_definitions(nrf-802154-driver-interface
INTERFACE
# Disable Frame Timestamps
@ -100,8 +101,20 @@ if (SL_OPENSOURCE OR NRF53_SERIES)
NRF_802154_DELAYED_TRX_ENABLED=0
# Disable IFS
NRF_802154_IFS_ENABLED=0
# Disable IE writer
NRF_802154_IE_WRITER_ENABLED=0
)
elseif (NRF53_SERIES)
target_compile_definitions(nrf-802154-driver-interface
INTERFACE
# Disable IFS
NRF_802154_IFS_ENABLED=0
)
endif()
if (NRF_802154_PROJECT_CONFIG)
target_compile_definitions(nrf-802154-driver-interface
INTERFACE
# Propagate project config from build system defines
NRF_802154_PROJECT_CONFIG="${NRF_802154_PROJECT_CONFIG}"
)
endif()

View File

@ -102,11 +102,12 @@ void nrf_802154_deinit(void);
*/
extern void nrf_802154_custom_part_of_radio_init(void);
#if !NRF_802154_INTERNAL_RADIO_IRQ_HANDLING
#if !NRF_802154_INTERNAL_RADIO_IRQ_HANDLING || defined(DOXYGEN)
/**
* @brief Handles the interrupt request from the RADIO peripheral.
*
* @note If NRF_802154_INTERNAL_RADIO_IRQ_HANDLING is enabled, the driver internally handles the
* @note If @ref NRF_802154_INTERNAL_RADIO_IRQ_HANDLING is enabled, the driver internally handles the
* RADIO IRQ, and this function must not be called.
*
* This function is intended for use in an operating system environment, where the OS handles IRQ
@ -114,13 +115,15 @@ extern void nrf_802154_custom_part_of_radio_init(void);
* radio IRQ to the driver (that is, SoftDevice).
*/
void nrf_802154_radio_irq_handler(void);
#endif // !NRF_802154_INTERNAL_RADIO_IRQ_HANDLING
#if !NRF_802154_INTERNAL_SWI_IRQ_HANDLING
#if !NRF_802154_INTERNAL_SWI_IRQ_HANDLING || defined(DOXYGEN)
/**
* @brief Handles the interrupt request from the RADIO peripheral.
*
* @note If NRF_802154_INTERNAL_SWI_IRQ_HANDLING is enabled, the driver internally handles the
* @note If @ref NRF_802154_INTERNAL_SWI_IRQ_HANDLING is enabled, the driver internally handles the
* SWI IRQ, and this function must not be called.
*
* This function is intended for use in an operating system environment, where the OS handles IRQ
@ -128,6 +131,7 @@ void nrf_802154_radio_irq_handler(void);
* radio IRQ to the driver (that is, SoftDevice).
*/
void nrf_802154_swi_irq_handler(void);
#endif // !NRF_802154_INTERNAL_SWI_IRQ_HANDLING
/**
@ -204,8 +208,8 @@ nrf_802154_sl_ant_div_mode_t nrf_802154_antenna_diversity_tx_mode_get(void);
* @brief Manually selects the antenna to be used for rx.
*
* For antenna to be switched, antenna diversity rx mode needs
* to be @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, antenna will
* be only switched after @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL is set.
* to be @c NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, antenna will
* be only switched after @c NRF_802154_SL_ANT_DIV_MODE_MANUAL is set.
*
* @param[in] antenna Antenna to be used.
*
@ -218,9 +222,8 @@ bool nrf_802154_antenna_diversity_rx_antenna_set(nrf_802154_sl_ant_div_antenna_t
* @brief Gets antenna currently used for rx.
*
* @note The antenna read by this function is currently used rx antenna only if
* antenna diversity rx mode is set to @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise,
* antenna diversity rx mode is set to @c NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise,
* currently used antenna may be different.
* @sa nrf_802154_sl_ant_div_mode_set
*
* @return Currently used antenna.
*/
@ -230,8 +233,8 @@ nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_rx_antenna_get(void
* @brief Manually selects the antenna to be used for tx.
*
* For antenna to be switched, antenna diversity tx mode needs
* to be @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, antenna will
* be only switched after @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL is set.
* to be @c NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, antenna will
* be only switched after @c NRF_802154_SL_ANT_DIV_MODE_MANUAL is set.
*
* @param[in] antenna Antenna to be used.
*
@ -244,9 +247,8 @@ bool nrf_802154_antenna_diversity_tx_antenna_set(nrf_802154_sl_ant_div_antenna_t
* @brief Gets antenna currently used for tx.
*
* @note The antenna read by this function is currently used tx antenna only if
* antenna diversity tx mode is set to @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise,
* antenna diversity tx mode is set to @c NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise,
* currently used antenna may be different.
* @sa nrf_802154_sl_ant_div_mode_set
*
* @return Currently used antenna.
*/
@ -255,7 +257,7 @@ nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_tx_antenna_get(void
/**
* @brief Gets which antenna was selected as best for the last reception.
*
* @note In three cases @ref NRF_802154_SL_ANT_DIV_ANTENNA_NONE may be returned:
* @note In three cases @c NRF_802154_SL_ANT_DIV_ANTENNA_NONE may be returned:
* - No frame was received yet.
* - Last frame was received with antenna diversity auto mode disabled.
* - RSSI measurements didn't have enough time to finish during last frame reception
@ -327,14 +329,13 @@ void nrf_802154_antenna_diversity_timer_irq_handler(void);
* @brief Gets the current time.
*
* The time returned by this function is to be used to calculate timing parameters for
* @ref nrf_802154_transmit_at and @ref nrf_802154_receive_at functions.
* @ref nrf_802154_transmit_raw_at and @ref nrf_802154_receive_at functions.
*
* @returns Current time in microseconds.
*/
uint32_t nrf_802154_time_get(void);
/**
* @}
* @defgroup nrf_802154_addresses Setting addresses and PAN ID of the device
* @{
*/
@ -462,7 +463,7 @@ bool nrf_802154_receive(void);
* This function works as a delayed version of @ref nrf_802154_receive. It is asynchronous.
* It queues the delayed reception using the Radio Scheduler module.
* If the delayed reception cannot be performed (@ref nrf_802154_receive_at would return false)
* or the requested reception timeslot is denied, @ref nrf_drv_radio802154_receive_failed is called
* or the requested reception timeslot is denied, @ref nrf_802154_receive_failed is called
* with the @ref NRF_802154_RX_ERROR_DELAYED_TIMESLOT_DENIED argument.
*
* If the requested reception time is in the past, the function returns false and does not
@ -509,23 +510,26 @@ bool nrf_802154_receive_at(uint32_t t0,
*/
bool nrf_802154_receive_at_cancel(uint32_t id);
#if NRF_802154_USE_RAW_API
#if NRF_802154_USE_RAW_API || defined(DOXYGEN)
/**
* @brief Changes the radio state to @ref RADIO_STATE_TX.
*
* @note If the CPU is halted or interrupted while this function is executed,
* @ref nrf_802154_transmitted or @ref nrf_802154_transmit_failed can be called before this
* @ref nrf_802154_transmitted_raw or @ref nrf_802154_transmit_failed can be called before this
* function returns a result.
*
* @note This function is implemented in zero-copy fashion. It passes the given buffer pointer to
* the RADIO peripheral.
*
* @note This function is available if @ref NRF_802154_USE_RAW_API is enabled.
*
* In the transmit state, the radio transmits a given frame. If requested, it waits for
* an ACK frame. Depending on @ref NRF_802154_ACK_TIMEOUT_ENABLED, the radio driver automatically
* stops waiting for an ACK frame or waits indefinitely for an ACK frame. If it is configured to
* wait, the MAC layer is responsible for calling @ref nrf_802154_receive or
* @ref nrf_802154_sleep after the ACK timeout.
* The transmission result is reported to the higher layer by calls to @ref nrf_802154_transmitted
* The transmission result is reported to the higher layer by calls to @ref nrf_802154_transmitted_raw
* or @ref nrf_802154_transmit_failed.
*
* @verbatim
@ -543,8 +547,11 @@ bool nrf_802154_receive_at_cancel(uint32_t id);
* The CRC is computed automatically by the radio hardware. Therefore,
* the FCS field can contain any bytes.
* @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data
* to transmit and additional parameters for the procedure.
* If NULL, @ref NRF_802154_TRANSMIT_METADATA_DEFAULT_INIT is used.
* to transmit. If @c NULL following metadata are used:
* Field | Value
* ----------------|-----------------------------------------------------
* @c frame_props | @ref NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT
* @c cca | @c true
*
* @retval true The transmission procedure was scheduled.
* @retval false The driver could not schedule the transmission procedure.
@ -552,7 +559,9 @@ bool nrf_802154_receive_at_cancel(uint32_t id);
bool nrf_802154_transmit_raw(uint8_t * p_data,
const nrf_802154_transmit_metadata_t * p_metadata);
#else // NRF_802154_USE_RAW_API
#endif // NRF_802154_USE_RAW_API
#if !NRF_802154_USE_RAW_API || defined(DOXYGEN)
/**
* @brief Changes the radio state to transmit.
@ -565,6 +574,8 @@ bool nrf_802154_transmit_raw(uint8_t * p_data,
* make a frame copy. To prevent unnecessary memory consumption and to perform zero-copy
* transmission, use @ref nrf_802154_transmit_raw instead.
*
* @note This function is available if @ref NRF_802154_USE_RAW_API is disabled.
*
* In the transmit state, the radio transmits a given frame. If requested, it waits for
* an ACK frame. Depending on @ref NRF_802154_ACK_TIMEOUT_ENABLED, the radio driver automatically
* stops waiting for an ACK frame or waits indefinitely for an ACK frame. If it is configured to
@ -588,8 +599,11 @@ bool nrf_802154_transmit_raw(uint8_t * p_data,
* @param[in] length Length of the given frame. This value must exclude PHR and FCS fields
* from the given frame (exact size of buffer pointed to by @p p_data).
* @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data
* to transmit and additional parameters for the procedure.
* If NULL, @ref NRF_802154_TRANSMIT_METADATA_DEFAULT_INIT is used.
* to transmit. If @c NULL following metadata are used:
* Field | Value
* ----------------|-----------------------------------------------------
* @c frame_props | @ref NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT
* @c cca | @c true
*
* @retval true The transmission procedure was scheduled.
* @retval false The driver could not schedule the transmission procedure.
@ -598,7 +612,7 @@ bool nrf_802154_transmit(const uint8_t * p_data,
uint8_t length,
const nrf_802154_transmit_metadata_t * p_metadata);
#endif // NRF_802154_USE_RAW_API
#endif // !NRF_802154_USE_RAW_API
/**
* @brief Requests transmission at the specified time.
@ -606,18 +620,19 @@ bool nrf_802154_transmit(const uint8_t * p_data,
* @note This function is implemented in a zero-copy fashion. It passes the given buffer pointer to
* the RADIO peripheral.
*
*
* This function works as a delayed version of @ref nrf_802154_transmit_raw. It is asynchronous.
* It queues the delayed transmission using the Radio Scheduler module and performs it
* at the specified time.
*
* If the delayed transmission is successfully performed, @ref nrf_802154_transmitted is called.
* If the delayed transmission cannot be performed (@ref nrf_802154_transmit_raw would return false)
* If the delayed transmission is successfully performed, @ref nrf_802154_transmitted_raw is called.
* If the delayed transmission cannot be performed ( @ref nrf_802154_transmit_raw would return @c false)
* or the requested transmission timeslot is denied, @ref nrf_802154_transmit_failed with the
* @ref NRF_802154_TX_ERROR_TIMESLOT_DENIED argument is called.
*
* This function is designed to transmit the first symbol of SHR at the given time.
*
* If the requested transmission time is in the past, the function returns false and does not
* If the requested transmission time is in the past, the function returns @c false and does not
* schedule transmission.
*
* A successfully scheduled transmission can be cancelled by a call
@ -631,8 +646,12 @@ bool nrf_802154_transmit(const uint8_t * p_data,
* in microseconds (us).
* @param[in] dt Delta of delay time from @p t0, in microseconds (us).
* @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data
* to transmit and additional parameters for the procedure.
* If NULL, @ref NRF_802154_TRANSMIT_METADATA_DEFAULT_INIT is used.
* to transmit. If @c NULL following metadata are used:
* Field | Value
* ----------------|-----------------------------------------------------
* @c frame_props | @ref NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT
* @c cca | @c true
* @c channel | As returned by @ref nrf_802154_channel_get
*
* @retval true The transmission procedure was scheduled.
* @retval false The driver could not schedule the transmission procedure.
@ -691,6 +710,8 @@ bool nrf_802154_energy_detection(uint32_t time_us);
*/
bool nrf_802154_cca(void);
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Changes the radio state to continuous carrier.
*
@ -723,6 +744,8 @@ bool nrf_802154_modulated_carrier(const uint8_t * p_data);
* @{
*/
#endif
/**
* @brief Notifies about the start of the ACK frame transmission.
*
@ -732,7 +755,7 @@ bool nrf_802154_modulated_carrier(const uint8_t * p_data);
*/
extern void nrf_802154_tx_ack_started(const uint8_t * p_data);
#if NRF_802154_USE_RAW_API
#if NRF_802154_USE_RAW_API || defined(DOXYGEN)
/**
* @brief Notifies that a frame was received.
@ -741,6 +764,9 @@ extern void nrf_802154_tx_ack_started(const uint8_t * p_data);
* to receive a frame) until @ref nrf_802154_buffer_free_raw is called.
* @note The buffer pointed to by @p p_data may be modified by the function handler (and other
* modules) until @ref nrf_802154_buffer_free_raw is called.
* @note This callout is called by the nRF 802.15.4 Radio Driver if @ref NRF_802154_USE_RAW_API
* is enabled. Default implementation of this function provided by
* the nRF 802.15.4 Radio Driver calls @ref nrf_802154_received_timestamp_raw .
*
* @verbatim
* p_data
@ -771,6 +797,8 @@ extern void nrf_802154_received_raw(uint8_t * p_data, int8_t power, uint8_t lqi)
* the timestamp may be invalid. This erroneous situation is indicated by
* the @ref NRF_802154_NO_TIMESTAMP value of the @p time parameter.
*
* @note This callout is called by the default implementation of @ref nrf_802154_received_raw.
*
* @param[in] p_data Pointer to a buffer that contains PHR and PSDU of the received frame.
* The first byte in the buffer is the length of the frame (PHR). The following
* bytes contain the frame itself (PSDU). The length byte (PHR) includes FCS.
@ -786,8 +814,9 @@ extern void nrf_802154_received_timestamp_raw(uint8_t * p_data,
uint8_t lqi,
uint32_t time);
#else // NRF_802154_USE_RAW_API
#endif // NRF_802154_USE_RAW_API
#if !NRF_802154_USE_RAW_API || defined(DOXYGEN)
/**
* @brief Notifies that a frame was received.
*
@ -795,6 +824,9 @@ extern void nrf_802154_received_timestamp_raw(uint8_t * p_data,
* be used to receive a frame) until @ref nrf_802154_buffer_free is called.
* @note The buffer pointed to by @p p_data can be modified by the function handler (and other
* modules) until @ref nrf_802154_buffer_free is called.
* @note This callout is called by the nRF 802.15.4 Radio Driver if @ref NRF_802154_USE_RAW_API
* is disabled. Default implementation of this function provided by
* the nRF 802.15.4 Radio Driver calls @ref nrf_802154_received_timestamp .
*
* @verbatim
* p_data
@ -822,6 +854,7 @@ extern void nrf_802154_received(uint8_t * p_data, uint8_t length, int8_t power,
* @note The received frame usually contains a timestamp. However, due to a race condition,
* the timestamp may be invalid. This erroneous situation is indicated by
* the @ref NRF_802154_NO_TIMESTAMP value of the @p time parameter.
* @note This callout is called by the default implementation of @ref nrf_802154_received .
*
* @param[in] p_data Pointer to a buffer that contains only the payload of the received frame
* (PSDU without FCS).
@ -865,23 +898,24 @@ extern void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id);
*/
extern void nrf_802154_tx_started(const uint8_t * p_frame);
#if NRF_802154_USE_RAW_API
#if NRF_802154_USE_RAW_API || defined(DOXYGEN)
/**
* @brief Notifies that a frame was transmitted.
*
* @note If ACK was requested for the transmitted frame, this function is called after a proper ACK
* is received. If ACK was not requested, this function is called just after transmission has
* ended.
* @note The buffer pointed to by @ref nrf_802154_transmit_done_metadata_t.data.transmitted.p_ack
* @note The buffer pointed to by @c nrf_802154_transmit_done_metadata_t::data.transmitted.p_ack
* is not modified by the radio driver (and cannot be used to receive a frame) until
* @ref nrf_802154_buffer_free_raw is called.
* @note The buffer pointed to by @ref nrf_802154_transmit_done_metadata_t.data.transmitted.p_ack
* @note The buffer pointed to by @c nrf_802154_transmit_done_metadata_t::data.transmitted.p_ack
* may be modified by the function handler (and other modules) until
* @ref nrf_802154_buffer_free_raw is called.
* @note @ref nrf_802154_transmit_done_metadata_t.data.transmitted.time granularity depends on the
* @note @c nrf_802154_transmit_done_metadata_t::data.transmitted.time granularity depends on the
* granularity of the timer driver in the
* platform/timer directory.
* @note This callout is called by the nRF 802.15.4 Radio Driver if @ref NRF_802154_USE_RAW_API
* is enabled.
*
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the transmitted frame.
* @param[in] p_metadata Pointer to a metadata structure describing frame passed in @p p_frame.
@ -889,26 +923,29 @@ extern void nrf_802154_tx_started(const uint8_t * p_frame);
extern void nrf_802154_transmitted_raw(uint8_t * p_frame,
const nrf_802154_transmit_done_metadata_t * p_metadata);
#else // NRF_802154_USE_RAW_API
#endif // NRF_802154_USE_RAW_API
#if !NRF_802154_USE_RAW_API || defined(DOXYGEN)
/**
* @brief Notifies that a frame was transmitted.
*
* @note If ACK was requested for the transmitted frame, this function is called after a proper ACK
* is received. If ACK was not requested, this function is called just after transmission has
* ended.
* @note The buffer pointed to by @ref nrf_802154_transmit_done_metadata_t.data.transmitted.p_ack
* @note The buffer pointed to by @c nrf_802154_transmit_done_metadata_t::data.transmitted.p_ack
* is not modified by the radio driver (and cannot be used to receive a frame) until
* @ref nrf_802154_buffer_free_raw is called.
* @note The buffer pointed to by @ref nrf_802154_transmit_done_metadata_t.data.transmitted.p_ack
* @ref nrf_802154_buffer_free is called.
* @note The buffer pointed to by @c nrf_802154_transmit_done_metadata_t::data.transmitted.p_ack
* may be modified by the function handler (and other modules) until
* @ref nrf_802154_buffer_free_raw is called.
* @ref nrf_802154_buffer_free is called.
* @note The next higher layer must handle either @ref nrf_802154_transmitted or
* @ref nrf_802154_transmitted_raw. It should not handle both functions.
* @note @ref nrf_802154_transmit_done_metadata_t.data.transmitted.time granularity depends on the
* @note @c nrf_802154_transmit_done_metadata_t::data.transmitted.time granularity depends on the
* granularity of the timer driver in the platform/timer directory.
* @note Including a timestamp for received frames uses resources like CPU time and memory. If the
* timestamp is not required, use @ref nrf_802154_received instead.
* @note This callout is called by the nRF 802.15.4 Radio Driver if @ref NRF_802154_USE_RAW_API
* is disabled.
*
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the transmitted frame.
* @param[in] p_metadata Pointer to a metadata structure describing frame passed in @p p_frame.
@ -923,7 +960,7 @@ extern void nrf_802154_transmitted(uint8_t * p
*
* This function is called if the transmission procedure fails.
*
* @note Frame data values in @ref nrf_802154_transmit_done_metadata_t.data are invalid for
* @note Frame data values in @ref nrf_802154_transmit_done_metadata_t::data are invalid for
* @ref nrf_802154_transmit_failed callout.
*
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame that was not
@ -973,7 +1010,7 @@ extern void nrf_802154_cca_failed(nrf_802154_cca_error_t error);
* @{
*/
#if NRF_802154_USE_RAW_API
#if NRF_802154_USE_RAW_API || defined(DOXYGEN)
/**
* @brief Notifies the driver that the buffer containing the received frame is not used anymore.
@ -981,6 +1018,7 @@ extern void nrf_802154_cca_failed(nrf_802154_cca_error_t error);
* @note The buffer pointed to by @p p_data may be modified by this function.
* @note This function can be safely called only from the main context. To free the buffer from
* a callback or the IRQ context, use @ref nrf_802154_buffer_free_immediately_raw.
* @note This function is available if @ref NRF_802154_USE_RAW_API is enabled.
*
* @param[in] p_data Pointer to the buffer containing the received data that is no longer needed
* by the higher layer.
@ -994,6 +1032,7 @@ void nrf_802154_buffer_free_raw(uint8_t * p_data);
* @note This function can be safely called from any context. If the driver is busy processing
* a request called from a context with lower priority, this function returns false and
* the caller should free the buffer later.
* @note This function is available if @ref NRF_802154_USE_RAW_API is enabled.
*
* @param[in] p_data Pointer to the buffer containing the received data that is no longer needed
* by the higher layer.
@ -1003,7 +1042,9 @@ void nrf_802154_buffer_free_raw(uint8_t * p_data);
*/
bool nrf_802154_buffer_free_immediately_raw(uint8_t * p_data);
#else // NRF_802154_USE_RAW_API
#endif // NRF_802154_USE_RAW_API
#if !NRF_802154_USE_RAW_API || defined(DOXYGEN)
/**
* @brief Notifies the driver that the buffer containing the received frame is not used anymore.
@ -1011,6 +1052,7 @@ bool nrf_802154_buffer_free_immediately_raw(uint8_t * p_data);
* @note The buffer pointed to by @p p_data may be modified by this function.
* @note This function can be safely called only from the main context. To free the buffer from
* a callback or IRQ context, use @ref nrf_802154_buffer_free_immediately.
* @note This function is available if @ref NRF_802154_USE_RAW_API is disabled.
*
* @param[in] p_data Pointer to the buffer containing the received data that is no longer needed
* by the higher layer.
@ -1024,6 +1066,7 @@ void nrf_802154_buffer_free(uint8_t * p_data);
* @note This function can be safely called from any context. If the driver is busy processing
* a request called from a context with lower priority, this function returns false and
* the caller should free the buffer later.
* @note This function is available if @ref NRF_802154_USE_RAW_API is disabled.
*
* @param[in] p_data Pointer to the buffer containing the received data that is no longer needed
* by the higher layer.
@ -1033,7 +1076,7 @@ void nrf_802154_buffer_free(uint8_t * p_data);
*/
bool nrf_802154_buffer_free_immediately(uint8_t * p_data);
#endif // NRF_802154_USE_RAW_API
#endif // !NRF_802154_USE_RAW_API
/**
* @}
@ -1145,10 +1188,6 @@ bool nrf_802154_pan_coord_get(void);
*
* @note This method should be called after driver initialization, but before transceiver is enabled.
*
* When calling @ref nrf_802154_ack_data_pending_bit_should_be_set, one of several algorithms
* for source address matching will be chosen. To ensure a specific algorithm is selected,
* call this function before @ref rf_802154_ack_data_pending_bit_should_be_set.
*
* @param[in] match_method Source address matching method to be used.
*/
void nrf_802154_src_addr_matching_method_set(nrf_802154_src_addr_match_t match_method);
@ -1185,6 +1224,7 @@ void nrf_802154_src_addr_matching_method_set(nrf_802154_src_addr_match_t match_m
* To better illustrate, if RSSI is to be inserted into ACKs for specific address,
* following ie data needs to be prepared:
*
* @verbatim
* +------------+----------------------+---------------------------------+-----------------------------+
* | Bytes: 0-1 | 2-4 | 5 | 6 |
* +------------+----------------------+---------------------------------+-----------------------------+
@ -1192,11 +1232,12 @@ void nrf_802154_src_addr_matching_method_set(nrf_802154_src_addr_match_t match_m
* +------------+----------------------+---------------------------------+-----------------------------+
* | |
* | <------------------IE Vendor-specific data------------------> |
* @endverbatim
*
* When sending ACK with this data, before transmission, RSSI of the last received frame
* will be written into byte 6.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @param[in] p_addr Array of bytes containing the address of the node (little-endian).
* @param[in] extended If the given address is an extended MAC address or a short MAC address.
@ -1225,7 +1266,7 @@ bool nrf_802154_ack_data_set(const uint8_t * p_addr,
* - For Standard-compliant, @ref NRF_802154_SRC_ADDR_MATCH_ALWAYS_1
* For more information, see @ref nrf_802154_src_addr_match_t.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @param[in] p_addr Array of bytes containing the address of the node (little-endian).
* @param[in] extended If the given address is an extended MAC address or a short MAC address.
@ -1269,7 +1310,7 @@ void nrf_802154_auto_pending_bit_set(bool enabled);
* - For Standard-compliant, @ref NRF_802154_SRC_ADDR_MATCH_ALWAYS_1
* For more information, see @ref nrf_802154_src_addr_match_t.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @note This function makes a copy of the given address.
*
@ -1291,7 +1332,7 @@ bool nrf_802154_pending_bit_for_addr_set(const uint8_t * p_addr, bool extended);
* - For Standard-compliant, @ref NRF_802154_SRC_ADDR_MATCH_ALWAYS_1
* For more information, see @ref nrf_802154_src_addr_match_t.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @param[in] p_addr Array of bytes containing the address of the node (little-endian).
* @param[in] extended If the given address is an extended MAC address or a short MAC address.
@ -1311,7 +1352,7 @@ bool nrf_802154_pending_bit_for_addr_clear(const uint8_t * p_addr, bool extended
* - For Standard-compliant, @ref NRF_802154_SRC_ADDR_MATCH_ALWAYS_1
* For more information, see @ref nrf_802154_src_addr_match_t.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @param[in] extended If the function is to remove all extended MAC addresses or all short
* addresses.
@ -1344,8 +1385,8 @@ void nrf_802154_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg);
* @defgroup nrf_802154_csma CSMA-CA procedure
* @{
*/
#if NRF_802154_CSMA_CA_ENABLED
#if NRF_802154_USE_RAW_API
#if NRF_802154_CSMA_CA_ENABLED || defined(DOXYGEN)
#if NRF_802154_USE_RAW_API || defined(DOXYGEN)
/**
* @brief Performs the CSMA-CA procedure and transmits a frame in case of success.
@ -1360,10 +1401,15 @@ void nrf_802154_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg);
* to time out waiting for the ACK frame. This timer can be started
* by @ref nrf_802154_tx_started. When the timer expires, the MAC layer is expected
* to call @ref nrf_802154_receive or @ref nrf_802154_sleep to stop waiting for the ACK frame.
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled and
* @ref NRF_802154_USE_RAW_API is enabled.
*
* @param[in] p_data Pointer to the frame to transmit. See also @ref nrf_802154_transmit_raw.
* @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data
* to transmit. If NULL, @ref NRF_802154_TRANSMIT_METADATA_DEFAULT_INIT is used.
* to transmit. If @c NULL following metadata are used:
* Field | Value
* ----------------|-----------------------------------------------------
* @c frame_props | @ref NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT
*
* @retval true The chain of CSMA-CA and transmission procedure was scheduled.
* @retval false The driver could not schedule the procedure chain.
@ -1386,12 +1432,16 @@ bool nrf_802154_transmit_csma_ca_raw(uint8_t
* to time out waiting for the ACK frame. This timer can be started
* by @ref nrf_802154_tx_started. When the timer expires, the MAC layer is expected
* to call @ref nrf_802154_receive or @ref nrf_802154_sleep to stop waiting for the ACK frame.
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled and
* @ref NRF_802154_USE_RAW_API is disabled.
*
* @param[in] p_data Pointer to the frame to transmit. See also @ref nrf_802154_transmit.
* @param[in] length Length of the given frame. See also @ref nrf_802154_transmit.
* @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data
* to transmit. If NULL, @ref NRF_802154_TRANSMIT_METADATA_DEFAULT_INIT
* is used.
* to transmit. If @c NULL following metadata are used:
* Field | Value
* ----------------|-----------------------------------------------------
* @c frame_props | @ref NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT
*
* @retval true The chain of CSMA-CA and transmission procedure was scheduled.
* @retval false The driver could not schedule the procedure chain.
@ -1405,6 +1455,8 @@ bool nrf_802154_transmit_csma_ca(const uint8_t *
/**
* @brief Sets the minimum value of the backoff exponent (BE) in the CSMA-CA algorithm.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @param[in] min_be Minimum value of the backoff exponent.
*
* @retval true When value provided by @p min_be has been set successfully.
@ -1415,6 +1467,8 @@ bool nrf_802154_csma_ca_min_be_set(uint8_t min_be);
/**
* @brief Gets the minimum value of the backoff exponent (BE) in the CSMA-CA algorithm.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @return Current minimum value of the backoff exponent.
*/
uint8_t nrf_802154_csma_ca_min_be_get(void);
@ -1422,6 +1476,8 @@ uint8_t nrf_802154_csma_ca_min_be_get(void);
/**
* @brief Sets the maximum value of the backoff exponent (BE) in the CSMA-CA algorithm.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @param[in] max_be Maximum value of the backoff exponent.
*
* @retval true When value provided by @p max_be has been set successfully.
@ -1432,6 +1488,8 @@ bool nrf_802154_csma_ca_max_be_set(uint8_t max_be);
/**
* @brief Gets the maximum value of the backoff exponent (BE) in the CSMA-CA algorithm.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @return Current maximum value of the backoff exponent.
*/
uint8_t nrf_802154_csma_ca_max_be_get(void);
@ -1440,6 +1498,8 @@ uint8_t nrf_802154_csma_ca_max_be_get(void);
* @brief Sets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring
* a channel access failure.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @param[in] max_backoffs Maximum number of backoffs.
*/
void nrf_802154_csma_ca_max_backoffs_set(uint8_t max_backoffs);
@ -1448,6 +1508,8 @@ void nrf_802154_csma_ca_max_backoffs_set(uint8_t max_backoffs);
* @brief Gets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring
* a channel access failure.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @return Current maximum number of backoffs.
*/
uint8_t nrf_802154_csma_ca_max_backoffs_get(void);
@ -1459,13 +1521,15 @@ uint8_t nrf_802154_csma_ca_max_backoffs_get(void);
* @defgroup nrf_802154_timeout ACK timeout procedure
* @{
*/
#if NRF_802154_ACK_TIMEOUT_ENABLED
#if NRF_802154_ACK_TIMEOUT_ENABLED || defined(DOXYGEN)
/**
* @brief Sets timeout for the ACK timeout feature.
*
* A timeout is notified by @ref nrf_802154_transmit_failed.
*
* @note This function is available if @ref NRF_802154_ACK_TIMEOUT_ENABLED is enabled.
*
* @param[in] time Timeout in microseconds (us).
* A default value is defined in nrf_802154_config.h.
*/
@ -1612,11 +1676,13 @@ void nrf_802154_stat_totals_get(nrf_802154_stat_totals_t * p_stat_totals);
* @defgroup nrf_802154_ifs Inter-frame spacing feature
* @{
*/
#if NRF_802154_IFS_ENABLED
#if NRF_802154_IFS_ENABLED || defined(DOXYGEN)
/**
* @brief Gets IFS operation mode.
*
* @note This function is available if @ref NRF_802154_IFS_ENABLED is enabled.
*
* @return Current IFS operation mode. Refer to @ref nrf_802154_ifs_mode_t for details.
*/
nrf_802154_ifs_mode_t nrf_802154_ifs_mode_get(void);
@ -1624,6 +1690,8 @@ nrf_802154_ifs_mode_t nrf_802154_ifs_mode_get(void);
/**
* @brief Sets IFS operation mode.
*
* @note This function is available if @ref NRF_802154_IFS_ENABLED is enabled.
*
* @param[in] mode IFS operation mode. Refer to @ref nrf_802154_ifs_mode_t for details.
*
* @retval true The update of IFS operation mode was successful.
@ -1634,6 +1702,8 @@ bool nrf_802154_ifs_mode_set(nrf_802154_ifs_mode_t mode);
/**
* @brief Gets Short IFS period in microseconds.
*
* @note This function is available if @ref NRF_802154_IFS_ENABLED is enabled.
*
* @return Current Short IFS period in microseconds.
*/
uint16_t nrf_802154_ifs_min_sifs_period_get(void);
@ -1641,6 +1711,8 @@ uint16_t nrf_802154_ifs_min_sifs_period_get(void);
/**
* @brief Sets Short IFS period in microseconds.
*
* @note This function is available if @ref NRF_802154_IFS_ENABLED is enabled.
*
* @param[in] period Short IFS period in microseconds.
*/
void nrf_802154_ifs_min_sifs_period_set(uint16_t period);
@ -1648,6 +1720,8 @@ void nrf_802154_ifs_min_sifs_period_set(uint16_t period);
/**
* @brief Gets Long IFS period in microseconds.
*
* @note This function is available if @ref NRF_802154_IFS_ENABLED is enabled.
*
* @return Current Long IFS period in microseconds.
*/
uint16_t nrf_802154_ifs_min_lifs_period_get(void);
@ -1655,6 +1729,8 @@ uint16_t nrf_802154_ifs_min_lifs_period_get(void);
/**
* @brief Sets Long IFS period in microseconds.
*
* @note This function is available if @ref NRF_802154_IFS_ENABLED is enabled.
*
* @param[in] period Long IFS period in microseconds.
*/
void nrf_802154_ifs_min_lifs_period_set(uint16_t period);
@ -1674,8 +1750,6 @@ void nrf_802154_ifs_min_lifs_period_set(uint16_t period);
*/
nrf_802154_capabilities_t nrf_802154_capabilities_get(void);
/** @} */
/**
* @}
* @defgroup nrf_802154_security Radio driver MAC security feature.

View File

@ -106,7 +106,6 @@ extern "C" {
* In this case, the internal handling must be disabled.
*
*/
#ifndef NRF_802154_INTERNAL_RADIO_IRQ_HANDLING
#define NRF_802154_INTERNAL_RADIO_IRQ_HANDLING 0
#endif
@ -120,7 +119,6 @@ extern "C" {
* In this case, the internal handling must be disabled.
*
*/
#ifndef NRF_802154_INTERNAL_SWI_IRQ_HANDLING
#define NRF_802154_INTERNAL_SWI_IRQ_HANDLING 1
#endif
@ -162,7 +160,7 @@ extern "C" {
* When this flag is set, the RAW API is available for the MAC layer. It is recommended to use
* the RAW API because it provides more optimized functions.
*
* @note If the RAW API is not available for the MAC layer, only less optimized functions performing
* @note If the RAW API is not enabled for the MAC layer, only less optimized functions performing
* copy are available.
*
*/
@ -231,8 +229,10 @@ extern "C" {
*
* If timestamps are to be added to the frames received.
* Enabling this feature enables the functions @ref nrf_802154_received_timestamp_raw,
* @ref nrf_802154_received_timestamp, @ref nrf_802154_transmitted_timestamp_raw, and
* @ref nrf_802154_transmitted_timestamp, which add timestamps to the frames received.
* @ref nrf_802154_received_timestamp which add timestamps to the frames received.
* Enables also proper value of frame timestamp
* ( @c nrf_802154_transmit_done_metadata_t::data.transmitted.time ) passed as metadata to
* @ref nrf_802154_transmitted and @ref nrf_802154_transmitted_raw,
* This option also enables timestamping in stats.
*
*/
@ -287,7 +287,7 @@ extern "C" {
* (see IEEE 802.15.4-2015: 6.2.5.1).
*
* @note The minimum value of the backoff exponent may be changed from default by calling the
* @ref nrf_802154_pib_csmaca_min_be_set function.
* @ref nrf_802154_csma_ca_min_be_set function.
*
*/
#ifdef NRF_802154_CSMA_CA_MIN_BE
@ -304,7 +304,7 @@ extern "C" {
* (see IEEE 802.15.4-2015: 6.2.5.1).
*
* @note The maximum value of the backoff exponent may be changed from default by calling the
* @ref nrf_802154_pib_csmaca_max_be_set function.
* @ref nrf_802154_csma_ca_max_be_set function.
*
*/
#ifdef NRF_802154_CSMA_CA_MAX_BE
@ -321,7 +321,7 @@ extern "C" {
* a channel access failure.
*
* @note The maximum number of backoffs may be changed from default by calling the
* @ref nrf_802154_pib_csmaca_max_backoffs_set function.
* @ref nrf_802154_csma_ca_max_backoffs_set function.
*
*/
#ifdef NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS
@ -376,7 +376,7 @@ extern "C" {
#endif
/**
* @def NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT
* @def NRF_802154_PRECISE_ACK_TIMEOUT_DEFAULT_TIMEOUT
*
* The default timeout in microseconds (us) for the precise ACK timeout feature.
*
@ -435,7 +435,7 @@ extern "C" {
/**
* @}
* @defgroup nrf_802154_coex WiFi coexistence feature configuration
* @defgroup nrf_802154_config_coex WiFi coexistence feature configuration
* @{
*/
@ -450,7 +450,7 @@ extern "C" {
/**
* @}
* @defgroup nrf_802154_stats Statistics configuration
* @defgroup nrf_802154_config_stats Statistics configuration
* @{
*/
@ -482,7 +482,7 @@ extern "C" {
/**
* @}
* @defgroup nrf_802154_security Security configuration
* @defgroup nrf_802154_config_security Security configuration
* @{
*/
@ -533,12 +533,26 @@ extern "C" {
#define NRF_802154_IE_WRITER_ENABLED 1
#endif
/**
* @def NRF_802154_CARRIER_FUNCTIONS_ENABLED
*
* Enables functions used for test purposes: nrf_802154_continuous_carrier and
* nrf_802154_modulated_carrier
*/
#ifndef NRF_802154_CARRIER_FUNCTIONS_ENABLED
#define NRF_802154_CARRIER_FUNCTIONS_ENABLED 1
#endif
/**
*@}
**/
/**
*@}
**/
#ifdef __cplusplus
}
#endif
#endif // NRF_802154_CONFIG_H__
/**
*@}
**/

View File

@ -40,8 +40,8 @@
#ifndef NRF_802154_CONST_H_
#define NRF_802154_CONST_H_
#include <stdint.h>
#include "nrf_802154_config.h"
#define RAW_LENGTH_OFFSET 0 ///< Byte containing the frame length in a raw frame.
#define RAW_PAYLOAD_OFFSET 1 ///< Offset of the frame payload in a raw frame
#define ACK_HEADER_WITH_PENDING 0x12 ///< The first byte of an ACK frame containing a pending bit.
#define ACK_HEADER_WITHOUT_PENDING 0x02 ///< The first byte of an ACK frame without a pending bit.
@ -173,6 +173,7 @@
#define TURNAROUND_TIME 192UL ///< RX-to-TX or TX-to-RX turnaround time (aTurnaroundTime), in microseconds (us).
#define CCA_TIME 128UL ///< Time required to perform CCA detection (aCcaTime), in microseconds (us).
#define ACK_IFS TURNAROUND_TIME ///< Ack Inter Frame Spacing [us] - delay between last symbol of received frame and first symbol of transmitted Ack
#define UNIT_BACKOFF_PERIOD (TURNAROUND_TIME + CCA_TIME) ///< Number of symbols in the basic time period used by CSMA-CA algorithm (aUnitBackoffPeriod), in (us).
#define PHY_US_PER_SYMBOL 16 ///< Duration of a single symbol in microseconds (us).
@ -228,18 +229,10 @@ typedef enum
REQ_ORIG_HIGHER_LAYER,
REQ_ORIG_CORE,
REQ_ORIG_RSCH,
#if NRF_802154_CSMA_CA_ENABLED
REQ_ORIG_CSMA_CA,
#endif // NRF_802154_CSMA_CA_ENABLED
#if NRF_802154_ACK_TIMEOUT_ENABLED
REQ_ORIG_ACK_TIMEOUT,
#endif // NRF_802154_ACK_TIMEOUT_ENABLED
#if NRF_802154_DELAYED_TRX_ENABLED
REQ_ORIG_DELAYED_TRX,
#endif // NRF_802154_DELAYED_TRX_ENABLED
#if NRF_802154_IFS_ENABLED
REQ_ORIG_IFS,
#endif // NRF_802154_IFS_ENABLED
} req_originator_t;
#endif // NRF_802154_CONST_H_

View File

@ -170,7 +170,7 @@ typedef uint8_t nrf_802154_ack_data_t;
* @brief Methods of source address matching.
*
* You can use one of the following methods that can be set during the initialization phase
* by calling @ref nrf_802154_src_matching_method:
* by calling @ref nrf_802154_src_addr_matching_method_set :
* - For Thread: @ref NRF_802154_SRC_ADDR_MATCH_THREAD -- The pending bit is set only for the addresses found in the list.
* - For Zigbee: @ref NRF_802154_SRC_ADDR_MATCH_ZIGBEE -- The pending bit is cleared only for the short addresses found in the list.\n
* This method does not set pending bit in non-command and non-data-request frames.
@ -366,12 +366,6 @@ typedef struct
bool use_global_frame_counter; // !< Whether to use the global frame counter instead of the one defined in this structure.
} nrf_802154_key_t;
/**
* @brief Function pointer used for notifying about transmission failure.
*/
typedef void (* nrf_802154_transmit_failed_notification_t)(uint8_t * p_frame,
nrf_802154_tx_error_t error);
/**
* @brief Structure with frame properties associated with the transmission operation.
*
@ -466,6 +460,14 @@ typedef struct
// until its preconditions are met.
} nrf_802154_transmit_params_t;
/**
* @brief Function pointer used for notifying about transmission failure.
*/
typedef void (* nrf_802154_transmit_failed_notification_t)(
uint8_t * p_frame,
nrf_802154_tx_error_t error,
const nrf_802154_transmit_done_metadata_t * p_meta);
/**
*@}
**/

View File

@ -50,7 +50,7 @@ extern "C" {
/**
* @defgroup nrf_802154_random Random Abstraction Layer for the 802.15.4 driver
* @{
* @ingroup nrf_802154_random
* @ingroup nrf_802154
* @brief The pseudo-random number generator Abstraction Layer interface for the 802.15.4 driver.
*
* The Random Abstraction Layer is an abstraction layer of a pseudo-random number generator that is

View File

@ -115,7 +115,7 @@ void nrf_802154_ack_data_reset(bool extended, nrf_802154_ack_data_t data_type);
*
* When calling @ref nrf_802154_ack_data_pending_bit_should_be_set, one of several algorithms
* for source address matching will be chosen. To ensure a specific algorithm is selected,
* call this function before @ref rf_802154_ack_data_pending_bit_should_be_set.
* call this function before @ref nrf_802154_ack_data_pending_bit_should_be_set.
*
* @param[in] match_method Source matching method to be used.
*/

View File

@ -41,7 +41,6 @@
#include "nrf_802154_ack_generator.h"
#include <assert.h>
#include <stdlib.h>
#include "nrf_802154_const.h"
#include "nrf_802154_enh_ack_generator.h"
@ -78,6 +77,13 @@ void nrf_802154_ack_generator_init(void)
nrf_802154_enh_ack_generator_init();
}
void nrf_802154_ack_generator_reset(void)
{
// Both generators are reset to enable sending both Imm-Ack and Enh-Ack.
nrf_802154_imm_ack_generator_reset();
nrf_802154_enh_ack_generator_reset();
}
uint8_t * nrf_802154_ack_generator_create(const nrf_802154_frame_parser_data_t * p_frame_data)
{
// This function should not be called if ACK is not requested.

View File

@ -47,13 +47,26 @@
/** Initializes the ACK generator module. */
void nrf_802154_ack_generator_init(void);
/** Creates an ACK in response to the provided frame and inserts it into a radio buffer.
/** @brief Resets the ACK generator module.
*
* @note This function should be called for every received frame to be acknowledged before
* @ref nrf_802154_ack_generator_create is called for that frame.
*/
void nrf_802154_ack_generator_reset(void);
/** @brief Creates an ACK in response to the provided frame and inserts it into a radio buffer.
*
* @note Only those contents of the frame being acknowledged marked by @p p_frame_data as valid
* are used for ACK generation. If any data necessary to generate an ACK is missing or marked as
* invalid by @p p_frame_data, this function returns NULL. Once more data becomes available and valid,
* this function can be called again and the generation will be continued. That allows for
* generating ACK iteratively as data to be acknowledged is being received.
*
* @param [in] p_frame_data Pointer to the parser data of the frame for which an Ack
* will be generated.
*
* @returns Either pointer to a constant buffer that contains PHR and PSDU
* of the created ACK frame, or NULL in case of an invalid frame.
* of the created ACK frame, or NULL when the response cannot be created.
*/
uint8_t * nrf_802154_ack_generator_create(
const nrf_802154_frame_parser_data_t * p_frame_data);

View File

@ -54,12 +54,29 @@
#define ENH_ACK_MAX_SIZE MAX_PACKET_SIZE
static uint8_t m_ack_data[ENH_ACK_MAX_SIZE + PHR_SIZE];
static void ack_buffer_clear(nrf_802154_frame_parser_data_t * p_ack_data)
typedef enum
{
memset(&m_ack_data[PHR_OFFSET], 0U, PHR_SIZE + FCF_SIZE);
(void)nrf_802154_frame_parser_data_init(m_ack_data, 0U, PARSE_LEVEL_NONE, p_ack_data);
ACK_STATE_RESET,
ACK_STATE_INVALID,
ACK_STATE_PROCESSING,
ACK_STATE_COMPLETE,
} ack_state_t;
static ack_state_t m_ack_state;
static uint8_t m_ack[ENH_ACK_MAX_SIZE + PHR_SIZE];
static nrf_802154_frame_parser_data_t m_ack_data;
static const uint8_t * mp_ie_data;
static uint8_t m_ie_data_len;
static void ack_state_set(ack_state_t state_to_set)
{
m_ack_state = state_to_set;
}
static inline ack_state_t ack_state_get(void)
{
return m_ack_state;
}
static uint8_t sequence_number_set(const nrf_802154_frame_parser_data_t * p_frame_data)
@ -68,7 +85,7 @@ static uint8_t sequence_number_set(const nrf_802154_frame_parser_data_t * p_fram
if (p_frame_dsn != NULL)
{
m_ack_data[DSN_OFFSET] = *p_frame_dsn;
m_ack[DSN_OFFSET] = *p_frame_dsn;
return DSN_SIZE;
}
@ -82,14 +99,14 @@ static uint8_t sequence_number_set(const nrf_802154_frame_parser_data_t * p_fram
static void fcf_frame_type_set(void)
{
m_ack_data[FRAME_TYPE_OFFSET] |= FRAME_TYPE_ACK;
m_ack[FRAME_TYPE_OFFSET] |= FRAME_TYPE_ACK;
}
static void fcf_security_enabled_set(const nrf_802154_frame_parser_data_t * p_frame_data)
{
if (nrf_802154_frame_parser_security_enabled_bit_is_set(p_frame_data))
{
m_ack_data[SECURITY_ENABLED_OFFSET] |= SECURITY_ENABLED_BIT;
m_ack[SECURITY_ENABLED_OFFSET] |= SECURITY_ENABLED_BIT;
}
}
@ -97,7 +114,7 @@ static void fcf_frame_pending_set(const nrf_802154_frame_parser_data_t * p_frame
{
if (nrf_802154_ack_data_pending_bit_should_be_set(p_frame_data))
{
m_ack_data[FRAME_PENDING_OFFSET] |= FRAME_PENDING_BIT;
m_ack[FRAME_PENDING_OFFSET] |= FRAME_PENDING_BIT;
}
}
@ -105,7 +122,7 @@ static void fcf_panid_compression_set(const nrf_802154_frame_parser_data_t * p_f
{
if (nrf_802154_frame_parser_panid_compression_is_set(p_frame_data))
{
m_ack_data[PAN_ID_COMPR_OFFSET] |= PAN_ID_COMPR_MASK;
m_ack[PAN_ID_COMPR_OFFSET] |= PAN_ID_COMPR_MASK;
}
}
@ -113,7 +130,7 @@ static void fcf_sequence_number_suppression_set(const nrf_802154_frame_parser_da
{
if (nrf_802154_frame_parser_dsn_suppress_bit_is_set(p_frame_data))
{
m_ack_data[DSN_SUPPRESS_OFFSET] |= DSN_SUPPRESS_BIT;
m_ack[DSN_SUPPRESS_OFFSET] |= DSN_SUPPRESS_BIT;
}
}
@ -121,7 +138,7 @@ static void fcf_ie_present_set(bool ie_present)
{
if (ie_present)
{
m_ack_data[IE_PRESENT_OFFSET] |= IE_PRESENT_BIT;
m_ack[IE_PRESENT_OFFSET] |= IE_PRESENT_BIT;
}
}
@ -129,40 +146,51 @@ static void fcf_dst_addressing_mode_set(const nrf_802154_frame_parser_data_t * p
{
if (nrf_802154_frame_parser_src_addr_is_extended(p_frame_data))
{
m_ack_data[DEST_ADDR_TYPE_OFFSET] |= DEST_ADDR_TYPE_EXTENDED;
m_ack[DEST_ADDR_TYPE_OFFSET] |= DEST_ADDR_TYPE_EXTENDED;
}
else if (nrf_802154_frame_parser_src_addr_is_short(p_frame_data))
{
m_ack_data[DEST_ADDR_TYPE_OFFSET] |= DEST_ADDR_TYPE_SHORT;
m_ack[DEST_ADDR_TYPE_OFFSET] |= DEST_ADDR_TYPE_SHORT;
}
else
{
m_ack_data[DEST_ADDR_TYPE_OFFSET] |= DEST_ADDR_TYPE_NONE;
m_ack[DEST_ADDR_TYPE_OFFSET] |= DEST_ADDR_TYPE_NONE;
}
}
static void fcf_src_addressing_mode_set(void)
{
m_ack_data[SRC_ADDR_TYPE_OFFSET] |= SRC_ADDR_TYPE_NONE;
m_ack[SRC_ADDR_TYPE_OFFSET] |= SRC_ADDR_TYPE_NONE;
}
static void fcf_frame_version_set(void)
{
m_ack_data[FRAME_VERSION_OFFSET] |= FRAME_VERSION_2;
m_ack[FRAME_VERSION_OFFSET] |= FRAME_VERSION_2;
}
static uint8_t frame_control_set(const nrf_802154_frame_parser_data_t * p_frame_data,
bool ie_present)
{
fcf_frame_type_set();
fcf_security_enabled_set(p_frame_data);
fcf_frame_pending_set(p_frame_data);
fcf_panid_compression_set(p_frame_data);
fcf_sequence_number_suppression_set(p_frame_data);
fcf_ie_present_set(ie_present);
fcf_dst_addressing_mode_set(p_frame_data);
fcf_frame_version_set();
fcf_src_addressing_mode_set();
nrf_802154_frame_parser_level_t level = nrf_802154_frame_parser_parse_level_get(p_frame_data);
if (level >= PARSE_LEVEL_FCF_OFFSETS)
{
fcf_frame_type_set();
fcf_security_enabled_set(p_frame_data);
fcf_panid_compression_set(p_frame_data);
fcf_sequence_number_suppression_set(p_frame_data);
fcf_ie_present_set(ie_present);
fcf_dst_addressing_mode_set(p_frame_data);
fcf_frame_version_set();
fcf_src_addressing_mode_set();
}
if (level >= PARSE_LEVEL_FULL)
{
// As some frame pending bit setting algorithms depend on MAC payload,
// the entire frame must be known to set this field.
fcf_frame_pending_set(p_frame_data);
}
return FCF_SIZE;
}
@ -440,6 +468,179 @@ static bool encryption_prepare(const nrf_802154_frame_parser_data_t * p_ack_data
#endif // NRF_802154_ENCRYPTION_ENABLED
}
/***************************************************************************************************
* @section Enhanced ACK generation
**************************************************************************************************/
static void fcf_process(const nrf_802154_frame_parser_data_t * p_frame_data,
uint8_t * p_bytes_written)
{
// Set Frame Control field bits.
// Some of them might require correction when higher parse level is available
*p_bytes_written = frame_control_set(p_frame_data, false);
m_ack[PHR_OFFSET] += *p_bytes_written;
bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data,
m_ack[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_FCF_OFFSETS);
assert(result);
(void)result;
}
static void dst_addr_process(const nrf_802154_frame_parser_data_t * p_frame_data,
uint8_t * p_bytes_written)
{
// Set valid sequence number in ACK frame.
*p_bytes_written = sequence_number_set(p_frame_data);
m_ack[PHR_OFFSET] += *p_bytes_written;
// Set destination address and PAN ID.
*p_bytes_written = destination_set(p_frame_data, &m_ack_data);
m_ack[PHR_OFFSET] += *p_bytes_written;
bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data,
m_ack[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_DST_ADDRESSING_END);
assert(result);
(void)result;
}
static void addr_end_process(const nrf_802154_frame_parser_data_t * p_frame_data)
{
// Set source address and PAN ID.
source_set();
// Having the frame's source address, presence of IEs can be determined.
// coverity[unchecked_value]
mp_ie_data = nrf_802154_ack_data_ie_get(
nrf_802154_frame_parser_src_addr_get(p_frame_data),
nrf_802154_frame_parser_src_addr_is_extended(p_frame_data),
&m_ie_data_len);
// Update the IE present bit in Frame Control field knowing if IEs should be present.
fcf_ie_present_set(mp_ie_data != NULL);
bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data,
m_ack[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_ADDRESSING_END);
assert(result);
(void)result;
}
static bool aux_sec_hdr_process(const nrf_802154_frame_parser_data_t * p_frame_data,
uint8_t * p_bytes_written)
{
if (security_header_set(p_frame_data, &m_ack_data, p_bytes_written) == false)
{
return false;
}
m_ack[PHR_OFFSET] += *p_bytes_written;
bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data,
m_ack[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_AUX_SEC_HDR_END);
assert(result);
(void)result;
return true;
}
static void ie_process(const nrf_802154_frame_parser_data_t * p_frame_data,
uint8_t * p_bytes_written)
{
// Set IE header.
ie_header_set(mp_ie_data, m_ie_data_len, &m_ack_data);
m_ack[PHR_OFFSET] += m_ie_data_len;
// Terminate the IE header if needed.
*p_bytes_written = ie_header_terminate(mp_ie_data, m_ie_data_len, &m_ack_data);
m_ack[PHR_OFFSET] += *p_bytes_written + FCS_SIZE;
bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data,
m_ack[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_FULL);
assert(result);
(void)result;
}
static bool encryption_process(void)
{
return encryption_prepare(&m_ack_data);
}
static uint8_t * ack_process(
const nrf_802154_frame_parser_data_t * p_frame_data,
bool * p_processing_done)
{
uint8_t bytes_written = 0U;
nrf_802154_frame_parser_level_t frame_parse_level = nrf_802154_frame_parser_parse_level_get(
p_frame_data);
nrf_802154_frame_parser_level_t ack_parse_level = nrf_802154_frame_parser_parse_level_get(
&m_ack_data);
*p_processing_done = false;
if ((frame_parse_level >= PARSE_LEVEL_FCF_OFFSETS) &&
(ack_parse_level < PARSE_LEVEL_FCF_OFFSETS))
{
fcf_process(p_frame_data, &bytes_written);
}
if ((frame_parse_level >= PARSE_LEVEL_DST_ADDRESSING_END) &&
(ack_parse_level < PARSE_LEVEL_DST_ADDRESSING_END))
{
dst_addr_process(p_frame_data, &bytes_written);
}
if ((frame_parse_level >= PARSE_LEVEL_ADDRESSING_END) &&
(ack_parse_level < PARSE_LEVEL_ADDRESSING_END))
{
addr_end_process(p_frame_data);
}
if ((frame_parse_level >= PARSE_LEVEL_AUX_SEC_HDR_END) &&
(ack_parse_level < PARSE_LEVEL_AUX_SEC_HDR_END))
{
if (!aux_sec_hdr_process(p_frame_data, &bytes_written))
{
// Failure to set auxiliary security header, the ACK cannot be created. Exit immediately
*p_processing_done = true;
return NULL;
}
ie_process(p_frame_data, &bytes_written);
}
if (frame_parse_level == PARSE_LEVEL_FULL)
{
// With the entire frame validated update the Frame Pending bit in Frame Control field
fcf_frame_pending_set(p_frame_data);
if (encryption_process())
{
// Success. Processing completed
*p_processing_done = true;
return m_ack;
}
else
{
// Failure to prepare encryption even though it's required, the ACK cannot be created.
// Exit immediately
*p_processing_done = true;
return NULL;
}
}
return NULL;
}
/***************************************************************************************************
* @section Public API implementation
**************************************************************************************************/
@ -449,89 +650,45 @@ void nrf_802154_enh_ack_generator_init(void)
// Intentionally empty.
}
void nrf_802154_enh_ack_generator_reset(void)
{
memset(m_ack, 0U, sizeof(m_ack));
(void)nrf_802154_frame_parser_data_init(m_ack, 0U, PARSE_LEVEL_NONE, &m_ack_data);
mp_ie_data = 0U;
m_ie_data_len = 0U;
m_ack_state = ACK_STATE_RESET;
}
uint8_t * nrf_802154_enh_ack_generator_create(
const nrf_802154_frame_parser_data_t * p_frame_data)
{
nrf_802154_frame_parser_data_t ack_data;
bool result;
uint8_t bytes_written = 0U;
uint8_t ie_data_len = 0U;
// coverity[unchecked_value]
const uint8_t * p_ie_data = nrf_802154_ack_data_ie_get(
nrf_802154_frame_parser_src_addr_get(p_frame_data),
nrf_802154_frame_parser_src_addr_is_extended(p_frame_data),
&ie_data_len);
// Clear previously created ACK.
ack_buffer_clear(&ack_data);
// Set Frame Control field bits.
bytes_written = frame_control_set(p_frame_data, p_ie_data != NULL);
m_ack_data[PHR_OFFSET] += bytes_written;
result = nrf_802154_frame_parser_valid_data_extend(&ack_data,
m_ack_data[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_FCF_OFFSETS);
assert(result);
(void)result;
// Set valid sequence number in ACK frame.
bytes_written = sequence_number_set(p_frame_data);
m_ack_data[PHR_OFFSET] += bytes_written;
// Set destination address and PAN ID.
bytes_written = destination_set(p_frame_data, &ack_data);
m_ack_data[PHR_OFFSET] += bytes_written;
// Set source address and PAN ID.
source_set();
if (security_header_set(p_frame_data, &ack_data, &bytes_written) == false)
switch (ack_state_get())
{
// Failure to set auxiliary security header: The ACK cannot be created.
ack_buffer_clear(&ack_data);
return NULL;
case ACK_STATE_RESET:
ack_state_set(ACK_STATE_PROCESSING);
// Fallthrough
case ACK_STATE_PROCESSING:
{
bool processing_done;
uint8_t * p_ack = ack_process(p_frame_data, &processing_done);
if (processing_done)
{
ack_state_set(p_ack ? ACK_STATE_COMPLETE : ACK_STATE_INVALID);
}
return processing_done ? p_ack : NULL;
}
case ACK_STATE_INVALID:
return NULL;
case ACK_STATE_COMPLETE:
return m_ack;
default:
assert(false);
return NULL;
}
m_ack_data[PHR_OFFSET] += bytes_written;
result = nrf_802154_frame_parser_valid_data_extend(&ack_data,
m_ack_data[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_AUX_SEC_HDR_END);
assert(result);
(void)result;
// Set IE header.
ie_header_set(p_ie_data, ie_data_len, &ack_data);
m_ack_data[PHR_OFFSET] += ie_data_len;
// Terminate the IE header if needed.
bytes_written = ie_header_terminate(p_ie_data, ie_data_len, &ack_data);
m_ack_data[PHR_OFFSET] += bytes_written + FCS_SIZE;
result = nrf_802154_frame_parser_valid_data_extend(&ack_data,
m_ack_data[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_FULL);
assert(result);
(void)result;
// Prepare encryption.
if (!encryption_prepare(&ack_data))
{
// Failure to prepare encryption even though it's required. The ACK cannot be created.
ack_buffer_clear(&ack_data);
return NULL;
}
return m_ack_data;
}
#ifdef TEST
void nrf_802154_enh_ack_generator_module_reset(void)
{
memset(m_ack_data, 0U, sizeof(m_ack_data));
}
#endif // TEST

View File

@ -48,9 +48,20 @@
/** Initializes the Enhanced ACK generator module. */
void nrf_802154_enh_ack_generator_init(void);
/** Creates an Enhanced ACK in response to the provided frame.
/** @brief Resets the Enhanced ACK generator module.
*
* This function creates an Enhanced ACK frame and inserts it into a radio buffer.
* @note This function should be called for every received frame to be acknowledged before
* @ref nrf_802154_enh_ack_generator_create is called for that frame.
*/
void nrf_802154_enh_ack_generator_reset(void);
/** @brief Creates an Enhanced ACK in response to the provided frame.
*
* @note Only those contents of the frame being acknowledged marked by @p p_frame_data as valid
* are used for ACK generation. If any data necessary to generate an ACK is missing or marked as
* invalid by @p p_frame_data, this function returns NULL. Once more data becomes available and valid,
* this function can be called again and the generation will be continued. That allows for
* generating ACK iteratively as data to be acknowledged is being received.
*
* @param [in] p_frame_data Pointer to the parser data of the frame for which an Ack
* will be generated.

View File

@ -57,9 +57,20 @@ void nrf_802154_imm_ack_generator_init(void)
memcpy(m_ack_data, ack_data, sizeof(ack_data));
}
void nrf_802154_imm_ack_generator_reset(void)
{
// Intentionally empty
}
uint8_t * nrf_802154_imm_ack_generator_create(
const nrf_802154_frame_parser_data_t * p_frame_data)
{
if (nrf_802154_frame_parser_parse_level_get(p_frame_data) < PARSE_LEVEL_FULL)
{
// The entire frame being acknowledged is necessary to correctly generate Ack
return NULL;
}
const uint8_t * frame_dsn = nrf_802154_frame_parser_dsn_get(p_frame_data);
if (frame_dsn == NULL)

View File

@ -49,15 +49,27 @@
/** Initializes the Immediate ACK generator module. */
void nrf_802154_imm_ack_generator_init(void);
/** Creates an Immediate ACK in response to the provided frame.
/** @brief Resets the Immediate ACK generator module.
*
* This function creates an Immediate ACK frame and inserts it into a radio buffer.
* @note This function should be called for every received frame to be acknowledged before
* @ref nrf_802154_imm_ack_generator_create is called for that frame.
*/
void nrf_802154_imm_ack_generator_reset(void);
/** @brief Creates an Immediate ACK in response to the provided frame.
*
* @note Only those contents of the frame being acknowledged marked by @p p_frame_data as valid
* are used for ACK generation. If any data necessary to generate an ACK is missing or marked as
* invalid by @p p_frame_data, this function returns NULL. Once more data becomes available and valid,
* this function can be called again and the generation will be continued. That allows for
* generating ACK iteratively as data to be acknowledged is being received.
*
* @param [in] p_frame_data Pointer to the parser data of the frame for which an Ack
* will be generated.
*
* @returns Pointer to a constant buffer that contains PHR and PSDU of the created
* Immediate ACK frame.
* @returns Either pointer to a constant buffer that contains PHR and PSDU
* of the created Immediate ACK frame, or NULL when the response cannot be
* created.
*/
uint8_t * nrf_802154_imm_ack_generator_create(
const nrf_802154_frame_parser_data_t * p_frame_data);

View File

@ -42,7 +42,7 @@
#include "nrf_802154_types.h"
/**
* @defgroup nrf_802154_csma_ca 802.15.4 driver ACK timeout support
* @defgroup nrf_802154_ack_timeout 802.15.4 driver ACK timeout support
* @{
* @ingroup nrf_802154
* @brief ACK timeout feature.

View File

@ -45,17 +45,14 @@
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "nrf_802154_config.h"
#include "nrf_802154_const.h"
#include "nrf_802154_debug.h"
#include "nrf_802154_notification.h"
#include "nrf_802154_pib.h"
#include "nrf_802154_procedures_duration.h"
#include "nrf_802154_request.h"
#include "nrf_802154_stats.h"
#include "mac_features/nrf_802154_frame_parser.h"
#include "platform/nrf_802154_random.h"
#include "rsch/nrf_802154_rsch.h"
#include "timer/nrf_802154_timer_sched.h"
@ -145,7 +142,12 @@ static void notify_busy_channel(bool result)
// the comparison uses `greater or equal` instead of `greater than`.
if (!result && (m_nb >= nrf_802154_pib_csmaca_max_backoffs_get()))
{
nrf_802154_notify_transmit_failed(mp_data, NRF_802154_TX_ERROR_BUSY_CHANNEL);
// core rejected attempt, use my current frame_props
nrf_802154_transmit_done_metadata_t metadata = {};
metadata.frame_props = m_data_props;
nrf_802154_notify_transmit_failed(mp_data, NRF_802154_TX_ERROR_BUSY_CHANNEL, &metadata);
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);

View File

@ -73,10 +73,10 @@
*/
typedef enum
{
DELAYED_TRX_OP_STATE_STOPPED, ///< Delayed operation stopped.
DELAYED_TRX_OP_STATE_PENDING, ///< Delayed operation scheduled and waiting for timeslot.
DELAYED_TRX_OP_STATE_ONGOING, ///< Delayed operation ongoing (during timeslot).
DELAYED_TRX_OP_STATE_NB ///< Number of delayed operation states.
DELAYED_TRX_OP_STATE_STOPPED = (1 << 0), ///< Delayed operation stopped.
DELAYED_TRX_OP_STATE_PENDING = (1 << 1), ///< Delayed operation scheduled and waiting for timeslot.
DELAYED_TRX_OP_STATE_ONGOING = (1 << 2), ///< Delayed operation ongoing (during timeslot).
DELAYED_TRX_OP_STATE_ALLOWED_MSK = ((1 << 3) - 1) ///< Mask of allowed delayed operation states.
} delayed_trx_op_state_t;
/**
@ -313,18 +313,18 @@ static dly_op_data_t * dly_rx_data_atomically_pop(void)
/**
* Set state of a delayed operation.
*
* @param[in] p_dly_op_data Data of the delayed operation.
* @param[in] expected_state Expected delayed operation state prior state transition.
* @param[in] new_state Delayed operation state to enter.
* @param[in] p_dly_op_data Data of the delayed operation.
* @param[in] expected_state_mask Mask of expected delayed operation states prior state transition.
* @param[in] new_state Delayed operation state to enter.
*
* @retval true Successfully set the new state.
* @retval false Failed to set the new state.
*/
static bool dly_op_state_set(dly_op_data_t * p_dly_op_data,
delayed_trx_op_state_t expected_state,
uint32_t expected_state_mask,
delayed_trx_op_state_t new_state)
{
assert(new_state < DELAYED_TRX_OP_STATE_NB);
assert(new_state & DELAYED_TRX_OP_STATE_ALLOWED_MSK);
switch (p_dly_op_data->op)
{
@ -337,7 +337,7 @@ static bool dly_op_state_set(dly_op_data_t * p_dly_op_data,
{
current_state = (delayed_trx_op_state_t)__LDREXB((uint8_t *)&p_dly_op_data->state);
if (current_state != expected_state)
if (0 == (current_state & expected_state_mask))
{
__CLREX();
return false;
@ -434,8 +434,15 @@ static void notify_rx_timeout(void * p_context)
DELAYED_TRX_OP_STATE_ONGOING,
DELAYED_TRX_OP_STATE_STOPPED))
{
nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_DELAYED_TIMEOUT,
p_dly_op_data->id);
bool notified = nrf_802154_notify_receive_failed(
NRF_802154_RX_ERROR_DELAYED_TIMEOUT,
p_dly_op_data->id,
false);
// It should always be possible to notify DRX result
assert(notified);
(void)notified;
dly_ts_slot_release(p_dly_op_data);
}
@ -467,8 +474,13 @@ static void dly_tx_result_notify(bool result)
if (!result)
{
// core rejected attempt, use my current frame_props
nrf_802154_transmit_done_metadata_t metadata = {};
metadata.frame_props = p_dly_op_data->tx.params.frame_props;
nrf_802154_notify_transmit_failed(p_dly_op_data->tx.p_data,
NRF_802154_TX_ERROR_TIMESLOT_DENIED);
NRF_802154_TX_ERROR_TIMESLOT_DENIED,
&metadata);
}
dly_ts_slot_release(p_dly_op_data);
@ -509,8 +521,14 @@ static void dly_rx_result_notify(bool result)
assert(state_set);
(void)state_set;
nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_DELAYED_ABORTED,
p_parallel_ongoing_dly_op_data->id);
bool notified = nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_DELAYED_ABORTED,
p_parallel_ongoing_dly_op_data->id,
false);
// It should always be possible to notify DRX result
assert(notified);
(void)notified;
dly_ts_slot_release(p_parallel_ongoing_dly_op_data);
}
@ -542,8 +560,15 @@ static void dly_rx_result_notify(bool result)
assert(state_set);
(void)state_set;
nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_DELAYED_TIMESLOT_DENIED,
p_dly_op_data->id);
bool notified = nrf_802154_notify_receive_failed(
NRF_802154_RX_ERROR_DELAYED_TIMESLOT_DENIED,
p_dly_op_data->id,
false);
// It should always be possible to notify DRX result
assert(notified);
(void)notified;
dly_ts_slot_release(p_dly_op_data);
}
@ -693,12 +718,14 @@ void nrf_802154_delayed_trx_init(void)
for (uint32_t i = 0; i < sizeof(m_dly_rx_data) / sizeof(m_dly_rx_data[0]); i++)
{
m_dly_rx_data[i].id = NRF_802154_RESERVED_INVALID_ID;
m_dly_rx_data[i].state = DELAYED_TRX_OP_STATE_STOPPED;
m_dly_rx_data[i].id = NRF_802154_RESERVED_INVALID_ID;
}
for (uint32_t i = 0; i < sizeof(m_dly_tx_data) / sizeof(m_dly_tx_data[0]); i++)
{
m_dly_tx_data[i].id = NRF_802154_RESERVED_INVALID_ID;
m_dly_tx_data[i].state = DELAYED_TRX_OP_STATE_STOPPED;
m_dly_tx_data[i].id = NRF_802154_RESERVED_INVALID_ID;
}
}
@ -822,10 +849,13 @@ bool nrf_802154_delayed_trx_receive_cancel(uint32_t id)
nrf_802154_timer_sched_remove(&p_dly_op_data->rx.timeout_timer, &was_running);
p_dly_op_data->state = DELAYED_TRX_OP_STATE_STOPPED;
p_dly_op_data->id = NRF_802154_RESERVED_INVALID_ID;
bool stopped = dly_op_state_set(p_dly_op_data,
DELAYED_TRX_OP_STATE_PENDING | DELAYED_TRX_OP_STATE_ONGOING,
DELAYED_TRX_OP_STATE_STOPPED);
result = result || was_running;
p_dly_op_data->id = NRF_802154_RESERVED_INVALID_ID;
result = (result || was_running) && stopped;
return result;
}
@ -843,8 +873,15 @@ bool nrf_802154_delayed_trx_abort(nrf_802154_term_t term_lvl, req_originator_t r
DELAYED_TRX_OP_STATE_ONGOING,
DELAYED_TRX_OP_STATE_STOPPED))
{
nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_DELAYED_ABORTED,
p_dly_op_data->id);
bool notified = nrf_802154_notify_receive_failed(
NRF_802154_RX_ERROR_DELAYED_ABORTED,
p_dly_op_data->id,
false);
// It should always be possible to notify DRX result
assert(notified);
(void)notified;
dly_ts_slot_release(p_dly_op_data);
}

View File

@ -39,6 +39,7 @@
#include <stdint.h>
#include "nrf_802154_const.h"
#include "nrf_802154_config.h"
#include "nrf_802154_types.h"
#if NRF_802154_DELAYED_TRX_ENABLED

View File

@ -412,12 +412,10 @@ static nrf_802154_rx_error_t dst_addr_check(const nrf_802154_frame_parser_data_t
}
}
if (p_dst_addr == NULL)
{
return NRF_802154_RX_ERROR_INVALID_DEST_ADDR;
}
uint8_t dst_addr_size =
p_dst_addr ? nrf_802154_frame_parser_dst_addr_size_get(p_frame_data) : 0U;
switch (nrf_802154_frame_parser_dst_addr_size_get(p_frame_data))
switch (dst_addr_size)
{
case SHORT_ADDRESS_SIZE:
return dst_short_addr_check(p_dst_addr) ? NRF_802154_RX_ERROR_NONE :

View File

@ -354,9 +354,8 @@ static bool full_parse(nrf_802154_frame_parser_data_t * p_parser_data)
uint8_t offset = p_parser_data->helper.aux_sec_hdr_end_offset;
uint8_t psdu_length = nrf_802154_frame_parser_frame_length_get(p_parser_data);
const uint8_t * p_ie_header;
const uint8_t * p_mfr;
const uint8_t * p_end_addr;
const uint8_t * p_iterator;
const uint8_t * p_ie_end_addr;
if (((psdu_length + PHR_SIZE) != p_parser_data->valid_data_len) ||
(psdu_length > MAX_PACKET_SIZE))
@ -369,25 +368,36 @@ static bool full_parse(nrf_802154_frame_parser_data_t * p_parser_data)
p_parser_data->mhr.header_ie_offset = offset;
p_ie_header = &p_parser_data->p_frame[offset];
p_mfr = nrf_802154_frame_parser_mfr_get(p_parser_data);
p_end_addr = nrf_802154_frame_parser_mfr_get(p_parser_data) - mic_size_get(p_parser_data);
p_iterator = nrf_802154_frame_parser_header_ie_iterator_begin(p_ie_header);
while (nrf_802154_frame_parser_ie_iterator_end(p_iterator, p_mfr) == false)
while (!nrf_802154_frame_parser_ie_iterator_end(p_iterator, p_end_addr))
{
p_ie_end_addr = nrf_802154_frame_parser_ie_content_address_get(p_iterator) +
nrf_802154_frame_parser_ie_length_get(p_iterator);
p_iterator = nrf_802154_frame_parser_ie_iterator_next(p_iterator);
// Boundary check
if (p_ie_end_addr > p_mfr)
if (p_iterator > p_end_addr)
{
// Boundary check failed
return false;
}
p_iterator = nrf_802154_frame_parser_ie_iterator_next(p_iterator);
else if (p_iterator == p_end_addr)
{
// End of frame; IE header has no termination.
offset = p_iterator - p_parser_data->p_frame;
break;
}
else if (nrf_802154_frame_parser_ie_iterator_end(p_iterator, p_end_addr))
{
// End of IE header; termination reached.
offset = nrf_802154_frame_parser_ie_content_address_get(p_iterator) -
p_parser_data->p_frame;
break;
}
else
{
// Intentionally empty
}
}
offset = nrf_802154_frame_parser_ie_content_address_get(p_iterator) -
p_parser_data->p_frame;
}
if (offset != nrf_802154_frame_parser_mfr_offset_get(p_parser_data))

View File

@ -45,7 +45,6 @@
#include "nrf_802154_core.h"
#include "nrf_802154_nrfx_addons.h"
#include "nrf_802154_tx_work_buffer.h"
#include "nrf_802154_utils.h"
#include "nrf_802154_utils_byteorder.h"
#include <assert.h>

View File

@ -41,7 +41,7 @@
#include "nrf_802154_types.h"
/**
* @defgroup nrf_802154_ie_writer 802.15.4 driver Information Element writer
* @defgroup nrf_802154_ie_writer Radio driver Information Element data injection feature.
* @{
* @ingroup nrf_802154
* @brief Information element writer module.

View File

@ -72,7 +72,12 @@ static void ifs_tx_result_notify(bool result)
{
if (!result)
{
nrf_802154_notify_transmit_failed(m_context.p_data, NRF_802154_TX_ERROR_TIMESLOT_DENIED);
nrf_802154_transmit_done_metadata_t metadata = {};
metadata.frame_props = m_context.params.frame_props;
nrf_802154_notify_transmit_failed(m_context.p_data,
NRF_802154_TX_ERROR_TIMESLOT_DENIED,
&metadata);
}
}
@ -99,11 +104,16 @@ static bool is_ifs_needed_by_address(const uint8_t * p_frame)
PARSE_LEVEL_ADDRESSING_END,
&frame_data);
assert(result);
(void)result;
addr = nrf_802154_frame_parser_dst_addr_get(&frame_data);
is_extended = nrf_802154_frame_parser_dst_addr_is_extended(&frame_data);
if (result)
{
addr = nrf_802154_frame_parser_dst_addr_get(&frame_data);
is_extended = nrf_802154_frame_parser_dst_addr_is_extended(&frame_data);
}
else
{
addr = NULL;
is_extended = false;
}
if (!addr)
{
@ -226,11 +236,16 @@ void nrf_802154_ifs_transmitted_hook(const uint8_t * p_frame)
PARSE_LEVEL_ADDRESSING_END,
&frame_data);
assert(result);
(void)result;
addr = nrf_802154_frame_parser_dst_addr_get(&frame_data);
m_is_last_address_extended = nrf_802154_frame_parser_dst_addr_is_extended(&frame_data);
if (result)
{
addr = nrf_802154_frame_parser_dst_addr_get(&frame_data);
m_is_last_address_extended = nrf_802154_frame_parser_dst_addr_is_extended(&frame_data);
}
else
{
addr = NULL;
m_is_last_address_extended = false;
}
if (!addr)
{
@ -268,8 +283,14 @@ bool nrf_802154_ifs_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig)
if (was_running)
{
ifs_operation_t * p_op = (ifs_operation_t *)m_timer.p_context;
// The IFS was still waiting, so the transmission didn't occur
// at all. Notify with frame_props passed in nrf_802154_ifs_pretransmission hook
nrf_802154_transmit_done_metadata_t metadata = {};
nrf_802154_notify_transmit_failed(p_op->p_data, NRF_802154_TX_ERROR_ABORTED);
metadata.frame_props = m_context.params.frame_props;
nrf_802154_notify_transmit_failed(p_op->p_data,
NRF_802154_TX_ERROR_ABORTED,
&metadata);
}
}
else

View File

@ -50,6 +50,7 @@
#include "nrf_802154_notification.h"
#include "nrf_802154_procedures_duration.h"
#include "nrf_802154_request.h"
#include "nrf_802154_tx_work_buffer.h"
#include "timer/nrf_802154_timer_sched.h"
#if NRF_802154_ACK_TIMEOUT_ENABLED
@ -68,7 +69,11 @@ static void notify_tx_error(bool result)
{
if (result)
{
nrf_802154_notify_transmit_failed(mp_frame, NRF_802154_TX_ERROR_NO_ACK);
// If waiting for ack timeout occurred, the transmission must had already finished.
nrf_802154_transmit_done_metadata_t metadata = {0};
nrf_802154_tx_work_buffer_original_frame_update(mp_frame, &metadata.frame_props);
nrf_802154_notify_transmit_failed(mp_frame, NRF_802154_TX_ERROR_NO_ACK, &metadata);
}
}

View File

@ -44,7 +44,6 @@
#include "mac_features/nrf_802154_security_pib.h"
#include "nrf_802154_config.h"
#include "nrf_802154_const.h"
#include "nrf_802154_notification.h"
#include "nrf_802154_tx_work_buffer.h"
#include "nrf_802154_utils_byteorder.h"
@ -197,14 +196,24 @@ bool nrf_802154_security_writer_tx_setup(
break;
case NRF_802154_SECURITY_ERROR_KEY_NOT_FOUND:
notify_function(p_frame, NRF_802154_TX_ERROR_KEY_ID_INVALID);
{
nrf_802154_transmit_done_metadata_t metadata = {};
metadata.frame_props = p_params->frame_props;
notify_function(p_frame, NRF_802154_TX_ERROR_KEY_ID_INVALID, &metadata);
result = false;
break;
}
break;
case NRF_802154_SECURITY_ERROR_FRAME_COUNTER_OVERFLOW:
notify_function(p_frame, NRF_802154_TX_ERROR_FRAME_COUNTER_ERROR);
{
nrf_802154_transmit_done_metadata_t metadata = {};
metadata.frame_props = p_params->frame_props;
notify_function(p_frame, NRF_802154_TX_ERROR_FRAME_COUNTER_ERROR, &metadata);
result = false;
break;
}
break;
default:
/* frame_counter_inject function shall not return other error codes than those

View File

@ -57,7 +57,6 @@
#include "nrf_802154_nrfx_addons.h"
#include "nrf_802154_pib.h"
#include "nrf_802154_request.h"
#include "nrf_802154_rssi.h"
#include "nrf_802154_rx_buffer.h"
#include "nrf_802154_stats.h"
#include "hal/nrf_radio.h"
@ -79,12 +78,10 @@
#include "mac_features/ack_generator/nrf_802154_ack_data.h"
#include "nrf_802154_sl_ant_div.h"
#include "nrf_802154_sl_crit_sect_if.h"
#include "nrf_802154_sl_capabilities.h"
#define RAW_LENGTH_OFFSET 0
#define RAW_PAYLOAD_OFFSET 1
#if !NRF_802154_USE_RAW_API
#if !NRF_802154_USE_RAW_API || NRF_802154_CARRIER_FUNCTIONS_ENABLED
/** Static transmit buffer used by @sa nrf_802154_transmit() family of functions.
*
* If none of functions using this buffer is called and link time optimization is enabled, this
@ -92,6 +89,9 @@
*/
static uint8_t m_tx_buffer[RAW_PAYLOAD_OFFSET + MAX_PACKET_SIZE];
#endif // !NRF_802154_USE_RAW_API || NRF_802154_CARRIER_FUNCTIONS_ENABLED
#if !NRF_802154_USE_RAW_API
/**
* @brief Fill transmit buffer with given data.
*
@ -110,6 +110,24 @@ static void tx_buffer_fill(const uint8_t * p_data, uint8_t length)
#endif // !NRF_802154_USE_RAW_API
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Fill the transmit buffer with given data in order to use it with the
* modulated carrier functionality.
*
* @param[in] p_data Pointer to array containing modulating data.
*/
static void tx_buffer_fill_for_modulated_carrier(const uint8_t * p_data)
{
uint8_t length = p_data[RAW_LENGTH_OFFSET];
assert(length <= MAX_PACKET_SIZE);
memcpy(m_tx_buffer, p_data, RAW_PAYLOAD_OFFSET + length);
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
static inline bool are_frame_properties_valid(const nrf_802154_transmitted_frame_props_t * p_props)
{
return p_props->dynamic_data_is_set || !(p_props->is_secured);
@ -203,7 +221,7 @@ uint32_t nrf_802154_first_symbol_timestamp_get(uint32_t end_timestamp, uint8_t p
void nrf_802154_init(void)
{
nrf_802154_sl_crit_sect_interface_t crit_sect_int =
static const nrf_802154_sl_crit_sect_interface_t crit_sect_int =
{
.enter = nrf_802154_critical_section_enter,
.exit = nrf_802154_critical_section_exit
@ -213,6 +231,7 @@ void nrf_802154_init(void)
nrf_802154_core_init();
nrf_802154_clock_init();
nrf_802154_critical_section_init();
nrf_802154_sl_crit_sect_init(&crit_sect_int);
nrf_802154_debug_init();
nrf_802154_notification_init();
nrf_802154_lp_timer_init();
@ -221,7 +240,7 @@ void nrf_802154_init(void)
nrf_802154_rsch_prio_drop_init();
nrf_802154_random_init();
nrf_802154_request_init();
nrf_802154_rsch_crit_sect_init(&crit_sect_int);
nrf_802154_rsch_crit_sect_init();
nrf_802154_rsch_init();
nrf_802154_rx_buffer_init();
nrf_802154_temperature_init();
@ -379,11 +398,15 @@ nrf_802154_state_t nrf_802154_state_get(void)
case RADIO_STATE_CCA:
return NRF_802154_STATE_CCA;
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_CONTINUOUS_CARRIER:
return NRF_802154_STATE_CONTINUOUS_CARRIER;
case RADIO_STATE_MODULATED_CARRIER:
return NRF_802154_STATE_MODULATED_CARRIER;
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
}
return NRF_802154_STATE_INVALID;
@ -542,7 +565,7 @@ bool nrf_802154_transmit_raw_at(uint8_t * p_data
result = are_frame_properties_valid(&p_metadata->frame_props);
if (result)
{
result = nrf_802154_delayed_trx_transmit(p_data, t0, dt, p_metadata);
result = nrf_802154_request_transmit_raw_at(p_data, t0, dt, p_metadata);
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
@ -555,7 +578,7 @@ bool nrf_802154_transmit_at_cancel(void)
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
result = nrf_802154_delayed_trx_transmit_cancel();
result = nrf_802154_request_transmit_at_cancel();
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return result;
@ -571,7 +594,7 @@ bool nrf_802154_receive_at(uint32_t t0,
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
result = nrf_802154_delayed_trx_receive(t0, dt, timeout, channel, id);
result = nrf_802154_request_receive_at(t0, dt, timeout, channel, id);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return result;
@ -583,7 +606,7 @@ bool nrf_802154_receive_at_cancel(uint32_t id)
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
result = nrf_802154_delayed_trx_receive_cancel(id);
result = nrf_802154_request_receive_at_cancel(id);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return result;
@ -615,6 +638,8 @@ bool nrf_802154_cca(void)
return result;
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_continuous_carrier(void)
{
bool result;
@ -633,12 +658,16 @@ bool nrf_802154_modulated_carrier(const uint8_t * p_data)
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
result = nrf_802154_request_modulated_carrier(NRF_802154_TERM_NONE, p_data);
tx_buffer_fill_for_modulated_carrier(p_data);
result = nrf_802154_request_modulated_carrier(NRF_802154_TERM_NONE, m_tx_buffer);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return result;
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
#if NRF_802154_USE_RAW_API
void nrf_802154_buffer_free_raw(uint8_t * p_data)

View File

@ -39,6 +39,7 @@
#include "hal/nrf_ecb.h"
#include "nrf_802154_const.h"
#include "nrf_802154_config.h"
#include "nrf_802154_tx_work_buffer.h"
#include "platform/nrf_802154_irq.h"
@ -138,6 +139,7 @@ static void ecb_init(void)
nrf_802154_irq_clear_pending(ECB_IRQn);
nrf_802154_irq_enable(ECB_IRQn);
nrf_ecb_int_enable(NRF_ECB, NRF_ECB_INT_ENDECB_MASK);
nrf_ecb_int_enable(NRF_ECB, NRF_ECB_INT_ERRORECB_MASK);
}
/******************************************************************************/
@ -384,7 +386,8 @@ static void ecb_irq_handler(void)
uint8_t len = 0;
uint8_t offset;
if (nrf_ecb_event_check(NRF_ECB, NRF_ECB_EVENT_ENDECB))
if (nrf_ecb_int_enable_check(NRF_ECB, NRF_ECB_INT_ENDECB_MASK) &&
nrf_ecb_event_check(NRF_ECB, NRF_ECB_EVENT_ENDECB))
{
nrf_ecb_event_clear(NRF_ECB, NRF_ECB_EVENT_ENDECB);
@ -451,6 +454,23 @@ static void ecb_irq_handler(void)
break;
}
}
if (nrf_ecb_int_enable_check(NRF_ECB, NRF_ECB_INT_ERRORECB_MASK) &&
nrf_ecb_event_check(NRF_ECB, NRF_ECB_EVENT_ERRORECB))
{
/*
* It is possible that the ERRORECB event is caused by the
* AAR and CCM peripherals, which share the same hardware resources.
* At this point it is assumed, that ECB, AAR and CCM peripherals
* are not used by anything, except the 802.15.4 driver and
* other MPSL clients and thus it is impossible that ECB was aborted
* for any other reason, than the TX failed event caused by a terminated
* 802.15.4 transmit operation or end of timeslot.
*
* Therefore no action is taken in this handler.
*/
nrf_ecb_event_clear(NRF_ECB, NRF_ECB_EVENT_ERRORECB);
}
}
/**
@ -465,6 +485,11 @@ static void start_ecb_auth_transformation(void)
nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STARTECB);
}
void nrf_802154_aes_ccm_transform_reset(void)
{
m_aes_ccm_data.raw_frame = NULL;
}
bool nrf_802154_aes_ccm_transform_prepare(const nrf_802154_aes_ccm_data_t * p_aes_ccm_data)
{
// Verify that all necessary data is available
@ -519,6 +544,10 @@ void nrf_802154_aes_ccm_transform_start(uint8_t * p_frame)
uint8_t auth_flags = auth_flags_format(&m_aes_ccm_data);
uint8_t * p_x = m_x;
uint8_t * p_b = m_b;
ptrdiff_t offset = mp_ciphertext - mp_work_buffer;
// Copy updated part of the frame
memcpy(mp_work_buffer, p_frame, offset);
// initial settings
memset(p_x, 0, NRF_802154_AES_CCM_BLOCK_SIZE);
@ -530,3 +559,24 @@ void nrf_802154_aes_ccm_transform_start(uint8_t * p_frame)
nrf_ecb_set_key(m_aes_ccm_data.key);
start_ecb_auth_transformation();
}
void nrf_802154_aes_ccm_transform_abort(uint8_t * p_frame)
{
// Verify that the encryption of the correct frame is being aborted.
if (p_frame != m_aes_ccm_data.raw_frame)
{
return;
}
/*
* Temporarily disable ENDECB interrupt, trigger STOPECB task
* to stop encryption in case it is still running and clear
* the ENDECB event in case the encryption has completed.
*/
nrf_ecb_int_disable(NRF_ECB, NRF_ECB_INT_ENDECB_MASK);
nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STOPECB);
nrf_ecb_event_clear(NRF_ECB, NRF_ECB_EVENT_ENDECB);
nrf_ecb_int_enable(NRF_ECB, NRF_ECB_INT_ENDECB_MASK);
m_aes_ccm_data.raw_frame = NULL;
}

View File

@ -62,6 +62,11 @@ typedef struct
uint8_t * raw_frame; ///< Pointer to the buffer that contains the PHR and PSDU of the transmitted frame.
} nrf_802154_aes_ccm_data_t;
/**
* @brief Resets AES-CCM* transformation.
*/
void nrf_802154_aes_ccm_transform_reset(void);
/**
* @brief Prepares AES-CCM* transformation.
*
@ -84,4 +89,11 @@ bool nrf_802154_aes_ccm_transform_prepare(const nrf_802154_aes_ccm_data_t * p_ae
*/
void nrf_802154_aes_ccm_transform_start(uint8_t * p_frame);
/**
* @brief Aborts AES-CCM* transformation.
*
* @param[in] p_frame Pointer to the buffer that contains a frame being transmitted.
*/
void nrf_802154_aes_ccm_transform_abort(uint8_t * p_frame);
#endif // NRF_802154_AES_CCM_H_

View File

@ -54,7 +54,6 @@
#include "nrf_802154_debug.h"
#include "nrf_802154_notification.h"
#include "nrf_802154_nrfx_addons.h"
#include "nrf_802154_peripherals.h"
#include "nrf_802154_pib.h"
#include "nrf_802154_procedures_duration.h"
#include "nrf_802154_rssi.h"
@ -67,11 +66,8 @@
#include "nrf_802154_utils.h"
#include "drivers/nrfx_errors.h"
#include "hal/nrf_radio.h"
#include "mpsl_fem_protocol_api.h"
#include "mac_features/nrf_802154_delayed_trx.h"
#include "mac_features/nrf_802154_filter.h"
#include "mac_features/nrf_802154_frame_parser.h"
#include "mac_features/ack_generator/nrf_802154_ack_data.h"
#include "mac_features/ack_generator/nrf_802154_ack_generator.h"
#include "rsch/nrf_802154_rsch.h"
#include "rsch/nrf_802154_rsch_crit_sect.h"
@ -79,6 +75,7 @@
#include "timer/nrf_802154_timer_sched.h"
#include "platform/nrf_802154_hp_timer.h"
#include "platform/nrf_802154_irq.h"
#include "protocol/mpsl_fem_protocol_api.h"
#include "nrf_802154_core_hooks.h"
#include "nrf_802154_sl_ant_div.h"
@ -91,12 +88,10 @@
/// Overhead of hardware preparation for ED procedure (aTurnaroundTime) [number of iterations]
#define ED_ITERS_OVERHEAD 2U
#define ACK_IFS TURNAROUND_TIME ///< Ack Inter Frame Spacing [us] - delay between last symbol of received frame and first symbol of transmitted Ack
#define MAX_CRIT_SECT_TIME 60 ///< Maximal time that the driver spends in single critical section.
#define MAX_CRIT_SECT_TIME 60 ///< Maximal time that the driver spends in single critical section.
#define LQI_VALUE_FACTOR 4 ///< Factor needed to calculate LQI value based on data from RADIO peripheral
#define LQI_MAX 0xff ///< Maximal LQI value
#define LQI_VALUE_FACTOR 4 ///< Factor needed to calculate LQI value based on data from RADIO peripheral
#define LQI_MAX 0xff ///< Maximal LQI value
/** Get LQI of given received packet. If CRC is calculated by hardware LQI is included instead of CRC
* in the frame. Length is stored in byte with index 0; CRC is 2 last bytes.
@ -133,7 +128,6 @@ typedef struct
{
bool frame_filtered : 1; ///< If frame being received passed filtering operation.
bool frame_parsed : 1; ///< If frame being received has been parsed
bool frame_parsed_result : 1;
bool rx_timeslot_requested : 1; ///< If timeslot for the frame being received is already requested.
bool tx_with_cca : 1; ///< If currently transmitted frame is transmitted with cca.
bool tx_diminished_prio : 1; ///< If priority of the current transmission should be diminished.
@ -215,7 +209,6 @@ static void rx_flags_clear(void)
m_flags.frame_filtered = false;
m_flags.rx_timeslot_requested = false;
m_flags.frame_parsed = false;
m_flags.frame_parsed_result = false;
}
/** Wait for the RSSI measurement. */
@ -297,9 +290,7 @@ static uint32_t timer_coord_timestamp_get(void)
static void received_frame_notify(uint8_t * p_data)
{
nrf_802154_notify_received(p_data, // data
m_last_rssi, // rssi
m_last_lqi); // lqi
nrf_802154_notify_received(p_data, m_last_rssi, m_last_lqi);
}
/** Allow nesting critical sections and notify MAC layer that a frame was received. */
@ -317,7 +308,9 @@ static void receive_failed_notify(nrf_802154_rx_error_t error)
{
nrf_802154_critical_section_nesting_allow();
nrf_802154_notify_receive_failed(error, m_rx_window_id);
// Don't care about the result - if the notification cannot be performed
// no impact on the device's operation is expected
(void)nrf_802154_notify_receive_failed(error, m_rx_window_id, true);
nrf_802154_critical_section_nesting_deny();
}
@ -381,20 +374,24 @@ static void transmitted_frame_notify(uint8_t * p_ack, int8_t power, uint8_t lqi)
}
/** Notify MAC layer that transmission procedure failed. */
static void transmit_failed_notify(uint8_t * p_frame, nrf_802154_tx_error_t error)
static void transmit_failed_notify(uint8_t * p_frame,
nrf_802154_tx_error_t error,
const nrf_802154_transmit_done_metadata_t * p_meta)
{
if (nrf_802154_core_hooks_tx_failed(p_frame, error))
{
nrf_802154_notify_transmit_failed(p_frame, error);
nrf_802154_notify_transmit_failed(p_frame, error, p_meta);
}
}
/** Allow nesting critical sections and notify MAC layer that transmission procedure failed. */
static void transmit_failed_notify_and_nesting_allow(nrf_802154_tx_error_t error)
static void transmit_failed_notify_and_nesting_allow(
nrf_802154_tx_error_t error,
const nrf_802154_transmit_done_metadata_t * p_meta)
{
nrf_802154_critical_section_nesting_allow();
transmit_failed_notify(mp_tx_data, error);
transmit_failed_notify(mp_tx_data, error, p_meta);
nrf_802154_critical_section_nesting_deny();
}
@ -584,8 +581,10 @@ static rsch_prio_t min_required_rsch_prio(radio_state_t state)
case RADIO_STATE_TX:
case RADIO_STATE_TX_ACK:
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_CONTINUOUS_CARRIER:
case RADIO_STATE_MODULATED_CARRIER:
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
return RSCH_PRIO_TX;
case RADIO_STATE_CCA_TX:
@ -685,8 +684,10 @@ static bool can_terminate_current_operation(radio_state_t state,
{
case RADIO_STATE_SLEEP:
case RADIO_STATE_FALLING_ASLEEP:
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_CONTINUOUS_CARRIER:
case RADIO_STATE_MODULATED_CARRIER:
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
result = true;
break;
@ -716,31 +717,48 @@ static void operation_terminated_notify(radio_state_t state, bool receiving_psdu
{
case RADIO_STATE_SLEEP:
case RADIO_STATE_FALLING_ASLEEP:
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_CONTINUOUS_CARRIER:
case RADIO_STATE_MODULATED_CARRIER:
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
break;
case RADIO_STATE_RX:
if (receiving_psdu_now)
{
nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_ABORTED, m_rx_window_id);
// Don't care about the result - if the notification cannot be performed
// no impact on the device's operation is expected
(void)nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_ABORTED,
m_rx_window_id,
true);
}
break;
case RADIO_STATE_TX_ACK:
mp_current_rx_buffer->free = false;
nrf_802154_core_hooks_tx_ack_failed(mp_ack, NRF_802154_TX_ERROR_ABORTED);
received_frame_notify(mp_current_rx_buffer->data);
break;
case RADIO_STATE_CCA_TX:
case RADIO_STATE_TX:
transmit_failed_notify(mp_tx_data, NRF_802154_TX_ERROR_ABORTED);
break;
{
nrf_802154_transmit_done_metadata_t metadata = {};
nrf_802154_tx_work_buffer_original_frame_update(mp_tx_data, &metadata.frame_props);
transmit_failed_notify(mp_tx_data, NRF_802154_TX_ERROR_ABORTED, &metadata);
}
break;
case RADIO_STATE_RX_ACK:
transmit_failed_notify(mp_tx_data, NRF_802154_TX_ERROR_ABORTED);
break;
{
nrf_802154_transmit_done_metadata_t metadata = {};
nrf_802154_tx_work_buffer_original_frame_update(mp_tx_data, &metadata.frame_props);
transmit_failed_notify(mp_tx_data, NRF_802154_TX_ERROR_ABORTED, &metadata);
}
break;
case RADIO_STATE_ED:
nrf_802154_notify_energy_detection_failed(NRF_802154_ED_ERROR_ABORTED);
@ -901,7 +919,11 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl,
/** Enter Sleep state. */
static void sleep_init(void)
{
nrf_802154_timer_coord_stop();
// This function is always executed from a critical section, so this check is safe.
if (timeslot_is_granted())
{
nrf_802154_timer_coord_stop();
}
}
/** Initialize Falling Asleep operation. */
@ -1027,12 +1049,10 @@ static void rx_init(void)
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
// Configure the timer coordinator to get a timestamp of the END event which
// fires several cycles after CRCOK or CRCERROR events.
nrf_802154_timer_coord_timestamp_prepare(
nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_END));
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_end_event_handle_get());
#else
// Configure the timer coordinator to get a timestamp of the CRCOK event.
nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO,
NRF_RADIO_EVENT_CRCOK));
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_crcok_event_handle_get());
#endif
#endif
@ -1069,14 +1089,12 @@ static bool tx_init(const uint8_t * p_data, bool cca)
// Configure the timer coordinator to get a time stamp of the READY event.
// Note: This event triggers CCASTART, so the time stamp of READY event
// is the time stamp when CCA started.
nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO,
NRF_RADIO_EVENT_READY));
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_ready_event_handle_get());
}
else
{
// Configure the timer coordinator to get a time stamp of the PHYEND event.
nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO,
NRF_RADIO_EVENT_PHYEND));
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_phyend_event_handle_get());
}
#endif
@ -1132,6 +1150,8 @@ static void cca_init(void)
nrf_802154_trx_standalone_cca();
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/** Initialize Continuous Carrier operation. */
static void continuous_carrier_init(void)
{
@ -1164,6 +1184,8 @@ static void modulated_carrier_init(const uint8_t * p_data)
nrf_802154_trx_modulated_carrier(p_data);
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
/***************************************************************************************************
* @section Radio Scheduler notification handlers
**************************************************************************************************/
@ -1211,20 +1233,29 @@ static void on_timeslot_ended(void)
case RADIO_STATE_TX_ACK:
state_set(RADIO_STATE_RX);
mp_current_rx_buffer->free = false;
nrf_802154_core_hooks_tx_ack_failed(mp_ack, NRF_802154_TX_ERROR_TIMESLOT_ENDED);
received_frame_notify_and_nesting_allow(mp_current_rx_buffer->data);
break;
case RADIO_STATE_CCA_TX:
case RADIO_STATE_TX:
case RADIO_STATE_RX_ACK:
{
state_set(RADIO_STATE_RX);
transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_TIMESLOT_ENDED);
break;
nrf_802154_transmit_done_metadata_t metadata = {};
nrf_802154_tx_work_buffer_original_frame_update(mp_tx_data, &metadata.frame_props);
transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_TIMESLOT_ENDED,
&metadata);
}
break;
case RADIO_STATE_ED:
case RADIO_STATE_CCA:
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_CONTINUOUS_CARRIER:
case RADIO_STATE_MODULATED_CARRIER:
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_SLEEP:
// Intentionally empty.
break;
@ -1285,8 +1316,10 @@ static void on_preconditions_denied(radio_state_t state)
case RADIO_STATE_ED:
case RADIO_STATE_CCA:
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_CONTINUOUS_CARRIER:
case RADIO_STATE_MODULATED_CARRIER:
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_SLEEP:
// Intentionally empty.
break;
@ -1332,6 +1365,7 @@ static void on_preconditions_approved(radio_state_t state)
cca_init();
break;
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_CONTINUOUS_CARRIER:
continuous_carrier_init();
break;
@ -1339,6 +1373,7 @@ static void on_preconditions_approved(radio_state_t state)
case RADIO_STATE_MODULATED_CARRIER:
modulated_carrier_init(mp_tx_data);
break;
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
default:
assert(false);
@ -1633,12 +1668,10 @@ uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc)
/* Request boosted preconditions */
nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_RX);
/* Request next bcc match event just after all frame bytes are received
* but before FCS. This happens 64us before frame is fully received.
* This time is used for preparation of possible ACK transmission
*/
m_flags.frame_parsed = false;
m_flags.frame_parsed_result = false;
/* Request next bcc match event to occur when basic data necessary for Ack
* generation is received. */
m_flags.frame_parsed = false;
nrf_802154_ack_generator_reset();
bcc = PHR_SIZE +
nrf_802154_frame_parser_addressing_end_offset_get(&m_current_rx_frame_data) +
@ -1671,52 +1704,40 @@ uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc)
{
if (nrf_802154_frame_parser_security_enabled_bit_is_set(&m_current_rx_frame_data))
{
if (nrf_802154_frame_parser_parse_level_get(&m_current_rx_frame_data) <
PARSE_LEVEL_ADDRESSING_END)
{
// All addressing fields and Security Control byte have been received.
uint8_t parsable_bytes =
PHR_SIZE +
nrf_802154_frame_parser_addressing_end_offset_get(&m_current_rx_frame_data) +
SECURITY_CONTROL_SIZE;
(void)nrf_802154_frame_parser_valid_data_extend(
if (nrf_802154_frame_parser_valid_data_extend(
&m_current_rx_frame_data,
parsable_bytes,
PARSE_LEVEL_SEC_CTRL_OFFSETS);
// Having parsed Security Control field, length of Auxiliary Security Header is
// known. Set BCC there
bcc = PHR_SIZE +
nrf_802154_frame_parser_aux_sec_hdr_end_offset_get(&m_current_rx_frame_data);
}
else if (nrf_802154_frame_parser_parse_level_get(&m_current_rx_frame_data) <
PARSE_LEVEL_AUX_SEC_HDR_END)
num_data_bytes,
PARSE_LEVEL_AUX_SEC_HDR_END))
{
// All security fields have been received.
uint8_t parsable_bytes =
PHR_SIZE +
nrf_802154_frame_parser_aux_sec_hdr_end_offset_get(&m_current_rx_frame_data);
m_flags.frame_parsed = true;
m_flags.frame_parsed_result = nrf_802154_frame_parser_valid_data_extend(
&m_current_rx_frame_data,
parsable_bytes,
PARSE_LEVEL_AUX_SEC_HDR_END);
m_flags.frame_parsed = true;
}
else if (nrf_802154_frame_parser_valid_data_extend(
&m_current_rx_frame_data,
num_data_bytes,
PARSE_LEVEL_SEC_CTRL_OFFSETS))
{
// All addressing fields and Security Control byte have been received.
// With the Security Control field, length of Auxiliary Security Header can be
// determined. Set BCC there
bcc = PHR_SIZE +
nrf_802154_frame_parser_aux_sec_hdr_end_offset_get(&m_current_rx_frame_data);
}
else
{
// This code should be unreachable.
}
}
else if (nrf_802154_frame_parser_valid_data_extend(
&m_current_rx_frame_data,
num_data_bytes,
PARSE_LEVEL_ADDRESSING_END))
{
m_flags.frame_parsed = true;
}
else
{
m_flags.frame_parsed = true;
m_flags.frame_parsed_result = nrf_802154_frame_parser_valid_data_extend(
&m_current_rx_frame_data,
PHR_SIZE +
nrf_802154_frame_parser_addressing_end_offset_get(&m_current_rx_frame_data),
PARSE_LEVEL_ADDRESSING_END);
// This code should be unreachable.
}
}
else
@ -1744,17 +1765,19 @@ uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc)
// which could result in spurious RF emission.
rx_init();
nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_TIMESLOT_ENDED, m_rx_window_id);
// Don't care about the result - if the notification cannot be performed
// no impact on the device's operation is expected
(void)nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_TIMESLOT_ENDED,
m_rx_window_id,
true);
}
}
if (m_flags.frame_filtered &&
m_flags.frame_parsed_result &&
m_flags.frame_parsed &&
nrf_802154_frame_parser_ar_bit_is_set(&m_current_rx_frame_data) &&
nrf_802154_pib_auto_ack_get())
{
nrf_802154_tx_work_buffer_reset(&m_default_frame_props);
mp_ack = nrf_802154_ack_generator_create(&m_current_rx_frame_data);
}
@ -1866,8 +1889,7 @@ void nrf_802154_trx_receive_frame_crcerror(void)
// Configure the timer coordinator to get a timestamp of the END event which
// fires several cycles after CRCOK or CRCERROR events.
nrf_802154_timer_coord_timestamp_prepare(
nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_END));
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_end_event_handle_get());
#endif
#else
@ -1989,27 +2011,23 @@ void nrf_802154_trx_receive_frame_received(void)
nrf_802154_sl_ant_div_rx_frame_received_notify();
bool send_ack = m_flags.frame_filtered &&
nrf_802154_frame_parser_ar_bit_is_set(&m_current_rx_frame_data) &&
nrf_802154_pib_auto_ack_get();
bool send_ack = false;
bool parse_result = nrf_802154_frame_parser_valid_data_extend(
&m_current_rx_frame_data,
PHR_SIZE + nrf_802154_frame_parser_frame_length_get(&m_current_rx_frame_data),
PARSE_LEVEL_FULL);
#if NRF_802154_DISABLE_BCC_MATCHING
bool parse_result = nrf_802154_frame_parser_valid_data_extend(&m_current_rx_frame_data,
p_received_data[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_FULL);
nrf_802154_tx_work_buffer_reset(&m_default_frame_props);
if (send_ack && parse_result)
if (m_flags.frame_filtered &&
parse_result &&
nrf_802154_frame_parser_ar_bit_is_set(&m_current_rx_frame_data) &&
nrf_802154_pib_auto_ack_get())
{
mp_ack = nrf_802154_ack_generator_create(&m_current_rx_frame_data);
nrf_802154_tx_work_buffer_reset(&m_default_frame_props);
mp_ack = nrf_802154_ack_generator_create(&m_current_rx_frame_data);
send_ack = (mp_ack != NULL);
}
#else
bool parse_result = m_flags.frame_parsed_result;
#endif
if (send_ack && parse_result && (NULL != mp_ack))
if (send_ack)
{
state_set(RADIO_STATE_TX_ACK);
@ -2196,12 +2214,10 @@ void nrf_802154_trx_transmit_frame_transmitted(void)
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
// Configure the timer coordinator to get a timestamp of the END event which
// fires several cycles after CRCOK or CRCERROR events.
nrf_802154_timer_coord_timestamp_prepare(
nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_END));
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_end_event_handle_get());
#else
// Configure the timer coordinator to get a timestamp of the CRCOK event.
nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO,
NRF_RADIO_EVENT_CRCOK));
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_crcok_event_handle_get());
#endif
#endif
@ -2270,8 +2286,11 @@ static bool ack_match_check_version_2(const uint8_t * p_tx_frame, const uint8_t
p_tx_frame[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_ADDRESSING_END,
&tx_data);
assert(parse_result);
(void)parse_result;
if (!parse_result)
{
return false;
}
parse_result = nrf_802154_frame_parser_data_init(p_ack_frame,
p_ack_frame[PHR_OFFSET] + PHR_SIZE,
PARSE_LEVEL_ADDRESSING_END,
@ -2337,7 +2356,10 @@ static void on_bad_ack(void)
rx_init();
transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_INVALID_ACK);
nrf_802154_transmit_done_metadata_t metadata = {};
nrf_802154_tx_work_buffer_original_frame_update(mp_tx_data, &metadata.frame_props);
transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_INVALID_ACK, &metadata);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
@ -2415,8 +2437,7 @@ void nrf_802154_trx_transmit_frame_ccaidle(void)
uint32_t ts = timer_coord_timestamp_get();
// Configure the timer coordinator to get a timestamp of the PHYEND event.
nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO,
NRF_RADIO_EVENT_PHYEND));
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_phyend_event_handle_get());
// Update stat timestamp of CCASTART event
nrf_802154_stat_timestamp_write(last_cca_start_timestamp, ts);
@ -2446,7 +2467,10 @@ void nrf_802154_trx_transmit_frame_ccabusy(void)
state_set(RADIO_STATE_RX);
rx_init();
transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_BUSY_CHANNEL);
nrf_802154_transmit_done_metadata_t metadata = {};
nrf_802154_tx_work_buffer_original_frame_update(mp_tx_data, &metadata.frame_props);
transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_BUSY_CHANNEL, &metadata);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
@ -2743,6 +2767,8 @@ bool nrf_802154_core_cca(nrf_802154_term_t term_lvl)
return result;
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_core_continuous_carrier(nrf_802154_term_t term_lvl)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -2793,6 +2819,8 @@ bool nrf_802154_core_modulated_carrier(nrf_802154_term_t term_lvl,
return result;
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_core_notify_buffer_free(uint8_t * p_data)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -2843,6 +2871,7 @@ bool nrf_802154_core_channel_update(req_originator_t req_orig)
}
break;
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case RADIO_STATE_CONTINUOUS_CARRIER:
if (timeslot_is_granted())
{
@ -2857,6 +2886,7 @@ bool nrf_802154_core_channel_update(req_originator_t req_orig)
}
break;
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
default:
// Don't perform any additional action in any other state.
break;

View File

@ -58,29 +58,32 @@ extern "C" {
typedef enum
{
// Sleep
RADIO_STATE_SLEEP, ///< Low power mode (disabled) - the only state in which all radio preconditions are not requested.
RADIO_STATE_FALLING_ASLEEP, ///< Before entering the sleep state, all radio preconditions are requested.
RADIO_STATE_SLEEP, ///< Low power mode (disabled) - the only state in which all radio preconditions are not requested.
RADIO_STATE_FALLING_ASLEEP, ///< Before entering the sleep state, all radio preconditions are requested.
// Receive
RADIO_STATE_RX, ///< The receiver is enabled and it is receiving frames.
RADIO_STATE_TX_ACK, ///< The frame is received and the ACK is being transmitted.
RADIO_STATE_RX, ///< The receiver is enabled and it is receiving frames.
RADIO_STATE_TX_ACK, ///< The frame is received and the ACK is being transmitted.
// Transmit
RADIO_STATE_CCA_TX, ///< Performing CCA followed by the frame transmission.
RADIO_STATE_TX, ///< Transmitting data frame (or beacon).
RADIO_STATE_RX_ACK, ///< Receiving ACK after the transmitted frame.
RADIO_STATE_CCA_TX, ///< Performing CCA followed by the frame transmission.
RADIO_STATE_TX, ///< Transmitting data frame (or beacon).
RADIO_STATE_RX_ACK, ///< Receiving ACK after the transmitted frame.
// Energy Detection
RADIO_STATE_ED, ///< Performing the energy detection procedure.
RADIO_STATE_ED, ///< Performing the energy detection procedure.
// CCA
RADIO_STATE_CCA, ///< Performing the CCA procedure.
RADIO_STATE_CCA, ///< Performing the CCA procedure.
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
// Continuous carrier
RADIO_STATE_CONTINUOUS_CARRIER, ///< Emitting the continuous carrier wave.
// Modulated carrier
RADIO_STATE_MODULATED_CARRIER ///< Emitting the modulated carrier signal.
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
} radio_state_t;
/**
@ -177,6 +180,8 @@ bool nrf_802154_core_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_
*/
bool nrf_802154_core_cca(nrf_802154_term_t term_lvl);
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Requests the transition to the @ref RADIO_STATE_CONTINUOUS_CARRIER state.
*
@ -201,6 +206,8 @@ bool nrf_802154_core_continuous_carrier(nrf_802154_term_t term_lvl);
bool nrf_802154_core_modulated_carrier(nrf_802154_term_t term_lvl,
const uint8_t * p_data);
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
/***************************************************************************************************
* @section State machine notifications
**************************************************************************************************/

View File

@ -64,6 +64,7 @@ typedef bool (* tx_setup_hook)(uint8_t * p_frame
nrf_802154_transmit_failed_notification_t notify_function);
typedef void (* transmitted_hook)(const uint8_t * p_frame);
typedef bool (* tx_failed_hook)(uint8_t * p_frame, nrf_802154_tx_error_t error);
typedef void (* tx_ack_failed_hook)(uint8_t * p_ack, nrf_802154_tx_error_t error);
typedef bool (* tx_started_hook)(uint8_t * p_frame);
typedef void (* rx_started_hook)(const uint8_t * p_frame);
typedef void (* rx_ack_started_hook)(void);
@ -138,6 +139,19 @@ static const tx_failed_hook m_tx_failed_hooks[] =
nrf_802154_ack_timeout_tx_failed_hook,
#endif
#if NRF_802154_ENCRYPTION_ENABLED
nrf_802154_encrypt_tx_failed_hook,
#endif
NULL,
};
static const tx_ack_failed_hook m_tx_ack_failed_hooks[] =
{
#if NRF_802154_ENCRYPTION_ENABLED
nrf_802154_encrypt_tx_ack_failed_hook,
#endif
NULL,
};
@ -306,6 +320,19 @@ bool nrf_802154_core_hooks_tx_failed(uint8_t * p_frame, nrf_802154_tx_error_t er
return result;
}
void nrf_802154_core_hooks_tx_ack_failed(uint8_t * p_ack, nrf_802154_tx_error_t error)
{
for (uint32_t i = 0; i < sizeof(m_tx_ack_failed_hooks) / sizeof(m_tx_ack_failed_hooks[0]); i++)
{
if (m_tx_ack_failed_hooks[i] == NULL)
{
break;
}
m_tx_ack_failed_hooks[i](p_ack, error);
}
}
bool nrf_802154_core_hooks_tx_started(uint8_t * p_frame)
{
bool result = true;

View File

@ -117,6 +117,15 @@ void nrf_802154_core_hooks_transmitted(const uint8_t * p_frame);
*/
bool nrf_802154_core_hooks_tx_failed(uint8_t * p_frame, nrf_802154_tx_error_t error);
/**
* @brief Processes hooks for the ACK TX failed event.
*
* @param[in] p_ack Pointer to a buffer that contains PHR and PSDU of the ACK frame
* that was not transmitted.
* @param[in] error Cause of the failed transmission.
*/
void nrf_802154_core_hooks_tx_ack_failed(uint8_t * p_ack, nrf_802154_tx_error_t error);
/**
* @brief Processes hooks for the TX started event.
*

View File

@ -48,7 +48,6 @@
#include "nrf_802154_config.h"
#include "nrf_802154_debug.h"
#include "nrf_802154_utils.h"
#include "hal/nrf_radio.h"
#include "rsch/nrf_802154_rsch.h"
#include "platform/nrf_802154_lp_timer.h"
#include "platform/nrf_802154_irq.h"
@ -59,7 +58,6 @@
#define NESTED_CRITICAL_SECTION_ALLOWED_PRIORITY_NONE (-1)
static volatile uint8_t m_critical_section_monitor; ///< Monitors each critical section enter operation
static volatile uint8_t m_nested_critical_section_counter; ///< Counter of nested critical sections
static volatile int8_t m_nested_critical_section_allowed_priority; ///< Indicator if nested critical sections are currently allowed
@ -104,106 +102,87 @@ static int8_t active_priority_convert(uint32_t active_priority)
return active_priority == UINT32_MAX ? INT8_MAX : (int8_t)active_priority;
}
/** @brief Check if active vector priority is equal to priority that allows nested crit sections.
*
* @retval true Active vector priority allows nested critical sections.
* @retval false Active vector priority denies nested critical sections.
*/
static bool nested_critical_section_is_allowed_in_this_context(void)
/**@brief Returns priority of the currently executing context */
static int8_t active_vector_priority_get(void)
{
return m_nested_critical_section_allowed_priority ==
active_priority_convert(nrf_802154_critical_section_active_vector_priority_get());
return active_priority_convert(nrf_802154_critical_section_active_vector_priority_get());
}
static bool critical_section_enter(bool forced)
{
bool result = false;
uint8_t cnt;
bool result = false;
int8_t active_vector_priority;
nrf_802154_mcu_critical_state_t mcu_cs;
/* We assume that preempting interrupts won't change the priority
* of the currently executing one.
*/
active_vector_priority = active_vector_priority_get();
nrf_802154_mcu_critical_enter(mcu_cs);
if (forced ||
(m_nested_critical_section_counter == 0) ||
nested_critical_section_is_allowed_in_this_context())
(m_nested_critical_section_allowed_priority == active_vector_priority))
{
nrf_802154_mcu_critical_state_t mcu_cs;
uint8_t cnt = m_nested_critical_section_counter;
nrf_802154_mcu_critical_enter(mcu_cs);
++cnt;
m_nested_critical_section_counter = cnt;
do
if (cnt == 1U)
{
cnt = __LDREXB(&m_nested_critical_section_counter);
assert(cnt < UINT8_MAX);
nrf_802154_lp_timer_critical_section_enter();
radio_critical_section_enter();
}
while (__STREXB(cnt + 1, &m_nested_critical_section_counter));
nrf_802154_critical_section_rsch_enter();
nrf_802154_lp_timer_critical_section_enter();
radio_critical_section_enter();
nrf_802154_mcu_critical_exit(mcu_cs);
m_critical_section_monitor++;
result = true;
}
nrf_802154_mcu_critical_exit(mcu_cs);
return result;
}
static void critical_section_exit(void)
{
uint8_t cnt = m_nested_critical_section_counter;
uint8_t monitor;
uint8_t atomic_cnt;
static bool exiting_crit_sect;
bool result;
assert(cnt > 0);
bool succeed = false;
do
{
monitor = m_critical_section_monitor;
uint8_t cnt;
nrf_802154_mcu_critical_state_t mcu_cs;
// If critical section is not nested exit critical section
if (cnt == 1)
nrf_802154_mcu_critical_enter(mcu_cs);
cnt = m_nested_critical_section_counter;
assert(cnt > 0);
--cnt;
if (cnt == 0U)
{
assert(!exiting_crit_sect);
(void)exiting_crit_sect;
exiting_crit_sect = true;
if (nrf_802154_critical_section_rsch_event_is_pending())
{
nrf_802154_mcu_critical_exit(mcu_cs);
nrf_802154_critical_section_rsch_process_pending();
continue;
}
nrf_802154_critical_section_rsch_exit();
radio_critical_section_exit();
nrf_802154_lp_timer_critical_section_exit();
exiting_crit_sect = false;
}
do
{
atomic_cnt = __LDREXB(&m_nested_critical_section_counter);
assert(atomic_cnt == cnt);
}
while (__STREXB(atomic_cnt - 1, &m_nested_critical_section_counter));
m_nested_critical_section_counter = cnt;
// If critical section is not nested verify if during exit procedure RSCH notified
// change of state or critical section was visited by higher priority IRQ meantime.
if (cnt == 1)
{
// Check if critical section must be exited again.
if (nrf_802154_critical_section_rsch_event_is_pending() ||
(monitor != m_critical_section_monitor))
{
result = critical_section_enter(false);
assert(result);
(void)result;
}
else
{
break;
}
}
nrf_802154_mcu_critical_exit(mcu_cs);
succeed = true;
}
while (cnt == 1);
while (!succeed);
}
/***************************************************************************************************
@ -257,8 +236,7 @@ void nrf_802154_critical_section_nesting_allow(void)
NESTED_CRITICAL_SECTION_ALLOWED_PRIORITY_NONE);
assert(m_nested_critical_section_counter >= 1);
m_nested_critical_section_allowed_priority = active_priority_convert(
nrf_802154_critical_section_active_vector_priority_get());
m_nested_critical_section_allowed_priority = active_vector_priority_get();
}
void nrf_802154_critical_section_nesting_deny(void)

View File

@ -106,21 +106,18 @@ bool nrf_802154_critical_section_is_nested(void);
*/
uint32_t nrf_802154_critical_section_active_vector_priority_get(void);
/**
* @brief Function for entering a critical section in the RSCH module.
*/
extern void nrf_802154_critical_section_rsch_enter(void);
/**
* @brief Function for exiting a critical section in the RSCH module.
*/
extern void nrf_802154_critical_section_rsch_exit(void);
/**
* @brief Checks if there is a pending event in the RSCH critical section.
*/
extern bool nrf_802154_critical_section_rsch_event_is_pending(void);
/**
* @brief Process a pending RSCH event.
*
* This function must be called from inside of the critical section.
*/
extern void nrf_802154_critical_section_rsch_process_pending(void);
/**
*@}
**/

View File

@ -63,10 +63,10 @@
nrf_802154_sl_log_local_event(verbosity, local_event_id, param_u16)
/**@brief Records log about event (with parameter) related to global resource.
* @param verbosity Verbosity level of the module in which log is recorded required to emit log.
* @param event_id Event identifier whose meaning is defined globally. Possible values 0...63
* @param param_u16 Additional parameter to be logged with event. Meaning
* of the parameter is defined by value of global_event_id.
* @param verbosity Verbosity level of the module in which log is recorded required to emit log.
* @param global_event_id Event identifier whose meaning is defined globally. Possible values 0...63
* @param param_u16 Additional parameter to be logged with event. Meaning
* of the parameter is defined by value of global_event_id.
*/
#define nrf_802154_log_global_event(verbosity, global_event_id, param_u16) \
nrf_802154_sl_log_global_event(verbosity, global_event_id, param_u16)

View File

@ -57,11 +57,12 @@ typedef enum
NRF_802154_DRV_MODULE_ID_APPLICATION = 1U,
NRF_802154_DRV_MODULE_ID_CORE = 2U,
NRF_802154_DRV_MODULE_ID_CRITICAL_SECTION = 3U,
NRF_802154_DRV_MODULE_ID_TRX = 4U,
NRF_802154_DRV_MODULE_ID_CSMACA = 5U,
NRF_802154_DRV_MODULE_ID_DELAYED_TRX = 6U,
NRF_802154_DRV_MODULE_ID_ACK_TIMEOUT = 7U,
NRF_802154_DRV_MODULE_ID_TRX_PPI = 8U,
NRF_802154_DRV_MODULE_ID_TRX = 4U,
NRF_802154_DRV_MODULE_ID_CSMACA = 5U,
NRF_802154_DRV_MODULE_ID_DELAYED_TRX = 6U,
NRF_802154_DRV_MODULE_ID_ACK_TIMEOUT = 7U,
NRF_802154_DRV_MODULE_ID_TRX_PPI = 8U,
NRF_802154_DRV_MODULE_ID_NOTIFICATION = 9U
} nrf_802154_drv_modules_list_t;
/**

View File

@ -301,6 +301,8 @@ bool nrf_802154_encrypt_ack_prepare(const nrf_802154_frame_parser_data_t * p_ack
nrf_802154_aes_ccm_data_t aes_ccm_data;
bool success = false;
nrf_802154_aes_ccm_transform_reset();
if (!nrf_802154_frame_parser_security_enabled_bit_is_set(p_ack_data))
{
success = true;
@ -323,6 +325,8 @@ bool nrf_802154_encrypt_tx_setup(
nrf_802154_transmit_params_t * p_params,
nrf_802154_transmit_failed_notification_t notify_function)
{
nrf_802154_aes_ccm_transform_reset();
if (p_params->frame_props.is_secured)
{
// The frame is already secured. Pass.
@ -356,7 +360,10 @@ bool nrf_802154_encrypt_tx_setup(
if (!success)
{
notify_function(p_frame, NRF_802154_TX_ERROR_KEY_ID_INVALID);
nrf_802154_transmit_done_metadata_t metadata = {};
metadata.frame_props = p_params->frame_props;
notify_function(p_frame, NRF_802154_TX_ERROR_KEY_ID_INVALID, &metadata);
}
return success;
@ -375,3 +382,19 @@ void nrf_802154_encrypt_tx_ack_started_hook(uint8_t * p_ack)
{
nrf_802154_aes_ccm_transform_start(p_ack);
}
bool nrf_802154_encrypt_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error)
{
(void)error;
nrf_802154_aes_ccm_transform_abort(p_frame);
return true;
}
void nrf_802154_encrypt_tx_ack_failed_hook(uint8_t * p_ack, nrf_802154_tx_error_t error)
{
(void)error;
nrf_802154_aes_ccm_transform_abort(p_ack);
}

View File

@ -90,4 +90,26 @@ bool nrf_802154_encrypt_tx_started_hook(uint8_t * p_frame);
*/
void nrf_802154_encrypt_tx_ack_started_hook(uint8_t * p_ack);
/**
* @brief TX failed hook for the encryption module.
*
* This function aborts the transformation procedure of the provided frame.
*
* @param[in] p_frame Pointer to the buffer that contains a frame being transmitted.
* @param[in] error Cause of the failed transmission.
*
* @retval true Always succeeds.
*/
bool nrf_802154_encrypt_tx_failed_hook(uint8_t * p_frame, nrf_802154_tx_error_t error);
/**
* @brief ACK TX failed hook for the encryption module.
*
* This function aborts the transformation procedure of the provided ACK frame.
*
* @param[in] p_ack Pointer to the buffer that contains a frame being transmitted.
* @param[in] error Cause of the failed transmission.
*/
void nrf_802154_encrypt_tx_ack_failed_hook(uint8_t * p_ack, nrf_802154_tx_error_t error);
#endif /* NRF_802154_ENCRYPT_H_ */

View File

@ -79,14 +79,18 @@ void nrf_802154_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi);
/**
* @brief Notifies the next higher layer that the reception of a frame failed.
*
* @param[in] error Error code that indicates the reason of the failure.
* @param[in] id Identifier of reception window the error occurred in.
* If the error is related to a delayed reception window requested through
* @ref nrf_802154_receive_at, the value of @p id equals the identifier
* of the scheduled reception window. Otherwise, the value of @p id equals
* @ref NRF_802154_RESERVED_IMM_RX_WINDOW_ID.
* @param[in] error Error code that indicates the reason of the failure.
* @param[in] id Identifier of reception window the error occurred in.
* If the error is related to a delayed reception window requested through
* @ref nrf_802154_receive_at, the value of @p id equals the identifier
* of the scheduled reception window. Otherwise, the value of @p id equals
* @ref NRF_802154_RESERVED_IMM_RX_WINDOW_ID.
* @param[in] allow_drop Indicates if the notification can be dropped safely.
*
* @retval true The next higher layer is bound to be notified about the frame reception failure.
* @retval false Notification could not be executed.
*/
void nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id);
bool nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id, bool allow_drop);
/**
* @brief Notifies the next higher layer that a frame was transmitted.
@ -109,9 +113,11 @@ void nrf_802154_notify_transmitted(uint8_t * p_frame
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame that failed
* the transmission operation.
* @param[in] error An error code indicating the reason of the failure.
* @param[in] p_metadata Pointer to a metadata structure to be notified.
*/
void nrf_802154_notify_transmit_failed(uint8_t * p_frame,
nrf_802154_tx_error_t error);
void nrf_802154_notify_transmit_failed(uint8_t * p_frame,
nrf_802154_tx_error_t error,
const nrf_802154_transmit_done_metadata_t * p_metadata);
/**
* @brief Notifies the next higher layer that the energy detection procedure ended.

View File

@ -38,6 +38,8 @@
*
*/
#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_NOTIFICATION
#include "nrf_802154_notification.h"
#include <stdbool.h>
@ -46,6 +48,7 @@
#include "nrf_802154.h"
#include "nrf_802154_critical_section.h"
#include "nrf_802154_debug.h"
#include "nrf_802154_tx_work_buffer.h"
#define RAW_LENGTH_OFFSET 0
@ -58,21 +61,35 @@ void nrf_802154_notification_init(void)
void nrf_802154_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
#if NRF_802154_USE_RAW_API
nrf_802154_received_raw(p_data, power, lqi);
#else // NRF_802154_USE_RAW_API
nrf_802154_received(p_data + RAW_PAYLOAD_OFFSET, p_data[RAW_LENGTH_OFFSET], power, lqi);
#endif // NRF_802154_USE_RAW_API
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
bool nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id, bool allow_drop)
{
(void)allow_drop;
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
nrf_802154_receive_failed(error, id);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return true;
}
void nrf_802154_notify_transmitted(uint8_t * p_frame,
nrf_802154_transmit_done_metadata_t * p_metadata)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
// Update the transmitted frame contents and update frame status flags
nrf_802154_tx_work_buffer_original_frame_update(p_frame,
&p_metadata->frame_props);
@ -88,41 +105,58 @@ void nrf_802154_notify_transmitted(uint8_t * p_frame
nrf_802154_transmitted(p_frame + RAW_PAYLOAD_OFFSET, p_metadata);
#endif // NRF_802154_USE_RAW_API
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_transmit_failed(uint8_t * p_frame,
nrf_802154_tx_error_t error)
void nrf_802154_notify_transmit_failed(uint8_t * p_frame,
nrf_802154_tx_error_t error,
const nrf_802154_transmit_done_metadata_t * p_metadata)
{
nrf_802154_transmit_done_metadata_t metadata = {0};
// Update the failed frame contents and update frame status flags
nrf_802154_tx_work_buffer_original_frame_update(p_frame,
&metadata.frame_props);
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
// Notify
#if NRF_802154_USE_RAW_API
nrf_802154_transmit_failed(p_frame, error, &metadata);
nrf_802154_transmit_failed(p_frame, error, p_metadata);
#else // NRF_802154_USE_RAW_API
nrf_802154_transmit_failed(p_frame + RAW_PAYLOAD_OFFSET, error, &metadata);
nrf_802154_transmit_failed(p_frame + RAW_PAYLOAD_OFFSET, error, p_metadata);
#endif // NRF_802154_USE_RAW_API
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_energy_detected(uint8_t result)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
nrf_802154_energy_detected(result);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_energy_detection_failed(nrf_802154_ed_error_t error)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
nrf_802154_energy_detection_failed(error);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_cca(bool is_free)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
nrf_802154_cca_done(is_free);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_cca_failed(nrf_802154_cca_error_t error)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
nrf_802154_cca_failed(error);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}

View File

@ -38,6 +38,8 @@
*
*/
#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_NOTIFICATION
#include "nrf_802154_notification.h"
#include <assert.h>
@ -47,28 +49,73 @@
#include "nrf_802154.h"
#include "nrf_802154_config.h"
#include "nrf_802154_debug.h"
#include "nrf_802154_peripherals.h"
#include "nrf_802154_queue.h"
#include "nrf_802154_swi.h"
#include "nrf_802154_tx_work_buffer.h"
#include "nrf_802154_utils.h"
#include "hal/nrf_egu.h"
#include "rsch/nrf_802154_rsch.h"
#define RAW_PAYLOAD_OFFSET 1
#define RAW_LENGTH_OFFSET 0
/** Size of notification queue.
/** @brief Size of pool of slots for notifications that must not be lost.
*
* One slot for each receive buffer, one for transmission, one for busy channel and one for energy
* detection.
* The pool needs to contain slots for:
* - immediate operation result notification
* ~ transmission
* ~ energy detection
* ~ standalone CCA
* - CSMA-CA result notification
* - DTX result notification
* - DRX timeout notifications
* - frame received notifications for each receive buffer.
*/
#define NTF_PRIMARY_POOL_SIZE \
(NRF_802154_RX_BUFFERS + NRF_802154_RSCH_DLY_TS_OP_DRX_SLOTS + 3)
/**
* The implementation uses 8-bit integers to address slots with the oldest bit
* indicating pool. That leaves 7 bits for addressing slots within a fixed pool.
* If the pool's size exceeds that width, throw an error.
*/
#if NTF_PRIMARY_POOL_SIZE > 0x7FU
#error NTF_PRIMARY_POOL_SIZE exceeds its bit width
#endif
/** @brief Size of pool of slots for notifications that can be ignored.
*
* The pool needs to contain slots for failed receptions. Its size is chosen arbitrarily.
*/
#define NTF_SECONDARY_POOL_SIZE 4
/** @brief Bitmask that represents slot pool used.
*/
#define NTF_POOL_ID_MASK (1U << 7)
/** @brief Bitmask that indicates a given slot comes from the primary pool.
*/
#define NTF_PRIMARY_POOL_ID_MASK (1U << 7)
/** @brief Bitmask that indicates a given slot comes from the secondary pool.
*/
#define NTF_SECONDARY_POOL_ID_MASK 0U
/** @brief Identifier of an invalid slot.
*/
#define NTF_INVALID_SLOT_ID UINT8_MAX
/** @brief Size of notification queue.
*
* One slot is lost due to simplified queue implementation.
*/
#define NTF_QUEUE_SIZE ((NRF_802154_RX_BUFFERS + 3) + 1)
#define NTF_QUEUE_SIZE (NTF_PRIMARY_POOL_SIZE + NTF_SECONDARY_POOL_SIZE + 1)
#define NTF_INT NRF_EGU_INT_TRIGGERED0 ///< Label of notification interrupt.
#define NTF_TASK NRF_EGU_TASK_TRIGGER0 ///< Label of notification task.
#define NTF_EVENT NRF_EGU_EVENT_TRIGGERED0 ///< Label of notification event.
#define NTF_INT NRF_EGU_INT_TRIGGERED0 ///< Label of notification interrupt.
#define NTF_TASK NRF_EGU_TASK_TRIGGER0 ///< Label of notification task.
#define NTF_EVENT NRF_EGU_EVENT_TRIGGERED0 ///< Label of notification event.
/// Types of notifications in notification queue.
typedef enum
@ -86,7 +133,8 @@ typedef enum
/// Notification data in the notification queue.
typedef struct
{
nrf_802154_ntf_type_t type; ///< Notification type.
volatile uint8_t taken; ///< Indicates if the slot is available.
nrf_802154_ntf_type_t type; ///< Notification type.
union
{
@ -138,11 +186,70 @@ typedef struct
} data; ///< Notification data depending on it's type.
} nrf_802154_ntf_data_t;
static nrf_802154_queue_t m_notifications_queue;
static nrf_802154_ntf_data_t m_notifications_queue_memory[NTF_QUEUE_SIZE];
/// Entry in the notification queue
typedef struct
{
uint8_t id; ///< Identifier of the pool and an entry within.
} nrf_802154_queue_entry_t;
static nrf_802154_ntf_data_t m_primary_ntf_pool[NTF_PRIMARY_POOL_SIZE];
static nrf_802154_ntf_data_t m_secondary_ntf_pool[NTF_SECONDARY_POOL_SIZE];
static nrf_802154_queue_t m_notifications_queue;
static nrf_802154_queue_entry_t m_notifications_queue_memory[NTF_QUEUE_SIZE];
static volatile nrf_802154_mcu_critical_state_t m_mcu_cs;
/** @brief Allocate notification slot from the specified pool.
*
* @param[inout] p_pool Pointer to a pool of slots.
* @param[in] pool_len Length of the pool.
*
* @return Index of the allocated slot or NTF_INVALID_SLOT_ID in case of failure.
*/
static uint8_t ntf_slot_alloc(nrf_802154_ntf_data_t * p_pool, size_t pool_len)
{
// Linear search for a free slot
for (size_t i = 0; i < pool_len; i++)
{
bool slot_found = true;
do
{
uint8_t taken = __LDREXB(&p_pool[i].taken);
if (taken)
{
// The slot is taken. Proceed to the next slot
__CLREX();
slot_found = false;
break;
}
}
while (__STREXB(true, &p_pool[i].taken));
__DMB();
if (slot_found)
{
// Free slot was found and it was successfully marked as taken
return i;
}
}
return NTF_INVALID_SLOT_ID;
}
/** @brief Release a slot.
*
* @param[inout] p_slot Pointer to a slot to free.
*/
static void ntf_slot_free(nrf_802154_ntf_data_t * p_slot)
{
__DMB();
p_slot->taken = false;
}
/**
* Enter notify block.
*
@ -151,7 +258,7 @@ static volatile nrf_802154_mcu_critical_state_t m_mcu_cs;
*
* @return Pointer to an empty slot in the notification queue.
*/
static nrf_802154_ntf_data_t * ntf_enter(void)
static nrf_802154_queue_entry_t * ntf_enter(void)
{
nrf_802154_mcu_critical_enter(m_mcu_cs);
@ -175,6 +282,18 @@ static void ntf_exit(void)
nrf_802154_mcu_critical_exit(m_mcu_cs);
}
/** @brief Push notification to the queue.
*
* @param[in] slot_id Identifier of the pool and a slot within.
*/
static void ntf_push(uint8_t slot_id)
{
nrf_802154_queue_entry_t * p_entry = ntf_enter();
p_entry->id = slot_id;
ntf_exit();
}
/**
* @brief Notifies the next higher layer that a frame was received.
*
@ -183,33 +302,78 @@ static void ntf_exit(void)
* @param[in] p_data Pointer to a buffer that contains PHR and PSDU of the received frame.
* @param[in] power RSSI measured during the frame reception.
* @param[in] lqi LQI that indicates the measured link quality during the frame reception.
*
* @retval true Notification enqueued successfully.
* @retval false Notification could not be performed.
*/
void swi_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi)
bool swi_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi)
{
nrf_802154_ntf_data_t * p_slot = ntf_enter();
uint8_t slot_id = ntf_slot_alloc(m_primary_ntf_pool, NTF_PRIMARY_POOL_SIZE);
if (slot_id == NTF_INVALID_SLOT_ID)
{
// No slots are available.
return false;
}
nrf_802154_ntf_data_t * p_slot = &m_primary_ntf_pool[slot_id];
p_slot->type = NTF_TYPE_RECEIVED;
p_slot->data.received.p_data = p_data;
p_slot->data.received.power = power;
p_slot->data.received.lqi = lqi;
ntf_exit();
ntf_push(slot_id | NTF_PRIMARY_POOL_ID_MASK);
return true;
}
/**
* @brief Notifies the next higher layer that the reception of a frame failed.
*
* @param[in] error Error code that indicates reason of the failure.
*
* @retval true Notification enqueued successfully.
* @retval false Notification could not be performed.
*/
void swi_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
bool swi_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id, bool allow_drop)
{
nrf_802154_ntf_data_t * p_slot = ntf_enter();
nrf_802154_ntf_data_t * p_pool;
size_t pool_len;
uint32_t pool_id_bitmask;
if (!allow_drop)
{
// Choose the primary pool for DRX-related errors
p_pool = m_primary_ntf_pool;
pool_len = NTF_PRIMARY_POOL_SIZE;
pool_id_bitmask = NTF_PRIMARY_POOL_ID_MASK;
}
else
{
// Choose the secondary pool for spurious reception errors
p_pool = m_secondary_ntf_pool;
pool_len = NTF_SECONDARY_POOL_SIZE;
pool_id_bitmask = NTF_SECONDARY_POOL_ID_MASK;
}
uint8_t slot_id = ntf_slot_alloc(p_pool, pool_len);
if (slot_id == NTF_INVALID_SLOT_ID)
{
// No slots are available.
return false;
}
nrf_802154_ntf_data_t * p_slot = &p_pool[slot_id];
p_slot->type = NTF_TYPE_RECEIVE_FAILED;
p_slot->data.receive_failed.error = error;
p_slot->data.receive_failed.id = id;
ntf_exit();
ntf_push(slot_id | pool_id_bitmask);
return true;
}
/**
@ -219,17 +383,30 @@ void swi_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
*
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the transmitted frame.
* @param[in] p_metadata Pointer to a metadata structure describing frame passed in @p p_frame.
*
* @retval true Notification enqueued successfully.
* @retval false Notification could not be performed.
*/
void swi_notify_transmitted(uint8_t * p_frame,
bool swi_notify_transmitted(uint8_t * p_frame,
nrf_802154_transmit_done_metadata_t * p_metadata)
{
nrf_802154_ntf_data_t * p_slot = ntf_enter();
uint8_t slot_id = ntf_slot_alloc(m_primary_ntf_pool, NTF_PRIMARY_POOL_SIZE);
if (slot_id == NTF_INVALID_SLOT_ID)
{
// No slots are available.
return false;
}
nrf_802154_ntf_data_t * p_slot = &m_primary_ntf_pool[slot_id];
p_slot->type = NTF_TYPE_TRANSMITTED;
p_slot->data.transmitted.p_frame = p_frame;
p_slot->data.transmitted.metadata = *p_metadata;
ntf_exit();
ntf_push(slot_id | NTF_PRIMARY_POOL_ID_MASK);
return true;
}
/**
@ -240,19 +417,32 @@ void swi_notify_transmitted(uint8_t * p_frame,
* the transmission.
* @param[in] error Reason of the transmission failure.
* @param[in] p_metadata Pointer to a metadata structure describing frame passed in @p p_frame.
*
* @retval true Notification enqueued successfully.
* @retval false Notification could not be performed.
*/
void swi_notify_transmit_failed(uint8_t * p_frame,
bool swi_notify_transmit_failed(uint8_t * p_frame,
nrf_802154_tx_error_t error,
const nrf_802154_transmit_done_metadata_t * p_metadata)
{
nrf_802154_ntf_data_t * p_slot = ntf_enter();
uint8_t slot_id = ntf_slot_alloc(m_primary_ntf_pool, NTF_PRIMARY_POOL_SIZE);
if (slot_id == NTF_INVALID_SLOT_ID)
{
// No slots are available.
return false;
}
nrf_802154_ntf_data_t * p_slot = &m_primary_ntf_pool[slot_id];
p_slot->type = NTF_TYPE_TRANSMIT_FAILED;
p_slot->data.transmit_failed.p_frame = p_frame;
p_slot->data.transmit_failed.error = error;
p_slot->data.transmit_failed.metadata = *p_metadata;
ntf_exit();
ntf_push(slot_id | NTF_PRIMARY_POOL_ID_MASK);
return true;
}
/**
@ -260,15 +450,28 @@ void swi_notify_transmit_failed(uint8_t * p_fr
* the SWI priority level.
*
* @param[in] result Detected energy level.
*
* @retval true Notification enqueued successfully.
* @retval false Notification could not be performed.
*/
void swi_notify_energy_detected(uint8_t result)
bool swi_notify_energy_detected(uint8_t result)
{
nrf_802154_ntf_data_t * p_slot = ntf_enter();
uint8_t slot_id = ntf_slot_alloc(m_primary_ntf_pool, NTF_PRIMARY_POOL_SIZE);
if (slot_id == NTF_INVALID_SLOT_ID)
{
// No slots are available.
return false;
}
nrf_802154_ntf_data_t * p_slot = &m_primary_ntf_pool[slot_id];
p_slot->type = NTF_TYPE_ENERGY_DETECTED;
p_slot->data.energy_detected.result = result;
ntf_exit();
ntf_push(slot_id | NTF_PRIMARY_POOL_ID_MASK);
return true;
}
/**
@ -276,15 +479,28 @@ void swi_notify_energy_detected(uint8_t result)
* the SWI priority level.
*
* @param[in] error Reason of the energy detection failure.
*
* @retval true Notification enqueued successfully.
* @retval false Notification could not be performed.
*/
void swi_notify_energy_detection_failed(nrf_802154_ed_error_t error)
bool swi_notify_energy_detection_failed(nrf_802154_ed_error_t error)
{
nrf_802154_ntf_data_t * p_slot = ntf_enter();
uint8_t slot_id = ntf_slot_alloc(m_primary_ntf_pool, NTF_PRIMARY_POOL_SIZE);
if (slot_id == NTF_INVALID_SLOT_ID)
{
// No slots are available.
return false;
}
nrf_802154_ntf_data_t * p_slot = &m_primary_ntf_pool[slot_id];
p_slot->type = NTF_TYPE_ENERGY_DETECTION_FAILED;
p_slot->data.energy_detection_failed.error = error;
ntf_exit();
ntf_push(slot_id | NTF_PRIMARY_POOL_ID_MASK);
return true;
}
/**
@ -293,15 +509,28 @@ void swi_notify_energy_detection_failed(nrf_802154_ed_error_t error)
* The notification is triggered from the SWI priority level.
*
* @param[in] channel_free If a free channel was detected.
*
* @retval true Notification enqueued successfully.
* @retval false Notification could not be performed.
*/
void swi_notify_cca(bool channel_free)
bool swi_notify_cca(bool channel_free)
{
nrf_802154_ntf_data_t * p_slot = ntf_enter();
uint8_t slot_id = ntf_slot_alloc(m_primary_ntf_pool, NTF_PRIMARY_POOL_SIZE);
if (slot_id == NTF_INVALID_SLOT_ID)
{
// No slots are available.
return false;
}
nrf_802154_ntf_data_t * p_slot = &m_primary_ntf_pool[slot_id];
p_slot->type = NTF_TYPE_CCA;
p_slot->data.cca.result = channel_free;
ntf_exit();
ntf_push(slot_id | NTF_PRIMARY_POOL_ID_MASK);
return true;
}
/**
@ -310,15 +539,28 @@ void swi_notify_cca(bool channel_free)
* The notification is triggered from the SWI priority level.
*
* @param[in] error Reason of the CCA failure.
*
* @retval true Notification enqueued successfully.
* @retval false Notification could not be performed.
*/
void swi_notify_cca_failed(nrf_802154_cca_error_t error)
bool swi_notify_cca_failed(nrf_802154_cca_error_t error)
{
nrf_802154_ntf_data_t * p_slot = ntf_enter();
uint8_t slot_id = ntf_slot_alloc(m_primary_ntf_pool, NTF_PRIMARY_POOL_SIZE);
if (slot_id == NTF_INVALID_SLOT_ID)
{
// No slots are available.
return false;
}
nrf_802154_ntf_data_t * p_slot = &m_primary_ntf_pool[slot_id];
p_slot->type = NTF_TYPE_CCA_FAILED;
p_slot->data.cca_failed.error = error;
ntf_exit();
ntf_push(slot_id | NTF_PRIMARY_POOL_ID_MASK);
return true;
}
void nrf_802154_notification_init(void)
@ -335,65 +577,128 @@ void nrf_802154_notification_init(void)
void nrf_802154_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi)
{
swi_notify_received(p_data, power, lqi);
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
bool notified = swi_notify_received(p_data, power, lqi);
// It should always be possible to notify a successful reception
assert(notified);
(void)notified;
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
bool nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error, uint32_t id, bool allow_drop)
{
swi_notify_receive_failed(error, id);
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
bool notified = swi_notify_receive_failed(error, id, allow_drop);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return notified;
}
void nrf_802154_notify_transmitted(uint8_t * p_frame,
nrf_802154_transmit_done_metadata_t * p_metadata)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
// Update the transmitted frame contents and update frame status flags
nrf_802154_tx_work_buffer_original_frame_update(p_frame,
&p_metadata->frame_props);
// Notify
swi_notify_transmitted(p_frame, p_metadata);
bool notified = swi_notify_transmitted(p_frame, p_metadata);
// It should always be possible to notify transmission result
assert(notified);
(void)notified;
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_transmit_failed(uint8_t * p_frame,
nrf_802154_tx_error_t error)
void nrf_802154_notify_transmit_failed(uint8_t * p_frame,
nrf_802154_tx_error_t error,
const nrf_802154_transmit_done_metadata_t * p_metadata)
{
nrf_802154_transmit_done_metadata_t metadata = {0};
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
// Update the failed frame contents and update frame status flags
nrf_802154_tx_work_buffer_original_frame_update(p_frame,
&metadata.frame_props);
bool notified = swi_notify_transmit_failed(p_frame, error, p_metadata);
// Notify
swi_notify_transmit_failed(p_frame, error, &metadata);
// It should always be possible to notify transmission result
assert(notified);
(void)notified;
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_energy_detected(uint8_t result)
{
swi_notify_energy_detected(result);
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
bool notified = swi_notify_energy_detected(result);
// It should always be possible to notify energy detection result
assert(notified);
(void)notified;
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_energy_detection_failed(nrf_802154_ed_error_t error)
{
swi_notify_energy_detection_failed(error);
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
bool notified = swi_notify_energy_detection_failed(error);
// It should always be possible to notify energy detection result
assert(notified);
(void)notified;
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_cca(bool is_free)
{
swi_notify_cca(is_free);
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
bool notified = swi_notify_cca(is_free);
// It should always be possible to notify CCA result
assert(notified);
(void)notified;
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notify_cca_failed(nrf_802154_cca_error_t error)
{
swi_notify_cca_failed(error);
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
bool notified = swi_notify_cca_failed(error);
// It should always be possible to notify CCA result
assert(notified);
(void)notified;
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
/**@brief Handles NTF_EVENT on NRF_802154_EGU_INSTANCE */
static void irq_handler_ntf_event(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
while (!nrf_802154_queue_is_empty(&m_notifications_queue))
{
nrf_802154_queue_entry_t * p_entry =
(nrf_802154_queue_entry_t *)nrf_802154_queue_pop_begin(&m_notifications_queue);
uint8_t slot_id = p_entry->id & (~NTF_POOL_ID_MASK);
nrf_802154_ntf_data_t * p_slot =
(nrf_802154_ntf_data_t *)nrf_802154_queue_pop_begin(&m_notifications_queue);
(p_entry->id & NTF_POOL_ID_MASK) ? &m_primary_ntf_pool[slot_id] :
&m_secondary_ntf_pool[slot_id];
switch (p_slot->type)
{
@ -468,7 +773,10 @@ static void irq_handler_ntf_event(void)
}
nrf_802154_queue_pop_commit(&m_notifications_queue);
ntf_slot_free(p_slot);
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
void nrf_802154_notification_swi_irq_handler(void)

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2017 - 2021, Nordic Semiconductor ASA
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file
* This file supplies bitmasks specifying which of the peripherals are used
* by the 802.15.4 driver.
*
* Bitmasks currently provided applies to:
* - PPI or DPPI channels (g_nrf_802154_used_nrf_ppi_channels)
* - PPI or DPPI channel groups (g_nrf_802154_used_nrf_ppi_groups)
*/
#include "nrf_802154_peripherals.h"
#include <stdint.h>
#if NRF_802154_VERIFY_PERIPHS_ALLOC_AGAINST_MPSL
/* Obtaining the MPSL_RESERVED_.. macros */
#include "mpsl.h"
#endif
#if defined(NRF52_SERIES)
#define NRF_802154_PPI_CH_USED_MSK NRF_802154_PPI_CHANNELS_USED_MASK
#define NRF_802154_PPI_GR_USED_MSK NRF_802154_PPI_GROUPS_USED_MASK
#elif defined(NRF53_SERIES)
#define NRF_802154_PPI_CH_USED_MSK NRF_802154_DPPI_CHANNELS_USED_MASK
#define NRF_802154_PPI_GR_USED_MSK NRF_802154_DPPI_GROUPS_USED_MASK
#else
#error Unsupported chip family
#endif
const uint32_t g_nrf_802154_used_nrf_ppi_channels = NRF_802154_PPI_CH_USED_MSK;
const uint32_t g_nrf_802154_used_nrf_ppi_groups = NRF_802154_PPI_GR_USED_MSK;
#if NRF_802154_VERIFY_PERIPHS_ALLOC_AGAINST_MPSL
#if ((NRF_802154_PPI_CH_USED_MSK & MPSL_RESERVED_PPI_CHANNELS) != 0UL)
#error PPI channels for 802.15.4 driver overlap with MPSL channels
#endif
#if ((NRF_802154_PPI_GR_USED_MSK & MPSL_RESERVED_PPI_GROUPS) != 0UL)
#error PPI groups for 802.15.4 driver overlap with MPSL groups
#endif
#endif // NRF_802154_VERIFY_PERIPHS_ALLOC_AGAINST_MPSL

View File

@ -344,7 +344,7 @@ extern "C" {
#endif
/**
* @def NRF_80254_PPI_CHANNELS_USED_MASK
* @def NRF_802154_PPI_CHANNELS_USED_MASK
*
* Bit mask of PPI channels used by the 802.15.4 driver.
*/

View File

@ -44,6 +44,7 @@
#include <nrfx.h>
#include "nrf_802154_config.h"
#include "nrf_802154_debug.h"
#include "nrf_802154_sl_periphs.h"
#ifdef __cplusplus
extern "C" {
@ -113,15 +114,63 @@ extern "C" {
#endif
/**
* @def NRF_802154_DPPI_RADIO_DISABLED_TO_EGU
* @def NRF_802154_DPPI_RADIO_DISABLED
*
* The DPPI channel that connects RADIO_DISABLED event to EGU task.
* The DPPI channel that publishes RADIO_DISABLED event.
*
* @note This option is used by the core module regardless of the driver configuration.
*
*/
#ifndef NRF_802154_DPPI_RADIO_DISABLED_TO_EGU
#define NRF_802154_DPPI_RADIO_DISABLED_TO_EGU 6U
#ifndef NRF_802154_DPPI_RADIO_DISABLED
#define NRF_802154_DPPI_RADIO_DISABLED 7U
#endif
/**
* @def NRF_802154_DPPI_RADIO_READY
*
* The DPPI channel that publishes RADIO_READY event.
*
* @note This option is used by the core module regardless of the driver configuration.
*
*/
#ifndef NRF_802154_DPPI_RADIO_READY
#define NRF_802154_DPPI_RADIO_READY 4U
#endif
/**
* @def NRF_802154_DPPI_RADIO_ADDRESS
*
* The DPPI channel that publishes RADIO_ADDRESS event.
*
* @note This option is used by the core module regardless of the driver configuration.
*
*/
#ifndef NRF_802154_DPPI_RADIO_ADDRESS
#define NRF_802154_DPPI_RADIO_ADDRESS 5U
#endif
/**
* @def NRF_802154_DPPI_RADIO_END
*
* The DPPI channel that publishes RADIO_END event.
*
* @note This option is used by the core module regardless of the driver configuration.
*
*/
#ifndef NRF_802154_DPPI_RADIO_END
#define NRF_802154_DPPI_RADIO_END 6U
#endif
/**
* @def NRF_802154_DPPI_RADIO_PHYEND
*
* The DPPI channel that publishes RADIO_PHYEND event.
*
* @note This option is used by the core module regardless of the driver configuration.
*
*/
#ifndef NRF_802154_DPPI_RADIO_PHYEND
#define NRF_802154_DPPI_RADIO_PHYEND 12U
#endif
/**
@ -134,7 +183,7 @@ extern "C" {
*
*/
#ifndef NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP
#define NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP 7U
#define NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP 10U
#endif
/**
@ -147,7 +196,7 @@ extern "C" {
*
*/
#ifndef NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN
#define NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN 7U
#define NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN 10U
#endif
/**
@ -161,6 +210,28 @@ extern "C" {
#define NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC 8U
#endif
/**
* @def NRF_802154_DPPI_RADIO_CCAIDLE
*
* The DPPI channel that RADIO.CCAIDLE event publishes to
*/
#ifndef NRF_802154_DPPI_RADIO_CCAIDLE
#define NRF_802154_DPPI_RADIO_CCAIDLE 9U
#endif
/**
* @def NRF_802154_DPPI_TIMESTAMPS_USED_MASK
*
* Helper bit mask of DPPI channels used by the 802.15.4 driver for timestamping.
*/
#ifdef NRF_802154_FRAME_TIMESTAMP_ENABLED
#define NRF_802154_DPPI_TIMESTAMPS_USED_MASK \
((1UL << NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE) | \
(1UL << NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE))
#else // NRF_802154_FRAME_TIMESTAMP_ENABLED
#define NRF_802154_DPPI_TIMESTAMPS_USED_MASK 0U
#endif // NRF_802154_FRAME_TIMESTAMP_ENABLED
/**
* @def NRF_802154_DPPI_CHANNELS_USED_MASK
*
@ -168,10 +239,16 @@ extern "C" {
*/
#ifndef NRF_802154_DPPI_CHANNELS_USED_MASK
#define NRF_802154_DPPI_CHANNELS_USED_MASK ( \
(1UL << NRF_802154_DPPI_RADIO_DISABLED_TO_EGU) | \
(1UL << NRF_802154_DPPI_RADIO_DISABLED) | \
(1UL << NRF_802154_DPPI_RADIO_READY) | \
(1UL << NRF_802154_DPPI_RADIO_ADDRESS) | \
(1UL << NRF_802154_DPPI_RADIO_END) | \
(1UL << NRF_802154_DPPI_RADIO_PHYEND) | \
(1UL << NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP) | \
(1UL << NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN) | \
(1UL << NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC))
(1UL << NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC) | \
(1UL << NRF_802154_DPPI_RADIO_CCAIDLE) | \
NRF_802154_DPPI_TIMESTAMPS_USED_MASK)
#endif // NRF_802154_DPPI_CHANNELS_USED_MASK
/**

View File

@ -47,7 +47,6 @@
#include "nrf_802154_config.h"
#include "nrf_802154_const.h"
#include "nrf_802154_nrfx_addons.h"
#include "nrf_802154_utils.h"
#include "fal/nrf_802154_fal.h"

View File

@ -125,6 +125,8 @@ bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl, uint32_t ti
*/
bool nrf_802154_request_cca(nrf_802154_term_t term_lvl);
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Requests entering the @ref RADIO_STATE_CONTINUOUS_CARRIER state.
*
@ -139,6 +141,7 @@ bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl);
* @brief Requests entering the @ref RADIO_STATE_MODULATED_CARRIER state.
*
* @param[in] term_lvl Termination level of this request. Selects procedures to abort.
* @param[in] p_data Pointer to a buffer to modulate the carrier with.
*
* @retval true The driver will enter the modulated carrier state.
* @retval false The driver cannot enter the modulated carrier state due to an ongoing operation.
@ -146,6 +149,8 @@ bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl);
bool nrf_802154_request_modulated_carrier(nrf_802154_term_t term_lvl,
const uint8_t * p_data);
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Requests the driver to free the given buffer.
*
@ -180,6 +185,76 @@ bool nrf_802154_request_rssi_measure(void);
*/
bool nrf_802154_request_rssi_measurement_get(int8_t * p_rssi);
#if NRF_802154_DELAYED_TRX_ENABLED
/**
* @brief Requests a call to @ref nrf_802154_delayed_trx_transmit.
*
* @param[in] p_data Pointer to the array with data to transmit. The first byte must contain
* the frame length (including FCS). The following bytes contain data.
* The CRC is computed automatically by the radio hardware. Therefore,
* the FCS field can contain any bytes.
* @param[in] t0 Base of delay time - absolute time used by the Timer Scheduler,
* in microseconds (us).
* @param[in] dt Delta of delay time from @p t0, in microseconds (us).
* @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data
* to transmit. If @c NULL following metadata are used:
* Field | Value
* ----------------|-----------------------------------------------------
* @c frame_props | @ref NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT
* @c cca | @c true
* @c channel | As returned by @ref nrf_802154_channel_get
*
* @retval true The transmission procedure was scheduled.
* @retval false The driver could not schedule the transmission procedure.
*/
bool nrf_802154_request_transmit_raw_at(uint8_t * p_data,
uint32_t t0,
uint32_t dt,
const nrf_802154_transmit_at_metadata_t * p_metadata);
/**
* @brief Requests a call to @ref nrf_802154_delayed_trx_transmit_cancel.
*
* @retval true The delayed transmission was scheduled and successfully cancelled.
* @retval false No delayed transmission was scheduled.
*/
bool nrf_802154_request_transmit_at_cancel(void);
/**
* @brief Requests a call to @ref nrf_802154_delayed_trx_receive.
*
* @param[in] t0 Base of delay time - absolute time used by the Timer Scheduler,
* in microseconds (us).
* @param[in] dt Delta of delay time from @p t0, in microseconds (us).
* @param[in] timeout Reception timeout (counted from @p t0 + @p dt), in microseconds (us).
* @param[in] channel Radio channel on which the frame is to be received.
* @param[in] id Identifier of the scheduled reception window. If the reception has been
* scheduled successfully, the value of this parameter can be used in
* @ref nrf_802154_receive_at_cancel to cancel it.
*
* @retval true The reception procedure was scheduled.
* @retval false The driver could not schedule the reception procedure.
*/
bool nrf_802154_request_receive_at(uint32_t t0,
uint32_t dt,
uint32_t timeout,
uint8_t channel,
uint32_t id);
/**
* @brief Requests a call to @ref nrf_802154_delayed_trx_receive_cancel.
*
* @param[in] id Identifier of the delayed reception window to be cancelled. If the provided
* value does not refer to any scheduled or active receive window, the function
* returns false.
*
* @retval true The delayed reception was scheduled and successfully cancelled.
* @retval false No delayed reception was scheduled.
*/
bool nrf_802154_request_receive_at_cancel(uint32_t id);
#endif // NRF_802154_DELAYED_TRX_ENABLED
/**
*@}
**/

View File

@ -44,6 +44,7 @@
#include <stdint.h>
#include "nrf_802154_core.h"
#include "mac_features/nrf_802154_delayed_trx.h"
#include "hal/nrf_radio.h"
#define REQUEST_FUNCTION_PARMS(func_core, ...) \
@ -108,6 +109,8 @@ bool nrf_802154_request_cca(nrf_802154_term_t term_lvl)
REQUEST_FUNCTION_PARMS(nrf_802154_core_cca, term_lvl)
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl)
{
REQUEST_FUNCTION_PARMS(nrf_802154_core_continuous_carrier, term_lvl)
@ -119,6 +122,8 @@ bool nrf_802154_request_modulated_carrier(nrf_802154_term_t term_lvl,
REQUEST_FUNCTION_PARMS(nrf_802154_core_modulated_carrier, term_lvl, p_data)
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_request_buffer_free(uint8_t * p_data)
{
REQUEST_FUNCTION_PARMS(nrf_802154_core_notify_buffer_free, p_data)
@ -148,3 +153,38 @@ bool nrf_802154_request_rssi_measurement_get(int8_t * p_rssi)
{
REQUEST_FUNCTION_PARMS(nrf_802154_core_last_rssi_measurement_get, p_rssi)
}
static inline bool are_frame_properties_valid(const nrf_802154_transmitted_frame_props_t * p_props)
{
return p_props->dynamic_data_is_set || !(p_props->is_secured);
}
#if NRF_802154_DELAYED_TRX_ENABLED
bool nrf_802154_request_transmit_raw_at(uint8_t * p_data,
uint32_t t0,
uint32_t dt,
const nrf_802154_transmit_at_metadata_t * p_metadata)
{
REQUEST_FUNCTION_PARMS(nrf_802154_delayed_trx_transmit, p_data, t0, dt, p_metadata);
}
bool nrf_802154_request_transmit_at_cancel(void)
{
REQUEST_FUNCTION(nrf_802154_delayed_trx_transmit_cancel);
}
bool nrf_802154_request_receive_at(uint32_t t0,
uint32_t dt,
uint32_t timeout,
uint8_t channel,
uint32_t id)
{
REQUEST_FUNCTION_PARMS(nrf_802154_delayed_trx_receive, t0, dt, timeout, channel, id);
}
bool nrf_802154_request_receive_at_cancel(uint32_t id)
{
REQUEST_FUNCTION_PARMS(nrf_802154_delayed_trx_receive_cancel, id);
}
#endif

View File

@ -52,9 +52,11 @@
#include "nrf_802154_queue.h"
#include "nrf_802154_rx_buffer.h"
#include "nrf_802154_swi.h"
#include "nrf_802154_types.h"
#include "nrf_802154_utils.h"
#include "hal/nrf_radio.h"
#include "hal/nrf_egu.h"
#include "mac_features/nrf_802154_delayed_trx.h"
#include "platform/nrf_802154_irq.h"
#include <nrf.h>
@ -85,6 +87,10 @@ typedef enum
REQ_TYPE_RSSI_MEASURE,
REQ_TYPE_RSSI_GET,
REQ_TYPE_ANTENNA_UPDATE,
REQ_TYPE_TRANSMIT_AT,
REQ_TYPE_TRANSMIT_AT_CANCEL,
REQ_TYPE_RECEIVE_AT,
REQ_TYPE_RECEIVE_AT_CANCEL,
} nrf_802154_req_type_t;
/// Request data in request queue.
@ -133,6 +139,7 @@ typedef struct
bool * p_result; ///< CCA request result.
} cca; ///< CCA request details.
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
struct
{
nrf_802154_term_t term_lvl; ///< Request priority.
@ -145,6 +152,7 @@ typedef struct
const uint8_t * p_data; ///< Pointer to a buffer to modulate the carrier wave with.
bool * p_result; ///< Modulated carrier request result.
} modulated_carrier; ///< Modulated carrier request details.
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
struct
{
@ -178,7 +186,41 @@ typedef struct
{
bool * p_result; ///< Antenna update request result.
} antenna_update; ///< Antenna update request details.
} data; ///< Request data depending on its type.
#if NRF_802154_DELAYED_TRX_ENABLED
struct
{
uint8_t * p_data;
uint32_t t0;
uint32_t dt;
const nrf_802154_transmit_at_metadata_t * p_metadata;
bool * p_result;
} transmit_at;
struct
{
bool * p_result;
} transmit_at_cancel;
struct
{
uint32_t t0;
uint32_t dt;
uint32_t timeout;
uint8_t channel;
uint32_t id;
bool * p_result;
} receive_at;
struct
{
uint32_t id;
bool * p_result;
} receive_at_cancel;
#endif // NRF_802154_DELAYED_TRX_ENABLED
} data; ///< Request data depending on its type.
} nrf_802154_req_data_t;
/**@brief Instance of a requests queue */
@ -388,6 +430,8 @@ static void swi_cca(nrf_802154_term_t term_lvl, bool * p_result)
req_exit();
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Requests entering the @ref RADIO_STATE_CONTINUOUS_CARRIER state from the SWI priority.
*
@ -426,6 +470,8 @@ static void swi_modulated_carrier(nrf_802154_term_t term_lvl,
req_exit();
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Notifies the core module that the given buffer is not used anymore and can be freed.
*
@ -527,6 +573,68 @@ static void swi_rssi_measurement_get(int8_t * p_rssi, bool * p_result)
req_exit();
}
#if NRF_802154_DELAYED_TRX_ENABLED
static void swi_transmit_at(uint8_t * p_data,
uint32_t t0,
uint32_t dt,
const nrf_802154_transmit_at_metadata_t * p_metadata,
bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
p_slot->type = REQ_TYPE_TRANSMIT_AT;
p_slot->data.transmit_at.p_data = p_data;
p_slot->data.transmit_at.t0 = t0;
p_slot->data.transmit_at.dt = dt;
p_slot->data.transmit_at.p_metadata = p_metadata;
p_slot->data.transmit_at.p_result = p_result;
req_exit();
}
static void swi_transmit_at_cancel(bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
p_slot->type = REQ_TYPE_TRANSMIT_AT_CANCEL;
p_slot->data.transmit_at_cancel.p_result = p_result;
req_exit();
}
static void swi_receive_at(uint32_t t0,
uint32_t dt,
uint32_t timeout,
uint8_t channel,
uint32_t id,
bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
p_slot->type = REQ_TYPE_RECEIVE_AT;
p_slot->data.receive_at.t0 = t0;
p_slot->data.receive_at.dt = dt;
p_slot->data.receive_at.timeout = timeout;
p_slot->data.receive_at.channel = channel;
p_slot->data.receive_at.id = id;
p_slot->data.receive_at.p_result = p_result;
req_exit();
}
static void swi_receive_at_cancel(uint32_t id, bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
p_slot->type = REQ_TYPE_RECEIVE_AT_CANCEL;
p_slot->data.receive_at_cancel.id = id;
p_slot->data.receive_at_cancel.p_result = p_result;
req_exit();
}
#endif // NRF_802154_DELAYED_TRX_ENABLED
void nrf_802154_request_init(void)
{
nrf_802154_queue_init(&m_requests_queue,
@ -588,6 +696,7 @@ bool nrf_802154_request_cca(nrf_802154_term_t term_lvl)
REQUEST_FUNCTION(nrf_802154_core_cca, swi_cca, term_lvl)
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl)
{
REQUEST_FUNCTION(nrf_802154_core_continuous_carrier,
@ -604,6 +713,8 @@ bool nrf_802154_request_modulated_carrier(nrf_802154_term_t term_lvl,
p_data)
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_request_buffer_free(uint8_t * p_data)
{
REQUEST_FUNCTION(nrf_802154_core_notify_buffer_free, swi_buffer_free, p_data)
@ -636,6 +747,36 @@ bool nrf_802154_request_rssi_measurement_get(int8_t * p_rssi)
p_rssi)
}
#if NRF_802154_DELAYED_TRX_ENABLED
bool nrf_802154_request_transmit_raw_at(uint8_t * p_data,
uint32_t t0,
uint32_t dt,
const nrf_802154_transmit_at_metadata_t * p_metadata)
{
REQUEST_FUNCTION(nrf_802154_delayed_trx_transmit, swi_transmit_at, p_data, t0, dt, p_metadata);
}
bool nrf_802154_request_transmit_at_cancel(void)
{
REQUEST_FUNCTION_NO_ARGS(nrf_802154_delayed_trx_transmit_cancel, swi_transmit_at_cancel);
}
bool nrf_802154_request_receive_at(uint32_t t0,
uint32_t dt,
uint32_t timeout,
uint8_t channel,
uint32_t id)
{
REQUEST_FUNCTION(nrf_802154_delayed_trx_receive, swi_receive_at, t0, dt, timeout, channel, id);
}
bool nrf_802154_request_receive_at_cancel(uint32_t id)
{
REQUEST_FUNCTION(nrf_802154_delayed_trx_receive_cancel, swi_receive_at_cancel, id);
}
#endif // NRF_802154_DELAYED_TRX_ENABLED
/**@brief Handles REQ_EVENT on NRF_802154_EGU_INSTANCE */
static void irq_handler_req_event(void)
{
@ -680,6 +821,8 @@ static void irq_handler_req_event(void)
*(p_slot->data.cca.p_result) = nrf_802154_core_cca(p_slot->data.cca.term_lvl);
break;
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case REQ_TYPE_CONTINUOUS_CARRIER:
*(p_slot->data.continuous_carrier.p_result) =
nrf_802154_core_continuous_carrier(
@ -692,6 +835,8 @@ static void irq_handler_req_event(void)
p_slot->data.modulated_carrier.p_data);
break;
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
case REQ_TYPE_BUFFER_FREE:
*(p_slot->data.buffer_free.p_result) =
nrf_802154_core_notify_buffer_free(p_slot->data.buffer_free.p_data);
@ -719,6 +864,35 @@ static void irq_handler_req_event(void)
*(p_slot->data.antenna_update.p_result) = nrf_802154_core_antenna_update();
break;
#if NRF_802154_DELAYED_TRX_ENABLED
case REQ_TYPE_TRANSMIT_AT:
*(p_slot->data.transmit_at.p_result) =
nrf_802154_delayed_trx_transmit(p_slot->data.transmit_at.p_data,
p_slot->data.transmit_at.t0,
p_slot->data.transmit_at.dt,
p_slot->data.transmit_at.p_metadata);
break;
case REQ_TYPE_TRANSMIT_AT_CANCEL:
*(p_slot->data.transmit_at_cancel.p_result) =
nrf_802154_delayed_trx_transmit_cancel();
break;
case REQ_TYPE_RECEIVE_AT:
*(p_slot->data.receive_at.p_result) =
nrf_802154_delayed_trx_receive(p_slot->data.receive_at.t0,
p_slot->data.receive_at.dt,
p_slot->data.receive_at.timeout,
p_slot->data.receive_at.channel,
p_slot->data.receive_at.id);
break;
case REQ_TYPE_RECEIVE_AT_CANCEL:
*(p_slot->data.receive_at_cancel.p_result) =
nrf_802154_delayed_trx_receive_cancel(p_slot->data.receive_at_cancel.id);
break;
#endif // NRF_802154_DELAYED_TRX_ENABLED
default:
assert(false);
}

View File

@ -38,7 +38,7 @@
#include <stdint.h>
/**
* @defgroup nrf_802154_rssi RSSI calculations used internally in the 802.15.4 driver
* @defgroup nrf_802154_rssi RSSI measurement function
* @{
* @ingroup nrf_802154
* @brief RSSI calculations used internally in the 802.15.4 driver.

View File

@ -48,7 +48,6 @@
#include "nrf_802154.h"
#include "nrf_802154_config.h"
#include "nrf_802154_peripherals.h"
#include "nrf_802154_utils.h"
#include "platform/nrf_802154_irq.h"
#if NRF_802154_INTERNAL_SWI_IRQ_HANDLING

View File

@ -41,7 +41,6 @@
#include "nrf_802154_config.h"
#include "nrf_802154_const.h"
#include "nrf_802154_nrfx_addons.h"
#include "nrf_802154_types.h"
#include "nrf_802154_peripherals.h"
#include "nrf_802154_pib.h"
@ -57,8 +56,8 @@
#include "nrf_802154_procedures_duration.h"
#include "nrf_802154_critical_section.h"
#include "mpsl_fem_config_common.h"
#include "mpsl_fem_protocol_api.h"
#include "platform/nrf_802154_irq.h"
#include "protocol/mpsl_fem_protocol_api.h"
#include "nrf_802154_sl_ant_div.h"
@ -76,6 +75,7 @@
#elif defined(NRF5340_XXAA)
#define PPI_CCAIDLE_FEM 0
#define RADIO_BASE NRF_RADIO_NS_BASE
#define FICR_BASE NRF_FICR_NS_BASE
#endif
#if NRF_802154_DISABLE_BCC_MATCHING
@ -133,9 +133,8 @@ void nrf_802154_radio_irq_handler(void); ///< Prototype required by internal RAD
/// Common parameters for the FEM handling.
static const mpsl_fem_event_t m_activate_rx_cc0 =
{
.type = MPSL_FEM_EVENT_TYPE_TIMER,
.override_ppi = false,
.event.timer =
.type = MPSL_FEM_EVENT_TYPE_TIMER,
.event.timer =
{
.p_timer_instance = NRF_802154_TIMER_INSTANCE,
.compare_channel_mask = ((1 << NRF_TIMER_CC_CHANNEL0) | (1 << NRF_TIMER_CC_CHANNEL2)),
@ -147,9 +146,8 @@ static const mpsl_fem_event_t m_activate_rx_cc0 =
static const mpsl_fem_event_t m_activate_tx_cc0 =
{
.type = MPSL_FEM_EVENT_TYPE_TIMER,
.override_ppi = false,
.event.timer =
.type = MPSL_FEM_EVENT_TYPE_TIMER,
.event.timer =
{
.p_timer_instance = NRF_802154_TIMER_INSTANCE,
.compare_channel_mask = ((1 << NRF_TIMER_CC_CHANNEL0) | (1 << NRF_TIMER_CC_CHANNEL2)),
@ -161,10 +159,14 @@ static const mpsl_fem_event_t m_activate_tx_cc0 =
static const mpsl_fem_event_t m_ccaidle =
{
.type = MPSL_FEM_EVENT_TYPE_GENERIC,
.override_ppi = true,
.ppi_ch_id = PPI_CCAIDLE_FEM,
.event.generic.register_address = ((uint32_t)RADIO_BASE + (uint32_t)NRF_RADIO_EVENT_CCAIDLE)
.type = MPSL_FEM_EVENT_TYPE_GENERIC,
#if defined(NRF52_SERIES)
.override_ppi = true,
.ppi_ch_id = PPI_CCAIDLE_FEM,
.event.generic.event = ((uint32_t)RADIO_BASE + (uint32_t)NRF_RADIO_EVENT_CCAIDLE)
#elif defined(NRF53_SERIES)
.event.generic.event = NRF_802154_DPPI_RADIO_CCAIDLE
#endif
};
/**@brief Fal event used by @ref nrf_802154_trx_transmit_ack and @ref txack_finish */
@ -207,8 +209,12 @@ static void receive_ack_abort(void);
static void transmit_frame_abort(void);
static void transmit_ack_abort(void);
static void standalone_cca_abort(void);
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
static void continuous_carrier_abort(void);
static void modulated_carrier_abort(void);
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
static void energy_detection_abort(void);
/** Clear flags describing frame being received. */
@ -310,6 +316,9 @@ static void fem_for_lna_reset(void)
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK);
nrf_802154_trx_ppi_for_fem_clear();
/* There is no need to explicitly deactivate LNA pin during reset as mpsl_fem_abort_set is used
* to provide a deactivation mechanism on DISABLED event.
*/
}
/** Configure FEM to set PA at appropriate time.
@ -406,31 +415,51 @@ static void fem_for_tx_reset(bool cca)
static void device_config_254_apply_tx(void)
{
uint32_t ficr_reg1 = *(volatile uint32_t *)0x10000330UL;
uint32_t ficr_reg2 = *(volatile uint32_t *)0x10000334UL;
uint32_t ficr_reg3 = *(volatile uint32_t *)0x10000338UL;
/* Check if the device is fixed by testing FICR register value.
*
* Only one of the FICR register is tested to optimize the procedure. All the registers shall
* have consistent values, i.e. all registers contain reset values or all registers contain
* values that shall be written to to the radio registers. If it is not true, then it is
* a hardware bug.
*/
/* Check if the device is fixed by testing every FICR register's value separately. */
if (ficr_reg1 != 0xffffffffUL)
{
volatile uint32_t * p_radio_reg1 = (volatile uint32_t *)0x4000174cUL;
volatile uint32_t * p_radio_reg2 = (volatile uint32_t *)0x40001584UL;
volatile uint32_t * p_radio_reg3 = (volatile uint32_t *)0x40001588UL;
uint32_t ficr_reg2 = *(volatile uint32_t *)0x10000334UL;
uint32_t ficr_reg3 = *(volatile uint32_t *)0x10000338UL;
*p_radio_reg1 = ficr_reg1;
}
if (ficr_reg2 != 0xffffffffUL)
{
volatile uint32_t * p_radio_reg2 = (volatile uint32_t *)0x40001584UL;
*p_radio_reg2 = ficr_reg2;
}
if (ficr_reg3 != 0xffffffffUL)
{
volatile uint32_t * p_radio_reg3 = (volatile uint32_t *)0x40001588UL;
*p_radio_reg3 = ficr_reg3;
}
}
#endif
/** @brief Applies ERRATA-117
*
* Shall be called after setting RADIO mode to NRF_RADIO_MODE_IEEE802154_250KBIT.
*/
#if defined(NRF5340_XXAA)
static void errata_117_apply(void)
{
/* Register at 0x01FF0084. */
uint32_t ficr_reg = *(volatile uint32_t *)(FICR_BASE + 0x84UL);
/* Register at 0x41008588. */
volatile uint32_t * p_radio_reg = (volatile uint32_t *)(RADIO_BASE + 0x588UL);
*p_radio_reg = ficr_reg;
}
#endif
void nrf_802154_trx_module_reset(void)
{
m_trx_state = TRX_STATE_DISABLED;
@ -478,6 +507,11 @@ void nrf_802154_trx_enable(void)
nrf_radio_mode_set(NRF_RADIO, NRF_RADIO_MODE_IEEE802154_250KBIT);
#if defined(NRF5340_XXAA)
// Apply ERRATA-117 after setting RADIO mode to NRF_RADIO_MODE_IEEE802154_250KBIT.
errata_117_apply();
#endif
memset(&packet_conf, 0, sizeof(packet_conf));
packet_conf.lflen = 8;
packet_conf.plen = NRF_RADIO_PREAMBLE_LENGTH_32BIT_ZERO;
@ -490,6 +524,8 @@ void nrf_802154_trx_enable(void)
// Configure CRC
nrf_radio_crc_configure(NRF_RADIO, CRC_LENGTH, NRF_RADIO_CRC_ADDR_IEEE802154, CRC_POLYNOMIAL);
nrf_802154_trx_ppi_for_enable();
// Configure CCA
cca_configuration_update();
@ -509,6 +545,9 @@ void nrf_802154_trx_enable(void)
defined(NRF52811_XXAA)
mpsl_fem_abort_set(nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_DISABLED),
PPI_CHGRP_ABORT);
#elif defined(NRF53_SERIES)
mpsl_fem_abort_set(NRF_802154_DPPI_RADIO_DISABLED,
0U); /* The group parameter is ignored by FEM for nRF53 */
#endif
mpsl_fem_deactivate_now(MPSL_FEM_ALL);
@ -554,6 +593,7 @@ static void ppi_all_clear(void)
nrf_802154_trx_ppi_for_fem_clear();
break;
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case TRX_STATE_CONTINUOUS_CARRIER:
nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_TXEN, false);
nrf_802154_trx_ppi_for_fem_clear();
@ -563,6 +603,7 @@ static void ppi_all_clear(void)
nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_TXEN, false);
nrf_802154_trx_ppi_for_fem_clear();
break;
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
case TRX_STATE_ENERGY_DETECTION:
nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_RXEN, false);
@ -572,29 +613,13 @@ static void ppi_all_clear(void)
default:
assert(false);
}
nrf_802154_trx_ppi_for_disable();
}
static void fem_power_down_now(void)
{
mpsl_fem_deactivate_now(MPSL_FEM_ALL);
if (nrf_802154_trx_ppi_for_fem_powerdown_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0))
{
// FEM requires timer to run to perform powering down operation
nrf_timer_event_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0);
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START);
while (!nrf_timer_event_check(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0))
{
// Wait until the event is set.
// The waiting takes several microseconds
}
nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK);
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
nrf_802154_trx_ppi_for_fem_powerdown_clear();
}
mpsl_fem_disable();
}
void nrf_802154_trx_disable(void)
@ -622,15 +647,9 @@ void nrf_802154_trx_disable(void)
nrf_radio_power_set(NRF_RADIO, true);
#if defined(NRF52840_XXAA) || \
defined(NRF52833_XXAA) || \
defined(NRF52820_XXAA) || \
defined(NRF52811_XXAA)
mpsl_fem_lna_configuration_clear();
mpsl_fem_pa_configuration_clear();
mpsl_fem_abort_clear();
#endif
// TODO: Deconfigure FAL PA and LNA here?
mpsl_fem_deactivate_now(MPSL_FEM_ALL);
if (m_trx_state != TRX_STATE_IDLE)
{
@ -774,11 +793,13 @@ void nrf_802154_trx_antenna_update(void)
case TRX_STATE_STANDALONE_CCA:
case TRX_STATE_RXACK:
case TRX_STATE_TXFRAME:
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case TRX_STATE_CONTINUOUS_CARRIER:
case TRX_STATE_MODULATED_CARRIER:
tx_antenna_update();
break;
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
default:
/* Intentionally empty */
break;
@ -1502,6 +1523,7 @@ void nrf_802154_trx_abort(void)
standalone_cca_abort();
break;
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case TRX_STATE_CONTINUOUS_CARRIER:
continuous_carrier_abort();
break;
@ -1509,6 +1531,7 @@ void nrf_802154_trx_abort(void)
case TRX_STATE_MODULATED_CARRIER:
modulated_carrier_abort();
break;
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
case TRX_STATE_ENERGY_DETECTION:
energy_detection_abort();
@ -1746,6 +1769,8 @@ static void standalone_cca_abort(void)
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
void nrf_802154_trx_continuous_carrier(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -1865,6 +1890,8 @@ static void modulated_carrier_abort()
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
void nrf_802154_trx_energy_detection(uint32_t ed_count)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -2521,3 +2548,57 @@ void nrf_802154_trx_swi_irq_handler(void)
}
#endif
const nrf_802154_sl_event_handle_t * nrf_802154_trx_radio_end_event_handle_get(void)
{
static const nrf_802154_sl_event_handle_t r = {
#if defined(DPPI_PRESENT)
.event_addr = NRF_802154_DPPI_RADIO_END,
.shared = true
#else
.event_addr = (uint32_t)&NRF_RADIO->EVENTS_END
#endif
};
return &r;
}
const nrf_802154_sl_event_handle_t * nrf_802154_trx_radio_ready_event_handle_get(void)
{
static const nrf_802154_sl_event_handle_t r = {
#if defined(DPPI_PRESENT)
.event_addr = NRF_802154_DPPI_RADIO_READY,
.shared = true
#else
.event_addr = (uint32_t)&NRF_RADIO->EVENTS_READY
#endif
};
return &r;
}
const nrf_802154_sl_event_handle_t * nrf_802154_trx_radio_crcok_event_handle_get(void)
{
static const nrf_802154_sl_event_handle_t r = {
.event_addr = (uint32_t)&NRF_RADIO->EVENTS_CRCOK,
#if defined(DPPI_PRESENT)
.shared = false
#endif
};
return &r;
}
const nrf_802154_sl_event_handle_t * nrf_802154_trx_radio_phyend_event_handle_get(void)
{
static const nrf_802154_sl_event_handle_t r = {
#if defined(DPPI_PRESENT)
.event_addr = NRF_802154_DPPI_RADIO_PHYEND,
.shared = true
#else
.event_addr = (uint32_t)&NRF_RADIO->EVENTS_PHYEND
#endif
};
return &r;
}

View File

@ -46,6 +46,7 @@
#include <stdint.h>
#include "nrf_802154_config.h"
#include "nrf_802154_sl_types.h"
#ifdef __cplusplus
extern "C" {
@ -157,8 +158,7 @@ void nrf_802154_trx_disable(void);
* @brief Updates currently used antenna.
*
* This function sets the antenna to be used based on antenna diversity interface
* configuration and TRX state. See @ref nrf_802154_sl_ant_div_mode_set,
* @ref nrf_802154_sl_ant_div_antenna_set.
* configuration and TRX state.
*/
void nrf_802154_trx_antenna_update(void);
@ -350,7 +350,7 @@ void nrf_802154_trx_transmit_frame(const void * p_tra
/**@brief Puts the trx module into transmit ACK mode.
*
* @note This function may be called from @ref nrf_802154_trx_receive_received handler only.
* @note This function may be called from @ref nrf_802154_trx_receive_frame_received handler only.
* This is because in this condition only the TIMER peripheral is running and allows timed transmission.
*
* @param[in] p_transmit_buffer Pointer to a buffer containing ACK frame to be transmitted.
@ -384,6 +384,8 @@ bool nrf_802154_trx_go_idle(void);
*/
void nrf_802154_trx_standalone_cca(void);
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**@brief Starts generating continuous carrier.
*
* Generation of a continuous carrier generates no handlers. It may be terminated by a call to
@ -410,6 +412,8 @@ void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer);
/** @brief Restarts generating modulated carrier.*/
void nrf_802154_trx_modulated_carrier_restart(void);
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**@brief Puts trx module into energy detection mode.
*
* Operation ends up with a call to @ref nrf_802154_trx_energy_detection_finished handler.
@ -459,7 +463,7 @@ extern void nrf_802154_trx_receive_ack_started(void);
*
* @note This handler may be triggered several times during receive of a preamble
* of a frame. It can be followed by call to @ref nrf_802154_trx_receive_frame_started
* (if enabled) and then by @ref nrf_802154_trx_receive_frame_crcok or
* (if enabled) and then by @ref nrf_802154_trx_receive_frame_received or
* @ref nrf_802154_trx_receive_frame_crcerror, but there is possibility
* that it will not be followed by these calls (In case when the RADIO didn't found
* full preamble.). If implementation of this handler starts some
@ -486,7 +490,7 @@ extern void nrf_802154_trx_receive_frame_started(void);
/**@brief Handler called during reception of a frame, when given number of bytes is received.
*
* This handler is called from an ISR when given number of bytes (see @ref nrf_802154_trx_receive)
* This handler is called from an ISR when given number of bytes (see @ref nrf_802154_trx_receive_frame)
* have been just received.
*
* @note If the handler decides to abort receive by a call to @ref nrf_802154_trx_abort or
@ -591,7 +595,7 @@ extern void nrf_802154_trx_receive_ack_crcerror(void);
/**@brief Handler called when a cca operation during transmit attempt started.
*
* This handler is called from an ISR when:
* - transmit operation with cca has been started with a call to @ref nrf_802154_transmit_frame(cca=true).
* - transmit operation with cca has been started with a call to @ref nrf_802154_trx_transmit_frame(cca=true).
* - transmit operation was started with parameter @c notifications_mask containing
* TRX_TRANSMIT_NOTIFICATION_CCASTARTED
* - the RADIO peripheral started CCA operation.
@ -604,7 +608,7 @@ extern void nrf_802154_trx_transmit_frame_ccastarted(void);
/**@brief Handler called when a cca operation during transmit attempt was successful.
*
* This handler is called from an ISR when:
* - transmit operation with cca has been started with a call to @ref nrf_802154_transmit_frame(cca=true).
* - transmit operation with cca has been started with a call to @ref nrf_802154_trx_transmit_frame(cca=true).
* - the RADIO detected that channel was free.
*
* When this handler is called following holds:
@ -619,7 +623,7 @@ extern void nrf_802154_trx_transmit_frame_ccaidle(void);
/**@brief Handler called when a cca operation during transmit attempt failed.
*
* This handler is called from an ISR when:
* - transmit operation with cca has been started with a call to @ref nrf_802154_transmit_frame(cca=true).
* - transmit operation with cca has been started with a call to @ref nrf_802154_trx_transmit_frame(cca=true).
* - the RADIO detected that channel was busy.
*
* When this handler is called following holds:
@ -759,11 +763,34 @@ extern void nrf_802154_trx_standalone_cca_finished(bool channel_was_idle);
* - @ref nrf_802154_trx_go_idle,
* - @ref nrf_802154_trx_disable.
*
* @param channel_was_idle Informs implementation of the handler if channel was idle.
* true means the channel was idle, false means the channel was busy.
* @param ed_sample Sample of detected energy.
*/
extern void nrf_802154_trx_energy_detection_finished(uint8_t ed_sample);
/**@brief Returns RADIO->EVENTS_END handle that hardware can subscribe to.
*
* @return RADIO->EVENTS_END handle that hardware can subscribe to.
*/
const nrf_802154_sl_event_handle_t * nrf_802154_trx_radio_end_event_handle_get(void);
/**@brief Returns RADIO->EVENTS_READY handle that hardware can subscribe to.
*
* @return RADIO->EVENTS_READY handle that hardware can subscribe to.
*/
const nrf_802154_sl_event_handle_t * nrf_802154_trx_radio_ready_event_handle_get(void);
/**@brief Returns RADIO->EVENTS_CRCOK handle that hardware can subscribe to.
*
* @return RADIO->EVENTS_CRCOK handle that hardware can subscribe to.
*/
const nrf_802154_sl_event_handle_t * nrf_802154_trx_radio_crcok_event_handle_get(void);
/**@brief Returns RADIO->EVENTS_PHYEND handle that hardware can subscribe to.
*
* @return RADIO->EVENTS_PHYEND handle that hardware can subscribe to.
*/
const nrf_802154_sl_event_handle_t * nrf_802154_trx_radio_phyend_event_handle_get(void);
#ifdef __cplusplus
}
#endif

View File

@ -54,11 +54,45 @@
#define DPPI_CHGRP_RAMP_UP NRF_DPPI_CHANNEL_GROUP0 ///< PPI group used to disable self-disabling PPIs
#define DPPI_CHGRP_RAMP_UP_DIS_TASK NRF_DPPI_TASK_CHG0_DIS ///< PPI task used to disable self-disabling PPIs
#define PPI_DISABLED_EGU NRF_802154_DPPI_RADIO_DISABLED_TO_EGU
#define PPI_DISABLED_EGU NRF_802154_DPPI_RADIO_DISABLED
#define PPI_EGU_RAMP_UP NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP
#define PPI_TIMER_TX_ACK NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN
#define PPI_RADIO_SYNC_EGU_SYNC NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC
void nrf_802154_trx_ppi_for_enable(void)
{
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_DISABLED, PPI_DISABLED_EGU);
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_READY, NRF_802154_DPPI_RADIO_READY);
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS, NRF_802154_DPPI_RADIO_ADDRESS);
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_END, NRF_802154_DPPI_RADIO_END);
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_PHYEND, NRF_802154_DPPI_RADIO_PHYEND);
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE, NRF_802154_DPPI_RADIO_CCAIDLE);
nrf_dppi_channels_enable(NRF_DPPIC,
(1UL << PPI_DISABLED_EGU) |
(1UL << NRF_802154_DPPI_RADIO_READY) |
(1UL << NRF_802154_DPPI_RADIO_ADDRESS) |
(1UL << NRF_802154_DPPI_RADIO_END) |
(1UL << NRF_802154_DPPI_RADIO_PHYEND) |
(1UL << NRF_802154_DPPI_RADIO_CCAIDLE));
}
void nrf_802154_trx_ppi_for_disable(void)
{
nrf_dppi_channels_disable(NRF_DPPIC,
(1UL << PPI_DISABLED_EGU) |
(1UL << NRF_802154_DPPI_RADIO_READY) |
(1UL << NRF_802154_DPPI_RADIO_ADDRESS) |
(1UL << NRF_802154_DPPI_RADIO_END) |
(1UL << NRF_802154_DPPI_RADIO_PHYEND) |
(1UL << NRF_802154_DPPI_RADIO_CCAIDLE));
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE);
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND);
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_END);
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS);
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
}
void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool start_timer)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
@ -77,11 +111,9 @@ void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool star
}
nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, EGU_TASK, PPI_DISABLED_EGU);
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_DISABLED, PPI_DISABLED_EGU);
nrf_dppi_channels_enable(NRF_DPPIC,
(1UL << PPI_EGU_RAMP_UP) |
(1UL << PPI_DISABLED_EGU));
(1UL << PPI_EGU_RAMP_UP));
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
@ -91,8 +123,7 @@ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool st
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
nrf_dppi_channels_disable(NRF_DPPIC,
(1UL << PPI_EGU_RAMP_UP) |
(1UL << PPI_DISABLED_EGU));
(1UL << PPI_EGU_RAMP_UP));
nrf_egu_publish_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT);
nrf_radio_subscribe_clear(NRF_RADIO, ramp_up_task);
@ -105,7 +136,6 @@ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool st
}
nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, EGU_TASK);
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
@ -189,26 +219,6 @@ void nrf_802154_trx_ppi_for_fem_clear(void)
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
bool nrf_802154_trx_ppi_for_fem_powerdown_set(NRF_TIMER_Type * p_instance,
uint32_t compare_channel)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
// TODO: Implement this function when FEM API supports nRF53
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
return false;
}
void nrf_802154_trx_ppi_for_fem_powerdown_clear(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
// TODO: Implement this function when FEM API supports nRF53
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
uint32_t nrf_802154_trx_ppi_group_for_abort_get(void)
{
// TODO: Implement it when external event (like coex) can abort radio operation

View File

@ -45,7 +45,7 @@
#include "nrf_802154_debug_log.h"
#include "nrf_802154_peripherals.h"
#include "mpsl_fem_protocol_api.h"
#include "protocol/mpsl_fem_protocol_api.h"
#include "hal/nrf_egu.h"
#include "hal/nrf_ppi.h"
@ -66,6 +66,16 @@
#define PPI_TIMER_TX_ACK NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN ///< PPI that connects TIMER COMPARE event with RADIO TXEN task
#define PPI_RADIO_SYNC_EGU_SYNC NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC ///< PPI that connects RADIO SYNC event with EGU task for SYNC channel
void nrf_802154_trx_ppi_for_enable(void)
{
// Intentionally empty.
}
void nrf_802154_trx_ppi_for_disable(void)
{
// Intentionally empty.
}
void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool start_timer)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
@ -226,33 +236,6 @@ void nrf_802154_trx_ppi_for_fem_clear(void)
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
bool nrf_802154_trx_ppi_for_fem_powerdown_set(NRF_TIMER_Type * p_instance,
uint32_t compare_channel)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
// PPI_EGU_TIMER_START is reused here on purpose, to save resources,
// as fem powerdown cannot be scheduled simultaneously with fem ramp-up.
bool result = mpsl_fem_prepare_powerdown(p_instance,
compare_channel,
PPI_EGU_TIMER_START,
nrf_radio_event_address_get(NRF_RADIO,
NRF_RADIO_EVENT_DISABLED));
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
return result;
}
void nrf_802154_trx_ppi_for_fem_powerdown_clear(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
nrf_ppi_channel_disable(NRF_PPI, PPI_EGU_TIMER_START);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
uint32_t nrf_802154_trx_ppi_group_for_abort_get(void)
{
return (uint32_t)PPI_CHGRP_ABORT;

View File

@ -46,6 +46,21 @@
#include "hal/nrf_egu.h"
#include "hal/nrf_radio.h"
/**
* @brief Configures (D)PPI connections required for TRX operation.
*
* Actions performed by this function in DPPI variant:
* - RADIO_DISABLED event is published to DPPI designated by NRF_802154_DPPI_RADIO_DISABLED
* - NRF_RADIO_EVENT_CCAIDLE is published to DPPI designated by NRF_802154_DPPI_RADIO_CCAIDLE
* The DPPIs mentioned above may be then subscribed to.
*/
void nrf_802154_trx_ppi_for_enable(void);
/**
* @brief Clears (D)PPI connections required for TRX operation.
*/
void nrf_802154_trx_ppi_for_disable(void);
/**
* @brief Set PPIs to connect RADIO DISABLED event with tasks needed to ramp up.
*
@ -103,7 +118,7 @@ bool nrf_802154_trx_ppi_for_ramp_up_was_triggered(void);
void nrf_802154_trx_ppi_for_ack_tx_set(void);
/**
* @brief Clear PPIs to connect TIMER event with radio TXEN task, needed to ramp up for ACK TX. See @ref void nrf_802154_trx_ppi_for_ack_tx_set
* @brief Clear PPIs to connect TIMER event with radio TXEN task, needed to ramp up for ACK TX. See @ref nrf_802154_trx_ppi_for_ack_tx_set
*/
void nrf_802154_trx_ppi_for_ack_tx_clear(void);
@ -118,27 +133,6 @@ void nrf_802154_trx_ppi_for_fem_set(void);
*/
void nrf_802154_trx_ppi_for_fem_clear(void);
/**
* @brief Prepare FEM to enter powerdown state.
*
* @param[in] p_instance Timer instance that is used to schedule the transition to the Power Down state.
* @param[in] compare_channel Compare channel to hold a value for the timer.
*
* @note This function and @ref nrf_802154_trx_ppi_for_fem_powerdown_clear looks not symetrical.
* It seems it could be better designed. We shall refactor it when porting FEM support to
* nRF53 family.
*
* @retval true FEM powerdown procedure has started.
* @retval false FEM powerdown procedure is not needed.
*/
bool nrf_802154_trx_ppi_for_fem_powerdown_set(NRF_TIMER_Type * p_instance,
uint32_t compare_channel);
/**
* @brief Unconfigure PPIs needed to enter the powerdown state by FEM.
*/
void nrf_802154_trx_ppi_for_fem_powerdown_clear(void);
/**
* @brief Get PPI group id used for disabling radio operations by an external event.
*/

View File

@ -100,9 +100,8 @@ const uint8_t * nrf_802154_tx_work_buffer_get(const uint8_t * p_original_frame);
* buffer. This function performs all necessary updates of the original buffer in place.
*
* @param[inout] p_original_frame Pointer to the original frame to be transmitted.
* @param[out] p_frame_props Pointer to a structure to which @ref m_is_secured and
* @ref m_is_dynamic_data_updated flags' values are to be
* stored.
* @param[out] p_frame_props Pointer to a structure to which properties of the frame
* to be transmitted are stored.
*/
void nrf_802154_tx_work_buffer_original_frame_update(
uint8_t * p_original_frame,

View File

@ -48,10 +48,28 @@
#include "nrf_802154_config.h"
#include "nrf_802154_types.h"
/**
* @brief Timestamp value indicating that the timestamp is inaccurate.
*/
#define NRF_802154_NO_TIMESTAMP 0
/**
* @brief Invalid delayed timeslot identifier.
*/
#define NRF_802154_RESERVED_INVALID_ID UINT32_MAX
/**
* @brief Reception window identifier reserved for immediate reception.
*/
#define NRF_802154_RESERVED_IMM_RX_WINDOW_ID (UINT32_MAX - 1)
#define NRF_802154_RESERVED_IMM_RX_WINDOW_ID (UINT32_MAX - 1)
/**
* @brief Upper bound for delayed reception window identifiers used by the application.
*
* All integers ranging from 0 to @ref NRF_802154_RESERVED_DRX_ID_UPPER_BOUND (inclusive)
* can be used by the application as identifiers of delayed reception windows.
*/
#define NRF_802154_RESERVED_DRX_ID_UPPER_BOUND (UINT32_MAX - 4)
/**
* @brief Select the source matching algorithm.
@ -77,7 +95,7 @@ void nrf_802154_src_addr_matching_method_set(nrf_802154_src_addr_match_t match_m
* - For Standard-compliant, @ref NRF_802154_SRC_ADDR_MATCH_ALWAYS_1
* For more information, see @ref nrf_802154_src_addr_match_t.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @param[in] p_addr Array of bytes containing the address of the node (little-endian).
* @param[in] extended If the given address is an extended MAC address or a short MAC address.
@ -106,7 +124,7 @@ bool nrf_802154_ack_data_set(const uint8_t * p_addr,
* - For Standard-compliant, @ref NRF_802154_SRC_ADDR_MATCH_ALWAYS_1
* For more information, see @ref nrf_802154_src_addr_match_t.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @param[in] p_addr Array of bytes containing the address of the node (little-endian).
* @param[in] extended If the given address is an extended MAC address or a short MAC address.
@ -150,7 +168,7 @@ void nrf_802154_auto_pending_bit_set(bool enabled);
* - For Standard-compliant, @ref NRF_802154_SRC_ADDR_MATCH_ALWAYS_1
* For more information, see @ref nrf_802154_src_addr_match_t.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @note This function makes a copy of the given address.
*
@ -172,7 +190,7 @@ bool nrf_802154_pending_bit_for_addr_set(const uint8_t * p_addr, bool extended);
* - For Standard-compliant, @ref NRF_802154_SRC_ADDR_MATCH_ALWAYS_1
* For more information, see @ref nrf_802154_src_addr_match_t.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @param[in] p_addr Array of bytes containing the address of the node (little-endian).
* @param[in] extended If the given address is an extended MAC address or a short MAC address.
@ -192,13 +210,28 @@ bool nrf_802154_pending_bit_for_addr_clear(const uint8_t * p_addr, bool extended
* - For Standard-compliant, @ref NRF_802154_SRC_ADDR_MATCH_ALWAYS_1
* For more information, see @ref nrf_802154_src_addr_match_t.
*
* The method can be set during initialization phase by calling @ref nrf_802154_src_matching_method.
* The method can be set during initialization phase by calling @ref nrf_802154_src_addr_matching_method_set.
*
* @param[in] extended If the function is to remove all extended MAC addresses or all short
* addresses.
*/
void nrf_802154_pending_bit_for_addr_reset(bool extended);
/**
* @brief Configures the radio CCA mode and threshold.
*
* @param[in] p_cca_cfg Pointer to the CCA configuration structure. Only fields relevant to
* the selected mode are updated.
*/
void nrf_802154_cca_cfg_set(const nrf_802154_cca_cfg_t * p_cca_cfg);
/**
* @brief Gets the current radio CCA configuration.
*
* @param[out] p_cca_cfg Pointer to the structure for the current CCA configuration.
*/
void nrf_802154_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg);
/**
* @brief Initializes the 802.15.4 driver.
*
@ -235,6 +268,59 @@ bool nrf_802154_sleep(void);
*/
bool nrf_802154_receive(void);
/**
* @brief Requests reception at the specified time.
*
* This function works as a delayed version of @ref nrf_802154_receive. It is asynchronous.
* It queues the delayed reception using the Radio Scheduler module.
* If the delayed reception cannot be performed (@ref nrf_802154_receive_at would return false)
* or the requested reception timeslot is denied, @ref nrf_802154_receive_failed is called
* with the @ref NRF_802154_RX_ERROR_DELAYED_TIMESLOT_DENIED argument.
*
* If the requested reception time is in the past, the function returns false and does not
* schedule reception.
*
* A scheduled reception can be cancelled by a call to @ref nrf_802154_receive_at_cancel.
*
* @note The identifier @p id must be unique. It must not have the same value as identifiers
* of other delayed timeslots active at the moment, so that it can be mapped unambiguously
* to an active delayed operation if the request is successful. In particular, none of the reserved
* identifiers can be used.
*
* @param[in] t0 Base of delay time - absolute time used by the Timer Scheduler,
* in microseconds (us).
* @param[in] dt Delta of delay time from @p t0, in microseconds (us).
* @param[in] timeout Reception timeout (counted from @p t0 + @p dt), in microseconds (us).
* @param[in] channel Radio channel on which the frame is to be received.
* @param[in] id Identifier of the scheduled reception window. If the reception has been
* scheduled successfully, the value of this parameter can be used in
* @ref nrf_802154_receive_at_cancel to cancel it.
*
* @retval true The reception procedure was scheduled.
* @retval false The driver could not schedule the reception procedure.
*/
bool nrf_802154_receive_at(uint32_t t0,
uint32_t dt,
uint32_t timeout,
uint8_t channel,
uint32_t id);
/**
* @brief Cancels a delayed reception scheduled by a call to @ref nrf_802154_receive_at.
*
* If the receive window has been scheduled but has not started yet, this function prevents
* entering the receive window. If the receive window has been scheduled and has already started,
* the radio remains in the receive state, but a window timeout will not be reported.
*
* @param[in] id Identifier of the delayed reception window to be cancelled. If the provided
* value does not refer to any scheduled or active receive window, the function
* returns false.
*
* @retval true The delayed reception was scheduled and successfully cancelled.
* @retval false No delayed reception was scheduled.
*/
bool nrf_802154_receive_at_cancel(uint32_t id);
/** @brief Sets the channel on which the radio is to operate.
*
* @param[in] channel Channel number (11-26).
@ -312,6 +398,36 @@ void nrf_802154_promiscuous_set(bool enabled);
*/
bool nrf_802154_cca(void);
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Changes the radio state to continuous carrier.
*
* @note When the radio is emitting continuous carrier signals, it blocks all transmissions on the
* selected channel. This function is to be called only during radio tests. Do not
* use it during normal device operation.
*
* @retval true The continuous carrier procedure was scheduled.
* @retval false The driver could not schedule the continuous carrier procedure.
*/
bool nrf_802154_continuous_carrier(void);
/**
* @brief Changes the radio state to modulated carrier.
*
* @note When the radio is emitting modulated carrier signals, it blocks all transmissions on the
* selected channel. This function is to be called only during radio tests. Do not
* use it during normal device operation.
*
* @param[in] p_data Pointer to a buffer to modulate the carrier with. The first byte is the data length.
*
* @retval true The modulated carrier procedure was scheduled.
* @retval false The driver could not schedule the modulated carrier procedure.
*/
bool nrf_802154_modulated_carrier(const uint8_t * p_data);
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Changes the radio state to energy detection.
*
@ -366,8 +482,11 @@ bool nrf_802154_energy_detection(uint32_t time_us);
* The CRC is computed automatically by the radio hardware. Therefore,
* the FCS field can contain any bytes.
* @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data
* to transmit and additional parameters for the procedure.
* If NULL, @ref NRF_802154_TRANSMIT_METADATA_DEFAULT_INIT is used.
* to transmit. If @c NULL following metadata are used:
* Field | Value
* ----------------|-----------------------------------------------------
* @c frame_props | @ref NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT
* @c cca | @c true
*
* @retval true The transmission procedure was scheduled.
* @retval false The driver could not schedule the transmission procedure.
@ -375,6 +494,13 @@ bool nrf_802154_energy_detection(uint32_t time_us);
bool nrf_802154_transmit_raw(uint8_t * p_data,
const nrf_802154_transmit_metadata_t * p_metadata);
/**
* @}
* @defgroup nrf_802154_csma CSMA-CA procedure
* @{
*/
#if NRF_802154_CSMA_CA_ENABLED || defined(DOXYGEN)
/**
* @brief Performs the CSMA-CA procedure and transmits a frame in case of success.
*
@ -391,7 +517,10 @@ bool nrf_802154_transmit_raw(uint8_t * p_data,
*
* @param[in] p_data Pointer to the frame to transmit. See also @ref nrf_802154_transmit_raw.
* @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data
* to transmit. If NULL, @ref NRF_802154_TRANSMIT_METADATA_DEFAULT_INIT is used.
* to transmit. If @c NULL following metadata are used:
* Field | Value
* ----------------|-----------------------------------------------------
* @c frame_props | @ref NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT
*
* @retval true The chain of CSMA-CA and transmission procedure was scheduled.
* @retval false The driver could not schedule the procedure chain.
@ -399,6 +528,132 @@ bool nrf_802154_transmit_raw(uint8_t * p_data,
bool nrf_802154_transmit_csma_ca_raw(uint8_t * p_data,
const nrf_802154_transmit_csma_ca_metadata_t * p_metadata);
/**
* @brief Sets the minimum value of the backoff exponent (BE) in the CSMA-CA algorithm.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @param[in] min_be Minimum value of the backoff exponent.
*
* @retval true When value provided by @p min_be has been set successfully.
* @retval false Otherwise.
*/
bool nrf_802154_csma_ca_min_be_set(uint8_t min_be);
/**
* @brief Gets the minimum value of the backoff exponent (BE) in the CSMA-CA algorithm.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @return Current minimum value of the backoff exponent.
*/
uint8_t nrf_802154_csma_ca_min_be_get(void);
/**
* @brief Sets the maximum value of the backoff exponent (BE) in the CSMA-CA algorithm.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @param[in] max_be Maximum value of the backoff exponent.
*
* @retval true When value provided by @p max_be has been set successfully.
* @retval false Otherwise.
*/
bool nrf_802154_csma_ca_max_be_set(uint8_t max_be);
/**
* @brief Gets the maximum value of the backoff exponent (BE) in the CSMA-CA algorithm.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @return Current maximum value of the backoff exponent.
*/
uint8_t nrf_802154_csma_ca_max_be_get(void);
/**
* @brief Sets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring
* a channel access failure.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @param[in] max_backoffs Maximum number of backoffs.
*/
void nrf_802154_csma_ca_max_backoffs_set(uint8_t max_backoffs);
/**
* @brief Gets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring
* a channel access failure.
*
* @note This function is available if @ref NRF_802154_CSMA_CA_ENABLED is enabled.
*
* @return Current maximum number of backoffs.
*/
uint8_t nrf_802154_csma_ca_max_backoffs_get(void);
#endif // NRF_802154_CSMA_CA_ENABLED
/**
* @brief Requests transmission at the specified time.
*
* @note This function is implemented in a zero-copy fashion. It passes the given buffer pointer to
* the RADIO peripheral.
*
*
* This function works as a delayed version of @ref nrf_802154_transmit_raw. It is asynchronous.
* It queues the delayed transmission using the Radio Scheduler module and performs it
* at the specified time.
*
* If the delayed transmission is successfully performed, @ref nrf_802154_transmitted_raw is called.
* If the delayed transmission cannot be performed ( @ref nrf_802154_transmit_raw would return @c false)
* or the requested transmission timeslot is denied, @ref nrf_802154_transmit_failed with the
* @ref NRF_802154_TX_ERROR_TIMESLOT_DENIED argument is called.
*
* This function is designed to transmit the first symbol of SHR at the given time.
*
* If the requested transmission time is in the past, the function returns @c false and does not
* schedule transmission.
*
* A successfully scheduled transmission can be cancelled by a call
* to @ref nrf_802154_transmit_at_cancel.
*
* @param[in] p_data Pointer to the array with data to transmit. The first byte must contain
* the frame length (including FCS). The following bytes contain data.
* The CRC is computed automatically by the radio hardware. Therefore,
* the FCS field can contain any bytes.
* @param[in] t0 Base of delay time - absolute time used by the Timer Scheduler,
* in microseconds (us).
* @param[in] dt Delta of delay time from @p t0, in microseconds (us).
* @param[in] p_metadata Pointer to metadata structure. Contains detailed properties of data
* to transmit. If @c NULL following metadata are used:
* Field | Value
* ----------------|-----------------------------------------------------
* @c frame_props | @ref NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT
* @c cca | @c true
* @c channel | As returned by @ref nrf_802154_channel_get
*
* @retval true The transmission procedure was scheduled.
* @retval false The driver could not schedule the transmission procedure.
*/
bool nrf_802154_transmit_raw_at(uint8_t * p_data,
uint32_t t0,
uint32_t dt,
const nrf_802154_transmit_at_metadata_t * p_metadata);
/**
* @brief Cancels a delayed transmission scheduled by a call to @ref nrf_802154_transmit_raw_at.
*
* If a delayed transmission has been scheduled but the transmission has not been started yet,
* a call to this function prevents the transmission. If the transmission is ongoing,
* it will not be aborted.
*
* If a delayed transmission has not been scheduled (or has already finished), this function does
* not change state and returns false.
*
* @retval true The delayed transmission was scheduled and successfully cancelled.
* @retval false No delayed transmission was scheduled.
*/
bool nrf_802154_transmit_at_cancel(void);
/**
* @brief Notifies the driver that the buffer containing the received frame is not used anymore.
*
@ -437,6 +692,24 @@ int8_t nrf_802154_tx_power_get(void);
*/
int8_t nrf_802154_dbm_from_energy_level_calculate(uint8_t energy_level);
/**
* @brief Calculates the timestamp of the first symbol of the preamble in a received frame.
*
* @param[in] end_timestamp Timestamp of the end of the last symbol in the frame,
* in microseconds.
* @param[in] psdu_length Number of bytes in the frame PSDU.
*
* @return Timestamp of the beginning of the first preamble symbol of a given frame,
* in microseconds.
*/
uint32_t nrf_802154_first_symbol_timestamp_get(uint32_t end_timestamp, uint8_t psdu_length);
/**
* @}
* @defgroup nrf_802154_capabilities Radio driver run-time capabilities feature.
* @{
*/
/**
* @brief Gets nRF 802.15.4 Radio Driver Capabilities.
*
@ -454,4 +727,73 @@ nrf_802154_capabilities_t nrf_802154_capabilities_get(void);
*/
uint32_t nrf_802154_time_get(void);
/**
* @}
* @defgroup nrf_802154_security Radio driver MAC security feature.
* @{
*/
/**
* @brief Sets nRF 802.15.4 Radio Driver Global MAC Frame Counter.
*
* The driver automatically increments the counter in every outgoing frame
* which uses the Global MAC Frame Counter.
* This call is meant to set the initial value of the frame counter.
*
* @param[in] frame_counter Global MAC Frame Counter to set.
*/
void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter);
/**
* @brief Store the 802.15.4 MAC Security Key inside the nRF 802.15.4 Radio Driver.
*
* @param[in] p_key Pointer to the key to store. Refer to @ref nrf_802154_key_t for details.
* Storing the key copies the content of the key and key ID into the Radio Driver.
* This input parameter can be destroyed after the call.
*
* @note This function is not reentrant and must be called from thread context only.
*
* @retval NRF_802154_SECURITY_ERROR_NONE Storing of key is successful.
* @retval NRF_802154_SECURITY_ERROR_TYPE_NOT_SUPPORTED Type of the key is not supported.
* @retval NRF_802154_SECURITY_ERROR_MODE_NOT_SUPPORTED ID mode of the key is not supported.
* @retval NRF_802154_SECURITY_ERROR_ALREADY_PRESENT Failed to store the key - key of such id is already
* present. Remove the key first to overwrite.
* @retval NRF_802154_SECURITY_ERROR_STORAGE_FULL Failed to store the key - storage full.
*/
nrf_802154_security_error_t nrf_802154_security_key_store(nrf_802154_key_t * p_key);
/**
* @brief Remove the 802.15.4 MAC Security Key from the nRF 802.15.4 Radio Driver.
*
* @param[in] p_id Pointer to the ID of the key to remove.
*
* @note This function is not reentrant and must be called from thread context only.
*
* @retval NRF_802154_SECURITY_ERROR_NONE Removal of key is successful.
* @retval NRF_802154_SECURITY_ERROR_KEY_NOT_FOUND Failed to remove the key - no such key found.
*/
nrf_802154_security_error_t nrf_802154_security_key_remove(nrf_802154_key_id_t * p_id);
/**
* @}
* @defgroup nrf_802154_ie_writer Radio driver Information Element data injection feature.
* @{
*/
/**
* @brief Sets the value of CSL period to inject into the CSL information element.
*
* @param[in] period CSL period value.
*/
void nrf_802154_csl_writer_period_set(uint16_t period);
/** @} */
/**
* @brief Get time stamps of events gathered by the last operation.
*
* @param[out] p_stat_timestamps Structure that will be filled with current time stamps of events.
*/
void nrf_802154_stat_timestamps_get(nrf_802154_stat_timestamps_t * p_stat_timestamps);
#endif

View File

@ -44,7 +44,6 @@ extern "C" {
#endif
/**
* @}
* @defgroup nrf_802154_config_csma CSMA/CA procedure configuration
* @{
*/
@ -62,12 +61,59 @@ extern "C" {
#endif
#endif
/**
*@}
**/
/**
* @defgroup nrf_802154_config_dtrx Delayed operations configuration
* @{
*/
/**
* @def NRF_802154_DELAYED_TRX_ENABLED
*
* If the delayed transmission and the receive window features are available.
*
*/
#if !defined(CONFIG_NRF_802154_SL_OPENSOURCE)
#ifndef NRF_802154_DELAYED_TRX_ENABLED
#define NRF_802154_DELAYED_TRX_ENABLED 1
#endif
#endif
/**
* @}
* @defgroup nrf_802154_config_security Security configuration
* @{
*/
/**
* @def NRF_802154_SECURITY_KEY_STORAGE_SIZE
*
* Configures the number of keys which are available in the Key Storage.
* This configuration is implementation-independent.
*/
#ifndef NRF_802154_SECURITY_KEY_STORAGE_SIZE
#define NRF_802154_SECURITY_KEY_STORAGE_SIZE 3
#endif
/**
*@}
**/
/**
* @def NRF_802154_CARRIER_FUNCTIONS_ENABLED
*
* Enables functions used for test purposes: nrf_802154_continuous_carrier and
* nrf_802154_modulated_carrier
*/
#ifndef NRF_802154_CARRIER_FUNCTIONS_ENABLED
#define NRF_802154_CARRIER_FUNCTIONS_ENABLED 1
#endif
#ifdef __cplusplus
}
#endif
#endif // NRF_802154_CONFIG_H__
/**
*@}
**/

View File

@ -40,13 +40,190 @@
#ifndef NRF_802154_CONST_H_
#define NRF_802154_CONST_H_
#define MAX_PACKET_SIZE 127 ///< Maximum size of the radio packet.
#define PAN_ID_SIZE 2 ///< Size of the PAN ID.
#define RAW_LENGTH_OFFSET 0 ///< Byte containing the frame length in a raw frame.
#define RAW_PAYLOAD_OFFSET 1 ///< Offset of the frame payload in a raw frame
#define EXTENDED_ADDRESS_SIZE 8 ///< Size of the Extended Mac Address.
#define SHORT_ADDRESS_SIZE 2 ///< Size of the Short Mac Address.
#define ACK_HEADER_WITH_PENDING 0x12 ///< The first byte of an ACK frame containing a pending bit.
#define ACK_HEADER_WITHOUT_PENDING 0x02 ///< The first byte of an ACK frame without a pending bit.
#define ED_MIN_DBM (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#define ACK_REQUEST_OFFSET 1 ///< Byte containing the ACK request bit (+1 for the frame length byte).
#define ACK_REQUEST_BIT (1 << 5) ///< ACK request bit.
#define ASN_IN_NONCE_BIT 0x40 ///< Bit containing the ASN in Nonce field.
#define DEST_ADDR_TYPE_OFFSET 2 ///< Byte containing the destination address type (+1 for the frame length byte).
#define DEST_ADDR_TYPE_MASK 0x0c ///< Mask of bits containing the destination address type.
#define DEST_ADDR_TYPE_EXTENDED 0x0c ///< Bits containing the extended destination address type.
#define DEST_ADDR_TYPE_NONE 0x00 ///< Bits containing a not-present destination address type.
#define DEST_ADDR_TYPE_SHORT 0x08 ///< Bits containing the short destination address type.
#define DEST_ADDR_OFFSET 6 ///< Offset of the destination address in the Data frame (+1 for the frame length byte).
#define DSN_OFFSET 3 ///< Byte containing the DSN value (+1 for the frame length byte).
#define DSN_SUPPRESS_OFFSET 2 ///< Byte containing the DSN suppression field.
#define DSN_SUPPRESS_BIT 0x01 ///< Bits containing the DSN suppression field.
#define FRAME_COUNTER_SUPPRESS_BIT 0x20 ///< Bit containing the Frame Counter Suppression field.
#define FRAME_PENDING_OFFSET 1 ///< Byte containing a pending bit (+1 for the frame length byte).
#define FRAME_PENDING_BIT (1 << 4) ///< Pending bit.
#define FRAME_TYPE_OFFSET 1 ///< Byte containing the frame type bits (+1 for the frame length byte).
#define FRAME_TYPE_MASK 0x07 ///< Mask of bits containing the frame type.
#define FRAME_TYPE_ACK 0x02 ///< Bits containing the ACK frame type.
#define FRAME_TYPE_BEACON 0x00 ///< Bits containing the Beacon frame type.
#define FRAME_TYPE_COMMAND 0x03 ///< Bits containing the Command frame type.
#define FRAME_TYPE_DATA 0x01 ///< Bits containing the Data frame type.
#define FRAME_TYPE_EXTENDED 0x07 ///< Bits containing the Extended frame type.
#define FRAME_TYPE_FRAGMENT 0x06 ///< Bits containing the Fragment or the Frak frame type.
#define FRAME_TYPE_MULTIPURPOSE 0x05 ///< Bits containing the Multipurpose frame type.
#define FRAME_VERSION_OFFSET 2 ///< Byte containing the frame version bits (+1 for the frame length byte).
#define FRAME_VERSION_MASK 0x30 ///< Mask of bits containing the frame version.
#define FRAME_VERSION_0 0x00 ///< Bits containing the frame version 0b00.
#define FRAME_VERSION_1 0x10 ///< Bits containing the frame version 0b01.
#define FRAME_VERSION_2 0x20 ///< Bits containing the frame version 0b10.
#define FRAME_VERSION_3 0x30 ///< Bits containing the frame version 0b11.
#define IE_HEADER_LENGTH_MASK 0x3f ///< Mask of bits containing the length of an IE header content.
#define IE_PRESENT_OFFSET 2 ///< Byte containing the IE Present bit.
#define IE_PRESENT_BIT 0x02 ///< Bits containing the IE Present field.
#define KEY_ID_MODE_0 0 ///< Value of the 0x00 Key Identifier Mode.
#define KEY_ID_MODE_1 1 ///< Value of the 0x01 Key Identifier Mode.
#define KEY_ID_MODE_2 2 ///< Value of the 0x10 Key Identifier Mode.
#define KEY_ID_MODE_3 3 ///< Value of the 0x11 Key Identifier Mode.
#define KEY_ID_MODE_MASK 0x18 ///< Mask of bits containing Key Identifier Mode in the Security Control field.
#define KEY_ID_MODE_BIT_OFFSET 3 ///< Number of bits the Key Identifier Mode is offset in the Security Control field.
#define KEY_ID_MODE_0_MASK 0 ///< Bits containing the 0x00 Key Identifier Mode.
#define KEY_ID_MODE_1_MASK 0x08 ///< Bits containing the 0x01 Key Identifier Mode.
#define KEY_ID_MODE_2_MASK 0x10 ///< Bits containing the 0x10 Key Identifier Mode.
#define KEY_ID_MODE_3_MASK 0x18 ///< Bits containing the 0x11 Key Identifier Mode.
#define KEY_SRC_KEY_ID_MODE_0_SIZE 0 ///< Size of the Key Source field when Key Identifier Mode equals 0.
#define KEY_SRC_KEY_ID_MODE_1_SIZE 0 ///< Size of the Key Source field when Key Identifier Mode equals 1.
#define KEY_SRC_KEY_ID_MODE_2_SIZE 4 ///< Size of the Key Source field when Key Identifier Mode equals 2.
#define KEY_SRC_KEY_ID_MODE_3_SIZE 8 ///< Size of the Key Source field when Key Identifier Mode equals 3.
#define KEY_IDX_SIZE 1 ///< Size of the Key Index field
#define MAC_CMD_COMMAND_ID_SIZE 1 ///< Size of the MAC Command ID field.
#define MAC_CMD_ASSOC_REQ 0x01 ///< Command frame identifier for MAC Association request.
#define MAC_CMD_ASSOC_RESP 0x02 ///< Command frame identifier for MAC Association response.
#define MAC_CMD_DISASSOC_NOTIFY 0x03 ///< Command frame identifier for MAC Disaccociation notification.
#define MAC_CMD_DATA_REQ 0x04 ///< Command frame identifier for MAC Data Requests.
#define MAC_CMD_PANID_CONFLICT 0x05 ///< Command frame identifier for MAC PAN ID conflict notification.
#define MAC_CMD_ORPHAN_NOTIFY 0x06 ///< Command frame identifier for MAC Orphan notification.
#define MAC_CMD_BEACON_REQ 0x07 ///< Command frame identifier for MAC Beacon.
#define MAC_CMD_COORD_REALIGN 0x08 ///< Command frame identifier for MAC Coordinator realignment.
#define MAC_CMD_GTS_REQUEST 0x09 ///< Command frame identifier for MAC GTS request.
#define PAN_ID_COMPR_OFFSET 1 ///< Byte containing the PAN ID compression bit (+1 for the frame length byte).
#define PAN_ID_COMPR_MASK 0x40 ///< PAN ID compression bit.
#define PAN_ID_OFFSET 4 ///< Offset of PAN ID in the Data frame (+1 for the frame length byte).
#define PHR_OFFSET 0 ///< Offset of the PHY header in a frame.
#define PHR_LENGTH_MASK 0x7f ///< Mask of the PHR length field
#define PSDU_OFFSET 1 ///< Offset of the PHY payload.
#define SECURITY_ENABLED_OFFSET 1 ///< Byte containing the Security Enabled bit.
#define SECURITY_ENABLED_BIT 0x08 ///< Bits containing the Security Enabled field.
#define SECURITY_LEVEL_MASK 0x07 ///< Mask of bits containing the Security level field.
#define SECURITY_LEVEL_NONE 0x00 ///< Bits indicating a frame with no security attributes (0b000).
#define SECURITY_LEVEL_MIC_32 0x01 ///< Bits containing the 32-bit Message Integrity Code (0b001).
#define SECURITY_LEVEL_MIC_64 0x02 ///< Bits containing the 64-bit Message Integrity Code (0b010).
#define SECURITY_LEVEL_MIC_128 0x03 ///< Bits containing the 128-bit Message Integrity Code (0b011).
#define SECURITY_LEVEL_ENC_MIC_32 0x05 ///< Bits containing the 32-bit Encrypted Message Integrity Code (0b101).
#define SECURITY_LEVEL_ENC_MIC_64 0x06 ///< Bits containing the 64-bit Encrypted Message Integrity Code (0b110).
#define SECURITY_LEVEL_ENC_MIC_128 0x07 ///< Bits containing the 128-bit Encrypted Message Integrity Code (0b111).
#define SECURITY_LEVEL_MIC_LEVEL_MASK 0x03 ///< Mask of bits encoding the Message Integrity Code length.
#define SRC_ADDR_TYPE_EXTENDED 0xc0 ///< Bits containing the extended source address type.
#define SRC_ADDR_TYPE_NONE 0x00 ///< Bits containing a not-present source address type.
#define SRC_ADDR_TYPE_MASK 0xc0 ///< Mask of bits containing the source address type.
#define SRC_ADDR_TYPE_OFFSET 2 ///< Byte containing the source address type (+1 for the frame length byte).
#define SRC_ADDR_TYPE_SHORT 0x80 ///< Bits containing the short source address type.
#define SRC_ADDR_OFFSET_SHORT_DST 8 ///< Offset of the source address in the Data frame if the destination address is short.
#define SRC_ADDR_OFFSET_EXTENDED_DST 14 ///< Offset of the source address in the Data frame if the destination address is extended.
#define DSN_SIZE 1 ///< Size of the Sequence Number field.
#define FCF_SIZE 2 ///< Size of the FCF field.
#define FCS_SIZE 2 ///< Size of the FCS field.
#define FRAME_COUNTER_SIZE 4 ///< Size of the Frame Counter field.
#define IE_HEADER_SIZE 2 ///< Size of the obligatory IE Header field elements.
#define IMM_ACK_LENGTH 5 ///< Length of the ACK frame.
#define KEY_ID_MODE_1_SIZE 1 ///< Size of the 0x01 Key Identifier Mode field.
#define KEY_ID_MODE_2_SIZE 5 ///< Size of the 0x10 Key Identifier Mode field.
#define KEY_ID_MODE_3_SIZE 9 ///< Size of the 0x11 Key Identifier Mode field.
#define MAX_PACKET_SIZE 127 ///< Maximum size of the radio packet.
#define MIC_32_SIZE 4 ///< Size of MIC with the MIC-32 and ENC-MIC-32 security attributes.
#define MIC_64_SIZE 8 ///< Size of MIC with the MIC-64 and ENC-MIC-64 security attributes.
#define MIC_128_SIZE 16 ///< Size of MIC with the MIC-128 and ENC-MIC-128 security attributes.
#define PAN_ID_SIZE 2 ///< Size of the PAN ID.
#define PHR_SIZE 1 ///< Size of the PHR field.
#define SECURITY_CONTROL_SIZE 1 ///< Size of the Security Control field.
#define AES_CCM_KEY_SIZE 16 ///< Size of AES CCM Key.
#define EXTENDED_ADDRESS_SIZE 8 ///< Size of the Extended Mac Address.
#define SHORT_ADDRESS_SIZE 2 ///< Size of the Short Mac Address.
#define TURNAROUND_TIME 192UL ///< RX-to-TX or TX-to-RX turnaround time (aTurnaroundTime), in microseconds (us).
#define CCA_TIME 128UL ///< Time required to perform CCA detection (aCcaTime), in microseconds (us).
#define UNIT_BACKOFF_PERIOD (TURNAROUND_TIME + CCA_TIME) ///< Number of symbols in the basic time period used by CSMA-CA algorithm (aUnitBackoffPeriod), in (us).
#define PHY_US_PER_SYMBOL 16 ///< Duration of a single symbol in microseconds (us).
#define PHY_SYMBOLS_PER_OCTET 2 ///< Number of symbols in a single byte (octet).
#define PHY_SHR_SYMBOLS 10 ///< Number of symbols in the Synchronization Header (SHR).
#define ED_RESULT_MAX 0xff ///< Maximal ED result.
#define BROADCAST_ADDRESS ((uint8_t[SHORT_ADDRESS_SIZE]) {0xff, 0xff}) ///< Broadcast short address.
#define MIN_SIFS_PERIOD_US 192 ///< Minimum Short IFS period default value in us.
#define MIN_LIFS_PERIOD_US 640 ///< Minimum Long IFS period default value in us.
#define MAX_SIFS_FRAME_SIZE 18 ///< Maximum frame length which can be followed by the Short Interframe Space.
#define NRF_802154_RESERVED_CSMACA_ID (UINT32_MAX - 2) ///< Delayed timeslot identifier reserved for CSMA/CA procedure.
#define NRF_802154_RESERVED_DTX_ID (UINT32_MAX - 3) ///< Delayed timeslot identifier reserved for delayed transmissions.
#define IE_VENDOR_ID 0x00 ///< Vendor-specific IE identifier
#define IE_VENDOR_SIZE_MIN 3 ///< Vendor-specific IE minimum length
#define IE_VENDOR_OUI_OFFSET 0 ///< Vendor-specific IE OUI offset
#define IE_VENDOR_THREAD_SUBTYPE_OFFSET 3 ///< Thread Vendor-specific IE subtype offset
#define IE_VENDOR_THREAD_DATA_OFFSET 4 ///< Thread Vendor-specific IE DATA offset
#define IE_VENDOR_THREAD_OUI 0xeab89b ///< Thread Vendor-specific IE OUI
#define IE_VENDOR_THREAD_SIZE_MIN 4 ///< Thread Vendor-specific IE minimum length
#define IE_VENDOR_THREAD_ACK_PROBING_ID 0x00 ///< Thread Vendor-specific ACK Probing IE subtype ID
#define IE_VENDOR_THREAD_ACK_SIZE_MIN 5 ///< Thread Vendor-specific ACK Probing IE minimum size
#define IE_VENDOR_THREAD_ACK_SIZE_MAX 6 ///< Thread Vendor-specific ACK Probing IE maximum size
#define IE_VENDOR_THREAD_RSSI_TOKEN 0x01 ///< Thread Vendor-specific ACK Probing IE RSSI value placeholder
#define IE_VENDOR_THREAD_MARGIN_TOKEN 0x02 ///< Thread Vendor-specific ACK Probing IE Link margin value placeholder
#define IE_VENDOR_THREAD_LQI_TOKEN 0x03 ///< Thread Vendor-specific ACK Probing IE LQI value placeholder
#define IE_VENDOR_THREAD_RSSI_FLOOR -130 ///< Thread Vendor-specific ACK Probing RSSI floor value used for scaling
#define IE_VENDOR_THREAD_MARGIN_FLOOR 0 ///< Thread Vendor-specific ACK Probing margin floor value used for scaling
#define IE_VENDOR_THREAD_RSSI_CEIL 0 ///< Thread Vendor-specific ACK Probing RSSI ceil value used for scaling
#define IE_VENDOR_THREAD_MARGIN_CEIL 130 ///< Thread Vendor-specific ACK Probing margin ceil value used for scaling
#define IE_CSL_SYMBOLS_PER_UNIT 10 ///< Number of symbols per phase/period unit
#define IE_CSL_PERIOD_MAX 0xffff ///< Maximum CSL IE phase/period value
#define IE_CSL_SIZE_MIN 4 ///< Minimal size of the CSL IE
#define IE_CSL_ID 0x1a ///< CSL IE identifier
#define IE_HT1 0x7e ///< Information Element Header Termination type 1
#define IE_HT2 0x7f ///< Information Element Header Termination type 2
#define IE_LENGTH_MASK 0x7f ///< Information element length mask
#define IE_LENGTH_OFFSET 0x00 ///< Information element length offset
#define IE_ID_OFFSET_0 0x00 ///< Offset of the octet containing the first part of the IE identifier.
#define IE_ID_OFFSET_1 0x01 ///< Offset of the octed containing the second part of the IE identifier.
#define IE_DATA_OFFSET 0x02 ///< Information element data offset
#define IE_HEADER_ELEMENT_ID_OFFSET 0x07 ///< Bit offset of Element ID field in a Header IE header.
#define ED_MIN_DBM (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#endif // NRF_802154_CONST_H_

View File

@ -88,7 +88,24 @@ typedef uint8_t nrf_802154_ed_error_t;
*/
typedef uint8_t nrf_802154_cca_error_t;
#define NRF_802154_CCA_ERROR_ABORTED 0x01 // !< Procedure was aborted by another operation.
#define NRF_802154_CCA_ERROR_ABORTED 0x01 // !< Procedure was aborted by another operation.
/** @brief RADIO Clear Channel Assessment modes. */
#define NRF_RADIO_CCA_MODE_ED 0x00
#define NRF_RADIO_CCA_MODE_CARRIER 0x01
#define NRF_RADIO_CCA_MODE_CARRIER_AND_ED 0x02
#define NRF_RADIO_CCA_MODE_CARRIER_OR_ED 0x03
/**
* @brief Structure for configuring CCA.
*/
typedef struct
{
uint8_t mode; // !< CCA mode.
uint8_t ed_threshold; // !< Busy threshold of the CCA energy. Not used in @ref NRF_RADIO_CCA_MODE_CARRIER.
uint8_t corr_threshold; // !< Busy threshold of the CCA correlator. Not used in @ref NRF_RADIO_CCA_MODE_ED.
uint8_t corr_limit; // !< Limit of occurrences above the busy threshold of the CCA correlator. Not used in @ref NRF_RADIO_CCA_MODE_ED.
} nrf_802154_cca_cfg_t;
/**
* @brief Types of data that can be set in an ACK message.
@ -102,7 +119,7 @@ typedef uint8_t nrf_802154_ack_data_t;
* @brief Methods of source address matching.
*
* You can use one of the following methods that can be set during the initialization phase
* by calling @ref nrf_802154_src_matching_method:
* by calling @ref nrf_802154_src_addr_matching_method_set:
* - For Thread: @ref NRF_802154_SRC_ADDR_MATCH_THREAD -- The pending bit is set only for the addresses found in the list.
* - For Zigbee: @ref NRF_802154_SRC_ADDR_MATCH_ZIGBEE -- The pending bit is cleared only for the short addresses found in the list.\n
* This method does not set pending bit in non-command and non-data-request frames.
@ -140,6 +157,25 @@ typedef uint32_t nrf_802154_capabilities_t;
#define NRF_802154_CAPABILITY_TIMESTAMP (1UL << 6UL) // !< Frame timestamping supported
#define NRF_802154_CAPABILITY_SECURITY (1UL << 7UL) // !< Frame security supported
/**
* @brief Type of structure holding time stamps of certain events.
*/
typedef struct
{
/**@brief Time stamp of last CSMA/CA procedure started. */
uint32_t last_csmaca_start_timestamp;
/**@brief Time stamp of last CCA start attempt. */
uint32_t last_cca_start_timestamp;
/**@brief Time stamp of last CCA attempt finished with CCA IDLE (channel was free to transmit). */
uint32_t last_cca_idle_timestamp;
/**@brief Time stamp when last bit of transmitted frame was sent on the air. */
uint32_t last_tx_end_timestamp;
/**@brief Time stamp when last bit of acknowledge frame was received */
uint32_t last_ack_end_timestamp;
/**@brief Time stamp when last bit of received frame was received. */
uint32_t last_rx_end_timestamp;
} nrf_802154_stat_timestamps_t;
/**
* @brief Structure with frame properties associated with the transmission operation.
*
@ -181,6 +217,16 @@ typedef struct
bool cca; // !< If the driver is to perform a CCA procedure before transmission.
} nrf_802154_transmit_metadata_t;
/**
* @brief Structure with transmit request metadata for scheduling transmission at a specific time.
*/
typedef struct
{
nrf_802154_transmitted_frame_props_t frame_props; // !< Properties of the frame to be transmitted.
bool cca; // !< If the driver is to perform a CCA procedure before transmission.
uint8_t channel; // !< Radio channel on which the frame is to be transmitted.
} nrf_802154_transmit_at_metadata_t;
/**
* @brief Structure with transmit request metadata for transmission preceded by CSMA-CA procedure.
*/
@ -213,6 +259,59 @@ typedef struct
} data; // !< Result values that are valid only for successful operations.
} nrf_802154_transmit_done_metadata_t;
/**
* @brief Possible errors during key handling.
*/
typedef uint8_t nrf_802154_security_error_t;
#define NRF_802154_SECURITY_ERROR_NONE 0x00 // !< There is no error.
#define NRF_802154_SECURITY_ERROR_STORAGE_FULL 0x01 // !< The key storage is full - removal of stored keys is needed.
#define NRF_802154_SECURITY_ERROR_KEY_NOT_FOUND 0x02 // !< The provided key was not found inside the storage.
#define NRF_802154_SECURITY_ERROR_ALREADY_PRESENT 0x03 // !< The storage already has the key of the same ID.
#define NRF_802154_SECURITY_ERROR_TYPE_NOT_SUPPORTED 0x04 // !< The provided key type is not supported.
#define NRF_802154_SECURITY_ERROR_MODE_NOT_SUPPORTED 0x05 // !< The provided key id mode is not supported.
#define NRF_802154_SECURITY_ERROR_FRAME_COUNTER_OVERFLOW 0x06 // !< The associated frame counter overflowed.
/**
* @brief Types of keys which can be used with the nRF 802.15.4 Radio Driver.
*
* Possible values:
* - @ref NRF_802154_KEY_CLEARTEXT,
*
*/
typedef uint32_t nrf_802154_key_type_t;
#define NRF_802154_KEY_CLEARTEXT 0x00 // !< Key stored in clear text.
/**
* @brief Type holding the value of Key Id Mode of the key stored in nRF 802.15.4 Radio Driver.
*/
typedef uint8_t nrf_802154_key_id_mode_t;
/**
* @brief Type holding the value of Key Id for the keys stored in nRF 802.15.4 Radio Driver.
*/
typedef struct
{
nrf_802154_key_id_mode_t mode; // !< Key Id Mode (0..3)
uint8_t * p_key_id; // !< Pointer to the Key Id field
} nrf_802154_key_id_t;
/**
* @brief Type of structure holding a 802.15.4 MAC Security Key.
*/
typedef struct
{
union
{
uint8_t * p_cleartext_key; // !< Pointer to the cleartext representation of the key.
} value; // !< Union holding different representations of the key.
nrf_802154_key_id_t id; // !< Key Id of the key.
nrf_802154_key_type_t type; // !< @ref nrf_802154_key_type_t type of the key used.
uint32_t frame_counter; // !< Frame counter to use in case @ref use_global_frame_counter is set to false.
bool use_global_frame_counter; // !< Whether to use the global frame counter instead of the one defined in this structure.
} nrf_802154_key_t;
/**
*@}
**/

View File

@ -60,12 +60,12 @@ extern "C" {
#endif /* CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT */
/**
* @brief Maximal size of a Spinel frame in 802.15.4 serializaiton.
* @brief Maximal size of a Spinel frame in 802.15.4 serialization.
*/
#define NRF_802154_SPINEL_FRAME_MAX_SIZE 256
#define NRF_802154_SPINEL_FRAME_MAX_SIZE 296
/**
* @brief Buffer size for Spinel frame in 802.15.4 serializaiton.
* @brief Buffer size for Spinel frame in 802.15.4 serialization.
*
* This macro can used as a replacement for @ref SPINEL_FRAME_BUFFER_SIZE in 802.15.4 serialization
* to reduce memory required for Spinel frame processing.

View File

@ -273,6 +273,120 @@ typedef enum
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TIME_GET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 34,
/**
* Vendor property for nrf_802154_cca_cfg_get serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_GET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 35,
/**
* Vendor property for nrf_802154_cca_cfg_set serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_SET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 36,
/**
* Vendor property for nrf_802154_transmit_raw_at serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW_AT =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 37,
/**
* Vendor property for nrf_802154_transmit_at_cancel serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_AT_CANCEL =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 38,
/**
* Vendor property for nrf_802154_receive_at serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 39,
/**
* Vendor property for nrf_802154_receive_at_cancel serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_CANCEL =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 40,
/**
* Vendor property for nrf_802154_security_global_frame_counter_set serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 41,
/**
* Vendor property for nrf_802154_security_key_store serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_STORE =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 42,
/**
* Vendor property for nrf_802154_security_key_remove serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_REMOVE =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 43,
/**
* Vendor property for nrf_802154_csl_writer_period_set serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_PERIOD_SET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 44,
/**
* Vendor property for nrf_802154_csma_ca_min_be_set serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_SET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 45,
/**
* Vendor property for nrf_802154_csma_ca_min_be_get serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_GET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 46,
/**
* Vendor property for nrf_802154_csma_ca_max_be_set serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_SET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 47,
/**
* Vendor property for nrf_802154_csma_ca_max_be_get serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_GET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 48,
/**
* Vendor property for nrf_802154_csma_ca_max_backoffs_set serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_SET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 49,
/**
* Vendor property for nrf_802154_csma_ca_max_backoffs_get serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 50,
/**
* Vendor property for nrf_802154_stat_timestamps_get serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_STAT_TIMESTAMPS_GET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 51,
/**
* Vendor property for nrf_802154_continuous_carrier serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CONTINUOUS_CARRIER =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 52,
/**
* Vendor property for nrf_802154_modulated_carrier serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_MODULATED_CARRIER =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 53,
} spinel_prop_vendor_key_t;
/**
@ -370,41 +484,204 @@ typedef enum
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_CSMA_CA_METADATA_S \
SPINEL_DATATYPE_NRF_802154_TRANSMITTED_FRAME_PROPS_S /* frame_props */
/**
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMIT_CSMA_CA_METADATA_S data type.
*/
#define NRF_802154_TRANSMIT_CSMA_CA_METADATA_ENCODE(tx_metadata) \
NRF_802154_TRANSMITTED_FRAME_PROPS_ENCODE((tx_metadata).frame_props)
/**
* @brief Decodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMIT_CSMA_CA_METADATA_S data type.
*/
#define NRF_802154_TRANSMIT_CSMA_CA_METADATA_DECODE(tx_metadata) \
NRF_802154_TRANSMITTED_FRAME_PROPS_DECODE((tx_metadata).frame_props)
/**
* @brief Spinel data type description for nrf_802154_csma_ca_min_be_set.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_SET SPINEL_DATATYPE_UINT8_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_min_be_set result.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_SET_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_min_be_get.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_GET SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_min_be_get result.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_GET_RET SPINEL_DATATYPE_UINT8_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_max_be_set.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_SET SPINEL_DATATYPE_UINT8_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_max_be_set result.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_SET_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_max_be_get.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_GET SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_max_be_get result.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_GET_RET SPINEL_DATATYPE_UINT8_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_max_backoffs_set.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BACKOFFS_SET SPINEL_DATATYPE_UINT8_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_max_backoffs_get.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_csma_ca_max_backoffs_get result.
*/
#define SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET_RET SPINEL_DATATYPE_UINT8_S
/**
* @brief Spinel data type description for nrf_802154_transmit_at_metadata_t.
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_AT_METADATA_S \
SPINEL_DATATYPE_NRF_802154_TRANSMITTED_FRAME_PROPS_S /* frame_props */ \
SPINEL_DATATYPE_BOOL_S /* cca */ \
SPINEL_DATATYPE_UINT8_S /* channel */
/**
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMIT_AT_METADATA_S data type.
*/
#define NRF_802154_TRANSMIT_AT_METADATA_ENCODE(tx_at_metadata) \
NRF_802154_TRANSMITTED_FRAME_PROPS_ENCODE((tx_at_metadata).frame_props), \
((tx_at_metadata).cca), \
((tx_at_metadata).channel)
/**
* @brief Decodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMIT_AT_METADATA_S data type.
*/
#define NRF_802154_TRANSMIT_AT_METADATA_DECODE(tx_at_metadata) \
NRF_802154_TRANSMITTED_FRAME_PROPS_DECODE((tx_at_metadata).frame_props), \
(&(tx_at_metadata).cca), \
(&(tx_at_metadata).channel)
/**
* @brief Spinel data type description for nrf_802154_cca_cfg_t.
*/
#define SPINEL_DATATYPE_NRF_802154_CCA_CFG_S \
SPINEL_DATATYPE_UINT8_S /* mode */ \
SPINEL_DATATYPE_UINT8_S /* ed_threshold */ \
SPINEL_DATATYPE_UINT8_S /* corr_threshold */ \
SPINEL_DATATYPE_UINT8_S /* corr_limit */
/**
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_CCA_CFG_S data type.
*/
#define NRF_802154_CCA_CFG_ENCODE(cca_cfg) \
((cca_cfg).mode), ((cca_cfg).ed_threshold), ((cca_cfg).corr_threshold), ((cca_cfg).corr_limit)
/**
* @brief Decodes an instance of @ref SPINEL_DATATYPE_NRF_802154_CCA_CFG_S data type.
*/
#define NRF_802154_CCA_CFG_DECODE(cca_cfg) \
(&(cca_cfg).mode), \
(&(cca_cfg).ed_threshold), \
(&(cca_cfg).corr_threshold), \
(&(cca_cfg).corr_limit)
/**
* @brief Spinel data type description for nrf_802154_stat_timestamps_t
*/
#define SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_S \
SPINEL_DATATYPE_UINT32_S \
SPINEL_DATATYPE_UINT32_S \
SPINEL_DATATYPE_UINT32_S \
SPINEL_DATATYPE_UINT32_S \
SPINEL_DATATYPE_UINT32_S \
SPINEL_DATATYPE_UINT32_S
/**
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_S data type.
*/
#define NRF_802154_STAT_TIMESTAMPS_ENCODE(stat_timestamps) \
((stat_timestamps).last_csmaca_start_timestamp), \
((stat_timestamps).last_cca_start_timestamp), \
((stat_timestamps).last_cca_idle_timestamp), \
((stat_timestamps).last_tx_end_timestamp), \
((stat_timestamps).last_ack_end_timestamp), \
((stat_timestamps).last_rx_end_timestamp)
/**
* @brief Decodes an instance of @ref SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_S data type.
*/
#define NRF_802154_STAT_TIMESTAMPS_DECODE(stat_timestamps) \
(&(stat_timestamps).last_csmaca_start_timestamp), \
(&(stat_timestamps).last_cca_start_timestamp), \
(&(stat_timestamps).last_cca_idle_timestamp), \
(&(stat_timestamps).last_tx_end_timestamp), \
(&(stat_timestamps).last_ack_end_timestamp), \
(&(stat_timestamps).last_rx_end_timestamp)
/**
* @brief Spinel data type description for SPINEL_PROP_LAST_STATUS.
*/
#define SPINEL_DATATYPE_SPINEL_PROP_LAST_STATUS SPINEL_DATATYPE_UINT_PACKED_S
#define SPINEL_DATATYPE_SPINEL_PROP_LAST_STATUS SPINEL_DATATYPE_UINT_PACKED_S
/**
* @brief Spinel data type description for nrf_802154_sleep.
*/
#define SPINEL_DATATYPE_NRF_802154_SLEEP SPINEL_DATATYPE_NULL_S
#define SPINEL_DATATYPE_NRF_802154_SLEEP SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_sleep result.
*/
#define SPINEL_DATATYPE_NRF_802154_SLEEP_RET SPINEL_DATATYPE_BOOL_S
#define SPINEL_DATATYPE_NRF_802154_SLEEP_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_receive.
*/
#define SPINEL_DATATYPE_NRF_802154_RECEIVE SPINEL_DATATYPE_NULL_S
#define SPINEL_DATATYPE_NRF_802154_RECEIVE SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_receive result.
*/
#define SPINEL_DATATYPE_NRF_802154_RECEIVE_RET SPINEL_DATATYPE_BOOL_S
#define SPINEL_DATATYPE_NRF_802154_RECEIVE_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_receive_at.
*/
#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT \
SPINEL_DATATYPE_UINT32_S /* t0 */ \
SPINEL_DATATYPE_UINT32_S /* dt */ \
SPINEL_DATATYPE_UINT32_S /* timeout */ \
SPINEL_DATATYPE_UINT8_S /* channel */ \
SPINEL_DATATYPE_UINT32_S /* window id */ \
/**
* @brief Spinel data type description for nrf_802154_receive_at result.
*/
#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_receive_at_cancel.
*/
#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_CANCEL SPINEL_DATATYPE_UINT32_S
/**
* @brief Spinel data type description for nrf_802154_receive_at_cancel result.
*/
#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_CANCEL_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_pan_id_set.
@ -471,6 +748,26 @@ typedef enum
*/
#define SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTION_FAILED SPINEL_DATATYPE_UINT8_S
/**
* @brief Spinel data type description for nrf_802154_continuous_carrier.
*/
#define SPINEL_DATATYPE_NRF_802154_CONTINUOUS_CARRIER SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_nrf_802154_continuous_carrier result.
*/
#define SPINEL_DATATYPE_NRF_802154_CONTINUOUS_CARRIER_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_modulated_carrier.
*/
#define SPINEL_DATATYPE_NRF_802154_MODULATED_CARRIER SPINEL_DATATYPE_DATA_S
/**
* @brief Spinel data type description for nrf_802154_nrf_802154_modulated_carrier result.
*/
#define SPINEL_DATATYPE_NRF_802154_MODULATED_CARRIER_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_tx_power_get.
*/
@ -531,6 +828,16 @@ typedef enum
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_CSMA_CA_RAW_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for return value of nrf_802154_transmit_raw_at
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_RAW_AT_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for return value of nrf_802154_transmit_at_cancel
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_AT_CANCEL_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type desription for nrf_802154_auto_pending_bit_set.
*/
@ -606,6 +913,20 @@ typedef enum
SPINEL_DATATYPE_NRF_802154_TRANSMIT_CSMA_CA_METADATA_S \
SPINEL_DATATYPE_NRF_802154_HDATA_S /* Frame to transmit with its handle */
/**
* @brief Spinel data type description for nrf_802154_transmit_raw_at
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_RAW_AT \
SPINEL_DATATYPE_NRF_802154_TRANSMIT_AT_METADATA_S \
SPINEL_DATATYPE_UINT32_S /* t0 */ \
SPINEL_DATATYPE_UINT32_S /* dt */ \
SPINEL_DATATYPE_NRF_802154_HDATA_S /* Frame to transmit with its handle */
/**
* @brief Spinel data type description for nrf_802154_sleep.
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_AT_CANCEL SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_transmit_done_metadata.
*/
@ -621,7 +942,7 @@ typedef enum
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMIT_DONE_METADATA_S data type.
*
* @param[in] metadata Transmit done metadata structure to be decoded.
* @param[in] ack_handle Variable containing handle to
* @param[in] ack_handle Variable containing handle to remote ack frame.
*/
#define NRF_802154_TRANSMIT_DONE_METADATA_ENCODE(metadata, ack_handle) \
NRF_802154_TRANSMITTED_FRAME_PROPS_ENCODE((metadata).frame_props), \
@ -649,20 +970,104 @@ typedef enum
&(metadata).data.transmitted.time, \
NRF_802154_HDATA_DECODE(ack_handle, (metadata).data.transmitted.p_ack, ack_length)
/**
* @brief Spinel data type description for nrf_802154_transmit_failed_metadata.
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED_METADATA_S \
SPINEL_DATATYPE_NRF_802154_TRANSMITTED_FRAME_PROPS_S /* Frame props */
/**
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED_METADATA_S data type.
*
* @param[in] metadata Transmit failed metadata structure to be encoded.
*/
#define NRF_802154_TRANSMIT_FAILED_METADATA_ENCODE(metadata) \
NRF_802154_TRANSMITTED_FRAME_PROPS_ENCODE((metadata).frame_props)
/**
* @brief Decodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED_METADATA_S data type.
*
* @param[out] metadata Transmit failed metadata structure to which store decoded data.
*/
#define NRF_802154_TRANSMIT_FAILED_METADATA_DECODE(metadata) \
NRF_802154_TRANSMITTED_FRAME_PROPS_DECODE((metadata).frame_props)
/**
* @brief Spinel data type description for nrf_802154_transmitted_raw.
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMITTED_RAW \
SPINEL_DATATYPE_UINT32_S /* Handle to transmitted frame */ \
#define SPINEL_DATATYPE_NRF_802154_TRANSMITTED_RAW \
SPINEL_DATATYPE_NRF_802154_HDATA_S /* Transmitted frame and its handle*/ \
SPINEL_DATATYPE_NRF_802154_TRANSMIT_DONE_METADATA_S /* Transmit done metadata */
/**
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMITTED_RAW data type.
*
* @param[in] frame_handle Variable containing remote frame handle.
* @param[in] frame_data Pointer to contents of frame.
* @param[in] metadata Transmit done metadata structure to be encoded.
* @param[in] ack_handle Variable containing handle to received Ack.
*/
#define NRF_802154_TRANSMITTED_RAW_ENCODE(frame_handle, frame_data, metadata, ack_handle) \
NRF_802154_HDATA_ENCODE(frame_handle, frame_data, frame_data[0] + 1), \
NRF_802154_TRANSMIT_DONE_METADATA_ENCODE(metadata, ack_handle)
/**
* @brief Decodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMITTED_RAW data type.
*
* @param[out] frame_handle Pointer variable to which store handle of transmitted frame.
* @param[out] frame_data Pointer to memory to which store contents of transmitted frame.
* @param[out] frame_length Variable to which store length of the decoded frame.
* @param[out] metadata Transmit done metadata structure to which store decoded data.
* @param[out] ack_handle Pointer variable to which store handle of ACK frame.
* @param[out] ack_length Variable to which store length of the decoded ACK frame.
*/
#define NRF_802154_TRANSMITTED_RAW_DECODE(frame_handle, \
frame_data, \
frame_length, \
metadata, \
ack_handle, \
ack_length) \
NRF_802154_HDATA_DECODE(frame_handle, frame_data, frame_length), \
NRF_802154_TRANSMIT_DONE_METADATA_DECODE(metadata, ack_handle, ack_length)
/**
* @brief Spinel data type description for nrf_802154_transmit_failed.
*/
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED \
SPINEL_DATATYPE_UINT32_S /* Handle to transmitted frame */ \
SPINEL_DATATYPE_UINT8_S /* Error code */ \
SPINEL_DATATYPE_NRF_802154_TRANSMITTED_FRAME_PROPS_S /* Frame props */
#define SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED \
SPINEL_DATATYPE_NRF_802154_HDATA_S /* Frame that was attempted to be transmitted and its handle */ \
SPINEL_DATATYPE_UINT8_S /* Error code */ \
SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED_METADATA_S /* Transmit failed metadata */
/**
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED data type.
*
* @param[in] frame_handle Variable containing remote frame handle.
* @param[in] frame_data Pointer to contents of frame.
* @param[in] error_code Error code to be encoded.
* @param[in] metadata Transmit failed metadata structure to be encoded.
*/
#define NRF_802154_TRANSMIT_FAILED_ENCODE(frame_handle, frame_data, error_code, metadata) \
NRF_802154_HDATA_ENCODE(frame_handle, frame_data, frame_data[0] + 1), \
error_code, \
NRF_802154_TRANSMIT_FAILED_METADATA_ENCODE(metadata)
/**
* @brief Decodes an instance of @ref SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED data type.
*
* @param[out] frame_handle Pointer variable to which store handle of frame failed to transmit.
* @param[out] frame_data Pointer to memory to which store contents of frame failed to transmit.
* @param[out] frame_length Variable to which store length of the decoded frame.
* @param[in] error_code Variable to which store decode error code.
* @param[out] metadata Transmit failed metadata structure to which store decoded data.
*/
#define NRF_802154_TRANSMIT_FAILED_DECODE(frame_handle, \
frame_data, \
frame_length, \
error_code, \
metadata) \
NRF_802154_HDATA_DECODE(frame_handle, frame_data, frame_length), \
&error_code, \
NRF_802154_TRANSMIT_FAILED_METADATA_DECODE(metadata)
/**
* @brief Spinel data type description for nrf_802154_capabilities_get.
@ -684,6 +1089,129 @@ typedef enum
*/
#define SPINEL_DATATYPE_NRF_802154_TIME_GET_RET SPINEL_DATATYPE_UINT32_S
/**
* @brief Spinel data type description for nrf_802154_cca_cfg_get.
*/
#define SPINEL_DATATYPE_NRF_802154_CCA_CFG_GET SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_cca_cfg_get_ret.
*/
#define SPINEL_DATATYPE_NRF_802154_CCA_CFG_GET_RET \
SPINEL_DATATYPE_NRF_802154_CCA_CFG_S
/**
* @brief Spinel data type description for nrf_802154_cca_cfg_get.
*/
#define SPINEL_DATATYPE_NRF_802154_CCA_CFG_SET \
SPINEL_DATATYPE_NRF_802154_CCA_CFG_S
/**
* @brief Spinel data type description for nrf_802154_security_global_frame_counter_set.
*/
#define SPINEL_DATATYPE_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET SPINEL_DATATYPE_UINT32_S
/**
* @brief Spinel data type description for nrf_802154_security_key_store.
*/
#define SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_STORE \
SPINEL_DATATYPE_STRUCT_S( \
SPINEL_DATATYPE_DATA_S /* Key value */ \
) \
SPINEL_DATATYPE_STRUCT_S( \
SPINEL_DATATYPE_UINT8_S /* Key mode */ \
SPINEL_DATATYPE_DATA_S /* Key ID */ \
) \
SPINEL_DATATYPE_UINT32_S /* Key type */ \
SPINEL_DATATYPE_UINT32_S /* Frame counter */ \
SPINEL_DATATYPE_BOOL_S /* Whether to use global frame counter */
/**
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_STORE data type.
*
* @param[in] key Key structure (of @ref nrf_802154_key_t type) to be encoded.
* @param[in] key_size Size of the key data, i.e. cleartext size.
* @param[in] key_id_size Size of the key id in @p key structure.
*/
#define NRF_802154_SECURITY_KEY_STORE_ENCODE(key, key_size, key_id_size) \
(key).value.p_cleartext_key, \
(key_size), \
(key).id.mode, \
(key).id.p_key_id, \
(key_id_size), \
(key).type, \
(key).frame_counter, \
(key).use_global_frame_counter
/**
* @brief Decodes an instance of @ref SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_STORE data type.
*
* @param[out] key Key structure (of @ref nrf_802154_key_t type) to which store decoded data.
* @param[out] key_size Variable to which store size of the decoded key, i.e. cleartext size.
* @param[out] key_id_size Variable to which store size of the decoded key ID.
*/
#define NRF_802154_SECURITY_KEY_STORE_DECODE(key, key_size, key_id_size) \
& (key).value.p_cleartext_key, \
&(key_size), \
&(key).id.mode, \
&(key).id.p_key_id, \
&(key_id_size), \
&(key).type, \
&(key).frame_counter, \
&(key).use_global_frame_counter
/**
* @brief Spinel data type description for nrf_802154_security_key_remove.
*/
#define SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_REMOVE \
SPINEL_DATATYPE_STRUCT_S( \
SPINEL_DATATYPE_UINT8_S /* Key mode */ \
SPINEL_DATATYPE_DATA_S /* Key ID */ \
)
/**
* @brief Encodes an instance of @ref SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_REMOVE data type.
*
* @param[in] key_id Key ID structure (of @ref nrf_802154_key_id_t type) to be encoded.
* @param[in] key_id_size Size of the key id in @p key_id structure.
*/
#define NRF_802154_SECURITY_KEY_REMOVE_ENCODE(key_id, key_id_size) \
(key_id).mode, \
(key_id).p_key_id, \
(key_id_size)
/**
* @brief Decodes an instance of @ref SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_STORE data type.
*
* @param[out] key_id Key ID structure (of @ref nrf_802154_key_id_t type) to which store decoded data.
* @param[out] key_id_size Variable to which store size of the decoded key ID.
*/
#define NRF_802154_SECURITY_KEY_REMOVE_DECODE(key_id, key_id_size) \
& (key_id).mode, \
&(key_id).p_key_id, \
&(key_id_size)
/**
* @brief Spinel data type description for return type for security commands.
*/
#define SPINEL_DATATYPE_NRF_802154_SECURITY_ERROR_RET SPINEL_DATATYPE_UINT8_S
/**
* @brief Spinel data type description for nrf_802154_csl_writer_period_set.
*/
#define SPINEL_DATATYPE_NRF_802154_CSL_WRITER_PERIOD_SET SPINEL_DATATYPE_UINT16_S
/**
* @brief Spinel data type description for nrf_802154_stat_timestamps_get
*/
#define SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_GET SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_stat_timestamps_get_ret.
*/
#define SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_GET_RET \
SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_S
#ifdef __cplusplus
}
#endif

View File

@ -48,6 +48,7 @@
#include "nrf_802154_serialization_error.h"
#include "nrf_802154.h"
#include "nrf_802154_types.h"
#ifdef __cplusplus
extern "C" {
@ -84,6 +85,23 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_generic_bool(
size_t property_data_len,
bool * p_bool_response);
/**
* @brief Decode SPINEL_DATATYPE_UINT8_S.
*
* @note This is used to decode `uint8_t` responses for several kinds of requests in 802.15.4 radio driver.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
* @param[out] p_uint8_response Pointer to decoded response value.
*
* @returns zero on success or negative error value on failure.
*
*/
nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_generic_uint8(
const void * p_property_data,
size_t property_data_len,
uint8_t * p_uint8_response);
/**
* @brief Decode SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TX_POWER_GET.
*
@ -132,7 +150,7 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_capabilities_get_r
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
* @param[out] p_capabilities Decoded capabilities.
* @param[out] p_time Decoded time.
*
* @returns zero on success or negative error value on failure.
*
@ -142,6 +160,36 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_time_get_ret(
size_t property_data_len,
uint32_t * p_time);
/**
* @brief Decode SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_GET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
* @param[out] p_cfg Decoded CCA configuration.
*
* @returns zero on success or negative error value on failure.
*
*/
nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_cca_cfg_get_ret(
const void * p_property_data,
size_t property_data_len,
nrf_802154_cca_cfg_t * p_cfg);
/**
* @brief Decode SPINEL_PROP_VENDOR_NORDIC_NRF_802154_STAT_TIMESTAMPS_GET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
* @param[out] p_stat_timestamps Decoded stat timestamps
*
* @returns zero on success or negative error value on failure.
*
*/
nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_stat_timestamps_get_ret(
const void * p_property_data,
size_t property_data_len,
nrf_802154_stat_timestamps_t * p_stat_timestamps);
/**
* @brief Decode and dispatch SPINEL_CMD_PROP_VALUE_IS.
*

View File

@ -45,7 +45,6 @@
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
static uint8_t * buffer_alloc(nrf_802154_buffer_t * p_buffer_pool, size_t buffer_pool_len)
{

View File

@ -61,6 +61,7 @@
#include "nrf_802154_buffer_mgr_src.h"
#include "nrf_802154.h"
#include "nrf_802154_config.h"
#include "nrf_802154_types.h"
/**
@ -111,16 +112,14 @@ bail:
/**
* @brief Wait with timeout for some single bool property to be received.
*
* @param[out] p_net_response Pointer to the bool variable which needs to be populated.
* @param[in] property_id Awaited property identifier.
* @param[in] timeout Timeout in us.
* @param[out] p_net_response Pointer to the bool variable which needs to be populated.
*
* @returns zero on success or negative error value on failure.
*
*/
static nrf_802154_ser_err_t net_generic_bool_response_await(
bool * p_net_response,
uint32_t timeout)
static nrf_802154_ser_err_t net_generic_bool_response_await(uint32_t timeout,
bool * p_net_response)
{
nrf_802154_ser_err_t res;
nrf_802154_spinel_notify_buff_t * p_notify_data = NULL;
@ -153,37 +152,37 @@ bail:
}
/**
* @brief Wait with timeout for channel property to be received.
* @brief Wait with timeout for some single uint8_t property to be received.
*
* @param[in] timeout Timeout in us.
* @param[out] p_channel Pointer to the channel variable which needs to be populated.
* @param[in] timeout Timeout in us.
* @param[out] p_net_response Pointer to the uint8_t variable which needs to be populated.
*
* @returns zero on success or negative error value on failure.
*
*/
static nrf_802154_ser_err_t channel_await(uint32_t timeout, uint8_t * p_channel)
static nrf_802154_ser_err_t net_generic_uint8_response_await(uint32_t timeout,
uint8_t * p_net_response)
{
nrf_802154_ser_err_t res;
nrf_802154_spinel_notify_buff_t * p_notify_data = NULL;
SERIALIZATION_ERROR_INIT(error);
p_notify_data = nrf_802154_spinel_response_notifier_property_await(
timeout);
p_notify_data = nrf_802154_spinel_response_notifier_property_await(timeout);
SERIALIZATION_ERROR_IF(p_notify_data == NULL,
NRF_802154_SERIALIZATION_ERROR_RESPONSE_TIMEOUT,
error,
bail);
res = nrf_802154_spinel_decode_prop_channel(p_notify_data->data,
p_notify_data->data_len,
p_channel);
res = nrf_802154_spinel_decode_prop_generic_uint8(p_notify_data->data,
p_notify_data->data_len,
p_net_response);
SERIALIZATION_ERROR_CHECK(res, error, bail);
NRF_802154_SPINEL_LOG_BANNER_RESPONSE();
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", *p_channel, "channel");
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", *p_net_response, "net response");
bail:
if (p_notify_data != NULL)
@ -322,6 +321,52 @@ bail:
return error;
}
/**
* @brief Wait with timeout for CCA configuration property to be received.
*
* @param[in] timeout Timeout in us.
* @param[out] p_cfg Pointer to the CCA configuration variable which needs to be populated.
*
* @returns zero on success or negative error value on failure.
*
*/
static nrf_802154_ser_err_t cca_cfg_await(uint32_t timeout,
nrf_802154_cca_cfg_t * p_cfg)
{
nrf_802154_ser_err_t res;
nrf_802154_spinel_notify_buff_t * p_notify_data = NULL;
SERIALIZATION_ERROR_INIT(error);
p_notify_data = nrf_802154_spinel_response_notifier_property_await(
timeout);
SERIALIZATION_ERROR_IF(p_notify_data == NULL,
NRF_802154_SERIALIZATION_ERROR_RESPONSE_TIMEOUT,
error,
bail);
res = nrf_802154_spinel_decode_prop_nrf_802154_cca_cfg_get_ret(p_notify_data->data,
p_notify_data->data_len,
p_cfg);
SERIALIZATION_ERROR_CHECK(res, error, bail);
NRF_802154_SPINEL_LOG_BANNER_RESPONSE();
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", p_cfg->mode, "Mode");
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", p_cfg->ed_threshold, "ED threshold");
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", p_cfg->corr_threshold, "Corr threshold");
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", p_cfg->corr_limit, "Corr limit");
bail:
if (p_notify_data != NULL)
{
nrf_802154_spinel_response_notifier_free(p_notify_data);
}
return error;
}
void nrf_802154_init(void)
{
nrf_802154_serialization_init();
@ -345,8 +390,8 @@ bool nrf_802154_sleep(void)
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(&sleep_remote_resp,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&sleep_remote_resp);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -374,8 +419,8 @@ bool nrf_802154_receive(void)
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(&receive_remote_resp,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&receive_remote_resp);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -385,6 +430,75 @@ bail:
return receive_remote_resp;
}
bool nrf_802154_receive_at(uint32_t t0,
uint32_t dt,
uint32_t timeout,
uint8_t channel,
uint32_t id)
{
nrf_802154_ser_err_t res;
bool rx_at_result = false;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT,
SPINEL_DATATYPE_NRF_802154_RECEIVE_AT,
t0,
dt,
timeout,
channel,
id);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&rx_at_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return rx_at_result;
}
bool nrf_802154_receive_at_cancel(uint32_t id)
{
nrf_802154_ser_err_t res;
bool cancel_result = false;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_CANCEL);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_CANCEL,
SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_CANCEL,
id);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&cancel_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return cancel_result;
}
void nrf_802154_pan_id_set(const uint8_t * p_pan_id)
{
nrf_802154_ser_err_t res;
@ -574,8 +688,8 @@ bool nrf_802154_ack_data_set(const uint8_t * p_addr,
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(&ack_data_set_res,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&ack_data_set_res);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -610,8 +724,8 @@ bool nrf_802154_ack_data_clear(const uint8_t * p_addr,
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(&ack_data_clear_res,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&ack_data_clear_res);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -668,8 +782,8 @@ bool nrf_802154_pending_bit_for_addr_set(const uint8_t * p_addr, bool extended)
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(&addr_set_res,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&addr_set_res);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -701,8 +815,8 @@ bool nrf_802154_pending_bit_for_addr_clear(const uint8_t * p_addr, bool extended
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(&addr_clr_res,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&addr_clr_res);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -784,7 +898,8 @@ uint8_t nrf_802154_channel_get(void)
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = channel_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT, &channel);
res = net_generic_uint8_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&channel);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
@ -811,8 +926,8 @@ bool nrf_802154_cca(void)
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(&cca_result,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&cca_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -822,6 +937,72 @@ bail:
return cca_result;
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_continuous_carrier(void)
{
nrf_802154_ser_err_t res;
bool continuous_carrier_result = false;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CONTINUOUS_CARRIER);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CONTINUOUS_CARRIER,
SPINEL_DATATYPE_NRF_802154_CONTINUOUS_CARRIER,
NULL);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&continuous_carrier_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return continuous_carrier_result;
}
bool nrf_802154_modulated_carrier(const uint8_t * p_data)
{
nrf_802154_ser_err_t res;
bool modulated_carrier_result = false;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
NRF_802154_SPINEL_LOG_BUFF(p_data, RAW_PAYLOAD_OFFSET + p_data[0]);
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_MODULATED_CARRIER);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_MODULATED_CARRIER,
SPINEL_DATATYPE_NRF_802154_MODULATED_CARRIER,
p_data,
RAW_PAYLOAD_OFFSET + p_data[0]);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&modulated_carrier_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return modulated_carrier_result;
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_energy_detection(uint32_t time_us)
{
nrf_802154_ser_err_t res;
@ -841,9 +1022,8 @@ bool nrf_802154_energy_detection(uint32_t time_us)
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(
&ed_result,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&ed_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -853,6 +1033,8 @@ bail:
return ed_result;
}
#if NRF_802154_CSMA_CA_ENABLED
bool nrf_802154_transmit_csma_ca_raw(uint8_t * p_data,
const nrf_802154_transmit_csma_ca_metadata_t * p_metadata)
{
@ -892,8 +1074,8 @@ bool nrf_802154_transmit_csma_ca_raw(uint8_t
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(&transmit_result,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&transmit_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -913,6 +1095,182 @@ bail:
return transmit_result;
}
bool nrf_802154_csma_ca_min_be_set(uint8_t min_be)
{
nrf_802154_ser_err_t res;
bool result = false;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
NRF_802154_SPINEL_LOG_VAR("%u", min_be);
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_SET);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_SET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_SET,
min_be);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return result;
}
uint8_t nrf_802154_csma_ca_min_be_get(void)
{
nrf_802154_ser_err_t res;
uint8_t min_be = 0;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_GET);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_GET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_GET,
&min_be);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_uint8_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&min_be);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return min_be;
}
bool nrf_802154_csma_ca_max_be_set(uint8_t max_be)
{
nrf_802154_ser_err_t res;
bool result = false;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
NRF_802154_SPINEL_LOG_VAR("%u", max_be);
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_SET);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_SET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_SET,
max_be);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return result;
}
uint8_t nrf_802154_csma_ca_max_be_get(void)
{
nrf_802154_ser_err_t res;
uint8_t max_be = 0;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_GET);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_GET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_GET,
&max_be);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_uint8_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&max_be);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return max_be;
}
void nrf_802154_csma_ca_max_backoffs_set(uint8_t max_backoffs)
{
nrf_802154_ser_err_t res;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
NRF_802154_SPINEL_LOG_VAR("%u", max_backoffs);
nrf_802154_spinel_response_notifier_lock_before_request(SPINEL_PROP_LAST_STATUS);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_SET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BACKOFFS_SET,
max_backoffs);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = status_ok_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return;
}
uint8_t nrf_802154_csma_ca_max_backoffs_get(void)
{
nrf_802154_ser_err_t res;
uint8_t max_backoffs = 0;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET,
&max_backoffs);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_uint8_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&max_backoffs);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return max_backoffs;
}
#endif // NRF_802154_CSMA_CA_ENABLED
bool nrf_802154_transmit_raw(uint8_t * p_data,
const nrf_802154_transmit_metadata_t * p_metadata)
{
@ -953,8 +1311,8 @@ bool nrf_802154_transmit_raw(uint8_t * p_data,
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(&transmit_result,
CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&transmit_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
@ -974,6 +1332,102 @@ bail:
return transmit_result;
}
bool nrf_802154_transmit_raw_at(uint8_t * p_data,
uint32_t t0,
uint32_t dt,
const nrf_802154_transmit_at_metadata_t * p_metadata)
{
nrf_802154_ser_err_t res;
uint32_t data_handle;
bool transmit_result = false;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
NRF_802154_SPINEL_LOG_BUFF(p_data, p_data[0]);
bool handle_added = nrf_802154_buffer_mgr_src_add(nrf_802154_spinel_src_buffer_mgr_get(),
p_data,
&data_handle);
if (p_metadata == NULL)
{
static const nrf_802154_transmit_at_metadata_t metadata_default =
{
.frame_props = NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT,
.cca = true,
.channel = 11
};
p_metadata = &metadata_default;
}
SERIALIZATION_ERROR_IF(!handle_added, NRF_802154_SERIALIZATION_ERROR_NO_MEMORY, error, bail);
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW_AT);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW_AT,
SPINEL_DATATYPE_NRF_802154_TRANSMIT_RAW_AT,
NRF_802154_TRANSMIT_AT_METADATA_ENCODE(*p_metadata),
t0,
dt,
NRF_802154_HDATA_ENCODE(data_handle, p_data, p_data[0]));
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&transmit_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
return transmit_result;
bail:
if (handle_added)
{
/* Rollback what we did until an error to avoid memory leak. */
nrf_802154_buffer_mgr_src_remove_by_buffer_handle(
nrf_802154_spinel_src_buffer_mgr_get(),
data_handle);
}
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return transmit_result;
}
bool nrf_802154_transmit_at_cancel(void)
{
nrf_802154_ser_err_t res;
bool cancel_result = false;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_AT_CANCEL);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_AT_CANCEL,
SPINEL_DATATYPE_NRF_802154_TRANSMIT_AT_CANCEL,
NULL);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&cancel_result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return cancel_result;
}
void nrf_802154_buffer_free_raw(uint8_t * p_data)
{
nrf_802154_ser_err_t res;
@ -1100,7 +1554,7 @@ bail:
uint32_t nrf_802154_time_get(void)
{
int32_t res;
uint32_t time;
uint32_t time = 0UL;
SERIALIZATION_ERROR_INIT(error);
@ -1125,7 +1579,239 @@ bail:
return time;
}
void nrf_802154_cca_cfg_set(const nrf_802154_cca_cfg_t * p_cfg)
{
nrf_802154_ser_err_t res;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", p_cfg->mode, "Mode");
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", p_cfg->ed_threshold, "ED threshold");
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", p_cfg->corr_threshold, "Corr threshold");
NRF_802154_SPINEL_LOG_VAR_NAMED("%u", p_cfg->corr_limit, "Corr limit");
nrf_802154_spinel_response_notifier_lock_before_request(SPINEL_PROP_LAST_STATUS);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_SET,
SPINEL_DATATYPE_NRF_802154_CCA_CFG_SET,
NRF_802154_CCA_CFG_ENCODE(*p_cfg));
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = status_ok_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return;
}
void nrf_802154_cca_cfg_get(nrf_802154_cca_cfg_t * p_cfg)
{
nrf_802154_ser_err_t res;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_GET);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_GET,
SPINEL_DATATYPE_NRF_802154_CCA_CFG_GET,
NULL);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = cca_cfg_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT, p_cfg);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
}
int8_t nrf_802154_dbm_from_energy_level_calculate(uint8_t energy_level)
{
return ED_MIN_DBM + (energy_level / ED_RESULT_FACTOR);
}
uint32_t nrf_802154_first_symbol_timestamp_get(uint32_t end_timestamp, uint8_t psdu_length)
{
uint32_t frame_symbols = PHY_SHR_SYMBOLS;
frame_symbols += (PHR_SIZE + psdu_length) * PHY_SYMBOLS_PER_OCTET;
return end_timestamp - (frame_symbols * PHY_US_PER_SYMBOL);
}
void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter)
{
nrf_802154_ser_err_t res;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(SPINEL_PROP_LAST_STATUS);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET,
SPINEL_DATATYPE_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET,
frame_counter);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = status_ok_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return;
}
nrf_802154_security_error_t nrf_802154_security_key_store(nrf_802154_key_t * p_key)
{
nrf_802154_ser_err_t res;
nrf_802154_security_error_t err = NRF_802154_SECURITY_ERROR_NONE;;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_STORE);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_STORE,
SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_STORE,
NRF_802154_SECURITY_KEY_STORE_ENCODE(*p_key, AES_CCM_KEY_SIZE, KEY_ID_MODE_3_SIZE));
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_uint8_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT, &err);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return err;
}
nrf_802154_security_error_t nrf_802154_security_key_remove(nrf_802154_key_id_t * p_id)
{
nrf_802154_ser_err_t res;
nrf_802154_security_error_t err = NRF_802154_SECURITY_ERROR_NONE;;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_REMOVE);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_REMOVE,
SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_REMOVE,
NRF_802154_SECURITY_KEY_REMOVE_ENCODE(*p_id, KEY_ID_MODE_3_SIZE));
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_uint8_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT, &err);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return err;
}
void nrf_802154_csl_writer_period_set(uint16_t period)
{
nrf_802154_ser_err_t res;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(SPINEL_PROP_LAST_STATUS);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_PERIOD_SET,
SPINEL_DATATYPE_NRF_802154_CSL_WRITER_PERIOD_SET,
period);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = status_ok_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return;
}
static nrf_802154_ser_err_t stat_timestamps_get_ret_await(uint32_t timeout,
nrf_802154_stat_timestamps_t * p_stat_timestamps)
{
nrf_802154_ser_err_t res;
nrf_802154_spinel_notify_buff_t * p_notify_data = NULL;
SERIALIZATION_ERROR_INIT(error);
p_notify_data = nrf_802154_spinel_response_notifier_property_await(
timeout);
SERIALIZATION_ERROR_IF(p_notify_data == NULL,
NRF_802154_SERIALIZATION_ERROR_RESPONSE_TIMEOUT,
error,
bail);
res = nrf_802154_spinel_decode_prop_nrf_802154_stat_timestamps_get_ret(
p_notify_data->data,
p_notify_data->data_len,
p_stat_timestamps);
SERIALIZATION_ERROR_CHECK(res, error, bail);
NRF_802154_SPINEL_LOG_BANNER_RESPONSE();
bail:
if (p_notify_data != NULL)
{
nrf_802154_spinel_response_notifier_free(p_notify_data);
}
return error;
}
void nrf_802154_stat_timestamps_get(nrf_802154_stat_timestamps_t * p_stat_timestamps)
{
nrf_802154_ser_err_t res;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_STAT_TIMESTAMPS_GET);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_STAT_TIMESTAMPS_GET,
SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_GET,
NULL);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = stat_timestamps_get_ret_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
p_stat_timestamps);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
}

View File

@ -34,6 +34,7 @@
#include <assert.h>
#include <stddef.h>
#include <string.h>
#ifndef TEST
#include <nrf.h>
@ -50,6 +51,8 @@
#include "nrf_802154_buffer_mgr_src.h"
#include "nrf_802154.h"
#include "nrf_802154_config.h"
#include "nrf_802154_const.h"
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_DONE.
@ -283,17 +286,21 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmitted_raw(
uint32_t remote_ack_handle;
void * p_ack;
size_t ack_hdata_len;
void * p_frame;
size_t frame_hdata_len;
void * p_local_frame;
void * p_serialized_frame;
void * p_ack_local_ptr = NULL;
nrf_802154_transmit_done_metadata_t metadata = {0};
spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_TRANSMITTED_RAW,
&frame_handle,
NRF_802154_TRANSMIT_DONE_METADATA_DECODE(metadata,
remote_ack_handle,
ack_hdata_len));
NRF_802154_TRANSMITTED_RAW_DECODE(frame_handle,
p_serialized_frame,
frame_hdata_len,
metadata,
remote_ack_handle,
ack_hdata_len));
p_ack = metadata.data.transmitted.p_ack;
@ -306,7 +313,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmitted_raw(
bool frame_found = nrf_802154_buffer_mgr_src_search_by_buffer_handle(
nrf_802154_spinel_src_buffer_mgr_get(),
frame_handle,
&p_frame);
&p_local_frame);
if (!frame_found)
{
@ -346,9 +353,13 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmitted_raw(
return NRF_802154_SERIALIZATION_ERROR_INVALID_BUFFER;
}
memcpy(p_local_frame,
p_serialized_frame,
NRF_802154_DATA_LEN_FROM_HDATA_LEN(frame_hdata_len));
// Overwrite ACK frame pointer with a newly allocated one.
metadata.data.transmitted.p_ack = p_ack_local_ptr;
nrf_802154_transmitted_raw(p_frame, &metadata);
nrf_802154_transmitted_raw(p_local_frame, &metadata);
return NRF_802154_SERIALIZATION_ERROR_OK;
}
@ -365,16 +376,19 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_failed(
{
uint32_t frame_handle;
nrf_802154_tx_error_t tx_error;
void * p_frame;
void * p_serialized_frame;
void * p_local_frame;
size_t frame_hdata_len;
nrf_802154_transmit_done_metadata_t metadata = {0};
spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED,
&frame_handle,
&tx_error,
NRF_802154_TRANSMITTED_FRAME_PROPS_DECODE(metadata.
frame_props));
NRF_802154_TRANSMIT_FAILED_DECODE(frame_handle,
p_serialized_frame,
frame_hdata_len,
tx_error,
metadata));
if (siz < 0)
{
@ -385,7 +399,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_failed(
bool frame_found = nrf_802154_buffer_mgr_src_search_by_buffer_handle(
nrf_802154_spinel_src_buffer_mgr_get(),
frame_handle,
&p_frame);
&p_local_frame);
if (!frame_found)
{
@ -403,7 +417,11 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_failed(
return NRF_802154_SERIALIZATION_ERROR_INVALID_BUFFER;
}
nrf_802154_transmit_failed(p_frame, tx_error, &metadata);
memcpy(p_local_frame,
p_serialized_frame,
NRF_802154_DATA_LEN_FROM_HDATA_LEN(frame_hdata_len));
nrf_802154_transmit_failed(p_local_frame, tx_error, &metadata);
return NRF_802154_SERIALIZATION_ERROR_OK;
}
@ -436,6 +454,20 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_generic_bool(
NRF_802154_SERIALIZATION_ERROR_OK);
}
nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_generic_uint8(
const void * p_property_data,
size_t property_data_len,
uint8_t * p_uint8_response)
{
spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_UINT8_S,
p_uint8_response);
return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
NRF_802154_SERIALIZATION_ERROR_OK);
}
nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_tx_power_get_ret(
const void * p_property_data,
size_t property_data_len,
@ -450,19 +482,6 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_tx_power_get_ret(
NRF_802154_SERIALIZATION_ERROR_OK);
}
nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_channel(const void * p_property_data,
size_t property_data_len,
uint8_t * p_channel)
{
spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_CHANNEL_GET_RET,
p_channel);
return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
NRF_802154_SERIALIZATION_ERROR_OK);
}
nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_capabilities_get_ret(
const void * p_property_data,
size_t property_data_len,
@ -491,6 +510,35 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_time_get_ret(
NRF_802154_SERIALIZATION_ERROR_OK);
}
nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_cca_cfg_get_ret(
const void * p_property_data,
size_t property_data_len,
nrf_802154_cca_cfg_t * p_cfg)
{
spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_CCA_CFG_GET_RET,
NRF_802154_CCA_CFG_DECODE(*p_cfg));
return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
NRF_802154_SERIALIZATION_ERROR_OK);
}
nrf_802154_ser_err_t nrf_802154_spinel_decode_prop_nrf_802154_stat_timestamps_get_ret(
const void * p_property_data,
size_t property_data_len,
nrf_802154_stat_timestamps_t * p_stat_timestamps)
{
spinel_ssize_t siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_GET_RET,
NRF_802154_STAT_TIMESTAMPS_DECODE(
*p_stat_timestamps));
return ((siz) < 0 ? NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE :
NRF_802154_SERIALIZATION_ERROR_OK);
}
nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_is(
const void * p_cmd_data,
size_t cmd_data_len)
@ -520,8 +568,18 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_is(
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA:
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_CANCEL:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA:
// fall through
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CONTINUOUS_CARRIER:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_MODULATED_CARRIER:
// fall through
#endif
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ENERGY_DETECTION:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TX_POWER_GET:
@ -532,6 +590,12 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_is(
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TIME_GET:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_GET:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_STORE:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_REMOVE:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PENDING_BIT_FOR_ADDR_SET:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PENDING_BIT_FOR_ADDR_CLEAR:
@ -542,7 +606,27 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_is(
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW_AT:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_AT_CANCEL:
// fall through
#if NRF_802154_CSMA_CA_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_CSMA_CA_RAW:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_SET:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_GET:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_SET:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_GET:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_SET:
// fall through
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET:
// fall through
#endif // NRF_802154_CSMA_CA_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_STAT_TIMESTAMPS_GET:
nrf_802154_spinel_response_notifier_property_notify(property,
p_property_data,
property_data_len);

View File

@ -48,6 +48,9 @@
#include "nrf_802154_buffer_mgr_src.h"
#include "nrf_802154.h"
#include "nrf_802154_config.h"
static uint8_t * mp_transmit_at_frame; ///< Pointer to the frame that was requested to delay-transmit
/**
* @brief Deal with SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SLEEP request and send response.
@ -93,16 +96,90 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_receive(const void * p
receive_response);
}
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_receive_at(
const void * p_property_data,
size_t property_data_len)
{
uint32_t t0;
uint32_t dt;
uint32_t timeout;
uint8_t channel;
uint32_t id;
spinel_ssize_t siz;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_RECEIVE_AT,
&t0,
&dt,
&timeout,
&channel,
&id);
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
bool result = nrf_802154_receive_at(t0, dt, timeout, channel, id);
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT,
SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_RET,
result);
}
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_CANCEL.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_receive_at_cancel(
const void * p_property_data,
size_t property_data_len)
{
uint32_t id;
spinel_ssize_t siz;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_CANCEL,
&id);
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
bool result = nrf_802154_receive_at_cancel(id);
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_CANCEL,
SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_CANCEL_RET,
result);
}
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_channel_get(const void * p_property_data,
size_t property_data_len)
{
(void)p_property_data;
(void)property_data_len;
uint8_t channel = nrf_802154_channel_get();
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CHANNEL_GET,
SPINEL_DATATYPE_NRF_802154_CHANNEL_GET_RET,
nrf_802154_channel_get());
channel);
}
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_channel_set(const void * p_property_data,
@ -130,7 +207,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_channel_set(const void
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_PAN_ID_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pan_id_set(
@ -166,7 +243,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pan_id_set(
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SHORT_ADDRESS_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_short_address_set(
@ -202,7 +279,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_short_address_set(
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_EXTENDED_ADDRESS_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_extended_address_set(
@ -238,7 +315,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_extended_address_set(
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PAN_COORD_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pan_coord_set(
@ -267,7 +344,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pan_coord_set(
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PROMISCUOUS_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_promiscuous_set(
@ -296,7 +373,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_promiscuous_set(
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_cca(const void * p_property_data,
@ -312,11 +389,76 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_cca(const void * p_pro
result);
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CONTINUOUS_CARRIER.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_continuous_carrier(
const void * p_property_data,
size_t property_data_len)
{
(void)p_property_data;
(void)property_data_len;
bool result = nrf_802154_continuous_carrier();
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CONTINUOUS_CARRIER,
SPINEL_DATATYPE_NRF_802154_CONTINUOUS_CARRIER_RET,
result);
}
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_MODULATED_CARRIER.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_modulated_carrier(
const void * p_property_data,
size_t property_data_len)
{
const void * p_buffer;
size_t p_buffer_len;
spinel_ssize_t siz = spinel_datatype_unpack(
p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_MODULATED_CARRIER,
&p_buffer,
&p_buffer_len);
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
if (p_buffer_len != RAW_PAYLOAD_OFFSET + ((uint8_t *)p_buffer)[0])
{
return NRF_802154_SERIALIZATION_ERROR_REQUEST_INVALID;
}
bool result = nrf_802154_modulated_carrier(p_buffer);
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_MODULATED_CARRIER,
SPINEL_DATATYPE_NRF_802154_MODULATED_CARRIER_RET,
result);
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ENERGY_DETECTION.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_energy_detection(
@ -348,7 +490,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_energy_detection(
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_AUTO_PENDING_BIT_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_auto_pending_bit_set(
const void * p_property_data,
@ -376,7 +518,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_auto_pending_bit_set(
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PENDING_BIT_FOR_ADDR_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pending_bit_for_addr_set(
const void * p_property_data,
@ -424,7 +566,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pending_bit_for_addr_s
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PENDING_BIT_FOR_ADDR_CLEAR.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pending_bit_for_addr_clear(
@ -473,7 +615,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pending_bit_for_addr_c
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PENDING_BIT_FOR_ADDR_RESET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pending_bit_for_addr_reset(
@ -502,7 +644,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pending_bit_for_addr_r
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SRC_ADDR_MATCHING_METHOD_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_src_addr_matching_method_set(
@ -543,7 +685,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_src_addr_matching_meth
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ACK_DATA_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_ack_data_set(
@ -602,7 +744,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_ack_data_set(
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ACK_DATA_CLEAR.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_ack_data_clear(
@ -648,11 +790,13 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_ack_data_clear(
ack_data_clear_res);
}
#if NRF_802154_CSMA_CA_ENABLED
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_TRANSMIT_CSMA_CA_RAW.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_csma_ca_raw(
@ -705,11 +849,174 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_csma_ca_raw(
result);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_csma_ca_min_be_set(
const void * p_property_data,
size_t property_data_len)
{
uint8_t min_be;
spinel_ssize_t siz;
bool result;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_CHANNEL_SET,
&min_be);
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
result = nrf_802154_csma_ca_min_be_set(min_be);
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_SET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_SET_RET,
result);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_GET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_csma_ca_min_be_get(
const void * p_property_data,
size_t property_data_len)
{
(void)p_property_data;
(void)property_data_len;
uint8_t min_be = nrf_802154_csma_ca_min_be_get();
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_GET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MIN_BE_GET_RET,
min_be);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_csma_ca_max_be_set(
const void * p_property_data,
size_t property_data_len)
{
uint8_t max_be;
spinel_ssize_t siz;
bool result;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_CHANNEL_SET,
&max_be);
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
result = nrf_802154_csma_ca_max_be_set(max_be);
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_SET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_SET_RET,
result);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_GET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_csma_ca_max_be_get(
const void * p_property_data,
size_t property_data_len)
{
(void)p_property_data;
(void)property_data_len;
uint8_t max_be = nrf_802154_csma_ca_max_be_get();
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_GET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BE_GET_RET,
max_be);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BACKOFFS_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_csma_ca_max_backoffs_set(
const void * p_property_data,
size_t property_data_len)
{
uint8_t max_backoffs;
spinel_ssize_t siz;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_CHANNEL_SET,
&max_backoffs);
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
nrf_802154_csma_ca_max_backoffs_set(max_backoffs);
return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to backoffs decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_csma_ca_max_backoffs_get(
const void * p_property_data,
size_t property_data_len)
{
(void)p_property_data;
(void)property_data_len;
uint8_t max_backoffs = nrf_802154_csma_ca_max_backoffs_get();
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET,
SPINEL_DATATYPE_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET_RET,
max_backoffs);
}
#endif // NRF_802154_CSMA_CA_ENABLED
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_TRANSMIT_RAW.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_raw(
@ -761,11 +1068,118 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_raw(
result);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_TRANSMIT_RAW_AT.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_raw_at(
const void * p_property_data,
size_t property_data_len)
{
uint32_t remote_frame_handle;
const void * p_frame;
size_t frame_hdata_len;
void * p_local_frame_ptr;
nrf_802154_transmit_at_metadata_t tx_metadata;
uint32_t t0;
uint32_t dt;
spinel_ssize_t siz = spinel_datatype_unpack(
p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_TRANSMIT_RAW_AT,
NRF_802154_TRANSMIT_AT_METADATA_DECODE(tx_metadata),
&t0,
&dt,
NRF_802154_HDATA_DECODE(remote_frame_handle, p_frame, frame_hdata_len));
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
// Map the remote handle to locally accessible pointer and copy the buffer content there
bool frame_added = nrf_802154_buffer_mgr_dst_add(
nrf_802154_spinel_dst_buffer_mgr_get(),
remote_frame_handle,
p_frame,
NRF_802154_DATA_LEN_FROM_HDATA_LEN(frame_hdata_len),
&p_local_frame_ptr);
if (!frame_added)
{
return NRF_802154_SERIALIZATION_ERROR_NO_MEMORY;
}
bool result = nrf_802154_transmit_raw_at(p_local_frame_ptr, t0, dt, &tx_metadata);
if (!result)
{
nrf_802154_buffer_mgr_dst_remove_by_local_pointer(nrf_802154_spinel_dst_buffer_mgr_get(),
p_local_frame_ptr);
}
else
{
// Latch the local pointer in case the transmission is cancelled
mp_transmit_at_frame = p_local_frame_ptr;
}
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW_AT,
SPINEL_DATATYPE_NRF_802154_TRANSMIT_RAW_AT_RET,
result);
}
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_AT_CANCEL.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_at_cancel(
const void * p_property_data,
size_t property_data_len)
{
(void)p_property_data;
(void)property_data_len;
bool result = nrf_802154_transmit_at_cancel();
if (result)
{
// The transmission was cancelled successfully
if (!mp_transmit_at_frame)
{
// This should never happen
return NRF_802154_SERIALIZATION_ERROR_INVALID_BUFFER;
}
// Free the local frame pointer
bool removed = nrf_802154_buffer_mgr_dst_remove_by_local_pointer(
nrf_802154_spinel_dst_buffer_mgr_get(),
mp_transmit_at_frame);
if (!removed)
{
return NRF_802154_SERIALIZATION_ERROR_INVALID_BUFFER;
}
}
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_AT_CANCEL,
SPINEL_DATATYPE_NRF_802154_TRANSMIT_AT_CANCEL_RET,
result);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_BUFFER_FREE_RAW.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_buffer_free_raw(
@ -814,7 +1228,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_buffer_free_raw(
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_TX_POWER_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_power_set(const void * p_property_data,
@ -841,7 +1255,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_power_set(const voi
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_TX_POWER_GET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_power_get(const void * p_property_data,
@ -864,7 +1278,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_power_get(const voi
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_CAPABILITIES_GET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_capabilities_get(
@ -888,7 +1302,7 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_capabilities_get(
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_TIME_GET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_data buffer.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_time_get(
@ -908,6 +1322,188 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_time_get(
time);
}
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_cca_cfg_get(const void * p_property_data,
size_t property_data_len)
{
(void)p_property_data;
(void)property_data_len;
nrf_802154_cca_cfg_t cfg;
nrf_802154_cca_cfg_get(&cfg);
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_GET,
SPINEL_DATATYPE_NRF_802154_CCA_CFG_GET_RET,
NRF_802154_CCA_CFG_ENCODE(cfg));
}
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_stat_timestamps_get(
const void * p_property_data,
size_t property_data_len)
{
(void)p_property_data;
(void)property_data_len;
nrf_802154_stat_timestamps_t t;
nrf_802154_stat_timestamps_get(&t);
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_STAT_TIMESTAMPS_GET,
SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_GET_RET,
NRF_802154_STAT_TIMESTAMPS_ENCODE(t));
}
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802514_cca_cfg_set(const void * p_property_data,
size_t property_data_len)
{
nrf_802154_cca_cfg_t cfg;
spinel_ssize_t siz;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_CCA_CFG_SET,
NRF_802154_CCA_CFG_DECODE(cfg));
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
nrf_802154_cca_cfg_set(&cfg);
return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_security_global_frame_counter_set(
const void * p_property_data,
size_t property_data_len)
{
spinel_ssize_t siz;
uint32_t frame_counter;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET,
&frame_counter);
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
nrf_802154_security_global_frame_counter_set(frame_counter);
return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_STORE.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_security_key_store(
const void * p_property_data,
size_t property_data_len)
{
spinel_ssize_t siz;
nrf_802154_key_t key = {0};
uint32_t key_size;
uint32_t key_id_size;
nrf_802154_security_error_t err;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_STORE,
NRF_802154_SECURITY_KEY_STORE_DECODE(key, key_size, key_id_size));
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
err = nrf_802154_security_key_store(&key);
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_STORE,
SPINEL_DATATYPE_NRF_802154_SECURITY_ERROR_RET,
err);
}
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_REMOVE.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_security_key_remove(
const void * p_property_data,
size_t property_data_len)
{
spinel_ssize_t siz;
uint8_t key_id_data[KEY_ID_MODE_3_SIZE];
nrf_802154_key_id_t key_id = {.p_key_id = key_id_data};
uint32_t key_id_size;
nrf_802154_security_error_t err;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_SECURITY_KEY_REMOVE,
NRF_802154_SECURITY_KEY_REMOVE_DECODE(key_id, key_id_size));
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
err = nrf_802154_security_key_remove(&key_id);
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_REMOVE,
SPINEL_DATATYPE_NRF_802154_SECURITY_ERROR_RET,
err);
}
#if NRF_802154_DELAYED_TRX_ENABLED && NRF_802154_IE_WRITER_ENABLED
/**
* @brief Decode and dispatch SPINEL_DATATYPE_NRF_802154_CSL_WRITER_PERIOD_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_csl_writer_period_set(
const void * p_property_data,
size_t property_data_len)
{
spinel_ssize_t siz;
uint16_t csl_period;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_CSL_WRITER_PERIOD_SET,
&csl_period);
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
nrf_802154_csl_writer_period_set(csl_period);
return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK);
}
#endif // NRF_802154_DELAYED_TRX_ENABLED && NRF_802154_IE_WRITER_ENABLED
nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_cmd_data,
size_t cmd_data_len)
{
@ -936,6 +1532,13 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE:
return spinel_decode_prop_nrf_802154_receive(p_property_data, property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT:
return spinel_decode_prop_nrf_802154_receive_at(p_property_data, property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_CANCEL:
return spinel_decode_prop_nrf_802154_receive_at_cancel(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CHANNEL_GET:
return spinel_decode_prop_nrf_802514_channel_get(p_property_data, property_data_len);
@ -983,6 +1586,18 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA:
return spinel_decode_prop_nrf_802154_cca(p_property_data, property_data_len);
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CONTINUOUS_CARRIER:
return spinel_decode_prop_nrf_802154_continuous_carrier(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_MODULATED_CARRIER:
return spinel_decode_prop_nrf_802154_modulated_carrier(p_property_data,
property_data_len);
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ENERGY_DETECTION:
return spinel_decode_prop_nrf_802154_energy_detection(p_property_data,
property_data_len);
@ -993,13 +1608,47 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TX_POWER_GET:
return spinel_decode_prop_nrf_802154_tx_power_get(p_property_data, property_data_len);
#if NRF_802154_CSMA_CA_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_CSMA_CA_RAW:
return spinel_decode_prop_nrf_802154_transmit_csma_ca_raw(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_SET:
return spinel_decode_prop_nrf_802514_csma_ca_min_be_set(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MIN_BE_GET:
return spinel_decode_prop_nrf_802514_csma_ca_min_be_get(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_SET:
return spinel_decode_prop_nrf_802514_csma_ca_max_be_set(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BE_GET:
return spinel_decode_prop_nrf_802514_csma_ca_max_be_get(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_SET:
return spinel_decode_prop_nrf_802514_csma_ca_max_backoffs_set(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSMA_CA_MAX_BACKOFFS_GET:
return spinel_decode_prop_nrf_802514_csma_ca_max_backoffs_get(p_property_data,
property_data_len);
#endif // NRF_802154_CSMA_CA_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW:
return spinel_decode_prop_nrf_802154_transmit_raw(p_property_data, property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_RAW_AT:
return spinel_decode_prop_nrf_802154_transmit_raw_at(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_AT_CANCEL:
return spinel_decode_prop_nrf_802154_transmit_at_cancel(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_BUFFER_FREE_RAW:
return spinel_decode_prop_nrf_802154_buffer_free_raw(p_property_data,
property_data_len);
@ -1012,6 +1661,12 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_
return spinel_decode_prop_nrf_802154_time_get(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_GET:
return spinel_decode_prop_nrf_802514_cca_cfg_get(p_property_data, property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA_CFG_SET:
return spinel_decode_prop_nrf_802514_cca_cfg_set(p_property_data, property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ACK_DATA_SET:
return spinel_decode_prop_nrf_802154_ack_data_set(p_property_data,
property_data_len);
@ -1020,6 +1675,28 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_
return spinel_decode_prop_nrf_802154_ack_data_clear(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET:
return spinel_decode_prop_nrf_802154_security_global_frame_counter_set(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_STORE:
return spinel_decode_prop_nrf_802154_security_key_store(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_REMOVE:
return spinel_decode_prop_nrf_802154_security_key_remove(p_property_data,
property_data_len);
#if NRF_802154_DELAYED_TRX_ENABLED && NRF_802154_IE_WRITER_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_PERIOD_SET:
return spinel_decode_prop_nrf_802154_csl_writer_period_set(p_property_data,
property_data_len);
#endif // NRF_802154_DELAYED_TRX_ENABLED && NRF_802154_IE_WRITER_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_STAT_TIMESTAMPS_GET:
return spinel_decode_prop_nrf_802514_stat_timestamps_get(p_property_data,
property_data_len);
default:
NRF_802154_SPINEL_LOG_RAW("Unsupported property: %s(%u)\n",
spinel_prop_key_to_cstr(property),

View File

@ -283,15 +283,8 @@ void nrf_802154_transmitted_raw(uint8_t * p_fr
{
uint32_t remote_frame_handle;
uint32_t ack_handle = 0;
uint32_t ack_len = 0;
uint8_t * p_ack = p_metadata->data.transmitted.p_ack;
/* Forcefully overwrite frame's properties due to KRKNWK-10114 not being implemented.
* This overwrite makes state of the frame consistent with its properties.
*/
((nrf_802154_transmit_done_metadata_t *)p_metadata)->frame_props =
NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
@ -323,16 +316,13 @@ void nrf_802154_transmitted_raw(uint8_t * p_fr
local_transmitted_frame_ptr_free((void *)p_frame);
SERIALIZATION_ERROR(NRF_802154_SERIALIZATION_ERROR_NO_MEMORY, error, bail);
}
ack_len = p_ack[0];
}
// Serialize the call
nrf_802154_ser_err_t res = nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMITTED_RAW,
SPINEL_DATATYPE_NRF_802154_TRANSMITTED_RAW,
remote_frame_handle,
NRF_802154_TRANSMIT_DONE_METADATA_ENCODE(*p_metadata, ack_handle));
NRF_802154_TRANSMITTED_RAW_ENCODE(remote_frame_handle, p_frame, *p_metadata, ack_handle));
// Free the local frame pointer no matter the result of serialization
local_transmitted_frame_ptr_free((void *)p_frame);
@ -357,12 +347,6 @@ void nrf_802154_transmit_failed(uint8_t * p_fr
NRF_802154_SPINEL_LOG_BANNER_CALLING();
NRF_802154_SPINEL_LOG_BUFF(p_frame, p_frame[0]);
/* Forcefully overwrite frame's properties due to KRKNWK-10114 not being implemented.
* This overwrite makes state of the frame consistent with its properties.
*/
((nrf_802154_transmit_done_metadata_t *)p_metadata)->frame_props =
NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT;
// Search for the handle to the original frame buffer based on the local pointer
bool frame_found = nrf_802154_buffer_mgr_dst_search_by_local_pointer(
nrf_802154_spinel_dst_buffer_mgr_get(),
@ -379,9 +363,7 @@ void nrf_802154_transmit_failed(uint8_t * p_fr
nrf_802154_ser_err_t res = nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_TRANSMIT_FAILED,
SPINEL_DATATYPE_NRF_802154_TRANSMIT_FAILED,
remote_frame_handle,
tx_error,
NRF_802154_TRANSMITTED_FRAME_PROPS_ENCODE(p_metadata->frame_props));
NRF_802154_TRANSMIT_FAILED_ENCODE(remote_frame_handle, p_frame, tx_error, *p_metadata));
// Free the local frame pointer no matter the result of serialization
local_transmitted_frame_ptr_free((void *)p_frame);

View File

@ -341,7 +341,7 @@ void nrf_802154_sl_ant_div_rx_preamble_detected_notify(void);
bool nrf_802154_sl_ant_div_rx_frame_started_notify(void);
/**
* @brief Notification to be called when frame is received successfuly.
* @brief Notification to be called when frame is received successfully.
*/
void nrf_802154_sl_ant_div_rx_frame_received_notify(void);

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2017 - 2021, Nordic Semiconductor ASA
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_802154_SL_CRIT_SECT_IF_H__
#define NRF_802154_SL_CRIT_SECT_IF_H__
#include <stdbool.h>
/**
* @defgroup nrf_802154_sl_crit_sect_if Interface of the critical section.
* @{
*/
/**
* @brief Pointer to function used to enter critical section.
*/
typedef bool (* nrf_802154_sl_crit_sect_enter_t)(void);
/**
* @brief Pointer to function used to exit critical section.
*/
typedef void (* nrf_802154_sl_crit_sect_exit_t)(void);
/**
* @brief Structure that holds interface of Radio Driver critical sections.
*/
typedef struct
{
nrf_802154_sl_crit_sect_enter_t enter;
nrf_802154_sl_crit_sect_exit_t exit;
} nrf_802154_sl_crit_sect_interface_t;
/**
* @brief Initializes the critical section interface.
*
* After the call SL library can use @ref nrf_802154_sl_crit_sect_enter and
* @ref nrf_802154_sl_crit_sect_exit to use critical section provided by the Radio Driver.
*
* @param[in] p_crit_sect_interface Pointer to a critical section interface of the Radio Driver.
* It must point to static data for lifetime of Radio Driver.
*/
void nrf_802154_sl_crit_sect_init(
const nrf_802154_sl_crit_sect_interface_t * p_crit_sect_interface);
/**
* @brief Enters into the critical section.
*
* @retval true Code entered into the critical section.
* @retval false Critical section was already taken, could not enter into critical section.
*/
static inline bool nrf_802154_sl_crit_sect_enter(void)
{
extern const nrf_802154_sl_crit_sect_interface_t * gp_nrf_802154_sl_crit_sect_interface;
return gp_nrf_802154_sl_crit_sect_interface->enter();
}
/**
* @brief Exits out of the critical section.
*/
static inline void nrf_802154_sl_crit_sect_exit(void)
{
extern const nrf_802154_sl_crit_sect_interface_t * gp_nrf_802154_sl_crit_sect_interface;
return gp_nrf_802154_sl_crit_sect_interface->exit();
}
/**
*@}
**/
#endif // NRF_802154_SL_CRIT_SECT_IF_H__

View File

@ -42,7 +42,38 @@
#include <nrf.h>
#include <nrfx.h>
#if defined(DPPI_PRESENT)
#include "hal/nrf_dppi.h"
#else
#include "hal/nrf_ppi.h"
#endif
/**
* @def NRF_802154_EGU_INSTANCE_NO
*
* Id of the EGU instance used by the driver to synchronize DPPIs and for requests and
* notifications if SWI is in use.
*
*/
#ifndef NRF_802154_EGU_INSTANCE_NO
#define NRF_802154_EGU_INSTANCE_NO 0
#endif
/**
* @def NRF_802154_EGU_INSTANCE
*
* The EGU instance used by the driver to synchronize PPIs and for requests and notifications if
* SWI is in use.
*
* @note This option is used by the core module regardless of the driver configuration.
*
*/
#define NRF_802154_EGU_INSTANCE NRFX_CONCAT_2(NRF_EGU, NRF_802154_EGU_INSTANCE_NO)
/**
* @def NRF_802154_EGU_TIMESTAMP_CHANNEL
*/
#define NRF_802154_EGU_TIMESTAMP_CHANNEL 4
/**
* @def NRF_802154_RTC_INSTANCE_NO
@ -122,8 +153,12 @@
*
*/
#ifndef NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE
#if defined(DPPI_PRESENT)
#define NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE 13U
#else
#define NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE NRF_PPI_CHANNEL13
#endif
#endif
/**
* @def NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE
@ -135,8 +170,12 @@
*
*/
#ifndef NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE
#if defined(DPPI_PRESENT)
#define NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE 11U
#else
#define NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE NRF_PPI_CHANNEL14
#endif
#endif
/**
* @def NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK
@ -157,7 +196,11 @@
*
*/
#ifndef NRF_802154_PPI_TIMESTAMP_GROUP
#if defined(DPPI_PRESENT)
#define NRF_802154_PPI_TIMESTAMP_GROUP NRF_DPPI_CHANNEL_GROUP1
#else
#define NRF_802154_PPI_TIMESTAMP_GROUP NRF_PPI_CHANNEL_GROUP2
#endif
#endif
#endif // NRF_802154_SL_PERIPHS_H__

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2020 - 2021, Nordic Semiconductor ASA
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file Common types provided by the nRF 802.15.4 Service Layer.
*
*/
#ifndef NRF_802154_SL_TYPES_H__
#define NRF_802154_SL_TYPES_H__
#include <stdint.h>
#include <stdbool.h>
#include <nrfx.h>
/**
* @brief Handle of a hardware event.
*
* This handle can be used to trigger peripheral tasks through hardware.
*/
typedef struct
{
/**
* @brief Actual handle to use when configuring hardware.
*
* On nRF52 series, this field represents an address of a hardware event
* that can be written to a PPI register.
*
* On nRF53 series, this field depending on @c shared might either represent
* an address of a hardware event that should publish to a DPPI channel,
* or a number of a DPPI channel that the hardware event of interest
* is already publishing to.
*/
uint32_t event_addr;
#if defined(DPPI_PRESENT)
/**
* @brief Indicates if the event is already publishing to a DPPI channel.
*/
bool shared;
#endif
} nrf_802154_sl_event_handle_t;
#endif // NRF_802154_SL_TYPES_H__

View File

@ -43,33 +43,12 @@
* @defgroup nrf_802154_rsch_crit_sect RSCH event queue used during critical sections
* @{
* @ingroup nrf_802154_rsch
* @brief The critical section implementation for the RSCH module.
*/
/**
* @brief Pointer to function used to enter critical section.
*/
typedef bool (* nrf_802154_sl_crit_sect_enter_t)(void);
/**
* @brief Pointer to function used to exit critical section.
*/
typedef void (* nrf_802154_sl_crit_sect_exit_t)(void);
/**
* @brief Structure that holds interface of Radio Scheduler critical sections.
*/
typedef struct
{
nrf_802154_sl_crit_sect_enter_t enter;
nrf_802154_sl_crit_sect_exit_t exit;
} nrf_802154_sl_crit_sect_interface_t;
/**
* @brief Initializes the RSCH critical section module.
*/
void nrf_802154_rsch_crit_sect_init(
const nrf_802154_sl_crit_sect_interface_t * p_crit_sect_interface);
void nrf_802154_rsch_crit_sect_init(void);
/**
* @brief Requests the priority level from RSCH through the critical section module.

View File

@ -43,6 +43,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "nrf_802154_sl_types.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -89,10 +91,9 @@ void nrf_802154_timer_coord_stop(void);
/**
* @brief Prepares for getting a precise timestamp of the given event.
*
* @param[in] event_addr Address of the peripheral register corresponding to the event that
* is to be time-stamped.
* @param[in] p_event Pointer to structure describing a hardware event to be timestamped.
*/
void nrf_802154_timer_coord_timestamp_prepare(uint32_t event_addr);
void nrf_802154_timer_coord_timestamp_prepare(const nrf_802154_sl_event_handle_t * p_event);
/**
* @brief Gets the timestamp of the recently prepared event.

View File

@ -47,6 +47,7 @@ target_sources(nrf-802154-sl
src/nrf_802154_sl_ant_div.c
src/nrf_802154_sl_capabilities.c
src/nrf_802154_sl_coex.c
src/nrf_802154_sl_crit_sect_if.c
src/nrf_802154_sl_fem.c
src/nrf_802154_sl_log.c
src/nrf_802154_sl_rsch.c

View File

@ -41,6 +41,22 @@ typedef enum
MPSL_FEM_EVENT_TYPE_GENERIC /**< Generic Event type. */
} mpsl_fem_event_type_t;
/** @brief Type representing a multiple-subscribable hardware event.
*
* For nRF52 series this is an address of an event within a peripheral. This
* event can be written to @c EEP register of a PPI channel, to make the
* PPI channel be driven by the event. For nRF52 series an event can be
* published to multiple PPI channels by hardware design, which makes it possible
* for multiple tasks to subscribe to it.
*
* For nRF53 series this is a number of a DPPI channel which is configured
* in such a way that certain event publishes to the DPPI channel and the
* DPPI channel is enabled. Ensuring above is responsibility of an user
* of the provided API. Multiple tasks can then subscribe to the DPPI channel
* (by hardware design) thus indirectly to the event.
*/
typedef uint32_t mpsl_subscribable_hw_event_t;
/** @brief MPSL Front End Module event. */
typedef struct
{
@ -73,17 +89,36 @@ typedef struct
/** Parameters when type is @ref MPSL_FEM_EVENT_TYPE_GENERIC. */
struct
{
/** Address of event register. */
uint32_t register_address;
/** Event triggerring required FEM operation. */
mpsl_subscribable_hw_event_t event;
/** Generic event, used in case of type equal to @ref mpsl_fem_event_type_t::MPSL_FEM_EVENT_TYPE_GENERIC. */
} generic;
} event;
#if defined(NRF52_SERIES)
/** False to ignore the PPI channel below and use the one set by application. True to use the PPI channel below. */
bool override_ppi;
/** PPI channel to be used for this event. */
uint8_t ppi_ch_id;
#endif
} mpsl_fem_event_t;
/** @brief Disable Front End Module.
*
* Some Front End Module devices can be explicitly disabled after PA and LNA activities are
* finished to preserve power.
*
* This function is intended to disable Front End Module shortly after radio operations are
* finished and the protocol does not expect more radio activities in short future, or passes
* radio control to other protocols in the system.
*
* Front End Module disabling process is synchronous and immediate.
*
* @retval 0
* @retval -NRF_EPERM FEM is configured to enable PA or LNA.
*/
int32_t mpsl_fem_disable(void);
/** @brief Sets up PA using the provided events for the upcoming radio transmission.
*
* Multiple configurations can be provided by repeating calls to this function
@ -209,18 +244,19 @@ void mpsl_fem_deactivate_now(mpsl_fem_functionality_t type);
/** @brief Instruct Front End Module to disable PA and LNA as soon as possible
* using the group following the event.
*
* @param[in] event Address of the event which is triggered when the abort condition occurs.
* @param[in] group PPI Group which shall be disabled when the abort event is triggered.
* @param[in] event An event which is triggered when the abort condition occurs.
* (See doc for @ref mpsl_subscribable_hw_event_t type.)
* @param[in] group (D)PPI Group which shall be disabled when the abort event is triggered.
*
* @retval 0 Setting of the abort sequence path is successful.
* @retval -NRF_EPERM Setting of the abort sequence path could not be performed.
*/
int32_t mpsl_fem_abort_set(uint32_t event, uint32_t group);
int32_t mpsl_fem_abort_set(mpsl_subscribable_hw_event_t event, uint32_t group);
/** @brief Adds one more PPI channel to the PPI Group prepared by the
* @ref mpsl_fem_abort_set function.
*
* @param[in] channel_to_add PPI channel to add to the PPI group.
* @param[in] channel_to_add (D)PPI channel to add to the (D)PPI group.
* @param[in] group The said PPI group.
*
* @retval 0 Setting of the abort sequence path is successful.
@ -231,7 +267,7 @@ int32_t mpsl_fem_abort_extend(uint32_t channel_to_add, uint32_t group);
/** @brief Removes one PPI channel from the PPI Group prepared by the
* @ref mpsl_fem_abort_set function.
*
* @param[in] channel_to_remove PPI channel to remove from the PPI group.
* @param[in] channel_to_remove (D)PPI channel to remove from the (D)PPI group.
* @param[in] group The said PPI group.
*
* @retval 0 Setting of the abort sequence path is successful.
@ -266,6 +302,8 @@ void mpsl_fem_cleanup(void);
void mpsl_fem_pa_is_configured(int8_t * const p_gain);
/** @brief Prepares the Front End Module to switch to the Power Down state.
*
* @deprecated This function is deprecated. Use @ref mpsl_fem_disable instead.
*
* This function makes sure the Front End Module shall be switched off in the
* appropriate time, using the hardware timer and its compare channel.

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2017 - 2021, Nordic Semiconductor ASA
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "nrf_802154_sl_crit_sect_if.h"
/**@brief Pointer to an interface of critical section. */
const nrf_802154_sl_crit_sect_interface_t * gp_nrf_802154_sl_crit_sect_interface;
void nrf_802154_sl_crit_sect_init(
const nrf_802154_sl_crit_sect_interface_t * p_crit_sect_interface)
{
gp_nrf_802154_sl_crit_sect_interface = p_crit_sect_interface;
}

View File

@ -37,12 +37,17 @@
#include <stdbool.h>
#include <stdint.h>
#include "mpsl_fem_protocol_api.h"
#include "protocol/mpsl_fem_protocol_api.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t mpsl_fem_disable(void)
{
return 0;
}
int32_t mpsl_fem_pa_configuration_set(const mpsl_fem_event_t * const p_activate_event,
const mpsl_fem_event_t * const p_deactivate_event)
{

View File

@ -157,6 +157,11 @@ bool nrf_802154_critical_section_rsch_event_is_pending(void)
return false;
}
void nrf_802154_critical_section_rsch_process_pending(void)
{
// Intentionally empty
}
bool nrf_802154_rsch_delayed_timeslot_request(const rsch_dly_ts_param_t * p_dly_ts_param)
{
(void)p_dly_ts_param;