diff --git a/examples/platforms/nrf52840/Makefile.am b/examples/platforms/nrf52840/Makefile.am index f169c75ba..1330fdd5c 100644 --- a/examples/platforms/nrf52840/Makefile.am +++ b/examples/platforms/nrf52840/Makefile.am @@ -140,27 +140,27 @@ PLATFORM_SOURCES $(NULL) endif -RADIO_DRIVER_SOURCES = \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rssi.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_802154_clock_sdk.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c \ - @top_builddir@/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.c \ +RADIO_DRIVER_SOURCES = \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_ack_pending_bit.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core_hooks.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_critical_section.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_debug.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_revision.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rsch.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rssi.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_rx_buffer.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/nrf_802154_timer_coord.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_delayed_trx.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/platform/clock/nrf_802154_clock_sdk.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/platform/hp_timer/nrf_802154_hp_timer.c \ + @top_builddir@/third_party/NordicSemiconductor/drivers/radio/timer_scheduler/nrf_802154_timer_sched.c \ $(NULL) NORDICSEMI_SOURCES = \ diff --git a/examples/platforms/nrf52840/platform-fem.h b/examples/platforms/nrf52840/platform-fem.h index d49c19de5..c444241b0 100644 --- a/examples/platforms/nrf52840/platform-fem.h +++ b/examples/platforms/nrf52840/platform-fem.h @@ -41,8 +41,8 @@ #define PLATFORM_FEM_DEFAULT_PA_PIN 26 /**< Default Power Amplifier pin. */ #define PLATFORM_FEM_DEFAULT_LNA_PIN 27 /**< Default Low Noise Amplifier pin. */ -#define PLATFORM_FEM_DEFAULT_SET_PPI_CHANNEL 18 /**< Default PPI channel for pin setting. */ -#define PLATFORM_FEM_DEFAULT_CLR_PPI_CHANNEL 19 /**< Default PPI channel for pin clearing. */ +#define PLATFORM_FEM_DEFAULT_SET_PPI_CHANNEL 15 /**< Default PPI channel for pin setting. */ +#define PLATFORM_FEM_DEFAULT_CLR_PPI_CHANNEL 16 /**< Default PPI channel for pin clearing. */ #define PLATFORM_FEM_DEFAULT_TIMER_MATCH_PPI_GROUP 4 /**< Default PPI channel group used to disable timer match PPI. */ #define PLATFORM_FEM_DEFAULT_RADIO_DISABLED_PPI_GROUP 5 /**< Default PPI channel group used to disable radio disabled PPI. */ #define PLATFORM_FEM_DEFAULT_LNA_GPIOTE_CHANNEL 6 /**< Default LNA GPIOTE channel for FEM control. */ diff --git a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h index ae0fb93d7..1653b89d9 100644 --- a/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h +++ b/third_party/NordicSemiconductor/drivers/radio/fem/nrf_fem_control_api.h @@ -57,10 +57,10 @@ extern "C" { #define NRF_FEM_CONTROL_DEFAULT_LNA_PIN 27 /** Default PPI channel for pin setting. */ -#define NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL 18 +#define NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL 15 /** Default PPI channel for pin clearing. */ -#define NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL 19 +#define NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL 16 /** Default GPIOTE channel for FEM control. */ #define NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL 6 diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h index e11ca86f9..7712d0dfd 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_ack_timeout.h @@ -47,8 +47,7 @@ /** * @brief Set timeout time for ACK timeout feature. * - * @param[in] time Timeout time in us. Timeout is started at the beginning of frame - * transmission (after transmission of PHR). + * @param[in] time Timeout time in us. * Default value is defined in nrf_802154_config.h. */ void nrf_802154_ack_timeout_time_set(uint32_t time); diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c index b3433a332..29fc0bf43 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_csma_ca.c @@ -48,6 +48,8 @@ #include "nrf_802154_request.h" #include "timer_scheduler/nrf_802154_timer_sched.h" +#if NRF_802154_CSMA_CA_ENABLED + static uint8_t m_nb; ///< The number of times the CSMA-CA algorithm was required to back off while attempting the current transmission. static uint8_t m_be; ///< Backoff exponent, which is related to how many backoff periods a device shall wait before attempting to assess a channel. @@ -252,3 +254,4 @@ bool nrf_802154_csma_ca_tx_started_hook(const uint8_t * p_frame) return true; } +#endif // NRF_802154_CSMA_CA_ENABLED diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c index fccb8bfae..87b75ea41 100644 --- a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_filter.c @@ -398,7 +398,7 @@ nrf_802154_rx_error_t nrf_802154_filter_frame_part(const uint8_t * p_psdu, uint8 { case FCF_CHECK_OFFSET: { - if (p_psdu[0] < ACK_LENGTH || p_psdu[0] > MAX_PACKET_SIZE) + if (p_psdu[0] < IMM_ACK_LENGTH || p_psdu[0] > MAX_PACKET_SIZE) { // Frame length is invalid result = NRF_802154_RX_ERROR_INVALID_FRAME; diff --git a/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c new file mode 100644 index 000000000..79d75b223 --- /dev/null +++ b/third_party/NordicSemiconductor/drivers/radio/mac_features/nrf_802154_precise_ack_timeout.c @@ -0,0 +1,171 @@ +/* Copyright (c) 2018, Nordic Semiconductor ASA + * All rights reserved. + * + * 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 implements ACK timeout procedure for the 802.15.4 driver. + * + */ + +#include "nrf_802154_ack_timeout.h" + +#include +#include +#include + +#include "nrf_802154_notification.h" +#include "nrf_802154_procedures_duration.h" +#include "nrf_802154_request.h" +#include "timer_scheduler/nrf_802154_timer_sched.h" + +#define RETRY_DELAY 500 ///< Procedure is delayed by this time if it cannot be performed at the moment [us]. +#define MAX_RETRY_DELAY 1000000 ///< Maximum allowed delay of procedure retry [us]. + +static void timeout_timer_retry(void); + +static uint32_t m_timeout = NRF_802154_PRECISE_ACK_TIMEOUT_DEFAULT_TIMEOUT; ///< ACK timeout in us. +static nrf_802154_timer_t m_timer; ///< Timer used to notify when the ACK frama is not received for too long. +static volatile bool m_procedure_is_active; +static const uint8_t * mp_frame; + +static void notify_tx_error(bool result) +{ + if (result) + { + nrf_802154_notify_transmit_failed(mp_frame, NRF_802154_TX_ERROR_NO_ACK); + } +} + +static void timeout_timer_fired(void * p_context) +{ + (void)p_context; + + if (m_procedure_is_active) + { + if (nrf_802154_request_receive(NRF_802154_TERM_802154, + REQ_ORIG_ACK_TIMEOUT, + notify_tx_error, + false)) + { + m_procedure_is_active = false; + } + else + { + timeout_timer_retry(); + } + } +} + +static void timeout_timer_retry(void) +{ + m_timer.dt += RETRY_DELAY; + assert(m_timer.dt <= MAX_RETRY_DELAY); + + nrf_802154_timer_sched_add(&m_timer, true); +} + +static void timeout_timer_start(void) +{ + m_timer.callback = timeout_timer_fired; + m_timer.p_context = NULL; + m_timer.t0 = nrf_802154_timer_sched_time_get(); + m_timer.dt = m_timeout + + IMM_ACK_DURATION + + nrf_802154_frame_duration_get(mp_frame[0], false, true); + + m_procedure_is_active = true; + + nrf_802154_timer_sched_add(&m_timer, true); +} + +static void timeout_timer_stop(void) +{ + m_procedure_is_active = false; + + // To make sure `timeout_timer_fired()` detects that procedure is being stopped if it preempts + // this function. + __DMB(); + + nrf_802154_timer_sched_remove(&m_timer); +} + +void nrf_802154_ack_timeout_time_set(uint32_t time) +{ + m_timeout = time; +} + +bool nrf_802154_ack_timeout_tx_started_hook(const uint8_t * p_frame) +{ + mp_frame = p_frame; + timeout_timer_start(); + + return true; +} + +bool nrf_802154_ack_timeout_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig) +{ + bool result; + + if (!m_procedure_is_active || req_orig == REQ_ORIG_ACK_TIMEOUT) + { + // Ignore if procedure is not running or self-request. + result = true; + } + else if (term_lvl >= NRF_802154_TERM_802154) + { + // Stop procedure only if termination level is high enough. + timeout_timer_stop(); + + result = true; + } + else + { + result = false; + } + + return result; +} + +void nrf_802154_ack_timeout_transmitted_hook(const uint8_t * p_frame) +{ + assert((p_frame == mp_frame) || (!m_procedure_is_active)); + + timeout_timer_stop(); +} + +bool nrf_802154_ack_timeout_tx_failed_hook(const uint8_t * p_frame, nrf_802154_tx_error_t error) +{ + (void)error; + assert((p_frame == mp_frame) || (!m_procedure_is_active)); + + timeout_timer_stop(); + + return true; +} diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c index 4dd205b00..ab1eecf86 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.c @@ -191,7 +191,7 @@ uint8_t nrf_802154_ccaedthres_from_dbm_calculate(int8_t dbm) uint32_t nrf_802154_first_symbol_timestamp_get(uint32_t end_timestamp, uint8_t psdu_length) { - uint32_t frame_symbols = PHY_SHR_DURATION; + uint32_t frame_symbols = PHY_SHR_SYMBOLS; frame_symbols += (PHR_SIZE + psdu_length) * PHY_SYMBOLS_PER_OCTET; return end_timestamp - (frame_symbols * PHY_US_PER_SYMBOL); diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h index 3cc7aeec3..9f18775de 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154.h @@ -304,7 +304,7 @@ bool nrf_802154_receive(void); * Depending on @ref NRF_802154_ACK_TIMEOUT_ENABLED, the radio driver automatically * stops waiting for an ACK frame or waits indefinitely for an ACK frame. If it is configured to * wait, the MAC layer is responsible for calling @ref nrf_802154_receive or - * @ref nrf_802154_sleep after the ACK time-out. + * @ref nrf_802154_sleep after the ACK timeout. * The transmission result is reported to the higher layer by calls to @ref nrf_802154_transmitted * or @ref nrf_802154_transmit_failed. * @@ -345,7 +345,7 @@ bool nrf_802154_transmit_raw(const uint8_t * p_data, bool cca); * Depending on @ref NRF_802154_ACK_TIMEOUT_ENABLED, the radio driver automatically * stops waiting for an ACK frame or waits indefinitely for an ACK frame. If it is configured to * wait, the MAC layer is responsible for calling @ref nrf_802154_receive or - * @ref nrf_802154_sleep after the ACK time-out. + * @ref nrf_802154_sleep after the ACK timeout. * The transmission result is reported to the higher layer by calls to @ref nrf_802154_transmitted * or @ref nrf_802154_transmit_failed. * @@ -1015,7 +1015,7 @@ void nrf_802154_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg); * @ref nrf_802154_transmit_failed. * * @note The driver may be configured to automatically time out waiting for an ACK frame depending - * on @ref NRF_802154_ACK_TIMEOUT_ENABLED. If automatic ACK time-out is disabled, the CSMA-CA + * on @ref NRF_802154_ACK_TIMEOUT_ENABLED. If automatic ACK timeout is disabled, the CSMA-CA * procedure does not time out waiting for an ACK frame if a frame with the ACK request bit * set was transmitted. The MAC layer should manage the timer to time out waiting for the ACK * frame. This timer can be started by @ref nrf_802154_tx_started. When the timer expires, @@ -1037,7 +1037,7 @@ void nrf_802154_transmit_csma_ca_raw(const uint8_t * p_data); * @ref nrf_802154_transmit_failed. * * @note The driver may be configured to automatically time out waiting for an ACK frame depending - * on @ref NRF_802154_ACK_TIMEOUT_ENABLED. If automatic ACK time-out is disabled, the CSMA-CA + * on @ref NRF_802154_ACK_TIMEOUT_ENABLED. If automatic ACK timeout is disabled, the CSMA-CA * procedure does not time out waiting for an ACK frame if a frame with the ACK request bit * set was transmitted. The MAC layer should manage the timer to time out waiting for the ACK * frame. This timer can be started by @ref nrf_802154_tx_started. When the timer expires, @@ -1056,19 +1056,18 @@ void nrf_802154_transmit_csma_ca(const uint8_t * p_data, uint8_t length); /** * @} - * @defgroup nrf_802154_timeout ACK time-out procedure + * @defgroup nrf_802154_timeout ACK timeout procedure * @{ */ #if NRF_802154_ACK_TIMEOUT_ENABLED /** - * @brief Set time-out for the ACK time-out feature. + * @brief Set timeout for the ACK timeout feature. * - * A time-out is notified by @ref nrf_802154_transmit_failed. + * A timeout is notified by @ref nrf_802154_transmit_failed. * - * @param[in] time Time-out in us. The time-out is started at the beginning of frame transmission - * (after transmission of PHR). A default value is defined in nrf_802154_config.h - * (@ref NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT). + * @param[in] time Timeout in us. + * A default value is defined in nrf_802154_config.h. */ void nrf_802154_ack_timeout_set(uint32_t time); diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h index aec1e42f6..640d939b2 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_config.h @@ -426,14 +426,14 @@ extern "C" { /** * @} - * @defgroup nrf_802154_config_timeout ACK time-out feature configuration + * @defgroup nrf_802154_config_timeout ACK timeout feature configuration * @{ */ /** * @def NRF_802154_ACK_TIMEOUT_ENABLED * - * If the ACK time-out feature should be enabled in the driver. + * If the ACK timeout feature should be enabled in the driver. * */ #ifndef NRF_802154_ACK_TIMEOUT_ENABLED @@ -443,13 +443,23 @@ extern "C" { /** * @def NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT * - * Default time-out in us for the ACK time-out feature. + * Default timeout in us for the ACK timeout feature. * */ #ifndef NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT #define NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT 7000 #endif +/** + * @def NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT + * + * Default time-out in us for the precise ACK time-out feature. + * + */ +#ifndef NRF_802154_PRECISE_ACK_TIMEOUT_DEFAULT_TIMEOUT +#define NRF_802154_PRECISE_ACK_TIMEOUT_DEFAULT_TIMEOUT 210 +#endif + /** * @} * @defgroup nrf_802154_config_transmission Transmission start notification feature configuration @@ -461,7 +471,7 @@ extern "C" { * * If notifications of started transmissions should be enabled in the driver. * - * @note This feature is enabled by default if the ACK time-out feature or CSMA-CA is enabled. + * @note This feature is enabled by default if the ACK timeout feature or CSMA-CA is enabled. * These features depend on notifications of transmission start. */ #ifndef NRF_802154_TX_STARTED_NOTIFY_ENABLED diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h index fd019e7cc..2d0aca2a6 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_const.h @@ -39,77 +39,77 @@ #include #include "nrf_802154_config.h" -#define ACK_HEADER_WITH_PENDING 0x12 ///< First byte of ACK frame containing pending bit -#define ACK_HEADER_WITHOUT_PENDING 0x02 ///< First byte of ACK frame without pending bit +#define ACK_HEADER_WITH_PENDING 0x12 ///< First byte of ACK frame containing pending bit. +#define ACK_HEADER_WITHOUT_PENDING 0x02 ///< First byte of ACK frame without pending bit. -#define ACK_REQUEST_OFFSET 1 ///< Byte containing Ack request bit (+1 for frame length byte) -#define ACK_REQUEST_BIT (1 << 5) ///< Ack request bit +#define ACK_REQUEST_OFFSET 1 ///< Byte containing Ack request bit (+1 for frame length byte). +#define ACK_REQUEST_BIT (1 << 5) ///< Ack request bit. -#define DEST_ADDR_TYPE_OFFSET 2 ///< Byte containing destination address type (+1 for frame length byte) -#define DEST_ADDR_TYPE_MASK 0x0c ///< Mask of bits containing destination address type -#define DEST_ADDR_TYPE_EXTENDED 0x0c ///< Bits containing extended destination address type -#define DEST_ADDR_TYPE_NONE 0x00 ///< Bits containing not present destination address type -#define DEST_ADDR_TYPE_SHORT 0x08 ///< Bits containing short destination address type -#define DEST_ADDR_OFFSET 6 ///< Offset of destination address in Data frame (+1 for frame length byte) +#define DEST_ADDR_TYPE_OFFSET 2 ///< Byte containing destination address type (+1 for frame length byte). +#define DEST_ADDR_TYPE_MASK 0x0c ///< Mask of bits containing destination address type. +#define DEST_ADDR_TYPE_EXTENDED 0x0c ///< Bits containing extended destination address type. +#define DEST_ADDR_TYPE_NONE 0x00 ///< Bits containing not present destination address type. +#define DEST_ADDR_TYPE_SHORT 0x08 ///< Bits containing short destination address type. +#define DEST_ADDR_OFFSET 6 ///< Offset of destination address in Data frame (+1 for frame length byte). -#define DSN_OFFSET 3 ///< Byte containing DSN value (+1 for frame length byte) +#define DSN_OFFSET 3 ///< Byte containing DSN value (+1 for frame length byte). -#define FRAME_PENDING_OFFSET 1 ///< Byte containing pending bit (+1 for frame length byte) -#define FRAME_PENDING_BIT (1 << 4) ///< Pending bit +#define FRAME_PENDING_OFFSET 1 ///< Byte containing pending bit (+1 for frame length byte). +#define FRAME_PENDING_BIT (1 << 4) ///< Pending bit. -#define FRAME_TYPE_OFFSET 1 ///< Byte containing frame type bits (+1 for frame length byte) -#define FRAME_TYPE_MASK 0x07 ///< Mask of bits containing frame type -#define FRAME_TYPE_ACK 0x02 ///< Bits containing ACK frame type -#define FRAME_TYPE_BEACON 0x00 ///< Bits containing Beacon frame type -#define FRAME_TYPE_COMMAND 0x03 ///< Bits containing Command frame type -#define FRAME_TYPE_DATA 0x01 ///< Bits containing Data frame type -#define FRAME_TYPE_EXTENDED 0x07 ///< Bits containing Extended frame type -#define FRAME_TYPE_FRAGMENT 0x06 ///< Bits containing Fragment or Frak frame type -#define FRAME_TYPE_MULTIPURPOSE 0x05 ///< Bits containing Multipurpose frame type +#define FRAME_TYPE_OFFSET 1 ///< Byte containing frame type bits (+1 for frame length byte). +#define FRAME_TYPE_MASK 0x07 ///< Mask of bits containing frame type. +#define FRAME_TYPE_ACK 0x02 ///< Bits containing ACK frame type. +#define FRAME_TYPE_BEACON 0x00 ///< Bits containing Beacon frame type. +#define FRAME_TYPE_COMMAND 0x03 ///< Bits containing Command frame type. +#define FRAME_TYPE_DATA 0x01 ///< Bits containing Data frame type. +#define FRAME_TYPE_EXTENDED 0x07 ///< Bits containing Extended frame type. +#define FRAME_TYPE_FRAGMENT 0x06 ///< Bits containing Fragment or Frak frame type. +#define FRAME_TYPE_MULTIPURPOSE 0x05 ///< Bits containing Multipurpose frame type. -#define FRAME_VERSION_OFFSET 2 ///< Byte containing frame version bits (+1 for frame length byte) -#define FRAME_VERSION_MASK 0x30 ///< Mask of bits containing frame version -#define FRAME_VERSION_0 0x00 ///< Bits containing frame version 0b00 -#define FRAME_VERSION_1 0x10 ///< Bits containing frame version 0b01 -#define FRAME_VERSION_2 0x20 ///< Bits containing frame version 0b10 -#define FRAME_VERSION_3 0x30 ///< Bits containing frame version 0b11 +#define FRAME_VERSION_OFFSET 2 ///< Byte containing frame version bits (+1 for frame length byte). +#define FRAME_VERSION_MASK 0x30 ///< Mask of bits containing frame version. +#define FRAME_VERSION_0 0x00 ///< Bits containing frame version 0b00. +#define FRAME_VERSION_1 0x10 ///< Bits containing frame version 0b01. +#define FRAME_VERSION_2 0x20 ///< Bits containing frame version 0b10. +#define FRAME_VERSION_3 0x30 ///< Bits containing frame version 0b11. -#define PAN_ID_COMPR_OFFSET 1 ///< Byte containing Pan Id compression bit (+1 for frame length byte) -#define PAN_ID_COMPR_MASK 0x40 ///< Pan Id compression bit +#define PAN_ID_COMPR_OFFSET 1 ///< Byte containing Pan Id compression bit (+1 for frame length byte). +#define PAN_ID_COMPR_MASK 0x40 ///< Pan Id compression bit. -#define PAN_ID_OFFSET 4 ///< Offset of Pan Id in Data frame (+1 for frame length byte) +#define PAN_ID_OFFSET 4 ///< Offset of Pan Id in Data frame (+1 for frame length byte). -#define SRC_ADDR_TYPE_EXTENDED 0xc0 ///< Bits containing extended source address type -#define SRC_ADDR_TYPE_NONE 0x00 ///< Bits containing not present source address type -#define SRC_ADDR_TYPE_MASK 0xc0 ///< Mask of bits containing source address type -#define SRC_ADDR_TYPE_OFFSET 2 ///< Byte containing source address type (+1 for frame length byte) -#define SRC_ADDR_TYPE_SHORT 0x80 ///< Bits containing short source address type +#define SRC_ADDR_TYPE_EXTENDED 0xc0 ///< Bits containing extended source address type. +#define SRC_ADDR_TYPE_NONE 0x00 ///< Bits containing not present source address type. +#define SRC_ADDR_TYPE_MASK 0xc0 ///< Mask of bits containing source address type. +#define SRC_ADDR_TYPE_OFFSET 2 ///< Byte containing source address type (+1 for frame length byte). +#define SRC_ADDR_TYPE_SHORT 0x80 ///< Bits containing short source address type. -#define SRC_ADDR_OFFSET_SHORT_DST 8 ///< Offset of source address in Data frame if destination address is short -#define SRC_ADDR_OFFSET_EXTENDED_DST 14 ///< Offset of source address in Data frame if destination address is extended +#define SRC_ADDR_OFFSET_SHORT_DST 8 ///< Offset of source address in Data frame if destination address is short. +#define SRC_ADDR_OFFSET_EXTENDED_DST 14 ///< Offset of source address in Data frame if destination address is extended. -#define PHR_SIZE 1 ///< Size of PHR field -#define FCF_SIZE 2 ///< Size of FCF field -#define PAN_ID_SIZE 2 ///< Size of Pan Id -#define SHORT_ADDRESS_SIZE 2 ///< Size of Short Mac Address -#define EXTENDED_ADDRESS_SIZE 8 ///< Size of Extended Mac Address -#define FCS_SIZE 2 ///< Size of FCS field -#define ACK_LENGTH 5 ///< Length of ACK frame -#define MAX_PACKET_SIZE 127 ///< Maximal size of radio packet +#define PHR_SIZE 1 ///< Size of PHR field. +#define FCF_SIZE 2 ///< Size of FCF field. +#define PAN_ID_SIZE 2 ///< Size of Pan Id. +#define SHORT_ADDRESS_SIZE 2 ///< Size of Short Mac Address. +#define EXTENDED_ADDRESS_SIZE 8 ///< Size of Extended Mac Address. +#define FCS_SIZE 2 ///< Size of FCS field. +#define IMM_ACK_LENGTH 5 ///< Length of ACK frame. +#define MAX_PACKET_SIZE 127 ///< Maximum size of radio packet. -#define TURNAROUND_TIME 192UL ///< aTurnaroundTime [us] -#define CCA_TIME 128UL ///< aCcaTime [us] -#define UNIT_BACKOFF_PERIOD (TURNAROUND_TIME + CCA_TIME) ///< aUnitBackoffPeriod [us] +#define TURNAROUND_TIME 192UL ///< aTurnaroundTime [us]. +#define CCA_TIME 128UL ///< aCcaTime [us]. +#define UNIT_BACKOFF_PERIOD (TURNAROUND_TIME + CCA_TIME) ///< aUnitBackoffPeriod [us]. -#define PHY_US_PER_SYMBOL 16 ///< Duration of single symbol in microseconds [us] -#define PHY_SYMBOLS_PER_OCTET 2 ///< Number of symbols in single byte (octet) -#define PHY_SHR_DURATION 10 ///< Number of symbols in Synchronization Header (SHR) +#define PHY_US_PER_SYMBOL 16 ///< Duration of a single symbol in microseconds [us]. +#define PHY_SYMBOLS_PER_OCTET 2 ///< Number of symbols in a single byte (octet). +#define PHY_SHR_SYMBOLS 10 ///< Number of symbols in Synchronization Header (SHR). -#define ED_MIN_DBM (-94) ///< dBm value corresponding to value 0 in EDSAMPLE register -#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate ED result based on data from RADIO peripheral -#define ED_RESULT_MAX 0xff ///< Maximal ED result +#define ED_MIN_DBM (-94) ///< dBm value corresponding to value 0 in EDSAMPLE register. +#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate ED result based on data from RADIO peripheral. +#define ED_RESULT_MAX 0xff ///< Maximal ED result. -#define BROADCAST_ADDRESS ((uint8_t [SHORT_ADDRESS_SIZE]) {0xff, 0xff}) ///< Broadcast Short Address +#define BROADCAST_ADDRESS ((uint8_t [SHORT_ADDRESS_SIZE]) {0xff, 0xff}) ///< Broadcast Short Address. typedef enum { diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c index a7dac12ab..155b11830 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_core.c @@ -177,12 +177,12 @@ static rx_buffer_t * mp_current_rx_buffer; static rx_buffer_t * const mp_current_rx_buffer = &nrf_802154_rx_buffers[0]; #endif -static uint8_t m_ack_psdu[ACK_LENGTH + 1]; ///< Ack frame buffer. -static const uint8_t * mp_tx_data; ///< Pointer to data to transmit. -static uint32_t m_ed_time_left; ///< Remaining time of current energy detection procedure [us]. -static uint8_t m_ed_result; ///< Result of current energy detection procedure. +static uint8_t m_ack_psdu[IMM_ACK_LENGTH + 1]; ///< ACK frame buffer. +static const 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 volatile radio_state_t m_state; ///< State of the radio driver +static volatile radio_state_t m_state; ///< State of the radio driver. typedef struct { @@ -905,14 +905,26 @@ static bool remaining_timeslot_time_is_enough_for_crit_sect(void) return nrf_802154_rsch_timeslot_us_left_get() >= MAX_CRIT_SECT_TIME; } +/** Check if critical section can be processed at the moment. + * + * @note This function returns valid result only inside critical section. + * + * @retval true There is enough time in current timeslot or timeslot is denied at the moment. + * @retval false Current timeslot ends too shortly to process critical section inside. + */ +static bool critical_section_can_be_processed_now(void) +{ + return !timeslot_is_granted() || remaining_timeslot_time_is_enough_for_crit_sect(); +} + /** Enter critical section and verify if there is enough time to complete operations within. */ -static bool critical_section_enter(void) +static bool critical_section_enter_and_verify_timeslot_length(void) { bool result = nrf_802154_critical_section_enter(); if (result) { - if (timeslot_is_granted() && !remaining_timeslot_time_is_enough_for_crit_sect()) + if (!critical_section_can_be_processed_now()) { result = false; @@ -2679,18 +2691,27 @@ radio_state_t nrf_802154_core_state_get(void) bool nrf_802154_core_sleep(nrf_802154_term_t term_lvl) { - bool result = critical_section_enter(); + bool result = nrf_802154_critical_section_enter(); if (result) { if ((m_state != RADIO_STATE_SLEEP) && (m_state != RADIO_STATE_FALLING_ASLEEP)) { - result = current_operation_terminate(term_lvl, REQ_ORIG_CORE, true); - - if (result) + if (critical_section_can_be_processed_now()) { - state_set(RADIO_STATE_FALLING_ASLEEP); - falling_asleep_init(); + result = current_operation_terminate(term_lvl, REQ_ORIG_CORE, true); + + if (result) + { + state_set(RADIO_STATE_FALLING_ASLEEP); + falling_asleep_init(); + } + } + else + { + nrf_radio_reset(); + state_set(RADIO_STATE_SLEEP); + sleep_init(); } } @@ -2705,18 +2726,25 @@ bool nrf_802154_core_receive(nrf_802154_term_t term_lvl, nrf_802154_notification_func_t notify_function, bool notify_abort) { - bool result = critical_section_enter(); + bool result = nrf_802154_critical_section_enter(); if (result) { if ((m_state != RADIO_STATE_RX) && (m_state != RADIO_STATE_TX_ACK)) { - result = current_operation_terminate(term_lvl, req_orig, notify_abort); - - if (result) + if (critical_section_can_be_processed_now()) { - state_set(RADIO_STATE_RX); - rx_init(true); + result = current_operation_terminate(term_lvl, req_orig, notify_abort); + + if (result) + { + state_set(RADIO_STATE_RX); + rx_init(true); + } + } + else + { + result = false; } if (notify_function != NULL) @@ -2745,7 +2773,7 @@ bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl, bool immediate, nrf_802154_notification_func_t notify_function) { - bool result = critical_section_enter(); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { @@ -2790,7 +2818,7 @@ bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl, bool nrf_802154_core_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us) { - bool result = critical_section_enter(); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { @@ -2812,7 +2840,7 @@ bool nrf_802154_core_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_ bool nrf_802154_core_cca(nrf_802154_term_t term_lvl) { - bool result = critical_section_enter(); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { @@ -2832,7 +2860,7 @@ bool nrf_802154_core_cca(nrf_802154_term_t term_lvl) bool nrf_802154_core_continuous_carrier(nrf_802154_term_t term_lvl) { - bool result = critical_section_enter(); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { @@ -2853,7 +2881,7 @@ bool nrf_802154_core_continuous_carrier(nrf_802154_term_t term_lvl) bool nrf_802154_core_notify_buffer_free(uint8_t * p_data) { rx_buffer_t * p_buffer = (rx_buffer_t *)p_data; - bool in_crit_sect = critical_section_enter(); + bool in_crit_sect = critical_section_enter_and_verify_timeslot_length(); p_buffer->free = true; @@ -2907,7 +2935,7 @@ bool nrf_802154_core_notify_buffer_free(uint8_t * p_data) bool nrf_802154_core_channel_update(void) { - bool result = critical_section_enter(); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { @@ -2968,7 +2996,7 @@ bool nrf_802154_core_channel_update(void) bool nrf_802154_core_cca_cfg_update(void) { - bool result = critical_section_enter(); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c index 5592e51e0..21d4f74fd 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_pib.c @@ -124,7 +124,7 @@ int8_t nrf_802154_pib_tx_power_get(void) void nrf_802154_pib_tx_power_set(int8_t dbm) { - const int8_t allowed_values[] = {-40, -20, -16, -12, -8, -4, 0, 2, 3, 4, 5, 6, 7, 8, 9}; + const int8_t allowed_values[] = {-40, -20, -16, -12, -8, -4, 0, 2, 3, 4, 5, 6, 7, 8}; const int8_t highest_value = allowed_values[(sizeof(allowed_values) / sizeof(allowed_values[0])) - 1]; if (dbm > highest_value) { diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h index 7e360c5b9..94a75306b 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_procedures_duration.h @@ -44,20 +44,23 @@ #define TX_RAMP_UP_TIME 40 // us #define RX_RAMP_UP_TIME 40 // us -#define RX_RAMP_DOWN_TIME 0 // us -#define MAX_RAMP_DOWN_TIME 6 // us +#define RX_RAMP_DOWN_TIME 0 // us +#define MAX_RAMP_DOWN_TIME 6 // us #define RX_TX_TURNAROUND_TIME 20 // us -#define A_CCA_DURATION 8 // sym -#define A_TURNAROUND_TIME 12 // sym -#define A_UNIT_BACKOFF_PERIOD 20 // sym +#define A_CCA_DURATION_SYMBOLS 8 // sym +#define A_TURNAROUND_TIME_SYMBOLS 12 // sym +#define A_UNIT_BACKOFF_SYMBOLS 20 // sym -#define NUM_OCTETS_IN_ACK 6 // bytes +#define PHY_SYMBOLS_FROM_OCTETS(octets) ((octets) * PHY_SYMBOLS_PER_OCTET) +#define PHY_US_TIME_FROM_SYMBOLS(symbols) ((symbols) * PHY_US_PER_SYMBOL) -#define MAC_ACK_WAIT_DURATION (A_UNIT_BACKOFF_PERIOD + \ - A_TURNAROUND_TIME + \ - PHY_SHR_DURATION + \ - (NUM_OCTETS_IN_ACK * PHY_SYMBOLS_PER_OCTET)) +#define IMM_ACK_SYMBOLS (PHY_SHR_SYMBOLS + PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE)) +#define IMM_ACK_DURATION (PHY_US_TIME_FROM_SYMBOLS(IMM_ACK_SYMBOLS)) + +#define MAC_IMM_ACK_WAIT_SYMBOLS (A_UNIT_BACKOFF_SYMBOLS + \ + A_TURNAROUND_TIME_SYMBOLS + \ + IMM_ACK_SYMBOLS) __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, bool cca, @@ -71,6 +74,25 @@ __STATIC_INLINE uint16_t nrf_802154_cca_duration_get(void); #ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE uint16_t nrf_802154_frame_duration_get(uint8_t psdu_length, + bool shr, + bool phr) +{ + uint16_t us_time = PHY_US_TIME_FROM_SYMBOLS(PHY_SYMBOLS_FROM_OCTETS(psdu_length)); + + if (phr) + { + us_time += PHY_US_TIME_FROM_SYMBOLS(PHY_SYMBOLS_FROM_OCTETS(PHR_SIZE)); + } + + if (shr) + { + us_time += PHY_US_TIME_FROM_SYMBOLS(PHY_SHR_SYMBOLS); + } + + return us_time; +} + __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, bool cca, bool ack_requested) @@ -79,57 +101,53 @@ __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, // if CCA: + RX ramp up + CCA + RX ramp down // + TX ramp up + SHR + PHR + PSDU // if ACK: + macAckWaitDuration - uint16_t result = PHY_SHR_DURATION + (psdu_length + 1) * PHY_SYMBOLS_PER_OCTET; + uint16_t us_time = MAX_RAMP_DOWN_TIME + TX_RAMP_UP_TIME + nrf_802154_frame_duration_get(psdu_length, true, true); if (ack_requested) { - result += MAC_ACK_WAIT_DURATION; + us_time += PHY_US_TIME_FROM_SYMBOLS(MAC_IMM_ACK_WAIT_SYMBOLS); } - result *= PHY_US_PER_SYMBOL; - - result += MAX_RAMP_DOWN_TIME + TX_RAMP_UP_TIME; - if (cca) { - result += RX_RAMP_UP_TIME + (A_CCA_DURATION * PHY_US_PER_SYMBOL) + RX_RAMP_DOWN_TIME; + us_time += RX_RAMP_UP_TIME + RX_RAMP_DOWN_TIME + PHY_US_TIME_FROM_SYMBOLS(A_CCA_DURATION_SYMBOLS); } - return result; + return us_time; } __STATIC_INLINE uint16_t nrf_802154_cca_before_tx_duration_get(void) { // CCA + turnaround time - uint16_t result = (A_CCA_DURATION * PHY_US_PER_SYMBOL) + RX_TX_TURNAROUND_TIME; + uint16_t us_time = PHY_US_TIME_FROM_SYMBOLS(A_CCA_DURATION_SYMBOLS) + RX_TX_TURNAROUND_TIME; - return result; + return us_time; } __STATIC_INLINE uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ack_requested) { // SHR + PHR + PSDU // if ACK: + aTurnaroundTime + ACK frame duration - uint16_t result = PHY_SHR_DURATION + ((psdu_length + 1) * PHY_SYMBOLS_PER_OCTET); + uint16_t us_time = nrf_802154_frame_duration_get(psdu_length, true, true); if (ack_requested) { - result += A_TURNAROUND_TIME + - PHY_SHR_DURATION + - (NUM_OCTETS_IN_ACK * PHY_SYMBOLS_PER_OCTET); + us_time += PHY_US_TIME_FROM_SYMBOLS(A_TURNAROUND_TIME_SYMBOLS + + PHY_SHR_SYMBOLS + + PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE)); } - result *= PHY_US_PER_SYMBOL; - - return result; + return us_time; } __STATIC_INLINE uint16_t nrf_802154_cca_duration_get(void) { // ramp down + rx ramp up + CCA - uint16_t result = MAX_RAMP_DOWN_TIME + RX_RAMP_UP_TIME + (A_CCA_DURATION * PHY_US_PER_SYMBOL); + uint16_t us_time = MAX_RAMP_DOWN_TIME + + RX_RAMP_UP_TIME + + PHY_US_TIME_FROM_SYMBOLS(A_CCA_DURATION_SYMBOLS); - return result; + return us_time; } #endif /* SUPPRESS_INLINE_IMPLEMENTATION */ diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c index f16754b68..de45decc8 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_request_swi.c @@ -44,12 +44,19 @@ #include "nrf_802154_core.h" #include "nrf_802154_critical_section.h" #include "nrf_802154_debug.h" +#include "nrf_802154_utils.h" #include "nrf_802154_rx_buffer.h" #include "nrf_802154_swi.h" #include "hal/nrf_radio.h" #include +/** Assert if SWI interrupt is disabled. */ +static inline void assert_interrupt_status(void) +{ + assert(nrf_is_nvic_irq_enabled(NRF_802154_SWI_IRQN)); +} + #define REQUEST_FUNCTION(func_core, func_swi, ...) \ bool result = false; \ \ @@ -59,6 +66,7 @@ } \ else \ { \ + assert_interrupt_status(); \ func_swi(__VA_ARGS__, &result); \ } \ \ @@ -73,6 +81,7 @@ } \ else \ { \ + assert_interrupt_status(); \ func_swi(&result); \ } \ \ diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h index abe44a4c2..67a39db64 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_types.h @@ -65,7 +65,7 @@ typedef uint8_t nrf_802154_tx_error_t; #define NRF_802154_TX_ERROR_INVALID_ACK 0x02 //!< Received ACK frame is other than expected. #define NRF_802154_TX_ERROR_NO_MEM 0x03 //!< No receive buffer is available to receive an ACK. #define NRF_802154_TX_ERROR_TIMESLOT_ENDED 0x04 //!< Radio timeslot ended during transmission procedure. -#define NRF_802154_TX_ERROR_NO_ACK 0x05 //!< ACK frame was not received during time-out period. +#define NRF_802154_TX_ERROR_NO_ACK 0x05 //!< ACK frame was not received during timeout period. #define NRF_802154_TX_ERROR_ABORTED 0x06 //!< Procedure was aborted by another driver operation with FORCE priority. #define NRF_802154_TX_ERROR_TIMESLOT_DENIED 0x07 //!< Transmission did not start due to denied timeslot request. diff --git a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h index 7ae62d386..713d6cd45 100644 --- a/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h +++ b/third_party/NordicSemiconductor/drivers/radio/nrf_802154_utils.h @@ -33,6 +33,7 @@ #include #include +#include "nrf.h" /** * @defgroup nrf_802154_utils Utils definitions used in the 802.15.4 driver. @@ -138,6 +139,19 @@ static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time) return result; } +/**@brief Checks if the provided interrupt is currently enabled. + * + * @note This function is valid only for ARM Cortex-M4 core. + * + * @params IRQn Interrupt number. + * + * @returns Zero if interrupt is disabled, non-zero value otherwise. + */ +static inline uint32_t nrf_is_nvic_irq_enabled(IRQn_Type IRQn) +{ + return (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)]) & ((uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); +} + /** *@} **/ diff --git a/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer_nodrv.c b/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer_nodrv.c index ca9979e2b..05884044f 100644 --- a/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer_nodrv.c +++ b/third_party/NordicSemiconductor/drivers/radio/platform/lp_timer/nrf_802154_lp_timer_nodrv.c @@ -89,9 +89,10 @@ static const compare_channel_descriptor_t m_cmp_ch[CHANNEL_CNT] = {{RTC_LP_TIMER static uint64_t m_target_times[CHANNEL_CNT]; ///< Target time of given channel [us]. -static volatile uint32_t m_offset_counter; ///< Counter of RTC overflows, incremented by 2 on each OVERFLOW event. -static volatile uint8_t m_mutex; ///< Mutex for write access to @ref m_offset_counter. -static volatile bool m_clock_ready; ///< Information that LFCLK is ready. +static volatile uint32_t m_offset_counter; ///< Counter of RTC overflows, incremented by 2 on each OVERFLOW event. +static volatile uint8_t m_mutex; ///< Mutex for write access to @ref m_offset_counter. +static volatile bool m_clock_ready; ///< Information that LFCLK is ready. +static volatile uint32_t m_lp_timer_irq_enabled; ///< Information that RTC interrupt was enabled while entering critical section. static uint32_t overflow_counter_get(void); @@ -390,6 +391,7 @@ void nrf_802154_lp_timer_init(void) m_offset_counter = 0; m_target_times[LP_TIMER_CHANNEL] = 0; m_clock_ready = false; + m_lp_timer_irq_enabled = 0; // Setup low frequency clock. nrf_802154_clock_lfclk_start(); @@ -439,12 +441,21 @@ void nrf_802154_lp_timer_deinit(void) void nrf_802154_lp_timer_critical_section_enter(void) { + if (nrf_is_nvic_irq_enabled(NRF_802154_RTC_IRQN)) + { + m_lp_timer_irq_enabled = 1; + } + NVIC_DisableIRQ(NRF_802154_RTC_IRQN); } void nrf_802154_lp_timer_critical_section_exit(void) { - NVIC_EnableIRQ(NRF_802154_RTC_IRQN); + if (m_lp_timer_irq_enabled) + { + m_lp_timer_irq_enabled = 0; + NVIC_EnableIRQ(NRF_802154_RTC_IRQN); + } } uint32_t nrf_802154_lp_timer_time_get(void)