From d9b8c61fb8cb45fa6d33b65283ffe8ecab34aae6 Mon Sep 17 00:00:00 2001
From: Bertrand Lemasle <blemasle@gmail.com>
Date: Wed, 21 Nov 2018 21:36:20 +1300
Subject: [PATCH] Added an abstraction layer to work on RTC lib trim again

---
 .vscode/c_cpp_properties.json | 43 +++++++++++++++--------------
 gpstracker.code-workspace     |  9 ++++--
 src/Rtc.cpp                   | 26 +++++++++---------
 src/RtcAbstraction.cpp        | 43 +++++++++++++++++++++++++++++
 src/RtcAbstraction.h          | 52 +++++++++++++++++++++++++++++++++++
 src/Time2.h                   |  2 +-
 6 files changed, 137 insertions(+), 38 deletions(-)
 create mode 100644 src/RtcAbstraction.cpp
 create mode 100644 src/RtcAbstraction.h

diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index 230d27d..988dfac 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -1,22 +1,23 @@
-{
-    "configurations": [
-        {
-            "name": "Win32",
-            "includePath": [
-				"${workspaceFolder}/src/**",
-				"${workspaceFolder}/../libraries/SIM808",
-				"${workspaceFolder}/../libraries/uDS3231",
-				"${workspaceFolder}/../libraries/E24",
-				"${workspaceFolder}/../libraries/Low-Power",
-				"${workspaceFolder}/../libraries/ArduinoLog",
-				"${config:arduino.path}/tools/**",
-				"${config:arduino.path}/hardware/arduino/avr/**",
-				"${config:arduino.path}/hardware/tools/avr/avr/include/**"
-            ],
-            "intelliSenseMode": "clang-x64",
-            "cStandard": "c11",
-            "cppStandard": "c++11"
-        }
-    ],
-    "version": 4
+{
+    "configurations": [
+        {
+            "name": "Win32",
+            "includePath": [
+				"${workspaceFolder}/src/**",
+				"${workspaceFolder}/../libraries/SIM808",
+				"${workspaceFolder}/../libraries/MD_DS3231",
+				"${workspaceFolder}/../libraries/uDS3231",
+				"${workspaceFolder}/../libraries/E24",
+				"${workspaceFolder}/../libraries/Low-Power",
+				"${workspaceFolder}/../libraries/ArduinoLog",
+				"${config:arduino.path}/tools/**",
+				"${config:arduino.path}/hardware/arduino/avr/**",
+				"${config:arduino.path}/hardware/tools/avr/avr/include/**"
+			],
+            "intelliSenseMode": "clang-x64",
+            "cStandard": "c11",
+            "cppStandard": "c++11"
+        }
+    ],
+    "version": 4
 }
\ No newline at end of file
diff --git a/gpstracker.code-workspace b/gpstracker.code-workspace
index 1f9a02e..bdb9aa3 100644
--- a/gpstracker.code-workspace
+++ b/gpstracker.code-workspace
@@ -6,9 +6,6 @@
 		{
 			"path": "../libraries/SIM808"
 		},
-		{
-			"path": "../libraries/uDS3231"
-		},
 		{
 			"path": "../libraries/E24"
 		},
@@ -17,6 +14,12 @@
 		},
 		{
 			"path": "../libraries/ArduinoLog"
+		},
+		{
+			"path": "C:/Users/bertr/Documents/Projects/Development/Arduino/libraries/MD_DS3231"
+		},
+		{
+			"path": "C:/Users/bertr/Documents/Projects/Development/Arduino/libraries/uDS3231"
 		}
 	],
 	"settings": {
diff --git a/src/Rtc.cpp b/src/Rtc.cpp
index 43e38ff..13d7fc3 100644
--- a/src/Rtc.cpp
+++ b/src/Rtc.cpp
@@ -4,26 +4,26 @@
 #include "Logging.h"
 
 #include <Wire.h>
-#include <uDS3231.h>
 
 #define LOGGER_NAME "Rtc"
 
 using namespace utils;
 
 namespace rtc {
+	RTC_A_CLASS RTC_A;
 
 	void setup() {
 		VERBOSE("setup");
 		hardware::i2c::powerOn();
-		RTC.control(DS3231_12H, DS3231_OFF); //24 hours clock
-		RTC.control(DS3231_A1_INT_ENABLE, DS3231_OFF); //Alarm 1 OFF
-		RTC.control(DS3231_INT_ENABLE, DS3231_ON); //INTCN ON
+		RTC_A.control(DS3231_12H, DS3231_OFF); //24 hours clock
+		RTC_A.control(DS3231_A1_INT_ENABLE, DS3231_OFF); //Alarm 1 OFF
+		RTC_A.control(DS3231_INT_ENABLE, DS3231_ON); //INTCN ON
 		hardware::i2c::powerOff();
 	}
 
 	int16_t getTemperature() {
 		hardware::i2c::powerOn();
-		float temperature = RTC.readTempRegister();
+		float temperature = RTC_A.readTempRegister();
 		hardware::i2c::powerOff();
 
 		return static_cast<int16_t>(temperature * 100);
@@ -31,7 +31,7 @@ namespace rtc {
 
 	bool isAccurate() {
 		hardware::i2c::powerOn();
-		bool accurate = RTC.status(DS3231_HALTED_FLAG) == DS3231_OFF;
+		bool accurate = RTC_A.status(DS3231_HALTED_FLAG) == DS3231_OFF;
 		hardware::i2c::powerOff();
 
 		return accurate;
@@ -45,7 +45,7 @@ namespace rtc {
 
 	void getTime(tmElements_t &time) {
 		hardware::i2c::powerOn();
-		RTC.readTime(time);
+		RTC_A.readTime(time);
 		hardware::i2c::powerOff();
 
 		VERBOSE_FORMAT("getTime", "%d/%d/%d %d:%d:%d", tmYearToCalendar(time.Year), time.Month, time.Day, time.Hour, time.Minute, time.Second);
@@ -55,8 +55,8 @@ namespace rtc {
 		VERBOSE_FORMAT("setTime", "%d/%d/%d %d:%d:%d", tmYearToCalendar(time.Year), time.Month, time.Day, time.Hour, time.Minute, time.Second);
 
 		hardware::i2c::powerOn();
-		RTC.writeTime(time);
-		RTC.control(DS3231_HALTED_FLAG, DS3231_OFF);
+		RTC_A.writeTime(time);
+		RTC_A.control(DS3231_HALTED_FLAG, DS3231_OFF);
 		hardware::i2c::powerOff();
 	}
 
@@ -72,11 +72,11 @@ namespace rtc {
 
 	void setAlarm(const tmElements_t &time) {
 		hardware::i2c::powerOn();
-		RTC.writeAlarm1(DS3231_ALM_HMS, time);
+		RTC_A.writeAlarm1(DS3231_ALM_HMS, time);
 
-		RTC.control(DS3231_A1_FLAG, DS3231_OFF); //reset Alarm 1 flag
-		RTC.control(DS3231_A1_INT_ENABLE, DS3231_ON); //Alarm 1 ON
-		RTC.control(DS3231_INT_ENABLE, DS3231_ON); //INTCN ON
+		RTC_A.control(DS3231_A1_FLAG, DS3231_OFF); //reset Alarm 1 flag
+		RTC_A.control(DS3231_A1_INT_ENABLE, DS3231_ON); //Alarm 1 ON
+		RTC_A.control(DS3231_INT_ENABLE, DS3231_ON); //INTCN ON
 
 		NOTICE_FORMAT("setAlarm", "Next alarm : %d:%d:%d", time.Hour, time.Minute, time.Second);
 
diff --git a/src/RtcAbstraction.cpp b/src/RtcAbstraction.cpp
new file mode 100644
index 0000000..80afb88
--- /dev/null
+++ b/src/RtcAbstraction.cpp
@@ -0,0 +1,43 @@
+#include "RtcAbstraction.h"
+
+void uDS3231_Ext::unpack(tmElements_t &time) {
+	time.Second = s;
+	time.Minute = m;
+	time.Hour = h;
+	time.Day = dd;
+	time.Month = mm;
+	time.Year = yyyy;
+}
+
+void uDS3231_Ext::pack(const tmElements_t &time) {
+	s = time.Second;
+	m = time.Minute;
+	h = time.Hour;
+	dd = time.Day;
+	mm = time.Month;
+	yyyy = time.Year;
+}
+
+boolean uDS3231_Ext::readTime(tmElements_t &time) {
+	bool result = MD_DS3231::readTime();
+	unpack(time);
+
+	return result;
+}
+
+boolean uDS3231_Ext::writeTime(const tmElements_t &time) {
+	pack(time);
+	return MD_DS3231::writeTime();
+}
+
+boolean uDS3231_Ext::readAlarm1(almType_t &almType, tmElements_t &time) {
+	almType = MD_DS3231::getAlarm1Type();
+	bool result = MD_DS3231::readAlarm1();
+
+	return result;
+}
+
+boolean uDS3231_Ext::writeAlarm1(almType_t almType, const tmElements_t &time) {
+	pack(time);
+	return MD_DS3231::writeAlarm1(almType);
+}
\ No newline at end of file
diff --git a/src/RtcAbstraction.h b/src/RtcAbstraction.h
new file mode 100644
index 0000000..43e9974
--- /dev/null
+++ b/src/RtcAbstraction.h
@@ -0,0 +1,52 @@
+#pragma once
+
+/**
+ * \def USE_UDS3231
+ * When defined, use the modified uDS3231 library instead of
+ * the stock MD_DS3231 one.
+ */
+//#define USE_UDS3231
+
+#ifdef USE_UDS3231
+#include <uDS3231.h>
+#else
+#include <MD_DS3231.h>
+#endif
+
+#ifndef USE_UDS3231
+
+//convenience macros to convert to and from tm years
+#define  tmYearToCalendar(Y) ((Y) + 2000)  // full four digit year
+#define  CalendarYrToTm(Y)   ((Y) - 2000)
+
+typedef unsigned long timestamp_t;
+
+typedef struct tmElements_t {
+	uint8_t Second;
+	uint8_t Minute;
+	uint8_t Hour;
+	uint8_t Day;
+	uint8_t Month;
+	uint8_t Year;   // year from 2000
+};
+
+class uDS3231_Ext : public MD_DS3231
+{
+private:
+	void unpack(tmElements_t &time)
+	void pack(const tmElements_t &time);
+public:
+	boolean readTime(tmElements_t &time);
+	boolean writeTime(const tmElements_t &time);
+
+	boolean readAlarm1(almType_t &almType, tmElements_t &time);
+	boolean writeAlarm1(almType_t almType, const tmElements_t &time);
+};
+
+#define RTC_A_CLASS uDS3231_Ext
+
+#else
+
+#define RTC_A_CLASS uDS3231
+
+#endif
diff --git a/src/Time2.h b/src/Time2.h
index 6f9947a..fa4f1f5 100644
--- a/src/Time2.h
+++ b/src/Time2.h
@@ -1,7 +1,7 @@
 #pragma once
 
 #include <Arduino.h>
-#include <uDS3231.h>
+#include "RtcAbstraction.h"
 
 namespace utils {
 	namespace time {