From 496b8411773243e1ad88a68652d6982ba2366d6b Mon Sep 17 00:00:00 2001 From: is-qian <2716275834@qq.com> Date: Tue, 21 Jan 2025 19:24:00 +0800 Subject: [PATCH 01/79] feat(esp32): Added a new device(xiao esp32s3 plus) (#10768) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(esp32): Added a new device(xiao esp32s3 plus) * Update boards.txt * Apply suggestions from code review * Fix filename error. * Fix filename error. * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- boards.txt | 178 ++++++++++++++++++ .../XIAO_ESP32S3_Plus/bootloader-tinyuf2.bin | Bin 0 -> 21408 bytes variants/XIAO_ESP32S3_Plus/partitions-8MB.csv | 10 + variants/XIAO_ESP32S3_Plus/pins_arduino.h | 90 +++++++++ variants/XIAO_ESP32S3_Plus/tinyuf2.bin | Bin 0 -> 141936 bytes 5 files changed, 278 insertions(+) create mode 100644 variants/XIAO_ESP32S3_Plus/bootloader-tinyuf2.bin create mode 100644 variants/XIAO_ESP32S3_Plus/partitions-8MB.csv create mode 100644 variants/XIAO_ESP32S3_Plus/pins_arduino.h create mode 100644 variants/XIAO_ESP32S3_Plus/tinyuf2.bin diff --git a/boards.txt b/boards.txt index 8e9655cda48..9ecd6359759 100644 --- a/boards.txt +++ b/boards.txt @@ -35211,6 +35211,184 @@ XIAO_ESP32S3.menu.EraseFlash.all.upload.erase_cmd=-e ############################################################## +XIAO_ESP32S3_Plus.name=XIAO_ESP32S3_PLUS +XIAO_ESP32S3_Plus.vid.0=0x2886 +XIAO_ESP32S3_Plus.pid.0=0x0063 +XIAO_ESP32S3_Plus.vid.1=0x2886 +XIAO_ESP32S3_Plus.pid.1=0x8063 + +XIAO_ESP32S3_Plus.bootloader.tool=esptool_py +XIAO_ESP32S3_Plus.bootloader.tool.default=esptool_py + +XIAO_ESP32S3_Plus.upload.tool=esptool_py +XIAO_ESP32S3_Plus.upload.tool.default=esptool_py +XIAO_ESP32S3_Plus.upload.tool.network=esp_ota + +XIAO_ESP32S3_Plus.upload.maximum_size=1310720 +XIAO_ESP32S3_Plus.upload.maximum_data_size=327680 +XIAO_ESP32S3_Plus.upload.flags= +XIAO_ESP32S3_Plus.upload.extra_flags= +XIAO_ESP32S3_Plus.upload.use_1200bps_touch=false +XIAO_ESP32S3_Plus.upload.wait_for_upload_port=false + +XIAO_ESP32S3_Plus.serial.disableDTR=false +XIAO_ESP32S3_Plus.serial.disableRTS=false + +XIAO_ESP32S3_Plus.build.tarch=xtensa +XIAO_ESP32S3_Plus.build.bootloader_addr=0x0 +XIAO_ESP32S3_Plus.build.target=esp32s3 +XIAO_ESP32S3_Plus.build.mcu=esp32s3 +XIAO_ESP32S3_Plus.build.core=esp32 +XIAO_ESP32S3_Plus.build.variant=XIAO_ESP32S3_Plus +XIAO_ESP32S3_Plus.build.board=XIAO_ESP32S3_PLUS + +XIAO_ESP32S3_Plus.build.usb_mode=0 +XIAO_ESP32S3_Plus.build.cdc_on_boot=1 +XIAO_ESP32S3_Plus.build.msc_on_boot=0 +XIAO_ESP32S3_Plus.build.dfu_on_boot=0 +XIAO_ESP32S3_Plus.build.f_cpu=240000000L +XIAO_ESP32S3_Plus.build.flash_size=8MB +XIAO_ESP32S3_Plus.build.flash_freq=80m +XIAO_ESP32S3_Plus.build.flash_mode=dio +XIAO_ESP32S3_Plus.build.boot=qio +XIAO_ESP32S3_Plus.build.boot_freq=80m +XIAO_ESP32S3_Plus.build.partitions=default_8MB +XIAO_ESP32S3_Plus.build.defines= +XIAO_ESP32S3_Plus.build.loop_core= +XIAO_ESP32S3_Plus.build.event_core= +XIAO_ESP32S3_Plus.build.psram_type=qspi +XIAO_ESP32S3_Plus.build.memory_type={build.boot}_{build.psram_type} + +XIAO_ESP32S3_Plus.menu.JTAGAdapter.default=Disabled +XIAO_ESP32S3_Plus.menu.JTAGAdapter.default.build.copy_jtag_files=0 +XIAO_ESP32S3_Plus.menu.JTAGAdapter.builtin=Integrated USB JTAG +XIAO_ESP32S3_Plus.menu.JTAGAdapter.builtin.build.openocdscript=esp32s3-builtin.cfg +XIAO_ESP32S3_Plus.menu.JTAGAdapter.builtin.build.copy_jtag_files=1 +XIAO_ESP32S3_Plus.menu.JTAGAdapter.external=FTDI Adapter +XIAO_ESP32S3_Plus.menu.JTAGAdapter.external.build.openocdscript=esp32s3-ftdi.cfg +XIAO_ESP32S3_Plus.menu.JTAGAdapter.external.build.copy_jtag_files=1 +XIAO_ESP32S3_Plus.menu.JTAGAdapter.bridge=ESP USB Bridge +XIAO_ESP32S3_Plus.menu.JTAGAdapter.bridge.build.openocdscript=esp32s3-bridge.cfg +XIAO_ESP32S3_Plus.menu.JTAGAdapter.bridge.build.copy_jtag_files=1 + +XIAO_ESP32S3_Plus.menu.PSRAM.disabled=Disabled +XIAO_ESP32S3_Plus.menu.PSRAM.disabled.build.defines= +XIAO_ESP32S3_Plus.menu.PSRAM.disabled.build.psram_type=qspi +XIAO_ESP32S3_Plus.menu.PSRAM.opi=OPI PSRAM +XIAO_ESP32S3_Plus.menu.PSRAM.opi.build.defines=-DBOARD_HAS_PSRAM +XIAO_ESP32S3_Plus.menu.PSRAM.opi.build.psram_type=opi + +XIAO_ESP32S3_Plus.menu.FlashMode.qio=QIO 80MHz +XIAO_ESP32S3_Plus.menu.FlashMode.qio.build.flash_mode=dio +XIAO_ESP32S3_Plus.menu.FlashMode.qio.build.boot=qio +XIAO_ESP32S3_Plus.menu.FlashMode.qio.build.boot_freq=80m +XIAO_ESP32S3_Plus.menu.FlashMode.qio.build.flash_freq=80m +XIAO_ESP32S3_Plus.menu.FlashMode.dio=DIO 80MHz +XIAO_ESP32S3_Plus.menu.FlashMode.dio.build.flash_mode=dio +XIAO_ESP32S3_Plus.menu.FlashMode.dio.build.boot=dio +XIAO_ESP32S3_Plus.menu.FlashMode.dio.build.boot_freq=80m +XIAO_ESP32S3_Plus.menu.FlashMode.dio.build.flash_freq=80m + +XIAO_ESP32S3_Plus.menu.FlashSize.8M=8MB (64Mb) +XIAO_ESP32S3_Plus.menu.FlashSize.8M.build.flash_size=8MB + +XIAO_ESP32S3_Plus.menu.LoopCore.1=Core 1 +XIAO_ESP32S3_Plus.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +XIAO_ESP32S3_Plus.menu.LoopCore.0=Core 0 +XIAO_ESP32S3_Plus.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +XIAO_ESP32S3_Plus.menu.EventsCore.1=Core 1 +XIAO_ESP32S3_Plus.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +XIAO_ESP32S3_Plus.menu.EventsCore.0=Core 0 +XIAO_ESP32S3_Plus.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +XIAO_ESP32S3_Plus.menu.USBMode.hwcdc=Hardware CDC and JTAG +XIAO_ESP32S3_Plus.menu.USBMode.hwcdc.build.usb_mode=1 +XIAO_ESP32S3_Plus.menu.USBMode.default=USB-OTG (TinyUSB) +XIAO_ESP32S3_Plus.menu.USBMode.default.build.usb_mode=0 + +XIAO_ESP32S3_Plus.menu.CDCOnBoot.default=Enabled +XIAO_ESP32S3_Plus.menu.CDCOnBoot.default.build.cdc_on_boot=1 +XIAO_ESP32S3_Plus.menu.CDCOnBoot.cdc=Disabled +XIAO_ESP32S3_Plus.menu.CDCOnBoot.cdc.build.cdc_on_boot=0 + +XIAO_ESP32S3_Plus.menu.MSCOnBoot.default=Disabled +XIAO_ESP32S3_Plus.menu.MSCOnBoot.default.build.msc_on_boot=0 +XIAO_ESP32S3_Plus.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +XIAO_ESP32S3_Plus.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +XIAO_ESP32S3_Plus.menu.DFUOnBoot.default=Disabled +XIAO_ESP32S3_Plus.menu.DFUOnBoot.default.build.dfu_on_boot=0 +XIAO_ESP32S3_Plus.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode) +XIAO_ESP32S3_Plus.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +XIAO_ESP32S3_Plus.menu.UploadMode.default=UART0 / Hardware CDC +XIAO_ESP32S3_Plus.menu.UploadMode.default.upload.use_1200bps_touch=false +XIAO_ESP32S3_Plus.menu.UploadMode.default.upload.wait_for_upload_port=false +XIAO_ESP32S3_Plus.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +XIAO_ESP32S3_Plus.menu.UploadMode.cdc.upload.use_1200bps_touch=true +XIAO_ESP32S3_Plus.menu.UploadMode.cdc.upload.wait_for_upload_port=true + +XIAO_ESP32S3_Plus.menu.PartitionScheme.default_8MB=Default with spiffs (3MB APP/1.5MB SPIFFS) +XIAO_ESP32S3_Plus.menu.PartitionScheme.default_8MB.build.partitions=default_8MB +XIAO_ESP32S3_Plus.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336 +XIAO_ESP32S3_Plus.menu.PartitionScheme.max_app_8MB=Maximum APP (7.9MB APP No OTA/No FS) +XIAO_ESP32S3_Plus.menu.PartitionScheme.max_app_8MB.build.partitions=max_app_8MB +XIAO_ESP32S3_Plus.menu.PartitionScheme.max_app_8MB.upload.maximum_size=8257536 +XIAO_ESP32S3_Plus.menu.PartitionScheme.tinyuf2=TinyUF2 8MB (2MB APP/3.7MB FFAT) +XIAO_ESP32S3_Plus.menu.PartitionScheme.tinyuf2.build.custom_bootloader=bootloader-tinyuf2 +XIAO_ESP32S3_Plus.menu.PartitionScheme.tinyuf2.build.custom_partitions=partitions-8MB +XIAO_ESP32S3_Plus.menu.PartitionScheme.tinyuf2.upload.maximum_size=2097152 +XIAO_ESP32S3_Plus.menu.PartitionScheme.tinyuf2.upload.extra_flags=0x410000 "{runtime.platform.path}/variants/{build.variant}/tinyuf2.bin" + +XIAO_ESP32S3_Plus.menu.CPUFreq.240=240MHz (WiFi) +XIAO_ESP32S3_Plus.menu.CPUFreq.240.build.f_cpu=240000000L +XIAO_ESP32S3_Plus.menu.CPUFreq.160=160MHz (WiFi) +XIAO_ESP32S3_Plus.menu.CPUFreq.160.build.f_cpu=160000000L +XIAO_ESP32S3_Plus.menu.CPUFreq.80=80MHz (WiFi) +XIAO_ESP32S3_Plus.menu.CPUFreq.80.build.f_cpu=80000000L +XIAO_ESP32S3_Plus.menu.CPUFreq.40=40MHz +XIAO_ESP32S3_Plus.menu.CPUFreq.40.build.f_cpu=40000000L +XIAO_ESP32S3_Plus.menu.CPUFreq.20=20MHz +XIAO_ESP32S3_Plus.menu.CPUFreq.20.build.f_cpu=20000000L +XIAO_ESP32S3_Plus.menu.CPUFreq.10=10MHz +XIAO_ESP32S3_Plus.menu.CPUFreq.10.build.f_cpu=10000000L + +XIAO_ESP32S3_Plus.menu.UploadSpeed.921600=921600 +XIAO_ESP32S3_Plus.menu.UploadSpeed.921600.upload.speed=921600 +XIAO_ESP32S3_Plus.menu.UploadSpeed.115200=115200 +XIAO_ESP32S3_Plus.menu.UploadSpeed.115200.upload.speed=115200 +XIAO_ESP32S3_Plus.menu.UploadSpeed.256000.windows=256000 +XIAO_ESP32S3_Plus.menu.UploadSpeed.256000.upload.speed=256000 +XIAO_ESP32S3_Plus.menu.UploadSpeed.230400.windows.upload.speed=256000 +XIAO_ESP32S3_Plus.menu.UploadSpeed.230400=230400 +XIAO_ESP32S3_Plus.menu.UploadSpeed.230400.upload.speed=230400 +XIAO_ESP32S3_Plus.menu.UploadSpeed.460800.linux=460800 +XIAO_ESP32S3_Plus.menu.UploadSpeed.460800.macosx=460800 +XIAO_ESP32S3_Plus.menu.UploadSpeed.460800.upload.speed=460800 +XIAO_ESP32S3_Plus.menu.UploadSpeed.512000.windows=512000 +XIAO_ESP32S3_Plus.menu.UploadSpeed.512000.upload.speed=512000 + +XIAO_ESP32S3_Plus.menu.DebugLevel.none=None +XIAO_ESP32S3_Plus.menu.DebugLevel.none.build.code_debug=0 +XIAO_ESP32S3_Plus.menu.DebugLevel.error=Error +XIAO_ESP32S3_Plus.menu.DebugLevel.error.build.code_debug=1 +XIAO_ESP32S3_Plus.menu.DebugLevel.warn=Warn +XIAO_ESP32S3_Plus.menu.DebugLevel.warn.build.code_debug=2 +XIAO_ESP32S3_Plus.menu.DebugLevel.info=Info +XIAO_ESP32S3_Plus.menu.DebugLevel.info.build.code_debug=3 +XIAO_ESP32S3_Plus.menu.DebugLevel.debug=Debug +XIAO_ESP32S3_Plus.menu.DebugLevel.debug.build.code_debug=4 +XIAO_ESP32S3_Plus.menu.DebugLevel.verbose=Verbose +XIAO_ESP32S3_Plus.menu.DebugLevel.verbose.build.code_debug=5 + +XIAO_ESP32S3_Plus.menu.EraseFlash.none=Disabled +XIAO_ESP32S3_Plus.menu.EraseFlash.none.upload.erase_cmd= +XIAO_ESP32S3_Plus.menu.EraseFlash.all=Enabled +XIAO_ESP32S3_Plus.menu.EraseFlash.all.upload.erase_cmd=-e + +############################################################## + connaxio_espoir.name=Connaxio's Espoir connaxio_espoir.vid.0=0x10C4 connaxio_espoir.pid.0=0x8D9A diff --git a/variants/XIAO_ESP32S3_Plus/bootloader-tinyuf2.bin b/variants/XIAO_ESP32S3_Plus/bootloader-tinyuf2.bin new file mode 100644 index 0000000000000000000000000000000000000000..b11e5b236f0992d8351b579c8283c03a5e32a85c GIT binary patch literal 21408 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 SVR0lq@zytgJh)Ff;r{>(gA@M% literal 0 HcmV?d00001 diff --git a/variants/XIAO_ESP32S3_Plus/partitions-8MB.csv b/variants/XIAO_ESP32S3_Plus/partitions-8MB.csv new file mode 100644 index 00000000000..4026378b6fb --- /dev/null +++ b/variants/XIAO_ESP32S3_Plus/partitions-8MB.csv @@ -0,0 +1,10 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +# bootloader.bin,, 0x1000, 32K +# partition table,, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K, +otadata, data, ota, 0xe000, 8K, +ota_0, 0, ota_0, 0x10000, 2048K, +ota_1, 0, ota_1, 0x210000, 2048K, +uf2, app, factory,0x410000, 256K, +ffat, data, fat, 0x450000, 3776K, diff --git a/variants/XIAO_ESP32S3_Plus/pins_arduino.h b/variants/XIAO_ESP32S3_Plus/pins_arduino.h new file mode 100644 index 00000000000..fb887287e35 --- /dev/null +++ b/variants/XIAO_ESP32S3_Plus/pins_arduino.h @@ -0,0 +1,90 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define USB_VID 0x2886 +#define USB_PID 0x0056 + +static const uint8_t LED_BUILTIN = 21; +#define BUILTIN_LED LED_BUILTIN // backward compatibility +#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN + +static const uint8_t TX = 43; +static const uint8_t RX = 44; + +static const uint8_t TX1 = 42; +static const uint8_t RX1 = 41; + +static const uint8_t SDA = 5; +static const uint8_t SCL = 6; + +static const uint8_t SS = 44; +static const uint8_t MOSI = 9; +static const uint8_t MISO = 8; +static const uint8_t SCK = 7; + +static const uint8_t MOSI1 = 11; +static const uint8_t MISO1 = 12; +static const uint8_t SCK1 = 13; + +static const uint8_t I2S_SCK = 39; +static const uint8_t I2S_SD = 38; +static const uint8_t I2S_WS = 40; + +static const uint8_t MTCK = 39; +static const uint8_t MTDO = 40; +static const uint8_t MTDI = 41; +static const uint8_t MTMS = 42; + +static const uint8_t DVP_Y8 = 11; +static const uint8_t DVP_YP = 12; +static const uint8_t DVP_PCLK = 13; +static const uint8_t DVP_VSYNC = 38; +static const uint8_t CAM_SCL = 39; +static const uint8_t CAM_SDA = 40; +static const uint8_t XMCLK = 10; + +static const uint8_t A0 = 1; +static const uint8_t A1 = 2; +static const uint8_t A2 = 3; +static const uint8_t A3 = 4; +static const uint8_t A4 = 5; +static const uint8_t A5 = 6; +static const uint8_t A8 = 7; +static const uint8_t A9 = 8; +static const uint8_t A10 = 9; +static const uint8_t ADC_BAT = 10; + +static const uint8_t D0 = 1; +static const uint8_t D1 = 2; +static const uint8_t D2 = 3; +static const uint8_t D3 = 4; +static const uint8_t D4 = 5; +static const uint8_t D5 = 6; +static const uint8_t D6 = 43; +static const uint8_t D7 = 44; +static const uint8_t D8 = 7; +static const uint8_t D9 = 8; +static const uint8_t D10 = 9; +static const uint8_t D11 = 38; +static const uint8_t D12 = 39; +static const uint8_t D13 = 40; +static const uint8_t D14 = 41; +static const uint8_t D15 = 42; +static const uint8_t D16 = 10; +static const uint8_t D17 = 13; +static const uint8_t D18 = 12; +static const uint8_t D19 = 11; + +static const uint8_t T1 = 1; +static const uint8_t T2 = 2; +static const uint8_t T3 = 3; +static const uint8_t T4 = 4; +static const uint8_t T5 = 5; +static const uint8_t T6 = 6; +static const uint8_t T7 = 7; +static const uint8_t T8 = 8; +static const uint8_t T9 = 9; + +#endif /* Pins_Arduino_h */ diff --git a/variants/XIAO_ESP32S3_Plus/tinyuf2.bin b/variants/XIAO_ESP32S3_Plus/tinyuf2.bin new file mode 100644 index 0000000000000000000000000000000000000000..86d981f8019368e49c7412d49731a0199b1722bd GIT binary patch literal 141936 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 literal 0 HcmV?d00001 From 7089c0a18873bdca74a1880ec9a73d6e03b523be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 21 Jan 2025 12:24:43 +0100 Subject: [PATCH 02/79] fix(zigbee): Update esp-zigbee-sdk to 1.6.2 + necessary changes --- boards.txt | 202 +++++++++--------- idf_component.yml | 4 +- .../src/ep/ZigbeeCarbonDioxideSensor.cpp | 3 - 3 files changed, 103 insertions(+), 106 deletions(-) diff --git a/boards.txt b/boards.txt index 8e9655cda48..f3c60dccf1d 100644 --- a/boards.txt +++ b/boards.txt @@ -536,22 +536,22 @@ esp32h2.menu.ZigbeeMode.default.build.zigbee_mode= esp32h2.menu.ZigbeeMode.default.build.zigbee_libs= esp32h2.menu.ZigbeeMode.ed=Zigbee ED (end device) esp32h2.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -esp32h2.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +esp32h2.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native esp32h2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32h2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32h2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +esp32h2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native esp32h2.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) esp32h2.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32h2.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +esp32h2.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native esp32h2.menu.ZigbeeMode.ed_debug=Zigbee ED (end device) - Debug esp32h2.menu.ZigbeeMode.ed_debug.build.zigbee_mode=-DZIGBEE_MODE_ED -esp32h2.menu.ZigbeeMode.ed_debug.build.zigbee_libs=-lesp_zb_api_ed.debug -lesp_zb_cli_command -lzboss_stack.ed.debug -lzboss_port.debug +esp32h2.menu.ZigbeeMode.ed_debug.build.zigbee_libs=-lesp_zb_api.ed.debug -lzboss_stack.ed.debug -lzboss_port.native.debug esp32h2.menu.ZigbeeMode.zczr_debug=Zigbee ZCZR (coordinator/router) - Debug esp32h2.menu.ZigbeeMode.zczr_debug.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32h2.menu.ZigbeeMode.zczr_debug.build.zigbee_libs=-lesp_zb_api_zczr.debug -lesp_zb_cli_command -lzboss_stack.zczr.debug -lzboss_port.debug +esp32h2.menu.ZigbeeMode.zczr_debug.build.zigbee_libs=-lesp_zb_api.zczr.debug -lzboss_stack.zczr.debug -lzboss_port.native.debug esp32h2.menu.ZigbeeMode.rcp_debug=Zigbee RCP (radio co-processor) - Debug esp32h2.menu.ZigbeeMode.rcp_debug.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32h2.menu.ZigbeeMode.rcp_debug.build.zigbee_libs=-lesp_zb_api_rcp.debug -lesp_zb_cli_command -lzboss_stack.rcp.debug -lzboss_port.debug +esp32h2.menu.ZigbeeMode.rcp_debug.build.zigbee_libs=-lesp_zb_api.rcp.debug -lzboss_stack.rcp.debug -lzboss_port.native.debug ############################################################## @@ -748,22 +748,22 @@ esp32c6.menu.ZigbeeMode.default.build.zigbee_mode= esp32c6.menu.ZigbeeMode.default.build.zigbee_libs= esp32c6.menu.ZigbeeMode.ed=Zigbee ED (end device) esp32c6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native esp32c6.menu.ZigbeeMode.ed_debug=Zigbee ED (end device) - Debug esp32c6.menu.ZigbeeMode.ed_debug.build.zigbee_mode=-DZIGBEE_MODE_ED -esp32c6.menu.ZigbeeMode.ed_debug.build.zigbee_libs=-lesp_zb_api_ed.debug -lesp_zb_cli_command -lzboss_stack.ed.debug -lzboss_port.debug +esp32c6.menu.ZigbeeMode.ed_debug.build.zigbee_libs=-lesp_zb_api.ed.debug -lzboss_stack.ed.debug -lzboss_port.native.debug esp32c6.menu.ZigbeeMode.zczr_debug=Zigbee ZCZR (coordinator/router) - Debug esp32c6.menu.ZigbeeMode.zczr_debug.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32c6.menu.ZigbeeMode.zczr_debug.build.zigbee_libs=-lesp_zb_api_zczr.debug -lesp_zb_cli_command -lzboss_stack.zczr.debug -lzboss_port.debug +esp32c6.menu.ZigbeeMode.zczr_debug.build.zigbee_libs=-lesp_zb_api.zczr.debug -lzboss_stack.zczr.debug -lzboss_port.native.debug esp32c6.menu.ZigbeeMode.rcp_debug=Zigbee RCP (radio co-processor) - Debug esp32c6.menu.ZigbeeMode.rcp_debug.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32c6.menu.ZigbeeMode.rcp_debug.build.zigbee_libs=-lesp_zb_api_rcp.debug -lesp_zb_cli_command -lzboss_stack.rcp.debug -lzboss_port.debug +esp32c6.menu.ZigbeeMode.rcp_debug.build.zigbee_libs=-lesp_zb_api.rcp.debug -lzboss_stack.rcp.debug -lzboss_port.native.debug ############################################################## @@ -1014,7 +1014,7 @@ esp32s3.menu.ZigbeeMode.default.build.zigbee_mode= esp32s3.menu.ZigbeeMode.default.build.zigbee_libs= esp32s3.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32s3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -1194,7 +1194,7 @@ esp32c3.menu.ZigbeeMode.default.build.zigbee_mode= esp32c3.menu.ZigbeeMode.default.build.zigbee_libs= esp32c3.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32c3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32c3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +esp32c3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -1401,7 +1401,7 @@ esp32s2.menu.ZigbeeMode.default.build.zigbee_mode= esp32s2.menu.ZigbeeMode.default.build.zigbee_libs= esp32s2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32s2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -1595,7 +1595,7 @@ esp32.menu.ZigbeeMode.default.build.zigbee_mode= esp32.menu.ZigbeeMode.default.build.zigbee_libs= esp32.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +esp32.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -4965,13 +4965,13 @@ um_tinyc6.menu.ZigbeeMode.default.build.zigbee_mode= um_tinyc6.menu.ZigbeeMode.default.build.zigbee_libs= um_tinyc6.menu.ZigbeeMode.ed=Zigbee ED (end device) um_tinyc6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -um_tinyc6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +um_tinyc6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native um_tinyc6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) um_tinyc6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -um_tinyc6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +um_tinyc6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native um_tinyc6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) um_tinyc6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -um_tinyc6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +um_tinyc6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -7790,7 +7790,7 @@ sparkfun_esp32s3_thing_plus.menu.ZigbeeMode.default.build.zigbee_mode= sparkfun_esp32s3_thing_plus.menu.ZigbeeMode.default.build.zigbee_libs= sparkfun_esp32s3_thing_plus.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator) sparkfun_esp32s3_thing_plus.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -sparkfun_esp32s3_thing_plus.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +sparkfun_esp32s3_thing_plus.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -7970,13 +7970,13 @@ sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.default.build.zigbee_mode= sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.default.build.zigbee_libs= sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.ed=Zigbee ED (end device) sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -8563,13 +8563,13 @@ sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.default.build.zigbee_mode= sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.default.build.zigbee_libs= sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.ed=Zigbee ED (end device) sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -11797,13 +11797,13 @@ dfrobot_beetle_esp32c6.menu.ZigbeeMode.default.build.zigbee_mode= dfrobot_beetle_esp32c6.menu.ZigbeeMode.default.build.zigbee_libs= dfrobot_beetle_esp32c6.menu.ZigbeeMode.ed=Zigbee ED (end device) dfrobot_beetle_esp32c6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -dfrobot_beetle_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +dfrobot_beetle_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native dfrobot_beetle_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) dfrobot_beetle_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -dfrobot_beetle_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +dfrobot_beetle_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native dfrobot_beetle_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) dfrobot_beetle_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -dfrobot_beetle_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +dfrobot_beetle_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -12346,13 +12346,13 @@ dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.default.build.zigbee_mode= dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.default.build.zigbee_libs= dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.ed=Zigbee ED (end device) dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -12948,7 +12948,7 @@ adafruit_metro_esp32s2.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_metro_esp32s2.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_metro_esp32s2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_metro_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_metro_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_metro_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Metro ESP32-S3 @@ -13151,7 +13151,7 @@ adafruit_metro_esp32s3.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_metro_esp32s3.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_metro_esp32s3.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_metro_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_metro_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_metro_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit MagTag 2.9" @@ -13334,7 +13334,7 @@ adafruit_magtag29_esp32s2.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_magtag29_esp32s2.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_magtag29_esp32s2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_magtag29_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_magtag29_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_magtag29_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit FunHouse @@ -13517,7 +13517,7 @@ adafruit_funhouse_esp32s2.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_funhouse_esp32s2.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_funhouse_esp32s2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_funhouse_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_funhouse_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_funhouse_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit ESP32 Feather @@ -13651,7 +13651,7 @@ featheresp32.menu.ZigbeeMode.default.build.zigbee_mode= featheresp32.menu.ZigbeeMode.default.build.zigbee_libs= featheresp32.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) featheresp32.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -featheresp32.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +featheresp32.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Feather ESP32 V2 @@ -13772,7 +13772,7 @@ adafruit_feather_esp32_v2.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_feather_esp32_v2.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_feather_esp32_v2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32_v2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_feather_esp32_v2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_feather_esp32_v2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Feather ESP32-S2 @@ -13955,7 +13955,7 @@ adafruit_feather_esp32s2.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_feather_esp32s2.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_feather_esp32s2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_feather_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_feather_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Feather ESP32-S2 TFT @@ -14138,7 +14138,7 @@ adafruit_feather_esp32s2_tft.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_feather_esp32s2_tft.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_feather_esp32s2_tft.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32s2_tft.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_feather_esp32s2_tft.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_feather_esp32s2_tft.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Feather ESP32-S2 Reverse TFT @@ -14321,7 +14321,7 @@ adafruit_feather_esp32s2_reversetft.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_feather_esp32s2_reversetft.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_feather_esp32s2_reversetft.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32s2_reversetft.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_feather_esp32s2_reversetft.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_feather_esp32s2_reversetft.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Feather ESP32-S3 2MB PSRAM @@ -14539,7 +14539,7 @@ adafruit_feather_esp32s3.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_feather_esp32s3.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_feather_esp32s3.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_feather_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_feather_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Feather ESP32-S3 No PSRAM @@ -14726,7 +14726,7 @@ adafruit_feather_esp32s3_nopsram.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_feather_esp32s3_nopsram.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_feather_esp32s3_nopsram.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32s3_nopsram.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_feather_esp32s3_nopsram.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_feather_esp32s3_nopsram.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Feather ESP32-S3 TFT @@ -14944,7 +14944,7 @@ adafruit_feather_esp32s3_tft.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_feather_esp32s3_tft.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_feather_esp32s3_tft.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32s3_tft.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_feather_esp32s3_tft.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_feather_esp32s3_tft.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Feather ESP32-S3 Reverse TFT @@ -15162,7 +15162,7 @@ adafruit_feather_esp32s3_reversetft.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_feather_esp32s3_reversetft.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_feather_esp32s3_reversetft.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32s3_reversetft.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_feather_esp32s3_reversetft.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_feather_esp32s3_reversetft.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################# # Feather C6 @@ -15334,13 +15334,13 @@ adafruit_feather_esp32c6.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_feather_esp32c6.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_feather_esp32c6.menu.ZigbeeMode.ed=Zigbee ED (end device) adafruit_feather_esp32c6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -adafruit_feather_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +adafruit_feather_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native adafruit_feather_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_feather_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_feather_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native adafruit_feather_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) adafruit_feather_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -adafruit_feather_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +adafruit_feather_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native @@ -15463,7 +15463,7 @@ adafruit_qtpy_esp32_pico.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_qtpy_esp32_pico.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_qtpy_esp32_pico.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_qtpy_esp32_pico.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_qtpy_esp32_pico.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_qtpy_esp32_pico.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit QT Py ESP32-C3 @@ -15598,7 +15598,7 @@ adafruit_qtpy_esp32c3.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_qtpy_esp32c3.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_qtpy_esp32c3.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_qtpy_esp32c3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_qtpy_esp32c3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_qtpy_esp32c3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit QT Py ESP32-S2 @@ -15781,7 +15781,7 @@ adafruit_qtpy_esp32s2.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_qtpy_esp32s2.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_qtpy_esp32s2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_qtpy_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_qtpy_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_qtpy_esp32s2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit QT Py ESP32-S3 No PSRAM @@ -15968,7 +15968,7 @@ adafruit_qtpy_esp32s3_nopsram.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_qtpy_esp32s3_nopsram.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_qtpy_esp32s3_nopsram.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_qtpy_esp32s3_nopsram.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_qtpy_esp32s3_nopsram.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_qtpy_esp32s3_nopsram.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit QT Py ESP32-S3 (4M Flash 2M PSRAM) @@ -16186,7 +16186,7 @@ adafruit_qtpy_esp32s3_n4r2.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_qtpy_esp32s3_n4r2.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_qtpy_esp32s3_n4r2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_qtpy_esp32s3_n4r2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_qtpy_esp32s3_n4r2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_qtpy_esp32s3_n4r2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit ItsyBitsy ESP32 @@ -16304,7 +16304,7 @@ adafruit_itsybitsy_esp32.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_itsybitsy_esp32.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_itsybitsy_esp32.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_itsybitsy_esp32.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_itsybitsy_esp32.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_itsybitsy_esp32.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit MatrixPortal ESP32-S3 @@ -16501,7 +16501,7 @@ adafruit_matrixportal_esp32s3.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_matrixportal_esp32s3.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_matrixportal_esp32s3.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_matrixportal_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_matrixportal_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_matrixportal_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit pyCamera S3 @@ -16719,7 +16719,7 @@ adafruit_camera_esp32s3.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_camera_esp32s3.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_camera_esp32s3.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_camera_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_camera_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_camera_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Qualia ESP32-S3 RGB666 @@ -16922,7 +16922,7 @@ adafruit_qualia_s3_rgb666.menu.ZigbeeMode.default.build.zigbee_mode= adafruit_qualia_s3_rgb666.menu.ZigbeeMode.default.build.zigbee_libs= adafruit_qualia_s3_rgb666.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_qualia_s3_rgb666.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -adafruit_qualia_s3_rgb666.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +adafruit_qualia_s3_rgb666.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Sparkle Motion w/ESP32 @@ -17056,7 +17056,7 @@ sparklemotion.menu.ZigbeeMode.default.build.zigbee_mode= sparklemotion.menu.ZigbeeMode.default.build.zigbee_libs= sparklemotion.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) sparklemotion.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -sparklemotion.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +sparklemotion.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## # Adafruit Sparkle Motion Mini w/ESP32 @@ -17190,7 +17190,7 @@ sparklemotionmini.menu.ZigbeeMode.default.build.zigbee_mode= sparklemotionmini.menu.ZigbeeMode.default.build.zigbee_libs= sparklemotionmini.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) sparklemotionmini.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -sparklemotionmini.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +sparklemotionmini.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -17644,7 +17644,7 @@ nologo_esp32s3_pico.menu.ZigbeeMode.default.build.zigbee_mode= nologo_esp32s3_pico.menu.ZigbeeMode.default.build.zigbee_libs= nologo_esp32s3_pico.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) nologo_esp32s3_pico.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -nologo_esp32s3_pico.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +nologo_esp32s3_pico.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -19577,13 +19577,13 @@ esp32c6-evb.menu.ZigbeeMode.default.build.zigbee_mode= esp32c6-evb.menu.ZigbeeMode.default.build.zigbee_libs= esp32c6-evb.menu.ZigbeeMode.ed=Zigbee ED (end device) esp32c6-evb.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -esp32c6-evb.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +esp32c6-evb.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native esp32c6-evb.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32c6-evb.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32c6-evb.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +esp32c6-evb.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native esp32c6-evb.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) esp32c6-evb.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32c6-evb.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +esp32c6-evb.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -19757,13 +19757,13 @@ esp32h2-devkitlipo.menu.ZigbeeMode.default.build.zigbee_mode= esp32h2-devkitlipo.menu.ZigbeeMode.default.build.zigbee_libs= esp32h2-devkitlipo.menu.ZigbeeMode.ed=Zigbee ED (end device) esp32h2-devkitlipo.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -esp32h2-devkitlipo.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +esp32h2-devkitlipo.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native esp32h2-devkitlipo.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32h2-devkitlipo.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32h2-devkitlipo.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +esp32h2-devkitlipo.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native esp32h2-devkitlipo.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) esp32h2-devkitlipo.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32h2-devkitlipo.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +esp32h2-devkitlipo.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -19954,7 +19954,7 @@ esp32-sbc-fabgl.menu.ZigbeeMode.default.build.zigbee_mode= esp32-sbc-fabgl.menu.ZigbeeMode.default.build.zigbee_libs= esp32-sbc-fabgl.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32-sbc-fabgl.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -esp32-sbc-fabgl.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +esp32-sbc-fabgl.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -24628,13 +24628,13 @@ m5stack_nanoc6.menu.ZigbeeMode.default.build.zigbee_mode= m5stack_nanoc6.menu.ZigbeeMode.default.build.zigbee_libs= m5stack_nanoc6.menu.ZigbeeMode.ed=Zigbee ED (end device) m5stack_nanoc6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -m5stack_nanoc6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +m5stack_nanoc6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native m5stack_nanoc6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) m5stack_nanoc6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -m5stack_nanoc6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +m5stack_nanoc6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native m5stack_nanoc6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) m5stack_nanoc6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -m5stack_nanoc6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +m5stack_nanoc6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -35023,13 +35023,13 @@ XIAO_ESP32C6.menu.ZigbeeMode.default.build.zigbee_mode= XIAO_ESP32C6.menu.ZigbeeMode.default.build.zigbee_libs= XIAO_ESP32C6.menu.ZigbeeMode.ed=Zigbee ED (end device) XIAO_ESP32C6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -XIAO_ESP32C6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +XIAO_ESP32C6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native XIAO_ESP32C6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) XIAO_ESP32C6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -XIAO_ESP32C6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +XIAO_ESP32C6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native XIAO_ESP32C6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) XIAO_ESP32C6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -XIAO_ESP32C6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +XIAO_ESP32C6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -39384,13 +39384,13 @@ ioxesp32c6.menu.ZigbeeMode.default.build.zigbee_mode= ioxesp32c6.menu.ZigbeeMode.default.build.zigbee_libs= ioxesp32c6.menu.ZigbeeMode.ed=Zigbee ED (end device) ioxesp32c6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -ioxesp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +ioxesp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native ioxesp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator) ioxesp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -ioxesp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +ioxesp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native ioxesp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) ioxesp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -ioxesp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +ioxesp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## # ATD1.47-S3 @@ -40568,13 +40568,13 @@ epulse_feather_c6.menu.ZigbeeMode.default.build.zigbee_mode= epulse_feather_c6.menu.ZigbeeMode.default.build.zigbee_libs= epulse_feather_c6.menu.ZigbeeMode.ed=Zigbee ED (end device) epulse_feather_c6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -epulse_feather_c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +epulse_feather_c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native epulse_feather_c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) epulse_feather_c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -epulse_feather_c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +epulse_feather_c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native epulse_feather_c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) epulse_feather_c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -epulse_feather_c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +epulse_feather_c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -43052,7 +43052,7 @@ jczn_2432s028r.menu.ZigbeeMode.default.build.zigbee_mode= jczn_2432s028r.menu.ZigbeeMode.default.build.zigbee_libs= jczn_2432s028r.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) jczn_2432s028r.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -jczn_2432s028r.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +jczn_2432s028r.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -44695,7 +44695,7 @@ waveshare_esp32_s3_touch_lcd_185.menu.ZigbeeMode.default.build.zigbee_mode= waveshare_esp32_s3_touch_lcd_185.menu.ZigbeeMode.default.build.zigbee_libs= waveshare_esp32_s3_touch_lcd_185.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) waveshare_esp32_s3_touch_lcd_185.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -waveshare_esp32_s3_touch_lcd_185.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +waveshare_esp32_s3_touch_lcd_185.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -44862,13 +44862,13 @@ cezerio_dev_esp32c6.menu.ZigbeeMode.default.build.zigbee_mode= cezerio_dev_esp32c6.menu.ZigbeeMode.default.build.zigbee_libs= cezerio_dev_esp32c6.menu.ZigbeeMode.ed=Zigbee ED (end device) cezerio_dev_esp32c6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -cezerio_dev_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +cezerio_dev_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native cezerio_dev_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator) cezerio_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -cezerio_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +cezerio_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native cezerio_dev_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) cezerio_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -cezerio_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +cezerio_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -45035,13 +45035,13 @@ cezerio_mini_dev_esp32c6.menu.ZigbeeMode.default.build.zigbee_mode= cezerio_mini_dev_esp32c6.menu.ZigbeeMode.default.build.zigbee_libs= cezerio_mini_dev_esp32c6.menu.ZigbeeMode.ed=Zigbee ED (end device) cezerio_mini_dev_esp32c6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -cezerio_mini_dev_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +cezerio_mini_dev_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native cezerio_mini_dev_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator) cezerio_mini_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -cezerio_mini_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +cezerio_mini_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native cezerio_mini_dev_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) cezerio_mini_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -cezerio_mini_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +cezerio_mini_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -45278,7 +45278,7 @@ waveshare_esp32_s3_lcd_185.menu.ZigbeeMode.default.build.zigbee_mode= waveshare_esp32_s3_lcd_185.menu.ZigbeeMode.default.build.zigbee_libs= waveshare_esp32_s3_lcd_185.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) waveshare_esp32_s3_lcd_185.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -waveshare_esp32_s3_lcd_185.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +waveshare_esp32_s3_lcd_185.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native ############################################################## @@ -45515,7 +45515,7 @@ waveshare_esp32_s3_touch_lcd_146.menu.ZigbeeMode.default.build.zigbee_mode= waveshare_esp32_s3_touch_lcd_146.menu.ZigbeeMode.default.build.zigbee_libs= waveshare_esp32_s3_touch_lcd_146.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) waveshare_esp32_s3_touch_lcd_146.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -waveshare_esp32_s3_touch_lcd_146.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +waveshare_esp32_s3_touch_lcd_146.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -45752,7 +45752,7 @@ waveshare_esp32_s3_lcd_146.menu.ZigbeeMode.default.build.zigbee_mode= waveshare_esp32_s3_lcd_146.menu.ZigbeeMode.default.build.zigbee_libs= waveshare_esp32_s3_lcd_146.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) waveshare_esp32_s3_lcd_146.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -waveshare_esp32_s3_lcd_146.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +waveshare_esp32_s3_lcd_146.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -45989,7 +45989,7 @@ waveshare_esp32_s3_touch_lcd_185_box.menu.ZigbeeMode.default.build.zigbee_mode= waveshare_esp32_s3_touch_lcd_185_box.menu.ZigbeeMode.default.build.zigbee_libs= waveshare_esp32_s3_touch_lcd_185_box.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) waveshare_esp32_s3_touch_lcd_185_box.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -waveshare_esp32_s3_touch_lcd_185_box.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +waveshare_esp32_s3_touch_lcd_185_box.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -46226,7 +46226,7 @@ waveshare_esp32_s3_lcd_147.menu.ZigbeeMode.default.build.zigbee_mode= waveshare_esp32_s3_lcd_147.menu.ZigbeeMode.default.build.zigbee_libs= waveshare_esp32_s3_lcd_147.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) waveshare_esp32_s3_lcd_147.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -waveshare_esp32_s3_lcd_147.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +waveshare_esp32_s3_lcd_147.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -46463,7 +46463,7 @@ waveshare_esp32_s3_touch_lcd_21.menu.ZigbeeMode.default.build.zigbee_mode= waveshare_esp32_s3_touch_lcd_21.menu.ZigbeeMode.default.build.zigbee_libs= waveshare_esp32_s3_touch_lcd_21.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) waveshare_esp32_s3_touch_lcd_21.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -waveshare_esp32_s3_touch_lcd_21.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +waveshare_esp32_s3_touch_lcd_21.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -46700,7 +46700,7 @@ waveshare_esp32_s3_touch_lcd_28.menu.ZigbeeMode.default.build.zigbee_mode= waveshare_esp32_s3_touch_lcd_28.menu.ZigbeeMode.default.build.zigbee_libs= waveshare_esp32_s3_touch_lcd_28.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) waveshare_esp32_s3_touch_lcd_28.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -waveshare_esp32_s3_touch_lcd_28.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +waveshare_esp32_s3_touch_lcd_28.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -46940,7 +46940,7 @@ waveshare_esp32_s3_relay_6ch.menu.ZigbeeMode.default.build.zigbee_mode= waveshare_esp32_s3_relay_6ch.menu.ZigbeeMode.default.build.zigbee_libs= waveshare_esp32_s3_relay_6ch.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) waveshare_esp32_s3_relay_6ch.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -waveshare_esp32_s3_relay_6ch.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +waveshare_esp32_s3_relay_6ch.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote ############################################################## @@ -47839,13 +47839,13 @@ Pcbcupid_GLYPH_H2.menu.ZigbeeMode.default.build.zigbee_mode= Pcbcupid_GLYPH_H2.menu.ZigbeeMode.default.build.zigbee_libs= Pcbcupid_GLYPH_H2.menu.ZigbeeMode.ed=Zigbee ED (end device) Pcbcupid_GLYPH_H2.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -Pcbcupid_GLYPH_H2.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +Pcbcupid_GLYPH_H2.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native Pcbcupid_GLYPH_H2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) Pcbcupid_GLYPH_H2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -Pcbcupid_GLYPH_H2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +Pcbcupid_GLYPH_H2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native Pcbcupid_GLYPH_H2.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) Pcbcupid_GLYPH_H2.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -Pcbcupid_GLYPH_H2.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +Pcbcupid_GLYPH_H2.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -47994,13 +47994,13 @@ Pcbcupid_GLYPH_C6.menu.ZigbeeMode.default.build.zigbee_mode= Pcbcupid_GLYPH_C6.menu.ZigbeeMode.default.build.zigbee_libs= Pcbcupid_GLYPH_C6.menu.ZigbeeMode.ed=Zigbee ED (end device) Pcbcupid_GLYPH_C6.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED -Pcbcupid_GLYPH_C6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port +Pcbcupid_GLYPH_C6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -lzboss_port.native Pcbcupid_GLYPH_C6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) Pcbcupid_GLYPH_C6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR -Pcbcupid_GLYPH_C6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port +Pcbcupid_GLYPH_C6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native Pcbcupid_GLYPH_C6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) Pcbcupid_GLYPH_C6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -Pcbcupid_GLYPH_C6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port +Pcbcupid_GLYPH_C6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## diff --git a/idf_component.yml b/idf_component.yml index 9c6bd159d42..2a36244cdfc 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -52,12 +52,12 @@ dependencies: espressif/esp_modem: version: "^1.1.0" espressif/esp-zboss-lib: - version: "==1.6.0" + version: "==1.6.2" require: public rules: - if: "target not in [esp32c2, esp32p4]" espressif/esp-zigbee-lib: - version: "==1.6.0" + version: "==1.6.2" require: public rules: - if: "target not in [esp32c2, esp32p4]" diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp index 5def43f4199..0fbb0881bcf 100644 --- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp @@ -42,9 +42,6 @@ void ZigbeeCarbonDioxideSensor::setTolerance(float tolerance) { } void ZigbeeCarbonDioxideSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) { - if (delta > 0) { - log_e("Delta reporting is currently not supported by the carbon dioxide sensor"); - } esp_zb_zcl_reporting_info_t reporting_info; memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t)); reporting_info.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV; From 15cbb1e857c6a0b4f6a88a611ff929e80ad5fe72 Mon Sep 17 00:00:00 2001 From: lsroka76 <95999074+lsroka76@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:38:50 +0100 Subject: [PATCH 03/79] Add IAS Zone Notification Message service to ZigbeeHandlers and ZigbeeEP.h (#10821) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update ZigbeeHandlers.cpp * Update ZigbeeEP.h * Update ZigbeeEP.h make addBoundDevice virtual for override * fix(zigbee): Update and reorder handlers * fix(zigbee): Place default handler to the end * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- libraries/Zigbee/src/ZigbeeEP.h | 11 +++++---- libraries/Zigbee/src/ZigbeeHandlers.cpp | 30 +++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index d8ed900a7e6..ac22143c4d7 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -105,6 +105,13 @@ class ZigbeeEP { virtual void zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented virtual void zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message); + virtual void zbIASZoneStatusChangeNotification(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) {}; + + virtual void addBoundDevice(zb_device_params_t *device) { + _bound_devices.push_back(device); + _is_bound = true; + } + void onIdentify(void (*callback)(uint16_t)) { _on_identify = callback; } @@ -125,10 +132,6 @@ class ZigbeeEP { SemaphoreHandle_t lock; zb_power_source_t _power_source; - void addBoundDevice(zb_device_params_t *device) { - _bound_devices.push_back(device); - _is_bound = true; - } friend class ZigbeeCore; }; diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index e387b7ce432..bccb27da7f8 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -9,6 +9,7 @@ static esp_err_t zb_attribute_set_handler(const esp_zb_zcl_set_attr_value_messag static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_message_t *message); static esp_err_t zb_cmd_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_resp_message_t *message); static esp_err_t zb_configure_report_resp_handler(const esp_zb_zcl_cmd_config_report_resp_message_t *message); +static esp_err_t zb_cmd_ias_zone_status_change_handler(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message); static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message); // Zigbee action handlers @@ -20,8 +21,11 @@ static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, case ESP_ZB_CORE_REPORT_ATTR_CB_ID: ret = zb_attribute_reporting_handler((esp_zb_zcl_report_attr_message_t *)message); break; case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID: ret = zb_cmd_read_attr_resp_handler((esp_zb_zcl_cmd_read_attr_resp_message_t *)message); break; case ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID: ret = zb_configure_report_resp_handler((esp_zb_zcl_cmd_config_report_resp_message_t *)message); break; - case ESP_ZB_CORE_CMD_DEFAULT_RESP_CB_ID: ret = zb_cmd_default_resp_handler((esp_zb_zcl_cmd_default_resp_message_t *)message); break; - default: log_w("Receive unhandled Zigbee action(0x%x) callback", callback_id); break; + case ESP_ZB_CORE_CMD_IAS_ZONE_ZONE_STATUS_CHANGE_NOT_ID: + ret = zb_cmd_ias_zone_status_change_handler((esp_zb_zcl_ias_zone_status_change_notification_message_t *)message); + break; + case ESP_ZB_CORE_CMD_DEFAULT_RESP_CB_ID: ret = zb_cmd_default_resp_handler((esp_zb_zcl_cmd_default_resp_message_t *)message); break; + default: log_w("Receive unhandled Zigbee action(0x%x) callback", callback_id); break; } return ret; } @@ -132,6 +136,28 @@ static esp_err_t zb_configure_report_resp_handler(const esp_zb_zcl_cmd_config_re return ESP_OK; } +static esp_err_t zb_cmd_ias_zone_status_change_handler(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) { + if (!message) { + log_e("Empty message"); + return ESP_FAIL; + } + if (message->info.status != ESP_ZB_ZCL_STATUS_SUCCESS) { + log_e("Received message: error status(%d)", message->info.status); + return ESP_ERR_INVALID_ARG; + } + log_v( + "IAS Zone Status Notification: from address(0x%x) src endpoint(%d) to dst endpoint(%d) cluster(0x%x)", message->info.src_address.u.short_addr, + message->info.src_endpoint, message->info.dst_endpoint, message->info.cluster + ); + + for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { + if (message->info.dst_endpoint == (*it)->getEndpoint()) { + (*it)->zbIASZoneStatusChangeNotification(message); + } + } + return ESP_OK; +} + static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message) { if (!message) { log_e("Empty message"); From 2fecc482b721b30085f2a9983aaf45f9d38cb064 Mon Sep 17 00:00:00 2001 From: lbernstone Date: Mon, 27 Jan 2025 00:39:15 -1000 Subject: [PATCH 04/79] fix(littlefs): Converted core disableWDT functions to bool (#10896) * fix(littlefs): Converted core disableWDT functions to bool * Missed the returns on core1 * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- cores/esp32/esp32-hal-misc.c | 12 ++++++++---- cores/esp32/esp32-hal.h | 4 ++-- libraries/LittleFS/src/LittleFS.cpp | 6 ++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/cores/esp32/esp32-hal-misc.c b/cores/esp32/esp32-hal-misc.c index 0bce548bdd2..02871872f83 100644 --- a/cores/esp32/esp32-hal-misc.c +++ b/cores/esp32/esp32-hal-misc.c @@ -156,11 +156,13 @@ void enableCore0WDT() { } } -void disableCore0WDT() { +bool disableCore0WDT() { TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCore(0); - if (idle_0 == NULL || esp_task_wdt_delete(idle_0) != ESP_OK) { + if (idle_0 == NULL || esp_task_wdt_status(idle_0) || esp_task_wdt_delete(idle_0) != ESP_OK) { log_e("Failed to remove Core 0 IDLE task from WDT"); + return false; } + return true; } #ifndef CONFIG_FREERTOS_UNICORE @@ -171,11 +173,13 @@ void enableCore1WDT() { } } -void disableCore1WDT() { +bool disableCore1WDT() { TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCore(1); - if (idle_1 == NULL || esp_task_wdt_delete(idle_1) != ESP_OK) { + if (idle_1 == NULL || esp_task_wdt_status(idle_1) || esp_task_wdt_delete(idle_1) != ESP_OK) { log_e("Failed to remove Core 1 IDLE task from WDT"); + return false; } + return true; } #endif diff --git a/cores/esp32/esp32-hal.h b/cores/esp32/esp32-hal.h index d0bd4b8bc93..5ed99aeb205 100644 --- a/cores/esp32/esp32-hal.h +++ b/cores/esp32/esp32-hal.h @@ -121,11 +121,11 @@ void feedLoopWDT(); //enable/disable WDT for the IDLE task on Core 0 (SYSTEM) void enableCore0WDT(); -void disableCore0WDT(); +bool disableCore0WDT(); #ifndef CONFIG_FREERTOS_UNICORE //enable/disable WDT for the IDLE task on Core 1 (Arduino) void enableCore1WDT(); -void disableCore1WDT(); +bool disableCore1WDT(); #endif //if xCoreID < 0 or CPU is unicore, it will use xTaskCreate, else xTaskCreatePinnedToCore diff --git a/libraries/LittleFS/src/LittleFS.cpp b/libraries/LittleFS/src/LittleFS.cpp index e86caeb74cc..761d1ba4c24 100644 --- a/libraries/LittleFS/src/LittleFS.cpp +++ b/libraries/LittleFS/src/LittleFS.cpp @@ -95,9 +95,11 @@ void LittleFSFS::end() { } bool LittleFSFS::format() { - disableCore0WDT(); + bool wdt_active = disableCore0WDT(); esp_err_t err = esp_littlefs_format(partitionLabel_); - enableCore0WDT(); + if (wdt_active) { + enableCore0WDT(); + } if (err) { log_e("Formatting LittleFS failed! Error: %d", err); return false; From 732a7cb4ee4ae4c5a3bcf07f15ac2526f3cefc06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 30 Jan 2025 18:11:40 +0100 Subject: [PATCH 05/79] feat(zigbee): Add Time cluster support + fix of duplicate indentify cluster (#10863) * feat(zigbee): Add Time cluster support * fix(zigbee): Remove duplicate of identify cluster * feat(zigbee): Remove unused variables in addTimeCluster * feat(zigbee): Update examples with optional Time cluster * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- .../Zigbee_Temperature_Sensor.ino | 21 +++ .../Zigbee_Thermostat/Zigbee_Thermostat.ino | 15 +++ libraries/Zigbee/src/ZigbeeEP.cpp | 125 ++++++++++++++++++ libraries/Zigbee/src/ZigbeeEP.h | 22 ++- libraries/Zigbee/src/ZigbeeHandlers.cpp | 2 + .../src/ep/ZigbeeCarbonDioxideSensor.cpp | 1 - libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp | 1 - .../Zigbee/src/ep/ZigbeeOccupancySensor.cpp | 1 - .../Zigbee/src/ep/ZigbeePressureSensor.cpp | 1 - 9 files changed, 181 insertions(+), 8 deletions(-) diff --git a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino index 27aa2db97bd..ad007abbbaa 100644 --- a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino +++ b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/Zigbee_Temperature_Sensor.ino @@ -36,6 +36,11 @@ #define TEMP_SENSOR_ENDPOINT_NUMBER 10 uint8_t button = BOOT_PIN; +// Optional Time cluster variables +struct tm timeinfo; +struct tm *localTime; +int32_t timezone; + ZigbeeTempSensor zbTempSensor = ZigbeeTempSensor(TEMP_SENSOR_ENDPOINT_NUMBER); /************************ Temp sensor *****************************/ @@ -66,6 +71,9 @@ void setup() { // Optional: Set tolerance for temperature measurement in °C (lowest possible value is 0.01°C) zbTempSensor.setTolerance(1); + // Optional: Time cluster configuration (default params, as this device will revieve time from coordinator) + zbTempSensor.addTimeCluster(); + // Add endpoint to Zigbee Core Zigbee.addEndpoint(&zbTempSensor); @@ -85,6 +93,19 @@ void setup() { } Serial.println(); + // Optional: If time cluster is added, time can be read from the coordinator + timeinfo = zbTempSensor.getTime(); + timezone = zbTempSensor.getTimezone(); + + Serial.println("UTC time:"); + Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); + + time_t local = mktime(&timeinfo) + timezone; + localTime = localtime(&local); + + Serial.println("Local time with timezone:"); + Serial.println(localTime, "%A, %B %d %Y %H:%M:%S"); + // Start Temperature sensor reading task xTaskCreate(temp_sensor_value_update, "temp_sensor_update", 2048, NULL, 10, NULL); diff --git a/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino b/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino index a4720feeba4..7cdf45ef711 100644 --- a/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino +++ b/libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino @@ -45,6 +45,8 @@ float sensor_max_temp; float sensor_min_temp; float sensor_tolerance; +struct tm timeinfo = {}; // Time structure for Time cluster + /****************** Temperature sensor handling *******************/ void recieveSensorTemp(float temperature) { Serial.printf("Temperature sensor value: %.2f°C\n", temperature); @@ -71,6 +73,19 @@ void setup() { //Optional: set Zigbee device name and model zbThermostat.setManufacturerAndModel("Espressif", "ZigbeeThermostat"); + //Optional Time cluster configuration + //example time January 13, 2025 13:30:30 CET + timeinfo.tm_year = 2025 - 1900; // = 2025 + timeinfo.tm_mon = 0; // January + timeinfo.tm_mday = 13; // 13th + timeinfo.tm_hour = 12; // 12 hours - 1 hour (CET) + timeinfo.tm_min = 30; // 30 minutes + timeinfo.tm_sec = 30; // 30 seconds + timeinfo.tm_isdst = -1; + + // Set time and gmt offset (timezone in seconds -> CET = +3600 seconds) + zbThermostat.addTimeCluster(timeinfo, 3600); + //Add endpoint to Zigbee Core Zigbee.addEndpoint(&zbThermostat); diff --git a/libraries/Zigbee/src/ZigbeeEP.cpp b/libraries/Zigbee/src/ZigbeeEP.cpp index adc87540b83..6a2ace0b90c 100644 --- a/libraries/Zigbee/src/ZigbeeEP.cpp +++ b/libraries/Zigbee/src/ZigbeeEP.cpp @@ -238,4 +238,129 @@ void ZigbeeEP::zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message) { } } +void ZigbeeEP::addTimeCluster(tm time, int32_t gmt_offset) { + time_t utc_time = 0; + + // Check if time is set + if (time.tm_year > 0) { + // Convert time to UTC + utc_time = mktime(&time); + } + + // Create time cluster server attributes + esp_zb_attribute_list_t *time_cluster_server = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_TIME); + esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID, (void *)&gmt_offset); + esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, (void *)&utc_time); + // Create time cluster client attributes + esp_zb_attribute_list_t *time_cluster_client = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_TIME); + // Add time clusters to cluster list + esp_zb_cluster_list_add_time_cluster(_cluster_list, time_cluster_server, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_time_cluster(_cluster_list, time_cluster_client, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE); +} + +void ZigbeeEP::setTime(tm time) { + time_t utc_time = mktime(&time); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, &utc_time, false); + esp_zb_lock_release(); +} + +void ZigbeeEP::setTimezone(int32_t gmt_offset) { + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID, &gmt_offset, false); + esp_zb_lock_release(); +} + +tm ZigbeeEP::getTime(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_addr_t ieee_addr) { + /* Read peer time */ + esp_zb_zcl_read_attr_cmd_t read_req; + + if (short_addr >= 0) { + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + read_req.zcl_basic_cmd.dst_addr_u.addr_short = (uint16_t)short_addr; + } else { + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t)); + } + + uint16_t attributes[] = {ESP_ZB_ZCL_ATTR_TIME_TIME_ID}; + read_req.attr_number = ZB_ARRAY_LENTH(attributes); + read_req.attr_field = attributes; + + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TIME; + + read_req.zcl_basic_cmd.dst_endpoint = endpoint; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + + // clear read time + _read_time = 0; + + log_v("Reading time from endpoint %d", endpoint); + esp_zb_zcl_read_attr_cmd_req(&read_req); + + //Wait for response or timeout + if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) { + log_e("Error while reading time"); + return tm(); + } + + struct tm *timeinfo = localtime(&_read_time); + if (timeinfo) { + return *timeinfo; + } else { + log_e("Error while converting time"); + return tm(); + } +} + +int32_t ZigbeeEP::getTimezone(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_addr_t ieee_addr) { + /* Read peer timezone */ + esp_zb_zcl_read_attr_cmd_t read_req; + + if (short_addr >= 0) { + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + read_req.zcl_basic_cmd.dst_addr_u.addr_short = (uint16_t)short_addr; + } else { + read_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + memcpy(read_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t)); + } + + uint16_t attributes[] = {ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID}; + read_req.attr_number = ZB_ARRAY_LENTH(attributes); + read_req.attr_field = attributes; + + read_req.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TIME; + + read_req.zcl_basic_cmd.dst_endpoint = endpoint; + read_req.zcl_basic_cmd.src_endpoint = _endpoint; + + // clear read timezone + _read_timezone = 0; + + log_v("Reading timezone from endpoint %d", endpoint); + esp_zb_zcl_read_attr_cmd_req(&read_req); + + //Wait for response or timeout + if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) { + log_e("Error while reading timezone"); + } + + return _read_timezone; +} + +void ZigbeeEP::zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute) { + /* Time cluster attributes */ + if (attribute->id == ESP_ZB_ZCL_ATTR_TIME_TIME_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_UTC_TIME) { + log_v("Time attribute received"); + log_v("Time: %lld", *(uint32_t *)attribute->data.value); + _read_time = *(uint32_t *)attribute->data.value; + xSemaphoreGive(lock); + } else if (attribute->id == ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID && attribute->data.type == ESP_ZB_ZCL_ATTR_TYPE_S32) { + log_v("Timezone attribute received"); + log_v("Timezone: %d", *(int32_t *)attribute->data.value); + _read_timezone = *(int32_t *)attribute->data.value; + xSemaphoreGive(lock); + } +} + #endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index ac22143c4d7..eae81fafbc3 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -82,16 +82,27 @@ class ZigbeeEP { _allow_multiple_binding = bind; } - // Manufacturer name and model implemented + // Set Manufacturer name and model void setManufacturerAndModel(const char *name, const char *model); - void setPowerSource(zb_power_source_t power_source, uint8_t percentage = 255); - void setBatteryPercentage(uint8_t percentage); - void reportBatteryPercentage(); // Methods to read manufacturer and model name from selected endpoint and short address char *readManufacturer(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr); char *readModel(uint8_t endpoint, uint16_t short_addr, esp_zb_ieee_addr_t ieee_addr); + // Set Power source and battery percentage for battery powered devices + void setPowerSource(zb_power_source_t power_source, uint8_t percentage = 255); + void setBatteryPercentage(uint8_t percentage); + void reportBatteryPercentage(); + + // Set time + void addTimeCluster(tm time = {0}, int32_t gmt_offset = 0); // gmt offset in seconds + void setTime(tm time); + void setTimezone(int32_t gmt_offset); + + // Get time from Coordinator or specific endpoint (blocking until response) + struct tm getTime(uint8_t endpoint = 1, int32_t short_addr = 0x0000, esp_zb_ieee_addr_t ieee_addr = {0}); + int32_t getTimezone(uint8_t endpoint = 1, int32_t short_addr = 0x0000, esp_zb_ieee_addr_t ieee_addr = {0}); // gmt offset in seconds + bool epAllowMultipleBinding() { return _allow_multiple_binding; } @@ -104,6 +115,7 @@ class ZigbeeEP { virtual void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) {}; virtual void zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented virtual void zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message); + virtual void zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented virtual void zbIASZoneStatusChangeNotification(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) {}; @@ -120,6 +132,8 @@ class ZigbeeEP { char *_read_manufacturer; char *_read_model; void (*_on_identify)(uint16_t time); + time_t _read_time; + int32_t _read_timezone; protected: uint8_t _endpoint; diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index bccb27da7f8..3b4992d81db 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -105,6 +105,8 @@ static esp_err_t zb_cmd_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_re if (variable->status == ESP_ZB_ZCL_STATUS_SUCCESS) { if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_BASIC) { (*it)->zbReadBasicCluster(&variable->attribute); //method zbReadBasicCluster implemented in the common EP class + } else if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_TIME) { + (*it)->zbReadTimeCluster(&variable->attribute); //method zbReadTimeCluster implemented in the common EP class } else { (*it)->zbAttributeRead(message->info.cluster, &variable->attribute); //method zbAttributeRead must be implemented in specific EP class } diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp index 5def43f4199..b4386b80386 100644 --- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp @@ -11,7 +11,6 @@ esp_zb_cluster_list_t *zigbee_carbon_dioxide_sensor_clusters_create(zigbee_carbo esp_zb_cluster_list_add_carbon_dioxide_measurement_cluster( cluster_list, esp_zb_carbon_dioxide_measurement_cluster_create(carbon_dioxide_meas_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE ); - esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); return cluster_list; } diff --git a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp index 75196e78543..36d66840967 100644 --- a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp @@ -9,7 +9,6 @@ esp_zb_cluster_list_t *zigbee_flow_sensor_clusters_create(zigbee_flow_sensor_cfg esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); esp_zb_cluster_list_add_flow_meas_cluster(cluster_list, esp_zb_flow_meas_cluster_create(flow_meas_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); return cluster_list; } diff --git a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp index 3a7acee040c..dec7910ac03 100644 --- a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp @@ -9,7 +9,6 @@ esp_zb_cluster_list_t *zigbee_occupancy_sensor_clusters_create(zigbee_occupancy_ esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); esp_zb_cluster_list_add_occupancy_sensing_cluster(cluster_list, esp_zb_occupancy_sensing_cluster_create(occupancy_meas_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); return cluster_list; } diff --git a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp index 24b4efb127e..b887680076d 100644 --- a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp @@ -9,7 +9,6 @@ esp_zb_cluster_list_t *zigbee_pressure_sensor_clusters_create(zigbee_pressure_se esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); esp_zb_cluster_list_add_pressure_meas_cluster(cluster_list, esp_zb_pressure_meas_cluster_create(pressure_meas_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); return cluster_list; } From 402ab56bf1d68f8fbc9788a168837b1534551390 Mon Sep 17 00:00:00 2001 From: TD-er Date: Thu, 30 Jan 2025 18:12:07 +0100 Subject: [PATCH 06/79] fix(SPIFFS): Use new disableWDT bool return value (#10909) Analogue to this PR, but for SPIFFS: https://github.com/espressif/arduino-esp32/pull/10896/files --- libraries/SPIFFS/src/SPIFFS.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/SPIFFS/src/SPIFFS.cpp b/libraries/SPIFFS/src/SPIFFS.cpp index a77b32990bf..0b2cc0d462d 100644 --- a/libraries/SPIFFS/src/SPIFFS.cpp +++ b/libraries/SPIFFS/src/SPIFFS.cpp @@ -91,9 +91,11 @@ void SPIFFSFS::end() { } bool SPIFFSFS::format() { - disableCore0WDT(); + bool wdt_active = disableCore0WDT(); esp_err_t err = esp_spiffs_format(partitionLabel_); - enableCore0WDT(); + if (wdt_active) { + enableCore0WDT(); + } if (err) { log_e("Formatting SPIFFS failed! Error: %d", err); return false; From f22866f888b713fa09c4b29b854a734478b407ad Mon Sep 17 00:00:00 2001 From: Jack Lin Date: Thu, 30 Jan 2025 09:14:08 -0800 Subject: [PATCH 07/79] Update HTTPS certificate in BasicHttpsClient.ino (#10911) The certificate is outdated. The current certificate can be found using `openssl s_client -showcerts -connect jigsaw.w3.org:443` --- .../BasicHttpsClient/BasicHttpsClient.ino | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino b/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino index eb6caef0724..73e127d1261 100644 --- a/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino +++ b/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino @@ -14,30 +14,32 @@ #include -// This is a Baltimore CyberTrust cert, the root Certificate Authority that +// This is a Google Trust Services cert, the root Certificate Authority that // signed the server certificate for the demo server https://jigsaw.w3.org in this -// example. This certificate is valid until Mon, 12 May 2025 23:59:00 GMT -const char *rootCACertificate = "-----BEGIN CERTIFICATE-----\n" - "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\n" - "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\n" - "VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\n" - "DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\n" - "ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\n" - "VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\n" - "mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\n" - "IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\n" - "mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\n" - "XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\n" - "dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\n" - "jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\n" - "BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\n" - "DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n" - "9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\n" - "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\n" - "Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\n" - "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\n" - "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n" - "-----END CERTIFICATE-----\n"; +// example. This certificate is valid until Jan 28 00:00:42 2028 GMT +const char *rootCACertificate = R"string_literal( +-----BEGIN CERTIFICATE----- +MIIDejCCAmKgAwIBAgIQf+UwvzMTQ77dghYQST2KGzANBgkqhkiG9w0BAQsFADBX +MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEQMA4GA1UE +CxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFsU2lnbiBSb290IENBMB4XDTIzMTEx +NTAzNDMyMVoXDTI4MDEyODAwMDA0MlowRzELMAkGA1UEBhMCVVMxIjAgBgNVBAoT +GUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBMTEMxFDASBgNVBAMTC0dUUyBSb290IFI0 +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE83Rzp2iLYK5DuDXFgTB7S0md+8Fhzube +Rr1r1WEYNa5A3XP3iZEwWus87oV8okB2O6nGuEfYKueSkWpz6bFyOZ8pn6KY019e +WIZlD6GEZQbR3IvJx3PIjGov5cSr0R2Ko4H/MIH8MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUgEzW63T/STaj1dj8tT7FavCUHYwwHwYDVR0jBBgwFoAUYHtmGkUN +l8qJUC99BM00qP/8/UswNgYIKwYBBQUHAQEEKjAoMCYGCCsGAQUFBzAChhpodHRw +Oi8vaS5wa2kuZ29vZy9nc3IxLmNydDAtBgNVHR8EJjAkMCKgIKAehhxodHRwOi8v +Yy5wa2kuZ29vZy9yL2dzcjEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqG +SIb3DQEBCwUAA4IBAQAYQrsPBtYDh5bjP2OBDwmkoWhIDDkic574y04tfzHpn+cJ +odI2D4SseesQ6bDrarZ7C30ddLibZatoKiws3UL9xnELz4ct92vID24FfVbiI1hY ++SW6FoVHkNeWIP0GCbaM4C6uVdF5dTUsMVs/ZbzNnIdCp5Gxmx5ejvEau8otR/Cs +kGN+hr/W5GvT1tMBjgWKZ1i4//emhA1JG1BbPzoLJQvyEotc03lXjTaCzv8mEbep +8RqZ7a2CPsgRbuvTPBwcOMBBmuFeU88+FSBX6+7iP0il8b4Z0QFqIwwMHfs/L6K1 +vepuoxtGzi4CZ68zJpiq1UvSqTbFJjtbD4seiMHl +-----END CERTIFICATE----- +)string_literal"; // Not sure if NetworkClientSecure checks the validity date of the certificate. // Setting clock just to be sure... From 0302b4db4741ae51ff45a3b1b533175ee0c0d92c Mon Sep 17 00:00:00 2001 From: "Sayed (Tashfi) Nowroz" Date: Fri, 31 Jan 2025 16:25:45 -0500 Subject: [PATCH 08/79] fix(logging): incorrect FPS logging (#10921) * fix(logging): Corrected FPS calculation Previously, last_frame was only updated once at the beginning of stream_handler, leading to incorrect FPS and avg_frame_time computation. This commit ensures last_frame is updated on each iteration after last FPS computation, resulting in accurate FPS logging. Fixes #10920 * Revert "fix(logging): Corrected FPS calculation" This reverts commit 0bb7b9555e7661c72dc3376cf8a001c6fd3758c8. * fix(loggin): Incorrect FPS computation fixed Corrected and tested change in FPS computation, suggested by @me-no-dev and found working with correct numbers. Previously, last_frame was only updated once at the beginning of stream_handler, leading to incorrect FPS and avg_frame_time computation. This commit ensures last_frame is updated on each iteration after last FPS computation, resulting in accurate FPS logging. Fixes #10920 --- libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp index 6b62ee9b6cf..81d643e37ac 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp +++ b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp @@ -281,6 +281,8 @@ static esp_err_t stream_handler(httpd_req_t *req) { int64_t fr_end = esp_timer_get_time(); int64_t frame_time = fr_end - last_frame; + last_frame = fr_end; + frame_time /= 1000; #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO uint32_t avg_frame_time = ra_filter_run(&ra_filter, frame_time); From 1c01fcd196ad8278feafe35bc785999db72a5425 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 4 Feb 2025 06:04:58 -0300 Subject: [PATCH 09/79] fix(uart): fixed esp32s2 uart ci test case (#10926) Wrong pins were used for baud rate detection test case, therefore no data was reaching UART1 RX FIFO from UART0 TX loopback. --- tests/validation/uart/uart.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/validation/uart/uart.ino b/tests/validation/uart/uart.ino index 27bd95da7f8..358276c00b4 100644 --- a/tests/validation/uart/uart.ino +++ b/tests/validation/uart/uart.ino @@ -399,7 +399,8 @@ void auto_baudrate_test(void) { if (TEST_UART_NUM == 1) { selected_serial = &Serial1; - uart_internal_loopback(0, RX1); + // UART1 pins were swapped because of ESP32-P4 + uart_internal_loopback(0, /*RX1*/ TX1); } else { #ifdef RX2 selected_serial = &Serial2; From 2040cbad51b7e9917729244f8781b66786ddd50c Mon Sep 17 00:00:00 2001 From: Akashdeep Deb Date: Tue, 4 Feb 2025 09:24:49 +0000 Subject: [PATCH 10/79] Update README.md to add ESP-SR (#10925) Adding ESP-SR to the documentation Co-authored-by: Me No Dev --- libraries/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/README.md b/libraries/README.md index 38765f99b52..aee5bb07614 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -88,6 +88,9 @@ arduino-esp32 includes libraries for Arduino compatibility along with some objec ### SPIFFS SPI Flash Filesystem (see [spiffs-plugin](https://github.com/me-no-dev/arduino-esp32fs-plugin) to upload to device) +### SR + ESP-SR helps users build AI speech solutions based on ESP32-S3 or ESP32-P4 chips + ### Ticker A timer to call functions on an interval From 6eb99d3ae32966bb985853fdf73d6da2e34fd565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 4 Feb 2025 10:25:11 +0100 Subject: [PATCH 11/79] feat(zigbee): Add IAS Zone endpoints (Contact Switch + Door/Window Handle) (#10918) * feat(zigbee): Add IAS Zone endpoints * ci(pre-commit): Apply automatic fixes * fix(ci): Typo fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- CMakeLists.txt | 2 + .../examples/Zigbee_Contact_Switch/README.md | 58 ++++++++++ .../Zigbee_Contact_Switch.ino | 100 ++++++++++++++++ .../examples/Zigbee_Contact_Switch/ci.json | 6 + libraries/Zigbee/src/Zigbee.h | 2 + libraries/Zigbee/src/ZigbeeEP.h | 1 + libraries/Zigbee/src/ZigbeeHandlers.cpp | 22 ++++ .../Zigbee/src/ep/ZigbeeContactSwitch.cpp | 96 ++++++++++++++++ libraries/Zigbee/src/ep/ZigbeeContactSwitch.h | 67 +++++++++++ .../Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 108 ++++++++++++++++++ .../Zigbee/src/ep/ZigbeeDoorWindowHandle.h | 71 ++++++++++++ 11 files changed, 533 insertions(+) create mode 100644 libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md create mode 100644 libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino create mode 100644 libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json create mode 100644 libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeContactSwitch.h create mode 100644 libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fd23d14d77..b3cb6c06cdc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -290,6 +290,8 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp + libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp + libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp ) set(ARDUINO_LIBRARY_BLE_SRCS diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md b/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md new file mode 100644 index 00000000000..a5a32358a7c --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/README.md @@ -0,0 +1,58 @@ +# Arduino-ESP32 Zigbee Contact Switch Example + +This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) contact switch (IAS Zone), +that can be used for example as window/door sensor having 2 states - closed/open. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Hardware Required + +* A USB cable for power supply and programming + +### Configure the Project + +Set the Button GPIO by changing the `button` variable. By default, it's the pin `BOOT_PIN` (BOOT button on ESP32-C6 and ESP32-H2). +Set the Sensor GPIO by changing the `sensor_pin` variable. + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ED (end device)` +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs` +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. +* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. + +## Troubleshooting + +If the End device flashed with this example is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino new file mode 100644 index 00000000000..ce9eedb683d --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/Zigbee_Contact_Switch.ino @@ -0,0 +1,100 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +/** + * @brief This example demonstrates Zigbee contact switch (IAS Zone). + * + * The example demonstrates how to use Zigbee library to create a end device contact switch. + * The contact switch is a Zigbee end device, which is reporting data to the Zigbee network. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ED +#error "Zigbee end device mode is not selected in Tools->Zigbee mode" +#endif + +#include "Zigbee.h" + +/* Zigbee contact sensor configuration */ +#define CONTACT_SWITCH_ENDPOINT_NUMBER 10 +uint8_t button = BOOT_PIN; +uint8_t sensor_pin = 4; + +ZigbeeContactSwitch zbContactSwitch = ZigbeeContactSwitch(CONTACT_SWITCH_ENDPOINT_NUMBER); + +void setup() { + Serial.begin(115200); + + // Init button + switch + pinMode(button, INPUT_PULLUP); + pinMode(sensor_pin, INPUT_PULLUP); + + // Optional: set Zigbee device name and model + zbContactSwitch.setManufacturerAndModel("Espressif", "ZigbeeContactSwitch"); + + // Add endpoint to Zigbee Core + Zigbee.addEndpoint(&zbContactSwitch); + + Serial.println("Starting Zigbee..."); + // When all EPs are registered, start Zigbee in End Device mode + if (!Zigbee.begin()) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } else { + Serial.println("Zigbee started successfully!"); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println(); +} + +void loop() { + // Checking pin for contact change + static bool contact = false; + if (digitalRead(sensor_pin) == HIGH && !contact) { + // Update contact sensor value + zbContactSwitch.setOpen(); + contact = true; + } else if (digitalRead(sensor_pin) == LOW && contact) { + zbContactSwitch.setClosed(); + contact = false; + } + + // Checking button for factory reset + if (digitalRead(button) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(button) == LOW) { + delay(50); + if ((millis() - startTime) > 3000) { + // If key pressed for more than 3secs, factory reset Zigbee and reboot + Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + delay(1000); + Zigbee.factoryReset(); + } + } + } + delay(100); +} diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json b/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json new file mode 100644 index 00000000000..7b7ccef8ed7 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json @@ -0,0 +1,6 @@ +{ + "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", + "requires": [ + "CONFIG_SOC_IEEE802154_SUPPORTED=y" + ] +} diff --git a/libraries/Zigbee/src/Zigbee.h b/libraries/Zigbee/src/Zigbee.h index cf58dc8d5d8..c97be9378a8 100644 --- a/libraries/Zigbee/src/Zigbee.h +++ b/libraries/Zigbee/src/Zigbee.h @@ -18,3 +18,5 @@ #include "ep/ZigbeeFlowSensor.h" #include "ep/ZigbeeOccupancySensor.h" #include "ep/ZigbeeCarbonDioxideSensor.h" +#include "ep/ZigbeeContactSwitch.h" +#include "ep/ZigbeeDoorWindowHandle.h" diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index eae81fafbc3..069db95aac0 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -118,6 +118,7 @@ class ZigbeeEP { virtual void zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented virtual void zbIASZoneStatusChangeNotification(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) {}; + virtual void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) {}; virtual void addBoundDevice(zb_device_params_t *device) { _bound_devices.push_back(device); diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index 3b4992d81db..52c38eb0633 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -10,6 +10,7 @@ static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_mes static esp_err_t zb_cmd_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_resp_message_t *message); static esp_err_t zb_configure_report_resp_handler(const esp_zb_zcl_cmd_config_report_resp_message_t *message); static esp_err_t zb_cmd_ias_zone_status_change_handler(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message); +static esp_err_t zb_cmd_ias_zone_enroll_response_handler(const esp_zb_zcl_ias_zone_enroll_response_message_t *message); static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message); // Zigbee action handlers @@ -24,6 +25,9 @@ static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, case ESP_ZB_CORE_CMD_IAS_ZONE_ZONE_STATUS_CHANGE_NOT_ID: ret = zb_cmd_ias_zone_status_change_handler((esp_zb_zcl_ias_zone_status_change_notification_message_t *)message); break; + case ESP_ZB_CORE_IAS_ZONE_ENROLL_RESPONSE_VALUE_CB_ID: + ret = zb_cmd_ias_zone_enroll_response_handler((esp_zb_zcl_ias_zone_enroll_response_message_t *)message); + break; case ESP_ZB_CORE_CMD_DEFAULT_RESP_CB_ID: ret = zb_cmd_default_resp_handler((esp_zb_zcl_cmd_default_resp_message_t *)message); break; default: log_w("Receive unhandled Zigbee action(0x%x) callback", callback_id); break; } @@ -160,6 +164,24 @@ static esp_err_t zb_cmd_ias_zone_status_change_handler(const esp_zb_zcl_ias_zone return ESP_OK; } +static esp_err_t zb_cmd_ias_zone_enroll_response_handler(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { + if (!message) { + log_e("Empty message"); + return ESP_FAIL; + } + if (message->info.status != ESP_ZB_ZCL_STATUS_SUCCESS) { + log_e("Received message: error status(%d)", message->info.status); + return ESP_ERR_INVALID_ARG; + } + log_v("IAS Zone Enroll Response received"); + for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { + if (message->info.dst_endpoint == (*it)->getEndpoint()) { + (*it)->zbIASZoneEnrollResponse(message); + } + } + return ESP_OK; +} + static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message) { if (!message) { log_e("Empty message"); diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp new file mode 100644 index 00000000000..9a3551b0581 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -0,0 +1,96 @@ +#include "ZigbeeContactSwitch.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +esp_zb_cluster_list_t *zigbee_contact_switch_clusters_create(zigbee_contact_switch_cfg_t *contact_switch) { + esp_zb_basic_cluster_cfg_t *basic_cfg = contact_switch ? &(contact_switch->basic_cfg) : NULL; + esp_zb_identify_cluster_cfg_t *identify_cfg = contact_switch ? &(contact_switch->identify_cfg) : NULL; + esp_zb_ias_zone_cluster_cfg_t *ias_zone_cfg = contact_switch ? &(contact_switch->ias_zone_cfg) : NULL; + esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_ias_zone_cluster(cluster_list, esp_zb_ias_zone_cluster_create(ias_zone_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + return cluster_list; +} + +ZigbeeContactSwitch::ZigbeeContactSwitch(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_IAS_ZONE_ID; + _zone_status = 0; + _zone_id = 0xff; + _ias_cie_endpoint = 1; + + //Create custom contact switch configuration + zigbee_contact_switch_cfg_t contact_switch_cfg = ZIGBEE_DEFAULT_CONTACT_SWITCH_CONFIG(); + _cluster_list = zigbee_contact_switch_clusters_create(&contact_switch_cfg); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_IAS_ZONE_ID, .app_device_version = 0}; +} + +void ZigbeeContactSwitch::setIASClientEndpoint(uint8_t ep_number) { + _ias_cie_endpoint = ep_number; +} + +void ZigbeeContactSwitch::setClosed() { + log_v("Setting Contact switch to closed"); + uint8_t closed = 0; // ALARM1 = 0, ALARM2 = 0 + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &closed, false + ); + esp_zb_lock_release(); + _zone_status = closed; + report(); +} + +void ZigbeeContactSwitch::setOpen() { + log_v("Setting Contact switch to open"); + uint8_t open = ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM1 | ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM2; // ALARM1 = 1, ALARM2 = 1 + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &open, false); + esp_zb_lock_release(); + _zone_status = open; + report(); +} + +void ZigbeeContactSwitch::report() { + /* Send IAS Zone status changed notification command */ + + esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd; + status_change_notif_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + status_change_notif_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + status_change_notif_cmd.zcl_basic_cmd.dst_endpoint = _ias_cie_endpoint; //default is 1 + memcpy(status_change_notif_cmd.zcl_basic_cmd.dst_addr_u.addr_long, _ias_cie_addr, sizeof(esp_zb_ieee_addr_t)); + + status_change_notif_cmd.zone_status = _zone_status; + status_change_notif_cmd.extend_status = 0; + status_change_notif_cmd.zone_id = _zone_id; + status_change_notif_cmd.delay = 0; + + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); + esp_zb_lock_release(); + log_v("IAS Zone status changed notification sent"); +} + +void ZigbeeContactSwitch::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE) { + log_v("IAS Zone Enroll Response: zone id(%d), status(%d)", message->zone_id, message->response_code); + if (message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) { + log_v("IAS Zone Enroll Response: success"); + esp_zb_lock_acquire(portMAX_DELAY); + memcpy( + _ias_cie_addr, + (*(esp_zb_ieee_addr_t *) + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID) + ->data_p), + sizeof(esp_zb_ieee_addr_t) + ); + esp_zb_lock_release(); + _zone_id = message->zone_id; + } + + } else { + log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); + } +} + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h new file mode 100644 index 00000000000..692caf092ba --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h @@ -0,0 +1,67 @@ +/* Class of Zigbee contact switch (IAS Zone) endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +// clang-format off +#define ZIGBEE_DEFAULT_CONTACT_SWITCH_CONFIG() \ + { \ + .basic_cfg = \ + { \ + .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE, \ + .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE, \ + }, \ + .identify_cfg = \ + { \ + .identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, \ + }, \ + .ias_zone_cfg = \ + { \ + .zone_state = ESP_ZB_ZCL_IAS_ZONE_ZONESTATE_NOT_ENROLLED, \ + .zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_CONTACT_SWITCH, \ + .zone_status = 0, \ + .ias_cie_addr = ESP_ZB_ZCL_ZONE_IAS_CIE_ADDR_DEFAULT, \ + .zone_id = 0xff, \ + .zone_ctx = {0, 0, 0, 0}, \ + }, \ + } +// clang-format on + +typedef struct zigbee_contact_switch_cfg_s { + esp_zb_basic_cluster_cfg_t basic_cfg; + esp_zb_identify_cluster_cfg_t identify_cfg; + esp_zb_ias_zone_cluster_cfg_t ias_zone_cfg; +} zigbee_contact_switch_cfg_t; + +class ZigbeeContactSwitch : public ZigbeeEP { +public: + ZigbeeContactSwitch(uint8_t endpoint); + ~ZigbeeContactSwitch() {} + + // Set the IAS Client endpoint number (default is 1) + void setIASClientEndpoint(uint8_t ep_number); + + // Set the contact switch value to closed + void setClosed(); + + // Set the contact switch value to open + void setOpen(); + + // Report the contact switch value, done automatically after setting the position + void report(); + +private: + void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; + uint8_t _zone_status; + uint8_t _zone_id; + esp_zb_ieee_addr_t _ias_cie_addr; + uint8_t _ias_cie_endpoint; +}; + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp new file mode 100644 index 00000000000..364b3ef6d9d --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -0,0 +1,108 @@ +#include "ZigbeeDoorWindowHandle.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +esp_zb_cluster_list_t *zigbee_door_window_handle_clusters_create(zigbee_door_window_handle_cfg_t *door_window_handle) { + esp_zb_basic_cluster_cfg_t *basic_cfg = door_window_handle ? &(door_window_handle->basic_cfg) : NULL; + esp_zb_identify_cluster_cfg_t *identify_cfg = door_window_handle ? &(door_window_handle->identify_cfg) : NULL; + esp_zb_ias_zone_cluster_cfg_t *ias_zone_cfg = door_window_handle ? &(door_window_handle->ias_zone_cfg) : NULL; + esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_ias_zone_cluster(cluster_list, esp_zb_ias_zone_cluster_create(ias_zone_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + return cluster_list; +} + +ZigbeeDoorWindowHandle::ZigbeeDoorWindowHandle(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_IAS_ZONE_ID; + _zone_status = 0; + _zone_id = 0xff; + _ias_cie_endpoint = 1; + + //Create custom door window handle configuration + zigbee_door_window_handle_cfg_t door_window_handle_cfg = ZIGBEE_DEFAULT_DOOR_WINDOW_HANDLE_CONFIG(); + _cluster_list = zigbee_door_window_handle_clusters_create(&door_window_handle_cfg); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_IAS_ZONE_ID, .app_device_version = 0}; +} + +void ZigbeeDoorWindowHandle::setIASClientEndpoint(uint8_t ep_number) { + _ias_cie_endpoint = ep_number; +} + +void ZigbeeDoorWindowHandle::setClosed() { + log_v("Setting Door/Window handle to closed"); + uint8_t closed = 0; // ALARM1 = 0, ALARM2 = 0 + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &closed, false + ); + esp_zb_lock_release(); + _zone_status = closed; + report(); +} + +void ZigbeeDoorWindowHandle::setOpen() { + log_v("Setting Door/Window handle to open"); + uint8_t open = ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM1 | ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM2; // ALARM1 = 1, ALARM2 = 1 + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &open, false); + esp_zb_lock_release(); + _zone_status = open; + report(); +} + +void ZigbeeDoorWindowHandle::setTilted() { + log_v("Setting Door/Window handle to tilted"); + uint8_t tilted = ESP_ZB_ZCL_IAS_ZONE_ZONE_STATUS_ALARM1; // ALARM1 = 1, ALARM2 = 0 + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &tilted, false + ); + esp_zb_lock_release(); + _zone_status = tilted; + report(); +} + +void ZigbeeDoorWindowHandle::report() { + /* Send IAS Zone status changed notification command */ + + esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd; + status_change_notif_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + status_change_notif_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + status_change_notif_cmd.zcl_basic_cmd.dst_endpoint = _ias_cie_endpoint; //default is 1 + memcpy(status_change_notif_cmd.zcl_basic_cmd.dst_addr_u.addr_long, _ias_cie_addr, sizeof(esp_zb_ieee_addr_t)); + + status_change_notif_cmd.zone_status = _zone_status; + status_change_notif_cmd.extend_status = 0; + status_change_notif_cmd.zone_id = _zone_id; + status_change_notif_cmd.delay = 0; + + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); + esp_zb_lock_release(); + log_v("IAS Zone status changed notification sent"); +} + +void ZigbeeDoorWindowHandle::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE) { + log_v("IAS Zone Enroll Response: zone id(%d), status(%d)", message->zone_id, message->response_code); + if (message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) { + log_v("IAS Zone Enroll Response: success"); + esp_zb_lock_acquire(portMAX_DELAY); + memcpy( + _ias_cie_addr, + (*(esp_zb_ieee_addr_t *) + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID) + ->data_p), + sizeof(esp_zb_ieee_addr_t) + ); + esp_zb_lock_release(); + _zone_id = message->zone_id; + } + + } else { + log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); + } +} + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h new file mode 100644 index 00000000000..e60316f8764 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h @@ -0,0 +1,71 @@ +/* Class of Zigbee door window handle (IAS Zone) endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +#define ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_DOOR_WINDOW_HANDLE 0x0016 +// clang-format off +#define ZIGBEE_DEFAULT_DOOR_WINDOW_HANDLE_CONFIG() \ + { \ + .basic_cfg = \ + { \ + .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE, \ + .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE, \ + }, \ + .identify_cfg = \ + { \ + .identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, \ + }, \ + .ias_zone_cfg = \ + { \ + .zone_state = ESP_ZB_ZCL_IAS_ZONE_ZONESTATE_NOT_ENROLLED, \ + .zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_DOOR_WINDOW_HANDLE, \ + .zone_status = 0, \ + .ias_cie_addr = ESP_ZB_ZCL_ZONE_IAS_CIE_ADDR_DEFAULT, \ + .zone_id = 0xff, \ + .zone_ctx = {0, 0, 0, 0}, \ + }, \ + } +// clang-format on + +typedef struct zigbee_door_window_handle_cfg_s { + esp_zb_basic_cluster_cfg_t basic_cfg; + esp_zb_identify_cluster_cfg_t identify_cfg; + esp_zb_ias_zone_cluster_cfg_t ias_zone_cfg; +} zigbee_door_window_handle_cfg_t; + +class ZigbeeDoorWindowHandle : public ZigbeeEP { +public: + ZigbeeDoorWindowHandle(uint8_t endpoint); + ~ZigbeeDoorWindowHandle() {} + + // Set the IAS Client endpoint number (default is 1) + void setIASClientEndpoint(uint8_t ep_number); + + // Set the door/window handle value to closed + void setClosed(); + + // Set the door/window handle value to open + void setOpen(); + + // Set the door/window handle value to tilted + void setTilted(); + + // Report the door/window handle value, done automatically after setting the position + void report(); + +private: + void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; + uint8_t _zone_status; + uint8_t _zone_id; + esp_zb_ieee_addr_t _ias_cie_addr; + uint8_t _ias_cie_endpoint; +}; + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED From b385562fa601d80633d5d0389e059a5b8ba0f2b7 Mon Sep 17 00:00:00 2001 From: thekurtovic <40248206+thekurtovic@users.noreply.github.com> Date: Tue, 4 Feb 2025 04:52:45 -0500 Subject: [PATCH 12/79] NetworkEvents allow stack size to be changed. (#10805) * feat(net): Allow for event task custom stack size * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: Me No Dev Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- libraries/Network/src/NetworkEvents.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libraries/Network/src/NetworkEvents.cpp b/libraries/Network/src/NetworkEvents.cpp index 1a7177bae61..161e55c5d01 100644 --- a/libraries/Network/src/NetworkEvents.cpp +++ b/libraries/Network/src/NetworkEvents.cpp @@ -8,6 +8,10 @@ #include "esp_task.h" #include "esp32-hal.h" +#ifndef ARDUINO_NETWORK_EVENT_TASK_STACK_SIZE +#define ARDUINO_NETWORK_EVENT_TASK_STACK_SIZE 4096 +#endif + NetworkEvents::NetworkEvents() : _arduino_event_group(NULL), _arduino_event_queue(NULL), _arduino_event_task_handle(NULL) {} NetworkEvents::~NetworkEvents() { @@ -61,8 +65,8 @@ bool NetworkEvents::initNetworkEvents() { [](void *self) { static_cast(self)->_checkForEvent(); }, - "arduino_events", // label - 4096, // event task's stack size + "arduino_events", // label + ARDUINO_NETWORK_EVENT_TASK_STACK_SIZE, // event task's stack size this, ESP_TASKD_EVENT_PRIO - 1, &_arduino_event_task_handle, ARDUINO_EVENT_RUNNING_CORE ); if (!_arduino_event_task_handle) { From 8b31d1e1a86c0b3bacc59ab1dacc22ee3c6507c0 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 4 Feb 2025 12:53:29 +0200 Subject: [PATCH 13/79] fix(ci): Disable some RainMaker examples on ESP32 (#10931) --- libraries/RainMaker/examples/RMakerCustomAirCooler/ci.json | 3 +++ libraries/RainMaker/examples/RMakerSonoffDualR3/ci.json | 3 +++ 2 files changed, 6 insertions(+) diff --git a/libraries/RainMaker/examples/RMakerCustomAirCooler/ci.json b/libraries/RainMaker/examples/RMakerCustomAirCooler/ci.json index 1c80eda1d90..ce63fe9ccf0 100644 --- a/libraries/RainMaker/examples/RMakerCustomAirCooler/ci.json +++ b/libraries/RainMaker/examples/RMakerCustomAirCooler/ci.json @@ -1,4 +1,7 @@ { + "targets": { + "esp32": false + }, "fqbn_append": "PartitionScheme=rainmaker_4MB", "requires": [ "CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=[1-9][0-9]*" diff --git a/libraries/RainMaker/examples/RMakerSonoffDualR3/ci.json b/libraries/RainMaker/examples/RMakerSonoffDualR3/ci.json index 1c80eda1d90..ce63fe9ccf0 100644 --- a/libraries/RainMaker/examples/RMakerSonoffDualR3/ci.json +++ b/libraries/RainMaker/examples/RMakerSonoffDualR3/ci.json @@ -1,4 +1,7 @@ { + "targets": { + "esp32": false + }, "fqbn_append": "PartitionScheme=rainmaker_4MB", "requires": [ "CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK=[1-9][0-9]*" From 6a1127625c1e12f222435dafbfa56aacc2098c97 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 4 Feb 2025 13:22:20 +0200 Subject: [PATCH 14/79] fix(ota): Make sure that ArduinoOTA.end() is called in the destructor (#10932) --- libraries/ArduinoOTA/src/ArduinoOTA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ArduinoOTA/src/ArduinoOTA.cpp b/libraries/ArduinoOTA/src/ArduinoOTA.cpp index 0ab5466ab20..cb3ddc1e797 100644 --- a/libraries/ArduinoOTA/src/ArduinoOTA.cpp +++ b/libraries/ArduinoOTA/src/ArduinoOTA.cpp @@ -29,7 +29,7 @@ ArduinoOTAClass::ArduinoOTAClass() _start_callback(NULL), _end_callback(NULL), _error_callback(NULL), _progress_callback(NULL) {} ArduinoOTAClass::~ArduinoOTAClass() { - _udp_ota.stop(); + end(); } ArduinoOTAClass &ArduinoOTAClass::onStart(THandlerFunction fn) { From db0bbad9348f7d9bd0ce79152f004c61daf8793a Mon Sep 17 00:00:00 2001 From: Henning Kulander Date: Tue, 4 Feb 2025 16:52:02 +0100 Subject: [PATCH 15/79] Created Zigbee Endpoint for Window Covering. (#10914) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(zigbee): Added Endpoint for Window Covering (#10913) * Added example Sketch. * Added window covering to CMakeLists.txt. * feat(zigbee): Window covering tilt support and fixes * fix(zigbee): Fix typos * ci(pre-commit): Apply automatic fixes * fix(ci): Fixes of typos --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- CMakeLists.txt | 1 + .../examples/Zigbee_Window_Covering/README.md | 69 ++++ .../Zigbee_Window_Covering.ino | 198 +++++++++++ .../examples/Zigbee_Window_Covering/ci.json | 6 + libraries/Zigbee/src/Zigbee.h | 1 + libraries/Zigbee/src/ZigbeeEP.h | 2 +- libraries/Zigbee/src/ZigbeeHandlers.cpp | 26 ++ .../Zigbee/src/ep/ZigbeeWindowCovering.cpp | 308 ++++++++++++++++++ .../Zigbee/src/ep/ZigbeeWindowCovering.h | 147 +++++++++ 9 files changed, 757 insertions(+), 1 deletion(-) create mode 100644 libraries/Zigbee/examples/Zigbee_Window_Covering/README.md create mode 100644 libraries/Zigbee/examples/Zigbee_Window_Covering/Zigbee_Window_Covering.ino create mode 100644 libraries/Zigbee/examples/Zigbee_Window_Covering/ci.json create mode 100644 libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeWindowCovering.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b3cb6c06cdc..40567d1b45c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,6 +292,7 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp + libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp ) set(ARDUINO_LIBRARY_BLE_SRCS diff --git a/libraries/Zigbee/examples/Zigbee_Window_Covering/README.md b/libraries/Zigbee/examples/Zigbee_Window_Covering/README.md new file mode 100644 index 00000000000..469560a0e0c --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Window_Covering/README.md @@ -0,0 +1,69 @@ +# Arduino-ESP32 Window Covering Example + +This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) window covering device. + +To see if the communication with your Zigbee network works, use the Serial monitor and watch for output there. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Hardware Required + +* A USB cable for power supply and programming +* Board (ESP32-H2 or ESP32-C6) as Zigbee end device and upload the Zigbee_Window_Covering example +* Zigbee network / coordinator (Other board with switch examples or Zigbee2mqtt or ZigbeeHomeAssistant like application) + +### Configure the Project + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ED (end device)` +* Select Tools / USB CDC On Boot: "Enabled" +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs` +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. +* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. + +## Troubleshooting + +If the End device flashed with this example is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. It is recommended to do this if you re-flash the coordinator. +You can do the following: + +* In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. +* Add to the sketch `Zigbee.factoryReset();` to reset the device and Zigbee stack. + +By default, the coordinator network is closed after rebooting or flashing new firmware. +To open the network you have 2 options: + +* Open network after reboot by setting `Zigbee.setRebootOpenNetwork(time);` before calling `Zigbee.begin();`. +* In application you can anytime call `Zigbee.openNetwork(time);` to open the network for devices to join. + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/Zigbee/examples/Zigbee_Window_Covering/Zigbee_Window_Covering.ino b/libraries/Zigbee/examples/Zigbee_Window_Covering/Zigbee_Window_Covering.ino new file mode 100644 index 00000000000..c7f9cf84f74 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Window_Covering/Zigbee_Window_Covering.ino @@ -0,0 +1,198 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +/** + * @brief This example demonstrates Zigbee Window Covering. + * + * The example demonstrates how to use Zigbee library to create a end device window covering device. + * The window covering is a Zigbee end device, which is moving the blinds (lift+tilt) and reporting + * its current position to the Zigbee network. + * + * Use setCoveringType() to set the type of covering (blind, shade, etc.). + * + * The example also demonstrates how to use the button to manually control the lift position. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by hennikul and Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ED +#error "Zigbee end device mode is not selected in Tools->Zigbee mode" +#endif + +#include "ZigbeeCore.h" +#include "ep/ZigbeeWindowCovering.h" + +#define ZIGBEE_COVERING_ENDPOINT 10 +#define BUTTON_PIN 9 // ESP32-C6/H2 Boot button + +#define MAX_LIFT 200 // centimeters from open position (0-900) +#define MIN_LIFT 0 + +#define MAX_TILT 40 // centimeters from open position (0-900) +#define MIN_TILT 0 + +uint16_t currentLift = MAX_LIFT; +uint8_t currentLiftPercentage = 100; + +uint16_t currentTilt = MAX_TILT; +uint8_t currentTiltPercentage = 100; + +ZigbeeWindowCovering zbCovering = ZigbeeWindowCovering(ZIGBEE_COVERING_ENDPOINT); + +void setup() { + Serial.begin(115200); + + // Init button for factory reset + pinMode(BUTTON_PIN, INPUT_PULLUP); + + // Optional: set Zigbee device name and model + zbCovering.setManufacturerAndModel("Espressif", "WindowBlinds"); + + // Set proper covering type, it defines which attributes are available + zbCovering.setCoveringType(BLIND_LIFT_AND_TILT); + + // Set configuration: operational, online, not commands_reversed, lift / tilt closed_loop, lift / tilt encoder_controlled + zbCovering.setConfigStatus(true, true, false, true, true, true, true); + + // Set mode: not motor_reversed, calibration_mode, not maintenance_mode, not leds_on + zbCovering.setMode(false, true, false, false); + + // Set limits of motion + zbCovering.setLimits(MIN_LIFT, MAX_LIFT, MIN_TILT, MAX_TILT); + + // Set callback function for open, close, filt and tilt change, stop + zbCovering.onOpen(fullOpen); + zbCovering.onClose(fullClose); + zbCovering.onGoToLiftPercentage(goToLiftPercentage); + zbCovering.onGoToTiltPercentage(goToTiltPercentage); + zbCovering.onStop(stopMotor); + + // Add endpoint to Zigbee Core + Serial.println("Adding ZigbeeWindowCovering endpoint to Zigbee Core"); + Zigbee.addEndpoint(&zbCovering); + + // When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE + Serial.println("Calling Zigbee.begin()"); + if (!Zigbee.begin()) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // Set initial position + zbCovering.setLiftPercentage(currentLiftPercentage); + zbCovering.setTiltPercentage(currentTiltPercentage); +} + +void loop() { + // Checking button for factory reset + if (digitalRead(BUTTON_PIN) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(BUTTON_PIN) == LOW) { + delay(50); + if ((millis() - startTime) > 3000) { + // If key pressed for more than 3secs, factory reset Zigbee and reboot + Serial.printf("Resetting Zigbee to factory settings, reboot.\n"); + Zigbee.factoryReset(); + delay(30000); + } + } + // Manual lift control simulation by pressing button + manualControl(); + } + delay(500); +} + +void fullOpen() { + /* This is where you would trigger your motor to go to full open state, currentLift should + be updated until full open has been reached in order to provide feedback to controller of actual position + The stop can be always called, so the movement can be stopped at any time */ + + // Our cover updates instantly! + currentLift = MAX_LIFT; + currentLiftPercentage = 100; + Serial.println("Opening cover"); + // Update the current position + zbCovering.setLiftPercentage(currentLiftPercentage); +} + +void fullClose() { + /* This is where you would trigger your motor to go to full close state, currentLift should + be updated until full close has been reached in order to provide feedback to controller of actual position + The stop can be always called, so the movement can be stopped at any time */ + + // Our cover updates instantly! + currentLift = MIN_LIFT; + currentLiftPercentage = 0; + Serial.println("Closing cover"); + // Update the current position + zbCovering.setLiftPercentage(currentLiftPercentage); +} + +void goToLiftPercentage(uint8_t liftPercentage) { + /* This is where you would trigger your motor to go towards liftPercentage, currentLift should + be updated until liftPercentage has been reached in order to provide feedback to controller */ + + // Our simulated cover updates instantly! + currentLift = (liftPercentage * MAX_LIFT) / 100; + currentLiftPercentage = liftPercentage; + Serial.printf("New requested lift from Zigbee: %d (%d)\n", currentLift, liftPercentage); + + // Update the current position + zbCovering.setLiftPercentage(currentLiftPercentage); //or setLiftPosition() +} + +void goToTiltPercentage(uint8_t tiltPercentage) { + /* This is where you would trigger your motor to go towards tiltPercentage, currentTilt should + be updated until tiltPercentage has been reached in order to provide feedback to controller */ + + // Our simulated cover updates instantly! + currentTilt = (tiltPercentage * MAX_TILT) / 100; + currentTiltPercentage = tiltPercentage; + Serial.printf("New requested tilt from Zigbee: %d (%d)\n", currentTilt, tiltPercentage); + + // Update the current position + zbCovering.setTiltPercentage(currentTiltPercentage); //or setTiltPosition() +} + +void stopMotor() { + // Motor can be stopped while moving cover toward current target, when stopped the actual position should be updated + Serial.println("Stopping motor"); + // Update the current position of both lift and tilt + zbCovering.setLiftPercentage(currentLiftPercentage); + zbCovering.setTiltPercentage(currentTiltPercentage); +} + +void manualControl() { + // Simulate lift percentage move by increasing it by 20% each time + currentLiftPercentage += 20; + if (currentLiftPercentage > 100) { + currentLiftPercentage = 0; + } + zbCovering.setLiftPercentage(currentLiftPercentage); + // Also setLiftPosition() can be used to set the exact position instead of percentage +} diff --git a/libraries/Zigbee/examples/Zigbee_Window_Covering/ci.json b/libraries/Zigbee/examples/Zigbee_Window_Covering/ci.json new file mode 100644 index 00000000000..7b7ccef8ed7 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Window_Covering/ci.json @@ -0,0 +1,6 @@ +{ + "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", + "requires": [ + "CONFIG_SOC_IEEE802154_SUPPORTED=y" + ] +} diff --git a/libraries/Zigbee/src/Zigbee.h b/libraries/Zigbee/src/Zigbee.h index c97be9378a8..49bfa44d5c1 100644 --- a/libraries/Zigbee/src/Zigbee.h +++ b/libraries/Zigbee/src/Zigbee.h @@ -20,3 +20,4 @@ #include "ep/ZigbeeCarbonDioxideSensor.h" #include "ep/ZigbeeContactSwitch.h" #include "ep/ZigbeeDoorWindowHandle.h" +#include "ep/ZigbeeWindowCovering.h" diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index 069db95aac0..fce0500ef0d 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -115,8 +115,8 @@ class ZigbeeEP { virtual void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) {}; virtual void zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented virtual void zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message); + virtual void zbWindowCoveringMovementCmd(const esp_zb_zcl_window_covering_movement_message_t *message) {}; virtual void zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented - virtual void zbIASZoneStatusChangeNotification(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message) {}; virtual void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) {}; diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index 52c38eb0633..575b25ef404 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -12,6 +12,7 @@ static esp_err_t zb_configure_report_resp_handler(const esp_zb_zcl_cmd_config_re static esp_err_t zb_cmd_ias_zone_status_change_handler(const esp_zb_zcl_ias_zone_status_change_notification_message_t *message); static esp_err_t zb_cmd_ias_zone_enroll_response_handler(const esp_zb_zcl_ias_zone_enroll_response_message_t *message); static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message); +static esp_err_t zb_window_covering_movement_resp_handler(const esp_zb_zcl_window_covering_movement_message_t *message); // Zigbee action handlers [[maybe_unused]] @@ -28,6 +29,9 @@ static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, case ESP_ZB_CORE_IAS_ZONE_ENROLL_RESPONSE_VALUE_CB_ID: ret = zb_cmd_ias_zone_enroll_response_handler((esp_zb_zcl_ias_zone_enroll_response_message_t *)message); break; + case ESP_ZB_CORE_WINDOW_COVERING_MOVEMENT_CB_ID: + ret = zb_window_covering_movement_resp_handler((esp_zb_zcl_window_covering_movement_message_t *)message); + break; case ESP_ZB_CORE_CMD_DEFAULT_RESP_CB_ID: ret = zb_cmd_default_resp_handler((esp_zb_zcl_cmd_default_resp_message_t *)message); break; default: log_w("Receive unhandled Zigbee action(0x%x) callback", callback_id); break; } @@ -198,4 +202,26 @@ static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_m return ESP_OK; } +static esp_err_t zb_window_covering_movement_resp_handler(const esp_zb_zcl_window_covering_movement_message_t *message) { + if (!message) { + log_e("Empty message"); + } + if (message->info.status != ESP_ZB_ZCL_STATUS_SUCCESS) { + log_e("Received message: error status(%d)", message->info.status); + } + + log_v( + "Received message: endpoint(%d), cluster(0x%x), command(0x%x), payload(%d)", message->info.dst_endpoint, message->info.cluster, message->command, + message->payload + ); + + // List through all Zigbee EPs and call the callback function, with the message + for (std::list::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) { + if (message->info.dst_endpoint == (*it)->getEndpoint()) { + (*it)->zbWindowCoveringMovementCmd(message); //method zbWindowCoveringMovementCmd must be implemented in specific EP class + } + } + return ESP_OK; +} + #endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp new file mode 100644 index 00000000000..970017165e2 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp @@ -0,0 +1,308 @@ + +#include "ZigbeeWindowCovering.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +esp_zb_cluster_list_t *ZigbeeWindowCovering::zigbee_window_covering_clusters_create(zigbee_window_covering_cfg_t *window_covering_cfg) { + esp_zb_attribute_list_t *esp_zb_basic_cluster = esp_zb_basic_cluster_create(&window_covering_cfg->basic_cfg); + esp_zb_attribute_list_t *esp_zb_identify_cluster = esp_zb_identify_cluster_create(&window_covering_cfg->identify_cfg); + esp_zb_attribute_list_t *esp_zb_groups_cluster = esp_zb_groups_cluster_create(&window_covering_cfg->groups_cfg); + esp_zb_attribute_list_t *esp_zb_scenes_cluster = esp_zb_scenes_cluster_create(&window_covering_cfg->scenes_cfg); + esp_zb_attribute_list_t *esp_zb_window_covering_cluster = esp_zb_window_covering_cluster_create(&window_covering_cfg->window_covering_cfg); + + esp_zb_window_covering_cluster_add_attr( + esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_PERCENTAGE_ID, &_current_lift_percentage + ); + esp_zb_window_covering_cluster_add_attr( + esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_PERCENTAGE_ID, &_current_tilt_percentage + ); + esp_zb_window_covering_cluster_add_attr(esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_ID, &_current_lift_position); + esp_zb_window_covering_cluster_add_attr(esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_ID, &_current_lift_position); + esp_zb_window_covering_cluster_add_attr( + esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_LIFT_ID, &_installed_open_limit_lift + ); + esp_zb_window_covering_cluster_add_attr( + esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_TILT_ID, &_installed_open_limit_tilt + ); + esp_zb_window_covering_cluster_add_attr( + esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_LIFT_ID, &_installed_closed_limit_lift + ); + esp_zb_window_covering_cluster_add_attr( + esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_TILT_ID, &_installed_closed_limit_tilt + ); + esp_zb_window_covering_cluster_add_attr( + esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_PHYSICAL_CLOSED_LIMIT_LIFT_ID, &_physical_closed_limit_lift + ); + esp_zb_window_covering_cluster_add_attr( + esp_zb_window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_PHY_CLOSED_LIMIT_TILT_ID, &_physical_closed_limit_lift + ); + + // ------------------------------ Create cluster list ------------------------------ + esp_zb_cluster_list_t *esp_zb_cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_cluster_list_add_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(esp_zb_cluster_list, esp_zb_identify_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_groups_cluster(esp_zb_cluster_list, esp_zb_groups_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_scenes_cluster(esp_zb_cluster_list, esp_zb_scenes_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_window_covering_cluster(esp_zb_cluster_list, esp_zb_window_covering_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + + return esp_zb_cluster_list; +} + +ZigbeeWindowCovering::ZigbeeWindowCovering(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_WINDOW_COVERING_DEVICE_ID; + + // set default values for window covering attributes + _current_lift_percentage = ESP_ZB_ZCL_WINDOW_COVERING_CURRENT_POSITION_LIFT_PERCENTAGE_DEFAULT_VALUE; + _current_tilt_percentage = ESP_ZB_ZCL_WINDOW_COVERING_CURRENT_POSITION_TILT_PERCENTAGE_DEFAULT_VALUE; + _installed_open_limit_lift = ESP_ZB_ZCL_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_LIFT_DEFAULT_VALUE; + _installed_closed_limit_lift = ESP_ZB_ZCL_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_LIFT_DEFAULT_VALUE; + _installed_open_limit_tilt = ESP_ZB_ZCL_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_TILT_DEFAULT_VALUE; + _installed_closed_limit_tilt = ESP_ZB_ZCL_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_TILT_DEFAULT_VALUE; + _current_lift_position = ESP_ZB_ZCL_WINDOW_COVERING_CURRENT_POSITION_LIFT_DEFAULT_VALUE; + _current_tilt_position = ESP_ZB_ZCL_WINDOW_COVERING_CURRENT_POSITION_TILT_DEFAULT_VALUE; + _physical_closed_limit_lift = ESP_ZB_ZCL_WINDOW_COVERING_PHYSICAL_CLOSED_LIMIT_LIFT_DEFAULT_VALUE; + _physical_closed_limit_tilt = ESP_ZB_ZCL_WINDOW_COVERING_PHY_CLOSED_LIMIT_TILT_DEFAULT_VALUE; + + // Create custom window covering configuration + zigbee_window_covering_cfg_t window_covering_cfg = ZIGBEE_DEFAULT_WINDOW_COVERING_CONFIG(); + _cluster_list = zigbee_window_covering_clusters_create(&window_covering_cfg); + + _ep_config = { + .endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_WINDOW_COVERING_DEVICE_ID, .app_device_version = 0 + }; +} + +// Configuration methods for window covering +void ZigbeeWindowCovering::setCoveringType(ZigbeeWindowCoveringType covering_type) { + esp_zb_attribute_list_t *window_covering_cluster = + esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_WINDOW_COVERING_TYPE_ID, (void *)&covering_type); +} + +void ZigbeeWindowCovering::setConfigStatus( + bool operational, bool online, bool commands_reversed, bool lift_closed_loop, bool tilt_closed_loop, bool lift_encoder_controlled, + bool tilt_encoder_controlled +) { + uint8_t config_status = (operational ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_OPERATIONAL : 0) | (online ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_ONLINE : 0) + | (commands_reversed ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_REVERSE_COMMANDS : 0) + | (lift_closed_loop ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_LIFT_CONTROL_IS_CLOSED_LOOP : 0) + | (tilt_closed_loop ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_TILT_CONTROL_IS_CLOSED_LOOP : 0) + | (lift_encoder_controlled ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_LIFT_ENCODER_CONTROLLED : 0) + | (tilt_encoder_controlled ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_TILT_ENCODER_CONTROLLED : 0); + + log_v("Updating window covering config status to %d", config_status); + + esp_zb_attribute_list_t *window_covering_cluster = + esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_STATUS_ID, (void *)&config_status); +} + +void ZigbeeWindowCovering::setMode(bool motor_reversed, bool calibration_mode, bool maintenance_mode, bool leds_on) { + uint8_t mode = (motor_reversed ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_REVERSED_MOTOR_DIRECTION : 0) + | (calibration_mode ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_RUN_IN_CALIBRATION_MODE : 0) + | (maintenance_mode ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_MOTOR_IS_RUNNING_IN_MAINTENANCE_MODE : 0) + | (leds_on ? ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_LEDS_WILL_DISPLAY_FEEDBACK : 0); + + log_v("Updating window covering mode to %d", mode); + + esp_zb_attribute_list_t *window_covering_cluster = + esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_MODE_ID, (void *)&mode); +} + +void ZigbeeWindowCovering::setLimits( + uint16_t installed_open_limit_lift, uint16_t installed_closed_limit_lift, uint16_t installed_open_limit_tilt, uint16_t installed_closed_limit_tilt +) { + _installed_open_limit_lift = installed_open_limit_lift; + _installed_closed_limit_lift = installed_closed_limit_lift; + _physical_closed_limit_lift = installed_closed_limit_lift; + _installed_open_limit_tilt = installed_open_limit_tilt; + _installed_closed_limit_tilt = installed_closed_limit_tilt; + _physical_closed_limit_tilt = installed_closed_limit_tilt; + + esp_zb_attribute_list_t *window_covering_cluster = + esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_LIFT_ID, (void *)&_installed_open_limit_lift); + esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_LIFT_ID, (void *)&_installed_closed_limit_lift); + esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_OPEN_LIMIT_TILT_ID, (void *)&_installed_open_limit_tilt); + esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_INSTALLED_CLOSED_LIMIT_TILT_ID, (void *)&_installed_closed_limit_tilt); + esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_PHYSICAL_CLOSED_LIMIT_LIFT_ID, (void *)&_physical_closed_limit_lift); + esp_zb_cluster_update_attr(window_covering_cluster, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_PHY_CLOSED_LIMIT_TILT_ID, (void *)&_physical_closed_limit_tilt); +} + +// Callback for handling incoming messages and commands +void ZigbeeWindowCovering::zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) { + //check the data and call right method + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING) { + log_v("Received attribute id: 0x%x / data.type: 0x%x", message->attribute.id, message->attribute.data.type); + if (message->attribute.id == ESP_ZB_ZCL_ATTR_WINDOW_COVERING_MODE_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_8BITMAP) { + uint8_t mode = *(uint8_t *)message->attribute.data.value; + bool motor_reversed = mode & ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_REVERSED_MOTOR_DIRECTION; + bool calibration_mode = mode & ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_RUN_IN_CALIBRATION_MODE; + bool maintenance_mode = mode & ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_MOTOR_IS_RUNNING_IN_MAINTENANCE_MODE; + bool leds_on = mode & ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_LEDS_WILL_DISPLAY_FEEDBACK; + log_v( + "Updating window covering mode to motor reversed: %d, calibration mode: %d, maintenance mode: %d, leds on: %d", motor_reversed, calibration_mode, + maintenance_mode, leds_on + ); + setMode(motor_reversed, calibration_mode, maintenance_mode, leds_on); + //Update Configuration status with motor reversed status + uint8_t config_status; + config_status = (*(uint8_t *)esp_zb_zcl_get_attribute( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_STATUS_ID + ) + ->data_p); + config_status = motor_reversed ? config_status | ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_REVERSE_COMMANDS + : config_status & ~ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_REVERSE_COMMANDS; + log_v("Updating window covering config status to %d", config_status); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CONFIG_STATUS_ID, &config_status, + false + ); + esp_zb_lock_release(); + return; + } + } else { + log_w("Received message ignored. Cluster ID: %d not supported for Window Covering", message->info.cluster); + } +} + +void ZigbeeWindowCovering::zbWindowCoveringMovementCmd(const esp_zb_zcl_window_covering_movement_message_t *message) { + // check the data and call right method + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING) { + if (message->command == ESP_ZB_ZCL_CMD_WINDOW_COVERING_UP_OPEN) { + open(); + return; + } else if (message->command == ESP_ZB_ZCL_CMD_WINDOW_COVERING_DOWN_CLOSE) { + close(); + return; + } else if (message->command == ESP_ZB_ZCL_CMD_WINDOW_COVERING_STOP) { + stop(); + return; + } else if (message->command == ESP_ZB_ZCL_CMD_WINDOW_COVERING_GO_TO_LIFT_PERCENTAGE) { + if (_current_lift_percentage != message->payload.percentage_lift_value) { + _current_lift_percentage = message->payload.percentage_lift_value; + goToLiftPercentage(_current_lift_percentage); + } + return; + } else if (message->command == ESP_ZB_ZCL_CMD_WINDOW_COVERING_GO_TO_TILT_PERCENTAGE) { + if (_current_tilt_percentage != message->payload.percentage_tilt_value) { + _current_tilt_percentage = message->payload.percentage_tilt_value; + goToTiltPercentage(_current_tilt_percentage); + } + } else { + log_w("Received message ignored. Command: %d not supported for Window Covering", message->command); + } + } else { + log_w("Received message ignored. Cluster ID: %d not supported for Window Covering", message->info.cluster); + } +} + +void ZigbeeWindowCovering::open() { + if (_on_open) { + _on_open(); + } +} + +void ZigbeeWindowCovering::close() { + if (_on_close) { + _on_close(); + } +} + +void ZigbeeWindowCovering::goToLiftPercentage(uint8_t lift_percentage) { + if (_on_go_to_lift_percentage) { + _on_go_to_lift_percentage(lift_percentage); + } +} + +void ZigbeeWindowCovering::goToTiltPercentage(uint8_t tilt_percentage) { + if (_on_go_to_tilt_percentage) { + _on_go_to_tilt_percentage(tilt_percentage); + } +} + +void ZigbeeWindowCovering::stop() { + if (_on_stop) { + _on_stop(); + } +} + +// Methods to control window covering from user application +void ZigbeeWindowCovering::setLiftPosition(uint16_t lift_position) { + // Update both lift attributes + _current_lift_position = lift_position; + _current_lift_percentage = ((lift_position - _installed_open_limit_lift) * 100) / (_installed_closed_limit_lift - _installed_open_limit_lift); + + log_v("Updating window covering lift position to %d (%d%)", _current_lift_position, _current_lift_percentage); + // set lift state + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_ID, + &_current_lift_position, false + ); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_PERCENTAGE_ID, + &_current_lift_percentage, false + ); + esp_zb_lock_release(); +} + +void ZigbeeWindowCovering::setLiftPercentage(uint8_t lift_percentage) { + // Update both lift attributes + _current_lift_percentage = lift_percentage; + _current_lift_position = _installed_open_limit_lift + ((_installed_closed_limit_lift - _installed_open_limit_lift) * lift_percentage) / 100; + + log_v("Updating window covering lift position to %d (%d%)", _current_lift_position, _current_lift_percentage); + // set lift state + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_ID, + &_current_lift_position, false + ); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_LIFT_PERCENTAGE_ID, + &_current_lift_percentage, false + ); + esp_zb_lock_release(); +} + +void ZigbeeWindowCovering::setTiltPosition(uint16_t tilt_position) { + // Update both tilt attributes + _current_tilt_position = tilt_position; + _current_tilt_percentage = ((tilt_position - _installed_open_limit_tilt) * 100) / (_installed_closed_limit_tilt - _installed_open_limit_tilt); + + log_v("Updating window covering tilt position to %d (%d%)", _current_tilt_position, _current_tilt_percentage); + // set lift state + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_ID, + &_current_tilt_position, false + ); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_PERCENTAGE_ID, + &_current_tilt_percentage, false + ); + esp_zb_lock_release(); +} + +void ZigbeeWindowCovering::setTiltPercentage(uint8_t tilt_percentage) { + // Update both tilt attributes + _current_tilt_percentage = tilt_percentage; + _current_tilt_position = _installed_open_limit_lift + ((_installed_closed_limit_tilt - _installed_open_limit_tilt) * tilt_percentage) / 100; + + log_v("Updating window covering tilt position to %d (%d%)", _current_tilt_position, _current_tilt_percentage); + // set lift state + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_ID, + &_current_tilt_position, false + ); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WINDOW_COVERING, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WINDOW_COVERING_CURRENT_POSITION_TILT_PERCENTAGE_ID, + &_current_tilt_percentage, false + ); + esp_zb_lock_release(); +} + +#endif // SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h new file mode 100644 index 00000000000..5cc2b13701a --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h @@ -0,0 +1,147 @@ +/* Class of Zigbee Window Covering endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +// Window covering types supported by Zigbee Window Covering cluster +enum ZigbeeWindowCoveringType { + ROLLERSHADE = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_ROLLERSHADE, // LIFT support + ROLLERSHADE_2_MOTOR = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_ROLLERSHADE_2_MOTOR, // LIFT support + ROLLERSHADE_EXTERIOR = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_ROLLERSHADE_EXTERIOR, // LIFT support + ROLLERSHADE_EXTERIOR_2_MOTOR = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_ROLLERSHADE_EXTERIOR_2_MOTOR, // LIFT support + DRAPERY = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_DRAPERY, // LIFT support + AWNING = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_AWNING, // LIFT support + SHUTTER = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_SHUTTER, // TILT support + BLIND_TILT_ONLY = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_TILT_BLIND_TILT_ONLY, // TILT support + BLIND_LIFT_AND_TILT = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_TILT_BLIND_LIFT_AND_TILT, // LIFT and TILT support + PROJECTOR_SCREEN = ESP_ZB_ZCL_ATTR_WINDOW_COVERING_TYPE_PROJECTOR_SCREEN, // LIFT support +}; + +// clang-format off +#define ZIGBEE_DEFAULT_WINDOW_COVERING_CONFIG() \ + { \ + .basic_cfg = \ + { \ + .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE, \ + .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE, \ + }, \ + .identify_cfg = \ + { \ + .identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, \ + }, \ + .groups_cfg = \ + { \ + .groups_name_support_id = ESP_ZB_ZCL_GROUPS_NAME_SUPPORT_DEFAULT_VALUE, \ + }, \ + .scenes_cfg = \ + { \ + .scenes_count = ESP_ZB_ZCL_SCENES_SCENE_COUNT_DEFAULT_VALUE, \ + .current_scene = ESP_ZB_ZCL_SCENES_CURRENT_SCENE_DEFAULT_VALUE, \ + .current_group = ESP_ZB_ZCL_SCENES_CURRENT_GROUP_DEFAULT_VALUE, \ + .scene_valid = ESP_ZB_ZCL_SCENES_SCENE_VALID_DEFAULT_VALUE, \ + .name_support = ESP_ZB_ZCL_SCENES_NAME_SUPPORT_DEFAULT_VALUE, \ + }, \ + .window_covering_cfg = \ + { \ + .covering_type = ESP_ZB_ZCL_WINDOW_COVERING_WINDOW_COVERING_TYPE_DEFAULT_VALUE, \ + .covering_status = ESP_ZB_ZCL_WINDOW_COVERING_CONFIG_STATUS_DEFAULT_VALUE, \ + .covering_mode = ESP_ZB_ZCL_WINDOW_COVERING_MODE_DEFAULT_VALUE, \ + }, \ + } +// clang-format on + +typedef struct zigbee_window_covering_cfg_s { + esp_zb_basic_cluster_cfg_t basic_cfg; + esp_zb_identify_cluster_cfg_t identify_cfg; + esp_zb_groups_cluster_cfg_t groups_cfg; + esp_zb_scenes_cluster_cfg_t scenes_cfg; + esp_zb_window_covering_cluster_cfg_t window_covering_cfg; +} zigbee_window_covering_cfg_t; + +class ZigbeeWindowCovering : public ZigbeeEP { +public: + ZigbeeWindowCovering(uint8_t endpoint); + ~ZigbeeWindowCovering(); + + // Set the callback functions for the window covering commands + void onOpen(void (*callback)()) { + _on_open = callback; + } + void onClose(void (*callback)()) { + _on_close = callback; + } + void onGoToLiftPercentage(void (*callback)(uint8_t)) { + _on_go_to_lift_percentage = callback; + } + void onGoToTiltPercentage(void (*callback)(uint8_t)) { + _on_go_to_tilt_percentage = callback; + } + void onStop(void (*callback)()) { + _on_stop = callback; + } + + // Set the window covering position in centimeters or percentage (0-100) + void setLiftPosition(uint16_t lift_position); + void setLiftPercentage(uint8_t lift_percentage); + void setTiltPosition(uint16_t tilt_position); + void setTiltPercentage(uint8_t tilt_percentage); + + // Set the window covering type (see ZigbeeWindowCoveringType) + void setCoveringType(ZigbeeWindowCoveringType covering_type); + + // Set window covering config/status, for more info see esp_zb_zcl_window_covering_config_status_t + void setConfigStatus( + bool operational, bool online, bool commands_reversed, bool lift_closed_loop, bool tilt_closed_loop, bool lift_encoder_controlled, + bool tilt_encoder_controlled + ); + + // Set configuration mode of window covering, for more info see esp_zb_zcl_window_covering_mode_t + void setMode(bool motor_reversed, bool calibration_mode, bool maintenance_mode, bool leds_on); + + // Set limits of motion, for more info see esp_zb_zcl_window_covering_info_attr_t + void setLimits( + uint16_t installed_open_limit_lift, uint16_t installed_closed_limit_lift, uint16_t installed_open_limit_tilt, uint16_t installed_closed_limit_tilt + ); + +private: + void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override; + void zbWindowCoveringMovementCmd(const esp_zb_zcl_window_covering_movement_message_t *message) override; + + // Create window covering cluster list + esp_zb_cluster_list_t *zigbee_window_covering_clusters_create(zigbee_window_covering_cfg_t *window_covering_cfg); + + void open(); + void close(); + void goToLiftPercentage(uint8_t); + void goToTiltPercentage(uint8_t); + void stop(); + + // callback function to be called on lift percentage change (lift percentage) + void (*_on_open)(); + void (*_on_close)(); + void (*_on_go_to_lift_percentage)(uint8_t); + void (*_on_go_to_tilt_percentage)(uint8_t); + void (*_on_stop)(); + + // Widows covering lift attributes + uint8_t _current_lift_percentage; + uint16_t _current_lift_position; + uint16_t _installed_open_limit_lift; + uint16_t _installed_closed_limit_lift; + uint16_t _physical_closed_limit_lift; + + // Windows covering tilt attributes + uint8_t _current_tilt_percentage; + uint16_t _current_tilt_position; + uint16_t _installed_open_limit_tilt; + uint16_t _installed_closed_limit_tilt; + uint16_t _physical_closed_limit_tilt; +}; + +#endif // SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED From 6fcaf690970401e63e75609628663b862a928b68 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Thu, 6 Feb 2025 11:19:27 +0200 Subject: [PATCH 16/79] fix(wifi): Make sure that esp-hosted events are propagated (#10939) --- libraries/Network/src/NetworkInterface.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/Network/src/NetworkInterface.cpp b/libraries/Network/src/NetworkInterface.cpp index 4f310821204..01790ec2493 100644 --- a/libraries/Network/src/NetworkInterface.cpp +++ b/libraries/Network/src/NetworkInterface.cpp @@ -81,7 +81,7 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void *event_data) { ); #endif memcpy(&arduino_event.event_info.got_ip, event_data, sizeof(ip_event_got_ip_t)); -#if SOC_WIFI_SUPPORTED +#if SOC_WIFI_SUPPORTED || CONFIG_ESP_WIFI_REMOTE_ENABLED if (_interface_id == ESP_NETIF_ID_STA) { arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP; } else @@ -96,7 +96,7 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void *event_data) { #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE log_v("%s Lost IP", desc()); #endif -#if SOC_WIFI_SUPPORTED +#if SOC_WIFI_SUPPORTED || CONFIG_ESP_WIFI_REMOTE_ENABLED if (_interface_id == ESP_NETIF_ID_STA) { arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_LOST_IP; } else @@ -123,7 +123,7 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void *event_data) { ); #endif memcpy(&arduino_event.event_info.got_ip6, event_data, sizeof(ip_event_got_ip6_t)); -#if SOC_WIFI_SUPPORTED +#if SOC_WIFI_SUPPORTED || CONFIG_ESP_WIFI_REMOTE_ENABLED if (_interface_id == ESP_NETIF_ID_STA) { arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_GOT_IP6; } else if (_interface_id == ESP_NETIF_ID_AP) { @@ -136,7 +136,7 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void *event_data) { arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP6; } #endif /* CONFIG_LWIP_IPV6 */ -#if SOC_WIFI_SUPPORTED +#if SOC_WIFI_SUPPORTED || CONFIG_ESP_WIFI_REMOTE_ENABLED } else if (event_id == IP_EVENT_AP_STAIPASSIGNED && _interface_id == ESP_NETIF_ID_AP) { setStatusBits(ESP_NETIF_HAS_IP_BIT); #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE From 5ba4c21a990f46b61ae8c7913b81e15064b2a8ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:06:07 +0100 Subject: [PATCH 17/79] fix(zigbee): Add default destructor and fix initialization of tm struct (#10943) --- libraries/Zigbee/src/ZigbeeEP.h | 2 +- libraries/Zigbee/src/ep/ZigbeeWindowCovering.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index fce0500ef0d..584873f50dd 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -95,7 +95,7 @@ class ZigbeeEP { void reportBatteryPercentage(); // Set time - void addTimeCluster(tm time = {0}, int32_t gmt_offset = 0); // gmt offset in seconds + void addTimeCluster(tm time = {}, int32_t gmt_offset = 0); // gmt offset in seconds void setTime(tm time); void setTimezone(int32_t gmt_offset); diff --git a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h index 5cc2b13701a..08e0a35f737 100644 --- a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h +++ b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h @@ -67,7 +67,7 @@ typedef struct zigbee_window_covering_cfg_s { class ZigbeeWindowCovering : public ZigbeeEP { public: ZigbeeWindowCovering(uint8_t endpoint); - ~ZigbeeWindowCovering(); + ~ZigbeeWindowCovering() {} // Set the callback functions for the window covering commands void onOpen(void (*callback)()) { From 250c1abf781eba8cec7a524090939c30e05b690c Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 12 Feb 2025 10:40:15 +0200 Subject: [PATCH 18/79] fix(i2s): Add missing initializer for I2S CLK config (#10963) * fix(i2s): Add missing initializer for I2S CLK config * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- libraries/ESP_I2S/src/ESP_I2S.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/ESP_I2S/src/ESP_I2S.cpp b/libraries/ESP_I2S/src/ESP_I2S.cpp index d0ceb0c4b4c..6bf8089e48a 100644 --- a/libraries/ESP_I2S/src/ESP_I2S.cpp +++ b/libraries/ESP_I2S/src/ESP_I2S.cpp @@ -11,6 +11,12 @@ #include "mp3dec.h" #endif +#if SOC_I2S_HW_VERSION_2 +#undef I2S_STD_CLK_DEFAULT_CONFIG +#define I2S_STD_CLK_DEFAULT_CONFIG(rate) \ + { .sample_rate_hz = rate, .clk_src = I2S_CLK_SRC_DEFAULT, .ext_clk_freq_hz = 0, .mclk_multiple = I2S_MCLK_MULTIPLE_256, } +#endif + #define I2S_READ_CHUNK_SIZE 1920 #define I2S_DEFAULT_CFG() \ From 7b651b64d61ccd513480305f60fae877b26f764f Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Thu, 13 Feb 2025 12:51:28 +0200 Subject: [PATCH 19/79] feat(cdc): Add support for two CDC ports at once (#10962) * feat(cdc): Add support for two CDC ports at once * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- cores/esp32/USBCDC.cpp | 68 ++++++++++++++++++++++++--------- cores/esp32/esp32-hal-tinyusb.c | 24 ++++++------ cores/esp32/esp32-hal-tinyusb.h | 8 ++++ 3 files changed, 72 insertions(+), 28 deletions(-) diff --git a/cores/esp32/USBCDC.cpp b/cores/esp32/USBCDC.cpp index 795a17dc0b8..945021a79e2 100644 --- a/cores/esp32/USBCDC.cpp +++ b/cores/esp32/USBCDC.cpp @@ -25,8 +25,7 @@ ESP_EVENT_DEFINE_BASE(ARDUINO_USB_CDC_EVENTS); esp_err_t arduino_usb_event_post(esp_event_base_t event_base, int32_t event_id, void *event_data, size_t event_data_size, TickType_t ticks_to_wait); esp_err_t arduino_usb_event_handler_register_with(esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler, void *event_handler_arg); -#define MAX_USB_CDC_DEVICES 2 -USBCDC *devices[MAX_USB_CDC_DEVICES] = {NULL, NULL}; +USBCDC *devices[CFG_TUD_CDC]; static uint16_t load_cdc_descriptor(uint8_t *dst, uint8_t *itf) { uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB CDC"); @@ -38,23 +37,43 @@ static uint16_t load_cdc_descriptor(uint8_t *dst, uint8_t *itf) { return TUD_CDC_DESC_LEN; } +static uint16_t load_cdc_descriptor2(uint8_t *dst, uint8_t *itf) { + uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB CDC2"); + uint8_t ep_ntfy = tinyusb_get_free_in_endpoint(); + TU_VERIFY(ep_ntfy != 0); + uint8_t ep_in = tinyusb_get_free_in_endpoint(); + TU_VERIFY(ep_in != 0); + uint8_t ep_out = tinyusb_get_free_out_endpoint(); + TU_VERIFY(ep_out != 0); + uint8_t descriptor[TUD_CDC_DESC_LEN] = { + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. + TUD_CDC_DESCRIPTOR(*itf, str_index, (uint8_t)(0x80 | ep_ntfy), CFG_TUD_ENDOINT_SIZE, ep_out, (uint8_t)(0x80 | ep_in), CFG_TUD_ENDOINT_SIZE) + }; + *itf += 2; + memcpy(dst, descriptor, TUD_CDC_DESC_LEN); + return TUD_CDC_DESC_LEN; +} + // Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { - if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL) { + //log_v("ITF: %u, DTR: %u, RTS: %u", itf, dtr, rts); + if (itf < CFG_TUD_CDC && devices[itf] != NULL) { devices[itf]->_onLineState(dtr, rts); } } // Invoked when line coding is change via SET_LINE_CODING void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const *p_line_coding) { - if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL) { + //log_v("ITF: %u, BITRATE: %lu, STOP_BITS: %u, PARITY: %u, DATA_BITS: %u", itf, p_line_coding->bit_rate, p_line_coding->stop_bits, p_line_coding->parity, p_line_coding->data_bits); + if (itf < CFG_TUD_CDC && devices[itf] != NULL) { devices[itf]->_onLineCoding(p_line_coding->bit_rate, p_line_coding->stop_bits, p_line_coding->parity, p_line_coding->data_bits); } } // Invoked when received new data void tud_cdc_rx_cb(uint8_t itf) { - if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL) { + //log_v("ITF: %u", itf); + if (itf < CFG_TUD_CDC && devices[itf] != NULL) { devices[itf]->_onRX(); } } @@ -66,13 +85,13 @@ void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { // Invoked when space becomes available in TX buffer void tud_cdc_tx_complete_cb(uint8_t itf) { - if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL) { + if (itf < CFG_TUD_CDC && devices[itf] != NULL) { devices[itf]->_onTX(); } } static void ARDUINO_ISR_ATTR cdc0_write_char(char c) { - if (devices[0] != NULL) { + if (CFG_TUD_CDC && devices[0] != NULL) { tud_cdc_n_write_char(0, c); } } @@ -84,9 +103,15 @@ static void usb_unplugged_cb(void *arg, esp_event_base_t event_base, int32_t eve USBCDC::USBCDC(uint8_t itfn) : itf(itfn), bit_rate(0), stop_bits(0), parity(0), data_bits(0), dtr(false), rts(false), connected(false), reboot_enable(true), rx_queue(NULL), tx_lock(NULL), tx_timeout_ms(250) { - tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor); - if (itf < MAX_USB_CDC_DEVICES) { + if (itf < CFG_TUD_CDC) { + if (itf == 0) { + tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor); + } else { + tinyusb_enable_interface(USB_INTERFACE_CDC2, TUD_CDC_DESC_LEN, load_cdc_descriptor2); + } arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this); + } else { + log_e("Maximum of %u CDC devices are supported", CFG_TUD_CDC); } } @@ -142,6 +167,9 @@ size_t USBCDC::setRxBufferSize(size_t rx_queue_len) { } void USBCDC::begin(unsigned long baud) { + if (itf >= CFG_TUD_CDC) { + return; + } if (tx_lock == NULL) { tx_lock = xSemaphoreCreateMutex(); } @@ -153,6 +181,9 @@ void USBCDC::begin(unsigned long baud) { } void USBCDC::end() { + if (itf >= CFG_TUD_CDC) { + return; + } connected = false; devices[itf] = NULL; setRxBufferSize(0); @@ -298,14 +329,14 @@ bool USBCDC::rebootEnabled(void) { } int USBCDC::available(void) { - if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL) { + if (itf >= CFG_TUD_CDC || rx_queue == NULL) { return -1; } return uxQueueMessagesWaiting(rx_queue); } int USBCDC::peek(void) { - if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL) { + if (itf >= CFG_TUD_CDC || rx_queue == NULL) { return -1; } uint8_t c; @@ -316,7 +347,7 @@ int USBCDC::peek(void) { } int USBCDC::read(void) { - if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL) { + if (itf >= CFG_TUD_CDC || rx_queue == NULL) { return -1; } uint8_t c = 0; @@ -327,7 +358,7 @@ int USBCDC::read(void) { } size_t USBCDC::read(uint8_t *buffer, size_t size) { - if (itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL) { + if (itf >= CFG_TUD_CDC || rx_queue == NULL) { return -1; } uint8_t c = 0; @@ -339,7 +370,7 @@ size_t USBCDC::read(uint8_t *buffer, size_t size) { } void USBCDC::flush(void) { - if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected(itf)) { + if (itf >= CFG_TUD_CDC || tx_lock == NULL || !tud_cdc_n_connected(itf)) { return; } if (xSemaphoreTake(tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS) { @@ -350,7 +381,7 @@ void USBCDC::flush(void) { } int USBCDC::availableForWrite(void) { - if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected(itf)) { + if (itf >= CFG_TUD_CDC || tx_lock == NULL || !tud_cdc_n_connected(itf)) { return 0; } if (xSemaphoreTake(tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS) { @@ -362,7 +393,7 @@ int USBCDC::availableForWrite(void) { } size_t USBCDC::write(const uint8_t *buffer, size_t size) { - if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || buffer == NULL || size == 0 || !tud_cdc_n_connected(itf)) { + if (itf >= CFG_TUD_CDC || tx_lock == NULL || buffer == NULL || size == 0 || !tud_cdc_n_connected(itf)) { return 0; } if (xPortInIsrContext()) { @@ -415,6 +446,9 @@ uint32_t USBCDC::baudRate() { } void USBCDC::setDebugOutput(bool en) { + if (itf) { + return; + } if (en) { uartSetDebug(NULL); ets_install_putc2((void (*)(char)) & cdc0_write_char); @@ -424,7 +458,7 @@ void USBCDC::setDebugOutput(bool en) { } USBCDC::operator bool() const { - if (itf >= MAX_USB_CDC_DEVICES) { + if (itf >= CFG_TUD_CDC) { return false; } return connected; diff --git a/cores/esp32/esp32-hal-tinyusb.c b/cores/esp32/esp32-hal-tinyusb.c index f83e8b61bd2..0991e08d27f 100644 --- a/cores/esp32/esp32-hal-tinyusb.c +++ b/cores/esp32/esp32-hal-tinyusb.c @@ -616,7 +616,7 @@ void usb_persist_restart(restart_type_t mode) { } static bool tinyusb_reserve_in_endpoint(uint8_t endpoint) { - if (endpoint > 6 || (tinyusb_endpoints.in & BIT(endpoint)) != 0) { + if (endpoint > CFG_TUD_NUM_EPS || (tinyusb_endpoints.in & BIT(endpoint)) != 0) { return false; } tinyusb_endpoints.in |= BIT(endpoint); @@ -624,7 +624,7 @@ static bool tinyusb_reserve_in_endpoint(uint8_t endpoint) { } static bool tinyusb_reserve_out_endpoint(uint8_t endpoint) { - if (endpoint > 6 || (tinyusb_endpoints.out & BIT(endpoint)) != 0) { + if (endpoint > CFG_TUD_NUM_EPS || (tinyusb_endpoints.out & BIT(endpoint)) != 0) { return false; } tinyusb_endpoints.out |= BIT(endpoint); @@ -632,11 +632,13 @@ static bool tinyusb_reserve_out_endpoint(uint8_t endpoint) { } static bool tinyusb_has_available_fifos(void) { - uint8_t max_endpoints = 4, active_endpoints = 0; + uint8_t max_endpoints = CFG_TUD_NUM_IN_EPS - 1, active_endpoints = 0; +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 if (tinyusb_loaded_interfaces_mask & BIT(USB_INTERFACE_CDC)) { - max_endpoints = 5; //CDC endpoint 0x85 is actually not linked to FIFO and not used + max_endpoints = CFG_TUD_NUM_IN_EPS; //CDC endpoint 0x85 is actually not linked to FIFO and not used } - for (uint8_t i = 1; i < 7; i++) { +#endif + for (uint8_t i = 1; i <= CFG_TUD_NUM_EPS; i++) { if ((tinyusb_endpoints.in & BIT(i)) != 0) { active_endpoints++; } @@ -771,7 +773,7 @@ static void usb_device_task(void *param) { * PUBLIC API * */ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR -const char *tinyusb_interface_names[USB_INTERFACE_MAX] = {"MSC", "DFU", "HID", "VENDOR", "CDC", "MIDI", "CUSTOM"}; +const char *tinyusb_interface_names[USB_INTERFACE_MAX] = {"MSC", "DFU", "HID", "VENDOR", "CDC", "CDC2", "MIDI", "CUSTOM"}; #endif static bool tinyusb_is_initialized = false; @@ -862,7 +864,7 @@ uint8_t tinyusb_get_free_duplex_endpoint(void) { log_e("No available IN endpoints"); return 0; } - for (uint8_t i = 1; i < 7; i++) { + for (uint8_t i = 1; i <= CFG_TUD_NUM_IN_EPS; i++) { if ((tinyusb_endpoints.in & BIT(i)) == 0 && (tinyusb_endpoints.out & BIT(i)) == 0) { tinyusb_endpoints.in |= BIT(i); tinyusb_endpoints.out |= BIT(i); @@ -878,13 +880,13 @@ uint8_t tinyusb_get_free_in_endpoint(void) { log_e("No available IN endpoints"); return 0; } - for (uint8_t i = 1; i < 7; i++) { + for (uint8_t i = 1; i <= CFG_TUD_NUM_IN_EPS; i++) { if ((tinyusb_endpoints.in & BIT(i)) == 0 && (tinyusb_endpoints.out & BIT(i)) != 0) { tinyusb_endpoints.in |= BIT(i); return i; } } - for (uint8_t i = 1; i < 7; i++) { + for (uint8_t i = 1; i <= CFG_TUD_NUM_IN_EPS; i++) { if ((tinyusb_endpoints.in & BIT(i)) == 0) { tinyusb_endpoints.in |= BIT(i); return i; @@ -894,13 +896,13 @@ uint8_t tinyusb_get_free_in_endpoint(void) { } uint8_t tinyusb_get_free_out_endpoint(void) { - for (uint8_t i = 1; i < 7; i++) { + for (uint8_t i = 1; i <= CFG_TUD_NUM_EPS; i++) { if ((tinyusb_endpoints.out & BIT(i)) == 0 && (tinyusb_endpoints.in & BIT(i)) != 0) { tinyusb_endpoints.out |= BIT(i); return i; } } - for (uint8_t i = 1; i < 7; i++) { + for (uint8_t i = 1; i <= CFG_TUD_NUM_EPS; i++) { if ((tinyusb_endpoints.out & BIT(i)) == 0) { tinyusb_endpoints.out |= BIT(i); return i; diff --git a/cores/esp32/esp32-hal-tinyusb.h b/cores/esp32/esp32-hal-tinyusb.h index 0b42760e69f..73210c4872b 100644 --- a/cores/esp32/esp32-hal-tinyusb.h +++ b/cores/esp32/esp32-hal-tinyusb.h @@ -38,6 +38,13 @@ extern "C" { #define CFG_TUD_ENDOINT_SIZE 64 #endif #endif +#if CONFIG_IDF_TARGET_ESP32P4 +#define CFG_TUD_NUM_EPS 15 +#define CFG_TUD_NUM_IN_EPS 8 +#else +#define CFG_TUD_NUM_EPS 6 +#define CFG_TUD_NUM_IN_EPS 5 +#endif typedef struct { uint16_t vid; @@ -88,6 +95,7 @@ typedef enum { USB_INTERFACE_HID, USB_INTERFACE_VENDOR, USB_INTERFACE_CDC, + USB_INTERFACE_CDC2, USB_INTERFACE_MIDI, USB_INTERFACE_CUSTOM, USB_INTERFACE_MAX From 6c3a49cac7815a160fe70da07bac66e56b6ef547 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 13:01:13 +0200 Subject: [PATCH 20/79] build(deps): bump cryptography from 43.0.1 to 44.0.1 in /tests (#10961) Bumps [cryptography](https://github.com/pyca/cryptography) from 43.0.1 to 44.0.1. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/43.0.1...44.0.1) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tests/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/requirements.txt b/tests/requirements.txt index cef0bf17881..c98c032a3ae 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,4 +1,4 @@ -cryptography==43.0.1 +cryptography==44.0.1 --only-binary cryptography pytest-cov==5.0.0 pytest-embedded-serial-esp==1.12.0 From 83abca1604d6118269f04228f57e93f493241e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 13 Feb 2025 12:02:35 +0100 Subject: [PATCH 21/79] feat(zigbee): Add OTA client cluster support (#10946) * feat(zigbee): Add OTA client cluster support * feat(zigbee): Add conditions to reject OTA upgrade * feat(zigbee): Add newest version of OTA handler * fix(zigbee): Fix errors and warnings, swap parameters order * feat(zigbee): Add simple OTA Client example * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- .../examples/Zigbee_OTA_Client/README.md | 68 ++++++ .../Zigbee_OTA_Client/Zigbee_OTA_Client.ino | 112 ++++++++++ .../Zigbee/examples/Zigbee_OTA_Client/ci.json | 6 + libraries/Zigbee/src/ZigbeeEP.cpp | 68 ++++++ libraries/Zigbee/src/ZigbeeEP.h | 23 +- libraries/Zigbee/src/ZigbeeHandlers.cpp | 205 ++++++++++++++++-- 6 files changed, 465 insertions(+), 17 deletions(-) create mode 100644 libraries/Zigbee/examples/Zigbee_OTA_Client/README.md create mode 100644 libraries/Zigbee/examples/Zigbee_OTA_Client/Zigbee_OTA_Client.ino create mode 100644 libraries/Zigbee/examples/Zigbee_OTA_Client/ci.json diff --git a/libraries/Zigbee/examples/Zigbee_OTA_Client/README.md b/libraries/Zigbee/examples/Zigbee_OTA_Client/README.md new file mode 100644 index 00000000000..143ff946f28 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_OTA_Client/README.md @@ -0,0 +1,68 @@ +# Arduino-ESP32 Zigbee OTA Client + on/off light Example + +This example shows how to configure the Zigbee end device with OTA Client and use it as a Home Automation (HA) on/off light. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Hardware Required + +* A USB cable for power supply and programming + +### Configure the Project + +Set the LED GPIO by changing the `LED_PIN` definition. By default, the LED_PIN is `RGB_BUILTIN`. +By default, the `rgbLedWrite` function is used to control the LED. You can change it to digitalWrite to control a simple LED. + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ED (end device)` +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs` +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. +* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. + +## Troubleshooting + +If the End device flashed with this example is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. It is recommended to do this if you re-flash the coordinator. +You can do the following: + +* In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. +* Add to the sketch `Zigbee.factoryReset();` to reset the device and Zigbee stack. + +By default, the coordinator network is closed after rebooting or flashing new firmware. +To open the network you have 2 options: + +* Open network after reboot by setting `Zigbee.setRebootOpenNetwork(time);` before calling `Zigbee.begin();`. +* In application you can anytime call `Zigbee.openNetwork(time);` to open the network for devices to join. + + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/Zigbee/examples/Zigbee_OTA_Client/Zigbee_OTA_Client.ino b/libraries/Zigbee/examples/Zigbee_OTA_Client/Zigbee_OTA_Client.ino new file mode 100644 index 00000000000..29d114014b4 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_OTA_Client/Zigbee_OTA_Client.ino @@ -0,0 +1,112 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +/** + * @brief This example demonstrates OTA support on light bulb. + * + * The example demonstrates how to use Zigbee library to create a end device light bulb with OTA support. + * The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ED +#error "Zigbee end device mode is not selected in Tools->Zigbee mode" +#endif + +#include "Zigbee.h" + +/* Zigbee light bulb configuration */ +#define ZIGBEE_LIGHT_ENDPOINT 1 +uint8_t led = RGB_BUILTIN; +uint8_t button = BOOT_PIN; + +/* Zigbee OTA configuration */ +#define OTA_UPGRADE_RUNNING_FILE_VERSION 0x01010100 // Increment this value when the running image is updated +#define OTA_UPGRADE_DOWNLOADED_FILE_VERSION 0x01010101 // Increment this value when the downloaded image is updated +#define OTA_UPGRADE_HW_VERSION 0x0101 // The hardware version, this can be used to differentiate between different hardware versions + +ZigbeeLight zbLight = ZigbeeLight(ZIGBEE_LIGHT_ENDPOINT); + +/********************* RGB LED functions **************************/ +void setLED(bool value) { + digitalWrite(led, value); +} + +/********************* Arduino functions **************************/ +void setup() { + Serial.begin(115200); + + // Init LED and turn it OFF (if LED_PIN == RGB_BUILTIN, the rgbLedWrite() will be used under the hood) + pinMode(led, OUTPUT); + digitalWrite(led, LOW); + + // Init button for factory reset + pinMode(button, INPUT_PULLUP); + + // Optional: set Zigbee device name and model + zbLight.setManufacturerAndModel("Espressif", "ZBLightBulb"); + + // Set callback function for light change + zbLight.onLightChange(setLED); + + // Add OTA client to the light bulb + zbLight.addOTAClient(OTA_UPGRADE_RUNNING_FILE_VERSION, OTA_UPGRADE_DOWNLOADED_FILE_VERSION, OTA_UPGRADE_HW_VERSION); + + // Add endpoint to Zigbee Core + Serial.println("Adding ZigbeeLight endpoint to Zigbee Core"); + Zigbee.addEndpoint(&zbLight); + + // When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE + if (!Zigbee.begin()) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // Start Zigbee OTA client query, first request is within a minute and the next requests are sent every hour automatically + zbLight.requestOTAUpdate(); +} + +void loop() { + // Checking button for factory reset + if (digitalRead(button) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(button) == LOW) { + delay(50); + if ((millis() - startTime) > 3000) { + // If key pressed for more than 3secs, factory reset Zigbee and reboot + Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + delay(1000); + Zigbee.factoryReset(); + } + } + // Toggle light by pressing the button + zbLight.setLight(!zbLight.getLightState()); + } + delay(100); +} diff --git a/libraries/Zigbee/examples/Zigbee_OTA_Client/ci.json b/libraries/Zigbee/examples/Zigbee_OTA_Client/ci.json new file mode 100644 index 00000000000..7b7ccef8ed7 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_OTA_Client/ci.json @@ -0,0 +1,6 @@ +{ + "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", + "requires": [ + "CONFIG_SOC_IEEE802154_SUPPORTED=y" + ] +} diff --git a/libraries/Zigbee/src/ZigbeeEP.cpp b/libraries/Zigbee/src/ZigbeeEP.cpp index 6a2ace0b90c..f3f890393eb 100644 --- a/libraries/Zigbee/src/ZigbeeEP.cpp +++ b/libraries/Zigbee/src/ZigbeeEP.cpp @@ -363,4 +363,72 @@ void ZigbeeEP::zbReadTimeCluster(const esp_zb_zcl_attribute_t *attribute) { } } +// typedef struct esp_zb_ota_cluster_cfg_s { +// uint32_t ota_upgrade_file_version; /*!< The attribute indicates the file version of the running firmware image on the device */ +// uint16_t ota_upgrade_manufacturer; /*!< The attribute indicates the value for the manufacturer of the device */ +// uint16_t ota_upgrade_image_type; /*!< The attribute indicates the the image type of the file that the client is currently downloading */ +// uint32_t ota_upgrade_downloaded_file_ver; /*!< The attribute indicates the file version of the downloaded image on the device*/ +// esp_zb_ota_cluster_cfg_t; + +// typedef struct esp_zb_zcl_ota_upgrade_client_variable_s { +// uint16_t timer_query; /*!< The field indicates the time of querying OTA image for OTA upgrade client */ +// uint16_t hw_version; /*!< The hardware version */ +// uint8_t max_data_size; /*!< The maximum size of OTA data */ +// } esp_zb_zcl_ota_upgrade_client_variable_t; + +void ZigbeeEP::addOTAClient( + uint32_t file_version, uint32_t downloaded_file_ver, uint16_t hw_version, uint16_t manufacturer, uint16_t image_type, uint8_t max_data_size +) { + + esp_zb_ota_cluster_cfg_t ota_cluster_cfg = {}; + ota_cluster_cfg.ota_upgrade_file_version = file_version; //OTA_UPGRADE_RUNNING_FILE_VERSION; + ota_cluster_cfg.ota_upgrade_downloaded_file_ver = downloaded_file_ver; //OTA_UPGRADE_DOWNLOADED_FILE_VERSION; + ota_cluster_cfg.ota_upgrade_manufacturer = manufacturer; //OTA_UPGRADE_MANUFACTURER; + ota_cluster_cfg.ota_upgrade_image_type = image_type; //OTA_UPGRADE_IMAGE_TYPE; + + esp_zb_attribute_list_t *ota_cluster = esp_zb_ota_cluster_create(&ota_cluster_cfg); + + esp_zb_zcl_ota_upgrade_client_variable_t variable_config = {}; + variable_config.timer_query = ESP_ZB_ZCL_OTA_UPGRADE_QUERY_TIMER_COUNT_DEF; + variable_config.hw_version = hw_version; //OTA_UPGRADE_HW_VERSION; + variable_config.max_data_size = max_data_size; //OTA_UPGRADE_MAX_DATA_SIZE; + + uint16_t ota_upgrade_server_addr = 0xffff; + uint8_t ota_upgrade_server_ep = 0xff; + + ESP_ERROR_CHECK(esp_zb_ota_cluster_add_attr(ota_cluster, ESP_ZB_ZCL_ATTR_OTA_UPGRADE_CLIENT_DATA_ID, (void *)&variable_config)); + ESP_ERROR_CHECK(esp_zb_ota_cluster_add_attr(ota_cluster, ESP_ZB_ZCL_ATTR_OTA_UPGRADE_SERVER_ADDR_ID, (void *)&ota_upgrade_server_addr)); + ESP_ERROR_CHECK(esp_zb_ota_cluster_add_attr(ota_cluster, ESP_ZB_ZCL_ATTR_OTA_UPGRADE_SERVER_ENDPOINT_ID, (void *)&ota_upgrade_server_ep)); + + ESP_ERROR_CHECK(esp_zb_cluster_list_add_ota_cluster(_cluster_list, ota_cluster, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE)); +} + +static void findOTAServer(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx) { + if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { + esp_zb_ota_upgrade_client_query_interval_set(*((uint8_t *)user_ctx), OTA_UPGRADE_QUERY_INTERVAL); + esp_zb_ota_upgrade_client_query_image_req(addr, endpoint); + log_i("Query OTA upgrade from server endpoint: %d after %d seconds", endpoint, OTA_UPGRADE_QUERY_INTERVAL); + } else { + log_w("No OTA Server found"); + } +} + +void ZigbeeEP::requestOTAUpdate() { + esp_zb_zdo_match_desc_req_param_t req; + uint16_t cluster_list[] = {ESP_ZB_ZCL_CLUSTER_ID_OTA_UPGRADE}; + + /* Match the OTA server of coordinator */ + req.addr_of_interest = 0x0000; + req.dst_nwk_addr = 0x0000; + req.num_in_clusters = 1; + req.num_out_clusters = 0; + req.profile_id = ESP_ZB_AF_HA_PROFILE_ID; + req.cluster_list = cluster_list; + esp_zb_lock_acquire(portMAX_DELAY); + if (esp_zb_bdb_dev_joined()) { + esp_zb_zdo_match_cluster(&req, findOTAServer, &_endpoint); + } + esp_zb_lock_release(); +} + #endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index 584873f50dd..72cde275293 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -8,7 +8,8 @@ #include /* Useful defines */ -#define ZB_CMD_TIMEOUT 10000 // 10 seconds +#define ZB_CMD_TIMEOUT 10000 // 10 seconds +#define OTA_UPGRADE_QUERY_INTERVAL (1 * 60) // 1 hour = 60 minutes #define ZB_ARRAY_LENTH(arr) (sizeof(arr) / sizeof(arr[0])) #define XYZ_TO_RGB(X, Y, Z, r, g, b) \ @@ -107,6 +108,26 @@ class ZigbeeEP { return _allow_multiple_binding; } + // OTA methods + /** + * @brief Add OTA client to the Zigbee endpoint. + * + * @param file_version The current file version of the OTA client. + * @param downloaded_file_ver The version of the downloaded file. + * @param hw_version The hardware version of the device. + * @param manufacturer The manufacturer code (default: 0x1001). + * @param image_type The image type code (default: 0x1011). + * @param max_data_size The maximum data size for OTA transfer (default and recommended: 223). + */ + void addOTAClient( + uint32_t file_version, uint32_t downloaded_file_ver, uint16_t hw_version, uint16_t manufacturer = 0x1001, uint16_t image_type = 0x1011, + uint8_t max_data_size = 223 + ); + /** + * @brief Request OTA update from the server, first request is within a minute and the next requests are sent every hour automatically. + */ + void requestOTAUpdate(); + // findEndpoind may be implemented by EPs to find and bind devices virtual void findEndpoint(esp_zb_zdo_match_desc_req_param_t *cmd_req) {}; diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index 575b25ef404..3af1b6c52aa 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -4,6 +4,26 @@ #if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#include "esp_ota_ops.h" +#if CONFIG_ZB_DELTA_OTA // Delta OTA, code is prepared for this feature but not enabled by default +#include "esp_delta_ota_ops.h" +#endif + +//OTA Upgrade defines and variables +#define OTA_ELEMENT_HEADER_LEN 6 /* OTA element format header size include tag identifier and length field */ + +/** + * @name Enumeration for the tag identifier denotes the type and format of the data within the element + * @anchor esp_ota_element_tag_id_t + */ +typedef enum esp_ota_element_tag_id_e { + UPGRADE_IMAGE = 0x0000, /*!< Upgrade image */ +} esp_ota_element_tag_id_t; + +static const esp_partition_t *s_ota_partition = NULL; +static esp_ota_handle_t s_ota_handle = 0; +static bool s_tagid_received = false; + // forward declaration of all implemented handlers static esp_err_t zb_attribute_set_handler(const esp_zb_zcl_set_attr_value_message_t *message); static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_message_t *message); @@ -13,6 +33,8 @@ static esp_err_t zb_cmd_ias_zone_status_change_handler(const esp_zb_zcl_ias_zone static esp_err_t zb_cmd_ias_zone_enroll_response_handler(const esp_zb_zcl_ias_zone_enroll_response_message_t *message); static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message); static esp_err_t zb_window_covering_movement_resp_handler(const esp_zb_zcl_window_covering_movement_message_t *message); +static esp_err_t zb_ota_upgrade_status_handler(const esp_zb_zcl_ota_upgrade_value_message_t *message); +static esp_err_t zb_ota_upgrade_query_image_resp_handler(const esp_zb_zcl_ota_upgrade_query_image_resp_message_t *message); // Zigbee action handlers [[maybe_unused]] @@ -32,6 +54,10 @@ static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, case ESP_ZB_CORE_WINDOW_COVERING_MOVEMENT_CB_ID: ret = zb_window_covering_movement_resp_handler((esp_zb_zcl_window_covering_movement_message_t *)message); break; + case ESP_ZB_CORE_OTA_UPGRADE_VALUE_CB_ID: ret = zb_ota_upgrade_status_handler((esp_zb_zcl_ota_upgrade_value_message_t *)message); break; + case ESP_ZB_CORE_OTA_UPGRADE_QUERY_IMAGE_RESP_CB_ID: + ret = zb_ota_upgrade_query_image_resp_handler((esp_zb_zcl_ota_upgrade_query_image_resp_message_t *)message); + break; case ESP_ZB_CORE_CMD_DEFAULT_RESP_CB_ID: ret = zb_cmd_default_resp_handler((esp_zb_zcl_cmd_default_resp_message_t *)message); break; default: log_w("Receive unhandled Zigbee action(0x%x) callback", callback_id); break; } @@ -186,22 +212,6 @@ static esp_err_t zb_cmd_ias_zone_enroll_response_handler(const esp_zb_zcl_ias_zo return ESP_OK; } -static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message) { - if (!message) { - log_e("Empty message"); - return ESP_FAIL; - } - if (message->info.status != ESP_ZB_ZCL_STATUS_SUCCESS) { - log_e("Received message: error status(%d)", message->info.status); - return ESP_ERR_INVALID_ARG; - } - log_v( - "Received default response: from address(0x%x), src_endpoint(%d) to dst_endpoint(%d), cluster(0x%x) with status 0x%x", - message->info.src_address.u.short_addr, message->info.src_endpoint, message->info.dst_endpoint, message->info.cluster, message->status_code - ); - return ESP_OK; -} - static esp_err_t zb_window_covering_movement_resp_handler(const esp_zb_zcl_window_covering_movement_message_t *message) { if (!message) { log_e("Empty message"); @@ -224,4 +234,167 @@ static esp_err_t zb_window_covering_movement_resp_handler(const esp_zb_zcl_windo return ESP_OK; } +static esp_err_t esp_element_ota_data(uint32_t total_size, const void *payload, uint16_t payload_size, void **outbuf, uint16_t *outlen) { + static uint16_t tagid = 0; + void *data_buf = NULL; + uint16_t data_len; + + if (!s_tagid_received) { + uint32_t length = 0; + if (!payload || payload_size <= OTA_ELEMENT_HEADER_LEN) { + log_e("Invalid element format"); + return ESP_ERR_INVALID_ARG; + } + + const uint8_t *payload_ptr = (const uint8_t *)payload; + tagid = *(const uint16_t *)payload_ptr; + length = *(const uint32_t *)(payload_ptr + sizeof(tagid)); + if ((length + OTA_ELEMENT_HEADER_LEN) != total_size) { + log_e("Invalid element length [%ld/%ld]", length, total_size); + return ESP_ERR_INVALID_ARG; + } + + s_tagid_received = true; + + data_buf = (void *)(payload_ptr + OTA_ELEMENT_HEADER_LEN); + data_len = payload_size - OTA_ELEMENT_HEADER_LEN; + } else { + data_buf = (void *)payload; + data_len = payload_size; + } + + switch (tagid) { + case UPGRADE_IMAGE: + *outbuf = data_buf; + *outlen = data_len; + break; + default: + log_e("Unsupported element tag identifier %d", tagid); + return ESP_ERR_INVALID_ARG; + break; + } + + return ESP_OK; +} + +static esp_err_t zb_ota_upgrade_status_handler(const esp_zb_zcl_ota_upgrade_value_message_t *message) { + static uint32_t total_size = 0; + static uint32_t offset = 0; + [[maybe_unused]] + static int64_t start_time = 0; + esp_err_t ret = ESP_OK; + + if (message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS) { + switch (message->upgrade_status) { + case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_START: + log_i("Zigbee - OTA upgrade start"); + start_time = esp_timer_get_time(); + s_ota_partition = esp_ota_get_next_update_partition(NULL); + assert(s_ota_partition); +#if CONFIG_ZB_DELTA_OTA + ret = esp_delta_ota_begin(s_ota_partition, 0, &s_ota_handle); +#else + ret = esp_ota_begin(s_ota_partition, 0, &s_ota_handle); +#endif + if (ret != ESP_OK) { + log_e("Zigbee - Failed to begin OTA partition, status: %s", esp_err_to_name(ret)); + return ret; + } + break; + case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_RECEIVE: + total_size = message->ota_header.image_size; + offset += message->payload_size; + log_i("Zigbee - OTA Client receives data: progress [%ld/%ld]", offset, total_size); + if (message->payload_size && message->payload) { + uint16_t payload_size = 0; + void *payload = NULL; + ret = esp_element_ota_data(total_size, message->payload, message->payload_size, &payload, &payload_size); + if (ret != ESP_OK) { + log_e("Zigbee - Failed to element OTA data, status: %s", esp_err_to_name(ret)); + return ret; + } +#if CONFIG_ZB_DELTA_OTA + ret = esp_delta_ota_write(s_ota_handle, payload, payload_size); +#else + ret = esp_ota_write(s_ota_handle, (const void *)payload, payload_size); +#endif + if (ret != ESP_OK) { + log_e("Zigbee - Failed to write OTA data to partition, status: %s", esp_err_to_name(ret)); + return ret; + } + } + break; + case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_APPLY: log_i("Zigbee - OTA upgrade apply"); break; + case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_CHECK: + ret = offset == total_size ? ESP_OK : ESP_FAIL; + offset = 0; + total_size = 0; + s_tagid_received = false; + log_i("Zigbee - OTA upgrade check status: %s", esp_err_to_name(ret)); + break; + case ESP_ZB_ZCL_OTA_UPGRADE_STATUS_FINISH: + log_i("Zigbee - OTA Finish"); + log_i( + "Zigbee - OTA Information: version: 0x%lx, manufacturer code: 0x%x, image type: 0x%x, total size: %ld bytes, cost time: %lld ms,", + message->ota_header.file_version, message->ota_header.manufacturer_code, message->ota_header.image_type, message->ota_header.image_size, + (esp_timer_get_time() - start_time) / 1000 + ); +#if CONFIG_ZB_DELTA_OTA + ret = esp_delta_ota_end(s_ota_handle); +#else + ret = esp_ota_end(s_ota_handle); +#endif + if (ret != ESP_OK) { + log_e("Zigbee - Failed to end OTA partition, status: %s", esp_err_to_name(ret)); + return ret; + } + ret = esp_ota_set_boot_partition(s_ota_partition); + if (ret != ESP_OK) { + log_e("Zigbee - Failed to set OTA boot partition, status: %s", esp_err_to_name(ret)); + return ret; + } + log_w("Zigbee - Prepare to restart system"); + esp_restart(); + break; + default: log_i("Zigbee - OTA status: %d", message->upgrade_status); break; + } + } + return ret; +} + +static esp_err_t zb_ota_upgrade_query_image_resp_handler(const esp_zb_zcl_ota_upgrade_query_image_resp_message_t *message) { + if (message->info.status == ESP_ZB_ZCL_STATUS_SUCCESS) { + log_i("Zigbee - Queried OTA image from address: 0x%04hx, endpoint: %d", message->server_addr.u.short_addr, message->server_endpoint); + log_i("Zigbee - Image version: 0x%lx, manufacturer code: 0x%x, image size: %ld", message->file_version, message->manufacturer_code, message->image_size); + if (message->image_size == 0) { + log_i("Zigbee - Rejecting OTA image upgrade, image size is 0"); + return ESP_FAIL; + } + if (message->file_version == 0) { + log_i("Zigbee - Rejecting OTA image upgrade, file version is 0"); + return ESP_FAIL; + } + log_i("Zigbee - Approving OTA image upgrade"); + } else { + log_i("Zigbee - OTA image upgrade response status: 0x%x", message->info.status); + } + return ESP_OK; +} + +static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_message_t *message) { + if (!message) { + log_e("Empty message"); + return ESP_FAIL; + } + if (message->info.status != ESP_ZB_ZCL_STATUS_SUCCESS) { + log_e("Received message: error status(%d)", message->info.status); + return ESP_ERR_INVALID_ARG; + } + log_v( + "Received default response: from address(0x%x), src_endpoint(%d) to dst_endpoint(%d), cluster(0x%x) with status 0x%x", + message->info.src_address.u.short_addr, message->info.src_endpoint, message->info.dst_endpoint, message->info.cluster, message->status_code + ); + return ESP_OK; +} + #endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED From 7f8c77f9ee7cfac433ef21304c7abf01cf2b86a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 13 Feb 2025 12:03:02 +0100 Subject: [PATCH 22/79] feat(zigbee): Add vibration sensor endpoint (#10944) --- CMakeLists.txt | 1 + .../Zigbee_Vibration_Sensor/README.md | 58 ++++++++++ .../Zigbee_Vibration_Sensor.ino | 104 ++++++++++++++++++ .../examples/Zigbee_Vibration_Sensor/ci.json | 6 + libraries/Zigbee/src/Zigbee.h | 1 + .../Zigbee/src/ep/ZigbeeVibrationSensor.cpp | 86 +++++++++++++++ .../Zigbee/src/ep/ZigbeeVibrationSensor.h | 64 +++++++++++ 7 files changed, 320 insertions(+) create mode 100644 libraries/Zigbee/examples/Zigbee_Vibration_Sensor/README.md create mode 100644 libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino create mode 100644 libraries/Zigbee/examples/Zigbee_Vibration_Sensor/ci.json create mode 100644 libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 40567d1b45c..5ee4ce664ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -293,6 +293,7 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp + libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp ) set(ARDUINO_LIBRARY_BLE_SRCS diff --git a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/README.md b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/README.md new file mode 100644 index 00000000000..b0e5b5f09e8 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/README.md @@ -0,0 +1,58 @@ +# Arduino-ESP32 Zigbee Vibration Sensor Example + +This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) vibration sensor (IAS Zone), +that can be used for example as a security device which is sensing a vibrations. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Hardware Required + +* A USB cable for power supply and programming + +### Configure the Project + +Set the Button GPIO by changing the `button` variable. By default, it's the pin `BOOT_PIN` (BOOT button on ESP32-C6 and ESP32-H2). +Set the Sensor GPIO by changing the `sensor_pin` variable. + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ED (end device)` +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs` +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. +* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. + +## Troubleshooting + +If the End device flashed with this example is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino new file mode 100644 index 00000000000..d9ac7b6e241 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/Zigbee_Vibration_Sensor.ino @@ -0,0 +1,104 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +/** + * @brief This example demonstrates Zigbee vibration sensor (IAS Zone). + * + * The example demonstrates how to use Zigbee library to create a end device vibration sensor. + * The vibration sensor is a Zigbee end device, which is reporting data to the Zigbee network. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ED +#error "Zigbee end device mode is not selected in Tools->Zigbee mode" +#endif + +#include "Zigbee.h" + +/* Zigbee vibration sensor configuration */ +#define VIBRATION_SENSOR_ENDPOINT_NUMBER 10 +uint8_t button = BOOT_PIN; +uint8_t sensor_pin = 4; + +ZigbeeVibrationSensor zbVibrationSensor = ZigbeeVibrationSensor(VIBRATION_SENSOR_ENDPOINT_NUMBER); + +void setup() { + Serial.begin(115200); + + // Init button + sensor + pinMode(button, INPUT_PULLUP); + pinMode(sensor_pin, INPUT); + + // Optional: set Zigbee device name and model + zbVibrationSensor.setManufacturerAndModel("Espressif", "ZigbeeVibrationSensor"); + + // Add endpoint to Zigbee Core + Zigbee.addEndpoint(&zbVibrationSensor); + + Serial.println("Starting Zigbee..."); + // When all EPs are registered, start Zigbee in End Device mode + if (!Zigbee.begin()) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } else { + Serial.println("Zigbee started successfully!"); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println(); +} + +void loop() { + // Checking pin for contact change + static bool sensed = false; + if (digitalRead(sensor_pin) == HIGH && !sensed) { + // Update contact sensor value + zbVibrationSensor.setVibration(true); + sensed = true; + //if sensed, wait 2 seconds before next sensing + delay(2000); + } else if (digitalRead(sensor_pin) == LOW && sensed) { + zbVibrationSensor.setVibration(false); + sensed = false; + //if not sensed, wait 0,5 seconds before next sensing + delay(500); + } + + // Checking button for factory reset + if (digitalRead(button) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(button) == LOW) { + delay(50); + if ((millis() - startTime) > 3000) { + // If key pressed for more than 3secs, factory reset Zigbee and reboot + Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + delay(1000); + Zigbee.factoryReset(); + } + } + } + delay(100); +} diff --git a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/ci.json b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/ci.json new file mode 100644 index 00000000000..7b7ccef8ed7 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/ci.json @@ -0,0 +1,6 @@ +{ + "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", + "requires": [ + "CONFIG_SOC_IEEE802154_SUPPORTED=y" + ] +} diff --git a/libraries/Zigbee/src/Zigbee.h b/libraries/Zigbee/src/Zigbee.h index 49bfa44d5c1..b785c28d0df 100644 --- a/libraries/Zigbee/src/Zigbee.h +++ b/libraries/Zigbee/src/Zigbee.h @@ -21,3 +21,4 @@ #include "ep/ZigbeeContactSwitch.h" #include "ep/ZigbeeDoorWindowHandle.h" #include "ep/ZigbeeWindowCovering.h" +#include "ep/ZigbeeVibrationSensor.h" diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp new file mode 100644 index 00000000000..2f2172c89df --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp @@ -0,0 +1,86 @@ +#include "ZigbeeVibrationSensor.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +esp_zb_cluster_list_t *zigbee_vibration_sensor_clusters_create(zigbee_vibration_sensor_cfg_t *vibration_sensor) { + esp_zb_basic_cluster_cfg_t *basic_cfg = vibration_sensor ? &(vibration_sensor->basic_cfg) : NULL; + esp_zb_identify_cluster_cfg_t *identify_cfg = vibration_sensor ? &(vibration_sensor->identify_cfg) : NULL; + esp_zb_ias_zone_cluster_cfg_t *ias_zone_cfg = vibration_sensor ? &(vibration_sensor->ias_zone_cfg) : NULL; + esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_ias_zone_cluster(cluster_list, esp_zb_ias_zone_cluster_create(ias_zone_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + return cluster_list; +} + +ZigbeeVibrationSensor::ZigbeeVibrationSensor(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_IAS_ZONE_ID; + _zone_status = 0; + _zone_id = 0xff; + _ias_cie_endpoint = 1; + + //Create custom vibration sensor configuration + zigbee_vibration_sensor_cfg_t vibration_sensor_cfg = ZIGBEE_DEFAULT_VIBRATION_SENSOR_CONFIG(); + _cluster_list = zigbee_vibration_sensor_clusters_create(&vibration_sensor_cfg); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_IAS_ZONE_ID, .app_device_version = 0}; +} + +void ZigbeeVibrationSensor::setIASClientEndpoint(uint8_t ep_number) { + _ias_cie_endpoint = ep_number; +} + +void ZigbeeVibrationSensor::setVibration(bool sensed) { + log_v("Setting Vibration sensor to %s", sensed ? "sensed" : "not sensed"); + uint8_t vibration = (uint8_t)sensed; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_ZONESTATUS_ID, &vibration, false + ); + esp_zb_lock_release(); + _zone_status = vibration; + report(); +} + +void ZigbeeVibrationSensor::report() { + /* Send IAS Zone status changed notification command */ + + esp_zb_zcl_ias_zone_status_change_notif_cmd_t status_change_notif_cmd; + status_change_notif_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + status_change_notif_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + status_change_notif_cmd.zcl_basic_cmd.dst_endpoint = _ias_cie_endpoint; //default is 1 + memcpy(status_change_notif_cmd.zcl_basic_cmd.dst_addr_u.addr_long, _ias_cie_addr, sizeof(esp_zb_ieee_addr_t)); + + status_change_notif_cmd.zone_status = _zone_status; + status_change_notif_cmd.extend_status = 0; + status_change_notif_cmd.zone_id = _zone_id; + status_change_notif_cmd.delay = 0; + + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_ias_zone_status_change_notif_cmd_req(&status_change_notif_cmd); + esp_zb_lock_release(); + log_v("IAS Zone status changed notification sent"); +} + +void ZigbeeVibrationSensor::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) { + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE) { + log_v("IAS Zone Enroll Response: zone id(%d), status(%d)", message->zone_id, message->response_code); + if (message->response_code == ESP_ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_CODE_SUCCESS) { + log_v("IAS Zone Enroll Response: success"); + esp_zb_lock_acquire(portMAX_DELAY); + memcpy( + _ias_cie_addr, + (*(esp_zb_ieee_addr_t *) + esp_zb_zcl_get_attribute(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_IAS_ZONE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_IAS_ZONE_IAS_CIE_ADDRESS_ID) + ->data_p), + sizeof(esp_zb_ieee_addr_t) + ); + esp_zb_lock_release(); + _zone_id = message->zone_id; + } + + } else { + log_w("Received message ignored. Cluster ID: %d not supported for On/Off Light", message->info.cluster); + } +} + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h new file mode 100644 index 00000000000..799cc943cdb --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h @@ -0,0 +1,64 @@ +/* Class of Zigbee contact switch (IAS Zone) endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +// clang-format off +#define ZIGBEE_DEFAULT_VIBRATION_SENSOR_CONFIG() \ + { \ + .basic_cfg = \ + { \ + .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE, \ + .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE, \ + }, \ + .identify_cfg = \ + { \ + .identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, \ + }, \ + .ias_zone_cfg = \ + { \ + .zone_state = ESP_ZB_ZCL_IAS_ZONE_ZONESTATE_NOT_ENROLLED, \ + .zone_type = ESP_ZB_ZCL_IAS_ZONE_ZONETYPE_VIBRATION_MOVEMENT, \ + .zone_status = 0, \ + .ias_cie_addr = ESP_ZB_ZCL_ZONE_IAS_CIE_ADDR_DEFAULT, \ + .zone_id = 0xff, \ + .zone_ctx = {0, 0, 0, 0}, \ + }, \ + } +// clang-format on + +typedef struct zigbee_vibration_sensor_cfg_s { + esp_zb_basic_cluster_cfg_t basic_cfg; + esp_zb_identify_cluster_cfg_t identify_cfg; + esp_zb_ias_zone_cluster_cfg_t ias_zone_cfg; +} zigbee_vibration_sensor_cfg_t; + +class ZigbeeVibrationSensor : public ZigbeeEP { +public: + ZigbeeVibrationSensor(uint8_t endpoint); + ~ZigbeeVibrationSensor() {} + + // Set the IAS Client endpoint number (default is 1) + void setIASClientEndpoint(uint8_t ep_number); + + // Set the vibration sensor value (true = sensed, false = not sensed) + void setVibration(bool sensed); + + // Report the vibration sensor value, done automatically after setting the sensed value + void report(); + +private: + void zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enroll_response_message_t *message) override; + uint8_t _zone_status; + uint8_t _zone_id; + esp_zb_ieee_addr_t _ias_cie_addr; + uint8_t _ias_cie_endpoint; +}; + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED From 606a4049a22f33ed32d8e3242b8d7bac536e0c8c Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Thu, 13 Feb 2025 13:16:30 +0200 Subject: [PATCH 23/79] IDF release/v5.3 (#10873) * IDF release/v5.3 adf53196 * IDF release/v5.3 fb25eb02 * IDF release/v5.3 fb25eb02 * IDF release/v5.3 fb25eb02 * IDF release/v5.3 fb25eb02 * IDF release/v5.3 489d7a2b --- package/package_esp32_index.template.json | 68 +++++++++++------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index ad031a4d155..5d73debe76f 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -42,7 +42,7 @@ { "packager": "esp32", "name": "esp32-arduino-libs", - "version": "idf-release_v5.3-cfea4f7c-v1" + "version": "idf-release_v5.3-489d7a2b-v1" }, { "packager": "esp32", @@ -95,63 +95,63 @@ "tools": [ { "name": "esp32-arduino-libs", - "version": "idf-release_v5.3-cfea4f7c-v1", + "version": "idf-release_v5.3-489d7a2b-v1", "systems": [ { "host": "i686-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "checksum": "SHA-256:1099291229a9be453c771c5867b8487a0266db9246b672417337b8f511d7f820", - "size": "341118284" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", + "size": "341414090" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "checksum": "SHA-256:1099291229a9be453c771c5867b8487a0266db9246b672417337b8f511d7f820", - "size": "341118284" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", + "size": "341414090" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "checksum": "SHA-256:1099291229a9be453c771c5867b8487a0266db9246b672417337b8f511d7f820", - "size": "341118284" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", + "size": "341414090" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "checksum": "SHA-256:1099291229a9be453c771c5867b8487a0266db9246b672417337b8f511d7f820", - "size": "341118284" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", + "size": "341414090" }, { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "checksum": "SHA-256:1099291229a9be453c771c5867b8487a0266db9246b672417337b8f511d7f820", - "size": "341118284" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", + "size": "341414090" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "checksum": "SHA-256:1099291229a9be453c771c5867b8487a0266db9246b672417337b8f511d7f820", - "size": "341118284" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", + "size": "341414090" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "checksum": "SHA-256:1099291229a9be453c771c5867b8487a0266db9246b672417337b8f511d7f820", - "size": "341118284" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", + "size": "341414090" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-cfea4f7c-v1.zip", - "checksum": "SHA-256:1099291229a9be453c771c5867b8487a0266db9246b672417337b8f511d7f820", - "size": "341118284" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", + "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", + "size": "341414090" } ] }, From fb6b788b30d69e57995d36db5374645e4c2b4a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 13 Feb 2025 12:34:30 +0100 Subject: [PATCH 24/79] feat(zigbee): Support HSV color commands for RGB light endpoint (#10959) * feat(zigbee): Support HSV color commands * ci(pre-commit): Apply automatic fixes * feat(zigbee): Add hue and sat attributes and update color capabilities * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: Me No Dev Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- libraries/Zigbee/src/ZigbeeEP.h | 16 +-- .../src/ep/ZigbeeColorDimmableLight.cpp | 116 +++++++++--------- .../Zigbee/src/ep/ZigbeeColorDimmableLight.h | 60 +++++++-- .../Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp | 50 ++------ 4 files changed, 126 insertions(+), 116 deletions(-) diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index 72cde275293..3bdd7f22b23 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -6,27 +6,13 @@ #if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED #include +#include /* Useful defines */ #define ZB_CMD_TIMEOUT 10000 // 10 seconds #define OTA_UPGRADE_QUERY_INTERVAL (1 * 60) // 1 hour = 60 minutes #define ZB_ARRAY_LENTH(arr) (sizeof(arr) / sizeof(arr[0])) -#define XYZ_TO_RGB(X, Y, Z, r, g, b) \ - { \ - r = (float)(3.240479 * (X) - 1.537150 * (Y) - 0.498535 * (Z)); \ - g = (float)(-0.969256 * (X) + 1.875992 * (Y) + 0.041556 * (Z)); \ - b = (float)(0.055648 * (X) - 0.204043 * (Y) + 1.057311 * (Z)); \ - if (r > 1) { \ - r = 1; \ - } \ - if (g > 1) { \ - g = 1; \ - } \ - if (b > 1) { \ - b = 1; \ - } \ - } #define RGB_TO_XYZ(r, g, b, X, Y, Z) \ { \ diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp index f034daba54a..7ffd6976e1f 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp @@ -4,8 +4,17 @@ ZigbeeColorDimmableLight::ZigbeeColorDimmableLight(uint8_t endpoint) : ZigbeeEP(endpoint) { _device_id = ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID; - esp_zb_color_dimmable_light_cfg_t light_cfg = ESP_ZB_DEFAULT_COLOR_DIMMABLE_LIGHT_CONFIG(); + esp_zb_color_dimmable_light_cfg_t light_cfg = ZIGBEE_DEFAULT_COLOR_DIMMABLE_LIGHT_CONFIG(); _cluster_list = esp_zb_color_dimmable_light_clusters_create(&light_cfg); + + //Add support for hue and saturation + uint8_t hue = 0; + uint8_t saturation = 0; + + esp_zb_attribute_list_t *color_cluster = esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_color_control_cluster_add_attr(color_cluster, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID, &hue); + esp_zb_color_control_cluster_add_attr(color_cluster, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID, &saturation); + _ep_config = { .endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID, .app_device_version = 0 }; @@ -13,9 +22,7 @@ ZigbeeColorDimmableLight::ZigbeeColorDimmableLight(uint8_t endpoint) : ZigbeeEP( //set default values _current_state = false; _current_level = 255; - _current_red = 255; - _current_green = 255; - _current_blue = 255; + _current_color = {255, 255, 255}; } uint16_t ZigbeeColorDimmableLight::getCurrentColorX() { @@ -32,37 +39,18 @@ uint16_t ZigbeeColorDimmableLight::getCurrentColorY() { ->data_p); } -void ZigbeeColorDimmableLight::calculateRGB(uint16_t x, uint16_t y, uint8_t &red, uint8_t &green, uint8_t &blue) { - float r, g, b, color_x, color_y; - color_x = (float)x / 65535; - color_y = (float)y / 65535; - - float color_X = color_x / color_y; - float color_Z = (1 - color_x - color_y) / color_y; - - XYZ_TO_RGB(color_X, 1, color_Z, r, g, b); - - red = (uint8_t)(r * (float)255); - green = (uint8_t)(g * (float)255); - blue = (uint8_t)(b * (float)255); +uint8_t ZigbeeColorDimmableLight::getCurrentColorHue() { + return (*(uint8_t *)esp_zb_zcl_get_attribute( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID + ) + ->data_p); } -void ZigbeeColorDimmableLight::calculateXY(uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y) { - // Convert RGB to XYZ - float r = (float)red / 255.0f; - float g = (float)green / 255.0f; - float b = (float)blue / 255.0f; - - float X, Y, Z; - RGB_TO_XYZ(r, g, b, X, Y, Z); - - // Convert XYZ to xy chromaticity coordinates - float color_x = X / (X + Y + Z); - float color_y = Y / (X + Y + Z); - - // Convert normalized xy to 16-bit values - x = (uint16_t)(color_x * 65535.0f); - y = (uint16_t)(color_y * 65535.0f); +uint8_t ZigbeeColorDimmableLight::getCurrentColorSaturation() { + return (*(uint16_t *)esp_zb_zcl_get_attribute( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID + ) + ->data_p); } //set attribute method -> method overridden in child class @@ -94,11 +82,7 @@ void ZigbeeColorDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_me uint16_t light_color_x = (*(uint16_t *)message->attribute.data.value); uint16_t light_color_y = getCurrentColorY(); //calculate RGB from XY and call setColor() - uint8_t red, green, blue; - calculateRGB(light_color_x, light_color_y, red, green, blue); - _current_blue = blue; - _current_green = green; - _current_red = red; + _current_color = espXYToRgbColor(255, light_color_x, light_color_y); //TODO: Check if level is correct lightChanged(); return; @@ -106,11 +90,17 @@ void ZigbeeColorDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_me uint16_t light_color_x = getCurrentColorX(); uint16_t light_color_y = (*(uint16_t *)message->attribute.data.value); //calculate RGB from XY and call setColor() - uint8_t red, green, blue; - calculateRGB(light_color_x, light_color_y, red, green, blue); - _current_blue = blue; - _current_green = green; - _current_red = red; + _current_color = espXYToRgbColor(255, light_color_x, light_color_y); //TODO: Check if level is correct + lightChanged(); + return; + } else if (message->attribute.id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) { + uint8_t light_color_hue = (*(uint8_t *)message->attribute.data.value); + _current_color = espHsvToRgbColor(light_color_hue, getCurrentColorSaturation(), 255); + lightChanged(); + return; + } else if (message->attribute.id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) { + uint8_t light_color_saturation = (*(uint8_t *)message->attribute.data.value); + _current_color = espHsvToRgbColor(getCurrentColorHue(), light_color_saturation, 255); lightChanged(); return; } else { @@ -123,7 +113,7 @@ void ZigbeeColorDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_me void ZigbeeColorDimmableLight::lightChanged() { if (_on_light_change) { - _on_light_change(_current_state, _current_red, _current_green, _current_blue, _current_level); + _on_light_change(_current_state, _current_color.r, _current_color.g, _current_color.b, _current_level); } } @@ -131,12 +121,13 @@ void ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red, //Update all attributes _current_state = state; _current_level = level; - _current_red = red; - _current_green = green; - _current_blue = blue; + _current_color = {red, green, blue}; lightChanged(); - log_v("Updating on/off light state to %d", state); + espXyColor_t xy_color = espRgbColorToXYColor(_current_color); + espHsvColor_t hsv_color = espRgbColorToHsvColor(_current_color); + + log_v("Updating light state: %d, level: %d, color: %d, %d, %d", state, level, red, green, blue); /* Update light clusters */ esp_zb_lock_acquire(portMAX_DELAY); //set on/off state @@ -147,28 +138,43 @@ void ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red, esp_zb_zcl_set_attribute_val( _endpoint, ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID, &_current_level, false ); - //set color - uint16_t color_x, color_y; - calculateXY(red, green, blue, color_x, color_y); + //set xy color + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID, &xy_color.x, false + ); esp_zb_zcl_set_attribute_val( - _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID, &color_x, false + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID, &xy_color.y, false ); + //set hsv color + uint8_t hue = (uint8_t)hsv_color.h; esp_zb_zcl_set_attribute_val( - _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID, &color_y, false + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID, &hue, false + ); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID, &hsv_color.s, false ); esp_zb_lock_release(); } void ZigbeeColorDimmableLight::setLightState(bool state) { - setLight(state, _current_level, _current_red, _current_green, _current_blue); + setLight(state, _current_level, _current_color.r, _current_color.g, _current_color.b); } void ZigbeeColorDimmableLight::setLightLevel(uint8_t level) { - setLight(_current_state, level, _current_red, _current_green, _current_blue); + setLight(_current_state, level, _current_color.r, _current_color.g, _current_color.b); } void ZigbeeColorDimmableLight::setLightColor(uint8_t red, uint8_t green, uint8_t blue) { setLight(_current_state, _current_level, red, green, blue); } +void ZigbeeColorDimmableLight::setLightColor(espRgbColor_t rgb_color) { + setLight(_current_state, _current_level, rgb_color.r, rgb_color.g, rgb_color.b); +} + +void ZigbeeColorDimmableLight::setLightColor(espHsvColor_t hsv_color) { + espRgbColor_t rgb_color = espHsvColorToRgbColor(hsv_color); + setLight(_current_state, _current_level, rgb_color.r, rgb_color.g, rgb_color.b); +} + #endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h index dad267c7b39..265fec1b37c 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h @@ -9,6 +9,47 @@ #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" +#define ZIGBEE_DEFAULT_COLOR_DIMMABLE_LIGHT_CONFIG() \ + { \ + .basic_cfg = \ + { \ + .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE, \ + .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE, \ + }, \ + .identify_cfg = \ + { \ + .identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, \ + }, \ + .groups_cfg = \ + { \ + .groups_name_support_id = ESP_ZB_ZCL_GROUPS_NAME_SUPPORT_DEFAULT_VALUE, \ + }, \ + .scenes_cfg = \ + { \ + .scenes_count = ESP_ZB_ZCL_SCENES_SCENE_COUNT_DEFAULT_VALUE, \ + .current_scene = ESP_ZB_ZCL_SCENES_CURRENT_SCENE_DEFAULT_VALUE, \ + .current_group = ESP_ZB_ZCL_SCENES_CURRENT_GROUP_DEFAULT_VALUE, \ + .scene_valid = ESP_ZB_ZCL_SCENES_SCENE_VALID_DEFAULT_VALUE, \ + .name_support = ESP_ZB_ZCL_SCENES_NAME_SUPPORT_DEFAULT_VALUE, \ + }, \ + .on_off_cfg = \ + { \ + .on_off = ESP_ZB_ZCL_ON_OFF_ON_OFF_DEFAULT_VALUE, \ + }, \ + .level_cfg = \ + { \ + .current_level = ESP_ZB_ZCL_LEVEL_CONTROL_CURRENT_LEVEL_DEFAULT_VALUE, \ + }, \ + .color_cfg = { \ + .current_x = ESP_ZB_ZCL_COLOR_CONTROL_CURRENT_X_DEF_VALUE, \ + .current_y = ESP_ZB_ZCL_COLOR_CONTROL_CURRENT_Y_DEF_VALUE, \ + .color_mode = ESP_ZB_ZCL_COLOR_CONTROL_COLOR_MODE_DEFAULT_VALUE, \ + .options = ESP_ZB_ZCL_COLOR_CONTROL_OPTIONS_DEFAULT_VALUE, \ + .enhanced_color_mode = ESP_ZB_ZCL_COLOR_CONTROL_ENHANCED_COLOR_MODE_DEFAULT_VALUE, \ + .color_capabilities = 0x0009, \ + }, \ + } + class ZigbeeColorDimmableLight : public ZigbeeEP { public: ZigbeeColorDimmableLight(uint8_t endpoint); @@ -24,6 +65,8 @@ class ZigbeeColorDimmableLight : public ZigbeeEP { void setLightState(bool state); void setLightLevel(uint8_t level); void setLightColor(uint8_t red, uint8_t green, uint8_t blue); + void setLightColor(espRgbColor_t rgb_color); + void setLightColor(espHsvColor_t hsv_color); void setLight(bool state, uint8_t level, uint8_t red, uint8_t green, uint8_t blue); bool getLightState() { @@ -32,23 +75,26 @@ class ZigbeeColorDimmableLight : public ZigbeeEP { uint8_t getLightLevel() { return _current_level; } + espRgbColor_t getLightColor() { + return _current_color; + } uint8_t getLightRed() { - return _current_red; + return _current_color.r; } uint8_t getLightGreen() { - return _current_green; + return _current_color.g; } uint8_t getLightBlue() { - return _current_blue; + return _current_color.b; } private: void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override; - void calculateRGB(uint16_t x, uint16_t y, uint8_t &red, uint8_t &green, uint8_t &blue); - void calculateXY(uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y); uint16_t getCurrentColorX(); uint16_t getCurrentColorY(); + uint8_t getCurrentColorHue(); + uint8_t getCurrentColorSaturation(); void lightChanged(); //callback function to be called on light change (State, R, G, B, Level) @@ -56,9 +102,7 @@ class ZigbeeColorDimmableLight : public ZigbeeEP { bool _current_state; uint8_t _current_level; - uint16_t _current_red; - uint16_t _current_green; - uint16_t _current_blue; + espRgbColor_t _current_color; }; #endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp index 4fd492a5477..7bdd8b8ad6a 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp @@ -16,24 +16,6 @@ ZigbeeColorDimmerSwitch::ZigbeeColorDimmerSwitch(uint8_t endpoint) : ZigbeeEP(en }; } -void ZigbeeColorDimmerSwitch::calculateXY(uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y) { - // Convert RGB to XYZ - float r = (float)red / 255.0f; - float g = (float)green / 255.0f; - float b = (float)blue / 255.0f; - - float X, Y, Z; - RGB_TO_XYZ(r, g, b, X, Y, Z); - - // Convert XYZ to xy chromaticity coordinates - float color_x = X / (X + Y + Z); - float color_y = Y / (X + Y + Z); - - // Convert normalized xy to 16-bit values - x = (uint16_t)(color_x * 65535.0f); - y = (uint16_t)(color_y * 65535.0f); -} - void ZigbeeColorDimmerSwitch::bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx) { if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { log_i("Bound successfully!"); @@ -417,15 +399,13 @@ void ZigbeeColorDimmerSwitch::setLightLevel(uint8_t level, uint8_t endpoint, esp void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t blue) { if (_is_bound) { - //Convert RGB to XY - uint16_t color_x, color_y; - calculateXY(red, green, blue, color_x, color_y); + espXyColor_t xy_color = espRgbToXYColor(red, green, blue); esp_zb_zcl_color_move_to_color_cmd_t cmd_req; cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; - cmd_req.color_x = color_x; - cmd_req.color_y = color_y; + cmd_req.color_x = xy_color.x; + cmd_req.color_y = xy_color.y; cmd_req.transition_time = 0; log_v("Sending 'set light color' command"); esp_zb_lock_acquire(portMAX_DELAY); @@ -438,16 +418,14 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint16_t group_addr) { if (_is_bound) { - //Convert RGB to XY - uint16_t color_x, color_y; - calculateXY(red, green, blue, color_x, color_y); + espXyColor_t xy_color = espRgbToXYColor(red, green, blue); esp_zb_zcl_color_move_to_color_cmd_t cmd_req; cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; - cmd_req.color_x = color_x; - cmd_req.color_y = color_y; + cmd_req.color_x = xy_color.x; + cmd_req.color_y = xy_color.y; cmd_req.transition_time = 0; log_v("Sending 'set light color' command to group address 0x%x", group_addr); esp_zb_lock_acquire(portMAX_DELAY); @@ -460,17 +438,15 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, uint16_t short_addr) { if (_is_bound) { - //Convert RGB to XY - uint16_t color_x, color_y; - calculateXY(red, green, blue, color_x, color_y); + espXyColor_t xy_color = espRgbToXYColor(red, green, blue); esp_zb_zcl_color_move_to_color_cmd_t cmd_req; cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; - cmd_req.color_x = color_x; - cmd_req.color_y = color_y; + cmd_req.color_x = xy_color.x; + cmd_req.color_y = xy_color.y; cmd_req.transition_time = 0; log_v("Sending 'set light color' command to endpoint %d, address 0x%x", endpoint, short_addr); esp_zb_lock_acquire(portMAX_DELAY); @@ -483,17 +459,15 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { if (_is_bound) { - //Convert RGB to XY - uint16_t color_x, color_y; - calculateXY(red, green, blue, color_x, color_y); + espXyColor_t xy_color = espRgbToXYColor(red, green, blue); esp_zb_zcl_color_move_to_color_cmd_t cmd_req; cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t)); - cmd_req.color_x = color_x; - cmd_req.color_y = color_y; + cmd_req.color_x = xy_color.x; + cmd_req.color_y = xy_color.y; cmd_req.transition_time = 0; log_v( "Sending 'set light color' command to endpoint %d, ieee address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", endpoint, ieee_addr[7], ieee_addr[6], From 6fb55a7f688742c50ccd715843b03d8e599f31bf Mon Sep 17 00:00:00 2001 From: vortigont Date: Thu, 13 Feb 2025 21:03:21 +0900 Subject: [PATCH 25/79] feat(board): Update 3rd party board Huidu HD-WF2/HD-WF4 (#10957) * feat(board): Update 3rd party board Huidu HD-WF2/HD-WF4 Followup #10779 - fixed flash mode to 'dio' - removed psram flags - corrected gpio mapping defines * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- boards.txt | 28 ---------- variants/huidu_hd_wf2/pins_arduino.h | 15 ------ variants/huidu_hd_wf4/pins_arduino.h | 77 +++++++++++++++------------- 3 files changed, 41 insertions(+), 79 deletions(-) diff --git a/boards.txt b/boards.txt index 9ecd6359759..86f821476cf 100644 --- a/boards.txt +++ b/boards.txt @@ -48923,20 +48923,6 @@ huidu_hd_wf2.menu.CPUFreq.80.build.f_cpu=80000000L huidu_hd_wf2.menu.CPUFreq.40=40MHz huidu_hd_wf2.menu.CPUFreq.40.build.f_cpu=40000000L -huidu_hd_wf2.menu.PSRAM.enabled=QSPI Flash fix -huidu_hd_wf2.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -huidu_hd_wf2.menu.PSRAM.enabled.build.psram_type=qspi - -huidu_hd_wf2.menu.FlashMode.qio=QIO 80MHz -huidu_hd_wf2.menu.FlashMode.qio.build.flash_mode=dio -huidu_hd_wf2.menu.FlashMode.qio.build.boot=qio -huidu_hd_wf2.menu.FlashMode.qio.build.boot_freq=80m -huidu_hd_wf2.menu.FlashMode.qio.build.flash_freq=80m -huidu_hd_wf2.menu.FlashMode.qio120=QIO 120MHz -huidu_hd_wf2.menu.FlashMode.qio120.build.flash_mode=dio -huidu_hd_wf2.menu.FlashMode.qio120.build.boot=qio -huidu_hd_wf2.menu.FlashMode.qio120.build.boot_freq=120m -huidu_hd_wf2.menu.FlashMode.qio120.build.flash_freq=80m huidu_hd_wf2.menu.FlashMode.dio=DIO 80MHz huidu_hd_wf2.menu.FlashMode.dio.build.flash_mode=dio huidu_hd_wf2.menu.FlashMode.dio.build.boot=dio @@ -49076,20 +49062,6 @@ huidu_hd_wf4.menu.CPUFreq.80.build.f_cpu=80000000L huidu_hd_wf4.menu.CPUFreq.40=40MHz huidu_hd_wf4.menu.CPUFreq.40.build.f_cpu=40000000L -huidu_hd_wf4.menu.PSRAM.enabled=QSPI Flash fix -huidu_hd_wf4.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -huidu_hd_wf4.menu.PSRAM.enabled.build.psram_type=qspi - -huidu_hd_wf4.menu.FlashMode.qio=QIO 80MHz -huidu_hd_wf4.menu.FlashMode.qio.build.flash_mode=dio -huidu_hd_wf4.menu.FlashMode.qio.build.boot=qio -huidu_hd_wf4.menu.FlashMode.qio.build.boot_freq=80m -huidu_hd_wf4.menu.FlashMode.qio.build.flash_freq=80m -huidu_hd_wf4.menu.FlashMode.qio120=QIO 120MHz -huidu_hd_wf4.menu.FlashMode.qio120.build.flash_mode=dio -huidu_hd_wf4.menu.FlashMode.qio120.build.boot=qio -huidu_hd_wf4.menu.FlashMode.qio120.build.boot_freq=120m -huidu_hd_wf4.menu.FlashMode.qio120.build.flash_freq=80m huidu_hd_wf4.menu.FlashMode.dio=DIO 80MHz huidu_hd_wf4.menu.FlashMode.dio.build.flash_mode=dio huidu_hd_wf4.menu.FlashMode.dio.build.boot=dio diff --git a/variants/huidu_hd_wf2/pins_arduino.h b/variants/huidu_hd_wf2/pins_arduino.h index 97d72dcc0f3..6068e4d6371 100644 --- a/variants/huidu_hd_wf2/pins_arduino.h +++ b/variants/huidu_hd_wf2/pins_arduino.h @@ -58,19 +58,4 @@ static const uint8_t MOSI = 11; static const uint8_t MISO = 13; static const uint8_t SCK = 12; -static const uint8_t T1 = WF2_X1_R1_PIN; -static const uint8_t T2 = WF2_X1_R2_PIN; -static const uint8_t T3 = WF2_X1_G1_PIN; -static const uint8_t T4 = WF2_X1_G2_PIN; -static const uint8_t T5 = WF2_X1_B1_PIN; -static const uint8_t T6 = WF2_X1_B2_PIN; -static const uint8_t T7 = WF2_A_PIN; -static const uint8_t T8 = WF2_B_PIN; -static const uint8_t T9 = WF2_C_PIN; -static const uint8_t T10 = WF2_D_PIN; -static const uint8_t T11 = WF2_X1_E_PIN; -static const uint8_t T12 = WF2_OE_PIN; -static const uint8_t T13 = WF2_CLK_PIN; -static const uint8_t T14 = WF2_LAT_PIN; - #endif /* Pins_Arduino_h */ diff --git a/variants/huidu_hd_wf4/pins_arduino.h b/variants/huidu_hd_wf4/pins_arduino.h index cd96db6c445..5b8667477bf 100644 --- a/variants/huidu_hd_wf4/pins_arduino.h +++ b/variants/huidu_hd_wf4/pins_arduino.h @@ -19,7 +19,7 @@ #define WF4_CLK_PIN 34 #define WF4_LAT_PIN 33 -// X1 +// X1 HUB75 #define WF4_X1_R1_PIN 2 #define WF4_X1_R2_PIN 3 #define WF4_X1_G1_PIN 6 @@ -28,7 +28,7 @@ #define WF4_X1_B2_PIN 11 #define WF4_X1_CS_PIN 45 // CS gpio must be set HIGH to enable X1 output -// X2 +// X2 HUB75 #define WF4_X2_R1_PIN 4 #define WF4_X2_R2_PIN 5 #define WF4_X2_G1_PIN 8 @@ -37,7 +37,7 @@ #define WF4_X2_B2_PIN 13 #define WF4_X2_CS_PIN WF4_X1_CS_PIN // CS gpio must be set HIGH to enable X2 output -// X3 +// X3 HUB75 #define WF4_X3_R1_PIN 2 #define WF4_X3_R2_PIN 3 #define WF4_X3_G1_PIN 6 @@ -46,7 +46,7 @@ #define WF4_X3_B2_PIN 11 #define WF4_X3_CS_PIN 14 // CS gpio must be set HIGH to enable X3 output -// X4 +// X4 HUB75 #define WF4_X4_R1_PIN 4 #define WF4_X4_R2_PIN 5 #define WF4_X4_G1_PIN 8 @@ -55,52 +55,57 @@ #define WF4_X4_B2_PIN 13 #define WF4_X4_CS_PIN WF4_X3_CS_PIN // CS gpio must be set HIGH to enable X4 output -//#define WF4_P1_PIN UART -#define WF4_P2_DATA_PIN 0 // GPIO0 boot -#define WF4_P5_DATA_PIN 16 // temperature -//#define WF4_P7_PIN VCC/GND -#define WF4_P11_DATA_PIN 15 // IR +// P1 is a UART connector +#define WF4_P1_RX_PIN 44 +#define WF4_P1_TX_PIN 43 + +// P2: PCB holes gpio/gnd +#define WF4_P2_DATA_PIN 0 // GPIO0 boot + +// P5: temperature sensor connector +#define WF4_P5_DATA_PIN 16 + +// P7: VCC/GPIO holes on PCB +#define WF4_P7_DATA_PIN 1 + +// P11: IR connector +#define WF4_P11_DATA_PIN 15 + +// P12: two gpio's, Vcc, GND #define WF4_P12_DATA1_PIN 47 #define WF4_P12_DATA2_PIN 18 -#define WF4_S1_DATA_PIN 17 // Button -#define WF4_S2_DATA_PIN 48 -#define WF4_S3_DATA_PIN 26 -#define WF4_S4_DATA_PIN 46 + +// S1 Button +#define WF4_S1_DATA_PIN 17 + +// S2-S3 PCB holes +#define WF4_S2_DATA_PIN 48 +#define WF4_S3_DATA_PIN 26 +#define WF4_S4_DATA_PIN 46 #define WF4_BUTTON_TEST WF4_S1_PIN // Test key button on PCB, 1=normal, 0=pressed #define WF4_LED_RUN_PIN 40 // Status LED on PCB #define WF4_BM8563_I2C_SDA 41 // RTC BM8563 I2C port #define WF4_BM8563_I2C_SCL 42 -#define WF4_USB_DM_PIN 19 -#define WF4_USB_DP_PIN 20 +#define WF4_USB_DN_PIN 19 // USB-A D- +#define WF4_USB_DP_PIN 20 // USB-A D+ #define LED_BUILTIN WF4_LED_RUN_PIN #define BUILTIN_LED LED_BUILTIN // backward compatibility -static const uint8_t TX = 43; -static const uint8_t RX = 44; +static const uint8_t TX = WF4_P1_TX_PIN; +static const uint8_t RX = WF4_P1_RX_PIN; static const uint8_t SDA = WF4_BM8563_I2C_SDA; static const uint8_t SCL = WF4_BM8563_I2C_SCL; -static const uint8_t SS = 10; -static const uint8_t MOSI = 11; -static const uint8_t MISO = 13; -static const uint8_t SCK = 12; - -static const uint8_t T1 = WF4_X1_R1_PIN; -static const uint8_t T2 = WF4_X1_R2_PIN; -static const uint8_t T3 = WF4_X1_G1_PIN; -static const uint8_t T4 = WF4_X1_G2_PIN; -static const uint8_t T5 = WF4_X1_B1_PIN; -static const uint8_t T6 = WF4_X1_B2_PIN; -static const uint8_t T7 = WF4_A_PIN; -static const uint8_t T8 = WF4_B_PIN; -static const uint8_t T9 = WF4_C_PIN; -static const uint8_t T10 = WF4_D_PIN; -static const uint8_t T11 = WF4_E_PIN; -static const uint8_t T12 = WF4_OE_PIN; -static const uint8_t T13 = WF4_CLK_PIN; -static const uint8_t T14 = WF4_LAT_PIN; +// there is no dedicated SPI connector on board, but SPI could be accessed via PCB holes +static const uint8_t SS = WF4_S2_DATA_PIN; +static const uint8_t MOSI = WF4_S3_DATA_PIN; +static const uint8_t MISO = WF4_S4_DATA_PIN; +static const uint8_t SCK = WF4_P7_DATA_PIN; + +// touch pins are mostly busy with HUB75 ports +static const uint8_t T1 = WF4_P7_DATA_PIN; #endif /* Pins_Arduino_h */ From 5488d5d23fb0da47f463fce89a879c4593a6231f Mon Sep 17 00:00:00 2001 From: TD-er Date: Thu, 13 Feb 2025 13:14:05 +0100 Subject: [PATCH 26/79] Fix crash when using String::move on empty string (#10938) (#10945) Fixes: #10938 Keep allocated memory when rhs fits Use case: Appending to a String with pre-allocated memory (e.g. from `reserve()`) No need to move 0-termination char in String::move Simplify calls to String::copy A lot of the same checks were done before calling `copy()` which should be done in the `copy()` function itself. String::copy() Should not copy more than given length Fix potential out of range in String::concat There is no prerequisite the given array has to be a 0-terminated char array. So we should only copy the length that has been given. The `setLen()` function will make sure the internal string is 0-terminated. So no need to dangerously assume there will be 1 more byte to copy Allow String::concat(const String &s) with s.buffer() == nullptr When constructing a String object, the internal buffer is a nullptr. However concatenating this to another String would return `false` while this is perfectly fine to do. --- cores/esp32/WString.cpp | 54 ++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 33 deletions(-) diff --git a/cores/esp32/WString.cpp b/cores/esp32/WString.cpp index 71183213ac2..5296a2d9652 100644 --- a/cores/esp32/WString.cpp +++ b/cores/esp32/WString.cpp @@ -226,11 +226,11 @@ bool String::changeBuffer(unsigned int maxStrLen) { /*********************************************/ String &String::copy(const char *cstr, unsigned int length) { - if (!reserve(length)) { + if (cstr == nullptr || !reserve(length)) { invalidate(); return *this; } - memmove(wbuffer(), cstr, length + 1); + memmove(wbuffer(), cstr, length); setLen(length); return *this; } @@ -239,15 +239,18 @@ String &String::copy(const char *cstr, unsigned int length) { void String::move(String &rhs) { if (buffer()) { if (capacity() >= rhs.len()) { - memmove(wbuffer(), rhs.buffer(), rhs.length() + 1); + // Use case: When 'reserve()' was called and the first + // assignment/append is the return value of a function. + if (rhs.len() && rhs.buffer()) { + memmove(wbuffer(), rhs.buffer(), rhs.length()); + } setLen(rhs.len()); rhs.invalidate(); return; - } else { - if (!isSSO()) { - free(wbuffer()); - setBuffer(nullptr); - } + } + if (!isSSO()) { + free(wbuffer()); + setBuffer(nullptr); } } if (rhs.isSSO()) { @@ -259,10 +262,7 @@ void String::move(String &rhs) { } setCapacity(rhs.capacity()); setLen(rhs.len()); - rhs.setSSO(false); - rhs.setCapacity(0); - rhs.setBuffer(nullptr); - rhs.setLen(0); + rhs.init(); } #endif @@ -270,12 +270,7 @@ String &String::operator=(const String &rhs) { if (this == &rhs) { return *this; } - if (rhs.buffer()) { - copy(rhs.buffer(), rhs.len()); - } else { - invalidate(); - } - return *this; + return copy(rhs.buffer(), rhs.len()); } #ifdef __GXX_EXPERIMENTAL_CXX0X__ @@ -295,12 +290,7 @@ String &String::operator=(StringSumHelper &&rval) { #endif String &String::operator=(const char *cstr) { - if (cstr) { - copy(cstr, strlen(cstr)); - } else { - invalidate(); - } - return *this; + return copy(cstr, strlen(cstr)); } /*********************************************/ @@ -311,23 +301,21 @@ bool String::concat(const String &s) { // Special case if we're concatting ourself (s += s;) since we may end up // realloc'ing the buffer and moving s.buffer in the method called if (&s == this) { - unsigned int newlen = 2 * len(); - if (!s.buffer()) { - return false; - } if (s.len() == 0) { return true; } + if (!s.buffer()) { + return false; + } + unsigned int newlen = 2 * len(); if (!reserve(newlen)) { return false; } memmove(wbuffer() + len(), buffer(), len()); setLen(newlen); - wbuffer()[len()] = 0; return true; - } else { - return concat(s.buffer(), s.len()); } + return concat(s.buffer(), s.len()); } bool String::concat(const char *cstr, unsigned int length) { @@ -343,10 +331,10 @@ bool String::concat(const char *cstr, unsigned int length) { } if (cstr >= wbuffer() && cstr < wbuffer() + len()) { // compatible with SSO in ram #6155 (case "x += x.c_str()") - memmove(wbuffer() + len(), cstr, length + 1); + memmove(wbuffer() + len(), cstr, length); } else { // compatible with source in flash #6367 - memcpy_P(wbuffer() + len(), cstr, length + 1); + memcpy_P(wbuffer() + len(), cstr, length); } setLen(newlen); return true; From 62082398d322c636184ba4b4a385f9b618f61a77 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 13 Feb 2025 14:32:20 +0200 Subject: [PATCH 27/79] Update core version to 3.1.2 --- cores/esp32/esp_arduino_version.h | 2 +- libraries/ArduinoOTA/library.properties | 2 +- libraries/AsyncUDP/library.properties | 2 +- libraries/BLE/library.properties | 2 +- libraries/BluetoothSerial/library.properties | 2 +- libraries/DNSServer/library.properties | 2 +- libraries/EEPROM/library.properties | 2 +- libraries/ESP32/library.properties | 2 +- libraries/ESP_I2S/library.properties | 2 +- libraries/ESP_NOW/library.properties | 2 +- libraries/ESP_SR/library.properties | 2 +- libraries/ESPmDNS/library.properties | 2 +- libraries/Ethernet/library.properties | 2 +- libraries/FFat/library.properties | 2 +- libraries/FS/library.properties | 2 +- libraries/HTTPClient/library.properties | 2 +- libraries/HTTPUpdate/library.properties | 2 +- libraries/HTTPUpdateServer/library.properties | 2 +- libraries/Insights/library.properties | 2 +- libraries/LittleFS/library.properties | 2 +- libraries/Matter/library.properties | 2 +- libraries/NetBIOS/library.properties | 2 +- libraries/Network/library.properties | 2 +- libraries/NetworkClientSecure/library.properties | 2 +- libraries/OpenThread/library.properties | 2 +- libraries/PPP/library.properties | 2 +- libraries/Preferences/library.properties | 2 +- libraries/RainMaker/library.properties | 2 +- libraries/SD/library.properties | 2 +- libraries/SD_MMC/library.properties | 2 +- libraries/SPI/library.properties | 2 +- libraries/SPIFFS/library.properties | 2 +- libraries/SimpleBLE/library.properties | 2 +- libraries/TFLiteMicro/library.properties | 2 +- libraries/Ticker/library.properties | 2 +- libraries/USB/library.properties | 2 +- libraries/Update/library.properties | 2 +- libraries/WebServer/library.properties | 2 +- libraries/WiFi/library.properties | 2 +- libraries/WiFiProv/library.properties | 2 +- libraries/Wire/library.properties | 2 +- libraries/Zigbee/library.properties | 2 +- package.json | 2 +- platform.txt | 2 +- 44 files changed, 44 insertions(+), 44 deletions(-) diff --git a/cores/esp32/esp_arduino_version.h b/cores/esp32/esp_arduino_version.h index dece36df1b8..4c9961053f9 100644 --- a/cores/esp32/esp_arduino_version.h +++ b/cores/esp32/esp_arduino_version.h @@ -23,7 +23,7 @@ extern "C" { /** Minor version number (x.X.x) */ #define ESP_ARDUINO_VERSION_MINOR 1 /** Patch version number (x.x.X) */ -#define ESP_ARDUINO_VERSION_PATCH 1 +#define ESP_ARDUINO_VERSION_PATCH 2 /** * Macro to convert ARDUINO version number into an integer diff --git a/libraries/ArduinoOTA/library.properties b/libraries/ArduinoOTA/library.properties index 524564ff699..76043001e9b 100644 --- a/libraries/ArduinoOTA/library.properties +++ b/libraries/ArduinoOTA/library.properties @@ -1,5 +1,5 @@ name=ArduinoOTA -version=3.1.1 +version=3.1.2 author=Ivan Grokhotkov and Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download. diff --git a/libraries/AsyncUDP/library.properties b/libraries/AsyncUDP/library.properties index 5b1afd68273..c27bbde2eb5 100644 --- a/libraries/AsyncUDP/library.properties +++ b/libraries/AsyncUDP/library.properties @@ -1,5 +1,5 @@ name=ESP32 Async UDP -version=3.1.1 +version=3.1.2 author=Me-No-Dev maintainer=Me-No-Dev sentence=Async UDP Library for ESP32 diff --git a/libraries/BLE/library.properties b/libraries/BLE/library.properties index afda29db686..35346c13b67 100644 --- a/libraries/BLE/library.properties +++ b/libraries/BLE/library.properties @@ -1,5 +1,5 @@ name=BLE -version=3.1.1 +version=3.1.2 author=Neil Kolban maintainer=Dariusz Krempa sentence=BLE functions for ESP32 diff --git a/libraries/BluetoothSerial/library.properties b/libraries/BluetoothSerial/library.properties index cf0dab07aa7..d33d461d77c 100644 --- a/libraries/BluetoothSerial/library.properties +++ b/libraries/BluetoothSerial/library.properties @@ -1,5 +1,5 @@ name=BluetoothSerial -version=3.1.1 +version=3.1.2 author=Evandro Copercini maintainer=Evandro Copercini sentence=Simple UART to Classical Bluetooth bridge for ESP32 diff --git a/libraries/DNSServer/library.properties b/libraries/DNSServer/library.properties index 8a6d1786625..7996c2fef5f 100644 --- a/libraries/DNSServer/library.properties +++ b/libraries/DNSServer/library.properties @@ -1,5 +1,5 @@ name=DNSServer -version=3.1.1 +version=3.1.2 author=Kristijan Novoselić maintainer=Kristijan Novoselić, sentence=A simple DNS server for ESP32. diff --git a/libraries/EEPROM/library.properties b/libraries/EEPROM/library.properties index d66116947c7..aabaf2e3be1 100644 --- a/libraries/EEPROM/library.properties +++ b/libraries/EEPROM/library.properties @@ -1,5 +1,5 @@ name=EEPROM -version=3.1.1 +version=3.1.2 author=Ivan Grokhotkov maintainer=Paolo Becchi sentence=Enables reading and writing data a sequential, addressable FLASH storage diff --git a/libraries/ESP32/library.properties b/libraries/ESP32/library.properties index 160b392f39e..f3cc3d94be2 100644 --- a/libraries/ESP32/library.properties +++ b/libraries/ESP32/library.properties @@ -1,5 +1,5 @@ name=ESP32 -version=3.1.1 +version=3.1.2 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 sketches examples diff --git a/libraries/ESP_I2S/library.properties b/libraries/ESP_I2S/library.properties index 3105266d708..8369862022c 100644 --- a/libraries/ESP_I2S/library.properties +++ b/libraries/ESP_I2S/library.properties @@ -1,5 +1,5 @@ name=ESP_I2S -version=3.1.1 +version=3.1.2 author=me-no-dev maintainer=me-no-dev sentence=Library for ESP I2S communication diff --git a/libraries/ESP_NOW/library.properties b/libraries/ESP_NOW/library.properties index ba52e080046..1f7999ed26f 100644 --- a/libraries/ESP_NOW/library.properties +++ b/libraries/ESP_NOW/library.properties @@ -1,5 +1,5 @@ name=ESP_NOW -version=3.1.1 +version=3.1.2 author=me-no-dev maintainer=P-R-O-C-H-Y sentence=Library for ESP_NOW diff --git a/libraries/ESP_SR/library.properties b/libraries/ESP_SR/library.properties index b52c0552cbb..35225ae79bc 100644 --- a/libraries/ESP_SR/library.properties +++ b/libraries/ESP_SR/library.properties @@ -1,5 +1,5 @@ name=ESP_SR -version=3.1.1 +version=3.1.2 author=me-no-dev maintainer=me-no-dev sentence=Library for ESP Sound Recognition diff --git a/libraries/ESPmDNS/library.properties b/libraries/ESPmDNS/library.properties index fe06ddb6851..3612e3a84de 100644 --- a/libraries/ESPmDNS/library.properties +++ b/libraries/ESPmDNS/library.properties @@ -1,5 +1,5 @@ name=ESPmDNS -version=3.1.1 +version=3.1.2 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 mDNS Library diff --git a/libraries/Ethernet/library.properties b/libraries/Ethernet/library.properties index e8075d15f11..82fff9cb85e 100644 --- a/libraries/Ethernet/library.properties +++ b/libraries/Ethernet/library.properties @@ -1,5 +1,5 @@ name=Ethernet -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection (local and Internet) using the ESP32 Ethernet. diff --git a/libraries/FFat/library.properties b/libraries/FFat/library.properties index e75ef4206a6..3c387cd3c64 100644 --- a/libraries/FFat/library.properties +++ b/libraries/FFat/library.properties @@ -1,5 +1,5 @@ name=FFat -version=3.1.1 +version=3.1.2 author=Hristo Gochkov, Ivan Grokhtkov, Larry Bernstone maintainer=Hristo Gochkov sentence=ESP32 FAT on Flash File System diff --git a/libraries/FS/library.properties b/libraries/FS/library.properties index b339f57356f..1a00810a221 100644 --- a/libraries/FS/library.properties +++ b/libraries/FS/library.properties @@ -1,5 +1,5 @@ name=FS -version=3.1.1 +version=3.1.2 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 File System diff --git a/libraries/HTTPClient/library.properties b/libraries/HTTPClient/library.properties index df11cb033b8..20f971ba3ea 100644 --- a/libraries/HTTPClient/library.properties +++ b/libraries/HTTPClient/library.properties @@ -1,5 +1,5 @@ name=HTTPClient -version=3.1.1 +version=3.1.2 author=Markus Sattler maintainer=Markus Sattler sentence=HTTP Client for ESP32 diff --git a/libraries/HTTPUpdate/library.properties b/libraries/HTTPUpdate/library.properties index dc02780c8d2..9145001ce31 100644 --- a/libraries/HTTPUpdate/library.properties +++ b/libraries/HTTPUpdate/library.properties @@ -1,5 +1,5 @@ name=HTTPUpdate -version=3.1.1 +version=3.1.2 author=Markus Sattler maintainer=Markus Sattler sentence=Http Update for ESP32 diff --git a/libraries/HTTPUpdateServer/library.properties b/libraries/HTTPUpdateServer/library.properties index 6cdcc1b34ea..7a05dd26e19 100644 --- a/libraries/HTTPUpdateServer/library.properties +++ b/libraries/HTTPUpdateServer/library.properties @@ -1,5 +1,5 @@ name=HTTPUpdateServer -version=3.1.1 +version=3.1.2 author=Hristo Kapanakov maintainer= sentence=Simple HTTP Update server based on the WebServer diff --git a/libraries/Insights/library.properties b/libraries/Insights/library.properties index 39b1f80c876..076b5b8d0fb 100644 --- a/libraries/Insights/library.properties +++ b/libraries/Insights/library.properties @@ -1,5 +1,5 @@ name=ESP Insights -version=3.1.1 +version=3.1.2 author=Sanket Wadekar maintainer=Sanket Wadekar sentence=ESP Insights diff --git a/libraries/LittleFS/library.properties b/libraries/LittleFS/library.properties index 9f665385dce..f0d29ce90d8 100644 --- a/libraries/LittleFS/library.properties +++ b/libraries/LittleFS/library.properties @@ -1,5 +1,5 @@ name=LittleFS -version=3.1.1 +version=3.1.2 author= maintainer= sentence=LittleFS for esp32 diff --git a/libraries/Matter/library.properties b/libraries/Matter/library.properties index 14a7f48c6de..7f84307354e 100644 --- a/libraries/Matter/library.properties +++ b/libraries/Matter/library.properties @@ -1,5 +1,5 @@ name=Matter -version=3.1.1 +version=3.1.2 author=Rodrigo Garcia | GitHub @SuGlider maintainer=Rodrigo Garcia sentence=Library for supporting Matter environment on ESP32. diff --git a/libraries/NetBIOS/library.properties b/libraries/NetBIOS/library.properties index f28405b7f64..571a5a75d9d 100644 --- a/libraries/NetBIOS/library.properties +++ b/libraries/NetBIOS/library.properties @@ -1,5 +1,5 @@ name=NetBIOS -version=3.1.1 +version=3.1.2 author=Pablo@xpablo.cz maintainer=Hristo Gochkov sentence=Enables NBNS (NetBIOS) name resolution. diff --git a/libraries/Network/library.properties b/libraries/Network/library.properties index d3a9f329306..e7dea53d2e7 100644 --- a/libraries/Network/library.properties +++ b/libraries/Network/library.properties @@ -1,5 +1,5 @@ name=Networking -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=General network management library. diff --git a/libraries/NetworkClientSecure/library.properties b/libraries/NetworkClientSecure/library.properties index 6d79dc61095..ec5ee5e2548 100644 --- a/libraries/NetworkClientSecure/library.properties +++ b/libraries/NetworkClientSecure/library.properties @@ -1,5 +1,5 @@ name=NetworkClientSecure -version=3.1.1 +version=3.1.2 author=Evandro Luis Copercini maintainer=Github Community sentence=Enables secure network connection (local and Internet) using the ESP32 built-in WiFi. diff --git a/libraries/OpenThread/library.properties b/libraries/OpenThread/library.properties index a50a803dfa6..ed4506d5efd 100644 --- a/libraries/OpenThread/library.properties +++ b/libraries/OpenThread/library.properties @@ -1,5 +1,5 @@ name=OpenThread -version=3.1.1 +version=3.1.2 author=Rodrigo Garcia | GitHub @SuGlider maintainer=Rodrigo Garcia sentence=Library for OpenThread Network on ESP32. diff --git a/libraries/PPP/library.properties b/libraries/PPP/library.properties index fefd89d4904..5266ac6f6f7 100644 --- a/libraries/PPP/library.properties +++ b/libraries/PPP/library.properties @@ -1,5 +1,5 @@ name=PPP -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection using GSM Modem. diff --git a/libraries/Preferences/library.properties b/libraries/Preferences/library.properties index 842ade94003..d5e3a99d081 100644 --- a/libraries/Preferences/library.properties +++ b/libraries/Preferences/library.properties @@ -1,5 +1,5 @@ name=Preferences -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Provides friendly access to ESP32's Non-Volatile Storage diff --git a/libraries/RainMaker/library.properties b/libraries/RainMaker/library.properties index 2f49258e78d..2ff5262c31a 100644 --- a/libraries/RainMaker/library.properties +++ b/libraries/RainMaker/library.properties @@ -1,5 +1,5 @@ name=ESP RainMaker -version=3.1.1 +version=3.1.2 author=Sweety Mhaiske maintainer=Hristo Gochkov sentence=ESP RainMaker Support diff --git a/libraries/SD/library.properties b/libraries/SD/library.properties index 117de77ca36..20815d220d2 100644 --- a/libraries/SD/library.properties +++ b/libraries/SD/library.properties @@ -1,5 +1,5 @@ name=SD -version=3.1.1 +version=3.1.2 author=Arduino, SparkFun maintainer=Arduino sentence=Enables reading and writing on SD cards. For all Arduino boards. diff --git a/libraries/SD_MMC/library.properties b/libraries/SD_MMC/library.properties index 72c12c61d5c..9ebf53dde74 100644 --- a/libraries/SD_MMC/library.properties +++ b/libraries/SD_MMC/library.properties @@ -1,5 +1,5 @@ name=SD_MMC -version=3.1.1 +version=3.1.2 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 SDMMC File System diff --git a/libraries/SPI/library.properties b/libraries/SPI/library.properties index 8c567f00d40..81c76fcca48 100644 --- a/libraries/SPI/library.properties +++ b/libraries/SPI/library.properties @@ -1,5 +1,5 @@ name=SPI -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For all Arduino boards, BUT Arduino DUE. diff --git a/libraries/SPIFFS/library.properties b/libraries/SPIFFS/library.properties index 68cb55ca124..94f38b3ea00 100644 --- a/libraries/SPIFFS/library.properties +++ b/libraries/SPIFFS/library.properties @@ -1,5 +1,5 @@ name=SPIFFS -version=3.1.1 +version=3.1.2 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 SPIFFS File System diff --git a/libraries/SimpleBLE/library.properties b/libraries/SimpleBLE/library.properties index a5541dd9750..1ad4a83a69a 100644 --- a/libraries/SimpleBLE/library.properties +++ b/libraries/SimpleBLE/library.properties @@ -1,5 +1,5 @@ name=SimpleBLE -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Provides really simple BLE advertizer with just on and off diff --git a/libraries/TFLiteMicro/library.properties b/libraries/TFLiteMicro/library.properties index ef9b474611f..39badc8ba1b 100644 --- a/libraries/TFLiteMicro/library.properties +++ b/libraries/TFLiteMicro/library.properties @@ -1,5 +1,5 @@ name=TFLite Micro -version=3.1.1 +version=3.1.2 author=Sanket Wadekar maintainer=Sanket Wadekar sentence=TensorFlow Lite for Microcontrollers diff --git a/libraries/Ticker/library.properties b/libraries/Ticker/library.properties index 8d123806109..080a4a17f40 100644 --- a/libraries/Ticker/library.properties +++ b/libraries/Ticker/library.properties @@ -1,5 +1,5 @@ name=Ticker -version=3.1.1 +version=3.1.2 author=Bert Melis maintainer=Hristo Gochkov sentence=Allows to call functions with a given interval. diff --git a/libraries/USB/library.properties b/libraries/USB/library.properties index 17d4e25cae2..9dc655dbd10 100644 --- a/libraries/USB/library.properties +++ b/libraries/USB/library.properties @@ -1,5 +1,5 @@ name=USB -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=ESP32S2 USB Library diff --git a/libraries/Update/library.properties b/libraries/Update/library.properties index 5af58e380e1..83fbfd4c901 100644 --- a/libraries/Update/library.properties +++ b/libraries/Update/library.properties @@ -1,5 +1,5 @@ name=Update -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=ESP32 Sketch Update Library diff --git a/libraries/WebServer/library.properties b/libraries/WebServer/library.properties index c225d6ebd95..73d8d87d690 100644 --- a/libraries/WebServer/library.properties +++ b/libraries/WebServer/library.properties @@ -1,5 +1,5 @@ name=WebServer -version=3.1.1 +version=3.1.2 author=Ivan Grokhotkov maintainer=Ivan Grokhtkov sentence=Simple web server library diff --git a/libraries/WiFi/library.properties b/libraries/WiFi/library.properties index a82ae45a2d2..608bf607bf7 100644 --- a/libraries/WiFi/library.properties +++ b/libraries/WiFi/library.properties @@ -1,5 +1,5 @@ name=WiFi -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection (local and Internet) using the ESP32 built-in WiFi. diff --git a/libraries/WiFiProv/library.properties b/libraries/WiFiProv/library.properties index 4cf8aa56b39..c87cbcd8cee 100644 --- a/libraries/WiFiProv/library.properties +++ b/libraries/WiFiProv/library.properties @@ -1,5 +1,5 @@ name=WiFiProv -version=3.1.1 +version=3.1.2 author=Switi Mhaiske maintainer=Hristo Gochkov sentence=Enables provisioning. diff --git a/libraries/Wire/library.properties b/libraries/Wire/library.properties index 04beb2053bb..a23b33f431d 100644 --- a/libraries/Wire/library.properties +++ b/libraries/Wire/library.properties @@ -1,5 +1,5 @@ name=Wire -version=3.1.1 +version=3.1.2 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. For esp8266 boards. diff --git a/libraries/Zigbee/library.properties b/libraries/Zigbee/library.properties index 87e0cd63e9f..18fb81548c0 100644 --- a/libraries/Zigbee/library.properties +++ b/libraries/Zigbee/library.properties @@ -1,5 +1,5 @@ name=Zigbee -version=3.1.1 +version=3.1.2 author=P-R-O-C-H-Y maintainer=Jan Procházka sentence=Enables zigbee connection with the ESP32 diff --git a/package.json b/package.json index 742b1154d63..748a2ad1bfb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "framework-arduinoespressif32", - "version": "3.1.1", + "version": "3.1.2", "description": "Arduino Wiring-based Framework for the Espressif ESP32, ESP32-P4, ESP32-S and ESP32-C series of SoCs", "keywords": [ "framework", diff --git a/platform.txt b/platform.txt index cc9608a4f9d..2b7d40cff11 100644 --- a/platform.txt +++ b/platform.txt @@ -1,5 +1,5 @@ name=ESP32 Arduino -version=3.1.1 +version=3.1.2 tools.esp32-arduino-libs.path={runtime.platform.path}/tools/esp32-arduino-libs tools.esp32-arduino-libs.path.windows={runtime.platform.path}\tools\esp32-arduino-libs From a7907cd07e605e4e9e37f0ec862e7da7a145fa38 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Fri, 14 Feb 2025 16:57:23 +0200 Subject: [PATCH 28/79] Add the latest versions to issue report template --- .github/ISSUE_TEMPLATE/Issue-report.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/Issue-report.yml b/.github/ISSUE_TEMPLATE/Issue-report.yml index e3a4e92926e..a902184f06b 100644 --- a/.github/ISSUE_TEMPLATE/Issue-report.yml +++ b/.github/ISSUE_TEMPLATE/Issue-report.yml @@ -41,6 +41,8 @@ body: options: - latest master (checkout manually) - latest development Release Candidate (RC-X) + - v3.1.2 + - v3.1.1 - v3.1.0 - v3.0.7 - v3.0.6 From a4ecdb1a0f9cae404d29295a60f04dc835dcfba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 14 Feb 2025 18:32:14 +0100 Subject: [PATCH 29/79] feat(zigbee): Bump esp-zigbee-sdk to 1.6.3 --- idf_component.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/idf_component.yml b/idf_component.yml index 2a36244cdfc..98678d5d381 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -52,12 +52,12 @@ dependencies: espressif/esp_modem: version: "^1.1.0" espressif/esp-zboss-lib: - version: "==1.6.2" + version: "==1.6.3" require: public rules: - if: "target not in [esp32c2, esp32p4]" espressif/esp-zigbee-lib: - version: "==1.6.2" + version: "==1.6.3" require: public rules: - if: "target not in [esp32c2, esp32p4]" From 20e5e706bef586c92b97ed3eb68281bcdd3ceb68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 17 Feb 2025 09:47:29 +0100 Subject: [PATCH 30/79] fix(boards): Delete removed Zigbee RCP mode --- boards.txt | 64 ------------------------------------------------------ 1 file changed, 64 deletions(-) diff --git a/boards.txt b/boards.txt index f3c60dccf1d..3fa2e865f0f 100644 --- a/boards.txt +++ b/boards.txt @@ -540,18 +540,12 @@ esp32h2.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -l esp32h2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32h2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR esp32h2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -esp32h2.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -esp32h2.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32h2.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native esp32h2.menu.ZigbeeMode.ed_debug=Zigbee ED (end device) - Debug esp32h2.menu.ZigbeeMode.ed_debug.build.zigbee_mode=-DZIGBEE_MODE_ED esp32h2.menu.ZigbeeMode.ed_debug.build.zigbee_libs=-lesp_zb_api.ed.debug -lzboss_stack.ed.debug -lzboss_port.native.debug esp32h2.menu.ZigbeeMode.zczr_debug=Zigbee ZCZR (coordinator/router) - Debug esp32h2.menu.ZigbeeMode.zczr_debug.build.zigbee_mode=-DZIGBEE_MODE_ZCZR esp32h2.menu.ZigbeeMode.zczr_debug.build.zigbee_libs=-lesp_zb_api.zczr.debug -lzboss_stack.zczr.debug -lzboss_port.native.debug -esp32h2.menu.ZigbeeMode.rcp_debug=Zigbee RCP (radio co-processor) - Debug -esp32h2.menu.ZigbeeMode.rcp_debug.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32h2.menu.ZigbeeMode.rcp_debug.build.zigbee_libs=-lesp_zb_api.rcp.debug -lzboss_stack.rcp.debug -lzboss_port.native.debug ############################################################## @@ -752,18 +746,12 @@ esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed -l esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native esp32c6.menu.ZigbeeMode.ed_debug=Zigbee ED (end device) - Debug esp32c6.menu.ZigbeeMode.ed_debug.build.zigbee_mode=-DZIGBEE_MODE_ED esp32c6.menu.ZigbeeMode.ed_debug.build.zigbee_libs=-lesp_zb_api.ed.debug -lzboss_stack.ed.debug -lzboss_port.native.debug esp32c6.menu.ZigbeeMode.zczr_debug=Zigbee ZCZR (coordinator/router) - Debug esp32c6.menu.ZigbeeMode.zczr_debug.build.zigbee_mode=-DZIGBEE_MODE_ZCZR esp32c6.menu.ZigbeeMode.zczr_debug.build.zigbee_libs=-lesp_zb_api.zczr.debug -lzboss_stack.zczr.debug -lzboss_port.native.debug -esp32c6.menu.ZigbeeMode.rcp_debug=Zigbee RCP (radio co-processor) - Debug -esp32c6.menu.ZigbeeMode.rcp_debug.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32c6.menu.ZigbeeMode.rcp_debug.build.zigbee_libs=-lesp_zb_api.rcp.debug -lzboss_stack.rcp.debug -lzboss_port.native.debug ############################################################## @@ -4969,9 +4957,6 @@ um_tinyc6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed um_tinyc6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) um_tinyc6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR um_tinyc6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -um_tinyc6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -um_tinyc6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -um_tinyc6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -7974,9 +7959,6 @@ sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -sparkfun_esp32c6_thing_plus.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -8567,9 +8549,6 @@ sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api. sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -sparkfun_esp32c6_qwiic_pocket.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -11801,9 +11780,6 @@ dfrobot_beetle_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzb dfrobot_beetle_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) dfrobot_beetle_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR dfrobot_beetle_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -dfrobot_beetle_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -dfrobot_beetle_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -dfrobot_beetle_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -12350,10 +12326,6 @@ dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -dfrobot_firebeetle2_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native - ############################################################## # dfrobot Romeo ESP32-S3 @@ -15338,11 +15310,6 @@ adafruit_feather_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -l adafruit_feather_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) adafruit_feather_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR adafruit_feather_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -adafruit_feather_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -adafruit_feather_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -adafruit_feather_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native - - ############################################################## # Adafruit QT Py ESP32 @@ -19581,9 +19548,6 @@ esp32c6-evb.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.e esp32c6-evb.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32c6-evb.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR esp32c6-evb.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -esp32c6-evb.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -esp32c6-evb.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32c6-evb.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -19761,9 +19725,6 @@ esp32h2-devkitlipo.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_ esp32h2-devkitlipo.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) esp32h2-devkitlipo.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR esp32h2-devkitlipo.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -esp32h2-devkitlipo.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -esp32h2-devkitlipo.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -esp32h2-devkitlipo.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -24632,9 +24593,6 @@ m5stack_nanoc6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stac m5stack_nanoc6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) m5stack_nanoc6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR m5stack_nanoc6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -m5stack_nanoc6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -m5stack_nanoc6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -m5stack_nanoc6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -35027,9 +34985,6 @@ XIAO_ESP32C6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack. XIAO_ESP32C6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) XIAO_ESP32C6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR XIAO_ESP32C6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -XIAO_ESP32C6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -XIAO_ESP32C6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -XIAO_ESP32C6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -39388,9 +39343,6 @@ ioxesp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_stack.ed ioxesp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator) ioxesp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR ioxesp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -ioxesp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -ioxesp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -ioxesp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## # ATD1.47-S3 @@ -40572,9 +40524,6 @@ epulse_feather_c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_s epulse_feather_c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) epulse_feather_c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR epulse_feather_c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -epulse_feather_c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -epulse_feather_c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -epulse_feather_c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -44866,9 +44815,6 @@ cezerio_dev_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss cezerio_dev_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator) cezerio_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR cezerio_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -cezerio_dev_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -cezerio_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -cezerio_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -45039,9 +44985,6 @@ cezerio_mini_dev_esp32c6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -l cezerio_mini_dev_esp32c6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator) cezerio_mini_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR cezerio_mini_dev_esp32c6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -cezerio_mini_dev_esp32c6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -cezerio_mini_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -cezerio_mini_dev_esp32c6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## @@ -47843,13 +47786,9 @@ Pcbcupid_GLYPH_H2.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_s Pcbcupid_GLYPH_H2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) Pcbcupid_GLYPH_H2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR Pcbcupid_GLYPH_H2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -Pcbcupid_GLYPH_H2.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -Pcbcupid_GLYPH_H2.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -Pcbcupid_GLYPH_H2.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## - Pcbcupid_GLYPH_C6.name=Pcbcupid GLYPH C6 Pcbcupid_GLYPH_C6.bootloader.tool=esptool_py @@ -47998,9 +47937,6 @@ Pcbcupid_GLYPH_C6.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api.ed -lzboss_s Pcbcupid_GLYPH_C6.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) Pcbcupid_GLYPH_C6.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR Pcbcupid_GLYPH_C6.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.native -Pcbcupid_GLYPH_C6.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor) -Pcbcupid_GLYPH_C6.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP -Pcbcupid_GLYPH_C6.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api.rcp -lzboss_stack.rcp -lzboss_port.native ############################################################## From 758cbd097d938199521c4be686807f473295e8bc Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 17 Feb 2025 14:27:41 +0100 Subject: [PATCH 31/79] Fix crash in String when using nullptr (#10971) (#10972) Fixes: #10971 --- cores/esp32/WString.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cores/esp32/WString.cpp b/cores/esp32/WString.cpp index 5296a2d9652..18e64767545 100644 --- a/cores/esp32/WString.cpp +++ b/cores/esp32/WString.cpp @@ -290,7 +290,8 @@ String &String::operator=(StringSumHelper &&rval) { #endif String &String::operator=(const char *cstr) { - return copy(cstr, strlen(cstr)); + const uint32_t length = cstr ? strlen(cstr) : 0u; + return copy(cstr, length); } /*********************************************/ From dbfde15b6ac25720c9132ebd33decf6b34d5e2af Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 17 Feb 2025 15:28:32 +0200 Subject: [PATCH 32/79] Update core version to 3.1.3 --- cores/esp32/esp_arduino_version.h | 2 +- libraries/ArduinoOTA/library.properties | 2 +- libraries/AsyncUDP/library.properties | 2 +- libraries/BLE/library.properties | 2 +- libraries/BluetoothSerial/library.properties | 2 +- libraries/DNSServer/library.properties | 2 +- libraries/EEPROM/library.properties | 2 +- libraries/ESP32/library.properties | 2 +- libraries/ESP_I2S/library.properties | 2 +- libraries/ESP_NOW/library.properties | 2 +- libraries/ESP_SR/library.properties | 2 +- libraries/ESPmDNS/library.properties | 2 +- libraries/Ethernet/library.properties | 2 +- libraries/FFat/library.properties | 2 +- libraries/FS/library.properties | 2 +- libraries/HTTPClient/library.properties | 2 +- libraries/HTTPUpdate/library.properties | 2 +- libraries/HTTPUpdateServer/library.properties | 2 +- libraries/Insights/library.properties | 2 +- libraries/LittleFS/library.properties | 2 +- libraries/Matter/library.properties | 2 +- libraries/NetBIOS/library.properties | 2 +- libraries/Network/library.properties | 2 +- libraries/NetworkClientSecure/library.properties | 2 +- libraries/OpenThread/library.properties | 2 +- libraries/PPP/library.properties | 2 +- libraries/Preferences/library.properties | 2 +- libraries/RainMaker/library.properties | 2 +- libraries/SD/library.properties | 2 +- libraries/SD_MMC/library.properties | 2 +- libraries/SPI/library.properties | 2 +- libraries/SPIFFS/library.properties | 2 +- libraries/SimpleBLE/library.properties | 2 +- libraries/TFLiteMicro/library.properties | 2 +- libraries/Ticker/library.properties | 2 +- libraries/USB/library.properties | 2 +- libraries/Update/library.properties | 2 +- libraries/WebServer/library.properties | 2 +- libraries/WiFi/library.properties | 2 +- libraries/WiFiProv/library.properties | 2 +- libraries/Wire/library.properties | 2 +- libraries/Zigbee/library.properties | 2 +- package.json | 2 +- platform.txt | 2 +- 44 files changed, 44 insertions(+), 44 deletions(-) diff --git a/cores/esp32/esp_arduino_version.h b/cores/esp32/esp_arduino_version.h index 4c9961053f9..f8b00d3a1dd 100644 --- a/cores/esp32/esp_arduino_version.h +++ b/cores/esp32/esp_arduino_version.h @@ -23,7 +23,7 @@ extern "C" { /** Minor version number (x.X.x) */ #define ESP_ARDUINO_VERSION_MINOR 1 /** Patch version number (x.x.X) */ -#define ESP_ARDUINO_VERSION_PATCH 2 +#define ESP_ARDUINO_VERSION_PATCH 3 /** * Macro to convert ARDUINO version number into an integer diff --git a/libraries/ArduinoOTA/library.properties b/libraries/ArduinoOTA/library.properties index 76043001e9b..bcccbe56b5e 100644 --- a/libraries/ArduinoOTA/library.properties +++ b/libraries/ArduinoOTA/library.properties @@ -1,5 +1,5 @@ name=ArduinoOTA -version=3.1.2 +version=3.1.3 author=Ivan Grokhotkov and Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download. diff --git a/libraries/AsyncUDP/library.properties b/libraries/AsyncUDP/library.properties index c27bbde2eb5..38543425ee1 100644 --- a/libraries/AsyncUDP/library.properties +++ b/libraries/AsyncUDP/library.properties @@ -1,5 +1,5 @@ name=ESP32 Async UDP -version=3.1.2 +version=3.1.3 author=Me-No-Dev maintainer=Me-No-Dev sentence=Async UDP Library for ESP32 diff --git a/libraries/BLE/library.properties b/libraries/BLE/library.properties index 35346c13b67..12da8222e0c 100644 --- a/libraries/BLE/library.properties +++ b/libraries/BLE/library.properties @@ -1,5 +1,5 @@ name=BLE -version=3.1.2 +version=3.1.3 author=Neil Kolban maintainer=Dariusz Krempa sentence=BLE functions for ESP32 diff --git a/libraries/BluetoothSerial/library.properties b/libraries/BluetoothSerial/library.properties index d33d461d77c..1cdb6302a8a 100644 --- a/libraries/BluetoothSerial/library.properties +++ b/libraries/BluetoothSerial/library.properties @@ -1,5 +1,5 @@ name=BluetoothSerial -version=3.1.2 +version=3.1.3 author=Evandro Copercini maintainer=Evandro Copercini sentence=Simple UART to Classical Bluetooth bridge for ESP32 diff --git a/libraries/DNSServer/library.properties b/libraries/DNSServer/library.properties index 7996c2fef5f..7531b2e52cd 100644 --- a/libraries/DNSServer/library.properties +++ b/libraries/DNSServer/library.properties @@ -1,5 +1,5 @@ name=DNSServer -version=3.1.2 +version=3.1.3 author=Kristijan Novoselić maintainer=Kristijan Novoselić, sentence=A simple DNS server for ESP32. diff --git a/libraries/EEPROM/library.properties b/libraries/EEPROM/library.properties index aabaf2e3be1..4eab97edf9a 100644 --- a/libraries/EEPROM/library.properties +++ b/libraries/EEPROM/library.properties @@ -1,5 +1,5 @@ name=EEPROM -version=3.1.2 +version=3.1.3 author=Ivan Grokhotkov maintainer=Paolo Becchi sentence=Enables reading and writing data a sequential, addressable FLASH storage diff --git a/libraries/ESP32/library.properties b/libraries/ESP32/library.properties index f3cc3d94be2..d8c88776595 100644 --- a/libraries/ESP32/library.properties +++ b/libraries/ESP32/library.properties @@ -1,5 +1,5 @@ name=ESP32 -version=3.1.2 +version=3.1.3 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 sketches examples diff --git a/libraries/ESP_I2S/library.properties b/libraries/ESP_I2S/library.properties index 8369862022c..44493d67ff2 100644 --- a/libraries/ESP_I2S/library.properties +++ b/libraries/ESP_I2S/library.properties @@ -1,5 +1,5 @@ name=ESP_I2S -version=3.1.2 +version=3.1.3 author=me-no-dev maintainer=me-no-dev sentence=Library for ESP I2S communication diff --git a/libraries/ESP_NOW/library.properties b/libraries/ESP_NOW/library.properties index 1f7999ed26f..79c97131fb3 100644 --- a/libraries/ESP_NOW/library.properties +++ b/libraries/ESP_NOW/library.properties @@ -1,5 +1,5 @@ name=ESP_NOW -version=3.1.2 +version=3.1.3 author=me-no-dev maintainer=P-R-O-C-H-Y sentence=Library for ESP_NOW diff --git a/libraries/ESP_SR/library.properties b/libraries/ESP_SR/library.properties index 35225ae79bc..6a59c25102f 100644 --- a/libraries/ESP_SR/library.properties +++ b/libraries/ESP_SR/library.properties @@ -1,5 +1,5 @@ name=ESP_SR -version=3.1.2 +version=3.1.3 author=me-no-dev maintainer=me-no-dev sentence=Library for ESP Sound Recognition diff --git a/libraries/ESPmDNS/library.properties b/libraries/ESPmDNS/library.properties index 3612e3a84de..925bb4fb258 100644 --- a/libraries/ESPmDNS/library.properties +++ b/libraries/ESPmDNS/library.properties @@ -1,5 +1,5 @@ name=ESPmDNS -version=3.1.2 +version=3.1.3 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 mDNS Library diff --git a/libraries/Ethernet/library.properties b/libraries/Ethernet/library.properties index 82fff9cb85e..da3bbbb2211 100644 --- a/libraries/Ethernet/library.properties +++ b/libraries/Ethernet/library.properties @@ -1,5 +1,5 @@ name=Ethernet -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection (local and Internet) using the ESP32 Ethernet. diff --git a/libraries/FFat/library.properties b/libraries/FFat/library.properties index 3c387cd3c64..574e184ba02 100644 --- a/libraries/FFat/library.properties +++ b/libraries/FFat/library.properties @@ -1,5 +1,5 @@ name=FFat -version=3.1.2 +version=3.1.3 author=Hristo Gochkov, Ivan Grokhtkov, Larry Bernstone maintainer=Hristo Gochkov sentence=ESP32 FAT on Flash File System diff --git a/libraries/FS/library.properties b/libraries/FS/library.properties index 1a00810a221..91fb4396ed4 100644 --- a/libraries/FS/library.properties +++ b/libraries/FS/library.properties @@ -1,5 +1,5 @@ name=FS -version=3.1.2 +version=3.1.3 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 File System diff --git a/libraries/HTTPClient/library.properties b/libraries/HTTPClient/library.properties index 20f971ba3ea..347ac4f122f 100644 --- a/libraries/HTTPClient/library.properties +++ b/libraries/HTTPClient/library.properties @@ -1,5 +1,5 @@ name=HTTPClient -version=3.1.2 +version=3.1.3 author=Markus Sattler maintainer=Markus Sattler sentence=HTTP Client for ESP32 diff --git a/libraries/HTTPUpdate/library.properties b/libraries/HTTPUpdate/library.properties index 9145001ce31..2bcb06bcad2 100644 --- a/libraries/HTTPUpdate/library.properties +++ b/libraries/HTTPUpdate/library.properties @@ -1,5 +1,5 @@ name=HTTPUpdate -version=3.1.2 +version=3.1.3 author=Markus Sattler maintainer=Markus Sattler sentence=Http Update for ESP32 diff --git a/libraries/HTTPUpdateServer/library.properties b/libraries/HTTPUpdateServer/library.properties index 7a05dd26e19..8eac2aab4cf 100644 --- a/libraries/HTTPUpdateServer/library.properties +++ b/libraries/HTTPUpdateServer/library.properties @@ -1,5 +1,5 @@ name=HTTPUpdateServer -version=3.1.2 +version=3.1.3 author=Hristo Kapanakov maintainer= sentence=Simple HTTP Update server based on the WebServer diff --git a/libraries/Insights/library.properties b/libraries/Insights/library.properties index 076b5b8d0fb..b33dd15755a 100644 --- a/libraries/Insights/library.properties +++ b/libraries/Insights/library.properties @@ -1,5 +1,5 @@ name=ESP Insights -version=3.1.2 +version=3.1.3 author=Sanket Wadekar maintainer=Sanket Wadekar sentence=ESP Insights diff --git a/libraries/LittleFS/library.properties b/libraries/LittleFS/library.properties index f0d29ce90d8..233e5b1ab56 100644 --- a/libraries/LittleFS/library.properties +++ b/libraries/LittleFS/library.properties @@ -1,5 +1,5 @@ name=LittleFS -version=3.1.2 +version=3.1.3 author= maintainer= sentence=LittleFS for esp32 diff --git a/libraries/Matter/library.properties b/libraries/Matter/library.properties index 7f84307354e..f0eea397fe8 100644 --- a/libraries/Matter/library.properties +++ b/libraries/Matter/library.properties @@ -1,5 +1,5 @@ name=Matter -version=3.1.2 +version=3.1.3 author=Rodrigo Garcia | GitHub @SuGlider maintainer=Rodrigo Garcia sentence=Library for supporting Matter environment on ESP32. diff --git a/libraries/NetBIOS/library.properties b/libraries/NetBIOS/library.properties index 571a5a75d9d..bf223a34828 100644 --- a/libraries/NetBIOS/library.properties +++ b/libraries/NetBIOS/library.properties @@ -1,5 +1,5 @@ name=NetBIOS -version=3.1.2 +version=3.1.3 author=Pablo@xpablo.cz maintainer=Hristo Gochkov sentence=Enables NBNS (NetBIOS) name resolution. diff --git a/libraries/Network/library.properties b/libraries/Network/library.properties index e7dea53d2e7..bd5d5677dca 100644 --- a/libraries/Network/library.properties +++ b/libraries/Network/library.properties @@ -1,5 +1,5 @@ name=Networking -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=General network management library. diff --git a/libraries/NetworkClientSecure/library.properties b/libraries/NetworkClientSecure/library.properties index ec5ee5e2548..0754e59fba5 100644 --- a/libraries/NetworkClientSecure/library.properties +++ b/libraries/NetworkClientSecure/library.properties @@ -1,5 +1,5 @@ name=NetworkClientSecure -version=3.1.2 +version=3.1.3 author=Evandro Luis Copercini maintainer=Github Community sentence=Enables secure network connection (local and Internet) using the ESP32 built-in WiFi. diff --git a/libraries/OpenThread/library.properties b/libraries/OpenThread/library.properties index ed4506d5efd..078c4b58acc 100644 --- a/libraries/OpenThread/library.properties +++ b/libraries/OpenThread/library.properties @@ -1,5 +1,5 @@ name=OpenThread -version=3.1.2 +version=3.1.3 author=Rodrigo Garcia | GitHub @SuGlider maintainer=Rodrigo Garcia sentence=Library for OpenThread Network on ESP32. diff --git a/libraries/PPP/library.properties b/libraries/PPP/library.properties index 5266ac6f6f7..2d5d3d83877 100644 --- a/libraries/PPP/library.properties +++ b/libraries/PPP/library.properties @@ -1,5 +1,5 @@ name=PPP -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection using GSM Modem. diff --git a/libraries/Preferences/library.properties b/libraries/Preferences/library.properties index d5e3a99d081..f6cdb8a074c 100644 --- a/libraries/Preferences/library.properties +++ b/libraries/Preferences/library.properties @@ -1,5 +1,5 @@ name=Preferences -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Provides friendly access to ESP32's Non-Volatile Storage diff --git a/libraries/RainMaker/library.properties b/libraries/RainMaker/library.properties index 2ff5262c31a..6b8ba658eb4 100644 --- a/libraries/RainMaker/library.properties +++ b/libraries/RainMaker/library.properties @@ -1,5 +1,5 @@ name=ESP RainMaker -version=3.1.2 +version=3.1.3 author=Sweety Mhaiske maintainer=Hristo Gochkov sentence=ESP RainMaker Support diff --git a/libraries/SD/library.properties b/libraries/SD/library.properties index 20815d220d2..00766c48470 100644 --- a/libraries/SD/library.properties +++ b/libraries/SD/library.properties @@ -1,5 +1,5 @@ name=SD -version=3.1.2 +version=3.1.3 author=Arduino, SparkFun maintainer=Arduino sentence=Enables reading and writing on SD cards. For all Arduino boards. diff --git a/libraries/SD_MMC/library.properties b/libraries/SD_MMC/library.properties index 9ebf53dde74..0cc0a80afd2 100644 --- a/libraries/SD_MMC/library.properties +++ b/libraries/SD_MMC/library.properties @@ -1,5 +1,5 @@ name=SD_MMC -version=3.1.2 +version=3.1.3 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 SDMMC File System diff --git a/libraries/SPI/library.properties b/libraries/SPI/library.properties index 81c76fcca48..57e44241438 100644 --- a/libraries/SPI/library.properties +++ b/libraries/SPI/library.properties @@ -1,5 +1,5 @@ name=SPI -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For all Arduino boards, BUT Arduino DUE. diff --git a/libraries/SPIFFS/library.properties b/libraries/SPIFFS/library.properties index 94f38b3ea00..5ecc75c000d 100644 --- a/libraries/SPIFFS/library.properties +++ b/libraries/SPIFFS/library.properties @@ -1,5 +1,5 @@ name=SPIFFS -version=3.1.2 +version=3.1.3 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 SPIFFS File System diff --git a/libraries/SimpleBLE/library.properties b/libraries/SimpleBLE/library.properties index 1ad4a83a69a..d5570c41751 100644 --- a/libraries/SimpleBLE/library.properties +++ b/libraries/SimpleBLE/library.properties @@ -1,5 +1,5 @@ name=SimpleBLE -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Provides really simple BLE advertizer with just on and off diff --git a/libraries/TFLiteMicro/library.properties b/libraries/TFLiteMicro/library.properties index 39badc8ba1b..259df824a45 100644 --- a/libraries/TFLiteMicro/library.properties +++ b/libraries/TFLiteMicro/library.properties @@ -1,5 +1,5 @@ name=TFLite Micro -version=3.1.2 +version=3.1.3 author=Sanket Wadekar maintainer=Sanket Wadekar sentence=TensorFlow Lite for Microcontrollers diff --git a/libraries/Ticker/library.properties b/libraries/Ticker/library.properties index 080a4a17f40..7f2cdab5220 100644 --- a/libraries/Ticker/library.properties +++ b/libraries/Ticker/library.properties @@ -1,5 +1,5 @@ name=Ticker -version=3.1.2 +version=3.1.3 author=Bert Melis maintainer=Hristo Gochkov sentence=Allows to call functions with a given interval. diff --git a/libraries/USB/library.properties b/libraries/USB/library.properties index 9dc655dbd10..e0bc6c4b7e7 100644 --- a/libraries/USB/library.properties +++ b/libraries/USB/library.properties @@ -1,5 +1,5 @@ name=USB -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=ESP32S2 USB Library diff --git a/libraries/Update/library.properties b/libraries/Update/library.properties index 83fbfd4c901..f81897a64d6 100644 --- a/libraries/Update/library.properties +++ b/libraries/Update/library.properties @@ -1,5 +1,5 @@ name=Update -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=ESP32 Sketch Update Library diff --git a/libraries/WebServer/library.properties b/libraries/WebServer/library.properties index 73d8d87d690..c9153541cb2 100644 --- a/libraries/WebServer/library.properties +++ b/libraries/WebServer/library.properties @@ -1,5 +1,5 @@ name=WebServer -version=3.1.2 +version=3.1.3 author=Ivan Grokhotkov maintainer=Ivan Grokhtkov sentence=Simple web server library diff --git a/libraries/WiFi/library.properties b/libraries/WiFi/library.properties index 608bf607bf7..e72f082f8e6 100644 --- a/libraries/WiFi/library.properties +++ b/libraries/WiFi/library.properties @@ -1,5 +1,5 @@ name=WiFi -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection (local and Internet) using the ESP32 built-in WiFi. diff --git a/libraries/WiFiProv/library.properties b/libraries/WiFiProv/library.properties index c87cbcd8cee..6334a5be5c4 100644 --- a/libraries/WiFiProv/library.properties +++ b/libraries/WiFiProv/library.properties @@ -1,5 +1,5 @@ name=WiFiProv -version=3.1.2 +version=3.1.3 author=Switi Mhaiske maintainer=Hristo Gochkov sentence=Enables provisioning. diff --git a/libraries/Wire/library.properties b/libraries/Wire/library.properties index a23b33f431d..044ba74c3d0 100644 --- a/libraries/Wire/library.properties +++ b/libraries/Wire/library.properties @@ -1,5 +1,5 @@ name=Wire -version=3.1.2 +version=3.1.3 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. For esp8266 boards. diff --git a/libraries/Zigbee/library.properties b/libraries/Zigbee/library.properties index 18fb81548c0..29704db1a92 100644 --- a/libraries/Zigbee/library.properties +++ b/libraries/Zigbee/library.properties @@ -1,5 +1,5 @@ name=Zigbee -version=3.1.2 +version=3.1.3 author=P-R-O-C-H-Y maintainer=Jan Procházka sentence=Enables zigbee connection with the ESP32 diff --git a/package.json b/package.json index 748a2ad1bfb..3a5c290a1cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "framework-arduinoespressif32", - "version": "3.1.2", + "version": "3.1.3", "description": "Arduino Wiring-based Framework for the Espressif ESP32, ESP32-P4, ESP32-S and ESP32-C series of SoCs", "keywords": [ "framework", diff --git a/platform.txt b/platform.txt index 2b7d40cff11..1c718369587 100644 --- a/platform.txt +++ b/platform.txt @@ -1,5 +1,5 @@ name=ESP32 Arduino -version=3.1.2 +version=3.1.3 tools.esp32-arduino-libs.path={runtime.platform.path}/tools/esp32-arduino-libs tools.esp32-arduino-libs.path.windows={runtime.platform.path}\tools\esp32-arduino-libs From 47343a43f73e20b32f51f62fd54ce918ec8339cf Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 8 Jan 2025 13:26:13 +0200 Subject: [PATCH 33/79] feat(idf): Add support for IDF v5.4 (#10823) --- CMakeLists.txt | 2 +- cores/esp32/esp32-hal-i2c-slave.c | 8 ++++++++ idf_component.yml | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ee4ce664ec..4b22f0fab1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ # idf.py build set(min_supported_idf_version "5.3.0") -set(max_supported_idf_version "5.3.99") +set(max_supported_idf_version "5.4.99") set(idf_version "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}") if ("${idf_version}" AND NOT "$ENV{ARDUINO_SKIP_IDF_VERSION_CHECK}") diff --git a/cores/esp32/esp32-hal-i2c-slave.c b/cores/esp32/esp32-hal-i2c-slave.c index 85eddcdfcf4..46c3a4d58c2 100644 --- a/cores/esp32/esp32-hal-i2c-slave.c +++ b/cores/esp32/esp32-hal-i2c-slave.c @@ -336,7 +336,11 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t #endif // !defined(CONFIG_IDF_TARGET_ESP32P4) i2c_ll_slave_init(i2c->dev); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) + i2c_ll_enable_fifo_mode(i2c->dev, true); +#else i2c_ll_slave_set_fifo_mode(i2c->dev, true); +#endif i2c_ll_set_slave_addr(i2c->dev, slaveID, false); i2c_ll_set_tout(i2c->dev, I2C_LL_MAX_TIMEOUT); i2c_slave_set_frequency(i2c, frequency); @@ -357,7 +361,11 @@ esp_err_t i2cSlaveInit(uint8_t num, int sda, int scl, uint16_t slaveID, uint32_t i2c_ll_disable_intr_mask(i2c->dev, I2C_LL_INTR_MASK); i2c_ll_clear_intr_mask(i2c->dev, I2C_LL_INTR_MASK); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) + i2c_ll_enable_fifo_mode(i2c->dev, true); +#else i2c_ll_slave_set_fifo_mode(i2c->dev, true); +#endif if (!i2c->intr_handle) { uint32_t flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_SHARED; diff --git a/idf_component.yml b/idf_component.yml index 9c6bd159d42..a8e6876b03f 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -44,7 +44,7 @@ files: - "platform.txt" - "programmers.txt" dependencies: - idf: ">=5.3,<5.4" + idf: ">=5.3,<5.5" # mdns 1.2.1 is necessary to build H2 with no WiFi espressif/mdns: version: "^1.2.3" From 50d85a6e9dfafd7ebb8e620ba54f6c7850e63e44 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 10 Jan 2025 14:07:07 +0200 Subject: [PATCH 34/79] fix(ci): Run CI against ESP-IDF v5.4 --- .github/workflows/push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 2ca9e52e48d..bd5acfa7a40 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -245,7 +245,7 @@ jobs: # See https://hub.docker.com/r/espressif/idf/tags and # https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html # for details. - idf_ver: ["release-v5.3"] + idf_ver: ["release-v5.4"] idf_target: [ "esp32", From 18cbd762c91fabeba649671ca682ea7eb624328d Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 15 Jan 2025 16:35:47 +0200 Subject: [PATCH 35/79] feat(eth): Add support for generic IEEE 802.3 driver (#10859) --- libraries/Ethernet/src/ETH.cpp | 3 +++ libraries/Ethernet/src/ETH.h | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/libraries/Ethernet/src/ETH.cpp b/libraries/Ethernet/src/ETH.cpp index fa8a2b97122..bf63de8724d 100644 --- a/libraries/Ethernet/src/ETH.cpp +++ b/libraries/Ethernet/src/ETH.cpp @@ -283,6 +283,9 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, i esp_eth_phy_t *phy = NULL; switch (type) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) + case ETH_PHY_GENERIC: phy = esp_eth_phy_new_generic(&phy_config); break; +#endif case ETH_PHY_LAN8720: phy = esp_eth_phy_new_lan87xx(&phy_config); break; case ETH_PHY_TLK110: phy = esp_eth_phy_new_ip101(&phy_config); break; case ETH_PHY_RTL8201: phy = esp_eth_phy_new_rtl8201(&phy_config); break; diff --git a/libraries/Ethernet/src/ETH.h b/libraries/Ethernet/src/ETH.h index 582835cf8ac..cbddac065b9 100644 --- a/libraries/Ethernet/src/ETH.h +++ b/libraries/Ethernet/src/ETH.h @@ -23,6 +23,7 @@ #ifndef _ETH_H_ #define _ETH_H_ +#include "esp_idf_version.h" // // Example configurations for pins_arduino.h to allow starting with ETH.begin(); @@ -127,6 +128,10 @@ typedef emac_rmii_clock_mode_t eth_clock_mode_t; typedef enum { #if CONFIG_ETH_USE_ESP32_EMAC +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) + ETH_PHY_GENERIC, +#define ETH_PHY_JL1101 ETH_PHY_GENERIC +#endif ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_RTL8201, From f0cf3b1af674edabafd3d0464c99eeabac0d33f8 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 21 Jan 2025 13:14:16 +0200 Subject: [PATCH 36/79] feat(i2c): Add support for the new I2C driver in IDF v5.4 (#10858) * feat(i2c): Add support for the new I2C driver in IDF v5.4 * fix(build): Add the new driver to CMakeLists.txt * fix(i2c): Guard sleep retention Not all chips can restore I2C bus after light sleep * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- CMakeLists.txt | 1 + cores/esp32/esp32-hal-i2c-ng.c | 445 ++++++++++++++++++++++++++++++++ cores/esp32/esp32-hal-i2c.c | 3 + libraries/Wire/src/Wire.cpp | 17 +- libraries/Wire/src/Wire.h | 9 + variants/esp32c6/pins_arduino.h | 5 + 6 files changed, 476 insertions(+), 4 deletions(-) create mode 100644 cores/esp32/esp32-hal-i2c-ng.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b22f0fab1b..a17c516936c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ set(CORE_SRCS cores/esp32/esp32-hal-dac.c cores/esp32/esp32-hal-gpio.c cores/esp32/esp32-hal-i2c.c + cores/esp32/esp32-hal-i2c-ng.c cores/esp32/esp32-hal-i2c-slave.c cores/esp32/esp32-hal-ledc.c cores/esp32/esp32-hal-matrix.c diff --git a/cores/esp32/esp32-hal-i2c-ng.c b/cores/esp32/esp32-hal-i2c-ng.c new file mode 100644 index 00000000000..8e48d0e0397 --- /dev/null +++ b/cores/esp32/esp32-hal-i2c-ng.c @@ -0,0 +1,445 @@ +// Copyright 2015-2025 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +#include "esp32-hal-i2c.h" + +#if SOC_I2C_SUPPORTED +#include "esp_idf_version.h" +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) +#include "esp32-hal.h" +#if !CONFIG_DISABLE_HAL_LOCKS +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#endif +#include "esp_attr.h" +#include "esp_system.h" +#include "soc/soc_caps.h" +#include "driver/i2c_master.h" +#include "esp32-hal-periman.h" + +typedef volatile struct { + bool initialized; + uint32_t frequency; +#if !CONFIG_DISABLE_HAL_LOCKS + SemaphoreHandle_t lock; +#endif + int8_t scl; + int8_t sda; + i2c_master_bus_handle_t bus_handle; + i2c_master_dev_handle_t dev_handles[128]; +} i2c_bus_t; + +static i2c_bus_t bus[SOC_I2C_NUM]; + +static bool i2cDetachBus(void *bus_i2c_num) { + uint8_t i2c_num = (int)bus_i2c_num - 1; + if (!bus[i2c_num].initialized) { + return true; + } + esp_err_t err = i2cDeinit(i2c_num); + if (err != ESP_OK) { + log_e("i2cDeinit failed with error: %d", err); + return false; + } + return true; +} + +bool i2cIsInit(uint8_t i2c_num) { + if (i2c_num >= SOC_I2C_NUM) { + return false; + } + return bus[i2c_num].initialized; +} + +esp_err_t i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) { + esp_err_t ret = ESP_OK; + if (i2c_num >= SOC_I2C_NUM) { + return ESP_ERR_INVALID_ARG; + } +#if !CONFIG_DISABLE_HAL_LOCKS + if (bus[i2c_num].lock == NULL) { + bus[i2c_num].lock = xSemaphoreCreateMutex(); + if (bus[i2c_num].lock == NULL) { + log_e("xSemaphoreCreateMutex failed"); + return ESP_ERR_NO_MEM; + } + } + //acquire lock + if (xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { + log_e("could not acquire lock"); + return ESP_FAIL; + } +#endif + if (bus[i2c_num].initialized) { + log_e("bus is already initialized"); + ret = ESP_FAIL; + goto init_fail; + } + + if (!frequency) { + frequency = 100000UL; + } else if (frequency > 1000000UL) { + frequency = 1000000UL; + } + + perimanSetBusDeinit(ESP32_BUS_TYPE_I2C_MASTER_SDA, i2cDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_I2C_MASTER_SCL, i2cDetachBus); + + if (!perimanClearPinBus(sda) || !perimanClearPinBus(scl)) { + ret = ESP_FAIL; + goto init_fail; + } + + log_i("Initializing I2C Master: num=%u sda=%d scl=%d freq=%lu", i2c_num, sda, scl, frequency); + + i2c_master_bus_handle_t bus_handle = NULL; + i2c_master_bus_config_t bus_config; + memset(&bus_config, 0, sizeof(i2c_master_bus_config_t)); + bus_config.i2c_port = (i2c_port_num_t)i2c_num; + bus_config.sda_io_num = (gpio_num_t)sda; + bus_config.scl_io_num = (gpio_num_t)scl; +#if SOC_LP_I2C_SUPPORTED + if (i2c_num >= SOC_HP_I2C_NUM) { + bus_config.lp_source_clk = LP_I2C_SCLK_DEFAULT; + } else +#endif + { + bus_config.clk_source = I2C_CLK_SRC_DEFAULT; + } + bus_config.glitch_ignore_cnt = 7; + bus_config.intr_priority = 0; // auto + bus_config.trans_queue_depth = 0; // only valid in asynchronous transaction, which Arduino does not use + bus_config.flags.enable_internal_pullup = 1; +#if SOC_I2C_SUPPORT_SLEEP_RETENTION + bus_config.flags.allow_pd = 1; // backup/restore the I2C registers before/after entering/exist sleep mode +#endif + + ret = i2c_new_master_bus(&bus_config, &bus_handle); + if (ret != ESP_OK) { + log_e("i2c_new_master_bus failed: [%d] %s", ret, esp_err_to_name(ret)); + } else { + bus[i2c_num].initialized = true; + bus[i2c_num].frequency = frequency; + bus[i2c_num].scl = scl; + bus[i2c_num].sda = sda; + bus[i2c_num].bus_handle = bus_handle; + for (uint8_t i = 0; i < 128; i++) { + bus[i2c_num].dev_handles[i] = NULL; + } + if (!perimanSetPinBus(sda, ESP32_BUS_TYPE_I2C_MASTER_SDA, (void *)(i2c_num + 1), i2c_num, -1) + || !perimanSetPinBus(scl, ESP32_BUS_TYPE_I2C_MASTER_SCL, (void *)(i2c_num + 1), i2c_num, -1)) { +#if !CONFIG_DISABLE_HAL_LOCKS + //release lock so that i2cDetachBus can execute i2cDeinit + xSemaphoreGive(bus[i2c_num].lock); +#endif + i2cDetachBus((void *)(i2c_num + 1)); + return ESP_FAIL; + } + } + +init_fail: +#if !CONFIG_DISABLE_HAL_LOCKS + //release lock + xSemaphoreGive(bus[i2c_num].lock); +#endif + return ret; +} + +esp_err_t i2cDeinit(uint8_t i2c_num) { + esp_err_t err = ESP_FAIL; + if (i2c_num >= SOC_I2C_NUM) { + return ESP_ERR_INVALID_ARG; + } +#if !CONFIG_DISABLE_HAL_LOCKS + //acquire lock + if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { + log_e("could not acquire lock"); + return err; + } +#endif + if (!bus[i2c_num].initialized) { + log_e("bus is not initialized"); + } else { + // remove devices from the bus + for (uint8_t i = 0; i < 128; i++) { + if (bus[i2c_num].dev_handles[i] != NULL) { + err = i2c_master_bus_rm_device(bus[i2c_num].dev_handles[i]); + bus[i2c_num].dev_handles[i] = NULL; + if (err != ESP_OK) { + log_e("i2c_master_bus_rm_device failed: [%d] %s", err, esp_err_to_name(err)); + } + } + } + err = i2c_del_master_bus(bus[i2c_num].bus_handle); + if (err != ESP_OK) { + log_e("i2c_del_master_bus failed: [%d] %s", err, esp_err_to_name(err)); + } else { + bus[i2c_num].initialized = false; + perimanClearPinBus(bus[i2c_num].scl); + perimanClearPinBus(bus[i2c_num].sda); + bus[i2c_num].scl = -1; + bus[i2c_num].sda = -1; + bus[i2c_num].bus_handle = NULL; + } + } +#if !CONFIG_DISABLE_HAL_LOCKS + //release lock + xSemaphoreGive(bus[i2c_num].lock); +#endif + return err; +} + +static esp_err_t i2cAddDeviceIfNeeded(uint8_t i2c_num, uint16_t address) { + esp_err_t ret = ESP_OK; + if (bus[i2c_num].dev_handles[address] == NULL) { + i2c_master_dev_handle_t dev_handle = NULL; + i2c_device_config_t dev_config; + memset(&dev_config, 0, sizeof(i2c_device_config_t)); + dev_config.dev_addr_length = I2C_ADDR_BIT_LEN_7; // Arduino supports only 7bit addresses + dev_config.device_address = address; + dev_config.scl_speed_hz = bus[i2c_num].frequency; + dev_config.scl_wait_us = 0; + dev_config.flags.disable_ack_check = 0; + + ret = i2c_master_bus_add_device(bus[i2c_num].bus_handle, &dev_config, &dev_handle); + if (ret != ESP_OK) { + log_e("i2c_master_bus_add_device failed: [%d] %s", ret, esp_err_to_name(ret)); + } else { + bus[i2c_num].dev_handles[address] = dev_handle; + log_v("added device: bus=%u addr=0x%x handle=0x%08x", i2c_num, address, dev_handle); + } + } + return ret; +} + +esp_err_t i2cWrite(uint8_t i2c_num, uint16_t address, const uint8_t *buff, size_t size, uint32_t timeOutMillis) { + esp_err_t ret = ESP_FAIL; + // i2c_cmd_handle_t cmd = NULL; + if (i2c_num >= SOC_I2C_NUM) { + return ESP_ERR_INVALID_ARG; + } + if (address >= 128) { + log_e("Only 7bit I2C addresses are supported"); + return ESP_ERR_INVALID_ARG; + } +#if !CONFIG_DISABLE_HAL_LOCKS + //acquire lock + if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { + log_e("could not acquire lock"); + return ret; + } +#endif + if (!bus[i2c_num].initialized) { + log_e("bus is not initialized"); + goto end; + } + + if (size == 0) { + // Probe device + ret = i2c_master_probe(bus[i2c_num].bus_handle, address, timeOutMillis); + if (ret != ESP_OK) { + log_v("i2c_master_probe failed: [%d] %s", ret, esp_err_to_name(ret)); + } + } else { + // writing data to device + ret = i2cAddDeviceIfNeeded(i2c_num, address); + if (ret != ESP_OK) { + goto end; + } + + log_v("i2c_master_transmit: bus=%u addr=0x%x handle=0x%08x size=%u", i2c_num, address, bus[i2c_num].dev_handles[address], size); + ret = i2c_master_transmit(bus[i2c_num].dev_handles[address], buff, size, timeOutMillis); + if (ret != ESP_OK) { + log_e("i2c_master_transmit failed: [%d] %s", ret, esp_err_to_name(ret)); + goto end; + } + + // wait for transactions to finish (is it needed with sync transactions?) + // ret = i2c_master_bus_wait_all_done(bus[i2c_num].bus_handle, timeOutMillis); + // if (ret != ESP_OK) { + // log_e("i2c_master_bus_wait_all_done failed: [%d] %s", ret, esp_err_to_name(ret)); + // goto end; + // } + } + +end: +#if !CONFIG_DISABLE_HAL_LOCKS + //release lock + xSemaphoreGive(bus[i2c_num].lock); +#endif + return ret; +} + +esp_err_t i2cRead(uint8_t i2c_num, uint16_t address, uint8_t *buff, size_t size, uint32_t timeOutMillis, size_t *readCount) { + esp_err_t ret = ESP_FAIL; + *readCount = 0; + if (i2c_num >= SOC_I2C_NUM) { + return ESP_ERR_INVALID_ARG; + } +#if !CONFIG_DISABLE_HAL_LOCKS + //acquire lock + if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { + log_e("could not acquire lock"); + return ret; + } +#endif + if (!bus[i2c_num].initialized) { + log_e("bus is not initialized"); + goto end; + } + + ret = i2cAddDeviceIfNeeded(i2c_num, address); + if (ret != ESP_OK) { + goto end; + } + + log_v("i2c_master_receive: bus=%u addr=0x%x handle=0x%08x size=%u", i2c_num, address, bus[i2c_num].dev_handles[address], size); + ret = i2c_master_receive(bus[i2c_num].dev_handles[address], buff, size, timeOutMillis); + if (ret != ESP_OK) { + log_e("i2c_master_receive failed: [%d] %s", ret, esp_err_to_name(ret)); + goto end; + } + + // wait for transactions to finish (is it needed with sync transactions?) + // ret = i2c_master_bus_wait_all_done(bus[i2c_num].bus_handle, timeOutMillis); + // if (ret != ESP_OK) { + // log_e("i2c_master_bus_wait_all_done failed: [%d] %s", ret, esp_err_to_name(ret)); + // goto end; + // } + *readCount = size; + +end: +#if !CONFIG_DISABLE_HAL_LOCKS + //release lock + xSemaphoreGive(bus[i2c_num].lock); +#endif + return ret; +} + +esp_err_t i2cWriteReadNonStop( + uint8_t i2c_num, uint16_t address, const uint8_t *wbuff, size_t wsize, uint8_t *rbuff, size_t rsize, uint32_t timeOutMillis, size_t *readCount +) { + esp_err_t ret = ESP_FAIL; + *readCount = 0; + if (i2c_num >= SOC_I2C_NUM) { + return ESP_ERR_INVALID_ARG; + } +#if !CONFIG_DISABLE_HAL_LOCKS + //acquire lock + if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { + log_e("could not acquire lock"); + return ret; + } +#endif + if (!bus[i2c_num].initialized) { + log_e("bus is not initialized"); + goto end; + } + + ret = i2cAddDeviceIfNeeded(i2c_num, address); + if (ret != ESP_OK) { + goto end; + } + + log_v("i2c_master_transmit_receive: bus=%u addr=0x%x handle=0x%08x write=%u read=%u", i2c_num, address, bus[i2c_num].dev_handles[address], wsize, rsize); + ret = i2c_master_transmit_receive(bus[i2c_num].dev_handles[address], wbuff, wsize, rbuff, rsize, timeOutMillis); + if (ret != ESP_OK) { + log_e("i2c_master_transmit_receive failed: [%d] %s", ret, esp_err_to_name(ret)); + goto end; + } + + // wait for transactions to finish (is it needed with sync transactions?) + // ret = i2c_master_bus_wait_all_done(bus[i2c_num].bus_handle, timeOutMillis); + // if (ret != ESP_OK) { + // log_e("i2c_master_bus_wait_all_done failed: [%d] %s", ret, esp_err_to_name(ret)); + // goto end; + // } + *readCount = rsize; + +end: +#if !CONFIG_DISABLE_HAL_LOCKS + //release lock + xSemaphoreGive(bus[i2c_num].lock); +#endif + return ret; +} + +esp_err_t i2cSetClock(uint8_t i2c_num, uint32_t frequency) { + esp_err_t ret = ESP_FAIL; + if (i2c_num >= SOC_I2C_NUM) { + return ESP_ERR_INVALID_ARG; + } +#if !CONFIG_DISABLE_HAL_LOCKS + //acquire lock + if (bus[i2c_num].lock == NULL || xSemaphoreTake(bus[i2c_num].lock, portMAX_DELAY) != pdTRUE) { + log_e("could not acquire lock"); + return ret; + } +#endif + if (!bus[i2c_num].initialized) { + log_e("bus is not initialized"); + goto end; + } + if (bus[i2c_num].frequency == frequency) { + ret = ESP_OK; + goto end; + } + if (!frequency) { + frequency = 100000UL; + } else if (frequency > 1000000UL) { + frequency = 1000000UL; + } + + bus[i2c_num].frequency = frequency; + + // loop through devices, remove them and then re-add them with the new frequency + for (uint8_t i = 0; i < 128; i++) { + if (bus[i2c_num].dev_handles[i] != NULL) { + ret = i2c_master_bus_rm_device(bus[i2c_num].dev_handles[i]); + if (ret != ESP_OK) { + log_e("i2c_master_bus_rm_device failed: [%d] %s", ret, esp_err_to_name(ret)); + goto end; + } else { + bus[i2c_num].dev_handles[i] = NULL; + ret = i2cAddDeviceIfNeeded(i2c_num, i); + if (ret != ESP_OK) { + goto end; + } + } + } + } + +end: +#if !CONFIG_DISABLE_HAL_LOCKS + //release lock + xSemaphoreGive(bus[i2c_num].lock); +#endif + return ret; +} + +esp_err_t i2cGetClock(uint8_t i2c_num, uint32_t *frequency) { + if (i2c_num >= SOC_I2C_NUM) { + return ESP_ERR_INVALID_ARG; + } + if (!bus[i2c_num].initialized) { + log_e("bus is not initialized"); + return ESP_FAIL; + } + *frequency = bus[i2c_num].frequency; + return ESP_OK; +} + +#endif /* ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) */ +#endif /* SOC_I2C_SUPPORTED */ diff --git a/cores/esp32/esp32-hal-i2c.c b/cores/esp32/esp32-hal-i2c.c index 359b2161201..71c8ae1c428 100644 --- a/cores/esp32/esp32-hal-i2c.c +++ b/cores/esp32/esp32-hal-i2c.c @@ -15,6 +15,8 @@ #include "esp32-hal-i2c.h" #if SOC_I2C_SUPPORTED +#include "esp_idf_version.h" +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 4, 0) #include "esp32-hal.h" #if !CONFIG_DISABLE_HAL_LOCKS #include "freertos/FreeRTOS.h" @@ -429,4 +431,5 @@ esp_err_t i2cGetClock(uint8_t i2c_num, uint32_t *frequency) { return ESP_OK; } +#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 4, 0) */ #endif /* SOC_I2C_SUPPORTED */ diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 24b0eb7c0a3..f8d9496389f 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -462,10 +462,11 @@ uint8_t TwoWire::endTransmission(bool sendStop) { nonStop = true; } switch (err) { - case ESP_OK: return 0; - case ESP_FAIL: return 2; - case ESP_ERR_TIMEOUT: return 5; - default: break; + case ESP_OK: return 0; + case ESP_FAIL: return 2; + case ESP_ERR_NOT_FOUND: return 2; + case ESP_ERR_TIMEOUT: return 5; + default: break; } return 4; } @@ -646,8 +647,16 @@ void TwoWire::onRequestService(uint8_t num, void *arg) { #endif /* SOC_I2C_SUPPORT_SLAVE */ TwoWire Wire = TwoWire(0); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) +#if SOC_I2C_NUM > 1 +TwoWire Wire1 = TwoWire(1); +#elif SOC_I2C_NUM > 2 +TwoWire Wire2 = TwoWire(2); +#endif /* SOC_I2C_NUM */ +#else #if SOC_HP_I2C_NUM > 1 TwoWire Wire1 = TwoWire(1); #endif /* SOC_HP_I2C_NUM */ +#endif #endif /* SOC_I2C_SUPPORTED */ diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 45f30c81ffc..0deab7d4a57 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -28,6 +28,7 @@ #include "soc/soc_caps.h" #if SOC_I2C_SUPPORTED +#include "esp_idf_version.h" #include #include @@ -144,9 +145,17 @@ class TwoWire : public HardwareI2C { }; extern TwoWire Wire; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) +#if SOC_I2C_NUM > 1 +extern TwoWire Wire1; +#elif SOC_I2C_NUM > 2 +extern TwoWire Wire2; +#endif /* SOC_I2C_NUM */ +#else #if SOC_HP_I2C_NUM > 1 extern TwoWire Wire1; #endif /* SOC_HP_I2C_NUM */ +#endif #endif /* SOC_I2C_SUPPORTED */ #endif /* TwoWire_h */ diff --git a/variants/esp32c6/pins_arduino.h b/variants/esp32c6/pins_arduino.h index 55afea91565..348db9f907e 100644 --- a/variants/esp32c6/pins_arduino.h +++ b/variants/esp32c6/pins_arduino.h @@ -32,4 +32,9 @@ static const uint8_t A4 = 4; static const uint8_t A5 = 5; static const uint8_t A6 = 6; +// LP I2C Pins are fixed on ESP32-C6 +#define WIRE1_PIN_DEFINED +static const uint8_t SDA1 = 6; +static const uint8_t SCL1 = 7; + #endif /* Pins_Arduino_h */ From 8e9f7c31c9152d5f2ca0f3b4adf3bfb68434a88d Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 18 Feb 2025 17:00:36 +0200 Subject: [PATCH 37/79] IDF release/v5.4 e37d33cc (#10980) --- package/package_esp32_index.template.json | 204 +++++++++++----------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index 5d73debe76f..2c86b6fe4dd 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -42,12 +42,12 @@ { "packager": "esp32", "name": "esp32-arduino-libs", - "version": "idf-release_v5.3-489d7a2b-v1" + "version": "idf-release_v5.4-e37d33cc-v2" }, { "packager": "esp32", "name": "xtensa-esp-elf-gcc", - "version": "esp-13.2.0_20240530" + "version": "esp-14.2.0_20241119" }, { "packager": "esp32", @@ -57,7 +57,7 @@ { "packager": "esp32", "name": "riscv32-esp-elf-gcc", - "version": "esp-13.2.0_20240530" + "version": "esp-14.2.0_20241119" }, { "packager": "esp32", @@ -95,125 +95,125 @@ "tools": [ { "name": "esp32-arduino-libs", - "version": "idf-release_v5.3-489d7a2b-v1", + "version": "idf-release_v5.4-e37d33cc-v2", "systems": [ { "host": "i686-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", - "size": "341414090" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", + "size": "339629117" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", - "size": "341414090" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", + "size": "339629117" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", - "size": "341414090" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", + "size": "339629117" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", - "size": "341414090" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", + "size": "339629117" }, { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", - "size": "341414090" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", + "size": "339629117" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", - "size": "341414090" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", + "size": "339629117" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", - "size": "341414090" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", + "size": "339629117" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.3/esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.3-489d7a2b-v1.zip", - "checksum": "SHA-256:489012502218a7d30f6c312764bc8d10830a51e1db29558f15181c68373d0095", - "size": "341414090" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", + "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", + "size": "339629117" } ] }, { "name": "xtensa-esp-elf-gcc", - "version": "esp-13.2.0_20240530", + "version": "esp-14.2.0_20241119", "systems": [ { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.gz", - "archiveFileName": "xtensa-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.gz", - "checksum": "SHA-256:bce77e8480701d5a90545369d1b5848f6048eb39c0022d2446d1e33a8e127490", - "size": "208911713" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/xtensa-esp-elf-14.2.0_20241119-x86_64-linux-gnu.tar.gz", + "archiveFileName": "xtensa-esp-elf-14.2.0_20241119-x86_64-linux-gnu.tar.gz", + "checksum": "SHA-256:b1859df334a85541ae746e1b86439f59180d87f8cf1cc04c2e770fadf9f006e9", + "size": "323678089" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-aarch64-linux-gnu.tar.gz", - "archiveFileName": "xtensa-esp-elf-13.2.0_20240530-aarch64-linux-gnu.tar.gz", - "checksum": "SHA-256:7c9e3c1adc733d042ed87b92daa1d6396e1b441c1755f1fa14cb88855719ba88", - "size": "202519931" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/xtensa-esp-elf-14.2.0_20241119-aarch64-linux-gnu.tar.gz", + "archiveFileName": "xtensa-esp-elf-14.2.0_20241119-aarch64-linux-gnu.tar.gz", + "checksum": "SHA-256:7ff023033a5c00e55b9fc0a0b26d18fb0e476c24e24c5b0459bcb2e05a3729f1", + "size": "320064691" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-arm-linux-gnueabi.tar.gz", - "archiveFileName": "xtensa-esp-elf-13.2.0_20240530-arm-linux-gnueabi.tar.gz", - "checksum": "SHA-256:d6955e8ea6af91574bf9213b92f32ca09eb8640103446b7fa19a63cfeeec5421", - "size": "202206516" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/xtensa-esp-elf-14.2.0_20241119-arm-linux-gnueabi.tar.gz", + "archiveFileName": "xtensa-esp-elf-14.2.0_20241119-arm-linux-gnueabi.tar.gz", + "checksum": "SHA-256:bb11dbf3ed25d4e0cc9e938749519e8236cfa2609e85742d311f1d869111805a", + "size": "319454139" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-i586-linux-gnu.tar.gz", - "archiveFileName": "xtensa-esp-elf-13.2.0_20240530-i586-linux-gnu.tar.gz", - "checksum": "SHA-256:3666ee74ecb693ee6488f11469802630a7b0d32608184045a4f35cb413f59e3d", - "size": "213304863" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/xtensa-esp-elf-14.2.0_20241119-i586-linux-gnu.tar.gz", + "archiveFileName": "xtensa-esp-elf-14.2.0_20241119-i586-linux-gnu.tar.gz", + "checksum": "SHA-256:5ac611dca62ec791d413d1f417d566c444b006d2a4f97bd749b15f782d87249b", + "size": "328335914" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-x86_64-apple-darwin.tar.gz", - "archiveFileName": "xtensa-esp-elf-13.2.0_20240530-x86_64-apple-darwin.tar.gz", - "checksum": "SHA-256:948cf57b6eecc898b5f70e06ad08ba88c08b627be570ec631dfcd72f6295194a", - "size": "221357024" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/xtensa-esp-elf-14.2.0_20241119-x86_64-apple-darwin_signed.tar.gz", + "archiveFileName": "xtensa-esp-elf-14.2.0_20241119-x86_64-apple-darwin_signed.tar.gz", + "checksum": "SHA-256:15b3e60362028eaeff9156dc82dac3f1436b4aeef3920b28d7650974d8c34751", + "size": "336215844" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-aarch64-apple-darwin.tar.gz", - "archiveFileName": "xtensa-esp-elf-13.2.0_20240530-aarch64-apple-darwin.tar.gz", - "checksum": "SHA-256:6f03fdf0cc14a7f3900ee59977f62e8626d8b7c208506e52f1fd883ac223427a", - "size": "199689745" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/xtensa-esp-elf-14.2.0_20241119-aarch64-apple-darwin_signed.tar.gz", + "archiveFileName": "xtensa-esp-elf-14.2.0_20241119-aarch64-apple-darwin_signed.tar.gz", + "checksum": "SHA-256:45c475518735133789bacccad31f872318b7ecc0b31cc9b7924aad880034f0bf", + "size": "318797396" }, { "host": "i686-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-i686-w64-mingw32_hotfix.zip", - "archiveFileName": "xtensa-esp-elf-13.2.0_20240530-i686-w64-mingw32_hotfix.zip", - "checksum": "SHA-256:d6b227c50e3c8e21d62502b3140e5ab74a4cb502c2b4169c36238b9858a8fb88", - "size": "266042967" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/xtensa-esp-elf-14.2.0_20241119-i686-w64-mingw32.zip", + "archiveFileName": "xtensa-esp-elf-14.2.0_20241119-i686-w64-mingw32.zip", + "checksum": "SHA-256:b30e450e0af279783c54a9ae77c3b367dd556b78eda930a92ec7b784a74c28c8", + "size": "382457717" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/xtensa-esp-elf-13.2.0_20240530-x86_64-w64-mingw32_hotfix.zip", - "archiveFileName": "xtensa-esp-elf-13.2.0_20240530-x86_64-w64-mingw32_hotfix.zip", - "checksum": "SHA-256:155ee97b531236e6a7c763395c68ca793e55e74d2cb4d38a23057a153e01e7d0", - "size": "269831985" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/xtensa-esp-elf-14.2.0_20241119-x86_64-w64-mingw32.zip", + "archiveFileName": "xtensa-esp-elf-14.2.0_20241119-x86_64-w64-mingw32.zip", + "checksum": "SHA-256:62ae704777d73c30689efff6e81178632a1ca44d1a2d60f4621eb997e040e028", + "size": "386316009" } ] }, @@ -281,63 +281,63 @@ }, { "name": "riscv32-esp-elf-gcc", - "version": "esp-13.2.0_20240530", + "version": "esp-14.2.0_20241119", "systems": [ { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.gz", - "archiveFileName": "riscv32-esp-elf-13.2.0_20240530-x86_64-linux-gnu.tar.gz", - "checksum": "SHA-256:e7fbfffbb19dcd3764a9848a141bf44e19ad0b48e0bd1515912345c26fe52fba", - "size": "294346758" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/riscv32-esp-elf-14.2.0_20241119-x86_64-linux-gnu.tar.gz", + "archiveFileName": "riscv32-esp-elf-14.2.0_20241119-x86_64-linux-gnu.tar.gz", + "checksum": "SHA-256:a16942465d33c7f0334c16e83bc6feb62e06eeb79cf19099293480bb8d48c0cd", + "size": "593721156" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-aarch64-linux-gnu.tar.gz", - "archiveFileName": "riscv32-esp-elf-13.2.0_20240530-aarch64-linux-gnu.tar.gz", - "checksum": "SHA-256:a178a895b807ed2e87d5d62153c36a6aae048581f527c0eb152f0a02b8de9571", - "size": "288374597" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/riscv32-esp-elf-14.2.0_20241119-aarch64-linux-gnu.tar.gz", + "archiveFileName": "riscv32-esp-elf-14.2.0_20241119-aarch64-linux-gnu.tar.gz", + "checksum": "SHA-256:22486233d0e0fd58a54ae453b701f195f1432fc6f2e17085b9d6c8d5d9acefb7", + "size": "587879927" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-arm-linux-gnueabi.tar.gz", - "archiveFileName": "riscv32-esp-elf-13.2.0_20240530-arm-linux-gnueabi.tar.gz", - "checksum": "SHA-256:4a2f176d0f5bc8a70645975e2a08ea94145fb69b7225c5cdcbd6024a4836aaf5", - "size": "287737495" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/riscv32-esp-elf-14.2.0_20241119-arm-linux-gnueabi.tar.gz", + "archiveFileName": "riscv32-esp-elf-14.2.0_20241119-arm-linux-gnueabi.tar.gz", + "checksum": "SHA-256:27a72d5d96cdb56dae2a1da5dfde1717c18a8c1f9a1454c8e34a8bd34abe662d", + "size": "586531522" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-i586-linux-gnu.tar.gz", - "archiveFileName": "riscv32-esp-elf-13.2.0_20240530-i586-linux-gnu.tar.gz", - "checksum": "SHA-256:7a6f02f1b2effafb18600bbf602818f6923fd320f000fb8659f34acbfda8812f", - "size": "299138540" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/riscv32-esp-elf-14.2.0_20241119-i586-linux-gnu.tar.gz", + "archiveFileName": "riscv32-esp-elf-14.2.0_20241119-i586-linux-gnu.tar.gz", + "checksum": "SHA-256:b7bd6e4cd53a4c55831d48e96a3d500bfffb091bec84a30bc8c3ad687e3eb3a2", + "size": "597070471" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-x86_64-apple-darwin.tar.gz", - "archiveFileName": "riscv32-esp-elf-13.2.0_20240530-x86_64-apple-darwin.tar.gz", - "checksum": "SHA-256:a193b4f025d0d836b0a9d9cbe760af1c53e53af66fc332fe98952bc4c456dd9a", - "size": "305025700" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/riscv32-esp-elf-14.2.0_20241119-x86_64-apple-darwin_signed.tar.gz", + "archiveFileName": "riscv32-esp-elf-14.2.0_20241119-x86_64-apple-darwin_signed.tar.gz", + "checksum": "SHA-256:5f8b571e1aedbe9f856f3bdeca6600cd5510ccff1ca102c4f001421eda560585", + "size": "602343061" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-aarch64-apple-darwin.tar.gz", - "archiveFileName": "riscv32-esp-elf-13.2.0_20240530-aarch64-apple-darwin.tar.gz", - "checksum": "SHA-256:7082dd2e2123dea5609a24092d19ac6612ae7e219df1d298de6b2f64cb4af0df", - "size": "285458443" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/riscv32-esp-elf-14.2.0_20241119-aarch64-apple-darwin_signed.tar.gz", + "archiveFileName": "riscv32-esp-elf-14.2.0_20241119-aarch64-apple-darwin_signed.tar.gz", + "checksum": "SHA-256:a7276042a7eb2d33c2dff7167539e445c32c07d43a2c6827e86d035642503e0b", + "size": "578521565" }, { "host": "i686-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-i686-w64-mingw32.zip", - "archiveFileName": "riscv32-esp-elf-13.2.0_20240530-i686-w64-mingw32.zip", - "checksum": "SHA-256:590bfb10576702639825581cc00c445da6e577012840a787137417e80d15f46d", - "size": "366573064" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/riscv32-esp-elf-14.2.0_20241119-i686-w64-mingw32.zip", + "archiveFileName": "riscv32-esp-elf-14.2.0_20241119-i686-w64-mingw32.zip", + "checksum": "SHA-256:54193a97bd75205678ead8d11f00b351cfa3c2a6e5ab5d966341358b9f9422d7", + "size": "672055172" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-13.2.0_20240530/riscv32-esp-elf-13.2.0_20240530-x86_64-w64-mingw32.zip", - "archiveFileName": "riscv32-esp-elf-13.2.0_20240530-x86_64-w64-mingw32.zip", - "checksum": "SHA-256:413eb9f6adf8fdaf25544d014c850fc09eb38bb93a2fc5ebd107ab1b0de1bb3a", - "size": "369820297" + "url": "https://github.com/espressif/crosstool-NG/releases/download/esp-14.2.0_20241119/riscv32-esp-elf-14.2.0_20241119-x86_64-w64-mingw32.zip", + "archiveFileName": "riscv32-esp-elf-14.2.0_20241119-x86_64-w64-mingw32.zip", + "checksum": "SHA-256:24c8407fa467448d394e0639436a5ede31caf1838e35e8435e19df58ebed438c", + "size": "677812937" } ] }, From 55f4f1bfa87acae8713fadc39b2f2c3f0d416f2e Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 18 Feb 2025 19:10:54 +0200 Subject: [PATCH 38/79] Update core version to 3.2.0 --- cores/esp32/esp_arduino_version.h | 4 ++-- libraries/ArduinoOTA/library.properties | 2 +- libraries/AsyncUDP/library.properties | 2 +- libraries/BLE/library.properties | 2 +- libraries/BluetoothSerial/library.properties | 2 +- libraries/DNSServer/library.properties | 2 +- libraries/EEPROM/library.properties | 2 +- libraries/ESP32/library.properties | 2 +- libraries/ESP_I2S/library.properties | 2 +- libraries/ESP_NOW/library.properties | 2 +- libraries/ESP_SR/library.properties | 2 +- libraries/ESPmDNS/library.properties | 2 +- libraries/Ethernet/library.properties | 2 +- libraries/FFat/library.properties | 2 +- libraries/FS/library.properties | 2 +- libraries/HTTPClient/library.properties | 2 +- libraries/HTTPUpdate/library.properties | 2 +- libraries/HTTPUpdateServer/library.properties | 2 +- libraries/Insights/library.properties | 2 +- libraries/LittleFS/library.properties | 2 +- libraries/Matter/library.properties | 2 +- libraries/NetBIOS/library.properties | 2 +- libraries/Network/library.properties | 2 +- libraries/NetworkClientSecure/library.properties | 2 +- libraries/OpenThread/library.properties | 2 +- libraries/PPP/library.properties | 2 +- libraries/Preferences/library.properties | 2 +- libraries/RainMaker/library.properties | 2 +- libraries/SD/library.properties | 2 +- libraries/SD_MMC/library.properties | 2 +- libraries/SPI/library.properties | 2 +- libraries/SPIFFS/library.properties | 2 +- libraries/SimpleBLE/library.properties | 2 +- libraries/TFLiteMicro/library.properties | 2 +- libraries/Ticker/library.properties | 2 +- libraries/USB/library.properties | 2 +- libraries/Update/library.properties | 2 +- libraries/WebServer/library.properties | 2 +- libraries/WiFi/library.properties | 2 +- libraries/WiFiProv/library.properties | 2 +- libraries/Wire/library.properties | 2 +- libraries/Zigbee/library.properties | 2 +- package.json | 2 +- platform.txt | 2 +- 44 files changed, 45 insertions(+), 45 deletions(-) diff --git a/cores/esp32/esp_arduino_version.h b/cores/esp32/esp_arduino_version.h index f8b00d3a1dd..b1355e908ae 100644 --- a/cores/esp32/esp_arduino_version.h +++ b/cores/esp32/esp_arduino_version.h @@ -21,9 +21,9 @@ extern "C" { /** Major version number (X.x.x) */ #define ESP_ARDUINO_VERSION_MAJOR 3 /** Minor version number (x.X.x) */ -#define ESP_ARDUINO_VERSION_MINOR 1 +#define ESP_ARDUINO_VERSION_MINOR 2 /** Patch version number (x.x.X) */ -#define ESP_ARDUINO_VERSION_PATCH 3 +#define ESP_ARDUINO_VERSION_PATCH 0 /** * Macro to convert ARDUINO version number into an integer diff --git a/libraries/ArduinoOTA/library.properties b/libraries/ArduinoOTA/library.properties index bcccbe56b5e..0796eddf318 100644 --- a/libraries/ArduinoOTA/library.properties +++ b/libraries/ArduinoOTA/library.properties @@ -1,5 +1,5 @@ name=ArduinoOTA -version=3.1.3 +version=3.2.0 author=Ivan Grokhotkov and Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download. diff --git a/libraries/AsyncUDP/library.properties b/libraries/AsyncUDP/library.properties index 38543425ee1..116dcbacaa8 100644 --- a/libraries/AsyncUDP/library.properties +++ b/libraries/AsyncUDP/library.properties @@ -1,5 +1,5 @@ name=ESP32 Async UDP -version=3.1.3 +version=3.2.0 author=Me-No-Dev maintainer=Me-No-Dev sentence=Async UDP Library for ESP32 diff --git a/libraries/BLE/library.properties b/libraries/BLE/library.properties index 12da8222e0c..7ef636223ec 100644 --- a/libraries/BLE/library.properties +++ b/libraries/BLE/library.properties @@ -1,5 +1,5 @@ name=BLE -version=3.1.3 +version=3.2.0 author=Neil Kolban maintainer=Dariusz Krempa sentence=BLE functions for ESP32 diff --git a/libraries/BluetoothSerial/library.properties b/libraries/BluetoothSerial/library.properties index 1cdb6302a8a..0a382410bba 100644 --- a/libraries/BluetoothSerial/library.properties +++ b/libraries/BluetoothSerial/library.properties @@ -1,5 +1,5 @@ name=BluetoothSerial -version=3.1.3 +version=3.2.0 author=Evandro Copercini maintainer=Evandro Copercini sentence=Simple UART to Classical Bluetooth bridge for ESP32 diff --git a/libraries/DNSServer/library.properties b/libraries/DNSServer/library.properties index 7531b2e52cd..5e70a6ec03a 100644 --- a/libraries/DNSServer/library.properties +++ b/libraries/DNSServer/library.properties @@ -1,5 +1,5 @@ name=DNSServer -version=3.1.3 +version=3.2.0 author=Kristijan Novoselić maintainer=Kristijan Novoselić, sentence=A simple DNS server for ESP32. diff --git a/libraries/EEPROM/library.properties b/libraries/EEPROM/library.properties index 4eab97edf9a..c7e48501c04 100644 --- a/libraries/EEPROM/library.properties +++ b/libraries/EEPROM/library.properties @@ -1,5 +1,5 @@ name=EEPROM -version=3.1.3 +version=3.2.0 author=Ivan Grokhotkov maintainer=Paolo Becchi sentence=Enables reading and writing data a sequential, addressable FLASH storage diff --git a/libraries/ESP32/library.properties b/libraries/ESP32/library.properties index d8c88776595..7ebc69be71f 100644 --- a/libraries/ESP32/library.properties +++ b/libraries/ESP32/library.properties @@ -1,5 +1,5 @@ name=ESP32 -version=3.1.3 +version=3.2.0 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 sketches examples diff --git a/libraries/ESP_I2S/library.properties b/libraries/ESP_I2S/library.properties index 44493d67ff2..263e9823275 100644 --- a/libraries/ESP_I2S/library.properties +++ b/libraries/ESP_I2S/library.properties @@ -1,5 +1,5 @@ name=ESP_I2S -version=3.1.3 +version=3.2.0 author=me-no-dev maintainer=me-no-dev sentence=Library for ESP I2S communication diff --git a/libraries/ESP_NOW/library.properties b/libraries/ESP_NOW/library.properties index 79c97131fb3..f3e5c109a9b 100644 --- a/libraries/ESP_NOW/library.properties +++ b/libraries/ESP_NOW/library.properties @@ -1,5 +1,5 @@ name=ESP_NOW -version=3.1.3 +version=3.2.0 author=me-no-dev maintainer=P-R-O-C-H-Y sentence=Library for ESP_NOW diff --git a/libraries/ESP_SR/library.properties b/libraries/ESP_SR/library.properties index 6a59c25102f..295761bd9fb 100644 --- a/libraries/ESP_SR/library.properties +++ b/libraries/ESP_SR/library.properties @@ -1,5 +1,5 @@ name=ESP_SR -version=3.1.3 +version=3.2.0 author=me-no-dev maintainer=me-no-dev sentence=Library for ESP Sound Recognition diff --git a/libraries/ESPmDNS/library.properties b/libraries/ESPmDNS/library.properties index 925bb4fb258..6d36d61b783 100644 --- a/libraries/ESPmDNS/library.properties +++ b/libraries/ESPmDNS/library.properties @@ -1,5 +1,5 @@ name=ESPmDNS -version=3.1.3 +version=3.2.0 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 mDNS Library diff --git a/libraries/Ethernet/library.properties b/libraries/Ethernet/library.properties index da3bbbb2211..d34ae036417 100644 --- a/libraries/Ethernet/library.properties +++ b/libraries/Ethernet/library.properties @@ -1,5 +1,5 @@ name=Ethernet -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection (local and Internet) using the ESP32 Ethernet. diff --git a/libraries/FFat/library.properties b/libraries/FFat/library.properties index 574e184ba02..35940fd5472 100644 --- a/libraries/FFat/library.properties +++ b/libraries/FFat/library.properties @@ -1,5 +1,5 @@ name=FFat -version=3.1.3 +version=3.2.0 author=Hristo Gochkov, Ivan Grokhtkov, Larry Bernstone maintainer=Hristo Gochkov sentence=ESP32 FAT on Flash File System diff --git a/libraries/FS/library.properties b/libraries/FS/library.properties index 91fb4396ed4..07bd296bb83 100644 --- a/libraries/FS/library.properties +++ b/libraries/FS/library.properties @@ -1,5 +1,5 @@ name=FS -version=3.1.3 +version=3.2.0 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 File System diff --git a/libraries/HTTPClient/library.properties b/libraries/HTTPClient/library.properties index 347ac4f122f..f2dafc36d1b 100644 --- a/libraries/HTTPClient/library.properties +++ b/libraries/HTTPClient/library.properties @@ -1,5 +1,5 @@ name=HTTPClient -version=3.1.3 +version=3.2.0 author=Markus Sattler maintainer=Markus Sattler sentence=HTTP Client for ESP32 diff --git a/libraries/HTTPUpdate/library.properties b/libraries/HTTPUpdate/library.properties index 2bcb06bcad2..419f3b97b3f 100644 --- a/libraries/HTTPUpdate/library.properties +++ b/libraries/HTTPUpdate/library.properties @@ -1,5 +1,5 @@ name=HTTPUpdate -version=3.1.3 +version=3.2.0 author=Markus Sattler maintainer=Markus Sattler sentence=Http Update for ESP32 diff --git a/libraries/HTTPUpdateServer/library.properties b/libraries/HTTPUpdateServer/library.properties index 8eac2aab4cf..9c793a26ac8 100644 --- a/libraries/HTTPUpdateServer/library.properties +++ b/libraries/HTTPUpdateServer/library.properties @@ -1,5 +1,5 @@ name=HTTPUpdateServer -version=3.1.3 +version=3.2.0 author=Hristo Kapanakov maintainer= sentence=Simple HTTP Update server based on the WebServer diff --git a/libraries/Insights/library.properties b/libraries/Insights/library.properties index b33dd15755a..fefe5aab177 100644 --- a/libraries/Insights/library.properties +++ b/libraries/Insights/library.properties @@ -1,5 +1,5 @@ name=ESP Insights -version=3.1.3 +version=3.2.0 author=Sanket Wadekar maintainer=Sanket Wadekar sentence=ESP Insights diff --git a/libraries/LittleFS/library.properties b/libraries/LittleFS/library.properties index 233e5b1ab56..a9dae69b7f8 100644 --- a/libraries/LittleFS/library.properties +++ b/libraries/LittleFS/library.properties @@ -1,5 +1,5 @@ name=LittleFS -version=3.1.3 +version=3.2.0 author= maintainer= sentence=LittleFS for esp32 diff --git a/libraries/Matter/library.properties b/libraries/Matter/library.properties index f0eea397fe8..ac9e0964ab5 100644 --- a/libraries/Matter/library.properties +++ b/libraries/Matter/library.properties @@ -1,5 +1,5 @@ name=Matter -version=3.1.3 +version=3.2.0 author=Rodrigo Garcia | GitHub @SuGlider maintainer=Rodrigo Garcia sentence=Library for supporting Matter environment on ESP32. diff --git a/libraries/NetBIOS/library.properties b/libraries/NetBIOS/library.properties index bf223a34828..5f134bfdc55 100644 --- a/libraries/NetBIOS/library.properties +++ b/libraries/NetBIOS/library.properties @@ -1,5 +1,5 @@ name=NetBIOS -version=3.1.3 +version=3.2.0 author=Pablo@xpablo.cz maintainer=Hristo Gochkov sentence=Enables NBNS (NetBIOS) name resolution. diff --git a/libraries/Network/library.properties b/libraries/Network/library.properties index bd5d5677dca..0b821e08d77 100644 --- a/libraries/Network/library.properties +++ b/libraries/Network/library.properties @@ -1,5 +1,5 @@ name=Networking -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=General network management library. diff --git a/libraries/NetworkClientSecure/library.properties b/libraries/NetworkClientSecure/library.properties index 0754e59fba5..455dea6a2bf 100644 --- a/libraries/NetworkClientSecure/library.properties +++ b/libraries/NetworkClientSecure/library.properties @@ -1,5 +1,5 @@ name=NetworkClientSecure -version=3.1.3 +version=3.2.0 author=Evandro Luis Copercini maintainer=Github Community sentence=Enables secure network connection (local and Internet) using the ESP32 built-in WiFi. diff --git a/libraries/OpenThread/library.properties b/libraries/OpenThread/library.properties index 078c4b58acc..0e547d188aa 100644 --- a/libraries/OpenThread/library.properties +++ b/libraries/OpenThread/library.properties @@ -1,5 +1,5 @@ name=OpenThread -version=3.1.3 +version=3.2.0 author=Rodrigo Garcia | GitHub @SuGlider maintainer=Rodrigo Garcia sentence=Library for OpenThread Network on ESP32. diff --git a/libraries/PPP/library.properties b/libraries/PPP/library.properties index 2d5d3d83877..7158a027b0a 100644 --- a/libraries/PPP/library.properties +++ b/libraries/PPP/library.properties @@ -1,5 +1,5 @@ name=PPP -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection using GSM Modem. diff --git a/libraries/Preferences/library.properties b/libraries/Preferences/library.properties index f6cdb8a074c..eb0158e4932 100644 --- a/libraries/Preferences/library.properties +++ b/libraries/Preferences/library.properties @@ -1,5 +1,5 @@ name=Preferences -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Provides friendly access to ESP32's Non-Volatile Storage diff --git a/libraries/RainMaker/library.properties b/libraries/RainMaker/library.properties index 6b8ba658eb4..95ce14d6708 100644 --- a/libraries/RainMaker/library.properties +++ b/libraries/RainMaker/library.properties @@ -1,5 +1,5 @@ name=ESP RainMaker -version=3.1.3 +version=3.2.0 author=Sweety Mhaiske maintainer=Hristo Gochkov sentence=ESP RainMaker Support diff --git a/libraries/SD/library.properties b/libraries/SD/library.properties index 00766c48470..66c4f5cfafd 100644 --- a/libraries/SD/library.properties +++ b/libraries/SD/library.properties @@ -1,5 +1,5 @@ name=SD -version=3.1.3 +version=3.2.0 author=Arduino, SparkFun maintainer=Arduino sentence=Enables reading and writing on SD cards. For all Arduino boards. diff --git a/libraries/SD_MMC/library.properties b/libraries/SD_MMC/library.properties index 0cc0a80afd2..855390e5057 100644 --- a/libraries/SD_MMC/library.properties +++ b/libraries/SD_MMC/library.properties @@ -1,5 +1,5 @@ name=SD_MMC -version=3.1.3 +version=3.2.0 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 SDMMC File System diff --git a/libraries/SPI/library.properties b/libraries/SPI/library.properties index 57e44241438..64db93aceeb 100644 --- a/libraries/SPI/library.properties +++ b/libraries/SPI/library.properties @@ -1,5 +1,5 @@ name=SPI -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For all Arduino boards, BUT Arduino DUE. diff --git a/libraries/SPIFFS/library.properties b/libraries/SPIFFS/library.properties index 5ecc75c000d..78f77fe9794 100644 --- a/libraries/SPIFFS/library.properties +++ b/libraries/SPIFFS/library.properties @@ -1,5 +1,5 @@ name=SPIFFS -version=3.1.3 +version=3.2.0 author=Hristo Gochkov, Ivan Grokhtkov maintainer=Hristo Gochkov sentence=ESP32 SPIFFS File System diff --git a/libraries/SimpleBLE/library.properties b/libraries/SimpleBLE/library.properties index d5570c41751..ad5e10d3acb 100644 --- a/libraries/SimpleBLE/library.properties +++ b/libraries/SimpleBLE/library.properties @@ -1,5 +1,5 @@ name=SimpleBLE -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Provides really simple BLE advertizer with just on and off diff --git a/libraries/TFLiteMicro/library.properties b/libraries/TFLiteMicro/library.properties index 259df824a45..1e8db045610 100644 --- a/libraries/TFLiteMicro/library.properties +++ b/libraries/TFLiteMicro/library.properties @@ -1,5 +1,5 @@ name=TFLite Micro -version=3.1.3 +version=3.2.0 author=Sanket Wadekar maintainer=Sanket Wadekar sentence=TensorFlow Lite for Microcontrollers diff --git a/libraries/Ticker/library.properties b/libraries/Ticker/library.properties index 7f2cdab5220..975db96d1ad 100644 --- a/libraries/Ticker/library.properties +++ b/libraries/Ticker/library.properties @@ -1,5 +1,5 @@ name=Ticker -version=3.1.3 +version=3.2.0 author=Bert Melis maintainer=Hristo Gochkov sentence=Allows to call functions with a given interval. diff --git a/libraries/USB/library.properties b/libraries/USB/library.properties index e0bc6c4b7e7..9d47dfc6719 100644 --- a/libraries/USB/library.properties +++ b/libraries/USB/library.properties @@ -1,5 +1,5 @@ name=USB -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=ESP32S2 USB Library diff --git a/libraries/Update/library.properties b/libraries/Update/library.properties index f81897a64d6..c3ee8f7e506 100644 --- a/libraries/Update/library.properties +++ b/libraries/Update/library.properties @@ -1,5 +1,5 @@ name=Update -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=ESP32 Sketch Update Library diff --git a/libraries/WebServer/library.properties b/libraries/WebServer/library.properties index c9153541cb2..2a9ff530d57 100644 --- a/libraries/WebServer/library.properties +++ b/libraries/WebServer/library.properties @@ -1,5 +1,5 @@ name=WebServer -version=3.1.3 +version=3.2.0 author=Ivan Grokhotkov maintainer=Ivan Grokhtkov sentence=Simple web server library diff --git a/libraries/WiFi/library.properties b/libraries/WiFi/library.properties index e72f082f8e6..03112c2fcc6 100644 --- a/libraries/WiFi/library.properties +++ b/libraries/WiFi/library.properties @@ -1,5 +1,5 @@ name=WiFi -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Enables network connection (local and Internet) using the ESP32 built-in WiFi. diff --git a/libraries/WiFiProv/library.properties b/libraries/WiFiProv/library.properties index 6334a5be5c4..13a63c50bb1 100644 --- a/libraries/WiFiProv/library.properties +++ b/libraries/WiFiProv/library.properties @@ -1,5 +1,5 @@ name=WiFiProv -version=3.1.3 +version=3.2.0 author=Switi Mhaiske maintainer=Hristo Gochkov sentence=Enables provisioning. diff --git a/libraries/Wire/library.properties b/libraries/Wire/library.properties index 044ba74c3d0..655f4bd3194 100644 --- a/libraries/Wire/library.properties +++ b/libraries/Wire/library.properties @@ -1,5 +1,5 @@ name=Wire -version=3.1.3 +version=3.2.0 author=Hristo Gochkov maintainer=Hristo Gochkov sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. For esp8266 boards. diff --git a/libraries/Zigbee/library.properties b/libraries/Zigbee/library.properties index 29704db1a92..9a558d70216 100644 --- a/libraries/Zigbee/library.properties +++ b/libraries/Zigbee/library.properties @@ -1,5 +1,5 @@ name=Zigbee -version=3.1.3 +version=3.2.0 author=P-R-O-C-H-Y maintainer=Jan Procházka sentence=Enables zigbee connection with the ESP32 diff --git a/package.json b/package.json index 3a5c290a1cd..9c918733209 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "framework-arduinoespressif32", - "version": "3.1.3", + "version": "3.2.0", "description": "Arduino Wiring-based Framework for the Espressif ESP32, ESP32-P4, ESP32-S and ESP32-C series of SoCs", "keywords": [ "framework", diff --git a/platform.txt b/platform.txt index 1c718369587..65be05b3bf4 100644 --- a/platform.txt +++ b/platform.txt @@ -1,5 +1,5 @@ name=ESP32 Arduino -version=3.1.3 +version=3.2.0 tools.esp32-arduino-libs.path={runtime.platform.path}/tools/esp32-arduino-libs tools.esp32-arduino-libs.path.windows={runtime.platform.path}\tools\esp32-arduino-libs From 646785e08668c299fc8c8a90ead588a57385d509 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 18 Feb 2025 20:01:18 -0300 Subject: [PATCH 39/79] feat(LP_UART): Implements the ESP32-C6/ESP32-P4 Low Power UART as a possible HardwareSerial port (#10967) * feat(uart): adds low power uart peripheral into hardware serial class * feat(lp_uart): pin setting for lp uart plus esp32p4 fixes * fix(uart): keeps the test as it was before. * fix(uart): updates the copyright year reference * fix(uart): updates the copyright year reference * feat(lp_uart): supports any number of lp uart port for the future * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: Me No Dev Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- cores/esp32/HardwareSerial.cpp | 126 ++++++++++------ cores/esp32/HardwareSerial.h | 23 ++- cores/esp32/esp32-hal-uart.c | 265 ++++++++++++++++++++++++++++----- cores/esp32/esp32-hal-uart.h | 3 +- 4 files changed, 330 insertions(+), 87 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index fb93dad1c47..c14dac7bc7e 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -23,40 +23,52 @@ #define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE -1 #endif +#if (SOC_UART_LP_NUM >= 1) +#define UART_HW_FIFO_LEN(uart_num) ((uart_num < SOC_UART_HP_NUM) ? SOC_UART_FIFO_LEN : SOC_LP_UART_FIFO_LEN) +#else +#define UART_HW_FIFO_LEN(uart_num) SOC_UART_FIFO_LEN +#endif + void serialEvent(void) __attribute__((weak)); -#if SOC_UART_HP_NUM > 1 +#if SOC_UART_NUM > 1 void serialEvent1(void) __attribute__((weak)); -#endif /* SOC_UART_HP_NUM > 1 */ +#endif /* SOC_UART_NUM > 1 */ -#if SOC_UART_HP_NUM > 2 +#if SOC_UART_NUM > 2 void serialEvent2(void) __attribute__((weak)); -#endif /* SOC_UART_HP_NUM > 2 */ +#endif /* SOC_UART_NUM > 2 */ -#if SOC_UART_HP_NUM > 3 +#if SOC_UART_NUM > 3 void serialEvent3(void) __attribute__((weak)); -#endif /* SOC_UART_HP_NUM > 3 */ +#endif /* SOC_UART_NUM > 3 */ -#if SOC_UART_HP_NUM > 4 +#if SOC_UART_NUM > 4 void serialEvent4(void) __attribute__((weak)); -#endif /* SOC_UART_HP_NUM > 4 */ +#endif /* SOC_UART_NUM > 4 */ + +#if SOC_UART_NUM > 5 +void serialEvent5(void) __attribute__((weak)); +#endif /* SOC_UART_NUM > 5 */ #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) // There is always Seria0 for UART0 HardwareSerial Serial0(0); -#if SOC_UART_HP_NUM > 1 +#if SOC_UART_NUM > 1 HardwareSerial Serial1(1); #endif -#if SOC_UART_HP_NUM > 2 +#if SOC_UART_NUM > 2 HardwareSerial Serial2(2); #endif -#if SOC_UART_HP_NUM > 3 +#if SOC_UART_NUM > 3 HardwareSerial Serial3(3); #endif -#if SOC_UART_HP_NUM > 4 +#if SOC_UART_NUM > 4 HardwareSerial Serial4(4); #endif - +#if (SOC_UART_NUM > 5) +HardwareSerial Serial5(5); +#endif #if HWCDC_SERIAL_IS_DEFINED == 1 // Hardware JTAG CDC Event extern void HWCDCSerialEvent(void) __attribute__((weak)); #endif @@ -81,26 +93,31 @@ void serialEventRun(void) { if (serialEvent && Serial0.available()) { serialEvent(); } -#if SOC_UART_HP_NUM > 1 +#if SOC_UART_NUM > 1 if (serialEvent1 && Serial1.available()) { serialEvent1(); } #endif -#if SOC_UART_HP_NUM > 2 +#if SOC_UART_NUM > 2 if (serialEvent2 && Serial2.available()) { serialEvent2(); } #endif -#if SOC_UART_HP_NUM > 3 +#if SOC_UART_NUM > 3 if (serialEvent3 && Serial3.available()) { serialEvent3(); } #endif -#if SOC_UART_HP_NUM > 4 +#if SOC_UART_NUM > 4 if (serialEvent4 && Serial4.available()) { serialEvent4(); } #endif +#if SOC_UART_NUM > 5 + if (serialEvent5 && Serial5.available()) { + serialEvent5(); + } +#endif } #endif @@ -185,7 +202,8 @@ void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout) { // in case that onReceive() shall work only with RX Timeout, FIFO shall be high // this is a work around for an IDF issue with events and low FIFO Full value (< 3) - if (_onReceiveTimeout) { + // Not valid for the LP UART + if (_onReceiveTimeout && _uart_nr < SOC_UART_HP_NUM) { uartSetRxFIFOFull(_uart, 120); log_w("OnReceive is set to Timeout only, thus FIFO Full is now 120 bytes."); } @@ -207,12 +225,13 @@ bool HardwareSerial::setRxFIFOFull(uint8_t fifoBytes) { HSERIAL_MUTEX_LOCK(); // in case that onReceive() shall work only with RX Timeout, FIFO shall be high // this is a work around for an IDF issue with events and low FIFO Full value (< 3) - if (_onReceiveCB != NULL && _onReceiveTimeout) { + // Not valid for the LP UART + if (_onReceiveCB != NULL && _onReceiveTimeout && _uart_nr < SOC_UART_HP_NUM) { fifoBytes = 120; log_w("OnReceive is set to Timeout only, thus FIFO Full is now 120 bytes."); } bool retCode = uartSetRxFIFOFull(_uart, fifoBytes); // Set new timeout - if (fifoBytes > 0 && fifoBytes < SOC_UART_FIFO_LEN - 1) { + if (fifoBytes > 0 && fifoBytes < UART_HW_FIFO_LEN(_uart_nr) - 1) { _rxFIFOFull = fifoBytes; } HSERIAL_MUTEX_UNLOCK(); @@ -298,8 +317,8 @@ void HardwareSerial::_uartEventTask(void *args) { } void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd) { - if (_uart_nr >= SOC_UART_HP_NUM) { - log_e("Serial number is invalid, please use a number from 0 to %u", SOC_UART_HP_NUM - 1); + if (_uart_nr >= SOC_UART_NUM) { + log_e("Serial number is invalid, please use a number from 0 to %u", SOC_UART_NUM - 1); return; } @@ -333,7 +352,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in txPin = _txPin < 0 ? (int8_t)SOC_TX0 : _txPin; } break; -#if SOC_UART_HP_NUM > 1 // may save some flash bytes... +#if SOC_UART_HP_NUM > 1 case UART_NUM_1: if (rxPin < 0 && txPin < 0) { // do not change RX1/TX1 if it has already been set before @@ -341,8 +360,8 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in txPin = _txPin < 0 ? (int8_t)TX1 : _txPin; } break; -#endif -#if SOC_UART_HP_NUM > 2 // may save some flash bytes... +#endif // UART_NUM_1 +#if SOC_UART_HP_NUM > 2 case UART_NUM_2: if (rxPin < 0 && txPin < 0) { // do not change RX2/TX2 if it has already been set before @@ -354,11 +373,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in #endif } break; -#endif -#if SOC_UART_HP_NUM > 3 // may save some flash bytes... +#endif // UART_NUM_2 +#if SOC_UART_HP_NUM > 3 case UART_NUM_3: if (rxPin < 0 && txPin < 0) { - // do not change RX2/TX2 if it has already been set before + // do not change RX3/TX3 if it has already been set before #ifdef RX3 rxPin = _rxPin < 0 ? (int8_t)RX3 : _rxPin; #endif @@ -367,11 +386,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in #endif } break; -#endif -#if SOC_UART_HP_NUM > 4 // may save some flash bytes... +#endif // UART_NUM_3 +#if SOC_UART_HP_NUM > 4 case UART_NUM_4: if (rxPin < 0 && txPin < 0) { - // do not change RX2/TX2 if it has already been set before + // do not change RX4/TX4 if it has already been set before #ifdef RX4 rxPin = _rxPin < 0 ? (int8_t)RX4 : _rxPin; #endif @@ -380,7 +399,20 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in #endif } break; +#endif // UART_NUM_4 +#if (SOC_UART_LP_NUM >= 1) + case LP_UART_NUM_0: + if (rxPin < 0 && txPin < 0) { + // do not change RX0_LP/TX0_LP if it has already been set before +#ifdef LP_RX0 + rxPin = _rxPin < 0 ? (int8_t)LP_RX0 : _rxPin; +#endif +#ifdef LP_TX0 + txPin = _txPin < 0 ? (int8_t)LP_TX0 : _txPin; #endif + } + break; +#endif // LP_UART_NUM_0 } } @@ -445,7 +477,8 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in if (!_rxFIFOFull) { // it has not being changed before calling begin() // set a default FIFO Full value for the IDF driver uint8_t fifoFull = 1; - if (baud > 57600 || (_onReceiveCB != NULL && _onReceiveTimeout)) { + // if baud rate is higher than 57600 or onReceive() is set, it will set FIFO Full to 120 bytes, except for LP UART + if (_uart_nr < SOC_UART_HP_NUM && (baud > 57600 || (_onReceiveCB != NULL && _onReceiveTimeout))) { fifoFull = 120; } uartSetRxFIFOFull(_uart, fifoFull); @@ -477,6 +510,12 @@ void HardwareSerial::setDebugOutput(bool en) { if (_uart == 0) { return; } +#if (SOC_UART_LP_NUM >= 1) + if (_uart_nr >= SOC_UART_HP_NUM) { + log_e("LP UART does not support Debug Output."); + return; + } +#endif if (en) { uartSetDebug(_uart); } else { @@ -581,34 +620,37 @@ bool HardwareSerial::setMode(SerialMode mode) { } // minimum total RX Buffer size is the UART FIFO space (128 bytes for most SoC) + 1. IDF imposition. +// LP UART has FIFO of 16 bytes size_t HardwareSerial::setRxBufferSize(size_t new_size) { if (_uart) { log_e("RX Buffer can't be resized when Serial is already running. Set it before calling begin()."); return 0; } - - if (new_size <= SOC_UART_FIFO_LEN) { - log_w("RX Buffer set to minimum value: %d.", SOC_UART_FIFO_LEN + 1); // ESP32, S2, S3 and C3 means higher than 128 - new_size = SOC_UART_FIFO_LEN + 1; + uint8_t FIFOLen = UART_HW_FIFO_LEN(_uart_nr); + // Valid value is higher than the FIFO length + if (new_size <= FIFOLen) { + new_size = FIFOLen + 1; + log_w("RX Buffer set to minimum value: %d.", new_size); } _rxBufferSize = new_size; return _rxBufferSize; } -// minimum total TX Buffer size is the UART FIFO space (128 bytes for most SoC). +// minimum total TX Buffer size is the UART FIFO space (128 bytes for most SoC) + 1. +// LP UART has FIFO of 16 bytes size_t HardwareSerial::setTxBufferSize(size_t new_size) { if (_uart) { log_e("TX Buffer can't be resized when Serial is already running. Set it before calling begin()."); return 0; } - - if (new_size <= SOC_UART_FIFO_LEN) { - log_w("TX Buffer set to minimum value: %d.", SOC_UART_FIFO_LEN); // ESP32, S2, S3 and C3 means higher than 128 - _txBufferSize = 0; // it will use just UART FIFO with SOC_UART_FIFO_LEN bytes (128 for most SoC) - return SOC_UART_FIFO_LEN; + uint8_t FIFOLen = UART_HW_FIFO_LEN(_uart_nr); + // Valid values are zero or higher than the FIFO length + if (new_size > 0 && new_size <= FIFOLen) { + new_size = FIFOLen + 1; + log_w("TX Buffer set to minimum value: %d.", new_size); } // if new_size is higher than SOC_UART_FIFO_LEN, TX Ringbuffer will be active and it will be used to report back "availableToWrite()" _txBufferSize = new_size; diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index a33d5def34d..e52428f0dd5 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -212,6 +212,16 @@ typedef enum { #endif #endif /* SOC_UART_HP_NUM > 2 */ +#if SOC_UART_LP_NUM >= 1 +#ifndef LP_RX0 +#define LP_RX0 (gpio_num_t) LP_U0RXD_GPIO_NUM +#endif + +#ifndef LP_TX0 +#define LP_TX0 (gpio_num_t) LP_U0TXD_GPIO_NUM +#endif +#endif /* SOC_UART_LP_NUM >= 1 */ + typedef std::function OnReceiveCb; typedef std::function OnReceiveErrorCb; @@ -259,7 +269,7 @@ class HardwareSerial : public Stream { // rxfifo_full_thrhd if the UART Flow Control Threshold in the UART FIFO (max 127) void begin( unsigned long baud, uint32_t config = SERIAL_8N1, int8_t rxPin = -1, int8_t txPin = -1, bool invert = false, unsigned long timeout_ms = 20000UL, - uint8_t rxfifo_full_thrhd = 112 + uint8_t rxfifo_full_thrhd = 120 ); void end(void); void updateBaudRate(unsigned long baud); @@ -365,18 +375,21 @@ extern void serialEventRun(void) __attribute__((weak)); #endif // ARDUINO_USB_CDC_ON_BOOT // There is always Seria0 for UART0 extern HardwareSerial Serial0; -#if SOC_UART_HP_NUM > 1 +#if SOC_UART_NUM > 1 extern HardwareSerial Serial1; #endif -#if SOC_UART_HP_NUM > 2 +#if SOC_UART_NUM > 2 extern HardwareSerial Serial2; #endif -#if SOC_UART_HP_NUM > 3 +#if SOC_UART_NUM > 3 extern HardwareSerial Serial3; #endif -#if SOC_UART_HP_NUM > 4 +#if SOC_UART_NUM > 4 extern HardwareSerial Serial4; #endif +#if SOC_UART_NUM > 5 +extern HardwareSerial Serial5; +#endif #endif //!defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) #endif // HardwareSerial_h diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 34a2660e3a3..59a95a084f6 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -1,4 +1,4 @@ -// Copyright 2015-2024 Espressif Systems (Shanghai) PTE LTD +// Copyright 2015-2025 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,6 +33,11 @@ #include "hal/gpio_hal.h" #include "esp_rom_gpio.h" +#include "driver/rtc_io.h" +#include "driver/lp_io.h" +#include "soc/uart_periph.h" +#include "esp_private/uart_share_hw_ctrl.h" + static int s_uart_debug_nr = 0; // UART number for debug output #define REF_TICK_BAUDRATE_LIMIT 250000 // this is maximum UART badrate using REF_TICK as clock @@ -62,18 +67,21 @@ struct uart_struct_t { static uart_t _uart_bus_array[] = { {0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, -#if SOC_UART_HP_NUM > 1 +#if SOC_UART_NUM > 1 {1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, #endif -#if SOC_UART_HP_NUM > 2 +#if SOC_UART_NUM > 2 {2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, #endif -#if SOC_UART_HP_NUM > 3 +#if SOC_UART_NUM > 3 {3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, #endif -#if SOC_UART_HP_NUM > 4 +#if SOC_UART_NUM > 4 {4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, #endif +#if SOC_UART_NUM > 5 + {5, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, +#endif }; #else @@ -88,27 +96,121 @@ static uart_t _uart_bus_array[] = { static uart_t _uart_bus_array[] = { {NULL, 0, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, -#if SOC_UART_HP_NUM > 1 +#if SOC_UART_NUM > 1 {NULL, 1, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, #endif -#if SOC_UART_HP_NUM > 2 +#if SOC_UART_NUM > 2 {NULL, 2, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, #endif -#if SOC_UART_HP_NUM > 3 +#if SOC_UART_NUM > 3 {NULL, 3, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, #endif -#if SOC_UART_HP_NUM > 4 +#if SOC_UART_NUM > 4 {NULL, 4, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, #endif +#if SOC_UART_NUM > 5 + {NULL, 5, false, 0, NULL, -1, -1, -1, -1, 0, 0, 0, 0, false, 0}, +#endif }; #endif +#if SOC_UART_LP_NUM >= 1 +// LP UART enable pins routine +static bool lp_uart_config_io(uint8_t uart_num, int8_t pin, rtc_gpio_mode_t direction, uint32_t idx) { + /* Skip configuration if the LP_IO is -1 */ + if (pin < 0) { + return true; + } + + // Initialize LP_IO + if (rtc_gpio_init(pin) != ESP_OK) { + log_e("Failed to initialize LP_IO %d", pin); + return false; + } + + // Set LP_IO direction + if (rtc_gpio_set_direction(pin, direction) != ESP_OK) { + log_e("Failed to set LP_IO %d direction", pin); + return false; + } + + // Connect pins + const uart_periph_sig_t *upin = &uart_periph_signal[uart_num].pins[idx]; +#if !SOC_LP_GPIO_MATRIX_SUPPORTED // ESP32-C6/C61/C5 + // When LP_IO Matrix is not support, LP_IO Mux must be connected to the pins + if (rtc_gpio_iomux_func_sel(pin, upin->iomux_func) != ESP_OK) { + log_e("Failed to set LP_IO pin %d into Mux function", pin); + return false; + } +#else // So far, only ESP32-P4 + // If the configured pin is the default LP_IO Mux pin for LP UART, then set the LP_IO MUX function + if (upin->default_gpio == pin) { + if (rtc_gpio_iomux_func_sel(pin, upin->iomux_func) != ESP_OK) { + log_e("Failed to set LP_IO pin %d into Mux function", pin); + return false; + } + } else { + // Otherwise, set the LP_IO Matrix and select FUNC1 + if (rtc_gpio_iomux_func_sel(pin, 1) != ESP_OK) { + log_e("Failed to set LP_IO pin %d into Mux function GPIO", pin); + return false; + } + // Connect the LP_IO to the LP UART peripheral signal + esp_err_t ret; + if (direction == RTC_GPIO_MODE_OUTPUT_ONLY) { + ret = lp_gpio_connect_out_signal(pin, UART_PERIPH_SIGNAL(uart_num, idx), 0, 0); + } else { + ret = lp_gpio_connect_in_signal(pin, UART_PERIPH_SIGNAL(uart_num, idx), 0); + } + if (ret != ESP_OK) { + log_e("Failed to connect LP_IO pin %d to UART%d signal", pin, uart_num); + return false; + } + } +#endif // SOC_LP_GPIO_MATRIX_SUPPORTED + + return true; +} + +// When LP UART needs the RTC IO MUX to set the pin, it will always have fixed pins for RX, TX, CTS and RTS +static bool lpuartCheckPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin, uint8_t uart_nr) { +// check if LP UART is being used and if the pins are valid +#if !SOC_LP_GPIO_MATRIX_SUPPORTED // ESP32-C6/C61/C5 + uint16_t lp_uart_fixed_pin = uart_periph_signal[uart_nr].pins[SOC_UART_RX_PIN_IDX].default_gpio; + if (uart_nr >= SOC_UART_HP_NUM) { // it is a LP UART NUM + if (rxPin > 0 && rxPin != lp_uart_fixed_pin) { + log_e("UART%d LP UART requires RX pin to be set to %d.", uart_nr, lp_uart_fixed_pin); + return false; + } + lp_uart_fixed_pin = uart_periph_signal[uart_nr].pins[SOC_UART_TX_PIN_IDX].default_gpio; + if (txPin > 0 && txPin != lp_uart_fixed_pin) { + log_e("UART%d LP UART requires TX pin to be set to %d.", uart_nr, lp_uart_fixed_pin); + return false; + } + lp_uart_fixed_pin = uart_periph_signal[uart_nr].pins[SOC_UART_CTS_PIN_IDX].default_gpio; + if (ctsPin > 0 && ctsPin != lp_uart_fixed_pin) { + log_e("UART%d LP UART requires CTS pin to be set to %d.", uart_nr, lp_uart_fixed_pin); + return false; + } + lp_uart_fixed_pin = uart_periph_signal[uart_nr].pins[SOC_UART_RTS_PIN_IDX].default_gpio; + if (rtsPin > 0 && rtsPin != lp_uart_fixed_pin) { + log_e("UART%d LP UART requires RTS pin to be set to %d.", uart_nr, lp_uart_fixed_pin); + return false; + } + } + return true; +#else // ESP32-P4 can set any pin for LP UART + return true; +#endif // SOC_LP_GPIO_MATRIX_SUPPORTED +} +#endif // SOC_UART_LP_NUM >= 1 + // Negative Pin Number will keep it unmodified, thus this function can detach individual pins // This function will also unset the pins in the Peripheral Manager and set the pin to -1 after detaching static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) { - if (uart_num >= SOC_UART_HP_NUM) { - log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); + if (uart_num >= SOC_UART_NUM) { + log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); return false; } // get UART information @@ -117,7 +219,7 @@ static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t //log_v("detaching UART%d pins: prev,pin RX(%d,%d) TX(%d,%d) CTS(%d,%d) RTS(%d,%d)", uart_num, // uart->_rxPin, rxPin, uart->_txPin, txPin, uart->_ctsPin, ctsPin, uart->_rtsPin, rtsPin); vTaskDelay(10); - // detaches pins and sets Peripheral Manager and UART information + // detaches HP and LP pins and sets Peripheral Manager and UART information if (rxPin >= 0 && uart->_rxPin == rxPin && perimanGetPinBusType(rxPin) == ESP32_BUS_TYPE_UART_RX) { gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rxPin], PIN_FUNC_GPIO); // avoids causing BREAK in the UART line @@ -194,8 +296,8 @@ static bool _uartDetachBus_RTS(void *busptr) { // Attach function for UART // connects the IO Pad, set Paripheral Manager and internal UART structure data static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) { - if (uart_num >= SOC_UART_HP_NUM) { - log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); + if (uart_num >= SOC_UART_NUM) { + log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); return false; } // get UART information @@ -203,6 +305,8 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t //log_v("attaching UART%d pins: prev,new RX(%d,%d) TX(%d,%d) CTS(%d,%d) RTS(%d,%d)", uart_num, // uart->_rxPin, rxPin, uart->_txPin, txPin, uart->_ctsPin, ctsPin, uart->_rtsPin, rtsPin); vTaskDelay(10); + // IDF uart_set_pin() checks if the pin is used within LP UART and if it is a valid RTC IO pin + // No need for Arduino Layer to check it again bool retCode = true; if (rxPin >= 0) { // forces a clean detaching from a previous peripheral @@ -211,6 +315,11 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t } // connect RX Pad bool ret = ESP_OK == uart_set_pin(uart->num, UART_PIN_NO_CHANGE, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); +#if SOC_UART_LP_NUM >= 1 + if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM + ret &= lp_uart_config_io(uart->num, rxPin, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_RX_PIN_IDX); + } +#endif if (ret) { ret &= perimanSetPinBus(rxPin, ESP32_BUS_TYPE_UART_RX, (void *)uart, uart_num, -1); if (ret) { @@ -229,6 +338,11 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t } // connect TX Pad bool ret = ESP_OK == uart_set_pin(uart->num, txPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); +#if SOC_UART_LP_NUM >= 1 + if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM + ret &= lp_uart_config_io(uart->num, txPin, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_TX_PIN_IDX); + } +#endif if (ret) { ret &= perimanSetPinBus(txPin, ESP32_BUS_TYPE_UART_TX, (void *)uart, uart_num, -1); if (ret) { @@ -247,6 +361,11 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t } // connect CTS Pad bool ret = ESP_OK == uart_set_pin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, ctsPin); +#if SOC_UART_LP_NUM >= 1 + if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM + ret &= lp_uart_config_io(uart->num, ctsPin, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_CTS_PIN_IDX); + } +#endif if (ret) { ret &= perimanSetPinBus(ctsPin, ESP32_BUS_TYPE_UART_CTS, (void *)uart, uart_num, -1); if (ret) { @@ -265,6 +384,11 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t } // connect RTS Pad bool ret = ESP_OK == uart_set_pin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, rtsPin, UART_PIN_NO_CHANGE); +#if SOC_UART_LP_NUM >= 1 + if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM + ret &= lp_uart_config_io(uart->num, rtsPin, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_RTS_PIN_IDX); + } +#endif if (ret) { ret &= perimanSetPinBus(rtsPin, ESP32_BUS_TYPE_UART_RTS, (void *)uart, uart_num, -1); if (ret) { @@ -321,13 +445,20 @@ bool uartIsDriverInstalled(uart_t *uart) { // Negative Pin Number will keep it unmodified, thus this function can set individual pins // When pins are changed, it will detach the previous one bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) { - if (uart_num >= SOC_UART_HP_NUM) { - log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); + if (uart_num >= SOC_UART_NUM) { + log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); return false; } // get UART information uart_t *uart = &_uart_bus_array[uart_num]; +#if SOC_UART_LP_NUM >= 1 + // check if LP UART is being used and if the pins are valid + if (!lpuartCheckPins(rxPin, txPin, ctsPin, rtsPin, uart_num)) { + return false; // failed to set pins + } +#endif + bool retCode = true; UART_MUTEX_LOCK(); @@ -391,7 +522,7 @@ bool _testUartBegin( uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint32_t rx_buffer_size, uint32_t tx_buffer_size, bool inverted, uint8_t rxfifo_full_thrhd ) { - if (uart_nr >= SOC_UART_HP_NUM) { + if (uart_nr >= SOC_UART_NUM) { return false; // no new driver has to be installed } uart_t *uart = &_uart_bus_array[uart_nr]; @@ -413,13 +544,24 @@ uart_t *uartBegin( uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint32_t rx_buffer_size, uint32_t tx_buffer_size, bool inverted, uint8_t rxfifo_full_thrhd ) { - if (uart_nr >= SOC_UART_HP_NUM) { - log_e("UART number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); + if (uart_nr >= SOC_UART_NUM) { + log_e("UART number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); return NULL; // no new driver was installed } uart_t *uart = &_uart_bus_array[uart_nr]; log_v("UART%d baud(%ld) Mode(%x) rxPin(%d) txPin(%d)", uart_nr, baudrate, config, rxPin, txPin); +#if SOC_UART_LP_NUM >= 1 + // check if LP UART is being used and if the pins are valid + if (!lpuartCheckPins(rxPin, txPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, uart_nr)) { + if (uart_is_driver_installed(uart_nr)) { + return uart; // keep the same installed driver + } else { + return NULL; // no new driver was installed + } + } +#endif + #if !CONFIG_DISABLE_HAL_LOCKS if (uart->lock == NULL) { uart->lock = xSemaphoreCreateMutex(); @@ -436,6 +578,10 @@ uart_t *uartBegin( if (uart->_rx_buffer_size != rx_buffer_size || uart->_tx_buffer_size != tx_buffer_size || uart->_inverted != inverted || uart->_rxfifo_full_thrhd != rxfifo_full_thrhd) { log_v("UART%d changing buffer sizes or inverted signal or rxfifo_full_thrhd. IDF driver will be restarted", uart_nr); + log_v("RX buffer size: %d -> %d", uart->_rx_buffer_size, rx_buffer_size); + log_v("TX buffer size: %d -> %d", uart->_tx_buffer_size, tx_buffer_size); + log_v("Inverted signal: %s -> %s", uart->_inverted ? "true" : "false", inverted ? "true" : "false"); + log_v("RX FIFO full threshold: %d -> %d", uart->_rxfifo_full_thrhd, rxfifo_full_thrhd); uartEnd(uart_nr); } else { bool retCode = true; @@ -500,7 +646,7 @@ uart_t *uartBegin( } UART_MUTEX_UNLOCK(); if (retCode) { - // UART driver was already working, just return the uart_t structure, syaing that no new driver was installed + // UART driver was already working, just return the uart_t structure, saying that no new driver was installed return uart; } // if we reach this point, it means that we need to restart the UART driver @@ -516,22 +662,39 @@ uart_t *uartBegin( uart_config.parity = (config & 0x3); uart_config.stop_bits = (config & 0x30) >> 4; uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; - uart_config.rx_flow_ctrl_thresh = rxfifo_full_thrhd; + uart_config.rx_flow_ctrl_thresh = rxfifo_full_thrhd >= UART_HW_FIFO_LEN(uart_nr) ? UART_HW_FIFO_LEN(uart_nr) - 6 : rxfifo_full_thrhd; + log_v( + "UART%d RX FIFO full threshold set to %d (value requested: %d || FIFO Max = %d)", uart_nr, uart_config.rx_flow_ctrl_thresh, rxfifo_full_thrhd, + UART_HW_FIFO_LEN(uart_nr) + ); + rxfifo_full_thrhd = uart_config.rx_flow_ctrl_thresh; // makes sure that it will be set correctly in the struct uart_config.baud_rate = baudrate; - // there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored - // therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue. +#if SOC_UART_LP_NUM >= 1 + if (uart_nr >= SOC_UART_HP_NUM) { // it is a LP UART NUM + uart_config.lp_source_clk = LP_UART_SCLK_DEFAULT; // use default LP clock + log_v("Setting UART%d to use LP clock", uart_nr); + } else +#endif + { + // there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored + // therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue. #if SOC_UART_SUPPORT_XTAL_CLK - uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4 + uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4 + log_v("Setting UART%d to use XTAL clock", uart_nr); #elif SOC_UART_SUPPORT_REF_TICK - if (baudrate <= REF_TICK_BAUDRATE_LIMIT) { - uart_config.source_clk = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps - } else { - uart_config.source_clk = UART_SCLK_APB; // baudrate may change with the APB Frequency! - } + if (baudrate <= REF_TICK_BAUDRATE_LIMIT) { + uart_config.source_clk = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 250 Kbps + log_v("Setting UART%d to use REF_TICK clock", uart_nr); + } else { + uart_config.source_clk = UART_SCLK_APB; // baudrate may change with the APB Frequency! + log_v("Setting UART%d to use APB clock", uart_nr); + } #else - // Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6 - uart_config.source_clk = UART_SCLK_DEFAULT; // baudrate may change with the APB Frequency! + // Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6 + uart_config.source_clk = UART_SCLK_DEFAULT; // baudrate may change with the APB Frequency! + log_v("Setting UART%d to use DEFAULT clock", uart_nr); #endif + } UART_MUTEX_LOCK(); bool retCode = ESP_OK == uart_driver_install(uart_nr, rx_buffer_size, tx_buffer_size, 20, &(uart->uart_event_queue), 0); @@ -611,16 +774,25 @@ bool uartSetRxFIFOFull(uart_t *uart, uint8_t numBytesFIFOFull) { if (uart == NULL) { return false; } - + uint8_t rxfifo_full_thrhd = numBytesFIFOFull >= UART_HW_FIFO_LEN(uart->num) ? UART_HW_FIFO_LEN(uart->num) - 6 : numBytesFIFOFull; UART_MUTEX_LOCK(); - bool retCode = (ESP_OK == uart_set_rx_full_threshold(uart->num, numBytesFIFOFull)); + bool retCode = (ESP_OK == uart_set_rx_full_threshold(uart->num, rxfifo_full_thrhd)); + if (retCode) { + uart->_rxfifo_full_thrhd = rxfifo_full_thrhd; + if (rxfifo_full_thrhd != numBytesFIFOFull) { + log_w("The RX FIFO Full value for UART%d was set to %d instead of %d", uart->num, rxfifo_full_thrhd, numBytesFIFOFull); + } + log_v("UART%d RX FIFO Full value set to %d from a requested value of %d", uart->num, rxfifo_full_thrhd, numBytesFIFOFull); + } else { + log_e("UART%d failed to set RX FIFO Full value to %d", uart->num, numBytesFIFOFull); + } UART_MUTEX_UNLOCK(); return retCode; } void uartEnd(uint8_t uart_num) { - if (uart_num >= SOC_UART_HP_NUM) { - log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_HP_NUM - 1); + if (uart_num >= SOC_UART_NUM) { + log_e("Serial number is invalid, please use number from 0 to %u", SOC_UART_NUM - 1); return; } // get UART information @@ -645,7 +817,7 @@ void uartSetRxInvert(uart_t *uart, bool invert) { // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_RXD_INV)); // else // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_INV_DISABLE)); - + log_e("uartSetRxInvert is not supported in ESP32C6, ESP32H2 and ESP32P4"); #else // this implementation is better over IDF API because it only affects RXD // this is supported in ESP32, ESP32-S2 and ESP32-C3 @@ -805,11 +977,23 @@ void uartSetBaudRate(uart_t *uart, uint32_t baud_rate) { return; } UART_MUTEX_LOCK(); -#if !SOC_UART_SUPPORT_XTAL_CLK +#if SOC_UART_SUPPORT_XTAL_CLK // ESP32-S3, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-H2 and ESP32-P4 + soc_module_clk_t newClkSrc = UART_SCLK_XTAL; +#if SOC_UART_LP_NUM >= 1 + if (uart->num >= SOC_UART_HP_NUM) { // it is a LP UART NUM + newClkSrc = LP_UART_SCLK_DEFAULT; // use default LP clock + } +#endif + // ESP32-P4 demands an atomic operation for setting the clock source + HP_UART_SRC_CLK_ATOMIC() { + uart_ll_set_sclk(UART_LL_GET_HW(uart->num), newClkSrc); + } +#else // ESP32, ESP32-S2 soc_module_clk_t newClkSrc = baud_rate <= REF_TICK_BAUDRATE_LIMIT ? SOC_MOD_CLK_REF_TICK : SOC_MOD_CLK_APB; uart_ll_set_sclk(UART_LL_GET_HW(uart->num), newClkSrc); #endif if (uart_set_baudrate(uart->num, baud_rate) == ESP_OK) { + log_v("Setting UART%d baud rate to %d.", uart->num, baud_rate); uart->_baudrate = baud_rate; } else { log_e("Setting UART%d baud rate to %d has failed.", uart->num, baud_rate); @@ -889,7 +1073,7 @@ void uart_install_putc() { // Routines that take care of UART mode in the HardwareSerial Class code // used to set UART_MODE_RS485_HALF_DUPLEX auto RTS for TXD for ESP32 chips bool uartSetMode(uart_t *uart, uart_mode_t mode) { - if (uart == NULL || uart->num >= SOC_UART_HP_NUM) { + if (uart == NULL || uart->num >= SOC_UART_NUM) { return false; } @@ -900,6 +1084,7 @@ bool uartSetMode(uart_t *uart, uart_mode_t mode) { } void uartSetDebug(uart_t *uart) { + // LP UART is not supported for debug if (uart == NULL || uart->num >= SOC_UART_HP_NUM) { s_uart_debug_nr = -1; } else { @@ -1170,7 +1355,9 @@ unsigned long uartDetectBaudrate(uart_t *uart) { This creates a loop that lets us receive anything we send on the UART without external wires. */ void uart_internal_loopback(uint8_t uartNum, int8_t rxPin) { - if (uartNum > SOC_UART_HP_NUM - 1 || !GPIO_IS_VALID_GPIO(rxPin)) { + // LP UART is not supported for loopback + if (uartNum >= SOC_UART_HP_NUM || !GPIO_IS_VALID_GPIO(rxPin)) { + log_e("UART%d is not supported for loopback or RX pin %d is invalid.", uartNum, rxPin); return; } esp_rom_gpio_connect_out_signal(rxPin, UART_TX_SIGNAL(uartNum), false, false); diff --git a/cores/esp32/esp32-hal-uart.h b/cores/esp32/esp32-hal-uart.h index 402b5785915..74249194da3 100644 --- a/cores/esp32/esp32-hal-uart.h +++ b/cores/esp32/esp32-hal-uart.h @@ -1,4 +1,4 @@ -// Copyright 2015-2023 Espressif Systems (Shanghai) PTE LTD +// Copyright 2015-2025 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ #include "soc/soc_caps.h" #if SOC_UART_SUPPORTED +#include "soc/uart_pins.h" #ifdef __cplusplus extern "C" { From 5afafdf4c6a7299e357662646970e490f4244771 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Wed, 19 Feb 2025 18:31:08 -0300 Subject: [PATCH 40/79] fix(matter): commentaries and messages related to factory reset (#10988) * fix(matter): commentaries and messages related to the factory reset * fix(matter): commentaries and messages typo --- .../examples/MatterComposedLights/MatterComposedLights.ino | 2 +- .../examples/MatterContactSensor/MatterContactSensor.ino | 2 +- libraries/Matter/examples/MatterFan/MatterFan.ino | 2 +- .../examples/MatterHumiditySensor/MatterHumiditySensor.ino | 2 +- .../examples/MatterOccupancySensor/MatterOccupancySensor.ino | 2 +- .../examples/MatterPressureSensor/MatterPressureSensor.ino | 4 ++-- .../MatterTemperatureSensor/MatterTemperatureSensor.ino | 2 +- .../Matter/examples/MatterThermostat/MatterThermostat.ino | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/Matter/examples/MatterComposedLights/MatterComposedLights.ino b/libraries/Matter/examples/MatterComposedLights/MatterComposedLights.ino index 9c3dcf05a83..b98cc8e19c9 100644 --- a/libraries/Matter/examples/MatterComposedLights/MatterComposedLights.ino +++ b/libraries/Matter/examples/MatterComposedLights/MatterComposedLights.ino @@ -128,7 +128,7 @@ void loop() { // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node uint32_t time_diff = millis() - button_time_stamp; if (button_state && time_diff > decommissioningTimeout) { - Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again."); + Serial.println("Decommissioning the Composed Light Matter Accessory. It shall be commissioned again."); Matter.decommission(); button_time_stamp = millis(); // avoid running decommissining again, reboot takes a second or so } diff --git a/libraries/Matter/examples/MatterContactSensor/MatterContactSensor.ino b/libraries/Matter/examples/MatterContactSensor/MatterContactSensor.ino index e27f70e613d..e4c41460d3a 100644 --- a/libraries/Matter/examples/MatterContactSensor/MatterContactSensor.ino +++ b/libraries/Matter/examples/MatterContactSensor/MatterContactSensor.ino @@ -140,7 +140,7 @@ void loop() { // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node if (button_state && time_diff > decommissioningTimeout) { - Serial.println("Decommissioning the Generic Switch Matter Accessory. It shall be commissioned again."); + Serial.println("Decommissioning Contact Sensor Matter Accessory. It shall be commissioned again."); Matter.decommission(); button_time_stamp = millis(); // avoid running decommissining again, reboot takes a second or so } diff --git a/libraries/Matter/examples/MatterFan/MatterFan.ino b/libraries/Matter/examples/MatterFan/MatterFan.ino index 3dc0c89fcf4..1094126a843 100644 --- a/libraries/Matter/examples/MatterFan/MatterFan.ino +++ b/libraries/Matter/examples/MatterFan/MatterFan.ino @@ -180,7 +180,7 @@ void loop() { // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node if (button_state && time_diff > decommissioningTimeout) { - Serial.println("Decommissioning the Generic Switch Matter Accessory. It shall be commissioned again."); + Serial.println("Decommissioning Fan Matter Accessory. It shall be commissioned again."); Matter.decommission(); button_time_stamp = millis(); // avoid running decommissining again, reboot takes a second or so } diff --git a/libraries/Matter/examples/MatterHumiditySensor/MatterHumiditySensor.ino b/libraries/Matter/examples/MatterHumiditySensor/MatterHumiditySensor.ino index 3fcab46c565..1c7889db849 100644 --- a/libraries/Matter/examples/MatterHumiditySensor/MatterHumiditySensor.ino +++ b/libraries/Matter/examples/MatterHumiditySensor/MatterHumiditySensor.ino @@ -122,7 +122,7 @@ void loop() { // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node uint32_t time_diff = millis() - button_time_stamp; if (button_state && time_diff > decommissioningTimeout) { - Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again."); + Serial.println("Decommissioning Humidity Sensor Matter Accessory. It shall be commissioned again."); Matter.decommission(); } diff --git a/libraries/Matter/examples/MatterOccupancySensor/MatterOccupancySensor.ino b/libraries/Matter/examples/MatterOccupancySensor/MatterOccupancySensor.ino index e88a9a8986b..333f178e9de 100644 --- a/libraries/Matter/examples/MatterOccupancySensor/MatterOccupancySensor.ino +++ b/libraries/Matter/examples/MatterOccupancySensor/MatterOccupancySensor.ino @@ -116,7 +116,7 @@ void loop() { // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node uint32_t time_diff = millis() - button_time_stamp; if (button_state && time_diff > decommissioningTimeout) { - Serial.println("Decommissioning the Generic Switch Matter Accessory. It shall be commissioned again."); + Serial.println("Decommissioning Occupancy Sensor Matter Accessory. It shall be commissioned again."); Matter.decommission(); button_time_stamp = millis(); // avoid running decommissining again, reboot takes a second or so } diff --git a/libraries/Matter/examples/MatterPressureSensor/MatterPressureSensor.ino b/libraries/Matter/examples/MatterPressureSensor/MatterPressureSensor.ino index 394a217b87a..db035e951c9 100644 --- a/libraries/Matter/examples/MatterPressureSensor/MatterPressureSensor.ino +++ b/libraries/Matter/examples/MatterPressureSensor/MatterPressureSensor.ino @@ -122,8 +122,8 @@ void loop() { // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node uint32_t time_diff = millis() - button_time_stamp; if (button_state && time_diff > decommissioningTimeout) { - // Factory reset is triggered if the button is pressed longer than 10 seconds - Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again."); + // Factory reset is triggered if the button is pressed longer than 5 seconds + Serial.println("Decommissioning Pressure Sensor Matter Accessory. It shall be commissioned again."); Matter.decommission(); } diff --git a/libraries/Matter/examples/MatterTemperatureSensor/MatterTemperatureSensor.ino b/libraries/Matter/examples/MatterTemperatureSensor/MatterTemperatureSensor.ino index a2866e4655e..086155aeffe 100644 --- a/libraries/Matter/examples/MatterTemperatureSensor/MatterTemperatureSensor.ino +++ b/libraries/Matter/examples/MatterTemperatureSensor/MatterTemperatureSensor.ino @@ -122,7 +122,7 @@ void loop() { // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node uint32_t time_diff = millis() - button_time_stamp; if (button_state && time_diff > decommissioningTimeout) { - Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again."); + Serial.println("Decommissioning Temperature Sensor Matter Accessory. It shall be commissioned again."); Matter.decommission(); button_time_stamp = millis(); // avoid running decommissining again, reboot takes a second or so } diff --git a/libraries/Matter/examples/MatterThermostat/MatterThermostat.ino b/libraries/Matter/examples/MatterThermostat/MatterThermostat.ino index 508b508573a..bf76477c846 100644 --- a/libraries/Matter/examples/MatterThermostat/MatterThermostat.ino +++ b/libraries/Matter/examples/MatterThermostat/MatterThermostat.ino @@ -234,7 +234,7 @@ void loop() { // Onboard User Button is kept pressed for longer than 5 seconds in order to decommission matter node uint32_t time_diff = millis() - button_time_stamp; if (button_state && time_diff > decommissioningTimeout) { - Serial.println("Decommissioning the Light Matter Accessory. It shall be commissioned again."); + Serial.println("Decommissioning Thermostat Matter Accessory. It shall be commissioned again."); Matter.decommission(); button_time_stamp = millis(); // avoid running decommissining again, reboot takes a second or so } From eec2af3d35d10152307cb878f5f39d288047f28d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Wed, 19 Feb 2025 22:31:37 +0100 Subject: [PATCH 41/79] feat(zigbee): Add range extender device endpoint (#10970) * feat(zigbee): Add range extender device endpoint * ci(pre-commit): Apply automatic fixes * fix(example): Fix typo catched by precommit --------- Co-authored-by: Me No Dev Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- CMakeLists.txt | 1 + .../examples/Zigbee_Range_Extender/README.md | 68 +++++++++++ .../Zigbee_Range_Extender.ino | 115 ++++++++++++++++++ .../examples/Zigbee_Range_Extender/ci.json | 6 + libraries/Zigbee/src/Zigbee.h | 1 + .../Zigbee/src/ep/ZigbeeRangeExtender.cpp | 15 +++ libraries/Zigbee/src/ep/ZigbeeRangeExtender.h | 18 +++ 7 files changed, 224 insertions(+) create mode 100644 libraries/Zigbee/examples/Zigbee_Range_Extender/README.md create mode 100644 libraries/Zigbee/examples/Zigbee_Range_Extender/Zigbee_Range_Extender.ino create mode 100644 libraries/Zigbee/examples/Zigbee_Range_Extender/ci.json create mode 100644 libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeRangeExtender.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a17c516936c..7436eb1833c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -295,6 +295,7 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp + libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp ) set(ARDUINO_LIBRARY_BLE_SRCS diff --git a/libraries/Zigbee/examples/Zigbee_Range_Extender/README.md b/libraries/Zigbee/examples/Zigbee_Range_Extender/README.md new file mode 100644 index 00000000000..198dd85b6ee --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Range_Extender/README.md @@ -0,0 +1,68 @@ +# Arduino-ESP32 Zigbee Range Extender (Router) Example + +This example shows how to configure the Zigbee Router device and use it as a Home Automation (HA) network range extender. + +To see if the communication with your Zigbee network works, use the Serial monitor and watch for output there. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Hardware Required + +* A USB cable for power supply and programming +* Board (ESP32-H2 or ESP32-C6) as Zigbee router device and upload the Zigbee_Range_Extender example +* Zigbee network / coordinator (Other board with switch examples or Zigbee2mqtt or ZigbeeHomeAssistant like application) + +### Configure the Project + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the Coordinator/Router device Zigbee mode: `Tools -> Zigbee mode: Zigbee ZCZR (coordinator/router)` +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs` (select correct size) +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. +* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. + +## Troubleshooting + +If the Router device flashed with this example is not connecting to the coordinator, erase the flash of the Router device before flashing the example to the board. It is recommended to do this if you re-flash the coordinator. +You can do the following: + +* In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. +* Add to the sketch `Zigbee.factoryReset();` to reset the device and Zigbee stack. + +By default, the coordinator network is closed after rebooting or flashing new firmware. +To open the network you have 2 options: + +* Open network after reboot by setting `Zigbee.setRebootOpenNetwork(time);` before calling `Zigbee.begin();`. +* In application you can anytime call `Zigbee.openNetwork(time);` to open the network for devices to join. + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/Zigbee/examples/Zigbee_Range_Extender/Zigbee_Range_Extender.ino b/libraries/Zigbee/examples/Zigbee_Range_Extender/Zigbee_Range_Extender.ino new file mode 100644 index 00000000000..3c4cfeb61dc --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Range_Extender/Zigbee_Range_Extender.ino @@ -0,0 +1,115 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +/** + * @brief This example demonstrates simple Zigbee Range Extender (router). + * + * The example demonstrates how to use Zigbee library to create a Zigbee network ragbe extender (router). + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ZCZR +#error "Zigbee coordinator/router mode is not selected in Tools->Zigbee mode" +#endif + +#include "Zigbee.h" + +/* Zigbee light bulb configuration */ +#define USE_CUSTOM_ZIGBEE_CONFIG 1 +#define ZIGBEE_EXTENDER_ENDPOINT 1 +uint8_t led = RGB_BUILTIN; +uint8_t button = BOOT_PIN; + +ZigbeeRangeExtender zbExtender = ZigbeeRangeExtender(ZIGBEE_EXTENDER_ENDPOINT); + +/************************** Identify ******************************/ +// Create a task on identify call to handle the identify function +void identify(uint16_t time) { + static uint8_t blink = 1; + log_d("Identify called for %d seconds", time); + if (time == 0) { + digitalWrite(led, LOW); + return; + } + digitalWrite(led, blink); + blink = !blink; +} + +/********************* Arduino functions **************************/ +void setup() { + Serial.begin(115200); + + // Init LED and turn it OFF (if LED_PIN == RGB_BUILTIN, the rgbLedWrite() will be used under the hood) + pinMode(led, OUTPUT); + digitalWrite(led, LOW); + + // Init button for factory reset + pinMode(button, INPUT_PULLUP); + + // Optional: Set callback function for device identify + zbExtender.onIdentify(identify); + + // Optional: Set Zigbee device name and model + zbExtender.setManufacturerAndModel("Espressif", "ZigbeeRangeExtender"); + + // Add endpoint to Zigbee Core + Serial.println("Adding Zigbee Extender endpoint to Zigbee Core"); + Zigbee.addEndpoint(&zbExtender); + +#if USE_CUSTOM_ZIGBEE_CONFIG + // Optional: Create a custom Zigbee configuration for Zigbee Extender + esp_zb_cfg_t zigbeeConfig = ZIGBEE_DEFAULT_ROUTER_CONFIG(); + zigbeeConfig.nwk_cfg.zczr_cfg.max_children = 20; // 10 is default + + // When all EPs are registered, start Zigbee with custom config + if (!Zigbee.begin(&zigbeeConfig)) { +#else + // When all EPs are registered, start Zigbee as ROUTER device + if (!Zigbee.begin(ZIGBEE_ROUTER)) { +#endif + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println(); +} + +void loop() { + // Checking button for factory reset + if (digitalRead(button) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(button) == LOW) { + delay(50); + if ((millis() - startTime) > 3000) { + // If key pressed for more than 3secs, factory reset Zigbee and reboot + Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + delay(1000); + Zigbee.factoryReset(); + } + } + } +} diff --git a/libraries/Zigbee/examples/Zigbee_Range_Extender/ci.json b/libraries/Zigbee/examples/Zigbee_Range_Extender/ci.json new file mode 100644 index 00000000000..e79a477da11 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Range_Extender/ci.json @@ -0,0 +1,6 @@ +{ + "fqbn_append": "PartitionScheme=zigbee_zczr,ZigbeeMode=zczr", + "requires": [ + "CONFIG_SOC_IEEE802154_SUPPORTED=y" + ] +} diff --git a/libraries/Zigbee/src/Zigbee.h b/libraries/Zigbee/src/Zigbee.h index b785c28d0df..7353f661416 100644 --- a/libraries/Zigbee/src/Zigbee.h +++ b/libraries/Zigbee/src/Zigbee.h @@ -22,3 +22,4 @@ #include "ep/ZigbeeDoorWindowHandle.h" #include "ep/ZigbeeWindowCovering.h" #include "ep/ZigbeeVibrationSensor.h" +#include "ep/ZigbeeRangeExtender.h" diff --git a/libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp b/libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp new file mode 100644 index 00000000000..b29e926c201 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp @@ -0,0 +1,15 @@ +#include "ZigbeeRangeExtender.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +ZigbeeRangeExtender::ZigbeeRangeExtender(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_RANGE_EXTENDER_DEVICE_ID; + + _cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_cluster_list_add_basic_cluster(_cluster_list, esp_zb_basic_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_identify_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_RANGE_EXTENDER_DEVICE_ID, .app_device_version = 0}; +} + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeRangeExtender.h b/libraries/Zigbee/src/ep/ZigbeeRangeExtender.h new file mode 100644 index 00000000000..7441f48ea7a --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeRangeExtender.h @@ -0,0 +1,18 @@ +/* Class of Zigbee Range Extender endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +class ZigbeeRangeExtender : public ZigbeeEP { +public: + ZigbeeRangeExtender(uint8_t endpoint); + ~ZigbeeRangeExtender() {} +}; + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED From 978b441cd4f22d1be8fda760bfe81da06930ba8e Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Wed, 19 Feb 2025 18:32:06 -0300 Subject: [PATCH 42/79] test(wokwi): Add I2C Master test and enable GPIO and PSRAM tests (#10848) * test(wokwi): Enable PSRAM test * fix(tests): Add missing diagram for ESP32-P4 * test(wokwi): Enable GPIO test * test(wokwi): Add I2C master test * fix(tests): Add missing requirement and improve logging * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- .github/scripts/tests_run.sh | 8 +- tests/requirements.txt | 1 + tests/validation/gpio/ci.json | 3 +- tests/validation/gpio/diagram.esp32p4.json | 28 ++ tests/validation/i2c_master/ci.json | 9 + .../validation/i2c_master/diagram.esp32.json | 24 ++ .../i2c_master/diagram.esp32c3.json | 25 ++ .../i2c_master/diagram.esp32c6.json | 26 ++ .../i2c_master/diagram.esp32h2.json | 24 ++ .../i2c_master/diagram.esp32p4.json | 24 ++ .../i2c_master/diagram.esp32s2.json | 24 ++ .../i2c_master/diagram.esp32s3.json | 24 ++ tests/validation/i2c_master/i2c_master.ino | 271 ++++++++++++++++++ .../validation/i2c_master/test_i2c_master.py | 2 + tests/validation/psram/ci.json | 3 +- 15 files changed, 488 insertions(+), 8 deletions(-) create mode 100644 tests/validation/gpio/diagram.esp32p4.json create mode 100644 tests/validation/i2c_master/ci.json create mode 100644 tests/validation/i2c_master/diagram.esp32.json create mode 100644 tests/validation/i2c_master/diagram.esp32c3.json create mode 100644 tests/validation/i2c_master/diagram.esp32c6.json create mode 100644 tests/validation/i2c_master/diagram.esp32h2.json create mode 100644 tests/validation/i2c_master/diagram.esp32p4.json create mode 100644 tests/validation/i2c_master/diagram.esp32s2.json create mode 100644 tests/validation/i2c_master/diagram.esp32s3.json create mode 100644 tests/validation/i2c_master/i2c_master.ino create mode 100644 tests/validation/i2c_master/test_i2c_master.py diff --git a/.github/scripts/tests_run.sh b/.github/scripts/tests_run.sh index 513fd16b371..8cb21ee519b 100755 --- a/.github/scripts/tests_run.sh +++ b/.github/scripts/tests_run.sh @@ -48,10 +48,10 @@ function run_test { return 0 fi - local right_target - right_target=$(grep -E "^CONFIG_IDF_TARGET=\"$target\"$" "$sdkconfig_path") - if [ -z "$right_target" ]; then - printf "\033[91mError: Sketch %s compiled for different target\n\033[0m\n" "$sketchname" + local compiled_target + compiled_target=$(grep -E "CONFIG_IDF_TARGET=" "$sdkconfig_path" | cut -d'"' -f2) + if [ "$compiled_target" != "$target" ]; then + printf "\033[91mError: Sketch %s compiled for %s, expected %s\033[0m\n" "$sketchname" "$compiled_target" "$target" printf "\n\n\n" return 1 fi diff --git a/tests/requirements.txt b/tests/requirements.txt index c98c032a3ae..b2bae3b86d0 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -5,3 +5,4 @@ pytest-embedded-serial-esp==1.12.0 pytest-embedded-arduino==1.12.0 pytest-embedded-wokwi==1.12.0 pytest-embedded-qemu==1.12.0 +esptool==4.8.1 diff --git a/tests/validation/gpio/ci.json b/tests/validation/gpio/ci.json index f03ec83b39d..7bc6a6ed163 100644 --- a/tests/validation/gpio/ci.json +++ b/tests/validation/gpio/ci.json @@ -1,7 +1,6 @@ { "platforms": { "hardware": false, - "qemu": false, - "wokwi": false + "qemu": false } } diff --git a/tests/validation/gpio/diagram.esp32p4.json b/tests/validation/gpio/diagram.esp32p4.json new file mode 100644 index 00000000000..ffb0cde2775 --- /dev/null +++ b/tests/validation/gpio/diagram.esp32p4.json @@ -0,0 +1,28 @@ +{ + "version": 1, + "author": "lucasssvaz", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-p4-function-ev", + "id": "esp32", + "top": -66.32, + "left": -277.63, + "attrs": {} + }, + { + "type": "wokwi-pushbutton", + "id": "btn1", + "top": -128.2, + "left": -19.2, + "attrs": { "color": "green", "bounce": "1" } + } + ], + "connections": [ + [ "esp32:38", "$serialMonitor:TX", "", [] ], + [ "esp32:37", "$serialMonitor:RX", "", [] ], + [ "btn1:2.r", "esp32:GND.3", "black", [ "h19.4", "v29" ] ], + [ "esp32:0", "btn1:1.l", "blue", [ "h-48", "v-67.2" ] ] + ], + "dependencies": {} +} diff --git a/tests/validation/i2c_master/ci.json b/tests/validation/i2c_master/ci.json new file mode 100644 index 00000000000..2b8792cd131 --- /dev/null +++ b/tests/validation/i2c_master/ci.json @@ -0,0 +1,9 @@ +{ + "platforms": { + "hardware": false, + "qemu": false + }, + "requires": [ + "CONFIG_SOC_I2C_SUPPORTED=y" + ] +} diff --git a/tests/validation/i2c_master/diagram.esp32.json b/tests/validation/i2c_master/diagram.esp32.json new file mode 100644 index 00000000000..28e5d2e9c23 --- /dev/null +++ b/tests/validation/i2c_master/diagram.esp32.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "author": "lucasssvaz", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-devkit-c-v4", + "id": "esp32", + "top": -57.6, + "left": -177.56, + "attrs": {} + }, + { "type": "wokwi-ds1307", "id": "rtc1", "top": -43.8, "left": -19.1, "attrs": {} } + ], + "connections": [ + [ "esp32:RX", "$serialMonitor:TX", "", [] ], + [ "esp32:TX", "$serialMonitor:RX", "", [] ], + [ "esp32:22", "rtc1:SCL", "green", [ "h38.4", "v-9.6" ] ], + [ "esp32:21", "rtc1:SDA", "blue", [ "h48", "v-28.8", "h19.2" ] ], + [ "esp32:GND.2", "rtc1:GND", "black", [ "v0" ] ], + [ "rtc1:5V", "esp32:5V", "red", [ "h-28.8", "v-67.6", "h-172.8", "v230.4" ] ] + ], + "dependencies": {} +} diff --git a/tests/validation/i2c_master/diagram.esp32c3.json b/tests/validation/i2c_master/diagram.esp32c3.json new file mode 100644 index 00000000000..a7471ec3ca1 --- /dev/null +++ b/tests/validation/i2c_master/diagram.esp32c3.json @@ -0,0 +1,25 @@ +{ + "version": 1, + "author": "lucasssvaz", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-c3-devkitm-1", + "id": "esp32", + "top": -57.6, + "left": -177.56, + "attrs": {} + }, + { "type": "wokwi-ds1307", "id": "rtc1", "top": -43.8, "left": -19.1, "attrs": {} } + ], + "connections": [ + [ "esp32:RX", "$serialMonitor:TX", "", [] ], + [ "esp32:TX", "$serialMonitor:RX", "", [] ], + [ "rtc1:5V", "esp32:5V", "red", [ "h-28.8", "v-67.6", "h-172.8", "v230.4" ] ], + [ "esp32:5V.1", "rtc1:5V", "red", [ "h-18.22", "v-144.3", "h153.6", "v48" ] ], + [ "esp32:GND.10", "rtc1:GND", "black", [ "h56.16", "v9.3" ] ], + [ "esp32:8", "rtc1:SDA", "green", [ "h17.76", "v-19.5" ] ], + [ "esp32:9", "rtc1:SCL", "blue", [ "h0" ] ] + ], + "dependencies": {} +} diff --git a/tests/validation/i2c_master/diagram.esp32c6.json b/tests/validation/i2c_master/diagram.esp32c6.json new file mode 100644 index 00000000000..9c759682ae5 --- /dev/null +++ b/tests/validation/i2c_master/diagram.esp32c6.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "author": "lucasssvaz", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-c6-devkitc-1", + "id": "esp32", + "top": -57.6, + "left": -177.56, + "attrs": {} + }, + { "type": "wokwi-ds1307", "id": "rtc1", "top": -43.8, "left": -19.1, "attrs": {} } + ], + "connections": [ + [ "esp32:RX", "$serialMonitor:TX", "", [] ], + [ "esp32:TX", "$serialMonitor:RX", "", [] ], + [ "rtc1:5V", "esp32:5V", "red", [ "h-28.8", "v-67.6", "h-172.8", "v230.4" ] ], + [ "esp32:5V.1", "rtc1:5V", "red", [ "h-18.22", "v-144.3", "h153.6", "v48" ] ], + [ "esp32:GND.10", "rtc1:GND", "black", [ "h56.16", "v9.3" ] ], + [ "esp32:23", "rtc1:SDA", "green", [ "h17.38", "v-23.51" ] ], + [ "esp32:GND.4", "rtc1:GND", "black", [ "h55.78", "v-4.31" ] ], + [ "esp32:22", "rtc1:SCL", "blue", [ "h26.98", "v-23.51" ] ] + ], + "dependencies": {} +} diff --git a/tests/validation/i2c_master/diagram.esp32h2.json b/tests/validation/i2c_master/diagram.esp32h2.json new file mode 100644 index 00000000000..d2a2acfecd7 --- /dev/null +++ b/tests/validation/i2c_master/diagram.esp32h2.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "author": "lucasssvaz", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-h2-devkitm-1", + "id": "esp32", + "top": -57.6, + "left": -177.56, + "attrs": {} + }, + { "type": "wokwi-ds1307", "id": "rtc1", "top": -43.8, "left": -19.1, "attrs": {} } + ], + "connections": [ + [ "esp32:RX", "$serialMonitor:TX", "", [] ], + [ "esp32:TX", "$serialMonitor:RX", "", [] ], + [ "esp32:GND.6", "rtc1:GND", "black", [ "h0" ] ], + [ "esp32:5V", "rtc1:5V", "red", [ "h-29.14", "v-160.97", "h172.8", "v48" ] ], + [ "esp32:12", "rtc1:SDA", "green", [ "h36.58", "v-36.17" ] ], + [ "esp32:22", "rtc1:SCL", "blue", [ "v-7.37", "h46.18", "v-38.4" ] ] + ], + "dependencies": {} +} diff --git a/tests/validation/i2c_master/diagram.esp32p4.json b/tests/validation/i2c_master/diagram.esp32p4.json new file mode 100644 index 00000000000..ab250c2aafd --- /dev/null +++ b/tests/validation/i2c_master/diagram.esp32p4.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "author": "lucasssvaz", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-p4-function-ev", + "id": "esp32", + "top": -57.6, + "left": -177.56, + "attrs": {} + }, + { "type": "wokwi-ds1307", "id": "rtc1", "top": -197.4, "left": 57.7, "attrs": {} } + ], + "connections": [ + [ "esp32:38", "$serialMonitor:TX", "", [] ], + [ "esp32:37", "$serialMonitor:RX", "", [] ], + [ "esp32:5V.1", "rtc1:5V", "red", [ "v0" ] ], + [ "esp32:GND.1", "rtc1:GND", "black", [ "v-133.52", "h5.53" ] ], + [ "esp32:7", "rtc1:SDA", "green", [ "v0" ] ], + [ "esp32:8", "rtc1:SCL", "blue", [ "h15.13", "v-114.12" ] ] + ], + "dependencies": {} +} diff --git a/tests/validation/i2c_master/diagram.esp32s2.json b/tests/validation/i2c_master/diagram.esp32s2.json new file mode 100644 index 00000000000..c34a176bd7e --- /dev/null +++ b/tests/validation/i2c_master/diagram.esp32s2.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "author": "lucasssvaz", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-s2-devkitm-1", + "id": "esp32", + "top": -57.6, + "left": -177.56, + "attrs": {} + }, + { "type": "wokwi-ds1307", "id": "rtc1", "top": -43.8, "left": -19.1, "attrs": {} } + ], + "connections": [ + [ "esp32:RX", "$serialMonitor:TX", "", [] ], + [ "esp32:TX", "$serialMonitor:RX", "", [] ], + [ "esp32:GND.2", "rtc1:GND", "black", [ "v0" ] ], + [ "rtc1:5V", "esp32:5V", "red", [ "h-28.8", "v-67.6", "h-172.8", "v230.4" ] ], + [ "esp32:8", "rtc1:SDA", "green", [ "h-19.47", "v-119.51", "h144", "v57.6" ] ], + [ "esp32:9", "rtc1:SCL", "blue", [ "h-29.07", "v-138.71", "h144", "v76.8" ] ] + ], + "dependencies": {} +} diff --git a/tests/validation/i2c_master/diagram.esp32s3.json b/tests/validation/i2c_master/diagram.esp32s3.json new file mode 100644 index 00000000000..6d168fb42e6 --- /dev/null +++ b/tests/validation/i2c_master/diagram.esp32s3.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "author": "lucasssvaz", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-s3-devkitc-1", + "id": "esp32", + "top": -57.6, + "left": -177.56, + "attrs": {} + }, + { "type": "wokwi-ds1307", "id": "rtc1", "top": -43.8, "left": -19.1, "attrs": {} } + ], + "connections": [ + [ "esp32:RX", "$serialMonitor:TX", "", [] ], + [ "esp32:TX", "$serialMonitor:RX", "", [] ], + [ "esp32:GND.2", "rtc1:GND", "black", [ "v0" ] ], + [ "rtc1:5V", "esp32:5V", "red", [ "h-28.8", "v-67.6", "h-172.8", "v230.4" ] ], + [ "esp32:8", "rtc1:SDA", "green", [ "h-19.47", "v-119.51", "h144", "v32.93", "h38.35" ] ], + [ "esp32:9", "rtc1:SCL", "blue", [ "h-29.07", "v-138.71", "h144", "v32.93", "h47.95" ] ] + ], + "dependencies": {} +} diff --git a/tests/validation/i2c_master/i2c_master.ino b/tests/validation/i2c_master/i2c_master.ino new file mode 100644 index 00000000000..3c7b2d9824a --- /dev/null +++ b/tests/validation/i2c_master/i2c_master.ino @@ -0,0 +1,271 @@ +/* + I2C Master Test for +*/ + +#include +#include +#include + +/* DS1307 functions */ + +const uint8_t DS1307_ADDR = 0x68; +const uint8_t start_sec = 1; +const uint8_t start_min = 2; +const uint8_t start_hour = 3; +const uint8_t start_day = 4; +const uint8_t start_month = 5; +const uint16_t start_year = 2020; + +static uint8_t read_sec = 0; +static uint8_t read_min = 0; +static uint8_t read_hour = 0; +static uint8_t read_day = 0; +static uint8_t read_month = 0; +static uint16_t read_year = 0; +static int peek_data = -1; + +const auto BCD2DEC = [](uint8_t num) -> uint8_t { + return ((num / 16 * 10) + (num % 16)); +}; + +const auto DEC2BCD = [](uint8_t num) -> uint8_t { + return ((num / 10 * 16) + (num % 10)); +}; + +void reset_read_values() { + read_sec = 0; + read_min = 0; + read_hour = 0; + read_day = 0; + read_month = 0; + read_year = 0; +} + +void ds1307_start(void) { + uint8_t sec; + + //Get seconds + Wire.beginTransmission(DS1307_ADDR); + Wire.write(0x00); + Wire.endTransmission(); + Wire.requestFrom(DS1307_ADDR, 1); + sec = Wire.read() & 0x7F; //Seconds without halt bit + + //Set seconds and start clock + Wire.beginTransmission(DS1307_ADDR); + Wire.write(0x00); + Wire.write(sec); + Wire.endTransmission(); +} + +void ds1307_stop(void) { + uint8_t sec; + + //Get seconds + Wire.beginTransmission(DS1307_ADDR); + Wire.write(0x00); + Wire.endTransmission(); + Wire.requestFrom(DS1307_ADDR, 1); + sec = Wire.read() | 0x80; //Seconds with halt bit + + //Set seconds and halt clock + Wire.beginTransmission(DS1307_ADDR); + Wire.write(0x00); + Wire.write(sec); + Wire.endTransmission(); +} + +void ds1307_get_time(uint8_t *sec, uint8_t *min, uint8_t *hour, uint8_t *day, uint8_t *month, uint16_t *year) { + //Get time + Wire.beginTransmission(DS1307_ADDR); + Wire.write(0x00); + Wire.endTransmission(); + Wire.requestFrom(DS1307_ADDR, 7); + + TEST_ASSERT_EQUAL(7, Wire.available()); + + if (peek_data == -1 && Wire.peek() != -1) { + peek_data = Wire.peek(); + } + + *sec = BCD2DEC(Wire.read() & 0x7F); //Seconds without halt bit + *min = BCD2DEC(Wire.read()); + *hour = BCD2DEC(Wire.read() & 0x3F); + Wire.read(); //Ignore day of week + *day = BCD2DEC(Wire.read()); + *month = BCD2DEC(Wire.read()); + *year = BCD2DEC(Wire.read()) + 2000; +} + +void ds1307_set_time(uint8_t sec, uint8_t min, uint8_t hour, uint8_t day, uint8_t month, uint16_t year) { + Wire.beginTransmission(DS1307_ADDR); + Wire.write(0x00); + Wire.write(DEC2BCD(sec)); + Wire.write(DEC2BCD(min)); + Wire.write(DEC2BCD(hour)); + Wire.write(DEC2BCD(0)); //Ignore day of week + Wire.write(DEC2BCD(day)); + Wire.write(DEC2BCD(month)); + Wire.write(DEC2BCD(year - 2000)); + Wire.endTransmission(); +} + +/* Unity functions */ + +// This function is automatically called by unity before each test is run +void setUp(void) { + reset_read_values(); + Wire.begin(); +} + +// This function is automatically called by unity after each test is run +void tearDown(void) { + //Reset time + ds1307_set_time(start_sec, start_min, start_hour, start_day, start_month, start_year); + + Wire.end(); +} + +void rtc_set_time() { + //Set time + ds1307_set_time(start_sec, start_min, start_hour, start_day, start_month, start_year); + + //Get time + ds1307_get_time(&read_sec, &read_min, &read_hour, &read_day, &read_month, &read_year); + + //Check time + TEST_ASSERT_EQUAL(start_sec, read_sec); + TEST_ASSERT_EQUAL(start_min, read_min); + TEST_ASSERT_EQUAL(start_hour, read_hour); + TEST_ASSERT_EQUAL(start_day, read_day); + TEST_ASSERT_EQUAL(start_month, read_month); + TEST_ASSERT_EQUAL(start_year, read_year); +} + +void rtc_run_clock() { + uint8_t old_sec = 0; + + //Run clock for 5 seconds + ds1307_start(); + delay(5000); + ds1307_stop(); + + //Get time + ds1307_get_time(&read_sec, &read_min, &read_hour, &read_day, &read_month, &read_year); + + //Check time + TEST_ASSERT_UINT8_WITHIN(2, start_sec + 5, read_sec); + TEST_ASSERT_EQUAL(start_min, read_min); + TEST_ASSERT_EQUAL(start_hour, read_hour); + TEST_ASSERT_EQUAL(start_day, read_day); + TEST_ASSERT_EQUAL(start_month, read_month); + TEST_ASSERT_EQUAL(start_year, read_year); + + old_sec = read_sec; + reset_read_values(); + + //Get time again to check that clock is stopped + delay(2000); + ds1307_get_time(&read_sec, &read_min, &read_hour, &read_day, &read_month, &read_year); + + //Check time + TEST_ASSERT_EQUAL(old_sec, read_sec); + TEST_ASSERT_EQUAL(start_min, read_min); + TEST_ASSERT_EQUAL(start_hour, read_hour); + TEST_ASSERT_EQUAL(start_day, read_day); + TEST_ASSERT_EQUAL(start_month, read_month); + TEST_ASSERT_EQUAL(start_year, read_year); +} + +void change_clock() { + //Get time + ds1307_get_time(&read_sec, &read_min, &read_hour, &read_day, &read_month, &read_year); + + //Check time + TEST_ASSERT_EQUAL(start_sec, read_sec); + TEST_ASSERT_EQUAL(start_min, read_min); + TEST_ASSERT_EQUAL(start_hour, read_hour); + TEST_ASSERT_EQUAL(start_day, read_day); + TEST_ASSERT_EQUAL(start_month, read_month); + TEST_ASSERT_EQUAL(start_year, read_year); + + Wire.setClock(400000); + reset_read_values(); + + TEST_ASSERT_EQUAL(400000, Wire.getClock()); + + //Get time + ds1307_get_time(&read_sec, &read_min, &read_hour, &read_day, &read_month, &read_year); + + //Check time + TEST_ASSERT_EQUAL(start_sec, read_sec); + TEST_ASSERT_EQUAL(start_min, read_min); + TEST_ASSERT_EQUAL(start_hour, read_hour); + TEST_ASSERT_EQUAL(start_day, read_day); + TEST_ASSERT_EQUAL(start_month, read_month); + TEST_ASSERT_EQUAL(start_year, read_year); +} + +void swap_pins() { + Wire.setPins(SCL, SDA); + Wire.begin(); + //Set time + ds1307_set_time(start_sec, start_min, start_hour, start_day, start_month, start_year); + + //Get time + ds1307_get_time(&read_sec, &read_min, &read_hour, &read_day, &read_month, &read_year); + + //Check time + TEST_ASSERT_EQUAL(start_sec, read_sec); + TEST_ASSERT_EQUAL(start_min, read_min); + TEST_ASSERT_EQUAL(start_hour, read_hour); + TEST_ASSERT_EQUAL(start_day, read_day); + TEST_ASSERT_EQUAL(start_month, read_month); + TEST_ASSERT_EQUAL(start_year, read_year); + + Wire.setPins(SDA, SCL); +} + +void test_api() { + int integer_ret; + + // Set Buffer Size + integer_ret = Wire.setBufferSize(32); + TEST_ASSERT_EQUAL(32, integer_ret); + integer_ret = Wire.setBufferSize(I2C_BUFFER_LENGTH); + TEST_ASSERT_EQUAL(I2C_BUFFER_LENGTH, integer_ret); + + // Set TimeOut + Wire.setTimeOut(100); + TEST_ASSERT_EQUAL(100, Wire.getTimeOut()); + + // Check if buffer can be peeked + TEST_ASSERT_GREATER_THAN(-1, peek_data); + + Wire.flush(); +} + +/* Main */ + +void setup() { + Serial.begin(115200); + while (!Serial) { + delay(10); + } + + log_d("Starting I2C Master"); + Wire.begin(); + + log_d("Starting tests"); + UNITY_BEGIN(); + RUN_TEST(rtc_set_time); + RUN_TEST(rtc_run_clock); + RUN_TEST(change_clock); + RUN_TEST(swap_pins); + RUN_TEST(test_api); + UNITY_END(); +} + +void loop() { + vTaskDelete(NULL); +} diff --git a/tests/validation/i2c_master/test_i2c_master.py b/tests/validation/i2c_master/test_i2c_master.py new file mode 100644 index 00000000000..da5f790c0f8 --- /dev/null +++ b/tests/validation/i2c_master/test_i2c_master.py @@ -0,0 +1,2 @@ +def test_i2c_master(dut): + dut.expect_unity_test_output(timeout=240) diff --git a/tests/validation/psram/ci.json b/tests/validation/psram/ci.json index 341df103671..999d3be953e 100644 --- a/tests/validation/psram/ci.json +++ b/tests/validation/psram/ci.json @@ -1,7 +1,6 @@ { "platforms": { - "qemu": false, - "wokwi": false + "qemu": false }, "requires": [ "CONFIG_SPIRAM=y" From cd95e4055bc4cc9df2e6e2bccdcdf9a1361b86d4 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Wed, 19 Feb 2025 19:52:01 -0300 Subject: [PATCH 43/79] ci(report): Add runtime tests report (#10764) --- .github/scripts/tests_run.sh | 10 ++++---- .github/workflows/tests_results.yml | 37 +++++++++++++++++++++++++---- .github/workflows/tests_wokwi.yml | 4 ++++ README.md | 2 +- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/.github/scripts/tests_run.sh b/.github/scripts/tests_run.sh index 8cb21ee519b..274666c8a44 100755 --- a/.github/scripts/tests_run.sh +++ b/.github/scripts/tests_run.sh @@ -11,9 +11,11 @@ function run_test { local error=0 local sdkconfig_path local extra_args + local test_type sketchdir=$(dirname "$sketch") sketchname=$(basename "$sketchdir") + test_type=$(basename "$(dirname "$sketchdir")") if [ "$options" -eq 0 ] && [ -f "$sketchdir"/ci.json ]; then len=$(jq -r --arg target "$target" '.fqbn[$target] | length' "$sketchdir"/ci.json) @@ -113,14 +115,14 @@ function run_test { rm "$sketchdir"/diagram.json 2>/dev/null || true result=0 - printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "${extra_args[*]@Q}" - bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" ${extra_args[*]@Q}; exit \$?" || result=$? + printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}" + bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$? printf "\n" if [ $result -ne 0 ]; then result=0 printf "\033[95mRetrying test: %s -- Config: %s\033[0m\n" "$sketchname" "$i" - printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "${extra_args[*]@Q}" - bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" ${extra_args[*]@Q}; exit \$?" || result=$? + printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}" + bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$? printf "\n" if [ $result -ne 0 ]; then printf "\033[91mFailed test: %s -- Config: %s\033[0m\n\n" "$sketchname" "$i" diff --git a/.github/workflows/tests_results.yml b/.github/workflows/tests_results.yml index 947de64ece5..9e213fad14e 100644 --- a/.github/workflows/tests_results.yml +++ b/.github/workflows/tests_results.yml @@ -41,6 +41,7 @@ jobs: original_sha=$(cat ./artifacts/parent-artifacts/sha.txt) original_ref=$(cat ./artifacts/parent-artifacts/ref.txt) original_conclusion=$(cat ./artifacts/parent-artifacts/conclusion.txt) + original_run_id=$(cat ./artifacts/parent-artifacts/run_id.txt) # Sanitize the values to avoid security issues @@ -59,17 +60,27 @@ jobs: # Conclusion: Allow alphabetical characters and underscores original_conclusion=$(echo "$original_conclusion" | tr -cd '[:alpha:]_') + # Run ID: Allow numeric characters + original_run_id=$(echo "$original_run_id" | tr -cd '[:digit:]') + echo "original_event=$original_event" >> $GITHUB_ENV echo "original_action=$original_action" >> $GITHUB_ENV echo "original_sha=$original_sha" >> $GITHUB_ENV echo "original_ref=$original_ref" >> $GITHUB_ENV echo "original_conclusion=$original_conclusion" >> $GITHUB_ENV + echo "original_run_id=$original_run_id" >> $GITHUB_ENV echo "original_event = $original_event" echo "original_action = $original_action" echo "original_sha = $original_sha" echo "original_ref = $original_ref" echo "original_conclusion = $original_conclusion" + echo "original_run_id = $original_run_id" + + - name: Print links to other runs + run: | + echo "Build, Hardware and QEMU tests: https://github.com/${{ github.repository }}/actions/runs/${{ env.original_run_id }}" + echo "Wokwi tests: https://github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}" - name: Publish Unit Test Results uses: EnricoMi/publish-unit-test-result-action@v2 @@ -80,6 +91,17 @@ jobs: files: ./artifacts/**/*.xml action_fail: true compare_to_earlier_commit: false + json_file: ./unity_results.json + json_suite_details: true + + - name: Upload JSON + uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: unity_results + overwrite: true + path: | + ./unity_results.json - name: Fail if tests failed if: ${{ env.original_conclusion == 'failure' || env.original_conclusion == 'timed_out' || github.event.workflow_run.conclusion == 'failure' || github.event.workflow_run.conclusion == 'timed_out' }} @@ -138,11 +160,18 @@ jobs: })).data; core.info(`${name} is ${state}`); - - name: Create output folder + - name: Generate report if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }} # codespell:ignore cancelled + env: + REPORT_FILE: ./runtime-tests-results/RUNTIME_TESTS_REPORT.md + WOKWI_RUN_ID: ${{ github.event.workflow_run.id }} + BUILD_RUN_ID: ${{ env.original_run_id }} + IS_FAILING: ${{ env.original_conclusion == 'failure' || env.original_conclusion == 'timed_out' || github.event.workflow_run.conclusion == 'failure' || github.event.workflow_run.conclusion == 'timed_out' || job.status == 'failure' }} run: | - rm -rf artifacts - mkdir -p runtime-tests-results + rm -rf artifacts $REPORT_FILE + mv -f ./unity_results.json ./runtime-tests-results/unity_results.json + touch $REPORT_FILE + python3 ./runtime-tests-results/table_generator.py ./runtime-tests-results/unity_results.json >> $REPORT_FILE - name: Generate badge if: ${{ !cancelled() && (env.original_event == 'schedule' || env.original_event == 'workflow_dispatch') }} # codespell:ignore cancelled @@ -161,6 +190,6 @@ jobs: git config user.email "41898282+github-actions[bot]@users.noreply.github.com" if [[ `git status --porcelain` ]]; then git add --all - git commit -m "Updated runtime tests badge" + git commit -m "Updated runtime tests report" git push origin HEAD:gh-pages fi diff --git a/.github/workflows/tests_wokwi.yml b/.github/workflows/tests_wokwi.yml index f5eb2efcad2..c254d5fa153 100644 --- a/.github/workflows/tests_wokwi.yml +++ b/.github/workflows/tests_wokwi.yml @@ -109,6 +109,10 @@ jobs: printf "\nAction = " cat artifacts/action.txt + printf "${{ github.event.workflow_run.id }}" >> artifacts/run_id.txt + printf "\nRun ID = " + cat artifacts/run_id.txt + if [ -z "$ref" ] || [ "$ref" == "null" ]; then echo "Failed to get PR number or ref" exit 1 diff --git a/README.md b/README.md index 0a9a6d0440c..9d300b25c54 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build Status](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/push.yml?branch=master&event=push&label=Compilation%20Tests)](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml?query=branch%3Amaster+event%3Apush) [![Verbose Build Status](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/push.yml?branch=master&event=schedule&label=Compilation%20Tests%20(Verbose))](https://github.com/espressif/arduino-esp32/actions/workflows/push.yml?query=branch%3Amaster+event%3Aschedule) [![External Libraries Test](https://img.shields.io/github/actions/workflow/status/espressif/arduino-esp32/lib.yml?branch=master&event=schedule&label=External%20Libraries%20Test)](https://github.com/espressif/arduino-esp32/blob/gh-pages/LIBRARIES_TEST.md) -[![Runtime Tests](https://github.com/espressif/arduino-esp32/blob/gh-pages/runtime-tests-results/badge.svg)](https://github.com/espressif/arduino-esp32/actions/workflows/tests_results.yml) +[![Runtime Tests](https://github.com/espressif/arduino-esp32/blob/gh-pages/runtime-tests-results/badge.svg)](https://github.com/espressif/arduino-esp32/blob/gh-pages/runtime-tests-results/RUNTIME_TESTS_REPORT.md) ### Need help or have a question? Join the chat at [Discord](https://discord.gg/8xY6e9crwv) or [open a new Discussion](https://github.com/espressif/arduino-esp32/discussions) From 9a783a5d2cce0b4abb3e0583e7df7af905f89a87 Mon Sep 17 00:00:00 2001 From: pwclay <57820386+pwclay@users.noreply.github.com> Date: Thu, 20 Feb 2025 21:59:43 +1300 Subject: [PATCH 44/79] feat(zigbee): Add Analog endpoint device (input, output, value clusters) (#10950) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add analog sensor modules * feat(zigbee): Add analog value, input and output support * fix(zigbee): add missing functiong to header file * fix(zigbee): Update log messages * ci(pre-commit): Apply automatic fixes * fix(example): Fix comment typo --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Co-authored-by: Me No Dev Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- CMakeLists.txt | 1 + .../Zigbee_Analog_Input_Output/README.md | 72 ++++++++++ .../Zigbee_Analog_Input_Output.ino | 119 +++++++++++++++++ .../Zigbee_Analog_Input_Output/ci.json | 6 + libraries/Zigbee/src/Zigbee.h | 1 + libraries/Zigbee/src/ep/ZigbeeAnalog.cpp | 124 ++++++++++++++++++ libraries/Zigbee/src/ep/ZigbeeAnalog.h | 76 +++++++++++ libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp | 3 +- 8 files changed, 401 insertions(+), 1 deletion(-) create mode 100644 libraries/Zigbee/examples/Zigbee_Analog_Input_Output/README.md create mode 100644 libraries/Zigbee/examples/Zigbee_Analog_Input_Output/Zigbee_Analog_Input_Output.ino create mode 100644 libraries/Zigbee/examples/Zigbee_Analog_Input_Output/ci.json create mode 100644 libraries/Zigbee/src/ep/ZigbeeAnalog.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeAnalog.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7436eb1833c..97ad068eb48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -295,6 +295,7 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp + libraries/Zigbee/src/ep/ZigbeeAnalog.cpp libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp ) diff --git a/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/README.md b/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/README.md new file mode 100644 index 00000000000..d62941755c7 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/README.md @@ -0,0 +1,72 @@ +# Arduino-ESP32 Zigbee Analog Input Output Example + +This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) analog input/output device. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +## Analog Sensor Functions + + * After this board first starts up, it would be configured locally to report an analog input on change or every 30 seconds. + * By clicking the button (BOOT) on this board, this board will immediately send a report of the current measured value to the network. + +## Hardware Required + +* A USB cable for power supply and programming + +### Configure the Project + +Set the ADC GPIO by changing the `analogPin` variable. By default, it's the pin `A0`. +Set the Button GPIO by changing the `button` variable. By default, it's the pin `BOOT_PIN` (BOOT button on ESP32-C6 and ESP32-H2). + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ED (end device)` +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs` +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. +* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. + +## Troubleshooting + +If the End device flashed with this example is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. It is recommended to do this if you re-flash the coordinator. +You can do the following: + +* In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. +* Add to the sketch `Zigbee.factoryReset();` to reset the device and Zigbee stack. + +By default, the coordinator network is closed after rebooting or flashing new firmware. +To open the network you have 2 options: + +* Open network after reboot by setting `Zigbee.setRebootOpenNetwork(time);` before calling `Zigbee.begin();`. +* In application you can anytime call `Zigbee.openNetwork(time);` to open the network for devices to join. + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/Zigbee_Analog_Input_Output.ino b/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/Zigbee_Analog_Input_Output.ino new file mode 100644 index 00000000000..e31407cc8be --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/Zigbee_Analog_Input_Output.ino @@ -0,0 +1,119 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +/** + * @brief This example demonstrates Zigbee analog input / output device. + * + * The example demonstrates how to use Zigbee library to create a end device analog device. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + * Modified by Pat Clay + */ + +#ifndef ZIGBEE_MODE_ED +#error "Zigbee end device mode is not selected in Tools->Zigbee mode" +#endif + +#include "Zigbee.h" + +/* Zigbee analog device configuration */ +#define ANALOG_DEVICE_ENDPOINT_NUMBER 1 + +uint8_t analogPin = A0; +uint8_t button = BOOT_PIN; + +ZigbeeAnalog zbAnalogDevice = ZigbeeAnalog(ANALOG_DEVICE_ENDPOINT_NUMBER); + +void onAnalogOutputChange(float analog_output) { + Serial.printf("Received analog output change: %.1f\r\n", analog_output); +} + +void setup() { + Serial.begin(115200); + Serial.println("Starting..."); + + // Init button switch + pinMode(button, INPUT_PULLUP); + + // Set analog resolution to 10 bits + analogReadResolution(10); + + // Optional: set Zigbee device name and model + zbAnalogDevice.setManufacturerAndModel("Espressif", "ZigbeeAnalogDevice"); + + // Add analog clusters to Zigbee Analog according your needs + zbAnalogDevice.addAnalogInput(); + zbAnalogDevice.addAnalogOutput(); + + // If analog output cluster is added, set callback function for analog output change + zbAnalogDevice.onAnalogOutputChange(onAnalogOutputChange); + + // Add endpoints to Zigbee Core + Zigbee.addEndpoint(&zbAnalogDevice); + + Serial.println("Starting Zigbee..."); + // When all EPs are registered, start Zigbee in End Device mode + if (!Zigbee.begin()) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } else { + Serial.println("Zigbee started successfully!"); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println("Connected"); + + // Optional: Add reporting for analog input + zbAnalogDevice.setAnalogInputReporting(0, 30, 10); // report every 30 seconds if value changes by 10 +} + +void loop() { + static uint32_t timeCounter = 0; + + // Read ADC value and update the analog value every 2s + if (!(timeCounter++ % 20)) { // delaying for 100ms x 20 = 2s + float analog = (float)analogRead(analogPin); + Serial.printf("Updating analog input to %.1f\r\n", analog); + zbAnalogDevice.setAnalogInput(analog); + + // Analog input supports reporting + zbAnalogDevice.reportAnalogInput(); + } + + // Checking button for factory reset and reporting + if (digitalRead(button) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(button) == LOW) { + delay(50); + if ((millis() - startTime) > 3000) { + // If key pressed for more than 3secs, factory reset Zigbee and reboot + Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + delay(1000); + Zigbee.factoryReset(); + } + } + } + delay(100); +} diff --git a/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/ci.json b/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/ci.json new file mode 100644 index 00000000000..7b7ccef8ed7 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/ci.json @@ -0,0 +1,6 @@ +{ + "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", + "requires": [ + "CONFIG_SOC_IEEE802154_SUPPORTED=y" + ] +} diff --git a/libraries/Zigbee/src/Zigbee.h b/libraries/Zigbee/src/Zigbee.h index 7353f661416..c8e7481e58f 100644 --- a/libraries/Zigbee/src/Zigbee.h +++ b/libraries/Zigbee/src/Zigbee.h @@ -15,6 +15,7 @@ #include "ep/ZigbeeTempSensor.h" #include "ep/ZigbeeThermostat.h" #include "ep/ZigbeePressureSensor.h" +#include "ep/ZigbeeAnalog.h" #include "ep/ZigbeeFlowSensor.h" #include "ep/ZigbeeOccupancySensor.h" #include "ep/ZigbeeCarbonDioxideSensor.h" diff --git a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp new file mode 100644 index 00000000000..25c199b345b --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp @@ -0,0 +1,124 @@ +#include "ZigbeeAnalog.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +esp_zb_cluster_list_t *zigbee_analog_clusters_create(zigbee_analog_cfg_t *analog_sensor) { + esp_zb_basic_cluster_cfg_t *basic_cfg = analog_sensor ? &(analog_sensor->basic_cfg) : NULL; + esp_zb_identify_cluster_cfg_t *identify_cfg = analog_sensor ? &(analog_sensor->identify_cfg) : NULL; + esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + return cluster_list; +} + +ZigbeeAnalog::ZigbeeAnalog(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID; + + //Create custom analog sensor configuration + zigbee_analog_cfg_t analog_cfg = ZIGBEE_DEFAULT_ANALOG_CONFIG(); + _cluster_list = zigbee_analog_clusters_create(&analog_cfg); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID, .app_device_version = 0}; +} + +void ZigbeeAnalog::addAnalogValue() { + esp_zb_cluster_list_add_analog_value_cluster(_cluster_list, esp_zb_analog_value_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + _analog_clusters |= ANALOG_VALUE; +} + +void ZigbeeAnalog::addAnalogInput() { + esp_zb_cluster_list_add_analog_input_cluster(_cluster_list, esp_zb_analog_input_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + _analog_clusters |= ANALOG_INPUT; +} + +void ZigbeeAnalog::addAnalogOutput() { + esp_zb_cluster_list_add_analog_output_cluster(_cluster_list, esp_zb_analog_output_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + _analog_clusters |= ANALOG_OUTPUT; +} + +//set attribute method -> method overridden in child class +void ZigbeeAnalog::zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) { + if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ANALOG_OUTPUT) { + if (message->attribute.id == ESP_ZB_ZCL_ATTR_ANALOG_OUTPUT_PRESENT_VALUE_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_SINGLE) { + float analog_output = *(float *)message->attribute.data.value; + analogOutputChanged(analog_output); + } else { + log_w("Received message ignored. Attribute ID: %d not supported for Analog Output", message->attribute.id); + } + } else { + log_w("Received message ignored. Cluster ID: %d not supported for Analog endpoint", message->info.cluster); + } +} + +void ZigbeeAnalog::analogOutputChanged(float analog_output) { + if (_on_analog_output_change) { + _on_analog_output_change(analog_output); + } else { + log_w("No callback function set for analog output change"); + } +} + +void ZigbeeAnalog::setAnalogValue(float analog) { + if (!(_analog_clusters & ANALOG_VALUE)) { + log_e("Analog Value cluster not added"); + return; + } + // float zb_analog = analog; + log_d("Setting analog value to %.1f", analog); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_ANALOG_VALUE, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ANALOG_VALUE_PRESENT_VALUE_ID, &analog, false + ); + esp_zb_lock_release(); +} + +void ZigbeeAnalog::setAnalogInput(float analog) { + if (!(_analog_clusters & ANALOG_INPUT)) { + log_e("Analog Input cluster not added"); + return; + } + // float zb_analog = analog; + log_d("Setting analog input to %.1f", analog); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_ANALOG_INPUT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ANALOG_INPUT_PRESENT_VALUE_ID, &analog, false + ); + esp_zb_lock_release(); +} + +void ZigbeeAnalog::reportAnalogInput() { + /* Send report attributes command */ + esp_zb_zcl_report_attr_cmd_t report_attr_cmd; + report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + report_attr_cmd.attributeID = ESP_ZB_ZCL_ATTR_ANALOG_INPUT_PRESENT_VALUE_ID; + report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; + report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_ANALOG_INPUT; + report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); + esp_zb_lock_release(); + log_v("Analog Input report sent"); +} + +void ZigbeeAnalog::setAnalogInputReporting(uint16_t min_interval, uint16_t max_interval, float delta) { + esp_zb_zcl_reporting_info_t reporting_info; + memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t)); + reporting_info.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV; + reporting_info.ep = _endpoint; + reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; + reporting_info.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE; + reporting_info.attr_id = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID; + reporting_info.u.send_info.min_interval = min_interval; + reporting_info.u.send_info.max_interval = max_interval; + reporting_info.u.send_info.def_min_interval = min_interval; + reporting_info.u.send_info.def_max_interval = max_interval; + reporting_info.u.send_info.delta.s32 = delta; + reporting_info.dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID; + reporting_info.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; + + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_update_reporting_info(&reporting_info); + esp_zb_lock_release(); +} + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeAnalog.h b/libraries/Zigbee/src/ep/ZigbeeAnalog.h new file mode 100644 index 00000000000..e3b22594324 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeAnalog.h @@ -0,0 +1,76 @@ +/* Class of Zigbee Analog sensor endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +// clang-format off +#define ZIGBEE_DEFAULT_ANALOG_CONFIG() \ + { \ + .basic_cfg = \ + { \ + .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE, \ + .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE, \ + }, \ + .identify_cfg = \ + { \ + .identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, \ + }, \ + } +// clang-format on + +//enum for bits set to check what analog cluster were added +enum zigbee_analog_clusters { + ANALOG_VALUE = 1, + ANALOG_INPUT = 2, + ANALOG_OUTPUT = 4 +}; + +typedef struct zigbee_analog_cfg_s { + esp_zb_basic_cluster_cfg_t basic_cfg; + esp_zb_identify_cluster_cfg_t identify_cfg; + esp_zb_analog_value_cluster_cfg_t analog_value_cfg; + esp_zb_analog_output_cluster_cfg_t analog_output_cfg; + esp_zb_analog_input_cluster_cfg_t analog_input_cfg; +} zigbee_analog_cfg_t; + +class ZigbeeAnalog : public ZigbeeEP { +public: + ZigbeeAnalog(uint8_t endpoint); + ~ZigbeeAnalog() {} + + // Add analog clusters + void addAnalogValue(); + void addAnalogInput(); + void addAnalogOutput(); + + // Use to set a cb function to be called on analog output change + void onAnalogOutputChange(void (*callback)(float analog)) { + _on_analog_output_change = callback; + } + + // Set the analog value / input + void setAnalogValue(float analog); + void setAnalogInput(float analog); + + // Report Analog Input + void reportAnalogInput(); + + // Set reporting for Analog Input + void setAnalogInputReporting(uint16_t min_interval, uint16_t max_interval, float delta); + +private: + void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override; + + void (*_on_analog_output_change)(float); + void analogOutputChanged(float analog_output); + + uint8_t _analog_clusters; +}; + +#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp index d419fb14adc..90df37b91f5 100644 --- a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp @@ -48,7 +48,8 @@ void ZigbeeTempSensor::setReporting(uint16_t min_interval, uint16_t max_interval reporting_info.u.send_info.def_max_interval = max_interval; reporting_info.u.send_info.delta.u16 = (uint16_t)(delta * 100); // Convert delta to ZCL uint16_t reporting_info.dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID; - reporting_info.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC, esp_zb_lock_acquire(portMAX_DELAY); + reporting_info.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; + esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_update_reporting_info(&reporting_info); esp_zb_lock_release(); } From 003db9e4c0c352344b984ba1ac25f6a3f706dfe5 Mon Sep 17 00:00:00 2001 From: SooDragon <82627949+SooDragon@users.noreply.github.com> Date: Fri, 21 Feb 2025 19:27:11 +0900 Subject: [PATCH 45/79] Update pins_arduino.h (#11000) --- variants/Geekble_ESP32C3/pins_arduino.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variants/Geekble_ESP32C3/pins_arduino.h b/variants/Geekble_ESP32C3/pins_arduino.h index 4eec3aa2f68..660313ce849 100644 --- a/variants/Geekble_ESP32C3/pins_arduino.h +++ b/variants/Geekble_ESP32C3/pins_arduino.h @@ -27,6 +27,6 @@ static const uint8_t A1 = 1; static const uint8_t A2 = 2; static const uint8_t A3 = 3; static const uint8_t A4 = 4; -static const uint8_t A5 = 5; +//static const uint8_t A5 = 5; // ADC1 no longer supported #endif /* Pins_Arduino_h */ From 543a647f2c806e038a115230f9a0e0ef3b561de5 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Fri, 21 Feb 2025 23:47:01 -0300 Subject: [PATCH 46/79] ci(test): Fix PSRAM test --- tests/validation/psram/diagram.esp32s3.json | 24 +++++++++++++++++++++ tests/validation/psram/psram.ino | 16 +++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/validation/psram/diagram.esp32s3.json diff --git a/tests/validation/psram/diagram.esp32s3.json b/tests/validation/psram/diagram.esp32s3.json new file mode 100644 index 00000000000..837ff1eed33 --- /dev/null +++ b/tests/validation/psram/diagram.esp32s3.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "author": "lucasssvaz", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-s3-devkitc-1", + "id": "esp", + "attrs": { "psramType": "octal" } + } + ], + "connections": [ + [ + "esp:TX", + "$serialMonitor:RX", + "" + ], + [ + "esp:RX", + "$serialMonitor:TX", + "" + ] + ] +} diff --git a/tests/validation/psram/psram.ino b/tests/validation/psram/psram.ino index 1304fe85cc1..a53be84fd68 100644 --- a/tests/validation/psram/psram.ino +++ b/tests/validation/psram/psram.ino @@ -4,6 +4,12 @@ #define MAX_TEST_SIZE 512 * 1024 // 512KB void *buf = NULL; +uint32_t psram_size = 0; + +void psram_found(void) { + psram_size = ESP.getPsramSize(); + TEST_ASSERT_TRUE(psram_size > 0); +} void test_malloc_success(void) { buf = ps_malloc(MAX_TEST_SIZE); @@ -96,6 +102,13 @@ void setup() { } UNITY_BEGIN(); + RUN_TEST(psram_found); + + if (psram_size == 0) { + UNITY_END(); + return; + } + RUN_TEST(test_malloc_success); RUN_TEST(test_malloc_fail); RUN_TEST(test_calloc_success); @@ -104,7 +117,8 @@ void setup() { RUN_TEST(test_memset_all_zeroes); RUN_TEST(test_memset_all_ones); RUN_TEST(test_memset_alternating); - RUN_TEST(test_memset_random); + //This test is disabled because it takes too long to run on some wokwi boards + //RUN_TEST(test_memset_random); RUN_TEST(test_memcpy); UNITY_END(); } From 42bd7456ce17013f73110b219e9aa96da4b6306e Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Fri, 21 Feb 2025 23:54:52 -0300 Subject: [PATCH 47/79] ci(test): Fix GPIO test --- tests/validation/gpio/scenario.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/validation/gpio/scenario.yaml b/tests/validation/gpio/scenario.yaml index a915b546b49..957f58b2176 100644 --- a/tests/validation/gpio/scenario.yaml +++ b/tests/validation/gpio/scenario.yaml @@ -6,31 +6,31 @@ steps: - wait-serial: "Button test" # Need for 1s delay for scenario to run properly - - delay: 1000ms + - delay: 5000ms # Press once - set-control: part-id: btn1 control: pressed value: 1 - - delay: 200ms + - delay: 2000ms - set-control: part-id: btn1 control: pressed value: 0 - - delay: 300ms + - delay: 3000ms # Press 2nd time - set-control: part-id: btn1 control: pressed value: 1 - - delay: 200ms + - delay: 2000ms - set-control: part-id: btn1 control: pressed value: 0 - - delay: 300ms + - delay: 3000ms # Press for the 3rd time - set-control: From 988dbe29731e2a2d09db2ed642c06271afa93705 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Sat, 22 Feb 2025 01:27:17 -0300 Subject: [PATCH 48/79] ci(test): Skip some PSRAM tests in P4 --- tests/validation/psram/psram.ino | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/validation/psram/psram.ino b/tests/validation/psram/psram.ino index a53be84fd68..7bf7bc11c5d 100644 --- a/tests/validation/psram/psram.ino +++ b/tests/validation/psram/psram.ino @@ -117,9 +117,11 @@ void setup() { RUN_TEST(test_memset_all_zeroes); RUN_TEST(test_memset_all_ones); RUN_TEST(test_memset_alternating); - //This test is disabled because it takes too long to run on some wokwi boards - //RUN_TEST(test_memset_random); +#ifndef CONFIG_IDF_TARGET_ESP32P4 + // These tests are taking too long on ESP32-P4 in Wokwi + RUN_TEST(test_memset_random); RUN_TEST(test_memcpy); +#endif UNITY_END(); } From 39be694127034bb54f9c15828393d844fb3a59eb Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Tue, 25 Feb 2025 05:06:18 -0300 Subject: [PATCH 49/79] ci(runners): Bump runner images version (#10960) * ci(runners): Bump runner images version * ci(arm): Use github arm images --- .github/workflows/build_py_tools.yml | 12 ++++-------- .github/workflows/push.yml | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build_py_tools.yml b/.github/workflows/build_py_tools.yml index 48e7f2c82d3..d4dfca9c8d1 100644 --- a/.github/workflows/build_py_tools.yml +++ b/.github/workflows/build_py_tools.yml @@ -12,7 +12,7 @@ on: jobs: find-changed-tools: name: Check if tools have been changed - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest outputs: any_changed: ${{ steps.verify-changed-files.outputs.any_changed }} all_changed_files: ${{ steps.verify-changed-files.outputs.all_changed_files }} @@ -55,7 +55,7 @@ jobs: strategy: fail-fast: false matrix: - os: [windows-latest, macos-latest, ubuntu-20.04, ARM] + os: [windows-latest, macos-latest, ubuntu-latest, ubuntu-24.04-arm] include: - os: windows-latest TARGET: win64 @@ -64,14 +64,12 @@ jobs: - os: macos-latest TARGET: macos SEPARATOR: ":" - - os: ubuntu-20.04 + - os: ubuntu-latest TARGET: linux-amd64 SEPARATOR: ":" - - os: ARM - CONTAINER: python:3.8-bullseye + - os: ubuntu-24.04-arm TARGET: arm SEPARATOR: ":" - container: ${{ matrix.CONTAINER }} # use python container on ARM env: DISTPATH: pytools-${{ matrix.TARGET }} PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi" @@ -96,8 +94,6 @@ jobs: token: ${{ secrets.TOOLS_UPLOAD_PAT }} ref: ${{ github.event.pull_request.head.ref }} - name: Set up Python 3.8 - # Skip setting python on ARM because of missing compatibility: https://github.com/actions/setup-python/issues/108 - if: matrix.os != 'ARM' uses: actions/setup-python@master with: python-version: 3.8 diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index bd5acfa7a40..211ed1658f9 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -237,7 +237,7 @@ jobs: needs.gen-chunks.outputs.build_all == 'true' || needs.gen-chunks.outputs.build_libraries == 'true' || needs.gen-chunks.outputs.build_idf == 'true' - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: fail-fast: false matrix: From 164fcc6a61587909b8903c05501bdc5ceacb6006 Mon Sep 17 00:00:00 2001 From: Eric Lewis Date: Tue, 25 Feb 2025 03:06:54 -0500 Subject: [PATCH 50/79] fix(board): Update feathers3 wire1 pin definition (#11001) * update feathers3 wire1 pin definition * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Rodrigo Garcia --- variants/um_feathers3/pins_arduino.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/variants/um_feathers3/pins_arduino.h b/variants/um_feathers3/pins_arduino.h index 8de87c688a9..1c81339c88e 100644 --- a/variants/um_feathers3/pins_arduino.h +++ b/variants/um_feathers3/pins_arduino.h @@ -16,6 +16,10 @@ static const uint8_t RX = 44; static const uint8_t SDA = 8; static const uint8_t SCL = 9; +#define WIRE1_PIN_DEFINED 1 // See Wire.cpp at bool TwoWire::initPins(int sdaPin, int sclPin) +static const uint8_t SDA1 = 16; +static const uint8_t SCL1 = 15; + static const uint8_t SS = 5; static const uint8_t MOSI = 35; static const uint8_t MISO = 37; From 0c18b17ac4ac608114cf580f1473de4b6cf3c607 Mon Sep 17 00:00:00 2001 From: SooDragon <82627949+SooDragon@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:07:12 +0900 Subject: [PATCH 51/79] feat(boards): Add Geekble-nano-ESP32S3 (#11005) * add new board add new board * fix(board): add LED_BUILTIN #define --------- Co-authored-by: Rodrigo Garcia --- boards.txt | 190 +++++++++++++++++++ variants/Geekble_Nano_ESP32S3/pins_arduino.h | 74 ++++++++ 2 files changed, 264 insertions(+) create mode 100644 variants/Geekble_Nano_ESP32S3/pins_arduino.h diff --git a/boards.txt b/boards.txt index a83684bca18..a3700c22ef8 100644 --- a/boards.txt +++ b/boards.txt @@ -40832,6 +40832,196 @@ Geekble_ESP32C3.menu.EraseFlash.none.upload.erase_cmd= Geekble_ESP32C3.menu.EraseFlash.all=Enabled Geekble_ESP32C3.menu.EraseFlash.all.upload.erase_cmd=-e +############################################################## + +Geekble_Nano_ESP32S3.name=Geekble nano ESP32-S3 +Geekble_Nano_ESP32S3.vid.0=0x303a +Geekble_Nano_ESP32S3.pid.0= 0x82C5 +Geekble_Nano_ESP32S3.upload_port.0.vid=0x303a +Geekble_Nano_ESP32S3.upload_port.0.pid= 0x82C5 + +Geekble_Nano_ESP32S3.bootloader.tool=esptool_py +Geekble_Nano_ESP32S3.bootloader.tool.default=esptool_py + +Geekble_Nano_ESP32S3.upload.tool=esptool_py +Geekble_Nano_ESP32S3.upload.tool.default=esptool_py +Geekble_Nano_ESP32S3.upload.tool.network=esp_ota + +Geekble_Nano_ESP32S3.upload.maximum_size=1310720 + +Geekble_Nano_ESP32S3.upload.maximum_data_size=327680 +Geekble_Nano_ESP32S3.upload.flags= +Geekble_Nano_ESP32S3.upload.extra_flags= +Geekble_Nano_ESP32S3.upload.use_1200bps_touch=false +Geekble_Nano_ESP32S3.upload.wait_for_upload_port=false + +Geekble_Nano_ESP32S3.serial.disableDTR=false +Geekble_Nano_ESP32S3.serial.disableRTS=false + +Geekble_Nano_ESP32S3.build.tarch=xtensa +Geekble_Nano_ESP32S3.build.bootloader_addr=0x0 +Geekble_Nano_ESP32S3.build.target=esp32s3 +Geekble_Nano_ESP32S3.build.mcu=esp32s3 +Geekble_Nano_ESP32S3.build.core=esp32 +Geekble_Nano_ESP32S3.build.variant=Geekble_Nano_ESP32S3 +Geekble_Nano_ESP32S3.build.board=GEEKBLE_NANO_ESP32S3 + +Geekble_Nano_ESP32S3.build.usb_mode=1 +Geekble_Nano_ESP32S3.build.cdc_on_boot=1 +Geekble_Nano_ESP32S3.build.msc_on_boot=0 +Geekble_Nano_ESP32S3.build.dfu_on_boot=0 +Geekble_Nano_ESP32S3.build.f_cpu=240000000L +Geekble_Nano_ESP32S3.build.flash_size=4MB +Geekble_Nano_ESP32S3.build.flash_freq=80m +Geekble_Nano_ESP32S3.build.flash_mode=dio +Geekble_Nano_ESP32S3.build.boot=qio +Geekble_Nano_ESP32S3.build.boot_freq=80m +Geekble_Nano_ESP32S3.build.partitions=default +Geekble_Nano_ESP32S3.build.defines= +Geekble_Nano_ESP32S3.build.loop_core= +Geekble_Nano_ESP32S3.build.event_core= +Geekble_Nano_ESP32S3.build.psram_type=qspi +Geekble_Nano_ESP32S3.build.memory_type={build.boot}_{build.psram_type} + +Geekble_Nano_ESP32S3.menu.PSRAM.disabled=Disabled +Geekble_Nano_ESP32S3.menu.PSRAM.disabled.build.defines= +Geekble_Nano_ESP32S3.menu.PSRAM.disabled.build.psram_type=qspi +Geekble_Nano_ESP32S3.menu.PSRAM.enabled=Enabled +Geekble_Nano_ESP32S3.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM +Geekble_Nano_ESP32S3.menu.PSRAM.enabled.build.psram_type=qspi + +Geekble_Nano_ESP32S3.menu.FlashMode.qio=QIO 80MHz +Geekble_Nano_ESP32S3.menu.FlashMode.qio.build.flash_mode=dio +Geekble_Nano_ESP32S3.menu.FlashMode.qio.build.boot=qio +Geekble_Nano_ESP32S3.menu.FlashMode.qio.build.boot_freq=80m +Geekble_Nano_ESP32S3.menu.FlashMode.qio.build.flash_freq=80m +Geekble_Nano_ESP32S3.menu.FlashMode.qio120=QIO 120MHz +Geekble_Nano_ESP32S3.menu.FlashMode.qio120.build.flash_mode=dio +Geekble_Nano_ESP32S3.menu.FlashMode.qio120.build.boot=qio +Geekble_Nano_ESP32S3.menu.FlashMode.qio120.build.boot_freq=120m +Geekble_Nano_ESP32S3.menu.FlashMode.qio120.build.flash_freq=80m + +Geekble_Nano_ESP32S3.menu.LoopCore.1=Core 1 +Geekble_Nano_ESP32S3.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +Geekble_Nano_ESP32S3.menu.LoopCore.0=Core 0 +Geekble_Nano_ESP32S3.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +Geekble_Nano_ESP32S3.menu.EventsCore.1=Core 1 +Geekble_Nano_ESP32S3.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +Geekble_Nano_ESP32S3.menu.EventsCore.0=Core 0 +Geekble_Nano_ESP32S3.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +Geekble_Nano_ESP32S3.menu.USBMode.hwcdc=Hardware CDC and JTAG +Geekble_Nano_ESP32S3.menu.USBMode.hwcdc.build.usb_mode=1 +Geekble_Nano_ESP32S3.menu.USBMode.default=USB-OTG (TinyUSB) +Geekble_Nano_ESP32S3.menu.USBMode.default.build.usb_mode=0 + +Geekble_Nano_ESP32S3.menu.CDCOnBoot.default=Disabled +Geekble_Nano_ESP32S3.menu.CDCOnBoot.default.build.cdc_on_boot=0 +Geekble_Nano_ESP32S3.menu.CDCOnBoot.cdc=Enabled +Geekble_Nano_ESP32S3.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 + +Geekble_Nano_ESP32S3.menu.MSCOnBoot.default=Disabled +Geekble_Nano_ESP32S3.menu.MSCOnBoot.default.build.msc_on_boot=0 +Geekble_Nano_ESP32S3.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +Geekble_Nano_ESP32S3.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +Geekble_Nano_ESP32S3.menu.DFUOnBoot.default=Disabled +Geekble_Nano_ESP32S3.menu.DFUOnBoot.default.build.dfu_on_boot=0 +Geekble_Nano_ESP32S3.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode) +Geekble_Nano_ESP32S3.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +Geekble_Nano_ESP32S3.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +Geekble_Nano_ESP32S3.menu.UploadMode.cdc.upload.use_1200bps_touch=true +Geekble_Nano_ESP32S3.menu.UploadMode.cdc.upload.wait_for_upload_port=true + +Geekble_Nano_ESP32S3.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +Geekble_Nano_ESP32S3.menu.PartitionScheme.default.build.partitions=default +Geekble_Nano_ESP32S3.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +Geekble_Nano_ESP32S3.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +Geekble_Nano_ESP32S3.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +Geekble_Nano_ESP32S3.menu.PartitionScheme.no_ota.build.partitions=no_ota +Geekble_Nano_ESP32S3.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +Geekble_Nano_ESP32S3.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +Geekble_Nano_ESP32S3.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +Geekble_Nano_ESP32S3.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +Geekble_Nano_ESP32S3.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +Geekble_Nano_ESP32S3.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +Geekble_Nano_ESP32S3.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +Geekble_Nano_ESP32S3.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +Geekble_Nano_ESP32S3.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +Geekble_Nano_ESP32S3.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +Geekble_Nano_ESP32S3.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +Geekble_Nano_ESP32S3.menu.PartitionScheme.huge_app.build.partitions=huge_app +Geekble_Nano_ESP32S3.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +Geekble_Nano_ESP32S3.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +Geekble_Nano_ESP32S3.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +Geekble_Nano_ESP32S3.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 +Geekble_Nano_ESP32S3.menu.PartitionScheme.rainmaker=RainMaker 4MB +Geekble_Nano_ESP32S3.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +Geekble_Nano_ESP32S3.menu.PartitionScheme.rainmaker.upload.maximum_size=1966080 +Geekble_Nano_ESP32S3.menu.PartitionScheme.rainmaker_4MB=RainMaker 4MB No OTA +Geekble_Nano_ESP32S3.menu.PartitionScheme.rainmaker_4MB.build.partitions=rainmaker_4MB_no_ota +Geekble_Nano_ESP32S3.menu.PartitionScheme.rainmaker_4MB.upload.maximum_size=4038656 + +Geekble_Nano_ESP32S3.menu.PartitionScheme.otanofs=OTA no FS (2MB APP with OTA) +Geekble_Nano_ESP32S3.menu.PartitionScheme.otanofs.build.custom_partitions=ota_nofs_4MB +Geekble_Nano_ESP32S3.menu.PartitionScheme.otanofs.upload.maximum_size=2031616 +Geekble_Nano_ESP32S3.menu.PartitionScheme.all_app=Max APP (4MB APP no OTA) +Geekble_Nano_ESP32S3.menu.PartitionScheme.all_app.build.custom_partitions=max_app_4MB +Geekble_Nano_ESP32S3.menu.PartitionScheme.all_app.upload.maximum_size=4063232 + +Geekble_Nano_ESP32S3.menu.PartitionScheme.custom=Custom +Geekble_Nano_ESP32S3.menu.PartitionScheme.custom.build.partitions= +Geekble_Nano_ESP32S3.menu.PartitionScheme.custom.upload.maximum_size=16777216 + +Geekble_Nano_ESP32S3.menu.CPUFreq.240=240MHz (WiFi) +Geekble_Nano_ESP32S3.menu.CPUFreq.240.build.f_cpu=240000000L +Geekble_Nano_ESP32S3.menu.CPUFreq.160=160MHz (WiFi) +Geekble_Nano_ESP32S3.menu.CPUFreq.160.build.f_cpu=160000000L +Geekble_Nano_ESP32S3.menu.CPUFreq.80=80MHz (WiFi) +Geekble_Nano_ESP32S3.menu.CPUFreq.80.build.f_cpu=80000000L +Geekble_Nano_ESP32S3.menu.CPUFreq.40=40MHz +Geekble_Nano_ESP32S3.menu.CPUFreq.40.build.f_cpu=40000000L +Geekble_Nano_ESP32S3.menu.CPUFreq.20=20MHz +Geekble_Nano_ESP32S3.menu.CPUFreq.20.build.f_cpu=20000000L +Geekble_Nano_ESP32S3.menu.CPUFreq.10=10MHz +Geekble_Nano_ESP32S3.menu.CPUFreq.10.build.f_cpu=10000000L + +Geekble_Nano_ESP32S3.menu.UploadSpeed.921600=921600 +Geekble_Nano_ESP32S3.menu.UploadSpeed.921600.upload.speed=921600 +Geekble_Nano_ESP32S3.menu.UploadSpeed.115200=115200 +Geekble_Nano_ESP32S3.menu.UploadSpeed.115200.upload.speed=115200 +Geekble_Nano_ESP32S3.menu.UploadSpeed.256000.windows=256000 +Geekble_Nano_ESP32S3.menu.UploadSpeed.256000.upload.speed=256000 +Geekble_Nano_ESP32S3.menu.UploadSpeed.230400.windows.upload.speed=256000 +Geekble_Nano_ESP32S3.menu.UploadSpeed.230400=230400 +Geekble_Nano_ESP32S3.menu.UploadSpeed.230400.upload.speed=230400 +Geekble_Nano_ESP32S3.menu.UploadSpeed.460800.linux=460800 +Geekble_Nano_ESP32S3.menu.UploadSpeed.460800.macosx=460800 +Geekble_Nano_ESP32S3.menu.UploadSpeed.460800.upload.speed=460800 +Geekble_Nano_ESP32S3.menu.UploadSpeed.512000.windows=512000 +Geekble_Nano_ESP32S3.menu.UploadSpeed.512000.upload.speed=512000 + +Geekble_Nano_ESP32S3.menu.DebugLevel.none=None +Geekble_Nano_ESP32S3.menu.DebugLevel.none.build.code_debug=0 +Geekble_Nano_ESP32S3.menu.DebugLevel.error=Error +Geekble_Nano_ESP32S3.menu.DebugLevel.error.build.code_debug=1 +Geekble_Nano_ESP32S3.menu.DebugLevel.warn=Warn +Geekble_Nano_ESP32S3.menu.DebugLevel.warn.build.code_debug=2 +Geekble_Nano_ESP32S3.menu.DebugLevel.info=Info +Geekble_Nano_ESP32S3.menu.DebugLevel.info.build.code_debug=3 +Geekble_Nano_ESP32S3.menu.DebugLevel.debug=Debug +Geekble_Nano_ESP32S3.menu.DebugLevel.debug.build.code_debug=4 +Geekble_Nano_ESP32S3.menu.DebugLevel.verbose=Verbose +Geekble_Nano_ESP32S3.menu.DebugLevel.verbose.build.code_debug=5 + +Geekble_Nano_ESP32S3.menu.EraseFlash.none=Disabled +Geekble_Nano_ESP32S3.menu.EraseFlash.none.upload.erase_cmd= +Geekble_Nano_ESP32S3.menu.EraseFlash.all=Enabled +Geekble_Nano_ESP32S3.menu.EraseFlash.all.upload.erase_cmd=-e + + ############################################################## waveshare_esp32_s3_zero.name=Waveshare ESP32-S3-Zero diff --git a/variants/Geekble_Nano_ESP32S3/pins_arduino.h b/variants/Geekble_Nano_ESP32S3/pins_arduino.h new file mode 100644 index 00000000000..657c0d5d51b --- /dev/null +++ b/variants/Geekble_Nano_ESP32S3/pins_arduino.h @@ -0,0 +1,74 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define USB_VID 0x303a +#define USB_PID 0x82C5 +#define USB_MANUFACTURER "Geekble" +#define USB_PRODUCT "Geekble nano ESP32-S3" +#define USB_SERIAL "" // Empty string for MAC address + +static const uint8_t D0 = 44; // also RX +static const uint8_t D1 = 43; // also TX +static const uint8_t D2 = 5; +static const uint8_t D3 = 6; // also CTS +static const uint8_t D4 = 7; // also DSR +static const uint8_t D5 = 8; +static const uint8_t D6 = 9; +static const uint8_t D7 = 10; +static const uint8_t D8 = 17; +static const uint8_t D9 = 18; +static const uint8_t D10 = 21; // also SS +static const uint8_t D11 = 38; // also MOSI +static const uint8_t D12 = 47; // also MISO +static const uint8_t D13 = 48; // also SCK, LED_BUILTIN + +static const uint8_t A0 = 1; // also DTR +static const uint8_t A1 = 2; +static const uint8_t A2 = 3; +static const uint8_t A3 = 4; +static const uint8_t A4 = 11; // also SDA +static const uint8_t A5 = 12; // also SCL +static const uint8_t A6 = 13; +static const uint8_t A7 = 14; + +// alternate pin functions + +static const uint8_t LED_BUILTIN = D13; +#define BUILTIN_LED LED_BUILTIN // backward compatibility +#define LED_BUILTIN LED_BUILTIN // allow testing #ifdef LED_BUILTIN + +static const uint8_t SW_BUILTIN = 0; + +static const uint8_t TX = D1; +static const uint8_t RX = D0; +static const uint8_t RTS = 45; +static const uint8_t CTS = D3; +static const uint8_t DTR = A0; +static const uint8_t DSR = D4; + +static const uint8_t SS = D10; +static const uint8_t MOSI = D11; +static const uint8_t MISO = D12; +static const uint8_t SCK = D13; + +static const uint8_t SDA = A4; +static const uint8_t SCL = A5; + +// Touch input capable pins on the header +static const uint8_t T1 = 1; +static const uint8_t T2 = 2; +static const uint8_t T3 = 3; +static const uint8_t T4 = 4; +static const uint8_t T5 = 5; +static const uint8_t T6 = 6; +static const uint8_t T7 = 7; + +#define PIN_I2S_SCK D7 +#define PIN_I2S_FS D8 +#define PIN_I2S_SD D9 +#define PIN_I2S_SD_OUT D9 // same as bidir +#define PIN_I2S_SD_IN D10 + +#endif /* Pins_Arduino_h */ From b33470e44bf2fe5c9371e2a8d94ba8defc023df7 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 25 Feb 2025 10:13:10 +0200 Subject: [PATCH 52/79] IDF release/v5.4 (#10998) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * IDF release/v5.4 bcb3c32d * fix(zigbee): Remove the need of native ieee802154 radio --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> --- libraries/Zigbee/src/ZigbeeCore.cpp | 4 +- libraries/Zigbee/src/ZigbeeCore.h | 4 +- libraries/Zigbee/src/ZigbeeEP.cpp | 4 +- libraries/Zigbee/src/ZigbeeEP.h | 4 +- libraries/Zigbee/src/ZigbeeHandlers.cpp | 4 +- libraries/Zigbee/src/ep/ZigbeeAnalog.cpp | 4 +- libraries/Zigbee/src/ep/ZigbeeAnalog.h | 4 +- .../src/ep/ZigbeeCarbonDioxideSensor.cpp | 4 +- .../Zigbee/src/ep/ZigbeeCarbonDioxideSensor.h | 4 +- .../src/ep/ZigbeeColorDimmableLight.cpp | 4 +- .../Zigbee/src/ep/ZigbeeColorDimmableLight.h | 4 +- .../Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp | 4 +- .../Zigbee/src/ep/ZigbeeColorDimmerSwitch.h | 4 +- .../Zigbee/src/ep/ZigbeeContactSwitch.cpp | 4 +- libraries/Zigbee/src/ep/ZigbeeContactSwitch.h | 4 +- .../Zigbee/src/ep/ZigbeeDimmableLight.cpp | 2 +- libraries/Zigbee/src/ep/ZigbeeDimmableLight.h | 2 +- .../Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp | 4 +- .../Zigbee/src/ep/ZigbeeDoorWindowHandle.h | 4 +- libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp | 4 +- libraries/Zigbee/src/ep/ZigbeeFlowSensor.h | 4 +- libraries/Zigbee/src/ep/ZigbeeLight.cpp | 4 +- libraries/Zigbee/src/ep/ZigbeeLight.h | 4 +- .../Zigbee/src/ep/ZigbeeOccupancySensor.cpp | 4 +- .../Zigbee/src/ep/ZigbeeOccupancySensor.h | 4 +- .../Zigbee/src/ep/ZigbeePressureSensor.cpp | 4 +- .../Zigbee/src/ep/ZigbeePressureSensor.h | 4 +- .../Zigbee/src/ep/ZigbeeRangeExtender.cpp | 4 +- libraries/Zigbee/src/ep/ZigbeeRangeExtender.h | 4 +- libraries/Zigbee/src/ep/ZigbeeSwitch.cpp | 4 +- libraries/Zigbee/src/ep/ZigbeeSwitch.h | 4 +- libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp | 4 +- libraries/Zigbee/src/ep/ZigbeeTempSensor.h | 4 +- libraries/Zigbee/src/ep/ZigbeeThermostat.cpp | 4 +- libraries/Zigbee/src/ep/ZigbeeThermostat.h | 4 +- .../Zigbee/src/ep/ZigbeeVibrationSensor.cpp | 4 +- .../Zigbee/src/ep/ZigbeeVibrationSensor.h | 4 +- .../Zigbee/src/ep/ZigbeeWindowCovering.cpp | 4 +- .../Zigbee/src/ep/ZigbeeWindowCovering.h | 4 +- package/package_esp32_index.template.json | 68 +++++++++---------- 40 files changed, 110 insertions(+), 110 deletions(-) diff --git a/libraries/Zigbee/src/ZigbeeCore.cpp b/libraries/Zigbee/src/ZigbeeCore.cpp index 19f4d0872b8..0fad546bb15 100644 --- a/libraries/Zigbee/src/ZigbeeCore.cpp +++ b/libraries/Zigbee/src/ZigbeeCore.cpp @@ -1,7 +1,7 @@ /* Zigbee Core Functions */ #include "ZigbeeCore.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeHandlers.cpp" #include "Arduino.h" @@ -526,4 +526,4 @@ const char *ZigbeeCore::getDeviceTypeString(esp_zb_ha_standard_devices_t deviceI ZigbeeCore Zigbee = ZigbeeCore(); -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ZigbeeCore.h b/libraries/Zigbee/src/ZigbeeCore.h index 02dce54e5ff..1d6e32babe0 100644 --- a/libraries/Zigbee/src/ZigbeeCore.h +++ b/libraries/Zigbee/src/ZigbeeCore.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "esp_zigbee_core.h" #include "zdo/esp_zigbee_zdo_common.h" @@ -144,4 +144,4 @@ class ZigbeeCore { extern ZigbeeCore Zigbee; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ZigbeeEP.cpp b/libraries/Zigbee/src/ZigbeeEP.cpp index f3f890393eb..8320215707b 100644 --- a/libraries/Zigbee/src/ZigbeeEP.cpp +++ b/libraries/Zigbee/src/ZigbeeEP.cpp @@ -2,7 +2,7 @@ #include "ZigbeeEP.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "esp_zigbee_cluster.h" #include "zcl/esp_zigbee_zcl_power_config.h" @@ -431,4 +431,4 @@ void ZigbeeEP::requestOTAUpdate() { esp_zb_lock_release(); } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index 3bdd7f22b23..14b9ff61040 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -3,7 +3,7 @@ #pragma once #include "ZigbeeCore.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include #include @@ -157,4 +157,4 @@ class ZigbeeEP { friend class ZigbeeCore; }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ZigbeeHandlers.cpp b/libraries/Zigbee/src/ZigbeeHandlers.cpp index 3af1b6c52aa..eeeb1e8013a 100644 --- a/libraries/Zigbee/src/ZigbeeHandlers.cpp +++ b/libraries/Zigbee/src/ZigbeeHandlers.cpp @@ -2,7 +2,7 @@ #include "ZigbeeCore.h" #include "Arduino.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "esp_ota_ops.h" #if CONFIG_ZB_DELTA_OTA // Delta OTA, code is prepared for this feature but not enabled by default @@ -397,4 +397,4 @@ static esp_err_t zb_cmd_default_resp_handler(const esp_zb_zcl_cmd_default_resp_m return ESP_OK; } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp index 25c199b345b..9d1b53fd310 100644 --- a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp @@ -1,5 +1,5 @@ #include "ZigbeeAnalog.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED esp_zb_cluster_list_t *zigbee_analog_clusters_create(zigbee_analog_cfg_t *analog_sensor) { esp_zb_basic_cluster_cfg_t *basic_cfg = analog_sensor ? &(analog_sensor->basic_cfg) : NULL; @@ -121,4 +121,4 @@ void ZigbeeAnalog::setAnalogInputReporting(uint16_t min_interval, uint16_t max_i esp_zb_lock_release(); } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeAnalog.h b/libraries/Zigbee/src/ep/ZigbeeAnalog.h index e3b22594324..8993c6ea1a4 100644 --- a/libraries/Zigbee/src/ep/ZigbeeAnalog.h +++ b/libraries/Zigbee/src/ep/ZigbeeAnalog.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -73,4 +73,4 @@ class ZigbeeAnalog : public ZigbeeEP { uint8_t _analog_clusters; }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp index ad351f1a75d..15e13d04d7e 100644 --- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp @@ -1,5 +1,5 @@ #include "ZigbeeCarbonDioxideSensor.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED esp_zb_cluster_list_t *zigbee_carbon_dioxide_sensor_clusters_create(zigbee_carbon_dioxide_sensor_cfg_t *carbon_dioxide_sensor) { esp_zb_basic_cluster_cfg_t *basic_cfg = carbon_dioxide_sensor ? &(carbon_dioxide_sensor->basic_cfg) : NULL; @@ -90,4 +90,4 @@ void ZigbeeCarbonDioxideSensor::report() { log_v("Carbon dioxide report sent"); } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.h b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.h index 7744fd02f00..41a9a4fb355 100644 --- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.h +++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -58,4 +58,4 @@ class ZigbeeCarbonDioxideSensor : public ZigbeeEP { void report(); }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp index 7ffd6976e1f..585b1549816 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp @@ -1,5 +1,5 @@ #include "ZigbeeColorDimmableLight.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED ZigbeeColorDimmableLight::ZigbeeColorDimmableLight(uint8_t endpoint) : ZigbeeEP(endpoint) { _device_id = ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID; @@ -177,4 +177,4 @@ void ZigbeeColorDimmableLight::setLightColor(espHsvColor_t hsv_color) { setLight(_current_state, _current_level, rgb_color.r, rgb_color.g, rgb_color.b); } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h index 265fec1b37c..64df3565793 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -105,4 +105,4 @@ class ZigbeeColorDimmableLight : public ZigbeeEP { espRgbColor_t _current_color; }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp index 7bdd8b8ad6a..68f287153cb 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp @@ -1,5 +1,5 @@ #include "ZigbeeColorDimmerSwitch.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED // Initialize the static instance pointer ZigbeeColorDimmerSwitch *ZigbeeColorDimmerSwitch::_instance = nullptr; @@ -481,4 +481,4 @@ void ZigbeeColorDimmerSwitch::setLightColor(uint8_t red, uint8_t green, uint8_t } } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h index ca67fb4ba62..dbe50a20230 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -55,4 +55,4 @@ class ZigbeeColorDimmerSwitch : public ZigbeeEP { void calculateXY(uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y); }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp index 9a3551b0581..6237315d5d9 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.cpp @@ -1,5 +1,5 @@ #include "ZigbeeContactSwitch.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED esp_zb_cluster_list_t *zigbee_contact_switch_clusters_create(zigbee_contact_switch_cfg_t *contact_switch) { esp_zb_basic_cluster_cfg_t *basic_cfg = contact_switch ? &(contact_switch->basic_cfg) : NULL; @@ -93,4 +93,4 @@ void ZigbeeContactSwitch::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_enro } } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h index 692caf092ba..f44ce1cec40 100644 --- a/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeContactSwitch.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -64,4 +64,4 @@ class ZigbeeContactSwitch : public ZigbeeEP { uint8_t _ias_cie_endpoint; }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp b/libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp index 00d3aac3752..34622d1d2db 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeDimmableLight.cpp @@ -1,6 +1,6 @@ #include "ZigbeeDimmableLight.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "esp_zigbee_cluster.h" diff --git a/libraries/Zigbee/src/ep/ZigbeeDimmableLight.h b/libraries/Zigbee/src/ep/ZigbeeDimmableLight.h index 6f92c3315e4..45c3e97c00b 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDimmableLight.h +++ b/libraries/Zigbee/src/ep/ZigbeeDimmableLight.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp index 364b3ef6d9d..70008fbab10 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.cpp @@ -1,5 +1,5 @@ #include "ZigbeeDoorWindowHandle.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED esp_zb_cluster_list_t *zigbee_door_window_handle_clusters_create(zigbee_door_window_handle_cfg_t *door_window_handle) { esp_zb_basic_cluster_cfg_t *basic_cfg = door_window_handle ? &(door_window_handle->basic_cfg) : NULL; @@ -105,4 +105,4 @@ void ZigbeeDoorWindowHandle::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_e } } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h index e60316f8764..8d4eff9e45a 100644 --- a/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h +++ b/libraries/Zigbee/src/ep/ZigbeeDoorWindowHandle.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -68,4 +68,4 @@ class ZigbeeDoorWindowHandle : public ZigbeeEP { uint8_t _ias_cie_endpoint; }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp index 36d66840967..d8fea88342e 100644 --- a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp @@ -1,5 +1,5 @@ #include "ZigbeeFlowSensor.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED esp_zb_cluster_list_t *zigbee_flow_sensor_clusters_create(zigbee_flow_sensor_cfg_t *flow_sensor) { esp_zb_basic_cluster_cfg_t *basic_cfg = flow_sensor ? &(flow_sensor->basic_cfg) : NULL; @@ -86,4 +86,4 @@ void ZigbeeFlowSensor::report() { log_v("Flow report sent"); } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.h b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.h index 7d5ec26f7ec..5e9e20e4d1a 100644 --- a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.h +++ b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -57,4 +57,4 @@ class ZigbeeFlowSensor : public ZigbeeEP { void report(); }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeLight.cpp b/libraries/Zigbee/src/ep/ZigbeeLight.cpp index 100efe34a86..2a87db71287 100644 --- a/libraries/Zigbee/src/ep/ZigbeeLight.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeLight.cpp @@ -1,5 +1,5 @@ #include "ZigbeeLight.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED ZigbeeLight::ZigbeeLight(uint8_t endpoint) : ZigbeeEP(endpoint) { _device_id = ESP_ZB_HA_ON_OFF_LIGHT_DEVICE_ID; @@ -46,4 +46,4 @@ void ZigbeeLight::setLight(bool state) { esp_zb_lock_release(); } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeLight.h b/libraries/Zigbee/src/ep/ZigbeeLight.h index 8cf8c35f781..807802be9b3 100644 --- a/libraries/Zigbee/src/ep/ZigbeeLight.h +++ b/libraries/Zigbee/src/ep/ZigbeeLight.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -38,4 +38,4 @@ class ZigbeeLight : public ZigbeeEP { bool _current_state; }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp index dec7910ac03..830e4397137 100644 --- a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp @@ -1,5 +1,5 @@ #include "ZigbeeOccupancySensor.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED esp_zb_cluster_list_t *zigbee_occupancy_sensor_clusters_create(zigbee_occupancy_sensor_cfg_t *occupancy_sensor) { esp_zb_basic_cluster_cfg_t *basic_cfg = occupancy_sensor ? &(occupancy_sensor->basic_cfg) : NULL; @@ -56,4 +56,4 @@ void ZigbeeOccupancySensor::report() { log_v("Occupancy report sent"); } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.h b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.h index 40c5eddbbdd..fa622d5a707 100644 --- a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.h +++ b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -51,4 +51,4 @@ class ZigbeeOccupancySensor : public ZigbeeEP { void report(); }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp index b887680076d..9c181710bc2 100644 --- a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp @@ -1,5 +1,5 @@ #include "ZigbeePressureSensor.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED esp_zb_cluster_list_t *zigbee_pressure_sensor_clusters_create(zigbee_pressure_sensor_cfg_t *pressure_sensor) { esp_zb_basic_cluster_cfg_t *basic_cfg = pressure_sensor ? &(pressure_sensor->basic_cfg) : NULL; @@ -82,4 +82,4 @@ void ZigbeePressureSensor::report() { log_v("Pressure report sent"); } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeePressureSensor.h b/libraries/Zigbee/src/ep/ZigbeePressureSensor.h index 2d72ef04c06..db14dd1c341 100644 --- a/libraries/Zigbee/src/ep/ZigbeePressureSensor.h +++ b/libraries/Zigbee/src/ep/ZigbeePressureSensor.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -57,4 +57,4 @@ class ZigbeePressureSensor : public ZigbeeEP { void report(); }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp b/libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp index b29e926c201..20db20d758a 100644 --- a/libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp @@ -1,5 +1,5 @@ #include "ZigbeeRangeExtender.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED ZigbeeRangeExtender::ZigbeeRangeExtender(uint8_t endpoint) : ZigbeeEP(endpoint) { _device_id = ESP_ZB_HA_RANGE_EXTENDER_DEVICE_ID; @@ -12,4 +12,4 @@ ZigbeeRangeExtender::ZigbeeRangeExtender(uint8_t endpoint) : ZigbeeEP(endpoint) _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_RANGE_EXTENDER_DEVICE_ID, .app_device_version = 0}; } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeRangeExtender.h b/libraries/Zigbee/src/ep/ZigbeeRangeExtender.h index 7441f48ea7a..f9e4a963164 100644 --- a/libraries/Zigbee/src/ep/ZigbeeRangeExtender.h +++ b/libraries/Zigbee/src/ep/ZigbeeRangeExtender.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -15,4 +15,4 @@ class ZigbeeRangeExtender : public ZigbeeEP { ~ZigbeeRangeExtender() {} }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp index f6b36d7f0d4..86c68ae1870 100644 --- a/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeSwitch.cpp @@ -1,5 +1,5 @@ #include "ZigbeeSwitch.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED // Initialize the static instance pointer ZigbeeSwitch *ZigbeeSwitch::_instance = nullptr; @@ -313,4 +313,4 @@ void ZigbeeSwitch::lightOnWithTimedOff(uint8_t on_off_control, uint16_t time_on, } } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeSwitch.h b/libraries/Zigbee/src/ep/ZigbeeSwitch.h index b638bfe823a..5c527bec6e3 100644 --- a/libraries/Zigbee/src/ep/ZigbeeSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeSwitch.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -43,4 +43,4 @@ class ZigbeeSwitch : public ZigbeeEP { static void findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx); }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp index 90df37b91f5..c3991593422 100644 --- a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp @@ -1,5 +1,5 @@ #include "ZigbeeTempSensor.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED ZigbeeTempSensor::ZigbeeTempSensor(uint8_t endpoint) : ZigbeeEP(endpoint) { _device_id = ESP_ZB_HA_TEMPERATURE_SENSOR_DEVICE_ID; @@ -150,4 +150,4 @@ void ZigbeeTempSensor::report() { } } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeTempSensor.h b/libraries/Zigbee/src/ep/ZigbeeTempSensor.h index e610ff8d356..41da03d9db8 100644 --- a/libraries/Zigbee/src/ep/ZigbeeTempSensor.h +++ b/libraries/Zigbee/src/ep/ZigbeeTempSensor.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -48,4 +48,4 @@ class ZigbeeTempSensor : public ZigbeeEP { bool _humidity_sensor; }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp b/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp index f8957f073a5..357bcaed1bc 100644 --- a/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeThermostat.cpp @@ -1,5 +1,5 @@ #include "ZigbeeThermostat.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED static float zb_s16_to_temperature(int16_t value) { return 1.0 * value / 100; @@ -202,4 +202,4 @@ void ZigbeeThermostat::setTemperatureReporting(uint16_t min_interval, uint16_t m esp_zb_lock_release(); } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeThermostat.h b/libraries/Zigbee/src/ep/ZigbeeThermostat.h index 669ed9ab50a..7895115e1d1 100644 --- a/libraries/Zigbee/src/ep/ZigbeeThermostat.h +++ b/libraries/Zigbee/src/ep/ZigbeeThermostat.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -62,4 +62,4 @@ class ZigbeeThermostat : public ZigbeeEP { void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) override; }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp index 2f2172c89df..9fc75297262 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp @@ -1,5 +1,5 @@ #include "ZigbeeVibrationSensor.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED esp_zb_cluster_list_t *zigbee_vibration_sensor_clusters_create(zigbee_vibration_sensor_cfg_t *vibration_sensor) { esp_zb_basic_cluster_cfg_t *basic_cfg = vibration_sensor ? &(vibration_sensor->basic_cfg) : NULL; @@ -83,4 +83,4 @@ void ZigbeeVibrationSensor::zbIASZoneEnrollResponse(const esp_zb_zcl_ias_zone_en } } -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h index 799cc943cdb..1ee3740dcc3 100644 --- a/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h +++ b/libraries/Zigbee/src/ep/ZigbeeVibrationSensor.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -61,4 +61,4 @@ class ZigbeeVibrationSensor : public ZigbeeEP { uint8_t _ias_cie_endpoint; }; -#endif //SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp index 970017165e2..f6d6ec268ea 100644 --- a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.cpp @@ -1,6 +1,6 @@ #include "ZigbeeWindowCovering.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED esp_zb_cluster_list_t *ZigbeeWindowCovering::zigbee_window_covering_clusters_create(zigbee_window_covering_cfg_t *window_covering_cfg) { esp_zb_attribute_list_t *esp_zb_basic_cluster = esp_zb_basic_cluster_create(&window_covering_cfg->basic_cfg); @@ -305,4 +305,4 @@ void ZigbeeWindowCovering::setTiltPercentage(uint8_t tilt_percentage) { esp_zb_lock_release(); } -#endif // SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h index 08e0a35f737..f3a368370c4 100644 --- a/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h +++ b/libraries/Zigbee/src/ep/ZigbeeWindowCovering.h @@ -4,7 +4,7 @@ #include "soc/soc_caps.h" #include "sdkconfig.h" -#if SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#if CONFIG_ZB_ENABLED #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" @@ -144,4 +144,4 @@ class ZigbeeWindowCovering : public ZigbeeEP { uint16_t _physical_closed_limit_tilt; }; -#endif // SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED +#endif // CONFIG_ZB_ENABLED diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index 2c86b6fe4dd..5a37e95930a 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -42,7 +42,7 @@ { "packager": "esp32", "name": "esp32-arduino-libs", - "version": "idf-release_v5.4-e37d33cc-v2" + "version": "idf-release_v5.4-bcb3c32d-v1" }, { "packager": "esp32", @@ -95,63 +95,63 @@ "tools": [ { "name": "esp32-arduino-libs", - "version": "idf-release_v5.4-e37d33cc-v2", + "version": "idf-release_v5.4-bcb3c32d-v1", "systems": [ { "host": "i686-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", - "size": "339629117" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", + "size": "345570903" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", - "size": "339629117" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", + "size": "345570903" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", - "size": "339629117" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", + "size": "345570903" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", - "size": "339629117" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", + "size": "345570903" }, { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", - "size": "339629117" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", + "size": "345570903" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", - "size": "339629117" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", + "size": "345570903" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", - "size": "339629117" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", + "size": "345570903" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-e37d33cc-v2.zip", - "checksum": "SHA-256:815e53a44eb4e0b59335b97cc0f66ad76a48ea61013dff5289db169f0bb8631c", - "size": "339629117" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", + "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", + "size": "345570903" } ] }, From c76c2eab3751f23087f43b82e60f58beec8ef706 Mon Sep 17 00:00:00 2001 From: Hoan Pham <83377800+mhpham23@users.noreply.github.com> Date: Tue, 25 Feb 2025 03:13:35 -0500 Subject: [PATCH 53/79] Update of Boards.txt & variants - Adding CYObot board - 3rd party board (#10947) * Adding CYObot board - 3rd party board 1. Adding Pin Header file for CYObot to variants folder 2. Add CYObot config to boards.txt * feat(cyobot): adding cyobot_v2_esp32s3 board Change comments in pin header file for cyobot board * fix(cyobot_v2_esp32s3): fix variant name fix variant name for cyobot board * fix(boards.txt): fix name of CYOBot board - Change name to uppercase * fix(CYOBot): fix boards.txt & pin_arduino.h * fix(pins_arduino.h): capitalize name * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- boards.txt | 252 ++++++++++++++++++++++ variants/cyobot_v2_esp32s3/pins_arduino.h | 52 +++++ 2 files changed, 304 insertions(+) create mode 100644 variants/cyobot_v2_esp32s3/pins_arduino.h diff --git a/boards.txt b/boards.txt index a3700c22ef8..e1c9283f197 100644 --- a/boards.txt +++ b/boards.txt @@ -49221,3 +49221,255 @@ huidu_hd_wf4.menu.EraseFlash.all=Enabled huidu_hd_wf4.menu.EraseFlash.all.upload.erase_cmd=-e ############################################################## + +# CYOBot (CYOBrain V2 ESP32S3) Board +cyobot_v2_esp32s3.name=CYOBOT V2 ESP32S3 + +cyobot_v2_esp32s3.bootloader.tool=esptool_py +cyobot_v2_esp32s3.bootloader.tool.default=esptool_py + +cyobot_v2_esp32s3.upload.tool=esptool_py +cyobot_v2_esp32s3.upload.tool.default=esptool_py +cyobot_v2_esp32s3.upload.tool.network=esp_ota + +cyobot_v2_esp32s3.upload.maximum_size=1310720 +cyobot_v2_esp32s3.upload.maximum_data_size=327680 +cyobot_v2_esp32s3.upload.flags= +cyobot_v2_esp32s3.upload.extra_flags= +cyobot_v2_esp32s3.upload.use_1200bps_touch=false +cyobot_v2_esp32s3.upload.wait_for_upload_port=false + +cyobot_v2_esp32s3.serial.disableDTR=false +cyobot_v2_esp32s3.serial.disableRTS=false + +cyobot_v2_esp32s3.build.tarch=xtensa +cyobot_v2_esp32s3.build.bootloader_addr=0x0 +cyobot_v2_esp32s3.build.target=esp32s3 +cyobot_v2_esp32s3.build.mcu=esp32s3 +cyobot_v2_esp32s3.build.core=esp32 +cyobot_v2_esp32s3.build.variant=cyobot_v2_esp32s3 +cyobot_v2_esp32s3.build.board=CYOBOT_V2_ESP32S3 + +cyobot_v2_esp32s3.build.usb_mode=1 +cyobot_v2_esp32s3.build.cdc_on_boot=0 +cyobot_v2_esp32s3.build.msc_on_boot=0 +cyobot_v2_esp32s3.build.dfu_on_boot=0 +cyobot_v2_esp32s3.build.f_cpu=240000000L +cyobot_v2_esp32s3.build.flash_size=4MB +cyobot_v2_esp32s3.build.flash_freq=80m +cyobot_v2_esp32s3.build.flash_mode=dio +cyobot_v2_esp32s3.build.boot=qio +cyobot_v2_esp32s3.build.boot_freq=80m +cyobot_v2_esp32s3.build.partitions=default +cyobot_v2_esp32s3.build.defines= +cyobot_v2_esp32s3.build.loop_core= +cyobot_v2_esp32s3.build.event_core= +cyobot_v2_esp32s3.build.psram_type=qspi +cyobot_v2_esp32s3.build.memory_type={build.boot}_{build.psram_type} + +## IDE 2.0 Seems to not update the value +cyobot_v2_esp32s3.menu.JTAGAdapter.default=Disabled +cyobot_v2_esp32s3.menu.JTAGAdapter.default.build.copy_jtag_files=0 +cyobot_v2_esp32s3.menu.JTAGAdapter.builtin=Integrated USB JTAG +cyobot_v2_esp32s3.menu.JTAGAdapter.builtin.build.openocdscript=cyobot_v2_esp32s3-builtin.cfg +cyobot_v2_esp32s3.menu.JTAGAdapter.builtin.build.copy_jtag_files=1 +cyobot_v2_esp32s3.menu.JTAGAdapter.external=FTDI Adapter +cyobot_v2_esp32s3.menu.JTAGAdapter.external.build.openocdscript=cyobot_v2_esp32s3-ftdi.cfg +cyobot_v2_esp32s3.menu.JTAGAdapter.external.build.copy_jtag_files=1 +cyobot_v2_esp32s3.menu.JTAGAdapter.bridge=ESP USB Bridge +cyobot_v2_esp32s3.menu.JTAGAdapter.bridge.build.openocdscript=cyobot_v2_esp32s3-bridge.cfg +cyobot_v2_esp32s3.menu.JTAGAdapter.bridge.build.copy_jtag_files=1 + +cyobot_v2_esp32s3.menu.PSRAM.disabled=Disabled +cyobot_v2_esp32s3.menu.PSRAM.disabled.build.defines= +cyobot_v2_esp32s3.menu.PSRAM.disabled.build.psram_type=qspi +cyobot_v2_esp32s3.menu.PSRAM.enabled=QSPI PSRAM +cyobot_v2_esp32s3.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM +cyobot_v2_esp32s3.menu.PSRAM.enabled.build.psram_type=qspi +cyobot_v2_esp32s3.menu.PSRAM.opi=OPI PSRAM +cyobot_v2_esp32s3.menu.PSRAM.opi.build.defines=-DBOARD_HAS_PSRAM +cyobot_v2_esp32s3.menu.PSRAM.opi.build.psram_type=opi + +cyobot_v2_esp32s3.menu.FlashMode.qio=QIO 80MHz +cyobot_v2_esp32s3.menu.FlashMode.qio.build.flash_mode=dio +cyobot_v2_esp32s3.menu.FlashMode.qio.build.boot=qio +cyobot_v2_esp32s3.menu.FlashMode.qio.build.boot_freq=80m +cyobot_v2_esp32s3.menu.FlashMode.qio.build.flash_freq=80m +cyobot_v2_esp32s3.menu.FlashMode.qio120=QIO 120MHz +cyobot_v2_esp32s3.menu.FlashMode.qio120.build.flash_mode=dio +cyobot_v2_esp32s3.menu.FlashMode.qio120.build.boot=qio +cyobot_v2_esp32s3.menu.FlashMode.qio120.build.boot_freq=120m +cyobot_v2_esp32s3.menu.FlashMode.qio120.build.flash_freq=80m +cyobot_v2_esp32s3.menu.FlashMode.dio=DIO 80MHz +cyobot_v2_esp32s3.menu.FlashMode.dio.build.flash_mode=dio +cyobot_v2_esp32s3.menu.FlashMode.dio.build.boot=dio +cyobot_v2_esp32s3.menu.FlashMode.dio.build.boot_freq=80m +cyobot_v2_esp32s3.menu.FlashMode.dio.build.flash_freq=80m +cyobot_v2_esp32s3.menu.FlashMode.opi=OPI 80MHz +cyobot_v2_esp32s3.menu.FlashMode.opi.build.flash_mode=dout +cyobot_v2_esp32s3.menu.FlashMode.opi.build.boot=opi +cyobot_v2_esp32s3.menu.FlashMode.opi.build.boot_freq=80m +cyobot_v2_esp32s3.menu.FlashMode.opi.build.flash_freq=80m + +cyobot_v2_esp32s3.menu.FlashSize.4M=4MB (32Mb) +cyobot_v2_esp32s3.menu.FlashSize.4M.build.flash_size=4MB +cyobot_v2_esp32s3.menu.FlashSize.8M=8MB (64Mb) +cyobot_v2_esp32s3.menu.FlashSize.8M.build.flash_size=8MB +cyobot_v2_esp32s3.menu.FlashSize.16M=16MB (128Mb) +cyobot_v2_esp32s3.menu.FlashSize.16M.build.flash_size=16MB +cyobot_v2_esp32s3.menu.FlashSize.32M=32MB (256Mb) +cyobot_v2_esp32s3.menu.FlashSize.32M.build.flash_size=32MB + +cyobot_v2_esp32s3.menu.LoopCore.1=Core 1 +cyobot_v2_esp32s3.menu.LoopCore.1.build.loop_core=-DARDUINO_RUNNING_CORE=1 +cyobot_v2_esp32s3.menu.LoopCore.0=Core 0 +cyobot_v2_esp32s3.menu.LoopCore.0.build.loop_core=-DARDUINO_RUNNING_CORE=0 + +cyobot_v2_esp32s3.menu.EventsCore.1=Core 1 +cyobot_v2_esp32s3.menu.EventsCore.1.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=1 +cyobot_v2_esp32s3.menu.EventsCore.0=Core 0 +cyobot_v2_esp32s3.menu.EventsCore.0.build.event_core=-DARDUINO_EVENT_RUNNING_CORE=0 + +cyobot_v2_esp32s3.menu.USBMode.hwcdc=Hardware CDC and JTAG +cyobot_v2_esp32s3.menu.USBMode.hwcdc.build.usb_mode=1 +cyobot_v2_esp32s3.menu.USBMode.default=USB-OTG (TinyUSB) +cyobot_v2_esp32s3.menu.USBMode.default.build.usb_mode=0 + +cyobot_v2_esp32s3.menu.CDCOnBoot.default=Disabled +cyobot_v2_esp32s3.menu.CDCOnBoot.default.build.cdc_on_boot=0 +cyobot_v2_esp32s3.menu.CDCOnBoot.cdc=Enabled +cyobot_v2_esp32s3.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 + +cyobot_v2_esp32s3.menu.MSCOnBoot.default=Disabled +cyobot_v2_esp32s3.menu.MSCOnBoot.default.build.msc_on_boot=0 +cyobot_v2_esp32s3.menu.MSCOnBoot.msc=Enabled (Requires USB-OTG Mode) +cyobot_v2_esp32s3.menu.MSCOnBoot.msc.build.msc_on_boot=1 + +cyobot_v2_esp32s3.menu.DFUOnBoot.default=Disabled +cyobot_v2_esp32s3.menu.DFUOnBoot.default.build.dfu_on_boot=0 +cyobot_v2_esp32s3.menu.DFUOnBoot.dfu=Enabled (Requires USB-OTG Mode) +cyobot_v2_esp32s3.menu.DFUOnBoot.dfu.build.dfu_on_boot=1 + +cyobot_v2_esp32s3.menu.UploadMode.default=UART0 / Hardware CDC +cyobot_v2_esp32s3.menu.UploadMode.default.upload.use_1200bps_touch=false +cyobot_v2_esp32s3.menu.UploadMode.default.upload.wait_for_upload_port=false +cyobot_v2_esp32s3.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) +cyobot_v2_esp32s3.menu.UploadMode.cdc.upload.use_1200bps_touch=true +cyobot_v2_esp32s3.menu.UploadMode.cdc.upload.wait_for_upload_port=true + +cyobot_v2_esp32s3.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +cyobot_v2_esp32s3.menu.PartitionScheme.default.build.partitions=default +cyobot_v2_esp32s3.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +cyobot_v2_esp32s3.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +cyobot_v2_esp32s3.menu.PartitionScheme.default_8MB=8M with spiffs (3MB APP/1.5MB SPIFFS) +cyobot_v2_esp32s3.menu.PartitionScheme.default_8MB.build.partitions=default_8MB +cyobot_v2_esp32s3.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336 +cyobot_v2_esp32s3.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +cyobot_v2_esp32s3.menu.PartitionScheme.minimal.build.partitions=minimal +cyobot_v2_esp32s3.menu.PartitionScheme.no_fs=No FS 4MB (2MB APP x2) +cyobot_v2_esp32s3.menu.PartitionScheme.no_fs.build.partitions=no_fs +cyobot_v2_esp32s3.menu.PartitionScheme.no_fs.upload.maximum_size=2031616 +cyobot_v2_esp32s3.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +cyobot_v2_esp32s3.menu.PartitionScheme.no_ota.build.partitions=no_ota +cyobot_v2_esp32s3.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +cyobot_v2_esp32s3.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +cyobot_v2_esp32s3.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +cyobot_v2_esp32s3.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +cyobot_v2_esp32s3.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +cyobot_v2_esp32s3.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +cyobot_v2_esp32s3.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +cyobot_v2_esp32s3.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +cyobot_v2_esp32s3.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +cyobot_v2_esp32s3.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +cyobot_v2_esp32s3.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +cyobot_v2_esp32s3.menu.PartitionScheme.huge_app.build.partitions=huge_app +cyobot_v2_esp32s3.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +cyobot_v2_esp32s3.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +cyobot_v2_esp32s3.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +cyobot_v2_esp32s3.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 +cyobot_v2_esp32s3.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FATFS) +cyobot_v2_esp32s3.menu.PartitionScheme.fatflash.build.partitions=ffat +cyobot_v2_esp32s3.menu.PartitionScheme.fatflash.upload.maximum_size=2097152 +cyobot_v2_esp32s3.menu.PartitionScheme.app3M_fat9M_16MB=16M Flash (3MB APP/9.9MB FATFS) +cyobot_v2_esp32s3.menu.PartitionScheme.app3M_fat9M_16MB.build.partitions=app3M_fat9M_16MB +cyobot_v2_esp32s3.menu.PartitionScheme.app3M_fat9M_16MB.upload.maximum_size=3145728 +cyobot_v2_esp32s3.menu.PartitionScheme.rainmaker=RainMaker 4MB +cyobot_v2_esp32s3.menu.PartitionScheme.rainmaker.build.partitions=rainmaker +cyobot_v2_esp32s3.menu.PartitionScheme.rainmaker.upload.maximum_size=1966080 +cyobot_v2_esp32s3.menu.PartitionScheme.rainmaker_4MB=RainMaker 4MB No OTA +cyobot_v2_esp32s3.menu.PartitionScheme.rainmaker_4MB.build.partitions=rainmaker_4MB_no_ota +cyobot_v2_esp32s3.menu.PartitionScheme.rainmaker_4MB.upload.maximum_size=4038656 +cyobot_v2_esp32s3.menu.PartitionScheme.rainmaker_8MB=RainMaker 8MB +cyobot_v2_esp32s3.menu.PartitionScheme.rainmaker_8MB.build.partitions=rainmaker_8MB +cyobot_v2_esp32s3.menu.PartitionScheme.rainmaker_8MB.upload.maximum_size=4116480 +cyobot_v2_esp32s3.menu.PartitionScheme.app5M_fat24M_32MB=32M Flash (4.8MB APP/22MB FATFS) +cyobot_v2_esp32s3.menu.PartitionScheme.app5M_fat24M_32MB.build.partitions=large_fat_32MB +cyobot_v2_esp32s3.menu.PartitionScheme.app5M_fat24M_32MB.upload.maximum_size=4718592 +cyobot_v2_esp32s3.menu.PartitionScheme.app5M_little24M_32MB=32M Flash (4.8MB APP/22MB LittleFS) +cyobot_v2_esp32s3.menu.PartitionScheme.app5M_little24M_32MB.build.partitions=large_littlefs_32MB +cyobot_v2_esp32s3.menu.PartitionScheme.app5M_little24M_32MB.upload.maximum_size=4718592 +cyobot_v2_esp32s3.menu.PartitionScheme.esp_sr_16=ESP SR 16M (3MB APP/7MB SPIFFS/2.9MB MODEL) +cyobot_v2_esp32s3.menu.PartitionScheme.esp_sr_16.upload.maximum_size=3145728 +cyobot_v2_esp32s3.menu.PartitionScheme.esp_sr_16.upload.extra_flags=0xD10000 {build.path}/srmodels.bin +cyobot_v2_esp32s3.menu.PartitionScheme.esp_sr_16.build.partitions=esp_sr_16 +cyobot_v2_esp32s3.menu.PartitionScheme.zigbee_zczr=Zigbee ZCZR 4MB with spiffs +cyobot_v2_esp32s3.menu.PartitionScheme.zigbee_zczr.build.partitions=zigbee_zczr +cyobot_v2_esp32s3.menu.PartitionScheme.zigbee_zczr.upload.maximum_size=1310720 +cyobot_v2_esp32s3.menu.PartitionScheme.custom=Custom +cyobot_v2_esp32s3.menu.PartitionScheme.custom.build.partitions= +cyobot_v2_esp32s3.menu.PartitionScheme.custom.upload.maximum_size=16777216 + +cyobot_v2_esp32s3.menu.CPUFreq.240=240MHz (WiFi) +cyobot_v2_esp32s3.menu.CPUFreq.240.build.f_cpu=240000000L +cyobot_v2_esp32s3.menu.CPUFreq.160=160MHz (WiFi) +cyobot_v2_esp32s3.menu.CPUFreq.160.build.f_cpu=160000000L +cyobot_v2_esp32s3.menu.CPUFreq.80=80MHz (WiFi) +cyobot_v2_esp32s3.menu.CPUFreq.80.build.f_cpu=80000000L +cyobot_v2_esp32s3.menu.CPUFreq.40=40MHz +cyobot_v2_esp32s3.menu.CPUFreq.40.build.f_cpu=40000000L +cyobot_v2_esp32s3.menu.CPUFreq.20=20MHz +cyobot_v2_esp32s3.menu.CPUFreq.20.build.f_cpu=20000000L +cyobot_v2_esp32s3.menu.CPUFreq.10=10MHz +cyobot_v2_esp32s3.menu.CPUFreq.10.build.f_cpu=10000000L + +cyobot_v2_esp32s3.menu.UploadSpeed.921600=921600 +cyobot_v2_esp32s3.menu.UploadSpeed.921600.upload.speed=921600 +cyobot_v2_esp32s3.menu.UploadSpeed.115200=115200 +cyobot_v2_esp32s3.menu.UploadSpeed.115200.upload.speed=115200 +cyobot_v2_esp32s3.menu.UploadSpeed.256000.windows=256000 +cyobot_v2_esp32s3.menu.UploadSpeed.256000.upload.speed=256000 +cyobot_v2_esp32s3.menu.UploadSpeed.230400.windows.upload.speed=256000 +cyobot_v2_esp32s3.menu.UploadSpeed.230400=230400 +cyobot_v2_esp32s3.menu.UploadSpeed.230400.upload.speed=230400 +cyobot_v2_esp32s3.menu.UploadSpeed.460800.linux=460800 +cyobot_v2_esp32s3.menu.UploadSpeed.460800.macosx=460800 +cyobot_v2_esp32s3.menu.UploadSpeed.460800.upload.speed=460800 +cyobot_v2_esp32s3.menu.UploadSpeed.512000.windows=512000 +cyobot_v2_esp32s3.menu.UploadSpeed.512000.upload.speed=512000 + +cyobot_v2_esp32s3.menu.DebugLevel.none=None +cyobot_v2_esp32s3.menu.DebugLevel.none.build.code_debug=0 +cyobot_v2_esp32s3.menu.DebugLevel.error=Error +cyobot_v2_esp32s3.menu.DebugLevel.error.build.code_debug=1 +cyobot_v2_esp32s3.menu.DebugLevel.warn=Warn +cyobot_v2_esp32s3.menu.DebugLevel.warn.build.code_debug=2 +cyobot_v2_esp32s3.menu.DebugLevel.info=Info +cyobot_v2_esp32s3.menu.DebugLevel.info.build.code_debug=3 +cyobot_v2_esp32s3.menu.DebugLevel.debug=Debug +cyobot_v2_esp32s3.menu.DebugLevel.debug.build.code_debug=4 +cyobot_v2_esp32s3.menu.DebugLevel.verbose=Verbose +cyobot_v2_esp32s3.menu.DebugLevel.verbose.build.code_debug=5 + +cyobot_v2_esp32s3.menu.EraseFlash.none=Disabled +cyobot_v2_esp32s3.menu.EraseFlash.none.upload.erase_cmd= +cyobot_v2_esp32s3.menu.EraseFlash.all=Enabled +cyobot_v2_esp32s3.menu.EraseFlash.all.upload.erase_cmd=-e + +cyobot_v2_esp32s3.menu.ZigbeeMode.default=Disabled +cyobot_v2_esp32s3.menu.ZigbeeMode.default.build.zigbee_mode= +cyobot_v2_esp32s3.menu.ZigbeeMode.default.build.zigbee_libs= +cyobot_v2_esp32s3.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator/router) +cyobot_v2_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR +cyobot_v2_esp32s3.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api.zczr -lzboss_stack.zczr -lzboss_port.remote + +############################################################## diff --git a/variants/cyobot_v2_esp32s3/pins_arduino.h b/variants/cyobot_v2_esp32s3/pins_arduino.h new file mode 100644 index 00000000000..45f0968ef2a --- /dev/null +++ b/variants/cyobot_v2_esp32s3/pins_arduino.h @@ -0,0 +1,52 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define USB_MANUFACTURER "CYOBot" +#define USB_PRODUCT "CYOBrain ESP32S3" +#define USB_SERIAL "" // Empty string for MAC address + +static const uint8_t BUTTON0 = 4; +static const uint8_t BUTTON1 = 38; +static const uint8_t LED = 24; + +static const uint8_t BAT_MEAS = 6; +static const uint8_t CHAR_DET = 23; + +static const uint8_t NEO_BASE = 7; +static const uint8_t NEO_BRAIN = 15; + +static const uint8_t I2S0_MCLK = 16; +static const uint8_t I2S0_DSDIN = 8; +static const uint8_t I2S0_SCLK = 9; +static const uint8_t I2S0_LRCK = 45; + +static const uint8_t SDA = 17; +static const uint8_t SCL = 18; + +static const uint8_t SS = 5; +static const uint8_t MOSI = 2; +static const uint8_t MISO = 42; +static const uint8_t SCK = 41; + +static const uint8_t ENCODER1_A = 39; +static const uint8_t ENCODER1_B = 40; +static const uint8_t ENCODER2_B = 19; +static const uint8_t ENCODER2_A = 20; + +static const uint8_t UART1_RXD = 3; +static const uint8_t UART1_TXD = 1; + +static const uint8_t GPIO46 = 46; +static const uint8_t ESP_IO0 = 0; + +static const uint8_t SD_OUT = 10; +static const uint8_t SD_SPI_MOSI = 11; +static const uint8_t SD_SPI_CLK = 12; +static const uint8_t SD_SPI_MISO = 13; +static const uint8_t SD_SPI_CS = 14; + +static const uint8_t PA_CTRL = 25; + +#endif /* Pins_Arduino_h */ From 1467d874549280ad6542ce1a96fd39a47f45562d Mon Sep 17 00:00:00 2001 From: oddlama Date: Tue, 25 Feb 2025 09:17:17 +0100 Subject: [PATCH 54/79] fix(zigbee): use correct pressure cluster function in setTolerance (#11008) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> --- libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp index 9c181710bc2..44e3eace610 100644 --- a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp @@ -33,7 +33,7 @@ void ZigbeePressureSensor::setMinMaxValue(int16_t min, int16_t max) { void ZigbeePressureSensor::setTolerance(uint16_t tolerance) { esp_zb_attribute_list_t *pressure_measure_cluster = esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_temperature_meas_cluster_add_attr(pressure_measure_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_TOLERANCE_ID, (void *)&tolerance); + esp_zb_pressure_meas_cluster_add_attr(pressure_measure_cluster, ESP_ZB_ZCL_ATTR_PRESSURE_MEASUREMENT_TOLERANCE_ID, (void *)&tolerance); } void ZigbeePressureSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) { @@ -58,7 +58,7 @@ void ZigbeePressureSensor::setReporting(uint16_t min_interval, uint16_t max_inte void ZigbeePressureSensor::setPressure(int16_t pressure) { log_v("Updating pressure sensor value..."); - /* Update temperature sensor measured value */ + /* Update pressure sensor measured value */ log_d("Setting pressure to %d hPa", pressure); esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_set_attribute_val( From 09d89c6da119db31de461a4bdda85f6ecc4c5ea0 Mon Sep 17 00:00:00 2001 From: Gonzalo Brusco Date: Tue, 25 Feb 2025 12:58:10 -0300 Subject: [PATCH 55/79] Fix HardwareSerial config (#11007) --- cores/esp32/HardwareSerial.cpp | 12 ------------ cores/esp32/HardwareSerial.h | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index c14dac7bc7e..76135691411 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -11,18 +11,6 @@ #include "driver/uart.h" #include "freertos/queue.h" -#ifndef ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE -#define ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE 2048 -#endif - -#ifndef ARDUINO_SERIAL_EVENT_TASK_PRIORITY -#define ARDUINO_SERIAL_EVENT_TASK_PRIORITY (configMAX_PRIORITIES - 1) -#endif - -#ifndef ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE -#define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE -1 -#endif - #if (SOC_UART_LP_NUM >= 1) #define UART_HW_FIFO_LEN(uart_num) ((uart_num < SOC_UART_HP_NUM) ? SOC_UART_FIFO_LEN : SOC_LP_UART_FIFO_LEN) #else diff --git a/cores/esp32/HardwareSerial.h b/cores/esp32/HardwareSerial.h index e52428f0dd5..b1f6df17724 100644 --- a/cores/esp32/HardwareSerial.h +++ b/cores/esp32/HardwareSerial.h @@ -97,15 +97,27 @@ typedef enum { } hardwareSerial_error_t; #ifndef ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE +#ifndef CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE #define ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE 2048 +#else +#define ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE +#endif #endif #ifndef ARDUINO_SERIAL_EVENT_TASK_PRIORITY +#ifndef CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY #define ARDUINO_SERIAL_EVENT_TASK_PRIORITY (configMAX_PRIORITIES - 1) +#else +#define ARDUINO_SERIAL_EVENT_TASK_PRIORITY CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY +#endif #endif #ifndef ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE +#ifndef CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE #define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE -1 +#else +#define ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE +#endif #endif // UART0 pins are defined by default by the bootloader. From 7485c653bb949fd182d1eaa46f53f7947b348149 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:00:39 -0300 Subject: [PATCH 56/79] ci(zigbee): Check if Zigbee is enabled for CI tests (#11012) * ci(zigbee): Check if Zigbee is enabled for CI tests * ci(zigbee): Fix requirements * fix(zigbee): Use LED_BUILTIN for range extender * fix(zigbee): Use default GPIO if LED_BUILTINnot defined --- .../Zigbee/examples/Zigbee_Analog_Input_Output/ci.json | 3 ++- .../Zigbee/examples/Zigbee_CarbonDioxide_Sensor/ci.json | 3 ++- .../Zigbee/examples/Zigbee_Color_Dimmable_Light/ci.json | 3 ++- .../Zigbee/examples/Zigbee_Color_Dimmer_Switch/ci.json | 2 +- libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json | 3 ++- libraries/Zigbee/examples/Zigbee_Dimmable_Light/ci.json | 3 ++- libraries/Zigbee/examples/Zigbee_OTA_Client/ci.json | 3 ++- libraries/Zigbee/examples/Zigbee_Occupancy_Sensor/ci.json | 3 ++- libraries/Zigbee/examples/Zigbee_On_Off_Light/ci.json | 3 ++- libraries/Zigbee/examples/Zigbee_On_Off_Switch/ci.json | 2 +- .../Zigbee/examples/Zigbee_Pressure_Flow_Sensor/ci.json | 3 ++- .../Zigbee_Range_Extender/Zigbee_Range_Extender.ino | 7 ++++++- libraries/Zigbee/examples/Zigbee_Range_Extender/ci.json | 2 +- libraries/Zigbee/examples/Zigbee_Scan_Networks/ci.json | 3 ++- .../Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/ci.json | 3 ++- .../Zigbee/examples/Zigbee_Temperature_Sensor/ci.json | 3 ++- libraries/Zigbee/examples/Zigbee_Thermostat/ci.json | 2 +- libraries/Zigbee/examples/Zigbee_Vibration_Sensor/ci.json | 3 ++- libraries/Zigbee/examples/Zigbee_Window_Covering/ci.json | 3 ++- 19 files changed, 38 insertions(+), 19 deletions(-) diff --git a/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/ci.json b/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Analog_Input_Output/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_CarbonDioxide_Sensor/ci.json b/libraries/Zigbee/examples/Zigbee_CarbonDioxide_Sensor/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_CarbonDioxide_Sensor/ci.json +++ b/libraries/Zigbee/examples/Zigbee_CarbonDioxide_Sensor/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/ci.json b/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Color_Dimmable_Light/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/ci.json b/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/ci.json index e79a477da11..15d6190e4ae 100644 --- a/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/ci.json @@ -1,6 +1,6 @@ { "fqbn_append": "PartitionScheme=zigbee_zczr,ZigbeeMode=zczr", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json b/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Contact_Switch/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Dimmable_Light/ci.json b/libraries/Zigbee/examples/Zigbee_Dimmable_Light/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Dimmable_Light/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Dimmable_Light/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_OTA_Client/ci.json b/libraries/Zigbee/examples/Zigbee_OTA_Client/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_OTA_Client/ci.json +++ b/libraries/Zigbee/examples/Zigbee_OTA_Client/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Occupancy_Sensor/ci.json b/libraries/Zigbee/examples/Zigbee_Occupancy_Sensor/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Occupancy_Sensor/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Occupancy_Sensor/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_On_Off_Light/ci.json b/libraries/Zigbee/examples/Zigbee_On_Off_Light/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_On_Off_Light/ci.json +++ b/libraries/Zigbee/examples/Zigbee_On_Off_Light/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_On_Off_Switch/ci.json b/libraries/Zigbee/examples/Zigbee_On_Off_Switch/ci.json index e79a477da11..15d6190e4ae 100644 --- a/libraries/Zigbee/examples/Zigbee_On_Off_Switch/ci.json +++ b/libraries/Zigbee/examples/Zigbee_On_Off_Switch/ci.json @@ -1,6 +1,6 @@ { "fqbn_append": "PartitionScheme=zigbee_zczr,ZigbeeMode=zczr", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Pressure_Flow_Sensor/ci.json b/libraries/Zigbee/examples/Zigbee_Pressure_Flow_Sensor/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Pressure_Flow_Sensor/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Pressure_Flow_Sensor/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Range_Extender/Zigbee_Range_Extender.ino b/libraries/Zigbee/examples/Zigbee_Range_Extender/Zigbee_Range_Extender.ino index 3c4cfeb61dc..a1ba90fbaf6 100644 --- a/libraries/Zigbee/examples/Zigbee_Range_Extender/Zigbee_Range_Extender.ino +++ b/libraries/Zigbee/examples/Zigbee_Range_Extender/Zigbee_Range_Extender.ino @@ -34,7 +34,12 @@ /* Zigbee light bulb configuration */ #define USE_CUSTOM_ZIGBEE_CONFIG 1 #define ZIGBEE_EXTENDER_ENDPOINT 1 -uint8_t led = RGB_BUILTIN; + +#ifndef LED_BUILTIN +#define LED_BUILTIN 4 +#endif + +uint8_t led = LED_BUILTIN; uint8_t button = BOOT_PIN; ZigbeeRangeExtender zbExtender = ZigbeeRangeExtender(ZIGBEE_EXTENDER_ENDPOINT); diff --git a/libraries/Zigbee/examples/Zigbee_Range_Extender/ci.json b/libraries/Zigbee/examples/Zigbee_Range_Extender/ci.json index e79a477da11..15d6190e4ae 100644 --- a/libraries/Zigbee/examples/Zigbee_Range_Extender/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Range_Extender/ci.json @@ -1,6 +1,6 @@ { "fqbn_append": "PartitionScheme=zigbee_zczr,ZigbeeMode=zczr", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Scan_Networks/ci.json b/libraries/Zigbee/examples/Zigbee_Scan_Networks/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Scan_Networks/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Scan_Networks/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/ci.json b/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/ci.json b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Temperature_Sensor/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Thermostat/ci.json b/libraries/Zigbee/examples/Zigbee_Thermostat/ci.json index e79a477da11..15d6190e4ae 100644 --- a/libraries/Zigbee/examples/Zigbee_Thermostat/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Thermostat/ci.json @@ -1,6 +1,6 @@ { "fqbn_append": "PartitionScheme=zigbee_zczr,ZigbeeMode=zczr", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/ci.json b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Vibration_Sensor/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } diff --git a/libraries/Zigbee/examples/Zigbee_Window_Covering/ci.json b/libraries/Zigbee/examples/Zigbee_Window_Covering/ci.json index 7b7ccef8ed7..ceacc367801 100644 --- a/libraries/Zigbee/examples/Zigbee_Window_Covering/ci.json +++ b/libraries/Zigbee/examples/Zigbee_Window_Covering/ci.json @@ -1,6 +1,7 @@ { "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", "requires": [ - "CONFIG_SOC_IEEE802154_SUPPORTED=y" + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" ] } From 923da957e444501a5a8d7a03a92954426becf8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Wed, 26 Feb 2025 10:49:24 +0100 Subject: [PATCH 57/79] feat(zigbee): Add ZigbeeGateway endpoint support + Time Cluster bugfix (#11009) * fix(zigbee): Remove the need of native ieee802154 radio * feat(zigbee): Add ZigbeeGateway endpoint support * fix(zigbee): Fix TimeCluster missing status attribute * feat(zigbee): Add new src to CMakeLists * feaz(zigbee): Update keywords.txt with latest updates * feat(zigbee): Add 8MB Zigbee ZCZR partitions to other socs * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Rodrigo Garcia --- CMakeLists.txt | 1 + boards.txt | 12 ++ .../Zigbee/examples/Zigbee_Gateway/README.md | 64 +++++++++ .../Zigbee_Gateway/Zigbee_Gateway.ino | 130 ++++++++++++++++++ .../Zigbee/examples/Zigbee_Gateway/ci.json | 10 ++ libraries/Zigbee/keywords.txt | 50 ++++++- libraries/Zigbee/src/Zigbee.h | 1 + libraries/Zigbee/src/ZigbeeCore.cpp | 8 +- libraries/Zigbee/src/ZigbeeCore.h | 20 +++ libraries/Zigbee/src/ZigbeeEP.cpp | 17 ++- libraries/Zigbee/src/ZigbeeEP.h | 1 + libraries/Zigbee/src/ep/ZigbeeGateway.cpp | 15 ++ libraries/Zigbee/src/ep/ZigbeeGateway.h | 18 +++ 13 files changed, 341 insertions(+), 6 deletions(-) create mode 100644 libraries/Zigbee/examples/Zigbee_Gateway/README.md create mode 100644 libraries/Zigbee/examples/Zigbee_Gateway/Zigbee_Gateway.ino create mode 100644 libraries/Zigbee/examples/Zigbee_Gateway/ci.json create mode 100644 libraries/Zigbee/src/ep/ZigbeeGateway.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeGateway.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 97ad068eb48..32d17e5f68d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -297,6 +297,7 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS libraries/Zigbee/src/ep/ZigbeeVibrationSensor.cpp libraries/Zigbee/src/ep/ZigbeeAnalog.cpp libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp + libraries/Zigbee/src/ep/ZigbeeGateway.cpp ) set(ARDUINO_LIBRARY_BLE_SRCS diff --git a/boards.txt b/boards.txt index e1c9283f197..2afe45f50a6 100644 --- a/boards.txt +++ b/boards.txt @@ -947,6 +947,9 @@ esp32s3.menu.PartitionScheme.esp_sr_16.build.partitions=esp_sr_16 esp32s3.menu.PartitionScheme.zigbee_zczr=Zigbee ZCZR 4MB with spiffs esp32s3.menu.PartitionScheme.zigbee_zczr.build.partitions=zigbee_zczr esp32s3.menu.PartitionScheme.zigbee_zczr.upload.maximum_size=1310720 +esp32s3.menu.PartitionScheme.zigbee_zczr_8MB=Zigbee ZCZR 8MB with spiffs +esp32s3.menu.PartitionScheme.zigbee_zczr_8MB.build.partitions=zigbee_zczr_8MB +esp32s3.menu.PartitionScheme.zigbee_zczr_8MB.upload.maximum_size=3407872 esp32s3.menu.PartitionScheme.custom=Custom esp32s3.menu.PartitionScheme.custom.build.partitions= esp32s3.menu.PartitionScheme.custom.upload.maximum_size=16777216 @@ -1108,6 +1111,9 @@ esp32c3.menu.PartitionScheme.rainmaker_8MB.upload.maximum_size=4116480 esp32c3.menu.PartitionScheme.zigbee_zczr=Zigbee ZCZR 4MB with spiffs esp32c3.menu.PartitionScheme.zigbee_zczr.build.partitions=zigbee_zczr esp32c3.menu.PartitionScheme.zigbee_zczr.upload.maximum_size=1310720 +esp32c3.menu.PartitionScheme.zigbee_zczr_8MB=Zigbee ZCZR 8MB with spiffs +esp32c3.menu.PartitionScheme.zigbee_zczr_8MB.build.partitions=zigbee_zczr_8MB +esp32c3.menu.PartitionScheme.zigbee_zczr_8MB.upload.maximum_size=3407872 esp32c3.menu.PartitionScheme.custom=Custom esp32c3.menu.PartitionScheme.custom.build.partitions= esp32c3.menu.PartitionScheme.custom.upload.maximum_size=16777216 @@ -1313,6 +1319,9 @@ esp32s2.menu.PartitionScheme.rainmaker_8MB.upload.maximum_size=4116480 esp32s2.menu.PartitionScheme.zigbee_zczr=Zigbee ZCZR 4MB with spiffs esp32s2.menu.PartitionScheme.zigbee_zczr.build.partitions=zigbee_zczr esp32s2.menu.PartitionScheme.zigbee_zczr.upload.maximum_size=1310720 +esp32s2.menu.PartitionScheme.zigbee_zczr_8MB=Zigbee ZCZR 8MB with spiffs +esp32s2.menu.PartitionScheme.zigbee_zczr_8MB.build.partitions=zigbee_zczr_8MB +esp32s2.menu.PartitionScheme.zigbee_zczr_8MB.upload.maximum_size=3407872 esp32s2.menu.PartitionScheme.custom=Custom esp32s2.menu.PartitionScheme.custom.build.partitions= esp32s2.menu.PartitionScheme.custom.upload.maximum_size=16777216 @@ -1493,6 +1502,9 @@ esp32.menu.PartitionScheme.rainmaker_8MB.upload.maximum_size=4116480 esp32.menu.PartitionScheme.zigbee_zczr=Zigbee ZCZR 4MB with spiffs esp32.menu.PartitionScheme.zigbee_zczr.build.partitions=zigbee_zczr esp32.menu.PartitionScheme.zigbee_zczr.upload.maximum_size=1310720 +esp32.menu.PartitionScheme.zigbee_zczr_8MB=Zigbee ZCZR 8MB with spiffs +esp32.menu.PartitionScheme.zigbee_zczr_8MB.build.partitions=zigbee_zczr_8MB +esp32.menu.PartitionScheme.zigbee_zczr_8MB.upload.maximum_size=3407872 esp32.menu.PartitionScheme.custom=Custom esp32.menu.PartitionScheme.custom.build.partitions= esp32.menu.PartitionScheme.custom.upload.maximum_size=16777216 diff --git a/libraries/Zigbee/examples/Zigbee_Gateway/README.md b/libraries/Zigbee/examples/Zigbee_Gateway/README.md new file mode 100644 index 00000000000..4156538ccd9 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Gateway/README.md @@ -0,0 +1,64 @@ +# Arduino-ESP32 Zigbee Gateway Example + +This example shows how to configure Zigbee Gateway device, running on SoCs without native IEEE 802.15.4. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | -------- | + +## Hardware Required + +* One development board (ESP32-H2 or ESP32-C6) acting as Zigbee Radio Co-processor loaded with [ot_rcp example](https://github.com/espressif/esp-idf/tree/master/examples/openthread/ot_rcp). +* A USB cable for power supply and programming. +* Choose another board from supported targets as Zigbee coordinator/router and upload the Zigbee_Gateway example. + +### Configure the Project + +Set the RCP connection (UART) by changing the `GATEWAY_RCP_UART_PORT`, `GATEWAY_RCP_RX_PIN` and `GATEWAY_RCP_TX_PIN` definition. + +#### Using Arduino IDE + +To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the Coordinator Zigbee mode: `Tools -> Zigbee mode: Zigbee ZCZR (coordinator/router)`. +* Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs`. +* Select the COM port: `Tools -> Port: xxx where the `xxx` is the detected COM port. +* Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. + +## Troubleshooting + +* In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. + +By default, the coordinator network is closed after rebooting or flashing new firmware. +To open the network you have 2 options: + +* Open network after reboot by setting `Zigbee.setRebootOpenNetwork(time);` before calling `Zigbee.begin();`. +* In application you can anytime call `Zigbee.openNetwork(time);` to open the network for devices to join. + +***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** + +* **LED not blinking:** Check the wiring connection and the IO selection. +* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. +* **COM port not detected:** Check the USB cable and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Official ESP32 Forum: [Link](https://esp32.com) +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/Zigbee/examples/Zigbee_Gateway/Zigbee_Gateway.ino b/libraries/Zigbee/examples/Zigbee_Gateway/Zigbee_Gateway.ino new file mode 100644 index 00000000000..402227b9a3d --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Gateway/Zigbee_Gateway.ino @@ -0,0 +1,130 @@ +// Copyright 2025 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +/** + * @brief This example demonstrates simple Zigbee Gateway functionality. + * + * The example demonstrates how to use Zigbee library on ESP32s to create a Zigbee Gateway, updating the time from NTP server. + * The Gateway is able to communicate with Zigbee end devices and send/receive data to/from them. + * The Gateway is also able to communicate with the cloud or other devices over Wi-Fi / BLE. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode->Zigbee ZCZR (coordinator/router) + * and also the correct partition scheme must be selected in Tools->Partition Scheme->Zigbee ZCZR + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ZCZR +#error "Zigbee coordinator mode is not selected in Tools->Zigbee mode" +#endif + +#include "Zigbee.h" +#include +#include "time.h" +#include "esp_sntp.h" + +/* Zigbee gateway configuration */ +#define GATEWAY_ENDPOINT_NUMBER 1 +#define GATEWAY_RCP_UART_PORT UART_NUM_1 // UART 0 is used for Serial communication +#define GATEWAY_RCP_RX_PIN 4 +#define GATEWAY_RCP_TX_PIN 5 + +ZigbeeGateway zbGateway = ZigbeeGateway(GATEWAY_ENDPOINT_NUMBER); + +/* Wi-Fi credentials */ +const char *ssid = "your-ssid"; +const char *password = "your-password"; + +/* NTP server configuration */ +const char *ntpServer1 = "pool.ntp.org"; +const char *ntpServer2 = "time.nist.gov"; +const long gmtOffset_sec = 3600; +const int daylightOffset_sec = 3600; +const char *time_zone = "CET-1CEST,M3.5.0,M10.5.0/3"; // TimeZone rule for Europe/Rome including daylight adjustment rules (optional) + +/* Time structure */ +struct tm timeinfo; + +/********************* Arduino functions **************************/ +void setup() { + Serial.begin(115200); + + // Initialize Wi-Fi and connect to AP + WiFi.begin(ssid, password); + esp_sntp_servermode_dhcp(1); // (optional) + + Serial.print("Connecting to WiFi"); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("WiFi connected"); + + // Initialize Zigbee and Begin Zigbee stack + // Optional: set Zigbee device name and model + zbGateway.setManufacturerAndModel("Espressif", "ZigbeeGateway"); + zbGateway.addTimeCluster(timeinfo, gmtOffset_sec); + + // Add endpoint to Zigbee Core + Serial.println("Adding Zigbee Gateway endpoint"); + Zigbee.addEndpoint(&zbGateway); + + // Optional: Open network for 180 seconds after boot + Zigbee.setRebootOpenNetwork(180); + + // Set custom radio configuration for RCP communication + esp_zb_radio_config_t radio_config = ZIGBEE_DEFAULT_UART_RCP_RADIO_CONFIG(); + radio_config.radio_uart_config.port = GATEWAY_RCP_UART_PORT; + radio_config.radio_uart_config.rx_pin = (gpio_num_t)GATEWAY_RCP_RX_PIN; + radio_config.radio_uart_config.tx_pin = (gpio_num_t)GATEWAY_RCP_TX_PIN; + + Zigbee.setRadioConfig(radio_config); + + // When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR or ZIGBEE_ROUTER mode + if (!Zigbee.begin(ZIGBEE_COORDINATOR)) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } + + // set notification call-back function + sntp_set_time_sync_notification_cb(timeavailable); + sntp_set_sync_interval(30000); // sync every 30 seconds + + // config time zone and NTP servers + configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2); +} + +void loop() { + // Nothing to do here in this example +} + +void printLocalTime() { + if (!getLocalTime(&timeinfo)) { + Serial.println("No time available (yet)"); + return; + } + Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); + zbGateway.setTime(timeinfo); + Serial.println("Time updated in Zigbee Gateway"); +} + +// Callback function (gets called when time adjusts via NTP) +void timeavailable(struct timeval *t) { + Serial.println("Got time adjustment from NTP!"); + printLocalTime(); +} diff --git a/libraries/Zigbee/examples/Zigbee_Gateway/ci.json b/libraries/Zigbee/examples/Zigbee_Gateway/ci.json new file mode 100644 index 00000000000..23e1c59d1da --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Gateway/ci.json @@ -0,0 +1,10 @@ +{ + "fqbn_append": "PartitionScheme=zigbee_zczr_8MB,ZigbeeMode=zczr", + "requires": [ + "CONFIG_ZB_ENABLED=y" + ], + "targets": { + "esp32c6": false, + "esp32h2": false + } +} diff --git a/libraries/Zigbee/keywords.txt b/libraries/Zigbee/keywords.txt index 483d54eb712..2eeed5878a7 100644 --- a/libraries/Zigbee/keywords.txt +++ b/libraries/Zigbee/keywords.txt @@ -21,12 +21,22 @@ ZigbeeThermostat KEYWORD1 ZigbeeFlowSensor KEYWORD1 ZigbeePressureSensor KEYWORD1 ZigbeeOccupancySensor KEYWORD1 +ZigbeeAnalog KEYWORD1 +ZigbeeCarbonDioxideSensor KEYWORD1 +ZigbeeContactSwitch KEYWORD1 +ZigbeeDoorWindowHandle KEYWORD1 +ZigbeeGateway KEYWORD1 +ZigbeeRangeExtender KEYWORD1 +ZigbeeVibrationSensor KEYWORD1 +ZigbeeWindowCovering KEYWORD1 # Other zigbee_role_t KEYWORD1 zbstring_t KEYWORD1 zb_device_params_t KEYWORD1 zigbee_scan_result_t KEYWORD1 +zb_power_source_t KEYWORD1 +ZigbeeWindowCoveringType KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) @@ -126,6 +136,43 @@ setSensorType KEYWORD2 # ZigbeeCarbonDioxideSensor setCarbonDioxide KEYWORD2 +# ZigbeeAnalog +addAnalogValue KEYWORD2 +addAnalogInput KEYWORD2 +addAnalogOutput KEYWORD2 +onAnalogOutputChange KEYWORD2 +setAnalogValue KEYWORD2 +setAnalogInput KEYWORD2 +reportAnalogInput KEYWORD2 +setAnalogInputReporting KEYWORD2 + +# ZigbeeCarbonDioxideSensor +setCarbonDioxide KEYWORD2 + +# ZigbeeContactSwitch + ZigbeeDoorWindowHandle +setIASClientEndpoint KEYWORD2 +setClosed KEYWORD2 +setOpen KEYWORD2 +setTilted KEYWORD2 + +# ZigbeeVibrationSensor +setVibration KEYWORD2 + +ZigbeeWindowCovering +onOpen KEYWORD2 +onClose KEYWORD2 +onGoToLiftPercentage KEYWORD2 +onGoToTiltPercentage KEYWORD2 +onStop KEYWORD2 +setLiftPosition KEYWORD2 +setLiftPercentage KEYWORD2 +setTiltPosition KEYWORD2 +setTiltPercentage KEYWORD2 +setCoveringType KEYWORD2 +setConfigStatus KEYWORD2 +setMode KEYWORD2 +setLimits KEYWORD2 + ####################################### # Constants (LITERAL1) ####################################### @@ -137,7 +184,6 @@ ZIGBEE_DEFAULT_ED_CONFIG LITERAL1 ZIGBEE_DEFAULT_ROUTER_CONFIG LITERAL1 ZIGBEE_DEFAULT_COORDINATOR_CONFIG LITERAL1 ZIGBEE_DEFAULT_RADIO_CONFIG LITERAL1 +ZIGBEE_DEFAULT_UART_RCP_RADIO_CONFIG LITERAL1 ZIGBEE_DEFAULT_HOST_CONFIG LITERAL1 ZB_ARRAY_LENTH LITERAL1 -XYZ_TO_RGB LITERAL1 -RGB_TO_XYZ LITERAL1 diff --git a/libraries/Zigbee/src/Zigbee.h b/libraries/Zigbee/src/Zigbee.h index c8e7481e58f..9ccf1e7d8f2 100644 --- a/libraries/Zigbee/src/Zigbee.h +++ b/libraries/Zigbee/src/Zigbee.h @@ -24,3 +24,4 @@ #include "ep/ZigbeeWindowCovering.h" #include "ep/ZigbeeVibrationSensor.h" #include "ep/ZigbeeRangeExtender.h" +#include "ep/ZigbeeGateway.h" diff --git a/libraries/Zigbee/src/ZigbeeCore.cpp b/libraries/Zigbee/src/ZigbeeCore.cpp index 0fad546bb15..bd5849bb4b8 100644 --- a/libraries/Zigbee/src/ZigbeeCore.cpp +++ b/libraries/Zigbee/src/ZigbeeCore.cpp @@ -87,7 +87,11 @@ void ZigbeeCore::addEndpoint(ZigbeeEP *ep) { return; } - esp_zb_ep_list_add_ep(_zb_ep_list, ep->_cluster_list, ep->_ep_config); + if (ep->_device_id == ESP_ZB_HA_HOME_GATEWAY_DEVICE_ID) { + esp_zb_ep_list_add_gateway_ep(_zb_ep_list, ep->_cluster_list, ep->_ep_config); + } else { + esp_zb_ep_list_add_ep(_zb_ep_list, ep->_cluster_list, ep->_ep_config); + } } static void esp_zb_task(void *pvParameters) { @@ -156,7 +160,7 @@ bool ZigbeeCore::zigbeeInit(esp_zb_cfg_t *zb_cfg, bool erase_nvs) { } // Create Zigbee task and start Zigbee stack - xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL); + xTaskCreate(esp_zb_task, "Zigbee_main", 8192, NULL, 5, NULL); return true; } diff --git a/libraries/Zigbee/src/ZigbeeCore.h b/libraries/Zigbee/src/ZigbeeCore.h index 1d6e32babe0..a26e17e58a7 100644 --- a/libraries/Zigbee/src/ZigbeeCore.h +++ b/libraries/Zigbee/src/ZigbeeCore.h @@ -60,6 +60,26 @@ typedef enum { } \ } +#define ZIGBEE_DEFAULT_UART_RCP_RADIO_CONFIG() \ + { \ + .radio_mode = ZB_RADIO_MODE_UART_RCP, \ + .radio_uart_config = { \ + .port = UART_NUM_1, \ + .rx_pin = GPIO_NUM_NC, \ + .tx_pin = GPIO_NUM_NC, \ + .uart_config = \ + { \ + .baud_rate = 460800, \ + .data_bits = UART_DATA_8_BITS, \ + .parity = UART_PARITY_DISABLE, \ + .stop_bits = UART_STOP_BITS_1, \ + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \ + .rx_flow_ctrl_thresh = 0, \ + .source_clk = UART_SCLK_DEFAULT, \ + }, \ + }, \ + } + class ZigbeeCore { private: esp_zb_radio_config_t _radio_config; diff --git a/libraries/Zigbee/src/ZigbeeEP.cpp b/libraries/Zigbee/src/ZigbeeEP.cpp index 8320215707b..6774e9111f1 100644 --- a/libraries/Zigbee/src/ZigbeeEP.cpp +++ b/libraries/Zigbee/src/ZigbeeEP.cpp @@ -19,6 +19,7 @@ ZigbeeEP::ZigbeeEP(uint8_t endpoint) { _ep_config.endpoint = 0; _cluster_list = nullptr; _on_identify = nullptr; + _time_status = 0; if (!lock) { lock = xSemaphoreCreateBinary(); if (lock == NULL) { @@ -240,7 +241,6 @@ void ZigbeeEP::zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message) { void ZigbeeEP::addTimeCluster(tm time, int32_t gmt_offset) { time_t utc_time = 0; - // Check if time is set if (time.tm_year > 0) { // Convert time to UTC @@ -251,6 +251,7 @@ void ZigbeeEP::addTimeCluster(tm time, int32_t gmt_offset) { esp_zb_attribute_list_t *time_cluster_server = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_TIME); esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ZONE_ID, (void *)&gmt_offset); esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, (void *)&utc_time); + esp_zb_time_cluster_add_attr(time_cluster_server, ESP_ZB_ZCL_ATTR_TIME_TIME_STATUS_ID, (void *)&_time_status); // Create time cluster client attributes esp_zb_attribute_list_t *time_cluster_client = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_TIME); // Add time clusters to cluster list @@ -260,6 +261,7 @@ void ZigbeeEP::addTimeCluster(tm time, int32_t gmt_offset) { void ZigbeeEP::setTime(tm time) { time_t utc_time = mktime(&time); + log_d("Setting time to %lld", utc_time); esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_set_attribute_val(_endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_ID, &utc_time, false); esp_zb_lock_release(); @@ -306,6 +308,16 @@ tm ZigbeeEP::getTime(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_addr_t ie struct tm *timeinfo = localtime(&_read_time); if (timeinfo) { + // Update time + setTime(*timeinfo); + // Update time status to synced + _time_status |= 0x02; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_TIME, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TIME_TIME_STATUS_ID, &_time_status, false + ); + esp_zb_lock_release(); + return *timeinfo; } else { log_e("Error while converting time"); @@ -343,8 +355,9 @@ int32_t ZigbeeEP::getTimezone(uint8_t endpoint, int32_t short_addr, esp_zb_ieee_ //Wait for response or timeout if (xSemaphoreTake(lock, ZB_CMD_TIMEOUT) != pdTRUE) { log_e("Error while reading timezone"); + return 0; } - + setTimezone(_read_timezone); return _read_timezone; } diff --git a/libraries/Zigbee/src/ZigbeeEP.h b/libraries/Zigbee/src/ZigbeeEP.h index 14b9ff61040..0a4e3e9d252 100644 --- a/libraries/Zigbee/src/ZigbeeEP.h +++ b/libraries/Zigbee/src/ZigbeeEP.h @@ -153,6 +153,7 @@ class ZigbeeEP { std::list _bound_devices; SemaphoreHandle_t lock; zb_power_source_t _power_source; + uint8_t _time_status; friend class ZigbeeCore; }; diff --git a/libraries/Zigbee/src/ep/ZigbeeGateway.cpp b/libraries/Zigbee/src/ep/ZigbeeGateway.cpp new file mode 100644 index 00000000000..b0be81395ca --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeGateway.cpp @@ -0,0 +1,15 @@ +#include "ZigbeeGateway.h" +#if CONFIG_ZB_ENABLED + +ZigbeeGateway::ZigbeeGateway(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_HOME_GATEWAY_DEVICE_ID; + + _cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_cluster_list_add_basic_cluster(_cluster_list, esp_zb_basic_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_identify_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(_cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY), ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_HOME_GATEWAY_DEVICE_ID, .app_device_version = 0}; +} + +#endif // CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeGateway.h b/libraries/Zigbee/src/ep/ZigbeeGateway.h new file mode 100644 index 00000000000..3925630c0b8 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeGateway.h @@ -0,0 +1,18 @@ +/* Class of Zigbee Gateway endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +class ZigbeeGateway : public ZigbeeEP { +public: + ZigbeeGateway(uint8_t endpoint); + ~ZigbeeGateway() {} +}; + +#endif // CONFIG_ZB_ENABLED From e3bcc58672d39574f3a4fbe3c8c0b2f1844cc202 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Wed, 26 Feb 2025 06:49:42 -0300 Subject: [PATCH 58/79] ci(esp32p4): Add missing options for P4 (#11014) Co-authored-by: Rodrigo Garcia --- tests/validation/democfg/ci.json | 7 ++++--- tests/validation/nvs/ci.json | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/validation/democfg/ci.json b/tests/validation/democfg/ci.json index e4f275a4bca..cf5c796644e 100644 --- a/tests/validation/democfg/ci.json +++ b/tests/validation/democfg/ci.json @@ -14,17 +14,18 @@ "platforms": { "hardware": true, "qemu": false, - "wokwi": true + "wokwi": false }, "requires": [ "CONFIG_SOC_UART_SUPPORTED=y" ], "targets": { "esp32": true, - "esp32c3": true, + "esp32c3": false, "esp32c6": true, "esp32h2": false, "esp32s2": true, - "esp32s3": true + "esp32s3": true, + "esp32p4": false } } diff --git a/tests/validation/nvs/ci.json b/tests/validation/nvs/ci.json index bddf221e3c0..7f8ce83ec54 100644 --- a/tests/validation/nvs/ci.json +++ b/tests/validation/nvs/ci.json @@ -28,6 +28,12 @@ "espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app,FlashMode=qio", "espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app,FlashMode=qio120", "espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app,FlashMode=dio" + ], + "esp32p4": [ + "espressif:esp32:esp32p4:PSRAM=enabled,USBMode=default,PartitionScheme=huge_app,FlashMode=dio", + "espressif:esp32:esp32p4:PSRAM=enabled,USBMode=default,PartitionScheme=huge_app,FlashMode=dio,FlashFreq=40", + "espressif:esp32:esp32p4:PSRAM=enabled,USBMode=default,PartitionScheme=huge_app,FlashMode=qio", + "espressif:esp32:esp32p4:PSRAM=enabled,USBMode=default,PartitionScheme=huge_app,FlashMode=qio,FlashFreq=40" ] }, "platforms": { From 7575fa0ce8fc8eb3cf886fe28ef1bd881cbbe01d Mon Sep 17 00:00:00 2001 From: oddlama Date: Wed, 26 Feb 2025 10:50:28 +0100 Subject: [PATCH 59/79] fix(zigbee): use correct carbon dioxide cluster function in setTolerance (#11015) * fix(zigbee): use correct carbon dioxide cluster function in setTolerance * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp index 15e13d04d7e..f7c0a19bc78 100644 --- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp @@ -37,7 +37,9 @@ void ZigbeeCarbonDioxideSensor::setTolerance(float tolerance) { float zb_tolerance = tolerance / 1000000.0f; esp_zb_attribute_list_t *carbon_dioxide_measure_cluster = esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_CARBON_DIOXIDE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); - esp_zb_temperature_meas_cluster_add_attr(carbon_dioxide_measure_cluster, ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance); + esp_zb_carbon_dioxide_measurement_cluster_add_attr( + carbon_dioxide_measure_cluster, ESP_ZB_ZCL_ATTR_CARBON_DIOXIDE_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance + ); } void ZigbeeCarbonDioxideSensor::setReporting(uint16_t min_interval, uint16_t max_interval, uint16_t delta) { From 684a9312e6e117cefc67ade4da7d9f0b700dc020 Mon Sep 17 00:00:00 2001 From: iranl Date: Wed, 5 Mar 2025 11:45:11 +0100 Subject: [PATCH 60/79] fix(bt): Compile error on ESP32-P4 (#11035) * fix(bt): Fix compile error on ESP32-P4 * fix(bt): Fix compile error on ESP32-P4 --- cores/esp32/esp32-hal-misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-misc.c b/cores/esp32/esp32-hal-misc.c index 02871872f83..50e2973d27a 100644 --- a/cores/esp32/esp32-hal-misc.c +++ b/cores/esp32/esp32-hal-misc.c @@ -25,7 +25,7 @@ #include "esp_ota_ops.h" #endif //CONFIG_APP_ROLLBACK_ENABLE #include "esp_private/startup_internal.h" -#ifdef CONFIG_BT_ENABLED +#if defined(CONFIG_BT_ENABLED) && SOC_BT_SUPPORTED #include "esp_bt.h" #endif //CONFIG_BT_ENABLED #include @@ -305,7 +305,7 @@ void initArduino() { if (err) { log_e("Failed to initialize NVS! Error: %u", err); } -#ifdef CONFIG_BT_ENABLED +#if defined(CONFIG_BT_ENABLED) && SOC_BT_SUPPORTED if (!btInUse()) { esp_bt_controller_mem_release(ESP_BT_MODE_BTDM); } From 9e2f75564127a9853f80f3eb637b264406cb2f30 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Wed, 5 Mar 2025 08:33:20 -0300 Subject: [PATCH 61/79] test(i2c): Add test to scan bus (#11022) * test(i2c): Add test to scan bus * test(i2c): Add scan test with wifi running * fix(i2c): Simplify test --- tests/validation/i2c_master/i2c_master.ino | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/validation/i2c_master/i2c_master.ino b/tests/validation/i2c_master/i2c_master.ino index 3c7b2d9824a..9b4cc508a35 100644 --- a/tests/validation/i2c_master/i2c_master.ino +++ b/tests/validation/i2c_master/i2c_master.ino @@ -5,6 +5,11 @@ #include #include #include +#include +#include +#include + +#include "sdkconfig.h" /* DS1307 functions */ @@ -24,6 +29,9 @@ static uint8_t read_month = 0; static uint16_t read_year = 0; static int peek_data = -1; +const char *ssid = "Wokwi-GUEST"; +const char *password = ""; + const auto BCD2DEC = [](uint8_t num) -> uint8_t { return ((num / 16 * 10) + (num % 16)); }; @@ -245,6 +253,42 @@ void test_api() { Wire.flush(); } +bool device_found() { + uint8_t err; + + for (uint8_t address = 1; address < 127; ++address) { + Wire.beginTransmission(address); + err = Wire.endTransmission(); + log_d("Address: 0x%02X, Error: %d", address, err); + if (err == 0) { + log_i("Found device at address: 0x%02X", address); + } else if (address == DS1307_ADDR) { + log_e("Failed to find DS1307"); + return false; + } + } + + return true; +} + +void scan_bus() { + TEST_ASSERT_TRUE(device_found()); +} + +#if SOC_WIFI_SUPPORTED +void scan_bus_with_wifi() { + // delete old config + WiFi.disconnect(true, true, 1000); + delay(1000); + WiFi.begin(ssid, password); + delay(5000); + bool found = device_found(); + WiFi.disconnect(true, true, 1000); + + TEST_ASSERT_TRUE(found); +} +#endif + /* Main */ void setup() { @@ -258,6 +302,10 @@ void setup() { log_d("Starting tests"); UNITY_BEGIN(); + RUN_TEST(scan_bus); +#if SOC_WIFI_SUPPORTED + RUN_TEST(scan_bus_with_wifi); +#endif RUN_TEST(rtc_set_time); RUN_TEST(rtc_run_clock); RUN_TEST(change_clock); From fb5f11b638b377398e6320d48065e8515248d527 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Fri, 7 Mar 2025 19:00:58 -0300 Subject: [PATCH 62/79] feat(matter): necessary changes to insights version for esp_matter (#11042) * feat(matter): necessary changes to insights version for esp_matter * feat(rainmaker): update RainMaker version to 1.5.2 --- idf_component.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/idf_component.yml b/idf_component.yml index 94a69caec2f..967c4ecf0f6 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -69,7 +69,7 @@ dependencies: espressif/network_provisioning: version: "1.0.2" espressif/esp_rainmaker: - version: "1.5.0" + version: "1.5.2" rules: - if: "target not in [esp32c2, esp32p4]" espressif/rmaker_common: @@ -77,16 +77,16 @@ dependencies: rules: - if: "target not in [esp32c2, esp32p4]" espressif/esp_insights: - version: "1.0.1" + version: "1.2.2" rules: - if: "target not in [esp32c2, esp32p4]" # New version breaks esp_insights 1.0.1 espressif/esp_diag_data_store: - version: "1.0.1" + version: "1.0.2" rules: - if: "target not in [esp32c2, esp32p4]" espressif/esp_diagnostics: - version: "1.0.2" + version: "1.2.1" rules: - if: "target not in [esp32c2, esp32p4]" espressif/cbor: From efb02d30ac1b863490a9de49374b18890e84b1f3 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Sun, 9 Mar 2025 08:20:59 -0300 Subject: [PATCH 63/79] feat(gpio): allows mixing digital and analog read/write operations (#11016) * feat(gpio): allows mixing digital and analog read/write operations * fix(gpio): simple mistake in calling __pinMode() fnuction * fix(gpio): simple mistake in calling __pinMode() fnuction * feat(gpio): update the log message to tell the solution for the error. * feat(gpio): warn user about digitalRead() used with non GPIO pin * fix(gpio): wrong peripheral manager test case --- cores/esp32/esp32-hal-gpio.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cores/esp32/esp32-hal-gpio.c b/cores/esp32/esp32-hal-gpio.c index b11636daf81..c681be077b3 100644 --- a/cores/esp32/esp32-hal-gpio.c +++ b/cores/esp32/esp32-hal-gpio.c @@ -173,7 +173,7 @@ extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val) { if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) != NULL) { gpio_set_level((gpio_num_t)pin, val); } else { - log_e("IO %i is not set as GPIO.", pin); + log_e("IO %i is not set as GPIO. Execute digitalMode(%i, OUTPUT) first.", pin, pin); } } @@ -182,14 +182,12 @@ extern int ARDUINO_ISR_ATTR __digitalRead(uint8_t pin) { if (pin == RGB_BUILTIN) { return RGB_BUILTIN_storage; } -#endif - - if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) != NULL) { - return gpio_get_level((gpio_num_t)pin); - } else { - log_e("IO %i is not set as GPIO.", pin); - return 0; +#endif // RGB_BUILTIN + // This work when the pin is set as GPIO and in INPUT mode. For all other pin functions, it may return inconsistent response + if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) == NULL) { + log_w("IO %i is not set as GPIO. digitalRead() may return an inconsistent value."); } + return gpio_get_level((gpio_num_t)pin); } static void ARDUINO_ISR_ATTR __onPinInterrupt(void *arg) { From 4677ea6ad82d3bb78bec9b10edbe2745fe5a0fc0 Mon Sep 17 00:00:00 2001 From: Oli Date: Mon, 10 Mar 2025 11:53:43 +0000 Subject: [PATCH 64/79] Fix to issue #11044 (#11064) Fix to a copy-paste error that causes a Guru Meditation crash with Zigbee Analog Example. --- libraries/Zigbee/src/ep/ZigbeeAnalog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp index 9d1b53fd310..b6d581450aa 100644 --- a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp @@ -105,7 +105,7 @@ void ZigbeeAnalog::setAnalogInputReporting(uint16_t min_interval, uint16_t max_i memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t)); reporting_info.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV; reporting_info.ep = _endpoint; - reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; + reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_ANALOG_INPUT; reporting_info.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE; reporting_info.attr_id = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID; reporting_info.u.send_info.min_interval = min_interval; From 8575d04ab54789bac24ebe3a1c6428a8246ac897 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Mon, 10 Mar 2025 21:19:22 +0200 Subject: [PATCH 65/79] fix(eth): Fix RMII Ethernet not being able to be restarted (#11048) --- libraries/Ethernet/src/ETH.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/libraries/Ethernet/src/ETH.cpp b/libraries/Ethernet/src/ETH.cpp index bf63de8724d..f347616c340 100644 --- a/libraries/Ethernet/src/ETH.cpp +++ b/libraries/Ethernet/src/ETH.cpp @@ -271,8 +271,8 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, i eth_mac_config.sw_reset_timeout_ms = 1000; eth_mac_config.rx_task_stack_size = _task_stack_size; - esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config, ð_mac_config); - if (mac == NULL) { + _mac = esp_eth_mac_new_esp32(&mac_config, ð_mac_config); + if (_mac == NULL) { log_e("esp_eth_mac_new_esp32 failed"); return false; } @@ -281,26 +281,25 @@ bool ETHClass::begin(eth_phy_type_t type, int32_t phy_addr, int mdc, int mdio, i phy_config.phy_addr = phy_addr; phy_config.reset_gpio_num = _pin_power; - esp_eth_phy_t *phy = NULL; switch (type) { #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0) - case ETH_PHY_GENERIC: phy = esp_eth_phy_new_generic(&phy_config); break; + case ETH_PHY_GENERIC: _phy = esp_eth_phy_new_generic(&phy_config); break; #endif - case ETH_PHY_LAN8720: phy = esp_eth_phy_new_lan87xx(&phy_config); break; - case ETH_PHY_TLK110: phy = esp_eth_phy_new_ip101(&phy_config); break; - case ETH_PHY_RTL8201: phy = esp_eth_phy_new_rtl8201(&phy_config); break; - case ETH_PHY_DP83848: phy = esp_eth_phy_new_dp83848(&phy_config); break; - case ETH_PHY_KSZ8041: phy = esp_eth_phy_new_ksz80xx(&phy_config); break; - case ETH_PHY_KSZ8081: phy = esp_eth_phy_new_ksz80xx(&phy_config); break; + case ETH_PHY_LAN8720: _phy = esp_eth_phy_new_lan87xx(&phy_config); break; + case ETH_PHY_TLK110: _phy = esp_eth_phy_new_ip101(&phy_config); break; + case ETH_PHY_RTL8201: _phy = esp_eth_phy_new_rtl8201(&phy_config); break; + case ETH_PHY_DP83848: _phy = esp_eth_phy_new_dp83848(&phy_config); break; + case ETH_PHY_KSZ8041: _phy = esp_eth_phy_new_ksz80xx(&phy_config); break; + case ETH_PHY_KSZ8081: _phy = esp_eth_phy_new_ksz80xx(&phy_config); break; default: log_e("Unsupported PHY %d", type); break; } - if (phy == NULL) { + if (_phy == NULL) { log_e("esp_eth_phy_new failed"); return false; } _eth_handle = NULL; - esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy); + esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(_mac, _phy); ret = esp_eth_driver_install(ð_config, &_eth_handle); if (ret != ESP_OK) { log_e("Ethernet driver install failed: %d", ret); From eeb6a26ed1e25e723b9660986567ddd1c174d27c Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Mon, 10 Mar 2025 21:19:46 +0200 Subject: [PATCH 66/79] fix(wifi): Disable properly LR mode if it was enabled before (#11052) * fix(wifi): Disable properly LR mode if it was enabled before * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- libraries/WiFi/src/WiFiGeneric.cpp | 70 ++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index 40e3b12c687..aa994963514 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -308,7 +308,7 @@ bool wifiLowLevelInit(bool persistent) { esp_err_t err = esp_wifi_init(&cfg); if (err) { - log_e("esp_wifi_init %d", err); + log_e("esp_wifi_init 0x%x: %s", err, esp_err_to_name(err)); lowLevelInitDone = false; return lowLevelInitDone; } @@ -375,7 +375,7 @@ static bool espWiFiStart() { esp_err_t err = esp_wifi_start(); if (err != ESP_OK) { _esp_wifi_started = false; - log_e("esp_wifi_start %d", err); + log_e("esp_wifi_start 0x%x: %s", err, esp_err_to_name(err)); return _esp_wifi_started; } return _esp_wifi_started; @@ -389,7 +389,7 @@ static bool espWiFiStop() { _esp_wifi_started = false; err = esp_wifi_stop(); if (err) { - log_e("Could not stop WiFi! %d", err); + log_e("Could not stop WiFi! 0x%x: %s", err, esp_err_to_name(err)); _esp_wifi_started = true; return false; } @@ -478,7 +478,7 @@ int WiFiGenericClass::setChannel(uint8_t primary, wifi_second_chan_t secondary) ret = esp_wifi_get_country(&country); if (ret != ESP_OK) { - log_e("Failed to get country info"); + log_e("Failed to get country info 0x%x: %s", ret, esp_err_to_name(ret)); return ret; } @@ -492,7 +492,7 @@ int WiFiGenericClass::setChannel(uint8_t primary, wifi_second_chan_t secondary) ret = esp_wifi_set_channel(primary, secondary); if (ret != ESP_OK) { - log_e("Failed to set channel"); + log_e("Failed to set channel 0x%x: %s", ret, esp_err_to_name(ret)); return ret; } @@ -562,13 +562,13 @@ bool WiFiGenericClass::mode(wifi_mode_t m) { if (((m & WIFI_MODE_STA) != 0) && ((cm & WIFI_MODE_STA) == 0)) { err = esp_netif_set_hostname(esp_netifs[ESP_IF_WIFI_STA], NetworkManager::getHostname()); if (err) { - log_e("Could not set hostname! %d", err); + log_e("Could not set hostname! 0x%x: %s", err, esp_err_to_name(err)); return false; } } err = esp_wifi_set_mode(m); if (err) { - log_e("Could not set mode! %d", err); + log_e("Could not set mode! 0x%x: %s", err, esp_err_to_name(err)); return false; } @@ -585,17 +585,44 @@ bool WiFiGenericClass::mode(wifi_mode_t m) { if (m & WIFI_MODE_STA) { err = esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_LR); if (err != ESP_OK) { - log_e("Could not enable long range on STA! %d", err); + log_e("Could not enable long range on STA! 0x%x: %s", err, esp_err_to_name(err)); return false; } } if (m & WIFI_MODE_AP) { err = esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_LR); if (err != ESP_OK) { - log_e("Could not enable long range on AP! %d", err); + log_e("Could not enable long range on AP! 0x%x: %s", err, esp_err_to_name(err)); return false; } } + } else { +#if CONFIG_SOC_WIFI_HE_SUPPORT +#define WIFI_PROTOCOL_DEFAULT (WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_11AX) +#else +#define WIFI_PROTOCOL_DEFAULT (WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N) +#endif + uint8_t current_protocol = 0; + if (m & WIFI_MODE_STA) { + err = esp_wifi_get_protocol(WIFI_IF_STA, ¤t_protocol); + if (err == ESP_OK && current_protocol == WIFI_PROTOCOL_LR) { + log_v("Disabling long range on STA"); + err = esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_DEFAULT); + if (err != ESP_OK) { + log_e("Could not disable long range on STA! 0x%x: %s", err, esp_err_to_name(err)); + } + } + } + if (m & WIFI_MODE_AP) { + err = esp_wifi_get_protocol(WIFI_IF_AP, ¤t_protocol); + if (err == ESP_OK && current_protocol == WIFI_PROTOCOL_LR) { + log_v("Disabling long range on AP"); + err = esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_DEFAULT); + if (err != ESP_OK) { + log_e("Could not disable long range on AP! 0x%x: %s", err, esp_err_to_name(err)); + } + } + } } if (!espWiFiStart()) { return false; @@ -683,8 +710,9 @@ bool WiFiGenericClass::setSleep(wifi_ps_type_t sleepType) { if (sleepType != _sleepEnabled) { _sleepEnabled = sleepType; if (WiFi.STA.started()) { - if (esp_wifi_set_ps(_sleepEnabled) != ESP_OK) { - log_e("esp_wifi_set_ps failed!"); + esp_err_t err = esp_wifi_set_ps(_sleepEnabled); + if (err != ESP_OK) { + log_e("esp_wifi_set_ps failed!: 0x%x: %s", err, esp_err_to_name(err)); return false; } } @@ -748,8 +776,9 @@ bool WiFiGenericClass::initiateFTM(uint8_t frm_count, uint16_t burst_period, uin memcpy(ftmi_cfg.resp_mac, mac, 6); } // Request FTM session with the Responder - if (ESP_OK != esp_wifi_ftm_initiate_session(&ftmi_cfg)) { - log_e("Failed to initiate FTM session"); + esp_err_t err = esp_wifi_ftm_initiate_session(&ftmi_cfg); + if (ESP_OK != err) { + log_e("Failed to initiate FTM session: 0x%x: %s", err, esp_err_to_name(err)); return false; } return true; @@ -768,8 +797,9 @@ bool WiFiGenericClass::setDualAntennaConfig(uint8_t gpio_ant1, uint8_t gpio_ant2 esp_phy_ant_gpio_config_t wifi_ant_io; - if (ESP_OK != esp_phy_get_ant_gpio(&wifi_ant_io)) { - log_e("Failed to get antenna configuration"); + esp_err_t err = esp_phy_get_ant_gpio(&wifi_ant_io); + if (ESP_OK != err) { + log_e("Failed to get antenna configuration: 0x%x: %s", err, esp_err_to_name(err)); return false; } @@ -778,8 +808,9 @@ bool WiFiGenericClass::setDualAntennaConfig(uint8_t gpio_ant1, uint8_t gpio_ant2 wifi_ant_io.gpio_cfg[1].gpio_num = gpio_ant2; wifi_ant_io.gpio_cfg[1].gpio_select = 1; - if (ESP_OK != esp_phy_set_ant_gpio(&wifi_ant_io)) { - log_e("Failed to set antenna GPIO configuration"); + err = esp_phy_set_ant_gpio(&wifi_ant_io); + if (ESP_OK != err) { + log_e("Failed to set antenna GPIO configuration: 0x%x: %s", err, esp_err_to_name(err)); return false; } @@ -827,8 +858,9 @@ bool WiFiGenericClass::setDualAntennaConfig(uint8_t gpio_ant1, uint8_t gpio_ant2 } set_ant: - if (ESP_OK != esp_phy_set_ant(&ant_config)) { - log_e("Failed to set antenna configuration"); + err = esp_phy_set_ant(&ant_config); + if (ESP_OK != err) { + log_e("Failed to set antenna configuration: 0x%x: %s", err, esp_err_to_name(err)); return false; } #endif From bf5265c7d8330d741993bc977c7eb1bfcf8716e1 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Mon, 10 Mar 2025 21:20:07 +0200 Subject: [PATCH 67/79] feat(eth): Add setters for negotiation, speed and duplex modes (#11053) * feat(eth): Add setters for negotiation, speed and duplex modes * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- libraries/Ethernet/src/ETH.cpp | 37 +++++++++++++++++++++++++++++++++- libraries/Ethernet/src/ETH.h | 8 +++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/libraries/Ethernet/src/ETH.cpp b/libraries/Ethernet/src/ETH.cpp index f347616c340..542a7e2a218 100644 --- a/libraries/Ethernet/src/ETH.cpp +++ b/libraries/Ethernet/src/ETH.cpp @@ -1009,6 +1009,18 @@ bool ETHClass::fullDuplex() const { return (link_duplex == ETH_DUPLEX_FULL); } +bool ETHClass::setFullDuplex(bool on) { + if (_eth_handle == NULL) { + return false; + } + eth_duplex_t link_duplex = on ? ETH_DUPLEX_FULL : ETH_DUPLEX_HALF; + esp_err_t err = esp_eth_ioctl(_eth_handle, ETH_CMD_S_DUPLEX_MODE, &link_duplex); + if (err != ESP_OK) { + log_e("Failed to set duplex mode: 0x%x: %s", err, esp_err_to_name(err)); + } + return err == ESP_OK; +} + bool ETHClass::autoNegotiation() const { if (_eth_handle == NULL) { return false; @@ -1018,6 +1030,17 @@ bool ETHClass::autoNegotiation() const { return auto_nego; } +bool ETHClass::setAutoNegotiation(bool on) { + if (_eth_handle == NULL) { + return false; + } + esp_err_t err = esp_eth_ioctl(_eth_handle, ETH_CMD_S_AUTONEGO, &on); + if (err != ESP_OK) { + log_e("Failed to set auto negotiation: 0x%x: %s", err, esp_err_to_name(err)); + } + return err == ESP_OK; +} + uint32_t ETHClass::phyAddr() const { if (_eth_handle == NULL) { return 0; @@ -1027,7 +1050,7 @@ uint32_t ETHClass::phyAddr() const { return phy_addr; } -uint8_t ETHClass::linkSpeed() const { +uint16_t ETHClass::linkSpeed() const { if (_eth_handle == NULL) { return 0; } @@ -1036,6 +1059,18 @@ uint8_t ETHClass::linkSpeed() const { return (link_speed == ETH_SPEED_10M) ? 10 : 100; } +bool ETHClass::setLinkSpeed(uint16_t speed) { + if (_eth_handle == NULL) { + return false; + } + eth_speed_t link_speed = (speed == 10) ? ETH_SPEED_10M : ETH_SPEED_100M; + esp_err_t err = esp_eth_ioctl(_eth_handle, ETH_CMD_S_SPEED, &link_speed); + if (err != ESP_OK) { + log_e("Failed to set link speed: 0x%x: %s", err, esp_err_to_name(err)); + } + return err == ESP_OK; +} + // void ETHClass::getMac(uint8_t* mac) // { // if(_eth_handle != NULL && mac != NULL){ diff --git a/libraries/Ethernet/src/ETH.h b/libraries/Ethernet/src/ETH.h index cbddac065b9..891863e34bf 100644 --- a/libraries/Ethernet/src/ETH.h +++ b/libraries/Ethernet/src/ETH.h @@ -192,8 +192,14 @@ class ETHClass : public NetworkInterface { // ETH Handle APIs bool fullDuplex() const; - uint8_t linkSpeed() const; + bool setFullDuplex(bool on); + + uint16_t linkSpeed() const; + bool setLinkSpeed(uint16_t speed); //10 or 100 + bool autoNegotiation() const; + bool setAutoNegotiation(bool on); + uint32_t phyAddr() const; esp_eth_handle_t handle() const; From 665d6f8e8d2dec4e2ea7835d02d2033c9c5c788f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 10 Mar 2025 20:20:34 +0100 Subject: [PATCH 68/79] fix(zigbee): Use correct attributeID in setAnalogInputReporting (#11065) --- libraries/Zigbee/src/ep/ZigbeeAnalog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp index b6d581450aa..92cfaa09da6 100644 --- a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp @@ -107,7 +107,7 @@ void ZigbeeAnalog::setAnalogInputReporting(uint16_t min_interval, uint16_t max_i reporting_info.ep = _endpoint; reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_ANALOG_INPUT; reporting_info.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE; - reporting_info.attr_id = ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID; + reporting_info.attr_id = ESP_ZB_ZCL_ATTR_ANALOG_INPUT_PRESENT_VALUE_ID; reporting_info.u.send_info.min_interval = min_interval; reporting_info.u.send_info.max_interval = max_interval; reporting_info.u.send_info.def_min_interval = min_interval; From 2276f0b79401ffd63f7719975461dd0c5f68155a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 10 Mar 2025 20:21:00 +0100 Subject: [PATCH 69/79] fix(zigbee): Add manuf_code to report attribure commands (#11066) --- .../Zigbee_Temp_Hum_Sensor_Sleepy.ino | 4 ++-- libraries/Zigbee/src/ep/ZigbeeAnalog.cpp | 1 + libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp | 1 + libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp | 1 + libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp | 1 + libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp | 1 + libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp | 2 ++ 7 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino b/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino index 60bd784cca9..65df4b02957 100644 --- a/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino +++ b/libraries/Zigbee/examples/Zigbee_Temp_Hum_Sensor_Sleepy/Zigbee_Temp_Hum_Sensor_Sleepy.ino @@ -125,8 +125,8 @@ void loop() { int startTime = millis(); while (digitalRead(button) == LOW) { delay(50); - if ((millis() - startTime) > 3000) { - // If key pressed for more than 3secs, factory reset Zigbee and reboot + if ((millis() - startTime) > 10000) { + // If key pressed for more than 10secs, factory reset Zigbee and reboot Serial.println("Resetting Zigbee to factory and rebooting in 1s."); delay(1000); Zigbee.factoryReset(); diff --git a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp index 92cfaa09da6..417eeb6d98c 100644 --- a/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeAnalog.cpp @@ -93,6 +93,7 @@ void ZigbeeAnalog::reportAnalogInput() { report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_ANALOG_INPUT; report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); diff --git a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp index f7c0a19bc78..2718d9275c2 100644 --- a/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeCarbonDioxideSensor.cpp @@ -85,6 +85,7 @@ void ZigbeeCarbonDioxideSensor::report() { report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_CARBON_DIOXIDE_MEASUREMENT; report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); diff --git a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp index d8fea88342e..11fbf7c906b 100644 --- a/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeFlowSensor.cpp @@ -79,6 +79,7 @@ void ZigbeeFlowSensor::report() { report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_FLOW_MEASUREMENT; report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); diff --git a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp index 830e4397137..31a1f7e90e1 100644 --- a/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeOccupancySensor.cpp @@ -49,6 +49,7 @@ void ZigbeeOccupancySensor::report() { report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_OCCUPANCY_SENSING; report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); diff --git a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp index 44e3eace610..21456a51511 100644 --- a/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeePressureSensor.cpp @@ -75,6 +75,7 @@ void ZigbeePressureSensor::report() { report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_PRESSURE_MEASUREMENT; report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); diff --git a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp index c3991593422..b3ff03f0a6b 100644 --- a/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeTempSensor.cpp @@ -74,6 +74,7 @@ void ZigbeeTempSensor::reportTemperature() { report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT; report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); @@ -116,6 +117,7 @@ void ZigbeeTempSensor::reportHumidity() { report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT; report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; esp_zb_lock_acquire(portMAX_DELAY); esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); From e680e7b538026a88616b8247a8909e10fcc64843 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Mon, 10 Mar 2025 16:21:25 -0300 Subject: [PATCH 70/79] fix(matter): removes a few matter 1.4 / IDF 5.4 compilation warning messages (#11067) * fix(matter): uninitialized fields warning * fix(matter): uninitialized fields warning --- libraries/Matter/src/MatterEndpoints/MatterColorLight.h | 4 ++-- .../Matter/src/MatterEndpoints/MatterEnhancedColorLight.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Matter/src/MatterEndpoints/MatterColorLight.h b/libraries/Matter/src/MatterEndpoints/MatterColorLight.h index b896afa9b7a..99449addd50 100644 --- a/libraries/Matter/src/MatterEndpoints/MatterColorLight.h +++ b/libraries/Matter/src/MatterEndpoints/MatterColorLight.h @@ -66,8 +66,8 @@ class MatterColorLight : public MatterEndPoint { protected: bool started = false; - bool onOffState = false; // default initial state is off, but it can be changed by begin(bool) - espHsvColor_t colorHSV = {0}; // default initial color HSV is black, but it can be changed by begin(bool, espHsvColor_t) + bool onOffState = false; // default initial state is off, but it can be changed by begin(bool) + espHsvColor_t colorHSV = {0, 0, 0}; // default initial color HSV is black, but it can be changed by begin(bool, espHsvColor_t) EndPointOnOffCB _onChangeOnOffCB = NULL; EndPointRGBColorCB _onChangeColorCB = NULL; EndPointCB _onChangeCB = NULL; diff --git a/libraries/Matter/src/MatterEndpoints/MatterEnhancedColorLight.h b/libraries/Matter/src/MatterEndpoints/MatterEnhancedColorLight.h index ff6e69e3e65..a4baef968a4 100644 --- a/libraries/Matter/src/MatterEndpoints/MatterEnhancedColorLight.h +++ b/libraries/Matter/src/MatterEndpoints/MatterEnhancedColorLight.h @@ -91,7 +91,7 @@ class MatterEnhancedColorLight : public MatterEndPoint { bool started = false; bool onOffState = false; // default initial state is off, but it can be changed by begin(bool) uint8_t brightnessLevel = 0; // default initial brightness is 0, but it can be changed by begin(bool, uint8_t) - espHsvColor_t colorHSV = {0}; // default initial color HSV is black, but it can be changed by begin(bool, uint8_t, espHsvColor_t) + espHsvColor_t colorHSV = {0, 0, 0}; // default initial color HSV is black, but it can be changed by begin(bool, uint8_t, espHsvColor_t) uint16_t colorTemperatureLevel = 0; // default initial color temperature is 0, but it can be changed by begin(bool, uint8_t, espHsvColor_t, uint16_t) EndPointOnOffCB _onChangeOnOffCB = NULL; EndPointBrightnessCB _onChangeBrightnessCB = NULL; From d9dbc4af41efdceb958aa05925f0eeacec679d78 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Mon, 10 Mar 2025 17:00:34 -0300 Subject: [PATCH 71/79] fix(matter): examples must set pin to Digital Mode after analogWrite() and before digitalWrite() (#11070) * fix(matter): itshall set digital mode before digitalWrite * fix(matter): example must set pin in digital mode before writting * fix(matter): example shall set digital mode before writing * fix(matter): digitalMode necessary before digitalWrite(LOW) * fix(matter): example must set digital mode after analogwrite * fix(matter): wrong copy paste * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- .../Matter/examples/MatterColorLight/MatterColorLight.ino | 4 ++++ .../examples/MatterDimmableLight/MatterDimmableLight.ino | 4 ++++ .../MatterEnhancedColorLight/MatterEnhancedColorLight.ino | 4 ++++ libraries/Matter/examples/MatterFan/MatterFan.ino | 4 ++++ .../MatterTemperatureLight/MatterTemperatureLight.ino | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/libraries/Matter/examples/MatterColorLight/MatterColorLight.ino b/libraries/Matter/examples/MatterColorLight/MatterColorLight.ino index dd1724f602d..f3e45887576 100644 --- a/libraries/Matter/examples/MatterColorLight/MatterColorLight.ino +++ b/libraries/Matter/examples/MatterColorLight/MatterColorLight.ino @@ -60,6 +60,10 @@ bool setLightState(bool state, espHsvColor_t colorHSV) { analogWrite(ledPin, colorHSV.v); #endif } else { +#ifndef RGB_BUILTIN + // after analogWrite(), it is necessary to set the GPIO to digital mode first + pinMode(ledPin, OUTPUT); +#endif digitalWrite(ledPin, LOW); } // store last HSV Color and OnOff state for when the Light is restarted / power goes off diff --git a/libraries/Matter/examples/MatterDimmableLight/MatterDimmableLight.ino b/libraries/Matter/examples/MatterDimmableLight/MatterDimmableLight.ino index cb8b8b6f17f..79751905c20 100644 --- a/libraries/Matter/examples/MatterDimmableLight/MatterDimmableLight.ino +++ b/libraries/Matter/examples/MatterDimmableLight/MatterDimmableLight.ino @@ -56,6 +56,10 @@ bool setLightState(bool state, uint8_t brightness) { analogWrite(ledPin, brightness); #endif } else { +#ifndef RGB_BUILTIN + // after analogWrite(), it is necessary to set the GPIO to digital mode first + pinMode(ledPin, OUTPUT); +#endif digitalWrite(ledPin, LOW); } // store last Brightness and OnOff state for when the Light is restarted / power goes off diff --git a/libraries/Matter/examples/MatterEnhancedColorLight/MatterEnhancedColorLight.ino b/libraries/Matter/examples/MatterEnhancedColorLight/MatterEnhancedColorLight.ino index bd2d13899ca..8e12581fdf2 100644 --- a/libraries/Matter/examples/MatterEnhancedColorLight/MatterEnhancedColorLight.ino +++ b/libraries/Matter/examples/MatterEnhancedColorLight/MatterEnhancedColorLight.ino @@ -64,6 +64,10 @@ bool setLightState(bool state, espHsvColor_t colorHSV, uint8_t brighteness, uint analogWrite(ledPin, colorHSV.v); #endif } else { +#ifndef RGB_BUILTIN + // after analogWrite(), it is necessary to set the GPIO to digital mode first + pinMode(ledPin, OUTPUT); +#endif digitalWrite(ledPin, LOW); } // store last HSV Color and OnOff state for when the Light is restarted / power goes off diff --git a/libraries/Matter/examples/MatterFan/MatterFan.ino b/libraries/Matter/examples/MatterFan/MatterFan.ino index 1094126a843..705aa4853da 100644 --- a/libraries/Matter/examples/MatterFan/MatterFan.ino +++ b/libraries/Matter/examples/MatterFan/MatterFan.ino @@ -49,6 +49,10 @@ void fanDCMotorDrive(bool fanState, uint8_t speedPercent) { // drive the Fan DC motor if (fanState == false) { // turn off the Fan +#ifndef RGB_BUILTIN + // after analogWrite(), it is necessary to set the GPIO to digital mode first + pinMode(dcMotorPin, OUTPUT); +#endif digitalWrite(dcMotorPin, LOW); } else { // set the Fan speed diff --git a/libraries/Matter/examples/MatterTemperatureLight/MatterTemperatureLight.ino b/libraries/Matter/examples/MatterTemperatureLight/MatterTemperatureLight.ino index b814ba89704..d46427591ab 100644 --- a/libraries/Matter/examples/MatterTemperatureLight/MatterTemperatureLight.ino +++ b/libraries/Matter/examples/MatterTemperatureLight/MatterTemperatureLight.ino @@ -66,6 +66,10 @@ bool setLightState(bool state, uint8_t brightness, uint16_t temperature_Mireds) analogWrite(ledPin, brightness); #endif } else { +#ifndef RGB_BUILTIN + // after analogWrite(), it is necessary to set the GPIO to digital mode first + pinMode(ledPin, OUTPUT); +#endif digitalWrite(ledPin, LOW); } // store last Brightness and OnOff state for when the Light is restarted / power goes off From e8a243c1db973b5cdd68949c1dfc8c8bfd11c887 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Mon, 10 Mar 2025 17:18:12 -0300 Subject: [PATCH 72/79] fix(network): fixes a macro name conflict warning (#11068) * fix(network): fixes a macro name conflict warning * feat(networking): removed local maco definition in favor of IDF one --- libraries/Network/src/NetworkClient.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/Network/src/NetworkClient.cpp b/libraries/Network/src/NetworkClient.cpp index da83597d2c6..89411a42453 100644 --- a/libraries/Network/src/NetworkClient.cpp +++ b/libraries/Network/src/NetworkClient.cpp @@ -23,7 +23,11 @@ #include #include -#define IN6_IS_ADDR_V4MAPPED(a) ((((__const uint32_t *)(a))[0] == 0) && (((__const uint32_t *)(a))[1] == 0) && (((__const uint32_t *)(a))[2] == htonl(0xffff))) +// It is already defined in IDF as: +//#define IN6_IS_ADDR_V4MAPPED(a) ip6_addr_isipv4mappedipv6((ip6_addr_t*)(a)) +//#define ip6_addr_isipv4mappedipv6(ip6addr) (((ip6addr)->addr[0] == 0) && ((ip6addr)->addr[1] == 0) && (((ip6addr)->addr[2]) == PP_HTONL(0x0000FFFFUL))) +// Keeping as a memory of the change. +//#define _IN6_IS_ADDR_V4MAPPED(a) ((((__const uint32_t *)(a))[0] == 0) && (((__const uint32_t *)(a))[1] == 0) && (((__const uint32_t *)(a))[2] == htonl(0xffff))) #define WIFI_CLIENT_DEF_CONN_TIMEOUT_MS (3000) #define WIFI_CLIENT_MAX_WRITE_RETRY (10) From bda7c4811728e538b4ea393a5be148cbb614daed Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 11 Mar 2025 00:26:18 +0200 Subject: [PATCH 73/79] IDF release/v5.4 d4aa25a3 (#11060) IDF release/v5.4 d4aa25a3 --- package/package_esp32_index.template.json | 68 +++++++++++------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/package/package_esp32_index.template.json b/package/package_esp32_index.template.json index 5a37e95930a..249ab43acc6 100644 --- a/package/package_esp32_index.template.json +++ b/package/package_esp32_index.template.json @@ -42,7 +42,7 @@ { "packager": "esp32", "name": "esp32-arduino-libs", - "version": "idf-release_v5.4-bcb3c32d-v1" + "version": "idf-release_v5.4-d4aa25a3-v1" }, { "packager": "esp32", @@ -95,63 +95,63 @@ "tools": [ { "name": "esp32-arduino-libs", - "version": "idf-release_v5.4-bcb3c32d-v1", + "version": "idf-release_v5.4-d4aa25a3-v1", "systems": [ { "host": "i686-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", - "size": "345570903" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "checksum": "SHA-256:81101d580ebafb78f71bd494f4f5162fd829279d18634282c0f8f95c9e928335", + "size": "350941396" }, { "host": "x86_64-mingw32", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", - "size": "345570903" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "checksum": "SHA-256:81101d580ebafb78f71bd494f4f5162fd829279d18634282c0f8f95c9e928335", + "size": "350941396" }, { "host": "arm64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", - "size": "345570903" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "checksum": "SHA-256:81101d580ebafb78f71bd494f4f5162fd829279d18634282c0f8f95c9e928335", + "size": "350941396" }, { "host": "x86_64-apple-darwin", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", - "size": "345570903" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "checksum": "SHA-256:81101d580ebafb78f71bd494f4f5162fd829279d18634282c0f8f95c9e928335", + "size": "350941396" }, { "host": "x86_64-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", - "size": "345570903" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "checksum": "SHA-256:81101d580ebafb78f71bd494f4f5162fd829279d18634282c0f8f95c9e928335", + "size": "350941396" }, { "host": "i686-pc-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", - "size": "345570903" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "checksum": "SHA-256:81101d580ebafb78f71bd494f4f5162fd829279d18634282c0f8f95c9e928335", + "size": "350941396" }, { "host": "aarch64-linux-gnu", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", - "size": "345570903" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "checksum": "SHA-256:81101d580ebafb78f71bd494f4f5162fd829279d18634282c0f8f95c9e928335", + "size": "350941396" }, { "host": "arm-linux-gnueabihf", - "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-bcb3c32d-v1.zip", - "checksum": "SHA-256:2ab7a8565d4eadd805c1d00c9a1550292d3287dc43efa166d7ad3ba5322344bb", - "size": "345570903" + "url": "https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.4/esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "archiveFileName": "esp32-arduino-libs-idf-release_v5.4-d4aa25a3-v1.zip", + "checksum": "SHA-256:81101d580ebafb78f71bd494f4f5162fd829279d18634282c0f8f95c9e928335", + "size": "350941396" } ] }, From 07d6a5a0d2f774bd7b004b1bc647d601199a0489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Wed, 12 Mar 2025 14:38:09 +0100 Subject: [PATCH 74/79] feat(Zigbee): Adding Zigbee Wind speed sensor endpoint (#10455) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create ZigbeeWindSpeedSensor.h * Create ZigbeeWindSpeedSensor.cpp * Update ZigbeeWindSpeedSensor.cpp * Update ZigbeeWindSpeedSensor.cpp * Create ZigbeeWindSpeedSensor.ino * Update ZigbeeWindSpeedSensor.ino * Update ZigbeeWindSpeedSensor.ino * Create ci.json * Rename ZigbeeWindSpeedSensor.ino to Zigbee_Wind_Speed_Sensor.ino * Rename ci.json to ci.json * Update CMakeLists.txt * Update Zigbee_Wind_Speed_Sensor.ino * Update Zigbee_Wind_Speed_Sensor.ino * Update Zigbee_Wind_Speed_Sensor.ino * Update ZigbeeWindSpeedSensor.cpp * Update ZigbeeWindSpeedSensor.cpp Use ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID device id * feat(zigbee): Add windspeed sensor endpoint * Update Zigbee.h Add ZigbeeWindSpeedSensor.h * update example * add missing sdkconfig include * add readme * ci(pre-commit): Apply automatic fixes * Update README.md --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- CMakeLists.txt | 1 + .../Zigbee_Wind_Speed_Sensor/README.md | 60 +++++++++ .../Zigbee_Wind_Speed_Sensor.ino | 119 ++++++++++++++++++ .../examples/Zigbee_Wind_Speed_Sensor/ci.json | 7 ++ libraries/Zigbee/src/Zigbee.h | 1 + .../Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp | 98 +++++++++++++++ .../Zigbee/src/ep/ZigbeeWindSpeedSensor.h | 56 +++++++++ 7 files changed, 342 insertions(+) create mode 100644 libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/README.md create mode 100644 libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/Zigbee_Wind_Speed_Sensor.ino create mode 100644 libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/ci.json create mode 100644 libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp create mode 100644 libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 32d17e5f68d..d2a9162a9ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -298,6 +298,7 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS libraries/Zigbee/src/ep/ZigbeeAnalog.cpp libraries/Zigbee/src/ep/ZigbeeRangeExtender.cpp libraries/Zigbee/src/ep/ZigbeeGateway.cpp + libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp ) set(ARDUINO_LIBRARY_BLE_SRCS diff --git a/libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/README.md b/libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/README.md new file mode 100644 index 00000000000..826c7666e6b --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/README.md @@ -0,0 +1,60 @@ +# Zigbee Wind Speed Sensor Integration with HomeAssistant ZHA + +This guide provides a workaround for integrating a Zigbee Wind Speed Sensor with HomeAssistant using the ZHA integration. Since the wind speed cluster is not natively supported, we will use the ZHA Toolkit from HACS to read the wind speed attribute and store it in a helper variable. +## Alternative Option: Creating a Custom Quirk + +For advanced users, a more robust solution is to create a custom quirk for your Zigbee Wind Speed Sensor. This approach involves writing a custom device handler that directly supports the wind speed cluster, providing a more seamless integration with HomeAssistant. + +Creating a custom quirk can be complex and requires familiarity with Python and the Zigbee protocol. However, it offers greater flexibility and control over your device's behavior. + +For more information and guidance on creating custom quirks, visit the [ZHA Device Handlers repository](https://github.com/zigpy/zha-device-handlers/). + +## Prerequisites + +- HomeAssistant installed and running +- Zigbee Wind Speed Sensor paired with HomeAssistant ZHA +- HACS (Home Assistant Community Store) installed. For more information, visit [HACS](https://hacs.xyz) + +## Steps + +### 1. Install ZHA Toolkit + +1. Open HomeAssistant. +2. Navigate to HACS > Integrations. +3. Search for "ZHA Toolkit - Service for advanced Zigbee Usage" and install it. For more information, visit the [ZHA Toolkit repository](https://github.com/mdeweerd/zha-toolkit). +4. Restart HomeAssistant to apply changes. + +### 2. Create a Helper Variable + +1. Go to Configuration -> Devices & Services -> Helpers. +2. Click on "Add Helper" and select "Number". +3. Name the helper (e.g., `wind_speed`), set the minimum and maximum values, and save it. + +### 3. Create an Automation + +1. Go to Configuration > Automations & Scenes. +2. Click on "Add Automation" and choose "Start with an empty automation". +3. Set a name for the automation (e.g., `Read Wind Speed`). +4. Add a trigger: + - Trigger Type: Time Pattern + - Every: 30 seconds +5. Add an action (Then do): + - Action Type: ZHA Toolkit: Read Attribute + - Setup the action: + ```yaml + action: zha_toolkit.attr_read + metadata: {} + data: + ieee: f0:f5:bd:ff:fe:0e:61:30 #set device IEEE address + endpoint: 10 #set windspeed device endpoint + cluster: 1035 #use this windspeed cluster + attribute: 0 #read measurement value + state_id: input_number.wind_speed #save to created helper variable + state_value_template: value/100 #use correct value format (convert u16 to float) + ``` +6. Save the automation. + +## Conclusion + +By following these steps, you can successfully integrate your Zigbee Wind Speed Sensor with HomeAssistant using the ZHA integration and ZHA Toolkit. The wind speed readings will be updated every 30 seconds and stored in the helper variable for use in your HomeAssistant setup. +The helper variable `wind_speed` is now an entity in HomeAssistant. You can use this entity to display the wind speed on your dashboard or in other automations. diff --git a/libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/Zigbee_Wind_Speed_Sensor.ino b/libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/Zigbee_Wind_Speed_Sensor.ino new file mode 100644 index 00000000000..1c24df9a091 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/Zigbee_Wind_Speed_Sensor.ino @@ -0,0 +1,119 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +/** + * @brief This example demonstrates Zigbee windspeed sensor. + * + * The example demonstrates how to use Zigbee library to create a end device wind speed sensor. + * The wind speed sensor is a Zigbee end device, which is controlled by a Zigbee coordinator. + * + * Proper Zigbee mode must be selected in Tools->Zigbee mode + * and also the correct partition scheme must be selected in Tools->Partition Scheme. + * + * Please check the README.md for instructions and more detailed description. + * + * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) + */ + +#ifndef ZIGBEE_MODE_ED +#error "Zigbee coordinator mode is not selected in Tools->Zigbee mode" +#endif + +#include "Zigbee.h" + +#define BUTTON_PIN 9 //Boot button for C6/H2 +#define WIND_SPEED_SENSOR_ENDPOINT_NUMBER 10 + +ZigbeeWindSpeedSensor zbWindSpeedSensor = ZigbeeWindSpeedSensor(WIND_SPEED_SENSOR_ENDPOINT_NUMBER); + +/************************ WindSpeed sensor *****************************/ +static void windspeed_sensor_value_update(void *arg) { + for (;;) { + // Read wind speed sensor value (simulated now by temperature sensor) + float windspeed = temperatureRead(); + log_v("Wind speed sensor value: %.2fm/s", windspeed); + // Update windspeed value in Windspeed sensor EP + zbWindSpeedSensor.setWindSpeed(windspeed); + delay(1000); + } +} + +/********************* Arduino functions **************************/ +void setup() { + Serial.begin(115200); + while (!Serial) { + delay(10); + } + + // Init button switch + pinMode(BUTTON_PIN, INPUT); + + // Optional: set Zigbee device name and model + zbWindSpeedSensor.setManufacturerAndModel("Espressif", "ZigbeeWindSpeedSensor"); + + // Set minimum and maximum windspeed measurement value in m/s + zbWindSpeedSensor.setMinMaxValue(0, 50); + + // Set tolerance for windspeed measurement in m/s (lowest possible value is 0.01 m/s) + zbWindSpeedSensor.setTolerance(1); + + // Add endpoint to Zigbee Core + Zigbee.addEndpoint(&zbWindSpeedSensor); + + Serial.println("Starting Zigbee..."); + // When all EPs are registered, start Zigbee in End Device mode + if (!Zigbee.begin()) { + Serial.println("Zigbee failed to start!"); + Serial.println("Rebooting..."); + ESP.restart(); + } else { + Serial.println("Zigbee started successfully!"); + } + Serial.println("Connecting to network"); + while (!Zigbee.connected()) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // Start Wind speed sensor reading task + xTaskCreate(windspeed_sensor_value_update, "wind_speed_sensor_update", 2048, NULL, 10, NULL); + + // Set reporting interval for windspeed measurement in seconds, must be called after Zigbee.begin() + // min_interval and max_interval in seconds, delta (WindSpeed change in m/s) + // if min = 1 and max = 0, reporting is sent only when windspeed changes by delta + // if min = 0 and max = 10, reporting is sent every 10 seconds or windspeed changes by delta + // if min = 0, max = 10 and delta = 0, reporting is sent every 10 seconds regardless of windspeed change + zbWindSpeedSensor.setReporting(1, 0, 1); +} + +void loop() { + // Checking button for factory reset + if (digitalRead(BUTTON_PIN) == LOW) { // Push button pressed + // Key debounce handling + delay(100); + int startTime = millis(); + while (digitalRead(BUTTON_PIN) == LOW) { + delay(50); + if ((millis() - startTime) > 3000) { + // If key pressed for more than 3secs, factory reset Zigbee and reboot + Serial.println("Resetting Zigbee to factory and rebooting in 1s."); + delay(1000); + Zigbee.factoryReset(); + } + } + zbWindSpeedSensor.reportWindSpeed(); + } + delay(100); +} diff --git a/libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/ci.json b/libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/ci.json new file mode 100644 index 00000000000..ceacc367801 --- /dev/null +++ b/libraries/Zigbee/examples/Zigbee_Wind_Speed_Sensor/ci.json @@ -0,0 +1,7 @@ +{ + "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", + "requires": [ + "CONFIG_SOC_IEEE802154_SUPPORTED=y", + "CONFIG_ZB_ENABLED=y" + ] +} diff --git a/libraries/Zigbee/src/Zigbee.h b/libraries/Zigbee/src/Zigbee.h index 9ccf1e7d8f2..e5f669ba899 100644 --- a/libraries/Zigbee/src/Zigbee.h +++ b/libraries/Zigbee/src/Zigbee.h @@ -25,3 +25,4 @@ #include "ep/ZigbeeVibrationSensor.h" #include "ep/ZigbeeRangeExtender.h" #include "ep/ZigbeeGateway.h" +#include "ep/ZigbeeWindSpeedSensor.h" diff --git a/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp b/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp new file mode 100644 index 00000000000..d93b02adbc3 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.cpp @@ -0,0 +1,98 @@ +#include "ZigbeeWindSpeedSensor.h" +#if CONFIG_ZB_ENABLED + +esp_zb_cluster_list_t *zigbee_wind_speed_sensor_clusters_create(zigbee_wind_speed_sensor_cfg_t *wind_speed_sensor) { + esp_zb_basic_cluster_cfg_t *basic_cfg = wind_speed_sensor ? &(wind_speed_sensor->basic_cfg) : NULL; + esp_zb_identify_cluster_cfg_t *identify_cfg = wind_speed_sensor ? &(wind_speed_sensor->identify_cfg) : NULL; + esp_zb_wind_speed_measurement_cluster_cfg_t *wind_speed_cfg = wind_speed_sensor ? &(wind_speed_sensor->wind_speed_meas_cfg) : NULL; + esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create(); + esp_zb_cluster_list_add_basic_cluster(cluster_list, esp_zb_basic_cluster_create(basic_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_identify_cluster(cluster_list, esp_zb_identify_cluster_create(identify_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_cluster_list_add_wind_speed_measurement_cluster( + cluster_list, esp_zb_wind_speed_measurement_cluster_create(wind_speed_cfg), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE + ); + return cluster_list; +} + +// There is no device_id for wind speed sensor, we use a generic one +ZigbeeWindSpeedSensor::ZigbeeWindSpeedSensor(uint8_t endpoint) : ZigbeeEP(endpoint) { + _device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID; + + zigbee_wind_speed_sensor_cfg_t windspeed_sensor_cfg = ZIGBEE_DEFAULT_WIND_SPEED_SENSOR_CONFIG(); + _cluster_list = zigbee_wind_speed_sensor_clusters_create(&windspeed_sensor_cfg); + + _ep_config = {.endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID, .app_device_version = 0}; +} + +static uint16_t zb_windspeed_to_u16(float windspeed) { + return (uint16_t)(windspeed * 100); +} + +void ZigbeeWindSpeedSensor::setMinMaxValue(float min, float max) { + uint16_t zb_min = zb_windspeed_to_u16(min); + uint16_t zb_max = zb_windspeed_to_u16(max); + esp_zb_attribute_list_t *windspeed_measure_cluster = + esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WIND_SPEED_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + // + esp_zb_cluster_update_attr(windspeed_measure_cluster, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MIN_MEASURED_VALUE_ID, (void *)&zb_min); + esp_zb_cluster_update_attr(windspeed_measure_cluster, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MAX_MEASURED_VALUE_ID, (void *)&zb_max); +} + +void ZigbeeWindSpeedSensor::setTolerance(float tolerance) { + // Convert tolerance to ZCL uint16_t + uint16_t zb_tolerance = zb_windspeed_to_u16(tolerance); + esp_zb_attribute_list_t *windspeed_measure_cluster = + esp_zb_cluster_list_get_cluster(_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_WIND_SPEED_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE); + esp_zb_wind_speed_measurement_cluster_add_attr(windspeed_measure_cluster, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_TOLERANCE_ID, (void *)&zb_tolerance); +} + +void ZigbeeWindSpeedSensor::setReporting(uint16_t min_interval, uint16_t max_interval, float delta) { + esp_zb_zcl_reporting_info_t reporting_info; + memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t)); + reporting_info.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV; + reporting_info.ep = _endpoint; + reporting_info.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_WIND_SPEED_MEASUREMENT; + reporting_info.cluster_role = ESP_ZB_ZCL_CLUSTER_SERVER_ROLE; + reporting_info.attr_id = ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MEASURED_VALUE_ID; + reporting_info.u.send_info.min_interval = min_interval; + reporting_info.u.send_info.max_interval = max_interval; + reporting_info.u.send_info.def_min_interval = min_interval; + reporting_info.u.send_info.def_max_interval = max_interval; + reporting_info.u.send_info.delta.u16 = (uint16_t)(delta * 100); // Convert delta to ZCL uint16_t + reporting_info.dst.profile_id = ESP_ZB_AF_HA_PROFILE_ID; + reporting_info.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_update_reporting_info(&reporting_info); + esp_zb_lock_release(); +} + +void ZigbeeWindSpeedSensor::setWindSpeed(float windspeed) { + uint16_t zb_windspeed = zb_windspeed_to_u16(windspeed); + log_v("Updating windspeed sensor value..."); + /* Update windspeed sensor measured value */ + log_d("Setting windspeed to %d", zb_windspeed); + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_set_attribute_val( + _endpoint, ESP_ZB_ZCL_CLUSTER_ID_WIND_SPEED_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MEASURED_VALUE_ID, + &zb_windspeed, false + ); + esp_zb_lock_release(); +} + +void ZigbeeWindSpeedSensor::reportWindSpeed() { + /* Send report attributes command */ + esp_zb_zcl_report_attr_cmd_t report_attr_cmd; + report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + report_attr_cmd.attributeID = ESP_ZB_ZCL_ATTR_WIND_SPEED_MEASUREMENT_MEASURED_VALUE_ID; + report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI; + report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_WIND_SPEED_MEASUREMENT; + report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint; + report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC; + + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd); + esp_zb_lock_release(); + log_v("Wind speed measurement report sent"); +} + +#endif //CONFIG_ZB_ENABLED diff --git a/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.h b/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.h new file mode 100644 index 00000000000..e091d3ae548 --- /dev/null +++ b/libraries/Zigbee/src/ep/ZigbeeWindSpeedSensor.h @@ -0,0 +1,56 @@ +/* Class of Zigbee WindSpeed sensor endpoint inherited from common EP class */ + +#pragma once + +#include "soc/soc_caps.h" +#include "sdkconfig.h" +#if CONFIG_ZB_ENABLED + +#include "ZigbeeEP.h" +#include "ha/esp_zigbee_ha_standard.h" + +#define ZIGBEE_DEFAULT_WIND_SPEED_SENSOR_CONFIG() \ + { \ + .basic_cfg = \ + { \ + .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE, \ + .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE, \ + }, \ + .identify_cfg = \ + { \ + .identify_time = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE, \ + }, \ + .wind_speed_meas_cfg = { \ + .measured_value = ESP_ZB_ZCL_WIND_SPEED_MEASUREMENT_MEASURED_VALUE_DEFAULT, \ + .min_measured_value = ESP_ZB_ZCL_WIND_SPEED_MEASUREMENT_MIN_MEASURED_VALUE_DEFAULT, \ + .max_measured_value = ESP_ZB_ZCL_WIND_SPEED_MEASUREMENT_MAX_MEASURED_VALUE_DEFAULT, \ + }, \ + } + +typedef struct zigbee_wind_speed_sensor_cfg_s { + esp_zb_basic_cluster_cfg_t basic_cfg; /*!< Basic cluster configuration, @ref esp_zb_basic_cluster_cfg_s */ + esp_zb_identify_cluster_cfg_t identify_cfg; /*!< Identify cluster configuration, @ref esp_zb_identify_cluster_cfg_s */ + esp_zb_wind_speed_measurement_cluster_cfg_t + wind_speed_meas_cfg; /*!< Wind speed measurement cluster configuration, @ref esp_zb_wind_speed_measurement_cluster_cfg_s */ +} zigbee_wind_speed_sensor_cfg_t; + +class ZigbeeWindSpeedSensor : public ZigbeeEP { +public: + ZigbeeWindSpeedSensor(uint8_t endpoint); + ~ZigbeeWindSpeedSensor() {} + + // Set the WindSpeed value in 0,01 m/s + void setWindSpeed(float value); + + // Set the min and max value for the WindSpeed sensor + void setMinMaxValue(float min, float max); + + // Set the tolerance value for the WindSpeed sensor + void setTolerance(float tolerance); + + // Set the reporting interval for WindSpeed measurement in seconds and delta + void setReporting(uint16_t min_interval, uint16_t max_interval, float delta); + void reportWindSpeed(); +}; + +#endif //CONFIG_ZB_ENABLED From c2b0482511911fd6b57b160f7cdf5cc1187ddaab Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Thu, 13 Mar 2025 06:44:23 -0300 Subject: [PATCH 75/79] ci(hw): Fix files being overwritten (#11019) Co-authored-by: Sugar Glider Co-authored-by: Me No Dev --- .github/scripts/sketch_utils.sh | 4 ++-- .github/scripts/tests_run.sh | 10 +++++----- .github/workflows/tests_build.yml | 24 ++++++++++++------------ .github/workflows/tests_hw.yml | 16 +++++++++++++--- .github/workflows/tests_qemu.yml | 2 +- .github/workflows/tests_wokwi.yml | 2 +- docs/en/contributing.rst | 4 ++-- 7 files changed, 36 insertions(+), 26 deletions(-) diff --git a/.github/scripts/sketch_utils.sh b/.github/scripts/sketch_utils.sh index 00d7d1bc232..e536da50111 100755 --- a/.github/scripts/sketch_utils.sh +++ b/.github/scripts/sketch_utils.sh @@ -244,7 +244,7 @@ function build_sketch { # build_sketch [ext build_dir="$ARDUINO_BUILD_DIR" elif [ "$len" -eq 1 ]; then # build_dir="$sketchdir/build" - build_dir="$HOME/.arduino/tests/$sketchname/build.tmp" + build_dir="$HOME/.arduino/tests/$target/$sketchname/build.tmp" fi output_file="$HOME/.arduino/cli_compile_output.txt" @@ -254,7 +254,7 @@ function build_sketch { # build_sketch [ext for i in $(seq 0 $((len - 1))); do if [ "$len" -ne 1 ]; then # build_dir="$sketchdir/build$i" - build_dir="$HOME/.arduino/tests/$sketchname/build$i.tmp" + build_dir="$HOME/.arduino/tests/$target/$sketchname/build$i.tmp" fi rm -rf "$build_dir" mkdir -p "$build_dir" diff --git a/.github/scripts/tests_run.sh b/.github/scripts/tests_run.sh index 274666c8a44..1c4bee79742 100755 --- a/.github/scripts/tests_run.sh +++ b/.github/scripts/tests_run.sh @@ -27,9 +27,9 @@ function run_test { fi if [ "$len" -eq 1 ]; then - sdkconfig_path="$HOME/.arduino/tests/$sketchname/build.tmp/sdkconfig" + sdkconfig_path="$HOME/.arduino/tests/$target/$sketchname/build.tmp/sdkconfig" else - sdkconfig_path="$HOME/.arduino/tests/$sketchname/build0.tmp/sdkconfig" + sdkconfig_path="$HOME/.arduino/tests/$target/$sketchname/build0.tmp/sdkconfig" fi if [ -f "$sketchdir"/ci.json ]; then @@ -45,7 +45,7 @@ function run_test { fi if [ ! -f "$sdkconfig_path" ]; then - printf "\033[93mSketch %s not built\nMight be due to missing target requirements or build failure\033[0m\n" "$sketchname" + printf "\033[93mSketch %s build not found in %s\nMight be due to missing target requirements or build failure\033[0m\n" "$(dirname "$sdkconfig_path")" "$sketchname" printf "\n\n\n" return 0 fi @@ -60,7 +60,7 @@ function run_test { if [ "$len" -eq 1 ]; then # build_dir="$sketchdir/build" - build_dir="$HOME/.arduino/tests/$sketchname/build.tmp" + build_dir="$HOME/.arduino/tests/$target/$sketchname/build.tmp" report_file="$sketchdir/$target/$sketchname.xml" fi @@ -83,7 +83,7 @@ function run_test { if [ "$len" -ne 1 ]; then # build_dir="$sketchdir/build$i" - build_dir="$HOME/.arduino/tests/$sketchname/build$i.tmp" + build_dir="$HOME/.arduino/tests/$target/$sketchname/build$i.tmp" report_file="$sketchdir/$target/$sketchname$i.xml" fi diff --git a/.github/workflows/tests_build.yml b/.github/workflows/tests_build.yml index 7a5a2959657..7a10c95ed22 100644 --- a/.github/workflows/tests_build.yml +++ b/.github/workflows/tests_build.yml @@ -26,10 +26,10 @@ jobs: with: key: tests-${{ env.id }}-bin path: | - ~/.arduino/tests/**/build*.tmp/*.bin - ~/.arduino/tests/**/build*.tmp/*.elf - ~/.arduino/tests/**/build*.tmp/*.json - ~/.arduino/tests/**/build*.tmp/sdkconfig + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.bin + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.elf + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.json + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/sdkconfig - name: Evaluate if tests should be built id: check-build @@ -73,10 +73,10 @@ jobs: with: key: tests-${{ env.id }}-bin path: | - ~/.arduino/tests/**/build*.tmp/*.bin - ~/.arduino/tests/**/build*.tmp/*.elf - ~/.arduino/tests/**/build*.tmp/*.json - ~/.arduino/tests/**/build*.tmp/sdkconfig + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.bin + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.elf + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.json + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/sdkconfig - name: Upload ${{ inputs.chip }} ${{ inputs.type }} binaries as artifacts uses: actions/upload-artifact@v4 @@ -84,7 +84,7 @@ jobs: name: tests-bin-${{ inputs.chip }}-${{ inputs.type }} overwrite: true path: | - ~/.arduino/tests/**/build*.tmp/*.bin - ~/.arduino/tests/**/build*.tmp/*.elf - ~/.arduino/tests/**/build*.tmp/*.json - ~/.arduino/tests/**/build*.tmp/sdkconfig + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.bin + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.elf + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/*.json + ~/.arduino/tests/${{ inputs.chip }}/**/build*.tmp/sdkconfig diff --git a/.github/workflows/tests_hw.yml b/.github/workflows/tests_hw.yml index 76480ed7c0e..6c15ba79a7f 100644 --- a/.github/workflows/tests_hw.yml +++ b/.github/workflows/tests_hw.yml @@ -22,13 +22,18 @@ defaults: jobs: hardware-test: name: Hardware ${{ inputs.chip }} ${{ inputs.type }} tests - runs-on: [arduino, "${{ inputs.chip }}"] + runs-on: ["arduino", "${{ inputs.chip }}"] env: id: ${{ github.event.pull_request.number || github.ref }}-${{ github.event.pull_request.head.sha || github.sha }}-${{ inputs.chip }}-${{ inputs.type }} container: image: python:3.10.1-bullseye - options: --privileged + options: --privileged --device-cgroup-rule="c 188:* rmw" --device-cgroup-rule="c 166:* rmw" steps: + - name: Clean workspace + run: | + rm -rf ./* + rm -rf ~/.arduino/tests + - name: Check if already passed id: cache-results if: github.event.pull_request.number != null @@ -81,7 +86,12 @@ jobs: with: name: tests-bin-${{ inputs.chip }}-${{ inputs.type }} path: | - ~/.arduino/tests + ~/.arduino/tests/${{ inputs.chip }} + + - name: List binaries + if: ${{ steps.check-tests.outputs.enabled == 'true' }} + run: | + ls -laR ~/.arduino/tests - name: Run Tests if: ${{ steps.check-tests.outputs.enabled == 'true' }} diff --git a/.github/workflows/tests_qemu.yml b/.github/workflows/tests_qemu.yml index 6675909c9df..6c5934ce69a 100644 --- a/.github/workflows/tests_qemu.yml +++ b/.github/workflows/tests_qemu.yml @@ -117,7 +117,7 @@ jobs: with: name: tests-bin-${{ inputs.chip }}-${{ inputs.type }} path: | - ~/.arduino/tests + ~/.arduino/tests/${{ inputs.chip }} - name: Run Tests if: ${{ steps.check-tests.outputs.enabled == 'true' }} diff --git a/.github/workflows/tests_wokwi.yml b/.github/workflows/tests_wokwi.yml index c254d5fa153..4e5d3ceca51 100644 --- a/.github/workflows/tests_wokwi.yml +++ b/.github/workflows/tests_wokwi.yml @@ -276,7 +276,7 @@ jobs: run-id: ${{ github.event.workflow_run.id }} name: tests-bin-${{ matrix.chip }}-${{ matrix.type }} path: | - ~/.arduino/tests + ~/.arduino/tests/${{ matrix.chip }} - name: Run Tests if: ${{ steps.check-tests.outputs.enabled == 'true' }} diff --git a/docs/en/contributing.rst b/docs/en/contributing.rst index fb7843f1fb6..4093c60ec64 100644 --- a/docs/en/contributing.rst +++ b/docs/en/contributing.rst @@ -318,7 +318,7 @@ ESP32-C3 target, you would run: ./.github/scripts/tests_build.sh -s uart -t esp32c3 -You should see the output of the build process and the test binary should be generated in the ``~/.arduino/tests//build.tmp`` folder. +You should see the output of the build process and the test binary should be generated in the ``~/.arduino/tests///build.tmp`` folder. Now that the test is built, you can run it in the target board. Connect the target board to your computer and run: @@ -339,7 +339,7 @@ The test will run on the target board and you should see the output of the test lucassvaz@Lucas--MacBook-Pro esp32 % ./.github/scripts/tests_run.sh -s uart -t esp32c3 Sketch uart test type: validation Running test: uart -- Config: Default - pytest tests --build-dir /Users/lucassvaz/.arduino/tests/uart/build.tmp -k test_uart --junit-xml=/Users/lucassvaz/Espressif/Arduino/hardware/espressif/esp32/tests/validation/uart/esp32c3/uart.xml --embedded-services esp,arduino + pytest tests --build-dir /Users/lucassvaz/.arduino/tests/esp32c3/uart/build.tmp -k test_uart --junit-xml=/Users/lucassvaz/Espressif/Arduino/hardware/espressif/esp32/tests/validation/uart/esp32c3/uart.xml --embedded-services esp,arduino =============================================================================================== test session starts ================================================================================================ platform darwin -- Python 3.12.3, pytest-8.2.2, pluggy-1.5.0 rootdir: /Users/lucassvaz/Espressif/Arduino/hardware/espressif/esp32/tests From 2a3de9c41533c0559e7c16ea34f4315e5fc2205d Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Thu, 13 Mar 2025 07:02:43 -0300 Subject: [PATCH 76/79] test(i2c): Do not use delta as Wokwi timing can be inconsistent (#11080) * test(i2c): Do not use delta as Wokwi timing can be inconsistent * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- tests/validation/i2c_master/i2c_master.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/validation/i2c_master/i2c_master.ino b/tests/validation/i2c_master/i2c_master.ino index 9b4cc508a35..41e7d2ae5f9 100644 --- a/tests/validation/i2c_master/i2c_master.ino +++ b/tests/validation/i2c_master/i2c_master.ino @@ -162,7 +162,7 @@ void rtc_run_clock() { ds1307_get_time(&read_sec, &read_min, &read_hour, &read_day, &read_month, &read_year); //Check time - TEST_ASSERT_UINT8_WITHIN(2, start_sec + 5, read_sec); + TEST_ASSERT_NOT_EQUAL(start_sec, read_sec); //Seconds should have changed TEST_ASSERT_EQUAL(start_min, read_min); TEST_ASSERT_EQUAL(start_hour, read_hour); TEST_ASSERT_EQUAL(start_day, read_day); From e61d9a8b4ad91e8b5c8484c00741d9ef2e14d2d1 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Sat, 15 Mar 2025 18:26:27 -0300 Subject: [PATCH 77/79] ci(actions): Replace changed-files --- .github/scripts/set_push_chunks.sh | 78 ++++++++++++++++++++++++++-- .github/workflows/build_py_tools.yml | 18 +++---- .github/workflows/pre-commit.yml | 14 ++++- .github/workflows/push.yml | 54 ++----------------- 4 files changed, 102 insertions(+), 62 deletions(-) diff --git a/.github/scripts/set_push_chunks.sh b/.github/scripts/set_push_chunks.sh index ff0af7da6e8..32c11976309 100644 --- a/.github/scripts/set_push_chunks.sh +++ b/.github/scripts/set_push_chunks.sh @@ -2,6 +2,78 @@ build_all=false chunks_count=0 +last_check_files="" + +# Define the file patterns +core_files=( + '\.github/.*' + 'cores/.*' + 'package/.*' + 'tools/.*' + 'platform\.txt' + 'programmers\.txt' + 'variants/esp32/.*' + 'variants/esp32c3/.*' + 'variants/esp32c6/.*' + 'variants/esp32h2/.*' + 'variants/esp32p4/.*' + 'variants/esp32s2/.*' + 'variants/esp32s3/.*' +) +library_files=( + 'libraries/.*/examples/.*' + 'libraries/.*/src/.*' +) +networking_files=( + 'libraries/Network/src/.*' +) +fs_files=( + 'libraries/FS/src/.*' +) +static_sketches_files=( + 'libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure\.ino' + 'libraries/BLE/examples/Server/Server\.ino' + 'libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer\.ino' + 'libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics\.ino' + 'libraries/NetworkClientSecure/src/.*' + 'libraries/BLE/src/.*' + 'libraries/Insights/src/.*' +) +idf_files=( + 'idf_component\.yml' + 'Kconfig\.projbuild' + 'CMakeLists\.txt' + 'variants/esp32c2/.*' +) + +# Function to check if any files match the patterns +check_files() { + local patterns=("$@") + local files_found="" + for pattern in "${patterns[@]}"; do + if [[ $IS_PR != 'true' ]]; then + files_found+="$(gh api repos/espressif/arduino-esp32/commits/"$GITHUB_SHA" --jq '.files[].filename' | grep -E "$pattern") " + else + files_found+="$(gh pr diff "$PR_NUM" --name-only | grep -E "$pattern") " + fi + done + + last_check_files=$(echo "$files_found" | xargs) + if [[ -n $last_check_files ]]; then + echo 'true' + else + echo 'false' + fi +} + +# Output the results +CORE_CHANGED=$(check_files "${core_files[@]}") +LIB_CHANGED=$(check_files "${library_files[@]}") +LIB_FILES=$last_check_files +NETWORKING_CHANGED=$(check_files "${networking_files[@]}") +FS_CHANGED=$(check_files "${fs_files[@]}") +STATIC_SKETCHES_CHANGED=$(check_files "${static_sketches_files[@]}") +IDF_CHANGED=$(check_files "${idf_files[@]}") if [[ $CORE_CHANGED == 'true' ]] || [[ $IS_PR != 'true' ]]; then echo "Core files changed or not a PR. Building all." @@ -76,9 +148,9 @@ chunks+="]" { echo "build_all=$build_all" - echo "build_libraries=$BUILD_LIBRARIES" - echo "build_static_sketches=$BUILD_STATIC_SKETCHES" - echo "build_idf=$BUILD_IDF" + echo "build_libraries=$LIB_CHANGED" + echo "build_static_sketches=$STATIC_SKETCHES_CHANGED" + echo "build_idf=$IDF_CHANGED" echo "chunk_count=$chunks_count" echo "chunks=$chunks" } >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/build_py_tools.yml b/.github/workflows/build_py_tools.yml index d4dfca9c8d1..f64ab658c0c 100644 --- a/.github/workflows/build_py_tools.yml +++ b/.github/workflows/build_py_tools.yml @@ -30,16 +30,16 @@ jobs: echo "Make sure you are using a branch inside the repository and not a fork." - name: Verify Python Tools Changed - uses: tj-actions/changed-files@v41 id: verify-changed-files - with: - fetch_depth: "2" - since_last_remote_commit: "true" - files: | - tools/get.py - tools/espota.py - tools/gen_esp32part.py - tools/gen_insights_package.py + run: | + CHANGED_FILES=$(git log -1 --name-only --pretty=format: -- tools/get.py tools/espota.py tools/gen_esp32part.py tools/gen_insights_package.py) + echo "all_changed_files=$CHANGED_FILES" >> $GITHUB_OUTPUT + if [ -n "$CHANGED_FILES" ]; then + echo "any_changed=true" >> $GITHUB_OUTPUT + else + echo "any_changed=false" >> $GITHUB_OUTPUT + fi + - name: List all changed files shell: bash run: | diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index dc009e445da..0a45adfc728 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -58,7 +58,19 @@ jobs: - name: Get changed files id: changed-files - uses: tj-actions/changed-files@v42.0.2 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUM: ${{ github.event.pull_request.number }} + IS_PR: ${{ github.event_name == 'pull_request' }} + GITHUB_SHA: ${{ github.sha }} + run: | + if [[ $IS_PR != 'true' ]]; then + files_changed=$(gh api repos/espressif/arduino-esp32/commits/"$GITHUB_SHA" --jq '.files[].filename') + else + files_changed=$(gh pr diff "$PR_NUM" --name-only) + fi + echo "all_changed_files=$files_changed" >> $GITHUB_OUTPUT + echo "Changed files: $files_changed" - name: Run pre-commit hooks in changed files run: pre-commit run --color=always --show-diff-on-failure --files ${{ steps.changed-files.outputs.all_changed_files }} diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 211ed1658f9..feb32f95d03 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -45,12 +45,13 @@ on: - "!.github/scripts/tests_*" - "!.github/scripts/upload_*" - "variants/esp32/**/*" - - "variants/esp32s2/**/*" - - "variants/esp32s3/**/*" - "variants/esp32c2/**/*" - "variants/esp32c3/**/*" - "variants/esp32c6/**/*" - "variants/esp32h2/**/*" + - "variants/esp32p4/**/*" + - "variants/esp32s2/**/*" + - "variants/esp32s3/**/*" concurrency: group: build-${{github.event.pull_request.number || github.ref}} @@ -85,58 +86,13 @@ jobs: with: fetch-depth: 2 - - name: Get changed files - id: changed-files - uses: tj-actions/changed-files@v44 - with: - files_yaml: | - core: - - '.github/**' - - 'cores/**' - - 'package/**' - - 'tools/**' - - 'platform.txt' - - 'programmers.txt' - - "variants/esp32/**/*" - - "variants/esp32s2/**/*" - - "variants/esp32s3/**/*" - - "variants/esp32c3/**/*" - - "variants/esp32c6/**/*" - - "variants/esp32h2/**/*" - libraries: - - 'libraries/**/examples/**' - - 'libraries/**/src/**' - networking: - - 'libraries/Network/src/**' - fs: - - 'libraries/FS/src/**' - static_sketeches: - - 'libraries/NetworkClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino' - - 'libraries/BLE/examples/Server/Server.ino' - - 'libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino' - - 'libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino' - - 'libraries/NetworkClientSecure/src/**' - - 'libraries/BLE/src/**' - - 'libraries/Insights/src/**' - idf: - - 'idf_component.yml' - - 'Kconfig.projbuild' - - 'CMakeLists.txt' - - "variants/esp32c2/**/*" - - name: Set chunks id: set-chunks env: - LIB_FILES: ${{ steps.changed-files.outputs.libraries_all_changed_files }} IS_PR: ${{ github.event_name == 'pull_request' }} + PR_NUM: ${{ github.event.pull_request.number }} MAX_CHUNKS: ${{ env.MAX_CHUNKS }} - BUILD_IDF: ${{ steps.changed-files.outputs.idf_any_changed == 'true' }} - BUILD_LIBRARIES: ${{ steps.changed-files.outputs.libraries_any_changed == 'true' }} - BUILD_STATIC_SKETCHES: ${{ steps.changed-files.outputs.static_sketeches_any_changed == 'true' }} - FS_CHANGED: ${{ steps.changed-files.outputs.fs_any_changed == 'true' }} - NETWORKING_CHANGED: ${{ steps.changed-files.outputs.networking_any_changed == 'true' }} - CORE_CHANGED: ${{ steps.changed-files.outputs.core_any_changed == 'true' }} - LIB_CHANGED: ${{ steps.changed-files.outputs.libraries_any_changed == 'true' }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | bash ./.github/scripts/set_push_chunks.sh From 87d89ea51530c4d614ece42eeebf6d90a491ecc4 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Sat, 15 Mar 2025 18:31:39 -0300 Subject: [PATCH 78/79] fix --- .github/workflows/build_py_tools.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_py_tools.yml b/.github/workflows/build_py_tools.yml index f64ab658c0c..3a4dd4e18af 100644 --- a/.github/workflows/build_py_tools.yml +++ b/.github/workflows/build_py_tools.yml @@ -33,7 +33,7 @@ jobs: id: verify-changed-files run: | CHANGED_FILES=$(git log -1 --name-only --pretty=format: -- tools/get.py tools/espota.py tools/gen_esp32part.py tools/gen_insights_package.py) - echo "all_changed_files=$CHANGED_FILES" >> $GITHUB_OUTPUT + echo all_changed_files="$CHANGED_FILES" >> $GITHUB_OUTPUT if [ -n "$CHANGED_FILES" ]; then echo "any_changed=true" >> $GITHUB_OUTPUT else From 3304ae014d86f74884a62f3ebb3e9c1ba423c0c9 Mon Sep 17 00:00:00 2001 From: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Date: Sat, 15 Mar 2025 18:34:04 -0300 Subject: [PATCH 79/79] fix --- .github/workflows/build_py_tools.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_py_tools.yml b/.github/workflows/build_py_tools.yml index 3a4dd4e18af..0e785ad5b16 100644 --- a/.github/workflows/build_py_tools.yml +++ b/.github/workflows/build_py_tools.yml @@ -33,7 +33,8 @@ jobs: id: verify-changed-files run: | CHANGED_FILES=$(git log -1 --name-only --pretty=format: -- tools/get.py tools/espota.py tools/gen_esp32part.py tools/gen_insights_package.py) - echo all_changed_files="$CHANGED_FILES" >> $GITHUB_OUTPUT + CHANGED_FILES=$(echo "$CHANGED_FILES" | tr '\n' ' ') + echo "all_changed_files=$CHANGED_FILES" >> $GITHUB_OUTPUT if [ -n "$CHANGED_FILES" ]; then echo "any_changed=true" >> $GITHUB_OUTPUT else