mirror of https://github.com/arendst/Tasmota.git
Add support for PCF85363 RTC as used in Shelly 3EM
Add support for PCF85363 RTC as used in Shelly 3EM (#13515)
This commit is contained in:
parent
b82f7d9ed7
commit
c20bc70d1c
|
@ -13,7 +13,8 @@ All notable changes to this project will be documented in this file.
|
|||
- Full DS3231 integration and synchronisation when using UBX (=GPS), NTP or manual time
|
||||
- LVGL Splash screen and ``SetOption135 1`` to disable splash screen
|
||||
- Command ``RfTimeout 100..60000`` to disable duplicate RfReceive. Default 1000 (#15061)
|
||||
- Support for Shelly 3EM (#13515)
|
||||
- Support for ADE7880 3 phase energy monitor as used in Shelly 3EM (#13515)
|
||||
- Support for PCF85363 RTC as used in Shelly 3EM (#13515)
|
||||
|
||||
### Changed
|
||||
- Extent number of pulsetimers from 8 to 32 (#8266)
|
||||
|
|
|
@ -99,3 +99,4 @@ Index | Define | Driver | Device | Address(es) | Description
|
|||
63 | USE_HM330X | xsns_93 | HM330X | 0x40 | Particule sensor
|
||||
64 | USE_HDC2010 | xsns_94 | HDC2010 | 0x40 | Temperature and Humidity sensor
|
||||
65 | USE_ADE7880 | xnrg_23 | ADE7880 | 0x38 | Energy monitor
|
||||
66 | USE_PCF85363 | xsns_99 | PCF85363 | 0x51 | Real time clock
|
||||
|
|
|
@ -112,7 +112,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
|||
- NeoPool commands ``NPpHMin``, ``NPpHMax``, ``NPpH``, ``NPRedox``, ``NPHydrolysis``, ``NPIonization``, ``NPChlorine`` and ``NPControl`` [#15015](https://github.com/arendst/Tasmota/issues/15015)
|
||||
- NeoPool system voltages display
|
||||
- TasmotaSerial implement ``end()``
|
||||
- Support for Shelly 3EM [#13515](https://github.com/arendst/Tasmota/issues/13515)
|
||||
- Support for ADE7880 3 phase energy monitor as used in Shelly 3EM [#13515](https://github.com/arendst/Tasmota/issues/13515)
|
||||
- Support for PCF85363 RTC as used in Shelly 3EM (#13515)
|
||||
- Full DS3231 integration and synchronisation when using UBX (=GPS), NTP or manual time
|
||||
- ESP32 Berry always enable rules
|
||||
- ESP32 Berry bootloop protection
|
||||
|
|
|
@ -669,6 +669,7 @@
|
|||
// #define HM330X_DEFAULT_ADDRESS 0x40 // Option: change default I2C address for HM330X used in SeedSTudio Particucle Sensor
|
||||
// #define HM330X_WARMUP_DELAY 30 // Option: change warmup delay during which data are not read from sensor after a power up
|
||||
// #define HM330X_HIDE_OUT_OF_DATE false // Option: change to true to hide data from web GUI and SENSOR while sensor is asleep
|
||||
// #define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC (I2C address 0x51) (+0k7 code)
|
||||
|
||||
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
|
||||
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
|
||||
|
|
|
@ -1965,6 +1965,16 @@ void SerialSendDecimal(char *values)
|
|||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
uint8_t Bcd2Dec(uint8_t n) {
|
||||
return n - 6 * (n >> 4);
|
||||
}
|
||||
|
||||
uint8_t Dec2Bcd(uint8_t n) {
|
||||
return n + 6 * (n / 10);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Sleep aware time scheduler functions borrowed from ESPEasy
|
||||
\*********************************************************************************************/
|
||||
|
|
|
@ -795,10 +795,11 @@ void ResponseAppendFeatures(void)
|
|||
feature8 |= 0x00400000; // xnrg_22_bl6523.ino
|
||||
#endif
|
||||
#if defined(USE_ENERGY_SENSOR) && defined(USE_I2C) && defined(USE_ADE7880)
|
||||
feature8 |= 0x00800000;
|
||||
feature8 |= 0x00800000; // xnrg_23_ade7880.ino
|
||||
#endif
|
||||
#if defined(USE_I2C) && defined(USE_PCF85363)
|
||||
feature8 |= 0x01000000; // xsns_96_pcf85393.ino
|
||||
#endif
|
||||
|
||||
// feature8 |= 0x01000000;
|
||||
// feature8 |= 0x02000000;
|
||||
// feature8 |= 0x04000000;
|
||||
// feature8 |= 0x08000000;
|
||||
|
|
|
@ -150,6 +150,7 @@
|
|||
//#define USE_AM2320 // [I2cDriver60] Enable AM2320 temperature and humidity Sensor (I2C address 0x5C) (+1k code)
|
||||
//#define USE_T67XX // [I2cDriver61] Enable Telaire T67XX CO2 sensor (I2C address 0x15) (+1k3 code)
|
||||
//#define USE_HDC2010 // [I2cDriver64] Enable HDC2010 temperature/humidity sensor (I2C address 0x40) (+1k5 code)
|
||||
//#define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC (I2C address 0x51) (+0k7 code)
|
||||
|
||||
//#define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC)
|
||||
//#define USE_RC522 // Add support for MFRC522 13.56Mhz Rfid reader (+6k code)
|
||||
|
|
|
@ -242,6 +242,7 @@
|
|||
//#define USE_BM8563 // [I2cDriver59] Enable BM8563 RTC - found in M5Stack - support both I2C buses on ESP32 (I2C address 0x51) (+2k5 code)
|
||||
//#define USE_AM2320 // [I2cDriver60] Enable AM2320 temperature and humidity Sensor (I2C address 0x5C) (+1k code)
|
||||
//#define USE_T67XX // [I2cDriver61] Enable Telaire T67XX CO2 sensor (I2C address 0x15) (+1k3 code)
|
||||
//#define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC (I2C address 0x51) (+0k7 code)
|
||||
|
||||
//#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
|
||||
//#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
|
||||
|
@ -376,6 +377,7 @@
|
|||
//#define USE_EZORGB // [I2cDriver55] Enable support for EZO's RGB sensor (+0k5 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
//#define USE_EZOPMP // [I2cDriver55] Enable support for EZO's PMP sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
|
||||
//#define USE_SEESAW_SOIL // [I2cDriver56] Enable Capacitice Soil Moisture & Temperature Sensor (I2C addresses 0x36 - 0x39) (+1k3 code)
|
||||
//#define USE_PCF85363 // [I2cDriver66] Enable PCF85363 RTC (I2C address 0x51) (+0k7 code)
|
||||
|
||||
#define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC)
|
||||
//#define USE_RC522 // Add support for MFRC522 13.56Mhz Rfid reader (+6k code)
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
xsns_96_pcf85363.ino - PCF85363 RTC chip support for Tasmota
|
||||
|
||||
SPDX-FileCopyrightText: 2022 Theo Arends
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
#ifdef USE_I2C
|
||||
#ifdef USE_PCF85363
|
||||
/*********************************************************************************************\
|
||||
* PCF85363 support
|
||||
*
|
||||
* I2C Address: 0x51
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XSNS_96 96
|
||||
#define XI2C_66 66 // See I2CDEVICES.md
|
||||
|
||||
#define USE_PCF85363_ADDR 0x51 // PCF85363 I2C Address
|
||||
|
||||
bool pcf85363_detected = false;
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Read time and return the epoch time (second since 1-1-1970 00:00)
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
uint32_t Pcf85363ReadTime(void) {
|
||||
Wire.beginTransmission((uint8_t)USE_PCF85363_ADDR);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
|
||||
uint8_t buffer[8];
|
||||
Wire.requestFrom((int)USE_PCF85363_ADDR, (int)8);
|
||||
for (uint32_t i = 0; i < 8; i++) { buffer[i] = Wire.read(); }
|
||||
Wire.endTransmission();
|
||||
|
||||
TIME_T tm;
|
||||
tm.second = Bcd2Dec(buffer[1] & 0x7F);
|
||||
tm.minute = Bcd2Dec(buffer[2] & 0x7F);
|
||||
tm.hour = Bcd2Dec(buffer[3]);
|
||||
tm.day_of_month = Bcd2Dec(buffer[4]);
|
||||
tm.day_of_week = buffer[5];
|
||||
tm.month = Bcd2Dec(buffer[6]);
|
||||
tm.year = 30 + Bcd2Dec(buffer[7]); // Offset from 1970. So 2022 - 1970 = 52
|
||||
return MakeTime(tm);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Get time as TIME_T and set time to this value
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
void Pcf85363SetTime(uint32_t epoch_time) {
|
||||
TIME_T tm;
|
||||
BreakTime(epoch_time, tm);
|
||||
|
||||
uint8_t buffer[8];
|
||||
buffer[0] = 0x00; // 100th_seconds (not used)
|
||||
buffer[1] = Dec2Bcd(tm.second);
|
||||
buffer[2] = Dec2Bcd(tm.minute);
|
||||
buffer[3] = Dec2Bcd(tm.hour);
|
||||
buffer[4] = Dec2Bcd(tm.day_of_month);
|
||||
buffer[5] = tm.day_of_week;
|
||||
buffer[6] = Dec2Bcd(tm.month);
|
||||
buffer[7] = Dec2Bcd(tm.year -30); // Offset from 1970
|
||||
/*
|
||||
// Handbook page 13
|
||||
Wire.beginTransmission((uint8_t)USE_PCF85363_ADDR);
|
||||
Wire.write(0x2E);
|
||||
Wire.write(0x01); // Set stop
|
||||
Wire.write(0xA4); // Clear prescaler
|
||||
for (uint32_t i = 0; i < 8; i++) { Wire.write(buffer[i]); }
|
||||
Wire.endTransmission();
|
||||
Wire.beginTransmission((uint8_t)USE_PCF85363_ADDR);
|
||||
Wire.write(0x2E);
|
||||
Wire.write(0x00); // Set start
|
||||
Wire.endTransmission();
|
||||
*/
|
||||
Wire.beginTransmission((uint8_t)USE_PCF85363_ADDR);
|
||||
Wire.write(0x00);
|
||||
for (uint32_t i = 0; i < 8; i++) { Wire.write(buffer[i]); }
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------*\
|
||||
* Dump all registers
|
||||
\*-------------------------------------------------------------------------------------------*/
|
||||
/*
|
||||
void Pcf85363Dump(void) {
|
||||
uint8_t buffer[64];
|
||||
|
||||
// 0x00 to 0x2F
|
||||
Wire.beginTransmission((uint8_t)USE_PCF85363_ADDR);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((int)USE_PCF85363_ADDR, (int)48);
|
||||
for (uint32_t i = 0; i < 48; i++) {
|
||||
buffer[i] = Wire.read();
|
||||
}
|
||||
Wire.endTransmission();
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("P85: Read 0x00: %48_H"), buffer);
|
||||
|
||||
// 0x40 to 0x7F
|
||||
Wire.beginTransmission((uint8_t)USE_PCF85363_ADDR);
|
||||
Wire.write(0x40);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((int)USE_PCF85363_ADDR, (int)64);
|
||||
for (uint32_t i = 0; i < 64; i++) {
|
||||
buffer[i] = Wire.read();
|
||||
}
|
||||
Wire.endTransmission();
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("P85: Read 0x40: %64_H"), buffer);
|
||||
}
|
||||
*/
|
||||
/*********************************************************************************************/
|
||||
|
||||
void Pcf85363Detect(void) {
|
||||
if (!I2cSetDevice(USE_PCF85363_ADDR)) { return; }
|
||||
I2cSetActiveFound(USE_PCF85363_ADDR, "PCF85363");
|
||||
|
||||
pcf85363_detected = true;
|
||||
|
||||
if (Rtc.utc_time < START_VALID_TIME) { // Not sync with NTP/GPS (time not valid), so read time
|
||||
uint32_t time = Pcf85363ReadTime(); // Read UTC TIME
|
||||
if (time > START_VALID_TIME) {
|
||||
Rtc.utc_time = time;
|
||||
RtcSync("PCF85363");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Pcf85363TimeSynced(void) {
|
||||
if ((Rtc.utc_time > START_VALID_TIME) && // Valid UTC time
|
||||
(abs((int32_t)(Rtc.utc_time - Pcf85363ReadTime())) > 2)) { // Time has drifted from RTC more than 2 seconds
|
||||
Pcf85363SetTime(Rtc.utc_time); // Update time
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("P85: Re-synced (" D_UTC_TIME ") %s"), GetDateAndTime(DT_UTC).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xsns96(uint8_t function) {
|
||||
if (!I2cEnabled(XI2C_66)) { return false; }
|
||||
|
||||
bool result = false;
|
||||
|
||||
if (FUNC_INIT == function) {
|
||||
Pcf85363Detect();
|
||||
}
|
||||
else if (pcf85363_detected) {
|
||||
switch (function) {
|
||||
case FUNC_TIME_SYNCED:
|
||||
Pcf85363TimeSynced();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_PCF85363
|
||||
#endif // USE_I2C
|
|
@ -263,7 +263,7 @@ a_features = [[
|
|||
"USE_HRG15","USE_VINDRIKTNING","USE_SCD40","USE_HM330X",
|
||||
"USE_HDC2010","USE_LSC_MCSL","USE_SONOFF_SPM","USE_SHIFT595",
|
||||
"USE_SDM230","USE_CM110x","USE_BL6523","USE_ADE7880",
|
||||
"","","","",
|
||||
"USE_PCF85363","","","",
|
||||
"","","",""
|
||||
]]
|
||||
|
||||
|
|
Loading…
Reference in New Issue