Initial commit
This commit is contained in:
commit
e02859a336
75
01_Source/matter-light-c6-wifi/CMakeLists.txt
Normal file
75
01_Source/matter-light-c6-wifi/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{ESP_MATTER_PATH})
|
||||||
|
message(FATAL_ERROR "Please set ESP_MATTER_PATH to the path of esp-matter repo")
|
||||||
|
endif(NOT DEFINED ENV{ESP_MATTER_PATH})
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
||||||
|
if("${IDF_TARGET}" STREQUAL "esp32" OR "${IDF_TARGET}" STREQUAL "")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c3")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c3_devkit_m)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c2")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c2_devkit_m)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32h2")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32h2_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32s3")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32s3_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c6")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c6_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c61")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c61_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c5")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c5_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32p4")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/hollow)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported IDF_TARGET")
|
||||||
|
endif()
|
||||||
|
endif(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
||||||
|
|
||||||
|
set(ESP_MATTER_PATH_RAW "$ENV{ESP_MATTER_PATH}")
|
||||||
|
string(STRIP "${ESP_MATTER_PATH_RAW}" ESP_MATTER_PATH_RAW)
|
||||||
|
file(TO_CMAKE_PATH "${ESP_MATTER_PATH_RAW}" ESP_MATTER_PATH)
|
||||||
|
set(ENV{ESP_MATTER_PATH} "${ESP_MATTER_PATH}")
|
||||||
|
|
||||||
|
set(ESP_MATTER_DEVICE_PATH_RAW "$ENV{ESP_MATTER_DEVICE_PATH}")
|
||||||
|
string(STRIP "${ESP_MATTER_DEVICE_PATH_RAW}" ESP_MATTER_DEVICE_PATH_RAW)
|
||||||
|
file(TO_CMAKE_PATH "${ESP_MATTER_DEVICE_PATH_RAW}" ESP_MATTER_DEVICE_PATH)
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} "${ESP_MATTER_DEVICE_PATH}")
|
||||||
|
|
||||||
|
set(PROJECT_VER "2.0" CACHE STRING "Application version")
|
||||||
|
set(PROJECT_VER_NUMBER 2 CACHE STRING "Application version number")
|
||||||
|
set(MATTER_SDK_PATH ${ESP_MATTER_PATH}/connectedhomeip/connectedhomeip)
|
||||||
|
|
||||||
|
# This should be done before using the IDF_TARGET variable.
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
include(${ESP_MATTER_PATH}/examples/common/cmake_common/components_include.cmake)
|
||||||
|
include($ENV{ESP_MATTER_DEVICE_PATH}/esp_matter_device.cmake)
|
||||||
|
|
||||||
|
set(EXTRA_COMPONENT_DIRS
|
||||||
|
"${ESP_MATTER_PATH}/examples/common"
|
||||||
|
"${MATTER_SDK_PATH}/config/esp32/components"
|
||||||
|
"${ESP_MATTER_PATH}/components"
|
||||||
|
"${ESP_MATTER_PATH}/device_hal/device"
|
||||||
|
${extra_components_dirs_append})
|
||||||
|
|
||||||
|
project(light)
|
||||||
|
|
||||||
|
# WARNING: This is just an example for using key for decrypting the encrypted OTA image
|
||||||
|
# Please do not use it as is.
|
||||||
|
if(CONFIG_ENABLE_ENCRYPTED_OTA)
|
||||||
|
target_add_binary_data(light.elf "esp_image_encryption_key.pem" TEXT)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_IDF_TARGET_ESP32C2)
|
||||||
|
include(relinker)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DCHIP_HAVE_CONFIG_H;-Wno-overloaded-virtual" APPEND)
|
||||||
|
idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND)
|
||||||
|
# For RISCV chips, 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)
|
||||||
75
01_Source/matter-light-c6-wifi/CMakeLists_1.txt
Normal file
75
01_Source/matter-light-c6-wifi/CMakeLists_1.txt
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{ESP_MATTER_PATH})
|
||||||
|
message(FATAL_ERROR "Please set ESP_MATTER_PATH to the path of esp-matter repo")
|
||||||
|
endif(NOT DEFINED ENV{ESP_MATTER_PATH})
|
||||||
|
|
||||||
|
if(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
||||||
|
if("${IDF_TARGET}" STREQUAL "esp32" OR "${IDF_TARGET}" STREQUAL "")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c3")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c3_devkit_m)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c2")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c2_devkit_m)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32h2")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32h2_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32s3")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32s3_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c6")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c6_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c61")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c61_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32c5")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c5_devkit_c)
|
||||||
|
elseif("${IDF_TARGET}" STREQUAL "esp32p4")
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/hollow)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported IDF_TARGET")
|
||||||
|
endif()
|
||||||
|
endif(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
||||||
|
|
||||||
|
set(ESP_MATTER_PATH_RAW "$ENV{ESP_MATTER_PATH}")
|
||||||
|
string(STRIP "${ESP_MATTER_PATH_RAW}" ESP_MATTER_PATH_RAW)
|
||||||
|
file(TO_CMAKE_PATH "${ESP_MATTER_PATH_RAW}" ESP_MATTER_PATH)
|
||||||
|
set(ENV{ESP_MATTER_PATH} "${ESP_MATTER_PATH}")
|
||||||
|
|
||||||
|
set(ESP_MATTER_DEVICE_PATH_RAW "$ENV{ESP_MATTER_DEVICE_PATH}")
|
||||||
|
string(STRIP "${ESP_MATTER_DEVICE_PATH_RAW}" ESP_MATTER_DEVICE_PATH_RAW)
|
||||||
|
file(TO_CMAKE_PATH "${ESP_MATTER_DEVICE_PATH_RAW}" ESP_MATTER_DEVICE_PATH)
|
||||||
|
set(ENV{ESP_MATTER_DEVICE_PATH} "${ESP_MATTER_DEVICE_PATH}")
|
||||||
|
|
||||||
|
set(PROJECT_VER "1.0")
|
||||||
|
set(PROJECT_VER_NUMBER 1)
|
||||||
|
set(MATTER_SDK_PATH ${ESP_MATTER_PATH}/connectedhomeip/connectedhomeip)
|
||||||
|
|
||||||
|
# This should be done before using the IDF_TARGET variable.
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
include(${ESP_MATTER_PATH}/examples/common/cmake_common/components_include.cmake)
|
||||||
|
include($ENV{ESP_MATTER_DEVICE_PATH}/esp_matter_device.cmake)
|
||||||
|
|
||||||
|
set(EXTRA_COMPONENT_DIRS
|
||||||
|
"${ESP_MATTER_PATH}/examples/common"
|
||||||
|
"${MATTER_SDK_PATH}/config/esp32/components"
|
||||||
|
"${ESP_MATTER_PATH}/components"
|
||||||
|
"${ESP_MATTER_PATH}/device_hal/device"
|
||||||
|
${extra_components_dirs_append})
|
||||||
|
|
||||||
|
project(light)
|
||||||
|
|
||||||
|
# WARNING: This is just an example for using key for decrypting the encrypted OTA image
|
||||||
|
# Please do not use it as is.
|
||||||
|
if(CONFIG_ENABLE_ENCRYPTED_OTA)
|
||||||
|
target_add_binary_data(light.elf "esp_image_encryption_key.pem" TEXT)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_IDF_TARGET_ESP32C2)
|
||||||
|
include(relinker)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DCHIP_HAVE_CONFIG_H;-Wno-overloaded-virtual" APPEND)
|
||||||
|
idf_build_set_property(C_COMPILE_OPTIONS "-Os" APPEND)
|
||||||
|
# For RISCV chips, 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)
|
||||||
414
01_Source/matter-light-c6-wifi/DEV_PROGRESS.md
Normal file
414
01_Source/matter-light-c6-wifi/DEV_PROGRESS.md
Normal file
|
|
@ -0,0 +1,414 @@
|
||||||
|
# ESP32-C6 Matter + ESP-NOW 混合固件开发进度(单色灯 + 双色温灯)
|
||||||
|
|
||||||
|
## 1. 项目目标(来自《项目制作需求》)
|
||||||
|
|
||||||
|
- 基于 ESP32(候选:C3/C6),开发 Matter + ESP-NOW 混合固件。
|
||||||
|
- 支持两类灯:
|
||||||
|
- 单色灯:开关 + 调光(白光)。
|
||||||
|
- 双色温灯:开关 + 调光 + 调色温(暖/冷)。
|
||||||
|
- 开发阶段:Wi-Fi commissioning(通过 Wi-Fi 完成配网)。
|
||||||
|
- 最终目标:Wi-Fi 完成配网、Thread 实现本地 mesh 控制(混合网络模式)。
|
||||||
|
- 需要 OTA、QR 码生成、VID/PID/DAC 相关出厂数据与认证准备支持。
|
||||||
|
- 交付:双版本(或可配置)源码仓库 + Factory/OTA 固件 + 烧录/QR 脚本 + 测试报告 + 技术文档。
|
||||||
|
|
||||||
|
## 1.1 关键硬性约束与解决方案
|
||||||
|
|
||||||
|
- 量产遥控器固件不变,且 ESP-NOW 固定信道为 `channel=1`。
|
||||||
|
- **问题**:若使用 Matter-over-Wi-Fi,Wi-Fi STA 信道会被路由器决定,与 ESP-NOW 固定 ch1 冲突。
|
||||||
|
- **解决方案**:利用 ESP32-C6 的**双射频**能力:
|
||||||
|
- **Wi-Fi 2.4GHz 射频**:专用于 ESP-NOW(固定 channel 1,不连接路由器做 STA)
|
||||||
|
- **802.15.4 射频**:专用于 Matter over Thread(与 Wi-Fi 射频完全独立)
|
||||||
|
- **BLE**:用于 Matter commissioning(配网阶段)
|
||||||
|
- 结论:单芯片 ESP32-C6 可实现 ESP-NOW + Matter 共存,无需依赖路由器信道。
|
||||||
|
|
||||||
|
## 1.2 需求对齐清单(当前工程状态)
|
||||||
|
|
||||||
|
| 需求项 | 状态 | 备注 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| ESP-NOW 代码功能 100% 保持 | 部分 | 已按遥控器协议实现 RX/配对/命令映射,但信道冲突仍未解决为“量产可用”方案 |
|
||||||
|
| Matter clusters: OnOff / LevelControl | 已完成 | 双 endpoint 已跑通 |
|
||||||
|
| Matter clusters: Groups / Scenes | 已完成(已验证) | 已在 App 上验证可创建/应用场景 |
|
||||||
|
| ColorControl(双色温) | 已完成(开发态) | 当前实现为 ColorTemperature;已确认硬件为 SK6812 RGBW 模块,调色温方向正常 |
|
||||||
|
| ESP-NOW 组播/广播组命令→所有控制器同步→Matter 状态更新 | 已完成(已稳定) | 控制器能处理 cmd 并更新 Matter 属性;组控一致性/延迟表现正常,无需再测试 |
|
||||||
|
| QR 码配网(Apple/Google/Alexa/RainMaker) | 部分 | iOS Home 已验证;Google/Alexa/RainMaker 未做系统性验证 |
|
||||||
|
| OTA(HTTP 远程服务器) | 已完成 | 已实现 HTTP OTA(从远程服务器下载固件),可通过 Matter shell 命令触发,已验证升级后 App version 变更 |
|
||||||
|
| Matter 标准 OTA | 暂停 | 采用 HTTP OTA(远程服务器)方案,不再推进标准 Matter OTA |
|
||||||
|
| 断电重置(如 3 次开关机) | 已完成(已稳定) | 已实现并验证:3 次重启触发 Matter 工厂重置(含 5 秒确认窗);已测试稳定,无需再测 |
|
||||||
|
| 交付:源码/编译说明/bin/脚本/测试报告 | 进行中 | 文档与脚本需要补齐并固化 |
|
||||||
|
|
||||||
|
## 1.4 当前进度总览(已完成 vs 未完成)
|
||||||
|
|
||||||
|
### 1.4.1 已完成
|
||||||
|
|
||||||
|
- HTTP OTA(远程服务器下载固件,shell 命令触发),并验证升级成功后 `App version` 变更(2.0 → 2.1)
|
||||||
|
- Matter clusters: Groups / Scenes 已在 App 上验证可创建/应用场景
|
||||||
|
- 分区表调整为双 OTA(`ota_0`/`ota_1`/`otadata`),固件大小可容纳 OTA 升级
|
||||||
|
- OTA 触发命令已接入 Matter shell(`matter esp ota <http://url>`)
|
||||||
|
- 已可在 Windows 上稳定完成 build/flash/monitor(含 GN/Pigweed 环境)
|
||||||
|
- 断电重置(工厂重置):已实现并验证 3 次重启触发 factory reset(含 5 秒确认窗),重置后进入可重新配网状态
|
||||||
|
- 修复断电计数不生效问题:将 NVS key 缩短到 15 字符以内并加入兼容读取逻辑
|
||||||
|
- ESP-NOW 配对与多设备联调:已支持“单遥控器(Zone1/Zone2)+ APP”控制两台 ESP32-C6 灯具;并修复“电源重启触发配对时未及时广播配对 beacon”的问题,提升遥控器绑定成功率
|
||||||
|
|
||||||
|
### 1.4.2 未完成(待办)
|
||||||
|
|
||||||
|
- 多生态验证:Google Home / Alexa / RainMaker 的 commissioning + 控制验证
|
||||||
|
- 交付物固化:一键环境初始化/构建脚本、烧录脚本、测试报告与完整技术文档
|
||||||
|
|
||||||
|
## 3. 已完成的关键里程碑
|
||||||
|
|
||||||
|
### 3.1 构建与烧录链路打通(Windows)
|
||||||
|
|
||||||
|
- 已实现:`idf.py build` 成功、可 `flash` 到 COM4、可 `monitor` 观察启动日志。
|
||||||
|
- 已解决的关键构建问题(历史记录):
|
||||||
|
- `gn command not found`:定位 `gn.exe` 并加入 PATH。
|
||||||
|
- Pigweed 环境变量缺失:补齐 `_PW_ACTUAL_ENVIRONMENT_ROOT`。
|
||||||
|
- 链接错误 `undefined reference to mbedtls_hkdf`:启用 `CONFIG_MBEDTLS_HKDF_C=y`。
|
||||||
|
- app 分区过小:切换到自定义分区表 `partitions.csv`(双 OTA),并设置 flash size=16MB(与硬件一致),最小 app 分区 `0x1E0000`。
|
||||||
|
- Windows 反斜杠路径导致 CMake `Invalid character escape`:CMakeLists 里将 env path 转为 CMake path。
|
||||||
|
|
||||||
|
补充:构建该工程的关键环境变量(PowerShell 会话级别):
|
||||||
|
|
||||||
|
- `ESP_MATTER_PATH=D:\ESP-LED\esp-matter-gh`
|
||||||
|
- `ESP_MATTER_DEVICE_PATH=D:\ESP-LED\esp-matter-gh\device_hal\device\esp32c6_devkit_c`
|
||||||
|
- `_PW_ACTUAL_ENVIRONMENT_ROOT=D:\ESP-LED\esp-matter-gh\connectedhomeip\connectedhomeip\third_party\pigweed\repo\environment`
|
||||||
|
- GN 工具路径(将目录加入 PATH):
|
||||||
|
- `...\third_party\pigweed\repo\environment\cipd\packages\pigweed`(包含 `gn.exe`)
|
||||||
|
|
||||||
|
### 3.2 Matter 双 endpoint 架构(已运行验证)
|
||||||
|
|
||||||
|
- 当前固件创建两个 endpoint:
|
||||||
|
- Endpoint 1:单色灯(OnOff + LevelControl)。
|
||||||
|
- Endpoint 2:双色温灯(OnOff + LevelControl + ColorControl(ColorTemperature))。
|
||||||
|
- 串口日志已确认:
|
||||||
|
- `RGB light created with endpoint_id 1`
|
||||||
|
- `CCT light created with endpoint_id 2`
|
||||||
|
|
||||||
|
### 3.3 驱动层对接(已跑通)
|
||||||
|
|
||||||
|
- Endpoint 1(单色灯):LEDC PWM 驱动(GPIO4/5/6)。
|
||||||
|
- Endpoint 2(双色温灯):RMT 驱动 SK6812(GPIO2)。
|
||||||
|
|
||||||
|
### 3.4 日志报错修复
|
||||||
|
|
||||||
|
- 修复启动时 `E data_model: Cluster cannot be NULL.`:
|
||||||
|
- 原因:对不含 ColorControl 的 endpoint 调用 `attribute::get(endpoint, ColorControl...)`。
|
||||||
|
- 处理:先检查 `cluster::get(endpoint, ColorControl::Id)` 是否存在,再读取 ColorMode / Hue / Temp 等属性。
|
||||||
|
|
||||||
|
### 3.5 iOS Home / Matter Commissioning + 控制验证(已完成)
|
||||||
|
|
||||||
|
- 现状:手机端已完成配网,Home App 可同时控制两个灯的开关/亮度/(CCT 灯)色温。
|
||||||
|
- 关键修复:为满足 iOS Home 的发现/配网流程,已启用 BLE commissioning:
|
||||||
|
- `CONFIG_BT_ENABLED=y`
|
||||||
|
- `CONFIG_BT_NIMBLE_ENABLED=y`
|
||||||
|
- `CONFIG_ENABLE_CHIPOBLE=y`
|
||||||
|
- 串口日志关键特征(表示 BLE commissioning 正常):
|
||||||
|
- `Configuring CHIPoBLE advertising ...`
|
||||||
|
- `CHIPoBLE advertising started`
|
||||||
|
- `Commissioning window opened`
|
||||||
|
- 设备启动时可打印 Onboarding Codes(用于手动输入/生成二维码):
|
||||||
|
- MT 串(SetupQRCode):`MT:Y.K9042C00KA0648G00`
|
||||||
|
- 11 位码(Manual pairing code):`34970112332`
|
||||||
|
- 注意:上述二维码/手动码为开发阶段示例/测试参数(默认 VID/PID 等),量产需替换正式 VID/PID、DAC/CD/工厂数据与每台唯一的 onboarding 信息。
|
||||||
|
|
||||||
|
### 3.6 单芯片双射频方案验证成功(2026-01-07)
|
||||||
|
|
||||||
|
- **架构**:ESP32-C6 单芯片同时运行:
|
||||||
|
- **Thread (802.15.4)**:Matter 网络层
|
||||||
|
- **Wi-Fi (channel 1)**:ESP-NOW 接收(不连接路由器)
|
||||||
|
- **BLE**:Matter commissioning
|
||||||
|
- **关键配置**:
|
||||||
|
- `CONFIG_ENABLE_WIFI_STATION=n`:禁用 Matter Wi-Fi STA
|
||||||
|
- `CONFIG_ENABLE_THREAD=y`:启用 Matter over Thread
|
||||||
|
- 独立初始化 Wi-Fi 用于 ESP-NOW,固定 channel 1
|
||||||
|
- **验证通过的日志特征**:
|
||||||
|
- `OpenThread started: OK`
|
||||||
|
- `Wi-Fi channel fixed to 1 for ESP-NOW`
|
||||||
|
- `ESP-NOW RX initialized`
|
||||||
|
- `CHIPoBLE advertising started`
|
||||||
|
- `Server Listening...`
|
||||||
|
- **固件大小**:~2MB(含 Thread + Wi-Fi + BLE + ESP-NOW)
|
||||||
|
- **状态**:设备稳定启动,无崩溃
|
||||||
|
|
||||||
|
### 3.7 HTTP OTA(远程服务器)验证成功(2026-01-15)
|
||||||
|
|
||||||
|
- **目标**:支持“远程服务器方式”OTA(HTTP),不依赖 HTTPS/TLS,固件体积可控。
|
||||||
|
- **实现概览**:
|
||||||
|
- 使用 `esp_http_client` + `esp_ota_*` 实现分段下载与写入 OTA 分区。
|
||||||
|
- 提供 Matter shell 命令触发:`matter esp ota <http://url>`。
|
||||||
|
- 仅支持 `http://`,拒绝 `https://` 以减小固件体积。
|
||||||
|
- **验证结果(串口日志特征)**:
|
||||||
|
- `HTTP OTA progress: ... 100%`
|
||||||
|
- `HTTP OTA upgrade successful! Rebooting in 3 seconds...`
|
||||||
|
- 重启后:`Loaded app from partition at offset 0x210000`(切换到 ota_1)
|
||||||
|
- 重启后:`App version: 2.1`(已确认版本号随固件更新)
|
||||||
|
|
||||||
|
### 3.8 多设备控制联调进展(APP + ESP-NOW 遥控器)(2026-01-15)
|
||||||
|
|
||||||
|
- **目标**:一台遥控器 + 手机 App 同时控制两台 ESP32-C6 灯具(两块开发板)。
|
||||||
|
- **实现状态**:
|
||||||
|
- App 侧(iOS Home)已可同时添加两台设备并分别控制。
|
||||||
|
- 遥控器侧支持 Zone1/Zone2 独立绑定不同灯具(通过 ESP-NOW 配对流程完成)。
|
||||||
|
- **配对机制(开发态)**:
|
||||||
|
- 3 次重启:触发 Matter factory reset(5 秒确认窗)。
|
||||||
|
- 5 次重启:进入 ESP-NOW pairing mode(5 秒确认窗)。
|
||||||
|
- 遥控器在目标 Zone 下长按配对键,设备收到 `0xA5` 后退出配对模式。
|
||||||
|
- **关键修复**:
|
||||||
|
- 修复“电源重启触发配对模式后,因 Wi-Fi 连接状态导致配对 beacon 未及时广播”的问题:进入配对后将主动启动配对 beacon 广播,确保遥控器可发现并完成绑定。
|
||||||
|
|
||||||
|
## 4. 当前仍在进行中的问题/待验证点
|
||||||
|
|
||||||
|
### 4.1 单色灯输出"白光"的定义与实现(已确定:RGB 三路混白)
|
||||||
|
|
||||||
|
- 当前单色灯硬件接法为 RGB 三路 PWM(GPIO4/5/6)。
|
||||||
|
- 已做的软件调整:将 RGB 三路占空比设置为 1:1:1(同亮度混色)以尽量呈现白光。
|
||||||
|
- 已确认:单色灯即 RGB 三路混白方案(不做单通道白灯条改造)。
|
||||||
|
- 注意:RGB 分立灯珠近距离仍可能看到“三色点”,属于物理结构;可通过扩散罩/导光改善。
|
||||||
|
|
||||||
|
### 4.2 双色温灯的“暖/冷”实现(已确认:SK6812 RGBW)
|
||||||
|
|
||||||
|
- 已确认:双色温灯硬件为 SK6812 RGBW 模块,采用 RMT 单线驱动。
|
||||||
|
- 当前实现:Matter ColorTemperature(mireds)→ 颜色映射 → SK6812 输出;调色温方向已验证正确。
|
||||||
|
- 注意:SK6812 RGBW 的“色温”属于近似实现(需要 RGB 参与补色),效果取决于映射/校准策略。
|
||||||
|
- 状态:当前效果表现正常,无需再做专项“色温校准/一致性测试”。
|
||||||
|
|
||||||
|
### 4.3 Flash 容量提示告警(已解决)
|
||||||
|
|
||||||
|
- 现象:启动时提示检测到 16MB,但固件镜像头标记为 4MB:
|
||||||
|
- `Detected size(16384k) larger than the size in the binary image header(4096k)`
|
||||||
|
- 影响:通常可运行,但不利于后续分区与 OTA 风险控制。
|
||||||
|
- 已处理并确认:将工程 Flash size 配置调整为 16MB(`CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y`),已复测确认告警消失。
|
||||||
|
|
||||||
|
## 5. 控制器/遥控器(ESP-NOW)现状梳理(已读源码)
|
||||||
|
|
||||||
|
- 控制器原码路径:`D:\ESP-LED\控制器原码\Ecolight\...`
|
||||||
|
- 协议:ESP-NOW(channel=1)
|
||||||
|
- Pairing beacon magic:`0xABCDEF01`(4字节)
|
||||||
|
- 命令(1字节):
|
||||||
|
- `0x01` Toggle
|
||||||
|
- `0x02` On
|
||||||
|
- `0x03` Brightness Up
|
||||||
|
- `0x04` Brightness Down
|
||||||
|
- `0x05` Off
|
||||||
|
- `0xA5` Pairing Confirm
|
||||||
|
|
||||||
|
结论:控制器原码与甲方提供的遥控器一致,且该 ESP-NOW 遥控协议可接入当前 Matter 灯固件(C6 端作为 ESPNOW 接收端),收到命令后同步更新 Matter 属性。
|
||||||
|
|
||||||
|
## 6. VID/PID/DAC/QR 码阶段性策略
|
||||||
|
|
||||||
|
- 开发阶段可以使用示例/测试用的 VID/PID/证书链推进开发。
|
||||||
|
- 后续拿到正式 VID/PID/DAC 后:
|
||||||
|
- 替换证书与出厂数据。
|
||||||
|
- 重新生成 QR。
|
||||||
|
- 通常需要恢复出厂并重新配网(属正常流程)。
|
||||||
|
|
||||||
|
## 7. 下一步开发路线图(按阶段)
|
||||||
|
|
||||||
|
### 阶段 A:功能验证与参数固化(短期)
|
||||||
|
|
||||||
|
- 单色灯:明确硬件定义(RGB 混白 vs 单路白灯条),固化白光方案。
|
||||||
|
- 双色温:已确认 SK6812 RGBW,固化色温映射与效果参数(端点/曲线/gamma/限幅),并确认通道顺序与供电/信号稳定性。
|
||||||
|
- 建立功能测试用例并记录:
|
||||||
|
- endpoint 1:开/关、亮度
|
||||||
|
- endpoint 2:开/关、亮度、色温
|
||||||
|
|
||||||
|
### 阶段 B:ESP-NOW + Matter 共存(核心)
|
||||||
|
|
||||||
|
- 在 C6 Matter 固件中加入 ESPNOW RX:
|
||||||
|
- 接收 1-byte 命令并映射到 endpoint 1/2 的 Matter 属性更新。
|
||||||
|
- 目标:遥控器控制灯,Matter 侧状态同步。
|
||||||
|
- 解决 Wi-Fi channel 与 ESPNOW channel=1 的冲突(以“遥控器固件不变”为前提):
|
||||||
|
- 方案 1(最小改动,但依赖环境):路由器/热点 2.4G 固定 `channel=1`。
|
||||||
|
- 方案 2(推荐量产架构):双芯片/双射频解耦(ESP-NOW 固定 ch1 与 Matter Wi-Fi 任意信道互不影响)。
|
||||||
|
- 方案 3(与 Addendum 对齐):Wi-Fi 用于 commissioning,日常控制走 Thread(需要 Thread Border Router 环境),从而避免 Wi-Fi 信道对 ESP-NOW 的牵制。
|
||||||
|
- 性能目标:端到端延迟 < 20ms(需要定义测量方法和基准)。
|
||||||
|
|
||||||
|
### 7.2 芯片选型建议(C3 vs C6)
|
||||||
|
|
||||||
|
- 若坚持单芯片承载 Matter(含 Groups/Scenes/OTA/多生态)+ 应用逻辑 + ESPNOW:更推荐 ESP32-C6。
|
||||||
|
- 原因:内存与资源更充足,Matter 生态适配与稳定性更优,且可扩展 Thread(满足 Addendum)。
|
||||||
|
- 若控制器仍使用 ESP32-C3:需要评估以下风险项:
|
||||||
|
- Matter + BLE commissioning + OTA + Groups/Scenes 的 RAM/Flash 压力。
|
||||||
|
- 与 ESPNOW 同时运行的峰值内存/任务栈/队列占用。
|
||||||
|
- 当路由器信道不可控且遥控器固件不变时:
|
||||||
|
- 单芯片方案存在先天信道冲突。
|
||||||
|
- 需要硬件/架构调整(例如额外加一颗 C3 专做 ESPNOW 固定 ch1,C6 专做 Matter/Wi-Fi/Thread,通过 UART/SPI 同步状态)。
|
||||||
|
|
||||||
|
### 7.3 方案 A(双芯片解耦)系统架构(量产推荐)
|
||||||
|
|
||||||
|
#### 7.3.1 总体思路
|
||||||
|
|
||||||
|
- MCU1(ESP-NOW 控制器,建议 ESP32-C3):
|
||||||
|
- 只负责:ESP-NOW(固定 ch1)、遥控器配对/命令接收、组控广播一致性、驱动输出(PWM/RMT/恒流等)。
|
||||||
|
- 不连接路由器(或不承担 Matter Wi-Fi)。
|
||||||
|
- MCU2(Matter 控制器,建议 ESP32-C6):
|
||||||
|
- 只负责:Matter over Wi-Fi(commissioning/长久在线/多生态)、(可选)Thread、Matter OTA、Groups/Scenes/状态机。
|
||||||
|
- 通过 UART/SPI 与 MCU1 交换“控制命令/状态变化/诊断”。
|
||||||
|
|
||||||
|
补充确认:本项目采用 UART 作为 MCU1↔MCU2 通信方式。
|
||||||
|
|
||||||
|
#### 7.3.2 数据流与一致性目标
|
||||||
|
|
||||||
|
- 遥控器 → MCU1(ESP-NOW RX)→
|
||||||
|
- MCU1 先本地执行灯控(保证延迟与体验不变)
|
||||||
|
- MCU1 同步上报事件给 MCU2(用于 Matter 属性更新与组/场景一致性)
|
||||||
|
- App/Matter → MCU2(属性更新/命令)→ MCU2 下发到 MCU1 → MCU1 执行驱动输出 → MCU1 回报最终状态给 MCU2(闭环)
|
||||||
|
|
||||||
|
#### 7.3.3 量产可测的关键指标
|
||||||
|
|
||||||
|
- 遥控器端到端延迟(按键到灯输出):目标 < 20 ms(以 MCU1 本地执行为准)
|
||||||
|
- Matter 状态同步延迟(灯输出到 Matter 属性更新可见):给出目标与测量方法(建议 < 200 ms)
|
||||||
|
- 长期稳定性:Wi-Fi/Matter 长久在线,不影响 MCU1 的 ESP-NOW 实时性
|
||||||
|
|
||||||
|
#### 7.3.4 PCB/硬件接口建议(小改动范围)
|
||||||
|
|
||||||
|
- UART:
|
||||||
|
- MCU1_TX -> MCU2_RX(GPIO 待定:MCU1=____ / MCU2=____)
|
||||||
|
- MCU1_RX <- MCU2_TX(GPIO 待定:MCU1=____ / MCU2=____)
|
||||||
|
- 可选硬件流控(建议预留焊盘,量产可按稳定性决定是否启用):
|
||||||
|
- MCU2->MCU1 `RESET_REQ`(请求 MCU1 执行:清码/恢复出厂/重新配对/进入测试)
|
||||||
|
- MCU1->MCU2 `IRQ_EVT`(有新事件/状态上报,降低轮询开销)
|
||||||
|
- 电平:两者均为 3.3V TTL(无需电平转换)
|
||||||
|
- 调试:建议预留测试点(TX/RX/GND)便于产线与现场抓包
|
||||||
|
|
||||||
|
## 8. 测试计划(面向交付物)
|
||||||
|
|
||||||
|
### 8.1 遥控器 + ESP-NOW(不改固件)
|
||||||
|
|
||||||
|
- 工厂重置:三次断电/复位触发工厂重置(含 5 秒确认窗)
|
||||||
|
- 配对:五次断电/复位进入配对模式;遥控器 slot 长按配对
|
||||||
|
- 单控:0x01..0x05 全命令覆盖,重复按键/长按/连发
|
||||||
|
- 组控:遥控器广播组命令,多个控制器同步输出一致
|
||||||
|
- 延迟:示波器/逻辑分析仪测量(按键触发到 GPIO/PWM 变化),记录 P50/P95
|
||||||
|
|
||||||
|
### 8.2 Matter 多生态(MCU2)
|
||||||
|
|
||||||
|
- Apple Home / Google Home / Alexa(至少两项)commissioning 演示
|
||||||
|
- Clusters:OnOff/LevelControl/Groups/Scenes(双色温含 ColorControl)
|
||||||
|
- OTA:升级演示 + 回滚验证
|
||||||
|
|
||||||
|
### 8.3 共存与稳定性
|
||||||
|
|
||||||
|
- Wi-Fi 长久在线(24h/72h)期间,遥控器控制无明显延迟/无丢包异常
|
||||||
|
- 异常恢复:
|
||||||
|
- MCU1 重启不影响 MCU2(Matter 仍在线;状态恢复后同步)
|
||||||
|
- MCU2 重启不影响 MCU1(遥控器控制不中断;MCU2 恢复后重新拉取状态)
|
||||||
|
|
||||||
|
## 9. Matter 功能测试用例(建议用 chip-tool 记录)
|
||||||
|
|
||||||
|
### Endpoint 1(单色灯:开关/调光)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chip-tool onoff on 1 1
|
||||||
|
chip-tool onoff off 1 1
|
||||||
|
chip-tool levelcontrol movetolevelwithonoff 1 1 10 0 0
|
||||||
|
chip-tool levelcontrol movetolevelwithonoff 1 1 200 0 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Endpoint 2(双色温灯:开关/调光/色温)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chip-tool onoff on 1 2
|
||||||
|
chip-tool onoff off 1 2
|
||||||
|
chip-tool levelcontrol movetolevelwithonoff 1 2 20 0 0
|
||||||
|
chip-tool levelcontrol movetolevelwithonoff 1 2 220 0 0
|
||||||
|
chip-tool colorcontrol movetocolortemperature 1 2 153 0 0
|
||||||
|
chip-tool colorcontrol movetocolortemperature 1 2 450 0 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 10. 风险与注意事项
|
||||||
|
|
||||||
|
- ESPNOW channel 固定为 1:当路由器信道不可固定到 1 且遥控器固件不可改时,单芯片方案存在先天冲突,需要改架构。
|
||||||
|
- 单色灯“白光”体验可能受硬件(RGB 三色灯珠)限制,软件无法消除近距离三色颗粒。
|
||||||
|
- 双色温(SK6812 RGBW)“色温”为近似实现:不同亮度下可能存在色偏;需要通过端点/曲线/gamma 与 RGB/W 分配进行校准。
|
||||||
|
- Thread + Wi-Fi 混合网络模式需要明确最终产品拓扑与测试方法。
|
||||||
|
|
||||||
|
## 11. MCU 间通信协议草案(方案 A)
|
||||||
|
|
||||||
|
### 11.1 物理层与链路建议
|
||||||
|
|
||||||
|
- UART:建议 921600 或 1Mbps,8N1
|
||||||
|
- 帧格式:固定 header + version + flags + type + seq + len + payload + CRC32
|
||||||
|
- 可靠性建议:
|
||||||
|
- 带 `seq` 与 `ACK`(至少对“状态设置/模式切换/工厂重置”等关键命令)
|
||||||
|
- 对“按键事件上报”可不必 ACK,但需要丢包容忍(MCU2 以 MCU1 的最终状态为准)
|
||||||
|
|
||||||
|
### 11.1.1 帧格式(建议稿,可直接实现)
|
||||||
|
|
||||||
|
- `SOF`:2 bytes,固定 `0x55 0xAA`
|
||||||
|
- `VER`:1 byte,协议版本(初版 `0x01`)
|
||||||
|
- `FLAGS`:1 byte
|
||||||
|
- bit0:是否需要 ACK
|
||||||
|
- bit1:是否为 ACK 包
|
||||||
|
- bit2:错误包
|
||||||
|
- bit3..7:预留
|
||||||
|
- `TYPE`:1 byte,消息类型
|
||||||
|
- `SEQ`:2 bytes,递增序号(小端)
|
||||||
|
- `LEN`:2 bytes,payload 长度(小端,0..1024 建议上限)
|
||||||
|
- `PAYLOAD`:LEN bytes
|
||||||
|
- `CRC32`:4 bytes(对从 `VER` 到 `PAYLOAD` 的 CRC32,小端)
|
||||||
|
|
||||||
|
### 11.1.2 ACK/重试/超时(建议稿)
|
||||||
|
|
||||||
|
- 对 `FLAGS.need_ack=1` 的包:
|
||||||
|
- 接收方在成功处理后回 `ACK` 包(`FLAGS.is_ack=1`,`SEQ` 原样回显,`TYPE`=原 TYPE 或 `TYPE=ACK(0x7F)` 二选一)
|
||||||
|
- 发送方超时 `T_ACK=50ms` 未收到 ACK:重发,最多 `N_RETRY=3`
|
||||||
|
- 连续失败后进入降级策略:记录错误计数并上报 `EVT_DIAG`(或触发重新握手)
|
||||||
|
- 对 `EVT_KEY_CMD`:可 `need_ack=0`(允许丢);但要求 MCU1 后续用 `EVT_LOCAL_STATE` 做闭环状态同步
|
||||||
|
|
||||||
|
### 11.1.3 上电/复位握手(建议稿)
|
||||||
|
|
||||||
|
- MCU2 启动后发送 `HELLO`(包含 MCU2 fw_ver/proto_ver/boot_reason)
|
||||||
|
- MCU1 回 `HELLO_RSP`(包含 MCU1 fw_ver/proto_ver、灯型/能力、当前输出状态摘要)
|
||||||
|
- MCU2 收到后发送 `GET_STATE`(拉取完整状态),并以此刷新 Matter 属性(避免 MCU2 重启后状态漂移)
|
||||||
|
|
||||||
|
### 11.2 消息类型(最小集)
|
||||||
|
|
||||||
|
- `EVT_KEY_CMD`(MCU1→MCU2):遥控器命令事件
|
||||||
|
- 字段:cmd(0x01..0x05/扩展)、src_mac、timestamp、group_mode/slot
|
||||||
|
- `EVT_LOCAL_STATE`(MCU1→MCU2):MCU1 本地执行后的最终状态
|
||||||
|
- 字段:endpoint/light_id、onoff、level、cct(如有)、transition_time
|
||||||
|
- `SET_STATE`(MCU2→MCU1):来自 Matter 的控制请求
|
||||||
|
- 字段:目标灯/组、onoff/level/cct、期望渐变时间
|
||||||
|
- `SET_MODE`(MCU2→MCU1):模式切换(配对、清码、恢复出厂、进入测试模式)
|
||||||
|
- `HEARTBEAT`(双向):存活与版本信息(fw_ver、proto_ver、uptime、heap)
|
||||||
|
|
||||||
|
建议补充类型:
|
||||||
|
|
||||||
|
- `GET_STATE`(MCU2→MCU1):请求 MCU1 上报完整状态
|
||||||
|
- `EVT_DIAG`(双向):错误码/计数器(CRC 错、丢包、重试次数、WDT、重启原因)
|
||||||
|
|
||||||
|
### 11.2.1 字段定义建议(便于落地与调试)
|
||||||
|
|
||||||
|
- `light_id`:1 byte
|
||||||
|
- `0x01` 单色灯
|
||||||
|
- `0x02` 双色温灯
|
||||||
|
- `onoff`:1 byte(0/1)
|
||||||
|
- `level`:1 byte(0..254,按 Matter 约定)
|
||||||
|
- `cct_mireds`:2 bytes(小端,按 Matter ColorTemperatureMireds)
|
||||||
|
- `transition_ms`:2 bytes(小端)
|
||||||
|
- `timestamp_ms`:4 bytes(小端,MCU1 uptime 毫秒)
|
||||||
|
|
||||||
|
### 11.3 一致性原则(避免双写打架)
|
||||||
|
|
||||||
|
- MCU1 为“灯输出唯一权威”(source of truth for physical output)。
|
||||||
|
- MCU2 为“ Matter 属性权威”(source of truth for ecosystem state)。
|
||||||
|
- MCU2 更新 Matter 属性应以 `EVT_LOCAL_STATE` 为准,而不是以 `EVT_KEY_CMD` 直接推导(防止执行失败/限幅/场景叠加导致不一致)。
|
||||||
|
|
||||||
|
## 11.4 PCB 连线清单(方案 A,UART)
|
||||||
|
|
||||||
|
- UART:
|
||||||
|
- MCU1_TX -> MCU2_RX(GPIO 待定:MCU1=____ / MCU2=____)
|
||||||
|
- MCU1_RX <- MCU2_TX(GPIO 待定:MCU1=____ / MCU2=____)
|
||||||
|
- 可选硬件流控(建议预留焊盘,量产可按稳定性决定是否启用):
|
||||||
|
- MCU1_RTS / MCU1_CTS
|
||||||
|
- MCU2_RTS / MCU2_CTS
|
||||||
|
- 额外控制/中断线(建议预留):
|
||||||
|
- MCU2->MCU1 `RESET_REQ`(请求 MCU1 执行:清码/恢复出厂/重新配对/进入测试)
|
||||||
|
- MCU1->MCU2 `IRQ_EVT`(有新事件/状态上报,降低轮询开销)
|
||||||
|
- 电平:两者均为 3.3V TTL(无需电平转换)
|
||||||
|
- 调试:建议预留测试点(TX/RX/GND)便于产线与现场抓包
|
||||||
|
|
||||||
|
## 13. 可对外汇报摘要(可直接发甲方)
|
||||||
|
|
||||||
|
本阶段已完成 ESP32-C6 Matter + ESP-NOW 混合固件的核心功能联调:固件已实现双 endpoint(单色灯 + 双色温灯)并通过 iOS Home 完成 Matter commissioning 与控制验证;同时接入甲方量产遥控器的 ESP-NOW 协议(channel=1、命令 0x01..0x05/0xA5),可通过“5 次重启进入配对模式 + 遥控器 Zone 配对”实现一台遥控器(Zone1/Zone2)分别绑定两台 ESP32-C6 灯具。当前 APP(iOS Home)与遥控器均可对两台设备进行控制;设备支持 HTTP OTA(远程服务器下载升级,支持双 OTA 分区切换),已验证升级后版本号变化。下一步将推进 Google Home/Alexa/RainMaker 等生态兼容性测试,并固化交付脚本、测试报告与完整技术文档。
|
||||||
|
|
||||||
40
01_Source/matter-light-c6-wifi/README.md
Normal file
40
01_Source/matter-light-c6-wifi/README.md
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Light
|
||||||
|
|
||||||
|
This example creates a Color Temperature Light device using the ESP
|
||||||
|
Matter data model.
|
||||||
|
|
||||||
|
See the [docs](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html) for more information about building and flashing the firmware.
|
||||||
|
|
||||||
|
## 1. Additional Environment Setup
|
||||||
|
|
||||||
|
No additional setup is required.
|
||||||
|
|
||||||
|
## 2. Post Commissioning Setup
|
||||||
|
|
||||||
|
No additional setup is required.
|
||||||
|
|
||||||
|
## 3. Device Performance
|
||||||
|
|
||||||
|
### 3.1 Memory usage
|
||||||
|
|
||||||
|
The following is the Memory and Flash Usage.
|
||||||
|
|
||||||
|
- `Bootup` == Device just finished booting up. Device is not
|
||||||
|
commissionined or connected to wifi yet.
|
||||||
|
- `After Commissioning` == Device is conneted to wifi and is also
|
||||||
|
commissioned and is rebooted.
|
||||||
|
- device used: esp32c3_devkit_m
|
||||||
|
- tested on:
|
||||||
|
[6a244a7](https://github.com/espressif/esp-matter/commit/6a244a7b1e5c70b0aa1bf57254f19718b0755d95)
|
||||||
|
(2022-06-16)
|
||||||
|
|
||||||
|
| | Bootup | After Commissioning |
|
||||||
|
|:- |:-: |:-: |
|
||||||
|
|**Free Internal Memory** |108KB |105KB |
|
||||||
|
|
||||||
|
**Flash Usage**: Firmware binary size: 1.26MB
|
||||||
|
|
||||||
|
This should give you a good idea about the amount of free memory that is
|
||||||
|
available for you to run your application's code.
|
||||||
|
|
||||||
|
Applications that do not require BLE post commissioning, can disable it using app_ble_disable() once commissioning is complete. It is not done explicitly because of a known issue with esp32c3 and will be fixed with the next IDF release (v4.4.2).
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c5"
|
||||||
|
|
||||||
|
# libsodium
|
||||||
|
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
|
||||||
|
|
||||||
|
# NIMBLE
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_EXT_ADV=n
|
||||||
|
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
|
||||||
|
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n
|
||||||
|
|
||||||
|
# Enable OpenThread
|
||||||
|
CONFIG_OPENTHREAD_ENABLED=y
|
||||||
|
CONFIG_OPENTHREAD_SRP_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_DNS_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
|
||||||
|
CONFIG_OPENTHREAD_CLI=n
|
||||||
|
|
||||||
|
# Disable lwip ipv6 autoconfig
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=n
|
||||||
|
|
||||||
|
# Use a custom partition table
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# LwIP config for OpenThread
|
||||||
|
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||||
|
CONFIG_LWIP_MULTICAST_PING=y
|
||||||
|
|
||||||
|
# MDNS platform
|
||||||
|
CONFIG_USE_MINIMAL_MDNS=n
|
||||||
|
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
|
||||||
|
|
||||||
|
# Enable OTA Requestor
|
||||||
|
CONFIG_ENABLE_OTA_REQUESTOR=y
|
||||||
|
|
||||||
|
# Disable STA for ESP32C5
|
||||||
|
CONFIG_ENABLE_WIFI_STATION=n
|
||||||
|
|
||||||
|
# Button
|
||||||
|
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||||
|
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||||
|
|
||||||
|
# Enable chip shell
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=y
|
||||||
|
|
||||||
|
# ESP32-C5-DevKitC-1 Settings
|
||||||
|
# Buttons
|
||||||
|
CONFIG_BSP_BUTTONS_NUM=1
|
||||||
|
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
|
||||||
|
CONFIG_BSP_BUTTON_1_GPIO=28
|
||||||
|
CONFIG_BSP_BUTTON_1_LEVEL=0
|
||||||
|
# LEDs
|
||||||
|
CONFIG_BSP_LEDS_NUM=1
|
||||||
|
CONFIG_BSP_LED_TYPE_RGB=y
|
||||||
|
CONFIG_BSP_LED_RGB_GPIO=27
|
||||||
|
CONFIG_BSP_LED_RGB_BACKEND_RMT=y
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c5"
|
||||||
|
|
||||||
|
# libsodium
|
||||||
|
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
|
||||||
|
|
||||||
|
# NIMBLE
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_EXT_ADV=n
|
||||||
|
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
|
||||||
|
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n
|
||||||
|
|
||||||
|
# Enable OpenThread
|
||||||
|
CONFIG_OPENTHREAD_ENABLED=y
|
||||||
|
CONFIG_OPENTHREAD_SRP_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_DNS_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
|
||||||
|
CONFIG_OPENTHREAD_CLI=n
|
||||||
|
|
||||||
|
# Disable lwip ipv6 autoconfig
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=n
|
||||||
|
|
||||||
|
# Use a custom partition table
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# LwIP config for OpenThread
|
||||||
|
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||||
|
CONFIG_LWIP_MULTICAST_PING=y
|
||||||
|
|
||||||
|
# MDNS platform
|
||||||
|
CONFIG_USE_MINIMAL_MDNS=n
|
||||||
|
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
|
||||||
|
|
||||||
|
# Enable OTA Requestor
|
||||||
|
CONFIG_ENABLE_OTA_REQUESTOR=y
|
||||||
|
|
||||||
|
# Disable STA for ESP32C5
|
||||||
|
CONFIG_ENABLE_WIFI_STATION=n
|
||||||
|
|
||||||
|
# Button
|
||||||
|
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||||
|
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||||
|
|
||||||
|
# Enable chip shell
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=y
|
||||||
|
|
||||||
|
# ESP32-C5-DevKitC-1 Settings
|
||||||
|
# Buttons
|
||||||
|
CONFIG_BSP_BUTTONS_NUM=1
|
||||||
|
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
|
||||||
|
CONFIG_BSP_BUTTON_1_GPIO=28
|
||||||
|
CONFIG_BSP_BUTTON_1_LEVEL=0
|
||||||
|
# LEDs
|
||||||
|
CONFIG_BSP_LEDS_NUM=1
|
||||||
|
CONFIG_BSP_LED_TYPE_RGB=y
|
||||||
|
CONFIG_BSP_LED_RGB_GPIO=27
|
||||||
|
CONFIG_BSP_LED_RGB_BACKEND_RMT=y
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c5"
|
||||||
|
|
||||||
|
# libsodium
|
||||||
|
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
|
||||||
|
|
||||||
|
# NIMBLE
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_EXT_ADV=n
|
||||||
|
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
|
||||||
|
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n
|
||||||
|
|
||||||
|
# Enable OpenThread
|
||||||
|
CONFIG_OPENTHREAD_ENABLED=y
|
||||||
|
CONFIG_OPENTHREAD_SRP_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_DNS_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
|
||||||
|
CONFIG_OPENTHREAD_CLI=n
|
||||||
|
|
||||||
|
# Disable lwip ipv6 autoconfig
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=n
|
||||||
|
|
||||||
|
# Use a custom partition table
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# This example use 3 dynamic endpoints: RootNode, light, and secondary network commissioning
|
||||||
|
CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT=3
|
||||||
|
|
||||||
|
# LwIP config for OpenThread
|
||||||
|
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||||
|
CONFIG_LWIP_MULTICAST_PING=y
|
||||||
|
|
||||||
|
# MDNS platform
|
||||||
|
CONFIG_USE_MINIMAL_MDNS=n
|
||||||
|
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
|
||||||
|
|
||||||
|
# Enable OTA Requestor
|
||||||
|
CONFIG_ENABLE_OTA_REQUESTOR=y
|
||||||
|
|
||||||
|
# Disable AP
|
||||||
|
CONFIG_ENABLE_WIFI_STATION=y
|
||||||
|
CONFIG_ENABLE_WIFI_AP=n
|
||||||
|
|
||||||
|
# Button
|
||||||
|
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||||
|
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||||
|
|
||||||
|
# Enable chip shell
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=y
|
||||||
|
|
||||||
|
# ESP32-C5-DevKitC-1 Settings
|
||||||
|
# Buttons
|
||||||
|
CONFIG_BSP_BUTTONS_NUM=1
|
||||||
|
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
|
||||||
|
CONFIG_BSP_BUTTON_1_GPIO=28
|
||||||
|
CONFIG_BSP_BUTTON_1_LEVEL=0
|
||||||
|
# LEDs
|
||||||
|
CONFIG_BSP_LEDS_NUM=1
|
||||||
|
CONFIG_BSP_LED_TYPE_RGB=y
|
||||||
|
CONFIG_BSP_LED_RGB_GPIO=27
|
||||||
|
CONFIG_BSP_LED_RGB_BACKEND_RMT=y
|
||||||
|
|
||||||
|
# Firmware size optimization
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
|
||||||
|
CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS=y
|
||||||
|
CONFIG_NEWLIB_NANO_FORMAT=y
|
||||||
|
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
|
||||||
|
|
||||||
|
# Set endpoint id for Thread and Wi-Fi, depending on the secondary network interface endpoint id.
|
||||||
|
CONFIG_THREAD_NETWORK_ENDPOINT_ID=2
|
||||||
|
CONFIG_WIFI_NETWORK_ENDPOINT_ID=0
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c5"
|
||||||
|
|
||||||
|
# libsodium
|
||||||
|
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
|
||||||
|
|
||||||
|
# NIMBLE
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_EXT_ADV=n
|
||||||
|
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
|
||||||
|
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n
|
||||||
|
|
||||||
|
# Enable OpenThread
|
||||||
|
CONFIG_OPENTHREAD_ENABLED=y
|
||||||
|
CONFIG_OPENTHREAD_SRP_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_DNS_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
|
||||||
|
CONFIG_OPENTHREAD_CLI=n
|
||||||
|
|
||||||
|
# Disable lwip ipv6 autoconfig
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=n
|
||||||
|
|
||||||
|
# Use a custom partition table
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# This example use 3 dynamic endpoints: RootNode, light, and secondary network commissioning
|
||||||
|
CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT=3
|
||||||
|
|
||||||
|
# LwIP config for OpenThread
|
||||||
|
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||||
|
CONFIG_LWIP_MULTICAST_PING=y
|
||||||
|
|
||||||
|
# MDNS platform
|
||||||
|
CONFIG_USE_MINIMAL_MDNS=n
|
||||||
|
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
|
||||||
|
|
||||||
|
# Enable OTA Requestor
|
||||||
|
CONFIG_ENABLE_OTA_REQUESTOR=y
|
||||||
|
|
||||||
|
# Disable AP
|
||||||
|
CONFIG_ENABLE_WIFI_STATION=y
|
||||||
|
CONFIG_ENABLE_WIFI_AP=n
|
||||||
|
|
||||||
|
# Button
|
||||||
|
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||||
|
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||||
|
|
||||||
|
# Enable chip shell
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=y
|
||||||
|
|
||||||
|
# ESP32-C5-DevKitC-1 Settings
|
||||||
|
# Buttons
|
||||||
|
CONFIG_BSP_BUTTONS_NUM=1
|
||||||
|
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
|
||||||
|
CONFIG_BSP_BUTTON_1_GPIO=28
|
||||||
|
CONFIG_BSP_BUTTON_1_LEVEL=0
|
||||||
|
# LEDs
|
||||||
|
CONFIG_BSP_LEDS_NUM=1
|
||||||
|
CONFIG_BSP_LED_TYPE_RGB=y
|
||||||
|
CONFIG_BSP_LED_RGB_GPIO=27
|
||||||
|
CONFIG_BSP_LED_RGB_BACKEND_RMT=y
|
||||||
|
|
||||||
|
# Firmware size optimization
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
|
||||||
|
CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS=y
|
||||||
|
CONFIG_NEWLIB_NANO_FORMAT=y
|
||||||
|
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
|
||||||
|
|
||||||
|
# Set endpoint id for Thread and Wi-Fi, depending on the secondary network interface endpoint id.
|
||||||
|
CONFIG_THREAD_NETWORK_ENDPOINT_ID=2
|
||||||
|
CONFIG_WIFI_NETWORK_ENDPOINT_ID=0
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c6"
|
||||||
|
|
||||||
|
# libsodium
|
||||||
|
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
|
||||||
|
|
||||||
|
# NIMBLE
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_EXT_ADV=n
|
||||||
|
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
|
||||||
|
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n
|
||||||
|
|
||||||
|
# Enable OpenThread
|
||||||
|
CONFIG_OPENTHREAD_ENABLED=y
|
||||||
|
CONFIG_OPENTHREAD_SRP_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_DNS_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
|
||||||
|
CONFIG_OPENTHREAD_CLI=n
|
||||||
|
|
||||||
|
# Disable lwip ipv6 autoconfig
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=n
|
||||||
|
|
||||||
|
# Use a custom partition table
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# LwIP config for OpenThread
|
||||||
|
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||||
|
CONFIG_LWIP_MULTICAST_PING=y
|
||||||
|
|
||||||
|
# MDNS platform
|
||||||
|
CONFIG_USE_MINIMAL_MDNS=n
|
||||||
|
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
|
||||||
|
|
||||||
|
# Enable OTA Requestor
|
||||||
|
CONFIG_ENABLE_OTA_REQUESTOR=y
|
||||||
|
|
||||||
|
# Disable STA for ESP32C6
|
||||||
|
CONFIG_ENABLE_WIFI_STATION=n
|
||||||
|
|
||||||
|
# Button
|
||||||
|
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||||
|
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||||
|
|
||||||
|
# Enable chip shell
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=y
|
||||||
|
|
||||||
|
# ESP32-C6-DevKitM-1 Settings
|
||||||
|
# Buttons
|
||||||
|
CONFIG_BSP_BUTTONS_NUM=1
|
||||||
|
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
|
||||||
|
CONFIG_BSP_BUTTON_1_GPIO=9
|
||||||
|
CONFIG_BSP_BUTTON_1_LEVEL=0
|
||||||
|
# LEDs
|
||||||
|
CONFIG_BSP_LEDS_NUM=1
|
||||||
|
CONFIG_BSP_LED_TYPE_RGB=y
|
||||||
|
CONFIG_BSP_LED_RGB_GPIO=8
|
||||||
|
CONFIG_BSP_LED_RGB_BACKEND_RMT=y
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c6"
|
||||||
|
|
||||||
|
# libsodium
|
||||||
|
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
|
||||||
|
|
||||||
|
# NIMBLE
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_EXT_ADV=n
|
||||||
|
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
|
||||||
|
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n
|
||||||
|
|
||||||
|
# Enable OpenThread
|
||||||
|
CONFIG_OPENTHREAD_ENABLED=y
|
||||||
|
CONFIG_OPENTHREAD_SRP_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_DNS_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
|
||||||
|
CONFIG_OPENTHREAD_CLI=n
|
||||||
|
|
||||||
|
# Disable lwip ipv6 autoconfig
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=n
|
||||||
|
|
||||||
|
# Use a custom partition table
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# LwIP config for OpenThread
|
||||||
|
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||||
|
CONFIG_LWIP_MULTICAST_PING=y
|
||||||
|
|
||||||
|
# MDNS platform
|
||||||
|
CONFIG_USE_MINIMAL_MDNS=n
|
||||||
|
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
|
||||||
|
|
||||||
|
# Enable OTA Requestor
|
||||||
|
CONFIG_ENABLE_OTA_REQUESTOR=y
|
||||||
|
|
||||||
|
# Disable AP
|
||||||
|
CONFIG_ENABLE_WIFI_STATION=y
|
||||||
|
CONFIG_ENABLE_WIFI_AP=n
|
||||||
|
|
||||||
|
# Button
|
||||||
|
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||||
|
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||||
|
|
||||||
|
# Enable chip shell
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=y
|
||||||
|
|
||||||
|
# This example use 3 dynamic endpoints: RootNode, light, and secondary network commissioning
|
||||||
|
CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT=3
|
||||||
|
|
||||||
|
# ESP32-C6-DevKitM-1 Settings
|
||||||
|
# Buttons
|
||||||
|
CONFIG_BSP_BUTTONS_NUM=1
|
||||||
|
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
|
||||||
|
CONFIG_BSP_BUTTON_1_GPIO=9
|
||||||
|
CONFIG_BSP_BUTTON_1_LEVEL=0
|
||||||
|
# LEDs
|
||||||
|
CONFIG_BSP_LEDS_NUM=1
|
||||||
|
CONFIG_BSP_LED_TYPE_RGB=y
|
||||||
|
CONFIG_BSP_LED_RGB_GPIO=8
|
||||||
|
CONFIG_BSP_LED_RGB_BACKEND_RMT=y
|
||||||
|
|
||||||
|
# Firmware size optimization
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
|
||||||
|
CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS=y
|
||||||
|
CONFIG_NEWLIB_NANO_FORMAT=y
|
||||||
|
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
|
||||||
|
|
||||||
|
# Set endpoint id for Thread and Wi-Fi, depending on the secondary network interface endpoint id.
|
||||||
|
CONFIG_THREAD_NETWORK_ENDPOINT_ID=2
|
||||||
|
CONFIG_WIFI_NETWORK_ENDPOINT_ID=0
|
||||||
|
|
@ -0,0 +1,174 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c2"
|
||||||
|
|
||||||
|
# Compiler options
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||||
|
CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS=y
|
||||||
|
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
|
||||||
|
|
||||||
|
## NimBLE Options
|
||||||
|
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
|
||||||
|
CONFIG_BT_NIMBLE_MAX_BONDS=2
|
||||||
|
CONFIG_BT_NIMBLE_MAX_CCCDS=2
|
||||||
|
CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=3072
|
||||||
|
CONFIG_BT_NIMBLE_ROLE_CENTRAL=n
|
||||||
|
CONFIG_BT_NIMBLE_ROLE_OBSERVER=n
|
||||||
|
CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
|
||||||
|
CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n
|
||||||
|
CONFIG_BT_NIMBLE_WHITELIST_SIZE=1
|
||||||
|
CONFIG_BT_NIMBLE_GATT_MAX_PROCS=1
|
||||||
|
CONFIG_BT_NIMBLE_MSYS_1_BLOCK_COUNT=10
|
||||||
|
CONFIG_BT_NIMBLE_MSYS_1_BLOCK_SIZE=100
|
||||||
|
CONFIG_BT_NIMBLE_MSYS_2_BLOCK_COUNT=4
|
||||||
|
CONFIG_BT_NIMBLE_MSYS_2_BLOCK_SIZE=320
|
||||||
|
CONFIG_BT_NIMBLE_ACL_BUF_COUNT=5
|
||||||
|
CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=5
|
||||||
|
CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=3
|
||||||
|
CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n
|
||||||
|
|
||||||
|
## Controller Options
|
||||||
|
CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE=3072
|
||||||
|
CONFIG_BT_LE_LL_RESOLV_LIST_SIZE=1
|
||||||
|
CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT=1
|
||||||
|
|
||||||
|
# Release BT IRAM memory
|
||||||
|
CONFIG_BT_RELEASE_IRAM=y
|
||||||
|
|
||||||
|
# SPI Configuration
|
||||||
|
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
|
||||||
|
CONFIG_SPI_SLAVE_ISR_IN_IRAM=n
|
||||||
|
|
||||||
|
# Ethernet
|
||||||
|
CONFIG_ETH_USE_SPI_ETHERNET=n
|
||||||
|
|
||||||
|
# Event Loop Library
|
||||||
|
CONFIG_ESP_EVENT_POST_FROM_ISR=n
|
||||||
|
|
||||||
|
# Chip revision
|
||||||
|
CONFIG_ESP32C2_REV2_DEVELOPMENT=y
|
||||||
|
|
||||||
|
# Main XTAL Config
|
||||||
|
CONFIG_XTAL_FREQ_26=y
|
||||||
|
CONFIG_XTAL_FREQ_40=n
|
||||||
|
|
||||||
|
# ESP Ringbuf
|
||||||
|
CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||||
|
CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH=y
|
||||||
|
|
||||||
|
# ESP System Settings
|
||||||
|
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=16
|
||||||
|
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2048
|
||||||
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=3072
|
||||||
|
|
||||||
|
## Memory protection
|
||||||
|
CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT=n
|
||||||
|
|
||||||
|
# High resolution timer (esp_timer)
|
||||||
|
CONFIG_ESP_TIMER_TASK_STACK_SIZE=2048
|
||||||
|
|
||||||
|
# Wi-Fi
|
||||||
|
CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=n
|
||||||
|
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=3
|
||||||
|
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=6
|
||||||
|
CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=6
|
||||||
|
CONFIG_ESP32_WIFI_IRAM_OPT=n
|
||||||
|
CONFIG_ESP32_WIFI_RX_IRAM_OPT=n
|
||||||
|
CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=n
|
||||||
|
CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=n
|
||||||
|
CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=n
|
||||||
|
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
|
||||||
|
|
||||||
|
# FreeRTOS
|
||||||
|
## Kernel
|
||||||
|
CONFIG_FREERTOS_HZ=1000
|
||||||
|
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
|
||||||
|
## Port
|
||||||
|
CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=n
|
||||||
|
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||||
|
CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y
|
||||||
|
|
||||||
|
# Hardware Abstraction Layer (HAL) and Low Level (LL)
|
||||||
|
CONFIG_HAL_ASSERTION_DISABLE=y
|
||||||
|
|
||||||
|
# LWIP
|
||||||
|
CONFIG_LWIP_IPV4=n
|
||||||
|
CONFIG_LWIP_MAX_SOCKETS=5
|
||||||
|
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=16
|
||||||
|
CONFIG_LWIP_DHCPS=n
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=y
|
||||||
|
CONFIG_LWIP_MAX_ACTIVE_TCP=5
|
||||||
|
CONFIG_LWIP_MAX_LISTENING_TCP=5
|
||||||
|
CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=n
|
||||||
|
CONFIG_LWIP_TCP_SYNMAXRTX=12
|
||||||
|
CONFIG_LWIP_TCP_MSL=40000
|
||||||
|
CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=16000
|
||||||
|
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=4096
|
||||||
|
CONFIG_LWIP_TCP_WND_DEFAULT=2440
|
||||||
|
CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS=y
|
||||||
|
CONFIG_LWIP_TCP_RTO_TIME=1500
|
||||||
|
CONFIG_LWIP_MAX_UDP_PCBS=8
|
||||||
|
CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=2560
|
||||||
|
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
|
||||||
|
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
|
||||||
|
|
||||||
|
# mbedTLS
|
||||||
|
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
|
||||||
|
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
|
||||||
|
CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=y
|
||||||
|
CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y
|
||||||
|
CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=n
|
||||||
|
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y
|
||||||
|
CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y
|
||||||
|
CONFIG_MBEDTLS_SSL_PROTO_SSL3=n
|
||||||
|
CONFIG_MBEDTLS_SSL_PROTO_TLS1=n
|
||||||
|
CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=n
|
||||||
|
|
||||||
|
# ESP-MQTT Configurations
|
||||||
|
CONFIG_MQTT_PROTOCOL_311=n
|
||||||
|
|
||||||
|
# Protocomm
|
||||||
|
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=n
|
||||||
|
CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=n
|
||||||
|
|
||||||
|
# SPI Flash driver
|
||||||
|
CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=n
|
||||||
|
CONFIG_SPI_FLASH_ROM_IMPL=y
|
||||||
|
|
||||||
|
# Websocket
|
||||||
|
CONFIG_WS_TRANSPORT=n
|
||||||
|
|
||||||
|
# Virtual file system
|
||||||
|
CONFIG_VFS_SUPPORT_DIR=n
|
||||||
|
CONFIG_VFS_SUPPORT_SELECT=n
|
||||||
|
CONFIG_VFS_SUPPORT_TERMIOS=n
|
||||||
|
|
||||||
|
# Wear Levelling
|
||||||
|
CONFIG_WL_SECTOR_SIZE_512=y
|
||||||
|
|
||||||
|
# CHIP Core
|
||||||
|
## General Options
|
||||||
|
CONFIG_MAX_EXCHANGE_CONTEXTS=6
|
||||||
|
CONFIG_MAX_BINDINGS=6
|
||||||
|
CONFIG_MAX_PEER_NODES=12
|
||||||
|
CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS=6
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=n
|
||||||
|
CONFIG_DISABLE_IPV4=y
|
||||||
|
CONFIG_BUILD_CHIP_TESTS=n
|
||||||
|
## Networking Options
|
||||||
|
CONFIG_NUM_TCP_ENDPOINTS=1
|
||||||
|
CONFIG_NUM_UDP_ENDPOINTS=6
|
||||||
|
## System Options
|
||||||
|
CONFIG_NUM_TIMERS=24
|
||||||
|
CONFIG_ENABLE_OTA_REQUESTOR=y
|
||||||
|
|
||||||
|
# CHIP Device Layer
|
||||||
|
## General Options
|
||||||
|
CONFIG_CHIP_TASK_STACK_SIZE=7168
|
||||||
|
CONFIG_MAX_EVENT_QUEUE_SIZE=20
|
||||||
|
## Event Logging Options
|
||||||
|
CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=256
|
||||||
|
CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE=256
|
||||||
|
CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE=256
|
||||||
|
|
||||||
|
# ESP Matter
|
||||||
|
CONFIG_ESP_MATTER_MAX_DEVICE_TYPE_COUNT=4
|
||||||
|
CONFIG_ESP_MATTER_MAX_DYNAMIC_ENDPOINT_COUNT=4
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
# CMake Utilities
|
||||||
|
CONFIG_CU_RELINKER_ENABLE=y
|
||||||
|
CONFIG_CU_RELINKER_ENABLE_CUSTOMIZED_CONFIGURATION_FILES=y
|
||||||
|
CONFIG_CU_RELINKER_CUSTOMIZED_CONFIGURATION_FILES_PATH="../common/relinker/esp32c2_v5.1"
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
# CMake Utilities
|
||||||
|
CONFIG_CU_RELINKER_ENABLE=y
|
||||||
|
CONFIG_CU_RELINKER_ENABLE_CUSTOMIZED_CONFIGURATION_FILES=y
|
||||||
|
CONFIG_CU_RELINKER_CUSTOMIZED_CONFIGURATION_FILES_PATH="../common/relinker/esp32c2_v5.2"
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
# CMake Utilities
|
||||||
|
CONFIG_CU_RELINKER_ENABLE=y
|
||||||
|
CONFIG_CU_RELINKER_ENABLE_CUSTOMIZED_CONFIGURATION_FILES=y
|
||||||
|
CONFIG_CU_RELINKER_CUSTOMIZED_CONFIGURATION_FILES_PATH="../common/relinker/esp32c2_v5.4"
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c3"
|
||||||
|
|
||||||
|
# ESP32-C3-DevKitC-02 Settings
|
||||||
|
# Buttons
|
||||||
|
CONFIG_BSP_BUTTONS_NUM=1
|
||||||
|
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
|
||||||
|
CONFIG_BSP_BUTTON_1_GPIO=9
|
||||||
|
CONFIG_BSP_BUTTON_1_LEVEL=0
|
||||||
|
# LEDs
|
||||||
|
CONFIG_BSP_LEDS_NUM=1
|
||||||
|
CONFIG_BSP_LED_TYPE_RGB=y
|
||||||
|
CONFIG_BSP_LED_RGB_GPIO=8
|
||||||
|
CONFIG_BSP_LED_RGB_BACKEND_RMT=y
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c5"
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c61"
|
||||||
|
|
||||||
|
# ESP Ringbuf
|
||||||
|
CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||||
|
CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH=y
|
||||||
|
# FreeRTOS
|
||||||
|
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||||
|
CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y
|
||||||
|
|
||||||
|
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32h2"
|
||||||
|
|
||||||
|
# Enable OpenThread
|
||||||
|
CONFIG_OPENTHREAD_ENABLED=y
|
||||||
|
CONFIG_OPENTHREAD_SRP_CLIENT=y
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC=n
|
||||||
|
CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
|
||||||
|
CONFIG_OPENTHREAD_CLI=n
|
||||||
|
|
||||||
|
# Disable lwip ipv6 autoconfig
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=n
|
||||||
|
|
||||||
|
# LwIP config for OpenThread
|
||||||
|
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||||
|
CONFIG_LWIP_MULTICAST_PING=y
|
||||||
|
|
||||||
|
# MDNS platform
|
||||||
|
CONFIG_USE_MINIMAL_MDNS=n
|
||||||
|
|
||||||
|
# Disable STA
|
||||||
|
CONFIG_ENABLE_WIFI_STATION=n
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32p4"
|
||||||
|
|
||||||
|
# Enable BLE Host but use remote controller
|
||||||
|
CONFIG_BT_NIMBLE_TRANSPORT_UART=n
|
||||||
|
CONFIG_ESP_ENABLE_BT=y
|
||||||
|
|
||||||
|
# Increase main task stack size
|
||||||
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096
|
||||||
|
|
||||||
|
# Do not deinit BLE after commissioning
|
||||||
|
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n
|
||||||
|
|
||||||
|
# ESP32-P4 Function EV Board use ESP32C6 as slave device
|
||||||
|
CONFIG_SLAVE_IDF_TARGET_ESP32C6=y
|
||||||
|
|
||||||
|
# BSP button
|
||||||
|
CONFIG_BSP_BUTTON_1_GPIO=35
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32s3"
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Default to 921600 baud when flashing and monitoring device
|
||||||
|
CONFIG_ESPTOOLPY_BAUD_921600B=y
|
||||||
|
CONFIG_ESPTOOLPY_BAUD=921600
|
||||||
|
CONFIG_ESPTOOLPY_COMPRESSED=y
|
||||||
|
CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
|
||||||
|
CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
|
|
||||||
|
#enable BT
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
|
||||||
|
#disable BT connection reattempt
|
||||||
|
CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n
|
||||||
|
|
||||||
|
#enable lwip ipv6 autoconfig
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=y
|
||||||
|
|
||||||
|
# Use a custom partition table
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# Disable chip tests
|
||||||
|
CONFIG_BUILD_CHIP_TESTS=n
|
||||||
|
|
||||||
|
#enable lwIP route hooks
|
||||||
|
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
|
||||||
|
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
|
||||||
|
|
||||||
|
# Button
|
||||||
|
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||||
|
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||||
|
|
||||||
|
# External Platform
|
||||||
|
CONFIG_CHIP_ENABLE_EXTERNAL_PLATFORM=y
|
||||||
|
CONFIG_CHIP_EXTERNAL_PLATFORM_DIR="../../../../../platform/ESP32_custom"
|
||||||
|
CONFIG_CHIP_EXTERNAL_PLATFORM_INCLUDE_DIR="../../../../.."
|
||||||
|
|
||||||
|
# disable softap by default
|
||||||
|
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
|
||||||
|
|
||||||
|
# Disable DS Peripheral
|
||||||
|
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n
|
||||||
|
|
||||||
|
# Enable HKDF in mbedtls
|
||||||
|
CONFIG_MBEDTLS_HKDF_C=y
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Default to 921600 baud when flashing and monitoring device
|
||||||
|
CONFIG_ESPTOOLPY_BAUD_921600B=y
|
||||||
|
CONFIG_ESPTOOLPY_BAUD=921600
|
||||||
|
CONFIG_ESPTOOLPY_COMPRESSED=y
|
||||||
|
CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
|
||||||
|
CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
|
|
||||||
|
#enable BT
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
|
||||||
|
#disable BT connection reattempt
|
||||||
|
CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT=n
|
||||||
|
|
||||||
|
#enable lwip ipv6 autoconfig
|
||||||
|
CONFIG_LWIP_IPV6_AUTOCONFIG=y
|
||||||
|
|
||||||
|
# Use a custom partition table
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
|
||||||
|
# Disable chip shell
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=n
|
||||||
|
|
||||||
|
# Disable chip tests
|
||||||
|
CONFIG_BUILD_CHIP_TESTS=n
|
||||||
|
|
||||||
|
#enable lwIP route hooks
|
||||||
|
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
|
||||||
|
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
|
||||||
|
|
||||||
|
# Button
|
||||||
|
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||||
|
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||||
|
|
||||||
|
# External Platform
|
||||||
|
CONFIG_CHIP_ENABLE_EXTERNAL_PLATFORM=y
|
||||||
|
CONFIG_CHIP_EXTERNAL_PLATFORM_DIR="../../../../../builds/app-frameworks/platform/ESP32_custom"
|
||||||
|
CONFIG_CHIP_EXTERNAL_PLATFORM_INCLUDE_DIR="../../../../../builds/app-frameworks/"
|
||||||
|
|
||||||
|
# disable softap by default
|
||||||
|
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
|
||||||
|
|
||||||
|
# Disable DS Peripheral
|
||||||
|
CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n
|
||||||
|
|
||||||
|
# Enable HKDF in mbedtls
|
||||||
|
CONFIG_MBEDTLS_HKDF_C=y
|
||||||
|
|
||||||
|
# ESP32-DevKit Settings
|
||||||
|
# Buttons
|
||||||
|
CONFIG_BSP_BUTTONS_NUM=1
|
||||||
|
CONFIG_BSP_BUTTON_1_TYPE_GPIO=y
|
||||||
|
CONFIG_BSP_BUTTON_1_GPIO=0
|
||||||
|
CONFIG_BSP_BUTTON_1_LEVEL=0
|
||||||
|
# LEDs
|
||||||
|
CONFIG_BSP_LEDS_NUM=0
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=n
|
||||||
File diff suppressed because it is too large
Load Diff
211
01_Source/matter-light-c6-wifi/dependencies.lock
Normal file
211
01_Source/matter-light-c6-wifi/dependencies.lock
Normal file
|
|
@ -0,0 +1,211 @@
|
||||||
|
dependencies:
|
||||||
|
espressif/button:
|
||||||
|
component_hash: fccb18c37f1cfe0797b74a53a44d3f400f5fd01f4993b40052dfb7f401915089
|
||||||
|
dependencies:
|
||||||
|
- name: espressif/cmake_utilities
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
version: '*'
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=4.0'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 4.1.5
|
||||||
|
espressif/cbor:
|
||||||
|
component_hash: dad9ca860963e930366510a10b422b3125a4fb27b979712ed65efcbcd742de50
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.0'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 0.6.1~4
|
||||||
|
espressif/cmake_utilities:
|
||||||
|
component_hash: 05165f30922b422b4b90c08845e6d449329b97370fbd06309803d8cb539d79e3
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=4.1'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 1.1.1
|
||||||
|
espressif/esp-serial-flasher:
|
||||||
|
component_hash: dcc42a16712a1a636509cf0bf90e14032d7f2141784b533613b267b6aa318d52
|
||||||
|
dependencies: []
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 0.0.11
|
||||||
|
espressif/esp_delta_ota:
|
||||||
|
component_hash: 147161b602ef51e9f6649eb6d90c4d4ac3c94228cb264fa0e68be7877180462d
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=4.3'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.1.4
|
||||||
|
espressif/esp_diag_data_store:
|
||||||
|
component_hash: 93f20de81abb791b4482f1bc99afdc24b25c3ee42aacceeb636e9943e677b1c5
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.1'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 1.1.0
|
||||||
|
espressif/esp_diagnostics:
|
||||||
|
component_hash: 405803b11fbccfd9c8a26df0b1228081f588ffdb7d1e0c754300e7a2c6241aab
|
||||||
|
dependencies:
|
||||||
|
- name: espressif/rmaker_common
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
version: ~1.5.0
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.1'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 1.3.0
|
||||||
|
espressif/esp_encrypted_img:
|
||||||
|
component_hash: e5a065c140fbc6a69a1de4fa1731b7596cc34a4a50b57913b2dc34c9ad3a0a70
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=4.4'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 2.3.0
|
||||||
|
espressif/esp_insights:
|
||||||
|
component_hash: 5a394c1eacddff2dbeff840abb0108ad5f54fb076048520b50c3f4a9b59415fe
|
||||||
|
dependencies:
|
||||||
|
- name: espressif/cbor
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
version: ~0.6
|
||||||
|
- name: espressif/esp_diag_data_store
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
version: 1.1.0
|
||||||
|
- name: espressif/esp_diagnostics
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
version: '>=1.3.0'
|
||||||
|
- name: espressif/rmaker_common
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
version: ~1.5.0
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.1'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.3.1
|
||||||
|
espressif/esp_rcp_update:
|
||||||
|
component_hash: 37f535edd527a45faeaad649c0c56af36e5399074e52d83f0990fce466844dde
|
||||||
|
dependencies:
|
||||||
|
- name: espressif/esp-serial-flasher
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
version: ~0.0.0
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.0'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.3.1
|
||||||
|
espressif/esp_secure_cert_mgr:
|
||||||
|
component_hash: e8ce8d5ac0ef4ef5df12fdb266190413c4170ad39b394435f0e3115a4fddc6a6
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=4.3'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 2.7.2
|
||||||
|
espressif/jsmn:
|
||||||
|
component_hash: d80350c41bbaa827c98a25b6072df00884e72f54885996fab4a4f0aebce6b6c3
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=4.3'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 1.1.0
|
||||||
|
espressif/json_generator:
|
||||||
|
component_hash: 45033e1c199b13f1c8c1b544fb7d4e2df6a8e3071ebdcb1b22582b61a7974ff2
|
||||||
|
dependencies: []
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.1.2
|
||||||
|
espressif/json_parser:
|
||||||
|
component_hash: d74b81729ad06ec11ff5eb5b1b0d7df1d00e6027fc11471f4b139c70dcf1b1e4
|
||||||
|
dependencies:
|
||||||
|
- name: espressif/jsmn
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
rules:
|
||||||
|
- if: idf_version >=5.0
|
||||||
|
version: ~1.1
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.0.3
|
||||||
|
espressif/led_strip:
|
||||||
|
component_hash: e8179c56057c243e80a8286c39361eb4bef33e42eb5f7fc841ea877597ca13f7
|
||||||
|
dependencies: []
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.0.0
|
||||||
|
espressif/mdns:
|
||||||
|
component_hash: 29e47564b1a7ee778135e17fbbf2a2773f71c97ebabfe626c8eda7c958a7ad16
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.0'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.9.1
|
||||||
|
espressif/rmaker_common:
|
||||||
|
component_hash: 842d2aaf486a24f11827a86b1147ee8ac7e1881f45e3d65a2141aff5bcbf276a
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.1'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
type: service
|
||||||
|
version: 1.5.3
|
||||||
|
idf:
|
||||||
|
source:
|
||||||
|
type: idf
|
||||||
|
version: 5.5.1
|
||||||
|
direct_dependencies:
|
||||||
|
- espressif/button
|
||||||
|
- espressif/esp_delta_ota
|
||||||
|
- espressif/esp_encrypted_img
|
||||||
|
- espressif/esp_insights
|
||||||
|
- espressif/esp_rcp_update
|
||||||
|
- espressif/esp_secure_cert_mgr
|
||||||
|
- espressif/json_generator
|
||||||
|
- espressif/json_parser
|
||||||
|
- espressif/led_strip
|
||||||
|
- espressif/mdns
|
||||||
|
manifest_hash: c15eaa367fc776fc22627b4c6568183a61ea17ab6b629ec496d666a22ea0947a
|
||||||
|
target: esp32c6
|
||||||
|
version: 2.0.0
|
||||||
14
01_Source/matter-light-c6-wifi/main/CMakeLists.txt
Normal file
14
01_Source/matter-light-c6-wifi/main/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
idf_component_register(SRC_DIRS "."
|
||||||
|
PRIV_INCLUDE_DIRS "." "../../OTA" "${ESP_MATTER_PATH}/examples/common/utils"
|
||||||
|
PRIV_REQUIRES app_update esp_http_client
|
||||||
|
esp_wifi esp_event esp_netif esp_timer nvs_flash
|
||||||
|
esp_matter esp_matter_console
|
||||||
|
device button app_reset)
|
||||||
|
|
||||||
|
if (CONFIG_ENABLE_SET_CERT_DECLARATION_API)
|
||||||
|
target_add_binary_data(${COMPONENT_TARGET} "certification_declaration/certification_declaration.der" BINARY)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H")
|
||||||
|
|
||||||
|
target_sources(${COMPONENT_LIB} PRIVATE "../../OTA/OtaManager.cpp")
|
||||||
11
01_Source/matter-light-c6-wifi/main/Kconfig.projbuild
Normal file
11
01_Source/matter-light-c6-wifi/main/Kconfig.projbuild
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
menu "Example Configuration"
|
||||||
|
|
||||||
|
config ENABLE_MEMORY_PROFILING
|
||||||
|
bool "Enable Memory Profiling"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable this option to include memory profiling features in the example.
|
||||||
|
This will allow you to monitor memory usage during runtime.
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
542
01_Source/matter-light-c6-wifi/main/app_driver.cpp
Normal file
542
01_Source/matter-light-c6-wifi/main/app_driver.cpp
Normal file
|
|
@ -0,0 +1,542 @@
|
||||||
|
/*
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <esp_matter.h>
|
||||||
|
#include <app_priv.h>
|
||||||
|
#include <common_macros.h>
|
||||||
|
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/task.h>
|
||||||
|
|
||||||
|
#include <driver/ledc.h>
|
||||||
|
#include <driver/rmt.h>
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
#include <button_gpio.h>
|
||||||
|
|
||||||
|
using namespace chip::app::Clusters;
|
||||||
|
using namespace esp_matter;
|
||||||
|
|
||||||
|
static const char *TAG = "app_driver";
|
||||||
|
extern uint16_t rgb_light_endpoint_id;
|
||||||
|
extern uint16_t cct_light_endpoint_id;
|
||||||
|
|
||||||
|
// Global variables to store current XY color coordinates
|
||||||
|
static uint16_t current_x = 0;
|
||||||
|
static uint16_t current_y = 0;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
APP_LIGHT_TYPE_RGB_PWM = 1,
|
||||||
|
APP_LIGHT_TYPE_SK6812 = 2,
|
||||||
|
} app_light_type_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
app_light_type_t type;
|
||||||
|
bool power;
|
||||||
|
uint8_t brightness;
|
||||||
|
} app_rgb_pwm_light_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
app_light_type_t type;
|
||||||
|
bool power;
|
||||||
|
uint8_t brightness;
|
||||||
|
uint32_t temperature_kelvin;
|
||||||
|
rmt_channel_t rmt_channel;
|
||||||
|
uint32_t strip_len;
|
||||||
|
uint8_t *buffer;
|
||||||
|
} app_sk6812_light_t;
|
||||||
|
|
||||||
|
static void kelvin_to_rgb(uint32_t kelvin, uint8_t *out_r, uint8_t *out_g, uint8_t *out_b)
|
||||||
|
{
|
||||||
|
if (!out_r || !out_g || !out_b) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (kelvin < 1000) {
|
||||||
|
kelvin = 1000;
|
||||||
|
}
|
||||||
|
if (kelvin > 40000) {
|
||||||
|
kelvin = 40000;
|
||||||
|
}
|
||||||
|
|
||||||
|
float temp = (float)kelvin / 100.0f;
|
||||||
|
float r;
|
||||||
|
float g;
|
||||||
|
float b;
|
||||||
|
|
||||||
|
if (temp <= 66.0f) {
|
||||||
|
r = 255.0f;
|
||||||
|
g = 99.4708025861f * logf(temp) - 161.1195681661f;
|
||||||
|
if (temp <= 19.0f) {
|
||||||
|
b = 0.0f;
|
||||||
|
} else {
|
||||||
|
b = 138.5177312231f * logf(temp - 10.0f) - 305.0447927307f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r = 329.698727446f * powf(temp - 60.0f, -0.1332047592f);
|
||||||
|
g = 288.1221695283f * powf(temp - 60.0f, -0.0755148492f);
|
||||||
|
b = 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r < 0.0f) r = 0.0f;
|
||||||
|
if (r > 255.0f) r = 255.0f;
|
||||||
|
if (g < 0.0f) g = 0.0f;
|
||||||
|
if (g > 255.0f) g = 255.0f;
|
||||||
|
if (b < 0.0f) b = 0.0f;
|
||||||
|
if (b > 255.0f) b = 255.0f;
|
||||||
|
|
||||||
|
*out_r = (uint8_t)r;
|
||||||
|
*out_g = (uint8_t)g;
|
||||||
|
*out_b = (uint8_t)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t rgb_pwm_apply(app_rgb_pwm_light_t *light)
|
||||||
|
{
|
||||||
|
if (!light) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t max_duty = (1U << 13) - 1;
|
||||||
|
uint32_t duty = 0;
|
||||||
|
if (light->power) {
|
||||||
|
duty = ((uint32_t)light->brightness * max_duty) / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t white_r_scale = 100;
|
||||||
|
const uint32_t white_g_scale = 100;
|
||||||
|
const uint32_t white_b_scale = 100;
|
||||||
|
uint32_t duty_r = (duty * white_r_scale) / 100;
|
||||||
|
uint32_t duty_g = (duty * white_g_scale) / 100;
|
||||||
|
uint32_t duty_b = (duty * white_b_scale) / 100;
|
||||||
|
if (duty_r > max_duty) duty_r = max_duty;
|
||||||
|
if (duty_g > max_duty) duty_g = max_duty;
|
||||||
|
if (duty_b > max_duty) duty_b = max_duty;
|
||||||
|
|
||||||
|
// Common-anode RGB module: LED is ON when GPIO is LOW. So invert duty in software.
|
||||||
|
uint32_t duty_r_inv = max_duty - duty_r;
|
||||||
|
uint32_t duty_g_inv = max_duty - duty_g;
|
||||||
|
uint32_t duty_b_inv = max_duty - duty_b;
|
||||||
|
|
||||||
|
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty_r_inv);
|
||||||
|
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
|
||||||
|
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1, duty_g_inv);
|
||||||
|
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1);
|
||||||
|
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2, duty_b_inv);
|
||||||
|
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t ws_t0h_ticks = 0;
|
||||||
|
static uint32_t ws_t1h_ticks = 0;
|
||||||
|
static uint32_t ws_t0l_ticks = 0;
|
||||||
|
static uint32_t ws_t1l_ticks = 0;
|
||||||
|
|
||||||
|
static void IRAM_ATTR ws2812_like_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num,
|
||||||
|
size_t *translated_size, size_t *item_num)
|
||||||
|
{
|
||||||
|
if (src == NULL || dest == NULL) {
|
||||||
|
*translated_size = 0;
|
||||||
|
*item_num = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rmt_item32_t bit0 = {{{ ws_t0h_ticks, 1, ws_t0l_ticks, 0 }}};
|
||||||
|
const rmt_item32_t bit1 = {{{ ws_t1h_ticks, 1, ws_t1l_ticks, 0 }}};
|
||||||
|
size_t size = 0;
|
||||||
|
size_t num = 0;
|
||||||
|
const uint8_t *psrc = (const uint8_t *)src;
|
||||||
|
rmt_item32_t *pdest = dest;
|
||||||
|
while (size < src_size && num < wanted_num) {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
if (*psrc & (1 << (7 - i))) {
|
||||||
|
pdest->val = bit1.val;
|
||||||
|
} else {
|
||||||
|
pdest->val = bit0.val;
|
||||||
|
}
|
||||||
|
num++;
|
||||||
|
pdest++;
|
||||||
|
}
|
||||||
|
size++;
|
||||||
|
psrc++;
|
||||||
|
}
|
||||||
|
*translated_size = size;
|
||||||
|
*item_num = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t sk6812_apply(app_sk6812_light_t *light)
|
||||||
|
{
|
||||||
|
if (!light || !light->buffer) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t r = 0;
|
||||||
|
uint8_t g = 0;
|
||||||
|
uint8_t b = 0;
|
||||||
|
uint8_t w = 0;
|
||||||
|
|
||||||
|
if (light->power) {
|
||||||
|
kelvin_to_rgb(light->temperature_kelvin, &r, &g, &b);
|
||||||
|
const uint32_t scale = light->brightness;
|
||||||
|
r = (uint8_t)(((uint32_t)r * scale) / 100);
|
||||||
|
g = (uint8_t)(((uint32_t)g * scale) / 100);
|
||||||
|
b = (uint8_t)(((uint32_t)b * scale) / 100);
|
||||||
|
w = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SK6812 RGBW byte order is commonly GRBW
|
||||||
|
for (uint32_t i = 0; i < light->strip_len; i++) {
|
||||||
|
uint32_t start = i * 4;
|
||||||
|
light->buffer[start + 0] = g;
|
||||||
|
light->buffer[start + 1] = r;
|
||||||
|
light->buffer[start + 2] = b;
|
||||||
|
light->buffer[start + 3] = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t ret = rmt_write_sample(light->rmt_channel, light->buffer, light->strip_len * 4, true);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return rmt_wait_tx_done(light->rmt_channel, pdMS_TO_TICKS(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do any conversions/remapping for the actual value here */
|
||||||
|
static esp_err_t app_driver_light_set_power(app_driver_handle_t handle, esp_matter_attr_val_t *val)
|
||||||
|
{
|
||||||
|
if (!handle) {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
if (!val) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
app_light_type_t type = ((app_rgb_pwm_light_t *)handle)->type;
|
||||||
|
if (type == APP_LIGHT_TYPE_RGB_PWM) {
|
||||||
|
app_rgb_pwm_light_t *h = (app_rgb_pwm_light_t *)handle;
|
||||||
|
h->power = val->val.b;
|
||||||
|
return rgb_pwm_apply(h);
|
||||||
|
}
|
||||||
|
if (type == APP_LIGHT_TYPE_SK6812) {
|
||||||
|
app_sk6812_light_t *h = (app_sk6812_light_t *)handle;
|
||||||
|
h->power = val->val.b;
|
||||||
|
return sk6812_apply(h);
|
||||||
|
}
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t app_driver_light_set_brightness(app_driver_handle_t handle, esp_matter_attr_val_t *val)
|
||||||
|
{
|
||||||
|
if (!handle) {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
int value = REMAP_TO_RANGE(val->val.u8, MATTER_BRIGHTNESS, STANDARD_BRIGHTNESS);
|
||||||
|
if (value < 0) {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
if (value > 100) {
|
||||||
|
value = 100;
|
||||||
|
}
|
||||||
|
app_light_type_t type = ((app_rgb_pwm_light_t *)handle)->type;
|
||||||
|
if (type == APP_LIGHT_TYPE_RGB_PWM) {
|
||||||
|
app_rgb_pwm_light_t *h = (app_rgb_pwm_light_t *)handle;
|
||||||
|
h->brightness = (uint8_t)value;
|
||||||
|
return rgb_pwm_apply(h);
|
||||||
|
}
|
||||||
|
if (type == APP_LIGHT_TYPE_SK6812) {
|
||||||
|
app_sk6812_light_t *h = (app_sk6812_light_t *)handle;
|
||||||
|
h->brightness = (uint8_t)value;
|
||||||
|
return sk6812_apply(h);
|
||||||
|
}
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t app_driver_light_set_hue(app_driver_handle_t handle, esp_matter_attr_val_t *val)
|
||||||
|
{
|
||||||
|
int value = REMAP_TO_RANGE(val->val.u8, MATTER_HUE, STANDARD_HUE);
|
||||||
|
(void)value;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t app_driver_light_set_saturation(app_driver_handle_t handle, esp_matter_attr_val_t *val)
|
||||||
|
{
|
||||||
|
int value = REMAP_TO_RANGE(val->val.u8, MATTER_SATURATION, STANDARD_SATURATION);
|
||||||
|
(void)value;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t app_driver_light_set_temperature(app_driver_handle_t handle, esp_matter_attr_val_t *val)
|
||||||
|
{
|
||||||
|
if (!handle) {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
uint32_t value = REMAP_TO_RANGE_INVERSE(val->val.u16, STANDARD_TEMPERATURE_FACTOR);
|
||||||
|
app_light_type_t type = ((app_rgb_pwm_light_t *)handle)->type;
|
||||||
|
if (type == APP_LIGHT_TYPE_SK6812) {
|
||||||
|
app_sk6812_light_t *h = (app_sk6812_light_t *)handle;
|
||||||
|
h->temperature_kelvin = value;
|
||||||
|
return sk6812_apply(h);
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t app_driver_light_set_xy(app_driver_handle_t handle, uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
(void)handle;
|
||||||
|
(void)x;
|
||||||
|
(void)y;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void app_driver_button_long_press_cb(void *arg, void *data)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Button LONG PRESS - entering ESP-NOW pairing mode");
|
||||||
|
app_enter_espnow_pairing_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void app_driver_button_toggle_cb(void *arg, void *data)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Toggle button pressed");
|
||||||
|
uint16_t endpoint_id = rgb_light_endpoint_id;
|
||||||
|
uint32_t cluster_id = OnOff::Id;
|
||||||
|
uint32_t attribute_id = OnOff::Attributes::OnOff::Id;
|
||||||
|
|
||||||
|
attribute_t *attribute = attribute::get(endpoint_id, cluster_id, attribute_id);
|
||||||
|
|
||||||
|
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
val.val.b = !val.val.b;
|
||||||
|
attribute::update(endpoint_id, cluster_id, attribute_id, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
|
||||||
|
uint32_t attribute_id, esp_matter_attr_val_t *val)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
(void)endpoint_id;
|
||||||
|
if (!driver_handle) {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
if (cluster_id == OnOff::Id) {
|
||||||
|
if (attribute_id == OnOff::Attributes::OnOff::Id) {
|
||||||
|
err = app_driver_light_set_power(driver_handle, val);
|
||||||
|
}
|
||||||
|
} else if (cluster_id == LevelControl::Id) {
|
||||||
|
if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
|
||||||
|
err = app_driver_light_set_brightness(driver_handle, val);
|
||||||
|
}
|
||||||
|
} else if (cluster_id == ColorControl::Id) {
|
||||||
|
if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
|
||||||
|
err = app_driver_light_set_hue(driver_handle, val);
|
||||||
|
} else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
|
||||||
|
err = app_driver_light_set_saturation(driver_handle, val);
|
||||||
|
} else if (attribute_id == ColorControl::Attributes::ColorTemperatureMireds::Id) {
|
||||||
|
err = app_driver_light_set_temperature(driver_handle, val);
|
||||||
|
} else if (attribute_id == ColorControl::Attributes::CurrentX::Id) {
|
||||||
|
current_x = val->val.u16;
|
||||||
|
err = app_driver_light_set_xy(driver_handle, current_x, current_y);
|
||||||
|
} else if (attribute_id == ColorControl::Attributes::CurrentY::Id) {
|
||||||
|
current_y = val->val.u16;
|
||||||
|
err = app_driver_light_set_xy(driver_handle, current_x, current_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t app_driver_light_set_defaults(uint16_t endpoint_id)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
void *priv_data = endpoint::get_priv_data(endpoint_id);
|
||||||
|
app_driver_handle_t handle = (app_driver_handle_t)priv_data;
|
||||||
|
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||||
|
|
||||||
|
/* Setting brightness */
|
||||||
|
attribute_t *attribute = attribute::get(endpoint_id, LevelControl::Id, LevelControl::Attributes::CurrentLevel::Id);
|
||||||
|
if (attribute) {
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
err |= app_driver_light_set_brightness(handle, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setting color */
|
||||||
|
cluster_t *color_cluster = cluster::get(endpoint_id, ColorControl::Id);
|
||||||
|
if (color_cluster) {
|
||||||
|
attribute = attribute::get(color_cluster, ColorControl::Attributes::ColorMode::Id);
|
||||||
|
if (attribute) {
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
if (val.val.u8 == (uint8_t)ColorControl::ColorMode::kCurrentHueAndCurrentSaturation) {
|
||||||
|
/* Setting hue */
|
||||||
|
attribute = attribute::get(color_cluster, ColorControl::Attributes::CurrentHue::Id);
|
||||||
|
if (attribute) {
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
err |= app_driver_light_set_hue(handle, &val);
|
||||||
|
}
|
||||||
|
/* Setting saturation */
|
||||||
|
attribute = attribute::get(color_cluster, ColorControl::Attributes::CurrentSaturation::Id);
|
||||||
|
if (attribute) {
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
err |= app_driver_light_set_saturation(handle, &val);
|
||||||
|
}
|
||||||
|
} else if (val.val.u8 == (uint8_t)ColorControl::ColorMode::kColorTemperature) {
|
||||||
|
/* Setting temperature */
|
||||||
|
attribute = attribute::get(color_cluster, ColorControl::Attributes::ColorTemperatureMireds::Id);
|
||||||
|
if (attribute) {
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
err |= app_driver_light_set_temperature(handle, &val);
|
||||||
|
}
|
||||||
|
} else if (val.val.u8 == (uint8_t)ColorControl::ColorMode::kCurrentXAndCurrentY) {
|
||||||
|
/* Setting XY coordinates */
|
||||||
|
attribute = attribute::get(color_cluster, ColorControl::Attributes::CurrentX::Id);
|
||||||
|
if (attribute) {
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
current_x = val.val.u16;
|
||||||
|
}
|
||||||
|
attribute = attribute::get(color_cluster, ColorControl::Attributes::CurrentY::Id);
|
||||||
|
if (attribute) {
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
current_y = val.val.u16;
|
||||||
|
}
|
||||||
|
err |= app_driver_light_set_xy(handle, current_x, current_y);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Color mode not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setting power */
|
||||||
|
attribute = attribute::get(endpoint_id, OnOff::Id, OnOff::Attributes::OnOff::Id);
|
||||||
|
if (attribute) {
|
||||||
|
attribute::get_val(attribute, &val);
|
||||||
|
err |= app_driver_light_set_power(handle, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
app_driver_handle_t app_driver_light_init()
|
||||||
|
{
|
||||||
|
return app_driver_rgb_light_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
app_driver_handle_t app_driver_rgb_light_init()
|
||||||
|
{
|
||||||
|
const int rgb_r_gpio = 4;
|
||||||
|
const int rgb_g_gpio = 5;
|
||||||
|
const int rgb_b_gpio = 6;
|
||||||
|
|
||||||
|
ledc_timer_config_t ledc_timer = {
|
||||||
|
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||||
|
.duty_resolution = LEDC_TIMER_13_BIT,
|
||||||
|
.timer_num = LEDC_TIMER_0,
|
||||||
|
.freq_hz = 5000,
|
||||||
|
.clk_cfg = LEDC_AUTO_CLK,
|
||||||
|
};
|
||||||
|
if (ledc_timer_config(&ledc_timer) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "LEDC timer config failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ledc_channel_config_t ch0 = {
|
||||||
|
.gpio_num = rgb_r_gpio,
|
||||||
|
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||||
|
.channel = LEDC_CHANNEL_0,
|
||||||
|
.intr_type = LEDC_INTR_DISABLE,
|
||||||
|
.timer_sel = LEDC_TIMER_0,
|
||||||
|
.duty = 0,
|
||||||
|
.hpoint = 0,
|
||||||
|
};
|
||||||
|
ledc_channel_config_t ch1 = ch0;
|
||||||
|
ch1.gpio_num = rgb_g_gpio;
|
||||||
|
ch1.channel = LEDC_CHANNEL_1;
|
||||||
|
ledc_channel_config_t ch2 = ch0;
|
||||||
|
ch2.gpio_num = rgb_b_gpio;
|
||||||
|
ch2.channel = LEDC_CHANNEL_2;
|
||||||
|
|
||||||
|
if (ledc_channel_config(&ch0) != ESP_OK || ledc_channel_config(&ch1) != ESP_OK || ledc_channel_config(&ch2) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "LEDC channel config failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
app_rgb_pwm_light_t *light = (app_rgb_pwm_light_t *)calloc(1, sizeof(app_rgb_pwm_light_t));
|
||||||
|
if (!light) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
light->type = APP_LIGHT_TYPE_RGB_PWM;
|
||||||
|
light->power = DEFAULT_POWER;
|
||||||
|
light->brightness = STANDARD_BRIGHTNESS;
|
||||||
|
rgb_pwm_apply(light);
|
||||||
|
return (app_driver_handle_t)light;
|
||||||
|
}
|
||||||
|
|
||||||
|
app_driver_handle_t app_driver_cct_light_init()
|
||||||
|
{
|
||||||
|
const int sk6812_gpio = 2;
|
||||||
|
const rmt_channel_t channel = RMT_CHANNEL_0;
|
||||||
|
const uint32_t strip_len = 8;
|
||||||
|
|
||||||
|
rmt_config_t rmt_cfg = RMT_DEFAULT_CONFIG_TX((gpio_num_t)sk6812_gpio, channel);
|
||||||
|
rmt_cfg.clk_div = 2;
|
||||||
|
if (rmt_config(&rmt_cfg) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "RMT config failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (rmt_driver_install(rmt_cfg.channel, 0, 0) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "RMT driver install failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t counter_clk_hz = 0;
|
||||||
|
if (rmt_get_counter_clock(rmt_cfg.channel, &counter_clk_hz) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "RMT get counter clock failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// Use WS2812-like timings which work for many SK6812 modules
|
||||||
|
const float ratio = (float)counter_clk_hz / 1e9f;
|
||||||
|
ws_t0h_ticks = (uint32_t)(ratio * 350.0f);
|
||||||
|
ws_t0l_ticks = (uint32_t)(ratio * 1000.0f);
|
||||||
|
ws_t1h_ticks = (uint32_t)(ratio * 1000.0f);
|
||||||
|
ws_t1l_ticks = (uint32_t)(ratio * 350.0f);
|
||||||
|
|
||||||
|
rmt_translator_init(rmt_cfg.channel, ws2812_like_rmt_adapter);
|
||||||
|
|
||||||
|
app_sk6812_light_t *light = (app_sk6812_light_t *)calloc(1, sizeof(app_sk6812_light_t));
|
||||||
|
if (!light) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
light->type = APP_LIGHT_TYPE_SK6812;
|
||||||
|
light->power = DEFAULT_POWER;
|
||||||
|
light->brightness = STANDARD_BRIGHTNESS;
|
||||||
|
light->temperature_kelvin = 4000;
|
||||||
|
light->rmt_channel = rmt_cfg.channel;
|
||||||
|
light->strip_len = strip_len;
|
||||||
|
light->buffer = (uint8_t *)calloc(strip_len * 4, 1);
|
||||||
|
if (!light->buffer) {
|
||||||
|
free(light);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sk6812_apply(light);
|
||||||
|
return (app_driver_handle_t)light;
|
||||||
|
}
|
||||||
|
|
||||||
|
app_driver_handle_t app_driver_button_init()
|
||||||
|
{
|
||||||
|
/* Initialize button */
|
||||||
|
button_handle_t handle = NULL;
|
||||||
|
const button_config_t btn_cfg = {0};
|
||||||
|
const button_gpio_config_t btn_gpio_cfg = button_driver_get_config();
|
||||||
|
|
||||||
|
if (iot_button_new_gpio_device(&btn_cfg, &btn_gpio_cfg, &handle) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to create button device");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
iot_button_register_cb(handle, BUTTON_PRESS_DOWN, NULL, app_driver_button_toggle_cb, NULL);
|
||||||
|
iot_button_register_cb(handle, BUTTON_LONG_PRESS_START, NULL, app_driver_button_long_press_cb, NULL);
|
||||||
|
|
||||||
|
return (app_driver_handle_t)handle;
|
||||||
|
}
|
||||||
1305
01_Source/matter-light-c6-wifi/main/app_main.cpp
Normal file
1305
01_Source/matter-light-c6-wifi/main/app_main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
114
01_Source/matter-light-c6-wifi/main/app_priv.h
Normal file
114
01_Source/matter-light-c6-wifi/main/app_priv.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include <esp_matter.h>
|
||||||
|
|
||||||
|
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
|
||||||
|
#include "esp_openthread_types.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Standard max values (used for remapping attributes) */
|
||||||
|
#define STANDARD_BRIGHTNESS 100
|
||||||
|
#define STANDARD_HUE 360
|
||||||
|
#define STANDARD_SATURATION 100
|
||||||
|
#define STANDARD_TEMPERATURE_FACTOR 1000000
|
||||||
|
|
||||||
|
/** Matter max values (used for remapping attributes) */
|
||||||
|
#define MATTER_BRIGHTNESS 254
|
||||||
|
#define MATTER_HUE 254
|
||||||
|
#define MATTER_SATURATION 254
|
||||||
|
#define MATTER_TEMPERATURE_FACTOR 1000000
|
||||||
|
|
||||||
|
/** Default attribute values used during initialization */
|
||||||
|
#define DEFAULT_POWER true
|
||||||
|
#define DEFAULT_BRIGHTNESS 64
|
||||||
|
#define DEFAULT_HUE 128
|
||||||
|
#define DEFAULT_SATURATION 254
|
||||||
|
|
||||||
|
typedef void *app_driver_handle_t;
|
||||||
|
|
||||||
|
/** Initialize the light driver
|
||||||
|
*
|
||||||
|
* This initializes the light driver associated with the selected board.
|
||||||
|
*
|
||||||
|
* @return Handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
app_driver_handle_t app_driver_light_init();
|
||||||
|
|
||||||
|
app_driver_handle_t app_driver_rgb_light_init();
|
||||||
|
|
||||||
|
app_driver_handle_t app_driver_cct_light_init();
|
||||||
|
|
||||||
|
/** Initialize the button driver
|
||||||
|
*
|
||||||
|
* This initializes the button driver associated with the selected board.
|
||||||
|
*
|
||||||
|
* @return Handle on success.
|
||||||
|
* @return NULL in case of failure.
|
||||||
|
*/
|
||||||
|
app_driver_handle_t app_driver_button_init();
|
||||||
|
|
||||||
|
/** Enter ESP-NOW pairing mode
|
||||||
|
*
|
||||||
|
* Called from button long press callback to enter ESP-NOW pairing mode.
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void app_enter_espnow_pairing_mode();
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Driver Update
|
||||||
|
*
|
||||||
|
* This API should be called to update the driver for the attribute being updated.
|
||||||
|
* This is usually called from the common `app_attribute_update_cb()`.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint ID of the attribute.
|
||||||
|
* @param[in] cluster_id Cluster ID of the attribute.
|
||||||
|
* @param[in] attribute_id Attribute ID of the attribute.
|
||||||
|
* @param[in] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
|
||||||
|
uint32_t attribute_id, esp_matter_attr_val_t *val);
|
||||||
|
|
||||||
|
/** Set defaults for light driver
|
||||||
|
*
|
||||||
|
* Set the attribute drivers to their default values from the created data model.
|
||||||
|
*
|
||||||
|
* @param[in] endpoint_id Endpoint ID of the driver.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success.
|
||||||
|
* @return error in case of failure.
|
||||||
|
*/
|
||||||
|
esp_err_t app_driver_light_set_defaults(uint16_t endpoint_id);
|
||||||
|
|
||||||
|
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.radio_mode = RADIO_MODE_NATIVE, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.host_connection_mode = HOST_CONNECTION_MODE_NONE, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \
|
||||||
|
{ \
|
||||||
|
.storage_partition_name = "nvs", .netif_queue_size = 10, .task_queue_size = 10, \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Binary file not shown.
6
01_Source/matter-light-c6-wifi/main/idf_component.yml
Normal file
6
01_Source/matter-light-c6-wifi/main/idf_component.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
dependencies:
|
||||||
|
espressif/cmake_utilities:
|
||||||
|
version: "^1"
|
||||||
|
rules: # will add "optional_component" only when all if clauses are True
|
||||||
|
- if: "idf_version >=5.0"
|
||||||
|
- if: "target in [esp32c2]"
|
||||||
10
01_Source/matter-light-c6-wifi/partitions.csv
Normal file
10
01_Source/matter-light-c6-wifi/partitions.csv
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
|
||||||
|
# Thread + Matter + ESP-NOW firmware requires ~2MB, using single factory partition for development
|
||||||
|
esp_secure_cert, 0x3F, ,0xd000, 0x2000, encrypted
|
||||||
|
nvs, data, nvs, 0x10000, 0xC000,
|
||||||
|
otadata, data, ota, 0x1C000, 0x2000,
|
||||||
|
nvs_keys, data, nvs_keys,0x1E000, 0x1000, encrypted
|
||||||
|
phy_init, data, phy, 0x1F000, 0x1000,
|
||||||
|
ota_0, app, ota_0, 0x20000, 0x600000,
|
||||||
|
ota_1, app, ota_1, 0x620000, 0x600000
|
||||||
|
3292
01_Source/matter-light-c6-wifi/sdkconfig
Normal file
3292
01_Source/matter-light-c6-wifi/sdkconfig
Normal file
File diff suppressed because it is too large
Load Diff
16
01_Source/matter-light-c6-wifi/sdkconfig.defaults
Normal file
16
01_Source/matter-light-c6-wifi/sdkconfig.defaults
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c6"
|
||||||
|
|
||||||
|
# Enable Wi-Fi STA for Matter over Wi-Fi (REQUIRED for App control)
|
||||||
|
CONFIG_ENABLE_WIFI_STATION=y
|
||||||
|
CONFIG_ENABLE_WIFI_AP=n
|
||||||
|
|
||||||
|
# Disable Thread for now (enable later for mesh)
|
||||||
|
CONFIG_OPENTHREAD_ENABLED=n
|
||||||
|
|
||||||
|
# BLE for commissioning
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
|
||||||
|
# Custom partition
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
33
01_Source/matter-light-c6-wifi/sdkconfig.defaults.esp32c6
Normal file
33
01_Source/matter-light-c6-wifi/sdkconfig.defaults.esp32c6
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
CONFIG_IDF_TARGET="esp32c6"
|
||||||
|
|
||||||
|
CONFIG_MBEDTLS_HKDF_C=y
|
||||||
|
|
||||||
|
# Custom partition table
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||||
|
|
||||||
|
CONFIG_DEVICE_SOFTWARE_VERSION_NUMBER=2
|
||||||
|
|
||||||
|
# BLE for Matter commissioning
|
||||||
|
CONFIG_BT_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
CONFIG_BT_NIMBLE_EXT_ADV=n
|
||||||
|
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
|
||||||
|
CONFIG_ENABLE_CHIPOBLE=y
|
||||||
|
|
||||||
|
# Disable OpenThread - use Wi-Fi for Matter
|
||||||
|
CONFIG_OPENTHREAD_ENABLED=n
|
||||||
|
CONFIG_CHIP_ENABLE_OPENTHREAD=n
|
||||||
|
CONFIG_ENABLE_THREAD=n
|
||||||
|
|
||||||
|
CONFIG_ENABLE_CHIP_SHELL=y
|
||||||
|
|
||||||
|
# Enable Wi-Fi for Matter AND ESP-NOW
|
||||||
|
CONFIG_ESP_WIFI_ENABLED=y
|
||||||
|
CONFIG_ENABLE_WIFI_STATION=y
|
||||||
|
CONFIG_ENABLE_WIFI_AP=n
|
||||||
|
|
||||||
|
CONFIG_ENABLE_OTA_REQUESTOR=y
|
||||||
|
CONFIG_CHIP_OTA_IMAGE_BUILD=y
|
||||||
|
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
|
||||||
BIN
02_Firmware_Binaries/cct/factory/bootloader.bin
Normal file
BIN
02_Firmware_Binaries/cct/factory/bootloader.bin
Normal file
Binary file not shown.
BIN
02_Firmware_Binaries/cct/factory/light.bin
Normal file
BIN
02_Firmware_Binaries/cct/factory/light.bin
Normal file
Binary file not shown.
1
02_Firmware_Binaries/cct/factory/ota_data_initial.bin
Normal file
1
02_Firmware_Binaries/cct/factory/ota_data_initial.bin
Normal file
File diff suppressed because one or more lines are too long
BIN
02_Firmware_Binaries/cct/factory/partition-table.bin
Normal file
BIN
02_Firmware_Binaries/cct/factory/partition-table.bin
Normal file
Binary file not shown.
BIN
02_Firmware_Binaries/cct/ota/light.bin
Normal file
BIN
02_Firmware_Binaries/cct/ota/light.bin
Normal file
Binary file not shown.
72
03_Flash_and_Tools/Base38.py
Normal file
72
03_Flash_and_Tools/Base38.py
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022 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.
|
||||||
|
|
||||||
|
# TODO: Implement the decode method
|
||||||
|
|
||||||
|
CODES = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||||
|
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||||
|
'U', 'V', 'W', 'X', 'Y', 'Z', '-', '.']
|
||||||
|
RADIX = len(CODES)
|
||||||
|
BASE38_CHARS_NEEDED_IN_CHUNK = [2, 4, 5]
|
||||||
|
MAX_BYTES_IN_CHUNK = 3
|
||||||
|
MAX_ENCODED_BYTES_IN_CHUNK = 5
|
||||||
|
|
||||||
|
|
||||||
|
def encode(bytes):
|
||||||
|
total_bytes = len(bytes)
|
||||||
|
qrcode = ''
|
||||||
|
|
||||||
|
for i in range(0, total_bytes, MAX_BYTES_IN_CHUNK):
|
||||||
|
if (i + MAX_BYTES_IN_CHUNK) > total_bytes:
|
||||||
|
bytes_in_chunk = total_bytes - i
|
||||||
|
else:
|
||||||
|
bytes_in_chunk = MAX_BYTES_IN_CHUNK
|
||||||
|
|
||||||
|
value = 0
|
||||||
|
for j in range(i, i + bytes_in_chunk):
|
||||||
|
value = value + (bytes[j] << (8 * (j - i)))
|
||||||
|
|
||||||
|
base38_chars_needed = BASE38_CHARS_NEEDED_IN_CHUNK[bytes_in_chunk - 1]
|
||||||
|
while base38_chars_needed > 0:
|
||||||
|
qrcode += CODES[int(value % RADIX)]
|
||||||
|
value = int(value / RADIX)
|
||||||
|
base38_chars_needed -= 1
|
||||||
|
|
||||||
|
return qrcode
|
||||||
|
|
||||||
|
|
||||||
|
def decode(qrcode):
|
||||||
|
total_chars = len(qrcode)
|
||||||
|
decoded_bytes = bytearray()
|
||||||
|
|
||||||
|
for i in range(0, total_chars, MAX_ENCODED_BYTES_IN_CHUNK):
|
||||||
|
if (i + MAX_ENCODED_BYTES_IN_CHUNK) > total_chars:
|
||||||
|
chars_in_chunk = total_chars - i
|
||||||
|
else:
|
||||||
|
chars_in_chunk = MAX_ENCODED_BYTES_IN_CHUNK
|
||||||
|
|
||||||
|
value = 0
|
||||||
|
for j in range(i + chars_in_chunk - 1, i - 1, -1):
|
||||||
|
value = value * RADIX + CODES.index(qrcode[j])
|
||||||
|
|
||||||
|
bytes_in_chunk = BASE38_CHARS_NEEDED_IN_CHUNK.index(chars_in_chunk) + 1
|
||||||
|
for k in range(0, bytes_in_chunk):
|
||||||
|
decoded_bytes.append(value & 0xFF)
|
||||||
|
value = value >> 8
|
||||||
|
|
||||||
|
return decoded_bytes
|
||||||
119
03_Flash_and_Tools/Flash_Guide_CN.md
Normal file
119
03_Flash_and_Tools/Flash_Guide_CN.md
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
# 烧录与编译说明(Windows,ESP32-C6)
|
||||||
|
|
||||||
|
本说明适用于交付目录中的工程与固件:
|
||||||
|
- 源码:`Deliverable/01_Source/matter-light-c6-wifi`
|
||||||
|
- 预编译固件:`Deliverable/02_Firmware_Binaries/cct/*`
|
||||||
|
|
||||||
|
> 备注:本项目基于 ESP-IDF v5.2+;你当前环境若已安装 Espressif IDF(例如 v5.5.1)也可直接使用。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 环境准备
|
||||||
|
|
||||||
|
### 1.1 安装/启用 ESP-IDF(PowerShell)
|
||||||
|
|
||||||
|
以你机器上的默认安装路径为例(如不同请替换):
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# 进入你的 ESP-IDF 目录后执行(不要在命令里写 cd 的话,也可以直接在该目录打开 PowerShell)
|
||||||
|
# 示例:C:\Espressif\frameworks\esp-idf-v5.5.1
|
||||||
|
. "C:\Espressif\frameworks\esp-idf-v5.5.1\export.ps1"
|
||||||
|
|
||||||
|
idf.py --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 串口与硬件
|
||||||
|
|
||||||
|
- 连接 ESP32-C6 开发板(建议 16MB Flash 版本)。
|
||||||
|
- 在设备管理器确认串口号(如 `COM4`)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 从源码编译并烧录(推荐,最稳)
|
||||||
|
|
||||||
|
在工程目录执行:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cd D:\ESP-LED\Deliverable\01_Source\matter-light-c6-wifi
|
||||||
|
|
||||||
|
# 清理并编译
|
||||||
|
idf.py fullclean
|
||||||
|
idf.py build
|
||||||
|
|
||||||
|
# 烧录并监视(将 COM4 替换成你的串口)
|
||||||
|
idf.py -p COM4 flash monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
停止串口监视:按 `Ctrl+]`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 直接烧录预编译 Factory 固件(无需重新编译)
|
||||||
|
|
||||||
|
预编译 Factory 固件路径:
|
||||||
|
|
||||||
|
- `Deliverable/02_Firmware_Binaries/cct/factory/bootloader.bin`
|
||||||
|
- `Deliverable/02_Firmware_Binaries/cct/factory/partition-table.bin`
|
||||||
|
- `Deliverable/02_Firmware_Binaries/cct/factory/ota_data_initial.bin`
|
||||||
|
- `Deliverable/02_Firmware_Binaries/cct/factory/light.bin`
|
||||||
|
|
||||||
|
烧录地址(来自工程构建输出 `flasher_args.json/flash_args`):
|
||||||
|
|
||||||
|
- `0x0000` bootloader
|
||||||
|
- `0x8000` partition-table
|
||||||
|
- `0x1C000` ota_data_initial
|
||||||
|
- `0x20000` app (`light.bin`)
|
||||||
|
|
||||||
|
### 3.1 使用 `esptool.py` 一次性写入
|
||||||
|
|
||||||
|
确保已执行过 `export.ps1`,然后运行:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$PORT="COM4" # 替换为你的串口
|
||||||
|
$BAUD="921600" # 可改成 460800/115200 以提升稳定性
|
||||||
|
|
||||||
|
$BASE="D:\ESP-LED\Deliverable\02_Firmware_Binaries\cct\factory"
|
||||||
|
|
||||||
|
python -m esptool --chip esp32c6 -p $PORT -b $BAUD `
|
||||||
|
--before default_reset --after hard_reset `
|
||||||
|
write_flash --flash_mode dio --flash_freq 80m --flash_size 16MB `
|
||||||
|
0x0 "$BASE\bootloader.bin" `
|
||||||
|
0x8000 "$BASE\partition-table.bin" `
|
||||||
|
0x1c000 "$BASE\ota_data_initial.bin" `
|
||||||
|
0x20000 "$BASE\light.bin"
|
||||||
|
```
|
||||||
|
|
||||||
|
> 如果你的板子实际是 4MB Flash,可把 `--flash_size 16MB` 改为 `4MB`。
|
||||||
|
|
||||||
|
### 3.2 监视串口日志
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
idf.py -p COM4 monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. OTA 固件文件说明(给服务器/升级用)
|
||||||
|
|
||||||
|
OTA 文件路径:
|
||||||
|
- `Deliverable/02_Firmware_Binaries/cct/ota/light.bin`
|
||||||
|
|
||||||
|
说明:
|
||||||
|
- `light.bin` 用于 OTA 升级包(用于远程 HTTP OTA 场景的下载与升级)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 常见问题
|
||||||
|
|
||||||
|
### 5.1 找不到 `python` / `idf.py`
|
||||||
|
|
||||||
|
确保已执行 `export.ps1`,且使用的是同一个 PowerShell 窗口。
|
||||||
|
|
||||||
|
### 5.2 串口被占用
|
||||||
|
|
||||||
|
关闭其它串口工具(如 Arduino 串口监视器、串口调试助手)。
|
||||||
|
|
||||||
|
### 5.3 Flash size 警告
|
||||||
|
|
||||||
|
如果日志提示“Detected size larger than size in binary image header”,请确认:
|
||||||
|
- 工程配置选择了正确的 Flash size(建议 16MB),并重新 `idf.py fullclean build`。
|
||||||
85
03_Flash_and_Tools/QR_Guide_CN.md
Normal file
85
03_Flash_and_Tools/QR_Guide_CN.md
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
# QR 码/配网码生成说明(Matter Onboarding Codes)
|
||||||
|
|
||||||
|
本目录已包含一个可直接使用的脚本,用于生成/解析 Matter 的:
|
||||||
|
- **QR Code 字符串**(以 `MT:` 开头)
|
||||||
|
- **Manual Pairing Code**(11位或21位数字)
|
||||||
|
|
||||||
|
对应文件:
|
||||||
|
- `SetupPayload.py`
|
||||||
|
- `Base38.py`
|
||||||
|
- 依赖列表:`requirements.setuppayload.txt`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 安装 Python 依赖
|
||||||
|
|
||||||
|
在 PowerShell 中进入本目录:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cd D:\ESP-LED\Deliverable\03_Flash_and_Tools
|
||||||
|
python -m pip install -r .\requirements.setuppayload.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 生成配网码(推荐用法)
|
||||||
|
|
||||||
|
### 2.1 生成(仅标准 flow)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python .\SetupPayload.py generate -d 3840 -p 20202021
|
||||||
|
```
|
||||||
|
|
||||||
|
输出示例:
|
||||||
|
- `Manualcode : 34970112332`
|
||||||
|
- `QRCode : MT:...`
|
||||||
|
|
||||||
|
### 2.2 生成(带 VID/PID)
|
||||||
|
|
||||||
|
当 commissioning flow 非 0 时,会把 VID/PID 编进 manual code:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python .\SetupPayload.py generate -d 3840 -p 20202021 -cf 2 -vid 65521 -pid 32768 -dm 2
|
||||||
|
```
|
||||||
|
|
||||||
|
参数说明:
|
||||||
|
- `-d` / `--discriminator`:0..4095
|
||||||
|
- `-p` / `--passcode`:1..0x5F5E0FE
|
||||||
|
- `-vid` / `--vendor-id`:0..65535
|
||||||
|
- `-pid` / `--product-id`:0..65535
|
||||||
|
- `-dm` / `--discovery-cap-bitmask`:
|
||||||
|
- 0: SoftAP
|
||||||
|
- 1: BLE
|
||||||
|
- 2: OnNetwork
|
||||||
|
- 默认 4(脚本里描述为 OnNetwork;不同实现可能有组合值)
|
||||||
|
- `-cf` / `--commissioning-flow`:
|
||||||
|
- 0: Standard
|
||||||
|
- 1: User-Intent
|
||||||
|
- 2: Custom
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 解析配网码
|
||||||
|
|
||||||
|
解析 QR 字符串:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python .\SetupPayload.py parse "MT:00000CQM00KA0648G00"
|
||||||
|
```
|
||||||
|
|
||||||
|
解析 Manual pairing code:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python .\SetupPayload.py parse 34970112332
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 交付说明(测试数据 vs 量产数据)
|
||||||
|
|
||||||
|
当前工程处于开发/演示阶段,通常使用测试用的 VID/PID/证书/配网参数:
|
||||||
|
- 可以用于演示配网与控制。
|
||||||
|
- 若后续甲方申请 CSA 认证并进入量产:
|
||||||
|
- 需要使用正式 VID/PID
|
||||||
|
- 每台设备需要唯一的出厂数据(如 DAC/证书链、唯一 passcode/discriminator 或出厂注入策略)
|
||||||
|
- 通常需要重新生成 QR 并恢复出厂重新配网(属正常流程)
|
||||||
220
03_Flash_and_Tools/SetupPayload.py
Normal file
220
03_Flash_and_Tools/SetupPayload.py
Normal file
|
|
@ -0,0 +1,220 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 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.
|
||||||
|
|
||||||
|
import enum
|
||||||
|
|
||||||
|
import Base38
|
||||||
|
import click
|
||||||
|
from bitarray import bitarray
|
||||||
|
from bitarray.util import int2ba, zeros
|
||||||
|
from construct import BitsInteger, BitStruct, Enum
|
||||||
|
from stdnum.verhoeff import calc_check_digit
|
||||||
|
|
||||||
|
# Format for constructing manualcode
|
||||||
|
manualcode_format = BitStruct(
|
||||||
|
'version' / BitsInteger(1),
|
||||||
|
'vid_pid_present' / BitsInteger(1),
|
||||||
|
'discriminator' / BitsInteger(4),
|
||||||
|
'pincode_lsb' / BitsInteger(14),
|
||||||
|
'pincode_msb' / BitsInteger(13),
|
||||||
|
'vid' / BitsInteger(16),
|
||||||
|
'pid' / BitsInteger(16),
|
||||||
|
'padding' / BitsInteger(7), # this is intentional as BitStruct only takes 8-bit aligned data
|
||||||
|
)
|
||||||
|
|
||||||
|
# Format for constructing qrcode
|
||||||
|
# qrcode bytes are packed as lsb....msb, hence the order is reversed
|
||||||
|
qrcode_format = BitStruct(
|
||||||
|
'padding' / BitsInteger(4),
|
||||||
|
'pincode' / BitsInteger(27),
|
||||||
|
'discriminator' / BitsInteger(12),
|
||||||
|
'discovery' / BitsInteger(8),
|
||||||
|
'flow' / Enum(BitsInteger(2),
|
||||||
|
Standard=0, UserIntent=1, Custom=2),
|
||||||
|
'pid' / BitsInteger(16),
|
||||||
|
'vid' / BitsInteger(16),
|
||||||
|
'version' / BitsInteger(3),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CommissioningFlow(enum.IntEnum):
|
||||||
|
Standard = 0
|
||||||
|
UserIntent = 1
|
||||||
|
Custom = 2
|
||||||
|
|
||||||
|
|
||||||
|
class SetupPayload:
|
||||||
|
def __init__(self, discriminator, pincode, rendezvous=4, flow=CommissioningFlow.Standard, vid=0, pid=0):
|
||||||
|
self.long_discriminator = discriminator
|
||||||
|
self.short_discriminator = discriminator >> 8
|
||||||
|
self.pincode = pincode
|
||||||
|
self.discovery = rendezvous
|
||||||
|
self.flow = flow
|
||||||
|
self.vid = vid
|
||||||
|
self.pid = pid
|
||||||
|
|
||||||
|
def p_print(self):
|
||||||
|
print('{:<{}} :{}'.format('Flow', 24, self.flow))
|
||||||
|
print('{:<{}} :{}'.format('Pincode', 24, self.pincode))
|
||||||
|
print('{:<{}} :{}'.format('Short Discriminator', 24, self.short_discriminator))
|
||||||
|
if self.long_discriminator:
|
||||||
|
print('{:<{}} :{}'.format('Long Discriminator', 24, self.long_discriminator))
|
||||||
|
if self.discovery:
|
||||||
|
print('{:<{}} :{}'.format('Discovery Capabilities', 24, self.discovery))
|
||||||
|
if self.vid is not None and self.pid is not None:
|
||||||
|
print('{:<{}} :{:<{}} (0x{:04x})'.format('Vendor Id', 24, self.vid, 6, self.vid))
|
||||||
|
print('{:<{}} :{:<{}} (0x{:04x})'.format('Product Id', 24, self.pid, 6, self.pid))
|
||||||
|
|
||||||
|
def qrcode_dict(self):
|
||||||
|
return {
|
||||||
|
'version': 0,
|
||||||
|
'vid': self.vid,
|
||||||
|
'pid': self.pid,
|
||||||
|
'flow': int(self.flow),
|
||||||
|
'discovery': self.discovery,
|
||||||
|
'discriminator': self.long_discriminator,
|
||||||
|
'pincode': self.pincode,
|
||||||
|
'padding': 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
def manualcode_dict(self):
|
||||||
|
return {
|
||||||
|
'version': 0,
|
||||||
|
'vid_pid_present': 0 if self.flow == CommissioningFlow.Standard else 1,
|
||||||
|
'discriminator': self.short_discriminator,
|
||||||
|
'pincode_lsb': self.pincode & 0x3FFF, # 14 ls-bits
|
||||||
|
'pincode_msb': self.pincode >> 14, # 13 ms-bits
|
||||||
|
'vid': 0 if self.flow == CommissioningFlow.Standard else self.vid,
|
||||||
|
'pid': 0 if self.flow == CommissioningFlow.Standard else self.pid,
|
||||||
|
'padding': 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
def generate_qrcode(self):
|
||||||
|
data = qrcode_format.build(self.qrcode_dict())
|
||||||
|
b38_encoded = Base38.encode(data[::-1]) # reversing
|
||||||
|
return 'MT:{}'.format(b38_encoded)
|
||||||
|
|
||||||
|
def generate_manualcode(self):
|
||||||
|
CHUNK1_START = 0
|
||||||
|
CHUNK1_LEN = 4
|
||||||
|
CHUNK2_START = CHUNK1_START + CHUNK1_LEN
|
||||||
|
CHUNK2_LEN = 16
|
||||||
|
CHUNK3_START = CHUNK2_START + CHUNK2_LEN
|
||||||
|
CHUNK3_LEN = 13
|
||||||
|
|
||||||
|
bytes = manualcode_format.build(self.manualcode_dict())
|
||||||
|
bits = bitarray()
|
||||||
|
bits.frombytes(bytes)
|
||||||
|
|
||||||
|
chunk1 = str(int(bits[CHUNK1_START:CHUNK1_START + CHUNK1_LEN].to01(), 2)).zfill(1)
|
||||||
|
chunk2 = str(int(bits[CHUNK2_START:CHUNK2_START + CHUNK2_LEN].to01(), 2)).zfill(5)
|
||||||
|
chunk3 = str(int(bits[CHUNK3_START:CHUNK3_START + CHUNK3_LEN].to01(), 2)).zfill(4)
|
||||||
|
chunk4 = str(self.vid).zfill(5) if self.flow != CommissioningFlow.Standard else ''
|
||||||
|
chunk5 = str(self.pid).zfill(5) if self.flow != CommissioningFlow.Standard else ''
|
||||||
|
payload = '{}{}{}{}{}'.format(chunk1, chunk2, chunk3, chunk4, chunk5)
|
||||||
|
return '{}{}'.format(payload, calc_check_digit(payload))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_container(container, is_qrcode):
|
||||||
|
payload = None
|
||||||
|
if is_qrcode:
|
||||||
|
payload = SetupPayload(container['discriminator'], container['pincode'],
|
||||||
|
container['discovery'], CommissioningFlow(container['flow'].__int__()),
|
||||||
|
container['vid'], container['pid'])
|
||||||
|
else:
|
||||||
|
payload = SetupPayload(discriminator=container['discriminator'],
|
||||||
|
pincode=(container['pincode_msb'] << 14) | container['pincode_lsb'],
|
||||||
|
vid=container['vid'] if container['vid_pid_present'] else None,
|
||||||
|
pid=container['pid'] if container['vid_pid_present'] else None)
|
||||||
|
payload.short_discriminator = container['discriminator']
|
||||||
|
payload.long_discriminator = None
|
||||||
|
payload.discovery = None
|
||||||
|
payload.flow = 2 if container['vid_pid_present'] else 0
|
||||||
|
|
||||||
|
return payload
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_qrcode(payload):
|
||||||
|
payload = payload[3:] # remove 'MT:'
|
||||||
|
b38_decoded = Base38.decode(payload)[::-1]
|
||||||
|
container = qrcode_format.parse(b38_decoded)
|
||||||
|
return SetupPayload.from_container(container, is_qrcode=True)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse_manualcode(payload):
|
||||||
|
payload_len = len(payload)
|
||||||
|
if payload_len != 11 and payload_len != 21:
|
||||||
|
print('Invalid length')
|
||||||
|
return None
|
||||||
|
|
||||||
|
# if first digit is greater than 7 the its not v1
|
||||||
|
if int(str(payload)[0]) > 7:
|
||||||
|
print('incorrect first digit')
|
||||||
|
return None
|
||||||
|
|
||||||
|
if calc_check_digit(payload[:-1]) != str(payload)[-1]:
|
||||||
|
print('check digit mismatch')
|
||||||
|
return None
|
||||||
|
|
||||||
|
# vid_pid_present bit position
|
||||||
|
is_long = int(str(payload)[0]) & (1 << 2)
|
||||||
|
|
||||||
|
bits = int2ba(int(payload[0]), length=4)
|
||||||
|
bits += int2ba(int(payload[1:6]), length=16)
|
||||||
|
bits += int2ba(int(payload[6:10]), length=13)
|
||||||
|
bits += int2ba(int(payload[10:15]), length=16) if is_long else zeros(16)
|
||||||
|
bits += int2ba(int(payload[15:20]), length=16) if is_long else zeros(16)
|
||||||
|
bits += zeros(7) # padding
|
||||||
|
|
||||||
|
container = manualcode_format.parse(bits.tobytes())
|
||||||
|
return SetupPayload.from_container(container, is_qrcode=False)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse(payload):
|
||||||
|
if payload.startswith('MT:'):
|
||||||
|
return SetupPayload.parse_qrcode(payload)
|
||||||
|
else:
|
||||||
|
return SetupPayload.parse_manualcode(payload)
|
||||||
|
|
||||||
|
|
||||||
|
@click.group()
|
||||||
|
def cli():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
@click.argument('payload')
|
||||||
|
def parse(payload):
|
||||||
|
click.echo(f'Parsing payload: {payload}')
|
||||||
|
SetupPayload.parse(payload).p_print()
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
@click.option('--discriminator', '-d', required=True, type=click.IntRange(0, 0xFFF), help='Discriminator')
|
||||||
|
@click.option('--passcode', '-p', required=True, type=click.IntRange(1, 0x5F5E0FE), help='setup pincode')
|
||||||
|
@click.option('--vendor-id', '-vid', type=click.IntRange(0, 0xFFFF), default=0, help='Vendor ID')
|
||||||
|
@click.option('--product-id', '-pid', type=click.IntRange(0, 0xFFFF), default=0, help='Product ID')
|
||||||
|
@click.option('--discovery-cap-bitmask', '-dm', type=click.IntRange(0, 7), default=4, help='Commissionable device discovery capability bitmask. 0:SoftAP, 1:BLE, 2:OnNetwork. Default: OnNetwork')
|
||||||
|
@click.option('--commissioning-flow', '-cf', type=click.IntRange(0, 2), default=0, help='Commissioning flow, 0:Standard, 1:User-Intent, 2:Custom')
|
||||||
|
def generate(passcode, discriminator, vendor_id, product_id, discovery_cap_bitmask, commissioning_flow):
|
||||||
|
payload = SetupPayload(discriminator, passcode, discovery_cap_bitmask, commissioning_flow, vendor_id, product_id)
|
||||||
|
print("Manualcode : {}".format(payload.generate_manualcode()))
|
||||||
|
print("QRCode : {}".format(payload.generate_qrcode()))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
cli()
|
||||||
22
03_Flash_and_Tools/SetupPayload_README.md
Normal file
22
03_Flash_and_Tools/SetupPayload_README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
## Python tool to generate and parse Matter onboarding codes
|
||||||
|
|
||||||
|
Generates and parses Manual Pairing Code and QR Code
|
||||||
|
|
||||||
|
#### example usage:
|
||||||
|
|
||||||
|
- Parse
|
||||||
|
|
||||||
|
```
|
||||||
|
./SetupPayload.py parse MT:U9VJ0OMV172PX813210
|
||||||
|
./SetupPayload.py parse 34970112332
|
||||||
|
```
|
||||||
|
|
||||||
|
- Generate
|
||||||
|
|
||||||
|
```
|
||||||
|
./SetupPayload.py generate --help
|
||||||
|
./SetupPayload.py generate -d 3840 -p 20202021
|
||||||
|
./SetupPayload.py generate -d 3840 -p 20202021 --vendor-id 65521 --product-id 32768 -cf 0 -dm 2
|
||||||
|
```
|
||||||
|
|
||||||
|
For more details please refer Matter Specification
|
||||||
4
03_Flash_and_Tools/requirements.setuppayload.txt
Normal file
4
03_Flash_and_Tools/requirements.setuppayload.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
bitarray>=2.8.1
|
||||||
|
click>=8.1.3
|
||||||
|
construct>=2.10.68
|
||||||
|
python_stdnum==1.18
|
||||||
Binary file not shown.
BIN
04_Test_Report/OTA_HTTP/微信图片_2026-01-26_154226_211.png
Normal file
BIN
04_Test_Report/OTA_HTTP/微信图片_2026-01-26_154226_211.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
BIN
04_Test_Report/OTA_HTTP/微信图片_2026-01-26_154253_705.png
Normal file
BIN
04_Test_Report/OTA_HTTP/微信图片_2026-01-26_154253_705.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
BIN
04_Test_Report/OTA_HTTP/微信图片_2026-01-26_154313_486.png
Normal file
BIN
04_Test_Report/OTA_HTTP/微信图片_2026-01-26_154313_486.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 543 KiB |
Binary file not shown.
48
04_Test_Report/README.md
Normal file
48
04_Test_Report/README.md
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
# 测试报告说明(截图/视频提交)
|
||||||
|
|
||||||
|
本目录用于存放项目验收所需的截图/视频证据。
|
||||||
|
|
||||||
|
建议提交内容:
|
||||||
|
|
||||||
|
## 1. AppleHome
|
||||||
|
- 配网演示(扫码/输入码)
|
||||||
|
- 设备上线后:开关、亮度、(双色温)色温控制
|
||||||
|
|
||||||
|
## 2. GoogleHome
|
||||||
|
- 配网演示
|
||||||
|
- 基本控制演示
|
||||||
|
|
||||||
|
## 3. Alexa
|
||||||
|
- 配网演示
|
||||||
|
- 基本控制演示
|
||||||
|
|
||||||
|
## 4. RainMaker
|
||||||
|
- 配网演示
|
||||||
|
- 基本控制演示
|
||||||
|
|
||||||
|
## 5. Remote_Control_and_Group_Control
|
||||||
|
- 遥控器单控演示(单台设备)
|
||||||
|
- 遥控器组控/广播命令演示(多台设备同步)
|
||||||
|
- App 与遥控器同时控制(状态同步)
|
||||||
|
|
||||||
|
## 6. OTA_HTTP
|
||||||
|
- 服务器上放置 `light.bin` 的目录/URL 截图
|
||||||
|
- 设备端执行 `matter esp ota <url>` 的视频/截图
|
||||||
|
- 升级前后 `App version` 对比(串口日志/截图)
|
||||||
|
|
||||||
|
## 7. Power_Cycle_Reset
|
||||||
|
- 3 次断电/重启触发 factory reset 的视频/截图
|
||||||
|
- reset 后进入可重新配网状态的截图
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 文件命名建议
|
||||||
|
|
||||||
|
建议格式:
|
||||||
|
|
||||||
|
- `YYYYMMDD_<场景>_<简述>.mp4`
|
||||||
|
- `YYYYMMDD_<场景>_<简述>.png`
|
||||||
|
|
||||||
|
例如:
|
||||||
|
- `20260119_AppleHome_Commissioning.mp4`
|
||||||
|
- `20260119_OTA_HTTP_Upgrade_2.0_to_2.1.mp4`
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
04_Test_Report/Remote_Control_and_Group_Control/双版本(单色,双色温).mp4
Normal file
BIN
04_Test_Report/Remote_Control_and_Group_Control/双版本(单色,双色温).mp4
Normal file
Binary file not shown.
56
05_Docs/Architecture.md
Normal file
56
05_Docs/Architecture.md
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
# 技术方案与架构说明(ESP32-C6 Matter + ESP-NOW)
|
||||||
|
|
||||||
|
## 1. 总体目标
|
||||||
|
|
||||||
|
在 ESP32-C6 单芯片上实现:
|
||||||
|
- 遥控器侧 ESP-NOW 控制(固定信道 `channel=1`)
|
||||||
|
- Matter 侧生态接入(Apple Home 已验证)
|
||||||
|
- 远程 HTTP OTA 升级
|
||||||
|
|
||||||
|
## 2. 网络/射频架构(核心)
|
||||||
|
|
||||||
|
为满足“遥控器固件不变 + ESP-NOW 固定信道=1”的约束,采用 ESP32-C6 双射频分工:
|
||||||
|
|
||||||
|
- **Wi-Fi 2.4GHz 射频**:专用于 ESP-NOW(固定 channel=1)
|
||||||
|
- **802.15.4 射频(Thread)**:用于 Matter 网络承载
|
||||||
|
- **BLE**:用于 Matter commissioning(配网阶段)
|
||||||
|
|
||||||
|
该架构可避免 Wi-Fi STA 信道由路由器决定导致与 ESP-NOW 冲突的问题。
|
||||||
|
|
||||||
|
## 3. Matter 设备模型
|
||||||
|
|
||||||
|
- **Endpoint 1(单色灯)**:OnOff + LevelControl
|
||||||
|
- **Endpoint 2(双色温灯)**:OnOff + LevelControl + ColorControl(ColorTemperature)
|
||||||
|
- 已验证:Groups / Scenes 可创建与应用
|
||||||
|
|
||||||
|
## 4. 驱动与硬件接口
|
||||||
|
|
||||||
|
- 单色灯:LEDC PWM(RGB 三路混白)
|
||||||
|
- 双色温:SK6812 RGBW,RMT 单线驱动,使用 ColorTemperature 映射实现色温效果
|
||||||
|
|
||||||
|
## 5. ESP-NOW 与 Matter 状态同步
|
||||||
|
|
||||||
|
- 设备接收遥控器 ESP-NOW 命令(0x01..0x05/0xA5),映射为灯控动作
|
||||||
|
- 同步更新 Matter 属性,保证 App 侧状态一致
|
||||||
|
- 支持多设备联调:遥控器 Zone1/Zone2 + App 同时控制两台灯具
|
||||||
|
|
||||||
|
## 6. OTA 方案(交付采用)
|
||||||
|
|
||||||
|
交付采用 **HTTP OTA(远程服务器下载固件)**:
|
||||||
|
- 设备从 HTTP 服务器下载 `light.bin` 并写入 OTA 分区
|
||||||
|
- 通过 Matter shell 命令触发:`matter esp ota <http://url>`
|
||||||
|
- 分区表为双 OTA:`ota_0/ota_1/otadata`
|
||||||
|
|
||||||
|
详细部署说明见:`OTA_HTTP_Deploy_Guide.md`。
|
||||||
|
|
||||||
|
## 7. 配网与二维码
|
||||||
|
|
||||||
|
- 设备启动可输出 onboarding codes(QR 字符串 `MT:...` 与 manual pairing code)
|
||||||
|
- 交付提供 `SetupPayload.py` 工具用于生成/解析配网码
|
||||||
|
|
||||||
|
## 8. 工程与交付
|
||||||
|
|
||||||
|
- 源码快照:`Deliverable/01_Source/matter-light-c6-wifi`
|
||||||
|
- 固件 bin:`Deliverable/02_Firmware_Binaries/*`
|
||||||
|
- 烧录说明:`Deliverable/03_Flash_and_Tools/Flash_Guide_CN.md`
|
||||||
|
- 测试素材目录:`Deliverable/04_Test_Report/`
|
||||||
414
05_Docs/DEV_PROGRESS.md
Normal file
414
05_Docs/DEV_PROGRESS.md
Normal file
|
|
@ -0,0 +1,414 @@
|
||||||
|
# ESP32-C6 Matter + ESP-NOW 混合固件开发进度(单色灯 + 双色温灯)
|
||||||
|
|
||||||
|
## 1. 项目目标(来自《项目制作需求》)
|
||||||
|
|
||||||
|
- 基于 ESP32(候选:C3/C6),开发 Matter + ESP-NOW 混合固件。
|
||||||
|
- 支持两类灯:
|
||||||
|
- 单色灯:开关 + 调光(白光)。
|
||||||
|
- 双色温灯:开关 + 调光 + 调色温(暖/冷)。
|
||||||
|
- 开发阶段:Wi-Fi commissioning(通过 Wi-Fi 完成配网)。
|
||||||
|
- 最终目标:Wi-Fi 完成配网、Thread 实现本地 mesh 控制(混合网络模式)。
|
||||||
|
- 需要 OTA、QR 码生成、VID/PID/DAC 相关出厂数据与认证准备支持。
|
||||||
|
- 交付:双版本(或可配置)源码仓库 + Factory/OTA 固件 + 烧录/QR 脚本 + 测试报告 + 技术文档。
|
||||||
|
|
||||||
|
## 1.1 关键硬性约束与解决方案
|
||||||
|
|
||||||
|
- 量产遥控器固件不变,且 ESP-NOW 固定信道为 `channel=1`。
|
||||||
|
- **问题**:若使用 Matter-over-Wi-Fi,Wi-Fi STA 信道会被路由器决定,与 ESP-NOW 固定 ch1 冲突。
|
||||||
|
- **解决方案**:利用 ESP32-C6 的**双射频**能力:
|
||||||
|
- **Wi-Fi 2.4GHz 射频**:专用于 ESP-NOW(固定 channel 1,不连接路由器做 STA)
|
||||||
|
- **802.15.4 射频**:专用于 Matter over Thread(与 Wi-Fi 射频完全独立)
|
||||||
|
- **BLE**:用于 Matter commissioning(配网阶段)
|
||||||
|
- 结论:单芯片 ESP32-C6 可实现 ESP-NOW + Matter 共存,无需依赖路由器信道。
|
||||||
|
|
||||||
|
## 1.2 需求对齐清单(当前工程状态)
|
||||||
|
|
||||||
|
| 需求项 | 状态 | 备注 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| ESP-NOW 代码功能 100% 保持 | 部分 | 已按遥控器协议实现 RX/配对/命令映射,但信道冲突仍未解决为“量产可用”方案 |
|
||||||
|
| Matter clusters: OnOff / LevelControl | 已完成 | 双 endpoint 已跑通 |
|
||||||
|
| Matter clusters: Groups / Scenes | 已完成(已验证) | 已在 App 上验证可创建/应用场景 |
|
||||||
|
| ColorControl(双色温) | 已完成(开发态) | 当前实现为 ColorTemperature;已确认硬件为 SK6812 RGBW 模块,调色温方向正常 |
|
||||||
|
| ESP-NOW 组播/广播组命令→所有控制器同步→Matter 状态更新 | 已完成(已稳定) | 控制器能处理 cmd 并更新 Matter 属性;组控一致性/延迟表现正常,无需再测试 |
|
||||||
|
| QR 码配网(Apple/Google/Alexa/RainMaker) | 部分 | iOS Home 已验证;Google/Alexa/RainMaker 未做系统性验证 |
|
||||||
|
| OTA(HTTP 远程服务器) | 已完成 | 已实现 HTTP OTA(从远程服务器下载固件),可通过 Matter shell 命令触发,已验证升级后 App version 变更 |
|
||||||
|
| Matter 标准 OTA | 暂停 | 采用 HTTP OTA(远程服务器)方案,不再推进标准 Matter OTA |
|
||||||
|
| 断电重置(如 3 次开关机) | 已完成(已稳定) | 已实现并验证:3 次重启触发 Matter 工厂重置(含 5 秒确认窗);已测试稳定,无需再测 |
|
||||||
|
| 交付:源码/编译说明/bin/脚本/测试报告 | 进行中 | 文档与脚本需要补齐并固化 |
|
||||||
|
|
||||||
|
## 1.4 当前进度总览(已完成 vs 未完成)
|
||||||
|
|
||||||
|
### 1.4.1 已完成
|
||||||
|
|
||||||
|
- HTTP OTA(远程服务器下载固件,shell 命令触发),并验证升级成功后 `App version` 变更(2.0 → 2.1)
|
||||||
|
- Matter clusters: Groups / Scenes 已在 App 上验证可创建/应用场景
|
||||||
|
- 分区表调整为双 OTA(`ota_0`/`ota_1`/`otadata`),固件大小可容纳 OTA 升级
|
||||||
|
- OTA 触发命令已接入 Matter shell(`matter esp ota <http://url>`)
|
||||||
|
- 已可在 Windows 上稳定完成 build/flash/monitor(含 GN/Pigweed 环境)
|
||||||
|
- 断电重置(工厂重置):已实现并验证 3 次重启触发 factory reset(含 5 秒确认窗),重置后进入可重新配网状态
|
||||||
|
- 修复断电计数不生效问题:将 NVS key 缩短到 15 字符以内并加入兼容读取逻辑
|
||||||
|
- ESP-NOW 配对与多设备联调:已支持“单遥控器(Zone1/Zone2)+ APP”控制两台 ESP32-C6 灯具;并修复“电源重启触发配对时未及时广播配对 beacon”的问题,提升遥控器绑定成功率
|
||||||
|
|
||||||
|
### 1.4.2 未完成(待办)
|
||||||
|
|
||||||
|
- 多生态验证:Google Home / Alexa / RainMaker 的 commissioning + 控制验证
|
||||||
|
- 交付物固化:一键环境初始化/构建脚本、烧录脚本、测试报告与完整技术文档
|
||||||
|
|
||||||
|
## 3. 已完成的关键里程碑
|
||||||
|
|
||||||
|
### 3.1 构建与烧录链路打通(Windows)
|
||||||
|
|
||||||
|
- 已实现:`idf.py build` 成功、可 `flash` 到 COM4、可 `monitor` 观察启动日志。
|
||||||
|
- 已解决的关键构建问题(历史记录):
|
||||||
|
- `gn command not found`:定位 `gn.exe` 并加入 PATH。
|
||||||
|
- Pigweed 环境变量缺失:补齐 `_PW_ACTUAL_ENVIRONMENT_ROOT`。
|
||||||
|
- 链接错误 `undefined reference to mbedtls_hkdf`:启用 `CONFIG_MBEDTLS_HKDF_C=y`。
|
||||||
|
- app 分区过小:切换到自定义分区表 `partitions.csv`(双 OTA),并设置 flash size=16MB(与硬件一致),最小 app 分区 `0x1E0000`。
|
||||||
|
- Windows 反斜杠路径导致 CMake `Invalid character escape`:CMakeLists 里将 env path 转为 CMake path。
|
||||||
|
|
||||||
|
补充:构建该工程的关键环境变量(PowerShell 会话级别):
|
||||||
|
|
||||||
|
- `ESP_MATTER_PATH=D:\ESP-LED\esp-matter-gh`
|
||||||
|
- `ESP_MATTER_DEVICE_PATH=D:\ESP-LED\esp-matter-gh\device_hal\device\esp32c6_devkit_c`
|
||||||
|
- `_PW_ACTUAL_ENVIRONMENT_ROOT=D:\ESP-LED\esp-matter-gh\connectedhomeip\connectedhomeip\third_party\pigweed\repo\environment`
|
||||||
|
- GN 工具路径(将目录加入 PATH):
|
||||||
|
- `...\third_party\pigweed\repo\environment\cipd\packages\pigweed`(包含 `gn.exe`)
|
||||||
|
|
||||||
|
### 3.2 Matter 双 endpoint 架构(已运行验证)
|
||||||
|
|
||||||
|
- 当前固件创建两个 endpoint:
|
||||||
|
- Endpoint 1:单色灯(OnOff + LevelControl)。
|
||||||
|
- Endpoint 2:双色温灯(OnOff + LevelControl + ColorControl(ColorTemperature))。
|
||||||
|
- 串口日志已确认:
|
||||||
|
- `RGB light created with endpoint_id 1`
|
||||||
|
- `CCT light created with endpoint_id 2`
|
||||||
|
|
||||||
|
### 3.3 驱动层对接(已跑通)
|
||||||
|
|
||||||
|
- Endpoint 1(单色灯):LEDC PWM 驱动(GPIO4/5/6)。
|
||||||
|
- Endpoint 2(双色温灯):RMT 驱动 SK6812(GPIO2)。
|
||||||
|
|
||||||
|
### 3.4 日志报错修复
|
||||||
|
|
||||||
|
- 修复启动时 `E data_model: Cluster cannot be NULL.`:
|
||||||
|
- 原因:对不含 ColorControl 的 endpoint 调用 `attribute::get(endpoint, ColorControl...)`。
|
||||||
|
- 处理:先检查 `cluster::get(endpoint, ColorControl::Id)` 是否存在,再读取 ColorMode / Hue / Temp 等属性。
|
||||||
|
|
||||||
|
### 3.5 iOS Home / Matter Commissioning + 控制验证(已完成)
|
||||||
|
|
||||||
|
- 现状:手机端已完成配网,Home App 可同时控制两个灯的开关/亮度/(CCT 灯)色温。
|
||||||
|
- 关键修复:为满足 iOS Home 的发现/配网流程,已启用 BLE commissioning:
|
||||||
|
- `CONFIG_BT_ENABLED=y`
|
||||||
|
- `CONFIG_BT_NIMBLE_ENABLED=y`
|
||||||
|
- `CONFIG_ENABLE_CHIPOBLE=y`
|
||||||
|
- 串口日志关键特征(表示 BLE commissioning 正常):
|
||||||
|
- `Configuring CHIPoBLE advertising ...`
|
||||||
|
- `CHIPoBLE advertising started`
|
||||||
|
- `Commissioning window opened`
|
||||||
|
- 设备启动时可打印 Onboarding Codes(用于手动输入/生成二维码):
|
||||||
|
- MT 串(SetupQRCode):`MT:Y.K9042C00KA0648G00`
|
||||||
|
- 11 位码(Manual pairing code):`34970112332`
|
||||||
|
- 注意:上述二维码/手动码为开发阶段示例/测试参数(默认 VID/PID 等),量产需替换正式 VID/PID、DAC/CD/工厂数据与每台唯一的 onboarding 信息。
|
||||||
|
|
||||||
|
### 3.6 单芯片双射频方案验证成功(2026-01-07)
|
||||||
|
|
||||||
|
- **架构**:ESP32-C6 单芯片同时运行:
|
||||||
|
- **Thread (802.15.4)**:Matter 网络层
|
||||||
|
- **Wi-Fi (channel 1)**:ESP-NOW 接收(不连接路由器)
|
||||||
|
- **BLE**:Matter commissioning
|
||||||
|
- **关键配置**:
|
||||||
|
- `CONFIG_ENABLE_WIFI_STATION=n`:禁用 Matter Wi-Fi STA
|
||||||
|
- `CONFIG_ENABLE_THREAD=y`:启用 Matter over Thread
|
||||||
|
- 独立初始化 Wi-Fi 用于 ESP-NOW,固定 channel 1
|
||||||
|
- **验证通过的日志特征**:
|
||||||
|
- `OpenThread started: OK`
|
||||||
|
- `Wi-Fi channel fixed to 1 for ESP-NOW`
|
||||||
|
- `ESP-NOW RX initialized`
|
||||||
|
- `CHIPoBLE advertising started`
|
||||||
|
- `Server Listening...`
|
||||||
|
- **固件大小**:~2MB(含 Thread + Wi-Fi + BLE + ESP-NOW)
|
||||||
|
- **状态**:设备稳定启动,无崩溃
|
||||||
|
|
||||||
|
### 3.7 HTTP OTA(远程服务器)验证成功(2026-01-15)
|
||||||
|
|
||||||
|
- **目标**:支持“远程服务器方式”OTA(HTTP),不依赖 HTTPS/TLS,固件体积可控。
|
||||||
|
- **实现概览**:
|
||||||
|
- 使用 `esp_http_client` + `esp_ota_*` 实现分段下载与写入 OTA 分区。
|
||||||
|
- 提供 Matter shell 命令触发:`matter esp ota <http://url>`。
|
||||||
|
- 仅支持 `http://`,拒绝 `https://` 以减小固件体积。
|
||||||
|
- **验证结果(串口日志特征)**:
|
||||||
|
- `HTTP OTA progress: ... 100%`
|
||||||
|
- `HTTP OTA upgrade successful! Rebooting in 3 seconds...`
|
||||||
|
- 重启后:`Loaded app from partition at offset 0x210000`(切换到 ota_1)
|
||||||
|
- 重启后:`App version: 2.1`(已确认版本号随固件更新)
|
||||||
|
|
||||||
|
### 3.8 多设备控制联调进展(APP + ESP-NOW 遥控器)(2026-01-15)
|
||||||
|
|
||||||
|
- **目标**:一台遥控器 + 手机 App 同时控制两台 ESP32-C6 灯具(两块开发板)。
|
||||||
|
- **实现状态**:
|
||||||
|
- App 侧(iOS Home)已可同时添加两台设备并分别控制。
|
||||||
|
- 遥控器侧支持 Zone1/Zone2 独立绑定不同灯具(通过 ESP-NOW 配对流程完成)。
|
||||||
|
- **配对机制(开发态)**:
|
||||||
|
- 3 次重启:触发 Matter factory reset(5 秒确认窗)。
|
||||||
|
- 5 次重启:进入 ESP-NOW pairing mode(5 秒确认窗)。
|
||||||
|
- 遥控器在目标 Zone 下长按配对键,设备收到 `0xA5` 后退出配对模式。
|
||||||
|
- **关键修复**:
|
||||||
|
- 修复“电源重启触发配对模式后,因 Wi-Fi 连接状态导致配对 beacon 未及时广播”的问题:进入配对后将主动启动配对 beacon 广播,确保遥控器可发现并完成绑定。
|
||||||
|
|
||||||
|
## 4. 当前仍在进行中的问题/待验证点
|
||||||
|
|
||||||
|
### 4.1 单色灯输出"白光"的定义与实现(已确定:RGB 三路混白)
|
||||||
|
|
||||||
|
- 当前单色灯硬件接法为 RGB 三路 PWM(GPIO4/5/6)。
|
||||||
|
- 已做的软件调整:将 RGB 三路占空比设置为 1:1:1(同亮度混色)以尽量呈现白光。
|
||||||
|
- 已确认:单色灯即 RGB 三路混白方案(不做单通道白灯条改造)。
|
||||||
|
- 注意:RGB 分立灯珠近距离仍可能看到“三色点”,属于物理结构;可通过扩散罩/导光改善。
|
||||||
|
|
||||||
|
### 4.2 双色温灯的“暖/冷”实现(已确认:SK6812 RGBW)
|
||||||
|
|
||||||
|
- 已确认:双色温灯硬件为 SK6812 RGBW 模块,采用 RMT 单线驱动。
|
||||||
|
- 当前实现:Matter ColorTemperature(mireds)→ 颜色映射 → SK6812 输出;调色温方向已验证正确。
|
||||||
|
- 注意:SK6812 RGBW 的“色温”属于近似实现(需要 RGB 参与补色),效果取决于映射/校准策略。
|
||||||
|
- 状态:当前效果表现正常,无需再做专项“色温校准/一致性测试”。
|
||||||
|
|
||||||
|
### 4.3 Flash 容量提示告警(已解决)
|
||||||
|
|
||||||
|
- 现象:启动时提示检测到 16MB,但固件镜像头标记为 4MB:
|
||||||
|
- `Detected size(16384k) larger than the size in the binary image header(4096k)`
|
||||||
|
- 影响:通常可运行,但不利于后续分区与 OTA 风险控制。
|
||||||
|
- 已处理并确认:将工程 Flash size 配置调整为 16MB(`CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y`),已复测确认告警消失。
|
||||||
|
|
||||||
|
## 5. 控制器/遥控器(ESP-NOW)现状梳理(已读源码)
|
||||||
|
|
||||||
|
- 控制器原码路径:`D:\ESP-LED\控制器原码\Ecolight\...`
|
||||||
|
- 协议:ESP-NOW(channel=1)
|
||||||
|
- Pairing beacon magic:`0xABCDEF01`(4字节)
|
||||||
|
- 命令(1字节):
|
||||||
|
- `0x01` Toggle
|
||||||
|
- `0x02` On
|
||||||
|
- `0x03` Brightness Up
|
||||||
|
- `0x04` Brightness Down
|
||||||
|
- `0x05` Off
|
||||||
|
- `0xA5` Pairing Confirm
|
||||||
|
|
||||||
|
结论:控制器原码与甲方提供的遥控器一致,且该 ESP-NOW 遥控协议可接入当前 Matter 灯固件(C6 端作为 ESPNOW 接收端),收到命令后同步更新 Matter 属性。
|
||||||
|
|
||||||
|
## 6. VID/PID/DAC/QR 码阶段性策略
|
||||||
|
|
||||||
|
- 开发阶段可以使用示例/测试用的 VID/PID/证书链推进开发。
|
||||||
|
- 后续拿到正式 VID/PID/DAC 后:
|
||||||
|
- 替换证书与出厂数据。
|
||||||
|
- 重新生成 QR。
|
||||||
|
- 通常需要恢复出厂并重新配网(属正常流程)。
|
||||||
|
|
||||||
|
## 7. 下一步开发路线图(按阶段)
|
||||||
|
|
||||||
|
### 阶段 A:功能验证与参数固化(短期)
|
||||||
|
|
||||||
|
- 单色灯:明确硬件定义(RGB 混白 vs 单路白灯条),固化白光方案。
|
||||||
|
- 双色温:已确认 SK6812 RGBW,固化色温映射与效果参数(端点/曲线/gamma/限幅),并确认通道顺序与供电/信号稳定性。
|
||||||
|
- 建立功能测试用例并记录:
|
||||||
|
- endpoint 1:开/关、亮度
|
||||||
|
- endpoint 2:开/关、亮度、色温
|
||||||
|
|
||||||
|
### 阶段 B:ESP-NOW + Matter 共存(核心)
|
||||||
|
|
||||||
|
- 在 C6 Matter 固件中加入 ESPNOW RX:
|
||||||
|
- 接收 1-byte 命令并映射到 endpoint 1/2 的 Matter 属性更新。
|
||||||
|
- 目标:遥控器控制灯,Matter 侧状态同步。
|
||||||
|
- 解决 Wi-Fi channel 与 ESPNOW channel=1 的冲突(以“遥控器固件不变”为前提):
|
||||||
|
- 方案 1(最小改动,但依赖环境):路由器/热点 2.4G 固定 `channel=1`。
|
||||||
|
- 方案 2(推荐量产架构):双芯片/双射频解耦(ESP-NOW 固定 ch1 与 Matter Wi-Fi 任意信道互不影响)。
|
||||||
|
- 方案 3(与 Addendum 对齐):Wi-Fi 用于 commissioning,日常控制走 Thread(需要 Thread Border Router 环境),从而避免 Wi-Fi 信道对 ESP-NOW 的牵制。
|
||||||
|
- 性能目标:端到端延迟 < 20ms(需要定义测量方法和基准)。
|
||||||
|
|
||||||
|
### 7.2 芯片选型建议(C3 vs C6)
|
||||||
|
|
||||||
|
- 若坚持单芯片承载 Matter(含 Groups/Scenes/OTA/多生态)+ 应用逻辑 + ESPNOW:更推荐 ESP32-C6。
|
||||||
|
- 原因:内存与资源更充足,Matter 生态适配与稳定性更优,且可扩展 Thread(满足 Addendum)。
|
||||||
|
- 若控制器仍使用 ESP32-C3:需要评估以下风险项:
|
||||||
|
- Matter + BLE commissioning + OTA + Groups/Scenes 的 RAM/Flash 压力。
|
||||||
|
- 与 ESPNOW 同时运行的峰值内存/任务栈/队列占用。
|
||||||
|
- 当路由器信道不可控且遥控器固件不变时:
|
||||||
|
- 单芯片方案存在先天信道冲突。
|
||||||
|
- 需要硬件/架构调整(例如额外加一颗 C3 专做 ESPNOW 固定 ch1,C6 专做 Matter/Wi-Fi/Thread,通过 UART/SPI 同步状态)。
|
||||||
|
|
||||||
|
### 7.3 方案 A(双芯片解耦)系统架构(量产推荐)
|
||||||
|
|
||||||
|
#### 7.3.1 总体思路
|
||||||
|
|
||||||
|
- MCU1(ESP-NOW 控制器,建议 ESP32-C3):
|
||||||
|
- 只负责:ESP-NOW(固定 ch1)、遥控器配对/命令接收、组控广播一致性、驱动输出(PWM/RMT/恒流等)。
|
||||||
|
- 不连接路由器(或不承担 Matter Wi-Fi)。
|
||||||
|
- MCU2(Matter 控制器,建议 ESP32-C6):
|
||||||
|
- 只负责:Matter over Wi-Fi(commissioning/长久在线/多生态)、(可选)Thread、Matter OTA、Groups/Scenes/状态机。
|
||||||
|
- 通过 UART/SPI 与 MCU1 交换“控制命令/状态变化/诊断”。
|
||||||
|
|
||||||
|
补充确认:本项目采用 UART 作为 MCU1↔MCU2 通信方式。
|
||||||
|
|
||||||
|
#### 7.3.2 数据流与一致性目标
|
||||||
|
|
||||||
|
- 遥控器 → MCU1(ESP-NOW RX)→
|
||||||
|
- MCU1 先本地执行灯控(保证延迟与体验不变)
|
||||||
|
- MCU1 同步上报事件给 MCU2(用于 Matter 属性更新与组/场景一致性)
|
||||||
|
- App/Matter → MCU2(属性更新/命令)→ MCU2 下发到 MCU1 → MCU1 执行驱动输出 → MCU1 回报最终状态给 MCU2(闭环)
|
||||||
|
|
||||||
|
#### 7.3.3 量产可测的关键指标
|
||||||
|
|
||||||
|
- 遥控器端到端延迟(按键到灯输出):目标 < 20 ms(以 MCU1 本地执行为准)
|
||||||
|
- Matter 状态同步延迟(灯输出到 Matter 属性更新可见):给出目标与测量方法(建议 < 200 ms)
|
||||||
|
- 长期稳定性:Wi-Fi/Matter 长久在线,不影响 MCU1 的 ESP-NOW 实时性
|
||||||
|
|
||||||
|
#### 7.3.4 PCB/硬件接口建议(小改动范围)
|
||||||
|
|
||||||
|
- UART:
|
||||||
|
- MCU1_TX -> MCU2_RX(GPIO 待定:MCU1=____ / MCU2=____)
|
||||||
|
- MCU1_RX <- MCU2_TX(GPIO 待定:MCU1=____ / MCU2=____)
|
||||||
|
- 可选硬件流控(建议预留焊盘,量产可按稳定性决定是否启用):
|
||||||
|
- MCU2->MCU1 `RESET_REQ`(请求 MCU1 执行:清码/恢复出厂/重新配对/进入测试)
|
||||||
|
- MCU1->MCU2 `IRQ_EVT`(有新事件/状态上报,降低轮询开销)
|
||||||
|
- 电平:两者均为 3.3V TTL(无需电平转换)
|
||||||
|
- 调试:建议预留测试点(TX/RX/GND)便于产线与现场抓包
|
||||||
|
|
||||||
|
## 8. 测试计划(面向交付物)
|
||||||
|
|
||||||
|
### 8.1 遥控器 + ESP-NOW(不改固件)
|
||||||
|
|
||||||
|
- 工厂重置:三次断电/复位触发工厂重置(含 5 秒确认窗)
|
||||||
|
- 配对:五次断电/复位进入配对模式;遥控器 slot 长按配对
|
||||||
|
- 单控:0x01..0x05 全命令覆盖,重复按键/长按/连发
|
||||||
|
- 组控:遥控器广播组命令,多个控制器同步输出一致
|
||||||
|
- 延迟:示波器/逻辑分析仪测量(按键触发到 GPIO/PWM 变化),记录 P50/P95
|
||||||
|
|
||||||
|
### 8.2 Matter 多生态(MCU2)
|
||||||
|
|
||||||
|
- Apple Home / Google Home / Alexa(至少两项)commissioning 演示
|
||||||
|
- Clusters:OnOff/LevelControl/Groups/Scenes(双色温含 ColorControl)
|
||||||
|
- OTA:升级演示 + 回滚验证
|
||||||
|
|
||||||
|
### 8.3 共存与稳定性
|
||||||
|
|
||||||
|
- Wi-Fi 长久在线(24h/72h)期间,遥控器控制无明显延迟/无丢包异常
|
||||||
|
- 异常恢复:
|
||||||
|
- MCU1 重启不影响 MCU2(Matter 仍在线;状态恢复后同步)
|
||||||
|
- MCU2 重启不影响 MCU1(遥控器控制不中断;MCU2 恢复后重新拉取状态)
|
||||||
|
|
||||||
|
## 9. Matter 功能测试用例(建议用 chip-tool 记录)
|
||||||
|
|
||||||
|
### Endpoint 1(单色灯:开关/调光)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chip-tool onoff on 1 1
|
||||||
|
chip-tool onoff off 1 1
|
||||||
|
chip-tool levelcontrol movetolevelwithonoff 1 1 10 0 0
|
||||||
|
chip-tool levelcontrol movetolevelwithonoff 1 1 200 0 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Endpoint 2(双色温灯:开关/调光/色温)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chip-tool onoff on 1 2
|
||||||
|
chip-tool onoff off 1 2
|
||||||
|
chip-tool levelcontrol movetolevelwithonoff 1 2 20 0 0
|
||||||
|
chip-tool levelcontrol movetolevelwithonoff 1 2 220 0 0
|
||||||
|
chip-tool colorcontrol movetocolortemperature 1 2 153 0 0
|
||||||
|
chip-tool colorcontrol movetocolortemperature 1 2 450 0 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## 10. 风险与注意事项
|
||||||
|
|
||||||
|
- ESPNOW channel 固定为 1:当路由器信道不可固定到 1 且遥控器固件不可改时,单芯片方案存在先天冲突,需要改架构。
|
||||||
|
- 单色灯“白光”体验可能受硬件(RGB 三色灯珠)限制,软件无法消除近距离三色颗粒。
|
||||||
|
- 双色温(SK6812 RGBW)“色温”为近似实现:不同亮度下可能存在色偏;需要通过端点/曲线/gamma 与 RGB/W 分配进行校准。
|
||||||
|
- Thread + Wi-Fi 混合网络模式需要明确最终产品拓扑与测试方法。
|
||||||
|
|
||||||
|
## 11. MCU 间通信协议草案(方案 A)
|
||||||
|
|
||||||
|
### 11.1 物理层与链路建议
|
||||||
|
|
||||||
|
- UART:建议 921600 或 1Mbps,8N1
|
||||||
|
- 帧格式:固定 header + version + flags + type + seq + len + payload + CRC32
|
||||||
|
- 可靠性建议:
|
||||||
|
- 带 `seq` 与 `ACK`(至少对“状态设置/模式切换/工厂重置”等关键命令)
|
||||||
|
- 对“按键事件上报”可不必 ACK,但需要丢包容忍(MCU2 以 MCU1 的最终状态为准)
|
||||||
|
|
||||||
|
### 11.1.1 帧格式(建议稿,可直接实现)
|
||||||
|
|
||||||
|
- `SOF`:2 bytes,固定 `0x55 0xAA`
|
||||||
|
- `VER`:1 byte,协议版本(初版 `0x01`)
|
||||||
|
- `FLAGS`:1 byte
|
||||||
|
- bit0:是否需要 ACK
|
||||||
|
- bit1:是否为 ACK 包
|
||||||
|
- bit2:错误包
|
||||||
|
- bit3..7:预留
|
||||||
|
- `TYPE`:1 byte,消息类型
|
||||||
|
- `SEQ`:2 bytes,递增序号(小端)
|
||||||
|
- `LEN`:2 bytes,payload 长度(小端,0..1024 建议上限)
|
||||||
|
- `PAYLOAD`:LEN bytes
|
||||||
|
- `CRC32`:4 bytes(对从 `VER` 到 `PAYLOAD` 的 CRC32,小端)
|
||||||
|
|
||||||
|
### 11.1.2 ACK/重试/超时(建议稿)
|
||||||
|
|
||||||
|
- 对 `FLAGS.need_ack=1` 的包:
|
||||||
|
- 接收方在成功处理后回 `ACK` 包(`FLAGS.is_ack=1`,`SEQ` 原样回显,`TYPE`=原 TYPE 或 `TYPE=ACK(0x7F)` 二选一)
|
||||||
|
- 发送方超时 `T_ACK=50ms` 未收到 ACK:重发,最多 `N_RETRY=3`
|
||||||
|
- 连续失败后进入降级策略:记录错误计数并上报 `EVT_DIAG`(或触发重新握手)
|
||||||
|
- 对 `EVT_KEY_CMD`:可 `need_ack=0`(允许丢);但要求 MCU1 后续用 `EVT_LOCAL_STATE` 做闭环状态同步
|
||||||
|
|
||||||
|
### 11.1.3 上电/复位握手(建议稿)
|
||||||
|
|
||||||
|
- MCU2 启动后发送 `HELLO`(包含 MCU2 fw_ver/proto_ver/boot_reason)
|
||||||
|
- MCU1 回 `HELLO_RSP`(包含 MCU1 fw_ver/proto_ver、灯型/能力、当前输出状态摘要)
|
||||||
|
- MCU2 收到后发送 `GET_STATE`(拉取完整状态),并以此刷新 Matter 属性(避免 MCU2 重启后状态漂移)
|
||||||
|
|
||||||
|
### 11.2 消息类型(最小集)
|
||||||
|
|
||||||
|
- `EVT_KEY_CMD`(MCU1→MCU2):遥控器命令事件
|
||||||
|
- 字段:cmd(0x01..0x05/扩展)、src_mac、timestamp、group_mode/slot
|
||||||
|
- `EVT_LOCAL_STATE`(MCU1→MCU2):MCU1 本地执行后的最终状态
|
||||||
|
- 字段:endpoint/light_id、onoff、level、cct(如有)、transition_time
|
||||||
|
- `SET_STATE`(MCU2→MCU1):来自 Matter 的控制请求
|
||||||
|
- 字段:目标灯/组、onoff/level/cct、期望渐变时间
|
||||||
|
- `SET_MODE`(MCU2→MCU1):模式切换(配对、清码、恢复出厂、进入测试模式)
|
||||||
|
- `HEARTBEAT`(双向):存活与版本信息(fw_ver、proto_ver、uptime、heap)
|
||||||
|
|
||||||
|
建议补充类型:
|
||||||
|
|
||||||
|
- `GET_STATE`(MCU2→MCU1):请求 MCU1 上报完整状态
|
||||||
|
- `EVT_DIAG`(双向):错误码/计数器(CRC 错、丢包、重试次数、WDT、重启原因)
|
||||||
|
|
||||||
|
### 11.2.1 字段定义建议(便于落地与调试)
|
||||||
|
|
||||||
|
- `light_id`:1 byte
|
||||||
|
- `0x01` 单色灯
|
||||||
|
- `0x02` 双色温灯
|
||||||
|
- `onoff`:1 byte(0/1)
|
||||||
|
- `level`:1 byte(0..254,按 Matter 约定)
|
||||||
|
- `cct_mireds`:2 bytes(小端,按 Matter ColorTemperatureMireds)
|
||||||
|
- `transition_ms`:2 bytes(小端)
|
||||||
|
- `timestamp_ms`:4 bytes(小端,MCU1 uptime 毫秒)
|
||||||
|
|
||||||
|
### 11.3 一致性原则(避免双写打架)
|
||||||
|
|
||||||
|
- MCU1 为“灯输出唯一权威”(source of truth for physical output)。
|
||||||
|
- MCU2 为“ Matter 属性权威”(source of truth for ecosystem state)。
|
||||||
|
- MCU2 更新 Matter 属性应以 `EVT_LOCAL_STATE` 为准,而不是以 `EVT_KEY_CMD` 直接推导(防止执行失败/限幅/场景叠加导致不一致)。
|
||||||
|
|
||||||
|
## 11.4 PCB 连线清单(方案 A,UART)
|
||||||
|
|
||||||
|
- UART:
|
||||||
|
- MCU1_TX -> MCU2_RX(GPIO 待定:MCU1=____ / MCU2=____)
|
||||||
|
- MCU1_RX <- MCU2_TX(GPIO 待定:MCU1=____ / MCU2=____)
|
||||||
|
- 可选硬件流控(建议预留焊盘,量产可按稳定性决定是否启用):
|
||||||
|
- MCU1_RTS / MCU1_CTS
|
||||||
|
- MCU2_RTS / MCU2_CTS
|
||||||
|
- 额外控制/中断线(建议预留):
|
||||||
|
- MCU2->MCU1 `RESET_REQ`(请求 MCU1 执行:清码/恢复出厂/重新配对/进入测试)
|
||||||
|
- MCU1->MCU2 `IRQ_EVT`(有新事件/状态上报,降低轮询开销)
|
||||||
|
- 电平:两者均为 3.3V TTL(无需电平转换)
|
||||||
|
- 调试:建议预留测试点(TX/RX/GND)便于产线与现场抓包
|
||||||
|
|
||||||
|
## 13. 可对外汇报摘要(可直接发甲方)
|
||||||
|
|
||||||
|
本阶段已完成 ESP32-C6 Matter + ESP-NOW 混合固件的核心功能联调:固件已实现双 endpoint(单色灯 + 双色温灯)并通过 iOS Home 完成 Matter commissioning 与控制验证;同时接入甲方量产遥控器的 ESP-NOW 协议(channel=1、命令 0x01..0x05/0xA5),可通过“5 次重启进入配对模式 + 遥控器 Zone 配对”实现一台遥控器(Zone1/Zone2)分别绑定两台 ESP32-C6 灯具。当前 APP(iOS Home)与遥控器均可对两台设备进行控制;设备支持 HTTP OTA(远程服务器下载升级,支持双 OTA 分区切换),已验证升级后版本号变化。下一步将推进 Google Home/Alexa/RainMaker 等生态兼容性测试,并固化交付脚本、测试报告与完整技术文档。
|
||||||
|
|
||||||
123
05_Docs/OTA_HTTP_Deploy_Guide.md
Normal file
123
05_Docs/OTA_HTTP_Deploy_Guide.md
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
# 远程 HTTP OTA 部署说明(ESP32-C6,HTTP OTA)
|
||||||
|
|
||||||
|
本项目采用“远程服务器 HTTP OTA”方案(设备从 HTTP 服务器下载 `light.bin` 并写入 OTA 分区),不依赖 Matter 标准 OTA Provider。
|
||||||
|
|
||||||
|
交付目录相关文件:
|
||||||
|
- OTA 文件:`Deliverable/02_Firmware_Binaries/cct/ota/light.bin`
|
||||||
|
- 设备端触发命令:Matter shell 命令 `matter esp ota <http://...>`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. OTA 文件与命名建议
|
||||||
|
|
||||||
|
建议按“产品/型号/版本号”组织目录,避免覆盖与混淆。
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
```
|
||||||
|
/ota/
|
||||||
|
cct/
|
||||||
|
2.1/
|
||||||
|
light.bin
|
||||||
|
sha256.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
- `light.bin`:本次升级包
|
||||||
|
- `sha256.txt`(建议):文件校验值(用于发布侧校验/人工核对)
|
||||||
|
|
||||||
|
> 备注:当前设备端实现为 HTTP OTA(非 HTTPS),因此建议仅在内网或受控网络环境使用;若后续要上公网,建议评估签名校验或改为 HTTPS。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 部署方式(最简单:静态 HTTP)
|
||||||
|
|
||||||
|
任何能提供静态文件下载的 HTTP 服务都可以,例如:
|
||||||
|
- Nginx
|
||||||
|
- Apache
|
||||||
|
- Python 简易 HTTP 服务(仅用于开发/演示)
|
||||||
|
|
||||||
|
### 2.1 示例:Python 简易 HTTP(演示用)
|
||||||
|
|
||||||
|
在放置 `light.bin` 的目录启动:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Windows PowerShell
|
||||||
|
python -m http.server 8000
|
||||||
|
```
|
||||||
|
|
||||||
|
访问 URL 示例:
|
||||||
|
- `http://<PC_IP>:8000/light.bin`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 设备端触发 OTA
|
||||||
|
|
||||||
|
### 3.1 触发命令
|
||||||
|
|
||||||
|
设备串口进入 Matter shell 后,执行:
|
||||||
|
|
||||||
|
```text
|
||||||
|
matter esp ota http://<SERVER_IP>:<PORT>/path/to/light.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
```text
|
||||||
|
matter esp ota http://192.168.1.10:8000/light.bin
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 预期日志特征
|
||||||
|
|
||||||
|
升级过程中一般可看到:
|
||||||
|
- 下载进度(0% → 100%)
|
||||||
|
- 写入 OTA 分区成功
|
||||||
|
- 提示升级成功并延时重启
|
||||||
|
- 重启后从另一 OTA 分区启动(例如 `Loaded app from partition ...`)
|
||||||
|
- 启动日志中的 `App version` 更新
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 版本管理建议
|
||||||
|
|
||||||
|
### 4.1 版本号两件事需要一致
|
||||||
|
|
||||||
|
- **固件内部版本号**(启动日志里的 `App version`)
|
||||||
|
- **OTA 镜像头版本字段**(用于升级判断与记录)
|
||||||
|
|
||||||
|
建议每次发布新固件时同步更新版本号(例如 2.0 → 2.1)。
|
||||||
|
|
||||||
|
### 4.2 服务器侧发布策略
|
||||||
|
|
||||||
|
- 不覆盖旧版本文件,按版本目录存放
|
||||||
|
- 用“latest”软链接/重定向(可选)
|
||||||
|
- 记录每次发布的:版本号、发布时间、文件 SHA256
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 常见问题排查
|
||||||
|
|
||||||
|
### 5.1 设备提示 404/无法连接
|
||||||
|
|
||||||
|
- 检查 URL 是否可在 PC 浏览器直接下载
|
||||||
|
- 检查服务器与设备是否在同一网段、是否被防火墙拦截
|
||||||
|
- 确认端口未被占用
|
||||||
|
|
||||||
|
### 5.2 下载中断/升级失败
|
||||||
|
|
||||||
|
- 检查 Wi-Fi/Thread 网络稳定性(尤其是演示环境)
|
||||||
|
- 检查固件文件大小是否超出分区容量
|
||||||
|
- 确认分区表为双 OTA(`ota_0/ota_1/otadata`)
|
||||||
|
|
||||||
|
### 5.3 升级后版本号未变化
|
||||||
|
|
||||||
|
- 确认你上传的是新版本 `light.bin`
|
||||||
|
- 确认构建时已修改工程版本号(例如 `PROJECT_VER` / `PROJECT_VER_NUMBER`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 交付说明(建议写在测试报告里)
|
||||||
|
|
||||||
|
建议在测试报告中附:
|
||||||
|
- 服务器目录与 URL 示例
|
||||||
|
- 设备执行 `matter esp ota` 的截图/视频
|
||||||
|
- 升级前后 `App version` 对比截图/视频
|
||||||
Loading…
Reference in New Issue
Block a user