diff --git a/drivers/nrf_802154/driver/include/nrf_802154.h b/drivers/nrf_802154/driver/include/nrf_802154.h index 6fd4b3e..e617d2a 100644 --- a/drivers/nrf_802154/driver/include/nrf_802154.h +++ b/drivers/nrf_802154/driver/include/nrf_802154.h @@ -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 diff --git a/drivers/nrf_802154/driver/include/nrf_802154_types.h b/drivers/nrf_802154/driver/include/nrf_802154_types.h index 076f8f4..e9ce17a 100644 --- a/drivers/nrf_802154/driver/include/nrf_802154_types.h +++ b/drivers/nrf_802154/driver/include/nrf_802154_types.h @@ -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. */ diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c index 452a817..793f320 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_csma_ca.c @@ -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. /** diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c index e0dfa4f..48595d6 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c @@ -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 @@ -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 diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.h b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.h index 06ab7e7..6eef26d 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.h +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.h @@ -38,7 +38,7 @@ #include #include -#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); + /** *@} **/ diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ifs.h b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ifs.h index ab339a5..84af466 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ifs.h +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ifs.h @@ -39,7 +39,7 @@ #include #include "nrf_802154_const.h" -#include "nrf_802154_types.h" +#include "nrf_802154_types_internal.h" /** * @brief Initializes the Interframe Spacing handling feature. diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.h b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.h index 95c30db..4db8a86 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.h +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_security_writer.h @@ -38,7 +38,7 @@ #include #include -#include "nrf_802154_types.h" +#include "nrf_802154_types_internal.h" /** * @brief Transmission setup hook for the security writer module. diff --git a/drivers/nrf_802154/driver/src/nrf_802154.c b/drivers/nrf_802154/driver/src/nrf_802154.c index e3c8571..a0972ff 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154.c +++ b/drivers/nrf_802154/driver/src/nrf_802154.c @@ -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) diff --git a/drivers/nrf_802154/driver/src/nrf_802154_core.c b/drivers/nrf_802154/driver/src/nrf_802154_core.c index 90dc8e4..0b6857b 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_core.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_core.c @@ -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); diff --git a/drivers/nrf_802154/driver/src/nrf_802154_core.h b/drivers/nrf_802154/driver/src/nrf_802154_core.h index 94cb8a9..2929c2e 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_core.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_core.h @@ -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; diff --git a/drivers/nrf_802154/driver/src/nrf_802154_core_hooks.c b/drivers/nrf_802154/driver/src/nrf_802154_core_hooks.c index a7df321..48b1b05 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_core_hooks.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_core_hooks.c @@ -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, diff --git a/drivers/nrf_802154/driver/src/nrf_802154_core_hooks.h b/drivers/nrf_802154/driver/src/nrf_802154_core_hooks.h index 4fc43d0..50beaad 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_core_hooks.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_core_hooks.h @@ -39,7 +39,7 @@ #include #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 diff --git a/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c b/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c index 6a02b91..f6db2e4 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c @@ -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" diff --git a/drivers/nrf_802154/driver/src/nrf_802154_encrypt.h b/drivers/nrf_802154/driver/src/nrf_802154_encrypt.h index d155c09..5e100d5 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_encrypt.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_encrypt.h @@ -38,7 +38,7 @@ #include #include -#include "nrf_802154_types.h" +#include "nrf_802154_types_internal.h" #include "mac_features/nrf_802154_frame_parser.h" #ifdef __cplusplus diff --git a/drivers/nrf_802154/driver/src/nrf_802154_request.h b/drivers/nrf_802154/driver/src/nrf_802154_request.h index 506f19d..5e3b8a6 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_request.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_request.h @@ -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" { diff --git a/drivers/nrf_802154/driver/src/nrf_802154_request_swi.c b/drivers/nrf_802154/driver/src/nrf_802154_request_swi.c index 5c69b8c..230ebd5 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_request_swi.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_request_swi.c @@ -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" diff --git a/drivers/nrf_802154/driver/src/nrf_802154_rssi.h b/drivers/nrf_802154/driver/src/nrf_802154_rssi.h index 7604c8c..0f60b72 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_rssi.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_rssi.h @@ -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. */ diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx.c b/drivers/nrf_802154/driver/src/nrf_802154_trx.c index c309522..49d90f3 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx.c @@ -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(); diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx.h b/drivers/nrf_802154/driver/src/nrf_802154_trx.h index 10a212b..09bfa90 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx.h @@ -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); diff --git a/drivers/nrf_802154/driver/src/nrf_802154_tx_power.c b/drivers/nrf_802154/driver/src/nrf_802154_tx_power.c index bf4f532..6e9efc2 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_tx_power.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_tx_power.c @@ -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); } diff --git a/drivers/nrf_802154/driver/src/nrf_802154_tx_power.h b/drivers/nrf_802154/driver/src/nrf_802154_tx_power.h index 1116c1a..b45c5bb 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_tx_power.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_tx_power.h @@ -38,6 +38,7 @@ #include #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); /** *@} diff --git a/drivers/nrf_802154/driver/src/nrf_802154_types_internal.h b/drivers/nrf_802154/driver/src/nrf_802154_types_internal.h new file mode 100644 index 0000000..4fc2dfd --- /dev/null +++ b/drivers/nrf_802154/driver/src/nrf_802154_types_internal.h @@ -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__ diff --git a/drivers/nrf_802154/serialization/include/host/nrf_802154.h b/drivers/nrf_802154/serialization/include/host/nrf_802154.h index e30d585..37aff46 100644 --- a/drivers/nrf_802154/serialization/include/host/nrf_802154.h +++ b/drivers/nrf_802154/serialization/include/host/nrf_802154.h @@ -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 diff --git a/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h b/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h index 214f30e..85a8122 100644 --- a/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h +++ b/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h @@ -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. diff --git a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c index 8567c82..4090a60 100644 --- a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c +++ b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c @@ -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) { diff --git a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c index 3bd17cf..7a1447f 100644 --- a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c +++ b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c @@ -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: diff --git a/drivers/nrf_802154/sl/include/nrf_802154_fal.h b/drivers/nrf_802154/sl/include/nrf_802154_fal.h index adfc39c..4add13e 100644 --- a/drivers/nrf_802154/sl/include/nrf_802154_fal.h +++ b/drivers/nrf_802154/sl/include/nrf_802154_fal.h @@ -41,6 +41,7 @@ #define NRF_802154_FAL_H_ #include +#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 } diff --git a/drivers/nrf_802154/sl/sl_opensource/include/protocol/mpsl_fem_protocol_api.h b/drivers/nrf_802154/sl/sl_opensource/include/protocol/mpsl_fem_protocol_api.h index c156b0f..299bef9 100644 --- a/drivers/nrf_802154/sl/sl_opensource/include/protocol/mpsl_fem_protocol_api.h +++ b/drivers/nrf_802154/sl/sl_opensource/include/protocol/mpsl_fem_protocol_api.h @@ -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. diff --git a/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_fem.c b/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_fem.c index 83604fb..0dec3f2 100644 --- a/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_fem.c +++ b/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_fem.c @@ -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