321 lines
9.0 KiB
C++
321 lines
9.0 KiB
C++
#include "MCP7940_ADI.h"
|
|
|
|
#include <Wire.h>
|
|
|
|
// Serial Monitor Cheat Cheat for setting time and alarms
|
|
// SETTING TIME
|
|
// format set a to 1 if 12hr mode, then b to 1 if PM, otherwise set to 00 for 24hr mode
|
|
// Thh:mm:22 ab mm/dd/yr w
|
|
|
|
// Example for setting time to 3:41:00PM 2/4/17 SAT
|
|
////T03:41:00 11 02/04/17 7
|
|
|
|
// SETTING ALARM
|
|
// abc = alarm mask, like 001=Minutes alarm
|
|
// d = AM/PM, 1=PM w=weekday
|
|
// A0hh:mm:ss abc d mm/dd w
|
|
// Example for setting alarm for 12:13PM on Sunday 2/4
|
|
// A012:13:00 111 1 02/04 1
|
|
|
|
// defines
|
|
#define RTCADDR B1101111 // page11 datasheet
|
|
#define RTCSEC 0x00
|
|
#define RTCMIN 0x01
|
|
#define RTCHOUR 0x02
|
|
#define RTCWKDAY 0x03
|
|
#define RTCDATE 0x04
|
|
#define RTCMTH 0x05
|
|
#define RTCYEAR 0x06
|
|
#define CONTROL 0x07
|
|
#define OSCTRIM 0x08
|
|
#define ALM0SEC 0x0A
|
|
#define ALM0MIN 0x0B
|
|
#define ALM0HOUR 0x0C
|
|
#define ALM0WKDAY 0x0D
|
|
#define ALM0DATE 0x0E
|
|
#define ALM0MTH 0x0F
|
|
#define ALM1SEC 0x11
|
|
#define ALM1MIN 0x12
|
|
#define ALM1HOUR 0x13
|
|
#define ALM1WKDAY 0x14
|
|
#define ALM1DATE 0x15
|
|
#define ALM1MTH 0x16
|
|
#define PWRDNMIN 0x18
|
|
#define PWRDNHOUR 0x19
|
|
#define PWRDNDATE 0x1A
|
|
#define PWRDNMTH 0x1B
|
|
#define PWRUPMIN 0x1C
|
|
#define PWRUPHOUR 0x1D
|
|
#define PWRUPDATE 0x1E
|
|
#define PWRUPMTH 0x1F
|
|
|
|
// variables used here
|
|
byte rtcSeconds, rtcMinutes, rtcHours;
|
|
byte rtcWeekDay, rtcDay, rtcMonth, rtcYear;
|
|
boolean rtc12hrMode, rtcPM, rtcOscRunning, rtcPowerFail, rtcVbatEn;
|
|
String weekDay[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
|
|
boolean mfpPinTriggered = false;
|
|
|
|
void rtcInit()
|
|
{ // RTC Initialize
|
|
int i;
|
|
// sets up I2C at 100kHz
|
|
Wire.setClock(100000);
|
|
Wire.begin();
|
|
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(CONTROL);
|
|
Wire.write(0x00); // clear out the entire control register // was 0x41
|
|
Wire.endTransmission();
|
|
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(RTCWKDAY);
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(RTCADDR, 1);
|
|
delay(1);
|
|
byte rtcWeekdayRegister = Wire.read();
|
|
rtcWeekdayRegister |= 0x08; // enable Battery backup
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(RTCWKDAY);
|
|
Wire.write(rtcWeekdayRegister);
|
|
Wire.endTransmission();
|
|
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(RTCSEC);
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(RTCADDR, 1);
|
|
delay(1);
|
|
byte rtcSecondRegister = Wire.read(); // read out seconds
|
|
rtcSecondRegister |= 0x80; // flip the start bit to ON
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(RTCSEC);
|
|
Wire.write(rtcSecondRegister); // write it back in... now the RTC is running
|
|
Wire.endTransmission();
|
|
|
|
// read time out of rtc
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(RTCSEC);
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(RTCADDR, 7); // pull out all timekeeping registers
|
|
delay(1); // little delay
|
|
}
|
|
|
|
uint32_t getEpochRtc(void)
|
|
{
|
|
|
|
uint32_t ep;
|
|
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(RTCSEC);
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(RTCADDR, 7); // pull out all timekeeping registers
|
|
delay(1); // little delay
|
|
|
|
// now read each byte in and clear off bits we don't need, hence the AND operations
|
|
rtcSeconds = Wire.read() & 0x7F;
|
|
rtcMinutes = Wire.read() & 0x7F;
|
|
rtcHours = Wire.read() & 0x7F;
|
|
rtcWeekDay = Wire.read() & 0x3F;
|
|
rtcDay = Wire.read() & 0x3F;
|
|
rtcMonth = Wire.read() & 0x3F;
|
|
rtcYear = Wire.read();
|
|
|
|
// now format the data, combine lower and upper parts of byte to give decimal number
|
|
rtcSeconds = (rtcSeconds >> 4) * 10 + (rtcSeconds & 0x0F);
|
|
rtcMinutes = (rtcMinutes >> 4) * 10 + (rtcMinutes & 0x0F);
|
|
|
|
if ((rtcHours >> 6) == 1) // check for 12hr mode
|
|
rtc12hrMode = true;
|
|
else
|
|
rtc12hrMode = false;
|
|
|
|
// 12hr check and formatting of Hours
|
|
if (rtc12hrMode)
|
|
{ // 12 hr mode so get PM/AM
|
|
if ((rtcHours >> 5) & 0x01 == 1)
|
|
rtcPM = true;
|
|
else
|
|
rtcPM = false;
|
|
rtcHours = ((rtcHours >> 4) & 0x01) * 10 + (rtcHours & 0x0F); // only up to 12
|
|
}
|
|
else
|
|
{ // 24hr mode
|
|
rtcPM = false;
|
|
rtcHours = ((rtcHours >> 4) & 0x03) * 10 + (rtcHours & 0x0F); // uses both Tens digits, '23'
|
|
}
|
|
|
|
// weekday register has some other bits in it, that are pulled out here
|
|
if ((rtcWeekDay >> 5) & 0x01 == 1)
|
|
rtcOscRunning = true; // good thing to check to make sure the RTC is running
|
|
else
|
|
rtcOscRunning = false;
|
|
if ((rtcWeekDay >> 4) & 0x01 == 1)
|
|
rtcPowerFail = true; // if the power fail bit is set, we can then go pull the timestamp for when it happened
|
|
else
|
|
rtcPowerFail = false;
|
|
if ((rtcWeekDay >> 3) & 0x01 == 1) // check to make sure the battery backup is enabled
|
|
rtcVbatEn = true;
|
|
else
|
|
rtcVbatEn = false;
|
|
|
|
rtcWeekDay = rtcWeekDay & 0x07; // only the bottom 3 bits for the actual weekday value
|
|
|
|
// more formatting bytes into decimal numbers
|
|
rtcDay = (rtcDay >> 4) * 10 + (rtcDay & 0x0F);
|
|
rtcMonth = ((rtcMonth >> 4) & 0x01) * 10 + (rtcMonth & 0x0F);
|
|
rtcYear = (rtcYear >> 4) * 10 + (rtcYear & 0x0F);
|
|
|
|
dt.Second = rtcSeconds;
|
|
dt.Minute = rtcMinutes;
|
|
dt.Hour = rtcHours;
|
|
dt.Wday = rtcWeekDay;
|
|
dt.Day = rtcDay;
|
|
dt.Month = rtcMonth;
|
|
dt.Year = rtcYear;
|
|
|
|
// dt.Year += 30; //from 1970. not 2000
|
|
dt.Year += 30;
|
|
ep = makeTime(dt);
|
|
// dt.Year -= 30;
|
|
|
|
if (VB)
|
|
{
|
|
Serial.print("Epoch Created: ");
|
|
Serial.println(ep);
|
|
// print everything out
|
|
Serial.print(rtcHours);
|
|
Serial.print(":");
|
|
Serial.print(rtcMinutes);
|
|
Serial.print(":");
|
|
Serial.print(rtcSeconds);
|
|
|
|
if (rtc12hrMode == true && rtcPM == true)
|
|
Serial.print(" PM ");
|
|
else if (rtc12hrMode == true && rtcPM == false)
|
|
Serial.print(" AM ");
|
|
|
|
if (rtc12hrMode == false)
|
|
Serial.print(" 24hr ");
|
|
|
|
if (rtcWeekDay > 0)
|
|
if (rtcWeekDay < 8)
|
|
{
|
|
// Serial.print("WeekDay=");
|
|
// Serial.print(rtcWeekDay);
|
|
Serial.print(weekDay[rtcWeekDay - 1]);
|
|
Serial.print(" ");
|
|
Serial.print(rtcMonth);
|
|
Serial.print("/");
|
|
Serial.print(rtcDay);
|
|
Serial.print("/");
|
|
Serial.print(rtcYear);
|
|
Serial.println("");
|
|
}
|
|
}
|
|
|
|
return (ep);
|
|
}
|
|
|
|
/*
|
|
void checkAlarm() {
|
|
if (mfpPinTriggered == true) {
|
|
Serial.println("MFP Triggered");
|
|
mfpPinTriggered = false;
|
|
Wire.beginTransmission(RTCADDR);//Enable Alarm0
|
|
Wire.write(ALM0WKDAY);
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(RTCADDR, 1);
|
|
delay(1);
|
|
byte alarm0Check = Wire.read();
|
|
Serial.println(alarm0Check, BIN);
|
|
if (((alarm0Check >> 3) & 0x01) == 1)
|
|
Serial.println("Alarm0 Triggered");
|
|
else Serial.println("Alarm0 False Alarm");
|
|
}
|
|
|
|
}
|
|
*/
|
|
|
|
void setEpochRtc(uint32_t ep)
|
|
{
|
|
tmElements_t et;
|
|
|
|
parms.write(69, ep); // just to monitor last rtc set
|
|
|
|
Serial.print("Setting RTC with Epoch: ");
|
|
Serial.println(ep);
|
|
|
|
// breakTime off by 30 years
|
|
breakTime(ep, et);
|
|
et.Year -= 30;
|
|
|
|
// let's go change the time:
|
|
// first stop the clock:
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(RTCSEC);
|
|
Wire.write(0x00);
|
|
Wire.endTransmission();
|
|
|
|
getEpochRtc();
|
|
// rtcGetTime();//go grab the time again just to make sure the osc stopped
|
|
|
|
if (rtcOscRunning == false)
|
|
{ // oscillator stopped, we're good
|
|
Serial.println("RTC has stopped - Changing Time");
|
|
Wire.beginTransmission(RTCADDR); // set the time/date
|
|
Wire.write(RTCSEC);
|
|
Wire.write(((et.Second / 10) << 4) + (et.Second % 10));
|
|
Wire.write(((et.Minute / 10) << 4) + (et.Minute % 10));
|
|
Wire.write(((et.Hour / 10) << 4) + (et.Hour % 10));
|
|
Wire.write(et.Wday + 8);
|
|
Wire.write(((et.Day / 10) << 4) + (et.Day % 10));
|
|
Wire.write(((et.Month / 10) << 4) + (et.Month % 10));
|
|
Wire.write(((et.Year / 10) << 4) + (et.Year % 10)); // two digit year
|
|
Wire.endTransmission();
|
|
|
|
Wire.beginTransmission(RTCADDR); // start back up
|
|
Wire.write(RTCSEC);
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(RTCADDR, 1);
|
|
delay(1);
|
|
byte rtcSecondRegister = Wire.read();
|
|
rtcSecondRegister |= 0x80; // start bit!
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(RTCSEC);
|
|
Wire.write(rtcSecondRegister);
|
|
Wire.endTransmission();
|
|
|
|
Wire.beginTransmission(RTCADDR); // Enable Alarm0
|
|
Wire.write(CONTROL);
|
|
Wire.endTransmission();
|
|
Wire.requestFrom(RTCADDR, 1);
|
|
delay(1);
|
|
byte rtcControlRegister = Wire.read();
|
|
rtcControlRegister |= 0x10; // enable alm0
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(CONTROL);
|
|
Wire.write(rtcControlRegister);
|
|
Wire.endTransmission();
|
|
}
|
|
Serial.println(" --RTC set finished");
|
|
}
|
|
|
|
String makeTimeStr(void)
|
|
{
|
|
getEpochRtc();
|
|
return (String(dt.Year - 30) + "-" + String(dt.Month) + "-" + String(dt.Day) + "-" + String(dt.Hour) + "-" + String(dt.Minute) + "-" + String(dt.Second));
|
|
}
|
|
|
|
void toggleMFP(void)
|
|
{
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(CONTROL);
|
|
Wire.write(0x80);
|
|
Wire.endTransmission();
|
|
delay(250);
|
|
Wire.beginTransmission(RTCADDR);
|
|
Wire.write(CONTROL);
|
|
Wire.write(0x00);
|
|
Wire.endTransmission();
|
|
}
|