Skip to content

Commit

Permalink
Merge branch 'feature/openthread-port-spinel-interface' into 'master'
Browse files Browse the repository at this point in the history
openthread: add SPI support in Radio Co-Processor

See merge request espressif/esp-idf!22368
  • Loading branch information
chshu committed Apr 6, 2023
2 parents f14e71f + 5a1578e commit c0097c1
Show file tree
Hide file tree
Showing 20 changed files with 811 additions and 56 deletions.
12 changes: 7 additions & 5 deletions components/openthread/CMakeLists.txt
Expand Up @@ -111,9 +111,11 @@ if(CONFIG_OPENTHREAD_ENABLED)

if(CONFIG_OPENTHREAD_RADIO_NATIVE)
list(APPEND exclude_srcs
"port/esp_openthread_radio_uart.cpp"
"port/esp_uart_spinel_interface.cpp")
elseif(CONFIG_OPENTHREAD_RADIO_SPINEL_UART)
"port/esp_openthread_radio_spinel.cpp"
"port/esp_spi_spinel_interface.cpp"
"port/esp_uart_spinel_interface.cpp"
)
elseif(CONFIG_OPENTHREAD_RADIO_SPINEL_UART OR CONFIG_OPENTHREAD_RADIO_SPINEL_SPI)
list(APPEND exclude_srcs
"port/esp_openthread_radio.c")
endif()
Expand Down Expand Up @@ -166,9 +168,9 @@ idf_component_register(SRC_DIRS "${src_dirs}"
EXCLUDE_SRCS "${exclude_srcs}"
INCLUDE_DIRS "${public_include_dirs}"
PRIV_INCLUDE_DIRS "${private_include_dirs}"
REQUIRES esp_netif lwip
REQUIRES esp_netif lwip driver
LDFRAGMENTS linker.lf
PRIV_REQUIRES console driver esp_event esp_partition esp_timer
PRIV_REQUIRES console esp_event esp_partition esp_timer
ieee802154 mbedtls spi_flash)

if(CONFIG_OPENTHREAD_ENABLED)
Expand Down
22 changes: 22 additions & 0 deletions components/openthread/Kconfig
Expand Up @@ -61,6 +61,12 @@ menu "OpenThread"
bool "Connect via UART"
help
Select this to connect to a Radio Co-Processor via UART.

config OPENTHREAD_RADIO_SPINEL_SPI
bool "Connect via SPI"
help
Select this to connect to a Radio Co-Processor via SPI.

endchoice

choice OPENTHREAD_DEVICE_TYPE
Expand Down Expand Up @@ -89,6 +95,22 @@ menu "OpenThread"
radio only device.
endchoice

choice OPENTHREAD_RCP_TRANSPORT
prompt "The RCP transport type"
depends on OPENTHREAD_RADIO
default OPENTHREAD_RCP_UART

config OPENTHREAD_RCP_UART
bool "UART RCP"
help
Select this to enable UART connection to host.

config OPENTHREAD_RCP_SPI
bool "SPI RCP"
help
Select this to enable SPI connection to host.
endchoice

config OPENTHREAD_CLI
bool "Enable Openthread Command-Line Interface"
depends on OPENTHREAD_ENABLED
Expand Down
44 changes: 39 additions & 5 deletions components/openthread/include/esp_openthread_types.h
Expand Up @@ -11,6 +11,10 @@
#include <sys/select.h>

#include "esp_event_base.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "driver/spi_slave.h"
#include "hal/gpio_types.h"
#include "hal/uart_types.h"

#ifdef __cplusplus
Expand Down Expand Up @@ -60,10 +64,33 @@ typedef struct {
typedef struct {
uart_port_t port; /*!< UART port number */
uart_config_t uart_config; /*!< UART configuration, see uart_config_t docs */
int rx_pin; /*!< UART RX pin */
int tx_pin; /*!< UART TX pin */
gpio_num_t rx_pin; /*!< UART RX pin */
gpio_num_t tx_pin; /*!< UART TX pin */
} esp_openthread_uart_config_t;

/**
* @brief The spi port config for OpenThread.
*
*/
typedef struct {
spi_host_device_t host_device; /*!< SPI host device */
spi_dma_chan_t dma_channel; /*!< DMA channel */
spi_bus_config_t spi_interface; /*!< SPI bus */
spi_device_interface_config_t spi_device; /*!< SPI peripheral device */
gpio_num_t intr_pin; /*!< SPI interrupt pin */
} esp_openthread_spi_host_config_t;

/**
* @brief The spi slave config for OpenThread.
*
*/
typedef struct {
spi_host_device_t host_device; /*!< SPI host device */
spi_bus_config_t bus_config; /*!< SPI bus config */
spi_slave_interface_config_t slave_config; /*!< SPI slave config */
gpio_num_t intr_pin; /*!< SPI interrupt pin */
} esp_openthread_spi_slave_config_t;

/**
* @brief The radio mode of OpenThread.
*
Expand All @@ -82,15 +109,19 @@ typedef enum {
HOST_CONNECTION_MODE_NONE = 0x0, /*!< Disable host connection */
HOST_CONNECTION_MODE_CLI_UART = 0x1, /*!< CLI UART connection to the host */
HOST_CONNECTION_MODE_RCP_UART = 0x2, /*!< RCP UART connection to the host */
HOST_CONNECTION_MODE_RCP_SPI = 0x3, /*!< RCP SPI connection to the host */
} esp_openthread_host_connection_mode_t;

/**
* @brief The OpenThread radio configuration
*
*/
typedef struct {
esp_openthread_radio_mode_t radio_mode; /*!< The radio mode */
esp_openthread_uart_config_t radio_uart_config; /*!< The uart configuration to RCP */
esp_openthread_radio_mode_t radio_mode; /*!< The radio mode */
union {
esp_openthread_uart_config_t radio_uart_config; /*!< The uart configuration to RCP */
esp_openthread_spi_host_config_t radio_spi_config; /*!< The spi configuration to RCP */
};
} esp_openthread_radio_config_t;

/**
Expand All @@ -99,7 +130,10 @@ typedef struct {
*/
typedef struct {
esp_openthread_host_connection_mode_t host_connection_mode; /*!< The host connection mode */
esp_openthread_uart_config_t host_uart_config; /*!< The uart configuration to host */
union {
esp_openthread_uart_config_t host_uart_config; /*!< The uart configuration to host */
esp_openthread_spi_slave_config_t spi_slave_config; /*!< The spi configuration to host */
};
} esp_openthread_host_connection_config_t;

/**
Expand Down
3 changes: 3 additions & 0 deletions components/openthread/linker.lf
Expand Up @@ -8,3 +8,6 @@ entries:
link_metrics (noflash_text)
mac (noflash_text)
sub_mac (noflash_text)

if OPENTHREAD_RCP_SPI = y:
ncp_spi (noflash_text)
28 changes: 22 additions & 6 deletions components/openthread/port/esp_openthread_platform.cpp
Expand Up @@ -14,6 +14,7 @@
#include "esp_openthread_flash.h"
#include "esp_openthread_lock.h"
#include "esp_openthread_radio.h"
#include "esp_openthread_spi_slave.h"
#include "esp_openthread_task_queue.h"
#include "esp_openthread_types.h"
#include "esp_openthread_uart.h"
Expand Down Expand Up @@ -87,30 +88,40 @@ void esp_openthread_platform_workflow_unregister(const char *name)
esp_err_t esp_openthread_platform_init(const esp_openthread_platform_config_t *config)
{
ESP_RETURN_ON_FALSE(config->radio_config.radio_mode == RADIO_MODE_NATIVE ||
config->radio_config.radio_mode == RADIO_MODE_UART_RCP,
config->radio_config.radio_mode == RADIO_MODE_UART_RCP ||
config->radio_config.radio_mode == RADIO_MODE_SPI_RCP,
ESP_ERR_INVALID_ARG, OT_PLAT_LOG_TAG, "Radio mode not supported");
ESP_RETURN_ON_FALSE(config->host_config.host_connection_mode == HOST_CONNECTION_MODE_NONE ||
config->host_config.host_connection_mode == HOST_CONNECTION_MODE_CLI_UART ||
config->host_config.host_connection_mode == HOST_CONNECTION_MODE_RCP_UART,
config->host_config.host_connection_mode == HOST_CONNECTION_MODE_RCP_UART ||
config->host_config.host_connection_mode == HOST_CONNECTION_MODE_RCP_SPI,
ESP_ERR_INVALID_ARG, OT_PLAT_LOG_TAG, "Host connection mode not supported");
ESP_RETURN_ON_FALSE(!s_openthread_platform_initialized, ESP_ERR_INVALID_STATE, OT_PLAT_LOG_TAG,
"OpenThread platform already initialized");

s_openthread_platform_initialized = true;
esp_err_t ret = ESP_OK;

/* Avoid to compile flash in RADIO type device */
#if !CONFIG_OPENTHREAD_RADIO
const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY,
config->port_config.storage_partition_name);

ESP_RETURN_ON_FALSE(partition, ESP_ERR_INVALID_ARG, OT_PLAT_LOG_TAG, "OpenThread storage partition not found");
esp_openthread_flash_set_partition(partition);
#endif

s_platform_config = *config;
esp_openthread_flash_set_partition(partition);
ESP_GOTO_ON_ERROR(esp_openthread_lock_init(), exit, OT_PLAT_LOG_TAG, "esp_openthread_lock_init failed");
ESP_GOTO_ON_ERROR(esp_openthread_alarm_init(), exit, OT_PLAT_LOG_TAG, "esp_openthread_alarm_init failed");
if (config->host_config.host_connection_mode == HOST_CONNECTION_MODE_CLI_UART ||

if (config->host_config.host_connection_mode == HOST_CONNECTION_MODE_RCP_SPI) {
ESP_GOTO_ON_ERROR(esp_openthread_spi_slave_init(config), exit, OT_PLAT_LOG_TAG,
"esp_openthread_spi_slave_init failed");
}else if (config->host_config.host_connection_mode == HOST_CONNECTION_MODE_CLI_UART ||
config->host_config.host_connection_mode == HOST_CONNECTION_MODE_RCP_UART) {
ESP_GOTO_ON_ERROR(esp_openthread_uart_init(config), exit, OT_PLAT_LOG_TAG, "esp_openthread_uart_init failed");
}

ESP_GOTO_ON_ERROR(esp_openthread_task_queue_init(config), exit, OT_PLAT_LOG_TAG,
"esp_openthread_task_queue_init failed");
ESP_GOTO_ON_ERROR(esp_openthread_radio_init(config), exit, OT_PLAT_LOG_TAG, "esp_openthread_radio_init failed");
Expand All @@ -135,9 +146,14 @@ esp_err_t esp_openthread_platform_deinit(void)
s_openthread_platform_initialized = false;
esp_openthread_task_queue_deinit();
esp_openthread_radio_deinit();
if (s_platform_config.host_config.host_connection_mode == HOST_CONNECTION_MODE_CLI_UART) {

if (s_platform_config.host_config.host_connection_mode == HOST_CONNECTION_MODE_RCP_SPI){
esp_openthread_spi_slave_deinit();
}else if (s_platform_config.host_config.host_connection_mode == HOST_CONNECTION_MODE_CLI_UART ||
s_platform_config.host_config.host_connection_mode == HOST_CONNECTION_MODE_RCP_UART) {
esp_openthread_uart_deinit();
}

esp_openthread_lock_deinit();
esp_openthread_alarm_deinit();
return ESP_OK;
Expand Down
9 changes: 9 additions & 0 deletions components/openthread/port/esp_openthread_radio.c
Expand Up @@ -736,3 +736,12 @@ otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)

return OT_ERROR_NONE;
}

otError otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aChannel, int8_t aMaxPower)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aChannel);
OT_UNUSED_VARIABLE(aMaxPower);

return OT_ERROR_NONE;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -13,26 +13,38 @@
#include "esp_openthread_platform.h"
#include "esp_openthread_types.h"
#include "esp_system.h"
#include "esp_spi_spinel_interface.hpp"
#include "esp_uart_spinel_interface.hpp"
#include "openthread-core-config.h"
#include "lib/spinel/radio_spinel.hpp"
#include "lib/spinel/spinel.h"
#include "openthread/platform/diag.h"
#include "openthread/platform/radio.h"

using esp::openthread::UartSpinelInterface;
using ot::Spinel::RadioSpinel;

#if CONFIG_OPENTHREAD_RADIO_SPINEL_UART
using esp::openthread::UartSpinelInterface;
static RadioSpinel<UartSpinelInterface, esp_openthread_mainloop_context_t> s_radio;
static const char *radiouart_workflow = "radio_uart";
#else // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
using esp::openthread::SpiSpinelInterface;
static RadioSpinel<SpiSpinelInterface, esp_openthread_mainloop_context_t> s_radio;
#endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART

static const char *radiospinel_workflow = "radio_spinel";

esp_err_t esp_openthread_radio_init(const esp_openthread_platform_config_t *config)
{
#if CONFIG_OPENTHREAD_RADIO_SPINEL_UART
ESP_RETURN_ON_ERROR(s_radio.GetSpinelInterface().Init(config->radio_config.radio_uart_config), OT_PLAT_LOG_TAG,
"Spinel interface init falied");
#else // CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
ESP_RETURN_ON_ERROR(s_radio.GetSpinelInterface().Init(config->radio_config.radio_spi_config), OT_PLAT_LOG_TAG,
"Spinel interface init failed");
#endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART
s_radio.Init(/*reset_radio=*/true, /*restore_dataset_from_ncp=*/false, /*skip_rcp_compatibility_check=*/false);
return esp_openthread_platform_workflow_register(&esp_openthread_radio_update, &esp_openthread_radio_process,
radiouart_workflow);
radiospinel_workflow);
}

void esp_openthread_register_rcp_failure_handler(esp_openthread_rcp_failure_handler handler)
Expand All @@ -48,7 +60,7 @@ void esp_openthread_rcp_deinit(void)
void esp_openthread_radio_deinit(void)
{
s_radio.Deinit();
esp_openthread_platform_workflow_unregister(radiouart_workflow);
esp_openthread_platform_workflow_unregister(radiospinel_workflow);
}

esp_err_t esp_openthread_radio_process(otInstance *instance, const esp_openthread_mainloop_context_t *mainloop)
Expand Down

0 comments on commit c0097c1

Please sign in to comment.