Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/ieee802154/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ zephyr_library_sources_ifdef(CONFIG_IEEE802154_NRF5 ieee802154_nrf5.c)
zephyr_library_sources_ifdef(CONFIG_IEEE802154_RF2XX ieee802154_rf2xx.c)
zephyr_library_sources_ifdef(CONFIG_IEEE802154_RF2XX ieee802154_rf2xx_iface.c)
zephyr_library_sources_ifdef(CONFIG_IEEE802154_TELINK_B91 ieee802154_b91.c)
zephyr_library_sources_ifdef(CONFIG_IEEE802154_OPENTHREAD_HOST_SPINEL ieee802154_ot_spinel.c)

if(CONFIG_SOC_CC1352R)
zephyr_library_compile_definitions("DeviceFamily_CC13X2")
Expand Down
2 changes: 2 additions & 0 deletions drivers/ieee802154/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ source "drivers/ieee802154/Kconfig.rf2xx"

source "drivers/ieee802154/Kconfig.dw1000"

source "drivers/ieee802154/Kconfig.ot_spinel"

menuconfig IEEE802154_UPIPE
bool "UART PIPE fake radio driver support for QEMU"
depends on (BOARD_QEMU_X86 || BOARD_QEMU_CORTEX_M3) && NETWORKING
Expand Down
18 changes: 18 additions & 0 deletions drivers/ieee802154/Kconfig.ot_spinel
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# OpenThread Host options

# Copyright (c) 2022, Basalte bv
# SPDX-License-Identifier: Apache-2.0

menuconfig IEEE802154_OPENTHREAD_HOST_SPINEL
bool "OpenThread Spinel driver"
depends on NET_L2_OPENTHREAD

if IEEE802154_OPENTHREAD_HOST_SPINEL

config IEEE802154_OPENTHREAD_HOST_SPINEL_DRV_NAME
string "OpenThread Spinel Driver's name"
default "IEEE802154_ot_spinel"
help
This option sets the driver name

endif
157 changes: 157 additions & 0 deletions drivers/ieee802154/ieee802154_ot_spinel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright (c) 2022, Basalte bv
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @file
* Dummy IEEE 802.15.4 interface driver. This is meant for network connectivity between
* a host and an RCP radio.
*/

#define LOG_MODULE_NAME ot_spinel
#define LOG_LEVEL CONFIG_NET_OPENTHREAD_HOST_LOG_LEVEL

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

#include <zephyr/kernel.h>

#include <stdbool.h>
#include <stddef.h>
#include <openthread/platform/radio.h>
#include <zephyr/net/openthread.h>
#include <zephyr/net/ieee802154_radio.h>

struct ot_spinel_context {
struct net_if *iface;
struct openthread_context *ot_context;
};

static void ot_spinel_iface_init(struct net_if *iface)
{
struct ot_spinel_context *ctx = net_if_get_device(iface)->data;
otExtAddress eui64;

ctx->iface = iface;

ieee802154_init(iface);

ctx->ot_context = net_if_l2_data(iface);

otPlatRadioGetIeeeEui64(ctx->ot_context->instance, eui64.m8);
net_if_set_link_addr(iface, eui64.m8, OT_EXT_ADDRESS_SIZE, NET_LINK_IEEE802154);
}

static enum ieee802154_hw_caps ot_spinel_get_capabilities(const struct device *dev)
{
ARG_UNUSED(dev);

return 0;
}

static int ot_spinel_cca(const struct device *dev)
{
ARG_UNUSED(dev);

return 0;
}

static int ot_spinel_set_channel(const struct device *dev, uint16_t channel)
{
ARG_UNUSED(dev);
ARG_UNUSED(channel);

return 0;
}

static int ot_spinel_filter(const struct device *dev,
bool set,
enum ieee802154_filter_type type,
const struct ieee802154_filter *filter)
{
ARG_UNUSED(dev);
ARG_UNUSED(set);
ARG_UNUSED(type);
ARG_UNUSED(filter);

return -ENOTSUP;
}

static int ot_spinel_set_txpower(const struct device *dev, int16_t dbm)
{
ARG_UNUSED(dev);
ARG_UNUSED(dbm);

return 0;
}

static int ot_spinel_tx(const struct device *dev,
enum ieee802154_tx_mode mode,
struct net_pkt *pkt,
struct net_buf *frag)
{
ARG_UNUSED(dev);
ARG_UNUSED(mode);
ARG_UNUSED(pkt);
ARG_UNUSED(frag);

return 0;
}

static int ot_spinel_start(const struct device *dev)
{
ARG_UNUSED(dev);

return 0;
}

static int ot_spinel_stop(const struct device *dev)
{
ARG_UNUSED(dev);

return 0;
}

static int ot_spinel_configure(const struct device *dev,
enum ieee802154_config_type type,
const struct ieee802154_config *config)
{
ARG_UNUSED(dev);
ARG_UNUSED(type);
ARG_UNUSED(config);

return 0;
}

static int ot_spinel_init(const struct device *dev)
{
ARG_UNUSED(dev);

return 0;
}

static struct ot_spinel_context ot_spinel_context_data;

static struct ieee802154_radio_api ot_spinel_if_api = {
.iface_api.init = ot_spinel_iface_init,

.get_capabilities = ot_spinel_get_capabilities,
.cca = ot_spinel_cca,
.set_channel = ot_spinel_set_channel,
.filter = ot_spinel_filter,
.set_txpower = ot_spinel_set_txpower,
.tx = ot_spinel_tx,
.start = ot_spinel_start,
.stop = ot_spinel_stop,
.configure = ot_spinel_configure,
Comment on lines +140 to +148
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are those dummy-implementations even needed, couldn't they be just NULL pointers? Noone should actaully call them as the radio layer for OT gets a custom implementation for this configuration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure how to add this file, but if the API isn't called from other subsystems, I can leave them as NULL. Isn't some shell command able to call these?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK they're not.

};

#define ot_spinel_MTU 1280

NET_DEVICE_INIT(ot_spinel, CONFIG_IEEE802154_OPENTHREAD_HOST_SPINEL_DRV_NAME,
ot_spinel_init, NULL, &ot_spinel_context_data, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &ot_spinel_if_api,
OPENTHREAD_L2, NET_L2_GET_CTX_TYPE(OPENTHREAD_L2),
ot_spinel_MTU);
10 changes: 8 additions & 2 deletions drivers/spi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,16 @@ config SPI_EXTENDED_MODES
it would require more features exposed into the SPI buffer.

config SPI_INIT_PRIORITY
int "Init priority"
int "Controller init priority"
default 70
help
Device driver initialization priority.
Controller driver initialization priority.

config SPI_INIT_PRIORITY_DEVICE
int "Device init priority"
default 71
help
Peripheral Device driver initialization priority.

config SPI_COMPLETION_TIMEOUT_TOLERANCE
int "Completion timeout tolerance (ms)"
Expand Down
42 changes: 42 additions & 0 deletions dts/bindings/misc/google,openthread-spinel.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) 2022, Basalte bv
# SPDX-License-Identifier: Apache-2.0

description: Virtual device to communicate with RCP using Spinel

compatible: "google,openthread-spinel"

include: spi-device.yaml

properties:
irq-gpios:
type: phandle-array
required: false
description: Interrupt pin

Optional interript pin asserted by the RCP
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Optional interript pin asserted by the RCP
Optional interrupt pin asserted by the RCP

radio device on data ready.

reset-gpios:
type: phandle-array
required: false
description: RESET pin

The RESET pin of the RCP radio device.

reset-time:
type: int
required: false
default: 1
description: The duration (in ms) for the RCP radio reset.

startup-time:
type: int
required: false
default: 0
description: The duration (in ms) for the RCP radio startup.

cs-delay:
type: int
required: false
default: 0
description: The delay (in ms) for the RCP radio chip select.
24 changes: 23 additions & 1 deletion modules/openthread/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ if(CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE)
set(OT_NCP_VENDOR_HOOK_SOURCE ${CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE} CACHE STRING "NCP vendor hook source file name" FORCE)
endif()

if(CONFIG_OPENTHREAD_HOSTPROCESSOR_SPINEL_RCP_RESTORATION_MAX_COUNT)
set(OT_RCP_RESTORATION_MAX_COUNT
"${CONFIG_OPENTHREAD_HOSTPROCESSOR_SPINEL_RCP_RESTORATION_MAX_COUNT}" CACHE STRING "set max RCP restoration count" FORCE)
endif()

# Zephyr logging options

if(CONFIG_LOG_BACKEND_SPINEL)
Expand Down Expand Up @@ -457,7 +462,7 @@ if(CONFIG_OPENTHREAD_COPROCESSOR_RCP)
list(APPEND ot_libs openthread-rcp)
endif()

if(CONFIG_OPENTHREAD_COPROCESSOR_NCP)
if(CONFIG_OPENTHREAD_COPROCESSOR_NCP OR CONFIG_OPENTHREAD_HOSTPROCESSOR)
if(CONFIG_OPENTHREAD_FTD)
list(APPEND ot_libs openthread-ncp-ftd)
elseif(CONFIG_OPENTHREAD_MTD)
Expand All @@ -481,6 +486,23 @@ if(CONFIG_OPENTHREAD_SETTINGS_RAM)
list(APPEND ot_libs openthread-platform-utils-static)
endif()

if(CONFIG_OPENTHREAD_HOSTPROCESSOR)
# Inject our platform spinel implementation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on why is it needed to inject those sources into OT libs, why can't it end up in the openthread_platform library with other platform files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OpenThread build system has private compile definitions for each library. This was the easiest way to make sure exactly the same definitions are set.
Because of the C++ template for the RadioSpinel instance, which is header-only.

set(ot_host_sources ${ZEPHYR_BASE}/subsys/net/lib/openthread/platform/radio_spinel.cpp)

if(CONFIG_OPENTHREAD_HOSTPROCESSOR_SPI)
list(APPEND ot_host_sources ${ZEPHYR_BASE}/subsys/net/lib/openthread/platform/spi_interface.cpp)
endif()

if(CONFIG_OPENTHREAD_FTD)
target_sources(openthread-ncp-ftd PRIVATE ${ot_host_sources})
elseif(CONFIG_OPENTHREAD_MTD)
target_sources(openthread-ncp-mtd PRIVATE ${ot_host_sources})
endif()

list(APPEND ot_libs openthread-platform)
endif()

zephyr_link_libraries(${ot_libs})

endif()
50 changes: 50 additions & 0 deletions subsys/net/l2/openthread/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,56 @@ config OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE

endif # OPENTHREAD_COPROCESSOR

config OPENTHREAD_HOSTPROCESSOR
bool "OpenThread Host-Processor"
depends on !OPENTHREAD_COPROCESSOR
select IEEE802154_OPENTHREAD_HOST_SPINEL
help
Enable Host-Processor in OpenThread stack.

if OPENTHREAD_HOSTPROCESSOR

choice
prompt "OpenThread Host-Processor transport type"
default OPENTHREAD_HOSTPROCESSOR_SPI
help
This option selects OpenThread network Host-Processor transport type

config OPENTHREAD_HOSTPROCESSOR_SPI
bool "SPI"
select SPI
select GPIO

endchoice

if OPENTHREAD_HOSTPROCESSOR_SPI

config OPENTHREAD_HOSTPROCESSOR_SPI_SMALL_PACKET_SIZE
int "Set smallest SPI packet size"
default 32
help
Smallest SPI packet size we can receive in a single transaction.

config OPENTHREAD_HOSTPROCESSOR_SPI_ALIGN_ALLOWANCE
int "Set SPI start alignment allowance"
default 16
help
Maximum number of 0xFF bytes to clip from start of MISO frame.

endif # OPENTHREAD_HOSTPROCESSOR_SPI

config OPENTHREAD_HOSTPROCESSOR_RESET_RADIO
bool "Reset Radio"
help
Reset the OpenThread Co-Processor Radio on init.

config OPENTHREAD_HOSTPROCESSOR_SPINEL_RCP_RESTORATION_MAX_COUNT
int "Set RCP max restoration count"
help
On RCP failure the maximum amount of restoration attempts.

endif # OPENTHREAD_HOSTPROCESSOR

config OPENTHREAD_PLATFORM_INFO
string "Platform information for OpenThread"
default "ZEPHYR"
Expand Down
7 changes: 7 additions & 0 deletions subsys/net/l2/openthread/openthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ extern void platformShellInit(otInstance *aInstance);

K_KERNEL_STACK_DEFINE(ot_stack_area, OT_STACK_SIZE);

#ifndef CONFIG_OPENTHREAD_HOSTPROCESSOR
static struct net_linkaddr *ll_addr;
#endif

static otStateChangedCallback state_changed_cb;

k_tid_t openthread_thread_id_get(void)
Expand Down Expand Up @@ -151,12 +154,14 @@ static int ncp_hdlc_send(const uint8_t *buf, uint16_t len)
return len;
}

#ifndef CONFIG_OPENTHREAD_HOSTPROCESSOR
void otPlatRadioGetIeeeEui64(otInstance *instance, uint8_t *ieee_eui64)
{
ARG_UNUSED(instance);

memcpy(ieee_eui64, ll_addr->addr, ll_addr->len);
}
#endif

void otTaskletsSignalPending(otInstance *instance)
{
Expand Down Expand Up @@ -485,7 +490,9 @@ static int openthread_init(struct net_if *iface)
k_mutex_init(&ot_context->api_lock);
k_work_init(&ot_context->api_work, openthread_process);

#ifndef CONFIG_OPENTHREAD_HOSTPROCESSOR
ll_addr = net_if_get_link_addr(iface);
#endif

openthread_api_mutex_lock(ot_context);

Expand Down
Loading