Skip to content

Commit

Permalink
Add Thread BR example for ESP32 (project-chip#34043)
Browse files Browse the repository at this point in the history
* Add thread br app for ESP32

* add README to a toctree

* zap regenerate

* fix CI

* add pendingdatasettimestamp attribute and run zap_regenerate
  • Loading branch information
wqx6 authored and austina-csa committed Aug 12, 2024
1 parent 28b8724 commit d0923b8
Show file tree
Hide file tree
Showing 28 changed files with 5,671 additions and 9 deletions.
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

0 comments on commit d0923b8

Please sign in to comment.