drivers: nrf_802154: Update the IEEE 802.15.4 component

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

sdk-nrf-802154 commit: 43a0e760e7e47589739da632f852237d6331dacf

Signed-off-by: Jędrzej Ciupis <jedrzej.ciupis@nordicsemi.no>
This commit is contained in:
Jędrzej Ciupis 2023-06-26 10:45:53 +02:00 committed by Carles Cufí
parent a1c3e0fbaa
commit 0d68181c95
39 changed files with 882 additions and 538 deletions

View File

@ -45,6 +45,7 @@ target_sources(nrf-802154-driver
PRIVATE
src/nrf_802154.c
src/nrf_802154_aes_ccm_acc_ecb.c
src/nrf_802154_bsim_utils.c
src/nrf_802154_core.c
src/nrf_802154_core_hooks.c
src/nrf_802154_critical_section.c
@ -106,12 +107,6 @@ 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

View File

@ -395,6 +395,10 @@ uint8_t nrf_802154_ccaedthres_from_dbm_calculate(int8_t dbm);
/**
* @brief Calculates the timestamp of the first symbol of the preamble in a received frame.
*
* @deprecated This function is deprecated. Use @ref nrf_802154_timestamp_end_to_phr_convert
* instead and adjust the code that calls this function to rely on the timestamp of the first symbol
* of the PHR, not the timestamp of the first symbol of the frame.
*
* @param[in] end_timestamp Timestamp of the end of the last symbol in the frame,
* in microseconds.
* @param[in] psdu_length Number of bytes in the frame PSDU.
@ -407,6 +411,10 @@ uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t p
/**
* @brief Calculates the timestamp of the MAC Header in a received frame.
*
* @deprecated This function is deprecated. Use @ref nrf_802154_timestamp_end_to_phr_convert
* instead and adjust the code that calls this function to rely on the timestamp of the first symbol
* of the PHR, not the MAC Header timestamp.
*
* @param[in] end_timestamp Timestamp of the end of the last symbol in the frame,
* in microseconds.
* @param[in] psdu_length Number of bytes in the frame PSDU.
@ -415,6 +423,33 @@ uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t p
*/
uint64_t nrf_802154_mhr_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length);
/**
* @brief Converts the timestamp of the frame's end to the timestamp of the start of its PHR.
*
* This function calculates the time when the first symbol of the PHR is at the local antenna. Note
* that this time is equivalent to: the end of the frame's SFD and RMARKER as defined in'
* IEEE 802.15.4-2020, Section 6.9.1.
*
* @param[in] end_timestamp Timestamp of the end of the last symbol in the frame,
* in microseconds.
* @param[in] psdu_length Number of bytes in the frame PSDU.
*
* @return Timestamp of the start of the PHR of a given frame, in microseconds.
*/
uint64_t nrf_802154_timestamp_end_to_phr_convert(uint64_t end_timestamp, uint8_t psdu_length);
/**
* @brief Converts the timestamp of the frame's PHR to the timestamp of the start of its SHR.
*
* This function converts the time when the first symbol of the frame's PHR is at the local antenna
* to the timestamp of the start of the frame's SHR.
*
* @param[in] phr_timestamp Timestamp of the frame's PHR.
*
* @return Timestamp of the start of the SHR of a given frame, in microseconds.
*/
uint64_t nrf_802154_timestamp_phr_to_shr_convert(uint64_t phr_timestamp);
/**
* @}
* @defgroup nrf_802154_transitions Functions to request FSM transitions and check current state
@ -1671,14 +1706,6 @@ void nrf_802154_stat_timestamps_get(nrf_802154_stat_timestamps_t * p_stat_timest
*/
void nrf_802154_stat_counters_reset(void);
/**
* @brief Get total times spent in certain states.
*
* @param[out] p_stat_totals Structure that will be filled with times spent in certain states
* until now.
*/
void nrf_802154_stat_totals_get(nrf_802154_stat_totals_t * p_stat_totals);
/**
* @}
* @defgroup nrf_802154_ifs Inter-frame spacing feature
@ -1828,16 +1855,22 @@ void nrf_802154_csl_writer_period_set(uint16_t period);
/**
* @brief Sets the anchor time based on which the next CSL window time and the CSL phase is calculated.
*
* This function sets an anchor time which is a time of a CSL window, based which on the times of future CSL windows are
* calculated. It is assumed that all other CSL windows occur at time @c anchor_time + @c n * @c csl_period where @c n is
* an integer. Note that the anchor time can be both in the past and in the future.
* This function sets an anchor time based on which the times of future CSL windows are calculated.
* When this anchor time is used for calculations, it is assumed that it points to a time where
* the first bit of MAC header of the frame received from a peer happens. In other words, the anchor
* time should point to a time where CSL phase would be equal 0. As a result, CSL phase can always
* be calculated relatively to a time given by the equation @c anchor_time + @c n * @c csl_period
* where @c n is an integer. Note that the reasoning holds irrespectively of signedness of @c n
* so the anchor time can be either in the past or in the future.
*
* This function should be called after calling @ref nrf_802154_csl_writer_period_set and every time when the CSL windows get desynchronized.
* This function should be called after calling @ref nrf_802154_csl_writer_period_set and every time
* when the CSL communication desynchronizes.
*
* If this function is not called, a legacy CSL operation mode is chosen, where the CSL phase is calculated based on the time of the nearest
* scheduled CSL window (and can be undefined, if no such window was scheduled).
* If this function is not called a legacy CSL operation mode is chosen. The CSL phase is then
* calculated based on the time of the nearest scheduled CSL reception window and can be undefined,
* if no such window was scheduled.
*
* @param[in] period Anchor time value.
* @param[in] anchor_time Anchor time in microseconds.
*/
void nrf_802154_csl_writer_anchor_time_set(uint64_t anchor_time);

View File

@ -229,18 +229,6 @@ extern "C" {
#define NRF_802154_FRAME_TIMESTAMP_ENABLED 1
#endif
/**
* @def NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
*
* 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.
*/
#ifndef NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
#define NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED \
(1 && NRF_802154_FRAME_TIMESTAMP_ENABLED)
#endif
/**
* @def NRF_802154_DELAYED_TRX_ENABLED
*
@ -264,6 +252,15 @@ extern "C" {
#define NRF_802154_TEST_MODES_ENABLED 0
#endif
/**
* @def NRF_802154_PAN_COORD_GET_ENABLED
*
* Enables the @ref nrf_802154_pan_coord_get function.
*/
#ifndef NRF_802154_PAN_COORD_GET_ENABLED
#define NRF_802154_PAN_COORD_GET_ENABLED 0
#endif
/**
* @}
* @defgroup nrf_802154_config_csma CSMA/CA procedure configuration

View File

@ -326,21 +326,6 @@ typedef struct
uint64_t last_rx_end_timestamp;
} nrf_802154_stat_timestamps_t;
/**
* @brief Type of structure holding total times spent in certain states.
*
* This structure holds fields of @c uint64_t type only.
*/
typedef struct
{
/**@brief Total time in microseconds spent with receiver turned on, but not actually receiving any frames. */
uint64_t total_listening_time;
/**@brief Total time in microseconds spent with receiver turned on and actually receiving frames. */
uint64_t total_receive_time;
/**@brief Total time in microseconds spent on transmission. */
uint64_t total_transmit_time;
} nrf_802154_stat_totals_t;
/**
* @brief Type of structure holding statistics about the Radio Driver behavior.
*/

View File

@ -116,6 +116,11 @@ typedef struct
uint8_t * p_data; ///< Pointer to a buffer containing PHR and PSDU of the frame requested to be transmitted.
nrf_802154_transmit_params_t params; ///< Transmission parameters.
uint8_t channel; ///< Channel number on which transmission should be performed.
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
uint64_t time; ///< Target time of the first bit of the frame.
#endif
} dly_tx_data_t;
/**

View File

@ -94,6 +94,7 @@ typedef uint32_t nrf_802154_filter_mode_t;
* @retval NRF_802154_RX_ERROR_INVALID_FRAME Verified part of the incoming frame is invalid.
* @retval NRF_802154_RX_ERROR_INVALID_DEST_ADDR Incoming frame has destination address that
* mismatches the address of this node.
* @retval NRF_802154_RX_ERROR_INVALID_LENGTH Received a frame with invalid length.
*/
nrf_802154_rx_error_t nrf_802154_filter_frame_part(
const nrf_802154_frame_parser_data_t * p_frame_data,

View File

@ -44,14 +44,21 @@
#include "mac_features/nrf_802154_delayed_trx.h"
#include "nrf_802154_core.h"
#include "nrf_802154_nrfx_addons.h"
#include "nrf_802154_procedures_duration.h"
#include "nrf_802154_tx_work_buffer.h"
#include "nrf_802154_utils_byteorder.h"
#include "nrf_802154_sl_timer.h"
#include <assert.h>
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
#include "nrf_802154_bsim_utils.h"
#endif
#if NRF_802154_IE_WRITER_ENABLED
#define CSL_US_PER_UNIT (IE_CSL_SYMBOLS_PER_UNIT * PHY_US_PER_SYMBOL)
typedef enum
{
IE_WRITER_RESET,
@ -69,9 +76,22 @@ static uint16_t m_csl_period; ///< CSL period value that will be injec
static uint64_t m_csl_anchor_time; ///< The anchor time based on which CSL window times are calculated
static bool m_csl_anchor_time_set; ///< Information if CSL anchor time was set by the higher layer
static bool csl_time_to_nearest_window_midpoint_get(uint32_t * p_time_to_midpoint)
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
static uint32_t m_csl_time_to_radio_address_us;
#endif
/** @brief Calulate CSL phase.
*
* @param[out] p_csl_phase Calculated CSL phase in units of 160us.
*
* @retval true The calculation was successful and @p p_csl_phase contains a valid CSL phase.
* @retval false The calculation failed and the value pointed to by @p p_csl_phase is undefined.
*/
static bool csl_phase_calc(uint32_t * p_csl_phase)
{
bool result = false;
bool result = false;
uint32_t us;
if (m_csl_anchor_time_set)
{
@ -79,26 +99,64 @@ static bool csl_time_to_nearest_window_midpoint_get(uint32_t * p_time_to_midpoin
if (result)
{
uint64_t now = nrf_802154_sl_timer_current_time_get();
uint32_t csl_period_us = m_csl_period * IE_CSL_SYMBOLS_PER_UNIT * PHY_US_PER_SYMBOL;
/*
* This function is executed in the handler of RADIO.ADDRESS event. According to the IPS,
* in 802.15.4 transmit sequence RADIO.FRAMESTART event is triggered after the SHR is
* transmitted (nRF52840 PS v1.7 -- 6.20.12.6 Transmit sequence). However, RADIO.ADDRESS
* event is also triggered in 802.15.4 transmit sequence with a constant 32us offset.
* This handler is therefore expected to execute 32us before the SHR transmission ends.
*
* The IEEE 802.15.4-2015 specification is unclear about which point in time the CSL Phase
* should refer to. Following the latest developments in the Thread specification, here
* it is going to be calculated relative to the beginning of the MHR. This function
* executes approximately 2 * 32us = 64us before the first bit of MHR. The calculation
* below takes it into account by adding 64us to the current time.
*/
uint64_t csl_ref_time_us = nrf_802154_sl_timer_current_time_get() + 64;
uint32_t csl_period_us = m_csl_period * IE_CSL_SYMBOLS_PER_UNIT * PHY_US_PER_SYMBOL;
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
/**
* In simulation this function is executed immediately after setting up radio ramp-up.
* The reference time calculated above must be increased with simulation-specific
* adjustments calculated earlier.
*/
csl_ref_time_us += m_csl_time_to_radio_address_us;
#endif /* defined(CONFIG_SOC_SERIES_BSIM_NRFXX) */
// Modulo of a negative number possibly will not be positive, so the below if-else clause is needed
if (now >= m_csl_anchor_time)
if (csl_ref_time_us >= m_csl_anchor_time)
{
uint32_t time_from_previous_window =
(uint32_t)((now - m_csl_anchor_time) % csl_period_us);
(uint32_t)((csl_ref_time_us - m_csl_anchor_time) % csl_period_us);
*p_time_to_midpoint = csl_period_us - time_from_previous_window;
us = csl_period_us - time_from_previous_window;
}
else
{
*p_time_to_midpoint = (uint32_t)((m_csl_anchor_time - now) % csl_period_us);
us = (uint32_t)((m_csl_anchor_time - csl_ref_time_us) % csl_period_us);
}
}
}
else
{
result = nrf_802154_delayed_trx_nearest_drx_time_to_midpoint_get(p_time_to_midpoint);
// Fallback to legacy method
result = nrf_802154_delayed_trx_nearest_drx_time_to_midpoint_get(&us);
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
/**
* In simulation this function is executed immediately after setting up radio ramp-up.
* The time to midpoint calculated above must be decreased with simulation-specific
* adjustments calculated earlier.
*/
us -= m_csl_time_to_radio_address_us;
#endif /* defined(CONFIG_SOC_SERIES_BSIM_NRFXX) */
}
if (result)
{
// Round to the nearest integer when converting us to CSL units
*p_csl_phase = (us + (CSL_US_PER_UNIT >> 1)) / CSL_US_PER_UNIT;
}
return result;
@ -112,8 +170,6 @@ static bool csl_time_to_nearest_window_midpoint_get(uint32_t * p_time_to_midpoin
*/
static void csl_ie_write_commit(bool * p_written)
{
uint32_t time_remaining;
uint32_t symbols;
uint32_t csl_phase;
if ((mp_csl_phase_addr == NULL) || (mp_csl_period_addr == NULL))
@ -122,22 +178,12 @@ static void csl_ie_write_commit(bool * p_written)
return;
}
if (csl_time_to_nearest_window_midpoint_get(&time_remaining) == false)
if (csl_phase_calc(&csl_phase) == false)
{
// No delayed DRX is pending. Do not write to the CSL IE.
// CSL Phase could not be determined. Do not write to the CSL IE.
return;
}
/*
* Note: The csl_ie_write_commit executes after the FRAMESTART event, which is triggered
* by the radio peripheral after the SHR (nRF52840 PS v1.2 -- 6.20.12.6 Transmit sequence).
* The symbol calculation should take into account the time needed for two symbols of the PHR.
* However, since we are measuring time to the DRX midpoint and not to the beginning, there
* is a bit or margin to spare and the calculation does not have to account for the PHR.
*/
symbols = time_remaining / PHY_US_PER_SYMBOL;
csl_phase = symbols / IE_CSL_SYMBOLS_PER_UNIT;
if (csl_phase > IE_CSL_PERIOD_MAX)
{
// CSL phase exceeds the maximum value. Do not write to the CSL IE
@ -505,6 +551,14 @@ bool nrf_802154_ie_writer_tx_started_hook(uint8_t * p_frame)
bool written = false;
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
nrf_802154_bsim_utils_core_hooks_adjustments_t adjustments;
nrf_802154_bsim_utils_core_hooks_adjustments_get(&adjustments);
m_csl_time_to_radio_address_us = adjustments.tx_started.time_to_radio_address_us;
#endif
ie_writer_commit(&written);
ie_writer_reset();
@ -527,6 +581,14 @@ void nrf_802154_ie_writer_tx_ack_started_hook(uint8_t * p_ack)
bool written = false;
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
nrf_802154_bsim_utils_core_hooks_adjustments_t adjustments;
nrf_802154_bsim_utils_core_hooks_adjustments_get(&adjustments);
m_csl_time_to_radio_address_us = adjustments.tx_ack_started.time_to_radio_address_us;
#endif
ie_writer_commit(&written);
ie_writer_reset();

View File

@ -137,7 +137,7 @@ void nrf_802154_ie_writer_csl_period_set(uint16_t period);
/**
* @brief Sets the anchor time based on which the next CSL window time and the CSL phase is calculated.
*
* @param[in] period Anchor time value.
* @param[in] anchor_time Anchor time value.
*/
void nrf_802154_ie_writer_csl_anchor_time_set(uint64_t anchor_time);

View File

@ -53,6 +53,10 @@
#include "nrf_802154_tx_work_buffer.h"
#include "nrf_802154_sl_timer.h"
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
#include "nrf_802154_bsim_utils.h"
#endif
#if NRF_802154_ACK_TIMEOUT_ENABLED
#define RETRY_DELAY 500 ///< Procedure is delayed by this time if it cannot be performed at the moment [us].
@ -66,18 +70,6 @@ static uint32_t m_dt;
static volatile bool m_procedure_is_active;
static uint8_t * mp_frame;
static void notify_tx_error(bool result)
{
if (result)
{
// If waiting for ack timeout occurred, the transmission must had already finished.
nrf_802154_transmit_done_metadata_t metadata = {0};
nrf_802154_tx_work_buffer_original_frame_update(mp_frame, &metadata.frame_props);
nrf_802154_notify_transmit_failed(mp_frame, NRF_802154_TX_ERROR_NO_ACK, &metadata);
}
}
static void timeout_timer_fired(nrf_802154_sl_timer_t * p_timer)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -86,11 +78,11 @@ static void timeout_timer_fired(nrf_802154_sl_timer_t * p_timer)
if (m_procedure_is_active)
{
if (nrf_802154_request_receive(NRF_802154_TERM_802154,
REQ_ORIG_ACK_TIMEOUT,
notify_tx_error,
false,
NRF_802154_RESERVED_IMM_RX_WINDOW_ID))
nrf_802154_ack_timeout_handle_params_t param = {0};
param.p_frame = mp_frame;
if (nrf_802154_request_ack_timeout_handle(&param))
{
m_procedure_is_active = false;
}
@ -122,9 +114,19 @@ static void timeout_timer_start(void)
uint64_t now = nrf_802154_sl_timer_current_time_get();
nrf_802154_sl_timer_ret_t ret;
m_dt = m_timeout +
IMM_ACK_DURATION +
nrf_802154_frame_duration_get(mp_frame[0], false, true);
m_dt = m_timeout + IMM_ACK_DURATION + nrf_802154_frame_duration_get(mp_frame[0], false, true);
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
/**
* In simulation, this function is executed immediately after setting up Tx ramp-up instead of
* handler of RADIO.ADDRESS event. The timeout must be increased with simulation-specific
* adjustments calculated earlier.
*/
nrf_802154_bsim_utils_core_hooks_adjustments_t adjustments;
nrf_802154_bsim_utils_core_hooks_adjustments_get(&adjustments);
m_dt += adjustments.tx_started.time_to_radio_address_us;
#endif
m_timer.action_type = NRF_802154_SL_TIMER_ACTION_TYPE_CALLBACK;
m_timer.action.callback.callback = timeout_timer_fired;

View File

@ -225,6 +225,18 @@ uint64_t nrf_802154_mhr_timestamp_get(uint64_t end_timestamp, uint8_t psdu_lengt
return end_timestamp - (psdu_length * PHY_SYMBOLS_PER_OCTET * PHY_US_PER_SYMBOL);
}
uint64_t nrf_802154_timestamp_end_to_phr_convert(uint64_t end_timestamp, uint8_t psdu_length)
{
uint32_t frame_symbols = (PHR_SIZE + psdu_length) * PHY_SYMBOLS_PER_OCTET;
return end_timestamp - (frame_symbols * PHY_US_PER_SYMBOL);
}
uint64_t nrf_802154_timestamp_phr_to_shr_convert(uint64_t phr_timestamp)
{
return phr_timestamp - (PHY_SHR_SYMBOLS * PHY_US_PER_SYMBOL);
}
void nrf_802154_init(void)
{
static const nrf_802154_sl_crit_sect_interface_t crit_sect_int =

View File

@ -128,7 +128,7 @@ static void ecb_init(void)
{
if (!m_initialized)
{
nrf_802154_irq_init(ECB_IRQn, NRF_802154_ECB_PRIORITY, ecb_irq_handler);
nrf_802154_irq_init(nrfx_get_irq_number(NRF_ECB), NRF_802154_ECB_PRIORITY, ecb_irq_handler);
m_initialized = true;
}
@ -136,8 +136,8 @@ static void ecb_init(void)
// TODO: what about ECB initialization in baremetal scenario?
nrf_ecb_init();
nrf_802154_irq_clear_pending(ECB_IRQn);
nrf_802154_irq_enable(ECB_IRQn);
nrf_802154_irq_clear_pending(nrfx_get_irq_number(NRF_ECB));
nrf_802154_irq_enable(nrfx_get_irq_number(NRF_ECB));
nrf_ecb_int_enable(NRF_ECB, NRF_ECB_INT_ENDECB_MASK);
nrf_ecb_int_enable(NRF_ECB, NRF_ECB_INT_ERRORECB_MASK);
}

View File

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

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2017 - 2023, Nordic Semiconductor ASA
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef NRF_802154_BSIM_UTILS_H__
#define NRF_802154_BSIM_UTILS_H__
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
#include "nrf_802154_types.h"
#include "nrf_802154_utils.h"
typedef struct
{
struct
{
uint32_t time_to_radio_address_us; ///< Time until RADIO->ADDRESS event in microseconds.
} tx_started;
struct
{
uint32_t time_to_radio_address_us; ///< Time until RADIO->ADDRESS event in microseconds.
} tx_ack_started;
} nrf_802154_bsim_utils_core_hooks_adjustments_t;
/**
* @brief Get adjustments for Tx started hook.
*/
void nrf_802154_bsim_utils_core_hooks_adjustments_get(
nrf_802154_bsim_utils_core_hooks_adjustments_t * p_obj);
/**
* @brief Set adjustments for Tx started hook.
*/
void nrf_802154_bsim_utils_core_hooks_adjustments_set(
const nrf_802154_bsim_utils_core_hooks_adjustments_t * p_obj);
#endif /* defined(CONFIG_SOC_SERIES_BSIM_NRFXX) */
#endif /* NRF_802154_BSIM_UTILS_H__ */

View File

@ -74,13 +74,17 @@
#include "rsch/nrf_802154_rsch.h"
#include "rsch/nrf_802154_rsch_crit_sect.h"
#include "timer/nrf_802154_timer_coord.h"
#include "platform/nrf_802154_hp_timer.h"
#include "platform/nrf_802154_irq.h"
#include "protocol/mpsl_fem_protocol_api.h"
#include "nrf_802154_core_hooks.h"
#include "nrf_802154_sl_ant_div.h"
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
#include "nrf_802154_bsim_utils.h"
#include "NRF_AES_ECB.h"
#endif
/// Delay before first check of received frame: 24 bits is PHY header and MAC Frame Control field.
#define BCC_INIT (3 * 8)
@ -128,11 +132,16 @@ static volatile radio_state_t m_state; ///< State of the
typedef struct
{
bool frame_filtered : 1; ///< If frame being received passed filtering operation.
bool frame_parsed : 1; ///< If frame being received has been parsed
bool rx_timeslot_requested : 1; ///< If timeslot for the frame being received is already requested.
bool tx_with_cca : 1; ///< If currently transmitted frame is transmitted with cca.
bool tx_diminished_prio : 1; ///< If priority of the current transmission should be diminished.
bool frame_filtered : 1; ///< If frame being received passed filtering operation.
bool frame_parsed : 1; ///< If frame being received has been parsed
bool rx_timeslot_requested : 1; ///< If timeslot for the frame being received is already requested.
bool tx_with_cca : 1; ///< If currently transmitted frame is transmitted with cca.
bool tx_diminished_prio : 1; ///< If priority of the current transmission should be diminished.
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
bool tx_started_notify : 1; ///< If higher layer should be notified that transmission started.
#endif
} nrf_802154_flags_t;
static nrf_802154_flags_t m_flags; ///< Flags used to store the current driver state.
@ -154,17 +163,6 @@ static nrf_802154_coex_tx_request_mode_t m_coex_tx_request_mode;
/** @brief Identifier of currently active reception window. */
static uint32_t m_rx_window_id;
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
#if !NRF_802154_FRAME_TIMESTAMP_ENABLED
#error NRF_802154_FRAME_TIMESTAMP_ENABLED == 0 when NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED != 0
#endif
#endif // NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
static uint32_t m_listening_start_hp_timestamp;
#endif
static const nrf_802154_transmitted_frame_props_t m_default_frame_props =
NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT;
@ -333,7 +331,14 @@ static void transmit_started_notify(void)
{
uint8_t * p_frame = mp_tx_data;
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
/**
* TX started hooks were executed before transmission started. Use latched result
*/
if (m_flags.tx_started_notify)
#else
if (nrf_802154_core_hooks_tx_started(p_frame))
#endif
{
nrf_802154_tx_started(p_frame);
}
@ -343,7 +348,13 @@ static void transmit_started_notify(void)
/** Notify MAC layer that transmission of ACK frame has started. */
static void transmit_ack_started_notify()
{
#if !defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
nrf_802154_core_hooks_tx_ack_started(mp_ack);
#else
/**
* Otherwise this was already called immediately after setting up the transmission.
*/
#endif
nrf_802154_tx_ack_started(mp_ack);
}
@ -763,82 +774,6 @@ static void operation_terminated_notify(radio_state_t state, bool receiving_psdu
}
}
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
static void operation_terminated_update_total_times(trx_state_t trx_state, uint32_t timestamp)
{
uint32_t t;
switch (trx_state)
{
case TRX_STATE_RXFRAME:
case TRX_STATE_RXACK:
t = timestamp - m_listening_start_hp_timestamp;
nrf_802154_stat_totals_increment(total_listening_time, t);
break;
default:
break;
}
}
static bool operation_terminated_update_total_times_is_required(trx_state_t trx_state)
{
switch (trx_state)
{
case TRX_STATE_RXFRAME:
case TRX_STATE_RXACK:
/* These cases must be in-sync with implementation of
* operation_terminated_update_total_times
*/
return true;
default:
return false;
}
}
#endif
static void trx_abort(void)
{
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
trx_state_t trx_state = nrf_802154_trx_state_get();
bool update_required = operation_terminated_update_total_times_is_required(trx_state);
#endif
nrf_802154_trx_abort();
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
if (update_required)
{
uint32_t timestamp = nrf_802154_hp_timer_current_time_get();
operation_terminated_update_total_times(trx_state, timestamp);
}
#endif
}
static void trx_disable(void)
{
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
trx_state_t trx_state = nrf_802154_trx_state_get();
bool update_required = operation_terminated_update_total_times_is_required(trx_state);
#endif
nrf_802154_trx_disable();
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
if (update_required)
{
uint32_t timestamp = nrf_802154_hp_timer_current_time_get();
operation_terminated_update_total_times(trx_state, timestamp);
}
#endif
}
/** Terminate ongoing operation.
*
* This function is called when MAC layer requests transition to another operation.
@ -872,7 +807,7 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl,
if (result)
{
trx_abort();
nrf_802154_trx_abort();
if (m_state == RADIO_STATE_RX)
{
@ -1066,23 +1001,9 @@ static void rx_init(nrf_802154_trx_ramp_up_trigger_mode_t ru_tr_mode, bool * p_a
}
}
#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)
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
// Configure the timer coordinator to get a timestamp of the END event which
// fires several cycles after CRCOK or CRCERROR events.
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_end_event_handle_get());
#else
// Configure the timer coordinator to get a timestamp of the CRCOK event.
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_crcok_event_handle_get());
#endif
#endif
// Find RX buffer if none available
@ -1135,6 +1056,44 @@ static bool tx_init(const uint8_t * p_data,
cca,
&m_tx_power,
m_trx_transmit_frame_notifications_mask);
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
/**
* In simulation the frame contents are latched when the first bit of the preamble is
* "transmitted" by the simulated radio. Any modifications performed after that (for example in
* handler of RADIO.ADDRESS event) have no effect on the frame received by other devices in the
* simulation.
*
* Because of these limitations of the simulation, modification of the transmitted frame buffer
* is performed immediately after the radio ramp-up start. Also, since in simulation no time
* passes while the CPU is executing code and the radio ramp-up is shorter than the time needed
* by the ECB peripheral to encrypt the longest possible 802.15.4 frame, the ECB is artificially
* sped up to guarantee that encryption completes before the transmission starts.
*/
nrf_802154_bsim_utils_core_hooks_adjustments_t adjustments;
adjustments.tx_started.time_to_radio_address_us =
nrf_802154_rsch_delayed_timeslot_time_to_hw_trigger_get();
if (cca)
{
adjustments.tx_started.time_to_radio_address_us +=
RX_RAMP_UP_TIME + CCA_TIME + RX_TX_TURNAROUND_TIME;
}
else
{
adjustments.tx_started.time_to_radio_address_us += TX_RAMP_UP_TIME;
}
adjustments.tx_started.time_to_radio_address_us += PHY_US_TIME_FROM_SYMBOLS(PHY_SHR_SYMBOLS);
nrf_802154_bsim_utils_core_hooks_adjustments_set(&adjustments);
m_flags.tx_started_notify = nrf_802154_core_hooks_tx_started(mp_tx_data);
nrf_802154_bsim_utils_core_hooks_adjustments_t zeroes = {0};
nrf_802154_bsim_utils_core_hooks_adjustments_set(&zeroes);
#endif
if (rampup_trigg_mode == TRX_RAMP_UP_HW_TRIGGER)
{
@ -1261,10 +1220,21 @@ static void on_timeslot_ended(void)
receiving_psdu_now = nrf_802154_trx_psdu_is_being_received();
}
trx_disable();
nrf_802154_trx_disable();
nrf_802154_timer_coord_stop();
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
/**
* In simulation no time passes while the CPU is executing code and the radio ramp-up is
* shorter than the time needed by the ECB peripheral to encrypt the longest possible
* 802.15.4 frame. The ECB is artificially sped up to guarantee that encryption completes
* before transmission starts. Reset its settings to not confuse other users of this
* peripheral outside of 802.15.4 timeslot.
*/
nrf_aes_ecb_cheat_reset_t_ecb();
#endif
nrf_802154_rsch_continuous_ended();
result = nrf_802154_core_hooks_terminate(NRF_802154_TERM_802154, REQ_ORIG_RSCH);
@ -1340,7 +1310,7 @@ static void on_preconditions_denied(radio_state_t state)
receiving_psdu_now = nrf_802154_trx_psdu_is_being_received();
}
trx_abort();
nrf_802154_trx_abort();
switch (state)
{
@ -1392,7 +1362,7 @@ static void on_preconditions_approved(radio_state_t state)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
trx_abort();
nrf_802154_trx_abort();
switch (state)
{
@ -1447,6 +1417,15 @@ static void on_timeslot_started(void)
nrf_802154_timer_coord_start();
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
/**
* In simulation no time passes while the CPU is executing code and the radio ramp-up is shorter
* than the time needed by the ECB peripheral to encrypt the longest possible 802.15.4 frame.
* Speed up the ECB to guarantee that encryption completes before transmission starts.
*/
nrf_aes_ecb_cheat_set_t_ecb(1);
#endif
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
}
@ -1780,21 +1759,25 @@ uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc)
nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_RX);
nrf_802154_ack_generator_reset();
}
}
if (nrf_802154_pib_promiscuous_get())
if (nrf_802154_pib_promiscuous_get())
{
/*
* In promiscuous mode all filtering should be ignored unless the frame has
* length 0 or above maximum frame length.
*/
uint8_t psdu_length = nrf_802154_frame_parser_frame_length_get(&m_current_rx_frame_data);
if (psdu_length > 0 && psdu_length <= MAX_PACKET_SIZE)
{
/*
* 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;
filter_result = NRF_802154_RX_ERROR_NONE;
}
}
if (filter_result != NRF_802154_RX_ERROR_NONE)
{
trx_abort();
nrf_802154_trx_abort();
rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
/* Release boosted preconditions */
@ -1846,7 +1829,7 @@ uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc)
else
{
// Disable receiver and wait for a new timeslot.
trx_abort();
nrf_802154_trx_abort();
// 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,
@ -1885,81 +1868,10 @@ void nrf_802154_trx_go_idle_finished(void)
static void on_bad_ack(void);
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
static void update_total_times_on_receive_end(uint32_t listening_start_hp_timestamp,
uint32_t receive_end_hp_timestamp, uint8_t phr)
{
uint32_t t_listening;
uint32_t t_frame;
t_frame = nrf_802154_frame_duration_get(phr, true, true);
t_listening = receive_end_hp_timestamp - listening_start_hp_timestamp;
if (t_frame > t_listening)
{
t_frame = t_listening;
}
t_listening -= t_frame;
nrf_802154_stat_totals_increment(total_listening_time, t_listening);
nrf_802154_stat_totals_increment(total_receive_time, t_frame);
}
#endif
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
void nrf_802154_stat_totals_get_notify(void)
{
// Total times are going to be read, update stat_totals to hold
// correct times until now.
nrf_802154_mcu_critical_state_t mcu_cs;
nrf_802154_mcu_critical_enter(mcu_cs);
trx_state_t trx_state = nrf_802154_trx_state_get();
if ((trx_state == TRX_STATE_RXFRAME) || (trx_state == TRX_STATE_RXACK))
{
uint32_t listening_end_timestamp = nrf_802154_hp_timer_current_time_get();
if (listening_end_timestamp - m_listening_start_hp_timestamp >= MAX_PHY_FRAME_TIME_US)
{
/* m_listening_start_hp_timestamp ... now - MAX_PHY_FRAME_TIME_US must be listening.
* Last MAX_PHY_FRAME_TIME_US is considered uncertain.
*/
listening_end_timestamp -= MAX_PHY_FRAME_TIME_US;
uint32_t t_listening = listening_end_timestamp - m_listening_start_hp_timestamp;
m_listening_start_hp_timestamp = listening_end_timestamp;
nrf_802154_stat_totals_increment(total_listening_time, t_listening);
}
else
{
/* Too little time passed since m_listening_start_hp_timestamp, we don't know
* if frame is being received now until it is received. */
}
}
nrf_802154_mcu_critical_exit(mcu_cs);
}
#endif
void nrf_802154_trx_receive_frame_crcerror(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
uint32_t receive_end_hp_timestamp = nrf_802154_hp_timer_timestamp_get();
uint32_t listening_start_hp_timestamp = m_listening_start_hp_timestamp;
#endif
assert(m_state == RADIO_STATE_RX);
rx_flags_clear();
rx_data_clear();
@ -1976,20 +1888,6 @@ void nrf_802154_trx_receive_frame_crcerror(void)
m_trx_receive_frame_notifications_mask,
&split_power);
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
m_listening_start_hp_timestamp = nrf_802154_hp_timer_current_time_get();
// Configure the timer coordinator to get a timestamp of the END event which
// fires several cycles after CRCOK or CRCERROR events.
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_end_event_handle_get());
#endif
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
update_total_times_on_receive_end(listening_start_hp_timestamp,
receive_end_hp_timestamp,
mp_current_rx_buffer->data[PHR_OFFSET]);
#endif
#if NRF_802154_NOTIFY_CRCERROR
receive_failed_notify(NRF_802154_RX_ERROR_INVALID_FCS);
#endif // NRF_802154_NOTIFY_CRCERROR
@ -2003,15 +1901,6 @@ void nrf_802154_trx_receive_ack_crcerror(void)
assert(m_state == RADIO_STATE_RX_ACK);
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
uint32_t receive_end_hp_timestamp = nrf_802154_hp_timer_timestamp_get();
uint32_t listening_start_hp_timestamp = m_listening_start_hp_timestamp;
update_total_times_on_receive_end(listening_start_hp_timestamp,
receive_end_hp_timestamp,
mp_current_rx_buffer->data[PHR_OFFSET]);
#endif
on_bad_ack();
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
@ -2028,15 +1917,6 @@ void nrf_802154_trx_receive_frame_received(void)
m_last_rssi = rssi_last_measurement_get();
m_last_lqi = lqi_get(p_received_data);
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
uint32_t receive_end_hp_timestamp = nrf_802154_hp_timer_timestamp_get();
uint32_t listening_start_hp_timestamp = m_listening_start_hp_timestamp;
update_total_times_on_receive_end(listening_start_hp_timestamp,
receive_end_hp_timestamp,
mp_current_rx_buffer->data[PHR_OFFSET]);
#endif
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),
@ -2099,6 +1979,33 @@ void nrf_802154_trx_receive_frame_received(void)
if (nrf_802154_trx_transmit_ack(nrf_802154_tx_work_buffer_get(mp_ack), ACK_IFS))
{
// Intentionally empty: transmitting ack, because we can
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
/**
* In simulation the frame contents are latched when the first bit of the
* preamble is "transmitted" by the simulated radio. Any modifications performed
* after that (for example in handler of RADIO.ADDRESS event) have no effect on
* the frame received by other devices in the simulation.
*
* Because of these limitations of the simulation, modification of the transmitted
* frame buffer is performed immediately after the radio ramp-up start. Also,
* since in simulation no time passes while the CPU is executing code and the
* radio ramp-up is shorter than the time needed by the ECB peripheral to encrypt
* the longest possible 802.15.4 frame, the ECB is artificially sped up to
* guarantee that encryption completes before the transmission starts.
*/
nrf_802154_bsim_utils_core_hooks_adjustments_t adjustments;
adjustments.tx_ack_started.time_to_radio_address_us =
ACK_IFS + TX_RAMP_UP_TIME + PHY_US_TIME_FROM_SYMBOLS(PHY_SHR_SYMBOLS);
nrf_802154_bsim_utils_core_hooks_adjustments_set(&adjustments);
nrf_802154_core_hooks_tx_ack_started(mp_ack);
nrf_802154_bsim_utils_core_hooks_adjustments_t zeroes = {0};
nrf_802154_bsim_utils_core_hooks_adjustments_set(&zeroes);
#endif /* defined(CONFIG_SOC_SERIES_BSIM_NRFXX) */
}
else
{
@ -2190,14 +2097,6 @@ void nrf_802154_trx_transmit_ack_transmitted(void)
assert(m_state == RADIO_STATE_TX_ACK);
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
uint32_t t_transmit = TX_RAMP_UP_TIME + nrf_802154_frame_duration_get(mp_ack[PHR_OFFSET],
true,
true);
nrf_802154_stat_totals_increment(total_transmit_time, t_transmit);
#endif
uint8_t * p_received_data = mp_current_rx_buffer->data;
// Current buffer used for receive operation will be passed to the application
@ -2216,12 +2115,6 @@ void nrf_802154_trx_transmit_frame_transmitted(void)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
uint32_t t_listening = 0U;
uint32_t t_transmit = 0U;
#endif
#if (NRF_802154_FRAME_TIMESTAMP_ENABLED)
uint64_t ts = timer_coord_timestamp_get();
@ -2236,29 +2129,8 @@ void nrf_802154_trx_transmit_frame_transmitted(void)
ts -= nrf_802154_frame_duration_get(mp_tx_data[0], true, true) + RX_TX_TURNAROUND_TIME;
nrf_802154_stat_timestamp_write(last_cca_idle_timestamp, ts);
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
uint64_t cca_start_ts;
nrf_802154_stat_timestamp_read(&cca_start_ts, last_cca_start_timestamp);
t_listening += RX_RAMP_UP_TIME + (uint32_t)(ts - cca_start_ts);
t_transmit += RX_TX_TURNAROUND_TIME;
#endif
}
else
{
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
t_transmit += TX_RAMP_UP_TIME;
#endif
}
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
t_transmit += nrf_802154_frame_duration_get(mp_tx_data[PHR_OFFSET], true, true);
nrf_802154_stat_totals_increment(total_listening_time, t_listening);
nrf_802154_stat_totals_increment(total_transmit_time, t_transmit);
#endif
#endif
if (ack_is_requested(mp_tx_data))
@ -2270,22 +2142,12 @@ void nrf_802154_trx_transmit_frame_transmitted(void)
nrf_802154_trx_receive_buffer_set(rx_buffer_get());
#if (NRF_802154_FRAME_TIMESTAMP_ENABLED)
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
// Configure the timer coordinator to get a timestamp of the END event which
// fires several cycles after CRCOK or CRCERROR events.
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_end_event_handle_get());
#else
// Configure the timer coordinator to get a timestamp of the CRCOK event.
nrf_802154_timer_coord_timestamp_prepare(nrf_802154_trx_radio_crcok_event_handle_get());
#endif
#endif
nrf_802154_trx_receive_ack();
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
m_listening_start_hp_timestamp = nrf_802154_hp_timer_current_time_get();
#endif
if (!rx_buffer_free)
{
rx_buffer_in_use_set(nrf_802154_rx_buffer_free_find());
@ -2430,15 +2292,6 @@ void nrf_802154_trx_receive_ack_received(void)
// CRC of received frame is correct
uint8_t * p_ack_data = mp_current_rx_buffer->data;
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
uint32_t receive_end_hp_timestamp = nrf_802154_hp_timer_timestamp_get();
uint32_t listening_start_hp_timestamp = m_listening_start_hp_timestamp;
update_total_times_on_receive_end(listening_start_hp_timestamp,
receive_end_hp_timestamp,
mp_current_rx_buffer->data[PHR_OFFSET]);
#endif
if (ack_match_check(mp_tx_data, p_ack_data))
{
#if (NRF_802154_FRAME_TIMESTAMP_ENABLED)
@ -2517,12 +2370,6 @@ void nrf_802154_trx_transmit_frame_ccabusy(void)
nrf_802154_stat_counter_increment(cca_failed_attempts);
#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED)
uint32_t t_listening = RX_RAMP_UP_TIME + PHY_US_TIME_FROM_SYMBOLS(A_CCA_DURATION_SYMBOLS);
nrf_802154_stat_totals_increment(total_listening_time, t_listening);
#endif
state_set(RADIO_STATE_RX);
rx_init(TRX_RAMP_UP_SW_TRIGGER, NULL);
@ -2652,6 +2499,38 @@ bool nrf_802154_core_sleep(nrf_802154_term_t term_lvl)
return result;
}
static bool core_receive(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
bool notify_abort,
uint32_t id)
{
bool result = current_operation_terminate(term_lvl, req_orig, notify_abort);
if (result)
{
m_trx_receive_frame_notifications_mask =
make_trx_frame_receive_notification_mask();
m_rx_window_id = id;
state_set(RADIO_STATE_RX);
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);
}
}
return result;
}
bool nrf_802154_core_receive(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
nrf_802154_notification_func_t notify_function,
@ -2668,29 +2547,7 @@ bool nrf_802154_core_receive(nrf_802154_term_t term_lvl,
{
if (critical_section_can_be_processed_now())
{
result = current_operation_terminate(term_lvl, req_orig, notify_abort);
if (result)
{
m_trx_receive_frame_notifications_mask =
make_trx_frame_receive_notification_mask();
m_rx_window_id = id;
state_set(RADIO_STATE_RX);
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);
}
}
result = core_receive(term_lvl, req_orig, notify_abort, id);
}
else
{
@ -2790,6 +2647,42 @@ bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl,
return result;
}
bool nrf_802154_core_ack_timeout_handle(const nrf_802154_ack_timeout_handle_params_t * p_param)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
bool result = critical_section_enter_and_verify_timeslot_length();
if (result)
{
if ((m_state == RADIO_STATE_RX_ACK) && (p_param->p_frame == mp_tx_data))
{
bool r;
r = core_receive(NRF_802154_TERM_802154,
REQ_ORIG_ACK_TIMEOUT,
false,
NRF_802154_RESERVED_IMM_RX_WINDOW_ID);
assert(r);
(void)r;
nrf_802154_transmit_done_metadata_t metadata = {0};
nrf_802154_tx_work_buffer_original_frame_update(p_param->p_frame,
&metadata.frame_props);
nrf_802154_notify_transmit_failed(p_param->p_frame,
NRF_802154_TX_ERROR_NO_ACK,
&metadata);
}
nrf_802154_critical_section_exit();
}
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
return result;
}
bool nrf_802154_core_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);

View File

@ -153,6 +153,16 @@ bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl,
nrf_802154_transmit_params_t * p_params,
nrf_802154_notification_func_t notify_function);
/**
* @brief Requests end of waiting for an ACK by the core.
*
* @param[in] p_param Pointer to the notification parameters;
*
* @return true Request handled.
* @return false Request rejected due to already occupied critical section.
*/
bool nrf_802154_core_ack_timeout_handle(const nrf_802154_ack_timeout_handle_params_t * p_param);
/**
* @brief Requests the transition to the @ref RADIO_STATE_ED state.
*
@ -227,8 +237,8 @@ bool nrf_802154_core_notify_buffer_free(uint8_t * p_data);
* @brief Notifies the core module that the next higher layer requested the change of the channel.
*
* The core is expected to update the frequency register of the peripheral and, if it is
* in the @ref RADIO_STATE_RX, in the @ref RADIO_STATE_CONTINUOUS_CARRIER
* or in the @ref RADIO_STATE_MODULATED_CARRIER state, the transceiver is disabled
* in the @c RADIO_STATE_RX, in the @c RADIO_STATE_CONTINUOUS_CARRIER
* or in the @c RADIO_STATE_MODULATED_CARRIER state, the transceiver is disabled
* and enabled again to use the new channel.
*
* @param[in] req_orig Module that originates this request.

View File

@ -46,7 +46,7 @@
#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.
#define ED_RSSISCALE 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#else
#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.

View File

@ -86,19 +86,6 @@ extern "C" {
NRF_802154_EGU_INSTANCE_NO, \
_IRQHandler)
/**
* @def NRF_802154_EGU_IRQN
*
* The SWI EGU IRQ number used by the driver for requests and notifications if SWI is in use.
*
* @note This option is used when the driver uses SWI to process requests and notifications.
*
*/
#define NRF_802154_EGU_IRQN \
NRFX_CONCAT_3(NRFX_CONCAT_3(SWI, NRF_802154_EGU_INSTANCE_NO, _EGU), \
NRF_802154_EGU_INSTANCE_NO, \
_IRQn)
/**
* @def NRF_802154_RTC_INSTANCE_NO
*

View File

@ -82,17 +82,6 @@ extern "C" {
#define NRF_802154_EGU_IRQ_HANDLER \
NRFX_CONCAT_3(EGU, NRF_802154_EGU_INSTANCE_NO, _IRQHandler)
/**
* @def NRF_802154_EGU_IRQN
*
* The SWI EGU IRQ number used by the driver for requests and notifications if SWI is in use.
*
* @note This option is used when the driver uses SWI to process requests and notifications.
*
*/
#define NRF_802154_EGU_IRQN \
NRFX_CONCAT_3(EGU, NRF_802154_EGU_INSTANCE_NO, _IRQn)
/**
* @def NRF_802154_EGU_RAMP_UP_EVENT
*
@ -262,7 +251,7 @@ extern "C" {
#endif // NRF_802154_TEST_MODES_ENABLED
/**
* @def NRF_802154_DPPI_RADIO_CCABUSY
* @def NRF_802154_DPPI_RADIO_HW_TRIGGER
*
* The DPPI channel that triggers radio
*/

View File

@ -104,6 +104,14 @@ bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
nrf_802154_transmit_params_t * p_params,
nrf_802154_notification_func_t notify_function);
/**
* @brief Request to handle Ack timeout by the core module.
*
* @param[in] p_param Parameter to pass to nrf_802154_core_ack_timeout_handle
*
*/
bool nrf_802154_request_ack_timeout_handle(const nrf_802154_ack_timeout_handle_params_t * p_param);
/**
* @brief Requests entering the @ref RADIO_STATE_ED state.
*

View File

@ -100,6 +100,11 @@ bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
notify_function)
}
bool nrf_802154_request_ack_timeout_handle(const nrf_802154_ack_timeout_handle_params_t * p_param)
{
REQUEST_FUNCTION_PARMS(nrf_802154_core_ack_timeout_handle, p_param);
}
bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us)
{
REQUEST_FUNCTION_PARMS(nrf_802154_core_energy_detection, term_lvl, time_us)

View File

@ -76,6 +76,7 @@ typedef enum
REQ_TYPE_SLEEP,
REQ_TYPE_RECEIVE,
REQ_TYPE_TRANSMIT,
REQ_TYPE_ACK_TIMEOUT_HANDLE,
REQ_TYPE_ENERGY_DETECTION,
REQ_TYPE_CCA,
REQ_TYPE_CONTINUOUS_CARRIER,
@ -126,6 +127,12 @@ typedef struct
bool * p_result; ///< Transmit request result.
} transmit; ///< Transmit request details.
struct
{
const nrf_802154_ack_timeout_handle_params_t * p_param;
bool * p_result;
} ack_timeout_handle;
struct
{
nrf_802154_term_t term_lvl; ///< Request priority.
@ -272,7 +279,7 @@ static void req_exit(void)
/** Assert if SWI interrupt is disabled. */
static inline void assert_interrupt_status(void)
{
assert(nrf_802154_irq_is_enabled(NRF_802154_EGU_IRQN));
assert(nrf_802154_irq_is_enabled(nrfx_get_irq_number(NRF_802154_EGU_INSTANCE)));
}
#define REQUEST_FUNCTION(func_core, func_swi, ...) \
@ -314,7 +321,7 @@ static bool active_vector_priority_is_high(void)
{
return nrf_802154_critical_section_active_vector_priority_get() <=
nrf_802154_irq_priority_get(NRF_802154_EGU_IRQN);
nrf_802154_irq_priority_get(nrfx_get_irq_number(NRF_802154_EGU_INSTANCE));
}
/**
@ -397,6 +404,18 @@ static void swi_transmit(nrf_802154_term_t term_lvl,
req_exit();
}
static void swi_ack_timeout_handle(const nrf_802154_ack_timeout_handle_params_t * p_param,
bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
p_slot->type = REQ_TYPE_ACK_TIMEOUT_HANDLE;
p_slot->data.ack_timeout_handle.p_param = p_param;
p_slot->data.ack_timeout_handle.p_result = p_result;
req_exit();
}
/**
* @brief Requests entering the @ref RADIO_STATE_ED state from the SWI priority.
*
@ -696,6 +715,11 @@ bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
notify_function)
}
bool nrf_802154_request_ack_timeout_handle(const nrf_802154_ack_timeout_handle_params_t * p_param)
{
REQUEST_FUNCTION(nrf_802154_core_ack_timeout_handle, swi_ack_timeout_handle, p_param);
}
bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl,
uint32_t time_us)
{
@ -831,6 +855,11 @@ static void irq_handler_req_event(void)
p_slot->data.transmit.notif_func);
break;
case REQ_TYPE_ACK_TIMEOUT_HANDLE:
*(p_slot->data.ack_timeout_handle.p_result) =
nrf_802154_core_ack_timeout_handle(p_slot->data.ack_timeout_handle.p_param);
break;
case REQ_TYPE_ENERGY_DETECTION:
*(p_slot->data.energy_detection.p_result) =
nrf_802154_core_energy_detection(

View File

@ -38,14 +38,10 @@
#include "nrf_802154_stats.h"
#define NUMBER_OF_STAT_COUNTERS (sizeof(nrf_802154_stat_counters_t) / sizeof(uint32_t))
#define NUMBER_OF_STAT_TOTALS (sizeof(nrf_802154_stat_totals_t) / sizeof(uint64_t))
/**@brief Structure holding statistics about the Radio Driver behavior. */
volatile nrf_802154_stats_t g_nrf_802154_stats;
/**@brief Structure holding total times spent in certain states. */
volatile nrf_802154_stat_totals_t g_nrf_802154_stat_totals;
void nrf_802154_stats_get(nrf_802154_stats_t * p_stats)
{
*p_stats = g_nrf_802154_stats;
@ -88,32 +84,3 @@ void nrf_802154_stat_counters_reset(void)
*(p_dst++) = 0U;
}
}
void nrf_802154_stat_totals_get(nrf_802154_stat_totals_t * p_stat_totals)
{
volatile uint64_t * p_dst = (volatile uint64_t *)p_stat_totals;
const uint64_t * p_src = (const uint64_t *)(&g_nrf_802154_stat_totals);
nrf_802154_stat_totals_get_notify();
for (size_t i = 0; i < NUMBER_OF_STAT_TOTALS; ++i)
{
nrf_802154_mcu_critical_state_t mcu_cs;
nrf_802154_mcu_critical_enter(mcu_cs);
*p_dst = *p_src;
nrf_802154_mcu_critical_exit(mcu_cs);
p_dst++;
p_src++;
}
}
__WEAK void nrf_802154_stat_totals_get_notify(void)
{
/* Implementation here is intentionally empty.
*
* Implementation can be provided by other module to update g_nrf_802154_stat_totals
* to hold state until the moment of call.
*/
}

View File

@ -38,12 +38,10 @@
#include "nrf_802154_types.h"
#include "nrf_802154_utils.h"
#if !defined(UNIT_TEST)
#if !defined(TEST)
// Don't use directly. Use provided nrf_802154_stat_xxxx API macros.
extern volatile nrf_802154_stats_t g_nrf_802154_stats;
extern volatile nrf_802154_stat_totals_t g_nrf_802154_stat_totals;
/**@brief Increment one of the @ref nrf_802154_stat_counters_t fields.
*
* @param field_name Identifier of struct member to increment
@ -87,20 +85,7 @@ extern volatile nrf_802154_stat_totals_t g_nrf_802154_stat_totals;
} \
while (0)
#define nrf_802154_stat_totals_increment(field_name, value) \
do \
{ \
nrf_802154_mcu_critical_state_t mcu_cs; \
\
nrf_802154_mcu_critical_enter(mcu_cs); \
(g_nrf_802154_stat_totals.field_name) += (value); \
nrf_802154_mcu_critical_exit(mcu_cs); \
} \
while (0)
extern void nrf_802154_stat_totals_get_notify(void);
#else // !defined(UNIT_TEST)
#else // !defined(TEST)
#define nrf_802154_stat_counter_increment(field_name) \
nrf_802154_stat_counter_increment_func(offsetof(nrf_802154_stat_counters_t, field_name))
@ -118,6 +103,6 @@ void nrf_802154_stat_counter_increment_func(size_t field_offset);
void nrf_802154_stat_timestamp_write_func(size_t field_offset, uint64_t value);
uint64_t nrf_802154_stat_timestamp_read_func(size_t field_offset);
#endif // !defined(UNIT_TEST)
#endif // !defined(TEST)
#endif /* NRF_802154_STATS_H_ */

View File

@ -84,8 +84,10 @@ void nrf_802154_swi_init(void)
if (!initialized)
{
nrf_802154_irq_init(NRF_802154_EGU_IRQN, NRF_802154_SWI_PRIORITY, swi_irq_handler);
nrf_802154_irq_enable(NRF_802154_EGU_IRQN);
nrf_802154_irq_init(nrfx_get_irq_number(NRF_802154_EGU_INSTANCE),
NRF_802154_SWI_PRIORITY,
swi_irq_handler);
nrf_802154_irq_enable(nrfx_get_irq_number(NRF_802154_EGU_INSTANCE));
initialized = true;
}
}

View File

@ -71,15 +71,13 @@
#define EGU_SYNC_TASK NRF_EGU_TASK_TRIGGER3
#define EGU_SYNC_INTMASK NRF_EGU_INT_TRIGGERED3
#if defined(NRF52840_XXAA) || \
defined(NRF52833_XXAA)
#if defined(DPPI_PRESENT)
#define RADIO_BASE NRF_RADIO_NS_BASE
#define FICR_BASE NRF_FICR_NS_BASE
#else
#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
#endif
#define SHORT_ADDRESS_BCSTART NRF_RADIO_SHORT_ADDRESS_BCSTART_MASK
@ -88,9 +86,15 @@
#define SHORTS_IDLE 0
/// Value set to SHORTS register for RX operation.
#if !defined(NRF52_SERIES)
#define SHORTS_RX (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \
NRF_RADIO_SHORT_PHYEND_DISABLE_MASK | \
SHORT_ADDRESS_BCSTART)
#else
#define SHORTS_RX (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \
NRF_RADIO_SHORT_END_DISABLE_MASK | \
SHORT_ADDRESS_BCSTART)
#endif
#define SHORTS_RX_FREE_BUFFER (NRF_RADIO_SHORT_RXREADY_START_MASK)
@ -106,9 +110,15 @@
#define SHORTS_TX (NRF_RADIO_SHORT_TXREADY_START_MASK | \
NRF_RADIO_SHORT_PHYEND_DISABLE_MASK)
#if !defined(NRF52_SERIES)
#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \
NRF_RADIO_SHORT_PHYEND_DISABLE_MASK)
#else
#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \
NRF_RADIO_SHORT_END_DISABLE_MASK)
#endif
#define SHORTS_MOD_CARRIER (NRF_RADIO_SHORT_TXREADY_START_MASK | \
NRF_RADIO_SHORT_PHYEND_START_MASK)
@ -180,12 +190,12 @@ static const mpsl_fem_event_t m_activate_tx_cc0 =
static const mpsl_fem_event_t m_ccaidle =
{
.type = MPSL_FEM_EVENT_TYPE_GENERIC,
#if defined(NRF52_SERIES)
#if defined(DPPI_PRESENT)
.event.generic.event = NRF_802154_DPPI_RADIO_CCAIDLE
#else
.override_ppi = true,
.ppi_ch_id = PPI_CCAIDLE_FEM,
.event.generic.event = ((uint32_t)RADIO_BASE + (uint32_t)NRF_RADIO_EVENT_CCAIDLE)
#elif defined(NRF53_SERIES)
.event.generic.event = NRF_802154_DPPI_RADIO_CCAIDLE
#endif
};
@ -232,7 +242,7 @@ static void modulated_carrier_abort(void);
static void energy_detection_abort(void);
/** Clear flags describing frame being received. */
void rx_flags_clear(void)
static void rx_flags_clear(void)
{
m_flags.missing_receive_buffer = false;
m_flags.psdu_being_received = false;
@ -257,7 +267,7 @@ static void txpower_set(nrf_radio_txpower_t txpower)
}
/** Initialize TIMER peripheral used by the driver. */
void nrf_timer_init(void)
static 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);
@ -300,7 +310,7 @@ static void yopan_158_workaround(void)
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);
uint32_t prescaler = NRF_TIMER_PRESCALER_CALCULATE(base_frequency, 1000000);
nrf_timer_prescaler_set(NRF_802154_TIMER_INSTANCE, prescaler);
}
@ -533,6 +543,40 @@ static void errata_117_apply(void)
*p_radio_reg = ficr_reg;
}
static uint32_t m_pa_mod_filter_latched = 0;
static bool m_pa_mod_filter_is_latched = false;
/** @brief Applies modulation fix when PA is used.
*
* Shall be called after setting RADIO mode to NRF_RADIO_MODE_IEEE802154_250KBIT.
*
* @param[in] enable @c true if the appropriate register should be modified
* @c false if it should return to its previous, latched value
*/
static void pa_modulation_fix_apply(bool enable)
{
volatile uint32_t * p_radio_reg = (volatile uint32_t *)(RADIO_BASE + 0x584UL);
if (enable)
{
int8_t pa_gain = 0;
mpsl_fem_pa_is_configured(&pa_gain);
if (pa_gain > 0)
{
m_pa_mod_filter_latched = *(p_radio_reg);
m_pa_mod_filter_is_latched = true;
*(p_radio_reg) = 0x40081B08;
}
}
else if (m_pa_mod_filter_is_latched)
{
*(p_radio_reg) = m_pa_mod_filter_latched;
m_pa_mod_filter_is_latched = false;
}
}
#endif
static inline void wait_until_radio_is_disabled(void)
@ -616,6 +660,7 @@ void nrf_802154_trx_enable(void)
#if defined(NRF5340_XXAA)
// Apply ERRATA-117 after setting RADIO mode to NRF_RADIO_MODE_IEEE802154_250KBIT.
errata_117_apply();
pa_modulation_fix_apply(true);
#endif
memset(&packet_conf, 0, sizeof(packet_conf));
@ -649,13 +694,12 @@ void nrf_802154_trx_enable(void)
assert(nrf_radio_shorts_get(NRF_RADIO) == SHORTS_IDLE);
#if defined(NRF52840_XXAA) || \
defined(NRF52833_XXAA)
#if defined(DPPI_PRESENT)
mpsl_fem_abort_set(NRF_802154_DPPI_RADIO_DISABLED,
0U); /* The group parameter is ignored by FEM for SoCs with DPPIs */
#else
mpsl_fem_abort_set(nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_DISABLED),
PPI_CHGRP_ABORT);
#elif defined(NRF53_SERIES)
mpsl_fem_abort_set(NRF_802154_DPPI_RADIO_DISABLED,
0U); /* The group parameter is ignored by FEM for nRF53 */
#endif
mpsl_fem_deactivate_now(MPSL_FEM_ALL);
@ -736,10 +780,13 @@ void nrf_802154_trx_disable(void)
if (m_trx_state != TRX_STATE_DISABLED)
{
#if defined(NRF5340_XXAA)
pa_modulation_fix_apply(false);
#endif
#if defined(RADIO_POWER_POWER_Msk)
nrf_radio_power_set(NRF_RADIO, false);
#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();
@ -750,6 +797,8 @@ void nrf_802154_trx_disable(void)
nrf_radio_reset();
#endif
nrf_802154_irq_clear_pending(nrfx_get_irq_number(NRF_RADIO));
#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);
@ -1020,6 +1069,13 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
uint32_t ints_to_enable = 0U;
uint32_t shorts = SHORTS_RX;
if (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_DISABLED))
{
// For DRX a DISABLE event might be pending as a leftover from
// an aborted operation. Clear it to avoid spurious interrupts.
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
}
// Force the TIMER to be stopped and count from 0.
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
@ -1068,7 +1124,11 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
if (rampup_trigg_mode == TRX_RAMP_UP_HW_TRIGGER)
{
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
#if !defined(NRF53_SERIES)
ints_to_enable |= (NRF_RADIO_INT_READY_MASK | NRF_RADIO_INT_DISABLED_MASK);
#else
ints_to_enable |= NRF_RADIO_INT_READY_MASK;
#endif
}
bool allow_sync_swi = false;
@ -1252,6 +1312,13 @@ void nrf_802154_trx_transmit_frame(const void * p_tra
uint32_t ints_to_enable = 0U;
if (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_DISABLED))
{
// For DTX a DISABLE event might be pending as a leftover from
// an aborted operation. Clear it to avoid spurious interrupts.
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
}
// Force the TIMER to be stopped and count from 0.
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
@ -1281,7 +1348,11 @@ void nrf_802154_trx_transmit_frame(const void * p_tra
if (rampup_trigg_mode == TRX_RAMP_UP_HW_TRIGGER)
{
nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
#if !defined(NRF53_SERIES)
ints_to_enable |= (NRF_RADIO_INT_READY_MASK | NRF_RADIO_INT_DISABLED_MASK);
#else
ints_to_enable |= NRF_RADIO_INT_READY_MASK;
#endif
}
if (cca)
@ -1435,7 +1506,16 @@ 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 | NRF_RADIO_INT_ADDRESS_MASK;
#if !defined(NRF53_SERIES)
uint32_t ints_to_enable = NRF_RADIO_INT_PHYEND_MASK |
NRF_RADIO_INT_ADDRESS_MASK |
NRF_RADIO_INT_DISABLED_MASK;
#else
uint32_t ints_to_enable = NRF_RADIO_INT_PHYEND_MASK |
NRF_RADIO_INT_ADDRESS_MASK;
#endif
nrf_radio_int_enable(NRF_RADIO, ints_to_enable);
}
@ -1503,7 +1583,8 @@ static void rxframe_finish_disable_ints(void)
uint32_t ints_to_disable = NRF_RADIO_INT_READY_MASK |
NRF_RADIO_INT_ADDRESS_MASK |
NRF_RADIO_INT_CRCOK_MASK;
NRF_RADIO_INT_CRCOK_MASK |
NRF_RADIO_INT_DISABLED_MASK;
ints_to_disable |= NRF_RADIO_INT_CRCERROR_MASK;
ints_to_disable |= NRF_RADIO_INT_BCMATCH_MASK;
@ -1530,12 +1611,12 @@ static void rxframe_finish(void)
* Below shown what is happening in the hardware
*
* TIMER is started by path:
* RADIO.SHORT_END_DISABLE -> RADIO.TASKS_DISABLE -> RADIO.EVENTS_DISABLED ->
* RADIO.SHORT_PHYEND_DISABLE -> RADIO.TASKS_DISABLE -> RADIO.EVENTS_DISABLED ->
* PPI_DISABLED_EGU -> EGU.TASKS_TRIGGER -> EGU.EVENTS_TRIGGERED -> PPI_EGU_TIMER_START -> TIMER.TASKS_START
*
* FEM's LNA mode is disabled by path:
* RADIO.SHORT_END_DISABLE -> RADIO.TASKS_DISABLE -> RADIO.EVENTS_DISABLED -> (FEM's PPI triggering disable LNA operation,
* see mpsl_fem_abort_set() )
* RADIO.SHORT_PHYEND_DISABLE -> RADIO.TASKS_DISABLE -> RADIO.EVENTS_DISABLED -> (FEM's PPI triggering disable LNA
* operation, see mpsl_fem_abort_set() )
*
* RADIO will not ramp up, as PPI_EGU_RAMP_UP channel is self-disabling, and
* it was disabled when receive ramp-up was started.
@ -2078,10 +2159,6 @@ 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:
@ -2220,7 +2297,8 @@ static void txframe_finish_disable_ints(void)
NRF_RADIO_INT_CCAIDLE_MASK |
NRF_RADIO_INT_CCABUSY_MASK |
NRF_RADIO_INT_ADDRESS_MASK |
NRF_RADIO_INT_READY_MASK);
NRF_RADIO_INT_READY_MASK |
NRF_RADIO_INT_DISABLED_MASK);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
@ -2317,7 +2395,9 @@ static void txack_finish(void)
// Anomaly 78: use SHUTDOWN instead of STOP and CLEAR.
nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN);
nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_PHYEND_MASK | NRF_RADIO_INT_ADDRESS_MASK);
nrf_radio_int_disable(NRF_RADIO,
NRF_RADIO_INT_PHYEND_MASK | NRF_RADIO_INT_ADDRESS_MASK |
NRF_RADIO_INT_DISABLED_MASK);
/* Current state of peripherals
* RADIO is either in TXDISABLE or DISABLED
@ -2406,6 +2486,17 @@ static void irq_handler_disabled(void)
go_idle_finish();
break;
case TRX_STATE_TXFRAME:
case TRX_STATE_TXACK:
case TRX_STATE_RXFRAME:
// Robust radio ramp-down requires that RADIO.DISABLE is cleared. If the ramp-up was
// triggered by software, the event was cleared already immediately after triggering
// RADIO.DISABLE task. If the ramp-up was triggered by (D)PPI, the event would need
// to be cleared. The IRQ handler does that on entry to irq_handler_disabled. What
// remains to be done is disabling the DISABLED interrupt, as it won't be needed.
nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_DISABLED_MASK);
break;
default:
assert(false);
}

View File

@ -48,6 +48,9 @@
#include "hal/nrf_radio.h"
#include "hal/nrf_timer.h"
#define EGU_EVENT NRF_802154_EGU_RAMP_UP_EVENT
#define EGU_TASK NRF_802154_EGU_RAMP_UP_TASK
#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
@ -130,7 +133,7 @@ void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ra
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, NRF_802154_EGU_RAMP_UP_EVENT);
nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT);
nrf_dppi_channels_include_in_group(NRF_802154_DPPIC_INSTANCE,
1UL << PPI_EGU_RAMP_UP,
@ -144,9 +147,9 @@ void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ra
nrf_timer_subscribe_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START, PPI_DISABLED_EGU);
}
nrf_egu_publish_set(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_EVENT, PPI_EGU_RAMP_UP);
nrf_egu_publish_set(NRF_802154_EGU_INSTANCE, EGU_EVENT, PPI_EGU_RAMP_UP);
nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_TASK, PPI_DISABLED_EGU);
nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, EGU_TASK, PPI_DISABLED_EGU);
nrf_dppi_channels_enable(NRF_802154_DPPIC_INSTANCE,
(1UL << PPI_EGU_RAMP_UP));
@ -173,7 +176,7 @@ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool st
nrf_dppi_channels_disable(NRF_802154_DPPIC_INSTANCE,
(1UL << PPI_EGU_RAMP_UP));
nrf_egu_publish_clear(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_EVENT);
nrf_egu_publish_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT);
nrf_radio_subscribe_clear(NRF_RADIO, ramp_up_task);
nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
nrf_dppi_subscribe_clear(NRF_802154_DPPIC_INSTANCE, DPPI_CHGRP_RAMP_UP_DIS_TASK);
@ -186,7 +189,7 @@ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool st
nrf_timer_subscribe_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START);
}
nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, NRF_802154_EGU_RAMP_UP_TASK);
nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, EGU_TASK);
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
@ -216,7 +219,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, NRF_802154_EGU_RAMP_UP_EVENT))
if (nrf_egu_event_check(NRF_802154_EGU_INSTANCE, EGU_EVENT))
{
// If EGU event is set, procedure is running.
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);

View File

@ -34,7 +34,6 @@
#include "nrf_802154_tx_power.h"
#include "nrf_802154_pib.h"
#include "nrf_802154_utils.h"
#include "nrf_802154_fal.h"
int8_t nrf_802154_tx_power_convert_metadata_to_tx_power_split(

View File

@ -83,8 +83,4 @@ int8_t nrf_802154_tx_power_split_pib_power_for_channel_get(
uint8_t channel,
nrf_802154_fal_tx_power_split_t * const p_split_power);
/**
*@}
**/
#endif // NRF_802154_TX_POWER_H__

View File

@ -47,4 +47,9 @@ typedef struct
// until its preconditions are met.
} nrf_802154_transmit_params_t;
typedef struct
{
uint8_t * p_frame; // !< Pointer to the frame for which the timeout of ack reception is notified.
} nrf_802154_ack_timeout_handle_params_t;
#endif // NRF_802154_TYPES_INTERNAL_H__

View File

@ -75,9 +75,6 @@
*/
#define NUMELTS(X) (sizeof((X)) / sizeof(X[0]))
/**@brief Wait procedure used in a busy loop. */
#define nrf_802154_busy_wait() __WFE()
/**@brief Active waiting for given number of microseconds.
*
* It is guaranteed that execution of this macro will take at least @c time_in_us

View File

@ -382,6 +382,17 @@ void nrf_802154_extended_address_set(const uint8_t * p_extended_address);
*/
void nrf_802154_pan_coord_set(bool enabled);
#if NRF_802154_PAN_COORD_GET_ENABLED
/**
* @brief Checks if the radio is configured as the PAN coordinator.
*
* @retval true The radio is configured as the PAN coordinator.
* @retval false The radio is not configured as the PAN coordinator.
*/
bool nrf_802154_pan_coord_get(void);
#endif // NRF_802154_PAN_COORD_GET_ENABLED
/**
* @brief Enables or disables the promiscuous radio mode.
*
@ -704,6 +715,10 @@ int8_t nrf_802154_dbm_from_energy_level_calculate(uint8_t energy_level);
/**
* @brief Calculates the timestamp of the first symbol of the preamble in a received frame.
*
* @deprecated This function is deprecated. Use @ref nrf_802154_timestamp_end_to_phr_convert
* instead and adjust the code that calls this function to rely on the timestamp of the first symbol
* of the PHR, not the timestamp of the first symbol of the frame.
*
* @param[in] end_timestamp Timestamp of the end of the last symbol in the frame,
* in microseconds.
* @param[in] psdu_length Number of bytes in the frame PSDU.
@ -716,6 +731,10 @@ uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t p
/**
* @brief Calculates the timestamp of the MAC Header in a received frame.
*
* @deprecated This function is deprecated. Use @ref nrf_802154_timestamp_end_to_phr_convert
* instead and adjust the code that calls this function to rely on the timestamp of the first symbol
* of the PHR, not the MAC Header timestamp.
*
* @param[in] end_timestamp Timestamp of the end of the last symbol in the frame,
* in microseconds.
* @param[in] psdu_length Number of bytes in the frame PSDU.
@ -724,6 +743,31 @@ uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t p
*/
uint64_t nrf_802154_mhr_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length);
/**
* @brief Converts the timestamp of the frame's end to the timestamp of the start of its PHR.
*
* This function calculates the time when the first symbol of the PHR is at the local antenna.
*
* @param[in] end_timestamp Timestamp of the end of the last symbol in the frame,
* in microseconds.
* @param[in] psdu_length Number of bytes in the frame PSDU.
*
* @return Timestamp of the start of the PHR of a given frame, in microseconds.
*/
uint64_t nrf_802154_timestamp_end_to_phr_convert(uint64_t end_timestamp, uint8_t psdu_length);
/**
* @brief Converts the timestamp of the frame's PHR to the timestamp of the start of its SHR.
*
* This function converts the time when the first symbol of the frame's PHR is at the local antenna
* to the timestamp of the start of the frame's SHR.
*
* @param[in] phr_timestamp Timestamp of the frame's PHR.
*
* @return Timestamp of the start of the SHR of a given frame, in microseconds.
*/
uint64_t nrf_802154_timestamp_phr_to_shr_convert(uint64_t phr_timestamp);
/**
* @}
* @defgroup nrf_802154_ifs Inter-frame spacing feature
@ -883,16 +927,22 @@ void nrf_802154_csl_writer_period_set(uint16_t period);
/**
* @brief Sets the anchor time based on which the next CSL window time and the CSL phase is calculated.
*
* This function sets an anchor time which is a time of a CSL window, based which on the times of future CSL windows are
* calculated. It is assumed that all other CSL windows occur at time @c anchor_time + @c n * @c csl_period, where @c n is
* an integer. Note that the anchor time can be both in the past and in the future.
* This function sets an anchor time based on which the times of future CSL windows are calculated.
* When this anchor time is used for calculations, it is assumed that it points to a time where
* the first bit of MAC header of the frame received from a peer happens. In other words, the anchor
* time should point to a time where CSL phase would be equal 0. As a result, CSL phase can always
* be calculated relatively to a time given by the equation @c anchor_time + @c n * @c csl_period
* where @c n is an integer. Note that the reasoning holds irrespectively of signedness of @c n
* so the anchor time can be either in the past or in the future.
*
* This function should be called after calling @ref nrf_802154_csl_writer_period_set and every time when the CSL windows get desynchronized.
* This function should be called after calling @ref nrf_802154_csl_writer_period_set and every time
* when the CSL communication desynchronizes.
*
* If this function is not called, a legacy CSL operation mode is chosen, where the CSL phase is calculated based on the time of the nearest
* scheduled CSL window (and can be undefined, if no such window was scheduled).
* If this function is not called a legacy CSL operation mode is chosen. The CSL phase is then
* calculated based on the time of the nearest scheduled CSL reception window and can be undefined,
* if no such window was scheduled.
*
* @param[in] period Anchor time value.
* @param[in] anchor_time Anchor time in microseconds.
*/
void nrf_802154_csl_writer_anchor_time_set(uint64_t anchor_time);

View File

@ -46,7 +46,7 @@
#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.
#define ED_RSSISCALE 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#else
#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.

View File

@ -53,10 +53,8 @@ extern "C" {
#ifndef CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT
/**
* @brief Default response timeout in us for response to serialized request.
*
* TODO: What timeout is good?
*/
#define CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT 100
#define CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT 500
#endif /* CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT */
/**

View File

@ -453,6 +453,12 @@ typedef enum
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_SECURITY_GLOBAL_FRAME_COUNTER_SET_IF_LARGER =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 64,
/**
* Vendor property for nrf_802154_pan_coord_get serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PAN_COORD_GET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 65,
} spinel_prop_vendor_key_t;
/**
@ -821,6 +827,16 @@ typedef enum
*/
#define SPINEL_DATATYPE_NRF_802154_PAN_COORD_SET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_pan_coord_get result.
*/
#define SPINEL_DATATYPE_NRF_802154_PAN_COORD_GET_RET SPINEL_DATATYPE_BOOL_S
/**
* @brief Spinel data type description for nrf_802154_pan_coord_get.
*/
#define SPINEL_DATATYPE_NRF_802154_PAN_COORD_GET SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_promiscuous_set.
*/

View File

@ -656,6 +656,40 @@ bail:
return;
}
#if NRF_802154_PAN_COORD_GET_ENABLED
bool nrf_802154_pan_coord_get(void)
{
nrf_802154_ser_err_t res;
bool result = false;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PAN_COORD_GET);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PAN_COORD_GET,
SPINEL_DATATYPE_NRF_802154_PAN_COORD_GET,
&result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT,
&result);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return result;
}
#endif // NRF_802154_PAN_COORD_GET_ENABLED
void nrf_802154_pan_coord_set(bool enabled)
{
nrf_802154_ser_err_t res;
@ -1794,6 +1828,18 @@ uint64_t nrf_802154_mhr_timestamp_get(uint64_t end_timestamp, uint8_t psdu_lengt
return end_timestamp - (psdu_length * PHY_SYMBOLS_PER_OCTET * PHY_US_PER_SYMBOL);
}
uint64_t nrf_802154_timestamp_end_to_phr_convert(uint64_t end_timestamp, uint8_t psdu_length)
{
uint32_t frame_symbols = (PHR_SIZE + psdu_length) * PHY_SYMBOLS_PER_OCTET;
return end_timestamp - (frame_symbols * PHY_US_PER_SYMBOL);
}
uint64_t nrf_802154_timestamp_phr_to_shr_convert(uint64_t phr_timestamp)
{
return phr_timestamp - (PHY_SHR_SYMBOLS * PHY_US_PER_SYMBOL);
}
void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter)
{
nrf_802154_ser_err_t res;

View File

@ -366,6 +366,25 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pan_coord_set(
return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK);
}
#if NRF_802154_PAN_COORD_GET_ENABLED
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_pan_coord_get(
const void * p_property_data,
size_t property_data_len)
{
(void)p_property_data;
(void)property_data_len;
bool result = nrf_802154_pan_coord_get();
return nrf_802154_spinel_send_cmd_prop_value_is(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PAN_COORD_GET,
SPINEL_DATATYPE_NRF_802154_PAN_COORD_GET_RET,
result);
}
#endif // NRF_802154_PAN_COORD_GET_ENABLED
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PROMISCUOUS_SET.
*
@ -1889,6 +1908,12 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PAN_COORD_SET:
return spinel_decode_prop_nrf_802154_pan_coord_set(p_property_data, property_data_len);
#if NRF_802154_PAN_COORD_GET_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PAN_COORD_GET:
return spinel_decode_prop_nrf_802154_pan_coord_get(p_property_data, property_data_len);
#endif // NRF_802154_PAN_COORD_GET_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_PROMISCUOUS_SET:
return spinel_decode_prop_nrf_802154_promiscuous_set(p_property_data,

View File

@ -40,6 +40,8 @@
#ifndef NRF_802154_SL_CONFIG_H__
#define NRF_802154_SL_CONFIG_H__
#include <nrfx.h>
#if NRF_802154_USE_INTERNAL_INCLUDES
#include "nrf_802154_sl_config_internal.h"
#endif
@ -81,7 +83,11 @@
* Configures if antenna diversity is to be enabled.
*/
#ifndef NRF_802154_SL_ANT_DIV_ENABLED
#if defined(PPI_PRESENT)
#define NRF_802154_SL_ANT_DIV_ENABLED 1
#else
#define NRF_802154_SL_ANT_DIV_ENABLED 0
#endif
#endif
#endif // NRF_802154_SL_CONFIG_H__

View File

@ -322,6 +322,7 @@ bool nrf_802154_rsch_delayed_timeslot_priority_update(rsch_dly_ts_id_t dly_ts_id
*/
bool nrf_802154_rsch_delayed_timeslot_time_to_start_get(rsch_dly_ts_id_t dly_ts_id,
uint64_t * p_time_to_start);
/**
* @brief Checks if there is a pending timeslot request.
*
@ -363,6 +364,15 @@ uint32_t nrf_802154_rsch_timeslot_us_left_get(void);
*/
extern void nrf_802154_rsch_continuous_prio_changed(rsch_prio_t prio);
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
/**
* @brief Retrieves time remaining to hardware trigger of a delayed timeslot.
*
* @note This function exists for testing purposes only. It should not be used in products.
*/
uint32_t nrf_802154_rsch_delayed_timeslot_time_to_hw_trigger_get(void);
#endif /* defined(CONFIG_SOC_SERIES_BSIM_NRFXX) */
/**
*@}
**/

View File

@ -187,3 +187,11 @@ bool nrf_802154_rsch_delayed_timeslot_ppi_update(uint32_t ppi_channel)
return false;
}
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
uint32_t nrf_802154_rsch_delayed_timeslot_time_to_hw_trigger_get(void)
{
return 0;
}
#endif