drivers: ieee802154: add CSL receiver for nRF5
Implement CSL receiver functionality in nRF5 radio driver. Signed-off-by: Eduardo Montoya <eduardo.montoya@nordicsemi.no>
This commit is contained in:
parent
141620519b
commit
0f73fbdbfe
8 changed files with 210 additions and 35 deletions
|
@ -135,6 +135,18 @@ config IEEE802154_2015
|
||||||
help
|
help
|
||||||
Enable radio driver support for IEEE 802.15.4-2015 frames, including security handling of frames and ACKs.
|
Enable radio driver support for IEEE 802.15.4-2015 frames, including security handling of frames and ACKs.
|
||||||
|
|
||||||
|
config IEEE802154_DELAY_TRX_ACC
|
||||||
|
int "Clock accuracy for delayed operations"
|
||||||
|
default 20
|
||||||
|
help
|
||||||
|
Accuracy of the clock used for scheduling radio delayed operations (delayed transmission
|
||||||
|
or delayed reception), in ppm.
|
||||||
|
|
||||||
|
config IEEE802154_CSL_ENDPOINT
|
||||||
|
bool "Enable support for CSL Endpoint"
|
||||||
|
help
|
||||||
|
Enable support for CSL Endpoint with delayed reception handling and CSL IE injection.
|
||||||
|
|
||||||
module = IEEE802154_DRIVER
|
module = IEEE802154_DRIVER
|
||||||
module-str = IEEE 802.15.4 driver
|
module-str = IEEE 802.15.4 driver
|
||||||
module-help = Sets log level for IEEE 802.15.4 Device Drivers.
|
module-help = Sets log level for IEEE 802.15.4 Device Drivers.
|
||||||
|
|
|
@ -57,7 +57,11 @@ static struct nrf5_802154_data nrf5_data;
|
||||||
#define ACK_REQUEST_BIT (1 << 5)
|
#define ACK_REQUEST_BIT (1 << 5)
|
||||||
#define FRAME_PENDING_BYTE 1
|
#define FRAME_PENDING_BYTE 1
|
||||||
#define FRAME_PENDING_BIT (1 << 4)
|
#define FRAME_PENDING_BIT (1 << 4)
|
||||||
#define TXTIME_OFFSET_US (5 * USEC_PER_MSEC)
|
#define TXTIME_OFFSET_US (1 * USEC_PER_MSEC)
|
||||||
|
|
||||||
|
#define DRX_SLOT_PH 0 /* Placeholder delayed reception window ID */
|
||||||
|
#define DRX_SLOT_RX 1 /* Actual delayed reception window ID */
|
||||||
|
#define PH_DURATION 10 /* Duration of the placeholder window, in microseconds */
|
||||||
|
|
||||||
#if defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE)
|
#if defined(CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE)
|
||||||
#if defined(CONFIG_SOC_NRF5340_CPUAPP)
|
#if defined(CONFIG_SOC_NRF5340_CPUAPP)
|
||||||
|
@ -217,6 +221,7 @@ static void nrf5_get_capabilities_at_boot(void)
|
||||||
IEEE802154_HW_TX_RX_ACK |
|
IEEE802154_HW_TX_RX_ACK |
|
||||||
IEEE802154_HW_ENERGY_SCAN |
|
IEEE802154_HW_ENERGY_SCAN |
|
||||||
((caps & NRF_802154_CAPABILITY_DELAYED_TX) ? IEEE802154_HW_TXTIME : 0UL) |
|
((caps & NRF_802154_CAPABILITY_DELAYED_TX) ? IEEE802154_HW_TXTIME : 0UL) |
|
||||||
|
((caps & NRF_802154_CAPABILITY_DELAYED_RX) ? IEEE802154_HW_RXTIME : 0UL) |
|
||||||
IEEE802154_HW_SLEEP_TO_TX |
|
IEEE802154_HW_SLEEP_TO_TX |
|
||||||
((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL);
|
((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL);
|
||||||
}
|
}
|
||||||
|
@ -565,6 +570,13 @@ static uint64_t nrf5_get_time(const struct device *dev)
|
||||||
return nrf_802154_time_get();
|
return nrf_802154_time_get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t nrf5_get_acc(const struct device *dev)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(dev);
|
||||||
|
|
||||||
|
return CONFIG_IEEE802154_DELAY_TRX_ACC;
|
||||||
|
}
|
||||||
|
|
||||||
static int nrf5_start(const struct device *dev)
|
static int nrf5_start(const struct device *dev)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
ARG_UNUSED(dev);
|
||||||
|
@ -582,7 +594,18 @@ static int nrf5_start(const struct device *dev)
|
||||||
|
|
||||||
static int nrf5_stop(const struct device *dev)
|
static int nrf5_stop(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
|
||||||
|
if (nrf_802154_sleep_if_idle() != NRF_802154_SLEEP_ERROR_NONE) {
|
||||||
|
if (nrf5_data.event_handler) {
|
||||||
|
nrf5_data.event_handler(dev, IEEE802154_EVENT_SLEEP, NULL);
|
||||||
|
} else {
|
||||||
|
LOG_WRN("Transition to radio sleep cannot be handled.");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
ARG_UNUSED(dev);
|
ARG_UNUSED(dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!nrf_802154_sleep()) {
|
if (!nrf_802154_sleep()) {
|
||||||
LOG_ERR("Error while stopping radio");
|
LOG_ERR("Error while stopping radio");
|
||||||
|
@ -692,6 +715,35 @@ static void nrf5_config_mac_keys(struct ieee802154_key *mac_keys)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NRF_802154_ENCRYPTION */
|
#endif /* CONFIG_NRF_802154_ENCRYPTION */
|
||||||
|
|
||||||
|
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
|
||||||
|
static void nrf5_receive_at(uint32_t start, uint32_t duration, uint8_t channel, uint32_t id)
|
||||||
|
{
|
||||||
|
nrf_802154_receive_at(start - TXTIME_OFFSET_US, TXTIME_OFFSET_US, duration, channel, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nrf5_config_csl_period(uint16_t period)
|
||||||
|
{
|
||||||
|
nrf_802154_receive_at_cancel(DRX_SLOT_PH);
|
||||||
|
nrf_802154_receive_at_cancel(DRX_SLOT_RX);
|
||||||
|
|
||||||
|
nrf_802154_csl_writer_period_set(period);
|
||||||
|
|
||||||
|
/* A placeholder reception window is scheduled so that the radio driver is able to inject
|
||||||
|
* the proper CSL Phase in the transmitted CSL Information Elements.
|
||||||
|
*/
|
||||||
|
nrf5_receive_at(nrf5_data.csl_rx_time, PH_DURATION, nrf_802154_channel_get(), DRX_SLOT_PH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nrf5_schedule_rx(uint8_t channel, uint32_t start, uint32_t duration)
|
||||||
|
{
|
||||||
|
nrf5_receive_at(start, duration, channel, DRX_SLOT_RX);
|
||||||
|
|
||||||
|
/* The placeholder reception window is rescheduled for the next period */
|
||||||
|
nrf_802154_receive_at_cancel(DRX_SLOT_PH);
|
||||||
|
nrf5_receive_at(nrf5_data.csl_rx_time, PH_DURATION, channel, DRX_SLOT_PH);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IEEE802154_CSL_ENDPOINT */
|
||||||
|
|
||||||
static int nrf5_configure(const struct device *dev,
|
static int nrf5_configure(const struct device *dev,
|
||||||
enum ieee802154_config_type type,
|
enum ieee802154_config_type type,
|
||||||
const struct ieee802154_config *config)
|
const struct ieee802154_config *config)
|
||||||
|
@ -766,6 +818,43 @@ static int nrf5_configure(const struct device *dev,
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_NRF_802154_ENCRYPTION */
|
#endif /* CONFIG_NRF_802154_ENCRYPTION */
|
||||||
|
|
||||||
|
case IEEE802154_CONFIG_ENH_ACK_HEADER_IE: {
|
||||||
|
uint8_t short_addr_le[SHORT_ADDRESS_SIZE];
|
||||||
|
uint8_t ext_addr_le[EXTENDED_ADDRESS_SIZE];
|
||||||
|
|
||||||
|
sys_put_le16(config->ack_ie.short_addr, short_addr_le);
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
memcpy(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE);
|
||||||
|
#else
|
||||||
|
sys_memcpy_swap(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (config->ack_ie.data_len > 0) {
|
||||||
|
nrf_802154_ack_data_set(short_addr_le, false, config->ack_ie.data,
|
||||||
|
config->ack_ie.data_len, NRF_802154_ACK_DATA_IE);
|
||||||
|
nrf_802154_ack_data_set(ext_addr_le, true, config->ack_ie.data,
|
||||||
|
config->ack_ie.data_len, NRF_802154_ACK_DATA_IE);
|
||||||
|
} else {
|
||||||
|
nrf_802154_ack_data_clear(short_addr_le, false, NRF_802154_ACK_DATA_IE);
|
||||||
|
nrf_802154_ack_data_clear(ext_addr_le, true, NRF_802154_ACK_DATA_IE);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
|
||||||
|
case IEEE802154_CONFIG_CSL_RX_TIME:
|
||||||
|
nrf5_data.csl_rx_time = config->csl_rx_time;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_CONFIG_RX_SLOT:
|
||||||
|
nrf5_schedule_rx(config->rx_slot.channel, config->rx_slot.start,
|
||||||
|
config->rx_slot.duration);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IEEE802154_CONFIG_CSL_PERIOD:
|
||||||
|
nrf5_config_csl_period(config->csl_period);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_IEEE802154_CSL_ENDPOINT */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -807,7 +896,14 @@ void nrf_802154_received_timestamp_raw(uint8_t *data, int8_t power, uint8_t lqi,
|
||||||
|
|
||||||
void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
|
void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_IEEE802154_CSL_ENDPOINT)
|
||||||
|
if ((id == DRX_SLOT_PH) || (id == DRX_SLOT_RX)) {
|
||||||
|
nrf5_stop(net_if_get_device(nrf5_data.iface));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
ARG_UNUSED(id);
|
ARG_UNUSED(id);
|
||||||
|
#endif
|
||||||
|
|
||||||
enum ieee802154_rx_fail_reason reason;
|
enum ieee802154_rx_fail_reason reason;
|
||||||
|
|
||||||
|
@ -949,6 +1045,7 @@ static struct ieee802154_radio_api nrf5_radio_api = {
|
||||||
.tx = nrf5_tx,
|
.tx = nrf5_tx,
|
||||||
.ed_scan = nrf5_energy_scan_start,
|
.ed_scan = nrf5_energy_scan_start,
|
||||||
.get_time = nrf5_get_time,
|
.get_time = nrf5_get_time,
|
||||||
|
.get_sch_acc = nrf5_get_acc,
|
||||||
.configure = nrf5_configure,
|
.configure = nrf5_configure,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,9 @@ struct nrf5_802154_data {
|
||||||
|
|
||||||
/* Capabilities of the network interface. */
|
/* Capabilities of the network interface. */
|
||||||
enum ieee802154_hw_caps capabilities;
|
enum ieee802154_hw_caps capabilities;
|
||||||
|
|
||||||
|
/* Next CSL receive time */
|
||||||
|
uint32_t csl_rx_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */
|
#endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */
|
||||||
|
|
|
@ -69,7 +69,8 @@ enum ieee802154_filter_type {
|
||||||
|
|
||||||
enum ieee802154_event {
|
enum ieee802154_event {
|
||||||
IEEE802154_EVENT_TX_STARTED, /* Data transmission started */
|
IEEE802154_EVENT_TX_STARTED, /* Data transmission started */
|
||||||
IEEE802154_EVENT_RX_FAILED /* Data reception failed */
|
IEEE802154_EVENT_RX_FAILED, /* Data reception failed */
|
||||||
|
IEEE802154_EVENT_SLEEP, /* Sleep pending */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ieee802154_rx_fail_reason {
|
enum ieee802154_rx_fail_reason {
|
||||||
|
@ -168,11 +169,45 @@ enum ieee802154_config_type {
|
||||||
/** Sets the current MAC frame counter value for radios supporting transmit security. */
|
/** Sets the current MAC frame counter value for radios supporting transmit security. */
|
||||||
IEEE802154_CONFIG_FRAME_COUNTER,
|
IEEE802154_CONFIG_FRAME_COUNTER,
|
||||||
|
|
||||||
/** Configure a radio reception slot */
|
/** Configure a radio reception slot. This can be used for any scheduler reception, e.g.:
|
||||||
|
* Zigbee GP device, CSL, TSCH, etc.
|
||||||
|
*
|
||||||
|
* In order to configure a CSL receiver the upper layer should combine several
|
||||||
|
* configuration options in the following way:
|
||||||
|
* 1. Use ``IEEE802154_CONFIG_ENH_ACK_HEADER_IE`` once to inform the radio driver of the
|
||||||
|
* short and extended addresses of the peer to which it should inject CSL IEs.
|
||||||
|
* 2. Use ``IEEE802154_CONFIG_CSL_RX_TIME`` periodically, before each use of
|
||||||
|
* ``IEEE802154_CONFIG_CSL_PERIOD`` setting parameters of the nearest CSL RX window, and
|
||||||
|
* before each use of IEEE_CONFIG_RX_SLOT setting parameters of the following (not the
|
||||||
|
* nearest one) CSL RX window, to allow the radio driver to calculate the proper CSL Phase
|
||||||
|
* to the nearest CSL window to inject in the CSL IEs for both transmitted data and ack
|
||||||
|
* frames.
|
||||||
|
* 3. Use ``IEEE802154_CONFIG_CSL_PERIOD`` on each value change to update the current CSL
|
||||||
|
* period value which will be injected in the CSL IEs together with the CSL Phase based on
|
||||||
|
* ``IEEE802154_CONFIG_CSL_RX_TIME``.
|
||||||
|
* 4. Use ``IEEE802154_CONFIG_RX_SLOT`` periodically to schedule the immediate receive
|
||||||
|
* window earlier enough before the expected window start time, taking into account
|
||||||
|
* possible clock drifts and scheduling uncertainties.
|
||||||
|
*
|
||||||
|
* This diagram shows the usage of the four options over time:
|
||||||
|
* Start CSL Schedule CSL window
|
||||||
|
*
|
||||||
|
* ENH_ACK_HEADER_IE CSL_RX_TIME (following window)
|
||||||
|
* | |
|
||||||
|
* | CSL_RX_TIME (nearest window) | RX_SLOT (nearest window)
|
||||||
|
* | | | |
|
||||||
|
* | | CSL_PERIOD | |
|
||||||
|
* | | | | |
|
||||||
|
* v v v v v
|
||||||
|
* ----------------------------------------------------------[ CSL window ]-----+
|
||||||
|
* ^ |
|
||||||
|
* | |
|
||||||
|
* +--------------------- loop ---------+
|
||||||
|
*/
|
||||||
IEEE802154_CONFIG_RX_SLOT,
|
IEEE802154_CONFIG_RX_SLOT,
|
||||||
|
|
||||||
/** Enable CSL receiver (Endpoint) */
|
/** Configure CSL receiver (Endpoint) period */
|
||||||
IEEE802154_CONFIG_CSL_RECEIVER,
|
IEEE802154_CONFIG_CSL_PERIOD,
|
||||||
|
|
||||||
/** Configure the next CSL receive window center, in units of microseconds,
|
/** Configure the next CSL receive window center, in units of microseconds,
|
||||||
* based on the radio time.
|
* based on the radio time.
|
||||||
|
@ -235,11 +270,8 @@ struct ieee802154_config {
|
||||||
uint32_t duration;
|
uint32_t duration;
|
||||||
} rx_slot;
|
} rx_slot;
|
||||||
|
|
||||||
/** ``IEEE802154_CONFIG_CSL_RECEIVER`` */
|
/** ``IEEE802154_CONFIG_CSL_PERIOD`` */
|
||||||
struct {
|
uint32_t csl_period;
|
||||||
uint32_t period;
|
|
||||||
const uint8_t *addr;
|
|
||||||
} csl_recv;
|
|
||||||
|
|
||||||
/** ``IEEE802154_CONFIG_CSL_RX_TIME`` */
|
/** ``IEEE802154_CONFIG_CSL_RX_TIME`` */
|
||||||
uint32_t csl_rx_time;
|
uint32_t csl_rx_time;
|
||||||
|
@ -315,11 +347,11 @@ struct ieee802154_radio_api {
|
||||||
uint64_t (*get_time)(const struct device *dev);
|
uint64_t (*get_time)(const struct device *dev);
|
||||||
|
|
||||||
/** Get the current accuracy, in units of ± ppm, of the clock used for
|
/** Get the current accuracy, in units of ± ppm, of the clock used for
|
||||||
* scheduling CSL transmissions or receive windows.
|
* scheduling delayed receive or transmit radio operations.
|
||||||
* Note: Implementations may optimize this value based on operational
|
* Note: Implementations may optimize this value based on operational
|
||||||
* conditions (i.e.: temperature).
|
* conditions (i.e.: temperature).
|
||||||
*/
|
*/
|
||||||
uint8_t (*get_csl_acc)(const struct device *dev);
|
uint8_t (*get_sch_acc)(const struct device *dev);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Make sure that the network interface API is properly setup inside
|
/* Make sure that the network interface API is properly setup inside
|
||||||
|
|
|
@ -88,7 +88,13 @@ config OPENTHREAD_CSL_SAMPLE_WINDOW
|
||||||
|
|
||||||
config OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
|
config OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
|
||||||
int "CSL receiver wake up margin in units of 10 symbols"
|
int "CSL receiver wake up margin in units of 10 symbols"
|
||||||
default 3
|
default 480
|
||||||
|
|
||||||
|
config OPENTHREAD_CSL_MIN_RECEIVE_ON
|
||||||
|
int "Minimum CSL receive window"
|
||||||
|
default 5696
|
||||||
|
help
|
||||||
|
The minimum CSL receive window (in microseconds) required to receive a full IEEE 802.15.4 frame
|
||||||
|
|
||||||
config OPENTHREAD_MAC_SOFTWARE_TX_SECURITY_ENABLE
|
config OPENTHREAD_MAC_SOFTWARE_TX_SECURITY_ENABLE
|
||||||
bool "Enable software transmission security logic"
|
bool "Enable software transmission security logic"
|
||||||
|
|
|
@ -22,6 +22,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "platform-zephyr.h"
|
#include "platform-zephyr.h"
|
||||||
|
#include "openthread-core-zephyr-config.h"
|
||||||
|
|
||||||
static bool timer_ms_fired, timer_us_fired;
|
static bool timer_ms_fired, timer_us_fired;
|
||||||
|
|
||||||
|
|
|
@ -140,8 +140,8 @@
|
||||||
* in platform.
|
* in platform.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE \
|
#define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE \
|
||||||
(OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE && \
|
(CONFIG_OPENTHREAD_CSL_RECEIVER && \
|
||||||
(OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2))
|
(OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2))
|
||||||
|
|
||||||
/* Zephyr does not use OpenThread's heap. mbedTLS will use heap memory allocated
|
/* Zephyr does not use OpenThread's heap. mbedTLS will use heap memory allocated
|
||||||
|
@ -283,7 +283,7 @@
|
||||||
*
|
*
|
||||||
* For some reasons, CSL receivers wake up a little later than expected. This
|
* For some reasons, CSL receivers wake up a little later than expected. This
|
||||||
* variable specifies how much time that CSL receiver would wake up earlier
|
* variable specifies how much time that CSL receiver would wake up earlier
|
||||||
* than the expected sample window. The time is in unit of 10 symbols.
|
* than the expected sample window. The time is in unit of microseconds.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
|
#ifdef CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
|
||||||
|
@ -291,6 +291,16 @@
|
||||||
CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
|
CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
|
||||||
#endif /* CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD */
|
#endif /* CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON
|
||||||
|
*
|
||||||
|
* The minimum CSL receive window (in microseconds) required to receive an IEEE 802.15.4 frame.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON
|
||||||
|
#define OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON
|
||||||
|
#endif /* CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
|
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
|
||||||
*
|
*
|
||||||
|
|
|
@ -60,11 +60,10 @@ enum pending_events {
|
||||||
PENDING_EVENT_RX_FAILED, /* The RX failed */
|
PENDING_EVENT_RX_FAILED, /* The RX failed */
|
||||||
PENDING_EVENT_TX_STARTED, /* Radio has started transmitting */
|
PENDING_EVENT_TX_STARTED, /* Radio has started transmitting */
|
||||||
PENDING_EVENT_TX_DONE, /* Radio transmission finished */
|
PENDING_EVENT_TX_DONE, /* Radio transmission finished */
|
||||||
PENDING_EVENT_DETECT_ENERGY, /* Requested to start Energy Detection
|
PENDING_EVENT_DETECT_ENERGY, /* Requested to start Energy Detection procedure */
|
||||||
* procedure.
|
PENDING_EVENT_DETECT_ENERGY_DONE, /* Energy Detection finished */
|
||||||
*/
|
PENDING_EVENT_SLEEP, /* Sleep if idle */
|
||||||
PENDING_EVENT_DETECT_ENERGY_DONE, /* Energy Detection finished. */
|
PENDING_EVENT_COUNT /* Keep last */
|
||||||
PENDING_EVENT_COUNT /* keep last */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
K_SEM_DEFINE(radio_sem, 0, 1);
|
K_SEM_DEFINE(radio_sem, 0, 1);
|
||||||
|
@ -200,6 +199,10 @@ void handle_radio_event(const struct device *dev, enum ieee802154_event evt,
|
||||||
}
|
}
|
||||||
set_pending_event(PENDING_EVENT_RX_FAILED);
|
set_pending_event(PENDING_EVENT_RX_FAILED);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case IEEE802154_EVENT_SLEEP:
|
||||||
|
set_pending_event(PENDING_EVENT_SLEEP);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* do nothing - ignore event */
|
/* do nothing - ignore event */
|
||||||
break;
|
break;
|
||||||
|
@ -476,6 +479,11 @@ void platformRadioProcess(otInstance *aInstance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_pending_event_set(PENDING_EVENT_SLEEP)) {
|
||||||
|
reset_pending_event(PENDING_EVENT_SLEEP);
|
||||||
|
ARG_UNUSED(otPlatRadioSleep(aInstance));
|
||||||
|
}
|
||||||
|
|
||||||
/* handle events that can't run during transmission */
|
/* handle events that can't run during transmission */
|
||||||
if (sState != OT_RADIO_STATE_TRANSMIT) {
|
if (sState != OT_RADIO_STATE_TRANSMIT) {
|
||||||
if (is_pending_event_set(PENDING_EVENT_DETECT_ENERGY)) {
|
if (is_pending_event_set(PENDING_EVENT_DETECT_ENERGY)) {
|
||||||
|
@ -570,8 +578,9 @@ otError otPlatRadioSleep(otInstance *aInstance)
|
||||||
sState == OT_RADIO_STATE_RECEIVE ||
|
sState == OT_RADIO_STATE_RECEIVE ||
|
||||||
sState == OT_RADIO_STATE_TRANSMIT) {
|
sState == OT_RADIO_STATE_TRANSMIT) {
|
||||||
error = OT_ERROR_NONE;
|
error = OT_ERROR_NONE;
|
||||||
sState = OT_RADIO_STATE_SLEEP;
|
if (radio_api->stop(radio_dev)) {
|
||||||
radio_api->stop(radio_dev);
|
sState = OT_RADIO_STATE_SLEEP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -1015,33 +1024,38 @@ void otPlatRadioSetMacFrameCounter(otInstance *aInstance,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_OPENTHREAD_CSL_RECEIVER)
|
#if defined(CONFIG_OPENTHREAD_CSL_RECEIVER)
|
||||||
otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod,
|
otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShortAddress aShortAddr,
|
||||||
const otExtAddress *aExtAddr)
|
const otExtAddress *aExtAddr)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
uint8_t ie_header[OT_IE_HEADER_SIZE + OT_CSL_IE_SIZE];
|
||||||
|
struct ieee802154_config config;
|
||||||
|
|
||||||
ARG_UNUSED(aInstance);
|
ARG_UNUSED(aInstance);
|
||||||
|
|
||||||
struct ieee802154_config config = {
|
ie_header[0] = CSL_IE_HEADER_BYTES_LO;
|
||||||
.csl_recv.period = aCslPeriod,
|
ie_header[1] = CSL_IE_HEADER_BYTES_HI;
|
||||||
.csl_recv.addr = aExtAddr->m8,
|
/* Leave CSL Phase empty intentionally */
|
||||||
};
|
sys_put_le16(aCslPeriod, &ie_header[OT_IE_HEADER_SIZE + 2]);
|
||||||
|
config.ack_ie.data = ie_header;
|
||||||
|
config.ack_ie.data_len = OT_IE_HEADER_SIZE + OT_CSL_IE_SIZE;
|
||||||
|
config.ack_ie.short_addr = aShortAddr;
|
||||||
|
config.ack_ie.ext_addr = aExtAddr->m8;
|
||||||
|
result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config);
|
||||||
|
|
||||||
result = radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RECEIVER,
|
config.csl_period = aCslPeriod;
|
||||||
&config);
|
result += radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_PERIOD, &config);
|
||||||
|
|
||||||
return result ? OT_ERROR_FAILED : OT_ERROR_NONE;
|
return result ? OT_ERROR_FAILED : OT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void otPlatRadioUpdateCslSampleTime(otInstance *aInstance,
|
void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime)
|
||||||
uint32_t aCslSampleTime)
|
|
||||||
{
|
{
|
||||||
ARG_UNUSED(aInstance);
|
ARG_UNUSED(aInstance);
|
||||||
|
|
||||||
struct ieee802154_config config = { .csl_rx_time = aCslSampleTime };
|
struct ieee802154_config config = { .csl_rx_time = aCslSampleTime };
|
||||||
|
|
||||||
(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RX_TIME,
|
(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RX_TIME, &config);
|
||||||
&config);
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_OPENTHREAD_CSL_RECEIVER */
|
#endif /* CONFIG_OPENTHREAD_CSL_RECEIVER */
|
||||||
|
|
||||||
|
@ -1049,7 +1063,7 @@ uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(aInstance);
|
ARG_UNUSED(aInstance);
|
||||||
|
|
||||||
return radio_api->get_csl_acc(radio_dev);
|
return radio_api->get_sch_acc(radio_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_OPENTHREAD_LINK_METRICS)
|
#if defined(CONFIG_OPENTHREAD_LINK_METRICS)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue