Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Thread BR example for ESP32 #34043

Merged
merged 7 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
7 changes: 7 additions & 0 deletions config/esp32/components/chip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,13 @@ if(NOT CONFIG_USE_MINIMAL_MDNS)
endif()
endif()

if(CONFIG_OPENTHREAD_BORDER_ROUTER)
idf_component_get_property(rcp_update_lib espressif__esp_rcp_update COMPONENT_LIB)
list(APPEND chip_libraries $<TARGET_FILE:${rcp_update_lib}>)
idf_component_get_property(serial_flasher_lib espressif__esp-serial-flasher COMPONENT_LIB)
list(APPEND chip_libraries $<TARGET_FILE:${serial_flasher_lib}>)
endif()

if (CONFIG_ENABLE_ENCRYPTED_OTA)
idf_component_get_property(esp_encrypted_img_lib espressif__esp_encrypted_img COMPONENT_LIB)
list(APPEND chip_libraries $<TARGET_FILE:${esp_encrypted_img_lib}>)
Expand Down
5 changes: 5 additions & 0 deletions config/esp32/components/chip/idf_component.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@ dependencies:
rules:
- if: "idf_version >=5.0"
- if: "target != esp32h2"

espressif/esp_rcp_update:
version: "1.0.3"
rules:
- if: "idf_version >=5.0"
9 changes: 9 additions & 0 deletions docs/examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,12 @@ network-manager-app/README

lit-icd-app/**/README
```

## Thread Border Router example

```{toctree}
:glob:
:maxdepth: 1

thread-br-app/**/README
```
4 changes: 2 additions & 2 deletions docs/guides/esp32/build_app_and_commission.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ $ out/debug/chip-tool pairing ble-wifi 12345 MY_SSID MY_PASSWORD 20202021 3840
#### Commissioning the Thread device (ESP32H2)

- For ESP32-H2, firstly start OpenThread Border Router, you can either use
[Raspberry Pi OpenThread Border Router](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/openthread_border_router_pi.md)
[Raspberry Pi OpenThread Border Router](../openthread_border_router_pi.md)
OR
[ESP32 OpenThread Border Router](https://github.com/espressif/esp-idf/tree/master/examples/openthread/ot_br)
[ESP32 OpenThread Border Router](../../../examples/thread-br-app/esp32/README.md)

- Get the active operational dataset.

Expand Down
8 changes: 8 additions & 0 deletions examples/platform/esp32/common/CommonDeviceCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ void CommonDeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, i
// newly selected address.
chip::app::DnssdServer::Instance().StartServer();
}
if (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned)
{
appDelegate = DeviceCallbacksDelegate::Instance().GetAppDelegate();
if (appDelegate != nullptr)
{
appDelegate->OnIPv6ConnectivityEstablished();
}
}
break;
}

Expand Down
1 change: 1 addition & 0 deletions examples/platform/esp32/common/CommonDeviceCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class DeviceCallbacksDelegate
virtual void OnIPv4ConnectivityEstablished() {}
virtual void OnIPv4ConnectivityLost() {}
virtual void OnDnssdInitialized() {}
virtual void OnIPv6ConnectivityEstablished() {}
DeviceCallbacksDelegate * mDelegate = nullptr;
void SetAppDelegate(DeviceCallbacksDelegate * delegate) { mDelegate = delegate; }
DeviceCallbacksDelegate * GetAppDelegate() { return mDelegate; }
Expand Down
5 changes: 3 additions & 2 deletions examples/platform/esp32/common/Esp32AppServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ using namespace chip::DeviceLayer;
static constexpr char TAG[] = "ESP32Appserver";

namespace {

#if CONFIG_TEST_EVENT_TRIGGER_ENABLED
static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
Expand Down Expand Up @@ -103,8 +102,10 @@ static size_t hex_string_to_binary(const char * hex_string, uint8_t * buf, size_
void Esp32AppServer::DeInitBLEIfCommissioned(void)
{
#ifdef CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING
if (chip::Server::GetInstance().GetFabricTable().FabricCount() > 0)
static bool bleAlreadyShutdown = false;
if (chip::Server::GetInstance().GetFabricTable().FabricCount() > 0 && (!bleAlreadyShutdown))
{
bleAlreadyShutdown = true;
chip::DeviceLayer::Internal::BLEMgr().Shutdown();
}
#endif /* CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING */
Expand Down
15 changes: 15 additions & 0 deletions examples/platform/esp32/common/Esp32ThreadInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include <platform/ESP32/OpenthreadLauncher.h>
#include <platform/ThreadStackManager.h>
#endif // CONFIG_OPENTHREAD_ENABLED
#ifdef CONFIG_OPENTHREAD_BORDER_ROUTER
#include <esp_spiffs.h>
#endif

#include <esp_log.h>
#if CONFIG_PM_ENABLE
Expand All @@ -39,6 +42,18 @@ void ESPOpenThreadInit()
.host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(),
.port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(),
};
#ifdef CONFIG_OPENTHREAD_BORDER_ROUTER
esp_vfs_spiffs_conf_t rcp_fw_conf = {
.base_path = "/rcp_fw", .partition_label = "rcp_fw", .max_files = 10, .format_if_mount_failed = false
};
if (ESP_OK != esp_vfs_spiffs_register(&rcp_fw_conf))
{
ESP_LOGE(TAG, "Failed to mount rcp firmware storage");
return;
}
esp_rcp_update_config_t rcp_update_config = ESP_OPENTHREAD_RCP_UPDATE_CONFIG();
openthread_init_br_rcp(&rcp_update_config);
#endif // CONFIG_OPENTHREAD_BORDER_ROUTER
set_openthread_platform_config(&config);

if (ThreadStackMgr().InitThreadStack() != CHIP_NO_ERROR)
Expand Down
59 changes: 59 additions & 0 deletions examples/platform/esp32/common/Esp32ThreadInit.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,57 @@
#if CONFIG_OPENTHREAD_ENABLED
#include "esp_openthread_types.h"

#if CONFIG_OPENTHREAD_RADIO_NATIVE
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
{ \
.radio_mode = RADIO_MODE_NATIVE, \
}
#elif CONFIG_OPENTHREAD_RADIO_SPINEL_UART
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
{ \
.radio_mode = RADIO_MODE_UART_RCP, \
.radio_uart_config = { \
.port = UART_NUM_1, \
.uart_config = \
{ \
.baud_rate = 460800, \
.data_bits = UART_DATA_8_BITS, \
.parity = UART_PARITY_DISABLE, \
.stop_bits = UART_STOP_BITS_1, \
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \
.rx_flow_ctrl_thresh = 0, \
.source_clk = UART_SCLK_DEFAULT, \
}, \
.rx_pin = GPIO_NUM_17, \
.tx_pin = GPIO_NUM_18, \
}, \
}
#else
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
{ \
.radio_mode = RADIO_MODE_SPI_RCP, \
.radio_spi_config = { \
.host_device = SPI2_HOST, \
.dma_channel = 2, \
.spi_interface = \
{ \
.mosi_io_num = 11, \
.sclk_io_num = 12, \
.miso_io_num = 13, \
}, \
.spi_device = \
{ \
.cs_ena_pretrans = 2, \
.input_delay_ns = 100, \
.mode = 0, \
.clock_speed_hz = 2500 * 1000, \
.spics_io_num = 10, \
.queue_size = 5, \
}, \
.intr_pin = 8, \
}, \
}
#endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART OR CONFIG_OPENTHREAD_RADIO_SPINEL_SPI

#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
{ \
Expand All @@ -36,6 +83,18 @@
{ \
.storage_partition_name = "nvs", .netif_queue_size = 10, .task_queue_size = 10, \
}

#ifdef CONFIG_OPENTHREAD_BORDER_ROUTER
#include <esp_rcp_update.h>
#define RCP_FIRMWARE_DIR "/spiffs/ot_rcp"

#define ESP_OPENTHREAD_RCP_UPDATE_CONFIG() \
{ \
.rcp_type = RCP_TYPE_ESP32H2_UART, .uart_rx_pin = 17, .uart_tx_pin = 18, .uart_port = 1, .uart_baudrate = 115200, \
.reset_pin = 7, .boot_pin = 8, .update_baudrate = 460800, .firmware_dir = "/rcp_fw/ot_rcp", .target_chip = ESP32H2_CHIP, \
}
#endif // CONFIG_OPENTHREAD_BORDER_ROUTER

#endif // CONFIG_OPENTHREAD_ENABLED

void ESPOpenThreadInit();
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ declare_args() {
chip_bt_bluedroid_enabled = true
chip_max_discovered_ip_addresses = 5
chip_enable_route_hook = false
chip_enable_thread_border_router = false
}

buildconfig_header("custom_buildconfig") {
Expand Down
5 changes: 5 additions & 0 deletions examples/thread-br-app/esp32/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.vscode

/build/
/sdkconfig
/sdkconfig.old
49 changes: 49 additions & 0 deletions examples/thread-br-app/esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#
# Copyright (c) 2021 Project CHIP Authors
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

set(PROJECT_VER "v1.0")
set(PROJECT_VER_NUMBER 1)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/../../common/cmake/idf_flashing.cmake)

set(EXTRA_COMPONENT_DIRS
"${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/config/esp32/components"
)

project(chip-thread-br-app)

# C++17 is required for RPC build.
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DCHIP_HAVE_CONFIG_H" APPEND)
idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND)
# For the C3, project_include.cmake sets -Wno-format, but does not clear various
# flags that depend on -Wformat
idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND)

# We don't need Thread Network Commissioning Driver
idf_build_set_property(COMPILE_OPTIONS "-D_NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_" APPEND)

# -Wmaybe-uninitialized has too many false positives, including on std::optional
# and chip::Optional. Make it nonfatal.
#
# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635
idf_build_set_property(COMPILE_OPTIONS "-Wno-error=maybe-uninitialized" APPEND)

flashing_script()
94 changes: 94 additions & 0 deletions examples/thread-br-app/esp32/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Matter ESP32 Thread Border Router Example

A prototype application that demonstrates OpenThread Border Router on ESP32-S3 +
ESP32-H2 Thread Border Router DevKit Board.

Please
[setup ESP-IDF and CHIP Environment](../../../docs/guides/esp32/setup_idf_chip.md)
and refer
[building and commissioning](../../../docs/guides/esp32/build_app_and_commission.md)
guides to get started.

---

- [OpenThread Border Router Board](#openthread-border-router-board)
- [OpenThread RCP](#openthread-rcp)
- [OpenThread CLI](#openthread-cli)
- [Setup Thread Network](#setup-thread-network)
- [Commissioning Thread End Devices](#commissioning-thread-end-devices)

---

### OpenThread Border Router Board

The ESP Thread border router board provides an integrated module of an ESP32-S3
and an ESP32-H2.

![Border Router Board](image/esp-thread-border-router-board.png)

### OpenThread RCP

We need to build an OpenThread RCP(Radio Co-Processor) firmware for ESP32-H2 of
the Border Router Board before building this Thread Border example.

```
cd $IDF_PATH/examples/openthread/ot_rcp
idf.py set-target esp32h2
idf.py build
```

Then we need to connect the USB2 port(ESP32-S3) of the Border Router Board to
your host machine. Build and flash this example.

```
cd ${CHIP_ROOT}/examples/thread-br-app/esp32
idf.py set-target esp32s3
idf.py build
idf.py -p {port} erase-flash flash monitor
```

This example will detect the RCP firmware built in ESP-IDF path and flash it to
the spiffs partition. When starting this example, the ESP32-S3 will compare the
versions of both the RCP firmware in the spiffs partition and the firmware on
ESP32-H2. if the spiffs RCP firmware is newer than the firmware on ESP32-H2, the
Thread BR will flash the RCP firmware to ESP32-H2 automatically.

### OpenThread CLI

After you build this example and flash it to the ESP32-S3 of Border Router
Board, you can access a standard OpenThread CLI via the device console with a
`matter otcli` prefix.

For instance, you can get the state:

```
> matter otcli state
Detached
Done
```

### Setup Thread Network

You can send SetActiveDatasetRequest command to the Thread BR after
commissioning it as a Matter-Over-Wi-Fi device to setup the Thread network or
join an existing Thread network.

```
./chip-tool pairing ble-wifi 1 <ssid> <password> 20202021 3840
./chip-tool generalcommissioning arm-fail-safe 180 1 1 0
./chip-tool threadborderroutermanagement set-active-dataset-request hex:<dataset-tlvs> 1 1 1
./chip-tool generalcommissioning commissioning-complete 1 0
```

The Thread BR with enable the Thread network interface and start Thread network
after it receives SetActiveDatasetRequest command. And after the Thread BR sets
up or join a Thread network, it will send the success response.

### Commissioning Thread End Devices

After setting up the Thread network, you can commission a Thread End-device to
the Thread network.

```
./chip-tool pairing ble-wifi 2 hex:<dataset_tlvs> <pincode> <discriminator>
```
Loading
Loading