|
|
|
|
|
|
|
|
#ifndef __RTCDS3234_H__ |
|
|
#define __RTCDS3234_H__ |
|
|
|
|
|
#include <Arduino.h> |
|
|
#include <SPI.h> |
|
|
|
|
|
#include "RtcDateTime.h" |
|
|
#include "RtcTemperature.h" |
|
|
#include "RtcUtility.h" |
|
|
|
|
|
|
|
|
//DS3234 Register Addresses |
|
|
const uint8_t DS3234_REG_WRITE_FLAG = 0x80; |
|
|
|
|
|
const uint8_t DS3234_REG_TIMEDATE = 0x00; |
|
|
|
|
|
const uint8_t DS3234_REG_ALARMONE = 0x07; |
|
|
const uint8_t DS3234_REG_ALARMTWO = 0x0B; |
|
|
|
|
|
const uint8_t DS3234_REG_CONTROL = 0x0E; |
|
|
const uint8_t DS3234_REG_STATUS = 0x0F; |
|
|
const uint8_t DS3234_REG_AGING = 0x10; |
|
|
|
|
|
const uint8_t DS3234_REG_TEMP = 0x11; |
|
|
|
|
|
const uint8_t DS3234_REG_RAM_ADDRESS = 0x18; |
|
|
const uint8_t DS3234_REG_RAM_DATA = 0x19; |
|
|
|
|
|
const uint8_t DS3234_RAMSTART = 0x00; |
|
|
const uint8_t DS3234_RAMEND = 0xFF; |
|
|
const uint8_t DS3234_RAMSIZE = DS3234_RAMEND - DS3234_RAMSTART; |
|
|
|
|
|
// DS3234 Control Register Bits |
|
|
const uint8_t DS3234_A1IE = 0; |
|
|
const uint8_t DS3234_A2IE = 1; |
|
|
const uint8_t DS3234_INTCN = 2; |
|
|
const uint8_t DS3234_RS1 = 3; |
|
|
const uint8_t DS3234_RS2 = 4; |
|
|
const uint8_t DS3234_CONV = 5; |
|
|
const uint8_t DS3234_BBSQW = 6; |
|
|
const uint8_t DS3234_EOSC = 7; |
|
|
const uint8_t DS3234_AIEMASK = (_BV(DS3234_A1IE) | _BV(DS3234_A2IE)); |
|
|
const uint8_t DS3234_RSMASK = (_BV(DS3234_RS1) | _BV(DS3234_RS2)); |
|
|
|
|
|
// DS3234 Status Register Bits |
|
|
const uint8_t DS3234_A1F = 0; |
|
|
const uint8_t DS3234_A2F = 1; |
|
|
const uint8_t DS3234_BSY = 2; |
|
|
const uint8_t DS3234_EN32KHZ = 3; |
|
|
const uint8_t DS3234_CRATE0 = 4; |
|
|
const uint8_t DS3234_CRATE1 = 5; |
|
|
const uint8_t DS3234_BB32KHZ = 6; |
|
|
const uint8_t DS3234_OSF = 7; |
|
|
const uint8_t DS3234_AIFMASK = (_BV(DS3234_A1F) | _BV(DS3234_A2F)); |
|
|
const uint8_t DS3234_CRATEMASK = (_BV(DS3234_CRATE0) | _BV(DS3234_CRATE1)); |
|
|
|
|
|
// seconds accuracy |
|
|
enum DS3234AlarmOneControl |
|
|
{ |
|
|
// bit order: A1M4 DY/DT A1M3 A1M2 A1M1 |
|
|
DS3234AlarmOneControl_HoursMinutesSecondsDayOfMonthMatch = 0x00, |
|
|
DS3234AlarmOneControl_OncePerSecond = 0x17, |
|
|
DS3234AlarmOneControl_SecondsMatch = 0x16, |
|
|
DS3234AlarmOneControl_MinutesSecondsMatch = 0x14, |
|
|
DS3234AlarmOneControl_HoursMinutesSecondsMatch = 0x10, |
|
|
DS3234AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch = 0x08, |
|
|
}; |
|
|
|
|
|
class DS3234AlarmOne |
|
|
{ |
|
|
public: |
|
|
DS3234AlarmOne( uint8_t dayOf, |
|
|
uint8_t hour, |
|
|
uint8_t minute, |
|
|
uint8_t second, |
|
|
DS3234AlarmOneControl controlFlags) : |
|
|
_flags(controlFlags), |
|
|
_dayOf(dayOf), |
|
|
_hour(hour), |
|
|
_minute(minute), |
|
|
_second(second) |
|
|
{ |
|
|
} |
|
|
|
|
|
uint8_t DayOf() const |
|
|
{ |
|
|
return _dayOf; |
|
|
} |
|
|
|
|
|
uint8_t Hour() const |
|
|
{ |
|
|
return _hour; |
|
|
} |
|
|
|
|
|
uint8_t Minute() const |
|
|
{ |
|
|
return _minute; |
|
|
} |
|
|
|
|
|
uint8_t Second() const |
|
|
{ |
|
|
return _second; |
|
|
} |
|
|
|
|
|
DS3234AlarmOneControl ControlFlags() const |
|
|
{ |
|
|
return _flags; |
|
|
} |
|
|
|
|
|
bool operator == (const DS3234AlarmOne& other) const |
|
|
{ |
|
|
return (_dayOf == other._dayOf && |
|
|
_hour == other._hour && |
|
|
_minute == other._minute && |
|
|
_second == other._second && |
|
|
_flags == other._flags); |
|
|
} |
|
|
|
|
|
bool operator != (const DS3234AlarmOne& other) const |
|
|
{ |
|
|
return !(*this == other); |
|
|
} |
|
|
|
|
|
protected: |
|
|
DS3234AlarmOneControl _flags; |
|
|
|
|
|
uint8_t _dayOf; |
|
|
uint8_t _hour; |
|
|
uint8_t _minute; |
|
|
uint8_t _second; |
|
|
}; |
|
|
|
|
|
// minutes accuracy |
|
|
enum DS3234AlarmTwoControl |
|
|
{ |
|
|
// bit order: A2M4 DY/DT A2M3 A2M2 |
|
|
DS3234AlarmTwoControl_HoursMinutesDayOfMonthMatch = 0x00, |
|
|
DS3234AlarmTwoControl_OncePerMinute = 0x0b, |
|
|
DS3234AlarmTwoControl_MinutesMatch = 0x0a, |
|
|
DS3234AlarmTwoControl_HoursMinutesMatch = 0x08, |
|
|
DS3234AlarmTwoControl_HoursMinutesDayOfWeekMatch = 0x04, |
|
|
}; |
|
|
|
|
|
class DS3234AlarmTwo |
|
|
{ |
|
|
public: |
|
|
DS3234AlarmTwo( uint8_t dayOf, |
|
|
uint8_t hour, |
|
|
uint8_t minute, |
|
|
DS3234AlarmTwoControl controlFlags) : |
|
|
_flags(controlFlags), |
|
|
_dayOf(dayOf), |
|
|
_hour(hour), |
|
|
_minute(minute) |
|
|
{ |
|
|
} |
|
|
|
|
|
uint8_t DayOf() const |
|
|
{ |
|
|
return _dayOf; |
|
|
} |
|
|
|
|
|
uint8_t Hour() const |
|
|
{ |
|
|
return _hour; |
|
|
} |
|
|
|
|
|
uint8_t Minute() const |
|
|
{ |
|
|
return _minute; |
|
|
} |
|
|
|
|
|
DS3234AlarmTwoControl ControlFlags() const |
|
|
{ |
|
|
return _flags; |
|
|
} |
|
|
|
|
|
bool operator == (const DS3234AlarmTwo& other) const |
|
|
{ |
|
|
return (_dayOf == other._dayOf && |
|
|
_hour == other._hour && |
|
|
_minute == other._minute && |
|
|
_flags == other._flags); |
|
|
} |
|
|
|
|
|
bool operator != (const DS3234AlarmTwo& other) const |
|
|
{ |
|
|
return !(*this == other); |
|
|
} |
|
|
|
|
|
protected: |
|
|
DS3234AlarmTwoControl _flags; |
|
|
|
|
|
uint8_t _dayOf; |
|
|
uint8_t _hour; |
|
|
uint8_t _minute; |
|
|
}; |
|
|
|
|
|
|
|
|
enum DS3234SquareWaveClock |
|
|
{ |
|
|
DS3234SquareWaveClock_1Hz = 0b00000000, |
|
|
DS3234SquareWaveClock_1kHz = 0b00001000, |
|
|
DS3234SquareWaveClock_4kHz = 0b00010000, |
|
|
DS3234SquareWaveClock_8kHz = 0b00011000, |
|
|
}; |
|
|
|
|
|
enum DS3234SquareWavePinMode |
|
|
{ |
|
|
DS3234SquareWavePin_ModeNone, |
|
|
DS3234SquareWavePin_ModeBatteryBackup, |
|
|
DS3234SquareWavePin_ModeClock, |
|
|
DS3234SquareWavePin_ModeAlarmOne, |
|
|
DS3234SquareWavePin_ModeAlarmTwo, |
|
|
DS3234SquareWavePin_ModeAlarmBoth |
|
|
}; |
|
|
|
|
|
enum DS3234TempCompensationRate |
|
|
{ |
|
|
DS3234TempCompensationRate_64Seconds, |
|
|
DS3234TempCompensationRate_128Seconds, |
|
|
DS3234TempCompensationRate_256Seconds, |
|
|
DS3234TempCompensationRate_512Seconds, |
|
|
}; |
|
|
|
|
|
enum DS3234AlarmFlag |
|
|
{ |
|
|
DS3234AlarmFlag_Alarm1 = 0x01, |
|
|
DS3234AlarmFlag_Alarm2 = 0x02, |
|
|
DS3234AlarmFlag_AlarmBoth = 0x03, |
|
|
}; |
|
|
|
|
|
const SPISettings c_Ds3234SpiSettings(1000000, MSBFIRST, SPI_MODE1); // CPHA must be used, so mode 1 or mode 3 are valid |
|
|
|
|
|
template<class T_SPI_METHOD> class RtcDS3234 |
|
|
{ |
|
|
public: |
|
|
RtcDS3234(T_SPI_METHOD& spi, uint8_t csPin) : |
|
|
_spi(spi), |
|
|
_csPin(csPin) |
|
|
{ |
|
|
} |
|
|
|
|
|
void Begin() |
|
|
{ |
|
|
UnselectChip(); |
|
|
pinMode(_csPin, OUTPUT); |
|
|
} |
|
|
|
|
|
bool IsDateTimeValid() |
|
|
{ |
|
|
uint8_t status = getReg(DS3234_REG_STATUS); |
|
|
return !(status & _BV(DS3234_OSF)); |
|
|
} |
|
|
|
|
|
bool GetIsRunning() |
|
|
{ |
|
|
uint8_t creg = getReg(DS3234_REG_CONTROL); |
|
|
return !(creg & _BV(DS3234_EOSC)); |
|
|
} |
|
|
|
|
|
void SetIsRunning(bool isRunning) |
|
|
{ |
|
|
uint8_t creg = getReg(DS3234_REG_CONTROL); |
|
|
if (isRunning) |
|
|
{ |
|
|
creg &= ~_BV(DS3234_EOSC); |
|
|
} |
|
|
else |
|
|
{ |
|
|
creg |= _BV(DS3234_EOSC); |
|
|
} |
|
|
setReg(DS3234_REG_CONTROL, creg); |
|
|
} |
|
|
|
|
|
void SetDateTime(const RtcDateTime& dt) |
|
|
{ |
|
|
// clear the invalid flag |
|
|
uint8_t status = getReg(DS3234_REG_STATUS); |
|
|
status &= ~_BV(DS3234_OSF); // clear the flag |
|
|
setReg(DS3234_REG_STATUS, status); |
|
|
|
|
|
// set the date time |
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
_spi.transfer(DS3234_REG_TIMEDATE | DS3234_REG_WRITE_FLAG); |
|
|
|
|
|
_spi.transfer(Uint8ToBcd(dt.Second())); |
|
|
_spi.transfer(Uint8ToBcd(dt.Minute())); |
|
|
_spi.transfer(Uint8ToBcd(dt.Hour())); // 24 hour mode only |
|
|
|
|
|
uint8_t year = dt.Year() - 2000; |
|
|
uint8_t centuryFlag = 0; |
|
|
|
|
|
if (year >= 100) |
|
|
{ |
|
|
year -= 100; |
|
|
centuryFlag = _BV(7); |
|
|
} |
|
|
|
|
|
// RTC Hardware Day of Week is 1-7, 1 = Monday |
|
|
// convert our Day of Week to Rtc Day of Week |
|
|
uint8_t rtcDow = RtcDateTime::ConvertDowToRtc(dt.DayOfWeek()); |
|
|
|
|
|
_spi.transfer(Uint8ToBcd(rtcDow)); |
|
|
|
|
|
_spi.transfer(Uint8ToBcd(dt.Day())); |
|
|
_spi.transfer(Uint8ToBcd(dt.Month()) | centuryFlag); |
|
|
_spi.transfer(Uint8ToBcd(year)); |
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
} |
|
|
|
|
|
RtcDateTime GetDateTime() |
|
|
{ |
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
|
|
|
_spi.transfer(DS3234_REG_TIMEDATE); |
|
|
|
|
|
uint8_t second = BcdToUint8(_spi.transfer(0)); |
|
|
uint8_t minute = BcdToUint8(_spi.transfer(0)); |
|
|
uint8_t hour = BcdToBin24Hour(_spi.transfer(0)); |
|
|
|
|
|
_spi.transfer(0); // throwing away day of week as we calculate it |
|
|
|
|
|
uint8_t dayOfMonth = BcdToUint8(_spi.transfer(0)); |
|
|
uint8_t monthRaw = _spi.transfer(0); |
|
|
uint16_t year = BcdToUint8(_spi.transfer(0)) + 2000; |
|
|
|
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
|
|
|
if (monthRaw & _BV(7)) // century wrap flag |
|
|
{ |
|
|
year += 100; |
|
|
} |
|
|
uint8_t month = BcdToUint8(monthRaw & 0x7f); |
|
|
|
|
|
return RtcDateTime(year, month, dayOfMonth, hour, minute, second); |
|
|
} |
|
|
|
|
|
RtcTemperature GetTemperature() |
|
|
{ |
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
_spi.transfer(DS3234_REG_TEMP); |
|
|
|
|
|
// Temperature is represented as a 10-bit code with a resolution |
|
|
// of 1/4th <EFBFBD>C and is accessable as a signed 16-bit integer at |
|
|
// locations 11h and 12h. |
|
|
// |
|
|
// | r11h | DP | r12h | |
|
|
// Bit: 15 14 13 12 11 10 9 8 . 7 6 5 4 3 2 1 0 -1 -2 |
|
|
// s i i i i i i i . f f 0 0 0 0 0 0 |
|
|
// |
|
|
// As it takes (8) right-shifts to register the decimal point (DP) to |
|
|
// the right of the 0th bit, the overall word scaling equals 256. |
|
|
// |
|
|
// For example, at +/- 25.25<EFBFBD>C, concatenated registers <r11h:r12h> = |
|
|
// 256 * (+/- 25+(1/4)) = +/- 6464, or 1940h / E6C0h. |
|
|
|
|
|
int8_t ms = _spi.transfer(0); // MS byte, signed temperature |
|
|
uint8_t ls = _spi.transfer(0); // LS byte is r12h |
|
|
|
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
|
|
|
return RtcTemperature(ms, ls); // LS byte is r12h |
|
|
} |
|
|
|
|
|
void Enable32kHzPin(bool enable) |
|
|
{ |
|
|
uint8_t sreg = getReg(DS3234_REG_STATUS); |
|
|
|
|
|
if (enable == true) |
|
|
{ |
|
|
sreg |= _BV(DS3234_EN32KHZ); |
|
|
} |
|
|
else |
|
|
{ |
|
|
sreg &= ~_BV(DS3234_EN32KHZ); |
|
|
} |
|
|
|
|
|
setReg(DS3234_REG_STATUS, sreg); |
|
|
} |
|
|
|
|
|
void SetSquareWavePin(DS3234SquareWavePinMode pinMode) |
|
|
{ |
|
|
uint8_t creg = getReg(DS3234_REG_CONTROL); |
|
|
|
|
|
// clear all relevant bits to a known "off" state |
|
|
creg &= ~(DS3234_AIEMASK | _BV(DS3234_BBSQW)); |
|
|
creg |= _BV(DS3234_INTCN); // set INTCN to disables SQW |
|
|
|
|
|
switch (pinMode) |
|
|
{ |
|
|
case DS3234SquareWavePin_ModeNone: |
|
|
break; |
|
|
|
|
|
case DS3234SquareWavePin_ModeBatteryBackup: |
|
|
creg |= _BV(DS3234_BBSQW); // set battery backup flag |
|
|
creg &= ~_BV(DS3234_INTCN); // clear INTCN to enable SQW |
|
|
break; |
|
|
|
|
|
case DS3234SquareWavePin_ModeClock: |
|
|
creg &= ~_BV(DS3234_INTCN); // clear INTCN to enable SQW |
|
|
break; |
|
|
|
|
|
case DS3234SquareWavePin_ModeAlarmOne: |
|
|
creg |= _BV(DS3234_A1IE); |
|
|
break; |
|
|
|
|
|
case DS3234SquareWavePin_ModeAlarmTwo: |
|
|
creg |= _BV(DS3234_A2IE); |
|
|
break; |
|
|
|
|
|
case DS3234SquareWavePin_ModeAlarmBoth: |
|
|
creg |= _BV(DS3234_A1IE) | _BV(DS3234_A2IE); |
|
|
break; |
|
|
} |
|
|
|
|
|
setReg(DS3234_REG_CONTROL, creg); |
|
|
} |
|
|
|
|
|
void SetSquareWavePinClockFrequency(DS3234SquareWaveClock freq) |
|
|
{ |
|
|
uint8_t creg = getReg(DS3234_REG_CONTROL); |
|
|
|
|
|
creg &= ~DS3234_RSMASK; // Set to 0 |
|
|
creg |= (freq & DS3234_RSMASK); // Set freq bits |
|
|
|
|
|
setReg(DS3234_REG_CONTROL, creg); |
|
|
} |
|
|
|
|
|
|
|
|
void SetAlarmOne(const DS3234AlarmOne& alarm) |
|
|
{ |
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
|
|
|
_spi.transfer(DS3234_REG_ALARMONE | DS3234_REG_WRITE_FLAG); |
|
|
|
|
|
_spi.transfer(Uint8ToBcd(alarm.Second()) | ((alarm.ControlFlags() & 0x01) << 7)); |
|
|
_spi.transfer(Uint8ToBcd(alarm.Minute()) | ((alarm.ControlFlags() & 0x02) << 6)); |
|
|
_spi.transfer(Uint8ToBcd(alarm.Hour()) | ((alarm.ControlFlags() & 0x04) << 5)); // 24 hour mode only |
|
|
|
|
|
uint8_t rtcDow = alarm.DayOf(); |
|
|
if (alarm.ControlFlags() == DS3234AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch) |
|
|
{ |
|
|
rtcDow = RtcDateTime::ConvertDowToRtc(rtcDow); |
|
|
} |
|
|
|
|
|
_spi.transfer(Uint8ToBcd(rtcDow) | ((alarm.ControlFlags() & 0x18) << 3)); |
|
|
|
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
} |
|
|
|
|
|
void SetAlarmTwo(const DS3234AlarmTwo& alarm) |
|
|
{ |
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
|
|
|
_spi.transfer(DS3234_REG_ALARMTWO | DS3234_REG_WRITE_FLAG); |
|
|
|
|
|
_spi.transfer(Uint8ToBcd(alarm.Minute()) | ((alarm.ControlFlags() & 0x01) << 7)); |
|
|
_spi.transfer(Uint8ToBcd(alarm.Hour()) | ((alarm.ControlFlags() & 0x02) << 6)); // 24 hour mode only |
|
|
|
|
|
// convert our Day of Week to Rtc Day of Week if needed |
|
|
uint8_t rtcDow = alarm.DayOf(); |
|
|
if (alarm.ControlFlags() == DS3234AlarmTwoControl_HoursMinutesDayOfWeekMatch) |
|
|
{ |
|
|
rtcDow = RtcDateTime::ConvertDowToRtc(rtcDow); |
|
|
} |
|
|
|
|
|
_spi.transfer(Uint8ToBcd(rtcDow) | ((alarm.ControlFlags() & 0x0c) << 4)); |
|
|
|
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
} |
|
|
|
|
|
DS3234AlarmOne GetAlarmOne() |
|
|
{ |
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
|
|
|
_spi.transfer(DS3234_REG_ALARMONE); |
|
|
|
|
|
uint8_t raw = _spi.transfer(0); |
|
|
uint8_t flags = (raw & 0x80) >> 7; |
|
|
uint8_t second = BcdToUint8(raw & 0x7F); |
|
|
|
|
|
raw = _spi.transfer(0); |
|
|
flags |= (raw & 0x80) >> 6; |
|
|
uint8_t minute = BcdToUint8(raw & 0x7F); |
|
|
|
|
|
raw = _spi.transfer(0); |
|
|
flags |= (raw & 0x80) >> 5; |
|
|
uint8_t hour = BcdToBin24Hour(raw & 0x7f); |
|
|
|
|
|
raw = _spi.transfer(0); |
|
|
flags |= (raw & 0xc0) >> 3; |
|
|
uint8_t dayOf = BcdToUint8(raw & 0x3f); |
|
|
|
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
|
|
|
if (flags == DS3234AlarmOneControl_HoursMinutesSecondsDayOfWeekMatch) |
|
|
{ |
|
|
dayOf = RtcDateTime::ConvertRtcToDow(dayOf); |
|
|
} |
|
|
|
|
|
return DS3234AlarmOne(dayOf, hour, minute, second, (DS3234AlarmOneControl)flags); |
|
|
} |
|
|
|
|
|
DS3234AlarmTwo GetAlarmTwo() |
|
|
{ |
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
|
|
|
_spi.transfer(DS3234_REG_ALARMTWO); |
|
|
|
|
|
uint8_t raw = _spi.transfer(0); |
|
|
uint8_t flags = (raw & 0x80) >> 7; |
|
|
uint8_t minute = BcdToUint8(raw & 0x7F); |
|
|
|
|
|
raw = _spi.transfer(0); |
|
|
flags |= (raw & 0x80) >> 6; |
|
|
uint8_t hour = BcdToBin24Hour(raw & 0x7f); |
|
|
|
|
|
raw = _spi.transfer(0); |
|
|
flags |= (raw & 0xc0) >> 4; |
|
|
uint8_t dayOf = BcdToUint8(raw & 0x3f); |
|
|
|
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
|
|
|
if (flags == DS3234AlarmTwoControl_HoursMinutesDayOfWeekMatch) |
|
|
{ |
|
|
dayOf = RtcDateTime::ConvertRtcToDow(dayOf); |
|
|
} |
|
|
|
|
|
return DS3234AlarmTwo(dayOf, hour, minute, (DS3234AlarmTwoControl)flags); |
|
|
} |
|
|
|
|
|
// Latch must be called after an alarm otherwise it will not |
|
|
// trigger again |
|
|
DS3234AlarmFlag LatchAlarmsTriggeredFlags() |
|
|
{ |
|
|
uint8_t sreg = getReg(DS3234_REG_STATUS); |
|
|
uint8_t alarmFlags = (sreg & DS3234_AIFMASK); |
|
|
sreg &= ~DS3234_AIFMASK; // clear the flags |
|
|
setReg(DS3234_REG_STATUS, sreg); |
|
|
return (DS3234AlarmFlag)alarmFlags; |
|
|
} |
|
|
|
|
|
void SetTemperatureCompensationRate(DS3234TempCompensationRate rate) |
|
|
{ |
|
|
uint8_t sreg = getReg(DS3234_REG_STATUS); |
|
|
|
|
|
sreg &= ~DS3234_CRATEMASK; |
|
|
sreg |= (rate << DS3234_CRATE0); |
|
|
|
|
|
setReg(DS3234_REG_STATUS, sreg); |
|
|
} |
|
|
|
|
|
DS3234TempCompensationRate GetTemperatureCompensationRate() |
|
|
{ |
|
|
uint8_t sreg = getReg(DS3234_REG_STATUS); |
|
|
return (sreg & DS3234_CRATEMASK) >> DS3234_CRATE0; |
|
|
} |
|
|
|
|
|
void ForceTemperatureCompensationUpdate(bool block) |
|
|
{ |
|
|
uint8_t creg = getReg(DS3234_REG_CONTROL); |
|
|
creg |= _BV(DS3234_CONV); // Write CONV bit |
|
|
setReg(DS3234_REG_CONTROL, creg); |
|
|
|
|
|
while (block && (creg & _BV(DS3234_CONV)) != 0) |
|
|
{ |
|
|
// Block until CONV is 0 |
|
|
creg = getReg(DS3234_REG_CONTROL); |
|
|
} |
|
|
} |
|
|
|
|
|
int8_t GetAgingOffset() |
|
|
{ |
|
|
return getReg(DS3234_REG_AGING); |
|
|
} |
|
|
|
|
|
void SetAgingOffset(int8_t value) |
|
|
{ |
|
|
setReg(DS3234_REG_AGING, value); |
|
|
} |
|
|
|
|
|
void SetMemory(uint8_t memoryAddress, uint8_t value) |
|
|
{ |
|
|
SetMemory(memoryAddress, &value, 1); |
|
|
} |
|
|
|
|
|
uint8_t GetMemory(uint8_t memoryAddress) |
|
|
{ |
|
|
uint8_t value; |
|
|
|
|
|
GetMemory(memoryAddress, &value, 1); |
|
|
|
|
|
return value; |
|
|
} |
|
|
|
|
|
uint8_t SetMemory(uint8_t memoryAddress, const uint8_t* pValue, uint8_t countBytes) |
|
|
{ |
|
|
uint8_t countWritten = 0; |
|
|
|
|
|
setReg(DS3234_REG_RAM_ADDRESS, memoryAddress); |
|
|
|
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
_spi.transfer(DS3234_REG_RAM_DATA | DS3234_REG_WRITE_FLAG); |
|
|
|
|
|
while (countBytes > 0) |
|
|
{ |
|
|
_spi.transfer(*pValue++); |
|
|
|
|
|
countBytes--; |
|
|
countWritten++; |
|
|
} |
|
|
|
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
|
|
|
return countWritten; |
|
|
} |
|
|
|
|
|
uint8_t GetMemory(uint8_t memoryAddress, uint8_t* pValue, uint8_t countBytes) |
|
|
{ |
|
|
// set address to read from |
|
|
setReg(DS3234_REG_RAM_ADDRESS, memoryAddress); |
|
|
|
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
_spi.transfer(DS3234_REG_RAM_DATA); |
|
|
|
|
|
// read the data |
|
|
uint8_t countRead = 0; |
|
|
|
|
|
while (countBytes-- > 0) |
|
|
{ |
|
|
*pValue++ = _spi.transfer(0); |
|
|
countRead++; |
|
|
} |
|
|
|
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
|
|
|
return countRead; |
|
|
} |
|
|
|
|
|
private: |
|
|
T_SPI_METHOD& _spi; |
|
|
uint8_t _csPin; |
|
|
|
|
|
void SelectChip() |
|
|
{ |
|
|
digitalWrite(_csPin, LOW); |
|
|
} |
|
|
void UnselectChip() |
|
|
{ |
|
|
digitalWrite(_csPin, HIGH); |
|
|
} |
|
|
|
|
|
uint8_t getReg(uint8_t regAddress) |
|
|
{ |
|
|
uint8_t regValue; |
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
_spi.transfer(regAddress); |
|
|
regValue = _spi.transfer(0); |
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
|
|
|
return regValue; |
|
|
} |
|
|
|
|
|
void setReg(uint8_t regAddress, uint8_t regValue) |
|
|
{ |
|
|
_spi.beginTransaction(c_Ds3234SpiSettings); |
|
|
SelectChip(); |
|
|
_spi.transfer(regAddress | DS3234_REG_WRITE_FLAG); |
|
|
_spi.transfer(regValue); |
|
|
UnselectChip(); |
|
|
_spi.endTransaction(); |
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
#endif // __RTCDS3234_H__
|
|
|
|