From 903c5c1de7da3f8804341b2c06660d7da5accb58 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 2 Nov 2021 14:54:32 +0100
Subject: [PATCH] Refactor BM8563 driver

---
 tasmota/xdrv_56_BM8563_RTC.ino | 97 ++++++++++++++++------------------
 1 file changed, 45 insertions(+), 52 deletions(-)

diff --git a/tasmota/xdrv_56_BM8563_RTC.ino b/tasmota/xdrv_56_BM8563_RTC.ino
index 1473da83c..9f8fd589b 100644
--- a/tasmota/xdrv_56_BM8563_RTC.ino
+++ b/tasmota/xdrv_56_BM8563_RTC.ino
@@ -1,7 +1,7 @@
 /*
-  xdrv_52_9_berry.ino - Berry scripting language
+  xdrv_56_BM8563_RTC.ino - BM8563 RTC
 
-  Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry
+  Copyright (C) 2021  Stephan Hadinger and Theo Arends
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -17,9 +17,13 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-
 #ifdef USE_I2C
 #ifdef USE_BM8563
+/*********************************************************************************************\
+ * BM8563 - Real Time Clock
+ *
+ * I2C Address: 0x51 (Fixed in library as BM8563_ADRESS)
+\*********************************************************************************************/
 
 #define XDRV_56             56
 #define XI2C_59             59  // See I2CDEVICES.md
@@ -32,31 +36,7 @@ struct {
   bool ntp_time_ok = false;
 } bm8563_driver;
 
-/*********************************************************************************************\
- * 
- *
-\*********************************************************************************************/
-void BM8563Detect(void) {
-#ifdef ESP32
-  if (!I2cSetDevice(BM8563_ADRESS, 0)) {
-    if (!I2cSetDevice(BM8563_ADRESS, 1)) { return; }        // check on bus 1
-    bm8563_driver.Rtc.setBus(1);                             // switch to bus 1
-    I2cSetActiveFound(BM8563_ADRESS, "BM8563", 1);
-  } else {
-    I2cSetActiveFound(BM8563_ADRESS, "BM8563", 0);
-  }
-#else
-  if (!I2cSetDevice(BM8563_ADRESS)) { return; }
-  I2cSetActiveFound(BM8563_ADRESS, "BM8563");
-#endif
-
-  bm8563_driver.Rtc.begin();
-  bm8563_driver.rtc_ready = true;
-}
-
-
 uint32_t BM8563GetUtc(void) {
-  if (!bm8563_driver.rtc_ready) return 0;
   RTC_TimeTypeDef RTCtime;
   // 1. read has errors ???
   bm8563_driver.Rtc.GetTime(&RTCtime);
@@ -75,7 +55,6 @@ uint32_t BM8563GetUtc(void) {
 }
 
 void BM8563SetUtc(uint32_t epoch_time) {
-  if (!bm8563_driver.rtc_ready) return;
   TIME_T tm;
   BreakTime(epoch_time, tm);
   RTC_TimeTypeDef RTCtime;
@@ -92,7 +71,7 @@ void BM8563SetUtc(uint32_t epoch_time) {
 }
 
 void InitTimeFromRTC(void) {
-  if (bm8563_driver.rtc_ready && Rtc.utc_time < START_VALID_TIME) {
+  if (Rtc.utc_time < START_VALID_TIME) {
     // set rtc from chip
     Rtc.utc_time = BM8563GetUtc();
 
@@ -102,7 +81,7 @@ void InitTimeFromRTC(void) {
     Rtc.daylight_saving_time = RuleToTime(Settings->tflag[1], RtcTime.year);
     Rtc.standard_time = RuleToTime(Settings->tflag[0], RtcTime.year);
     AddLog(LOG_LEVEL_INFO, PSTR("I2C: Set time from BM8563 to RTC (" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"),
-                GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str());
+      GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str());
     if (Rtc.local_time < START_VALID_TIME) {  // 2016-01-01
       TasmotaGlobal.rules_flag.time_init = 1;
     } else {
@@ -111,39 +90,53 @@ void InitTimeFromRTC(void) {
   }
 }
 
+void BM8563Detect(void) {
+#ifdef ESP32
+  if (!I2cSetDevice(BM8563_ADRESS, 0)) {
+    if (!I2cSetDevice(BM8563_ADRESS, 1)) { return; }        // check on bus 1
+    bm8563_driver.Rtc.setBus(1);                            // switch to bus 1
+    I2cSetActiveFound(BM8563_ADRESS, "BM8563", 1);
+  } else {
+    I2cSetActiveFound(BM8563_ADRESS, "BM8563", 0);
+  }
+#else
+  if (!I2cSetDevice(BM8563_ADRESS)) { return; }
+  I2cSetActiveFound(BM8563_ADRESS, "BM8563");
+#endif
+
+  bm8563_driver.Rtc.begin();
+  bm8563_driver.rtc_ready = true;
+
+  InitTimeFromRTC();
+}
 
 void BM8563EverySecond(void) {
-  if (bm8563_driver.rtc_ready) {
-    if (!bm8563_driver.ntp_time_ok && Rtc.utc_time > START_VALID_TIME && abs((int32_t)Rtc.utc_time - (int32_t)BM8563GetUtc()) > 3) {
-      BM8563SetUtc(Rtc.utc_time);
-      AddLog(LOG_LEVEL_INFO, PSTR("I2C: Write Time TO BM8563 from NTP (" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"),
-                  GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str());
-      bm8563_driver.ntp_time_ok = true;
-    }
+  if (!bm8563_driver.ntp_time_ok && (Rtc.utc_time > START_VALID_TIME) && abs((int32_t)Rtc.utc_time - (int32_t)BM8563GetUtc()) > 3) {
+    BM8563SetUtc(Rtc.utc_time);
+    AddLog(LOG_LEVEL_INFO, PSTR("I2C: Write time to BM8563 from NTP (" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"),
+      GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str());
+    bm8563_driver.ntp_time_ok = true;
   }
 }
 
 /*********************************************************************************************\
  * Interface
 \*********************************************************************************************/
-bool Xdrv56(uint8_t function)
-{
-  bool result = false;
+
+bool Xdrv56(uint8_t function) {
   if (!I2cEnabled(XI2C_59)) { return false; }
 
-  switch (function) {
-    // case FUNC_PRE_INIT: // we start Berry in pre_init so that other modules can call Berry in their init methods
-    case FUNC_INIT:  
-        BM8563Detect();
-        InitTimeFromRTC();
-      break;
+  bool result = false;
 
-    case FUNC_EVERY_SECOND:
-      BM8563EverySecond();
-      break;
-
-    case FUNC_SAVE_BEFORE_RESTART:
-      break;
+  if (FUNC_INIT == function) {
+    BM8563Detect();
+  }
+  else if (bm8563_driver.rtc_ready) {
+    switch (function) {
+      case FUNC_EVERY_SECOND:
+        BM8563EverySecond();
+        break;
+    }
   }
   return result;
 }