[nrf52840] update nRF52840 radio driver to version 1.2.2 (#3203)

This commit is contained in:
Kamil Sroka
2018-10-25 10:17:29 -07:00
committed by Jonathan Hui
parent 2446d36649
commit 71d9ba814c
18 changed files with 422 additions and 160 deletions
+21 -21
View File
@@ -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 = \
+2 -2
View File
@@ -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. */
@@ -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
@@ -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);
@@ -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
@@ -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;
@@ -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 <assert.h>
#include <stdbool.h>
#include <stdint.h>
#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;
}
+1 -1
View File
@@ -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);
+9 -10
View File
@@ -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);
@@ -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
@@ -39,77 +39,77 @@
#include <stdint.h>
#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
{
@@ -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)
{
@@ -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)
{
@@ -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 */
@@ -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 <nrf.h>
/** 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); \
} \
\
@@ -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.
@@ -33,6 +33,7 @@
#include <assert.h>
#include <stdint.h>
#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)));
}
/**
*@}
**/
@@ -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)