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
|
||||
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-str = IEEE 802.15.4 driver
|
||||
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 FRAME_PENDING_BYTE 1
|
||||
#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_SOC_NRF5340_CPUAPP)
|
||||
|
@ -217,6 +221,7 @@ static void nrf5_get_capabilities_at_boot(void)
|
|||
IEEE802154_HW_TX_RX_ACK |
|
||||
IEEE802154_HW_ENERGY_SCAN |
|
||||
((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 |
|
||||
((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();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
@ -582,7 +594,18 @@ static int nrf5_start(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);
|
||||
#endif
|
||||
|
||||
if (!nrf_802154_sleep()) {
|
||||
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 */
|
||||
|
||||
#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,
|
||||
enum ieee802154_config_type type,
|
||||
const struct ieee802154_config *config)
|
||||
|
@ -766,6 +818,43 @@ static int nrf5_configure(const struct device *dev,
|
|||
break;
|
||||
#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:
|
||||
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)
|
||||
{
|
||||
#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);
|
||||
#endif
|
||||
|
||||
enum ieee802154_rx_fail_reason reason;
|
||||
|
||||
|
@ -949,6 +1045,7 @@ static struct ieee802154_radio_api nrf5_radio_api = {
|
|||
.tx = nrf5_tx,
|
||||
.ed_scan = nrf5_energy_scan_start,
|
||||
.get_time = nrf5_get_time,
|
||||
.get_sch_acc = nrf5_get_acc,
|
||||
.configure = nrf5_configure,
|
||||
};
|
||||
|
||||
|
|
|
@ -83,6 +83,9 @@ struct nrf5_802154_data {
|
|||
|
||||
/* Capabilities of the network interface. */
|
||||
enum ieee802154_hw_caps capabilities;
|
||||
|
||||
/* Next CSL receive time */
|
||||
uint32_t csl_rx_time;
|
||||
};
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */
|
||||
|
|
|
@ -69,7 +69,8 @@ enum ieee802154_filter_type {
|
|||
|
||||
enum ieee802154_event {
|
||||
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 {
|
||||
|
@ -168,11 +169,45 @@ enum ieee802154_config_type {
|
|||
/** Sets the current MAC frame counter value for radios supporting transmit security. */
|
||||
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,
|
||||
|
||||
/** Enable CSL receiver (Endpoint) */
|
||||
IEEE802154_CONFIG_CSL_RECEIVER,
|
||||
/** Configure CSL receiver (Endpoint) period */
|
||||
IEEE802154_CONFIG_CSL_PERIOD,
|
||||
|
||||
/** Configure the next CSL receive window center, in units of microseconds,
|
||||
* based on the radio time.
|
||||
|
@ -235,11 +270,8 @@ struct ieee802154_config {
|
|||
uint32_t duration;
|
||||
} rx_slot;
|
||||
|
||||
/** ``IEEE802154_CONFIG_CSL_RECEIVER`` */
|
||||
struct {
|
||||
uint32_t period;
|
||||
const uint8_t *addr;
|
||||
} csl_recv;
|
||||
/** ``IEEE802154_CONFIG_CSL_PERIOD`` */
|
||||
uint32_t csl_period;
|
||||
|
||||
/** ``IEEE802154_CONFIG_CSL_RX_TIME`` */
|
||||
uint32_t csl_rx_time;
|
||||
|
@ -315,11 +347,11 @@ struct ieee802154_radio_api {
|
|||
uint64_t (*get_time)(const struct device *dev);
|
||||
|
||||
/** 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
|
||||
* 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
|
||||
|
|
|
@ -88,7 +88,13 @@ config OPENTHREAD_CSL_SAMPLE_WINDOW
|
|||
|
||||
config OPENTHREAD_CSL_RECEIVE_TIME_AHEAD
|
||||
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
|
||||
bool "Enable software transmission security logic"
|
||||
|
|
|
@ -22,6 +22,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
|||
#include <stdio.h>
|
||||
|
||||
#include "platform-zephyr.h"
|
||||
#include "openthread-core-zephyr-config.h"
|
||||
|
||||
static bool timer_ms_fired, timer_us_fired;
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@
|
|||
*
|
||||
*/
|
||||
#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))
|
||||
|
||||
/* 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
|
||||
* 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
|
||||
|
@ -291,6 +291,16 @@
|
|||
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
|
||||
*
|
||||
|
|
|
@ -60,11 +60,10 @@ enum pending_events {
|
|||
PENDING_EVENT_RX_FAILED, /* The RX failed */
|
||||
PENDING_EVENT_TX_STARTED, /* Radio has started transmitting */
|
||||
PENDING_EVENT_TX_DONE, /* Radio transmission finished */
|
||||
PENDING_EVENT_DETECT_ENERGY, /* Requested to start Energy Detection
|
||||
* procedure.
|
||||
*/
|
||||
PENDING_EVENT_DETECT_ENERGY_DONE, /* Energy Detection finished. */
|
||||
PENDING_EVENT_COUNT /* keep last */
|
||||
PENDING_EVENT_DETECT_ENERGY, /* Requested to start Energy Detection procedure */
|
||||
PENDING_EVENT_DETECT_ENERGY_DONE, /* Energy Detection finished */
|
||||
PENDING_EVENT_SLEEP, /* Sleep if idle */
|
||||
PENDING_EVENT_COUNT /* Keep last */
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case IEEE802154_EVENT_SLEEP:
|
||||
set_pending_event(PENDING_EVENT_SLEEP);
|
||||
break;
|
||||
default:
|
||||
/* do nothing - ignore event */
|
||||
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 */
|
||||
if (sState != OT_RADIO_STATE_TRANSMIT) {
|
||||
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_TRANSMIT) {
|
||||
error = OT_ERROR_NONE;
|
||||
if (radio_api->stop(radio_dev)) {
|
||||
sState = OT_RADIO_STATE_SLEEP;
|
||||
radio_api->stop(radio_dev);
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -1015,33 +1024,38 @@ void otPlatRadioSetMacFrameCounter(otInstance *aInstance,
|
|||
#endif
|
||||
|
||||
#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)
|
||||
{
|
||||
int result;
|
||||
uint8_t ie_header[OT_IE_HEADER_SIZE + OT_CSL_IE_SIZE];
|
||||
struct ieee802154_config config;
|
||||
|
||||
ARG_UNUSED(aInstance);
|
||||
|
||||
struct ieee802154_config config = {
|
||||
.csl_recv.period = aCslPeriod,
|
||||
.csl_recv.addr = aExtAddr->m8,
|
||||
};
|
||||
ie_header[0] = CSL_IE_HEADER_BYTES_LO;
|
||||
ie_header[1] = CSL_IE_HEADER_BYTES_HI;
|
||||
/* 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);
|
||||
config.csl_period = aCslPeriod;
|
||||
result += radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_PERIOD, &config);
|
||||
|
||||
return result ? OT_ERROR_FAILED : OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
void otPlatRadioUpdateCslSampleTime(otInstance *aInstance,
|
||||
uint32_t aCslSampleTime)
|
||||
void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime)
|
||||
{
|
||||
ARG_UNUSED(aInstance);
|
||||
|
||||
struct ieee802154_config config = { .csl_rx_time = aCslSampleTime };
|
||||
|
||||
(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RX_TIME,
|
||||
&config);
|
||||
(void)radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_RX_TIME, &config);
|
||||
}
|
||||
#endif /* CONFIG_OPENTHREAD_CSL_RECEIVER */
|
||||
|
||||
|
@ -1049,7 +1063,7 @@ uint8_t otPlatRadioGetCslAccuracy(otInstance *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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue