diff --git a/drivers/nrf_802154/CMakeLists.txt b/drivers/nrf_802154/CMakeLists.txt index 5fbcb20..636c7f8 100644 --- a/drivers/nrf_802154/CMakeLists.txt +++ b/drivers/nrf_802154/CMakeLists.txt @@ -39,3 +39,7 @@ add_subdirectory(driver) add_subdirectory(sl) add_subdirectory(serialization) + +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/internal/CMakeLists.txt) + add_subdirectory(internal) +endif () diff --git a/drivers/nrf_802154/driver/CMakeLists.txt b/drivers/nrf_802154/driver/CMakeLists.txt index 28f0340..b010429 100644 --- a/drivers/nrf_802154/driver/CMakeLists.txt +++ b/drivers/nrf_802154/driver/CMakeLists.txt @@ -106,6 +106,12 @@ if (SL_OPENSOURCE) ) 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) target_compile_definitions(nrf-802154-driver-interface INTERFACE diff --git a/drivers/nrf_802154/driver/include/nrf_802154.h b/drivers/nrf_802154/driver/include/nrf_802154.h index 6f71d31..0fcad0e 100644 --- a/drivers/nrf_802154/driver/include/nrf_802154.h +++ b/drivers/nrf_802154/driver/include/nrf_802154.h @@ -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); +/** + * @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. * diff --git a/drivers/nrf_802154/driver/include/nrf_802154_config.h b/drivers/nrf_802154/driver/include/nrf_802154_config.h index a1c4865..b00fe19 100644 --- a/drivers/nrf_802154/driver/include/nrf_802154_config.h +++ b/drivers/nrf_802154/driver/include/nrf_802154_config.h @@ -41,6 +41,10 @@ #include +#if NRF_802154_USE_INTERNAL_INCLUDES +#include "nrf_802154_config_internal.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -198,21 +202,6 @@ extern "C" { #define NRF_802154_RX_BUFFERS 16 #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 * @@ -245,12 +234,11 @@ extern "C" { * * 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 - * and @ref NRF_802154_DISABLE_BCC_MATCHING is 0. + * This option can be enabled when @ref NRF_802154_FRAME_TIMESTAMP_ENABLED is 1. */ #ifndef 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 /** @@ -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 diff --git a/drivers/nrf_802154/driver/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c b/drivers/nrf_802154/driver/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c index 62d20b3..ab03dba 100644 --- a/drivers/nrf_802154/driver/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c +++ b/drivers/nrf_802154/driver/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c @@ -474,13 +474,11 @@ static bool encryption_prepare(const nrf_802154_frame_parser_data_t * p_ack_data * @section Enhanced ACK generation **************************************************************************************************/ -static void fcf_process(const nrf_802154_frame_parser_data_t * p_frame_data, - uint8_t * p_bytes_written) +static void fcf_process(const nrf_802154_frame_parser_data_t * p_frame_data) { // Set Frame Control field bits. // Some of them might require correction when higher parse level is available - *p_bytes_written = frame_control_set(p_frame_data, false); - m_ack[PHR_OFFSET] += *p_bytes_written; + m_ack[PHR_OFFSET] += frame_control_set(p_frame_data, false); bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data, 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; } -static void dst_addr_process(const nrf_802154_frame_parser_data_t * p_frame_data, - uint8_t * p_bytes_written) -{ - // Set valid sequence number in ACK frame. - *p_bytes_written = sequence_number_set(p_frame_data); - m_ack[PHR_OFFSET] += *p_bytes_written; - - // Set destination address and PAN ID. - *p_bytes_written = destination_set(p_frame_data, &m_ack_data); - m_ack[PHR_OFFSET] += *p_bytes_written; - - bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data, - m_ack[PHR_OFFSET] + PHR_SIZE, - PARSE_LEVEL_DST_ADDRESSING_END); - - assert(result); - (void)result; -} - static void addr_end_process(const nrf_802154_frame_parser_data_t * p_frame_data) { + // Set 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. source_set(); @@ -532,15 +516,16 @@ static void addr_end_process(const nrf_802154_frame_parser_data_t * p_frame_data (void)result; } -static bool aux_sec_hdr_process(const nrf_802154_frame_parser_data_t * p_frame_data, - uint8_t * p_bytes_written) +static bool aux_sec_hdr_process(const nrf_802154_frame_parser_data_t * p_frame_data) { - 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; } - 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, 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; } -static void ie_process(const nrf_802154_frame_parser_data_t * p_frame_data, - uint8_t * p_bytes_written) +static void ie_process(const nrf_802154_frame_parser_data_t * p_frame_data) { // Set IE header. ie_header_set(mp_ie_data, m_ie_data_len, &m_ack_data); m_ack[PHR_OFFSET] += m_ie_data_len; // Terminate the IE header if needed. - *p_bytes_written = ie_header_terminate(mp_ie_data, m_ie_data_len, &m_ack_data); - m_ack[PHR_OFFSET] += *p_bytes_written + FCS_SIZE; + m_ack[PHR_OFFSET] += ie_header_terminate(mp_ie_data, m_ie_data_len, &m_ack_data) + FCS_SIZE; bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data, 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, bool * p_processing_done) { - uint8_t bytes_written = 0U; - nrf_802154_frame_parser_level_t frame_parse_level = nrf_802154_frame_parser_parse_level_get( p_frame_data); nrf_802154_frame_parser_level_t ack_parse_level = nrf_802154_frame_parser_parse_level_get( @@ -592,13 +573,7 @@ static uint8_t * ack_process( if ((frame_parse_level >= PARSE_LEVEL_FCF_OFFSETS) && (ack_parse_level < PARSE_LEVEL_FCF_OFFSETS)) { - fcf_process(p_frame_data, &bytes_written); - } - - if ((frame_parse_level >= PARSE_LEVEL_DST_ADDRESSING_END) && - (ack_parse_level < PARSE_LEVEL_DST_ADDRESSING_END)) - { - dst_addr_process(p_frame_data, &bytes_written); + fcf_process(p_frame_data); } 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) && (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 *p_processing_done = true; return NULL; } - ie_process(p_frame_data, &bytes_written); + ie_process(p_frame_data); } if (frame_parse_level == PARSE_LEVEL_FULL) diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c index a2989b9..e85cc69 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c @@ -271,6 +271,7 @@ static void random_backoff_start(void) rsch_dly_ts_param_t backoff_ts_param = { .trigger_time = nrf_802154_sl_timer_current_time_get() + backoff_us, + .ppi_trigger_en = false, .op = RSCH_DLY_TS_OP_CSMACA, .type = RSCH_DLY_TS_TYPE_RELAXED, .started_callback = frame_transmit, diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c index 6a78b3a..81a3d72 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c @@ -62,14 +62,19 @@ #include "nrf_802154_sl_utils.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 -/* The following time is the sum of 70us RTC_IRQHandler processing time, 40us of time that elapses - * from the moment a board starts transmission to the moment other boards (e.g. sniffer) are able - * to detect that frame and in case of TX - 93us that accounts for a delay of yet unknown origin. - */ -#define TX_SETUP_TIME 203u ///< 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. +#if defined(NRF52_SERIES) +#define TX_SETUP_TIME_MAX 270u ///< Maximum time needed to prepare TX procedure [us]. It does not include TX ramp-up time. +#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_MAX 360u ///< Maximum time needed to prepare TX procedure [us]. It does not include TX 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. @@ -768,7 +773,7 @@ bool nrf_802154_delayed_trx_transmit(uint8_t * p if (p_dly_tx_data != NULL) { - tx_time -= TX_SETUP_TIME; + tx_time -= TX_SETUP_TIME_MAX; tx_time -= TX_RAMP_UP_TIME; 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 = { .trigger_time = tx_time, + .ppi_trigger_en = true, + .ppi_trigger_dly = TX_SETUP_TIME_MAX, .prio = RSCH_PRIO_TX, .op = RSCH_DLY_TS_OP_DTX, .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) { - rx_time -= RX_SETUP_TIME; + rx_time -= RX_SETUP_TIME_MAX; rx_time -= RX_RAMP_UP_TIME; 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.channel = channel; @@ -828,6 +836,8 @@ bool nrf_802154_delayed_trx_receive(uint64_t rx_time, rsch_dly_ts_param_t dly_ts_param = { .trigger_time = rx_time, + .ppi_trigger_en = true, + .ppi_trigger_dly = RX_SETUP_TIME_MAX, .prio = RSCH_PRIO_IDLE_LISTENING, .op = RSCH_DLY_TS_OP_DRX, .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; uint64_t drx_time_to_start = UINT64_C(0xffffffff); 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++) { @@ -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, &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) { min_time_to_start = 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; } } diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_filter.c b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_filter.c index d006536..f56517d 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_filter.c +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_filter.c @@ -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 * 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. * If both of those conditions are not met, the function returns * NRF_802154_RX_ERROR_INVALID_DEST_ADDR. - * Otherwise, this function returns NRF_802154_RX_ERROR_NONE and inserts offset of addressing - * fields end to @p p_num_bytes. + * Otherwise, this function returns NRF_802154_RX_ERROR_NONE. * * @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. * * @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 * 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, - uint8_t * p_num_bytes, uint8_t frame_type) { 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)) { 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; 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; 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_EXTENDED: - *p_num_bytes = PANID_CHECK_OFFSET; - result = NRF_802154_RX_ERROR_NONE; + result = NRF_802154_RX_ERROR_NONE; break; 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 * NRF_802154_RX_ERROR_INVALID_FRAME. - * Otherwise, this function returns NRF_802154_RX_ERROR_NONE and inserts offset of addressing - * fields end to @p p_num_bytes. + * Otherwise, this function returns NRF_802154_RX_ERROR_NONE. * * @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. * * @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 * 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, - uint8_t * p_num_bytes, uint8_t frame_type) { nrf_802154_rx_error_t result; @@ -241,8 +232,7 @@ static nrf_802154_rx_error_t dst_addressing_end_offset_get_2015( } else { - *p_num_bytes = end_offset; - result = NRF_802154_RX_ERROR_NONE; + result = NRF_802154_RX_ERROR_NONE; } } 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 * 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[out] p_num_bytes Offset of addressing fields end. * @param[in] frame_type Type of 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 * 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, - uint8_t * p_num_bytes, uint8_t frame_type, 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_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; 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; 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_frame_parser_data_t * p_frame_data, - uint8_t * p_num_bytes) + const nrf_802154_frame_parser_data_t * p_frame_data, + nrf_802154_filter_mode_t filter_mode) { - nrf_802154_rx_error_t result = NRF_802154_RX_ERROR_INVALID_FRAME; - uint8_t frame_type = nrf_802154_frame_parser_frame_type_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); + 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_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: - if ((psdu_length < IMM_ACK_LENGTH) || (psdu_length > MAX_PACKET_SIZE)) - { - result = NRF_802154_RX_ERROR_INVALID_LENGTH; - break; - } + assert(nrf_802154_frame_parser_parse_level_get(p_frame_data) >= PARSE_LEVEL_FCF_OFFSETS); - if (!nrf_802154_frame_parser_valid_data_extend(p_frame_data, - *p_num_bytes, - PARSE_LEVEL_FCF_OFFSETS)) - { - result = NRF_802154_RX_ERROR_INVALID_FRAME; - break; - } + if ((psdu_length < IMM_ACK_LENGTH) || (psdu_length > MAX_PACKET_SIZE)) + { + return NRF_802154_RX_ERROR_INVALID_LENGTH; + } - if (!frame_type_and_version_filter(frame_type, frame_version)) - { - result = NRF_802154_RX_ERROR_INVALID_FRAME; - break; - } + if (!frame_type_and_version_filter(frame_type, frame_version)) + { + return NRF_802154_RX_ERROR_INVALID_FRAME; + } - if (!dst_addressing_may_be_present(frame_type)) - { - result = NRF_802154_RX_ERROR_NONE; - break; - } + if (dst_addressing_may_be_present(frame_type)) + { + result = dst_addressing_fcf_check(p_frame_data, + frame_type, + frame_version); + } + } - result = dst_addressing_end_offset_get(p_frame_data, - p_num_bytes, - frame_type, - frame_version); - break; + if (result != NRF_802154_RX_ERROR_NONE) + { + return result; + } - default: - if (!nrf_802154_frame_parser_valid_data_extend(p_frame_data, - *p_num_bytes, - PARSE_LEVEL_DST_ADDRESSING_END)) - { - result = NRF_802154_RX_ERROR_INVALID_FRAME; - break; - } + if (filter_mode & NRF_802154_FILTER_MODE_DST_ADDR) + { + assert(nrf_802154_frame_parser_parse_level_get( + p_frame_data) >= PARSE_LEVEL_DST_ADDRESSING_END); - result = dst_addr_check(p_frame_data); - break; + result = dst_addr_check(p_frame_data); } return result; diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_filter.h b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_filter.h index a47c91a..3ed1873 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_filter.h +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_filter.h @@ -53,26 +53,42 @@ * @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. * - * This function is called a few times for each received frame. The first call is after the FCF - * is received (PSDU length is 2 and @p p_num_bytes value is 3). The subsequent calls are performed - * when the number of bytes requested by the previous call is available. The iteration ends - * when the function does not request any more bytes to check. - * If the verified part of the function is correct, this function returns true and sets - * @p p_num_bytes to the number of bytes that should be available in PSDU during the next iteration. - * If the frame is correct and there is nothing more to check, this function returns true - * and does not modify the @p p_num_bytes value. If the verified frame is incorrect, this function - * returns false and the @p p_num_bytes value is undefined. + * This function filters the given frame within the scope specified by @p filter_mode argument. + * In the @c NRF_802154_FILTER_MODE_FCF filter mode the function will reject all frames that do + * not satisfy requirements that can be determined by parsing the FCF field, such as unsupported + * frame versions, unsupported frame types, or when destination addressing is not present in the + * frame and the node is not a coordinator. + * In the @c NRF_802154_FILTER_MODE_DST_ADDR filter mode the function will only check if the + * destination address matches the address of the current node. If the incoming frame has no address + * and the node is a coordinator the frame will be accepted. No validation of FCF is performend. * - * @param[inout] p_frame_data Pointer to a frame parser data of the frame to be filtered. - * The frame filter may increase the frame parse level to either - * PARSE_LEVEL_FCF_OFFSETS or PARSE_LEVEL_DST_ADDRESSING_END. - * @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 - * unchanged if no more iterations are to be performed during - * the filtering of the given frame. + * To perform a full filtering procedure it is necessary to call this function on the incoming frame + * with both @c NRF_802154_FILTER_MODE_FCF and @c NRF_802154_FILTER_MODE_DST_ADDR scopes in + * two iterations, or both at once using @c NRF_802154_FILTER_MODE_ALL. + * + * @param[in] p_frame_data Pointer to a frame parser data of the frame to be filtered. + * @param[in] filter_mode The filtering scope that should be performed by the function. * * @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. @@ -80,8 +96,8 @@ * mismatches the address of this node. */ nrf_802154_rx_error_t nrf_802154_filter_frame_part( - nrf_802154_frame_parser_data_t * p_frame_data, - uint8_t * p_num_bytes); + const nrf_802154_frame_parser_data_t * p_frame_data, + nrf_802154_filter_mode_t filter_mode); /** *@} diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_pib.h b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_pib.h index 0a481f9..0c7e4d2 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_pib.h +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_pib.h @@ -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); +/** + * @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. * diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_pib_ram.c b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_pib_ram.c index b8e7f17..6fe89f6 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_pib_ram.c +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_pib_ram.c @@ -36,6 +36,7 @@ #include "nrf_802154_config.h" #include "nrf_802154_const.h" +#include "nrf_802154_sl_atomics.h" #include #include @@ -222,6 +223,23 @@ void nrf_802154_security_pib_global_frame_counter_set(uint32_t 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( uint32_t * p_frame_counter, nrf_802154_key_id_t * p_id) diff --git a/drivers/nrf_802154/driver/src/nrf_802154.c b/drivers/nrf_802154/driver/src/nrf_802154.c index 2b7d0e2..42e1e16 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154.c +++ b/drivers/nrf_802154/driver/src/nrf_802154.c @@ -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); } +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) { return nrf_802154_security_pib_key_store(p_key); diff --git a/drivers/nrf_802154/driver/src/nrf_802154_core.c b/drivers/nrf_802154/driver/src/nrf_802154_core.c index 9c5fbbd..5111fea 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_core.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_core.c @@ -158,9 +158,6 @@ static uint32_t m_rx_window_id; #if !NRF_802154_FRAME_TIMESTAMP_ENABLED #error NRF_802154_FRAME_TIMESTAMP_ENABLED == 0 when NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED != 0 #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 #if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED @@ -197,6 +194,19 @@ static void state_set(radio_state_t 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. */ static void rx_data_clear(void) { @@ -337,7 +347,6 @@ static void transmit_ack_started_notify() nrf_802154_tx_ack_started(mp_ack); } -#if !NRF_802154_DISABLE_BCC_MATCHING /** Notify that reception of a frame has started. */ static void receive_started_notify(void) { @@ -346,8 +355,6 @@ static void receive_started_notify(void) nrf_802154_core_hooks_rx_started(p_frame); } -#endif - /** Notify MAC layer that a frame was transmitted. */ 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; } -/** 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; @@ -1029,11 +1047,31 @@ static void rx_init(void) (void)nrf_802154_tx_power_split_pib_power_get(&split_power); nrf_802154_trx_receive_frame(BCC_INIT / 8U, + ru_tr_mode, m_trx_receive_frame_notifications_mask, &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 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 #if (NRF_802154_FRAME_TIMESTAMP_ENABLED) @@ -1061,7 +1099,9 @@ static void rx_init(void) } /** 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( 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; nrf_802154_trx_transmit_frame(nrf_802154_tx_work_buffer_get(p_data), + rampup_trigg_mode, cca, &m_tx_power, 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; } @@ -1345,15 +1401,15 @@ static void on_preconditions_approved(radio_state_t state) break; case RADIO_STATE_RX: - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); break; 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; case RADIO_STATE_TX: - (void)tx_init(mp_tx_data, false); + (void)tx_init(mp_tx_data, TRX_RAMP_UP_SW_TRIGGER, false); break; 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); } -#if !NRF_802154_DISABLE_BCC_MATCHING uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - uint8_t prev_num_data_bytes; - uint8_t num_data_bytes; - nrf_802154_rx_error_t filter_result; - bool frame_accepted = true; + uint8_t next_bcc; + nrf_802154_filter_mode_t filter_mode; + bool parse_result; + 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); - if (!m_flags.frame_filtered) + switch (prev_level) { - filter_result = nrf_802154_filter_frame_part(&m_current_rx_frame_data, - &num_data_bytes); + case PARSE_LEVEL_NONE: + 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) - { - if (num_data_bytes != prev_num_data_bytes) - { - bcc = num_data_bytes; - } - else - { - m_flags.frame_filtered = true; + case PARSE_LEVEL_FCF_OFFSETS: + parse_level = PARSE_LEVEL_DST_ADDRESSING_END; + filter_mode = NRF_802154_FILTER_MODE_DST_ADDR; + should_filter = true; + break; - /* Request boosted preconditions */ - nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_RX); + case PARSE_LEVEL_DST_ADDRESSING_END: + parse_level = PARSE_LEVEL_SEC_CTRL_OFFSETS; + break; - /* Request next bcc match event to occur when basic data necessary for Ack - * generation is received. */ - m_flags.frame_parsed = false; - nrf_802154_ack_generator_reset(); + case PARSE_LEVEL_SEC_CTRL_OFFSETS: + parse_level = PARSE_LEVEL_AUX_SEC_HDR_END; + break; - bcc = PHR_SIZE + - nrf_802154_frame_parser_addressing_end_offset_get(&m_current_rx_frame_data) + - SECURITY_CONTROL_SIZE; - } - } - 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 + default: + /* Parsing completed. Nothing more to be done. */ + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return 0; } - 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( - mp_current_rx_buffer->data[0], - ack_is_requested(mp_current_rx_buffer->data)))) + should_filter = false; + filter_result = NRF_802154_RX_ERROR_INVALID_FRAME; + } + + 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; @@ -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 avoid hard reset of radio during TX ACK phase due to timeslot end, // 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 // 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 && - m_flags.frame_parsed && nrf_802154_frame_parser_ar_bit_is_set(&m_current_rx_frame_data) && 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); - return bcc; + return next_bcc; } -#endif - void nrf_802154_trx_go_idle_finished(void) { 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(); // 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); 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); nrf_802154_trx_receive_frame(BCC_INIT / 8U, + TRX_RAMP_UP_SW_TRIGGER, m_trx_receive_frame_notifications_mask, &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()); #endif -#else - // With BCC matching disabled trx module will re-arm automatically -#endif - #if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED update_total_times_on_receive_end(listening_start_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); - 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 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]); #endif -#if NRF_802154_DISABLE_BCC_MATCHING - uint8_t num_data_bytes = PHR_SIZE + FCF_SIZE; - uint8_t prev_num_data_bytes = 0; - nrf_802154_rx_error_t filter_result; + 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); - // Frame filtering - while (num_data_bytes != prev_num_data_bytes) + if (parse_result && !m_flags.frame_filtered) { - prev_num_data_bytes = num_data_bytes; - - // Keep checking consecutive parts of the frame header. - filter_result = nrf_802154_filter_frame_part(&m_current_rx_frame_data, &num_data_bytes); + filter_result = nrf_802154_filter_frame_part(&m_current_rx_frame_data, + NRF_802154_FILTER_MODE_ALL); 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()) { 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(); - 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); + bool send_ack = false; if (m_flags.frame_filtered && parse_result && @@ -2074,7 +2105,7 @@ void nrf_802154_trx_receive_frame_received(void) mp_current_rx_buffer->free = false; state_set(RADIO_STATE_RX); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); 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; state_set(RADIO_STATE_RX); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); received_frame_notify_and_nesting_allow(p_received_data); } @@ -2108,14 +2139,14 @@ void nrf_802154_trx_receive_frame_received(void) // Find new buffer 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); } else { // 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 // consecutively received frames). request_preconditions_for_state(m_state); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); -#if NRF_802154_DISABLE_BCC_MATCHING - 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 + receive_failed_notify(filter_result); } 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); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); 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); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); 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 state_set(RADIO_STATE_RX); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); 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; state_set(RADIO_STATE_RX); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); transmitted_frame_notify(p_ack_buffer->data, // phr + psdu 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); state_set(RADIO_STATE_RX); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); cca_notify(channel_was_idle); @@ -2500,7 +2524,7 @@ void nrf_802154_trx_transmit_frame_ccabusy(void) #endif state_set(RADIO_STATE_RX); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); 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()); 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)); @@ -2579,8 +2603,8 @@ void nrf_802154_core_deinit(void) mpsl_fem_cleanup(); - nrf_802154_irq_disable(RADIO_IRQn); - nrf_802154_irq_clear_pending(RADIO_IRQn); + nrf_802154_irq_disable(nrfx_get_irq_number(NRF_RADIO)); + nrf_802154_irq_clear_pending(nrfx_get_irq_number(NRF_RADIO)); 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 = make_trx_frame_receive_notification_mask(); + m_rx_window_id = id; 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 @@ -2716,13 +2753,14 @@ bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl, m_tx_power = p_params->tx_power; // 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 (!result) { state_set(RADIO_STATE_RX); - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); } } else @@ -2908,7 +2946,7 @@ bool nrf_802154_core_channel_update(req_originator_t req_orig) case RADIO_STATE_RX: if (current_operation_terminate(NRF_802154_TERM_802154, req_orig, true)) { - rx_init(); + rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL); } break; diff --git a/drivers/nrf_802154/driver/src/nrf_802154_critical_section.c b/drivers/nrf_802154/driver/src/nrf_802154_critical_section.c index d49f9e0..1f439c8 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_critical_section.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_critical_section.c @@ -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)) { - 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)) { - 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; } - 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); - active_priority = nrf_802154_irq_priority_get(irq_number); + assert(irq_number >= SVCall_IRQn); + + active_priority = NVIC_GetPriority(irq_number); return active_priority; } diff --git a/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c b/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c index e5d7a50..2e0351a 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c @@ -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; 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; } @@ -347,7 +348,8 @@ bool nrf_802154_encrypt_tx_setup( assert(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; } diff --git a/drivers/nrf_802154/driver/src/nrf_802154_nrfx_addons.h b/drivers/nrf_802154/driver/src/nrf_802154_nrfx_addons.h index d5770cb..d4cf6ec 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_nrfx_addons.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_nrfx_addons.h @@ -38,20 +38,18 @@ #include "nrfx.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 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 255/ED_RSSISCALE. */ -#if defined (NRF52840_XXAA) -#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. -#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. +#if 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 -#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 #define EDSAMPLE_MIN_REPORTED_VALUE (PHY_MIN_RECEIVER_SENSITIVITY - ED_RSSIOFFS + 10) ///< Minimal reported EDSAMPLE value (reported as 0) diff --git a/drivers/nrf_802154/driver/src/nrf_802154_peripherals.h b/drivers/nrf_802154/driver/src/nrf_802154_peripherals.h index 3f71829..c4d3a3f 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_peripherals.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_peripherals.h @@ -49,8 +49,10 @@ #include "nrf_802154_peripherals_nrf52.h" #elif defined(NRF5340_XXAA) #include "nrf_802154_peripherals_nrf53.h" -#else -#error Unsupported chip family +#endif + +#ifdef NRF_802154_USE_INTERNAL_INCLUDES +#include "nrf_802154_peripherals_internal.h" #endif #ifdef __cplusplus @@ -95,27 +97,6 @@ extern "C" { #define NRF_802154_TIMER_INSTANCE \ 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 * @@ -156,8 +137,7 @@ extern "C" { */ #ifndef NRF_802154_TIMERS_USED_MASK #define NRF_802154_TIMERS_USED_MASK ((1 << NRF_802154_HIGH_PRECISION_TIMER_INSTANCE_NO) | \ - (1 << NRF_802154_TIMER_INSTANCE_NO) | \ - (1 << NRF_802154_COUNTER_TIMER_INSTANCE_NO)) + (1 << NRF_802154_TIMER_INSTANCE_NO)) #endif // NRF_802154_TIMERS_USED_MASK /** diff --git a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_alloc.c b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_alloc.c index 5085106..6b53360 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_alloc.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_alloc.c @@ -51,10 +51,10 @@ #include "mpsl.h" #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_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_GR_USED_MSK NRF_802154_DPPI_GROUPS_USED_MASK #else diff --git a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf52.h b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf52.h index 969ca51..1730e22 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf52.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf52.h @@ -111,12 +111,30 @@ extern "C" { #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 * * 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. + * The peripheral is shared with @ref NRF_802154_PPI_RADIO_RAMP_UP_TRIGG. * */ #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 #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 * * The PPI channel that connects RADIO_SYNC event to EGU_SYNC task. * 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 #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 \ (1 << NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC) -#endif // NRF_802154_DISABLE_BCC_MATCHING - #ifdef NRF_802154_FRAME_TIMESTAMP_ENABLED /** @@ -341,6 +314,7 @@ extern "C" { */ #ifndef NRF_802154_PPI_CHANNELS_USED_MASK #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_TIMER_START) | \ (1 << NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR) | \ diff --git a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf53.h b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf53.h index f849b89..c0b708b 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf53.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf53.h @@ -93,6 +93,20 @@ extern "C" { #define NRF_802154_EGU_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 * @@ -112,6 +126,14 @@ extern "C" { #define NRF_802154_RTC_INSTANCE_NO 2 #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 * @@ -239,6 +261,15 @@ extern "C" { #define NRF_802154_DPPI_RADIO_TEST_MODE_USED_MASK 0U #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 * @@ -268,6 +299,7 @@ extern "C" { (1UL << NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN) | \ (1UL << NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC) | \ (1UL << NRF_802154_DPPI_RADIO_CCAIDLE) | \ + (1UL << NRF_802154_DPPI_RADIO_HW_TRIGGER) | \ NRF_802154_DPPI_RADIO_TEST_MODE_USED_MASK | \ NRF_802154_DPPI_TIMESTAMPS_USED_MASK) #endif // NRF_802154_DPPI_CHANNELS_USED_MASK diff --git a/drivers/nrf_802154/driver/src/nrf_802154_pib.c b/drivers/nrf_802154/driver/src/nrf_802154_pib.c index 43bca68..3f318d5 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_pib.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_pib.c @@ -160,13 +160,11 @@ static bool coex_rx_request_mode_is_supported(nrf_802154_coex_rx_request_mode_t 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: #endif case NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE: -#if !NRF_802154_DISABLE_BCC_MATCHING case NRF_802154_COEX_RX_REQUEST_MODE_DESTINED: -#endif result = true; 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_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; -#endif m_data.coex.tx_request_mode = NRF_802154_COEX_TX_REQUEST_MODE_ON_CCA_TOGGLE; #if NRF_802154_CSMA_CA_ENABLED diff --git a/drivers/nrf_802154/driver/src/nrf_802154_procedures_duration.h b/drivers/nrf_802154/driver/src/nrf_802154_procedures_duration.h index d6ffd53..9092100 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_procedures_duration.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_procedures_duration.h @@ -138,6 +138,15 @@ __STATIC_INLINE uint16_t nrf_802154_cca_before_tx_duration_get(void) 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) { // 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) { - us_time += PHY_US_TIME_FROM_SYMBOLS(A_TURNAROUND_TIME_SYMBOLS + - PHY_SHR_SYMBOLS + - PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE)); + us_time += nrf_802154_ack_duration_with_turnaround_get(); } return us_time; diff --git a/drivers/nrf_802154/driver/src/nrf_802154_rssi.c b/drivers/nrf_802154/driver/src/nrf_802154_rssi.c index 8415594..38cecd6 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_rssi.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_rssi.c @@ -99,7 +99,7 @@ int8_t nrf_802154_rssi_sample_temp_corr_value_get(uint8_t rssi_sample) return result; } -#elif defined(NRF5340_XXAA) +#else /** Macro for calculating x raised to the power of 2. */ #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; } -#else -#error Unsupported chip family #endif uint8_t nrf_802154_rssi_sample_corrected_get(uint8_t rssi_sample) diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx.c b/drivers/nrf_802154/driver/src/nrf_802154_trx.c index 34abeca..604aa7c 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx.c @@ -63,26 +63,26 @@ #include "nrf_802154_sl_ant_div.h" -#define EGU_SYNC_EVENT NRF_EGU_EVENT_TRIGGERED3 -#define EGU_SYNC_TASK NRF_EGU_TASK_TRIGGER3 -#define EGU_SYNC_INTMASK NRF_EGU_INT_TRIGGERED3 +#ifdef NRF_802154_USE_INTERNAL_INCLUDES +#include "nrf_802154_trx_internal.h" +#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) || \ 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_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 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 RADIO_BASE NRF_RADIO_BASE #elif defined(NRF5340_XXAA) -#define PPI_CCAIDLE_FEM 0 -#define RADIO_BASE NRF_RADIO_NS_BASE -#define FICR_BASE NRF_FICR_NS_BASE +#define PPI_CCAIDLE_FEM 0 +#define RADIO_BASE NRF_RADIO_NS_BASE +#define FICR_BASE NRF_FICR_NS_BASE #endif -#if NRF_802154_DISABLE_BCC_MATCHING -#define SHORT_ADDRESS_BCSTART 0UL -#else // NRF_802154_DISABLE_BCC_MATCHING #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. #define SHORTS_IDLE 0 @@ -130,6 +130,26 @@ void nrf_802154_radio_irq_handler(void); ///< Prototype required by internal RADIO IRQ handler #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. static const mpsl_fem_event_t m_activate_rx_cc0 = { @@ -176,20 +196,12 @@ static volatile trx_state_t m_trx_state; typedef struct { -#if !NRF_802154_DISABLE_BCC_MATCHING - bool psdu_being_received; ///< If PSDU is currently being received. - -#endif - - 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 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; + bool ccastarted_notif_en; + bool tx_started; ///< If the requested transmission has started. bool rssi_started; - volatile bool rssi_settled; } 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 bool m_transmit_with_cca; +static void timer_frequency_set_1mhz(void); + static void rxframe_finish_disable_ppis(void); static void rxack_finish_disable_ppis(void); static void txframe_finish_disable_ppis(bool cca); @@ -221,9 +235,7 @@ static void energy_detection_abort(void); void rx_flags_clear(void) { m_flags.missing_receive_buffer = false; -#if !NRF_802154_DISABLE_BCC_MATCHING - m_flags.psdu_being_received = false; -#endif // !NRF_802154_DISABLE_BCC_MATCHING + m_flags.psdu_being_received = false; } 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_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_prescaler_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_FREQ_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 + timer_frequency_set_1mhz(); } #if defined(NRF53_SERIES) @@ -290,13 +296,26 @@ static void yopan_158_workaround(void) #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. */ static void nrf_radio_reset(void) { 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, true); +#endif + + NRF_802154_TRX_RADIO_RESET_INTERNAL(); #if defined(NRF53_SERIES) yopan_158_workaround(); @@ -332,9 +351,11 @@ static void cca_configuration_update(void) static void irq_init(void) { #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 - nrf_802154_irq_enable(RADIO_IRQn); + nrf_802154_irq_enable(nrfx_get_irq_number(NRF_RADIO)); } 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()) { 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 +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) { m_trx_state = TRX_STATE_DISABLED; @@ -570,7 +618,11 @@ void nrf_802154_trx_enable(void) packet_conf.maxlen = MAX_PACKET_SIZE; 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); +#endif // Configure CRC 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 defined(RADIO_POWER_POWER_Msk) 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 */ 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_event_clear(NRF_802154_EGU_INSTANCE, EGU_SYNC_EVENT); #endif @@ -694,7 +754,9 @@ void nrf_802154_trx_disable(void) NRF_TIMER_SHORT_COMPARE1_STOP_MASK); 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); +#endif mpsl_fem_lna_configuration_clear(); mpsl_fem_pa_configuration_clear(); @@ -705,19 +767,10 @@ void nrf_802154_trx_disable(void) fem_power_down_now(); } -#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; -#endif + m_flags.psdu_being_received = false; m_flags.missing_receive_buffer = false; m_flags.rssi_started = false; -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - m_flags.tx_started = false; -#endif + m_flags.tx_started = false; 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) { -#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; -#endif // NRF_802154_DISABLE_BCC_MATCHING } 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, + nrf_802154_trx_ramp_up_trigger_mode_t rampup_trigg_mode, nrf_802154_trx_receive_notifications_t notifications_mask, 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 rx_flags_clear(); + + m_flags.rxstarted_notif_en = (notifications_mask & TRX_RECEIVE_NOTIFICATION_STARTED) != 0U; + // Clear the RSSI measurement flag. 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); // Set BCC -#if !NRF_802154_DISABLE_BCC_MATCHING assert(bcc != 0U); nrf_radio_bcc_set(NRF_RADIO, bcc * 8U); -#else - assert(bcc == 0U); - (void)bcc; -#endif // !NRF_802154_DISABLE_BCC_MATCHING // Enable IRQs -#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR); 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); ints_to_enable |= NRF_RADIO_INT_BCMATCH_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK); 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); - ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY); + ints_to_enable |= NRF_RADIO_INT_READY_MASK; } bool allow_sync_swi = false; @@ -1037,7 +1077,7 @@ void nrf_802154_trx_receive_frame(uint8_t bcc, if (allow_sync_swi) { -#if (NRF_802154_DISABLE_BCC_MATCHING || !defined(RADIO_INTENSET_SYNC_Msk)) +#if !defined(RADIO_INTENSET_SYNC_Msk) assert(false); #else // 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_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 -#if NRF_802154_DISABLE_BCC_MATCHING -#error Configuration unsupported anymore -#endif // NRF_802154_DISABLE_BCC_MATCHING - nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, true); + nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, rampup_trigg_mode, 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); } @@ -1128,7 +1163,7 @@ void nrf_802154_trx_receive_ack(void) fem_for_lna_set(); 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(); @@ -1159,7 +1194,9 @@ bool nrf_802154_trx_rssi_measure(void) m_flags.rssi_settled = true; } +#if defined(RADIO_EVENTS_RSSIEND_EVENTS_RSSIEND_Msk) nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND); +#endif nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RSSISTART); 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) { +#if defined(RADIO_EVENTS_RSSIEND_EVENTS_RSSIEND_Msk) 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, + nrf_802154_trx_ramp_up_trigger_mode_t rampup_trigg_mode, bool cca, const nrf_802154_fal_tx_power_split_t * p_tx_power, 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_transmit_with_cca = cca; + m_flags.ccastarted_notif_en = false; + txpower_set(p_tx_power->radio_tx_power); 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); 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) { 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) { 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); -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; m_flags.tx_started = false; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED nrf_radio_int_enable(NRF_RADIO, ints_to_enable); fem_for_tx_set(cca, &p_tx_power->fem); 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); } @@ -1330,9 +1384,7 @@ bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_ nrf_802154_trx_antenna_update(); 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); -#endif // Set PPIs 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) { - uint32_t ints_to_enable = NRF_RADIO_INT_PHYEND_MASK; - -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + uint32_t ints_to_enable = NRF_RADIO_INT_PHYEND_MASK | NRF_RADIO_INT_ADDRESS_MASK; nrf_radio_int_enable(NRF_RADIO, ints_to_enable); } 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 * 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); /* 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); @@ -1407,32 +1465,6 @@ bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_ 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) { 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); - 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; -#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR -#if !NRF_802154_DISABLE_BCC_MATCHING ints_to_disable |= NRF_RADIO_INT_BCMATCH_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING 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); #endif @@ -1481,13 +1511,7 @@ static void rxframe_finish_disable_ints(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; -#endif // NRF_802154_DISABLE_BCC_MATCHING } static void rxframe_finish(void) @@ -1604,6 +1628,11 @@ trx_state_t nrf_802154_trx_state_get(void) 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) { 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(); // 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(); @@ -1844,7 +1873,7 @@ void nrf_802154_trx_continuous_carrier(const nrf_802154_fal_tx_power_split_t * p nrf_802154_trx_antenna_update(); // 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(); @@ -1907,7 +1936,7 @@ void nrf_802154_trx_modulated_carrier(const void * p_ nrf_802154_trx_antenna_update(); // 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(); @@ -1958,7 +1987,9 @@ void nrf_802154_trx_energy_detection(uint32_t ed_count) ed_count--; /* 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); +#endif 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(); // 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(); @@ -2013,44 +2044,61 @@ static void irq_handler_ready(void) { 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_802154_trx_transmit_frame_ccastarted(); - - 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_802154_trx_ppi_for_ramp_up_reconfigure(); 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: - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_ADDRESS_MASK); - m_flags.tx_started = true; - nrf_802154_trx_transmit_frame_started(); + if (m_flags.ccastarted_notif_en) + { + nrf_802154_trx_transmit_frame_ccastarted(); + } break; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - case TRX_STATE_TXACK: - nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_ADDRESS_MASK); - nrf_802154_trx_transmit_ack_started(); + case TRX_STATE_RXFRAME: + break; + + 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; -#endif default: assert(false); @@ -2059,7 +2107,6 @@ static void irq_handler_address(void) nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } -#if !NRF_802154_DISABLE_BCC_MATCHING static void irq_handler_bcmatch(void) { 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); } -#endif - -#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR static void irq_handler_crcerror(void) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); @@ -2105,17 +2149,10 @@ static void irq_handler_crcerror(void) switch (m_trx_state) { 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(); /* On crc error TIMER is not needed, no ACK may be sent */ nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); m_trx_state = TRX_STATE_FINISHED; -#endif nrf_802154_trx_receive_frame_crcerror(); break; @@ -2132,8 +2169,6 @@ static void irq_handler_crcerror(void) nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } -#endif - static void irq_handler_crcok(void) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); @@ -2207,9 +2242,8 @@ static void txframe_finish(void) txframe_finish_disable_ints(); nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - m_flags.tx_started = false; -#endif + + m_flags.tx_started = false; m_flags.missing_receive_buffer = false; /* Current state of peripherals @@ -2233,9 +2267,8 @@ static void transmit_frame_abort(void) fem_for_tx_reset(m_transmit_with_cca); txframe_finish_disable_ints(); -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - m_flags.tx_started = false; -#endif + + m_flags.tx_started = false; m_flags.missing_receive_buffer = false; nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_CCASTOP); @@ -2489,7 +2522,6 @@ void nrf_802154_radio_irq_handler(void) irq_handler_address(); } -#if !NRF_802154_DISABLE_BCC_MATCHING // Check MAC frame header. if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_BCMATCH_MASK) && nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH)) @@ -2499,9 +2531,6 @@ void nrf_802154_radio_irq_handler(void) 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) && nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR)) { @@ -2509,7 +2538,6 @@ void nrf_802154_radio_irq_handler(void) 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) && 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 // 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); diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx.h b/drivers/nrf_802154/driver/src/nrf_802154_trx.h index 965c061..03b86d8 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx.h @@ -86,6 +86,13 @@ typedef enum TRX_STATE_FINISHED } 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. */ 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. * - * When NRF_802154_DISABLE_BCC_MATCHING == 0 * - 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) * - 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 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) * 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 * * @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. - * When @ref NRF_802154_DISABLE_BCC_MATCHING != 0, this value must be zero. + * @param[in] 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 + * 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. * 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. */ 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, 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 sending synchronization header (SHR). * - @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: * - 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, * 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 - * (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): * - The RADIO disables receive mode * - @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. * The number of bytes pointed by p_transmit buffer must * 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 * real transmission. If false no 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. */ void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer, + nrf_802154_trx_ramp_up_trigger_mode_t rampup_trigg_mode, bool cca, const nrf_802154_fal_tx_power_split_t * p_tx_power, 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) * * @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 - * the function @ref nrf_802154_trx_transmit_ack_started will be called. + * When transmission starts 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 * will be called. * @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.*/ 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. * * 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 * - the RADIO received a frame on air with incorrect crc * - * If NRF_802154_DISABLE_BCC_MATCHING == 0: * When this handler is called following holds: * - the RADIO peripheral started ramping down (or it ramped down already) * - 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_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 * @ref nrf_802154_trx_receive_frame as receive is restarted automatically by the hardware. * 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. * * 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. * - 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. * * 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. * - the RADIO peripheral sent synchronization header * diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx_dppi.c b/drivers/nrf_802154/driver/src/nrf_802154_trx_dppi.c index 1bd12c0..ad08cf0 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx_dppi.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx_dppi.c @@ -36,7 +36,7 @@ #include "nrfx.h" -#ifdef NRF53_SERIES +#if defined(DPPI_PRESENT) #include "nrf_802154_trx_ppi_api.h" @@ -48,9 +48,6 @@ #include "hal/nrf_radio.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_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 nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY, NRF_802154_DPPI_RADIO_CCABUSY); #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 (1UL << NRF_802154_DPPI_RADIO_CCABUSY) | #endif // NRF_802154_TEST_MODES_ENABLED (1UL << PPI_DISABLED_EGU) | (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_END) | (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) { - nrf_dppi_channels_disable(NRF_DPPIC, + nrf_dppi_channels_disable(NRF_802154_DPPIC_INSTANCE, #if NRF_802154_TEST_MODES_ENABLED (1UL << NRF_802154_DPPI_RADIO_CCABUSY) | #endif // NRF_802154_TEST_MODES_ENABLED (1UL << PPI_DISABLED_EGU) | (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_END) | (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 nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY); #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); } -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); // 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_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) { 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)); + 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); } +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) { 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)); - 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_dppi_subscribe_clear(NRF_DPPIC, DPPI_CHGRP_RAMP_UP_DIS_TASK); - nrf_dppi_channels_remove_from_group(NRF_DPPIC, 1UL << PPI_EGU_RAMP_UP, DPPI_CHGRP_RAMP_UP); + nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + 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) { 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); } @@ -179,7 +216,7 @@ bool nrf_802154_trx_ppi_for_ramp_up_was_triggered(void) // Wait for PPIs 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. 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_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); } @@ -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_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_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_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); } @@ -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_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_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 // NRF53_SERIES +#endif // defined(DPPI_PRESENT) diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi.c b/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi.c index 6b7fe4d..1961063 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi.c @@ -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_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_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 @@ -76,13 +77,22 @@ void nrf_802154_trx_ppi_for_disable(void) // Intentionally empty. } -void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool start_timer) +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); // Clr event EGU (needed for nrf_802154_trx_ppi_for_ramp_up_was_triggered) 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, PPI_EGU_RAMP_UP, 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), nrf_timer_task_address_get(NRF_802154_TIMER_INSTANCE, 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); } + 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_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)ramp_up_task; nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); uint32_t ppi_mask = (1UL << PPI_EGU_RAMP_UP) | - (1UL << PPI_DISABLED_EGU); + (1UL << PPI_RAMP_UP_TRG_EGU); 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_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) { diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi_api.h b/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi_api.h index c18dc69..b35558b 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi_api.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi_api.h @@ -45,6 +45,7 @@ #include "hal/nrf_egu.h" #include "hal/nrf_radio.h" +#include "nrf_802154_trx.h" /** * @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); /** - * @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 * | \--> self disable * if (start_timer) * \-------------> 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 * \--> self disable * * 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] trigg_mode Trigger mode the connections must conform to. * @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] 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); +/** + * @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. * @@ -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. * - * Radio ramp up starts by design from RADIO DISABLED event. This functions verifies this event - * and PPIs status. + * In TRX_RAMP_UP_SW_TRIGGER mode, radio ramp up starts by design from RADIO DISABLED event. + * 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 false PPIs were not triggered. To trigger them, the caller must trigger RADIO DISABLE task. diff --git a/drivers/nrf_802154/serialization/include/host/nrf_802154.h b/drivers/nrf_802154/serialization/include/host/nrf_802154.h index e5669b6..0ef5d7f 100644 --- a/drivers/nrf_802154/serialization/include/host/nrf_802154.h +++ b/drivers/nrf_802154/serialization/include/host/nrf_802154.h @@ -830,6 +830,13 @@ uint64_t nrf_802154_time_get(void); */ 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. * diff --git a/drivers/nrf_802154/serialization/src/include/nrf_802154_nrfx_addons.h b/drivers/nrf_802154/serialization/src/include/nrf_802154_nrfx_addons.h index 02eb55a..1a75886 100644 --- a/drivers/nrf_802154/serialization/src/include/nrf_802154_nrfx_addons.h +++ b/drivers/nrf_802154/serialization/src/include/nrf_802154_nrfx_addons.h @@ -44,14 +44,12 @@ that the maximum value in EDSAMPLE which can be reported in compliance with the 802.15.4 specification is 255/ED_RSSISCALE. */ -#if defined (NRF52840_XXAA) -#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. -#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. +#if 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 -#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 #define EDSAMPLE_MIN_REPORTED_VALUE (PHY_MIN_RECEIVER_SENSITIVITY - ED_RSSIOFFS + 10) ///< Minimal reported EDSAMPLE value (reported as 0) diff --git a/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h b/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h index 7452c23..837a774 100644 --- a/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h +++ b/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h @@ -447,6 +447,12 @@ typedef enum SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET = 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; /** diff --git a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c index a8a5522..4ff5373 100644 --- a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c +++ b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c @@ -1820,6 +1820,32 @@ bail: 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_ser_err_t res; diff --git a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c index 92d2947..c69eab9 100644 --- a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c +++ b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c @@ -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); } +/** + * @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. * @@ -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, 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: NRF_802154_SPINEL_LOG_RAW("Unsupported property: %s(%u)\n", spinel_prop_key_to_cstr(property), diff --git a/drivers/nrf_802154/sl/include/nrf_802154_sl_config.h b/drivers/nrf_802154/sl/include/nrf_802154_sl_config.h index fa78beb..5307d9d 100644 --- a/drivers/nrf_802154/sl/include/nrf_802154_sl_config.h +++ b/drivers/nrf_802154/sl/include/nrf_802154_sl_config.h @@ -40,6 +40,10 @@ #ifndef 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 * diff --git a/drivers/nrf_802154/sl/include/nrf_802154_sl_periphs.h b/drivers/nrf_802154/sl/include/nrf_802154_sl_periphs.h index 34ebb80..4b2a9d4 100644 --- a/drivers/nrf_802154/sl/include/nrf_802154_sl_periphs.h +++ b/drivers/nrf_802154/sl/include/nrf_802154_sl_periphs.h @@ -41,10 +41,9 @@ #define NRF_802154_SL_PERIPHS_H__ #include -#if defined(DPPI_PRESENT) -#include "hal/nrf_dppi.h" -#else -#include "hal/nrf_ppi.h" + +#if NRF_802154_USE_INTERNAL_INCLUDES +#include "nrf_802154_sl_periphs_internal.h" #endif /** diff --git a/drivers/nrf_802154/sl/include/nrf_802154_sl_timer.h b/drivers/nrf_802154/sl/include/nrf_802154_sl_timer.h index 1b570a9..54fd11f 100644 --- a/drivers/nrf_802154/sl/include/nrf_802154_sl_timer.h +++ b/drivers/nrf_802154/sl/include/nrf_802154_sl_timer.h @@ -65,6 +65,7 @@ extern "C" { * Possible values: * @ref NRF_802154_SL_TIMER_RET_SUCCESS * @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_INACTIVE * @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. */ #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. * * 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 * (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. */ -#define NRF_802154_SL_TIMER_RET_INACTIVE 4U +#define NRF_802154_SL_TIMER_RET_INACTIVE 5U /**@brief Type representing a timer. */ 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. */ #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. */ 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 * and functional until the requested hardware task is triggered or until the timer * 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; } 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); +/**@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); + /** *@} **/ diff --git a/drivers/nrf_802154/sl/include/rsch/nrf_802154_rsch.h b/drivers/nrf_802154/sl/include/rsch/nrf_802154_rsch.h index d8dbfeb..c5a50c9 100644 --- a/drivers/nrf_802154/sl/include/rsch/nrf_802154_rsch.h +++ b/drivers/nrf_802154/sl/include/rsch/nrf_802154_rsch.h @@ -164,6 +164,8 @@ typedef void (* rsch_dly_ts_started_callback_t)(rsch_dly_ts_id_t dly_ts_id); typedef struct { 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_dly_ts_op_t op; ///< Operation to be performed in 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); +/** + * @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. * diff --git a/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_rsch.c b/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_rsch.c index 1922d24..c94db17 100644 --- a/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_rsch.c +++ b/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_rsch.c @@ -180,3 +180,10 @@ bool nrf_802154_rsch_delayed_timeslot_priority_update(rsch_dly_ts_id_t dly_ts_id return false; } + +bool nrf_802154_rsch_delayed_timeslot_ppi_update(uint32_t ppi_channel) +{ + (void)ppi_channel; + + return false; +}