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: 362d2e7af15725f28225a4589ac67aa16c839f38

Signed-off-by: Jędrzej Ciupis <jedrzej.ciupis@nordicsemi.no>
This commit is contained in:
Jędrzej Ciupis 2022-11-14 09:12:04 +01:00 committed by Andrzej Głąbek
parent 4ee20fd6ca
commit fe0be3c354
29 changed files with 356 additions and 196 deletions

View File

@ -161,7 +161,7 @@ void nrf_802154_tx_power_set(int8_t power);
/**
* @brief Gets the currently set transmit power.
*
* @returns Currently used transmit power, in dBm.
* @returns Currently used real total transmit power, in dBm.
*/
int8_t nrf_802154_tx_power_get(void);
@ -1818,6 +1818,22 @@ nrf_802154_security_error_t nrf_802154_security_key_remove(nrf_802154_key_id_t *
*/
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 should be called after calling @ref nrf_802154_csl_writer_period_set and every time when the CSL windows get desynchronized.
*
* 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).
*
* @param[in] period Anchor time value.
*/
void nrf_802154_csl_writer_anchor_time_set(uint64_t anchor_time);
/**
* @}
* @defgroup nrf_802154_test_modes Test modes

View File

@ -481,27 +481,6 @@ typedef struct
} data; // !< Result values that are valid only for successful operations.
} nrf_802154_transmit_done_metadata_t;
/**
* @brief Represents components of tx_power to be applied for stages on transmit path.
*/
typedef struct
{
nrf_radio_txpower_t radio_tx_power; // !< TX power to be applied to the RADIO peripheral.
int8_t fem_gain; // !< Gain of the Front-End Module in dB.
} nrf_802154_tx_power_split_t;
/**
* @brief Structure that holds transmission parameters.
*/
typedef struct
{
nrf_802154_transmitted_frame_props_t frame_props; // !< Properties of the frame to be transmitted.
nrf_802154_tx_power_split_t tx_power; // !< Power to be used when transmitting the frame, split into components to be applied on each stage on transmit path.
bool cca; // !< If the driver is to perform CCA procedure before transmission.
bool immediate; // !< If true, the driver schedules transmission immediately or never. If false, the transmission may be postponed
// until its preconditions are met.
} nrf_802154_transmit_params_t;
/**
* @brief Function pointer used for notifying about transmission failure.
*/

View File

@ -77,7 +77,7 @@ static uint8_t m_be; ///< Backoff exponent,
static uint8_t * mp_data; ///< Pointer to a buffer containing PHR and PSDU of the frame being transmitted.
static nrf_802154_transmitted_frame_props_t m_data_props; ///< Structure containing detailed properties of data in buffer.
static nrf_802154_tx_power_split_t m_tx_power; ///< Power to be used when transmitting the frame split into components.
static nrf_802154_fal_tx_power_split_t m_tx_power; ///< Power to be used when transmitting the frame split into components.
static csma_ca_state_t m_state; ///< The current state of the CSMA-CA procedure.
/**

View File

@ -46,6 +46,7 @@
#include "nrf_802154_nrfx_addons.h"
#include "nrf_802154_tx_work_buffer.h"
#include "nrf_802154_utils_byteorder.h"
#include "nrf_802154_sl_timer.h"
#include <assert.h>
@ -62,9 +63,46 @@ static writer_state_t m_writer_state = IE_WRITER_RESET; ///< IE writer state
#if NRF_802154_DELAYED_TRX_ENABLED
static uint8_t * mp_csl_phase_addr; ///< Cached CSL information element phase field address
static uint8_t * mp_csl_period_addr; ///< Cached CSL information element period field address
static uint16_t m_csl_period; ///< CSL period value that will be injected to CSL information element
static uint8_t * mp_csl_phase_addr; ///< Cached CSL information element phase field address
static uint8_t * mp_csl_period_addr; ///< Cached CSL information element period field address
static uint16_t m_csl_period; ///< CSL period value that will be injected to CSL information element
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)
{
bool result = false;
if (m_csl_anchor_time_set)
{
result = (m_csl_period != 0);
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;
// Modulo of a negative number possibly will not be positive, so the below if-else clause is needed
if (now >= m_csl_anchor_time)
{
uint32_t time_from_previous_window =
(uint32_t)((now - m_csl_anchor_time) % csl_period_us);
*p_time_to_midpoint = csl_period_us - time_from_previous_window;
}
else
{
*p_time_to_midpoint = (uint32_t)((m_csl_anchor_time - now) % csl_period_us);
}
}
}
else
{
result = nrf_802154_delayed_trx_nearest_drx_time_to_midpoint_get(p_time_to_midpoint);
}
return result;
}
/**
* @brief Writes CSL phase to previously set memory address.
@ -84,7 +122,7 @@ static void csl_ie_write_commit(bool * p_written)
return;
}
if (nrf_802154_delayed_trx_nearest_drx_time_to_midpoint_get(&time_remaining) == false)
if (csl_time_to_nearest_window_midpoint_get(&time_remaining) == false)
{
// No delayed DRX is pending. Do not write to the CSL IE.
return;
@ -505,6 +543,12 @@ void nrf_802154_ie_writer_csl_period_set(uint16_t period)
m_csl_period = period;
}
void nrf_802154_ie_writer_csl_anchor_time_set(uint64_t anchor_time)
{
m_csl_anchor_time = anchor_time;
m_csl_anchor_time_set = true;
}
#endif // NRF_802154_DELAYED_TRX_ENABLED
#endif // NRF_802154_IE_WRITER_ENABLED

View File

@ -38,7 +38,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
/**
* @defgroup nrf_802154_ie_writer Radio driver Information Element data injection feature.
@ -134,6 +134,13 @@ bool nrf_802154_ie_writer_tx_started_hook(uint8_t * p_frame);
*/
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.
*/
void nrf_802154_ie_writer_csl_anchor_time_set(uint64_t anchor_time);
/**
*@}
**/

View File

@ -39,7 +39,7 @@
#include <stdint.h>
#include "nrf_802154_const.h"
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
/**
* @brief Initializes the Interframe Spacing handling feature.

View File

@ -38,7 +38,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
/**
* @brief Transmission setup hook for the security writer module.

View File

@ -156,11 +156,9 @@ void nrf_802154_tx_power_set(int8_t power)
int8_t nrf_802154_tx_power_get(void)
{
nrf_802154_tx_power_split_t split_power = {0};
nrf_802154_fal_tx_power_split_t split_power = {0};
(void)nrf_802154_tx_power_split_pib_power_get(&split_power);
return split_power.fem_gain + split_power.radio_tx_power;
return nrf_802154_tx_power_split_pib_power_get(&split_power);
}
bool nrf_802154_coex_rx_request_mode_set(nrf_802154_coex_rx_request_mode_t mode)
@ -1085,6 +1083,11 @@ void nrf_802154_csl_writer_period_set(uint16_t period)
nrf_802154_ie_writer_csl_period_set(period);
}
void nrf_802154_csl_writer_anchor_time_set(uint64_t anchor_time)
{
nrf_802154_ie_writer_csl_anchor_time_set(anchor_time);
}
#endif
__WEAK void nrf_802154_custom_part_of_radio_init(void)

View File

@ -64,7 +64,7 @@
#include "nrf_802154_trx.h"
#include "nrf_802154_tx_work_buffer.h"
#include "nrf_802154_tx_power.h"
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
#include "nrf_802154_utils.h"
#include "drivers/nrfx_errors.h"
#include "hal/nrf_radio.h"
@ -114,13 +114,13 @@ static rx_buffer_t * const mp_current_rx_buffer = &nrf_802154_rx_buffers[0];
#endif
static uint8_t * mp_ack; ///< Pointer to Ack frame buffer.
static uint8_t * mp_tx_data; ///< Pointer to the data to transmit.
static uint32_t m_ed_time_left; ///< Remaining time of the current energy detection procedure [us].
static uint8_t m_ed_result; ///< Result of the current energy detection procedure.
static uint8_t m_last_lqi; ///< LQI of the last received non-ACK frame, corrected for the temperature.
static nrf_802154_tx_power_split_t m_tx_power; ///< Power to be used to transmit the current frame split into components.
static int8_t m_last_rssi; ///< RSSI of the last received non-ACK frame, corrected for the temperature.
static uint8_t * mp_ack; ///< Pointer to Ack frame buffer.
static uint8_t * mp_tx_data; ///< Pointer to the data to transmit.
static uint32_t m_ed_time_left; ///< Remaining time of the current energy detection procedure [us].
static uint8_t m_ed_result; ///< Result of the current energy detection procedure.
static uint8_t m_last_lqi; ///< LQI of the last received non-ACK frame, corrected for the temperature.
static nrf_802154_fal_tx_power_split_t m_tx_power; ///< Power to be used to transmit the current frame split into components.
static int8_t m_last_rssi; ///< RSSI of the last received non-ACK frame, corrected for the temperature.
static nrf_802154_frame_parser_data_t m_current_rx_frame_data; ///< RX frame parser data.
@ -1024,7 +1024,7 @@ static void rx_init(void)
nrf_802154_trx_receive_buffer_set(rx_buffer_get());
nrf_802154_tx_power_split_t split_power = {0};
nrf_802154_fal_tx_power_split_t split_power = {0};
(void)nrf_802154_tx_power_split_pib_power_get(&split_power);
@ -1156,7 +1156,7 @@ static void continuous_carrier_init(void)
{
return;
}
nrf_802154_tx_power_split_t split_power = {0};
nrf_802154_fal_tx_power_split_t split_power = {0};
(void)nrf_802154_tx_power_split_pib_power_get(&split_power);
@ -1176,7 +1176,7 @@ static void modulated_carrier_init(const uint8_t * p_data)
return;
}
nrf_802154_tx_power_split_t split_power = {0};
nrf_802154_fal_tx_power_split_t split_power = {0};
(void)nrf_802154_tx_power_split_pib_power_get(&split_power);
@ -1908,7 +1908,7 @@ void nrf_802154_trx_receive_frame_crcerror(void)
#if !NRF_802154_DISABLE_BCC_MATCHING
request_preconditions_for_state(m_state);
nrf_802154_tx_power_split_t split_power = {0};
nrf_802154_fal_tx_power_split_t split_power = {0};
(void)nrf_802154_tx_power_split_pib_power_get(&split_power);

View File

@ -46,7 +46,7 @@
#include "nrf_802154_config.h"
#include "nrf_802154_notification.h"
#include "nrf_802154_rx_buffer.h"
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
#ifdef __cplusplus
extern "C" {
@ -58,31 +58,29 @@ extern "C" {
typedef enum
{
// Sleep
RADIO_STATE_SLEEP, ///< Low power mode (disabled) - the only state in which all radio preconditions are not requested.
RADIO_STATE_FALLING_ASLEEP, ///< Before entering the sleep state, all radio preconditions are requested.
RADIO_STATE_SLEEP, ///< Low power mode (disabled) - the only state in which all radio preconditions are not requested.
RADIO_STATE_FALLING_ASLEEP, ///< Before entering the sleep state, all radio preconditions are requested.
// Receive
RADIO_STATE_RX, ///< The receiver is enabled and it is receiving frames.
RADIO_STATE_TX_ACK, ///< The frame is received and the ACK is being transmitted.
RADIO_STATE_RX, ///< The receiver is enabled and it is receiving frames.
RADIO_STATE_TX_ACK, ///< The frame is received and the ACK is being transmitted.
// Transmit
RADIO_STATE_CCA_TX, ///< Performing CCA followed by the frame transmission.
RADIO_STATE_TX, ///< Transmitting data frame (or beacon).
RADIO_STATE_RX_ACK, ///< Receiving ACK after the transmitted frame.
RADIO_STATE_CCA_TX, ///< Performing CCA followed by the frame transmission.
RADIO_STATE_TX, ///< Transmitting data frame (or beacon).
RADIO_STATE_RX_ACK, ///< Receiving ACK after the transmitted frame.
// Energy Detection
RADIO_STATE_ED, ///< Performing the energy detection procedure.
RADIO_STATE_ED, ///< Performing the energy detection procedure.
// CCA
RADIO_STATE_CCA, ///< Performing the CCA procedure.
RADIO_STATE_CCA, ///< Performing the CCA procedure.
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
// Continuous carrier
RADIO_STATE_CONTINUOUS_CARRIER, ///< Emitting the continuous carrier wave.
// Modulated carrier
RADIO_STATE_MODULATED_CARRIER ///< Emitting the modulated carrier signal.
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
} radio_state_t;

View File

@ -53,7 +53,6 @@
#include "mac_features/nrf_802154_ifs.h"
#include "nrf_802154_encrypt.h"
#include "nrf_802154_config.h"
#include "nrf_802154_types.h"
typedef bool (* abort_hook)(nrf_802154_term_t term_lvl, req_originator_t req_orig);
typedef bool (* pre_transmission_hook)(uint8_t * p_frame,

View File

@ -39,7 +39,7 @@
#include <stdint.h>
#include "nrf_802154_const.h"
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
/**
* @defgroup nrf_802154_hooks Hooks for the 802.15.4 driver core

View File

@ -40,7 +40,7 @@
#include "nrf_802154_aes_ccm.h"
#include "nrf_802154_const.h"
#include "nrf_802154_pib.h"
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
#include "mac_features/nrf_802154_frame_parser.h"
#include "mac_features/nrf_802154_security_pib.h"

View File

@ -38,7 +38,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
#include "mac_features/nrf_802154_frame_parser.h"
#ifdef __cplusplus

View File

@ -40,7 +40,7 @@
#include "nrf_802154_const.h"
#include "nrf_802154_notification.h"
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
#ifdef __cplusplus
extern "C" {

View File

@ -51,7 +51,6 @@
#include "nrf_802154_queue.h"
#include "nrf_802154_rx_buffer.h"
#include "nrf_802154_swi.h"
#include "nrf_802154_types.h"
#include "nrf_802154_utils.h"
#include "mac_features/nrf_802154_csma_ca.h"
#include "hal/nrf_radio.h"

View File

@ -94,7 +94,7 @@ uint8_t nrf_802154_rssi_cca_ed_threshold_corrected_get(uint8_t cca_ed);
/**
* @brief Convert the hardware reported energy detection value to a value compliant with the 802.15.4 specification.
*
* @param[in] edsample The hardware reported value
* @param[in] ed_sample The hardware reported value
*
* @returns 802.15.4 compliant energy detection value.
*/

View File

@ -51,6 +51,9 @@
#include "hal/nrf_egu.h"
#include "hal/nrf_radio.h"
#include "hal/nrf_timer.h"
#if defined(NRF53_SERIES)
#include "hal/nrf_vreqctrl.h"
#endif
#include "nrf_802154_procedures_duration.h"
#include "nrf_802154_critical_section.h"
@ -195,7 +198,6 @@ static nrf_802154_flags_t m_flags; ///< Flags used to store the current driver s
/** @brief Value of TIMER internal counter from which the counting is resumed on RADIO.EVENTS_END event. */
static volatile uint32_t m_timer_value_on_radio_end_event;
static volatile bool m_transmit_with_cca;
static int8_t m_fem_gain_in_disabled;
static void rxframe_finish_disable_ppis(void);
static void rxack_finish_disable_ppis(void);
@ -226,13 +228,29 @@ void rx_flags_clear(void)
static void * volatile mp_receive_buffer;
static void txpower_set(nrf_radio_txpower_t txpower)
{
#ifdef NRF53_SERIES
bool radio_high_voltage_enable = false;
if ((int8_t)txpower > 0)
{
/* To get higher than 0dBm raise operating voltage of the radio, giving 3dBm power boost */
radio_high_voltage_enable = true;
txpower -= 3;
}
nrf_vreqctrl_radio_high_voltage_set(NRF_VREQCTRL_NS, radio_high_voltage_enable);
#endif
nrf_radio_txpower_set(NRF_RADIO, txpower);
}
/** Initialize TIMER peripheral used by the driver. */
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_frequency_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_FREQ_1MHz);
nrf_timer_prescaler_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_FREQ_1MHz);
#if NRF_802154_DISABLE_BCC_MATCHING
// Setup timer for detecting PSDU reception.
@ -320,9 +338,9 @@ static void fem_for_lna_reset(void)
*
* @note This function must be called before ramp up PPIs are configured.
*/
static void fem_for_pa_set(int8_t gain)
static void fem_for_pa_set(const mpsl_fem_gain_t * p_fem_gain_data)
{
(void)mpsl_fem_pa_gain_set(gain);
(void)mpsl_fem_pa_gain_set(p_fem_gain_data);
if (mpsl_fem_pa_configuration_set(&m_activate_tx_cc0, NULL) == 0)
{
nrf_timer_shorts_enable(m_activate_tx_cc0.event.timer.p_timer_instance,
@ -347,11 +365,11 @@ static void fem_for_pa_reset(void)
*
* @note This function must be called before ramp up PPIs are configured.
*/
static void fem_for_tx_set(bool cca, int8_t gain)
static void fem_for_tx_set(bool cca, const mpsl_fem_gain_t * p_fem_gain_data)
{
bool success;
(void)mpsl_fem_pa_gain_set(gain);
(void)mpsl_fem_pa_gain_set(p_fem_gain_data);
if (cca)
{
@ -461,7 +479,6 @@ void nrf_802154_trx_module_reset(void)
m_trx_state = TRX_STATE_DISABLED;
m_timer_value_on_radio_end_event = 0;
m_transmit_with_cca = false;
m_fem_gain_in_disabled = 0;
mp_receive_buffer = NULL;
memset(&m_flags, 0, sizeof(m_flags));
@ -534,8 +551,6 @@ void nrf_802154_trx_enable(void)
assert(nrf_radio_shorts_get(NRF_RADIO) == SHORTS_IDLE);
mpsl_fem_pa_is_configured(&m_fem_gain_in_disabled);
#if defined(NRF52840_XXAA) || \
defined(NRF52833_XXAA)
mpsl_fem_abort_set(nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_DISABLED),
@ -646,9 +661,6 @@ void nrf_802154_trx_disable(void)
mpsl_fem_pa_configuration_clear();
mpsl_fem_abort_clear();
/* Restore gain of the FEM to the state latched in nrf_802154_trx_enable */
(void)mpsl_fem_pa_gain_set(m_fem_gain_in_disabled);
if (m_trx_state != TRX_STATE_IDLE)
{
fem_power_down_now();
@ -909,9 +921,9 @@ bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer)
return result;
}
void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_802154_trx_receive_notifications_t notifications_mask,
const nrf_802154_tx_power_split_t * p_ack_tx_power)
void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_802154_trx_receive_notifications_t notifications_mask,
const nrf_802154_fal_tx_power_split_t * p_ack_tx_power)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -930,7 +942,7 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
m_flags.rssi_settled = false;
nrf_radio_txpower_set(NRF_RADIO, p_ack_tx_power->radio_tx_power);
txpower_set(p_ack_tx_power->radio_tx_power);
if (mp_receive_buffer != NULL)
{
@ -1017,7 +1029,7 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
}
// Set FEM PA gain for ACK transmission
mpsl_fem_pa_gain_set(p_ack_tx_power->fem_gain);
mpsl_fem_pa_gain_set(&p_ack_tx_power->fem);
m_timer_value_on_radio_end_event = delta_time;
@ -1145,7 +1157,7 @@ bool nrf_802154_trx_rssi_sample_is_available(void)
void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer,
bool cca,
const nrf_802154_tx_power_split_t * p_tx_power,
const nrf_802154_fal_tx_power_split_t * p_tx_power,
nrf_802154_trx_transmit_notifications_t notifications_mask)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -1158,7 +1170,7 @@ void nrf_802154_trx_transmit_frame(const void * p_tra
m_trx_state = TRX_STATE_TXFRAME;
m_transmit_with_cca = cca;
nrf_radio_txpower_set(NRF_RADIO, p_tx_power->radio_tx_power);
txpower_set(p_tx_power->radio_tx_power);
nrf_radio_packetptr_set(NRF_RADIO, p_transmit_buffer);
@ -1203,7 +1215,7 @@ void nrf_802154_trx_transmit_frame(const void * p_tra
nrf_radio_int_enable(NRF_RADIO, ints_to_enable);
fem_for_tx_set(cca, p_tx_power->fem_gain);
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);
@ -1775,7 +1787,7 @@ static void standalone_cca_abort(void)
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
void nrf_802154_trx_continuous_carrier(const nrf_802154_tx_power_split_t * p_tx_power)
void nrf_802154_trx_continuous_carrier(const nrf_802154_fal_tx_power_split_t * p_tx_power)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -1784,10 +1796,10 @@ void nrf_802154_trx_continuous_carrier(const nrf_802154_tx_power_split_t * p_tx_
m_trx_state = TRX_STATE_CONTINUOUS_CARRIER;
// Set Tx Power
nrf_radio_txpower_set(NRF_RADIO, p_tx_power->radio_tx_power);
txpower_set(p_tx_power->radio_tx_power);
// Set FEM
fem_for_pa_set(p_tx_power->fem_gain);
fem_for_pa_set(&p_tx_power->fem);
// Select antenna
nrf_802154_trx_antenna_update();
@ -1830,8 +1842,8 @@ static void continuous_carrier_abort(void)
nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH);
}
void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer,
const nrf_802154_tx_power_split_t * p_tx_power)
void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer,
const nrf_802154_fal_tx_power_split_t * p_tx_power)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -1841,7 +1853,7 @@ void nrf_802154_trx_modulated_carrier(const void * p_tran
m_trx_state = TRX_STATE_MODULATED_CARRIER;
// Set Tx Power
nrf_radio_txpower_set(NRF_RADIO, p_tx_power->radio_tx_power);
txpower_set(p_tx_power->radio_tx_power);
// Set Tx buffer
nrf_radio_packetptr_set(NRF_RADIO, p_transmit_buffer);
@ -1850,7 +1862,7 @@ void nrf_802154_trx_modulated_carrier(const void * p_tran
nrf_radio_shorts_set(NRF_RADIO, SHORTS_MOD_CARRIER);
// Set FEM
fem_for_pa_set(p_tx_power->fem_gain);
fem_for_pa_set(&p_tx_power->fem);
// Select antenna
nrf_802154_trx_antenna_update();

View File

@ -47,7 +47,7 @@
#include "nrf_802154_config.h"
#include "nrf_802154_sl_types.h"
#include "nrf_802154_types.h"
#include "nrf_802154_types_internal.h"
#ifdef __cplusplus
extern "C" {
@ -211,9 +211,9 @@ void nrf_802154_trx_cca_configuration_update(void);
* 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_receive_notifications_t notifications_mask,
const nrf_802154_tx_power_split_t * p_ack_tx_power);
void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_802154_trx_receive_notifications_t notifications_mask,
const nrf_802154_fal_tx_power_split_t * p_ack_tx_power);
/**@brief Puts the trx module into receive ACK mode.
*
@ -348,7 +348,7 @@ bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer);
*/
void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer,
bool cca,
const nrf_802154_tx_power_split_t * p_tx_power,
const nrf_802154_fal_tx_power_split_t * p_tx_power,
nrf_802154_trx_transmit_notifications_t notifications_mask);
/**@brief Puts the trx module into transmit ACK mode.
@ -396,7 +396,7 @@ void nrf_802154_trx_standalone_cca(void);
* Generation of a continuous carrier generates no handlers. It may be terminated by a call to
* @ref nrf_802154_trx_abort or @ref nrf_802154_trx_disable.
*/
void nrf_802154_trx_continuous_carrier(const nrf_802154_tx_power_split_t * p_tx_power);
void nrf_802154_trx_continuous_carrier(const nrf_802154_fal_tx_power_split_t * p_tx_power);
/**@brief Restarts generating continuous carrier
*
@ -413,8 +413,8 @@ void nrf_802154_trx_continuous_carrier_restart(void);
* @param[in] p_transmit_buffer Pointer to a buffer used for modulating the carrier wave.
* @param[in] p_tx_power Transmit power in dBm.
*/
void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer,
const nrf_802154_tx_power_split_t * p_tx_power);
void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer,
const nrf_802154_fal_tx_power_split_t * p_tx_power);
/** @brief Restarts generating modulated carrier.*/
void nrf_802154_trx_modulated_carrier_restart(void);

View File

@ -37,61 +37,30 @@
#include "nrf_802154_utils.h"
#include "nrf_802154_fal.h"
/**
* Constrains the TX power by the maximum allowed TX power allowed for a specific channel, splits it into
* components to be applied on each stage of the transmit path and for the TX power applied to the RADIO peripheral
* converts the integer value to a RADIO TX power allowed value.
*
* @param[in] channel The channel based on which the power should be constrained
* @param[in] tx_power Unconstrained TX power integer value.
* @param[out] split_power Pointer to the structure holding TX power split into constrained and converted components.
*
* @retval true Calculation performed successfully.
* @retval false Given @p power cannot be achieved. If requested value is too high
* the @p p_tx_power_split will be set to a value representing maximum
* achievable power. If the requested value is too low, the
* @p p_tx_power_split will be set to a value representing minimum
* achievable power.
*/
static bool constrain_split_and_convert_tx_power(
uint8_t channel,
int8_t tx_power,
nrf_802154_tx_power_split_t * const split_power)
{
int32_t ret = 0;
nrf_802154_fal_tx_power_split_t fal_split_power = {0};
ret = nrf_802154_fal_tx_power_split(channel, tx_power, &fal_split_power);
split_power->fem_gain = fal_split_power.fem_gain;
split_power->radio_tx_power = fal_split_power.radio_tx_power;
return (0 == ret);
}
bool nrf_802154_tx_power_convert_metadata_to_tx_power_split(
uint8_t channel,
nrf_802154_tx_power_metadata_t tx_power,
nrf_802154_tx_power_split_t * const p_tx_power_split)
int8_t nrf_802154_tx_power_convert_metadata_to_tx_power_split(
uint8_t channel,
nrf_802154_tx_power_metadata_t tx_power,
nrf_802154_fal_tx_power_split_t * const p_tx_power_split)
{
int8_t power_unconstrained =
tx_power.use_metadata_value ? tx_power.power : nrf_802154_pib_tx_power_get();
return constrain_split_and_convert_tx_power(channel, power_unconstrained, p_tx_power_split);
return nrf_802154_fal_tx_power_split(channel, power_unconstrained, p_tx_power_split);
}
bool nrf_802154_tx_power_split_pib_power_get(nrf_802154_tx_power_split_t * const p_split_power)
int8_t nrf_802154_tx_power_split_pib_power_get(
nrf_802154_fal_tx_power_split_t * const p_split_power)
{
return constrain_split_and_convert_tx_power(nrf_802154_pib_channel_get(),
nrf_802154_pib_tx_power_get(),
p_split_power);
return nrf_802154_fal_tx_power_split(nrf_802154_pib_channel_get(),
nrf_802154_pib_tx_power_get(),
p_split_power);
}
bool nrf_802154_tx_power_split_pib_power_for_channel_get(
uint8_t channel,
nrf_802154_tx_power_split_t * const p_split_power)
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)
{
return constrain_split_and_convert_tx_power(channel,
nrf_802154_pib_tx_power_get(),
p_split_power);
return nrf_802154_fal_tx_power_split(channel,
nrf_802154_pib_tx_power_get(),
p_split_power);
}

View File

@ -38,6 +38,7 @@
#include <stdint.h>
#include "nrf_802154.h"
#include "nrf_802154_types_internal.h"
/**@brief Convert tx_power value passed through metadata to raw components in dBms to be applied
* on each stage of the transmit path.
@ -48,18 +49,13 @@
* @param[in] tx_power The value passed to the transmit metadata.
* @param[out] p_tx_power_split Pointer to the structure holding TX power split into raw components in dBm.
*
* @retval true Calculation performed successfully.
* @retval false Given @p tx_power cannot be achieved. If requested value is too high
* the @p p_tx_power_split will be set to a value representing maximum
* achievable power. If the requested value is too low, the
* @p p_tx_power_split will be set to a value representing minimum
* achievable power.
* @retval The real achieved total transmission power in dBm.
*
*/
bool nrf_802154_tx_power_convert_metadata_to_tx_power_split(
uint8_t channel,
nrf_802154_tx_power_metadata_t tx_power,
nrf_802154_tx_power_split_t * const p_tx_power_split);
int8_t nrf_802154_tx_power_convert_metadata_to_tx_power_split(
uint8_t channel,
nrf_802154_tx_power_metadata_t tx_power,
nrf_802154_fal_tx_power_split_t * const p_tx_power_split);
/**@brief Get the transmit power stored in PIB after applying the power constraints for the current channel and splitting
* into components to be applied on each stage of the transmit path.
@ -68,16 +64,11 @@ bool nrf_802154_tx_power_convert_metadata_to_tx_power_split(
*
* @param[out] p_split_power Pointer to the structure holding TX power split into components in dBm.
*
* @retval true Calculation performed successfully.
* @retval false cannot be achieved. If requested value is too high
* Current power set in PIB the @p p_split_power will be set to a value representing maximum
* achievable power. If the requested value is too low, the
* @p p_split_power will be set to a value representing minimum
* achievable power.
* @retval The real achieved total transmission power in dBm.
*
*/
bool nrf_802154_tx_power_split_pib_power_get(nrf_802154_tx_power_split_t * const p_split_power);
int8_t nrf_802154_tx_power_split_pib_power_get(
nrf_802154_fal_tx_power_split_t * const p_split_power);
/**@brief Get the transmit power stored in PIB after applying the power constraints for the given channel and splitting
* into components to be applied on each stage of the transmit path.
@ -85,17 +76,12 @@ bool nrf_802154_tx_power_split_pib_power_get(nrf_802154_tx_power_split_t * const
* @param[in] channel The channel based on which the power should be constrained
* @param[out] p_split_power Pointer to the structure holding TX power split into components in dBm.
*
* @retval true Calculation performed successfully.
* @retval false Current power set in PIB cannot be achieved. If requested value is too high
* the @p p_split_power will be set to a value representing maximum
* achievable power. If the requested value is too low, the
* @p p_split_power will be set to a value representing minimum
* achievable power.
* @retval The real achieved total transmission power in dBm.
*
*/
bool nrf_802154_tx_power_split_pib_power_for_channel_get(
uint8_t channel,
nrf_802154_tx_power_split_t * const p_split_power);
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);
/**
*@}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2017 - 2022, 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_TYPES_INTERNAL_H__
#define NRF_802154_TYPES_INTERNAL_H__
#include "nrf_802154_types.h"
#include "nrf_802154_fal.h"
typedef struct
{
nrf_802154_transmitted_frame_props_t frame_props; // !< Properties of the frame to be transmitted.
nrf_802154_fal_tx_power_split_t tx_power; // !< Power to be used when transmitting the frame, split into components to be applied on each stage on transmit path.
bool cca; // !< If the driver is to perform CCA procedure before transmission.
bool immediate; // !< If true, the driver schedules transmission immediately or never. If false, the transmission may be postponed
// until its preconditions are met.
} nrf_802154_transmit_params_t;
#endif // NRF_802154_TYPES_INTERNAL_H__

View File

@ -873,6 +873,22 @@ nrf_802154_security_error_t nrf_802154_security_key_remove(nrf_802154_key_id_t *
*/
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 should be called after calling @ref nrf_802154_csl_writer_period_set and every time when the CSL windows get desynchronized.
*
* 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).
*
* @param[in] period Anchor time value.
*/
void nrf_802154_csl_writer_anchor_time_set(uint64_t anchor_time);
/**
* @}
* @defgroup nrf_802154_stats Statistics and measurements

View File

@ -441,6 +441,12 @@ typedef enum
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_IFS_MIN_LIFS_PERIOD_GET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 62,
/**
* Vendor property for nrf_802154_csl_writer_anchor_time_set serialization.
*/
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET =
SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 63,
} spinel_prop_vendor_key_t;
/**
@ -1299,17 +1305,22 @@ typedef enum
/**
* @brief Spinel data type description for return type for security commands.
*/
#define SPINEL_DATATYPE_NRF_802154_SECURITY_ERROR_RET SPINEL_DATATYPE_UINT8_S
#define SPINEL_DATATYPE_NRF_802154_SECURITY_ERROR_RET SPINEL_DATATYPE_UINT8_S
/**
* @brief Spinel data type description for nrf_802154_csl_writer_period_set.
*/
#define SPINEL_DATATYPE_NRF_802154_CSL_WRITER_PERIOD_SET SPINEL_DATATYPE_UINT16_S
#define SPINEL_DATATYPE_NRF_802154_CSL_WRITER_PERIOD_SET SPINEL_DATATYPE_UINT16_S
/**
* @brief Spinel data type description for nrf_802154_csl_writer_anchor_time_set.
*/
#define SPINEL_DATATYPE_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET SPINEL_DATATYPE_UINT64_S
/**
* @brief Spinel data type description for nrf_802154_stat_timestamps_get
*/
#define SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_GET SPINEL_DATATYPE_NULL_S
#define SPINEL_DATATYPE_NRF_802154_STAT_TIMESTAMPS_GET SPINEL_DATATYPE_NULL_S
/**
* @brief Spinel data type description for nrf_802154_stat_timestamps_get_ret.

View File

@ -1902,6 +1902,32 @@ bail:
return;
}
void nrf_802154_csl_writer_anchor_time_set(uint64_t anchor_time)
{
nrf_802154_ser_err_t res;
SERIALIZATION_ERROR_INIT(error);
NRF_802154_SPINEL_LOG_BANNER_CALLING();
nrf_802154_spinel_response_notifier_lock_before_request(SPINEL_PROP_LAST_STATUS);
res = nrf_802154_spinel_send_cmd_prop_value_set(
SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET,
SPINEL_DATATYPE_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET,
anchor_time);
SERIALIZATION_ERROR_CHECK(res, error, bail);
res = status_ok_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT);
SERIALIZATION_ERROR_CHECK(res, error, bail);
bail:
SERIALIZATION_ERROR_RAISE_IF_FAILED(error);
return;
}
static nrf_802154_ser_err_t stat_timestamps_get_ret_await(uint32_t timeout,
nrf_802154_stat_timestamps_t * p_stat_timestamps)
{

View File

@ -1751,6 +1751,34 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_csl_writer_period_set(
return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK);
}
/**
* @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET.
*
* @param[in] p_property_data Pointer to a buffer that contains data to be decoded.
* @param[in] property_data_len Size of the @ref p_property_data buffer.
*
*/
static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_csl_writer_anchor_time_set(
const void * p_property_data,
size_t property_data_len)
{
spinel_ssize_t siz;
uint64_t csl_anchor_time;
siz = spinel_datatype_unpack(p_property_data,
property_data_len,
SPINEL_DATATYPE_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET,
&csl_anchor_time);
if (siz < 0)
{
return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE;
}
nrf_802154_csl_writer_anchor_time_set(csl_anchor_time);
return nrf_802154_spinel_send_prop_last_status_is(SPINEL_STATUS_OK);
}
#endif // NRF_802154_DELAYED_TRX_ENABLED && NRF_802154_IE_WRITER_ENABLED
nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_cmd_data,
@ -1984,6 +2012,10 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_PERIOD_SET:
return spinel_decode_prop_nrf_802154_csl_writer_period_set(p_property_data,
property_data_len);
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CSL_WRITER_ANCHOR_TIME_SET:
return spinel_decode_prop_nrf_802154_csl_writer_anchor_time_set(p_property_data,
property_data_len);
#endif // NRF_802154_DELAYED_TRX_ENABLED && NRF_802154_IE_WRITER_ENABLED
case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_STAT_TIMESTAMPS_GET:

View File

@ -41,6 +41,7 @@
#define NRF_802154_FAL_H_
#include <stdint.h>
#include "protocol/mpsl_fem_protocol_api.h"
#ifdef __cplusplus
extern "C" {
@ -51,8 +52,8 @@ extern "C" {
*/
typedef struct
{
int8_t radio_tx_power; // !< TX power in dBm to be applied to the RADIO peripheral.
int8_t fem_gain; // !< Gain of the Front-End Module in dB.
int8_t radio_tx_power; // !< TX power in dBm to be applied to the RADIO peripheral.
mpsl_fem_gain_t fem; // !< Data needed to set the FEM gain
} nrf_802154_fal_tx_power_split_t;
/** @brief Splits transmit power value into components to be applied on each stage on the transmit path.
@ -63,11 +64,11 @@ typedef struct
* @param[in] power TX power in dBm requested for transmission on air.
* @param[out] p_tx_power_split Components of tx_power to be applied for stages on transmit path.
*
* @returns Always 0.
* @returns The real achieved total transmission power in dBm.
*/
int32_t nrf_802154_fal_tx_power_split(const uint8_t channel,
const int8_t power,
nrf_802154_fal_tx_power_split_t * const p_tx_power_split);
int8_t nrf_802154_fal_tx_power_split(const uint8_t channel,
const int8_t power,
nrf_802154_fal_tx_power_split_t * const p_tx_power_split);
#ifdef __cplusplus
}

View File

@ -106,14 +106,24 @@ typedef struct
/** TX power, dBm. */
typedef int8_t mpsl_tx_power_t;
/**
* @brief Represents data needed to set the FEM gain.
*/
typedef struct
{
int8_t gain_db; // !< Gain in dB.
uint8_t private_setting; // !< Setting of the Front-End Module. The interpretation of this field is specific
// for a given Front-End Module implementation.
} mpsl_fem_gain_t;
/** @brief Represents components of tx_power to be applied for stages on transmit path. */
typedef struct
{
/** TX power to be applied to the RADIO peripheral. */
mpsl_tx_power_t radio_tx_power;
/** Gain of the Front-End Module in dB. */
int8_t fem_gain;
/** Data needed to set the FEM gain. */
mpsl_fem_gain_t fem;
} mpsl_tx_power_split_t;
/** @brief Disable Front End Module.
@ -331,7 +341,7 @@ void mpsl_fem_tx_power_split(const mpsl_tx_power_t power,
* @retval 0 Gain has been set successfully.
* @retval -NRF_EINVAL Gain could not be set. Provided @p gain is invalid.
*/
int32_t mpsl_fem_pa_gain_set(int8_t gain);
int32_t mpsl_fem_pa_gain_set(const mpsl_fem_gain_t * p_gain);
/** @brief Checks if the PA signaling is configured and enabled, and gets
* the configured gain in dB.

View File

@ -176,13 +176,14 @@ void mpsl_fem_cleanup(void)
void mpsl_fem_tx_power_split(const mpsl_tx_power_t power,
mpsl_tx_power_split_t * const p_tx_power_split)
{
p_tx_power_split->radio_tx_power = to_radio_tx_power_convert(power);
p_tx_power_split->fem_gain = 0;
p_tx_power_split->radio_tx_power = to_radio_tx_power_convert(power);
p_tx_power_split->fem.gain_db = 0;
p_tx_power_split->fem.private_setting = 0;
}
int32_t mpsl_fem_pa_gain_set(int8_t gain)
int32_t mpsl_fem_pa_gain_set(const mpsl_fem_gain_t * p_gain)
{
(void)gain;
(void)p_gain;
return 0;
}
@ -209,16 +210,17 @@ bool mpsl_fem_device_config_254_apply_get(void)
return false;
}
int32_t nrf_802154_fal_tx_power_split(const uint8_t channel,
const int8_t power,
nrf_802154_fal_tx_power_split_t * const p_tx_power_split)
int8_t nrf_802154_fal_tx_power_split(const uint8_t channel,
const int8_t power,
nrf_802154_fal_tx_power_split_t * const p_tx_power_split)
{
(void)channel;
p_tx_power_split->radio_tx_power = to_radio_tx_power_convert(power);
p_tx_power_split->fem_gain = 0;
p_tx_power_split->radio_tx_power = to_radio_tx_power_convert(power);
p_tx_power_split->fem.gain_db = 0;
p_tx_power_split->fem.private_setting = 0;
return 0;
return p_tx_power_split->radio_tx_power;
}
#ifdef __cplusplus