Skip to content

Commit 68c15fc

Browse files
committed
Add thread br app for ESP32
1 parent 08dfc13 commit 68c15fc

26 files changed

+5401
-7
lines changed

config/esp32/components/chip/CMakeLists.txt

+7
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,13 @@ if(NOT CONFIG_USE_MINIMAL_MDNS)
467467
endif()
468468
endif()
469469

470+
if(CONFIG_OPENTHREAD_BORDER_ROUTER)
471+
idf_component_get_property(rcp_update_lib espressif__esp_rcp_update COMPONENT_LIB)
472+
list(APPEND chip_libraries $<TARGET_FILE:${rcp_update_lib}>)
473+
idf_component_get_property(serial_flasher_lib espressif__esp-serial-flasher COMPONENT_LIB)
474+
list(APPEND chip_libraries $<TARGET_FILE:${serial_flasher_lib}>)
475+
endif()
476+
470477
if (CONFIG_ENABLE_ENCRYPTED_OTA)
471478
idf_component_get_property(esp_encrypted_img_lib espressif__esp_encrypted_img COMPONENT_LIB)
472479
list(APPEND chip_libraries $<TARGET_FILE:${esp_encrypted_img_lib}>)

config/esp32/components/chip/idf_component.yml

+5
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ dependencies:
2525
rules:
2626
- if: "idf_version >=5.0"
2727
- if: "target != esp32h2"
28+
29+
espressif/esp_rcp_update:
30+
version: "1.0.3"
31+
rules:
32+
- if: "idf_version >=5.0"

examples/platform/esp32/common/CommonDeviceCallbacks.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ void CommonDeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, i
8484
// newly selected address.
8585
chip::app::DnssdServer::Instance().StartServer();
8686
}
87+
if (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned)
88+
{
89+
appDelegate = DeviceCallbacksDelegate::Instance().GetAppDelegate();
90+
if (appDelegate != nullptr)
91+
{
92+
appDelegate->OnIPv6ConnectivityEstablished();
93+
}
94+
}
8795
break;
8896
}
8997

examples/platform/esp32/common/CommonDeviceCallbacks.h

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class DeviceCallbacksDelegate
4141
virtual void OnIPv4ConnectivityEstablished() {}
4242
virtual void OnIPv4ConnectivityLost() {}
4343
virtual void OnDnssdInitialized() {}
44+
virtual void OnIPv6ConnectivityEstablished() {}
4445
DeviceCallbacksDelegate * mDelegate = nullptr;
4546
void SetAppDelegate(DeviceCallbacksDelegate * delegate) { mDelegate = delegate; }
4647
DeviceCallbacksDelegate * GetAppDelegate() { return mDelegate; }

examples/platform/esp32/common/Esp32AppServer.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ using namespace chip::DeviceLayer;
5151
static constexpr char TAG[] = "ESP32Appserver";
5252

5353
namespace {
54-
5554
#if CONFIG_TEST_EVENT_TRIGGER_ENABLED
5655
static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
5756
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
@@ -103,8 +102,10 @@ static size_t hex_string_to_binary(const char * hex_string, uint8_t * buf, size_
103102
void Esp32AppServer::DeInitBLEIfCommissioned(void)
104103
{
105104
#ifdef CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING
106-
if (chip::Server::GetInstance().GetFabricTable().FabricCount() > 0)
105+
static bool bleAlreadyShutdown = false;
106+
if (chip::Server::GetInstance().GetFabricTable().FabricCount() > 0 && (!bleAlreadyShutdown))
107107
{
108+
bleAlreadyShutdown = true;
108109
chip::DeviceLayer::Internal::BLEMgr().Shutdown();
109110
}
110111
#endif /* CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING */

examples/platform/esp32/common/Esp32ThreadInit.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include <platform/ESP32/OpenthreadLauncher.h>
2222
#include <platform/ThreadStackManager.h>
2323
#endif // CONFIG_OPENTHREAD_ENABLED
24+
#ifdef CONFIG_OPENTHREAD_BORDER_ROUTER
25+
#include <esp_spiffs.h>
26+
#endif
2427

2528
#include <esp_log.h>
2629
#if CONFIG_PM_ENABLE
@@ -39,6 +42,17 @@ void ESPOpenThreadInit()
3942
.host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(),
4043
.port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(),
4144
};
45+
#ifdef CONFIG_OPENTHREAD_BORDER_ROUTER
46+
esp_vfs_spiffs_conf_t rcp_fw_conf = {
47+
.base_path = "/rcp_fw", .partition_label = "rcp_fw", .max_files = 10, .format_if_mount_failed = false};
48+
if (ESP_OK != esp_vfs_spiffs_register(&rcp_fw_conf))
49+
{
50+
ESP_LOGE(TAG, "Failed to mount rcp firmware storage");
51+
return;
52+
}
53+
esp_rcp_update_config_t rcp_update_config = ESP_OPENTHREAD_RCP_UPDATE_CONFIG();
54+
openthread_init_br_rcp(&rcp_update_config);
55+
#endif // CONFIG_OPENTHREAD_BORDER_ROUTER
4256
set_openthread_platform_config(&config);
4357

4458
if (ThreadStackMgr().InitThreadStack() != CHIP_NO_ERROR)

examples/platform/esp32/common/Esp32ThreadInit.h

+59
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,57 @@
2222
#if CONFIG_OPENTHREAD_ENABLED
2323
#include "esp_openthread_types.h"
2424

25+
#if CONFIG_OPENTHREAD_RADIO_NATIVE
2526
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
2627
{ \
2728
.radio_mode = RADIO_MODE_NATIVE, \
2829
}
30+
#elif CONFIG_OPENTHREAD_RADIO_SPINEL_UART
31+
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
32+
{ \
33+
.radio_mode = RADIO_MODE_UART_RCP, \
34+
.radio_uart_config = { \
35+
.port = UART_NUM_1, \
36+
.uart_config = \
37+
{ \
38+
.baud_rate = 460800, \
39+
.data_bits = UART_DATA_8_BITS, \
40+
.parity = UART_PARITY_DISABLE, \
41+
.stop_bits = UART_STOP_BITS_1, \
42+
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \
43+
.rx_flow_ctrl_thresh = 0, \
44+
.source_clk = UART_SCLK_DEFAULT, \
45+
}, \
46+
.rx_pin = GPIO_NUM_17, \
47+
.tx_pin = GPIO_NUM_18, \
48+
}, \
49+
}
50+
#else
51+
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
52+
{ \
53+
.radio_mode = RADIO_MODE_SPI_RCP, \
54+
.radio_spi_config = { \
55+
.host_device = SPI2_HOST, \
56+
.dma_channel = 2, \
57+
.spi_interface = \
58+
{ \
59+
.mosi_io_num = 11, \
60+
.sclk_io_num = 12, \
61+
.miso_io_num = 13, \
62+
}, \
63+
.spi_device = \
64+
{ \
65+
.cs_ena_pretrans = 2, \
66+
.input_delay_ns = 100, \
67+
.mode = 0, \
68+
.clock_speed_hz = 2500 * 1000, \
69+
.spics_io_num = 10, \
70+
.queue_size = 5, \
71+
}, \
72+
.intr_pin = 8, \
73+
}, \
74+
}
75+
#endif // CONFIG_OPENTHREAD_RADIO_SPINEL_UART OR CONFIG_OPENTHREAD_RADIO_SPINEL_SPI
2976

3077
#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
3178
{ \
@@ -36,6 +83,18 @@
3683
{ \
3784
.storage_partition_name = "nvs", .netif_queue_size = 10, .task_queue_size = 10, \
3885
}
86+
87+
#ifdef CONFIG_OPENTHREAD_BORDER_ROUTER
88+
#include <esp_rcp_update.h>
89+
#define RCP_FIRMWARE_DIR "/spiffs/ot_rcp"
90+
91+
#define ESP_OPENTHREAD_RCP_UPDATE_CONFIG() \
92+
{ \
93+
.rcp_type = RCP_TYPE_ESP32H2_UART, .uart_rx_pin = 17, .uart_tx_pin = 18, .uart_port = 1, .uart_baudrate = 115200, \
94+
.reset_pin = 7, .boot_pin = 8, .update_baudrate = 460800, .firmware_dir = "/rcp_fw/ot_rcp", .target_chip = ESP32H2_CHIP, \
95+
}
96+
#endif // CONFIG_OPENTHREAD_BORDER_ROUTER
97+
3998
#endif // CONFIG_OPENTHREAD_ENABLED
4099

41100
void ESPOpenThreadInit();

examples/platform/esp32/external_platform/ESP32_custom/BUILD.gn

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ declare_args() {
2929
chip_bt_bluedroid_enabled = true
3030
chip_max_discovered_ip_addresses = 5
3131
chip_enable_route_hook = false
32-
chip_enable_thread_border_router = false
3332
}
3433

3534
buildconfig_header("custom_buildconfig") {
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.vscode
2+
3+
/build/
4+
/sdkconfig
5+
/sdkconfig.old
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#
2+
# Copyright (c) 2021 Project CHIP Authors
3+
# All rights reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# The following lines of boilerplate have to be in your project's
18+
# CMakeLists in this exact order for cmake to work correctly
19+
cmake_minimum_required(VERSION 3.5)
20+
21+
set(PROJECT_VER "v1.0")
22+
set(PROJECT_VER_NUMBER 1)
23+
24+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
25+
include(${CMAKE_CURRENT_LIST_DIR}/../../common/cmake/idf_flashing.cmake)
26+
27+
set(EXTRA_COMPONENT_DIRS
28+
"${CMAKE_CURRENT_LIST_DIR}/third_party/connectedhomeip/config/esp32/components"
29+
)
30+
31+
project(chip-thread-br-app)
32+
33+
# C++17 is required for RPC build.
34+
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DCHIP_HAVE_CONFIG_H" APPEND)
35+
idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND)
36+
# For the C3, project_include.cmake sets -Wno-format, but does not clear various
37+
# flags that depend on -Wformat
38+
idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND)
39+
40+
# We don't need Thread Network Commissioning Driver
41+
idf_build_set_property(COMPILE_OPTIONS "-D_NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_" APPEND)
42+
43+
# -Wmaybe-uninitialized has too many false positives, including on std::optional
44+
# and chip::Optional. Make it nonfatal.
45+
#
46+
# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635
47+
idf_build_set_property(COMPILE_OPTIONS "-Wno-error=maybe-uninitialized" APPEND)
48+
49+
flashing_script()
+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Matter ESP32 Thread Border Router Example
2+
3+
A prototype application that demonstrates OpenThread Border Router on ESP32-S3 + ESP32-H2
4+
Thread Border Router DevKit Board.
5+
6+
Please
7+
[setup ESP-IDF and CHIP Environment](../../../docs/guides/esp32/setup_idf_chip.md)
8+
and refer
9+
[building and commissioning](../../../docs/guides/esp32/build_app_and_commission.md)
10+
guides to get started.
11+
12+
---
13+
14+
- [OpenThread Border Router DevKit Board](#openthread-border-router-board)
15+
- [OpenThread RCP](#openthread-rcp)
16+
- [OpenThread CLI](#openthread-cli)
17+
- [Setup Thread Network](#setup-thread-network)
18+
- [Commissioning Thread End Devices](#commissioning-thread-end-devices)
19+
20+
---
21+
22+
### Thread Border Router Board
23+
24+
The ESP Thread border router board provides an integrated module of an ESP32-S3 and an ESP32-H2.
25+
26+
![br_dev_kit](./image/esp-thread-border-router-board.png)
27+
28+
### OpenThread RCP
29+
30+
We need to build an OpenThread RCP(Radio Co-Processor) firmware for ESP32-H2 of the Border Router Board
31+
before building this Thread Border example.
32+
33+
```
34+
cd $IDF_PATH/examples/openthread/ot_rcp
35+
idf.py set-target esp32h2
36+
idf.py build
37+
```
38+
39+
Then we need to connect the USB2 port(ESP32-S3) of the Border Router Board to your host machine. Build and flash
40+
this example.
41+
42+
```
43+
cd ${CHIP_ROOT}/examples/thread-br-app/esp32
44+
idf.py set-target esp32s3
45+
idf.py build
46+
idf.py -p {port} erase-flash flash monitor
47+
```
48+
49+
This example will detect the RCP firmware built in ESP-IDF path and flash it to the spiffs partition. When
50+
starting this example, the ESP32-S3 will compare the versions of both the RCP firmware in the spiffs partition and
51+
the firmware on ESP32-H2. if the spiffs RCP firmware is newer than the firmware on ESP32-H2, the Thread BR will flash
52+
the RCP firmware to ESP32-H2 automatically.
53+
54+
### OpenThread CLI
55+
56+
After you build this example and flash it to the ESP32-S3 of Border Router Board, you can access a standard
57+
OpenThread CLI via the device console with a `matter otcli` prefix.
58+
59+
For instance, you can get the state:
60+
```
61+
> matter otcli state
62+
Detached
63+
Done
64+
```
65+
66+
### Setup/Join Thread Network
67+
68+
You can send SetActiveDatasetRequest command to the Thread BR after commissioning it as a
69+
Matter-Over-Wi-Fi device to setup the Thread network or join an existing Thread network.
70+
71+
```
72+
./chip-tool pairing ble-wifi 1 <ssid> <password> 20202021 3840
73+
./chip-tool generalcommissioning arm-fail-safe 180 1 1 0
74+
./chip-tool threadborderroutermanagement set-active-dataset-request hex:<dataset-tlvs> 1 1 1
75+
```
76+
77+
The Thread BR with enable the Thread network interface and start Thread network after it receives
78+
SetActiveDatasetRequest command. And after the Thread BR sets up or join a Thread network, it will
79+
send the success response and disarm the fail safe timer.
80+
81+
### Commissioning Thread End Devices
82+
83+
After setting up the Thread network, you can commission a Thread End-device to the Thread network.
84+
85+
```
86+
./chip-tool pairing ble-wifi 2 hex:<dataset_tlvs> <pincode> <discriminator>
87+
```

0 commit comments

Comments
 (0)