RealTimeClock RTC-8564 library.
Diff: Rtc8564.cpp
- Revision:
- 0:ebc5f6d47cf5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Rtc8564.cpp Sat Feb 22 23:58:05 2014 +0000 @@ -0,0 +1,108 @@ +#include "Rtc8564.h" + +#define RTC_ADDR 0xA2 + +static uint8_t bcdToUint8(char bcd) +{ + uint8_t ret = bcd & 0x0F; + ret += ((bcd >> 4) & 0x0F) * 10; + return ret; +} + +static char uint8ToBcd(uint8_t uchar) +{ + char ret = ((uchar / 10) << 4); + ret += (uchar % 10); + return ret; +} + +Rtc8564::Rtc8564(I2C& i2c, PinName clockIn, PinMode pull) + :m_i2c(i2c), + m_clockIn(clockIn), + m_clockFp() +{ + m_clockIn.mode(pull); +} + +void Rtc8564::initialize() +{ + if(checkVoltageLow()) { + struct tm dateTime; + dateTime.tm_year = 100; // 2000-01-01 + dateTime.tm_mon = 0; + dateTime.tm_mday = 1; + dateTime.tm_wday = 6; // Saturday + dateTime.tm_hour = 0; // 00:00:00 + dateTime.tm_min = 0; + dateTime.tm_sec = 0; + dateTime.tm_isdst = -1; + setTime(&dateTime); + } + + char cmds[2] = {0}; + cmds[0] = 0x0D; + cmds[1] = 0x03; + m_i2c.write(RTC_ADDR, cmds, 2); + + m_clockIn.rise(this, &Rtc8564::clockRise); + + cmds[0] = 0x0D; + cmds[1] = 0x83; + m_i2c.write(RTC_ADDR, cmds, 2); +} + +void Rtc8564::setTime(struct tm* dateTime) +{ + char cmds[10] = {0}; + cmds[0] = 0x00; + cmds[1] = 0x20; + cmds[2] = 0; + cmds[3] = uint8ToBcd(dateTime->tm_sec); //second + cmds[4] = uint8ToBcd(dateTime->tm_min); //minute + cmds[5] = uint8ToBcd(dateTime->tm_hour); //hour + cmds[6] = uint8ToBcd(dateTime->tm_mday); //day + cmds[7] = dateTime->tm_wday; //weekday + cmds[8] = uint8ToBcd(dateTime->tm_mon + 1); //month + cmds[9] = uint8ToBcd(dateTime->tm_year % 100); //year + m_i2c.write(RTC_ADDR, cmds, 10); + + cmds[0] = 0x00; + cmds[1] = 0x0; + m_i2c.write(RTC_ADDR, cmds, 2); +} + +void Rtc8564::getTime(struct tm* dateTime) +{ + char cmds[7] = {0x02}; + + m_i2c.write(RTC_ADDR, cmds, 1); + m_i2c.read(RTC_ADDR, cmds, 7); + + dateTime->tm_sec = bcdToUint8(cmds[0] & 0x7F); + dateTime->tm_min = bcdToUint8(cmds[1] & 0x7F); + dateTime->tm_hour = bcdToUint8(cmds[2] & 0x3F); + dateTime->tm_mday = bcdToUint8(cmds[3] & 0x3F); + dateTime->tm_wday = bcdToUint8(cmds[4] & 0x07); + dateTime->tm_mon = bcdToUint8(cmds[5] & 0x1F) - 1; + dateTime->tm_year = bcdToUint8(cmds[6]) + 100; +} + +void Rtc8564::clock(void (*fptr)(void)) +{ + m_clockFp.attach(fptr); +} + +bool Rtc8564::checkVoltageLow() +{ + char cmds[1] = {0x02}; + + m_i2c.write(RTC_ADDR, cmds, 1); + m_i2c.read(RTC_ADDR, cmds, 1); + + return ((cmds[0] & 0x80) != 0); +} + +void Rtc8564::clockRise() +{ + m_clockFp.call(); +}