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; | |||||
} |