add complex support for RTC (ds3231 ds1307 etc)rtc
@ -0,0 +1,37 @@ | |||
/* | |||
RTC support module | |||
Copyright (C) 2018 by Pavel Chauzov <poulch at mail dot ru> | |||
*/ | |||
// ----------------------------------------------------------------------------- | |||
// RTC3231_SUPPORT | |||
// ----------------------------------------------------------------------------- | |||
#ifndef RTC_SUPPORT | |||
#define RTC_SUPPORT 0 // enable battery backed RTC for ntp | |||
#define RTC_PROVIDER RTC_DUMMY | |||
#endif | |||
#ifndef RTC_RECOVERY_CNT | |||
#define RTC_RECOVERY_CNT 10 // 0 no recovery | |||
#endif | |||
#ifndef RTC_NTP_SYNC_ENA | |||
#define RTC_NTP_SYNC_ENA 1 // enable sync RTC on NTP sync success | |||
#endif | |||
#if RTC_SUPPORT | |||
#if RTC_PROVIDER == RTC_PROVIDER_DS3231 | |||
#include "../rtc/ds3231.h" | |||
#elif RTC_PROVIDER == RTC_PROVIDER_DS1307 | |||
#include "../rtc/ds1307.h" | |||
#else | |||
#include "../rtc/dummy.h" | |||
#endif | |||
#endif |
@ -0,0 +1,95 @@ | |||
/* | |||
RTC support module | |||
Copyright (C) 2018 by Pavel Chauzov <poulch at mail dot ru> | |||
in debug terminal - RTC return current rtc time | |||
- RTC YYYY-MM-DD DoW HH:MM:SS setup rtc | |||
*/ | |||
#if RTC_SUPPORT | |||
static int _rtc_recovery = 0; | |||
static time_t ntp_getTime() { | |||
time_t tm = 0; | |||
if(_rtc_recovery == 0) { tm = NTP.getTime(); } | |||
if((_rtc_recovery !=0) || (tm == 0)) { | |||
_rtc_recovery++; | |||
tm = getTime_rtc(); | |||
// signal ntp loop to update clock but not rtc... | |||
_ntp_update = true; | |||
#if RTC_SUPPORT && RTC_NTP_SYNC_ENA | |||
_rtc_update = false; | |||
#endif | |||
} | |||
if(_rtc_recovery > RTC_RECOVERY_CNT) { _rtc_recovery = RTC_RECOVERY_CNT ? 0:1; } | |||
DEBUG_MSG_P(PSTR("[NTP] RTC Time : %s\n"), (char *) ntpDateTime(tm).c_str()); | |||
return tm; | |||
} | |||
//------------------------------------------------------------------------------ | |||
// Settings | |||
//------------------------------------------------------------------------------ | |||
#if TERMINAL_SUPPORT | |||
String _rtc_getValue(String data, char sep, int idx) { | |||
int found = 0; | |||
int si[] = {0, -1}; | |||
int maxi = data.length()-1; | |||
for(int i=0; i<=maxi && found<=idx; i++) { | |||
if(data.charAt(i)==sep || i==maxi) { | |||
found++; | |||
si[0] = si[1]+1; | |||
si[1] = (i == maxi) ? i+1 : i; | |||
} | |||
} | |||
return found>idx ? data.substring(si[0], si[1]) : "0"; | |||
} | |||
void _rtcInitCommands() { | |||
settingsRegisterCommand(F("RTC"), [](Embedis* e) { | |||
String rtc; | |||
time_t t; | |||
tmElements_t tm; | |||
if (e->argc == 1) { | |||
t = getTime_rtc(); | |||
DEBUG_MSG_P(PSTR("[NTP] GET RTC Local Time: %s\n"), (char *) ntpDateTime(t).c_str()); | |||
} | |||
if (e->argc > 3) { | |||
String sdate = String(e->argv[1]); | |||
String sdow = String(e->argv[2]); | |||
String stime = String(e->argv[3]); | |||
tm.Second = _rtc_getValue(stime,':',2).toInt(); | |||
tm.Minute = _rtc_getValue(stime,':',1).toInt(); | |||
tm.Hour = _rtc_getValue(stime,':',0).toInt(); | |||
tm.Wday = sdow.toInt(); | |||
tm.Day = _rtc_getValue(sdate,'-',2).toInt(); | |||
tm.Month = _rtc_getValue(sdate,'-',1).toInt(); | |||
tm.Year = y2kYearToTm(_rtc_getValue(sdate,'-',0).toInt()-2000); | |||
t = makeTime(tm); | |||
setTime_rtc(t); | |||
setTime(t); | |||
DEBUG_MSG_P(PSTR("[NTP] SET RTC Local Time: %s\n"), (char *) ntpDateTime(t).c_str()); | |||
} | |||
DEBUG_MSG_P(PSTR("+OK\n")); | |||
}); | |||
} | |||
#endif // TERMINAL_SUPPORT | |||
#endif |
@ -0,0 +1,17 @@ | |||
# RTC support module | |||
## commands in debug terminal | |||
- RTC return current rtc time | |||
- RTC YYYY-MM-DD DoW HH:MM:SS setup rtc | |||
## defines to enable support for modules in hardware.h | |||
- #define RTC_SUPPORT 0/1 enable/disable RTC support | |||
- #define RTC_PROVIDER RTC_PROVIDER_DS3231 etc... spec which rtc ic to use | |||
- #define RTC_RECOVERY_CNT 10(def) // 0 no attempt to switch back to NTP time | |||
- #define RTC_NTP_SYNC_ENA 0/1 // 0 independed rtc, not synced with ntp, | |||
1 rtc synced with ntp on ntp success | |||
## to add new rtc ic support | |||
- see ds3231.h as example, create your_ic.h file and write two | |||
functions time_t getTime_rtc() and uint8_t setTime_rtc(time_t nt) | |||
- define your provider constant in config/types.h | |||
- add your provider section in config/rtc.h |
@ -0,0 +1,55 @@ | |||
/* | |||
ds1307 support module | |||
not tested but it almost similar to ds3231, so it maybe work | |||
Copyright (C) 2018 by Pavel Chauzov <poulch at mail dot ru> | |||
*/ | |||
#pragma once | |||
#undef I2C_SUPPORT | |||
#define I2C_SUPPORT 1 // Explicitly request I2C support. | |||
#include <TimeLib.h> | |||
#define DS1307ADDR 0x68 | |||
#define _bcdToDec(val) ((uint8_t) ((val / 16 * 10) + (val % 16))) | |||
#define _decToBcd(val) ((uint8_t) ((val / 10 * 16) + (val % 10))) | |||
time_t getTime_rtc() { | |||
uint8_t data[7]; | |||
tmElements_t tm; | |||
i2c_write_uint8(DS1307ADDR,0); | |||
i2c_read_buffer(DS1307ADDR, data, 7); | |||
tm.Second = _bcdToDec(data[0]); | |||
tm.Minute = _bcdToDec(data[1]); | |||
tm.Hour = _bcdToDec(data[2]); | |||
tm.Wday = _bcdToDec(data[3]); | |||
tm.Day = _bcdToDec(data[4]); | |||
tm.Month = _bcdToDec(data[5]); | |||
tm.Year = y2kYearToTm(_bcdToDec(data[6])); | |||
return makeTime(tm); | |||
} | |||
uint8_t setTime_rtc(time_t nt) { | |||
uint8_t data[8]; | |||
tmElements_t ct; | |||
breakTime(nt, ct); | |||
data[0] = 0; | |||
data[1] = _decToBcd(ct.Second); | |||
data[2] = _decToBcd(ct.Minute); | |||
data[3] = _decToBcd(ct.Hour); | |||
data[4] = _decToBcd(ct.Wday); | |||
data[5] = _decToBcd(ct.Day); | |||
data[6] = _decToBcd(ct.Month); | |||
data[7] = _decToBcd(tmYearToY2k(ct.Year)); | |||
uint8_t s = i2c_write_buffer(DS1307ADDR, data, 8); | |||
return s; | |||
} |
@ -0,0 +1,52 @@ | |||
/* | |||
ds3231 support module | |||
Copyright (C) 2018 by Pavel Chauzov <poulch at mail dot ru> | |||
*/ | |||
#pragma once | |||
#undef I2C_SUPPORT | |||
#define I2C_SUPPORT 1 // Explicitly request I2C support. | |||
#include <TimeLib.h> | |||
#define DS3231ADDR 0x68 | |||
#define _bcdToDec(val) ((uint8_t) ((val / 16 * 10) + (val % 16))) | |||
#define _decToBcd(val) ((uint8_t) ((val / 10 * 16) + (val % 10))) | |||
time_t getTime_rtc() { | |||
uint8_t data[7]; | |||
tmElements_t tm; | |||
i2c_write_uint8(DS3231ADDR,0); | |||
i2c_read_buffer(DS3231ADDR, data, 7); | |||
tm.Second = _bcdToDec(data[0]); | |||
tm.Minute = _bcdToDec(data[1]); | |||
tm.Hour = _bcdToDec(data[2]); | |||
tm.Wday = _bcdToDec(data[3]); | |||
tm.Day = _bcdToDec(data[4]); | |||
tm.Month = _bcdToDec(data[5]); | |||
tm.Year = y2kYearToTm(_bcdToDec(data[6])); | |||
return makeTime(tm); | |||
} | |||
uint8_t setTime_rtc(time_t nt) { | |||
uint8_t data[8]; | |||
tmElements_t ct; | |||
breakTime(nt, ct); | |||
data[0] = 0; | |||
data[1] = _decToBcd(ct.Second); | |||
data[2] = _decToBcd(ct.Minute); | |||
data[3] = _decToBcd(ct.Hour); | |||
data[4] = _decToBcd(ct.Wday); | |||
data[5] = _decToBcd(ct.Day); | |||
data[6] = _decToBcd(ct.Month); | |||
data[7] = _decToBcd(tmYearToY2k(ct.Year)); | |||
uint8_t s = i2c_write_buffer(DS3231ADDR, data, 8); | |||
return s; | |||
} |
@ -0,0 +1,30 @@ | |||
/* | |||
dummyRTC support module | |||
Copyright (C) 2018 by Pavel Chauzov <poulch at mail dot ru> | |||
*/ | |||
#include <TimeLib.h> | |||
#define _bcdToDec(val) ((uint8_t) ((val / 16 * 10) + (val % 16))) | |||
#define _decToBcd(val) ((uint8_t) ((val / 10 * 16) + (val % 10))) | |||
time_t getTime_rtc() { | |||
tmElements_t tm; | |||
tm.Second = _bcdToDec(1); | |||
tm.Minute = _bcdToDec(0); | |||
tm.Hour = _bcdToDec(0); | |||
tm.Wday = _bcdToDec(0); | |||
tm.Day = _bcdToDec(1); | |||
tm.Month = _bcdToDec(1); | |||
tm.Year = y2kYearToTm(16); | |||
return makeTime(tm); | |||
} | |||
uint8_t setTime_rtc(time_t nt) { | |||
return 0; | |||
} |