You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
8.7 KiB

/*
DS1337.h - library for DS1337 I2C Real Time Clock
*/
#ifndef DS1337_h
#define DS1337_h
// include types & constants of Wiring core API
#include <WConstants.h>
#include <inttypes.h>
// include types & constants of Wire ic2 lib
#include <Wire/Wire.h>
// Include global RTC configs
#include "../configs/RTC/rtcConfig.h"
// Ucomment this to enable setting the clock from a
// unix time stamp with gmt and dst correction
#define DS1337_USE_SET_UTS
// Uncomment this enable setting the clock using BCD
//#define DS1337_USE_BCD_CLOCKSET
// Uncomment this if you need to read back unix time stamp (without DTS correction)
//#define DS1337_USE_GET_UTS
// Uncomment this to support alarms
#define DS1337_USE_ALARMS
/**
* Define the position of the RTC buffer values
**/
#define DS1337_SEC 0
#define DS1337_MIN 1
#define DS1337_HR 2
#define DS1337_DOW 3
#define DS1337_DATE 4
#define DS1337_MTH 5
#define DS1337_YR 6
#define DS1337_CNTY 7
// For use externally
#define RTC_SEC DS1337_SEC
#define RTC_MIN DS1337_MIN
#define RTC_HR DS1337_HR
#define RTC_DOW DS1337_DOW
#define RTC_DATE DS1337_DATE
#define RTC_MTH DS1337_MTH
#define RTC_YR DS1337_YR
#define RTC_CNTY DS1337_CNTY
/**
* Define the DS1337 I2C addresses
**/
#define DS1337_WADDR 0x68
#define DS1337_RADDR DS1337_WADDR | 0x01
/**
* Define registers and bit masks
**/
#define DS1337_LO_BCD B00001111
#define DS1337_HI_BCD B01110000
#define DS1337_HI_SEC B01110000
#define DS1337_HI_MIN B01110000
#define DS1337_HI_HR B00110000
#define DS1337_LO_DOW B00000111
#define DS1337_HI_DATE B00110000
#define DS1337_HI_MTH B00010000
#define DS1337_LO_CNTY B10000000
#define DS1337_HI_YR B11110000
#define DS1337_ARLM1 0x07
#define DS1337_ARLM1_LO_SEC B00001111
#define DS1337_ARLM1_HI_SEC B01110000
#define DS1337_ARLM1_LO_MIN B01110000
#define DS1337_ARLM1_HI_MIN B00001111
#define DS1337_SP 0x0E
#define DS1337_SP_EOSC B10000000
#define DS1337_SP_RS2 B00010000
#define DS1337_SP_RS1 B00001000
#define DS1337_SP_INTCN B00000100
#define DS1337_SP_A2IE B00000010
#define DS1337_SP_A1IE B00000001
#define DS1337_STATUS 0x0F
#define DS1337_STATUS_OSF B10000000
#define DS1337_STATUS_A2F B00000010
#define DS1337_STATUS_A1F B00000001
// Alarm registers and masks
#define DS1337_ALARM1 0x07
#define DS1337_ALARM2 0x0B
#define DS1337_ALARM_DT_MASK B01000000
#define DS1337_ALARM_MASK B10000000
#define DS1337_ALARM_MODE 4
#define DS1337_ALARM_DT 5
#define DS1337_ALARM_DT_DOW true
#define DS1337_ALARM_DT_DATE false
#define DS1337_ALARM_PER_SEC B00001111
#define DS1337_ALARM_PER_MIN B00000111 /* Used for alarm 2 only*/
#define DS1337_ALARM_MCH_SEC B00001110 /* Used for alarm 1 only */
#define DS1337_ALARM_MCH_MINSEC B00001100
#define DS1337_ALARM_MCH_HRMINSEC B00001000 /* Used for alarm 1 only */
#define DS1337_ALARM_MCH_DATEHRMINSEC B00000000
#define DS1337_ALARM_MCH_DOWHRMINSEC B10000000
// Alarm mode masks
#define DS1337_ALARM2_MODE_MASK B00001000
#define DS1337_ALARM_M1 B00000001
#define DS1337_ALARM_M2 B00000010
#define DS1337_ALARM_M3 B00000100
#define DS1337_ALARM_M4 B00001000
/**
* Macros
**/
#define clockStart() unsetRegister(DS1337_SP, DS1337_SP_EOSC)
#define clockStop() setRegister(DS1337_SP, DS1337_SP_EOSC)
#define getRegisterSP() getRegisterSP(DS1337_SP)
#define getRegisterStatus() getRegisterStatus(DS1337_STATUS)
#define getRegisterBit(reg, bitMask) (getRegister(reg) & bitMask) && bitMask
#ifndef ISLEAP
#define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
#endif
#ifndef BCDTOBIN
// This marco is for internal use only!
#define BCDTOBIN(index, hi) (10*((rtc_bcd[index] & hi)>>4))+(rtc_bcd[index] & DS1337_LO_BCD)
#endif
#ifndef BINTOBCD
#define BINTOBCD(val) ((((val)/10)<<4) + (val)%10)
#endif
/**
* getUTS: Macro for calculateUTS
* returns the time as a unix time stamp
* This function doesn't take into account having DST set or not!
**/
#ifdef DS1337_USE_GET_UTS
#define getUTS(refresh) calculateUTS( RTC.clockGet(DS1337_YR, true), RTC.clockGet(DS1337_MTH, false), \
RTC.clockGet(DS1337_DATE, false), RTC.clockGet(DS1337_HR, false), \
RTC.clockGet(DS1337_MIN, false), RTC.clockGet(DS1337_SEC, false) \
)
#endif
/**
* Use this macro to the time from a unix time stamp
**/
#if defined(DS1337_USE_SET_UTS)
#define clockSet(UTS) clockSetWithUTS(UTS, false)
#endif
/**
* Macros for getting time values without refreshing the RTC buffer
**/
#define clockGetSec() clockGet(DS1337_SEC, false)
#define clockGetMin() clockGet(DS1337_MIN, false)
#define clockGetHour() clockGet(DS1337_HR, false)
#define clockGetDate() clockGet(DS1337_DATE, false)
#define clockGetMonth() clockGet(DS1337_MTH, false)
#define clockGetDow() clockGet(DS1337_DOW, false)
/**
* Macros for getting time values refreshing the RTC buffer before each read.
**/
#define clockGetRSec() clockGet(DS1337_SEC, true)
#define clockGetRMin() clockGet(DS1337_MIN, true)
#define clockGetRHour() clockGet(DS1337_HR, true)
#define clockGetRDate() clockGet(DS1337_DATE, true)
#define clockGetRMonth() clockGet(DS1337_MTH, true)
#define clockGetRDow() clockGet(DS1337_DOW, true)
// library interface description
class DS1337
{
// user-accessible "public" interface
public:
/**
* clockExists: keeps track of the whether or not the RTC exists
**/
bool clockExists;
/**
* Class constructor
**/
DS1337();
/**
* Init: initializes the clock
* If the I2C scan mod is available, it'll verify the RTC is reachable
**/
int8_t Init(void);
/**
* checkClock: verifies the clock integrity
* Returns false when the integrity check fails
**/
boolean checkClock();
/**
* setRegister: sets a register bit fromt he register number and bitmask
**/
void setRegister(uint8_t, uint8_t);
/**
* unsetRegister: unsets a register bit fromt he register number and bitmask
**/
void unsetRegister(uint8_t, uint8_t);
/**
* getRegister: returns the specified register
**/
uint8_t getRegister(uint8_t);
/**
* clockGet: fills an array with the current time data
**/
void clockGet(uint16_t *);
/**
* clockGet: gets a specific item from the clock buffer
* use the second param to specify a buffer refresh
**/
uint16_t clockGet(uint8_t, boolean);
/**
* clockSet: Set the clock time using integer values
* Does not do any GMT or DST correction
**/
#ifdef DS1337_USE_BCD_CLOCKSET
void clockSet(uint8_t, uint16_t);
#endif
/**
* calculateUTS: returns the time as a unix time stamp
* This function doesn't take into account having DST set or not!
*
* Use the macro getUTS macro to access this function!
**/
#ifdef DS1337_USE_GET_UTS
uint32_t calculateUTS(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec);
#endif
/**
* clockSetWithUTS: sets the date & time from a unix time stamp
* pass the second param as true to skip DTS and GMT calculation
*
* Use the clockSet macro to access this function!
**/
void clockSetWithUTS(uint32_t, boolean);
/**
* Prints all of the DS1337 registers
**/
void printRegisters(void);
#ifdef DS1337_USE_ALARMS
/**
* alarmSelect: allows selection of the DS1337 alarm 1 or 2
* false for alarm 1 and true for alarm 2
**/
void alarmSelect(boolean);
/**
* Allows setting an alarm's date and time using integers
**/
void alarmSet(uint8_t, uint8_t);
/**
* alarmCheck: checks if an alarm flag was set and reset the flag
* set param to true to check for both registers false (or void) to check for the selected alarm
**/
boolean alarmCheck(boolean);
boolean alarmCheck(void); // Same as above using false
#endif
private:
/**
* Hold a unix time stamp
**/
#if defined(DS1337_USE_SET_UTS) || defined(DS1337_USE_GET_UTS)
uint32_t tt;
#endif
/**
* Holds the RTC BCD time buffer
**/
uint8_t rtc_bcd[8];
/**
* Writes a value to a clock register
**/
void writeRegister(uint8_t, uint8_t);
/**
* Write the RTC BCD buffer to the clock
**/
void clockSave(void);
/**
* Read the RTC BCD buffer to the clock
**/
void clockRead(void);
/**
* Converts a BCD to a binary integer
**/
uint8_t bcdToBin(uint8_t, uint8_t);
/**
* Converts a binary integer to BCD
**/
uint8_t binToBcd(uint8_t);
#ifdef DS1337_USE_ALARMS
/**
* Hold the buffer for alarm manipulation
**/
uint8_t rtc_alarm[4];
/**
* alarmId: keeps track of which alarm we are working with
**/
boolean alarmId;
/**
* Writes the alarm buffer to the RTC
**/
void alarmSave(void);
#endif
};
/**
* Define the Object's name
**/
extern DS1337 RTC;
#endif