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: e9eca1e61abc07f34604fa8154ca2eaca6f3c922

Signed-off-by: Jędrzej Ciupis <jedrzej.ciupis@nordicsemi.no>
This commit is contained in:
Jędrzej Ciupis 2023-03-06 14:04:29 +01:00 committed by Robert Lubos
parent 6c9f23498e
commit 609d4b41fe
38 changed files with 1060 additions and 758 deletions

View File

@ -39,3 +39,7 @@ add_subdirectory(driver)
add_subdirectory(sl) add_subdirectory(sl)
add_subdirectory(serialization) add_subdirectory(serialization)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/internal/CMakeLists.txt)
add_subdirectory(internal)
endif ()

View File

@ -106,6 +106,12 @@ if (SL_OPENSOURCE)
) )
endif() endif()
target_compile_definitions(nrf-802154-driver-interface
INTERFACE
# Disable total times measurement
NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED=0
)
if (NRF_802154_PROJECT_CONFIG) if (NRF_802154_PROJECT_CONFIG)
target_compile_definitions(nrf-802154-driver-interface target_compile_definitions(nrf-802154-driver-interface
INTERFACE INTERFACE

View File

@ -1775,6 +1775,13 @@ nrf_802154_capabilities_t nrf_802154_capabilities_get(void);
*/ */
void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter); void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter);
/**
* @brief Sets nRF 802.15.4 Radio Driver MAC Global Frame Counter if the value passed is larger than current.
*
* @param[in] frame_counter Frame counter to set.
*/
void nrf_802154_security_global_frame_counter_set_if_larger(uint32_t frame_counter);
/** /**
* @brief Store the 802.15.4 MAC Security Key inside the nRF 802.15.4 Radio Driver. * @brief Store the 802.15.4 MAC Security Key inside the nRF 802.15.4 Radio Driver.
* *

View File

@ -41,6 +41,10 @@
#include <nrfx.h> #include <nrfx.h>
#if NRF_802154_USE_INTERNAL_INCLUDES
#include "nrf_802154_config_internal.h"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -198,21 +202,6 @@ extern "C" {
#define NRF_802154_RX_BUFFERS 16 #define NRF_802154_RX_BUFFERS 16
#endif #endif
/**
* @def NRF_802154_DISABLE_BCC_MATCHING
*
* Setting this flag disables NRF_RADIO_EVENT_BCMATCH handling, and therefore the address filtering
* during the frame reception. With this flag set to 1, the address filtering is done after
* receiving a frame, during NRF_RADIO_EVENT_END handling.
*
* @note This option is incompatible with antenna diversity. If set to 1, antenna diversity
* must not be used.
*
*/
#ifndef NRF_802154_DISABLE_BCC_MATCHING
#define NRF_802154_DISABLE_BCC_MATCHING 0
#endif
/** /**
* @def NRF_802154_NOTIFY_CRCERROR * @def NRF_802154_NOTIFY_CRCERROR
* *
@ -245,12 +234,11 @@ extern "C" {
* *
* If measurement of total time spent in certain states is to be calculated. * If measurement of total time spent in certain states is to be calculated.
* *
* This option can be enabled when @ref NRF_802154_FRAME_TIMESTAMP_ENABLED is 1 * This option can be enabled when @ref NRF_802154_FRAME_TIMESTAMP_ENABLED is 1.
* and @ref NRF_802154_DISABLE_BCC_MATCHING is 0.
*/ */
#ifndef NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED #ifndef NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
#define NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED \ #define NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED \
(1 && NRF_802154_FRAME_TIMESTAMP_ENABLED && !NRF_802154_DISABLE_BCC_MATCHING) (1 && NRF_802154_FRAME_TIMESTAMP_ENABLED)
#endif #endif
/** /**
@ -430,22 +418,6 @@ extern "C" {
* @{ * @{
*/ */
/**
* @def NRF_802154_TX_STARTED_NOTIFY_ENABLED
*
* Indicates whether the notifications of the started transmissions are to be enabled in the driver.
*
* @note This feature is enabled by default if the ACK timeout feature or CSMA-CA is enabled.
* These features depend on the notifications of the transmission start.
*/
#ifndef NRF_802154_TX_STARTED_NOTIFY_ENABLED
#if NRF_802154_ACK_TIMEOUT_ENABLED || NRF_802154_CSMA_CA_ENABLED
#define NRF_802154_TX_STARTED_NOTIFY_ENABLED 1
#else
#define NRF_802154_TX_STARTED_NOTIFY_ENABLED 0
#endif
#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED
/** /**
* @} * @}
* @defgroup nrf_802154_config_coex WiFi coexistence feature configuration * @defgroup nrf_802154_config_coex WiFi coexistence feature configuration

View File

@ -474,13 +474,11 @@ static bool encryption_prepare(const nrf_802154_frame_parser_data_t * p_ack_data
* @section Enhanced ACK generation * @section Enhanced ACK generation
**************************************************************************************************/ **************************************************************************************************/
static void fcf_process(const nrf_802154_frame_parser_data_t * p_frame_data, static void fcf_process(const nrf_802154_frame_parser_data_t * p_frame_data)
uint8_t * p_bytes_written)
{ {
// Set Frame Control field bits. // Set Frame Control field bits.
// Some of them might require correction when higher parse level is available // 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] += 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, bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data,
m_ack[PHR_OFFSET] + PHR_SIZE, m_ack[PHR_OFFSET] + PHR_SIZE,
@ -490,27 +488,13 @@ static void fcf_process(const nrf_802154_frame_parser_data_t * p_frame_data,
(void)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) static void addr_end_process(const nrf_802154_frame_parser_data_t * p_frame_data)
{ {
// Set valid sequence number in ACK frame.
m_ack[PHR_OFFSET] += sequence_number_set(p_frame_data);
// Set destination address and PAN ID.
m_ack[PHR_OFFSET] += destination_set(p_frame_data, &m_ack_data);
// Set source address and PAN ID. // Set source address and PAN ID.
source_set(); source_set();
@ -532,15 +516,16 @@ static void addr_end_process(const nrf_802154_frame_parser_data_t * p_frame_data
(void)result; (void)result;
} }
static bool aux_sec_hdr_process(const nrf_802154_frame_parser_data_t * p_frame_data, 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) uint8_t bytes_written;
if (security_header_set(p_frame_data, &m_ack_data, &bytes_written) == false)
{ {
return false; return false;
} }
m_ack[PHR_OFFSET] += *p_bytes_written; m_ack[PHR_OFFSET] += bytes_written;
bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data, bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data,
m_ack[PHR_OFFSET] + PHR_SIZE, m_ack[PHR_OFFSET] + PHR_SIZE,
@ -552,16 +537,14 @@ static bool aux_sec_hdr_process(const nrf_802154_frame_parser_data_t * p_frame_d
return true; return true;
} }
static void ie_process(const nrf_802154_frame_parser_data_t * p_frame_data, static void ie_process(const nrf_802154_frame_parser_data_t * p_frame_data)
uint8_t * p_bytes_written)
{ {
// Set IE header. // Set IE header.
ie_header_set(mp_ie_data, m_ie_data_len, &m_ack_data); ie_header_set(mp_ie_data, m_ie_data_len, &m_ack_data);
m_ack[PHR_OFFSET] += m_ie_data_len; m_ack[PHR_OFFSET] += m_ie_data_len;
// Terminate the IE header if needed. // 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] += ie_header_terminate(mp_ie_data, m_ie_data_len, &m_ack_data) + FCS_SIZE;
m_ack[PHR_OFFSET] += *p_bytes_written + FCS_SIZE;
bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data, bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data,
m_ack[PHR_OFFSET] + PHR_SIZE, m_ack[PHR_OFFSET] + PHR_SIZE,
@ -580,8 +563,6 @@ static uint8_t * ack_process(
const nrf_802154_frame_parser_data_t * p_frame_data, const nrf_802154_frame_parser_data_t * p_frame_data,
bool * p_processing_done) 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( nrf_802154_frame_parser_level_t frame_parse_level = nrf_802154_frame_parser_parse_level_get(
p_frame_data); p_frame_data);
nrf_802154_frame_parser_level_t ack_parse_level = nrf_802154_frame_parser_parse_level_get( nrf_802154_frame_parser_level_t ack_parse_level = nrf_802154_frame_parser_parse_level_get(
@ -592,13 +573,7 @@ static uint8_t * ack_process(
if ((frame_parse_level >= PARSE_LEVEL_FCF_OFFSETS) && if ((frame_parse_level >= PARSE_LEVEL_FCF_OFFSETS) &&
(ack_parse_level < PARSE_LEVEL_FCF_OFFSETS)) (ack_parse_level < PARSE_LEVEL_FCF_OFFSETS))
{ {
fcf_process(p_frame_data, &bytes_written); fcf_process(p_frame_data);
}
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) && if ((frame_parse_level >= PARSE_LEVEL_ADDRESSING_END) &&
@ -610,14 +585,14 @@ static uint8_t * ack_process(
if ((frame_parse_level >= PARSE_LEVEL_AUX_SEC_HDR_END) && if ((frame_parse_level >= PARSE_LEVEL_AUX_SEC_HDR_END) &&
(ack_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)) if (!aux_sec_hdr_process(p_frame_data))
{ {
// Failure to set auxiliary security header, the ACK cannot be created. Exit immediately // Failure to set auxiliary security header, the ACK cannot be created. Exit immediately
*p_processing_done = true; *p_processing_done = true;
return NULL; return NULL;
} }
ie_process(p_frame_data, &bytes_written); ie_process(p_frame_data);
} }
if (frame_parse_level == PARSE_LEVEL_FULL) if (frame_parse_level == PARSE_LEVEL_FULL)

View File

@ -271,6 +271,7 @@ static void random_backoff_start(void)
rsch_dly_ts_param_t backoff_ts_param = rsch_dly_ts_param_t backoff_ts_param =
{ {
.trigger_time = nrf_802154_sl_timer_current_time_get() + backoff_us, .trigger_time = nrf_802154_sl_timer_current_time_get() + backoff_us,
.ppi_trigger_en = false,
.op = RSCH_DLY_TS_OP_CSMACA, .op = RSCH_DLY_TS_OP_CSMACA,
.type = RSCH_DLY_TS_TYPE_RELAXED, .type = RSCH_DLY_TS_TYPE_RELAXED,
.started_callback = frame_transmit, .started_callback = frame_transmit,

View File

@ -62,14 +62,19 @@
#include "nrf_802154_sl_utils.h" #include "nrf_802154_sl_utils.h"
#include "nrf_802154_sl_atomics.h" #include "nrf_802154_sl_atomics.h"
#ifdef NRF_802154_USE_INTERNAL_INCLUDES
#include "nrf_802154_delayed_trx_internal.h"
#endif
#if NRF_802154_DELAYED_TRX_ENABLED #if NRF_802154_DELAYED_TRX_ENABLED
/* The following time is the sum of 70us RTC_IRQHandler processing time, 40us of time that elapses #if defined(NRF52_SERIES)
* from the moment a board starts transmission to the moment other boards (e.g. sniffer) are able #define TX_SETUP_TIME_MAX 270u ///< Maximum time needed to prepare TX procedure [us]. It does not include TX ramp-up time.
* to detect that frame and in case of TX - 93us that accounts for a delay of yet unknown origin. #define RX_SETUP_TIME_MAX 270u ///< Maximum time needed to prepare RX procedure [us]. It does not include RX ramp-up time.
*/ #elif defined(NRF53_SERIES)
#define TX_SETUP_TIME 203u ///< Time needed to prepare TX procedure [us]. It does not include TX ramp-up time. #define TX_SETUP_TIME_MAX 360u ///< Maximum time needed to prepare TX procedure [us]. It does not include TX ramp-up time.
#define RX_SETUP_TIME 110u ///< Time needed to prepare RX procedure [us]. It does not include RX ramp-up time. #define RX_SETUP_TIME_MAX 290u ///< Maximum time needed to prepare RX procedure [us]. It does not include RX ramp-up time.
#endif
/** /**
* @brief States of delayed operations. * @brief States of delayed operations.
@ -768,7 +773,7 @@ bool nrf_802154_delayed_trx_transmit(uint8_t * p
if (p_dly_tx_data != NULL) if (p_dly_tx_data != NULL)
{ {
tx_time -= TX_SETUP_TIME; tx_time -= TX_SETUP_TIME_MAX;
tx_time -= TX_RAMP_UP_TIME; tx_time -= TX_RAMP_UP_TIME;
if (p_metadata->cca) if (p_metadata->cca)
@ -791,6 +796,8 @@ bool nrf_802154_delayed_trx_transmit(uint8_t * p
rsch_dly_ts_param_t dly_ts_param = rsch_dly_ts_param_t dly_ts_param =
{ {
.trigger_time = tx_time, .trigger_time = tx_time,
.ppi_trigger_en = true,
.ppi_trigger_dly = TX_SETUP_TIME_MAX,
.prio = RSCH_PRIO_TX, .prio = RSCH_PRIO_TX,
.op = RSCH_DLY_TS_OP_DTX, .op = RSCH_DLY_TS_OP_DTX,
.type = RSCH_DLY_TS_TYPE_PRECISE, .type = RSCH_DLY_TS_TYPE_PRECISE,
@ -814,12 +821,13 @@ bool nrf_802154_delayed_trx_receive(uint64_t rx_time,
if (p_dly_rx_data != NULL) if (p_dly_rx_data != NULL)
{ {
rx_time -= RX_SETUP_TIME; rx_time -= RX_SETUP_TIME_MAX;
rx_time -= RX_RAMP_UP_TIME; rx_time -= RX_RAMP_UP_TIME;
p_dly_rx_data->op = RSCH_DLY_TS_OP_DRX; p_dly_rx_data->op = RSCH_DLY_TS_OP_DRX;
p_dly_rx_data->rx.timeout_length = timeout + RX_RAMP_UP_TIME; p_dly_rx_data->rx.timeout_length = timeout + RX_RAMP_UP_TIME +
RX_SETUP_TIME_MAX;
p_dly_rx_data->rx.timeout_timer.action.callback.callback = notify_rx_timeout; p_dly_rx_data->rx.timeout_timer.action.callback.callback = notify_rx_timeout;
p_dly_rx_data->rx.channel = channel; p_dly_rx_data->rx.channel = channel;
@ -828,6 +836,8 @@ bool nrf_802154_delayed_trx_receive(uint64_t rx_time,
rsch_dly_ts_param_t dly_ts_param = rsch_dly_ts_param_t dly_ts_param =
{ {
.trigger_time = rx_time, .trigger_time = rx_time,
.ppi_trigger_en = true,
.ppi_trigger_dly = RX_SETUP_TIME_MAX,
.prio = RSCH_PRIO_IDLE_LISTENING, .prio = RSCH_PRIO_IDLE_LISTENING,
.op = RSCH_DLY_TS_OP_DRX, .op = RSCH_DLY_TS_OP_DRX,
.type = RSCH_DLY_TS_TYPE_PRECISE, .type = RSCH_DLY_TS_TYPE_PRECISE,
@ -938,6 +948,7 @@ bool nrf_802154_delayed_trx_nearest_drx_time_to_midpoint_get(uint32_t * p_drx_ti
uint32_t min_time_to_start = 0xffffffff; uint32_t min_time_to_start = 0xffffffff;
uint64_t drx_time_to_start = UINT64_C(0xffffffff); uint64_t drx_time_to_start = UINT64_C(0xffffffff);
uint32_t drx_time_to_midpoint; uint32_t drx_time_to_midpoint;
uint32_t drx_window_duration_time;
for (int i = 0; i < sizeof(m_dly_rx_data) / sizeof(m_dly_rx_data[0]); i++) for (int i = 0; i < sizeof(m_dly_rx_data) / sizeof(m_dly_rx_data[0]); i++)
{ {
@ -948,13 +959,15 @@ bool nrf_802154_delayed_trx_nearest_drx_time_to_midpoint_get(uint32_t * p_drx_ti
result = nrf_802154_rsch_delayed_timeslot_time_to_start_get(m_dly_rx_data[i].id, result = nrf_802154_rsch_delayed_timeslot_time_to_start_get(m_dly_rx_data[i].id,
&drx_time_to_start); &drx_time_to_start);
drx_time_to_start += RX_SETUP_TIME + RX_RAMP_UP_TIME; drx_time_to_start += RX_SETUP_TIME_MAX + RX_RAMP_UP_TIME;
if (result) if (result)
{ {
min_time_to_start = drx_time_to_start < min_time_to_start ? min_time_to_start = drx_time_to_start < min_time_to_start ?
(uint32_t)drx_time_to_start : min_time_to_start; (uint32_t)drx_time_to_start : min_time_to_start;
drx_time_to_midpoint = min_time_to_start + m_dly_rx_data[i].rx.timeout_length / 2; drx_window_duration_time = m_dly_rx_data[i].rx.timeout_length -
(RX_SETUP_TIME_MAX + RX_RAMP_UP_TIME);
drx_time_to_midpoint = min_time_to_start + drx_window_duration_time / 2;
} }
} }

View File

@ -132,7 +132,7 @@ static bool dst_addressing_may_be_present(uint8_t frame_type)
} }
/** /**
* @brief Get offset of end of addressing fields for given frame assuming its version is 2006. * @brief Verify if destination addressing bits in the FCF field are correct assuming its version is 2006.
* *
* If given frame contains errors that prevent getting offset, this function returns * If given frame contains errors that prevent getting offset, this function returns
* NRF_802154_RX_ERROR_INVALID_FRAME. If there are no destination address fields in given frame, * NRF_802154_RX_ERROR_INVALID_FRAME. If there are no destination address fields in given frame,
@ -140,11 +140,9 @@ static bool dst_addressing_may_be_present(uint8_t frame_type)
* beacon. * beacon.
* If both of those conditions are not met, the function returns * If both of those conditions are not met, the function returns
* NRF_802154_RX_ERROR_INVALID_DEST_ADDR. * NRF_802154_RX_ERROR_INVALID_DEST_ADDR.
* Otherwise, this function returns NRF_802154_RX_ERROR_NONE and inserts offset of addressing * Otherwise, this function returns NRF_802154_RX_ERROR_NONE.
* fields end to @p p_num_bytes.
* *
* @param[in] p_frame_data Pointer to the frame parser data. * @param[in] p_frame_data Pointer to the frame parser data.
* @param[out] p_num_bytes Offset of addressing fields end.
* @param[in] frame_type Type of incoming frame. * @param[in] frame_type Type of incoming frame.
* *
* @retval NRF_802154_RX_ERROR_NONE No errors in given frame were detected - it may be * @retval NRF_802154_RX_ERROR_NONE No errors in given frame were detected - it may be
@ -153,9 +151,8 @@ static bool dst_addressing_may_be_present(uint8_t frame_type)
* @retval NRF_802154_RX_ERROR_INVALID_FRAME Detected an error in given frame - it should be * @retval NRF_802154_RX_ERROR_INVALID_FRAME Detected an error in given frame - it should be
* discarded. * discarded.
*/ */
static nrf_802154_rx_error_t dst_addressing_end_offset_get_2006( static nrf_802154_rx_error_t dst_addressing_fcf_check_2006(
const nrf_802154_frame_parser_data_t * p_frame_data, const nrf_802154_frame_parser_data_t * p_frame_data,
uint8_t * p_num_bytes,
uint8_t frame_type) uint8_t frame_type)
{ {
nrf_802154_rx_error_t result; nrf_802154_rx_error_t result;
@ -163,13 +160,11 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2006(
switch (nrf_802154_frame_parser_dst_addr_type_get(p_frame_data)) switch (nrf_802154_frame_parser_dst_addr_type_get(p_frame_data))
{ {
case DEST_ADDR_TYPE_SHORT: case DEST_ADDR_TYPE_SHORT:
*p_num_bytes = SHORT_ADDR_CHECK_OFFSET; result = NRF_802154_RX_ERROR_NONE;
result = NRF_802154_RX_ERROR_NONE;
break; break;
case DEST_ADDR_TYPE_EXTENDED: case DEST_ADDR_TYPE_EXTENDED:
*p_num_bytes = EXTENDED_ADDR_CHECK_OFFSET; result = NRF_802154_RX_ERROR_NONE;
result = NRF_802154_RX_ERROR_NONE;
break; break;
case DEST_ADDR_TYPE_NONE: case DEST_ADDR_TYPE_NONE:
@ -179,8 +174,7 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2006(
{ {
case SRC_ADDR_TYPE_SHORT: case SRC_ADDR_TYPE_SHORT:
case SRC_ADDR_TYPE_EXTENDED: case SRC_ADDR_TYPE_EXTENDED:
*p_num_bytes = PANID_CHECK_OFFSET; result = NRF_802154_RX_ERROR_NONE;
result = NRF_802154_RX_ERROR_NONE;
break; break;
default: default:
@ -202,15 +196,13 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2006(
} }
/** /**
* @brief Get offset of end of addressing fields for given frame assuming its version is 2015. * @brief Verify if destination addressing bits in the FCF field are correct assuming its version is 2015.
* *
* If given frame contains errors that prevent getting offset, this function returns * If given frame contains errors that prevent getting offset, this function returns
* NRF_802154_RX_ERROR_INVALID_FRAME. * NRF_802154_RX_ERROR_INVALID_FRAME.
* Otherwise, this function returns NRF_802154_RX_ERROR_NONE and inserts offset of addressing * Otherwise, this function returns NRF_802154_RX_ERROR_NONE.
* fields end to @p p_num_bytes.
* *
* @param[in] p_frame_data Pointer to the frame parser data. * @param[in] p_frame_data Pointer to the frame parser data.
* @param[out] p_num_bytes Offset of addressing fields end.
* @param[in] frame_type Type of incoming frame. * @param[in] frame_type Type of incoming frame.
* *
* @retval NRF_802154_RX_ERROR_NONE No errors in given frame were detected - it may be * @retval NRF_802154_RX_ERROR_NONE No errors in given frame were detected - it may be
@ -218,9 +210,8 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2006(
* @retval NRF_802154_RX_ERROR_INVALID_FRAME Detected an error in given frame - it should be * @retval NRF_802154_RX_ERROR_INVALID_FRAME Detected an error in given frame - it should be
* discarded. * discarded.
*/ */
static nrf_802154_rx_error_t dst_addressing_end_offset_get_2015( static nrf_802154_rx_error_t dst_addressing_fcf_check_2015(
const nrf_802154_frame_parser_data_t * p_frame_data, const nrf_802154_frame_parser_data_t * p_frame_data,
uint8_t * p_num_bytes,
uint8_t frame_type) uint8_t frame_type)
{ {
nrf_802154_rx_error_t result; nrf_802154_rx_error_t result;
@ -241,8 +232,7 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2015(
} }
else else
{ {
*p_num_bytes = end_offset; result = NRF_802154_RX_ERROR_NONE;
result = NRF_802154_RX_ERROR_NONE;
} }
} }
break; break;
@ -266,13 +256,12 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2015(
} }
/** /**
* @brief Get offset of end of addressing fields for given frame. * @brief Verify if destination addressing bits in the FCF field are correct.
* *
* This function relays its arguments to either @ref dst_addressing_end_offset_get_2006 * This function relays its arguments to either @ref dst_addressing_end_offset_get_2006
* or @ref dst_addressing_end_offset_get_2015 depending on the frame version. * or @ref dst_addressing_end_offset_get_2015 depending on the frame version.
* *
* @param[in] p_frame_data Pointer to the frame parser data. * @param[in] p_frame_data Pointer to the frame parser data.
* @param[out] p_num_bytes Offset of addressing fields end.
* @param[in] frame_type Type of incoming frame. * @param[in] frame_type Type of incoming frame.
* @param[in] frame_version Version of the incoming frame. * @param[in] frame_version Version of the incoming frame.
* *
@ -282,9 +271,8 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2015(
* @retval NRF_802154_RX_ERROR_INVALID_FRAME Detected an error in given frame - it should be * @retval NRF_802154_RX_ERROR_INVALID_FRAME Detected an error in given frame - it should be
* discarded. * discarded.
*/ */
static nrf_802154_rx_error_t dst_addressing_end_offset_get( static nrf_802154_rx_error_t dst_addressing_fcf_check(
const nrf_802154_frame_parser_data_t * p_frame_data, const nrf_802154_frame_parser_data_t * p_frame_data,
uint8_t * p_num_bytes,
uint8_t frame_type, uint8_t frame_type,
uint8_t frame_version) uint8_t frame_version)
{ {
@ -294,11 +282,11 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get(
{ {
case FRAME_VERSION_0: case FRAME_VERSION_0:
case FRAME_VERSION_1: case FRAME_VERSION_1:
result = dst_addressing_end_offset_get_2006(p_frame_data, p_num_bytes, frame_type); result = dst_addressing_fcf_check_2006(p_frame_data, frame_type);
break; break;
case FRAME_VERSION_2: case FRAME_VERSION_2:
result = dst_addressing_end_offset_get_2015(p_frame_data, p_num_bytes, frame_type); result = dst_addressing_fcf_check_2015(p_frame_data, frame_type);
break; break;
default: default:
@ -441,60 +429,50 @@ static nrf_802154_rx_error_t dst_addr_check(const nrf_802154_frame_parser_data_t
} }
nrf_802154_rx_error_t nrf_802154_filter_frame_part( nrf_802154_rx_error_t nrf_802154_filter_frame_part(
nrf_802154_frame_parser_data_t * p_frame_data, const nrf_802154_frame_parser_data_t * p_frame_data,
uint8_t * p_num_bytes) nrf_802154_filter_mode_t filter_mode)
{ {
nrf_802154_rx_error_t result = NRF_802154_RX_ERROR_INVALID_FRAME; nrf_802154_rx_error_t result = NRF_802154_RX_ERROR_NONE;
uint8_t frame_type = nrf_802154_frame_parser_frame_type_get(p_frame_data); uint8_t frame_type = nrf_802154_frame_parser_frame_type_get(
uint8_t frame_version = nrf_802154_frame_parser_frame_version_get(p_frame_data); p_frame_data);
uint8_t psdu_length = nrf_802154_frame_parser_frame_length_get(p_frame_data); uint8_t frame_version = nrf_802154_frame_parser_frame_version_get(
p_frame_data);
uint8_t psdu_length = nrf_802154_frame_parser_frame_length_get(
p_frame_data);
switch (*p_num_bytes) if (filter_mode & NRF_802154_FILTER_MODE_FCF)
{ {
case FCF_CHECK_OFFSET: assert(nrf_802154_frame_parser_parse_level_get(p_frame_data) >= PARSE_LEVEL_FCF_OFFSETS);
if ((psdu_length < IMM_ACK_LENGTH) || (psdu_length > MAX_PACKET_SIZE))
{
result = NRF_802154_RX_ERROR_INVALID_LENGTH;
break;
}
if (!nrf_802154_frame_parser_valid_data_extend(p_frame_data, if ((psdu_length < IMM_ACK_LENGTH) || (psdu_length > MAX_PACKET_SIZE))
*p_num_bytes, {
PARSE_LEVEL_FCF_OFFSETS)) return NRF_802154_RX_ERROR_INVALID_LENGTH;
{ }
result = NRF_802154_RX_ERROR_INVALID_FRAME;
break;
}
if (!frame_type_and_version_filter(frame_type, frame_version)) if (!frame_type_and_version_filter(frame_type, frame_version))
{ {
result = NRF_802154_RX_ERROR_INVALID_FRAME; return NRF_802154_RX_ERROR_INVALID_FRAME;
break; }
}
if (!dst_addressing_may_be_present(frame_type)) if (dst_addressing_may_be_present(frame_type))
{ {
result = NRF_802154_RX_ERROR_NONE; result = dst_addressing_fcf_check(p_frame_data,
break; frame_type,
} frame_version);
}
}
result = dst_addressing_end_offset_get(p_frame_data, if (result != NRF_802154_RX_ERROR_NONE)
p_num_bytes, {
frame_type, return result;
frame_version); }
break;
default: if (filter_mode & NRF_802154_FILTER_MODE_DST_ADDR)
if (!nrf_802154_frame_parser_valid_data_extend(p_frame_data, {
*p_num_bytes, assert(nrf_802154_frame_parser_parse_level_get(
PARSE_LEVEL_DST_ADDRESSING_END)) p_frame_data) >= PARSE_LEVEL_DST_ADDRESSING_END);
{
result = NRF_802154_RX_ERROR_INVALID_FRAME;
break;
}
result = dst_addr_check(p_frame_data); result = dst_addr_check(p_frame_data);
break;
} }
return result; return result;

View File

@ -53,26 +53,42 @@
* @brief Procedures used to discard the incoming frames that contain unexpected data in PHR or MHR. * @brief Procedures used to discard the incoming frames that contain unexpected data in PHR or MHR.
*/ */
/**@brief Type representing the scope of frame filtering.
*
* Possible values:
* @ref NRF_802154_FILTER_MODE_FCF
* @ref NRF_802154_FILTER_MODE_DST_ADDR
*/
typedef uint32_t nrf_802154_filter_mode_t;
/**@brief Filter the frame based on the content of the FCF field. */
#define NRF_802154_FILTER_MODE_FCF (1UL << 0)
/**@brief Filter the frame based on the content of the destination addressing fields. */
#define NRF_802154_FILTER_MODE_DST_ADDR (1UL << 1)
/**@brief Perform all filtering tests. */
#define NRF_802154_FILTER_MODE_ALL (NRF_802154_FILTER_MODE_FCF | \
NRF_802154_FILTER_MODE_DST_ADDR)
/** /**
* @brief Verifies if the given part of the frame is valid. * @brief Verifies if the given part of the frame is valid.
* *
* This function is called a few times for each received frame. The first call is after the FCF * This function filters the given frame within the scope specified by @p filter_mode argument.
* is received (PSDU length is 2 and @p p_num_bytes value is 3). The subsequent calls are performed * In the @c NRF_802154_FILTER_MODE_FCF filter mode the function will reject all frames that do
* when the number of bytes requested by the previous call is available. The iteration ends * not satisfy requirements that can be determined by parsing the FCF field, such as unsupported
* when the function does not request any more bytes to check. * frame versions, unsupported frame types, or when destination addressing is not present in the
* If the verified part of the function is correct, this function returns true and sets * frame and the node is not a coordinator.
* @p p_num_bytes to the number of bytes that should be available in PSDU during the next iteration. * In the @c NRF_802154_FILTER_MODE_DST_ADDR filter mode the function will only check if the
* If the frame is correct and there is nothing more to check, this function returns true * destination address matches the address of the current node. If the incoming frame has no address
* and does not modify the @p p_num_bytes value. If the verified frame is incorrect, this function * and the node is a coordinator the frame will be accepted. No validation of FCF is performend.
* returns false and the @p p_num_bytes value is undefined.
* *
* @param[inout] p_frame_data Pointer to a frame parser data of the frame to be filtered. * To perform a full filtering procedure it is necessary to call this function on the incoming frame
* The frame filter may increase the frame parse level to either * with both @c NRF_802154_FILTER_MODE_FCF and @c NRF_802154_FILTER_MODE_DST_ADDR scopes in
* PARSE_LEVEL_FCF_OFFSETS or PARSE_LEVEL_DST_ADDRESSING_END. * two iterations, or both at once using @c NRF_802154_FILTER_MODE_ALL.
* @param[inout] p_num_bytes Number of bytes available in @p p_data buffer. This value is either *
* set to the requested number of bytes for the next iteration or remains * @param[in] p_frame_data Pointer to a frame parser data of the frame to be filtered.
* unchanged if no more iterations are to be performed during * @param[in] filter_mode The filtering scope that should be performed by the function.
* the filtering of the given frame.
* *
* @retval NRF_802154_RX_ERROR_NONE Verified part of the incoming frame is valid. * @retval NRF_802154_RX_ERROR_NONE Verified part of the incoming frame is valid.
* @retval NRF_802154_RX_ERROR_INVALID_FRAME Verified part of the incoming frame is invalid. * @retval NRF_802154_RX_ERROR_INVALID_FRAME Verified part of the incoming frame is invalid.
@ -80,8 +96,8 @@
* mismatches the address of this node. * mismatches the address of this node.
*/ */
nrf_802154_rx_error_t nrf_802154_filter_frame_part( nrf_802154_rx_error_t nrf_802154_filter_frame_part(
nrf_802154_frame_parser_data_t * p_frame_data, const nrf_802154_frame_parser_data_t * p_frame_data,
uint8_t * p_num_bytes); nrf_802154_filter_mode_t filter_mode);
/** /**
*@} *@}

View File

@ -103,6 +103,13 @@ nrf_802154_security_error_t nrf_802154_security_pib_key_use(nrf_802154_key_id_t
*/ */
void nrf_802154_security_pib_global_frame_counter_set(uint32_t frame_counter); void nrf_802154_security_pib_global_frame_counter_set(uint32_t frame_counter);
/**
* @brief Sets nRF 802.15.4 Radio Driver MAC Global Frame Counter if the value passed is larger than current.
*
* @param[in] frame_counter Frame counter to set.
*/
void nrf_802154_security_pib_global_frame_counter_set_if_larger(uint32_t frame_counter);
/** /**
* @brief Get the next 802.15.4 global frame counter. * @brief Get the next 802.15.4 global frame counter.
* *

View File

@ -36,6 +36,7 @@
#include "nrf_802154_config.h" #include "nrf_802154_config.h"
#include "nrf_802154_const.h" #include "nrf_802154_const.h"
#include "nrf_802154_sl_atomics.h"
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
@ -222,6 +223,23 @@ void nrf_802154_security_pib_global_frame_counter_set(uint32_t frame_counter)
m_global_frame_counter = frame_counter; m_global_frame_counter = frame_counter;
} }
void nrf_802154_security_pib_global_frame_counter_set_if_larger(uint32_t frame_counter)
{
uint32_t fc;
do
{
fc = m_global_frame_counter;
if (fc >= frame_counter)
{
break;
}
}
while (!nrf_802154_sl_atomic_cas_u32(&m_global_frame_counter, &fc, frame_counter));
}
nrf_802154_security_error_t nrf_802154_security_pib_frame_counter_get_next( nrf_802154_security_error_t nrf_802154_security_pib_frame_counter_get_next(
uint32_t * p_frame_counter, uint32_t * p_frame_counter,
nrf_802154_key_id_t * p_id) nrf_802154_key_id_t * p_id)

View File

@ -1066,6 +1066,11 @@ void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter)
nrf_802154_security_pib_global_frame_counter_set(frame_counter); nrf_802154_security_pib_global_frame_counter_set(frame_counter);
} }
void nrf_802154_security_global_frame_counter_set_if_larger(uint32_t frame_counter)
{
nrf_802154_security_pib_global_frame_counter_set_if_larger(frame_counter);
}
nrf_802154_security_error_t nrf_802154_security_key_store(nrf_802154_key_t * p_key) nrf_802154_security_error_t nrf_802154_security_key_store(nrf_802154_key_t * p_key)
{ {
return nrf_802154_security_pib_key_store(p_key); return nrf_802154_security_pib_key_store(p_key);

View File

@ -158,9 +158,6 @@ static uint32_t m_rx_window_id;
#if !NRF_802154_FRAME_TIMESTAMP_ENABLED #if !NRF_802154_FRAME_TIMESTAMP_ENABLED
#error NRF_802154_FRAME_TIMESTAMP_ENABLED == 0 when NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED != 0 #error NRF_802154_FRAME_TIMESTAMP_ENABLED == 0 when NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED != 0
#endif #endif
#if NRF_802154_DISABLE_BCC_MATCHING
#error NRF_802154_DISABLE_BCC_MATCHING != 0 when NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED != 0
#endif
#endif // NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED #endif // NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED #if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
@ -197,6 +194,19 @@ static void state_set(radio_state_t state)
request_preconditions_for_state(state); request_preconditions_for_state(state);
} }
/** Specifies what ramp up trigger mode to use when handling RX or TX operation request.
*
* It is assumed that the DELAYED_TRX module always requests HW mode both RX and TX,
* while in all other cases SW mode is required.
*
* @param[in] request_orig Module that originates the request.
*/
static nrf_802154_trx_ramp_up_trigger_mode_t ramp_up_mode_choose(req_originator_t request_orig)
{
return (request_orig == REQ_ORIG_DELAYED_TRX) ?
TRX_RAMP_UP_HW_TRIGGER : TRX_RAMP_UP_SW_TRIGGER;
}
/** Clear RX frame data. */ /** Clear RX frame data. */
static void rx_data_clear(void) static void rx_data_clear(void)
{ {
@ -337,7 +347,6 @@ static void transmit_ack_started_notify()
nrf_802154_tx_ack_started(mp_ack); nrf_802154_tx_ack_started(mp_ack);
} }
#if !NRF_802154_DISABLE_BCC_MATCHING
/** Notify that reception of a frame has started. */ /** Notify that reception of a frame has started. */
static void receive_started_notify(void) static void receive_started_notify(void)
{ {
@ -346,8 +355,6 @@ static void receive_started_notify(void)
nrf_802154_core_hooks_rx_started(p_frame); nrf_802154_core_hooks_rx_started(p_frame);
} }
#endif
/** Notify MAC layer that a frame was transmitted. */ /** Notify MAC layer that a frame was transmitted. */
static void transmitted_frame_notify(uint8_t * p_ack, int8_t power, uint8_t lqi) static void transmitted_frame_notify(uint8_t * p_ack, int8_t power, uint8_t lqi)
{ {
@ -1001,8 +1008,19 @@ static nrf_802154_trx_transmit_notifications_t make_trx_frame_transmit_notificat
return result; return result;
} }
/** Initialize RX operation. */ /**
static void rx_init(void) * @brief Initializes RX operation
*
* @param[in] ru_tr_mode Desired trigger mode for radio ramp up.
* @param[out] p_abort_shall_follow It is set to `true` when initialization fails and the trx
* module needs to be reset. When obtaining `true` here, the user
* is then obliged to call @ref nrf_802154_trx_abort. Such a case
* can only happen when @p ru_tr_mode = TRX_RAMP_UP_HW_TRIGGER.
* In all other cases, the value is not modified at all, so it
* should be initialized to `false` before calling the function.
* Can be NULL if @p ru_tr_mode is not TRX_RAMP_UP_HW_TRIGGER.
*/
static void rx_init(nrf_802154_trx_ramp_up_trigger_mode_t ru_tr_mode, bool * p_abort_shall_follow)
{ {
bool free_buffer; bool free_buffer;
@ -1029,11 +1047,31 @@ static void rx_init(void)
(void)nrf_802154_tx_power_split_pib_power_get(&split_power); (void)nrf_802154_tx_power_split_pib_power_get(&split_power);
nrf_802154_trx_receive_frame(BCC_INIT / 8U, nrf_802154_trx_receive_frame(BCC_INIT / 8U,
ru_tr_mode,
m_trx_receive_frame_notifications_mask, m_trx_receive_frame_notifications_mask,
&split_power); &split_power);
if (ru_tr_mode == TRX_RAMP_UP_HW_TRIGGER)
{
uint32_t ppi_ch = nrf_802154_trx_ramp_up_ppi_channel_get();
if (!nrf_802154_rsch_delayed_timeslot_ppi_update(ppi_ch))
{
/**
* The trigger has occurred. This has happened too early so there is a high risk
* that the radio will not ramp up. It is necessary to abort the operation.
*/
assert(p_abort_shall_follow);
*p_abort_shall_follow = true;
}
}
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED #if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
m_listening_start_hp_timestamp = nrf_802154_hp_timer_current_time_get(); m_listening_start_hp_timestamp = nrf_802154_hp_timer_current_time_get();
// The introduction of TRX_RAMP_UP_HW_TRIGGER broke the measurement method used here.
// Obtained timestamp is no more related to the moment when listening starts.
// TODO: Remove TOTAL_TIMES_MEASUREMENT feature, as it has been verified that it is
// not needed.
#endif #endif
#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) #if (NRF_802154_FRAME_TIMESTAMP_ENABLED)
@ -1061,7 +1099,9 @@ static void rx_init(void)
} }
/** Initialize TX operation. */ /** Initialize TX operation. */
static bool tx_init(const uint8_t * p_data, bool cca) static bool tx_init(const uint8_t * p_data,
nrf_802154_trx_ramp_up_trigger_mode_t rampup_trigg_mode,
bool cca)
{ {
if (!timeslot_is_granted() || !nrf_802154_rsch_timeslot_request( if (!timeslot_is_granted() || !nrf_802154_rsch_timeslot_request(
nrf_802154_tx_duration_get(p_data[0], cca, ack_is_requested(p_data)))) nrf_802154_tx_duration_get(p_data[0], cca, ack_is_requested(p_data))))
@ -1091,10 +1131,26 @@ static bool tx_init(const uint8_t * p_data, bool cca)
m_flags.tx_with_cca = cca; m_flags.tx_with_cca = cca;
nrf_802154_trx_transmit_frame(nrf_802154_tx_work_buffer_get(p_data), nrf_802154_trx_transmit_frame(nrf_802154_tx_work_buffer_get(p_data),
rampup_trigg_mode,
cca, cca,
&m_tx_power, &m_tx_power,
m_trx_transmit_frame_notifications_mask); m_trx_transmit_frame_notifications_mask);
if (rampup_trigg_mode == TRX_RAMP_UP_HW_TRIGGER)
{
uint32_t ppi_ch = nrf_802154_trx_ramp_up_ppi_channel_get();
if (!nrf_802154_rsch_delayed_timeslot_ppi_update(ppi_ch))
{
/**
* The trigger has occurred. This has happened too early so there is a high risk
* that the radio will not ramp up. It is necessary to abort the operation.
*/
nrf_802154_trx_abort();
return false;
}
}
return true; return true;
} }
@ -1345,15 +1401,15 @@ static void on_preconditions_approved(radio_state_t state)
break; break;
case RADIO_STATE_RX: case RADIO_STATE_RX:
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
break; break;
case RADIO_STATE_CCA_TX: case RADIO_STATE_CCA_TX:
(void)tx_init(mp_tx_data, true); (void)tx_init(mp_tx_data, TRX_RAMP_UP_SW_TRIGGER, true);
break; break;
case RADIO_STATE_TX: case RADIO_STATE_TX:
(void)tx_init(mp_tx_data, false); (void)tx_init(mp_tx_data, TRX_RAMP_UP_SW_TRIGGER, false);
break; break;
case RADIO_STATE_ED: case RADIO_STATE_ED:
@ -1659,122 +1715,129 @@ void nrf_802154_trx_receive_frame_started(void)
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
} }
#if !NRF_802154_DISABLE_BCC_MATCHING
uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc) uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
uint8_t prev_num_data_bytes; uint8_t next_bcc;
uint8_t num_data_bytes; nrf_802154_filter_mode_t filter_mode;
nrf_802154_rx_error_t filter_result; bool parse_result;
bool frame_accepted = true; bool should_filter = false;
nrf_802154_rx_error_t filter_result = NRF_802154_RX_ERROR_NONE;
nrf_802154_frame_parser_level_t parse_level = PARSE_LEVEL_NONE;
nrf_802154_frame_parser_level_t prev_level =
nrf_802154_frame_parser_parse_level_get(&m_current_rx_frame_data);
num_data_bytes = bcc;
prev_num_data_bytes = num_data_bytes;
assert(num_data_bytes >= PHR_SIZE + FCF_SIZE);
assert(m_state == RADIO_STATE_RX); assert(m_state == RADIO_STATE_RX);
if (!m_flags.frame_filtered) switch (prev_level)
{ {
filter_result = nrf_802154_filter_frame_part(&m_current_rx_frame_data, case PARSE_LEVEL_NONE:
&num_data_bytes); parse_level = PARSE_LEVEL_FCF_OFFSETS;
filter_mode = NRF_802154_FILTER_MODE_FCF;
should_filter = true;
break;
if (filter_result == NRF_802154_RX_ERROR_NONE) case PARSE_LEVEL_FCF_OFFSETS:
{ parse_level = PARSE_LEVEL_DST_ADDRESSING_END;
if (num_data_bytes != prev_num_data_bytes) filter_mode = NRF_802154_FILTER_MODE_DST_ADDR;
{ should_filter = true;
bcc = num_data_bytes; break;
}
else
{
m_flags.frame_filtered = true;
/* Request boosted preconditions */ case PARSE_LEVEL_DST_ADDRESSING_END:
nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_RX); parse_level = PARSE_LEVEL_SEC_CTRL_OFFSETS;
break;
/* Request next bcc match event to occur when basic data necessary for Ack case PARSE_LEVEL_SEC_CTRL_OFFSETS:
* generation is received. */ parse_level = PARSE_LEVEL_AUX_SEC_HDR_END;
m_flags.frame_parsed = false; break;
nrf_802154_ack_generator_reset();
bcc = PHR_SIZE + default:
nrf_802154_frame_parser_addressing_end_offset_get(&m_current_rx_frame_data) + /* Parsing completed. Nothing more to be done. */
SECURITY_CONTROL_SIZE; nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
} return 0;
}
else if ((filter_result == NRF_802154_RX_ERROR_INVALID_LENGTH) ||
(!nrf_802154_pib_promiscuous_get()))
{
trx_abort();
rx_init();
frame_accepted = false;
/* Release boosted preconditions */
request_preconditions_for_state(m_state);
if ((mp_current_rx_buffer->data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) !=
FRAME_TYPE_ACK)
{
receive_failed_notify(filter_result);
}
}
else
{
// Promiscuous mode, allow incorrect frames. Nothing to do here.
}
}
else if (!m_flags.frame_parsed)
{
if (nrf_802154_frame_parser_security_enabled_bit_is_set(&m_current_rx_frame_data))
{
if (nrf_802154_frame_parser_valid_data_extend(
&m_current_rx_frame_data,
num_data_bytes,
PARSE_LEVEL_AUX_SEC_HDR_END))
{
// All security fields have been received.
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
{
// This code should be unreachable.
}
}
else
{
// Nothing to do
} }
if ((!m_flags.rx_timeslot_requested) && (frame_accepted)) parse_result = nrf_802154_frame_parser_valid_data_extend(&m_current_rx_frame_data,
bcc,
parse_level);
if (!parse_result)
{ {
if (nrf_802154_rsch_timeslot_request(nrf_802154_rx_duration_get( should_filter = false;
mp_current_rx_buffer->data[0], filter_result = NRF_802154_RX_ERROR_INVALID_FRAME;
ack_is_requested(mp_current_rx_buffer->data)))) }
if (should_filter)
{
filter_result = nrf_802154_filter_frame_part(&m_current_rx_frame_data, filter_mode);
if ((filter_result == NRF_802154_RX_ERROR_NONE) &&
(filter_mode == NRF_802154_FILTER_MODE_DST_ADDR))
{
m_flags.frame_filtered = true;
nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_RX);
nrf_802154_ack_generator_reset();
}
if (nrf_802154_pib_promiscuous_get())
{
/*
* In promiscuous mode all filtering should be ignored unless the frame has
* invalid length.
*/
filter_result = filter_result == NRF_802154_RX_ERROR_INVALID_LENGTH ?
filter_result : NRF_802154_RX_ERROR_NONE;
}
}
if (filter_result != NRF_802154_RX_ERROR_NONE)
{
trx_abort();
rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
/* Release boosted preconditions */
request_preconditions_for_state(m_state);
if (nrf_802154_frame_parser_frame_type_get(&m_current_rx_frame_data) != FRAME_TYPE_ACK)
{
receive_failed_notify(filter_result);
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return 0;
}
switch (parse_level)
{
case PARSE_LEVEL_FCF_OFFSETS:
next_bcc = PHR_SIZE + nrf_802154_frame_parser_dst_addressing_end_offset_get(
&m_current_rx_frame_data);
break;
case PARSE_LEVEL_DST_ADDRESSING_END:
next_bcc = PHR_SIZE + nrf_802154_frame_parser_addressing_end_offset_get(
&m_current_rx_frame_data) + SECURITY_CONTROL_SIZE;
break;
case PARSE_LEVEL_SEC_CTRL_OFFSETS:
next_bcc = PHR_SIZE + nrf_802154_frame_parser_aux_sec_hdr_end_offset_get(
&m_current_rx_frame_data);
break;
default:
next_bcc = 0;
break;
}
if (!m_flags.rx_timeslot_requested)
{
uint16_t duration = nrf_802154_rx_duration_get(
mp_current_rx_buffer->data[0],
nrf_802154_frame_parser_ar_bit_is_set(&m_current_rx_frame_data));
if (nrf_802154_rsch_timeslot_request(duration))
{ {
m_flags.rx_timeslot_requested = true; m_flags.rx_timeslot_requested = true;
@ -1788,7 +1851,7 @@ uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc)
// We should not leave trx in temporary state, let's receive then. // We should not leave trx in temporary state, let's receive then.
// We avoid hard reset of radio during TX ACK phase due to timeslot end, // We avoid hard reset of radio during TX ACK phase due to timeslot end,
// which could result in spurious RF emission. // which could result in spurious RF emission.
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
// Don't care about the result - if the notification cannot be performed // Don't care about the result - if the notification cannot be performed
// no impact on the device's operation is expected // no impact on the device's operation is expected
@ -1799,7 +1862,6 @@ uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc)
} }
if (m_flags.frame_filtered && if (m_flags.frame_filtered &&
m_flags.frame_parsed &&
nrf_802154_frame_parser_ar_bit_is_set(&m_current_rx_frame_data) && nrf_802154_frame_parser_ar_bit_is_set(&m_current_rx_frame_data) &&
nrf_802154_pib_auto_ack_get()) nrf_802154_pib_auto_ack_get())
{ {
@ -1808,11 +1870,9 @@ uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc)
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return bcc; return next_bcc;
} }
#endif
void nrf_802154_trx_go_idle_finished(void) void nrf_802154_trx_go_idle_finished(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -1905,7 +1965,6 @@ void nrf_802154_trx_receive_frame_crcerror(void)
rx_data_clear(); rx_data_clear();
// We don't change receive buffer, receive will go to the same that was already used // We don't change receive buffer, receive will go to the same that was already used
#if !NRF_802154_DISABLE_BCC_MATCHING
request_preconditions_for_state(m_state); request_preconditions_for_state(m_state);
nrf_802154_fal_tx_power_split_t split_power = {0}; nrf_802154_fal_tx_power_split_t split_power = {0};
@ -1913,6 +1972,7 @@ void nrf_802154_trx_receive_frame_crcerror(void)
(void)nrf_802154_tx_power_split_pib_power_get(&split_power); (void)nrf_802154_tx_power_split_pib_power_get(&split_power);
nrf_802154_trx_receive_frame(BCC_INIT / 8U, nrf_802154_trx_receive_frame(BCC_INIT / 8U,
TRX_RAMP_UP_SW_TRIGGER,
m_trx_receive_frame_notifications_mask, m_trx_receive_frame_notifications_mask,
&split_power); &split_power);
@ -1924,10 +1984,6 @@ void nrf_802154_trx_receive_frame_crcerror(void)
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_end_event_handle_get()); nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_end_event_handle_get());
#endif #endif
#else
// With BCC matching disabled trx module will re-arm automatically
#endif
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED #if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
update_total_times_on_receive_end(listening_start_hp_timestamp, update_total_times_on_receive_end(listening_start_hp_timestamp,
receive_end_hp_timestamp, receive_end_hp_timestamp,
@ -1965,7 +2021,8 @@ void nrf_802154_trx_receive_frame_received(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
uint8_t * p_received_data = mp_current_rx_buffer->data; uint8_t * p_received_data = mp_current_rx_buffer->data;
nrf_802154_rx_error_t filter_result = NRF_802154_RX_ERROR_RUNTIME;
// Latch RSSI and LQI values before sending ACK // Latch RSSI and LQI values before sending ACK
m_last_rssi = rssi_last_measurement_get(); m_last_rssi = rssi_last_measurement_get();
@ -1980,57 +2037,35 @@ void nrf_802154_trx_receive_frame_received(void)
mp_current_rx_buffer->data[PHR_OFFSET]); mp_current_rx_buffer->data[PHR_OFFSET]);
#endif #endif
#if NRF_802154_DISABLE_BCC_MATCHING bool parse_result = nrf_802154_frame_parser_valid_data_extend(
uint8_t num_data_bytes = PHR_SIZE + FCF_SIZE; &m_current_rx_frame_data,
uint8_t prev_num_data_bytes = 0; PHR_SIZE + nrf_802154_frame_parser_frame_length_get(&m_current_rx_frame_data),
nrf_802154_rx_error_t filter_result; PARSE_LEVEL_FULL);
// Frame filtering if (parse_result && !m_flags.frame_filtered)
while (num_data_bytes != prev_num_data_bytes)
{ {
prev_num_data_bytes = num_data_bytes; filter_result = nrf_802154_filter_frame_part(&m_current_rx_frame_data,
NRF_802154_FILTER_MODE_ALL);
// Keep checking consecutive parts of the frame header.
filter_result = nrf_802154_filter_frame_part(&m_current_rx_frame_data, &num_data_bytes);
if (filter_result == NRF_802154_RX_ERROR_NONE) if (filter_result == NRF_802154_RX_ERROR_NONE)
{ {
if (num_data_bytes == prev_num_data_bytes) uint16_t duration = nrf_802154_ack_duration_with_turnaround_get();
if (nrf_802154_rsch_timeslot_request(duration))
{ {
m_flags.frame_filtered = true; m_flags.frame_filtered = true;
m_flags.rx_timeslot_requested = true;
nrf_802154_ack_generator_reset();
receive_started_notify();
}
else
{
filter_result = NRF_802154_RX_ERROR_TIMESLOT_ENDED;
} }
} }
else
{
break;
}
} }
// Timeslot request
if (m_flags.frame_filtered &&
nrf_802154_frame_parser_ar_bit_is_set(&m_current_rx_frame_data) &&
!nrf_802154_rsch_timeslot_request(nrf_802154_rx_duration_get(0, true)))
{
// Frame is destined to this node but there is no timeslot to transmit ACK.
// Just disable receiver and wait for a new timeslot.
nrf_802154_trx_abort();
rx_flags_clear();
rx_data_clear();
// Filter out received ACK frame if promiscuous mode is disabled.
if (((p_received_data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) != FRAME_TYPE_ACK) ||
nrf_802154_pib_promiscuous_get())
{
mp_current_rx_buffer->free = false;
received_frame_notify_and_nesting_allow(p_received_data);
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return;
}
#endif // NRF_802154_DISABLE_BCC_MATCHING
if (m_flags.frame_filtered || nrf_802154_pib_promiscuous_get()) if (m_flags.frame_filtered || nrf_802154_pib_promiscuous_get())
{ {
nrf_802154_stat_counter_increment(received_frames); nrf_802154_stat_counter_increment(received_frames);
@ -2043,11 +2078,7 @@ void nrf_802154_trx_receive_frame_received(void)
nrf_802154_sl_ant_div_rx_frame_received_notify(); nrf_802154_sl_ant_div_rx_frame_received_notify();
bool send_ack = false; 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 (m_flags.frame_filtered && if (m_flags.frame_filtered &&
parse_result && parse_result &&
@ -2074,7 +2105,7 @@ void nrf_802154_trx_receive_frame_received(void)
mp_current_rx_buffer->free = false; mp_current_rx_buffer->free = false;
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
received_frame_notify_and_nesting_allow(p_received_data); received_frame_notify_and_nesting_allow(p_received_data);
} }
@ -2090,7 +2121,7 @@ void nrf_802154_trx_receive_frame_received(void)
mp_current_rx_buffer->free = false; mp_current_rx_buffer->free = false;
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
received_frame_notify_and_nesting_allow(p_received_data); received_frame_notify_and_nesting_allow(p_received_data);
} }
@ -2108,14 +2139,14 @@ void nrf_802154_trx_receive_frame_received(void)
// Find new buffer // Find new buffer
rx_buffer_in_use_set(nrf_802154_rx_buffer_free_find()); rx_buffer_in_use_set(nrf_802154_rx_buffer_free_find());
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
received_frame_notify_and_nesting_allow(p_received_data); received_frame_notify_and_nesting_allow(p_received_data);
} }
else else
{ {
// Receive to the same buffer // Receive to the same buffer
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
} }
} }
} }
@ -2125,16 +2156,9 @@ void nrf_802154_trx_receive_frame_received(void)
// or problem due to software latency (i.e. handled BCMATCH, CRCERROR, CRCOK from two // or problem due to software latency (i.e. handled BCMATCH, CRCERROR, CRCOK from two
// consecutively received frames). // consecutively received frames).
request_preconditions_for_state(m_state); request_preconditions_for_state(m_state);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
#if NRF_802154_DISABLE_BCC_MATCHING receive_failed_notify(filter_result);
if ((p_received_data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) != FRAME_TYPE_ACK)
{
receive_failed_notify(filter_result);
}
#else // NRF_802154_DISABLE_BCC_MATCHING
receive_failed_notify(NRF_802154_RX_ERROR_RUNTIME);
#endif // NRF_802154_DISABLE_BCC_MATCHING
} }
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
@ -2181,7 +2205,7 @@ void nrf_802154_trx_transmit_ack_transmitted(void)
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
received_frame_notify_and_nesting_allow(p_received_data); received_frame_notify_and_nesting_allow(p_received_data);
@ -2273,7 +2297,7 @@ void nrf_802154_trx_transmit_frame_transmitted(void)
{ {
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
transmitted_frame_notify(NULL, 0, 0); transmitted_frame_notify(NULL, 0, 0);
} }
@ -2389,7 +2413,7 @@ static void on_bad_ack(void)
// We received either a frame with incorrect CRC or not an ACK frame or not matching ACK // We received either a frame with incorrect CRC or not an ACK frame or not matching ACK
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
nrf_802154_transmit_done_metadata_t metadata = {}; nrf_802154_transmit_done_metadata_t metadata = {};
@ -2428,7 +2452,7 @@ void nrf_802154_trx_receive_ack_received(void)
mp_current_rx_buffer->free = false; mp_current_rx_buffer->free = false;
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
transmitted_frame_notify(p_ack_buffer->data, // phr + psdu transmitted_frame_notify(p_ack_buffer->data, // phr + psdu
rssi_last_measurement_get(), // rssi rssi_last_measurement_get(), // rssi
@ -2447,7 +2471,7 @@ void nrf_802154_trx_standalone_cca_finished(bool channel_was_idle)
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
cca_notify(channel_was_idle); cca_notify(channel_was_idle);
@ -2500,7 +2524,7 @@ void nrf_802154_trx_transmit_frame_ccabusy(void)
#endif #endif
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
nrf_802154_transmit_done_metadata_t metadata = {}; nrf_802154_transmit_done_metadata_t metadata = {};
@ -2543,7 +2567,7 @@ void nrf_802154_trx_energy_detection_finished(uint8_t ed_sample)
nrf_802154_trx_channel_set(nrf_802154_pib_channel_get()); nrf_802154_trx_channel_set(nrf_802154_pib_channel_get());
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
energy_detected_notify(nrf_802154_rssi_ed_sample_convert(m_ed_result)); energy_detected_notify(nrf_802154_rssi_ed_sample_convert(m_ed_result));
@ -2579,8 +2603,8 @@ void nrf_802154_core_deinit(void)
mpsl_fem_cleanup(); mpsl_fem_cleanup();
nrf_802154_irq_disable(RADIO_IRQn); nrf_802154_irq_disable(nrfx_get_irq_number(NRF_RADIO));
nrf_802154_irq_clear_pending(RADIO_IRQn); nrf_802154_irq_clear_pending(nrfx_get_irq_number(NRF_RADIO));
nrf_802154_sl_timer_deinit(&m_rx_prestarted_timer); nrf_802154_sl_timer_deinit(&m_rx_prestarted_timer);
@ -2650,9 +2674,22 @@ bool nrf_802154_core_receive(nrf_802154_term_t term_lvl,
{ {
m_trx_receive_frame_notifications_mask = m_trx_receive_frame_notifications_mask =
make_trx_frame_receive_notification_mask(); make_trx_frame_receive_notification_mask();
m_rx_window_id = id; m_rx_window_id = id;
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init();
bool abort_shall_follow = false;
rx_init(ramp_up_mode_choose(req_orig), &abort_shall_follow);
if (abort_shall_follow)
{
nrf_802154_trx_abort();
// HW triggering failed, fallback is SW trigger.
// (fallback immunizes against the rare case of spurious lptimer firing)
rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
}
} }
} }
else else
@ -2716,13 +2753,14 @@ bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl,
m_tx_power = p_params->tx_power; m_tx_power = p_params->tx_power;
// coverity[check_return] // coverity[check_return]
result = tx_init(p_data, p_params->cca); result = tx_init(p_data, ramp_up_mode_choose(req_orig), p_params->cca);
if (p_params->immediate) if (p_params->immediate)
{ {
if (!result) if (!result)
{ {
state_set(RADIO_STATE_RX); state_set(RADIO_STATE_RX);
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
} }
} }
else else
@ -2908,7 +2946,7 @@ bool nrf_802154_core_channel_update(req_originator_t req_orig)
case RADIO_STATE_RX: case RADIO_STATE_RX:
if (current_operation_terminate(NRF_802154_TERM_802154, req_orig, true)) if (current_operation_terminate(NRF_802154_TERM_802154, req_orig, true))
{ {
rx_init(); rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
} }
break; break;

View File

@ -74,7 +74,7 @@ static void radio_critical_section_enter(void)
{ {
if (nrf_802154_rsch_prec_is_approved(RSCH_PREC_RAAL, RSCH_PRIO_MIN_APPROVED)) if (nrf_802154_rsch_prec_is_approved(RSCH_PREC_RAAL, RSCH_PRIO_MIN_APPROVED))
{ {
nrf_802154_irq_disable(RADIO_IRQn); nrf_802154_irq_disable(nrfx_get_irq_number(NRF_RADIO));
} }
} }
@ -87,7 +87,7 @@ static void radio_critical_section_exit(void)
{ {
if (nrf_802154_rsch_prec_is_approved(RSCH_PREC_RAAL, RSCH_PRIO_MIN_APPROVED)) if (nrf_802154_rsch_prec_is_approved(RSCH_PREC_RAAL, RSCH_PRIO_MIN_APPROVED))
{ {
nrf_802154_irq_enable(RADIO_IRQn); nrf_802154_irq_enable(nrfx_get_irq_number(NRF_RADIO));
} }
} }
@ -264,10 +264,11 @@ uint32_t nrf_802154_critical_section_active_vector_priority_get(void)
return UINT32_MAX; return UINT32_MAX;
} }
assert(active_vector_id >= CMSIS_IRQ_NUM_VECTACTIVE_DIFF); irq_number = (IRQn_Type)((int32_t)active_vector_id - CMSIS_IRQ_NUM_VECTACTIVE_DIFF);
irq_number = (IRQn_Type)(active_vector_id - CMSIS_IRQ_NUM_VECTACTIVE_DIFF); assert(irq_number >= SVCall_IRQn);
active_priority = nrf_802154_irq_priority_get(irq_number);
active_priority = NVIC_GetPriority(irq_number);
return active_priority; return active_priority;
} }

View File

@ -301,7 +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; nrf_802154_aes_ccm_data_t aes_ccm_data;
bool success = false; bool success = false;
if (!nrf_802154_frame_parser_security_enabled_bit_is_set(p_ack_data)) if (!nrf_802154_frame_parser_security_enabled_bit_is_set(p_ack_data) ||
(nrf_802154_frame_parser_sec_ctrl_sec_lvl_get(p_ack_data) == SECURITY_LEVEL_NONE))
{ {
success = true; success = true;
} }
@ -347,7 +348,8 @@ bool nrf_802154_encrypt_tx_setup(
assert(success); assert(success);
(void)success; (void)success;
if (!nrf_802154_frame_parser_security_enabled_bit_is_set(&frame_data)) if (!nrf_802154_frame_parser_security_enabled_bit_is_set(&frame_data) ||
(nrf_802154_frame_parser_sec_ctrl_sec_lvl_get(&frame_data) == SECURITY_LEVEL_NONE))
{ {
success = true; success = true;
} }

View File

@ -38,20 +38,18 @@
#include "nrfx.h" #include "nrfx.h"
#include "nrf_802154_const.h" #include "nrf_802154_const.h"
/* The usage of ED_RSSISCALE is described inprecisely in the nRF product specifications. The meaning of /* The usage of ED_RSSISCALE is described imprecisely in the nRF product specifications. The meaning of
this constant is the following: If we calculate ed_scaled = EDSAMPLE * ED_RSSISCALE, then this constant is the following: If we calculate ed_scaled = EDSAMPLE * ED_RSSISCALE, then
it is guaranteed that in the range 0-255 ed_scaled maps linearly to the ED power in dBm. This means, it is guaranteed that in the range 0-255 ed_scaled maps linearly to the ED power in dBm. This means,
that the maximum value in EDSAMPLE which can be reported in compliance with the 802.15.4 specification is that the maximum value in EDSAMPLE which can be reported in compliance with the 802.15.4 specification is
255/ED_RSSISCALE. */ 255/ED_RSSISCALE. */
#if defined (NRF52840_XXAA) #if defined (NRF52833_XXAA) || defined(NRF5340_XXAA)
#define ED_RSSIOFFS (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register. #define ED_RSSIOFFS (-93) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral. #define ED_RSSISCALE 5 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#elif defined (NRF52833_XXAA) || defined(NRF5340_XXAA)
#define ED_RSSIOFFS (-93) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 5 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#else #else
#error "Selected chip is not supported." #define ED_RSSIOFFS (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#endif #endif
#define EDSAMPLE_MIN_REPORTED_VALUE (PHY_MIN_RECEIVER_SENSITIVITY - ED_RSSIOFFS + 10) ///< Minimal reported EDSAMPLE value (reported as 0) #define EDSAMPLE_MIN_REPORTED_VALUE (PHY_MIN_RECEIVER_SENSITIVITY - ED_RSSIOFFS + 10) ///< Minimal reported EDSAMPLE value (reported as 0)

View File

@ -49,8 +49,10 @@
#include "nrf_802154_peripherals_nrf52.h" #include "nrf_802154_peripherals_nrf52.h"
#elif defined(NRF5340_XXAA) #elif defined(NRF5340_XXAA)
#include "nrf_802154_peripherals_nrf53.h" #include "nrf_802154_peripherals_nrf53.h"
#else #endif
#error Unsupported chip family
#ifdef NRF_802154_USE_INTERNAL_INCLUDES
#include "nrf_802154_peripherals_internal.h"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -95,27 +97,6 @@ extern "C" {
#define NRF_802154_TIMER_INSTANCE \ #define NRF_802154_TIMER_INSTANCE \
NRFX_CONCAT_2(NRF_TIMER, NRF_802154_TIMER_INSTANCE_NO) NRFX_CONCAT_2(NRF_TIMER, NRF_802154_TIMER_INSTANCE_NO)
/**
* @def NRF_802154_COUNTER_TIMER_INSTANCE_NO
*
* Number of the timer instance used for detecting when PSDU is being received.
*
*/
#ifndef NRF_802154_COUNTER_TIMER_INSTANCE_NO
#define NRF_802154_COUNTER_TIMER_INSTANCE_NO 2
#endif
/**
* @def NRF_802154_COUNTER_TIMER_INSTANCE
*
* The timer instance used by the driver for detecting when PSDU is being received.
*
* @note This configuration is used only when the NRF_RADIO_EVENT_BCMATCH event handling is disabled
* (see @ref NRF_802154_DISABLE_BCC_MATCHING).
*/
#define NRF_802154_COUNTER_TIMER_INSTANCE \
NRFX_CONCAT_2(NRF_TIMER, NRF_802154_COUNTER_TIMER_INSTANCE_NO)
/** /**
* @def NRF_802154_RTC_INSTANCE * @def NRF_802154_RTC_INSTANCE
* *
@ -156,8 +137,7 @@ extern "C" {
*/ */
#ifndef NRF_802154_TIMERS_USED_MASK #ifndef NRF_802154_TIMERS_USED_MASK
#define NRF_802154_TIMERS_USED_MASK ((1 << NRF_802154_HIGH_PRECISION_TIMER_INSTANCE_NO) | \ #define NRF_802154_TIMERS_USED_MASK ((1 << NRF_802154_HIGH_PRECISION_TIMER_INSTANCE_NO) | \
(1 << NRF_802154_TIMER_INSTANCE_NO) | \ (1 << NRF_802154_TIMER_INSTANCE_NO))
(1 << NRF_802154_COUNTER_TIMER_INSTANCE_NO))
#endif // NRF_802154_TIMERS_USED_MASK #endif // NRF_802154_TIMERS_USED_MASK
/** /**

View File

@ -51,10 +51,10 @@
#include "mpsl.h" #include "mpsl.h"
#endif #endif
#if defined(NRF52_SERIES) #if defined(PPI_PRESENT)
#define NRF_802154_PPI_CH_USED_MSK NRF_802154_PPI_CHANNELS_USED_MASK #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 #define NRF_802154_PPI_GR_USED_MSK NRF_802154_PPI_GROUPS_USED_MASK
#elif defined(NRF53_SERIES) #elif defined(DPPI_PRESENT)
#define NRF_802154_PPI_CH_USED_MSK NRF_802154_DPPI_CHANNELS_USED_MASK #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 #define NRF_802154_PPI_GR_USED_MSK NRF_802154_DPPI_GROUPS_USED_MASK
#else #else

View File

@ -111,12 +111,30 @@ extern "C" {
#endif // NRF_802154_RTC_INSTANCE_NO #endif // NRF_802154_RTC_INSTANCE_NO
/**
* @def NRF_802154_PPI_RADIO_RAMP_UP_TRIGG
*
* The PPI channel that connects ramp up triggering event to EGU task.
*
* @note The peripheral is shared with @ref NRF_802154_PPI_RADIO_DISABLED_TO_EGU in such a way
* that a receive or transmit request causes that ppi to be configured for ramp up
* triggering purpose, while in the EVENT_READY isr the ppi is reconfigured to follow the
* @ref NRF_802154_PPI_RADIO_DISABLED_TO_EGU description.
*
* @note This option is used regardless of the driver configuration.
*
*/
#ifndef NRF_802154_PPI_RADIO_RAMP_UP_TRIGG
#define NRF_802154_PPI_RADIO_RAMP_UP_TRIGG NRF_PPI_CHANNEL6
#endif
/** /**
* @def NRF_802154_PPI_RADIO_DISABLED_TO_EGU * @def NRF_802154_PPI_RADIO_DISABLED_TO_EGU
* *
* The PPI channel that connects RADIO_DISABLED event to EGU task. * The PPI channel that connects RADIO_DISABLED event to EGU task.
* *
* @note This option is used by the core module regardless of the driver configuration. * @note This option is used by the core module regardless of the driver configuration.
* The peripheral is shared with @ref NRF_802154_PPI_RADIO_RAMP_UP_TRIGG.
* *
*/ */
#ifndef NRF_802154_PPI_RADIO_DISABLED_TO_EGU #ifndef NRF_802154_PPI_RADIO_DISABLED_TO_EGU
@ -201,55 +219,12 @@ extern "C" {
#define NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE NRF_PPI_CHANNEL10 #define NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE NRF_PPI_CHANNEL10
#endif #endif
#if NRF_802154_DISABLE_BCC_MATCHING
/**
* @def NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT
*
* The PPI channel that connects RADIO_ADDRESS event to TIMER_COUNT task.
*
* @note This configuration is used only when the NRF_RADIO_EVENT_BCMATCH event handling is disabled
* (see @ref NRF_802154_DISABLE_BCC_MATCHING).
*
*/
#ifndef NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT
#define NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT NRF_PPI_CHANNEL11
#endif
/**
* @def NRF_802154_PPI_RADIO_CRCERROR_TO_COUNTER_CLEAR
*
* The PPI channel that connects RADIO_CRCERROR event to TIMER_CLEAR task.
*
* @note This option is used only when the NRF_RADIO_EVENT_BCMATCH event handling is disabled
* (see @ref NRF_802154_DISABLE_BCC_MATCHING).
*
*/
#ifndef NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR
#define NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR NRF_PPI_CHANNEL12
#endif
/**
* @def NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK
*
* Helper bit mask of PPI channels used additionally by the 802.15.4 driver when the BCC matching
* is disabled.
*/
#define NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK \
((1 << NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT) | \
(1 << NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR))
#else // NRF_802154_DISABLE_BCC_MATCHING
/** /**
* @def NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC * @def NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC
* *
* The PPI channel that connects RADIO_SYNC event to EGU_SYNC task. * The PPI channel that connects RADIO_SYNC event to EGU_SYNC task.
* EGU_SYNC task belongs to one of EGU channels * EGU_SYNC task belongs to one of EGU channels
* *
* @note This configuration is used only when the NRF_RADIO_EVENT_BCMATCH event handling is enabled
* (see @ref NRF_802154_DISABLE_BCC_MATCHING).
*
*/ */
#ifndef NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC #ifndef NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC
#define NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC NRF_PPI_CHANNEL11 #define NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC NRF_PPI_CHANNEL11
@ -258,8 +233,6 @@ extern "C" {
#define NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK \ #define NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK \
(1 << NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC) (1 << NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC)
#endif // NRF_802154_DISABLE_BCC_MATCHING
#ifdef NRF_802154_FRAME_TIMESTAMP_ENABLED #ifdef NRF_802154_FRAME_TIMESTAMP_ENABLED
/** /**
@ -341,6 +314,7 @@ extern "C" {
*/ */
#ifndef NRF_802154_PPI_CHANNELS_USED_MASK #ifndef NRF_802154_PPI_CHANNELS_USED_MASK
#define NRF_802154_PPI_CHANNELS_USED_MASK ((1 << NRF_802154_PPI_RADIO_DISABLED_TO_EGU) | \ #define NRF_802154_PPI_CHANNELS_USED_MASK ((1 << NRF_802154_PPI_RADIO_DISABLED_TO_EGU) | \
(1 << NRF_802154_PPI_RADIO_RAMP_UP_TRIGG) | \
(1 << NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP) | \ (1 << NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP) | \
(1 << NRF_802154_PPI_EGU_TO_TIMER_START) | \ (1 << NRF_802154_PPI_EGU_TO_TIMER_START) | \
(1 << NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR) | \ (1 << NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR) | \

View File

@ -93,6 +93,20 @@ extern "C" {
#define NRF_802154_EGU_IRQN \ #define NRF_802154_EGU_IRQN \
NRFX_CONCAT_3(EGU, NRF_802154_EGU_INSTANCE_NO, _IRQn) NRFX_CONCAT_3(EGU, NRF_802154_EGU_INSTANCE_NO, _IRQn)
/**
* @def NRF_802154_EGU_RAMP_UP_EVENT
*
* The EGU event used by the driver to trigger radio ramp-up.
*/
#define NRF_802154_EGU_RAMP_UP_EVENT NRF_EGU_EVENT_TRIGGERED15
/**
* @def NRF_802154_EGU_RAMP_UP_TASK
*
* The EGU task used by the driver to trigger radio ramp-up.
*/
#define NRF_802154_EGU_RAMP_UP_TASK NRF_EGU_TASK_TRIGGER15
/** /**
* @def NRF_802154_EGU_USED_MASK * @def NRF_802154_EGU_USED_MASK
* *
@ -112,6 +126,14 @@ extern "C" {
#define NRF_802154_RTC_INSTANCE_NO 2 #define NRF_802154_RTC_INSTANCE_NO 2
#endif #endif
/**
* @def NRF_802154_DPPIC_INSTANCE
*
* The DPPIC instance used by the driver to connect peripherals to radio.
*
*/
#define NRF_802154_DPPIC_INSTANCE NRF_DPPIC
/** /**
* @def NRF_802154_DPPI_RADIO_DISABLED * @def NRF_802154_DPPI_RADIO_DISABLED
* *
@ -239,6 +261,15 @@ extern "C" {
#define NRF_802154_DPPI_RADIO_TEST_MODE_USED_MASK 0U #define NRF_802154_DPPI_RADIO_TEST_MODE_USED_MASK 0U
#endif // NRF_802154_TEST_MODES_ENABLED #endif // NRF_802154_TEST_MODES_ENABLED
/**
* @def NRF_802154_DPPI_RADIO_CCABUSY
*
* The DPPI channel that triggers radio
*/
#ifndef NRF_802154_DPPI_RADIO_HW_TRIGGER
#define NRF_802154_DPPI_RADIO_HW_TRIGGER 15U
#endif
/** /**
* @def NRF_802154_DPPI_TIMESTAMPS_USED_MASK * @def NRF_802154_DPPI_TIMESTAMPS_USED_MASK
* *
@ -268,6 +299,7 @@ extern "C" {
(1UL << NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN) | \ (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) | \ (1UL << NRF_802154_DPPI_RADIO_CCAIDLE) | \
(1UL << NRF_802154_DPPI_RADIO_HW_TRIGGER) | \
NRF_802154_DPPI_RADIO_TEST_MODE_USED_MASK | \ NRF_802154_DPPI_RADIO_TEST_MODE_USED_MASK | \
NRF_802154_DPPI_TIMESTAMPS_USED_MASK) NRF_802154_DPPI_TIMESTAMPS_USED_MASK)
#endif // NRF_802154_DPPI_CHANNELS_USED_MASK #endif // NRF_802154_DPPI_CHANNELS_USED_MASK

View File

@ -160,13 +160,11 @@ static bool coex_rx_request_mode_is_supported(nrf_802154_coex_rx_request_mode_t
switch (mode) switch (mode)
{ {
#if !NRF_802154_DISABLE_BCC_MATCHING && defined(RADIO_INTENSET_SYNC_Msk) #if defined(RADIO_INTENSET_SYNC_Msk)
case NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION: case NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION:
#endif #endif
case NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE: case NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE:
#if !NRF_802154_DISABLE_BCC_MATCHING
case NRF_802154_COEX_RX_REQUEST_MODE_DESTINED: case NRF_802154_COEX_RX_REQUEST_MODE_DESTINED:
#endif
result = true; result = true;
break; break;
@ -194,11 +192,7 @@ void nrf_802154_pib_init(void)
m_data.cca.corr_threshold = NRF_802154_CCA_CORR_THRESHOLD_DEFAULT; m_data.cca.corr_threshold = NRF_802154_CCA_CORR_THRESHOLD_DEFAULT;
m_data.cca.corr_limit = NRF_802154_CCA_CORR_LIMIT_DEFAULT; m_data.cca.corr_limit = NRF_802154_CCA_CORR_LIMIT_DEFAULT;
#if NRF_802154_DISABLE_BCC_MATCHING
m_data.coex.rx_request_mode = NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE;
#else
m_data.coex.rx_request_mode = NRF_802154_COEX_RX_REQUEST_MODE_DESTINED; m_data.coex.rx_request_mode = NRF_802154_COEX_RX_REQUEST_MODE_DESTINED;
#endif
m_data.coex.tx_request_mode = NRF_802154_COEX_TX_REQUEST_MODE_ON_CCA_TOGGLE; m_data.coex.tx_request_mode = NRF_802154_COEX_TX_REQUEST_MODE_ON_CCA_TOGGLE;
#if NRF_802154_CSMA_CA_ENABLED #if NRF_802154_CSMA_CA_ENABLED

View File

@ -138,6 +138,15 @@ __STATIC_INLINE uint16_t nrf_802154_cca_before_tx_duration_get(void)
return us_time; return us_time;
} }
/**@brief Get the duration of the Ack frame along with turnaround in microseconds. */
__STATIC_INLINE uint16_t nrf_802154_ack_duration_with_turnaround_get(void)
{
// aTurnaroundTime + ACK frame duration
return PHY_US_TIME_FROM_SYMBOLS(A_TURNAROUND_TIME_SYMBOLS +
PHY_SHR_SYMBOLS +
PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE));
}
__STATIC_INLINE uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ack_requested) __STATIC_INLINE uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ack_requested)
{ {
// SHR + PHR + PSDU // SHR + PHR + PSDU
@ -146,9 +155,7 @@ __STATIC_INLINE uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ac
if (ack_requested) if (ack_requested)
{ {
us_time += PHY_US_TIME_FROM_SYMBOLS(A_TURNAROUND_TIME_SYMBOLS + us_time += nrf_802154_ack_duration_with_turnaround_get();
PHY_SHR_SYMBOLS +
PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE));
} }
return us_time; return us_time;

View File

@ -99,7 +99,7 @@ int8_t nrf_802154_rssi_sample_temp_corr_value_get(uint8_t rssi_sample)
return result; return result;
} }
#elif defined(NRF5340_XXAA) #else
/** Macro for calculating x raised to the power of 2. */ /** Macro for calculating x raised to the power of 2. */
#define POW_2(x) ((x) * (x)) #define POW_2(x) ((x) * (x))
@ -154,8 +154,6 @@ int8_t nrf_802154_rssi_sample_temp_corr_value_get(uint8_t rssi_sample)
return compensated_rssi - (int8_t)rssi_sample; return compensated_rssi - (int8_t)rssi_sample;
} }
#else
#error Unsupported chip family
#endif #endif
uint8_t nrf_802154_rssi_sample_corrected_get(uint8_t rssi_sample) uint8_t nrf_802154_rssi_sample_corrected_get(uint8_t rssi_sample)

View File

@ -63,26 +63,26 @@
#include "nrf_802154_sl_ant_div.h" #include "nrf_802154_sl_ant_div.h"
#define EGU_SYNC_EVENT NRF_EGU_EVENT_TRIGGERED3 #ifdef NRF_802154_USE_INTERNAL_INCLUDES
#define EGU_SYNC_TASK NRF_EGU_TASK_TRIGGER3 #include "nrf_802154_trx_internal.h"
#define EGU_SYNC_INTMASK NRF_EGU_INT_TRIGGERED3 #endif
#define EGU_SYNC_EVENT NRF_EGU_EVENT_TRIGGERED3
#define EGU_SYNC_TASK NRF_EGU_TASK_TRIGGER3
#define EGU_SYNC_INTMASK NRF_EGU_INT_TRIGGERED3
#if defined(NRF52840_XXAA) || \ #if defined(NRF52840_XXAA) || \
defined(NRF52833_XXAA) defined(NRF52833_XXAA)
#define PPI_CCAIDLE_FEM NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE ///< PPI that connects RADIO CCAIDLE event with GPIOTE tasks used by FEM #define PPI_CCAIDLE_FEM NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE ///< PPI that connects RADIO CCAIDLE event with GPIOTE tasks used by FEM
#define PPI_CHGRP_ABORT NRF_802154_PPI_ABORT_GROUP ///< PPI group used to disable PPIs when async event aborting radio operation is propagated through the system #define PPI_CHGRP_ABORT NRF_802154_PPI_ABORT_GROUP ///< PPI group used to disable PPIs when async event aborting radio operation is propagated through the system
#define RADIO_BASE NRF_RADIO_BASE #define RADIO_BASE NRF_RADIO_BASE
#elif defined(NRF5340_XXAA) #elif defined(NRF5340_XXAA)
#define PPI_CCAIDLE_FEM 0 #define PPI_CCAIDLE_FEM 0
#define RADIO_BASE NRF_RADIO_NS_BASE #define RADIO_BASE NRF_RADIO_NS_BASE
#define FICR_BASE NRF_FICR_NS_BASE #define FICR_BASE NRF_FICR_NS_BASE
#endif #endif
#if NRF_802154_DISABLE_BCC_MATCHING
#define SHORT_ADDRESS_BCSTART 0UL
#else // NRF_802154_DISABLE_BCC_MATCHING
#define SHORT_ADDRESS_BCSTART NRF_RADIO_SHORT_ADDRESS_BCSTART_MASK #define SHORT_ADDRESS_BCSTART NRF_RADIO_SHORT_ADDRESS_BCSTART_MASK
#endif // NRF_802154_DISABLE_BCC_MATCHING
/// Value set to SHORTS register when no shorts should be enabled. /// Value set to SHORTS register when no shorts should be enabled.
#define SHORTS_IDLE 0 #define SHORTS_IDLE 0
@ -130,6 +130,26 @@
void nrf_802154_radio_irq_handler(void); ///< Prototype required by internal RADIO IRQ handler void nrf_802154_radio_irq_handler(void); ///< Prototype required by internal RADIO IRQ handler
#endif // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING #endif // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING
#ifndef NRF_802154_TRX_ENABLE_INTERNAL
#define NRF_802154_TRX_ENABLE_INTERNAL() \
do \
{ \
} \
while (0)
#endif
#ifndef NRF_802154_TRX_RADIO_RESET_INTERNAL
#define NRF_802154_TRX_RADIO_RESET_INTERNAL() \
do \
{ \
} \
while (0)
#endif
#ifndef NRF_802154_TRX_TEST_MODE_ALLOW_LATE_TX_ACK
#define NRF_802154_TRX_TEST_MODE_ALLOW_LATE_TX_ACK 0
#endif
/// Common parameters for the FEM handling. /// Common parameters for the FEM handling.
static const mpsl_fem_event_t m_activate_rx_cc0 = static const mpsl_fem_event_t m_activate_rx_cc0 =
{ {
@ -176,20 +196,12 @@ static volatile trx_state_t m_trx_state;
typedef struct typedef struct
{ {
#if !NRF_802154_DISABLE_BCC_MATCHING bool psdu_being_received; ///< If PSDU is currently being received.
bool psdu_being_received; ///< If PSDU is currently being received. bool missing_receive_buffer; ///!< If trx entered receive state without receive buffer
bool rxstarted_notif_en;
#endif bool ccastarted_notif_en;
bool tx_started; ///< If the requested transmission has started.
bool missing_receive_buffer; ///!< If trx entered receive state without receive buffer
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED
bool tx_started; ///< If the requested transmission has started.
#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED
bool rssi_started; bool rssi_started;
volatile bool rssi_settled; volatile bool rssi_settled;
} nrf_802154_flags_t; } nrf_802154_flags_t;
@ -199,6 +211,8 @@ static nrf_802154_flags_t m_flags; ///< Flags used to store the current driver s
static volatile uint32_t m_timer_value_on_radio_end_event; static volatile uint32_t m_timer_value_on_radio_end_event;
static volatile bool m_transmit_with_cca; static volatile bool m_transmit_with_cca;
static void timer_frequency_set_1mhz(void);
static void rxframe_finish_disable_ppis(void); static void rxframe_finish_disable_ppis(void);
static void rxack_finish_disable_ppis(void); static void rxack_finish_disable_ppis(void);
static void txframe_finish_disable_ppis(bool cca); static void txframe_finish_disable_ppis(bool cca);
@ -221,9 +235,7 @@ static void energy_detection_abort(void);
void rx_flags_clear(void) void rx_flags_clear(void)
{ {
m_flags.missing_receive_buffer = false; m_flags.missing_receive_buffer = false;
#if !NRF_802154_DISABLE_BCC_MATCHING m_flags.psdu_being_received = false;
m_flags.psdu_being_received = false;
#endif // !NRF_802154_DISABLE_BCC_MATCHING
} }
static void * volatile mp_receive_buffer; static void * volatile mp_receive_buffer;
@ -250,13 +262,7 @@ void nrf_timer_init(void)
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
nrf_timer_mode_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_MODE_TIMER); nrf_timer_mode_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_MODE_TIMER);
nrf_timer_bit_width_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_BIT_WIDTH_32); nrf_timer_bit_width_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_BIT_WIDTH_32);
nrf_timer_prescaler_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_FREQ_1MHz); timer_frequency_set_1mhz();
#if NRF_802154_DISABLE_BCC_MATCHING
// Setup timer for detecting PSDU reception.
nrf_timer_mode_set(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_MODE_COUNTER);
nrf_timer_bit_width_set(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_BIT_WIDTH_8);
#endif
} }
#if defined(NRF53_SERIES) #if defined(NRF53_SERIES)
@ -290,13 +296,26 @@ static void yopan_158_workaround(void)
#endif /* NRF53_SERIES */ #endif /* NRF53_SERIES */
/** Sets the frequency of 1 MHz for NRF_802154_TIMER_INSTANCE. */
static void timer_frequency_set_1mhz(void)
{
uint32_t base_frequency = NRF_TIMER_BASE_FREQUENCY_GET(NRF_802154_TIMER_INSTANCE);
uint32_t prescaler = 31 - NRF_CLZ(base_frequency / 1000000);
nrf_timer_prescaler_set(NRF_802154_TIMER_INSTANCE, prescaler);
}
/** Reset radio peripheral. */ /** Reset radio peripheral. */
static void nrf_radio_reset(void) static void nrf_radio_reset(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
#if defined(RADIO_POWER_POWER_Msk)
nrf_radio_power_set(NRF_RADIO, false); nrf_radio_power_set(NRF_RADIO, false);
nrf_radio_power_set(NRF_RADIO, true); nrf_radio_power_set(NRF_RADIO, true);
#endif
NRF_802154_TRX_RADIO_RESET_INTERNAL();
#if defined(NRF53_SERIES) #if defined(NRF53_SERIES)
yopan_158_workaround(); yopan_158_workaround();
@ -332,9 +351,11 @@ static void cca_configuration_update(void)
static void irq_init(void) static void irq_init(void)
{ {
#if NRF_802154_INTERNAL_RADIO_IRQ_HANDLING #if NRF_802154_INTERNAL_RADIO_IRQ_HANDLING
nrf_802154_irq_init(RADIO_IRQn, NRF_802154_IRQ_PRIORITY, nrf_802154_radio_irq_handler); nrf_802154_irq_init(nrfx_get_irq_number(NRF_RADIO),
NRF_802154_IRQ_PRIORITY,
nrf_802154_radio_irq_handler);
#endif #endif
nrf_802154_irq_enable(RADIO_IRQn); nrf_802154_irq_enable(nrfx_get_irq_number(NRF_RADIO));
} }
static void trigger_disable_to_start_rampup(void) static void trigger_disable_to_start_rampup(void)
@ -342,6 +363,7 @@ static void trigger_disable_to_start_rampup(void)
if (!nrf_802154_trx_ppi_for_ramp_up_was_triggered()) if (!nrf_802154_trx_ppi_for_ramp_up_was_triggered())
{ {
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
} }
} }
@ -513,6 +535,32 @@ static void errata_117_apply(void)
#endif #endif
static inline void wait_until_radio_is_disabled(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
bool radio_is_disabled = false;
// RADIO should enter DISABLED state after no longer than RX ramp-down time, which is equal
// approximately 0.5us. Taking a bold assumption that a single iteration of the loop takes
// one cycle to complete, 32 iterations would amount to exactly 0.5 us of execution time.
// Please note that this approach ignores software latency completely, i.e. RADIO should
// have changed state already before entering this function due to ISR processing delays.
for (uint32_t i = 0; i < MAX_RXRAMPDOWN_CYCLES; i++)
{
if (nrf_radio_state_get(NRF_RADIO) == NRF_RADIO_STATE_DISABLED)
{
radio_is_disabled = true;
break;
}
}
assert(radio_is_disabled);
(void)radio_is_disabled;
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
void nrf_802154_trx_module_reset(void) void nrf_802154_trx_module_reset(void)
{ {
m_trx_state = TRX_STATE_DISABLED; m_trx_state = TRX_STATE_DISABLED;
@ -570,7 +618,11 @@ void nrf_802154_trx_enable(void)
packet_conf.maxlen = MAX_PACKET_SIZE; packet_conf.maxlen = MAX_PACKET_SIZE;
nrf_radio_packet_configure(NRF_RADIO, &packet_conf); nrf_radio_packet_configure(NRF_RADIO, &packet_conf);
NRF_802154_TRX_ENABLE_INTERNAL();
#if defined(RADIO_MODECNF0_RU_Msk)
nrf_radio_modecnf0_set(NRF_RADIO, true, 0); nrf_radio_modecnf0_set(NRF_RADIO, true, 0);
#endif
// Configure CRC // Configure CRC
nrf_radio_crc_configure(NRF_RADIO, CRC_LENGTH, NRF_RADIO_CRC_ADDR_IEEE802154, CRC_POLYNOMIAL); nrf_radio_crc_configure(NRF_RADIO, CRC_LENGTH, NRF_RADIO_CRC_ADDR_IEEE802154, CRC_POLYNOMIAL);
@ -677,13 +729,21 @@ void nrf_802154_trx_disable(void)
if (m_trx_state != TRX_STATE_DISABLED) if (m_trx_state != TRX_STATE_DISABLED)
{ {
#if defined(RADIO_POWER_POWER_Msk)
nrf_radio_power_set(NRF_RADIO, false); nrf_radio_power_set(NRF_RADIO, false);
nrf_802154_irq_clear_pending(RADIO_IRQn); #endif
nrf_802154_irq_clear_pending(nrfx_get_irq_number(NRF_RADIO));
/* While the RADIO is powered off deconfigure any PPIs used directly by trx module */ /* While the RADIO is powered off deconfigure any PPIs used directly by trx module */
ppi_all_clear(); ppi_all_clear();
#if !NRF_802154_DISABLE_BCC_MATCHING && defined(RADIO_INTENSET_SYNC_Msk) #if !defined(RADIO_POWER_POWER_Msk)
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
wait_until_radio_is_disabled();
nrf_radio_reset();
#endif
#if defined(RADIO_INTENSET_SYNC_Msk)
nrf_egu_int_disable(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK); nrf_egu_int_disable(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK);
nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_SYNC_EVENT); nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_SYNC_EVENT);
#endif #endif
@ -694,7 +754,9 @@ void nrf_802154_trx_disable(void)
NRF_TIMER_SHORT_COMPARE1_STOP_MASK); NRF_TIMER_SHORT_COMPARE1_STOP_MASK);
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
#if defined(RADIO_POWER_POWER_Msk)
nrf_radio_power_set(NRF_RADIO, true); nrf_radio_power_set(NRF_RADIO, true);
#endif
mpsl_fem_lna_configuration_clear(); mpsl_fem_lna_configuration_clear();
mpsl_fem_pa_configuration_clear(); mpsl_fem_pa_configuration_clear();
@ -705,19 +767,10 @@ void nrf_802154_trx_disable(void)
fem_power_down_now(); fem_power_down_now();
} }
#if NRF_802154_DISABLE_BCC_MATCHING m_flags.psdu_being_received = false;
// Anomaly 78: use SHUTDOWN instead of STOP and CLEAR.
nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
nrf_timer_shorts_disable(NRF_802154_COUNTER_TIMER_INSTANCE,
NRF_TIMER_SHORT_COMPARE1_STOP_MASK);
#else
m_flags.psdu_being_received = false;
#endif
m_flags.missing_receive_buffer = false; m_flags.missing_receive_buffer = false;
m_flags.rssi_started = false; m_flags.rssi_started = false;
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED m_flags.tx_started = false;
m_flags.tx_started = false;
#endif
m_trx_state = TRX_STATE_DISABLED; m_trx_state = TRX_STATE_DISABLED;
@ -879,17 +932,7 @@ void nrf_802154_trx_cca_configuration_update(void)
*/ */
bool nrf_802154_trx_psdu_is_being_received(void) bool nrf_802154_trx_psdu_is_being_received(void)
{ {
#if NRF_802154_DISABLE_BCC_MATCHING
nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE,
nrf_timer_capture_task_get(NRF_TIMER_CC_CHANNEL0));
uint32_t counter = nrf_timer_cc_get(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0);
assert(counter <= 1);
return counter > 0;
#else // NRF_802154_DISABLE_BCC_MATCHING
return m_flags.psdu_being_received; return m_flags.psdu_being_received;
#endif // NRF_802154_DISABLE_BCC_MATCHING
} }
bool nrf_802154_trx_receive_is_buffer_missing(void) bool nrf_802154_trx_receive_is_buffer_missing(void)
@ -961,6 +1004,7 @@ bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer)
} }
void nrf_802154_trx_receive_frame(uint8_t bcc, void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_802154_trx_ramp_up_trigger_mode_t rampup_trigg_mode,
nrf_802154_trx_receive_notifications_t notifications_mask, nrf_802154_trx_receive_notifications_t notifications_mask,
const nrf_802154_fal_tx_power_split_t * p_ack_tx_power) const nrf_802154_fal_tx_power_split_t * p_ack_tx_power)
{ {
@ -976,6 +1020,9 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
// Clear filtering flag // Clear filtering flag
rx_flags_clear(); rx_flags_clear();
m_flags.rxstarted_notif_en = (notifications_mask & TRX_RECEIVE_NOTIFICATION_STARTED) != 0U;
// Clear the RSSI measurement flag. // Clear the RSSI measurement flag.
m_flags.rssi_started = false; m_flags.rssi_started = false;
@ -998,30 +1045,23 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_radio_shorts_set(NRF_RADIO, shorts); nrf_radio_shorts_set(NRF_RADIO, shorts);
// Set BCC // Set BCC
#if !NRF_802154_DISABLE_BCC_MATCHING
assert(bcc != 0U); assert(bcc != 0U);
nrf_radio_bcc_set(NRF_RADIO, bcc * 8U); nrf_radio_bcc_set(NRF_RADIO, bcc * 8U);
#else
assert(bcc == 0U);
(void)bcc;
#endif // !NRF_802154_DISABLE_BCC_MATCHING
// Enable IRQs // Enable IRQs
#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR);
ints_to_enable |= NRF_RADIO_INT_CRCERROR_MASK; ints_to_enable |= NRF_RADIO_INT_CRCERROR_MASK;
#endif // !NRF_802154_DISABLE_BCC_MATCHING ||NRF_802154_NOTIFY_CRCERROR
#if !NRF_802154_DISABLE_BCC_MATCHING
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH);
ints_to_enable |= NRF_RADIO_INT_BCMATCH_MASK; ints_to_enable |= NRF_RADIO_INT_BCMATCH_MASK;
#endif // !NRF_802154_DISABLE_BCC_MATCHING
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK);
ints_to_enable |= NRF_RADIO_INT_CRCOK_MASK; ints_to_enable |= NRF_RADIO_INT_CRCOK_MASK;
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS);
ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK;
if ((notifications_mask & TRX_RECEIVE_NOTIFICATION_STARTED) != 0U) if (rampup_trigg_mode == TRX_RAMP_UP_HW_TRIGGER)
{ {
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; ints_to_enable |= NRF_RADIO_INT_READY_MASK;
} }
bool allow_sync_swi = false; bool allow_sync_swi = false;
@ -1037,7 +1077,7 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
if (allow_sync_swi) if (allow_sync_swi)
{ {
#if (NRF_802154_DISABLE_BCC_MATCHING || !defined(RADIO_INTENSET_SYNC_Msk)) #if !defined(RADIO_INTENSET_SYNC_Msk)
assert(false); assert(false);
#else #else
// The RADIO can't generate interrupt on EVENT_SYNC. Path to generate interrupt: // The RADIO can't generate interrupt on EVENT_SYNC. Path to generate interrupt:
@ -1079,18 +1119,13 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE,
NRF_TIMER_SHORT_COMPARE0_STOP_MASK); NRF_TIMER_SHORT_COMPARE0_STOP_MASK);
#if NRF_802154_DISABLE_BCC_MATCHING
nrf_timer_shorts_enable(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK);
nrf_timer_cc_set(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL1, 1);
#endif // NRF_802154_DISABLE_BCC_MATCHING
// Set PPIs // Set PPIs
#if NRF_802154_DISABLE_BCC_MATCHING nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, rampup_trigg_mode, true);
#error Configuration unsupported anymore
#endif // NRF_802154_DISABLE_BCC_MATCHING
nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, true);
trigger_disable_to_start_rampup(); if (rampup_trigg_mode == TRX_RAMP_UP_SW_TRIGGER)
{
trigger_disable_to_start_rampup();
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
} }
@ -1128,7 +1163,7 @@ void nrf_802154_trx_receive_ack(void)
fem_for_lna_set(); fem_for_lna_set();
nrf_802154_trx_antenna_update(); nrf_802154_trx_antenna_update();
nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, false); nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, TRX_RAMP_UP_SW_TRIGGER, false);
trigger_disable_to_start_rampup(); trigger_disable_to_start_rampup();
@ -1159,7 +1194,9 @@ bool nrf_802154_trx_rssi_measure(void)
m_flags.rssi_settled = true; m_flags.rssi_settled = true;
} }
#if defined(RADIO_EVENTS_RSSIEND_EVENTS_RSSIEND_Msk)
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND);
#endif
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RSSISTART); nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RSSISTART);
m_flags.rssi_started = true; m_flags.rssi_started = true;
@ -1191,10 +1228,15 @@ uint8_t nrf_802154_trx_rssi_last_sample_get(void)
bool nrf_802154_trx_rssi_sample_is_available(void) bool nrf_802154_trx_rssi_sample_is_available(void)
{ {
#if defined(RADIO_EVENTS_RSSIEND_EVENTS_RSSIEND_Msk)
return nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND); return nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND);
#else
return true;
#endif
} }
void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer, void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer,
nrf_802154_trx_ramp_up_trigger_mode_t rampup_trigg_mode,
bool cca, bool cca,
const nrf_802154_fal_tx_power_split_t * p_tx_power, const nrf_802154_fal_tx_power_split_t * p_tx_power,
nrf_802154_trx_transmit_notifications_t notifications_mask) nrf_802154_trx_transmit_notifications_t notifications_mask)
@ -1209,6 +1251,8 @@ void nrf_802154_trx_transmit_frame(const void * p_tra
m_trx_state = TRX_STATE_TXFRAME; m_trx_state = TRX_STATE_TXFRAME;
m_transmit_with_cca = cca; m_transmit_with_cca = cca;
m_flags.ccastarted_notif_en = false;
txpower_set(p_tx_power->radio_tx_power); txpower_set(p_tx_power->radio_tx_power);
nrf_radio_packetptr_set(NRF_RADIO, p_transmit_buffer); nrf_radio_packetptr_set(NRF_RADIO, p_transmit_buffer);
@ -1227,6 +1271,12 @@ void nrf_802154_trx_transmit_frame(const void * p_tra
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND);
ints_to_enable |= NRF_RADIO_INT_PHYEND_MASK; ints_to_enable |= NRF_RADIO_INT_PHYEND_MASK;
if (rampup_trigg_mode == TRX_RAMP_UP_HW_TRIGGER)
{
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
ints_to_enable |= NRF_RADIO_INT_READY_MASK;
}
if (cca) if (cca)
{ {
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY);
@ -1242,23 +1292,27 @@ void nrf_802154_trx_transmit_frame(const void * p_tra
if ((notifications_mask & TRX_TRANSMIT_NOTIFICATION_CCASTARTED) != 0U) if ((notifications_mask & TRX_TRANSMIT_NOTIFICATION_CCASTARTED) != 0U)
{ {
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
ints_to_enable |= NRF_RADIO_INT_READY_MASK; ints_to_enable |= NRF_RADIO_INT_READY_MASK;
m_flags.ccastarted_notif_en = true;
} }
} }
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS);
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED
ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK;
m_flags.tx_started = false; m_flags.tx_started = false;
#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED
nrf_radio_int_enable(NRF_RADIO, ints_to_enable); nrf_radio_int_enable(NRF_RADIO, ints_to_enable);
fem_for_tx_set(cca, &p_tx_power->fem); fem_for_tx_set(cca, &p_tx_power->fem);
nrf_802154_trx_antenna_update(); nrf_802154_trx_antenna_update();
nrf_802154_trx_ppi_for_ramp_up_set(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, false); nrf_802154_trx_ppi_for_ramp_up_set(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN,
rampup_trigg_mode,
false);
trigger_disable_to_start_rampup(); if (rampup_trigg_mode == TRX_RAMP_UP_SW_TRIGGER)
{
trigger_disable_to_start_rampup();
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
} }
@ -1330,9 +1384,7 @@ bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_
nrf_802154_trx_antenna_update(); nrf_802154_trx_antenna_update();
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND);
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS); nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS);
#endif
// Set PPIs // Set PPIs
nrf_802154_trx_ppi_for_ack_tx_set(); nrf_802154_trx_ppi_for_ack_tx_set();
@ -1376,16 +1428,13 @@ bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_
if (result) if (result)
{ {
uint32_t ints_to_enable = NRF_RADIO_INT_PHYEND_MASK; uint32_t ints_to_enable = NRF_RADIO_INT_PHYEND_MASK | NRF_RADIO_INT_ADDRESS_MASK;
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED
ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK;
#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED
nrf_radio_int_enable(NRF_RADIO, ints_to_enable); nrf_radio_int_enable(NRF_RADIO, ints_to_enable);
} }
else else
{ {
#if !NRF_802154_TRX_TEST_MODE_ALLOW_LATE_TX_ACK
/* We were to late with setting up PPI_TIMER_ACK, ack transmission was not triggered and /* We were to late with setting up PPI_TIMER_ACK, ack transmission was not triggered and
* will not be triggered in future. * will not be triggered in future.
*/ */
@ -1400,6 +1449,15 @@ bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
/* No callbacks will be called */ /* No callbacks will be called */
#else // !NRF_802154_TRX_TEST_MODE_ALLOW_LATE_TX_ACK
uint32_t ints_to_enable = NRF_RADIO_INT_PHYEND_MASK | NRF_RADIO_INT_ADDRESS_MASK;
nrf_radio_int_enable(NRF_RADIO, ints_to_enable);
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN);
result = true;
#endif // !NRF_802154_TRX_TEST_MODE_ALLOW_LATE_TX_ACK
} }
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
@ -1407,32 +1465,6 @@ bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_
return result; return result;
} }
static inline void wait_until_radio_is_disabled(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
bool radio_is_disabled = false;
// RADIO should enter DISABLED state after no longer than RX ramp-down time, which is equal
// approximately 0.5us. Taking a bold assumption that a single iteration of the loop takes
// one cycle to complete, 32 iterations would amount to exactly 0.5 us of execution time.
// Please note that this approach ignores software latency completely, i.e. RADIO should
// have changed state already before entering this function due to ISR processing delays.
for (uint32_t i = 0; i < MAX_RXRAMPDOWN_CYCLES; i++)
{
if (nrf_radio_state_get(NRF_RADIO) == NRF_RADIO_STATE_DISABLED)
{
radio_is_disabled = true;
break;
}
}
assert(radio_is_disabled);
(void)radio_is_disabled;
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
static void rxframe_finish_disable_ppis(void) static void rxframe_finish_disable_ppis(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
@ -1462,17 +1494,15 @@ static void rxframe_finish_disable_ints(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
uint32_t ints_to_disable = NRF_RADIO_INT_CRCOK_MASK | NRF_RADIO_INT_ADDRESS_MASK; uint32_t ints_to_disable = NRF_RADIO_INT_READY_MASK |
NRF_RADIO_INT_ADDRESS_MASK |
NRF_RADIO_INT_CRCOK_MASK;
#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR
ints_to_disable |= NRF_RADIO_INT_CRCERROR_MASK; ints_to_disable |= NRF_RADIO_INT_CRCERROR_MASK;
#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR
#if !NRF_802154_DISABLE_BCC_MATCHING
ints_to_disable |= NRF_RADIO_INT_BCMATCH_MASK; ints_to_disable |= NRF_RADIO_INT_BCMATCH_MASK;
#endif // !NRF_802154_DISABLE_BCC_MATCHING
nrf_radio_int_disable(NRF_RADIO, ints_to_disable); nrf_radio_int_disable(NRF_RADIO, ints_to_disable);
#if !NRF_802154_DISABLE_BCC_MATCHING && defined(RADIO_INTENSET_SYNC_Msk) #if defined(RADIO_INTENSET_SYNC_Msk)
nrf_egu_int_disable(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK); nrf_egu_int_disable(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK);
#endif #endif
@ -1481,13 +1511,7 @@ static void rxframe_finish_disable_ints(void)
static void rxframe_finish_psdu_is_not_being_received(void) static void rxframe_finish_psdu_is_not_being_received(void)
{ {
#if NRF_802154_DISABLE_BCC_MATCHING
// Anomaly 78: use SHUTDOWN instead of STOP and CLEAR.
nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
nrf_timer_shorts_disable(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK);
#else
m_flags.psdu_being_received = false; m_flags.psdu_being_received = false;
#endif // NRF_802154_DISABLE_BCC_MATCHING
} }
static void rxframe_finish(void) static void rxframe_finish(void)
@ -1604,6 +1628,11 @@ trx_state_t nrf_802154_trx_state_get(void)
return m_trx_state; return m_trx_state;
} }
uint32_t nrf_802154_trx_ramp_up_ppi_channel_get(void)
{
return nrf_802154_trx_ppi_for_ramp_up_channel_id_get();
}
static void go_idle_from_state_finished(void) static void go_idle_from_state_finished(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
@ -1788,7 +1817,7 @@ void nrf_802154_trx_standalone_cca(void)
nrf_802154_trx_antenna_update(); nrf_802154_trx_antenna_update();
// Set PPIs // Set PPIs
nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, false); nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, TRX_RAMP_UP_SW_TRIGGER, false);
trigger_disable_to_start_rampup(); trigger_disable_to_start_rampup();
@ -1844,7 +1873,7 @@ void nrf_802154_trx_continuous_carrier(const nrf_802154_fal_tx_power_split_t * p
nrf_802154_trx_antenna_update(); nrf_802154_trx_antenna_update();
// Set PPIs // Set PPIs
nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_TXEN, false); nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_TXEN, TRX_RAMP_UP_SW_TRIGGER, false);
trigger_disable_to_start_rampup(); trigger_disable_to_start_rampup();
@ -1907,7 +1936,7 @@ void nrf_802154_trx_modulated_carrier(const void * p_
nrf_802154_trx_antenna_update(); nrf_802154_trx_antenna_update();
// Set PPIs // Set PPIs
nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_TXEN, false); nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_TXEN, TRX_RAMP_UP_SW_TRIGGER, false);
trigger_disable_to_start_rampup(); trigger_disable_to_start_rampup();
@ -1958,7 +1987,9 @@ void nrf_802154_trx_energy_detection(uint32_t ed_count)
ed_count--; ed_count--;
/* Check that vd_count will fit into defined bits of register */ /* Check that vd_count will fit into defined bits of register */
#if defined(RADIO_EDCNT_EDCNT_Msk)
assert( (ed_count & (~RADIO_EDCNT_EDCNT_Msk)) == 0U); assert( (ed_count & (~RADIO_EDCNT_EDCNT_Msk)) == 0U);
#endif
nrf_radio_ed_loop_count_set(NRF_RADIO, ed_count); nrf_radio_ed_loop_count_set(NRF_RADIO, ed_count);
@ -1976,7 +2007,7 @@ void nrf_802154_trx_energy_detection(uint32_t ed_count)
nrf_802154_trx_antenna_update(); nrf_802154_trx_antenna_update();
// Set PPIs // Set PPIs
nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, false); nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, TRX_RAMP_UP_SW_TRIGGER, false);
trigger_disable_to_start_rampup(); trigger_disable_to_start_rampup();
@ -2013,44 +2044,61 @@ static void irq_handler_ready(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
assert(m_trx_state == TRX_STATE_TXFRAME);
nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_READY_MASK); nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_READY_MASK);
nrf_802154_trx_transmit_frame_ccastarted(); nrf_802154_trx_ppi_for_ramp_up_reconfigure();
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
static void irq_handler_address(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
switch (m_trx_state) switch (m_trx_state)
{ {
case TRX_STATE_RXFRAME:
nrf_802154_trx_receive_frame_started();
break;
case TRX_STATE_RXACK:
m_flags.rssi_started = true;
nrf_802154_trx_receive_ack_started();
break;
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED
case TRX_STATE_TXFRAME: case TRX_STATE_TXFRAME:
nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_ADDRESS_MASK); if (m_flags.ccastarted_notif_en)
m_flags.tx_started = true; {
nrf_802154_trx_transmit_frame_started(); nrf_802154_trx_transmit_frame_ccastarted();
}
break; break;
#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED case TRX_STATE_RXFRAME:
case TRX_STATE_TXACK: break;
nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_ADDRESS_MASK);
nrf_802154_trx_transmit_ack_started(); default:
assert(false);
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
static void irq_handler_address(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
// NRF_RADIO_TASK_DISABLE may have been triggered by (D)PPI, therefore event reg
// cleanup is required. It's done here
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
switch (m_trx_state)
{
case TRX_STATE_RXFRAME:
if (m_flags.rxstarted_notif_en)
{
nrf_802154_trx_receive_frame_started();
}
break;
case TRX_STATE_RXACK:
m_flags.rssi_started = true;
nrf_802154_trx_receive_ack_started();
break;
case TRX_STATE_TXFRAME:
nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_ADDRESS_MASK);
m_flags.tx_started = true;
nrf_802154_trx_transmit_frame_started();
break;
case TRX_STATE_TXACK:
nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_ADDRESS_MASK);
nrf_802154_trx_transmit_ack_started();
break; break;
#endif
default: default:
assert(false); assert(false);
@ -2059,7 +2107,6 @@ static void irq_handler_address(void)
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
} }
#if !NRF_802154_DISABLE_BCC_MATCHING
static void irq_handler_bcmatch(void) static void irq_handler_bcmatch(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -2095,9 +2142,6 @@ static void irq_handler_bcmatch(void)
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
} }
#endif
#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR
static void irq_handler_crcerror(void) static void irq_handler_crcerror(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -2105,17 +2149,10 @@ static void irq_handler_crcerror(void)
switch (m_trx_state) switch (m_trx_state)
{ {
case TRX_STATE_RXFRAME: case TRX_STATE_RXFRAME:
#if NRF_802154_DISABLE_BCC_MATCHING
/* The hardware restarts receive at the moment.
* The TIMER is being shutdown and restarted by the hardware see
* PPI_CRCERROR_CLEAR in nrf_802154_trx_receive_frame
*/
#else
rxframe_finish(); rxframe_finish();
/* On crc error TIMER is not needed, no ACK may be sent */ /* On crc error TIMER is not needed, no ACK may be sent */
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
m_trx_state = TRX_STATE_FINISHED; m_trx_state = TRX_STATE_FINISHED;
#endif
nrf_802154_trx_receive_frame_crcerror(); nrf_802154_trx_receive_frame_crcerror();
break; break;
@ -2132,8 +2169,6 @@ static void irq_handler_crcerror(void)
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
} }
#endif
static void irq_handler_crcok(void) static void irq_handler_crcok(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -2207,9 +2242,8 @@ static void txframe_finish(void)
txframe_finish_disable_ints(); txframe_finish_disable_ints();
nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE);
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED
m_flags.tx_started = false; m_flags.tx_started = false;
#endif
m_flags.missing_receive_buffer = false; m_flags.missing_receive_buffer = false;
/* Current state of peripherals /* Current state of peripherals
@ -2233,9 +2267,8 @@ static void transmit_frame_abort(void)
fem_for_tx_reset(m_transmit_with_cca); fem_for_tx_reset(m_transmit_with_cca);
txframe_finish_disable_ints(); txframe_finish_disable_ints();
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED
m_flags.tx_started = false; m_flags.tx_started = false;
#endif
m_flags.missing_receive_buffer = false; m_flags.missing_receive_buffer = false;
nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_CCASTOP); nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_CCASTOP);
@ -2489,7 +2522,6 @@ void nrf_802154_radio_irq_handler(void)
irq_handler_address(); irq_handler_address();
} }
#if !NRF_802154_DISABLE_BCC_MATCHING
// Check MAC frame header. // Check MAC frame header.
if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_BCMATCH_MASK) && if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_BCMATCH_MASK) &&
nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH)) nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH))
@ -2499,9 +2531,6 @@ void nrf_802154_radio_irq_handler(void)
irq_handler_bcmatch(); irq_handler_bcmatch();
} }
#endif // !NRF_802154_DISABLE_BCC_MATCHING
#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR
if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_CRCERROR_MASK) && if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_CRCERROR_MASK) &&
nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR)) nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR))
{ {
@ -2509,7 +2538,6 @@ void nrf_802154_radio_irq_handler(void)
irq_handler_crcerror(); irq_handler_crcerror();
} }
#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR
if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_CRCOK_MASK) && if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_CRCOK_MASK) &&
nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCOK)) nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCOK))
@ -2597,7 +2625,7 @@ void nrf_802154_trx_swi_irq_handler(void)
// Following will make it pending, and processing of RADIO_IRQ will start // Following will make it pending, and processing of RADIO_IRQ will start
// when critical section is left. // when critical section is left.
nrf_802154_irq_set_pending(RADIO_IRQn); nrf_802154_irq_set_pending(nrfx_get_irq_number(NRF_RADIO));
} }
nrf_802154_mcu_critical_exit(mcu_crit_state); nrf_802154_mcu_critical_exit(mcu_crit_state);

View File

@ -86,6 +86,13 @@ typedef enum
TRX_STATE_FINISHED TRX_STATE_FINISHED
} trx_state_t; } trx_state_t;
/**@brief Radio ramp up procedure triggering modes. */
typedef enum
{
TRX_RAMP_UP_SW_TRIGGER, ///< Triggering by RADIO_DISABLED, which is a software generated event.
TRX_RAMP_UP_HW_TRIGGER ///< Triggering by some other event that needs to publish to a dedicated (D)PPI channel.
} nrf_802154_trx_ramp_up_trigger_mode_t;
/**@brief Notifications that can be enabled for @ref nrf_802154_trx_receive_frame operation. */ /**@brief Notifications that can be enabled for @ref nrf_802154_trx_receive_frame operation. */
typedef enum typedef enum
{ {
@ -176,7 +183,6 @@ void nrf_802154_trx_cca_configuration_update(void);
* *
* The frame will be received into buffer set by @ref nrf_802154_trx_receive_buffer_set. * The frame will be received into buffer set by @ref nrf_802154_trx_receive_buffer_set.
* *
* When NRF_802154_DISABLE_BCC_MATCHING == 0
* - during receive @ref nrf_802154_trx_receive_frame_started handler is called when * - during receive @ref nrf_802154_trx_receive_frame_started handler is called when
* SHR field of a frame being received is received (only when @p notifications_mask contained @ref TRX_RECEIVE_NOTIFICATION_STARTED flag) * SHR field of a frame being received is received (only when @p notifications_mask contained @ref TRX_RECEIVE_NOTIFICATION_STARTED flag)
* - during receive @ref nrf_802154_trx_receive_frame_bcmatched handler is called when * - during receive @ref nrf_802154_trx_receive_frame_bcmatched handler is called when
@ -184,34 +190,25 @@ void nrf_802154_trx_cca_configuration_update(void);
* - when a frame is received with correct crc, @ref nrf_802154_trx_receive_frame_received is called * - when a frame is received with correct crc, @ref nrf_802154_trx_receive_frame_received is called
* - when a frame is received with incorrect crc, @ref nrf_802154_trx_receive_frame_crcerror is called * - when a frame is received with incorrect crc, @ref nrf_802154_trx_receive_frame_crcerror is called
* *
* When NRF_802154_DISABLE_BCC_MATCHING != 0
* - @ref nrf_802154_trx_receive_frame_prestarted handler is called when the RADIO initially syncs on received frame.
* This handler is called when @p notifications_mask contains @ref TRX_RECEIVE_NOTIFICATION_PRESTARTED.
* - @ref nrf_802154_trx_receive_frame_started handler is called when
* SHR field of a frame being received is received (only when @p notifications_mask contained @ref TRX_RECEIVE_NOTIFICATION_STARTED flag)
* - after the frame is received with correct crc, @ref nrf_802154_trx_receive_frame_received is called
* - after the frame is received with incorrect crc:
* - when NRF_802154_NOTIFY_CRCERROR == 0:
* - the hardware restarts receive automatically
* - no handler is called
* - when NRF_802154_NOTIFY_CRCERROR != 0:
* - the hardware restarts receive automatically
* - @ref nrf_802154_trx_receive_frame_crcerror is called
*
* When in @ref nrf_802154_trx_receive_frame_received, the TIMER is running allowing sending response (e.g. ACK frame) * When in @ref nrf_802154_trx_receive_frame_received, the TIMER is running allowing sending response (e.g. ACK frame)
* in time regime by a call to nrf_802154_trx_transmit_after_frame_received. * in time regime by a call to nrf_802154_trx_transmit_after_frame_received.
* *
* @note To receive ACK use @ref nrf_802154_trx_receive_ack * @note To receive ACK use @ref nrf_802154_trx_receive_ack
* *
* @param[in] bcc Number of received bytes after which @ref nrf_802154_trx_receive_frame_bcmatched will be called. * @param[in] bcc Number of received bytes after which @ref nrf_802154_trx_receive_frame_bcmatched will be called.
* This must not be zero if @ref NRF_802154_DISABLE_BCC_MATCHING == 0. * @param[in] rampup_trigg_mode Radio ramp up triggering mode to be used.
* When @ref NRF_802154_DISABLE_BCC_MATCHING != 0, this value must be zero. * If @ref TRX_RAMP_UP_SW_TRIGGER is selected, this function will trigger radio ramp up in a software manner
* and the caller is guaranteed that ramp up is ongoing when the function ends.
* If @ref TRX_RAMP_UP_HW_TRIGGER is selected, this function will prepare the operation but it will end
* without starting radio ramp up. In this case, it is assumed that the trigger will be generated
* on the (D)PPI channel specified by @ref nrf_802154_trx_ramp_up_ppi_channel_get. It is the user's
* responsibility to prepare the stimulation of this (D)PPI.
* @param[in] notifications_mask Selects additional notifications generated during a frame reception. * @param[in] notifications_mask Selects additional notifications generated during a frame reception.
* It is bitwise combination of @ref nrf_802154_trx_receive_notifications_t values. * It is bitwise combination of @ref nrf_802154_trx_receive_notifications_t values.
* When NRF_802154_DISABLE_BCC_MATCHING != 0, flag @ref TRX_RECEIVE_NOTIFICATION_PRESTARTED is forbidden.
* @param[in] p_ack_tx_power Selects the power which should be used to transmitted an ACK if required. * @param[in] p_ack_tx_power Selects the power which should be used to transmitted an ACK if required.
*/ */
void nrf_802154_trx_receive_frame(uint8_t bcc, void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_802154_trx_ramp_up_trigger_mode_t rampup_trigg_mode,
nrf_802154_trx_receive_notifications_t notifications_mask, nrf_802154_trx_receive_notifications_t notifications_mask,
const nrf_802154_fal_tx_power_split_t * p_ack_tx_power); const nrf_802154_fal_tx_power_split_t * p_ack_tx_power);
@ -313,8 +310,6 @@ bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer);
* - The RADIO starts ramp up in transmit mode. * - The RADIO starts ramp up in transmit mode.
* - The RADIO starts sending synchronization header (SHR). * - The RADIO starts sending synchronization header (SHR).
* - @ref nrf_802154_trx_transmit_frame_started handler is called from an ISR just after SHR is sent * - @ref nrf_802154_trx_transmit_frame_started handler is called from an ISR just after SHR is sent
* (only when @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED == 1).
* - @ref nrf_802154_trx_transmit_frame_transmitted handler is called from an ISR after full frame is sent on air.
* *
* When cca==true: * When cca==true:
* - The radio starts ramp up in receive mode, then it starts cca procedure. * - The radio starts ramp up in receive mode, then it starts cca procedure.
@ -327,8 +322,6 @@ bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer);
* - If @ref TRX_TRANSMIT_NOTIFICATION_CCAIDLE was present in notifications_mask, * - If @ref TRX_TRANSMIT_NOTIFICATION_CCAIDLE was present in notifications_mask,
* the @ref nrf_802154_trx_transmit_frame_ccaidle is called. * the @ref nrf_802154_trx_transmit_frame_ccaidle is called.
* - @ref nrf_802154_trx_transmit_frame_started handler is called from an ISR just after SHR is sent * - @ref nrf_802154_trx_transmit_frame_started handler is called from an ISR just after SHR is sent
* (only when @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED == 1).
* - @ref nrf_802154_trx_transmit_frame_transmitted handler is called from an ISR after full frame is sent on air.
* - If cca failed (channel was busy): * - If cca failed (channel was busy):
* - The RADIO disables receive mode * - The RADIO disables receive mode
* - @ref nrf_802154_trx_transmit_frame_ccabusy from an ISR handler is called * - @ref nrf_802154_trx_transmit_frame_ccabusy from an ISR handler is called
@ -338,6 +331,16 @@ bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer);
* bytes following p_transmit_buffer[0] to send. * bytes following p_transmit_buffer[0] to send.
* The number of bytes pointed by p_transmit buffer must * The number of bytes pointed by p_transmit buffer must
* be at least 1 and not less than p_transmit_buffer[0] + 1. * be at least 1 and not less than p_transmit_buffer[0] + 1.
* @param rampup_trigg_mode Radio ramp up triggering mode to be used.
* If @ref TRX_RAMP_UP_SW_TRIGGER is selected, this function
* will trigger radio ramp up in a software manner.
* If @ref TRX_RAMP_UP_HW_TRIGGER is selected, this function
* will prepare the operation but it will end without starting
* radio ramp up. In this case, it is assumed that the trigger
* will be generated on the (D)PPI channel specified by
* @ref nrf_802154_trx_ramp_up_ppi_channel_get.
* It is the user's responsibility to prepare the stimulation
* of this (D)PPI.
* @param cca Selects if CCA procedure should be performed prior to * @param cca Selects if CCA procedure should be performed prior to
* real transmission. If false no cca will be performed. * real transmission. If false no cca will be performed.
* If true, cca will be performed. * If true, cca will be performed.
@ -347,6 +350,7 @@ bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer);
* @note To transmit ack after frame is received use @ref nrf_802154_trx_transmit_ack. * @note To transmit ack after frame is received use @ref nrf_802154_trx_transmit_ack.
*/ */
void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer, void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer,
nrf_802154_trx_ramp_up_trigger_mode_t rampup_trigg_mode,
bool cca, bool cca,
const nrf_802154_fal_tx_power_split_t * p_tx_power, const nrf_802154_fal_tx_power_split_t * p_tx_power,
nrf_802154_trx_transmit_notifications_t notifications_mask); nrf_802154_trx_transmit_notifications_t notifications_mask);
@ -361,8 +365,7 @@ void nrf_802154_trx_transmit_frame(const void * p_tra
* @param[in] delay_us Delay (in microseconds) * @param[in] delay_us Delay (in microseconds)
* *
* @retval true If the function was called in time and ACK frame is scheduled for transmission. * @retval true If the function was called in time and ACK frame is scheduled for transmission.
* When transmission starts and @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED != 0 * When transmission starts the function @ref nrf_802154_trx_transmit_ack_started will be called.
* the function @ref nrf_802154_trx_transmit_ack_started will be called.
* When transmission is finished the function @ref nrf_802154_trx_transmit_ack_transmitted * When transmission is finished the function @ref nrf_802154_trx_transmit_ack_transmitted
* will be called. * will be called.
* @retval false If the function was called too late and given delay_us time gap * @retval false If the function was called too late and given delay_us time gap
@ -447,6 +450,11 @@ void nrf_802154_trx_abort(void);
* @return Current state of the TRX module.*/ * @return Current state of the TRX module.*/
trx_state_t nrf_802154_trx_state_get(void); trx_state_t nrf_802154_trx_state_get(void);
/**
* @brief Gets (D)PPI channel used to trigger ramp up procedure start.
*/
uint32_t nrf_802154_trx_ramp_up_ppi_channel_get(void);
/**@brief Handler called at the beginning of a ACK reception. /**@brief Handler called at the beginning of a ACK reception.
* *
* This handler is called from an ISR when receive of an ack has been started, and * This handler is called from an ISR when receive of an ack has been started, and
@ -538,7 +546,6 @@ extern void nrf_802154_trx_receive_frame_received(void);
* - receive operation has been started with a call to @ref nrf_802154_trx_receive_frame * - receive operation has been started with a call to @ref nrf_802154_trx_receive_frame
* - the RADIO received a frame on air with incorrect crc * - the RADIO received a frame on air with incorrect crc
* *
* If NRF_802154_DISABLE_BCC_MATCHING == 0:
* When this handler is called following holds: * When this handler is called following holds:
* - the RADIO peripheral started ramping down (or it ramped down already) * - the RADIO peripheral started ramping down (or it ramped down already)
* - trx module is in @c FINISHED state. * - trx module is in @c FINISHED state.
@ -550,9 +557,6 @@ extern void nrf_802154_trx_receive_frame_received(void);
* - @ref nrf_802154_trx_go_idle, * - @ref nrf_802154_trx_go_idle,
* - @ref nrf_802154_trx_disable. * - @ref nrf_802154_trx_disable.
* *
* If NRF_802154_DISABLE_BCC_MATCHING != 0:
* - the RADIO peripheral is restarted automatically (by hardware) in receive mode
* - trx module stays in @c RXFRAME state
* Implementation of @ref nrf_802154_trx_receive_frame_crcerror should not call * Implementation of @ref nrf_802154_trx_receive_frame_crcerror should not call
* @ref nrf_802154_trx_receive_frame as receive is restarted automatically by the hardware. * @ref nrf_802154_trx_receive_frame as receive is restarted automatically by the hardware.
* If the implementation wishes to change state it should call * If the implementation wishes to change state it should call
@ -649,7 +653,6 @@ extern void nrf_802154_trx_transmit_frame_ccabusy(void);
/**@brief Handler called when frame transmission has just started. /**@brief Handler called when frame transmission has just started.
* *
* This handler is called from an ISR when: * This handler is called from an ISR when:
* - @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED == 1 (see nrf_802154_config.h)
* - transmit operation was started by a call to @ref nrf_802154_trx_transmit_frame. * - transmit operation was started by a call to @ref nrf_802154_trx_transmit_frame.
* - the RADIO peripheral sent synchronization header * - the RADIO peripheral sent synchronization header
* *
@ -683,7 +686,6 @@ extern void nrf_802154_trx_transmit_frame_transmitted(void);
/**@brief Handler called when ack transmission has just been started. /**@brief Handler called when ack transmission has just been started.
* *
* This handler is called from an ISR when: * This handler is called from an ISR when:
* - @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED == 1 (see nrf_802154_config.h)
* - transmit operation was started by a call to @ref nrf_802154_trx_transmit_ack. * - transmit operation was started by a call to @ref nrf_802154_trx_transmit_ack.
* - the RADIO peripheral sent synchronization header * - the RADIO peripheral sent synchronization header
* *

View File

@ -36,7 +36,7 @@
#include "nrfx.h" #include "nrfx.h"
#ifdef NRF53_SERIES #if defined(DPPI_PRESENT)
#include "nrf_802154_trx_ppi_api.h" #include "nrf_802154_trx_ppi_api.h"
@ -48,9 +48,6 @@
#include "hal/nrf_radio.h" #include "hal/nrf_radio.h"
#include "hal/nrf_timer.h" #include "hal/nrf_timer.h"
#define EGU_EVENT NRF_EGU_EVENT_TRIGGERED15
#define EGU_TASK NRF_EGU_TASK_TRIGGER15
#define DPPI_CHGRP_RAMP_UP NRF_DPPI_CHANNEL_GROUP0 ///< PPI group used to disable self-disabling PPIs #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 DPPI_CHGRP_RAMP_UP_DIS_TASK NRF_DPPI_TASK_CHG0_DIS ///< PPI task used to disable self-disabling PPIs
@ -70,32 +67,46 @@ void nrf_802154_trx_ppi_for_enable(void)
#if NRF_802154_TEST_MODES_ENABLED #if NRF_802154_TEST_MODES_ENABLED
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY, NRF_802154_DPPI_RADIO_CCABUSY); nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY, NRF_802154_DPPI_RADIO_CCABUSY);
#endif // NRF_802154_TEST_MODES_ENABLED #endif // NRF_802154_TEST_MODES_ENABLED
#if defined(NRF_802154_DPPI_RADIO_TXREADY)
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_TXREADY, NRF_802154_DPPI_RADIO_TXREADY);
#endif
nrf_dppi_channels_enable(NRF_DPPIC, nrf_dppi_channels_enable(NRF_802154_DPPIC_INSTANCE,
#if NRF_802154_TEST_MODES_ENABLED #if NRF_802154_TEST_MODES_ENABLED
(1UL << NRF_802154_DPPI_RADIO_CCABUSY) | (1UL << NRF_802154_DPPI_RADIO_CCABUSY) |
#endif // NRF_802154_TEST_MODES_ENABLED #endif // NRF_802154_TEST_MODES_ENABLED
(1UL << PPI_DISABLED_EGU) | (1UL << PPI_DISABLED_EGU) |
(1UL << NRF_802154_DPPI_RADIO_READY) | (1UL << NRF_802154_DPPI_RADIO_READY) |
#if defined(NRF_802154_DPPI_RADIO_TXREADY)
(1UL << NRF_802154_DPPI_RADIO_TXREADY) |
#endif
(1UL << NRF_802154_DPPI_RADIO_ADDRESS) | (1UL << NRF_802154_DPPI_RADIO_ADDRESS) |
(1UL << NRF_802154_DPPI_RADIO_END) | (1UL << NRF_802154_DPPI_RADIO_END) |
(1UL << NRF_802154_DPPI_RADIO_PHYEND) | (1UL << NRF_802154_DPPI_RADIO_PHYEND) |
(1UL << NRF_802154_DPPI_RADIO_CCAIDLE)); (1UL << NRF_802154_DPPI_RADIO_CCAIDLE) |
(1UL << NRF_802154_DPPI_RADIO_HW_TRIGGER));
} }
void nrf_802154_trx_ppi_for_disable(void) void nrf_802154_trx_ppi_for_disable(void)
{ {
nrf_dppi_channels_disable(NRF_DPPIC, nrf_dppi_channels_disable(NRF_802154_DPPIC_INSTANCE,
#if NRF_802154_TEST_MODES_ENABLED #if NRF_802154_TEST_MODES_ENABLED
(1UL << NRF_802154_DPPI_RADIO_CCABUSY) | (1UL << NRF_802154_DPPI_RADIO_CCABUSY) |
#endif // NRF_802154_TEST_MODES_ENABLED #endif // NRF_802154_TEST_MODES_ENABLED
(1UL << PPI_DISABLED_EGU) | (1UL << PPI_DISABLED_EGU) |
(1UL << NRF_802154_DPPI_RADIO_READY) | (1UL << NRF_802154_DPPI_RADIO_READY) |
#if defined(NRF_802154_DPPI_RADIO_TXREADY)
(1UL << NRF_802154_DPPI_RADIO_TXREADY) |
#endif
(1UL << NRF_802154_DPPI_RADIO_ADDRESS) | (1UL << NRF_802154_DPPI_RADIO_ADDRESS) |
(1UL << NRF_802154_DPPI_RADIO_END) | (1UL << NRF_802154_DPPI_RADIO_END) |
(1UL << NRF_802154_DPPI_RADIO_PHYEND) | (1UL << NRF_802154_DPPI_RADIO_PHYEND) |
(1UL << NRF_802154_DPPI_RADIO_CCAIDLE)); (1UL << NRF_802154_DPPI_RADIO_CCAIDLE) |
(1UL << NRF_802154_DPPI_RADIO_HW_TRIGGER));
#if defined(NRF_802154_DPPI_RADIO_TXREADY)
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_TXREADY);
#endif
#if NRF_802154_TEST_MODES_ENABLED #if NRF_802154_TEST_MODES_ENABLED
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY); nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY);
#endif // NRF_802154_TEST_MODES_ENABLED #endif // NRF_802154_TEST_MODES_ENABLED
@ -107,49 +118,75 @@ void nrf_802154_trx_ppi_for_disable(void)
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED); 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) uint8_t nrf_802154_trx_ppi_for_ramp_up_channel_id_get(void)
{
return NRF_802154_DPPI_RADIO_HW_TRIGGER;
}
void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task,
nrf_802154_trx_ramp_up_trigger_mode_t trigg_mode,
bool start_timer)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
// Clr event EGU (needed for nrf_802154_trx_ppi_for_ramp_up_was_triggered) // Clr event EGU (needed for nrf_802154_trx_ppi_for_ramp_up_was_triggered)
nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT); nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_EVENT);
nrf_dppi_channels_include_in_group(NRF_802154_DPPIC_INSTANCE,
1UL << PPI_EGU_RAMP_UP,
DPPI_CHGRP_RAMP_UP);
nrf_dppi_channels_include_in_group(NRF_DPPIC, 1UL << PPI_EGU_RAMP_UP, DPPI_CHGRP_RAMP_UP);
nrf_egu_publish_set(NRF_802154_EGU_INSTANCE, EGU_EVENT, PPI_EGU_RAMP_UP);
nrf_radio_subscribe_set(NRF_RADIO, ramp_up_task, PPI_EGU_RAMP_UP); nrf_radio_subscribe_set(NRF_RADIO, ramp_up_task, PPI_EGU_RAMP_UP);
nrf_dppi_subscribe_set(NRF_DPPIC, DPPI_CHGRP_RAMP_UP_DIS_TASK, PPI_EGU_RAMP_UP); nrf_dppi_subscribe_set(NRF_802154_DPPIC_INSTANCE, DPPI_CHGRP_RAMP_UP_DIS_TASK, PPI_EGU_RAMP_UP);
if (start_timer) if (start_timer)
{ {
nrf_timer_subscribe_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START, PPI_DISABLED_EGU); nrf_timer_subscribe_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START, PPI_DISABLED_EGU);
} }
nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, EGU_TASK, PPI_DISABLED_EGU); nrf_egu_publish_set(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_EVENT, PPI_EGU_RAMP_UP);
nrf_dppi_channels_enable(NRF_DPPIC, nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_TASK, PPI_DISABLED_EGU);
nrf_dppi_channels_enable(NRF_802154_DPPIC_INSTANCE,
(1UL << PPI_EGU_RAMP_UP)); (1UL << PPI_EGU_RAMP_UP));
if (trigg_mode == TRX_RAMP_UP_HW_TRIGGER)
{
nrf_radio_subscribe_set(NRF_RADIO,
NRF_RADIO_TASK_DISABLE,
NRF_802154_DPPI_RADIO_HW_TRIGGER);
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
} }
void nrf_802154_trx_ppi_for_ramp_up_reconfigure(void)
{
// Intentionally empty
}
void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer) void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
nrf_dppi_channels_disable(NRF_DPPIC, nrf_dppi_channels_disable(NRF_802154_DPPIC_INSTANCE,
(1UL << PPI_EGU_RAMP_UP)); (1UL << PPI_EGU_RAMP_UP));
nrf_egu_publish_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT); nrf_egu_publish_clear(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_EVENT);
nrf_radio_subscribe_clear(NRF_RADIO, ramp_up_task); nrf_radio_subscribe_clear(NRF_RADIO, ramp_up_task);
nrf_dppi_subscribe_clear(NRF_DPPIC, DPPI_CHGRP_RAMP_UP_DIS_TASK); nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
nrf_dppi_channels_remove_from_group(NRF_DPPIC, 1UL << PPI_EGU_RAMP_UP, DPPI_CHGRP_RAMP_UP); nrf_dppi_subscribe_clear(NRF_802154_DPPIC_INSTANCE, DPPI_CHGRP_RAMP_UP_DIS_TASK);
nrf_dppi_channels_remove_from_group(NRF_802154_DPPIC_INSTANCE,
1UL << PPI_EGU_RAMP_UP,
DPPI_CHGRP_RAMP_UP);
if (start_timer) if (start_timer)
{ {
nrf_timer_subscribe_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START); nrf_timer_subscribe_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START);
} }
nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, EGU_TASK); nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_TASK);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
} }
@ -179,7 +216,7 @@ bool nrf_802154_trx_ppi_for_ramp_up_was_triggered(void)
// Wait for PPIs // Wait for PPIs
nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(); nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait();
if (nrf_egu_event_check(NRF_802154_EGU_INSTANCE, EGU_EVENT)) if (nrf_egu_event_check(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_EVENT))
{ {
// If EGU event is set, procedure is running. // If EGU event is set, procedure is running.
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
@ -198,7 +235,7 @@ void nrf_802154_trx_ppi_for_ack_tx_set(void)
nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, PPI_TIMER_TX_ACK); nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, PPI_TIMER_TX_ACK);
nrf_timer_publish_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE1, PPI_TIMER_TX_ACK); nrf_timer_publish_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE1, PPI_TIMER_TX_ACK);
nrf_dppi_channels_enable(NRF_DPPIC, (1UL << PPI_TIMER_TX_ACK)); nrf_dppi_channels_enable(NRF_802154_DPPIC_INSTANCE, (1UL << PPI_TIMER_TX_ACK));
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
} }
@ -207,7 +244,7 @@ void nrf_802154_trx_ppi_for_ack_tx_clear(void)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
nrf_dppi_channels_disable(NRF_DPPIC, (1UL << PPI_TIMER_TX_ACK)); nrf_dppi_channels_disable(NRF_802154_DPPIC_INSTANCE, (1UL << PPI_TIMER_TX_ACK));
nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN);
nrf_timer_publish_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE1); nrf_timer_publish_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE1);
@ -246,7 +283,7 @@ void nrf_802154_trx_ppi_for_radio_sync_set(nrf_egu_task_t task)
nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_SYNC, PPI_RADIO_SYNC_EGU_SYNC); nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_SYNC, PPI_RADIO_SYNC_EGU_SYNC);
nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, task, PPI_RADIO_SYNC_EGU_SYNC); nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, task, PPI_RADIO_SYNC_EGU_SYNC);
nrf_dppi_channels_enable(NRF_DPPIC, (1UL << PPI_RADIO_SYNC_EGU_SYNC)); nrf_dppi_channels_enable(NRF_802154_DPPIC_INSTANCE, (1UL << PPI_RADIO_SYNC_EGU_SYNC));
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
} }
@ -255,7 +292,7 @@ void nrf_802154_trx_ppi_for_radio_sync_clear(nrf_egu_task_t task)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
nrf_dppi_channels_disable(NRF_DPPIC, (1UL << PPI_RADIO_SYNC_EGU_SYNC)); nrf_dppi_channels_disable(NRF_802154_DPPIC_INSTANCE, (1UL << PPI_RADIO_SYNC_EGU_SYNC));
nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_SYNC); nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_SYNC);
nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, task); nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, task);
@ -264,4 +301,4 @@ void nrf_802154_trx_ppi_for_radio_sync_clear(nrf_egu_task_t task)
#endif #endif
#endif // NRF53_SERIES #endif // defined(DPPI_PRESENT)

View File

@ -61,6 +61,7 @@
#define PPI_CHGRP_ABORT NRF_802154_PPI_ABORT_GROUP ///< PPI group used to disable PPIs when async event aborting radio operation is propagated through the system #define PPI_CHGRP_ABORT NRF_802154_PPI_ABORT_GROUP ///< PPI group used to disable PPIs when async event aborting radio operation is propagated through the system
#define PPI_DISABLED_EGU NRF_802154_PPI_RADIO_DISABLED_TO_EGU ///< PPI that connects RADIO DISABLED event with EGU task #define PPI_DISABLED_EGU NRF_802154_PPI_RADIO_DISABLED_TO_EGU ///< PPI that connects RADIO DISABLED event with EGU task
#define PPI_RAMP_UP_TRG_EGU NRF_802154_PPI_RADIO_RAMP_UP_TRIGG ///< PPI that connects ramp up trigger event with EGU task
#define PPI_EGU_RAMP_UP NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP ///< PPI that connects EGU event with RADIO TXEN or RXEN task #define PPI_EGU_RAMP_UP NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP ///< PPI that connects EGU event with RADIO TXEN or RXEN task
#define PPI_EGU_TIMER_START NRF_802154_PPI_EGU_TO_TIMER_START ///< PPI that connects EGU event with TIMER START task #define PPI_EGU_TIMER_START NRF_802154_PPI_EGU_TO_TIMER_START ///< PPI that connects EGU event with TIMER START task
#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_TIMER_TX_ACK NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN ///< PPI that connects TIMER COMPARE event with RADIO TXEN task
@ -76,13 +77,22 @@ void nrf_802154_trx_ppi_for_disable(void)
// Intentionally empty. // Intentionally empty.
} }
void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool start_timer) uint8_t nrf_802154_trx_ppi_for_ramp_up_channel_id_get(void)
{
return PPI_RAMP_UP_TRG_EGU;
}
void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task,
nrf_802154_trx_ramp_up_trigger_mode_t trigg_mode,
bool start_timer)
{ {
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
// Clr event EGU (needed for nrf_802154_trx_ppi_for_ramp_up_was_triggered) // Clr event EGU (needed for nrf_802154_trx_ppi_for_ramp_up_was_triggered)
nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT); nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT);
uint32_t ppi_mask = (1UL << PPI_EGU_RAMP_UP) | (1UL << PPI_RAMP_UP_TRG_EGU);
nrf_ppi_channel_and_fork_endpoint_setup(NRF_PPI, nrf_ppi_channel_and_fork_endpoint_setup(NRF_PPI,
PPI_EGU_RAMP_UP, PPI_EGU_RAMP_UP,
nrf_egu_event_address_get( nrf_egu_event_address_get(
@ -100,35 +110,50 @@ void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool star
EGU_EVENT), EGU_EVENT),
nrf_timer_task_address_get(NRF_802154_TIMER_INSTANCE, nrf_timer_task_address_get(NRF_802154_TIMER_INSTANCE,
NRF_TIMER_TASK_START)); NRF_TIMER_TASK_START));
}
nrf_ppi_channel_endpoint_setup(NRF_PPI,
PPI_DISABLED_EGU,
nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_DISABLED),
nrf_egu_task_address_get(NRF_802154_EGU_INSTANCE, EGU_TASK));
nrf_ppi_channel_include_in_group(NRF_PPI, PPI_EGU_RAMP_UP, PPI_CHGRP_RAMP_UP);
uint32_t ppi_mask = (1UL << PPI_EGU_RAMP_UP) |
(1UL << PPI_DISABLED_EGU);
if (start_timer)
{
ppi_mask |= (1UL << PPI_EGU_TIMER_START); ppi_mask |= (1UL << PPI_EGU_TIMER_START);
} }
if (trigg_mode == TRX_RAMP_UP_SW_TRIGGER)
{
nrf_ppi_channel_endpoint_setup(NRF_PPI,
PPI_RAMP_UP_TRG_EGU,
nrf_radio_event_address_get(NRF_RADIO,
NRF_RADIO_EVENT_DISABLED),
nrf_egu_task_address_get(NRF_802154_EGU_INSTANCE, EGU_TASK));
}
else
{
nrf_ppi_task_endpoint_setup(NRF_PPI,
PPI_RAMP_UP_TRG_EGU,
nrf_egu_task_address_get(NRF_802154_EGU_INSTANCE, EGU_TASK));
}
nrf_ppi_channel_include_in_group(NRF_PPI, PPI_EGU_RAMP_UP, PPI_CHGRP_RAMP_UP);
nrf_ppi_channels_enable(NRF_PPI, ppi_mask); nrf_ppi_channels_enable(NRF_PPI, ppi_mask);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
} }
void nrf_802154_trx_ppi_for_ramp_up_reconfigure(void)
{
nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT);
nrf_ppi_channel_endpoint_setup(NRF_PPI,
PPI_DISABLED_EGU,
nrf_radio_event_address_get(NRF_RADIO,
NRF_RADIO_EVENT_DISABLED),
nrf_egu_task_address_get(NRF_802154_EGU_INSTANCE, EGU_TASK));
}
void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer) void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer)
{ {
(void)ramp_up_task; (void)ramp_up_task;
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH);
uint32_t ppi_mask = (1UL << PPI_EGU_RAMP_UP) | uint32_t ppi_mask = (1UL << PPI_EGU_RAMP_UP) |
(1UL << PPI_DISABLED_EGU); (1UL << PPI_RAMP_UP_TRG_EGU);
if (start_timer) if (start_timer)
{ {
@ -136,9 +161,8 @@ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool st
} }
nrf_ppi_channels_disable(NRF_PPI, ppi_mask); nrf_ppi_channels_disable(NRF_PPI, ppi_mask);
nrf_ppi_channel_and_fork_endpoint_setup(NRF_PPI, PPI_EGU_RAMP_UP, 0, 0, 0); nrf_ppi_channel_and_fork_endpoint_setup(NRF_PPI, PPI_EGU_RAMP_UP, 0, 0, 0);
nrf_ppi_channel_endpoint_setup(NRF_PPI, PPI_DISABLED_EGU, 0, 0); nrf_ppi_channel_endpoint_setup(NRF_PPI, PPI_RAMP_UP_TRG_EGU, 0, 0);
if (start_timer) if (start_timer)
{ {

View File

@ -45,6 +45,7 @@
#include "hal/nrf_egu.h" #include "hal/nrf_egu.h"
#include "hal/nrf_radio.h" #include "hal/nrf_radio.h"
#include "nrf_802154_trx.h"
/** /**
* @brief Configures (D)PPI connections required for TRX operation. * @brief Configures (D)PPI connections required for TRX operation.
@ -62,35 +63,80 @@ void nrf_802154_trx_ppi_for_enable(void);
void nrf_802154_trx_ppi_for_disable(void); void nrf_802154_trx_ppi_for_disable(void);
/** /**
* @brief Set PPIs to connect RADIO DISABLED event with tasks needed to ramp up. * @brief Set PPIs to connect trigger event with tasks needed to ramp up.
* *
* Connections created by this function in DPPI variant: * When @p trigg_mode is TRX_RAMP_UP_SW_TRIGGER, the trigger event is RADIO_DISABLED and
* PPI connections are made to it.
* When @p trigg_mode is TRX_RAMP_UP_HW_TRIGGER, the trigger event is defined outside the module
* and PPI connections are only partially created. To complete the connection creation, the trigger
* event must be connected to the (D)PPI channel specified with
* @ref nrf_802154_trx_ppi_for_ramp_up_channel_id_get.
*
* Connections created by this function in DPPI variant and TRX_RAMP_UP_SW_TRIGGER mode:
* *
* RADIO_DISABLED ----> EGU -----> ramp_up_task * RADIO_DISABLED ----> EGU -----> ramp_up_task
* | \--> self disable * | \--> self disable
* if (start_timer) * if (start_timer)
* \-------------> TIMER_START * \-------------> TIMER_START
* *
* Connections created by this function in PPI variant: * Connections created by this function in DPPI variant and TRX_RAMP_UP_HW_TRIGGER mode:
*
* [DPPI] -----------------------> RADIO_TASK_DISABLE
*
* RADIO_DISABLED ----> EGU -----> ramp_up_task
* | \--> self disable
* if (start_timer)
* \--------------> TIMER_START
*
* Connections created by this function in PPI variant and TRX_RAMP_UP_SW_TRIGGER mode:
* *
* RADIO_DISABLED ----> EGU -----> ramp_up_task * RADIO_DISABLED ----> EGU -----> ramp_up_task
* \--> self disable * \--> self disable
* *
* EGU ---> if (start_timer) ----> TIMER_START * EGU ---> if (start_timer) ----> TIMER_START
* *
* Connections created by this function in PPI variant and TRX_RAMP_UP_HW_TRIGGER mode:
*
* [PPI] --------> EGU ----------> ramp_up_task
* \--> self disable
*
* EGU ---> if (start_timer) ----> TIMER_START
*
* @param[in] ramp_up_task Task triggered to start ramp up procedure. * @param[in] ramp_up_task Task triggered to start ramp up procedure.
* @param[in] trigg_mode Trigger mode the connections must conform to.
* @param[in] start_timer If timer is to be started on RADIO DISABLED event. * @param[in] start_timer If timer is to be started on RADIO DISABLED event.
*/ */
void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool start_timer); void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task,
nrf_802154_trx_ramp_up_trigger_mode_t trigg_mode,
bool start_timer);
/** /**
* @brief Clear PPIs to connect RADIO DISABLED event with tasks needed to ramp up. * @brief Reconfigure (D)PPIs for the next steps in receiving or transmitting.
*
* Due to limited resources on some platforms, some PPIs have many uses: when starting an operation,
* one is used to trigger the radio ramp up, then when the radio is "up", this PPI must be
* reconfigured so it can be used to disable the radio when needed.
* This is the PPI reconfiguration routine. It is intended to be called in the radio READY event
* handler.
*/
void nrf_802154_trx_ppi_for_ramp_up_reconfigure(void);
/**
* @brief Clear (D)PPIs that are configured for ramp up procedure.
* *
* @param[in] ramp_up_task Task triggered to start ramp up procedure. * @param[in] ramp_up_task Task triggered to start ramp up procedure.
* @param[in] start_timer If timer start on RADIO DISABLED event is to be deconfigured as well. See @ref nrf_802154_trx_ppi_for_ramp_up_set. * @param[in] start_timer If timer start on RADIO DISABLED event is to be deconfigured as well. See @ref nrf_802154_trx_ppi_for_ramp_up_set.
*/ */
void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer); void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer);
/**
* @brief Get (D)PPI channel used to trigger ramp up procedure start.
*
* @retval NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP in DPPI variant.
* @retval NRF_802154_PPI_RADIO_RAMP_UP_TRIGG in PPI variant.
*/
uint8_t nrf_802154_trx_ppi_for_ramp_up_channel_id_get(void);
/** /**
* @brief Wait until PPIs configured to ramp up radio are propagated through PPI system. * @brief Wait until PPIs configured to ramp up radio are propagated through PPI system.
* *
@ -104,8 +150,13 @@ void nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(void);
/** /**
* @brief Detect if PPIs configured to start radio operation were triggered. * @brief Detect if PPIs configured to start radio operation were triggered.
* *
* Radio ramp up starts by design from RADIO DISABLED event. This functions verifies this event * In TRX_RAMP_UP_SW_TRIGGER mode, radio ramp up starts by design from RADIO DISABLED event.
* and PPIs status. * This functions verifies occurrence of this event and PPIs status.
*
* The function is intended to be used only when all of the following conditions apply:
* - the connections are already made with @ref nrf_802154_trx_ppi_for_ramp_up_set
* - TRX_RAMP_UP_SW_TRIGGER mode was used to create connections
* - connections have not yet been cleared
* *
* @retval true PPIs were triggered. * @retval true PPIs were triggered.
* @retval false PPIs were not triggered. To trigger them, the caller must trigger RADIO DISABLE task. * @retval false PPIs were not triggered. To trigger them, the caller must trigger RADIO DISABLE task.

View File

@ -830,6 +830,13 @@ uint64_t nrf_802154_time_get(void);
*/ */
void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter); void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter);
/**
* @brief Sets nRF 802.15.4 Radio Driver MAC Global Frame Counter if the value passed is larger than current.
*
* @param[in] frame_counter Frame counter to set.
*/
void nrf_802154_security_global_frame_counter_set_if_larger(uint32_t frame_counter);
/** /**
* @brief Store the 802.15.4 MAC Security Key inside the nRF 802.15.4 Radio Driver. * @brief Store the 802.15.4 MAC Security Key inside the nRF 802.15.4 Radio Driver.
* *

View File

@ -44,14 +44,12 @@
that the maximum value in EDSAMPLE which can be reported in compliance with the 802.15.4 specification is that the maximum value in EDSAMPLE which can be reported in compliance with the 802.15.4 specification is
255/ED_RSSISCALE. */ 255/ED_RSSISCALE. */
#if defined (NRF52840_XXAA) #if defined (NRF52833_XXAA) || defined(NRF5340_XXAA)
#define ED_RSSIOFFS (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register. #define ED_RSSIOFFS (-93) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral. #define ED_RSSISCALE 5 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#elif defined (NRF52833_XXAA) || defined(NRF5340_XXAA)
#define ED_RSSIOFFS (-93) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 5 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#else #else
#error "Selected chip is not supported." #define ED_RSSIOFFS (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#endif #endif
#define EDSAMPLE_MIN_REPORTED_VALUE (PHY_MIN_RECEIVER_SENSITIVITY - ED_RSSIOFFS + 10) ///< Minimal reported EDSAMPLE value (reported as 0) #define EDSAMPLE_MIN_REPORTED_VALUE (PHY_MIN_RECEIVER_SENSITIVITY - ED_RSSIOFFS + 10) ///< Minimal reported EDSAMPLE value (reported as 0)

View File

@ -447,6 +447,12 @@ typedef enum
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET = SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 63, SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 63,
/**
* Vendor property for nrf_802154_security_global_frame_counter_set_if_larger serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET_IF_LARGER =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 64,
} spinel_prop_vendor_key_t; } spinel_prop_vendor_key_t;
/** /**

View File

@ -1820,6 +1820,32 @@ bail:
return; return;
} }
void nrf_802154_security_global_frame_counter_set_if_larger(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_IF_LARGER,
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_security_error_t nrf_802154_security_key_store(nrf_802154_key_t * p_key)
{ {
nrf_802154_ser_err_t res; nrf_802154_ser_err_t res;

View File

@ -1653,6 +1653,35 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_security_global_frame_
return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK); return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK);
} }
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET_IF_LARGER.
*
* @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_if_larger(
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_if_larger(frame_counter);
return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK);
}
/** /**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_STORE. * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_KEY_STORE.
* *
@ -2022,6 +2051,11 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_
return spinel_decode_prop_nrf_802154_stat_timestamps_get(p_property_data, return spinel_decode_prop_nrf_802154_stat_timestamps_get(p_property_data,
property_data_len); property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET_IF_LARGER:
return spinel_decode_prop_nrf_802154_security_global_frame_counter_set_if_larger(
p_property_data,
property_data_len);
default: default:
NRF_802154_SPINEL_LOG_RAW("Unsupported property: %s(%u)\n", NRF_802154_SPINEL_LOG_RAW("Unsupported property: %s(%u)\n",
spinel_prop_key_to_cstr(property), spinel_prop_key_to_cstr(property),

View File

@ -40,6 +40,10 @@
#ifndef NRF_802154_SL_CONFIG_H__ #ifndef NRF_802154_SL_CONFIG_H__
#define NRF_802154_SL_CONFIG_H__ #define NRF_802154_SL_CONFIG_H__
#if NRF_802154_USE_INTERNAL_INCLUDES
#include "nrf_802154_sl_config_internal.h"
#endif
/** /**
* @def NRF_802154_SL_COEX_INITIALLY_ENABLED * @def NRF_802154_SL_COEX_INITIALLY_ENABLED
* *

View File

@ -41,10 +41,9 @@
#define NRF_802154_SL_PERIPHS_H__ #define NRF_802154_SL_PERIPHS_H__
#include <nrfx.h> #include <nrfx.h>
#if defined(DPPI_PRESENT)
#include "hal/nrf_dppi.h" #if NRF_802154_USE_INTERNAL_INCLUDES
#else #include "nrf_802154_sl_periphs_internal.h"
#include "hal/nrf_ppi.h"
#endif #endif
/** /**

View File

@ -65,6 +65,7 @@ extern "C" {
* Possible values: * Possible values:
* @ref NRF_802154_SL_TIMER_RET_SUCCESS * @ref NRF_802154_SL_TIMER_RET_SUCCESS
* @ref NRF_802154_SL_TIMER_RET_TOO_LATE * @ref NRF_802154_SL_TIMER_RET_TOO_LATE
* @ref NRF_802154_SL_TIMER_RET_TOO_DISTANT
* @ref NRF_802154_SL_TIMER_RET_NO_RESOURCES * @ref NRF_802154_SL_TIMER_RET_NO_RESOURCES
* @ref NRF_802154_SL_TIMER_RET_INACTIVE * @ref NRF_802154_SL_TIMER_RET_INACTIVE
* @ref NRF_802154_SL_TIMER_RET_BAD_REQUEST * @ref NRF_802154_SL_TIMER_RET_BAD_REQUEST
@ -83,6 +84,14 @@ typedef uint32_t nrf_802154_sl_timer_ret_t;
/**@brief Operation was requested too late to be performed in requested time. */ /**@brief Operation was requested too late to be performed in requested time. */
#define NRF_802154_SL_TIMER_RET_TOO_LATE 2U #define NRF_802154_SL_TIMER_RET_TOO_LATE 2U
/**@brief The trigger time for the requested operation is too distant.
*
* Some platforms have a limitation to how far in the future operation can be
* scheduled. This result may happen for @ref nrf_802154_sl_timer_add with
* @ref nrf_802154_sl_timer_t::trigger_time containing a value too far from `now`.
*/
#define NRF_802154_SL_TIMER_RET_TOO_DISTANT 3U
/**@brief There were no available resources required to schedule requested activity. /**@brief There were no available resources required to schedule requested activity.
* *
* This result may happen for @ref nrf_802154_sl_timer_add with * This result may happen for @ref nrf_802154_sl_timer_add with
@ -91,10 +100,10 @@ typedef uint32_t nrf_802154_sl_timer_ret_t;
* some hardware resources like PPI/DPPI channels, EGU channels, timer compare channels * some hardware resources like PPI/DPPI channels, EGU channels, timer compare channels
* (implementation dependent) were needed, but they were unavailable. * (implementation dependent) were needed, but they were unavailable.
*/ */
#define NRF_802154_SL_TIMER_RET_NO_RESOURCES 3U #define NRF_802154_SL_TIMER_RET_NO_RESOURCES 4U
/**@brief The timer was inactive at the moment of requested operation. */ /**@brief The timer was inactive at the moment of requested operation. */
#define NRF_802154_SL_TIMER_RET_INACTIVE 4U #define NRF_802154_SL_TIMER_RET_INACTIVE 5U
/**@brief Type representing a timer. */ /**@brief Type representing a timer. */
typedef struct nrf_802154_sl_timer_s nrf_802154_sl_timer_t; typedef struct nrf_802154_sl_timer_s nrf_802154_sl_timer_t;
@ -115,6 +124,11 @@ typedef uint8_t nrf_802154_sl_timer_action_type_t;
/**@brief Timer action type mask allowing triggering a hardware task. */ /**@brief Timer action type mask allowing triggering a hardware task. */
#define NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE (1U << 1) #define NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE (1U << 1)
/**
* @brief Special value that indicates that (D)PPI configuration is incomplete.
*/
#define NRF_802154_SL_TIMER_INVALID_PPI_CHANNEL UINT32_MAX
/**@brief Structure that represents private fields of a timer required by the implementation. */ /**@brief Structure that represents private fields of a timer required by the implementation. */
typedef struct typedef struct
{ {
@ -178,6 +192,11 @@ struct nrf_802154_sl_timer_s
* of these resources. Moreover, the API user must keep the hardware bindings enabled * of these resources. Moreover, the API user must keep the hardware bindings enabled
* and functional until the requested hardware task is triggered or until the timer * and functional until the requested hardware task is triggered or until the timer
* is successfully removed. * is successfully removed.
*
* A special value of @ref NRF_802154_SL_TIMER_INVALID_PPI_CHANNEL can be set. In this
* case, the binding creation is postponed and the user is required to use the
* @ref nrf_802154_sl_timer_update_ppi to complete the configuration. Must do so
* before @c trigger_time expires.
*/ */
uint32_t ppi_channel; uint32_t ppi_channel;
} hardware; } hardware;
@ -268,6 +287,25 @@ nrf_802154_sl_timer_ret_t nrf_802154_sl_timer_add(nrf_802154_sl_timer_t * p_time
*/ */
nrf_802154_sl_timer_ret_t nrf_802154_sl_timer_remove(nrf_802154_sl_timer_t * p_timer); nrf_802154_sl_timer_ret_t nrf_802154_sl_timer_remove(nrf_802154_sl_timer_t * p_timer);
/**@brief Updates the (D)PPI channel to be triggered.
*
* @param p_timer Pointer to a timer instance to be updated.
* @param ppi_chn Identifier of (D)PPI channel to be triggered at @c trigger_time.
*
* @retval NRF_802154_SL_TIMER_RET_SUCCESS
* The (D)PPI channel was updated and it was done on time, i.e. before specified
* trigger time.
* @retval NRF_802154_SL_TIMER_RET_TOO_LATE
* It has been detected that the timer has already fired and because of this the update
* could not complete at all or did not complete on time. Nevertheless, the (D)PPI may
* have been triggered, but it cannot be stated reliably.
* @retval NRF_802154_SL_TIMER_RET_BAD_REQUEST
* A user passed invalid parameters in @p p_timer, e.g. @c action_type does not contain
* @ref NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE.
*/
nrf_802154_sl_timer_ret_t nrf_802154_sl_timer_update_ppi(nrf_802154_sl_timer_t * p_timer,
uint32_t ppi_chn);
/** /**
*@} *@}
**/ **/

View File

@ -164,6 +164,8 @@ typedef void (* rsch_dly_ts_started_callback_t)(rsch_dly_ts_id_t dly_ts_id);
typedef struct typedef struct
{ {
uint64_t trigger_time; ///< Trigger time of the timeslot start, in microseconds. uint64_t trigger_time; ///< Trigger time of the timeslot start, in microseconds.
bool ppi_trigger_en; ///< Enable the (D)PPI triggering after the start of the timeslot.
uint32_t ppi_trigger_dly; ///< Time delta between @p trigger_time and the moment of (D)PPI triggering.
rsch_prio_t prio; ///< Priority level required for the delayed timeslot. rsch_prio_t prio; ///< Priority level required for the delayed timeslot.
rsch_dly_ts_op_t op; ///< Operation to be performed in the requested timeslot. rsch_dly_ts_op_t op; ///< Operation to be performed in the requested timeslot.
rsch_dly_ts_type_t type; ///< Type of the requested timeslot. rsch_dly_ts_type_t type; ///< Type of the requested timeslot.
@ -282,6 +284,19 @@ bool nrf_802154_rsch_delayed_timeslot_request(const rsch_dly_ts_param_t * p_dly_
*/ */
bool nrf_802154_rsch_delayed_timeslot_cancel(rsch_dly_ts_id_t dly_ts_id, bool handler); bool nrf_802154_rsch_delayed_timeslot_cancel(rsch_dly_ts_id_t dly_ts_id, bool handler);
/**
* @brief Updates the id of (D)PPI channel to be triggered in the current timeslot.
*
* The update must be done after the start of the timeslot but earlier than @c ppi_trigger_dly.
* If updating does not complete on time, (D)PPI triggering may not be performed.
*
* @retval true (D)PPI channel has been updated and it was done on time, i.e. before
* target trigger time.
* @retval false Update could not complete or did not complete on time. Nevertheless,
* the (D)PPI may have been triggered, but it cannot be stated reliably.
*/
bool nrf_802154_rsch_delayed_timeslot_ppi_update(uint32_t ppi_channel);
/** /**
* @brief Updates priority of a requested delayed timeslot. * @brief Updates priority of a requested delayed timeslot.
* *

View File

@ -180,3 +180,10 @@ bool nrf_802154_rsch_delayed_timeslot_priority_update(rsch_dly_ts_id_t dly_ts_id
return false; return false;
} }
bool nrf_802154_rsch_delayed_timeslot_ppi_update(uint32_t ppi_channel)
{
(void)ppi_channel;
return false;
}