diff --git a/I2CDEVICES.md b/I2CDEVICES.md index 79a2bf81ac12..616d3aa56d3a 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -129,5 +129,6 @@ Index | Define | Driver | Device | Address(es) | Bus2 | Descrip 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 91 | USE_MS5837 | xsns_116 | MS5837 | 0x76 | | Pressure and temperature sensor + 92 | USE_PCF85063 | xdrv_56 | PCF85063 | 0x51 | | PCF85063 Real time clock NOTE: Bus2 supported on ESP32 only. diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index fd053df5cf73..b7ae9dea94db 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -769,6 +769,7 @@ // #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_PCF85063 // [I2cDriver92] Enable PCF85063 RTC support (I2C address 0x51) // #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_xdrv_driver/xdrv_56_rtc_chips.ino b/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino index 079c4823088a..6536cdf73c16 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_56_rtc_chips.ino @@ -185,6 +185,112 @@ void DS3231Detected(void) { } #endif // USE_DS3231 + + +/*********************************************************************************************\ + * PCF85063 support + * + * I2C Address: 0x51 +\*********************************************************************************************/ +#ifdef USE_PCF85063 + +#define XI2C_92 92 // Unique ID for I2C device search + +#define PCF85063_ADDRESS 0x51 // PCF85063 I2C Address + + +#define PCF85063_REG_CTRL1 0x00 +#define PCF85063_REG_CTRL2 0x01 +#define PCF85063_REG_OFFSET 0x02 +#define PCF85063_REG_SECONDS 0x04 +#define PCF85063_REG_MINUTES 0x05 +#define PCF85063_REG_HOURS 0x06 +#define PCF85063_REG_DAYS 0x07 +#define PCF85063_REG_WEEKDAYS 0x08 +#define PCF85063_REG_MONTHS 0x09 +#define PCF85063_REG_YEARS 0x0A + + +uint32_t Pcf85063ReadTime(void) { + Wire.beginTransmission(RtcChip.address); + Wire.write(PCF85063_REG_SECONDS); + Wire.endTransmission(false); // false -> repeated start + Wire.requestFrom((uint8_t)RtcChip.address, (uint8_t)7); + + uint8_t sec = Wire.read(); // 0x04 + uint8_t min = Wire.read(); // 0x05 + uint8_t hour = Wire.read(); // 0x06 + uint8_t day = Wire.read(); // 0x07 + uint8_t wday = Wire.read(); // 0x08 + uint8_t month = Wire.read(); // 0x09 + uint8_t year = Wire.read(); // 0x0A + + TIME_T tm; + tm.second = Bcd2Dec(sec & 0x7F); + tm.minute = Bcd2Dec(min & 0x7F); + tm.hour = Bcd2Dec(hour & 0x3F); + tm.day_of_month = Bcd2Dec(day & 0x3F); + tm.day_of_week = wday & 0x07; + tm.month = Bcd2Dec(month & 0x1F) -1; + uint8_t y = Bcd2Dec(year); + tm.year = (y + 30); + return MakeTime(tm); +} + + +void Pcf85063SetTime(uint32_t epoch_time) { + TIME_T tm; + BreakTime(epoch_time, tm); + + + uint8_t year = (tm.year -30); + if (year > 99) { year = 99; } + + uint8_t bcd_sec = Dec2Bcd(tm.second); + uint8_t bcd_min = Dec2Bcd(tm.minute); + uint8_t bcd_hour = Dec2Bcd(tm.hour); + uint8_t bcd_day = Dec2Bcd(tm.day_of_month); + uint8_t bcd_wday = tm.day_of_week & 0x07; + uint8_t bcd_month = Dec2Bcd(tm.month +1); + uint8_t bcd_year = Dec2Bcd(year); + + Wire.beginTransmission(RtcChip.address); + Wire.write(PCF85063_REG_SECONDS); + Wire.write(bcd_sec); + Wire.write(bcd_min); + Wire.write(bcd_hour); + Wire.write(bcd_day); + Wire.write(bcd_wday); + Wire.write(bcd_month); + Wire.write(bcd_year); + Wire.endTransmission(); +} + +/*-------------------------------------------------------------------------------------------*\ + * Detection +\*-------------------------------------------------------------------------------------------*/ +void Pcf85063Detected(void) { + if (!RtcChip.detected && I2cEnabled(XI2C_92)) { + RtcChip.address = PCF85063_ADDRESS; + // Vyskúšame, či vieme prečítať nejaký register + if (I2cSetDevice(RtcChip.address)) { + // Skúsime napr. prečítať PCF85063_REG_CTRL1 + if (I2cValidRead(RtcChip.address, PCF85063_REG_CTRL1, 1)) { + RtcChip.detected = 1; + strcpy_P(RtcChip.name, PSTR("PCF85063")); + RtcChip.ReadTime = &Pcf85063ReadTime; + RtcChip.SetTime = &Pcf85063SetTime; + RtcChip.mem_size = -1; // Nemá extra user RAM, ak by si nepotreboval + + // Ak by si chcel implementovať MemRead/MemWrite, doplň RtcChip.MemRead a RtcChip.MemWrite + } + } + } +} +#endif // USE_PCF85063 + + + /*********************************************************************************************\ * BM8563 - Real Time Clock * @@ -500,6 +606,9 @@ void RtcChipDetect(void) { #ifdef USE_RX8010 Rx8010Detected(); #endif // USE_RX8010 +#ifdef USE_PCF85063 + Pcf85063Detected(); +#endif // USE_PCF85063 if (!RtcChip.detected) { return; }