diff --git a/.gitignore b/.gitignore index 3a575e21aca8..82c56687b3bc 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ .cache data unpacked_fs +unpacked_boards tasmota/user_config_override.h build build_output/* diff --git a/CHANGELOG.md b/CHANGELOG.md index 93bafed739bf..fd144f208eae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,20 +3,35 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [13.0.0.4] +## [13.1.0.1] ### Added -- ESP32 prepare for Arduino Core v3 and esp-idf v5 (#19264) ### Breaking Changed ### Changed -- Console height from default 318 pixels to viewport (#19241) -- Shutter button hold behaviour with grouptopic (#19263) ### Fixed ### Removed + +## [Released] - Development + +## [13.1.0] 20230815 +- Release Quentin + +## [13.0.0.4] 20230815 +### Added +- ESP32 prepare for Arduino Core v3 and esp-idf v5 (#19264) + +### Changed +- Console height from default 318 pixels to viewport (#19241) +- Shutter button hold behaviour with grouptopic (#19263) +- Thermostat improvements (#19279) +- PID controller improvements (#19285) +- HDC1080 detect device offline (#19298) +- ADE7953 lowered no load threshold (#19302) + ## [13.0.0.3] 20230805 ### Added - Support for MAX17043 fuel-gauge systems Lipo batteries (#18788) @@ -89,8 +104,6 @@ All notable changes to this project will be documented in this file. ### Removed - Support for ESP32-C3 with chip rev below 3 (old development boards) -## [Released] - ## [13.0.0] 20230626 - Release Qasim diff --git a/FIRMWARE.md b/FIRMWARE.md index f1fe619d5f51..ab962399c40c 100644 --- a/FIRMWARE.md +++ b/FIRMWARE.md @@ -18,7 +18,7 @@ See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/tasmota/C ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v13.0.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v13.1.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://ota.tasmota.com/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) [![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) diff --git a/README.md b/README.md index 94c86429e91e..14911249a137 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Firmware binaries can be downloaded from http://ota.tasmota.com/tasmota/release/ ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v13.0.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v13.1.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://ota.tasmota.com/tasmota/) [![Tasmota CI](https://github.com/arendst/Tasmota/actions/workflows/build_all_the_things.yml/badge.svg)](https://github.com/arendst/Tasmota/actions/workflows/build_all_the_things.yml) [![Build_development](https://github.com/arendst/Tasmota/actions/workflows/Tasmota_build_devel.yml/badge.svg)](https://github.com/arendst/Tasmota/actions/workflows/Tasmota_build_devel.yml) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 427f29da8751..9fc969ea7f82 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -75,7 +75,7 @@ Latest released binaries can be downloaded from - http://ota.tasmota.com/tasmota/release Historical binaries can be downloaded from -- http://ota.tasmota.com/tasmota/release-13.0.0 +- http://ota.tasmota.com/tasmota/release-13.1.0 The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz`` @@ -100,7 +100,7 @@ Latest released binaries can be downloaded from - https://ota.tasmota.com/tasmota32/release Historical binaries can be downloaded from -- https://ota.tasmota.com/tasmota32/release-13.0.0 +- https://ota.tasmota.com/tasmota32/release-13.1.0 The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin`` @@ -110,62 +110,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v13.0.0.4 +## Changelog v13.1.0.1 ### Added -- Command ``BrRestart`` to restart the Berry VM (experimental) [#19003](https://github.com/arendst/Tasmota/issues/19003) -- Command ``Delay -1`` to wait until next second [#18984](https://github.com/arendst/Tasmota/issues/18984) -- Command ``Restart 9`` to save all changes and go into deepsleep waiting for a reset [#19024](https://github.com/arendst/Tasmota/issues/19024) -- Support for MAX17043 fuel-gauge systems Lipo batteries [#18788](https://github.com/arendst/Tasmota/issues/18788) -- Support for multiple PCA9685 with extended functionality [#18805](https://github.com/arendst/Tasmota/issues/18805) -- Support for SGP41 TVOC/NOx Sensor [#18880](https://github.com/arendst/Tasmota/issues/18880) -- Support for DeepSleep battery level percentage [#19134](https://github.com/arendst/Tasmota/issues/19134) -- Zigbee decode Aqara 0000/FF01 attribute 03 as Temperature [#19210](https://github.com/arendst/Tasmota/issues/19210) -- ESP32 prepare for Arduino Core v3 and esp-idf v5 [#19264](https://github.com/arendst/Tasmota/issues/19264) -- Berry `getgbl` performance counter to `debug.counters()` [#19070](https://github.com/arendst/Tasmota/issues/19070) -- Berry `_class` can be used in `static var` initialization code [#19088](https://github.com/arendst/Tasmota/issues/19088) -- Berry `energy.update_total()` to call `EnergyUpdateTotal()` from energy driver [#19117](https://github.com/arendst/Tasmota/issues/19117) -- Berry `tasmota.loglevel()` and `tasmota.rtc_utc()` for faster performance [#19152](https://github.com/arendst/Tasmota/issues/19152) -- Berry metrics for memory allocation/deallocation/reallocation [#19150](https://github.com/arendst/Tasmota/issues/19150) -- Berry AES CCM decrypting in a single call to avoid any object allocation [#19153](https://github.com/arendst/Tasmota/issues/19153) -- Berry bytes `get` and `set` work for 3 bytes values [#19225](https://github.com/arendst/Tasmota/issues/19225) -- Partition Wizard is now able to convert to safeboot from Shelly partition layout [#19034](https://github.com/arendst/Tasmota/issues/19034) -- Matter option to disable bridge mode [#18992](https://github.com/arendst/Tasmota/issues/18992) -- Matter mini-profiler [#19075](https://github.com/arendst/Tasmota/issues/19075) -- Matter support for fabric_filtered request (for Google compatibility) [#19249](https://github.com/arendst/Tasmota/issues/19249) ### Breaking Changed -- Berry `bool( [] )` and `bool( {} )` now evaluate as `false` [#18986](https://github.com/arendst/Tasmota/issues/18986) -- Berry `import strict` now detects useless expression without side effects [#18997](https://github.com/arendst/Tasmota/issues/18997) ### Changed -- IRremoteESP8266 library from v2.8.5 to v2.8.6 -- ESP32 Framework (Arduino Core) from v2.0.10 to v2.0.11 -- ESP32 LVGL library from v8.3.7 to v8.3.8 (no functional change) -- Initial ``DisplayMode`` from 1 to 0 and ``DisplayDimmmer`` from 10% to 50% [#19138](https://github.com/arendst/Tasmota/issues/19138) -- Configuration backup and restore now supports ``.xdrvsetXXX`` files too [#18295](https://github.com/arendst/Tasmota/issues/18295) -- Reduced log level for TeleInfo [#19216](https://github.com/arendst/Tasmota/issues/19216) -- Console height from default 318 pixels to viewport [#19241](https://github.com/arendst/Tasmota/issues/19241) -- Shutter button hold behaviour with grouptopic [#19263](https://github.com/arendst/Tasmota/issues/19263) -- ESP32 shutter driver support up to 16 shutters [#18295](https://github.com/arendst/Tasmota/issues/18295) -- ESP32 autodetect flashsize and adjust filesystem [#19215](https://github.com/arendst/Tasmota/issues/19215) -- Berry extend `range(lower, upper, incr)` to arbitrary increment [#19120](https://github.com/arendst/Tasmota/issues/19120) -- Berry updated syntax highlighting plugin for VSCode [#19123](https://github.com/arendst/Tasmota/issues/19123) -- Berry `mqtt.publish` now distinguishes between `string` and `bytes` [#19196](https://github.com/arendst/Tasmota/issues/19196) -- Matter support for temperature in Fahrenheit (`SetOption8 1`) [#18987](https://github.com/arendst/Tasmota/issues/18987) -- Matter improve responsiveness [#19002](https://github.com/arendst/Tasmota/issues/19002) -- Matter improve latency for remote commands [#19072](https://github.com/arendst/Tasmota/issues/19072) -- Matter improve latency for single attribute reads and single commands [#19158](https://github.com/arendst/Tasmota/issues/19158) -- Matter increased polling frequency for local switches/occupancy [#19242](https://github.com/arendst/Tasmota/issues/19242) ### Fixed -- Berry Walrus Operator [#18982](https://github.com/arendst/Tasmota/issues/18982) -- MiElHVAC power commands regression from v12.4.0.1 [#18923](https://github.com/arendst/Tasmota/issues/18923) -- Zero cross dimmer minimum interrupt time [#19211](https://github.com/arendst/Tasmota/issues/19211) -- Fade would fail when the difference between start and target would be too small [#19248](https://github.com/arendst/Tasmota/issues/19248) -- Inverted shutter [#19243](https://github.com/arendst/Tasmota/issues/19243) -- ESP8266 SPI initialization for scripter, filesystem and MFRC522 [#19209](https://github.com/arendst/Tasmota/issues/19209) -- Matter support for large atribute responses [#19252](https://github.com/arendst/Tasmota/issues/19252) -- Matter auto-configuration Relay indices [#19255](https://github.com/arendst/Tasmota/issues/19255) ### Removed -- Support for ESP32-C3 with chip revision below 3 (old development boards) diff --git a/TEMPLATES.md b/TEMPLATES.md index 9160d0206182..4cb82b7866a4 100644 --- a/TEMPLATES.md +++ b/TEMPLATES.md @@ -5,7 +5,7 @@ # Templates -Find below the available templates as of June 2023. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) +Find below the available templates as of August 2023. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) ## Adapter Board ``` @@ -226,6 +226,7 @@ MS-108 In-Wall {"NAME":"MS-108","GPIO":[0,0,0,0,161,160,0,0,224,0, MS-108WR RF Curtain Module {"NAME":"MS-108WR","GPIO":[1,1,1,544,32,33,1,1,225,32,224,1,1,1],"FLAG":0,"BASE":18} Nous {"NAME":" Smart WiFi Curtain Module L12T","GPIO":[1,160,1,161,225,224,1,1,544,1,32,1,1,1],"FLAG":0,"BASE":18} QS-WIFI-C01-RF {"NAME":"Shutter-QS-WIFI-C01","GPIO":[0,0,1,0,288,0,0,0,32,33,224,225,0,0],"FLAG":0,"BASE":18} +wesmartify Smart Home Aktor Shut It TASMOTA {"NAME":"ITzy","GPIO":[0,0,0,0,225,224,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} ``` ## Curtain Switch @@ -257,10 +258,11 @@ Zemismart Backlit {"NAME":"WF-CS01","GPIO":[544,227,289,34,226,161,0, ## DIN Relay ``` -CurrySmarter Power Monitoring 30A {"NAME":"30A Breaker","GPIO":[0,0,0,0,7584,224,0,0,2720,32,2656,2624,320,0],"FLAG":0,"BASE":18} +CurrySmarter Power Monitoring 30A {"NAME":"30A Breaker on Led","GPIO":[0,0,0,0,7584,224,0,0,2720,32,2656,2624,320,0],"FLAG":0,"BASE":18} EARU DIN Circuit Breaker 1P 32A/50A {"NAME":"RDCBC-1P","GPIO":[320,0,0,0,0,0,0,0,32,224,0,0,0,0],"FLAG":0,"BASE":18} Hoch Circuit Breaker 1P {"NAME":"HOCH ZJSB9","GPIO":[32,0,0,0,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":18} Ketotek Single Phase Energy Monitor {"NAME":"Ketotek KTEM06","GPIO":[0,2272,0,2304,0,0,0,0,0,0,320,0,32,0],"FLAG":0,"BASE":54} +Martin Jerry 30A Circuit Breaker {"NAME":"30A Breaker","GPIO":[0,0,0,0,7584,224,0,0,2720,32,2656,2624,320,0],"FLAG":0,"BASE":18} OpenEnergyMonitor WiFi MQTT Thermostat {"NAME":"MQTT-RELAY","GPIO":[32,0,1,0,0,224,0,0,0,0,0,0,320,0],"FLAG":0,"BASE":18} RocketController ASTRA Controller {"NAME":"ASTRA R4A4","GPIO":[1,1,1,1,576,1,1,1,480,1,1,1,3232,3200,1,1,0,640,608,1,0,224,225,1152,0,0,0,0,227,226,160,161,162,0,0,163],"FLAG":0,"BASE":1} Shelly Pro 1 {"NAME":"Shelly Pro 1","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"} @@ -295,6 +297,7 @@ Adafruit QT Py ESP32 Pico {"NAME":"QTPy ESP32 Pico","GPIO":[32,3200,0,3232,1, AZ-Envy Environmental Sensor {"NAME":"AZ Envy","GPIO":[32,0,320,0,640,608,0,0,0,0,0,0,0,4704],"FLAG":0,"BASE":18} Coiaca Tasmota {"NAME":"AWR01t","GPIO":[576,1,1,128,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Coiaca Tasmota Development Board AWR12 {"NAME":"AWR12t","GPIO":[320,1,1,1,1,1,0,0,1,1,1,1,1,1],"FLAG":0,"BASE":18} +Dasduino CONNECTPLUS {"NAME":"Dasduino CONNECT","GPIO":[1,1,1376,1,640,608,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":18} Dasduino CONNECTPLUS {"NAME":"Dasduino CONNECTPLUS","GPIO":[32,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,640,608,1,0,1,1,1,0,0,0,0,1376,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} Espoir Rev 1.0.0 PoE+ {"NAME":"Espoir","GPIO":[0,0,1,0,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,5568,5600,1,7968,1,1,1,1],"FLAG":0,"BASE":1} KinCony 128 Channel Controller {"NAME":"KC868-A128","GPIO":[0,1,0,1,609,640,1,1,1,3232,3200,641,608,1,5600,0,0,1,0,5568,0,1,0,0,0,0,0,0,0,0,4705,4707,4706,0,0,4704],"FLAG":0,"BASE":1} @@ -392,7 +395,7 @@ Shelly Vintage 7W 750lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0, Shelly Vintage 7W 750lm 2700k {"NAME":"Shelly Vintage","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} SmartDGM 9W 806lm {"NAME":"L-WB9W1","GPIO":[0,0,0,0,0,416,0,0,160,0,0,0,0,0],"FLAG":0,"BASE":18} Smitch 10W 6500K {"NAME":"Smitch Ambience SB-0110","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Smitch 10W 6500K {"NAME":"Smitch Ambience SB-0110","GPIO":[0,0,0,0,416,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Smitch 10W 6500K {"NAME":"Smitch 10W 6500K Dimmable Bulb (SB0110 - E27)","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":1} TCP Smart 806lm Warm White {"NAME":"TCP Smart Clas","GPIO":[0,0,0,0,0,0,0,0,0,416,0,0,0,0],"FLAG":0,"BASE":1} TCP Smart 810lm Filament {"NAME":"TCP Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,448,0,0,0],"FLAG":0,"BASE":18} TCP Smart 810lm Filament {"NAME":"TCP Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,448,0,0,0],"FLAG":0,"BASE":18} @@ -605,6 +608,7 @@ AI Universal Remote {"NAME":"YTF IR Controller","GPIO":[1,1,1,1,320,108 AI Universal Remote Control {"NAME":"LQ-08","GPIO":[0,0,0,0,0,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} Alfawise KS1 {"NAME":"KS1","GPIO":[1,1792,32,1824,32,1088,0,0,320,0,1056,0,0,4704],"FLAG":0,"BASE":62} Antsig Universal Remote Controller {"NAME":"Antsig Smart Wi-Fi IR","GPIO":[1,1,1,1,320,1088,0,0,0,32,1056,0,0,0],"FLAG":0,"BASE":62} +Athom {"NAME":"Athom_IR_Remote","GPIO":[32,0,0,0,1056,1088,0,0,0,576,0,0,0,0],"FLAG":0,"BASE":18} Automate Things IR Bridge {"NAME":"AT-IRBR-1.0","GPIO":[0,0,0,0,1056,1088,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"Module 0"} Automate Things IR Bridge {"NAME":"AT-IRBR-1.4","GPIO":[1088,0,0,0,1056,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18,"CMND":"Module 0"} auvisio S06 {"NAME":"NX-4519-675","GPIO":[0,0,0,0,288,1088,0,0,0,0,1056,0,0,0],"FLAG":0,"BASE":18} @@ -710,6 +714,7 @@ ZJ-WF-ESP-A v1.1 {"NAME":"RGB2","GPIO":[0,0,0,0,0,0,0,0,417,416,418, ## LED Strip ``` Aldi Casalux RGB {"NAME":"DW-RGB-WI01","GPIO":[1088,0,0,0,416,0,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} +ARLEC 5m Colour Changing "Not available" Arlec Smart 1m CCT LED Strip Light {"NAME":"ALD155HA","GPIO":[0,0,1088,0,0,416,0,0,0,417,0,0,0,0],"FLAG":0,"BASE":18} Arlec Smart 2m LED Colour Changing Strip Light {"NAME":"Arlec_Light_Strip","GPIO":[1,1,1088,1,416,419,1,1,417,420,418,0,1,1],"FLAG":0,"BASE":18} Arlec Smart 5m White & Colour Changing {"NAME":"ALD556HA","GPIO":[0,0,1088,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} @@ -794,7 +799,7 @@ Deta 18W 1900lm T8 Tube {"NAME":"DETA Smart LED","GPIO":[0,0,0,0,0,0,0,0,0, electriQ MOODL Ambiance Lamp {"NAME":"ElectriQ MOODL","GPIO":[0,4640,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Gosund Table Lamp {"NAME":"Gosund LB3","GPIO":[0,0,0,0,0,418,0,0,417,419,0,416,0,0],"FLAG":0,"BASE":18} Hama Wall Light Square, 10 cm, IP 44 {"NAME":"Hama Wifi Wall Light","GPIO":[0,0,0,0,0,416,0,0,0,417,0,0,0,1],"FLAG":0,"BASE":18} -HiFree Table Lamp {"NAME":"TuyaMCU","GPIO":[108,1,107,1,1,1,1,1,1,1,1,1,1,1],"FLAG":0,"BASE":18} +HiFree Table Lamp {"NAME":"TuyaMCU","GPIO":[2304,1184,2272,1184,1184,1184,1184,1184,1184,1184,1184,1184,1184,0],"FLAG":0,"BASE":18} Hugoai Table Lamp {"NAME":"HG02","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,20 | TuyaMCU 26,21 | TuyaMCU 21,22 | TuyaMCU 23,23 | TuyaMCU 24,24 | DimmerRange 34,1000"} Iwoole Table Lamp {"NAME":"GLOBELAMP","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} Lepro Bedroom Lamp {"NAME":"Lepro 902101-US","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,0],"FLAG":0,"BASE":54,"CMND":"TuyaMCU 11,20 | TuyaMCU 26,21 | TuyaMCU 21,22 | TuyaMCU 23,23 | TuyaMCU 24,24 | DimmerRange 34,1000"} @@ -866,6 +871,7 @@ Xystec USB3.0 4 Port Hub {"NAME":"Xystec USB Hub","GPIO":[0,0,0,0,224,0,0,0, DT-Light ESP8285 Lighting {"NAME":"DMP-L1","GPIO":[1,1,0,1,1,1,0,0,1,1,1,1,1,1],"FLAG":0,"BASE":18} ESP-01D {"NAME":"ESP-01D","GPIO":[1,1,0,1,1,0,0,0,1,0,1,0,0,0],"FLAG":0,"BASE":18} ESP-01S {"NAME":"ESP-01","GPIO":[1,1,1,1,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +ESP-02S TYWE2S Replacement {"NAME":"ESP-02S","GPIO":[1,1,1,1,1,1,0,0,1,1,1,0,0,1],"FLAG":0,"BASE":18} ESP-12 {"NAME":"ESP-12","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,1,1],"FLAG":0,"BASE":18} ESP-15F {"NAME":"ESP-15F","GPIO":[1,1,0,1,1,1,0,0,0,544,0,0,0,0],"FLAG":0,"BASE":18} ESP-M2 {"NAME":"ESP-M2","GPIO":[1,1,1,1,1,1,0,0,1,1,1,1,0,1],"FLAG":0,"BASE":18} @@ -877,7 +883,6 @@ M5Stack M5Stamp Pico {"NAME":"M5Stamp Pico","GPIO":[1,1,0,1,0,0,0,0,0,0, MTools 16 Channel ESP32 Relay Driver 5V DC {"NAME":"16ch Board","GPIO":[1,1,237,1,232,1,1,1,228,231,1,1,233,230,234,235,0,238,239,236,0,224,227,226,0,0,0,0,229,225,1,1,1,0,0,1],"FLAG":0,"BASE":1} Shelly Universal Input/Output {"NAME":"Shelly Uni","GPIO":[320,0,0,0,225,1216,0,0,192,193,194,224,0,4864],"FLAG":0,"BASE":18} Sinilink MODBUS Interface {"NAME":"XY-WFPOW","GPIO":[0,8768,544,8800,32,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -TYWE2S Replacement {"NAME":"ESP-02S","GPIO":[1,1,1,1,1,1,0,0,1,1,1,0,0,1],"FLAG":0,"BASE":18} ``` ## Motion Sensor @@ -946,6 +951,7 @@ Ledvance Smart+ 16A {"NAME":"LEDVANCE Smart Wifi Outdoor Plug","GPIO":[ Ledvance Smart+ Compact {"NAME":"LEDVANCE SMART+ Compact Outdoor Plug ","GPIO":[0,0,0,0,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} LSC Dual Socket {"NAME":"LSC NFL-022","GPIO":[0,0,0,0,320,32,0,0,0,224,225,0,0,0],"FLAG":0,"BASE":18} LSC Dual Socket {"NAME":"LSC Outdoor Dual Socket","GPIO":[320,0,0,32,8673,8672,0,0,0,0,8674,0,8675,0],"FLAG":0,"BASE":18} +Luminea 16A {"NAME":"NX-4655-675","GPIO":[0,0,0,0,320,576,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Luminea 2 Outlet {"NAME":"Luminea","GPIO":[0,0,0,0,225,320,0,0,224,321,32,0,0,1],"FLAG":0,"BASE":18} Luminea NX-4458 {"NAME":"Luminea NX4458","GPIO":[32,0,0,0,2688,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":65} Master {"NAME":"Master_IOT-EXTPLUG","GPIO":[32,1,0,1,1,0,0,0,224,288,0,0,0,0],"FLAG":0,"BASE":1} @@ -968,6 +974,7 @@ Signstek EOP03-EU {"NAME":"Signstek EOP03","GPIO":[0,0,0,0,320,321,0, SK03 {"NAME":"SK03 Outdoor","GPIO":[32,0,0,0,2688,2656,0,0,2624,321,320,224,0,0],"FLAG":0,"BASE":57} STITCH {"NAME":"STITCH 35556","GPIO":[1,1,1,1,225,321,0,0,224,320,32,1,1,0],"FLAG":0,"BASE":18} Suraielec 40A Heavy Duty {"NAME":"Suraielec UBTW01B","GPIO":[0,0,0,0,544,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} +Tate Guard ZUM-26EU-X Dual {"NAME":"Tate Guard","GPIO":[0,0,0,0,224,288,0,0,225,288,32,0,0,0],"FLAG":0,"BASE":18} Teckin SS31 {"NAME":"Teckin SS31","GPIO":[1,1,1,1,320,321,1,1,224,32,225,1,1,1],"FLAG":0,"BASE":18} Teckin SS33 {"NAME":"Teckin SS31","GPIO":[0,0,0,226,320,321,0,0,224,32,225,0,0,1],"FLAG":0,"BASE":18} Teckin SS42 {"NAME":"Teckin SS42","GPIO":[0,0,0,0,320,321,0,0,224,32,225,0,0,0],"FLAG":0,"BASE":18} @@ -1069,6 +1076,7 @@ Avatto 10A {"NAME":"Avatto NAS-WR01W 10A 2021-12","GPIO":[0,0, Avatto JH-G01E {"NAME":"AVATTO JH-G01E","GPIO":[0,3072,0,3104,0,0,0,0,32,320,224,0,0,0],"FLAG":0,"BASE":41} Avatto OT06 16A {"NAME":"Avatto OT06","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} Avatto OT08 {"NAME":"Avatto OT08","GPIO":[416,0,418,0,417,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} +Avidsen Home {"NAME":"Avidsen HomePlug","GPIO":[0,0,0,0,224,35,0,0,289,288,0,0,0,0],"FLAG":0,"BASE":18} Awow X5P {"NAME":"Awow","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18} AWP02L-N {"NAME":"AWP02L-N","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224,0,0],"FLAG":0,"BASE":18} AzpenHome Smart {"NAME":"Socket2Me","GPIO":[288,1,1,1,225,1,0,0,224,1,32,1,1,0],"FLAG":0,"BASE":18} @@ -1137,6 +1145,7 @@ Coosa SP1 {"NAME":"COOSA SP1","GPIO":[321,1,320,1,0,2720,0,0, CooWoo {"NAME":"CooWoo AW01","GPIO":[0,0,0,0,288,160,0,0,256,0,0,0,0,0],"FLAG":0,"BASE":18} CozyLife HomeKit 16A {"NAME":"CozyLife 16A","GPIO":[0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,2720,0,0,2656,576,0,224,2624,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1} CrazyLynX WiFi {"NAME":"CrazyLynX","GPIO":[0,0,0,0,321,320,0,0,224,32,0,0,0,4704],"FLAG":0,"BASE":18} +Crest Single Power Adaptor {"NAME":"SHSPM1","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":52} Crest Smart Home Single Power Adaptor with 2 USB {"NAME":"Medion","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":52} CurrySmarter 16A {"NAME":"CurrySmarter 16A","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} CurrySmarter 16A Power Monitoring {"NAME":"Currysmarter XH-TW2P","GPIO":[0,0,0,2624,32,320,0,0,224,2720,2656,0,0,0],"FLAG":0,"BASE":18} @@ -1189,8 +1198,6 @@ Etekcity 15A {"NAME":"ESW15-US","GPIO":[0,0,0,0,0,224,0,0,2656,2 Etekcity 8A {"NAME":"ESW01-USA","GPIO":[0,0,0,0,224,544,0,0,2656,2688,32,2592,288,0],"FLAG":0,"BASE":55} EU3S {"NAME":"AWOW BSD33","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} Eva Logik {"NAME":"EVA LOGIK Plug","GPIO":[1,32,1,1,1,1,0,0,1,288,224,1,1,0],"FLAG":0,"BASE":18} -EZPlug V1 OpenSource {"NAME":"EZPlug V1","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":1} -EZPlug+ V1 {"NAME":"EZPlug+ V1","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":1} Febite {"NAME":"Febite","GPIO":[320,0,0,0,0,2720,0,0,224,32,2656,0,0,0],"FLAG":0,"BASE":1} Feit Electric PLUG/WIFI {"NAME":"Feit Wifi Plug","GPIO":[0,0,0,320,0,0,0,0,224,0,32,0,0,0],"FLAG":0,"BASE":18} FK-PW901U {"NAME":"FK-PW901U","GPIO":[320,1,1,1,1,226,0,0,224,32,227,225,1,0],"FLAG":0,"BASE":18} @@ -1311,6 +1318,7 @@ JuoYou 16A {"NAME":"Juoyou ZY-OYD","GPIO":[0,0,0,32,2720,2656, JVMAC-EU01 {"NAME":"JVMAC","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} Kaforto KW-US-801 {"NAME":"Kaforto US-801","GPIO":[32,576,0,227,2720,2656,0,0,2624,225,224,226,0,0],"FLAG":0,"BASE":18} Kauf esphome {"NAME":"KAUF Plug","GPIO":[576,0,320,0,224,2720,0,0,2624,32,2656,0,0,0],"FLAG":0,"BASE":18} +Kauf esphome {"NAME":"Kauf Plug","GPIO":[0,320,0,32,2720,2656,0,0,321,224,2624,0,0,0],"FLAG":0,"BASE":18} Kimire S12 {"NAME":"Kimire S12","GPIO":[1,1,1,32,1,1,0,0,1,320,224,1,1,0],"FLAG":0,"BASE":18} King-Link KL-US-WF002 {"NAME":"Kinglink-plug","GPIO":[0,0,0,0,0,224,0,0,288,32,0,0,0,0],"FLAG":0,"BASE":18} Kisslink SP200 {"NAME":"Kisslink SP200","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,4704],"FLAG":0,"BASE":18} @@ -1408,8 +1416,8 @@ NGS Loop Track 16A {"NAME":"LOOP","GPIO":[0,0,320,0,0,0,0,0,0,32,0,224 Nightlight and AC Outlet {"NAME":"SWN03","GPIO":[32,0,0,0,0,0,1,1,416,0,0,224,0,0],"FLAG":0,"BASE":18} Nishica SM-PW701I {"NAME":"SM-PW701I","GPIO":[1,1,1,1,1,1,1,1,224,288,32,1,1,1],"FLAG":0,"BASE":18} Nivian {"NAME":"Nivian Smart Socket","GPIO":[0,0,320,0,0,2688,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":18} -Nous 16A {"NAME":"NOUS A1T","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} Nous A1 {"NAME":"NOUS A1","GPIO":[320,0,576,0,2656,2720,0,0,2624,32,0,224,0,0],"FLAG":0,"BASE":45} +Nous A1T 16A {"NAME":"NOUS A1T","GPIO":[32,0,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":49} NX-SM112 {"NAME":"NX-SM112v3","GPIO":[0,0,0,0,2720,2656,0,0,576,32,2592,224,0,0],"FLAG":0,"BASE":45} NX-SM200 {"NAME":"NX-SM200","GPIO":[320,0,0,0,0,2720,0,0,224,32,2656,321,2624,0],"FLAG":0,"BASE":18} NX-SM210 {"NAME":"NX-SM210","GPIO":[0,32,0,0,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":18} @@ -1417,7 +1425,7 @@ NX-SM223 {"NAME":"Smart Thurmm","GPIO":[0,32,0,0,0,0,0,0,0,3 Oakter Oak Plug Plus 16A {"NAME":"Oakter OakPlug Plus","GPIO":[0,0,0,0,224,0,0,0,544,320,0,0,0,0],"FLAG":0,"BASE":18} Oakter OakPlug Mini 10A {"NAME":"Oakter OakPlug Mini","GPIO":[0,0,0,0,224,0,0,0,544,320,0,0,0,0],"FLAG":0,"BASE":18} Oakter OakPlug Plus (old) {"NAME":"Oakter OakPlug Plus (old)","GPIO":[0,0,0,0,224,0,0,0,0,320,0,0,544,0],"FLAG":0,"BASE":18} -Obi Stecker {"NAME":"OBI Socket","GPIO":[1,1,0,1,288,224,0,0,290,1,32,0,1,4704],"FLAG":0,"BASE":51} +Obi Stecker {"NAME":"Euromate","GPIO":[1,1,1,1,288,224,1,1,289,1,32,1,1,1],"FLAG":0,"BASE":18} Obi Stecker 2 {"NAME":"OBI Socket 2","GPIO":[0,0,0,0,224,32,0,0,320,289,0,0,0,0],"FLAG":0,"BASE":61} OFFONG 16A {"NAME":"OFFONG P1","GPIO":[0,32,0,0,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":18} Oittm Smart {"NAME":"Oittm","GPIO":[0,0,0,0,224,320,0,0,32,0,0,0,0,0],"FLAG":0,"BASE":1} @@ -1437,6 +1445,7 @@ OxaOxe NX-SP202 v2 {"NAME":"oxaoxe-dold","GPIO":[320,0,0,2624,32,2720, OZWI Smart {"NAME":"OZWI Smart Plug","GPIO":[0,0,0,0,288,0,0,0,224,32,544,0,0,0],"FLAG":0,"BASE":18} Panamalar Nightlight {"NAME":"Panamalar EWN0","GPIO":[32,0,0,0,0,0,1,1,416,0,0,224,0,0],"FLAG":0,"BASE":18} Panamalar NX-SM200 {"NAME":"NX-SM200","GPIO":[0,0,0,0,320,2720,0,0,2624,32,2656,224,0,4704],"FLAG":0,"BASE":18} +Polycam Hohm Lanre 16A {"NAME":"SLV1910001","GPIO":[0,0,0,32,2720,2656,0,0,2624,576,224,0,0,0],"FLAG":0,"BASE":18} Positivo PPW1000 {"NAME":"PPW1000","GPIO":[0,0,320,0,0,2720,0,0,2624,32,2656,224,0,0],"FLAG":0,"BASE":45} Positivo Max {"NAME":"PPW1600","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":55} PowerAdd BIE0091 {"NAME":"BIE0091","GPIO":[32,0,0,0,0,0,0,0,416,0,0,224,0,0],"FLAG":0,"BASE":18} @@ -1543,6 +1552,8 @@ Teckin SP27 {"NAME":"Teckin SP27","GPIO":[320,1,1,1,1,1,0,0,1,3 Tellur 16A 2 Ports {"NAME":"Tellur WiFi Smart Socket","GPIO":[0,0,0,2624,96,2688,0,0,224,33,2656,225,0,0],"FLAG":0,"BASE":18} Tellur 1USB 10A {"NAME":"Tellur TTL331021","GPIO":[0,0,544,0,288,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Tflag NX-SM100 {"NAME":"NX-SM100","GPIO":[320,0,0,0,0,2720,0,0,224,32,2656,321,2624,0],"FLAG":0,"BASE":18} +TH3D EZPlug V1 {"NAME":"EZPlug V1","GPIO":[0,0,0,32,0,0,0,0,0,320,224,0,0,0],"FLAG":0,"BASE":1} +TH3D EZPlug+ V1 {"NAME":"EZPlug+ V1","GPIO":[0,0,0,32,2720,2656,0,0,2624,320,224,0,0,0],"FLAG":0,"BASE":1} TikLok TL650 {"NAME":"TikLok Mini","GPIO":[0,0,0,0,321,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Timethinker C338 {"NAME":"C338","GPIO":[32,0,1,0,0,0,0,0,224,288,1,0,0,0],"FLAG":0,"BASE":1} Timethinker TK04 {"NAME":"TimethinkerEU","GPIO":[1,1,1,1,32,1,0,0,1,288,224,1,0,0],"FLAG":0,"BASE":18} @@ -1562,6 +1573,7 @@ Treatlife Dimmable {"NAME":"DP20","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0, Treatlife Smart {"NAME":"Treatlife SK50","GPIO":[1,1,1,1,320,576,1,1,224,1,32,1,1,1],"FLAG":0,"BASE":18} Tuya 16A Nightlight {"NAME":"Nightlight","GPIO":[225,0,320,0,226,227,0,0,34,64,0,224,0,0],"FLAG":0,"BASE":18} U10 Series {"NAME":"WIFI-Socket","GPIO":[1,32,1,1,1,1,1,1,1,320,224,1,1,4704],"FLAG":0,"BASE":18} +Ucomen Night Light {"NAME":"UCOMEN Plug","GPIO":[0,0,0,0,544,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} UltraBrite {"NAME":"UltraBrite Smart Plug","GPIO":[1,1,1,1,288,289,1,1,224,32,1,1,1,1],"FLAG":0,"BASE":18} Ultralink UL-P01W {"NAME":"UL-P01W","GPIO":[0,288,0,32,2720,2656,0,0,2624,544,224,0,0,0],"FLAG":0,"BASE":18} Unlocked Automation 15A {"NAME":"UA 100","GPIO":[0,0,0,0,320,321,0,0,224,32,0,0,0,1],"FLAG":0,"BASE":18} @@ -1613,7 +1625,7 @@ XS-A18 {"NAME":"XS-A18","GPIO":[416,0,417,0,0,418,0,0,0,32 XS-A23 {"NAME":"XS-A23","GPIO":[320,1,0,2624,32,2720,0,0,0,33,2656,224,225,0],"FLAG":0,"BASE":45} XS-SSA01 {"NAME":"XS-SSA01","GPIO":[1,0,0,1,0,0,0,0,320,32,1,224,1,0],"FLAG":0,"BASE":18} XS-SSA01 v2 {"NAME":"XS-SSA01","GPIO":[1,32,1,1,1,1,0,0,320,1,1,224,1,0],"FLAG":0,"BASE":18} -XS-SSA05 {"NAME":"XS-SSA05","GPIO":[257,1,1,2624,1,2688,0,0,224,32,2656,258,1,4704],"FLAG":0,"BASE":18} +XS-SSA05 {"NAME":"XS-SSA05","GPIO":[320,0,0,2624,544,2688,0,0,224,32,2656,0,0,4704],"FLAG":0,"BASE":18} XS-SSA06 {"NAME":"XS-SSA06","GPIO":[416,0,417,0,0,418,0,0,0,64,0,224,0,0],"FLAG":0,"BASE":18} Yagala SWA9 {"NAME":"SWA9","GPIO":[0,0,0,0,288,224,0,0,0,32,0,0,0,0],"FLAG":0,"BASE":18} Yelomin JH-G01E {"NAME":"Yelomin","GPIO":[0,3072,0,3104,0,0,0,0,32,320,224,0,0,0],"FLAG":0,"BASE":18} @@ -1706,12 +1718,13 @@ Konesky Type 1 {"NAME":"Konesky","GPIO":[0,0,0,0,228,225,0,0,227,3 Koogeek KLOE4 {"NAME":"Koogeek KLOE4","GPIO":[0,320,0,32,225,224,0,0,226,227,228,0,0,4704],"FLAG":0,"BASE":18} Larkkey 4AC 4USB {"NAME":"LARKKEY Strip","GPIO":[0,544,0,32,225,224,0,0,226,227,228,0,0,0],"FLAG":0,"BASE":18} LeFun SK2 {"NAME":"LeFun SK2","GPIO":[0,0,0,32,225,224,0,0,226,227,228,0,0,0],"FLAG":0,"BASE":18} +Lidl Silvercrest Zigbee {"NAME":"Lidl Silvercrest HG06338","GPIO":[0,288,0,0,225,226,0,0,32,224,576,0,0,0],"FLAG":0,"BASE":18} LITEdge Smart Power Strip {"NAME":"LITEEdge Power Strip","GPIO":[227,0,0,0,288,289,0,0,224,32,225,226,228,0],"FLAG":0,"BASE":18} Luminea 3AC+4USB 16A {"NAME":"Luminea-NX4473","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,0],"FLAG":0,"BASE":18} Maxcio ZLD-34EU-W {"NAME":"MAXCIO","GPIO":[0,320,0,32,225,224,0,0,0,226,227,0,0,4704],"FLAG":0,"BASE":18} Merkury Innovations Smart Surge {"NAME":"Merkury Power Strip MIC-SW002-199L","GPIO":[288,0,289,0,228,32,0,0,225,224,226,0,259,0],"FLAG":0,"BASE":18} Merkury Innovations SmartSurge {"NAME":"Merkury MI-SW001","GPIO":[288,0,289,0,228,32,0,0,225,224,226,0,227,0],"FLAG":0,"BASE":18} -Meross 4AC 4USB {"NAME":"HamaStrip","GPIO":[0,544,0,32,225,224,0,0,226,227,228,0,0,0],"FLAG":0,"BASE":18} +Meross 4AC 4USB {"NAME":"MSS425F","GPIO":[0,544,0,32,225,224,0,0,226,227,260,0,0,0],"FLAG":0,"BASE":18} Meross MSS425 {"NAME":"Meross MSS425","GPIO":[260,0,0,0,320,0,0,0,224,32,225,226,259,0],"FLAG":0,"BASE":18} Mirabella Genio 4 Outlet Power Board with 2 USB {"NAME":"Genio i002340","GPIO":[320,0,0,0,224,225,0,0,226,32,227,228,0,0],"FLAG":0,"BASE":18} Mirabella Genio Powerboard {"NAME":"Genio Powerboa","GPIO":[224,288,0,0,226,225,0,0,228,32,229,227,0,0],"FLAG":0,"BASE":18} @@ -1742,6 +1755,7 @@ Tellur 3AC 4USB {"NAME":"Tellur","GPIO":[0,320,0,32,225,224,0,0,0,2 Tessan {"NAME":"TESSAN A4L-BK","GPIO":[0,0,0,227,226,0,0,0,224,0,225,0,0,0],"FLAG":0,"BASE":18} Tonbux SM-SO301-U {"NAME":"Tonbux SM-SO30","GPIO":[320,0,0,0,256,0,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18} Useelink {"NAME":"Useelink","GPIO":[288,0,0,321,256,32,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18} +Useelink 4AC 2USB {"NAME":"306 Power Strip","GPIO":[576,0,576,291,259,32,0,0,257,258,256,0,228,0],"FLAG":0,"BASE":18} Vivitar HA-1007 {"NAME":"Vivitar HA-1007 Power Strip","GPIO":[544,0,0,0,227,228,0,0,225,224,226,0,35,1],"FLAG":0,"BASE":18} Vivitar HA-1007-AU {"NAME":"HA-1007-AU","GPIO":[320,32,0,322,256,321,0,0,258,257,259,0,228,0],"FLAG":0,"BASE":18} wesmartify essentials 3-socket 2 USB {"NAME":"Essentials Smart Home 3-socket USB Power Strip","GPIO":[0,0,0,0,544,226,0,0,224,32,225,0,0,0],"FLAG":0,"BASE":18} @@ -1883,6 +1897,8 @@ iQtech 9W 800lm {"NAME":"iQ-Tech RGBCCT 9W 800LM","GPIO":[0,0,0,0,4 Jeeo TF-QPZ13 800lm {"NAME":"Jeeo","GPIO":[0,0,0,0,2912,416,0,0,417,2976,2944,0,0,0],"FLAG":0,"BASE":18} Julun JL-021 5W Candle {"NAME":"E14 RGBCCT","GPIO":[0,0,0,0,419,420,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} Kauf esphome 10W {"NAME":"Kauf Bulb","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} +Kauf esphome A15 5W {"NAME":"Kauf Bulb","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} +Kauf esphome A19 7W {"NAME":"Kauf Bulb","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} KHSUIN BR30 13W 1300lm {"NAME":"KHSUIN 13W BR30","GPIO":[0,0,0,0,416,420,0,0,417,419,418,0,0,0],"FLAG":0,"BASE":18} Kogan 10W 1050lm {"NAME":"Kogan RGB+CCT","GPIO":[1,1,1,0,416,419,1,1,417,452,418,1,1,1],"FLAG":0,"BASE":18} Kohree 600lm {"NAME":"Kohree VHP560","GPIO":[0,0,0,0,416,420,0,0,417,419,418,0,0,0],"FLAG":0,"BASE":18} @@ -2133,6 +2149,7 @@ Nedis 6W 470lm {"NAME":"nedis Bulb","GPIO":[0,0,0,0,416,419,0,0,41 Nedis A60 800lm {"NAME":"Nedis RGBW","GPIO":[0,0,0,0,2912,416,0,0,0,2976,2944,0,0,4704],"FLAG":0,"BASE":18} Nedis C10 350lm {"NAME":"Nedis WIFILC10","GPIO":[0,0,0,0,418,416,0,0,419,417,420,0,0,4704],"FLAG":0,"BASE":18} Nedis PAR16 330lm {"NAME":"Nedis GU10","GPIO":[0,0,0,0,418,416,0,0,419,417,420,0,0,0],"FLAG":0,"BASE":18} +NGteco {"NAME":"NGTECO L100","GPIO":[0,0,0,0,0,418,0,0,417,0,416,419,0,0],"FLAG":0,"BASE":18} Novostella UT55506 10W 1050lm {"NAME":"Novostella 10W","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Onforu 7W 700lm {"NAME":"Onforu RGBW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Orbecco 5W 400lm {"NAME":"Orbecco Bulb","GPIO":[0,0,0,0,0,0,0,0,3008,0,3040,0,0,0],"FLAG":0,"BASE":27} @@ -2164,6 +2181,7 @@ Teckin 7.5W 800lm {"NAME":"Teckin SB60","GPIO":[0,0,0,0,416,419,0,0,4 Teckin SB50 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} Teckin SB50 v2 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,416,0,0,0,417,419,418,0,0,0],"FLAG":0,"BASE":18} Teckin SB51 800lm {"NAME":"Teckin SB51","GPIO":[0,0,0,0,419,0,0,0,417,418,416,0,0,0],"FLAG":0,"BASE":18} +TH3D EZBulb V1 {"NAME":"EZBulb V1","GPIO":[0,0,0,0,416,419,0,0,417,0,418,0,0,0],"FLAG":0,"BASE":18} TikLOk TL530 A19 7.5W 800lm {"NAME":"TikLOk WW-CW-L","GPIO":[0,0,0,0,0,416,0,0,417,0,0,0,0,0],"FLAG":0,"BASE":18} TVLive 7.5W 800lm {"NAME":"TVLIVE RGBCW","GPIO":[0,0,0,0,416,419,0,0,417,420,418,0,0,0],"FLAG":0,"BASE":18} Utorch LE7 600lm {"NAME":"Utorch LE7","GPIO":[0,0,0,0,0,417,0,0,418,0,419,416,0,0],"FLAG":0,"BASE":18} @@ -2573,9 +2591,9 @@ Sonoff TX T3 EU 2 Gang {"NAME":"Sonoff T3 TX 2CH","GPIO":[32,1,1,1,0,225,3 Sonoff TX T3 EU 3 Gang {"NAME":"TX T3EU3C","GPIO":[32,1,0,1,226,225,33,34,224,576,0,0,0,0],"FLAG":0,"BASE":30} Sonoff TX T3 US 3 Gang {"NAME":"TX T3US3C","GPIO":[32,1,0,1,226,225,33,34,224,576,0,0,0,0],"FLAG":0,"BASE":30} Sonoff TX T4 EU No Neutral 1 Gang {"NAME":"Sonoff T4 1CH","GPIO":[32,1,1,1,0,0,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":28} -Sonoff TX Ultimate 1 Gang {"NAME":"TX Ultimate 1","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,0,224,3232,0,480,3200,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Pixels 27"} -Sonoff TX Ultimate 2 Gang {"NAME":"TX Ultimate 1","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,225,224,3232,0,480,3200,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Pixels 27"} -Sonoff TX Ultimate 3 Gang {"NAME":"TX Ultimate 1","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,225,224,3232,0,480,3200,0,0,0,3840,226,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Pixels 27"} +Sonoff TX Ultimate 1 Gang {"NAME":"TX Ultimate 1","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,0,224,3232,0,480,3200,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"} +Sonoff TX Ultimate 2 Gang {"NAME":"TX Ultimate 2","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,225,224,3232,0,480,3200,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"} +Sonoff TX Ultimate 3 Gang {"NAME":"TX Ultimate 3","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,225,224,3232,0,480,3200,0,0,0,3840,226,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"} SPC Hera {"NAME":"SPC HERA","GPIO":[544,0,0,32,224,0,0,0,0,0,288,0,0,0],"FLAG":0,"BASE":18} SRL 2 Gang {"NAME":"SRL 4WW Switch","GPIO":[0,0,0,0,0,33,0,0,32,224,0,225,0,0],"FLAG":0,"BASE":18} SRL 4 Gang {"NAME":"SRL 4WW Switch","GPIO":[0,0,0,34,226,33,0,0,32,224,227,225,35,0],"FLAG":0,"BASE":18} @@ -2687,7 +2705,9 @@ Moes {"NAME":"Moes MS-104B","GPIO":[0,0,32,0,480,0,0,0,1 Moes 10A {"NAME":"Moes MS-101","GPIO":[0,0,0,0,0,320,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Moes Mini 3 Gang 1/2 Way {"NAME":"Moes MS-104C","GPIO":[0,0,0,34,32,33,0,0,224,225,226,0,0,0],"FLAG":0,"BASE":18} Nedis 10A {"NAME":"Nedis WIFIPS10WT","GPIO":[0,0,0,0,224,0,0,0,32,321,0,288,0,0],"FLAG":0,"BASE":18} +Nous 1 Channel Touch {"NAME":"NOUS L1T","GPIO":[544,0,1,32,0,0,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1} Nous 1/2 Channel {"NAME":"NOUS L13T Smart Switch Module","GPIO":[1,161,1,160,225,224,1,1,544,1,32,1,1,1],"FLAG":0,"BASE":18} +Nous 2 Channel Touch {"NAME":"NOUS L2T","GPIO":[544,289,1,32,225,33,0,0,0,224,288,0,0,0],"FLAG":0,"BASE":1} Nova Digital Basic 1 MS101 {"NAME":"NovaDigBasic1","GPIO":[0,1,0,1,320,0,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} PPA Contatto Wi-Fi {"NAME":"PPA Contatto","GPIO":[0,0,32,0,224,162,0,0,288,225,0,0,0,0],"FLAG":0,"BASE":18} PS-1604 16A {"NAME":"PS-1604 16A","GPIO":[32,1,1,1,1,0,0,0,224,320,1,0,0,0],"FLAG":0,"BASE":1} @@ -2786,6 +2806,7 @@ Tuya Gas/Water {"NAME":"Valve FM101","GPIO":[320,0,0,0,224,0,0,0,0 Aigostar P40 {"NAME":"Aigostar 8433325212278","GPIO":[0,0,0,0,544,288,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Aseer THWFS01 {"NAME":"ASEER-THWFS01","GPIO":[320,33,544,323,2720,2656,0,0,2624,225,321,224,32,0],"FLAG":0,"BASE":18} Athom {"NAME":"Athom SK01","GPIO":[0,0,0,3104,0,32,0,0,224,320,0,0,0,0],"FLAG":0,"BASE":18} +Athom 16A UK {"NAME":"Athom SK03-TAS","GPIO":[0,0,0,3104,0,32,0,0,224,576,0,0,0,0],"FLAG":0,"BASE":18} Bestten LO-2-W {"NAME":"BESTTEN LO-2-W","GPIO":[0,0,0,0,576,32,0,0,224,0,0,0,0,0],"FLAG":0,"BASE":18} BingoElec 16A {"NAME":"BingoElecPower","GPIO":[0,0,0,0,288,289,1,1,224,32,0,0,1,1],"FLAG":0,"BASE":18} BlitzWolf SHP8 {"NAME":"SHP8","GPIO":[0,320,0,32,2720,2656,0,0,2624,289,224,0,0,0],"FLAG":0,"BASE":64} @@ -2816,6 +2837,7 @@ Milfra UK Double USB Chager Twin {"NAME":"Milfra TBU02","GPIO":[0,0,0,0,288,33, Moes 16A {"NAME":"WK-EU(FR/UK)16M","GPIO":[0,288,0,32,2720,2656,0,0,2624,224,0,0,0,0],"FLAG":0,"BASE":18} Moes WWK Glass Panel {"NAME":"Smart Socket","GPIO":[0,0,0,0,288,289,0,0,224,32,0,0,0,0],"FLAG":0,"BASE":18} Oittm 120 {"NAME":"Oittm WS01","GPIO":[32,0,0,0,0,2592,0,0,224,2656,2688,288,0,0],"FLAG":0,"BASE":18} +PFS Presa Smart {"NAME":"PFS_PresaSmart","GPIO":[1,1,1,1,288,289,1,1,224,32,0,1,1,1],"FLAG":0,"BASE":18} PS-1607 {"NAME":"PS-1607","GPIO":[32,0,0,0,0,225,33,0,224,0,0,0,0,0],"FLAG":0,"BASE":18} Smanergy KA10 {"NAME":"KA10","GPIO":[0,320,0,32,2720,2656,0,0,2624,289,224,0,0,0],"FLAG":0,"BASE":64} Sonoff IW100 {"NAME":"Sonoff IW100","GPIO":[32,3072,0,3104,0,0,0,0,224,544,0,0,0,0],"FLAG":0,"BASE":41} diff --git a/boards/esp32c2.json b/boards/esp32c2.json new file mode 100644 index 000000000000..563a3357c15f --- /dev/null +++ b/boards/esp32c2.json @@ -0,0 +1,44 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32c2_out.ld" + }, + "core": "esp32", + "extra_flags": "-DESP32_4M -DESP32C2", + "f_cpu": "120000000L", + "f_flash": "60000000L", + "flash_mode": "dio", + "mcu": "esp32c2", + "variant": "esp32c2", + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32c2.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif Generic ESP32-C2 = 4M Flash", + "upload": { + "arduino": { + "flash_extra_images": [ + [ + "0x10000", + "variants/tasmota/tasmota32c2-safeboot.bin" + ] + ] + }, + "flash_size": "4MB", + "maximum_ram_size": 278528, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html", + "vendor": "Espressif" + } diff --git a/boards/esp32c2_2M.json b/boards/esp32c2_2M.json new file mode 100644 index 000000000000..36f16ffe3432 --- /dev/null +++ b/boards/esp32c2_2M.json @@ -0,0 +1,44 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32c2_out.ld" + }, + "core": "esp32", + "extra_flags": "-DESP32_2M -DESP32C2", + "f_cpu": "120000000L", + "f_flash": "60000000L", + "flash_mode": "dio", + "mcu": "esp32c2", + "variant": "esp32c2", + "partitions": "partitions/esp32_partition_app1245k_fs64k.csv" + }, + "connectivity": [ + "wifi", + "bluetooth" + ], + "debug": { + "openocd_target": "esp32c2.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif Generic ESP32-C2 = 2M Flash, Tasmota 1245kB Code/OTA, 64k FS", + "upload": { + "arduino": { + "flash_extra_images": [ + [ + "0x10000", + "variants/tasmota/tasmota32c2-safeboot.bin" + ] + ] + }, + "flash_size": "2MB", + "maximum_ram_size": 278528, + "maximum_size": 2097152, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32c6/esp32-c6-devkitc-1/index.html", + "vendor": "Espressif" + } diff --git a/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h index a9d149b71b27..953a216e7481 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/DotStarEsp32DmaSpiMethod.h @@ -29,12 +29,12 @@ License along with NeoPixel. If not, see #include "driver/spi_master.h" -#if defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(HSPI_HOST) +#if (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6)) && !defined(HSPI_HOST) // HSPI_HOST depreciated in C3 #define HSPI_HOST SPI2_HOST #endif -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) class Esp32VspiBus { public: @@ -52,7 +52,7 @@ class Esp32HspiBus const static int ParallelBits = 1; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) class Esp32Vspi2BitBus { public: @@ -70,7 +70,7 @@ class Esp32Hspi2BitBus const static int ParallelBits = 2; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) class Esp32Vspi4BitBus { public: @@ -174,7 +174,7 @@ template class DotStarEsp32DmaSpiMethod // If pins aren't specified, initialize bus with just the default SCK and MOSI pins for the SPI peripheral (no SS, no >1-bit pins) void Initialize() { -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) if (T_SPIBUS::SpiHostDevice == VSPI_HOST) { Initialize(SCK, -1, MOSI, -1, -1, -1); @@ -277,7 +277,7 @@ template class DotStarEsp32DmaSpiMethod int8_t _ssPin; }; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // Clock Speed and Default Definitions for DotStarEsp32DmaVspi typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi40MhzMethod; typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi20MhzMethod; @@ -303,7 +303,7 @@ typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaHspiHz typedef DotStarEsp32DmaHspi10MhzMethod DotStarEsp32DmaHspiMethod; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // Clock Speed and Default Definitions for DotStarEsp32DmaVspi2Bit typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi2Bit40MhzMethod; typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi2Bit20MhzMethod; @@ -329,7 +329,7 @@ typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaHsp typedef DotStarEsp32DmaHspi2Bit10MhzMethod DotStarEsp32DmaHspi2BitMethod; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // Clock Speed and Default Definitions for DotStarEsp32DmaVspi4Bit typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi4Bit40MhzMethod; typedef DotStarEsp32DmaSpiMethod DotStarEsp32DmaVspi4Bit20MhzMethod; diff --git a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c index 0f100cb41d6f..74a1ace8c24d 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c +++ b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.c @@ -20,7 +20,7 @@ #include "sdkconfig.h" // this sets useful config symbols, like CONFIG_IDF_TARGET_ESP32C3 // ESP32C3/S3 I2S is not supported yet due to significant changes to interface -#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #include #include @@ -41,20 +41,27 @@ #include "soc/gpio_reg.h" #include "soc/gpio_sig_map.h" #include "soc/io_mux_reg.h" +#if ESP_IDF_VERSION_MAJOR>=5 +#include "soc/rtc_cntl_periph.h" +#include "soc/periph_defs.h" +#else #include "soc/rtc_cntl_reg.h" +#include "soc/sens_reg.h" +#endif + #include "soc/i2s_struct.h" #if defined(CONFIG_IDF_TARGET_ESP32) /* included here for ESP-IDF v4.x compatibility */ #include "soc/dport_reg.h" #endif -#include "soc/sens_reg.h" + #include "driver/gpio.h" #include "driver/i2s.h" #include "driver/dac.h" #include "Esp32_i2s.h" #include "esp32-hal.h" -#if ESP_IDF_VERSION_MAJOR<=4 +#if ESP_IDF_VERSION_MAJOR<=4 || ESP_IDF_VERSION_MAJOR>=5 #define I2S_BASE_CLK (160000000L) #endif @@ -93,7 +100,11 @@ typedef struct { int8_t in; uint32_t rate; intr_handle_t isr_handle; +#if ESP_IDF_VERSION_MAJOR >= 5 + QueueHandle_t tx_queue; +#else xQueueHandle tx_queue; +#endif uint8_t* silence_buf; size_t silence_len; @@ -110,6 +121,10 @@ typedef struct { #define I2s_Is_Pending 1 #define I2s_Is_Sending 2 +#if ESP_IDF_VERSION_MAJOR >= 5 +#define I2S_NUM_MAX I2S_NUM_AUTO // not 100% correct +#endif + static uint8_t i2s_silence_buf[I2S_DMA_SILENCE_SIZE] = { 0 }; #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) diff --git a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h index 1249d2e11dd4..ea76b880774c 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/Esp32_i2s.h @@ -1,7 +1,7 @@ #pragma once // ESP32C3 I2S is not supported yet due to significant changes to interface -#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #ifdef __cplusplus extern "C" { diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h index 6f4b3c66f125..5fdb131bf377 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoBusChannel.h @@ -12,7 +12,7 @@ enum NeoBusChannel NeoBusChannel_0, NeoBusChannel_1, -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) NeoBusChannel_2, @@ -35,7 +35,7 @@ enum NeoBusChannel NeoBusChannel_7, #endif // !defined(CONFIG_IDF_TARGET_ESP32S2) -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #endif // ARDUINO_ARCH_ESP32 diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h index 9dbaa7fe76d9..330c4153bf43 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32I2sMethod.h @@ -27,12 +27,13 @@ License along with NeoPixel. If not, see #pragma once // ESP32C3 I2S is not supported yet due to significant changes to interface -#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) extern "C" { #include #include "Esp32_i2s.h" +#include "rom/gpio.h" } const uint16_t c_dmaBytesPerPixelBytes = 4; @@ -301,7 +302,7 @@ typedef NeoEsp32I2sMethodBase NeoEsp32I2s0400KbpsInvertedMethod; typedef NeoEsp32I2sMethodBase NeoEsp32I2s0Apa106InvertedMethod; -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) // (I2S_NUM_MAX == 2) typedef NeoEsp32I2sMethodBase NeoEsp32I2s1Ws2812xMethod; @@ -343,7 +344,7 @@ typedef NeoEsp32I2sMethodBase= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -66,7 +69,11 @@ void NeoEsp32RmtSpeed::_translate(const void* src, size_t size = 0; size_t num = 0; const uint8_t* psrc = static_cast(src); +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* pdest = dest; +#else rmt_item32_t* pdest = dest; +#endif for (;;) { @@ -110,7 +117,11 @@ void NeoEsp32RmtSpeed::_translate(const void* src, // https://stackoverflow.com/questions/19532826/what-does-a-dangerous-relocation-error-mean // void NeoEsp32RmtSpeedWs2811::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -121,7 +132,11 @@ void NeoEsp32RmtSpeedWs2811::Translate(const void* src, } void NeoEsp32RmtSpeedWs2812x::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -132,7 +147,11 @@ void NeoEsp32RmtSpeedWs2812x::Translate(const void* src, } void NeoEsp32RmtSpeedSk6812::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -143,7 +162,11 @@ void NeoEsp32RmtSpeedSk6812::Translate(const void* src, } void NeoEsp32RmtSpeedTm1814::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -154,7 +177,11 @@ void NeoEsp32RmtSpeedTm1814::Translate(const void* src, } void NeoEsp32RmtSpeedTm1829::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -165,7 +192,11 @@ void NeoEsp32RmtSpeedTm1829::Translate(const void* src, } void NeoEsp32RmtSpeedTm1914::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -176,7 +207,11 @@ void NeoEsp32RmtSpeedTm1914::Translate(const void* src, } void NeoEsp32RmtSpeed800Kbps::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -187,7 +222,11 @@ void NeoEsp32RmtSpeed800Kbps::Translate(const void* src, } void NeoEsp32RmtSpeed400Kbps::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -198,7 +237,11 @@ void NeoEsp32RmtSpeed400Kbps::Translate(const void* src, } void NeoEsp32RmtSpeedApa106::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -209,7 +252,11 @@ void NeoEsp32RmtSpeedApa106::Translate(const void* src, } void NeoEsp32RmtSpeedTx1812::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -220,7 +267,11 @@ void NeoEsp32RmtSpeedTx1812::Translate(const void* src, } void NeoEsp32RmtInvertedSpeedWs2811::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -231,7 +282,11 @@ void NeoEsp32RmtInvertedSpeedWs2811::Translate(const void* src, } void NeoEsp32RmtInvertedSpeedWs2812x::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -242,7 +297,11 @@ void NeoEsp32RmtInvertedSpeedWs2812x::Translate(const void* src, } void NeoEsp32RmtInvertedSpeedSk6812::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -253,7 +312,11 @@ void NeoEsp32RmtInvertedSpeedSk6812::Translate(const void* src, } void NeoEsp32RmtInvertedSpeedTm1814::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -264,7 +327,11 @@ void NeoEsp32RmtInvertedSpeedTm1814::Translate(const void* src, } void NeoEsp32RmtInvertedSpeedTm1829::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -275,7 +342,11 @@ void NeoEsp32RmtInvertedSpeedTm1829::Translate(const void* src, } void NeoEsp32RmtInvertedSpeedTm1914::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -286,7 +357,11 @@ void NeoEsp32RmtInvertedSpeedTm1914::Translate(const void* src, } void NeoEsp32RmtInvertedSpeed800Kbps::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -297,7 +372,11 @@ void NeoEsp32RmtInvertedSpeed800Kbps::Translate(const void* src, } void NeoEsp32RmtInvertedSpeed400Kbps::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -308,7 +387,11 @@ void NeoEsp32RmtInvertedSpeed400Kbps::Translate(const void* src, } void NeoEsp32RmtInvertedSpeedApa106::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, @@ -319,7 +402,11 @@ void NeoEsp32RmtInvertedSpeedApa106::Translate(const void* src, } void NeoEsp32RmtInvertedSpeedTx1812::Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif // ESP_IDF_VERSION_MAJOR >= 5 size_t src_size, size_t wanted_num, size_t* translated_size, diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h index 2ed7e4a0ecbf..c64a92fee7c9 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEsp32RmtMethod.h @@ -29,7 +29,7 @@ License along with NeoPixel. If not, see #pragma once -#ifdef ARDUINO_ARCH_ESP32 +#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C2) /* General Reference documentation for the APIs used in this implementation LOW LEVEL: (what is actually used) @@ -47,7 +47,128 @@ Esp32-hal-rmt.c extern "C" { +#if ESP_IDF_VERSION_MAJOR >= 5 +#include +#include "driver/rmt_tx.h" +#include "driver/rmt_encoder.h" + +typedef struct { + uint32_t resolution; /*!< Encoder resolution, in Hz */ +} led_strip_encoder_config_t; + +typedef struct { + rmt_encoder_t base; + rmt_encoder_t *bytes_encoder; + rmt_encoder_t *copy_encoder; + int state; + rmt_symbol_word_t reset_code; +} rmt_led_strip_encoder_t; + +static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_handle_t bytes_encoder = led_encoder->bytes_encoder; + rmt_encoder_handle_t copy_encoder = led_encoder->copy_encoder; + rmt_encode_state_t session_state = RMT_ENCODING_RESET; + rmt_encode_state_t state = RMT_ENCODING_RESET; + size_t encoded_symbols = 0; + switch (led_encoder->state) { + case 0: // send RGB data + encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, primary_data, data_size, &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = 1; // switch to next state when current encoding session finished + } + if (session_state & RMT_ENCODING_MEM_FULL) { + // static_cast(static_cast(a) | static_cast(b)); + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_MEM_FULL)); + goto out; // yield if there's no free space for encoding artifacts + } + // fall-through + case 1: // send reset code + encoded_symbols += copy_encoder->encode(copy_encoder, channel, &led_encoder->reset_code, + sizeof(led_encoder->reset_code), &session_state); + if (session_state & RMT_ENCODING_COMPLETE) { + led_encoder->state = RMT_ENCODING_RESET; // back to the initial encoding session + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_COMPLETE)); + } + if (session_state & RMT_ENCODING_MEM_FULL) { + state = static_cast(static_cast(state) | static_cast(RMT_ENCODING_MEM_FULL)); + goto out; // yield if there's no free space for encoding artifacts + } + } +out: + *ret_state = state; + return encoded_symbols; +} + +static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_del_encoder(led_encoder->bytes_encoder); + rmt_del_encoder(led_encoder->copy_encoder); + delete led_encoder; + return ESP_OK; +} + +static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) +{ + rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); + rmt_encoder_reset(led_encoder->bytes_encoder); + rmt_encoder_reset(led_encoder->copy_encoder); + led_encoder->state = RMT_ENCODING_RESET; + return ESP_OK; +} + +esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder) +{ + esp_err_t ret = ESP_OK; + rmt_led_strip_encoder_t *led_encoder = new rmt_led_strip_encoder_t; + // ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); + // led_encoder = (rmt_led_strip_encoder_t*)calloc(1, sizeof(rmt_led_strip_encoder_t)); + // ESP_GOTO_ON_FALSE(led_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for led strip encoder"); + led_encoder->base.encode = rmt_encode_led_strip; + led_encoder->base.del = rmt_del_led_strip_encoder; + led_encoder->base.reset = rmt_led_strip_encoder_reset; + // different led strip might have its own timing requirements, following parameter is for WS2812 + rmt_bytes_encoder_config_t bytes_encoder_config = {}; + bytes_encoder_config.bit0.level0 = 1; + bytes_encoder_config.bit0.duration0 = 0.3 * config->resolution / 1000000; // T0H=0.3us + bytes_encoder_config.bit0.level1 = 0; + bytes_encoder_config.bit0.duration1 = 0.9 * config->resolution / 1000000; // T0L=0.9us + bytes_encoder_config.bit1.level0 = 1; + bytes_encoder_config.bit1.duration0 = 0.3 * config->resolution / 1000000; // T0H=0.3us + bytes_encoder_config.bit1.level1 = 0; + bytes_encoder_config.bit1.duration1 = 0.9 * config->resolution / 1000000; // T0L=0.9us + bytes_encoder_config.flags.msb_first = 1; // WS2812 transfer bit order: G7...G0R7...R0B7...B0 + + // ESP_GOTO_ON_ERROR(rmt_new_bytes_encoder(&bytes_encoder_config, &led_encoder->bytes_encoder), err, TAG, "create bytes encoder failed"); + rmt_copy_encoder_config_t copy_encoder_config = {}; + // ESP_GOTO_ON_ERROR(rmt_new_copy_encoder(©_encoder_config, &led_encoder->copy_encoder), err, TAG, "create copy encoder failed"); + + uint32_t reset_ticks = config->resolution / 1000000 * 50 / 2; // reset code duration defaults to 50us + rmt_symbol_word_t reset_code_config = {}; + reset_code_config.level0 = 0; + reset_code_config.duration0 = reset_ticks; + reset_code_config.level1 = 0; + reset_code_config.duration1 = reset_ticks; + led_encoder->reset_code = reset_code_config; + *ret_encoder = &led_encoder->base; + return ESP_OK; +err: + if (led_encoder) { + if (led_encoder->bytes_encoder) { + rmt_del_encoder(led_encoder->bytes_encoder); + } + if (led_encoder->copy_encoder) { + rmt_del_encoder(led_encoder->copy_encoder); + } + free(led_encoder); + } + return ret; +} +#else #include +#endif } #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0) @@ -76,7 +197,11 @@ class NeoEsp32RmtSpeed const static uint32_t NsPerRmtTick = (NsPerSecond / RmtTicksPerSecond); // about 25 static void IRAM_ATTR _translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -90,27 +215,29 @@ class NeoEsp32RmtSpeed class NeoEsp32RmtSpeedBase : public NeoEsp32RmtSpeed { public: - // this is used rather than the rmt_item32_t as you can't correctly initialize + // this is used rather than the rmt_symbol_word_t as you can't correctly initialize // it as a static constexpr within the template inline constexpr static uint32_t Item32Val(uint16_t nsHigh, uint16_t nsLow) { return (FromNs(nsLow) << 16) | (1 << 15) | (FromNs(nsHigh)); } - +#if ESP_IDF_VERSION_MAJOR < 5 const static rmt_idle_level_t IdleLevel = RMT_IDLE_LEVEL_LOW; +#endif }; class NeoEsp32RmtInvertedSpeedBase : public NeoEsp32RmtSpeed { public: - // this is used rather than the rmt_item32_t as you can't correctly initialize + // this is used rather than the rmt_symbol_word_t as you can't correctly initialize // it as a static constexpr within the template inline constexpr static uint32_t Item32Val(uint16_t nsHigh, uint16_t nsLow) { return (FromNs(nsLow) << 16) | (1 << 31) | (FromNs(nsHigh)); } - +#if ESP_IDF_VERSION_MAJOR < 5 const static rmt_idle_level_t IdleLevel = RMT_IDLE_LEVEL_HIGH; +#endif }; class NeoEsp32RmtSpeedWs2811 : public NeoEsp32RmtSpeedBase @@ -121,7 +248,11 @@ class NeoEsp32RmtSpeedWs2811 : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -136,7 +267,11 @@ class NeoEsp32RmtSpeedWs2812x : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -151,7 +286,11 @@ class NeoEsp32RmtSpeedSk6812 : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -167,7 +306,11 @@ class NeoEsp32RmtSpeedTm1814 : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -183,7 +326,11 @@ class NeoEsp32RmtSpeedTm1829 : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -199,7 +346,11 @@ class NeoEsp32RmtSpeedTm1914 : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -214,7 +365,11 @@ class NeoEsp32RmtSpeed800Kbps : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -229,7 +384,11 @@ class NeoEsp32RmtSpeed400Kbps : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -244,7 +403,11 @@ class NeoEsp32RmtSpeedApa106 : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -259,7 +422,11 @@ class NeoEsp32RmtSpeedTx1812 : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -274,7 +441,11 @@ class NeoEsp32RmtInvertedSpeedWs2811 : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -289,7 +460,11 @@ class NeoEsp32RmtInvertedSpeedWs2812x : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(300000); // 300us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -304,7 +479,11 @@ class NeoEsp32RmtInvertedSpeedSk6812 : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -320,7 +499,11 @@ class NeoEsp32RmtInvertedSpeedTm1814 : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -336,7 +519,11 @@ class NeoEsp32RmtInvertedSpeedTm1829 : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -352,7 +539,11 @@ class NeoEsp32RmtInvertedSpeedTm1914 : public NeoEsp32RmtSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(200000); // 200us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -367,7 +558,11 @@ class NeoEsp32RmtInvertedSpeed800Kbps : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -382,7 +577,11 @@ class NeoEsp32RmtInvertedSpeed400Kbps : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -397,7 +596,11 @@ class NeoEsp32RmtInvertedSpeedApa106 : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(50000); // 50us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -412,7 +615,11 @@ class NeoEsp32RmtInvertedSpeedTx1812 : public NeoEsp32RmtInvertedSpeedBase const static DRAM_ATTR uint16_t RmtDurationReset = FromNs(80000); // 80us static void IRAM_ATTR Translate(const void* src, +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_symbol_word_t* dest, +#else rmt_item32_t* dest, +#endif size_t src_size, size_t wanted_num, size_t* translated_size, @@ -423,8 +630,11 @@ class NeoEsp32RmtChannel0 { public: NeoEsp32RmtChannel0() {}; - +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_channel_handle_t RmtChannelNumber = NULL; +#else const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_0; +#endif //ESP_IDF_VERSION_MAJOR >= 5 }; class NeoEsp32RmtChannel1 @@ -432,15 +642,24 @@ class NeoEsp32RmtChannel1 public: NeoEsp32RmtChannel1() {}; +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_channel_handle_t RmtChannelNumber = NULL; +#else const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_1; +#endif //ESP_IDF_VERSION_MAJOR >= 5 }; +#if !defined(CONFIG_IDF_TARGET_ESP32C6) // C6 only 2 RMT channels ?? class NeoEsp32RmtChannel2 { public: NeoEsp32RmtChannel2() {}; +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_channel_handle_t RmtChannelNumber = NULL; +#else const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_2; +#endif //ESP_IDF_VERSION_MAJOR >= 5 }; class NeoEsp32RmtChannel3 @@ -448,17 +667,26 @@ class NeoEsp32RmtChannel3 public: NeoEsp32RmtChannel3() {}; +#if ESP_IDF_VERSION_MAJOR >= 5 +protected: + rmt_channel_handle_t RmtChannelNumber = NULL; +#else const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_3; +#endif //ESP_IDF_VERSION_MAJOR >= 5 }; - -#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C6) +#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) class NeoEsp32RmtChannel4 { public: NeoEsp32RmtChannel4() {}; +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_channel_handle_t RmtChannelNumber = NULL; +#else const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_4; +#endif //ESP_IDF_VERSION_MAJOR >= 5 }; class NeoEsp32RmtChannel5 @@ -466,7 +694,11 @@ class NeoEsp32RmtChannel5 public: NeoEsp32RmtChannel5() {}; +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_channel_handle_t RmtChannelNumber = NULL; +#else const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_5; +#endif //ESP_IDF_VERSION_MAJOR >= 5 }; class NeoEsp32RmtChannel6 @@ -474,7 +706,11 @@ class NeoEsp32RmtChannel6 public: NeoEsp32RmtChannel6() {}; +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_channel_handle_t RmtChannelNumber = NULL; +#else const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_6; +#endif //ESP_IDF_VERSION_MAJOR >= 5 }; class NeoEsp32RmtChannel7 @@ -482,7 +718,11 @@ class NeoEsp32RmtChannel7 public: NeoEsp32RmtChannel7() {}; +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_channel_handle_t RmtChannelNumber = NULL; +#else const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_7; +#endif //ESP_IDF_VERSION_MAJOR >= 5 }; #endif @@ -491,13 +731,22 @@ class NeoEsp32RmtChannel7 class NeoEsp32RmtChannelN { public: +#if ESP_IDF_VERSION_MAJOR >= 5 + NeoEsp32RmtChannelN(NeoBusChannel channel) : + RmtChannelNumber(RmtChannelNumber) + { + RmtChannelNumber = NULL; + }; + NeoEsp32RmtChannelN() = delete; // no default constructor + rmt_channel_handle_t RmtChannelNumber = NULL; +#else NeoEsp32RmtChannelN(NeoBusChannel channel) : RmtChannelNumber(static_cast(channel)) { } NeoEsp32RmtChannelN() = delete; // no default constructor - const rmt_channel_t RmtChannelNumber; +#endif //ESP_IDF_VERSION_MAJOR >= 5 }; template class NeoEsp32RmtMethodBase @@ -511,7 +760,15 @@ template class NeoEsp32RmtMethodBase { construct(); } - +#if ESP_IDF_VERSION_MAJOR >= 5 + NeoEsp32RmtMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize, NeoBusChannel channel) : + _sizeData(pixelCount* elementSize + settingsSize), + _pin(pin), + _channel(channel) + { + construct(); + } +#else NeoEsp32RmtMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize, NeoBusChannel channel) : _sizeData(pixelCount* elementSize + settingsSize), _pin(pin), @@ -519,15 +776,19 @@ template class NeoEsp32RmtMethodBase { construct(); } +#endif ~NeoEsp32RmtMethodBase() { // wait until the last send finishes before destructing everything // arbitrary time out of 10 seconds - ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_wait_tx_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS)); - - ESP_ERROR_CHECK(rmt_driver_uninstall(_channel.RmtChannelNumber)); - +#if ESP_IDF_VERSION_MAJOR >= 5 + ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_tx_wait_all_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS)); + ESP_ERROR_CHECK( rmt_del_channel(_channel.RmtChannelNumber)); +#else + ESP_ERROR_CHECK (ESP_OK == rmt_wait_tx_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS)); + ESP_ERROR_CHECK( rmt_driver_uninstall(_channel.RmtChannelNumber)); +#endif gpio_matrix_out(_pin, 0x100, false, false); pinMode(_pin, INPUT); @@ -538,13 +799,17 @@ template class NeoEsp32RmtMethodBase bool IsReadyToUpdate() const { +#if ESP_IDF_VERSION_MAJOR >= 5 + return (ESP_OK == rmt_tx_wait_all_done(_channel.RmtChannelNumber, 0)); +#else return (ESP_OK == rmt_wait_tx_done(_channel.RmtChannelNumber, 0)); +#endif } void Initialize() { +#if ESP_IDF_VERSION_MAJOR < 5 rmt_config_t config = {}; - config.rmt_mode = RMT_MODE_TX; config.channel = _channel.RmtChannelNumber; config.gpio_num = static_cast(_pin); @@ -562,6 +827,28 @@ template class NeoEsp32RmtMethodBase ESP_ERROR_CHECK(rmt_config(&config)); ESP_ERROR_CHECK(rmt_driver_install(_channel.RmtChannelNumber, 0, NEOPIXELBUS_RMT_INT_FLAGS)); ESP_ERROR_CHECK(rmt_translator_init(_channel.RmtChannelNumber, T_SPEED::Translate)); +#else + // rmt_channel_handle_t tx_chan = NULL; + rmt_tx_channel_config_t config = {}; + config.clk_src = RMT_CLK_SRC_DEFAULT; + config.gpio_num = static_cast(_pin); + config.mem_block_symbols = 64; // memory block size, 64 * 4 = 256 Bytes + config.resolution_hz = 1 * 1000 * 1000; // 1 MHz tick resolution, i.e., 1 tick = 1 µs + config.trans_queue_depth = 4; // set the number of transactions that can pend in the background + config.flags.invert_out = false; // do not invert output signal + config.flags.with_dma = false; // do not need DMA backend + + ESP_ERROR_CHECK(rmt_new_tx_channel(&config,&_channel.RmtChannelNumber)); +#define RMT_LED_STRIP_RESOLUTION_HZ 10000000 // 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution) + led_strip_encoder_config_t encoder_config = {}; + encoder_config.resolution = RMT_LED_STRIP_RESOLUTION_HZ; + + ESP_ERROR_CHECK(rmt_new_led_strip_encoder(&encoder_config, &_led_encoder)); + + // ESP_LOGI(TAG, "Enable RMT TX channel"); + ESP_ERROR_CHECK(rmt_enable(_channel.RmtChannelNumber)); + +#endif //ESP_IDF_VERSION_MAJOR < 5 } void Update(bool maintainBufferConsistency) @@ -569,10 +856,18 @@ template class NeoEsp32RmtMethodBase // wait for not actively sending data // this will time out at 10 seconds, an arbitrarily long period of time // and do nothing if this happens +#if ESP_IDF_VERSION_MAJOR >= 5 + if (ESP_OK == ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_tx_wait_all_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS))) +#else if (ESP_OK == ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_wait_tx_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS))) +#endif { // now start the RMT transmit with the editing buffer before we swap +#if ESP_IDF_VERSION_MAJOR >= 5 + ESP_ERROR_CHECK(rmt_transmit(_channel.RmtChannelNumber, _led_encoder, _dataEditing, _sizeData, &_tx_config)); +#else ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_write_sample(_channel.RmtChannelNumber, _dataEditing, _sizeData, false)); +#endif if (maintainBufferConsistency) { @@ -604,7 +899,12 @@ template class NeoEsp32RmtMethodBase private: const size_t _sizeData; // Size of '_data*' buffers const uint8_t _pin; // output pin number - const T_CHANNEL _channel; // holds instance for multi channel support +#if ESP_IDF_VERSION_MAJOR >= 5 + rmt_transmit_config_t _tx_config = {}; + rmt_encoder_handle_t _led_encoder = NULL; +#endif + T_CHANNEL _channel; // holds instance for multi channel support + // Holds data stream which include LED color values and other settings as needed uint8_t* _dataEditing; // exposed for get and set @@ -655,7 +955,7 @@ typedef NeoEsp32RmtMethodBase NeoEs typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1800KbpsMethod; typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1400KbpsMethod; -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2811Method; typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2812xMethod; @@ -726,7 +1026,7 @@ typedef NeoEsp32RmtMethodBase NeoE typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7400KbpsMethod; #endif // !defined(CONFIG_IDF_TARGET_ESP32S2) -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C3) // inverted typedef NeoEsp32RmtMethodBase NeoEsp32RmtNWs2811InvertedMethod; @@ -762,7 +1062,7 @@ typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1800KbpsInvertedMethod; typedef NeoEsp32RmtMethodBase NeoEsp32Rmt1400KbpsInvertedMethod; -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2811InvertedMethod; typedef NeoEsp32RmtMethodBase NeoEsp32Rmt2Ws2812xInvertedMethod; @@ -833,16 +1133,16 @@ typedef NeoEsp32RmtMethodBase NeoEsp32Rmt7400KbpsInvertedMethod; #endif // !defined(CONFIG_IDF_TARGET_ESP32S2) -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C6) -#if defined(NEOPIXEL_ESP32_RMT_DEFAULT) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) +#if defined(NEOPIXEL_ESP32_RMT_DEFAULT) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) // Normally I2s method is the default, defining NEOPIXEL_ESP32_RMT_DEFAULT // will switch to use RMT as the default method // The ESP32S2 & ESP32C3 will always defualt to RMT -#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) // RMT channel 1 method is the default method for Esp32S2 & Esp32C3 typedef NeoEsp32Rmt1Ws2812xMethod NeoWs2813Method; @@ -908,8 +1208,8 @@ typedef NeoEsp32Rmt6Tx1812InvertedMethod NeoTx1812InvertedMethod; typedef NeoEsp32Rmt6Ws2812xInvertedMethod Neo800KbpsInvertedMethod; typedef NeoEsp32Rmt6400KbpsInvertedMethod Neo400KbpsInvertedMethod; -#endif // defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) -#endif // defined(NEOPIXEL_ESP32_RMT_DEFAULT) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // defined(NEOPIXEL_ESP32_RMT_DEFAULT) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) #endif diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp index 32c069f3d2e1..43cedf23933e 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.cpp @@ -29,8 +29,9 @@ License along with NeoPixel. If not, see #include // ESP32C3 I2S is not supported yet -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) +#include "soc/gpio_periph.h" static inline uint32_t getCycleCount(void) { uint32_t ccount; @@ -154,5 +155,5 @@ void IRAM_ATTR NeoEspBitBangBase_send_pixels_inv(uint8_t* pixels, uint8_t* end, } } -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #endif // defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) diff --git a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h index bfbd13545d7f..44f8654889ff 100644 --- a/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h +++ b/lib/lib_basic/NeoPixelBus/src/internal/NeoEspBitBangMethod.h @@ -29,7 +29,7 @@ License along with NeoPixel. If not, see #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) // ESP32C3 I2S is not supported yet -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #if defined(ARDUINO_ARCH_ESP8266) #include @@ -377,5 +377,5 @@ typedef NeoEsp8266BitBangSk6812InvertedMethod NeoEsp8266BitBangLc8812InvertedMet // ESP bitbang doesn't have defaults and should avoided except for testing -#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) +#endif // !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C2) && !defined(CONFIG_IDF_TARGET_ESP32C6) #endif // defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) diff --git a/lib/lib_basic/OneWire-Stickbreaker/OneWire.h b/lib/lib_basic/OneWire-Stickbreaker/OneWire.h index c92dda8d0afa..cdb3e41a8559 100644 --- a/lib/lib_basic/OneWire-Stickbreaker/OneWire.h +++ b/lib/lib_basic/OneWire-Stickbreaker/OneWire.h @@ -147,6 +147,9 @@ #elif defined(ARDUINO_ARCH_ESP32) #include +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "soc/gpio_periph.h" +#endif // ESP_IDF_VERSION_MAJOR >= 5 #define PIN_TO_BASEREG(pin) (0) #define PIN_TO_BITMASK(pin) (pin) #define IO_REG_TYPE uint32_t @@ -156,7 +159,7 @@ static inline __attribute__((always_inline)) IO_REG_TYPE directRead(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 // max. usable Pins are 23 for C6 (below flash pins) return (GPIO.in.val >> pin) & 0x1; #else // plain ESP32 if ( pin < 32 ) @@ -171,7 +174,7 @@ IO_REG_TYPE directRead(IO_REG_TYPE pin) static inline __attribute__((always_inline)) void directWriteLow(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 GPIO.out_w1tc.val = ((uint32_t)1 << pin); #else // plain ESP32 if ( pin < 32 ) @@ -184,7 +187,7 @@ void directWriteLow(IO_REG_TYPE pin) static inline __attribute__((always_inline)) void directWriteHigh(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 GPIO.out_w1ts.val = ((uint32_t)1 << pin); #else // plain ESP32 if ( pin < 32 ) @@ -197,7 +200,7 @@ void directWriteHigh(IO_REG_TYPE pin) static inline __attribute__((always_inline)) void directModeInput(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 GPIO.enable_w1tc.val = ((uint32_t)1 << (pin)); #else if ( digitalPinIsValid(pin) ) @@ -223,7 +226,7 @@ void directModeInput(IO_REG_TYPE pin) static inline __attribute__((always_inline)) void directModeOutput(IO_REG_TYPE pin) { -#if CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 GPIO.enable_w1ts.val = ((uint32_t)1 << (pin)); #else if ( digitalPinIsValid(pin) && pin <= 33 ) // pins above 33 can be only inputs @@ -550,4 +553,4 @@ class OneWire #endif }; -#endif +#endif \ No newline at end of file diff --git a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp index 1cd9a9de3d89..57a0a67a92d1 100644 --- a/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp +++ b/lib/lib_i2c/Adafruit_TSL2591_Library/Adafruit_TSL2591.cpp @@ -214,7 +214,7 @@ void Adafruit_TSL2591::setGain(tsl2591Gain_t gain) enable(); _gain = gain; - write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain); + write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, static_cast(_integration) | static_cast(_gain)); disable(); } @@ -245,7 +245,7 @@ void Adafruit_TSL2591::setTiming(tsl2591IntegrationTime_t integration) enable(); _integration = integration; - write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, _integration | _gain); + write8(TSL2591_COMMAND_BIT | TSL2591_REGISTER_CONTROL, static_cast(_integration) | static_cast(_gain)); disable(); } diff --git a/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.cpp b/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.cpp index f0e324eb8ede..a44a9cd324d4 100644 --- a/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.cpp +++ b/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.cpp @@ -47,7 +47,7 @@ bool Tsl2561::begin() { bool Tsl2561::readByte( register_t reg, uint8_t &val ) { _wire.beginTransmission(_addr); - _wire.write(reg | CONTROL_CMD); + _wire.write(reg | static_cast(CONTROL_CMD)); if( (_status = static_cast(_wire.endTransmission(false))) == ERR_OK ) { if( _wire.requestFrom(_addr, 1) == 1 ) { val = static_cast(_wire.read()); @@ -61,7 +61,7 @@ bool Tsl2561::readByte( register_t reg, uint8_t &val ) { bool Tsl2561::readWord( register_t reg, uint16_t &val ) { _wire.beginTransmission(_addr); - _wire.write(reg | CONTROL_CMD); + _wire.write(reg | static_cast(CONTROL_CMD)); if( (_status = static_cast(_wire.endTransmission(false))) == ERR_OK ) { if( _wire.requestFrom(_addr, 2) == 2 ) { val = static_cast(_wire.read()) & 0xff; @@ -76,7 +76,7 @@ bool Tsl2561::readWord( register_t reg, uint16_t &val ) { bool Tsl2561::writeByte( register_t reg, uint8_t val ) { _wire.beginTransmission(_addr); - _wire.write(reg | CONTROL_CMD); + _wire.write(reg | static_cast(CONTROL_CMD)); _wire.write(val); return (_status = static_cast(_wire.endTransmission())) == ERR_OK; } @@ -118,7 +118,7 @@ bool Tsl2561::off() { } bool Tsl2561::setSensitivity( bool gain, exposure_t exposure ) { - return writeByte(REG_TIMING, (gain ? GAIN_ON : GAIN_OFF) | exposure); + return writeByte(REG_TIMING, (gain ? GAIN_ON : GAIN_OFF) | static_cast(exposure)); } bool Tsl2561::getSensitivity( bool &gain, exposure_t &exposure ) diff --git a/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.h b/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.h index 147db2a7769d..84f86ee2729c 100644 --- a/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.h +++ b/lib/lib_i2c/Joba_Tsl2561-2.0.10/src/Tsl2561.h @@ -42,7 +42,7 @@ class Tsl2561 { ADDR_VDD = 0b1001001 } address_t; - typedef enum { + typedef enum : uint8_t { REG_CONTROL, // Control of basic functions REG_TIMING, // Integration time/gain control REG_THRESHLOWLOW, // Low byte of low interrupt threshold @@ -61,7 +61,7 @@ class Tsl2561 { REG_DATA1HIGH // High byte of ADC channel 1 } register_t; - enum { + enum : uint8_t{ CONTROL_CMD = 0b10000000, CONTROL_CLEAR = 0b01000000, CONTROL_WORD = 0b00100000, // SPI only? diff --git a/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcTxFrame.cpp b/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcTxFrame.cpp index fc8c4c9944fd..9efc5d824361 100644 --- a/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcTxFrame.cpp +++ b/lib/lib_i2c/Sensirion_Core/src/SensirionShdlcTxFrame.cpp @@ -53,7 +53,7 @@ uint16_t SensirionShdlcTxFrame::finish(void) { return error; } if (_index + 1 > _bufferSize) { - return TxFrameError | BufferSizeError; + return static_cast(TxFrameError) | BufferSizeError; } _buffer[_index++] = 0x7e; _isFinished = true; @@ -84,7 +84,7 @@ uint16_t SensirionShdlcTxFrame::addInt16(int16_t data) { uint16_t SensirionShdlcTxFrame::addUInt8(uint8_t data) { if (_index + 2 > _bufferSize) { - return TxFrameError | BufferSizeError; + return static_cast(TxFrameError) | BufferSizeError; } switch (data) { case 0x11: diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h index 07bc9c2d5c2e..8cae8d49955d 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -126,7 +126,12 @@ uint32_t analogGetTimerFrequency(uint8_t timer); #define ESPhttpUpdate httpUpdate +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "rom/ets_sys.h" +#else #define os_delay_us ets_delay_us +#endif + // Serial minimal type to hold the config typedef int SerConfu8; //typedef int SerialConfig; // Will be replaced enum in esp32_hal-uart.h (#7926) diff --git a/lib/libesp32/berry_int64/library.json b/lib/libesp32/berry_int64/library.json index 8fe3f3258273..6c72492e12ef 100644 --- a/lib/libesp32/berry_int64/library.json +++ b/lib/libesp32/berry_int64/library.json @@ -1,5 +1,5 @@ { - "name": "Berry int64 implementation for 32 bits architceture", + "name": "Berry int64 implementation for 32 bits architecture", "version": "1.0", "description": "Berry int64", "license": "MIT", diff --git a/partitions/esp32_partition_app1245k_fs64k.csv b/partitions/esp32_partition_app1245k_fs64k.csv new file mode 100644 index 000000000000..587d7ccb04a3 --- /dev/null +++ b/partitions/esp32_partition_app1245k_fs64k.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +safeboot, app, factory, 0x10000, 0xB0000, +app0, app, ota_0, 0xC0000, 0x130000, +spiffs, data, spiffs, 0x1f0000,0x10000, diff --git a/pio-tools/add_c_flags.py b/pio-tools/add_c_flags.py index 020a77f82a68..40d8a3937abb 100644 --- a/pio-tools/add_c_flags.py +++ b/pio-tools/add_c_flags.py @@ -4,4 +4,4 @@ env.Append(CFLAGS=["-Wno-discarded-qualifiers", "-Wno-implicit-function-declaration"]) # General options that are passed to the C++ compiler -env.Append(CXXFLAGS=["-Wno-volatile"]) \ No newline at end of file +env.Append(CXXFLAGS=["-Wno-volatile"]) diff --git a/pio-tools/pre_source_dir.py b/pio-tools/pre_source_dir.py index 6027d2ba9628..8ff1e8753f54 100644 --- a/pio-tools/pre_source_dir.py +++ b/pio-tools/pre_source_dir.py @@ -10,3 +10,8 @@ def FindInoNodes(env): ) env.AddMethod(FindInoNodes) + +# Pass flashmode at build time to macro +tasmota_flash_mode = "-DCONFIG_TASMOTA_FLASHMODE_" + (env.BoardConfig().get("build.flash_mode", "dio")).upper() +env.Append(CXXFLAGS=[tasmota_flash_mode]) +print(tasmota_flash_mode) diff --git a/platformio.ini b/platformio.ini index 83d80aa24575..bd648897b93b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,6 +24,7 @@ extra_configs = platformio_tasmota32.ini platformio_tasmota_env32.ini platformio_override.ini platformio_tasmota_cenv.ini + platformio_tasmota_core3_env.ini [common] platform = ${core.platform} diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 3aa0503dcc54..6d0d273bd671 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -42,8 +42,28 @@ extra_scripts = pre:pio-tools/add_c_flags.py post:pio-tools/post_esp32.py ${esp_defaults.extra_scripts} +[safeboot_flags] +lib_ignore = ESP Mail Client + IRremoteESP8266 + NeoPixelBus + OneWire + MFRC522 + universal display Library + ESP8266Audio + ESP8266SAM + FFat + Berry + Berry mapping to C + Berry Tasmota mapping + Berry int64 implementation for 32 bits architecture + Berry Matter protocol implementation + Micro-RTSP + re1.5 + DHT sensor library + ccronexpr + [core32] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.07.00/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.08.00/platform-espressif32.zip platform_packages = build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini index 0c2d57c92f0a..ed427a6edfb3 100644 --- a/platformio_tasmota_cenv_sample.ini +++ b/platformio_tasmota_cenv_sample.ini @@ -1,51 +1,3 @@ -[env:tasmota32c3-arduino30] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 -#platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1481/framework-arduinoespressif32-release_v5.1-69cdc81680.zip -extends = env:tasmota32_base -board = esp32c3 -build_unflags = ${env:tasmota32_base.build_unflags} - -DUSE_IPV6 - -flto - -mtarget-align -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_ARDUINO30 - -fno-lto - -DOTA_URL='""' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - ESP Mail Client - IRremoteESP8266 - NeoPixelBus - OneWire - MFRC522 - universal display Library - ESP8266Audio - ESP8266SAM - -[env:tasmota32c3-safeboot] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 -#platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1481/framework-arduinoespressif32-release_v5.1-69cdc81680.zip -extends = env:tasmota32_base -board = esp32c3 -build_unflags = ${env:tasmota32_base.build_unflags} - -DUSE_IPV6 - -flto - -mtarget-align -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -fno-lto - -DOTA_URL='""' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - ESP Mail Client - IRremoteESP8266 - NeoPixelBus - OneWire - MFRC522 - universal display Library - ESP8266Audio - ESP8266SAM - [env:tasmota-rangeextender] build_flags = ${env.build_flags} -DFIRMWARE_RANGE_EXTENDER diff --git a/platformio_tasmota_core3_env.ini b/platformio_tasmota_core3_env.ini new file mode 100644 index 000000000000..7d45687bb649 --- /dev/null +++ b/platformio_tasmota_core3_env.ini @@ -0,0 +1,193 @@ +[platformio] +; *** Build/upload environments for ESP32 Arduino Core 3.0 +; *** Renaming the file extension of this file from`ini`to `off` disables Arduino 3.0 support + +; *** Uncomment the line below and one or more env to select version(s) +; *** Uncomment of Platform in section [core32] is needed too to use Arduino Core 3.0 !! +default_envs = + tasmota32-arduino30 +; tasmota32s2-arduino30 +; tasmota32s3-arduino30 +; tasmota32c2-arduino30 +; tasmota32c3-arduino30 +; tasmota32c6-arduino30 +; tasmota32-safeboot +; tasmota32s2-safeboot +; tasmota32s3-safeboot +; tasmota32c2-safeboot +; tasmota32c3-safeboot +; tasmota32c6-safeboot + +[core32] +; *** Uncomment the line below to use Arduino Core 3.0 !! +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1494/framework-arduinoespressif32-release_v5.1-48aa82cc16.zip + +[esp32_arduino30] +build_unflags = ${esp32_defaults.build_unflags} + -DUSE_IPV6 + +[env:tasmota32-arduino30] +extends = env:tasmota32_base +board = esp32 +build_unflags = ${esp32_arduino30.build_unflags} +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_ARDUINO30 +monitor_filters = esp32_exception_decoder +lib_extra_dirs = lib/lib_ssl, lib/lib_basic, lib/lib_i2c, lib/libesp32, lib/libesp32_div +lib_ignore = ESP Mail Client + IRremoteESP8266 + MFRC522 + universal display Library + ESP8266Audio + ESP8266SAM + ESP32-HomeKit + +[env:tasmota32s2-arduino30] +extends = env:tasmota32_base +board = esp32s2 +build_unflags = ${esp32_arduino30.build_unflags} +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_ARDUINO30 +monitor_filters = esp32_exception_decoder +lib_extra_dirs = lib/lib_ssl, lib/lib_basic, lib/libesp32 +lib_ignore = ESP Mail Client + IRremoteESP8266 + MFRC522 + universal display Library + ESP8266Audio + ESP8266SAM + ESP32-HomeKit + +[env:tasmota32s3-arduino30] +extends = env:tasmota32_base +board = esp32s3-qio_qspi +build_unflags = ${esp32_arduino30.build_unflags} +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_ARDUINO30 +monitor_filters = esp32_exception_decoder +lib_extra_dirs = lib/lib_ssl, lib/lib_basic, lib/lib_i2c, lib/libesp32 +lib_ignore = ESP Mail Client + IRremoteESP8266 + MFRC522 + universal display Library + ESP8266Audio + ESP8266SAM + ESP32-HomeKit + + +[env:tasmota32c2-arduino30] +extends = env:tasmota32_base +board = esp32c2 +build_unflags = ${esp32_arduino30.build_unflags} + -flto + -mtarget-align +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_ARDUINO30 + -fno-lto + -DOTA_URL='""' +monitor_filters = esp32_exception_decoder +lib_extra_dirs = lib/lib_ssl, lib/lib_basic, lib/lib_i2c, lib/libesp32 +lib_ignore = + ESP Mail Client + IRremoteESP8266 + NeoPixelBus + MFRC522 + universal display Library + ESP8266Audio + ESP8266SAM + ESP32-HomeKit + +[env:tasmota32c3-arduino30] +extends = env:tasmota32_base +board = esp32c3 +build_unflags = ${esp32_arduino30.build_unflags} + -flto + -mtarget-align +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_ARDUINO30 + -fno-lto +monitor_filters = esp32_exception_decoder +lib_extra_dirs = lib/lib_ssl, lib/lib_basic, lib/lib_i2c, lib/libesp32 +lib_ignore = + ESP Mail Client + IRremoteESP8266 + MFRC522 + universal display Library + ESP8266Audio + ESP8266SAM + ESP32-HomeKit + +[env:tasmota32c6-arduino30] +extends = env:tasmota32_base +board = esp32c6 +build_unflags = ${esp32_arduino30.build_unflags} + -flto + -mtarget-align +build_flags = ${env:tasmota32_base.build_flags} + -fno-lto + -DFIRMWARE_ARDUINO30 + -DOTA_URL='""' +monitor_filters = esp32_exception_decoder +lib_extra_dirs = lib/lib_ssl, lib/lib_basic, lib/lib_i2c, lib/libesp32 +lib_ignore = ESP Mail Client + IRremoteESP8266 + MFRC522 + universal display Library + ESP8266Audio + ESP8266SAM + ESP32-HomeKit + +[env:tasmota32-safeboot] +extends = env:tasmota32-arduino30 +build_unflags = ${env:tasmota32-arduino30.build_unflags} + -DFIRMWARE_ARDUINO30 +build_flags = ${env:tasmota32-arduino30.build_flags} + -DFIRMWARE_SAFEBOOT +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32s2-safeboot] +extends = env:tasmota32s2-arduino30 +build_unflags = ${env:tasmota32s2-arduino30.build_unflags} + -DFIRMWARE_ARDUINO30 +build_flags = ${env:tasmota32s2-arduino30.build_flags} + -DFIRMWARE_SAFEBOOT +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32s3-safeboot] +extends = env:tasmota32s3-arduino30 +build_unflags = ${env:tasmota32s3-arduino30.build_unflags} + -DFIRMWARE_ARDUINO30 +build_flags = ${env:tasmota32s3-arduino30.build_flags} + -DFIRMWARE_SAFEBOOT +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32c2-safeboot] +extends = env:tasmota32c2-arduino30 +build_unflags = ${env:tasmota32c2-arduino30.build_unflags} + -DFIRMWARE_ARDUINO30 +build_flags = ${env:tasmota32c2-arduino30.build_flags} + -DFIRMWARE_SAFEBOOT +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32c3-safeboot] +extends = env:tasmota32c3-arduino30 +build_unflags = ${env:tasmota32c3-arduino30.build_unflags} + -DFIRMWARE_ARDUINO30 +build_flags = ${env:tasmota32c3-arduino30.build_flags} + -DFIRMWARE_SAFEBOOT +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32c6-safeboot] +extends = env:tasmota32c6-arduino30 +build_unflags = ${env:tasmota32c6-arduino30.build_unflags} + -DFIRMWARE_ARDUINO30 +build_flags = ${env:tasmota32c6-arduino30.build_flags} + -DFIRMWARE_SAFEBOOT +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 2322270f3e1e..3139e79d50af 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -15,8 +15,6 @@ lib_compat_mode = ${common.lib_compat_mode} lib_extra_dirs = ${common.lib_extra_dirs} lib/libesp32 lib/libesp32_lvgl - lib/libesp32_div - lib/libesp32_eink lib/libesp32_audio lib_ignore = HTTPUpdateServer @@ -40,86 +38,13 @@ lib_ignore = ; tasmota/berry/modules/Partition_Manager.tapp custom_files_upload = no_files -[env:tasmota32-arduino30] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 -#platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1481/framework-arduinoespressif32-release_v5.1-69cdc81680.zip -extends = env:tasmota32_base -board = esp32 -build_unflags = ${env:tasmota32_base.build_unflags} - -DUSE_IPV6 -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_ARDUINO30 - -DOTA_URL='""' -monitor_filters = esp32_exception_decoder -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - ESP Mail Client - IRremoteESP8266 - NeoPixelBus - OneWire - MFRC522 - universal display Library - ESP8266Audio - ESP8266SAM - -[env:tasmota32c6-arduino30] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 -#platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1481/framework-arduinoespressif32-release_v5.1-69cdc81680.zip -extends = env:tasmota32_base -board = esp32c6 -build_unflags = ${env:tasmota32_base.build_unflags} - -DUSE_IPV6 - -flto - -mtarget-align -build_flags = ${env:tasmota32_base.build_flags} - -fno-lto - -DFIRMWARE_ARDUINO30 - -DOTA_URL='""' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - ESP Mail Client - IRremoteESP8266 - NeoPixelBus - OneWire - MFRC522 - universal display Library - ESP8266Audio - ESP8266SAM - -[env:tasmota32c6-safeboot] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 -#platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1481/framework-arduinoespressif32-release_v5.1-69cdc81680.zip -extends = env:tasmota32_base -board = esp32c6 -build_unflags = ${env:tasmota32_base.build_unflags} - -DUSE_IPV6 - -flto - -mtarget-align -build_flags = ${env:tasmota32_base.build_flags} - -fno-lto - -DFIRMWARE_SAFEBOOT - -DOTA_URL='""' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - ESP Mail Client - IRremoteESP8266 - NeoPixelBus - OneWire - MFRC522 - universal display Library - ESP8266Audio - ESP8266SAM - [env:tasmota32-safeboot] extends = env:tasmota32_base build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-safeboot.bin"' lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - Micro-RTSP - ESP Mail Client - DHT sensor library +lib_ignore = ${safeboot_flags.lib_ignore} [env:tasmota32] extends = env:tasmota32_base @@ -204,10 +129,7 @@ build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32solo1-safeboot.bin"' lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - Micro-RTSP - ESP Mail Client - DHT sensor library +lib_ignore = ${safeboot_flags.lib_ignore} [env:tasmota32-zbbrdgpro] extends = env:tasmota32_base @@ -242,10 +164,7 @@ build_flags = ${env:tasmota32_base.build_flags} -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c3-safeboot.bin"' -fno-lto lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - Micro-RTSP - ESP Mail Client - DHT sensor library +lib_ignore = ${safeboot_flags.lib_ignore} [env:tasmota32c3] extends = env:tasmota32_base @@ -285,10 +204,7 @@ build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s2-safeboot.bin"' lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - Micro-RTSP - ESP Mail Client - DHT sensor library +lib_ignore = ${safeboot_flags.lib_ignore} [env:tasmota32s2] extends = env:tasmota32_base @@ -323,10 +239,7 @@ build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s3-safeboot.bin"' lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = - Micro-RTSP - ESP Mail Client - DHT sensor library +lib_ignore = ${safeboot_flags.lib_ignore} [env:tasmota32s3] extends = env:tasmota32_base diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h index 9daf1e90c653..b7023774c99f 100644 --- a/tasmota/include/i18n.h +++ b/tasmota/include/i18n.h @@ -824,6 +824,8 @@ #define D_LOG_TCP "TCP: " // TCP bridge #define D_LOG_BERRY "BRY: " // Berry scripting language #define D_LOG_LVGL "LVG: " // LVGL graphics engine +#define D_LOG_THERMOSTAT "THE: " // Thermostat driver +#define D_LOG_SENSOR "SNS: " // Sensor driver /********************************************************************************************/ diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index bbbfd60dbd13..c7a705844856 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -68,10 +68,8 @@ const uint8_t MAX_PWMS_LEGACY = 5; // Max number of PWM channels in fir const uint8_t MAX_PWMS = 8; // ESP32S2: 8 ledc PWM channels in total #elif defined(CONFIG_IDF_TARGET_ESP32S3) const uint8_t MAX_PWMS = 8; // ESP32S3: 8 ledc PWM channels in total - #elif defined(CONFIG_IDF_TARGET_ESP32C3) - const uint8_t MAX_PWMS = 6; // ESP32C3: 6 ledc PWM channels in total - #elif defined(CONFIG_IDF_TARGET_ESP32C6) - const uint8_t MAX_PWMS = 6; // ESP32C6: 6 ledc PWM channels in total + #elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6) + const uint8_t MAX_PWMS = 6; // ESP32C2/C3/C6: 6 ledc PWM channels in total #else const uint8_t MAX_PWMS = 5; // Unknown - revert to 5 PWM max #endif @@ -142,8 +140,8 @@ const uint8_t MAX_ADCS = 1; // Max number of ESP8266 ADC pins const uint8_t MAX_SWITCHES_TXT = 8; // Max number of switches user text #endif // ESP8266 #ifdef ESP32 -#ifdef CONFIG_IDF_TARGET_ESP32C3 -const uint8_t MAX_ADCS = 5; // Max number of ESP32-C3 ADC pins (ADC2 pins are unusable with Wifi enabled) +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) +const uint8_t MAX_ADCS = 5; // Max number of ESP32-C2/C3 ADC pins (ADC2 pins are unusable with Wifi enabled) #elif CONFIG_IDF_TARGET_ESP32C6 const uint8_t MAX_ADCS = 7; // Max number of ESP32-C6 ADC pins (ADC2 pins are unusable with Wifi enabled) #else // ESP32 @@ -325,7 +323,7 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to #define WIFI_SENSITIVITY_11b -880 #define WIFI_SENSITIVITY_54g -760 #define WIFI_SENSITIVITY_n -720 - #elif defined(CONFIG_IDF_TARGET_ESP32C3) + #elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) #define MAX_TX_PWR_DBM_11b 210 #define MAX_TX_PWR_DBM_54g 190 #define MAX_TX_PWR_DBM_n 185 diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index 21fc5c0ce0b1..9d353035c0cb 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -200,7 +200,6 @@ #define CODE_IMAGE_STR "arduino30" #endif - #undef FIRMWARE_LITE // Disable tasmota-lite with no sensors #undef FIRMWARE_SENSORS // Disable tasmota-sensors with useful sensors enabled #undef FIRMWARE_KNX_NO_EMULATION // Disable tasmota-knx with KNX but without Emulation @@ -238,21 +237,19 @@ #undef USE_SONOFF_D1 // Disable support for Sonoff D1 Dimmer (+0k7 code) #undef USE_SHELLY_DIMMER // Disable support for Shelly Dimmer (+3k code) -#undef USE_LIGHT // Disable support for lights -#undef USE_WS2812 +#define USE_LIGHT // Disable support for lights +#define USE_WS2812 -#undef USE_DS18x20 // Disable DS18x20 sensor +#define USE_DS18x20 // Enable DS18x20 sensor #undef USE_I2C // Disable all I2C sensors and devices +#define USE_COUNTER #undef USE_ENERGY_SENSOR // Disable energy sensors #undef USE_IR_REMOTE // Disable IR driver -#undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer -#undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer - -#undef USE_AC_ZERO_CROSS_DIMMER // Disable support for AC_ZERO_CROSS_DIMMER +#undef USE_AC_ZERO_CROSS_DIMMER // API for timers has changed with IDF 5.x #define USE_TLS #define USE_WEBSERVER diff --git a/tasmota/include/tasmota_globals.h b/tasmota/include/tasmota_globals.h index 3718a7e47d18..0965c0f7e95d 100644 --- a/tasmota/include/tasmota_globals.h +++ b/tasmota/include/tasmota_globals.h @@ -69,6 +69,23 @@ String EthernetMacAddress(void); #include "include/tasmota_configurations.h" // Preconfigured configurations +/*-------------------------------------------------------------------------------------------*\ + * ESP8266 and ESP32 build time definitions +\*-------------------------------------------------------------------------------------------*/ + +// created in pio-tools/pre_source_dir.py +#if defined(CONFIG_TASMOTA_FLASHMODE_QIO) + #define D_TASMOTA_FLASHMODE "QIO" +#elif defined(CONFIG_TASMOTA_FLASHMODE_QOUT) + #define D_TASMOTA_FLASHMODE "QOUT" +#elif defined(CONFIG_TASMOTA_FLASHMODE_DIO) + #define D_TASMOTA_FLASHMODE "DIO" +#elif defined(CONFIG_TASMOTA_FLASHMODE_DOUT) + #define D_TASMOTA_FLASHMODE "DOUT" +#else +#error "Please add missing flashmode definition in the lines above!" // could be upcoming octal modes +#endif // value check of CONFIG_TASMOTA_FLASHMODE + /*********************************************************************************************\ * ESP8266 specific parameters \*********************************************************************************************/ @@ -118,6 +135,7 @@ String EthernetMacAddress(void); /*-------------------------------------------------------------------------------------------*\ * End ESP32 specific parameters \*-------------------------------------------------------------------------------------------*/ + /*-------------------------------------------------------------------------------------------*\ * Start ESP32-C32 specific parameters - disable features not present in ESP32-C3 \*-------------------------------------------------------------------------------------------*/ diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 009934be739b..97696eaab796 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -1258,7 +1258,20 @@ typedef struct MYTMPLT8266 { #endif // ESP8266 #ifdef ESP32 -#ifdef CONFIG_IDF_TARGET_ESP32C3 +#if defined(CONFIG_IDF_TARGET_ESP32C2) + +/* **************************************** + * ESP32C2 + * ****************************************/ +#define MAX_GPIO_PIN 21 // Number of supported GPIO +#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration +#define MAX_USER_PINS 21 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 91011121314151617181920 +const char PINS_WEMOS[] PROGMEM = "AOAOAOAOAOIOIOIOIOIOIOFLFLFLFLFLFLFLIORXTX"; + +#elif defined(CONFIG_IDF_TARGET_ESP32C3) /* **************************************** * ESP32C3 @@ -1271,6 +1284,18 @@ typedef struct MYTMPLT8266 { // 0 1 2 3 4 5 6 7 8 9101112131415161718192021 const char PINS_WEMOS[] PROGMEM = "AOAOAOAOAOAOIOIOIOIOIOFLFLFLFLFLFLFLIOIORXTX"; +#elif defined(CONFIG_IDF_TARGET_ESP32C6) + +/* **************************************** + * ESP32C3 + * ****************************************/ +#define MAX_GPIO_PIN 31 // Number of supported GPIO +#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration (GPIO11 to 17) +#define MAX_USER_PINS 31 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031 +const char PINS_WEMOS[] PROGMEM = "AOAOAOAOAOAOAOIOIOIO----IOIOIOIOIOIOIOIOIOIOIOIOFLFLFLFLFLFLFLFL"; #elif defined(CONFIG_IDF_TARGET_ESP32S2) /* **************************************** @@ -2791,7 +2816,61 @@ const mytmplt8285 kModules8285[TMP_MAXMODULE_8266 - TMP_WEMOS] PROGMEM = { #endif // ESP8266 #ifdef ESP32 -#ifdef CONFIG_IDF_TARGET_ESP32C3 +#ifdef CONFIG_IDF_TARGET_ESP32C2 +/********************************************************************************************\ + * ESP32-C2 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported hardware modules +enum SupportedModulesESP32C2 { + WEMOS, // not really correct, a placeholder for now + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32C2|" + ; + +// !!! Update this list in the same order as SupportedModulesESP32C2 !!! +const mytmplt kModules[] PROGMEM = { + { // Generic ESP32C2 device + AGPIO(GPIO_USER), // 0 IO GPIO0, ADC1_CH0, RTC + AGPIO(GPIO_USER), // 1 IO GPIO1, ADC1_CH1, RTC + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC1_CH2, RTC + AGPIO(GPIO_USER), // 3 IO GPIO3, ADC1_CH3, RTC + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC1_CH4, RTC + AGPIO(GPIO_USER), // 5 IO GPIO5, RTC + AGPIO(GPIO_USER), // 6 IO GPIO6, + AGPIO(GPIO_USER), // 7 IO GPIO7, + AGPIO(GPIO_USER), // 8 IO GPIO8, Strapping + AGPIO(GPIO_USER), // 9 IO GPIO9, Strapping + AGPIO(GPIO_USER), // 10 IO GPIO10 + 0, // 11 IO GPIO11, output power supply for flash + 0, // 12 IO GPIO12, SPIHD + 0, // 13 IO GPIO13, SPIWP + 0, // 14 IO GPIO14, SPICS0 + 0, // 15 IO GPIO15, SPICLK + 0, // 16 IO GPIO16, SPID + 0, // 17 IO GPIO17, SPIQ + AGPIO(GPIO_USER), // 18 IO GPIO18, + AGPIO(GPIO_USER), // 19 IO GPIO19, U0RXD + AGPIO(GPIO_USER), // 20 IO GPIO20, U0TXD + 0 // Flag + }, +}; + +/*********************************************************************************************\ + Known templates +\*********************************************************************************************/ + +#elif CONFIG_IDF_TARGET_ESP32C3 /********************************************************************************************\ * ESP32-C3 Module templates \********************************************************************************************/ @@ -2846,6 +2925,70 @@ const mytmplt kModules[] PROGMEM = { Known templates \*********************************************************************************************/ +#elif CONFIG_IDF_TARGET_ESP32C6 +/********************************************************************************************\ + * ESP32-C6 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported hardware modules +enum SupportedModulesESP32C6 { + WEMOS, // not really correct, a placeholder for now + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32C6|" + ; + +// !!! Update this list in the same order as SupportedModulesESP32C2 !!! +const mytmplt kModules[] PROGMEM = { + { // Generic ESP32C2 device + AGPIO(GPIO_USER), // 0 IO GPIO0, ADC1_CH0, LP_GPIO0 + AGPIO(GPIO_USER), // 1 IO GPIO1, ADC1_CH1, LP_GPIO1 + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC1_CH2, LP_GPIO2 + AGPIO(GPIO_USER), // 3 IO GPIO3, ADC1_CH3, LP_GPIO3 + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC1_CH4, LP_GPIO4 , Strapping + AGPIO(GPIO_USER), // 5 IO GPIO5, ADC1_CH5, LP_GPIO5 , Strapping + AGPIO(GPIO_USER), // 6 IO GPIO6, ADC1_CH6, LP_GPIO6 + AGPIO(GPIO_USER), // 7 IO GPIO7, LP_GPIO7 + AGPIO(GPIO_USER), // 8 IO GPIO8, Strapping + AGPIO(GPIO_USER), // 9 IO GPIO9, Strapping + 0, // 10 IO not led out to any chip pins + 0, // 11 IO not led out to any chip pins + AGPIO(GPIO_USER), // 12 IO GPIO12, USB-JTAG + AGPIO(GPIO_USER), // 13 IO GPIO13, USB-JTAG + AGPIO(GPIO_USER), // 14 IO GPIO14, may be not led out + AGPIO(GPIO_USER), // 15 IO GPIO15, SPICLK + AGPIO(GPIO_USER), // 16 IO GPIO16, SPID + AGPIO(GPIO_USER), // 17 IO GPIO17, SPIQ + AGPIO(GPIO_USER), // 18 IO GPIO18, + AGPIO(GPIO_USER), // 19 IO GPIO19, U0RXD + AGPIO(GPIO_USER), // 20 IO GPIO20, U0TXD + AGPIO(GPIO_USER), // 21 IO GPIO18, + AGPIO(GPIO_USER), // 22 IO GPIO19, U0RXD + AGPIO(GPIO_USER), // 23 IO GPIO20, U0TXD + 0, // 24 IO GPIO18, SPI-FLASH + 0, // 25 IO GPIO19, SPI-FLASH + 0, // 26 IO GPIO20, SPI-FLASH + 0, // 27 IO GPIO20, SPI-FLASH + 0, // 28 IO GPIO18, SPI-FLASH + 0, // 29 IO GPIO19, SPI-FLASH + 0, // 30 IO GPIO20, SPI-FLASH + 0 // Flag + }, +}; + +/*********************************************************************************************\ + Known templates +\*********************************************************************************************/ + #elif defined(CONFIG_IDF_TARGET_ESP32S2) /********************************************************************************************\ diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index ef5fc44f4bb5..e85092d0c63e 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -608,9 +608,12 @@ typedef struct { uint8_t free_esp8266_3D2[42]; // 3D2 #endif // ESP8266 #ifdef ESP32 -#ifdef CONFIG_IDF_TARGET_ESP32C3 +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) uint8_t free_esp32c3_3D8[36]; // 3D8 - Due to smaller myio #endif // CONFIG_IDF_TARGET_ESP32C3 +#if defined(CONFIG_IDF_TARGET_ESP32C6) // TODO: Very unsure, that this is okay!! + uint8_t free_esp32c3_3D8[28]; // 3D8 - Due to smaller myio +#endif // CONFIG_IDF_TARGET_ESP32C6 #endif // ESP32 mytmplt user_template; // 3FC 2x15 bytes (ESP8266) / 2x37 bytes (ESP32) / 2x23 bytes (ESP32-C3) / 2x37 bytes (ESP32-S2) #ifdef ESP8266 @@ -620,7 +623,12 @@ typedef struct { #ifdef CONFIG_IDF_TARGET_ESP32C3 uint8_t free_esp32c3_42A[28]; // 42A - Due to smaller mytmplt #endif // CONFIG_IDF_TARGET_ESP32C3 - +#ifdef CONFIG_IDF_TARGET_ESP32C2 + uint8_t free_esp32c3_42A[29]; // 42A - Due to smaller mytmplt +#endif // CONFIG_IDF_TARGET_ESP32C2 +#ifdef CONFIG_IDF_TARGET_ESP32C6 + uint8_t free_esp32c3_42A[0]; // 42A - Due to smaller mytmplt +#endif // CONFIG_IDF_TARGET_ESP32C6 uint8_t eth_type; // 446 uint8_t eth_clk_mode; // 447 diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 14d021c89016..a5793dc77479 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -20,6 +20,6 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x0D000004; // 13.0.0.4 +const uint32_t VERSION = 0x0D010001; // 13.1.0.1 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 31e3e59350f3..e53b0c1728b9 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -1062,7 +1062,7 @@ #define THERMOSTAT_TIME_STD_DEV_PEAK_DET_OK 10 // Default standard deviation in minutes of the oscillation periods within the peak detection is successful // -- PID and Timeprop ------------------------------ // Both together will add +12k1 code -// #define use TIMEPROP // Add support for the timeprop feature (+9k1 code) +// #define USE_TIMEPROP // Add support for the timeprop feature (+9k1 code) // For details on the configuration please see the header of tasmota/xdrv_48_timeprop.ino // #define USE_PID // Add suport for the PID feature (+11k2 code) // For details on the configuration please see the header of tasmota/xdrv_49_pid.ino diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index e6ac6e6b8af8..0e20d6e50bd0 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -543,6 +543,10 @@ bool SettingsConfigRestore(void) { valid_settings = (3 == settings_buffer[0xF36]); // Settings->config_version ESP32S2 #elif CONFIG_IDF_TARGET_ESP32C3 valid_settings = (4 == settings_buffer[0xF36]); // Settings->config_version ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32C2 + valid_settings = (5 == settings_buffer[0xF36]); // Settings->config_version ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C6 + valid_settings = (6 == settings_buffer[0xF36]); // Settings->config_version ESP32C6 #else valid_settings = (1 == settings_buffer[0xF36]); // Settings->config_version ESP32 all other #endif // CONFIG_IDF_TARGET_ESP32S3 @@ -962,6 +966,10 @@ void SettingsDefaultSet2(void) { Settings->config_version = 3; // ESP32S2 #elif CONFIG_IDF_TARGET_ESP32C3 Settings->config_version = 4; // ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32C2 + Settings->config_version = 5; // ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C6 + Settings->config_version = 6; // ESP32C6 #else Settings->config_version = 1; // ESP32 #endif // CONFIG_IDF_TARGET_ESP32S3 @@ -1526,6 +1534,10 @@ void SettingsDelta(void) { Settings->config_version = 3; // ESP32S2 #elif CONFIG_IDF_TARGET_ESP32C3 Settings->config_version = 4; // ESP32C3 +#elif CONFIG_IDF_TARGET_ESP32C2 + Settings->config_version = 5; // ESP32C2 +#elif CONFIG_IDF_TARGET_ESP32C6 + Settings->config_version = 6; // ESP32C6 #else Settings->config_version = 1; // ESP32 #endif // CONFIG_IDF_TARGET_ESP32S3 @@ -1604,7 +1616,7 @@ void SettingsDelta(void) { if (Settings->version < 0x09040006) { Settings->mqtt_wifi_timeout = MQTT_WIFI_CLIENT_TIMEOUT / 100; } -#ifdef CONFIG_IDF_TARGET_ESP32C3 +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6) if (Settings->version < 0x09050002) { if (Settings->cfg_size != sizeof(TSettings)) { // Fix onetime Settings layout due to changed ESP32-C3 myio and mytmplt types sizes diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index dfe742d08445..ff1a1174e62b 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -1410,8 +1410,7 @@ void ConvertGpios(void) { } #endif // ESP8266 -int IRAM_ATTR Pin(uint32_t gpio, uint32_t index = 0); -int IRAM_ATTR Pin(uint32_t gpio, uint32_t index) { +int IRAM_ATTR Pin(uint32_t gpio, uint32_t index = 0) { uint16_t real_gpio = gpio << 5; uint16_t mask = 0xFFE0; if (index < GPIO_ANY) { @@ -1589,8 +1588,12 @@ void TemplateGpios(myio *gp) // Expand template to physical GPIO array, j=phy_GPIO, i=template_GPIO uint32_t j = 0; for (uint32_t i = 0; i < nitems(Settings->user_template.gp.io); i++) { -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 +#if defined(ESP32) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2)) dest[i] = src[i]; +#elif defined(CONFIG_IDF_TARGET_ESP32C6) + if (10 == i) { j = 12; } // skip 10-11 + dest[j] = src[i]; + j++; #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) if (22 == i) { j = 33; } // skip 22-32 dest[j] = src[i]; @@ -1658,8 +1661,10 @@ void SetModuleType(void) bool FlashPin(uint32_t pin) { -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 - return (((pin > 10) && (pin < 12)) || ((pin > 13) && (pin < 18))); // ESP32C3 has GPIOs 11-17 reserved for Flash, with some boards GPIOs 12 13 are useable +#if defined(ESP32) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2)) + return (((pin > 10) && (pin < 12)) || ((pin > 13) && (pin < 18))); // ESP32C3/C2 has GPIOs 11-17 reserved for Flash, with some boards GPIOs 12 13 are useable +#elif defined(CONFIG_IDF_TARGET_ESP32C6) +return (pin>23)||((pin>9)&&(pin<12) ); // ESP32C6 flash pins 24-30 #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) return (pin > 21) && (pin < 33); // ESP32S2 skip 22-32 #elif defined(CONFIG_IDF_TARGET_ESP32) @@ -1671,10 +1676,10 @@ bool FlashPin(uint32_t pin) bool RedPin(uint32_t pin) // pin may be dangerous to change, display in RED in template console { -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 +#if defined(ESP32) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2)) return (12==pin)||(13==pin); // ESP32C3: GPIOs 12 13 are usually used for Flash (mode QIO/QOUT) -#elif defined(CONFIG_IDF_TARGET_ESP32S2) - return false; // no red pin on ESP32S3 +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C6) + return false; // no red pin on ESP32S3 or C6 #elif defined(CONFIG_IDF_TARGET_ESP32S3) return (33<=pin) && (37>=pin); // ESP32S3: GPIOs 33..37 are usually used for PSRAM #elif defined(CONFIG_IDF_TARGET_ESP32) // red pins are 6-11 for original ESP32, other models like PICO are not impacted if flash pins are condfigured @@ -1690,7 +1695,7 @@ uint32_t ValidPin(uint32_t pin, uint32_t gpio, uint8_t isTuya = false) { return GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11 } -#if defined(CONFIG_IDF_TARGET_ESP32C3) +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6) // ignore #elif defined(CONFIG_IDF_TARGET_ESP32S2) // ignore diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 40be1cf49122..299f6951f296 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -829,7 +829,7 @@ void CmndStatus(void) #endif // ESP32 D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d" ",\"" D_JSON_FLASHCHIPID "\":\"%06X\"" - ",\"FlashFrequency\":%d,\"" D_JSON_FLASHMODE "\":\"%s\""), + ",\"FlashFrequency\":%d,\"" D_JSON_FLASHMODE "\":\"" D_TASMOTA_FLASHMODE "\""), ESP_getSketchSize()/1024, ESP_getFreeSketchSpace()/1024, ESP_getFreeHeap1024(), #ifdef ESP32 uxTaskGetStackHighWaterMark(nullptr) / 1024, ESP.getPsramSize()/1024, ESP.getFreePsram()/1024, @@ -839,7 +839,7 @@ void CmndStatus(void) ESP_getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024 #endif // ESP8266 , ESP_getFlashChipId() - , ESP.getFlashChipSpeed()/1000000, ESP_getFlashChipMode().c_str()); + , ESP.getFlashChipSpeed()/1000000); ResponseAppendFeatures(); XsnsDriverState(); ResponseAppend_P(PSTR(",\"Sensors\":")); @@ -1846,7 +1846,7 @@ void CmndTemplate(void) SettingsUpdateText(SET_TEMPLATE_NAME, PSTR("Merged")); uint32_t j = 0; for (uint32_t i = 0; i < nitems(Settings->user_template.gp.io); i++) { -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 +#if defined(ESP32) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6)) #else if (6 == i) { j = 9; } if (8 == i) { j = 12; } diff --git a/tasmota/tasmota_support/support_crash_recorder.ino b/tasmota/tasmota_support/support_crash_recorder.ino index be689733729a..928abb1b2c6f 100644 --- a/tasmota/tasmota_support/support_crash_recorder.ino +++ b/tasmota/tasmota_support/support_crash_recorder.ino @@ -256,7 +256,7 @@ void CrashDump(void) } ResponseJsonEnd(); } -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 extern "C" { // esp-idf 3.x diff --git a/tasmota/tasmota_support/support_esp.ino b/tasmota/tasmota_support/support_esp.ino index 91a497c0a57c..4eb21110bf9f 100644 --- a/tasmota/tasmota_support/support_esp.ino +++ b/tasmota/tasmota_support/support_esp.ino @@ -229,6 +229,8 @@ String GetCodeCores(void) { #define ESP32_ARCH "esp32s3" #elif CONFIG_IDF_TARGET_ESP32C3 #define ESP32_ARCH "esp32c3" +#elif CONFIG_IDF_TARGET_ESP32C2 + #define ESP32_ARCH "esp32c2" #elif CONFIG_IDF_TARGET_ESP32C6 #define ESP32_ARCH "esp32c6" #else @@ -250,6 +252,8 @@ String GetCodeCores(void) { #include "esp32s3/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 #include "esp32c3/rom/rtc.h" + #elif CONFIG_IDF_TARGET_ESP32C2 // ESP32-C3 + #include "esp32c2/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C6 // ESP32-C6 #include "esp32c6/rom/rtc.h" #else @@ -429,6 +433,9 @@ extern "C" { #elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 #include "esp32c3/rom/spi_flash.h" #define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32c3 is located at 0x0000 + #elif CONFIG_IDF_TARGET_ESP32C2 // ESP32-C2 + #include "esp32c2/rom/spi_flash.h" + #define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32c3 is located at 0x0000 #elif CONFIG_IDF_TARGET_ESP32C6 // ESP32-C6 #include "esp32c6/rom/spi_flash.h" #define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32c6 is located at 0x0000 @@ -644,7 +651,7 @@ uint32_t ESP_getChipId(void) { uint32_t ESP_getFlashChipMagicSize(void) { esp_image_header_t fhdr; - if(ESP.flashRead(ESP_FLASH_IMAGE_BASE, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) { + if(ESP.flashRead(ESP_FLASH_IMAGE_BASE, (uint32_t*)&fhdr.magic, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) { return 0; } return ESP_magicFlashChipSize(fhdr.spi_size); @@ -1181,25 +1188,6 @@ float ESP_getFreeHeap1024(void) { } */ -const char kFlashModes[] PROGMEM = "QIO|QOUT|DIO|DOUT|Fast|Slow"; -/* -typedef enum { - FM_QIO = 0x00, - FM_QOUT = 0x01, - FM_DIO = 0x02, - FM_DOUT = 0x03, - FM_FAST_READ = 0x04, - FM_SLOW_READ = 0x05, - FM_UNKNOWN = 0xff -} FlashMode_t; -*/ -String ESP_getFlashChipMode(void) { - uint32_t flash_mode = ESP.getFlashChipMode(); - if (flash_mode > 5) { flash_mode = 3; } - char stemp[6]; - return GetTextIndexed(stemp, sizeof(stemp), flash_mode, kFlashModes); -} - /*********************************************************************************************\ * High entropy hardware random generator * Thanks to DigitalAlchemist diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino index feb98c8a052c..792c7dc832d4 100644 --- a/tasmota/tasmota_support/support_tasmota.ino +++ b/tasmota/tasmota_support/support_tasmota.ino @@ -201,7 +201,8 @@ void ZeroCrossMomentEnd(void) { #endif } -void IRAM_ATTR ZeroCrossIsr(void) { +void IRAM_ATTR ZeroCrossIsr(void); +void ZeroCrossIsr(void) { uint32_t time = micros(); TasmotaGlobal.zc_interval = ((int32_t) (time - TasmotaGlobal.zc_time)); TasmotaGlobal.zc_time = time; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 54c477c7bdfc..4d966cfe1146 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -139,7 +139,7 @@ const char HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX[] PROGMEM = #include "./html_uncompressed/HTTP_SCRIPT_TEMPLATE.h" #endif -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 +#if defined(ESP32) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6)) const char HTTP_SCRIPT_TEMPLATE2[] PROGMEM = "for(i=0;i<" STR(MAX_USER_PINS) ";i++){" "sk(g[i],i);" // Set GPIO @@ -1617,8 +1617,8 @@ void HandleTemplateConfiguration(void) { WSContentBegin(200, CT_PLAIN); WSContentSend_P(PSTR("%s}1"), AnyModuleName(module).c_str()); // NAME: Generic for (uint32_t i = 0; i < nitems(template_gp.io); i++) { // 17,148,29,149,7,255,255,255,138,255,139,255,255 -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 - // ESP32C3 we always send all GPIOs, Flash are just hidden +#if defined(ESP32) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6)) + // ESP32C3/C2/C6 we always send all GPIOs, Flash are just hidden WSContentSend_P(PSTR("%s%d"), (i>0)?",":"", template_gp.io[i]); #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) if (!FlashPin(i)) { @@ -1669,8 +1669,8 @@ void HandleTemplateConfiguration(void) { "
")); WSContentSend_P(HTTP_TABLE100); for (uint32_t i = 0; i < MAX_GPIO_PIN; i++) { -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 - // ESP32C3 all gpios are in the template, flash are hidden +#if defined(ESP32) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6)) + // ESP32C3/C2/C6 all gpios are in the template, flash are hidden bool hidden = FlashPin(i); WSContentSend_P(PSTR("" D_GPIO "%d"), hidden ? PSTR(" hidden") : "", @@ -1720,7 +1720,7 @@ void TemplateSaveSettings(void) { uint32_t j = 0; for (uint32_t i = 0; i < nitems(Settings->user_template.gp.io); i++) { -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 +#if defined(ESP32) && (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C6)) snprintf_P(command, sizeof(command), PSTR("%s%s%d"), command, (i>0)?",":"", WebGetGpioArg(i)); #elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) if (22 == i) { j = 33; } // skip 22-32 @@ -2465,7 +2465,7 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1}2 ")); // Empty line WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d (%s)"), ESP_getChipId(), GetDeviceHardwareRevision().c_str()); - WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X (%s)"), ESP_getFlashChipId(), ESP_getFlashChipMode().c_str()); + WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X (" D_TASMOTA_FLASHMODE ")"), ESP_getFlashChipId()); #ifdef ESP32 WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%d KB"), ESP.getFlashChipSize() / 1024); WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%d KB"), ESP_getFlashChipMagicSize() / 1024); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino b/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino index f8bed9bd4f5b..3d7353c00da7 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_39_thermostat.ino @@ -192,7 +192,7 @@ void (* const ThermostatCommand[])(void) PROGMEM = { &CmndEnableOutputSet }; struct THERMOSTAT { - ThermostatStateBitfield status; // Bittfield including states as well as several flags + ThermostatStateBitfield status; // Bitfield including states as well as several flags uint32_t timestamp_temp_measured_update = 0; // Timestamp of latest measurement update uint32_t timestamp_temp_meas_change_update = 0; // Timestamp of latest measurement value change (> or < to previous) uint32_t timestamp_output_off = 0; // Timestamp of latest thermostat output Off state @@ -215,8 +215,8 @@ struct THERMOSTAT { uint32_t time_rampup_deadtime = 0; // Time constant of the thermostat system (step response time) uint32_t time_rampup_nextcycle = 0; // Time where the ramp-up controller shall start the next cycle int16_t temp_measured = 0; // Temperature measurement received from sensor in tenths of degrees celsius - int16_t temp_rampup_output_off = 0; // Temperature to swith off relay output within the ramp-up controller in tenths of degrees celsius - uint8_t time_output_delay = THERMOSTAT_TIME_OUTPUT_DELAY; // Output delay between state change and real actuation event (f.i. valve open/closed) + int16_t temp_rampup_output_off = 0; // Temperature to switch off relay output within the ramp-up controller in tenths of degrees celsius + uint8_t time_output_delay = THERMOSTAT_TIME_OUTPUT_DELAY; // Output delay between state change and real actuation event (eg. valve open/closed) uint8_t counter_rampup_cycles = 0; // Counter of ramp-up cycles uint8_t temp_rampup_pi_acc_error = THERMOSTAT_TEMP_PI_RAMPUP_ACC_E; // Accumulated error when switching from ramp-up controller to PI in hundreths of degrees celsius uint8_t temp_rampup_delta_out = THERMOSTAT_TEMP_RAMPUP_DELTA_OUT; // Minimum delta temperature to target to get out of the rampup mode, in tenths of degrees celsius @@ -227,17 +227,17 @@ struct THERMOSTAT { uint16_t time_rampup_max = THERMOSTAT_TIME_RAMPUP_MAX; // Time maximum ramp-up controller duration in minutes uint16_t time_rampup_cycle = THERMOSTAT_TIME_RAMPUP_CYCLE; // Time ramp-up cycle in minutes uint16_t time_allow_rampup = THERMOSTAT_TIME_ALLOW_RAMPUP; // Time in minutes after last target update to allow ramp-up controller phase - uint16_t time_sens_lost = THERMOSTAT_TIME_SENS_LOST; // Maximum time w/o sensor update to set it as lost in minutes + uint16_t time_sens_lost = THERMOSTAT_TIME_SENS_LOST; // Maximum time without sensor update to set it as lost in minutes uint16_t time_manual_to_auto = THERMOSTAT_TIME_MANUAL_TO_AUTO; // Time without input switch active to change from manual to automatic in minutes uint32_t time_reset = THERMOSTAT_TIME_RESET; // Reset time of the PI controller in seconds uint16_t time_pi_cycle = THERMOSTAT_TIME_PI_CYCLE; // Cycle time for the thermostat controller in minutes uint16_t time_max_action = THERMOSTAT_TIME_MAX_ACTION; // Maximum thermostat time per cycle in minutes uint16_t time_min_action = THERMOSTAT_TIME_MIN_ACTION; // Minimum thermostat time per cycle in minutes - uint16_t time_min_turnoff_action = THERMOSTAT_TIME_MIN_TURNOFF_ACTION; // Minimum turnoff time in minutes, below it the thermostat will stay on + uint16_t time_min_turnoff_action = THERMOSTAT_TIME_MIN_TURNOFF_ACTION; // Minimum turnoff time in minutes, below which the thermostat will stay on int16_t temp_frost_protect = THERMOSTAT_TEMP_FROST_PROTECT; // Minimum temperature for frost protection, in tenths of degrees celsius uint8_t temp_reset_anti_windup = THERMOSTAT_TEMP_RESET_ANTI_WINDUP; // Range where reset antiwindup is disabled, in tenths of degrees celsius int8_t temp_hysteresis = THERMOSTAT_TEMP_HYSTERESIS; // Range hysteresis for temperature PI controller, in tenths of degrees celsius - ThermostatDiagBitfield diag; // Bittfield including diagnostic flags + ThermostatDiagBitfield diag; // Bitfield including diagnostic flags #ifdef USE_PI_AUTOTUNING uint8_t dutycycle_step_autotune = THERMOSTAT_DUTYCYCLE_AUTOTUNE; // Duty cycle for the step response of the autotune PI function in % uint8_t peak_ctr = 0; // Peak counter for the autotuning function @@ -249,8 +249,8 @@ struct THERMOSTAT { uint16_t kP_pi_atune = 0; // kP value calculated by the autotune PI function multiplied by 100 (to avoid floating point operations) uint16_t kI_pi_atune = 0; // kI value calulated by the autotune PI function multiplied by 100 (to avoid floating point operations) int16_t temp_peaks_atune[THERMOSTAT_PEAKNUMBER_AUTOTUNE]; // Array to store temperature peaks to be used by the autotune PI function - int16_t temp_abs_max_atune; // Max temperature reached within autotune - int16_t temp_abs_min_atune; // Min temperature reached within autotune + int16_t temp_abs_max_atune; // Maximum temperature reached within autotune + int16_t temp_abs_min_atune; // Minimum temperature reached within autotune uint16_t time_peak_timestamps_atune[THERMOSTAT_PEAKNUMBER_AUTOTUNE]; // Array to store timestamps in minutes of the temperature peaks to be used by the autotune PI function uint16_t time_std_dev_peak_det_ok = THERMOSTAT_TIME_STD_DEV_PEAK_DET_OK; // Standard deviation in minutes of the oscillation periods within the peak detection is successful #endif // USE_PI_AUTOTUNING @@ -371,6 +371,12 @@ void ThermostatSignalPreProcessingSlow(uint8_t ctr_output) Thermostat[ctr_output].status.sensor_alive = IFACE_OFF; Thermostat[ctr_output].temp_measured_gradient = 0; Thermostat[ctr_output].temp_measured = 0; + + char result_chr[FLOATSZ]; + + dtostrfd((TasmotaGlobal.uptime - Thermostat[ctr_output].timestamp_temp_measured_update), 0, result_chr); + AddLog(LOG_LEVEL_ERROR, PSTR(D_LOG_THERMOSTAT "Thermostat sensor has not been seen for %s seconds"), result_chr); + } } @@ -597,11 +603,9 @@ void ThermostatOutputRelay(uint8_t ctr_output, uint32_t command) // then switch output to ON if ((command == IFACE_ON) && (Thermostat[ctr_output].status.status_output == IFACE_OFF)) { -//#ifndef DEBUG_THERMOSTAT if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_ON, SRC_THERMOSTAT); } -//#endif // DEBUG_THERMOSTAT Thermostat[ctr_output].status.status_output = IFACE_ON; #ifdef DEBUG_THERMOSTAT ThermostatVirtualSwitch(ctr_output); @@ -611,11 +615,9 @@ void ThermostatOutputRelay(uint8_t ctr_output, uint32_t command) // AND current output status is ON // then switch output to OFF else if ((command == IFACE_OFF) && (Thermostat[ctr_output].status.status_output == IFACE_ON)) { -//#ifndef DEBUG_THERMOSTAT if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_OFF, SRC_THERMOSTAT); } -//#endif // DEBUG_THERMOSTAT Thermostat[ctr_output].timestamp_output_off = TasmotaGlobal.uptime; Thermostat[ctr_output].status.status_output = IFACE_OFF; #ifdef DEBUG_THERMOSTAT @@ -682,14 +684,14 @@ void ThermostatCalculatePI(uint8_t ctr_output) Thermostat[ctr_output].temp_pi_accum_error = 0; } // Normal use of integrator - // result will be calculated with the cummulated previous error anterior - // and current error will be cummulated to the previous one + // result will be calculated with the accumulated previous error anterior + // and current error will be accumulated to the previous one else { // Hysteresis limiter // If error is less than or equal than hysteresis, limit output to 0, when temperature - // is rising, never when falling. Limit cummulated error. If this is not done, + // is rising, never when falling. Limit accumulated error. If this is not done, // there will be very strong control actions from the integral part due to a - // very high cummulated error when beingin hysteresis. This triggers high + // very high accumulated error when beingin hysteresis. This triggers high // integral actions // Update accumulated error @@ -739,7 +741,7 @@ void ThermostatCalculatePI(uint8_t ctr_output) // Antiwindup of the integrator // If integral calculation is bigger than cycle time, adjust result - // to the cycle time and error will not be cummulated + // to the cycle time and error will not be accumulated if (Thermostat[ctr_output].time_integral_pi > ((uint32_t)Thermostat[ctr_output].time_pi_cycle * 60)) { Thermostat[ctr_output].time_integral_pi = ((uint32_t)Thermostat[ctr_output].time_pi_cycle * 60); } @@ -750,7 +752,7 @@ void ThermostatCalculatePI(uint8_t ctr_output) // Antiwindup of the output // If result is bigger than cycle time, the result will be adjusted - // to the cylce time minus safety time and error will not be cummulated + // to the cylce time minus safety time and error will not be accumulated if (Thermostat[ctr_output].time_total_pi >= ((int32_t)Thermostat[ctr_output].time_pi_cycle * 60)) { // Limit to cycle time //at least switch down a minimum time Thermostat[ctr_output].time_total_pi = ((int32_t)Thermostat[ctr_output].time_pi_cycle * 60); @@ -1277,64 +1279,93 @@ void ThermostatVirtualSwitchCtrState(uint8_t ctr_output) Response_P(DOMOTICZ_MES, DOMOTICZ_IDX2, (0 == Thermostat[0].status.phase_hybrid_ctr) ? 0 : 1, ""); MqttPublish(domoticz_in_topic); } +#endif // DEBUG_THERMOSTAT void ThermostatDebug(uint8_t ctr_output) { + char ctr_output_chr[FLOATSZ]; char result_chr[FLOATSZ]; - AddLog(LOG_LEVEL_DEBUG, PSTR("")); - AddLog(LOG_LEVEL_DEBUG, PSTR("------ Thermostat Start ------")); + dtostrfd(ctr_output, 0, ctr_output_chr); dtostrfd(Thermostat[ctr_output].status.counter_seconds, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.counter_seconds: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].status.counter_seconds: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].status.thermostat_mode, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.thermostat_mode: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].status.thermostat_mode: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].diag.state_emergency, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].diag.state_emergency: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].diag.state_emergency: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].diag.output_inconsist_ctr, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].diag.output_inconsist_ctr: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].diag.output_inconsist_ctr: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].status.controller_mode, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.controller_mode: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].status.controller_mode: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].status.command_output, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.command_output: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].status.command_output: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].status.status_output, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.status_output: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].status.status_output: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].status.status_input, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.status_input: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].status.status_input: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].status.phase_hybrid_ctr, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.phase_hybrid_ctr: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].status.phase_hybrid_ctr: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].status.sensor_alive, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.sensor_alive: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].status.sensor_alive: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].status.status_cycle_active, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.status_cycle_active: %s"), result_chr); - dtostrfd(Thermostat[ctr_output].temp_pi_error, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_pi_error: %s"), result_chr); - dtostrfd(Thermostat[ctr_output].temp_pi_accum_error, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_pi_accum_error: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].status.status_cycle_active: %s"), ctr_output_chr, result_chr); + dtostrfd((float)Thermostat[ctr_output].temp_pi_error/100, 2, result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].temp_pi_error: %s degrees"), ctr_output_chr, result_chr); + dtostrfd((float)Thermostat[ctr_output].temp_pi_accum_error/100, 2, result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].temp_pi_accum_error: %s degrees"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].time_proportional_pi, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_proportional_pi: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].time_proportional_pi: %s seconds"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].time_integral_pi, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_integral_pi: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].time_integral_pi: %s seconds"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].time_total_pi, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_total_pi: %s"), result_chr); - dtostrfd(Thermostat[ctr_output].temp_measured_gradient, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_measured_gradient: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].time_total_pi: %s seconds"), ctr_output_chr, result_chr); + dtostrfd((float)Thermostat[ctr_output].temp_measured_gradient/1000, 3, result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].temp_measured_gradient: %s degrees/hour"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].time_rampup_deadtime, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_rampup_deadtime: %s"), result_chr); - dtostrfd(Thermostat[ctr_output].temp_rampup_meas_gradient, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_rampup_meas_gradient: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].time_rampup_deadtime: %s seconds"), ctr_output_chr, result_chr); + dtostrfd((float)Thermostat[ctr_output].temp_rampup_meas_gradient/1000, 3, result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].temp_rampup_meas_gradient: %s degrees/hour"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].time_ctr_changepoint, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_ctr_changepoint: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].time_ctr_changepoint: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].temp_rampup_output_off, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_rampup_output_off: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].temp_rampup_output_off: %s"), ctr_output_chr, result_chr); dtostrfd(Thermostat[ctr_output].time_ctr_checkpoint, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_ctr_checkpoint: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].time_ctr_checkpoint: %s"), ctr_output_chr, result_chr); dtostrfd(TasmotaGlobal.uptime, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("uptime: %s"), result_chr); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "uptime: %s"), result_chr); dtostrfd(TasmotaGlobal.power, 0, result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("power: %s"), result_chr); - AddLog(LOG_LEVEL_DEBUG, PSTR("------ Thermostat End ------")); - AddLog(LOG_LEVEL_DEBUG, PSTR("")); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_THERMOSTAT "power: %s"), result_chr); } -#endif // DEBUG_THERMOSTAT + +void DebugControllerParameters(uint8_t ctr_output) +{ + char ctr_output_chr[FLOATSZ]; + char result_chr[FLOATSZ]; + dtostrfd(ctr_output, 0, ctr_output_chr); + dtostrfd(Thermostat[ctr_output].status.controller_mode, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].CONTROLLERMODESET: %s"), ctr_output_chr, result_chr); + dtostrfd(Thermostat[ctr_output].time_pi_cycle, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TIMEPICYCLESET: %s minutes"), ctr_output_chr, result_chr); + dtostrfd(Thermostat[ctr_output].time_min_action, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TIMEMINACTIONSET: %s minutes"), ctr_output_chr, result_chr); + dtostrfd(Thermostat[ctr_output].time_max_action, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TIMEMAXACTIONSET: %s minutes"), ctr_output_chr, result_chr); + dtostrfd(Thermostat[ctr_output].time_allow_rampup, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TIMEALLOWRAMPUPSET: %s minutes"), ctr_output_chr, result_chr); + dtostrfd(Thermostat[ctr_output].time_rampup_cycle, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TIMERAMPUPCYCLESET: %s minutes"), ctr_output_chr, result_chr); + dtostrfd(Thermostat[ctr_output].time_rampup_max, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TIMERAMPUPMAXSET: %s minutes"), ctr_output_chr, result_chr); + dtostrfd(Thermostat[ctr_output].time_reset, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TIMERESETSET: %s seconds"), ctr_output_chr, result_chr); + dtostrfd(Thermostat[ctr_output].val_prop_band, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].PROPBANDSET: %s"), ctr_output_chr, result_chr); + dtostrfd((float)Thermostat[ctr_output].temp_reset_anti_windup/10, 1, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TEMPANTIWINDUPRESETSET: %s degrees"), ctr_output_chr, result_chr); + dtostrfd((float)Thermostat[ctr_output].temp_hysteresis/10, 1, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TEMPHYSTSET: %s degrees"), ctr_output_chr, result_chr); + dtostrfd(Thermostat[ctr_output].temp_rampup_delta_in, 0, result_chr); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_THERMOSTAT "Thermostat[%s].TEMPRUPDELTINSET: %s degrees"), ctr_output_chr, result_chr); + } uint8_t ThermostatGetDutyCycle(uint8_t ctr_output) { @@ -1417,6 +1448,9 @@ void CmndThermostatModeSet(void) Thermostat[ctr_output].status.command_output = IFACE_OFF; ThermostatOutputRelay(ctr_output, Thermostat[ctr_output].status.command_output); } + if ((value > THERMOSTAT_OFF) && (value < THERMOSTAT_MODES_MAX)) { + DebugControllerParameters(ctr_output); + } } ResponseCmndIdxNumber((int)Thermostat[ctr_output].status.thermostat_mode); } @@ -2167,9 +2201,7 @@ bool Xdrv39(uint32_t function) ThermostatSignalPreProcessingSlow(ctr_output); ThermostatController(ctr_output); ThermostatSignalPostProcessingSlow(ctr_output); -#ifdef DEBUG_THERMOSTAT ThermostatDebug(ctr_output); -#endif // DEBUG_THERMOSTAT } } break; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_48_timeprop.ino b/tasmota/tasmota_xdrv_driver/xdrv_48_timeprop.ino index 22f25623f728..d1fc6754a05b 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_48_timeprop.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_48_timeprop.ino @@ -64,7 +64,7 @@ #define TIMEPROP_CYCLETIMES 60 // cycle time seconds #define TIMEPROP_DEADTIMES 0 // actuator action time seconds #define TIMEPROP_OPINVERTS false // whether to invert the output - #define TIMEPROP_FALLBACK_POWERS 0 // falls back to this if too long betwen power updates + #define TIMEPROP_FALLBACK_POWERS 0.0 // falls back to this if too long betwen power updates #define TIMEPROP_MAX_UPDATE_INTERVALS 120 // max no secs that are allowed between power updates (0 to disable) #define TIMEPROP_RELAYS 1 // which relay to control 1:8 @@ -75,7 +75,7 @@ #define TIMEPROP_CYCLETIMES 60, 10 // cycle time seconds #define TIMEPROP_DEADTIMES 0, 0 // actuator action time seconds #define TIMEPROP_OPINVERTS false, false // whether to invert the output - #define TIMEPROP_FALLBACK_POWERS 0, 0 // falls back to this if too long betwen power updates + #define TIMEPROP_FALLBACK_POWERS 0.0, 0.0 // falls back to this if too long betwen power updates #define TIMEPROP_MAX_UPDATE_INTERVALS 120, 120 // max no secs that are allowed between power updates (0 to disable) #define TIMEPROP_RELAYS 1, 2 // which relay to control 1:8 @@ -85,13 +85,8 @@ -#define D_CMND_TIMEPROP "timeprop_" -#define D_CMND_TIMEPROP_SETPOWER "setpower_" // add index no on end (0:8) and data is power 0:1 - #include "Timeprop.h" -enum TimepropCommands { CMND_TIMEPROP_SETPOWER }; -const char kTimepropCommands[] PROGMEM = D_CMND_TIMEPROP_SETPOWER; #ifndef TIMEPROP_NUM_OUTPUTS #define TIMEPROP_NUM_OUTPUTS 1 // how many outputs to control (with separate alogorithm for each) @@ -106,7 +101,7 @@ const char kTimepropCommands[] PROGMEM = D_CMND_TIMEPROP_SETPOWER; #define TIMEPROP_OPINVERTS false // whether to invert the output #endif #ifndef TIMEPROP_FALLBACK_POWERS -#define TIMEPROP_FALLBACK_POWERS 0 // falls back to this if too long betwen power updates +#define TIMEPROP_FALLBACK_POWERS 0 // falls back to this if too long between power updates #endif #ifndef TIMEPROP_MAX_UPDATE_INTERVALS #define TIMEPROP_MAX_UPDATE_INTERVALS 120 // max no secs that are allowed between power updates (0 to disable) @@ -114,6 +109,9 @@ const char kTimepropCommands[] PROGMEM = D_CMND_TIMEPROP_SETPOWER; #ifndef TIMEPROP_RELAYS #define TIMEPROP_RELAYS 1 // which relay to control 1:8 #endif +#ifndef TIMEPROP_REPORT_SETTINGS +#define TIMEPROP_REPORT_SETTINGS false // set to true to include timeprop settings in json output +#endif static Timeprop timeprops[TIMEPROP_NUM_OUTPUTS]; static int relayNos[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_RELAYS}; @@ -126,6 +124,39 @@ struct { long current_time_secs = 0; // a counter that counts seconds since initialisation } Tprop; +#define D_CMND_TIMEPROP_PREFIX "Timeprop" +#define D_CMND_TIMEPROP_SETPOWER "_SetPower_" // underscores left in for backwards compatibility +#define D_CMND_TIMEPROP_SETCYCLETIME "SetCycleTime" +#define D_CMND_TIMEPROP_DEADTIME "SetDeadTime" +#define D_CMND_TIMEPROP_OPINVERT "SetOutputInvert" +#define D_CMND_TIMEPROP_FALLBACK_POWER "SetFallbackPower" +#define D_CMND_TIMEPROP_MAX_UPDATE_INTERVAL "SetMaxUpdateInterval" + +int cycleTimes[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_CYCLETIMES}; +int deadTimes[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_DEADTIMES}; +unsigned char opInverts[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_OPINVERTS}; +float fallbacks[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_FALLBACK_POWERS}; +int maxIntervals[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_MAX_UPDATE_INTERVALS}; + +enum TimepropCommands { CMND_TIMEPROP_SETPOWER }; + +const char kCommands[] PROGMEM = D_CMND_TIMEPROP_PREFIX "|" + D_CMND_TIMEPROP_SETPOWER "|" + D_CMND_TIMEPROP_SETCYCLETIME "|" + D_CMND_TIMEPROP_DEADTIME "|" + D_CMND_TIMEPROP_OPINVERT "|" + D_CMND_TIMEPROP_FALLBACK_POWER "|" + D_CMND_TIMEPROP_MAX_UPDATE_INTERVAL ; + +void (* const Command[])(void) PROGMEM = { + &CmndSetPower, + &CmndSetCycleTime, + &CmndSetDeadTime, + &CmndSetOutputInvert, + &CmndSetFallbackPower, + &CmndSetMaxUpdateInterval, +}; + /* call this from elsewhere if required to set the power value for one of the timeprop instances */ /* index specifies which one, 0 up */ void TimepropSetPower(int index, float power) { @@ -135,19 +166,125 @@ void TimepropSetPower(int index, float power) { } void TimepropInit(void) { - // AddLog(LOG_LEVEL_INFO, PSTR("TPR: Timeprop Init")); - int cycleTimes[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_CYCLETIMES}; - int deadTimes[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_DEADTIMES}; - int opInverts[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_OPINVERTS}; - int fallbacks[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_FALLBACK_POWERS}; - int maxIntervals[TIMEPROP_NUM_OUTPUTS] = {TIMEPROP_MAX_UPDATE_INTERVALS}; - for (int i = 0; i < TIMEPROP_NUM_OUTPUTS; i++) { Tprop.timeprops[i].initialise(cycleTimes[i], deadTimes[i], opInverts[i], fallbacks[i], maxIntervals[i], Tprop.current_time_secs); } } +void CmndSetPower(void) { + if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS) { + if(XdrvMailbox.data_len) { + float newPower=CharToFloat(XdrvMailbox.data); + timeprops[XdrvMailbox.index].setPower(newPower, Tprop.current_time_secs ); + ResponseCmndFloat(newPower, 2); + } + else { + ResponseCmndError(); + } + } +} + +// commands for settings all take the same form +// prefix commands with 'timeprop' +// then append the command string eg. 'SetCycleTime' +// then append the output number (0 for a single output) +// then append the value to set set, or +// leave blank to retrieve the current value +// eg. +// 'TimepropSetCycleTime0 120' will set the value of cycle time for output 0 to 120 +// 'TimepropSetCycleTime0' will retrieve the value of cycle time for output 0 + +void CmndSetCycleTime(void) { + if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS ) { + if(XdrvMailbox.data_len) { + int newCycleTime=TextToInt(XdrvMailbox.data); + if(newCycleTime>0) { + cycleTimes[XdrvMailbox.index] = newCycleTime; + Tprop.timeprops[XdrvMailbox.index].initialise(cycleTimes[XdrvMailbox.index], deadTimes[XdrvMailbox.index], opInverts[XdrvMailbox.index], fallbacks[XdrvMailbox.index], maxIntervals[XdrvMailbox.index], Tprop.current_time_secs); + ResponseCmndNumber(newCycleTime); + } + else { + ResponseCmndError(); + } + } + else { + ResponseCmndNumber(cycleTimes[XdrvMailbox.index]); + } + } +} + +void CmndSetDeadTime(void) { + if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS ) { + if(XdrvMailbox.data_len) { + int newDeadTime=TextToInt(XdrvMailbox.data); + if(newDeadTime>0) { + deadTimes[XdrvMailbox.index] = newDeadTime; + Tprop.timeprops[XdrvMailbox.index].initialise(cycleTimes[XdrvMailbox.index], deadTimes[XdrvMailbox.index], opInverts[XdrvMailbox.index], fallbacks[XdrvMailbox.index], maxIntervals[XdrvMailbox.index], Tprop.current_time_secs); + ResponseCmndNumber(newDeadTime); + } + else { + ResponseCmndError(); + } + } + else { + ResponseCmndNumber(deadTimes[XdrvMailbox.index]); + } + } +} + +void CmndSetOutputInvert(void) { + if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS ) { + if(XdrvMailbox.data_len) { + unsigned char newInvert=TextToInt(XdrvMailbox.data); + opInverts[XdrvMailbox.index] = newInvert; + Tprop.timeprops[XdrvMailbox.index].initialise(cycleTimes[XdrvMailbox.index], deadTimes[XdrvMailbox.index], opInverts[XdrvMailbox.index], fallbacks[XdrvMailbox.index], maxIntervals[XdrvMailbox.index], Tprop.current_time_secs); + ResponseCmndNumber(newInvert); + } + else { + ResponseCmndNumber(opInverts[XdrvMailbox.index]); + } + } +} + +void CmndSetFallbackPower(void) { + if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS ) { + if(XdrvMailbox.data_len) { + float newPower=CharToFloat(XdrvMailbox.data); + if(newPower>=0.0 && newPower<=1.0) { + fallbacks[XdrvMailbox.index] = newPower; + Tprop.timeprops[XdrvMailbox.index].initialise(cycleTimes[XdrvMailbox.index], deadTimes[XdrvMailbox.index], opInverts[XdrvMailbox.index], fallbacks[XdrvMailbox.index], maxIntervals[XdrvMailbox.index], Tprop.current_time_secs); + ResponseCmndFloat(newPower, 2); + } + else { + ResponseCmndError(); + } + } + else { + ResponseCmndFloat(fallbacks[XdrvMailbox.index], 2); + } + } +} + +void CmndSetMaxUpdateInterval(void) { + if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS ) { + if(XdrvMailbox.data_len) { + int newInterval=TextToInt(XdrvMailbox.data); + if(newInterval>0) { + maxIntervals[XdrvMailbox.index] = newInterval; + Tprop.timeprops[XdrvMailbox.index].initialise(cycleTimes[XdrvMailbox.index], deadTimes[XdrvMailbox.index], opInverts[XdrvMailbox.index], fallbacks[XdrvMailbox.index], maxIntervals[XdrvMailbox.index], Tprop.current_time_secs); + ResponseCmndNumber(newInterval); + } + else { + ResponseCmndError(); + } + } + else { + ResponseCmndNumber(maxIntervals[XdrvMailbox.index]); + } + } +} + void TimepropEverySecond(void) { Tprop.current_time_secs++; // increment time for (int i=0; i= 0 ? XdrvMailbox.topic : ""), - (XdrvMailbox.data_len >= 0 ? XdrvMailbox.data : "")); - */ - if (0 == strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_TIMEPROP), ua_prefix_len)) { - // command starts with timeprop_ - int command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + ua_prefix_len, kTimepropCommands); - if (CMND_TIMEPROP_SETPOWER == command_code) { - /* - AddLog(LOG_LEVEL_INFO, PSTR("Timeprop command timeprop_setpower: " - "index: %d data_len: %d payload: %d topic: %s data: %s"), - XdrvMailbox.index, - XdrvMailbox.data_len, - XdrvMailbox.payload, - (XdrvMailbox.payload >= 0 ? XdrvMailbox.topic : ""), - (XdrvMailbox.data_len >= 0 ? XdrvMailbox.data : "")); - */ - if (XdrvMailbox.index >=0 && XdrvMailbox.index < TIMEPROP_NUM_OUTPUTS) { - timeprops[XdrvMailbox.index].setPower( CharToFloat(XdrvMailbox.data), Tprop.current_time_secs ); - } - Response_P(PSTR("{\"" D_CMND_TIMEPROP D_CMND_TIMEPROP_SETPOWER "%d\":\"%s\"}"), XdrvMailbox.index, XdrvMailbox.data); - } - else { - serviced = false; - } - } else { - serviced = false; +void ShowValues(void) { +#if TIMEPROP_REPORT_SETTINGS + ResponseAppend_P(PSTR(",\"Timeprop\":{")); + for (int i=0; i Pid.max_interval && ((Pid.current_time_secs - Pid.last_pv_update_secs)%60)==0) { + AddLog(LOG_LEVEL_ERROR, PSTR("PID: Local temperature sensor missing for longer than PID_MAX_INTERVAL")); + } } } -/* struct XDRVMAILBOX { */ -/* uint16_t valid; */ -/* uint16_t index; */ -/* uint16_t data_len; */ -/* int16_t payload; */ -/* char *topic; */ -/* char *data; */ -/* } XdrvMailbox; */ - void CmndSetPv(void) { Pid.last_pv_update_secs = Pid.current_time_secs; if (XdrvMailbox.data_len > 0) { @@ -339,14 +366,11 @@ void CmndSetManualPower(void) { void CmndSetMaxInterval(void) { if (XdrvMailbox.payload >= 0) { Pid.pid.setMaxInterval(XdrvMailbox.payload); + Pid.max_interval=XdrvMailbox.payload; } ResponseCmndNumber(Pid.pid.getMaxInterval()); } -// case CMND_PID_SETUPDATE_SECS: -// Pid.update_secs = atoi(XdrvMailbox.data) ; -// if (Pid.update_secs < 0) -// Pid.update_secs = 0; void CmndSetUpdateSecs(void) { if (XdrvMailbox.payload >= 0) { Pid.update_secs = (XdrvMailbox.payload); @@ -364,51 +388,43 @@ void PIDShowValues(void) { double d_buf; ResponseAppend_P(PSTR(",\"PID\":{")); -// #define D_CMND_PID_SETPV "Pv" d_buf = Pid.pid.getPv(); dtostrfd(d_buf, 2, str_buf); ResponseAppend_P(PSTR("\"PidPv\":%s,"), str_buf); -// #define D_CMND_PID_SETSETPOINT "Sp" d_buf = Pid.pid.getSp(); dtostrfd(d_buf, 2, str_buf); ResponseAppend_P(PSTR("\"PidSp\":%s,"), str_buf); #if PID_REPORT_MORE_SETTINGS -// #define D_CMND_PID_SETPROPBAND "Pb" d_buf = Pid.pid.getPb(); dtostrfd(d_buf, 2, str_buf); ResponseAppend_P(PSTR("\"PidPb\":%s,"), str_buf); -// #define D_CMND_PID_SETINTEGRAL_TIME "Ti" d_buf = Pid.pid.getTi(); dtostrfd(d_buf, 2, str_buf); ResponseAppend_P(PSTR("\"PidTi\":%s,"), str_buf); -// #define D_CMND_PID_SETDERIVATIVE_TIME "Td" d_buf = Pid.pid.getTd(); dtostrfd(d_buf, 2, str_buf); ResponseAppend_P(PSTR("\"PidTd\":%s,"), str_buf); -// #define D_CMND_PID_SETINITIAL_INT "Initint" d_buf = Pid.pid.getInitialInt(); dtostrfd(d_buf, 2, str_buf); ResponseAppend_P(PSTR("\"PidInitialInt\":%s,"), str_buf); -// #define D_CMND_PID_SETDERIV_SMOOTH_FACTOR "DSmooth" d_buf = Pid.pid.getDSmooth(); dtostrfd(d_buf, 2, str_buf); ResponseAppend_P(PSTR("\"PidDSmooth\":%s,"), str_buf); -// #define D_CMND_PID_SETAUTO "Auto" chr_buf = Pid.pid.getAuto(); ResponseAppend_P(PSTR("\"PidAuto\":%d,"), chr_buf); -// #define D_CMND_PID_SETMANUAL_POWER "ManualPower" d_buf = Pid.pid.getManualPower(); dtostrfd(d_buf, 2, str_buf); ResponseAppend_P(PSTR("\"PidManualPower\":%s,"), str_buf); -// #define D_CMND_PID_SETMAX_INTERVAL "MaxInterval" i_buf = Pid.pid.getMaxInterval(); ResponseAppend_P(PSTR("\"PidMaxInterval\":%d,"), i_buf); - -// #define D_CMND_PID_SETUPDATE_SECS "UpdateSecs" + i_buf = Pid.current_time_secs - Pid.last_pv_update_secs; + ResponseAppend_P(PSTR("\"PidInterval\":%d,"), i_buf); ResponseAppend_P(PSTR("\"PidUpdateSecs\":%d,"), Pid.update_secs); #endif // PID_REPORT_MORE_SETTINGS + i_buf = (Pid.current_time_secs - Pid.last_pv_update_secs) > Pid.pid.getMaxInterval(); + ResponseAppend_P(PSTR("\"PidSensorLost\":%d,"), i_buf); // The actual power value d_buf = Pid.pid.tick(Pid.current_time_secs); dtostrfd(d_buf, 2, str_buf); @@ -417,6 +433,38 @@ void PIDShowValues(void) { ResponseAppend_P(PSTR("}")); } +void PIDShowValuesWeb(void) { + +#define D_PID_DISPLAY_NAME "PID Controller" +#define D_PID_SET_POINT "Set Point" +#define D_PID_PRESENT_VALUE "Current Value" +#define D_PID_POWER "Power" +#define D_PID_MODE "Controller Mode" +#define D_PID_MODE_AUTO "Auto" +#define D_PID_MODE_MANUAL "Manual" +#define D_PID_MODE_OFF "Off" + + const char HTTP_PID_HL[] PROGMEM = "{s}
{m}
{e}"; + const char HTTP_PID_INFO[] PROGMEM = "{s}" D_PID_DISPLAY_NAME "{m}%s{e}"; + const char HTTP_PID_SP_FORMAT[] PROGMEM = "{s}%s " "{m}%*_f "; + const char HTTP_PID_PV_FORMAT[] PROGMEM = "{s}%s " "{m}%*_f "; + const char HTTP_PID_POWER_FORMAT[] PROGMEM = "{s}%s " "{m}%*_f " D_UNIT_PERCENT; + + float f_buf; + + WSContentSend_P(HTTP_PID_HL); + WSContentSend_P(HTTP_PID_INFO, (Pid.pid.getAuto()==1) ? D_PID_MODE_AUTO : Pid.pid.tick(Pid.current_time_secs)>0.0f ? D_PID_MODE_MANUAL : D_PID_MODE_OFF); + + if (Pid.pid.getAuto()==1 || Pid.pid.tick(Pid.current_time_secs)>0.0f) { + f_buf = (float)Pid.pid.getSp(); + WSContentSend_PD(HTTP_PID_SP_FORMAT, D_PID_SET_POINT, 1, &f_buf); + f_buf = (float)Pid.pid.getPv(); + WSContentSend_PD(HTTP_PID_PV_FORMAT, D_PID_PRESENT_VALUE, 1, &f_buf); + f_buf = Pid.pid.tick(Pid.current_time_secs)*100.0f; + WSContentSend_PD(HTTP_PID_POWER_FORMAT, D_PID_POWER, 0, &f_buf); + } +} + void PIDRun(void) { double power = Pid.pid.tick(Pid.current_time_secs); #ifdef PID_DONT_USE_PID_TOPIC @@ -468,6 +516,9 @@ bool Xdrv49(uint32_t function) { case FUNC_JSON_APPEND: PIDShowValues(); break; + case FUNC_WEB_SENSOR: + PIDShowValuesWeb(); + break; } return result; } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino index c62f3bc30bcd..2b92e57b864d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino @@ -17,6 +17,8 @@ along with this program. If not, see . */ +#include +#ifdef SOC_RMT_SUPPORTED #ifdef USE_BERRY @@ -242,3 +244,4 @@ extern "C" { #endif // USE_WS2812 #endif // USE_BERRY +#endif // SOC_RMT_SUPPORTED \ No newline at end of file diff --git a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino index 9ddeb4928684..b10ef44c6455 100644 --- a/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino +++ b/tasmota/tasmota_xlgt_light/xlgt_01_ws2812.ino @@ -19,6 +19,15 @@ #ifdef USE_LIGHT #ifdef USE_WS2812 + +#ifdef ESP32 + #include "soc/soc_caps.h" +#else + #define SOC_RMT_SUPPORTED +#endif + +#if SOC_RMT_SUPPORTED + /*********************************************************************************************\ * WS2812 RGB / RGBW Leds using NeopixelBus library * @@ -849,5 +858,6 @@ bool Xlgt01(uint32_t function) return result; } +#endif // SOC_RMT_SUPPORTED #endif // USE_WS2812 #endif // USE_LIGHT diff --git a/tasmota/tasmota_xlgt_light/xlgt_02_my92x1.ino b/tasmota/tasmota_xlgt_light/xlgt_02_my92x1.ino index ec72df8d89b2..6eacca0ff5d4 100644 --- a/tasmota/tasmota_xlgt_light/xlgt_02_my92x1.ino +++ b/tasmota/tasmota_xlgt_light/xlgt_02_my92x1.ino @@ -31,9 +31,17 @@ struct MY92X1 { uint8_t model = 0; } My92x1; +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "rom/ets_sys.h" +#ifndef os_delay_us +#define os_delay_us ets_delay_us +#endif //os_delay_us +#else extern "C" { void os_delay_us(unsigned int); } +#endif + void LightDiPulse(uint8_t times) { diff --git a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino index 2f2c75795523..1da04c912cc6 100644 --- a/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino +++ b/tasmota/tasmota_xnrg_energy/xnrg_07_ade7953.ino @@ -78,6 +78,9 @@ #define ADE7953_PREF 1540 // 4194304 / (1540 / 1000) = 2723574 (= WGAIN, VAGAIN and VARGAIN) #define ADE7953_UREF 26000 // 4194304 / (26000 / 10000) = 1613194 (= VGAIN) #define ADE7953_IREF 10000 // 4194304 / (10000 / 10000) = 4194303 (= IGAIN, needs to be different than 4194304 in order to use calib.dat) +#define ADE7953_NO_LOAD_THRESHOLD 29196 // According to ADE7953 datasheet the default threshold for no load detection is 58,393 use half this value to measure lower (5w) powers. +#define ADE7953_NO_LOAD_ENABLE 0 // Set DISNOLOAD register to 0 to enable No-load detection +#define ADE7953_NO_LOAD_DISABLE 7 // Set DISNOLOAD register to 7 to disable No-load detection // Default calibration parameters can be overridden by a rule as documented above. #define ADE7953_GAIN_DEFAULT 4194304 // = 0x400000 range 2097152 (min) to 6291456 (max) @@ -120,7 +123,9 @@ enum Ade7953_16BitRegisters { ADE7943_PFB, // 0x10B R 16 S 0x0000 Power factor (Current Channel B) ADE7943_ANGLE_A, // 0x10C R 16 S 0x0000 Angle between the voltage input and the Current Channel A input ADE7943_ANGLE_B, // 0x10D R 16 S 0x0000 Angle between the voltage input and the Current Channel B input - ADE7943_Period // 0x10E R 16 U 0x0000 Period register + ADE7943_Period, // 0x10E R 16 U 0x0000 Period register + + ADE7953_RESERVED_0X120 = 0x120 // 0x120 This register should be set to 30h to meet the performance specified in Table 1. To modify this register, it must be unlocked by setting Register Address 0xFE to 0xAD immediately prior. }; enum Ade7953_32BitRegisters { @@ -128,6 +133,10 @@ enum Ade7953_32BitRegisters { // ---------------------------- ------ --- -- -- ---------- -------------------------------------------------------------------- ADE7953_ACCMODE = 0x301, // 0x301 R/W 24 U 0x000000 Accumulation mode (see Table 21) + ADE7953_AP_NOLOAD = 0x303, // 0x303 R/W 24 U 0x00E419 No load threshold for actual power + ADE7953_VAR_NOLOAD, // 0x304 R/W 24 U 0x00E419 No load threshold for reactive power + ADE7953_VA_NOLOAD, // 0x305 R/W 24 U 0x000000 No load threshold for appearant power + ADE7953_AVA = 0x310, // 0x310 R 24 S 0x000000 Instantaneous apparent power (Current Channel A) ADE7953_BVA, // 0x311 R 24 S 0x000000 Instantaneous apparent power (Current Channel B) ADE7953_AWATT, // 0x312 R 24 S 0x000000 Instantaneous active power (Current Channel A) @@ -402,9 +411,14 @@ void Ade7953Init(void) { Ade7953DumpRegs(chip); #endif // ADE7953_DUMP_REGS - Ade7953Write(ADE7953_CONFIG, 0x0004); // Locking the communication interface (Clear bit COMM_LOCK), Enable HPF - Ade7953Write(0x0FE, 0x00AD); // Unlock register 0x120 - Ade7953Write(0x120, 0x0030); // Configure optimum setting + Ade7953Write(ADE7953_CONFIG, 0x0004); // Locking the communication interface (Clear bit COMM_LOCK), Enable HPF + Ade7953Write(0x0FE, 0x00AD); // Unlock register 0x120 + Ade7953Write(ADE7953_RESERVED_0X120, 0x0030); // Configure optimum setting + Ade7953Write(ADE7953_DISNOLOAD, 0x07); // Disable no load detection, required before setting thresholds + Ade7953Write(ADE7953_AP_NOLOAD, ADE7953_NO_LOAD_THRESHOLD); // Set no load treshold for active power + Ade7953Write(ADE7953_VAR_NOLOAD, ADE7953_NO_LOAD_THRESHOLD); // Set no load treshold for reactive power + Ade7953Write(ADE7953_DISNOLOAD, 0x00); // Enable no load detection + #ifdef USE_ESP32_SPI // int32_t value = Ade7953Read(0x702); // Silicon version // AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Chip%d version %d"), chip +1, value); @@ -510,16 +524,11 @@ void Ade7953GetData(void) { for (uint32_t channel = 0; channel < Energy->phase_count; channel++) { Ade7953.voltage_rms[channel] = reg[channel][4]; Ade7953.current_rms[channel] = reg[channel][0]; - if (Ade7953.current_rms[channel] < 2000) { // No load threshold (20mA) - Ade7953.current_rms[channel] = 0; - Ade7953.active_power[channel] = 0; - } else { - Ade7953.active_power[channel] = abs(reg[channel][1]); - apparent_power[channel] = abs(reg[channel][2]); - reactive_power[channel] = abs(reg[channel][3]); - if ((ADE7953_SHELLY_EM == Ade7953.model) && (bitRead(acc_mode, 18 +(channel * 3)))) { // VARNLOAD - reactive_power[channel] = 0; - } + Ade7953.active_power[channel] = abs(reg[channel][1]); + apparent_power[channel] = abs(reg[channel][2]); + reactive_power[channel] = abs(reg[channel][3]); + if ((ADE7953_SHELLY_EM == Ade7953.model) && (bitRead(acc_mode, 18 +(channel * 3)))) { // VARNLOAD + reactive_power[channel] = 0; } } diff --git a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino index ba31983dbe6c..183fbb62c21a 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino @@ -47,7 +47,8 @@ struct COUNTER { } Counter; -void IRAM_ATTR CounterIsrArg(void *arg) { +void IRAM_ATTR CounterIsrArg(void *arg); +void CounterIsrArg(void *arg) { uint32_t index = *static_cast(arg); uint32_t time = micros(); diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino index 74ccc478e882..cc0586649b86 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_05_ds18x20.ino @@ -31,7 +31,8 @@ /* #define DS18x20_USE_ID_ALIAS in my_user_config.h or user_config_override.h * Use alias for fixed sensor name in scripts by autoexec. Command: DS18Alias XXXXXXXXXXXXXXXX,N where XXXXXXXXXXXXXXXX full serial and N number 1-255 * Result in JSON: "DS18Sens_2":{"Id":"000003287CD8","Temperature":26.3} (example with N=2) - * add 8 bytes used memory + * Setting N to an alphanumeric value, the complete name is replaced with it + * Result in JSON: "Outside1":{"Id":"000003287CD8","Temperature":26.3} (example with N=Outside1) */ #define DS18S20_CHIPID 0x10 // +/-0.5C 9-bit @@ -49,6 +50,8 @@ #define DS18X20_MAX_SENSORS 8 #endif +#define DS18X20_ALIAS_LEN 17 + const char kDs18x20Types[] PROGMEM = "DS18x20|DS18S20|DS1822|DS18B20|MAX31850"; uint8_t ds18x20_chipids[] = { 0, DS18S20_CHIPID, DS1822_CHIPID, DS18B20_CHIPID, MAX31850_CHIPID }; @@ -62,7 +65,7 @@ struct { uint8_t valid; int8_t pins_id; #ifdef DS18x20_USE_ID_ALIAS - uint8_t alias; + char *alias = (char*)calloc(DS18X20_ALIAS_LEN, 1); #endif // DS18x20_USE_ID_ALIAS } ds18x20_sensor[DS18X20_MAX_SENSORS]; @@ -357,7 +360,7 @@ void Ds18x20Init(void) { ids[DS18X20Data.sensors] = ids[DS18X20Data.sensors] << 8 | ds18x20_sensor[DS18X20Data.sensors].address[j]; } #ifdef DS18x20_USE_ID_ALIAS - ds18x20_sensor[DS18X20Data.sensors].alias=0; + ds18x20_sensor[DS18X20Data.sensors].alias[0] = '0'; #endif ds18x20_sensor[DS18X20Data.sensors].pins_id = pins; DS18X20Data.sensors++; @@ -472,24 +475,28 @@ void Ds18x20Name(uint8_t sensor) { } } GetTextIndexed(DS18X20Data.name, sizeof(DS18X20Data.name), index, kDs18x20Types); - if (DS18X20Data.sensors > 1) { + #ifdef DS18x20_USE_ID_AS_NAME - char address[17]; - for (uint32_t j = 0; j < 3; j++) { - sprintf(address+2*j, "%02X", ds18x20_sensor[ds18x20_sensor[sensor].index].address[3-j]); // Only last 3 bytes - } - snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%s"), DS18X20Data.name, IndexSeparator(), address); -#else -uint8_t print_ind = sensor +1; -#ifdef DS18x20_USE_ID_ALIAS - if (ds18x20_sensor[sensor].alias) { - snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("DS18Sens")); - print_ind = ds18x20_sensor[sensor].alias; + char address[17]; + for (uint32_t j = 0; j < 3; j++) { + sprintf(address+2*j, "%02X", ds18x20_sensor[ds18x20_sensor[sensor].index].address[3-j]); // Only last 3 bytes + } + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%s"), DS18X20Data.name, IndexSeparator(), address); +#elif defined(DS18x20_USE_ID_ALIAS) + if (ds18x20_sensor[sensor].alias[0] != '0') { + if (isdigit(ds18x20_sensor[sensor].alias[0])) { + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("DS18Sens%c%d"), IndexSeparator(), atoi(ds18x20_sensor[sensor].alias)); + } else { + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s"), ds18x20_sensor[sensor].alias); } -#endif - snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), print_ind); -#endif + } else { + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), sensor + 1); } +#else // no #defines set + if (DS18X20Data.sensors > 1) { + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), sensor + 1); + } +#endif } /********************************************************************************************/ @@ -574,25 +581,26 @@ void (* const DSCommand[])(void) PROGMEM = { &CmndDSAlias }; void CmndDSAlias(void) { - uint8_t tmp; - uint8_t sensor=255; - char argument[XdrvMailbox.data_len]; + char Argument1[XdrvMailbox.data_len]; + char Argument2[XdrvMailbox.data_len]; char address[17]; if (ArgC()==2) { - tmp=atoi(ArgV(argument, 2)); - ArgV(argument,1); + ArgV(Argument1, 1); + ArgV(Argument2, 2); + TrimSpace(Argument2); for (uint32_t i = 0; i < DS18X20Data.sensors; i++) { for (uint32_t j = 0; j < 8; j++) { sprintf(address+2*j, "%02X", ds18x20_sensor[i].address[7-j]); } - if (!strncmp(argument,address,12)) { - ds18x20_sensor[i].alias=tmp; + if (!strncmp(Argument1, address, 12) && Argument2[0]) { + snprintf_P(ds18x20_sensor[i].alias, DS18X20_ALIAS_LEN, PSTR("%s"), Argument2); break; } } } + Response_P(PSTR("{")); for (uint32_t i = 0; i < DS18X20Data.sensors; i++) { Ds18x20Name(i); @@ -601,7 +609,7 @@ void CmndDSAlias(void) { sprintf(address+2*j, "%02X", ds18x20_sensor[i].address[7-j]); // Skip sensor type and crc } ResponseAppend_P(PSTR("\"%s\":{\"" D_JSON_ID "\":\"%s\"}"),DS18X20Data.name, address); - if (i < DS18X20Data.sensors-1) {ResponseAppend_P(PSTR(","));} + if (i < DS18X20Data.sensors-1) ResponseAppend_P(PSTR(",")); } ResponseAppend_P(PSTR("}")); } diff --git a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino index 2113f1aed04f..914d9532af3f 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_05_esp32_ds18x20.ino @@ -29,8 +29,9 @@ /* #define DS18x20_USE_ID_ALIAS in my_user_config.h or user_config_override.h * Use alias for fixed sensor name in scripts by autoexec. Command: DS18Alias XXXXXXXXXXXXXXXX,N where XXXXXXXXXXXXXXXX full serial and N number 1-255 - * Result in JSON: "DS18Alias_2":{"Id":"000003287CD8","Temperature":26.3} (example with N=2) - * add 8 bytes used memory + * Result in JSON: "DS18Sens_2":{"Id":"000003287CD8","Temperature":26.3} (example with N=2) + * Setting N to an alphanumeric value, the complete name is replaced with it + * Result in JSON: "Outside1":{"Id":"000003287CD8","Temperature":26.3} (example with N=Outside1) */ #define DS18S20_CHIPID 0x10 // +/-0.5C 9-bit @@ -46,6 +47,8 @@ #define DS18X20_MAX_SENSORS 8 #endif +#define DS18X20_ALIAS_LEN 17 + const char kDs18x20Types[] PROGMEM = "DS18x20|DS18S20|DS1822|DS18B20|MAX31850"; uint8_t ds18x20_chipids[] = { 0, DS18S20_CHIPID, DS1822_CHIPID, DS18B20_CHIPID, MAX31850_CHIPID }; @@ -61,7 +64,7 @@ struct { uint8_t valid; int8_t pins_id; #ifdef DS18x20_USE_ID_ALIAS - uint8_t alias; + char *alias = (char*)calloc(DS18X20_ALIAS_LEN, 1); #endif //DS18x20_USE_ID_ALIAS } ds18x20_sensor[DS18X20_MAX_SENSORS]; @@ -108,7 +111,7 @@ void Ds18x20Search(void) { (ds18x20_sensor[num_sensors].address[0] == DS18B20_CHIPID) || (ds18x20_sensor[num_sensors].address[0] == MAX31850_CHIPID))) { #ifdef DS18x20_USE_ID_ALIAS - ds18x20_sensor[num_sensors].alias=0; + ds18x20_sensor[DS18X20Data.sensors].alias[0] = '0'; #endif ds18x20_sensor[num_sensors].pins_id = pins; num_sensors++; @@ -214,24 +217,28 @@ void Ds18x20Name(uint8_t sensor) { } } GetTextIndexed(DS18X20Data.name, sizeof(DS18X20Data.name), index, kDs18x20Types); - if (DS18X20Data.sensors > 1) { + #ifdef DS18x20_USE_ID_AS_NAME - char address[17]; - for (uint32_t j = 0; j < 3; j++) { - sprintf(address+2*j, "%02X", ds18x20_sensor[ds18x20_sensor[sensor].index].address[3-j]); // Only last 3 bytes - } - snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%s"), DS18X20Data.name, IndexSeparator(), address); -#else -uint8_t print_ind = sensor +1; -#ifdef DS18x20_USE_ID_ALIAS - if (ds18x20_sensor[sensor].alias) { - snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("DS18Sens")); - print_ind = ds18x20_sensor[sensor].alias; + char address[17]; + for (uint32_t j = 0; j < 3; j++) { + sprintf(address+2*j, "%02X", ds18x20_sensor[ds18x20_sensor[sensor].index].address[3-j]); // Only last 3 bytes + } + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%s"), DS18X20Data.name, IndexSeparator(), address); +#elif defined(DS18x20_USE_ID_ALIAS) + if (ds18x20_sensor[sensor].alias[0] != '0') { + if (isdigit(ds18x20_sensor[sensor].alias[0])) { + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("DS18Sens%c%d"), IndexSeparator(), atoi(ds18x20_sensor[sensor].alias)); + } else { + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s"), ds18x20_sensor[sensor].alias); } -#endif - snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), print_ind); -#endif + } else { + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), sensor + 1); } +#else // no #defines set + if (DS18X20Data.sensors > 1) { + snprintf_P(DS18X20Data.name, sizeof(DS18X20Data.name), PSTR("%s%c%d"), DS18X20Data.name, IndexSeparator(), sensor + 1); + } +#endif } /********************************************************************************************/ @@ -317,25 +324,26 @@ void (* const DSCommand[])(void) PROGMEM = { &CmndDSAlias }; void CmndDSAlias(void) { - uint8_t tmp; - uint8_t sensor=255; - char argument[XdrvMailbox.data_len]; + char Argument1[XdrvMailbox.data_len]; + char Argument2[XdrvMailbox.data_len]; char address[17]; if (ArgC()==2) { - tmp=atoi(ArgV(argument, 2)); - ArgV(argument,1); + ArgV(Argument1, 1); + ArgV(Argument2, 2); + TrimSpace(Argument2); for (uint32_t i = 0; i < DS18X20Data.sensors; i++) { for (uint32_t j = 0; j < 8; j++) { sprintf(address+2*j, "%02X", ds18x20_sensor[i].address[7-j]); } - if (!strncmp(argument,address,12)) { - ds18x20_sensor[i].alias=tmp; + if (!strncmp(Argument1, address, 12) && Argument2[0]) { + snprintf_P(ds18x20_sensor[i].alias, DS18X20_ALIAS_LEN, PSTR("%s"), Argument2); break; } } } + Response_P(PSTR("{")); for (uint32_t i = 0; i < DS18X20Data.sensors; i++) { Ds18x20Name(i); @@ -344,7 +352,7 @@ void CmndDSAlias(void) { sprintf(address+2*j, "%02X", ds18x20_sensor[i].address[7-j]); // Skip sensor type and crc } ResponseAppend_P(PSTR("\"%s\":{\"" D_JSON_ID "\":\"%s\"}"),DS18X20Data.name, address); - if (i < DS18X20Data.sensors-1) {ResponseAppend_P(PSTR(","));} + if (i < DS18X20Data.sensors-1) ResponseAppend_P(PSTR(",")); } ResponseAppend_P(PSTR("}")); } diff --git a/tasmota/tasmota_xsns_sensor/xsns_65_hdc1080.ino b/tasmota/tasmota_xsns_sensor/xsns_65_hdc1080.ino index 3d0f5ef29fff..159e7ccc9349 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_65_hdc1080.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_65_hdc1080.ino @@ -75,6 +75,7 @@ float hdc_humidity = 0.0f; uint8_t hdc_valid = 0; bool is_reading = false; +bool hdc_online = false; uint32_t hdc_next_read; /** @@ -176,7 +177,11 @@ bool HdcTriggerRead(void) { hdc_next_read = millis() + HDC1080_CONV_TIME; if(status) { - AddLog(LOG_LEVEL_DEBUG, PSTR("HdcTriggerRead: failed to open the transaction for HDC_REG_TEMP. Status = %d"), status); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_SENSOR "HdcTriggerRead: failed to open the transaction for HDC_REG_TEMP. Status = %d"), status); + if (!--hdc_valid) { + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_SENSOR "%s will be marked as offline"), (char*) hdc_type_name); + hdc_online = false; + } return false; } @@ -205,7 +210,11 @@ bool HdcRead(void) { status = HdcTransactionClose(HDC1080_ADDR, sensor_data, 4); if(status) { - AddLog(LOG_LEVEL_DEBUG, PSTR("HdcRead: failed to read HDC_REG_TEMP. Status = %d"), status); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_SENSOR "HdcRead: failed to read HDC_REG_TEMP. Status = %d"), status); + if (!--hdc_valid) { + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_SENSOR "%s will be marked as offline"), (char*) hdc_type_name); + hdc_online = false; + } return false; } @@ -213,7 +222,7 @@ bool HdcRead(void) { temp_data = (uint16_t) ((sensor_data[0] << 8) | sensor_data[1]); rh_data = (uint16_t) ((sensor_data[2] << 8) | sensor_data[3]); - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HdcRead: temperature raw data: 0x%04x; humidity raw data: 0x%04x"), temp_data, rh_data); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_SENSOR "HdcRead: temperature raw data: 0x%04x; humidity raw data: 0x%04x"), temp_data, rh_data); // read the temperature from the first 16 bits of the result @@ -241,9 +250,10 @@ void HdcDetect(void) { hdc_manufacturer_id = HdcReadManufacturerId(); hdc_device_id = HdcReadDeviceId(); - AddLog(LOG_LEVEL_DEBUG, PSTR("HdcDetect: detected device with manufacturerId = 0x%04X and deviceId = 0x%04X"), hdc_manufacturer_id, hdc_device_id); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_SENSOR "HdcDetect: detected device with manufacturerId = 0x%04X and deviceId = 0x%04X"), hdc_manufacturer_id, hdc_device_id); if (hdc_device_id == HDC1080_DEV_ID) { + hdc_online = true; HdcInit(); I2cSetActiveFound(HDC1080_ADDR, hdc_type_name); } @@ -255,7 +265,7 @@ void HdcDetect(void) { * */ void HdcEverySecond(void) { - if (TasmotaGlobal.uptime &1) { // Every 2 seconds + if (hdc_online & TasmotaGlobal.uptime &1) { // Every 2 seconds if (!HdcTriggerRead()) { AddLogMissed((char*) hdc_type_name, hdc_valid); } @@ -293,7 +303,7 @@ bool Xsns65(uint32_t function) else if (hdc_device_id) { switch (function) { case FUNC_EVERY_50_MSECOND: - if(is_reading && TimeReached(hdc_next_read)) { + if(hdc_online && is_reading && TimeReached(hdc_next_read)) { if(!HdcRead()) { AddLogMissed((char*) hdc_type_name, hdc_valid); }