From 1dff0b4b27bf40d0904d19b5a0cd7124b42e251b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 13 Sep 2024 13:53:01 +0200 Subject: [PATCH] Add support for RX8010 RTC as used in IOTTIMER (#21376) --- BUILDS.md | 10 +- CHANGELOG.md | 3 +- I2CDEVICES.md | 1 + RELEASENOTES.md | 2 + tasmota/my_user_config.h | 7 +- tasmota/tasmota_support/support_features.ino | 18 +-- .../tasmota_xdrv_driver/xdrv_56_rtc_chips.ino | 103 +++++++++++++++++- tools/decode-status.py | 4 +- 8 files changed, 130 insertions(+), 18 deletions(-) diff --git a/BUILDS.md b/BUILDS.md index db4a723ca..b8f12a5f6 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -104,10 +104,15 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the | | | | | | | | | **Feature or Sensor** | **l** | **t** | **k** | **s** | **i** | **d** | **Remarks** | | USE_I2C | - | x / x | x | x | - | x | +| USE_RTC_CHIPS | - | - / x | - | - | - | - | +| -USE_DS3231 | - | - / - | - | - | - | - | +| -USE_BM8563 | - | - / x | - | - | - | - | +| -USE_PCF85363 | - | - / - | - | - | - | - | +| -USE_RX8010 | - | - / - | - | - | - | - | | USE_SHT | - | - / x | - | x | - | - | | USE_HTU | - | - / x | - | x | - | - | | USE_BMP | - | - / x | - | x | - | - | -| USE_BME68X | - | - / x | - | x | - | - | +| -USE_BME68X | - | - / x | - | x | - | - | | USE_AMSX915 | - | - / - | - | - | - | - | | USE_SPL06_007 | - | - / - | - | - | - | - | | USE_QMP6988 | - | - / - | - | - | - | - | @@ -139,7 +144,6 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the | USE_ENS16x | - | - / - | - | - | - | - | | USE_ENS210 | - | - / - | - | - | - | - | | USE_MPU6050 | - | - / - | - | - | - | - | -| USE_DS3231 | - | - / - | - | - | - | - | | USE_MGC3130 | - | - / - | - | - | - | - | | USE_MAX44009 | - | - / - | - | - | - | - | | USE_SCD30 | - | - / x | - | x | - | - | @@ -187,12 +191,10 @@ Note: the `minimal` variant is not listed as it shouldn't be used outside of the | USE_EZORTD | - | - / - | - | - | - | - | | USE_SEESAW_SOIL | - | - / - | - | - | - | - | | USE_TOF10120 | - | - / - | - | - | - | - | -| USE_BM8563 | - | - / - | - | - | - | - | | USE_AM2320 | - | - / - | - | - | - | - | | USE_T67XX | - | - / - | - | - | - | - | | USE_HM330X | - | - / - | - | - | - | - | | USE_HDC2010 | - | - / - | - | - | - | - | -| USE_PCF85363 | - | - / - | - | - | - | - | | USE_DS3502 | - | - / - | - | - | - | - | | USE_HYT | - | - / - | - | - | - | - | | USE_LUXV30B | - | - / - | - | - | - | - | diff --git a/CHANGELOG.md b/CHANGELOG.md index bc96335c2..744800667 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ All notable changes to this project will be documented in this file. - Matter support for Zigbee Occupancy and Light 0/1/2 (OnOff / Dimmer / White Color Temperature) (#22110) - KNX additional KnxTx functions and define KNX_USE_DPT9 (#22071) - Support for I2C M5Unit (Mini)Scales using HX711 driver -- Berry virtual Energy driver +- Berry virtual Energy driver (#22134) +- Support for RX8010 RTC as used in IOTTIMER (#21376) ### Breaking Changed diff --git a/I2CDEVICES.md b/I2CDEVICES.md index 3ef72f1ca..d873bbd59 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -127,5 +127,6 @@ Index | Define | Driver | Device | Address(es) | Bus2 | Descrip 87 | USE_SPL06_007 | xsns_25 | SPL06-007 | 0x76 | | Pressure and temperature sensor 88 | USE_QMP6988 | xsns_28 | QMP6988 | 0x56, 0x70 | Yes | Pressure and temperature sensor 89 | USE_HX711_M5SCALES | xsns_34 | M5SCALES | 0x26 | Yes | M5Unit (Mini)Scales(HX711 STM32) U177 + 90 | USE_RX8010 | xdrv_56 | RX8010 | 0x32 | Yes | RX8010 RTC from IOTTIMER NOTE: Bus2 supported on ESP32 only. diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 0af15f1bf..dbaa834a7 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -124,6 +124,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Command ``SetOption69 1`` to enable Serial Bridge inverted Receive [#22000](https://github.com/arendst/Tasmota/issues/22000) - HX711 optional calibration precision option on command ``Sensor34 2 `` where `` is 1 to 20 [#13983](https://github.com/arendst/Tasmota/issues/13983) - Support for I2C M5Unit (Mini)Scales using HX711 driver +- Support for RX8010 RTC as used in IOTTIMER [#21376](https://github.com/arendst/Tasmota/issues/21376) - Energy command ``PowerSet 60,230`` to calibrate both Current and Power with known resistive load of 60W at 230V using calibrated Voltage - Energy command ``CurrentSet 60,230`` to calibrate both Power and Current with known resistive load of 60W at 230V using calibrated Voltage - Energy Log level 4 message when (Calculated) Apparent Power is less than Active Power indicating wrong calibration [#20653](https://github.com/arendst/Tasmota/issues/20653) @@ -132,6 +133,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - SML multi TRX line [#22056](https://github.com/arendst/Tasmota/issues/22056) - Zigbee Koenkk firmware 20240710 for Sonoff Zigbee ZBPro [#22076](https://github.com/arendst/Tasmota/issues/22076) - Berry Zigbee improvements to prepare Matter [#22083](https://github.com/arendst/Tasmota/issues/22083) +- Berry virtual Energy driver [#22134](https://github.com/arendst/Tasmota/issues/22134) - Matter support for Zigbee Temperature, Humidity and Pressure sensors [#22084](https://github.com/arendst/Tasmota/issues/22084) - Matter support for Zigbee Occupancy and Light 0/1/2 (OnOff / Dimmer / White Color Temperature) [#22110](https://github.com/arendst/Tasmota/issues/22110) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 4b5e7fdf1..a9f454770 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -751,10 +751,11 @@ // #define USE_QMP6988 // [I2cDriver88] Enable QMP6988 pressure and temperature sensor (I2C address 0x56 or 0x70) (+2k9 code) // #define USE_RTC_CHIPS // Enable RTC chip support and NTP server - Select only one -// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC (I2C address 0x68) (+1k2 code) +// #define USE_DS3231 // [I2cDriver26] Enable DS3231 RTC - used by Ulanzi TC001 (I2C address 0x68) (+1k2 code) // #define DS3231_ENABLE_TEMP // In DS3231 driver, enable the internal temperature sensor -// #define USE_BM8563 // [I2cDriver59] Enable BM8563 RTC - found in M5Stack - support both I2C buses on ESP32 (I2C address 0x51) (+2.5k code) -// #define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC - found Shelly 3EM (I2C address 0x51) (+0k7 code) +// #define USE_BM8563 // [I2cDriver59] Enable BM8563 RTC - used by M5Stack - support both I2C buses on ESP32 (I2C address 0x51) (+2.5k code) +// #define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC - used by Shelly 3EM (I2C address 0x51) (+0k7 code) +// #define USE_RX8010 // [I2cDriver90] Enable RX8010 RTC - used by IOTTIMER - support both I2C buses on ESP32 (I2C address 0x32) (+0k7 code) // #define USE_DISPLAY // Add I2C/TM1637/MAX7219 Display Support (+2k code) #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0 diff --git a/tasmota/tasmota_support/support_features.ino b/tasmota/tasmota_support/support_features.ino index be84d2617..bc86f8edb 100644 --- a/tasmota/tasmota_support/support_features.ino +++ b/tasmota/tasmota_support/support_features.ino @@ -348,8 +348,8 @@ constexpr uint32_t feature[] = { #if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM_AC) 0x00000200 | // xnrg_05_pzem_ac.ino #endif -#if defined(USE_I2C) && defined(USE_DS3231) - 0x00000400 | // xsns_33_ds3231.ino +#if defined(USE_I2C) && defined(USE_RTC_CHIPS) && defined(USE_DS3231) + 0x00000400 | // xdrv_56_rtc_chips.ino #endif #ifdef USE_HX711 0x00000800 | // xsns_34_hx711.ino @@ -719,8 +719,8 @@ constexpr uint32_t feature[] = { #ifdef USE_BERRY 0x00000008 | // xdrv_52_9_berry.ino #endif -#if defined(USE_I2C) && defined(USE_BM8563) - 0x00000010 | // xdrv_56_BM8563_RTC.ino +#if defined(USE_I2C) && defined(USE_RTC_CHIPS) && defined(USE_BM8563) + 0x00000010 | // xdrv_56_rtc_chips.ino #endif #if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_DUMMY) 0x00000020 | // xnrg_30_dummy.ino @@ -779,7 +779,7 @@ constexpr uint32_t feature[] = { #if defined(USE_ENERGY_SENSOR) && defined(USE_I2C) && defined(USE_ADE7880) 0x00800000 | // xnrg_23_ade7880.ino #endif -#if defined(USE_I2C) && defined(USE_PCF85363) +#if defined(USE_I2C) && defined(USE_RTC_CHIPS) && defined(USE_PCF85363) 0x01000000 | // xdrv_56_rtc_chips.ino #endif #if defined(USE_I2C) && defined(USE_DS3502) @@ -925,8 +925,12 @@ constexpr uint32_t feature[] = { #ifdef USE_WOOLIIS 0x00000080 | // xsns_115_wooliis.ino #endif -// 0x00000100 | // -// 0x00000200 | // +#if defined(USE_I2C) && defined(USE_HX711_M5SCALES) + 0x00000100 | // xsns_34_hx711.ino +#endif +#if defined(USE_I2C) && defined(USE_RTC_CHIPS) && defined(USE_RX8010) + 0x00000200 | // xdrv_56_rtc_chips.ino +#endif // 0x00000400 | // // 0x00000800 | // // 0x00001000 | // diff --git a/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino b/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino index eacd3a9d2..079c48230 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino @@ -10,6 +10,19 @@ #ifdef USE_RTC_CHIPS /*********************************************************************************************\ * RTC chip support + * + * #define USE_DS3231 + * DS1307 and DS3231 at I2C address 0x68 + * Used by Ulanzi TC001 + * #define USE_BM8563 + * BM8563 at I2C address 0x51 + * Used by M5Stack and IOTTIMER (v3) + * #define USE_PCF85363 + * PCF85363 at I2C address 0x51 + * Used by Shelly 3EM + * #define USE_RX8010 + * RX8010 at I2C address 0x32 + * Used by IOTTIMER (v1 and v2) \*********************************************************************************************/ #define XDRV_56 56 @@ -250,7 +263,6 @@ void BM8563Detected(void) { } #endif // USE_BM8563 - /*********************************************************************************************\ * PCF85363 support * @@ -382,6 +394,92 @@ void Pcf85363Detected(void) { } #endif // USE_PCF85363 +/*********************************************************************************************\ + * RX8010 - Real Time Clock + * based on linux/rtc-rx8010.c + * + * I2C Address: 0x32 +\*********************************************************************************************/ +#ifdef USE_RX8010 + +#define XI2C_90 90 // See I2CDEVICES.md + +#define RX8010_ADDRESS 0x32 // RX8010 I2C Address + +// RX8010 Register Addresses +#define RX8010_REG_SEC 0x10 +#define RX8010_REG_MIN 0x11 +#define RX8010_REG_HOUR 0x12 +#define RX8010_REG_WDAY 0x13 +#define RX8010_REG_MDAY 0x14 +#define RX8010_REG_MONTH 0x15 +#define RX8010_REG_YEAR 0x16 +#define RX8010_REG_CTRL 0x1F + +// Control Register (1Fh) bit positions +#define RX8010_BIT_CTRL_STOP 6 + +/*-------------------------------------------------------------------------------------------*\ + * Read time from RX8010 and return the epoch time (second since 1-1-1970 00:00) +\*-------------------------------------------------------------------------------------------*/ +uint32_t Rx8010ReadTime(void) { + TIME_T tm; + + uint8_t data[7]; + I2cReadBuffer(RtcChip.address, RX8010_REG_SEC, data, 7, RtcChip.bus); + tm.second = Bcd2Dec(data[0] & 0x7F); + tm.minute = Bcd2Dec(data[1] & 0x7F); + tm.hour = Bcd2Dec(data[2] & 0x3F); // Assumes 24hr clock + tm.day_of_month = Bcd2Dec(data[3] & 0x3F); + tm.month = Bcd2Dec(data[4] & 0x3F) -1; + tm.year = Bcd2Dec(data[5]); + if (tm.year < 70) { tm.year += 100; } + tm.day_of_week = Bcd2Dec(data[6] & 0x7F); + return MakeTime(tm); +} + +/*-------------------------------------------------------------------------------------------*\ + * Get time as TIME_T and set the RX8010 time to this value +\*-------------------------------------------------------------------------------------------*/ +void Rx8010SetTime(uint32_t epoch_time) { + TIME_T tm; + BreakTime(epoch_time, tm); + // Set STOP bit before changing clock/calendar + I2cWrite8(RtcChip.address, RX8010_REG_CTRL, I2cRead8(RtcChip.address, RX8010_REG_CTRL, RtcChip.bus) | _BV(RX8010_BIT_CTRL_STOP), RtcChip.bus); + uint8_t data[7]; + data[0] = Dec2Bcd(tm.second); + data[1] = Dec2Bcd(tm.minute); + data[2] = Dec2Bcd(tm.hour); + data[3] = Dec2Bcd(tm.day_of_month); + data[4] = Dec2Bcd(tm.month +1); + data[5] = Dec2Bcd(tm.year % 100); + data[6] = Dec2Bcd(tm.day_of_week); + I2cWriteBuffer(RtcChip.address, RX8010_REG_SEC, data, 7, RtcChip.bus); + // Clear STOP bit after changing clock/calendar + I2cWrite8(RtcChip.address, RX8010_REG_CTRL, I2cRead8(RtcChip.address, RX8010_REG_CTRL, RtcChip.bus) & ~_BV(RX8010_BIT_CTRL_STOP), RtcChip.bus); +} + +/*-------------------------------------------------------------------------------------------*\ + * Detection +\*-------------------------------------------------------------------------------------------*/ +void Rx8010Detected(void) { + if (!RtcChip.detected && I2cEnabled(XI2C_90)) { + RtcChip.address = RX8010_ADDRESS; + for (RtcChip.bus = 0; RtcChip.bus < 2; RtcChip.bus++) { + if (!I2cSetDevice(RtcChip.address, RtcChip.bus)) { continue; } + if (I2cValidRead(RtcChip.address, RX8010_REG_CTRL, 1, RtcChip.bus)) { + RtcChip.detected = 1; + strcpy_P(RtcChip.name, PSTR("RX8010")); + RtcChip.ReadTime = &Rx8010ReadTime; + RtcChip.SetTime = &Rx8010SetTime; + RtcChip.mem_size = -1; + break; + } + } + } +} +#endif // USE_RX8010 + /*********************************************************************************************\ * RTC Detect and time set \*********************************************************************************************/ @@ -399,6 +497,9 @@ void RtcChipDetect(void) { #ifdef USE_PCF85363 Pcf85363Detected(); #endif // USE_PCF85363 +#ifdef USE_RX8010 + Rx8010Detected(); +#endif // USE_RX8010 if (!RtcChip.detected) { return; } diff --git a/tools/decode-status.py b/tools/decode-status.py index 329c9985e..5c99b1a9b 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -306,7 +306,7 @@ a_features = [[ ],[ "USE_MAGIC_SWITCH","USE_PIPSOLAR","USE_GPIO_VIEWER","USE_AMSX915", "USE_SPI_LORA","USE_SPL06_007","USE_QMP6988","USE_WOOLIIS", - "","","","", + "USE_HX711_M5SCALES","USE_RX8010","","", "","","","", "","","","", "","","","", @@ -339,7 +339,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v14.2.0.3 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v14.2.0.4 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj))