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

Signed-off-by: Artur Hadasz <artur.hadasz@nordicsemi.no>
This commit is contained in:
Artur Hadasz 2022-06-02 15:38:51 +02:00 committed by Robert Lubos
parent a85bb3676d
commit d9e50d7287
26 changed files with 513 additions and 184 deletions

View File

@ -101,6 +101,8 @@ if (SL_OPENSOURCE)
NRF_802154_DELAYED_TRX_ENABLED=0
# Disable IFS
NRF_802154_IFS_ENABLED=0
# Disable CSMA-CA
NRF_802154_CSMA_CA_ENABLED=0
)
endif()

View File

@ -404,6 +404,17 @@ uint8_t nrf_802154_ccaedthres_from_dbm_calculate(int8_t dbm);
*/
uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length);
/**
* @brief Calculates the timestamp of the MAC Header in a received frame.
*
* @param[in] end_timestamp Timestamp of the end of the last symbol in the frame,
* in microseconds.
* @param[in] psdu_length Number of bytes in the frame PSDU.
*
* @return Timestamp of the MHR of a given frame, in microseconds.
*/
uint64_t nrf_802154_mhr_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length);
/**
* @}
* @defgroup nrf_802154_transitions Functions to request FSM transitions and check current state
@ -971,7 +982,9 @@ extern void nrf_802154_transmit_failed(uint8_t
* @brief Notifies that the energy detection procedure finished.
*
* @note This function passes the EnergyLevel defined in the 802.15.4-2006 specification:
* 0x00 - 0xff, proportionally to the detected energy level (dBm above receiver sensitivity).
* 0x00 - 0xff, where 0x00 represents -75dBm (10dBm above the worst allowed sensitivity level,
* which is -85dBm) and 0xff is the highest possible energy detection level, for which
* the measurements are guaranteed map linearly to the real energy level in dBm.
* To calculate the result in dBm, use @ref nrf_802154_dbm_from_energy_level_calculate.
*
* @param[in] result Maximum energy detected during the energy detection procedure.

View File

@ -180,6 +180,8 @@
#define PHY_SYMBOLS_PER_OCTET 2 ///< Number of symbols in a single byte (octet).
#define PHY_SHR_SYMBOLS 10 ///< Number of symbols in the Synchronization Header (SHR).
#define PHY_MIN_RECEIVER_SENSITIVITY -85 ///< Lowest receiver sensitivity level in dBm according to 802.15.4-2020 specification, chapter 12.3.4
#define ED_RESULT_MAX 0xff ///< Maximal ED result.
#define BROADCAST_ADDRESS ((uint8_t[SHORT_ADDRESS_SIZE]) {0xff, 0xff}) ///< Broadcast short address.

View File

@ -481,13 +481,22 @@ 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.
int8_t tx_power; // !< Power to be used when transmitting the frame.
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.

View File

@ -1,50 +0,0 @@
/*
* 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.
*
*/
/**
* @file
* This file contains implementation of the nRF 802.15.4 FEM abstraction layer.
*
*/
#include <stdint.h>
#include "nrf_802154_fal.h"
int8_t nrf_802154_fal_tx_power_get(const uint8_t channel, const int8_t power)
{
(void)channel;
return power;
}

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 int8_t m_tx_power; ///< Power in dBm to be used when transmitting the frame.
static nrf_802154_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.
/**
@ -363,9 +363,9 @@ bool nrf_802154_csma_ca_start(uint8_t * p_d
m_data_props = p_metadata->frame_props;
m_nb = 0;
m_be = nrf_802154_pib_csmaca_min_be_get();
m_tx_power =
nrf_802154_tx_power_convert_metadata_to_raw_value(nrf_802154_pib_channel_get(),
p_metadata->tx_power);
(void)nrf_802154_tx_power_convert_metadata_to_tx_power_split(nrf_802154_pib_channel_get(),
p_metadata->tx_power,
&m_tx_power);
random_backoff_start();

View File

@ -772,9 +772,9 @@ bool nrf_802154_delayed_trx_transmit(uint8_t * p
p_dly_tx_data->tx.p_data = p_data;
p_dly_tx_data->tx.params.frame_props = p_metadata->frame_props;
p_dly_tx_data->tx.params.tx_power = nrf_802154_tx_power_convert_metadata_to_raw_value(
p_metadata->channel,
p_metadata->tx_power);
(void)nrf_802154_tx_power_convert_metadata_to_tx_power_split(p_metadata->channel,
p_metadata->tx_power,
&p_dly_tx_data->tx.params.tx_power);
p_dly_tx_data->tx.params.cca = p_metadata->cca;
p_dly_tx_data->tx.params.immediate = true;
p_dly_tx_data->tx.channel = p_metadata->channel;
@ -939,6 +939,8 @@ bool nrf_802154_delayed_trx_nearest_drx_time_to_midpoint_get(uint32_t * p_drx_ti
result = nrf_802154_rsch_delayed_timeslot_time_to_start_get(m_dly_rx_data[i].id,
&drx_time_to_start);
drx_time_to_start += RX_SETUP_TIME + RX_RAMP_UP_TIME;
if (result)
{
min_time_to_start = drx_time_to_start < min_time_to_start ?

View File

@ -243,7 +243,7 @@ static void link_metrics_ie_write_commit(bool * p_written)
if (mp_lm_margin_addr != NULL)
{
*mp_lm_margin_addr = margin_scale((int16_t)rssi - ED_MIN_DBM);
*mp_lm_margin_addr = margin_scale((int16_t)rssi - ED_RSSIOFFS);
*p_written = true;
}
}

View File

@ -59,6 +59,7 @@
#include "nrf_802154_request.h"
#include "nrf_802154_rx_buffer.h"
#include "nrf_802154_tx_power.h"
#include "nrf_802154_rssi.h"
#include "nrf_802154_stats.h"
#include "hal/nrf_radio.h"
#include "platform/nrf_802154_clock.h"
@ -156,7 +157,11 @@ void nrf_802154_tx_power_set(int8_t power)
int8_t nrf_802154_tx_power_get(void)
{
return nrf_802154_tx_power_constrained_pib_power_get();
nrf_802154_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;
}
bool nrf_802154_coex_rx_request_mode_set(nrf_802154_coex_rx_request_mode_t mode)
@ -201,12 +206,12 @@ void nrf_802154_short_address_set(const uint8_t * p_short_address)
int8_t nrf_802154_dbm_from_energy_level_calculate(uint8_t energy_level)
{
return ED_MIN_DBM + (energy_level / ED_RESULT_FACTOR);
return nrf_802154_addons_dbm_from_energy_level_calculate(energy_level);
}
uint8_t nrf_802154_ccaedthres_from_dbm_calculate(int8_t dbm)
{
return dbm - ED_MIN_DBM;
return dbm - ED_RSSIOFFS;
}
uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length)
@ -218,6 +223,11 @@ uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t p
return end_timestamp - (frame_symbols * PHY_US_PER_SYMBOL);
}
uint64_t nrf_802154_mhr_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length)
{
return end_timestamp - (psdu_length * PHY_SYMBOLS_PER_OCTET * PHY_US_PER_SYMBOL);
}
void nrf_802154_init(void)
{
static const nrf_802154_sl_crit_sect_interface_t crit_sect_int =
@ -490,13 +500,15 @@ bool nrf_802154_transmit_raw(uint8_t * p_data,
nrf_802154_transmit_params_t params =
{
.frame_props = p_metadata->frame_props,
.tx_power = nrf_802154_tx_power_convert_metadata_to_raw_value(
nrf_802154_pib_channel_get(),
p_metadata->tx_power),
.cca = p_metadata->cca,
.immediate = false
.tx_power = {0},
.cca = p_metadata->cca,
.immediate = false
};
(void)nrf_802154_tx_power_convert_metadata_to_tx_power_split(nrf_802154_pib_channel_get(),
p_metadata->tx_power,
&params.tx_power);
result = are_frame_properties_valid(&params.frame_props);
if (result)
{
@ -536,13 +548,15 @@ bool nrf_802154_transmit(const uint8_t * p_data,
nrf_802154_transmit_params_t params =
{
.frame_props = p_metadata->frame_props,
.tx_power = nrf_802154_tx_power_convert_metadata_to_raw_value(
nrf_802154_pib_channel_get(),
p_metadata->tx_power),
.cca = p_metadata->cca,
.immediate = false
.tx_power = {0},
.cca = p_metadata->cca,
.immediate = false
};
(void)nrf_802154_tx_power_convert_metadata_to_tx_power_split(nrf_802154_pib_channel_get(),
p_metadata->tx_power,
&params.tx_power);
result = are_frame_properties_valid(&params.frame_props);
if (result)
{

View File

@ -115,13 +115,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 int8_t m_last_rssi; ///< RSSI of the last received non-ACK frame, corrected for the temperature.
static int8_t m_tx_power; ///< Power in dBm to be used to transmit the current frame.
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 nrf_802154_frame_parser_data_t m_current_rx_frame_data; ///< RX frame parser data.
@ -499,26 +499,6 @@ static bool ack_is_requested(const uint8_t * p_frame)
* @section Energy detection management
**************************************************************************************************/
/** Get ED result value.
*
* @param[in] ed_sample Energy Detection sample gathered from TRX module
* @returns ED result based on data collected during Energy Detection procedure.
*/
static uint8_t ed_result_get(uint8_t ed_sample)
{
uint32_t result;
result = nrf_802154_rssi_ed_corrected_get(ed_sample);
result *= ED_RESULT_FACTOR;
if (result > ED_RESULT_MAX)
{
result = ED_RESULT_MAX;
}
return (uint8_t)result;
}
/** Setup next iteration of energy detection procedure.
*
* Energy detection procedure is performed in iterations to make sure it is performed for requested
@ -1045,9 +1025,13 @@ static void rx_init(void)
nrf_802154_trx_receive_buffer_set(rx_buffer_get());
nrf_802154_tx_power_split_t split_power = {0};
(void)nrf_802154_tx_power_split_pib_power_get(&split_power);
nrf_802154_trx_receive_frame(BCC_INIT / 8U,
m_trx_receive_frame_notifications_mask,
nrf_802154_tx_power_constrained_pib_power_get());
&split_power);
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
m_listening_start_hp_timestamp = nrf_802154_hp_timer_current_time_get();
@ -1109,7 +1093,7 @@ static bool tx_init(const uint8_t * p_data, bool cca)
m_flags.tx_with_cca = cca;
nrf_802154_trx_transmit_frame(nrf_802154_tx_work_buffer_get(p_data),
cca,
m_tx_power,
&m_tx_power,
m_trx_transmit_frame_notifications_mask);
return true;
@ -1173,8 +1157,11 @@ static void continuous_carrier_init(void)
{
return;
}
nrf_802154_tx_power_split_t split_power = {0};
nrf_802154_trx_continuous_carrier(nrf_802154_tx_power_constrained_pib_power_get());
(void)nrf_802154_tx_power_split_pib_power_get(&split_power);
nrf_802154_trx_continuous_carrier(&split_power);
}
/** Initialize Modulated Carrier operation. */
@ -1190,7 +1177,11 @@ static void modulated_carrier_init(const uint8_t * p_data)
return;
}
nrf_802154_trx_modulated_carrier(p_data, nrf_802154_tx_power_constrained_pib_power_get());
nrf_802154_tx_power_split_t split_power = {0};
(void)nrf_802154_tx_power_split_pib_power_get(&split_power);
nrf_802154_trx_modulated_carrier(p_data, &split_power);
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
@ -1917,9 +1908,14 @@ void nrf_802154_trx_receive_frame_crcerror(void)
// We don't change receive buffer, receive will go to the same that was already used
#if !NRF_802154_DISABLE_BCC_MATCHING
request_preconditions_for_state(m_state);
nrf_802154_tx_power_split_t split_power = {0};
(void)nrf_802154_tx_power_split_pib_power_get(&split_power);
nrf_802154_trx_receive_frame(BCC_INIT / 8U,
m_trx_receive_frame_notifications_mask,
nrf_802154_tx_power_constrained_pib_power_get());
&split_power);
#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED
m_listening_start_hp_timestamp = nrf_802154_hp_timer_current_time_get();
@ -2550,7 +2546,7 @@ void nrf_802154_trx_energy_detection_finished(uint8_t ed_sample)
state_set(RADIO_STATE_RX);
rx_init();
energy_detected_notify(ed_result_get(m_ed_result));
energy_detected_notify(nrf_802154_rssi_ed_sample_convert(m_ed_result));
}

View File

@ -32,14 +32,43 @@
*
*/
#include "nrf.h"
#ifndef NRF_802154_NRFX_ADDONS_H__
#define NRF_802154_NRFX_ADDONS_H__
#if defined (NRF52840_XXAA) || defined(NRF52811_XXAA) || defined(NRF5340_XXAA_NETWORK)
#define ED_MIN_DBM (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#elif defined (NRF52833_XXAA) || defined(NRF52820_XXAA)
#define ED_MIN_DBM (-93) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RESULT_FACTOR 5 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#include "nrf.h"
#include "nrf_802154_const.h"
/* The usage of ED_RSSISCALE is described inprecisely in the nRF product specifications. The meaning of
this constant is the following: If we calculate ed_scaled = EDSAMPLE * ED_RSSISCALE, then
it is guaranteed that in the range 0-255 ed_scaled maps linearly to the ED power in dBm. This means,
that the maximum value in EDSAMPLE which can be reported in compliance with the 802.15.4 specification is
255/ED_RSSISCALE. */
#if defined (NRF52840_XXAA) || defined(NRF52811_XXAA)
#define ED_RSSIOFFS (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#elif defined (NRF52833_XXAA) || defined(NRF52820_XXAA) || defined(NRF5340_XXAA)
#define ED_RSSIOFFS (-93) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 5 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#else
#error "Selected chip is not supported."
#endif
#define EDSAMPLE_MIN_REPORTED_VALUE (PHY_MIN_RECEIVER_SENSITIVITY - ED_RSSIOFFS + 10) ///< Minimal reported EDSAMPLE value (reported as 0)
#define EDSAMPLE_MAX_REPORTED_VALUE (ED_RESULT_MAX / ED_RSSISCALE) ///< Maximal reported EDSAMPLE value (reported as 255)
/**
* @brief Converts the energy level received during the energy detection procedure to a dBm value.
*
* @param[in] energy_level Energy level value compliant with the 802.15.4 specification (0-255)
*
* @return Result of the energy detection procedure in dBm.
*/
static inline int8_t nrf_802154_addons_dbm_from_energy_level_calculate(uint8_t energy_level)
{
return ((int16_t)(EDSAMPLE_MAX_REPORTED_VALUE - EDSAMPLE_MIN_REPORTED_VALUE) *
((int16_t)energy_level)) /
ED_RESULT_MAX + EDSAMPLE_MIN_REPORTED_VALUE + ED_RSSIOFFS;
}
#endif // NRF_802154_NRFX_ADDONS_H__

View File

@ -38,6 +38,8 @@
*
*/
#include "nrf_802154_rssi.h"
#include "nrf_802154_nrfx_addons.h"
#include "nrf_802154_const.h"
#include "nrf.h"
#include <stdint.h>
@ -86,6 +88,8 @@ int8_t nrf_802154_rssi_sample_temp_corr_value_get(uint8_t rssi_sample)
}
else
{
// nRF52840 cannot work for a temperature above 85 degrees Celsius, so this part won't affect its operation,
// even if it isn't present in its errata.
result = -4;
}
#else
@ -107,10 +111,10 @@ int8_t nrf_802154_rssi_sample_temp_corr_value_get(uint8_t rssi_sample)
*
* Coefficients were calculated as round(x * RSSI_COEFF_BASE) based on Errata 87.
*/
#define RSSI_COEFF_A0 30198989L /* Initial value: 7.2 */
#define RSSI_COEFF_A1 6543114L /* Initial value: 1.56 */
#define RSSI_COEFF_A2 41524L /* Initial value: 9.9e-3 */
#define RSSI_COEFF_A3 205L /* Initial value: 4.9e-5 */
#define RSSI_COEFF_A0 30198989L /* Initial value: 7.2 */
#define RSSI_COEFF_A1 6543114L /* Initial value: 1.56 */
#define RSSI_COEFF_A2 41524L /* Initial value: 9.9e-3 */
#define RSSI_COEFF_A3 205L /* Initial value: 4.9e-5 */
#define RSSI_COEFF_TEMP 209715L /* Initial value: 0.05 */
/** @brief Value used to increase precision of calculations. */
#define RSSI_COEFF_BASE (1UL << 22U)
@ -164,7 +168,7 @@ uint8_t nrf_802154_rssi_lqi_corrected_get(uint8_t lqi)
return lqi - nrf_802154_rssi_sample_temp_corr_value_get(lqi);
}
uint8_t nrf_802154_rssi_ed_corrected_get(uint8_t ed)
int16_t nrf_802154_rssi_ed_corrected_get(int16_t ed)
{
return ed - nrf_802154_rssi_sample_temp_corr_value_get(ed);
}
@ -173,3 +177,31 @@ uint8_t nrf_802154_rssi_cca_ed_threshold_corrected_get(uint8_t cca_ed)
{
return cca_ed - nrf_802154_rssi_sample_temp_corr_value_get(cca_ed);
}
uint8_t nrf_802154_rssi_ed_sample_convert(uint8_t ed_sample)
{
int16_t result;
result = nrf_802154_rssi_ed_corrected_get(ed_sample);
result = ED_RESULT_MAX * (result - EDSAMPLE_MIN_REPORTED_VALUE) /
(EDSAMPLE_MAX_REPORTED_VALUE - EDSAMPLE_MIN_REPORTED_VALUE);
if (result < 0)
{
result = 0;
}
if (result > ED_RESULT_MAX)
{
result = ED_RESULT_MAX;
}
return (uint8_t)result;
}
int8_t nrf_802154_rssi_dbm_from_energy_level_calculate(uint8_t energy_level)
{
return ((int16_t)(EDSAMPLE_MAX_REPORTED_VALUE - EDSAMPLE_MIN_REPORTED_VALUE) *
((int16_t)energy_level)) /
ED_RESULT_MAX + EDSAMPLE_MIN_REPORTED_VALUE + ED_RSSIOFFS;
}

View File

@ -80,7 +80,7 @@ uint8_t nrf_802154_rssi_lqi_corrected_get(uint8_t lqi);
*
* @returns EDSAMPLE value corrected by a temperature factor.
*/
uint8_t nrf_802154_rssi_ed_corrected_get(uint8_t ed);
int16_t nrf_802154_rssi_ed_corrected_get(int16_t ed);
/**
* @brief Adjusts the CCA ED threshold value using a temperature correction factor.
@ -91,6 +91,24 @@ uint8_t nrf_802154_rssi_ed_corrected_get(uint8_t ed);
*/
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
*
* @returns 802.15.4 compliant energy detection value.
*/
uint8_t nrf_802154_rssi_ed_sample_convert(uint8_t ed_sample);
/**
* @brief Converts the energy level received during the energy detection procedure to a dBm value.
*
* @param[in] energy_level Energy level passed by @ref nrf_802154_energy_detected.
*
* @return Result of the energy detection procedure in dBm.
*/
int8_t nrf_802154_rssi_dbm_from_energy_level_calculate(uint8_t energy_level);
/**
*@}
**/

View File

@ -41,7 +41,6 @@
#include "nrf_802154_config.h"
#include "nrf_802154_const.h"
#include "nrf_802154_types.h"
#include "nrf_802154_peripherals.h"
#include "nrf_802154_pib.h"
#include "nrf_802154_rssi.h"
@ -198,6 +197,7 @@ 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);
@ -321,8 +321,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(void)
static void fem_for_pa_set(int8_t gain)
{
(void)mpsl_fem_pa_gain_set(gain);
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,10 +348,12 @@ 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)
static void fem_for_tx_set(bool cca, int8_t gain)
{
bool success;
(void)mpsl_fem_pa_gain_set(gain);
if (cca)
{
bool pa_set = false;
@ -461,6 +464,7 @@ 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));
@ -535,6 +539,8 @@ 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) || \
defined(NRF52820_XXAA) || \
@ -647,6 +653,9 @@ 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,7 +918,7 @@ bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer)
void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_802154_trx_receive_notifications_t notifications_mask,
int8_t ack_tx_power)
const nrf_802154_tx_power_split_t * p_ack_tx_power)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -928,7 +937,7 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
m_flags.rssi_settled = false;
nrf_radio_txpower_set(NRF_RADIO, (nrf_radio_txpower_t)ack_tx_power);
nrf_radio_txpower_set(NRF_RADIO, p_ack_tx_power->radio_tx_power);
if (mp_receive_buffer != NULL)
{
@ -1014,6 +1023,9 @@ void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_timer_cc_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0, delta_time);
}
// Set FEM PA gain for ACK transmission
mpsl_fem_pa_gain_set(p_ack_tx_power->fem_gain);
m_timer_value_on_radio_end_event = delta_time;
// Select antenna
@ -1140,7 +1152,7 @@ bool nrf_802154_trx_rssi_sample_is_available(void)
void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer,
bool cca,
int8_t tx_power,
const nrf_802154_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);
@ -1153,7 +1165,8 @@ 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, (nrf_radio_txpower_t)tx_power);
nrf_radio_txpower_set(NRF_RADIO, p_tx_power->radio_tx_power);
nrf_radio_packetptr_set(NRF_RADIO, p_transmit_buffer);
// Set shorts
@ -1197,7 +1210,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);
fem_for_tx_set(cca, p_tx_power->fem_gain);
nrf_802154_trx_antenna_update();
nrf_802154_trx_ppi_for_ramp_up_set(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, false);
@ -1769,7 +1782,7 @@ static void standalone_cca_abort(void)
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
void nrf_802154_trx_continuous_carrier(int8_t tx_power)
void nrf_802154_trx_continuous_carrier(const nrf_802154_tx_power_split_t * p_tx_power)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -1778,10 +1791,10 @@ void nrf_802154_trx_continuous_carrier(int8_t tx_power)
m_trx_state = TRX_STATE_CONTINUOUS_CARRIER;
// Set Tx Power
nrf_radio_txpower_set(NRF_RADIO, (nrf_radio_txpower_t)tx_power);
nrf_radio_txpower_set(NRF_RADIO, p_tx_power->radio_tx_power);
// Set FEM
fem_for_pa_set();
fem_for_pa_set(p_tx_power->fem_gain);
// Select antenna
nrf_802154_trx_antenna_update();
@ -1824,7 +1837,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, int8_t tx_power)
void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer,
const nrf_802154_tx_power_split_t * p_tx_power)
{
nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
@ -1834,7 +1848,7 @@ void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer, int8_t tx_
m_trx_state = TRX_STATE_MODULATED_CARRIER;
// Set Tx Power
nrf_radio_txpower_set(NRF_RADIO, (nrf_radio_txpower_t)tx_power);
nrf_radio_txpower_set(NRF_RADIO, p_tx_power->radio_tx_power);
// Set Tx buffer
nrf_radio_packetptr_set(NRF_RADIO, p_transmit_buffer);
@ -1843,7 +1857,7 @@ void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer, int8_t tx_
nrf_radio_shorts_set(NRF_RADIO, SHORTS_MOD_CARRIER);
// Set FEM
fem_for_pa_set();
fem_for_pa_set(p_tx_power->fem_gain);
// Select antenna
nrf_802154_trx_antenna_update();

View File

@ -47,6 +47,7 @@
#include "nrf_802154_config.h"
#include "nrf_802154_sl_types.h"
#include "nrf_802154_types.h"
#ifdef __cplusplus
extern "C" {
@ -208,11 +209,11 @@ void nrf_802154_trx_cca_configuration_update(void);
* @param[in] notifications_mask Selects additional notifications generated during a frame reception.
* It is bitwise combination of @ref nrf_802154_trx_receive_notifications_t values.
* When NRF_802154_DISABLE_BCC_MATCHING != 0, flag @ref TRX_RECEIVE_NOTIFICATION_PRESTARTED is forbidden.
* @param[in] ack_tx_power Selects the power which should be used to transmitted an ACK if required.
* @param[in] p_ack_tx_power Selects the power which should be used to transmitted an ACK if required.
*/
void nrf_802154_trx_receive_frame(uint8_t bcc,
nrf_802154_trx_receive_notifications_t notifications_mask,
int8_t ack_tx_power);
const nrf_802154_tx_power_split_t * p_ack_tx_power);
/**@brief Puts the trx module into receive ACK mode.
*
@ -340,14 +341,14 @@ bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer);
* @param cca Selects if CCA procedure should be performed prior to
* real transmission. If false no cca will be performed.
* If true, cca will be performed.
* @param tx_power Transmit power in dBm.
* @param p_tx_power Transmit power in dBm.
* @param notifications_mask Selects additional notifications generated during a frame transmission.
* It is bitwise combination of @ref nrf_802154_trx_transmit_notifications_t values.
* @note To transmit ack after frame is received use @ref nrf_802154_trx_transmit_ack.
*/
void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer,
bool cca,
int8_t tx_power,
const nrf_802154_tx_power_split_t * p_tx_power,
nrf_802154_trx_transmit_notifications_t notifications_mask);
/**@brief Puts the trx module into transmit ACK mode.
@ -390,12 +391,12 @@ void nrf_802154_trx_standalone_cca(void);
/**@brief Starts generating continuous carrier.
*
* @param[in] tx_power Transmit power in dBm.
* @param[in] p_tx_power Transmit power in dBm.
*
* 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(int8_t tx_power);
void nrf_802154_trx_continuous_carrier(const nrf_802154_tx_power_split_t * p_tx_power);
/**@brief Restarts generating continuous carrier
*
@ -410,9 +411,10 @@ void nrf_802154_trx_continuous_carrier_restart(void);
/**@brief Starts generating modulated carrier with given buffer.
*
* @param[in] p_transmit_buffer Pointer to a buffer used for modulating the carrier wave.
* @param[in] tx_power Transmit power in dBm.
* @param[in] p_tx_power Transmit power in dBm.
*/
void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer, int8_t tx_power);
void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer,
const nrf_802154_tx_power_split_t * p_tx_power);
/** @brief Restarts generating modulated carrier.*/
void nrf_802154_trx_modulated_carrier_restart(void);

View File

@ -35,7 +35,7 @@
#include "nrf_802154_tx_power.h"
#include "nrf_802154_pib.h"
#include "nrf_802154_utils.h"
#include "fal/nrf_802154_fal.h"
#include "nrf_802154_fal.h"
/**
* Converts TX power integer values to RADIO TX power allowed values.
@ -98,38 +98,60 @@ static nrf_radio_txpower_t to_radio_tx_power_convert(int8_t integer_tx_power)
}
/**
* Converts TX power integer values to RADIO TX power allowed values, constrained by the allowed TX power allowed for
* a specific channel.
* 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[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 RADIO TX power allowed and constrained value.
* @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 nrf_radio_txpower_t constrain_and_convert_tx_power(uint8_t channel, int8_t tx_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)
{
int8_t constrained_power = nrf_802154_fal_tx_power_get(channel, tx_power);
int32_t ret = 0;
nrf_802154_fal_tx_power_split_t fal_split_power = {0};
return to_radio_tx_power_convert(constrained_power);
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 = to_radio_tx_power_convert(fal_split_power.radio_tx_power);
return (0 == ret);
}
nrf_radio_txpower_t nrf_802154_tx_power_convert_metadata_to_raw_value(
uint8_t channel,
nrf_802154_tx_power_metadata_t tx_power)
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 power_unconstrained =
tx_power.use_metadata_value ? tx_power.power : nrf_802154_pib_tx_power_get();
return constrain_and_convert_tx_power(channel, power_unconstrained);
return constrain_split_and_convert_tx_power(channel, power_unconstrained, p_tx_power_split);
}
nrf_radio_txpower_t nrf_802154_tx_power_constrained_pib_power_get(void)
bool nrf_802154_tx_power_split_pib_power_get(nrf_802154_tx_power_split_t * const p_split_power)
{
return constrain_and_convert_tx_power(nrf_802154_pib_channel_get(),
nrf_802154_pib_tx_power_get());
return constrain_split_and_convert_tx_power(nrf_802154_pib_channel_get(),
nrf_802154_pib_tx_power_get(),
p_split_power);
}
nrf_radio_txpower_t nrf_802154_tx_power_constrained_pib_power_for_channel_get(uint8_t channel)
bool nrf_802154_tx_power_split_pib_power_for_channel_get(
uint8_t channel,
nrf_802154_tx_power_split_t * const p_split_power)
{
return constrain_and_convert_tx_power(channel, nrf_802154_pib_tx_power_get());
return constrain_split_and_convert_tx_power(channel,
nrf_802154_pib_tx_power_get(),
p_split_power);
}

View File

@ -39,37 +39,63 @@
#include "nrf_802154.h"
/**@brief Convert tx_power value passed through metadata to a raw value in dBm used by the core module.
/**@brief Convert tx_power value passed through metadata to raw components in dBms to be applied
* on each stage of the transmit path.
* This function also ensures that the value meets the constraints for the current channel.
* This function also ensures that the values meet the constraints for the given channel.
*
* @param[in] channel The channel to be used for transmission
* @param[in] tx_power The value passed to the transmit metadata.
* @param[in] channel The channel to be used for transmission
* @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 Returns the power in dBm which will be used to transmit the frame.
* @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.
*
*/
nrf_radio_txpower_t nrf_802154_tx_power_convert_metadata_to_raw_value(
uint8_t channel,
nrf_802154_tx_power_metadata_t tx_power);
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);
/**@brief Get the transmit power stored in PIB after applying the power constraints for the current channel.
/**@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.
*
* The current channel is acquired from PIB.
*
* @retval Returns the constrained power in dBm which will be used to transmit the frame.
* @param[out] p_split_power Pointer to the structure holding TX power split into components in dBm.
*
*/
nrf_radio_txpower_t nrf_802154_tx_power_constrained_pib_power_get(void);
* @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.
/**@brief Get the transmit power stored in PIB after applying the power constraints for the given channel.
*
* @param[in] channel The channel based on which the power should be constrained
*
* @retval Returns the power in dBm which will be used to transmit the frame.
*
*/
nrf_radio_txpower_t nrf_802154_tx_power_constrained_pib_power_for_channel_get(uint8_t channel);
bool nrf_802154_tx_power_split_pib_power_get(nrf_802154_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.
*
* @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.
*
*/
bool nrf_802154_tx_power_split_pib_power_for_channel_get(
uint8_t channel,
nrf_802154_tx_power_split_t * const p_split_power);
/**
*@}

View File

@ -713,6 +713,17 @@ int8_t nrf_802154_dbm_from_energy_level_calculate(uint8_t energy_level);
*/
uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length);
/**
* @brief Calculates the timestamp of the MAC Header in a received frame.
*
* @param[in] end_timestamp Timestamp of the end of the last symbol in the frame,
* in microseconds.
* @param[in] psdu_length Number of bytes in the frame PSDU.
*
* @return Timestamp of the MHR of a given frame, in microseconds.
*/
uint64_t nrf_802154_mhr_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length);
/**
* @}
* @defgroup nrf_802154_ifs Inter-frame spacing feature

View File

@ -72,7 +72,9 @@ extern void nrf_802154_cca_failed(nrf_802154_cca_error_t error);
* @brief Notifies that the energy detection procedure finished.
*
* @note This function passes the EnergyLevel defined in the 802.15.4-2006 specification:
* 0x00 - 0xff, proportionally to the detected energy level (dBm above receiver sensitivity).
* 0x00 - 0xff, where 0x00 represents -75dBm (10dBm above the worst allowed sensitivity level,
* which is -85dBm) and 0xff is the highest possible energy detection level, for which
* the measurements are guaranteed map linearly to the real energy level in dBm.
* To calculate the result in dBm, use @ref nrf_802154_dbm_from_energy_level_calculate.
*
* @param[in] result Maximum energy detected during the energy detection procedure.

View File

@ -179,6 +179,8 @@
#define PHY_SYMBOLS_PER_OCTET 2 ///< Number of symbols in a single byte (octet).
#define PHY_SHR_SYMBOLS 10 ///< Number of symbols in the Synchronization Header (SHR).
#define PHY_MIN_RECEIVER_SENSITIVITY -85 ///< Lowest receiver sensitivity level in dBm according to 802.15.4-2020 specification, chapter 12.3.4
#define ED_RESULT_MAX 0xff ///< Maximal ED result.
#define BROADCAST_ADDRESS ((uint8_t[SHORT_ADDRESS_SIZE]) {0xff, 0xff}) ///< Broadcast short address.
@ -223,7 +225,4 @@
#define IE_DATA_OFFSET 0x02 ///< Information element data offset
#define IE_HEADER_ELEMENT_ID_OFFSET 0x07 ///< Bit offset of Element ID field in a Header IE header.
#define ED_MIN_DBM (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#endif // NRF_802154_CONST_H_

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 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_NRFX_ADDONS_H__
#define NRF_802154_NRFX_ADDONS_H__
#include "nrf.h"
#include "nrf_802154_const.h"
/* The usage of ED_RSSISCALE is described imprecisely in the nRF product specifications. The meaning of
this constant is the following: If we calculate ed_scaled = EDSAMPLE * ED_RSSISCALE, then
it is guaranteed that in the range 0-255 ed_scaled maps linearly to the ED power in dBm. This means,
that the maximum value in EDSAMPLE which can be reported in compliance with the 802.15.4 specification is
255/ED_RSSISCALE. */
#if defined (NRF52840_XXAA) || defined(NRF52811_XXAA)
#define ED_RSSIOFFS (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#elif defined (NRF52833_XXAA) || defined(NRF52820_XXAA) || defined(NRF5340_XXAA)
#define ED_RSSIOFFS (-93) ///< dBm value corresponding to value 0 in the EDSAMPLE register.
#define ED_RSSISCALE 5 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral.
#else
#error "Selected chip is not supported."
#endif
#define EDSAMPLE_MIN_REPORTED_VALUE (PHY_MIN_RECEIVER_SENSITIVITY - ED_RSSIOFFS + 10) ///< Minimal reported EDSAMPLE value (reported as 0)
#define EDSAMPLE_MAX_REPORTED_VALUE (ED_RESULT_MAX / ED_RSSISCALE) ///< Maximal reported EDSAMPLE value (reported as 255)
/**
* @brief Converts the energy level received during the energy detection procedure to a dBm value.
*
* @param[in] energy_level Energy level value compliant with the 802.15.4 specification (0-255)
*
* @return Result of the energy detection procedure in dBm.
*/
static inline int8_t nrf_802154_addons_dbm_from_energy_level_calculate(uint8_t energy_level)
{
return ((int16_t)(EDSAMPLE_MAX_REPORTED_VALUE - EDSAMPLE_MIN_REPORTED_VALUE) *
((int16_t)energy_level)) /
ED_RESULT_MAX + EDSAMPLE_MIN_REPORTED_VALUE + ED_RSSIOFFS;
}
#endif // NRF_802154_NRFX_ADDONS_H__

View File

@ -63,6 +63,7 @@
#include "nrf_802154.h"
#include "nrf_802154_config.h"
#include "nrf_802154_types.h"
#include "nrf_802154_nrfx_addons.h"
/**
* @brief Wait with timeout for SPINEL_STATUS_OK to be received.
@ -1489,8 +1490,9 @@ bool nrf_802154_transmit_raw_at(uint8_t * p_data
{
.frame_props = NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT,
.cca = true,
.channel = 11,
.tx_power = {.use_metadata_value = false}
// channel set to 0 will be replaced on net core by the current channel from PIB
.channel = 0,
.tx_power = {.use_metadata_value = false}
};
p_metadata = &metadata_default;
@ -1769,7 +1771,7 @@ bail:
int8_t nrf_802154_dbm_from_energy_level_calculate(uint8_t energy_level)
{
return ED_MIN_DBM + (energy_level / ED_RESULT_FACTOR);
return nrf_802154_addons_dbm_from_energy_level_calculate(energy_level);
}
uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length)
@ -1781,6 +1783,11 @@ uint64_t nrf_802154_first_symbol_timestamp_get(uint64_t end_timestamp, uint8_t p
return end_timestamp - (frame_symbols * PHY_US_PER_SYMBOL);
}
uint64_t nrf_802154_mhr_timestamp_get(uint64_t end_timestamp, uint8_t psdu_length)
{
return end_timestamp - (psdu_length * PHY_SYMBOLS_PER_OCTET * PHY_US_PER_SYMBOL);
}
void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter)
{
nrf_802154_ser_err_t res;

View File

@ -1354,6 +1354,13 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_transmit_raw_at(
return NRF_802154_SERIALIZATION_ERROR_NO_MEMORY;
}
// tx_metadata.channel set to 0 means that NULL was passed as metadata on app core
// and the channel should be set to the current channel from PIB
if (0 == tx_metadata.channel)
{
tx_metadata.channel = nrf_802154_channel_get();
}
bool result = nrf_802154_transmit_raw_at(p_local_frame_ptr, tx_time, &tx_metadata);
if (!result)

View File

@ -46,6 +46,15 @@
extern "C" {
#endif
/**
* @brief Represents components of tx_power to be applied for stages on transmit path.
*/
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.
} nrf_802154_fal_tx_power_split_t;
/**
* @brief Returns 'power' value.
*
@ -58,6 +67,20 @@ extern "C" {
*/
int8_t nrf_802154_fal_tx_power_get(const uint8_t channel, const int8_t power);
/** @brief Splits transmit power value into components to be applied on each stage on the transmit path.
*
* @note This is a stub implementation used when MPSL is not linked.
*
* @param[in] channel Ignored.
* @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.
*/
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);
#ifdef __cplusplus
}
#endif

View File

@ -103,6 +103,19 @@ typedef struct
#endif
} mpsl_fem_event_t;
/** TX power, dBm. */
typedef int8_t mpsl_tx_power_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;
} mpsl_tx_power_split_t;
/** @brief Disable Front End Module.
*
* Some Front End Module devices can be explicitly disabled after PA and LNA activities are
@ -292,6 +305,38 @@ int32_t mpsl_fem_abort_clear(void);
*/
void mpsl_fem_cleanup(void);
/** @brief Splits transmit power value into components to be applied on each stage on transmit path.
*
* @note If the exact value of @p power cannot be achieved, this function attempts to use less
* power to not exceed constraint. However, if @p power is lower than the minimum achievable power,
* or larger than the maximum achievable power, the function returns failure.
*
* @param[in] power TX power requested for transmission on air.
* @param[out] p_tx_power_split Components of tx_power to be applied for stages on transmit path.
*
* @retval 0 Calculation performed successfully.
* @retval - ::NRF_EINVAL 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.
*/
int32_t mpsl_fem_tx_power_split(const mpsl_tx_power_t power,
mpsl_tx_power_split_t *const p_tx_power_split);
/** @brief Sets PA gain.
*
* @note The gain set by this function will be applied to radio transmissions
* following the call. If the function is called during radio transmission
* or during ramp-up for transmission it is unspecified if the gain is applied.
*
* @param[in] gain Gain in dB to be set.
*
* @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);
/** @brief Checks if the PA signaling is configured and enabled, and gets
* the configured gain in dB.
*

View File

@ -37,6 +37,8 @@
#include <stdbool.h>
#include <stdint.h>
#include "nrf_802154_fal.h"
#include "protocol/mpsl_fem_protocol_api.h"
#ifdef __cplusplus
@ -110,6 +112,22 @@ void mpsl_fem_cleanup(void)
// Intentionally empty
}
int32_t 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 = power;
p_tx_power_split->fem_gain = 0;
return 0;
}
int32_t mpsl_fem_pa_gain_set(int8_t gain)
{
(void)gain;
return 0;
}
void mpsl_fem_pa_is_configured(int8_t * const p_gain)
{
(void)p_gain;
@ -138,6 +156,18 @@ int8_t nrf_802154_fal_tx_power_get(const uint8_t channel, const int8_t power)
return power;
}
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)
{
(void)channel;
p_tx_power_split->radio_tx_power = power;
p_tx_power_split->fem_gain = 0;
return 0;
}
#ifdef __cplusplus
}
#endif