- implement generic support for on-device battery powered RTC Modules.

- implement support for I2C RV-3028 based RTC modules like the RAK12002
- pretty print some debug timestamps
This commit is contained in:
Thomas Göttgens 2022-04-27 11:05:08 +02:00
parent 3a9086dfc5
commit 9e97fac252
13 changed files with 72 additions and 13 deletions

View File

@ -72,7 +72,7 @@ size_t RedirectablePrint::logDebug(const char *format, ...)
// If we are the first message on a report, include the header // If we are the first message on a report, include the header
if (!isContinuationMessage) { if (!isContinuationMessage) {
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet); uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
if (rtc_sec > 0) { if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY; long hms = rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR; // hms += tz.tz_dsttime * SEC_PER_HOUR;

View File

@ -25,6 +25,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#pragma once #pragma once
#include <Arduino.h> #include <Arduino.h>
#ifdef RV3028_RTC
#include "Melopero_RV3028.h"
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Version // Version
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -54,7 +54,16 @@ void scanI2Cdevice(void)
DEBUG_MSG("unknown display found\n"); DEBUG_MSG("unknown display found\n");
} }
} }
#ifdef RV3028_RTC
if (addr == RV3028_RTC){
rtc_found = addr;
DEBUG_MSG("RV3028 RTC found\n");
Melopero_RV3028 rtc;
rtc.initI2C();
rtc.writeToRegister(0x35,0x07); // no Clkout
rtc.writeToRegister(0x37,0xB4);
}
#endif
if (addr == CARDKB_ADDR) { if (addr == CARDKB_ADDR) {
cardkb_found = addr; cardkb_found = addr;
DEBUG_MSG("m5 cardKB found\n"); DEBUG_MSG("m5 cardKB found\n");
@ -81,7 +90,7 @@ void scanI2Cdevice(void)
if (nDevices == 0) if (nDevices == 0)
DEBUG_MSG("No I2C devices found\n"); DEBUG_MSG("No I2C devices found\n");
else else
DEBUG_MSG("done\n"); DEBUG_MSG("%i I2C devices found\n",nDevices);
} }
#else #else
void scanI2Cdevice(void) {} void scanI2Cdevice(void) {}

View File

@ -65,7 +65,7 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
t.tm_year = d.year() - 1900; t.tm_year = d.year() - 1900;
t.tm_isdst = false; t.tm_isdst = false;
if (t.tm_mon > -1){ if (t.tm_mon > -1){
DEBUG_MSG("NMEA GPS time %d-%d-%d %d:%d:%d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); DEBUG_MSG("NMEA GPS time %02d-%02d-%02d %02d:%02d:%02d\n", d.year(), d.month(), t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
perhapsSetRTC(RTCQualityGPS, t); perhapsSetRTC(RTCQualityGPS, t);
return true; return true;
} else } else

View File

@ -1,5 +1,6 @@
#include "RTC.h" #include "RTC.h"
#include "configuration.h" #include "configuration.h"
#include "main.h"
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
@ -18,14 +19,35 @@ static uint64_t zeroOffsetSecs; // GPS based time in secs since 1970 - only upda
void readFromRTC() void readFromRTC()
{ {
struct timeval tv; /* btw settimeofday() is helpfull here too*/ struct timeval tv; /* btw settimeofday() is helpfull here too*/
#ifdef RV3028_RTC
if(rtc_found == RV3028_RTC) {
uint32_t now = millis();
Melopero_RV3028 rtc;
rtc.initI2C();
tm t;
t.tm_year = rtc.getYear() - 1900;
t.tm_mon = rtc.getMonth() - 1;
t.tm_mday = rtc.getDate();
t.tm_hour = rtc.getHour();
t.tm_min = rtc.getMinute();
t.tm_sec = rtc.getSecond();
tv.tv_sec = mktime(&t);
tv.tv_usec = 0;
DEBUG_MSG("Read RTC time from RV3028 as %ld\n", tv.tv_sec);
timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec;
if (currentQuality == RTCQualityNone) {
currentQuality = RTCQualityDevice;
}
}
#else
if (!gettimeofday(&tv, NULL)) { if (!gettimeofday(&tv, NULL)) {
uint32_t now = millis(); uint32_t now = millis();
DEBUG_MSG("Read RTC time as %ld\n", tv.tv_sec);
DEBUG_MSG("Read RTC time as %ld (cur millis %u) quality=%d\n", tv.tv_sec, now, currentQuality);
timeStartMsec = now; timeStartMsec = now;
zeroOffsetSecs = tv.tv_sec; zeroOffsetSecs = tv.tv_sec;
} }
#endif
} }
/// If we haven't yet set our RTC this boot, set it from a GPS derived time /// If we haven't yet set our RTC this boot, set it from a GPS derived time
@ -55,12 +77,20 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
zeroOffsetSecs = tv->tv_sec; zeroOffsetSecs = tv->tv_sec;
// If this platform has a setable RTC, set it // If this platform has a setable RTC, set it
#ifndef NO_ESP32 #ifdef RV3028_RTC
if(rtc_found == RV3028_RTC) {
Melopero_RV3028 rtc;
rtc.initI2C();
tm *t = localtime(&tv->tv_sec);
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
DEBUG_MSG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
}
#elif !defined(NO_ESP32)
settimeofday(tv, NULL); settimeofday(tv, NULL);
#endif #endif
// nrf52 doesn't have a readable RTC (yet - software not written) // nrf52 doesn't have a readable RTC (yet - software not written)
#if defined(PORTDUINO) || !defined(NO_ESP32) #if defined(PORTDUINO) || !defined(NO_ESP32) || defined(RV3028_RTC)
readFromRTC(); readFromRTC();
#endif #endif

View File

@ -5,17 +5,21 @@
#include <Arduino.h> #include <Arduino.h>
enum RTCQuality { enum RTCQuality {
/// We haven't had our RTC set yet /// We haven't had our RTC set yet
RTCQualityNone = 0, RTCQualityNone = 0,
/// We got time from an onboard peripheral after boot.
RTCQualityDevice = 1,
/// Some other node gave us a time we can use /// Some other node gave us a time we can use
RTCQualityFromNet = 1, RTCQualityFromNet = 2,
/// Our time is based on NTP /// Our time is based on NTP
RTCQualityNTP= 2, RTCQualityNTP= 3,
/// Our time is based on our own GPS /// Our time is based on our own GPS
RTCQualityGPS = 3 RTCQualityGPS = 4
}; };
RTCQuality getRTCQuality(); RTCQuality getRTCQuality();

View File

@ -1557,7 +1557,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
else else
uptime += String(seconds) + "s "; uptime += String(seconds) + "s ";
uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityFromNet); uint32_t rtc_sec = getValidTime(RTCQuality::RTCQualityDevice);
if (rtc_sec > 0) { if (rtc_sec > 0) {
long hms = rtc_sec % SEC_PER_DAY; long hms = rtc_sec % SEC_PER_DAY;
// hms += tz.tz_dsttime * SEC_PER_HOUR; // hms += tz.tz_dsttime * SEC_PER_HOUR;

View File

@ -79,6 +79,9 @@ uint8_t cardkb_found;
// The I2C address of the Faces Keyboard (if found) // The I2C address of the Faces Keyboard (if found)
uint8_t faceskb_found; uint8_t faceskb_found;
// The I2C address of the RTC Module (if found)
uint8_t rtc_found;
bool eink_found = true; bool eink_found = true;
uint32_t serialSinceMsec; uint32_t serialSinceMsec;

View File

@ -9,6 +9,7 @@ extern uint8_t screen_found;
extern uint8_t screen_model; extern uint8_t screen_model;
extern uint8_t cardkb_found; extern uint8_t cardkb_found;
extern uint8_t faceskb_found; extern uint8_t faceskb_found;
extern uint8_t rtc_found;
extern bool eink_found; extern bool eink_found;
extern bool axp192_found; extern bool axp192_found;

View File

@ -6,6 +6,7 @@ build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631 -D RAK_4631
src_filter = ${nrf52_base.src_filter} +<../variants/rak4631> src_filter = ${nrf52_base.src_filter} +<../variants/rak4631>
lib_deps = lib_deps =
${nrf52840_base.lib_deps} ${nrf52840_base.lib_deps}
melopero/Melopero RV3028@^1.1.0
debug_tool = jlink debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink ;upload_protocol = jlink

View File

@ -198,6 +198,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define GPS_RX_PIN PIN_SERIAL1_RX #define GPS_RX_PIN PIN_SERIAL1_RX
#define GPS_TX_PIN PIN_SERIAL1_TX #define GPS_TX_PIN PIN_SERIAL1_TX
// RAK12002 RTC Module
#define RV3028_RTC (uint8_t) 0b1010010
// Battery // Battery
// The battery sense is hooked to pin A0 (5) // The battery sense is hooked to pin A0 (5)
#define BATTERY_PIN PIN_A0 #define BATTERY_PIN PIN_A0

View File

@ -7,6 +7,7 @@ src_filter = ${nrf52_base.src_filter} +<../variants/rak4631_epaper>
lib_deps = lib_deps =
${nrf52840_base.lib_deps} ${nrf52840_base.lib_deps}
https://github.com/ZinggJM/GxEPD2.git https://github.com/ZinggJM/GxEPD2.git
melopero/Melopero RV3028@^1.1.0
debug_tool = jlink debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink ;upload_protocol = jlink

View File

@ -198,6 +198,9 @@ static const uint8_t SCK = PIN_SPI_SCK;
#define GPS_RX_PIN PIN_SERIAL1_RX #define GPS_RX_PIN PIN_SERIAL1_RX
#define GPS_TX_PIN PIN_SERIAL1_TX #define GPS_TX_PIN PIN_SERIAL1_TX
// RAK12002 RTC Module
#define RV3028_RTC (uint8_t) 0b1010010
// Battery // Battery
// The battery sense is hooked to pin A0 (5) // The battery sense is hooked to pin A0 (5)
#define BATTERY_PIN PIN_A0 #define BATTERY_PIN PIN_A0