Driver "ds1337.cpp":
extern "C" {
#include <Wire/Wire.h>
#include <avr/pgmspace.h>
#include <HardwareSerial.h>
}
#include "programStrings.h"
#include "ds1337.h"
#include "rtcConfig.h"
DS1337::DS1337()
{
#ifdef WIRE_LIB_SCAN_MOD
clockExists = false;
#endif
Wire.begin();
}
DS1337 RTC = DS1337();
#ifdef WIRE_LIB_SCAN_MOD
int8_t DS1337::clockInit(void)
{
// Account for the crystal power up!
delay(250);
// Check address and returns false is there is an error
if (Wire.checkAddress(DS1337_WADDR)) {
// Possibly set the default registers here
clockExists = true;
// Start the oscillator if need
if (getRegisterBit(DS1337_SP, DS1337_SP_EOSC))
{
clockStart();
}
return DS1337_WADDR;
} else clockExists = false;
return -1;
}
#endif
void DS1337::setRegister(uint8_t registerNumber, uint8_t registerMask)
{
writeRegister(registerNumber, (getRegister(registerNumber) | registerMask));
}
void DS1337::unsetRegister(uint8_t registerNumber, uint8_t registerMask)
{
writeRegister(registerNumber, (getRegister(registerNumber) & ~registerMask));
}
void DS1337::writeRegister(uint8_t registerNumber, uint8_t registerValue)
{
Wire.beginTransmission(DS1337_WADDR);
Wire.send(registerNumber);
Wire.send(registerValue);
Wire.endTransmission();
}
uint8_t DS1337::getRegister(uint8_t registerNumber)
{
Wire.beginTransmission(DS1337_WADDR);
Wire.send(registerNumber);
Wire.endTransmission();
Wire.requestFrom(DS1337_WADDR, 1);
return Wire.receive();
}
// PRIVATE FUNCTIONS
void DS1337::clockRead(void)
{
Wire.beginTransmission(DS1337_WADDR);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1337_WADDR, 7);
for(int i=0; i<7; i++)
{
if (Wire.available())
rtc_bcd[i] = Wire.receive();
}
}
void DS1337::clockSave(void)
{
Wire.beginTransmission(DS1337_WADDR);
Wire.send(0x00);
for(int i=0; i<7; i++)
{
Wire.send(rtc_bcd[i]);
}
Wire.endTransmission();
}
// PUBLIC FUNCTIONS
void DS1337::clockGet(uint16_t *rtc)
{
clockRead();
for(int i=0;i<8;i++) // cycle through each component, create array of data
{
rtc[i]=clockGet(i, 0);
}
}
uint16_t DS1337::clockGet(uint8_t c, boolean refresh)
{
if(refresh) clockRead();
int timeValue=-1;
switch(c)
{
case DS1337_SEC:
timeValue = (10*((rtc_bcd[DS1337_SEC] & DS1337_HI_SEC)>>4))+(rtc_bcd[DS1337_SEC] & DS1337_LO_BCD);
break;
case DS1337_MIN:
timeValue = (10*((rtc_bcd[DS1337_MIN] & DS1337_HI_MIN)>>4))+(rtc_bcd[DS1337_MIN] & DS1337_LO_BCD);
break;
case DS1337_HR:
timeValue = (10*((rtc_bcd[DS1337_HR] & DS1337_HI_HR)>>4))+(rtc_bcd[DS1337_HR] & DS1337_LO_BCD);
break;
case DS1337_DOW:
timeValue = rtc_bcd[DS1337_DOW] & DS1337_LO_DOW;
break;
case DS1337_DATE:
timeValue = (10*((rtc_bcd[DS1337_DATE] & DS1337_HI_DATE)>>4))+(rtc_bcd[DS1337_DATE] & DS1337_LO_BCD);
break;
case DS1337_MTH:
timeValue = (10*((rtc_bcd[DS1337_MTH] & DS1337_HI_MTH)>>4))+(rtc_bcd[DS1337_MTH] & DS1337_LO_BCD) & ~DS1337_LO_CNTY;
break;
case DS1337_YR:
timeValue = (10*((rtc_bcd[DS1337_YR] & DS1337_HI_YR)>>4))+(rtc_bcd[DS1337_YR] & DS1337_LO_BCD)+(1900 + (rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY ? 100 : 0));
break;
case DS1337_CNTY:
timeValue = rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY>>7;
break;
} // end switch
return timeValue;
}
void DS1337::clockSet(uint8_t timeSection, uint16_t timeValue)
{
switch(timeSection)
{
case DS1337_SEC:
if(timeValue<60 && timeValue>-1)
{
rtc_bcd[DS1337_SEC] = binToBcd(timeValue);
}
break;
case DS1337_MIN:
if(timeValue<60 && timeValue>-1)
{
rtc_bcd[DS1337_MIN] = binToBcd(timeValue);
}
break;
case DS1337_HR:
// TODO : AM/PM 12HR/24HR
if(timeValue<24 && timeValue>-1)
{
rtc_bcd[DS1337_HR] = binToBcd(timeValue);
}
break;
case DS1337_DOW:
if(timeValue<8 && timeValue>-1)
{
rtc_bcd[DS1337_DOW] = timeValue;
}
break;
case DS1337_DATE:
if(timeValue<31 && timeValue>-1)
{
rtc_bcd[DS1337_DATE] = binToBcd(timeValue);
}
break;
case DS1337_MTH:
if(timeValue<13 && timeValue>-1)
{
rtc_bcd[DS1337_MTH] = (binToBcd(timeValue) & ~DS1337_LO_CNTY) | (rtc_bcd[DS1337_MTH] & DS1337_LO_CNTY);
}
break;
case DS1337_YR:
if(timeValue<1000 && timeValue>-1)
{
rtc_bcd[DS1337_YR] = binToBcd(timeValue);
}
break;
case DS1337_CNTY:
if (timeValue > 0)
{
rtc_bcd[DS1337_MTH] = (rtc_bcd[DS1337_MTH] | DS1337_LO_CNTY);
} else {
rtc_bcd[DS1337_MTH] = (rtc_bcd[DS1337_MTH] & ~DS1337_LO_CNTY);
}
break;
} // end switch
clockSave();
}
uint32_t DS1337::calculateUTS(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
{
/* Number of days per month */
uint32_t tt;
const uint16_t monthcount[] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
/* Compute days */
tt = (year - 1970) * 365 + monthcount[month] + day - 1;
/* Compute for leap year */
for (month <= 2 ? year-- : 0; year >= 1970; year--)
if (isleap(year))
tt++;
/* Plus the time */
tt = sec + 60 * (min + 60 * (tt * 24 + hour - RTC_GMT_OFFSET));
return tt;
}
Rest to follow....