Realtime clock library for DS1307 and DS3231m
Dependents: vfd_modular_clock_mbed
ds1307.cpp
- Committer:
- perjg
- Date:
- 2015-08-10
- Revision:
- 2:6119507e6713
- Parent:
- 0:1602fdac44ec
File content as of revision 2:6119507e6713:
/* * RTC library - mbed * (C) 2011-15 Akafugu Corporation * * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * */ #include "ds1307.h" #define DS1307_SLAVE_ADDR 0xD0 DS1307::DS1307(I2C& i2c) : RTC() , m_i2c(i2c) { //m_i2c.frequency(100000); } void DS1307::begin() { } time_t DS1307::time() { return m_time; } struct tm* DS1307::getTime() { char rtc[7]; rtc[0] = 0; // second register, 0 int w = m_i2c.write(DS1307_SLAVE_ADDR, rtc, 1); int r = m_i2c.read(DS1307_SLAVE_ADDR, rtc, 7); // Clear clock halt bit from read data //rtc[0] &= ~(_BV(CH_BIT)); m_tm.tm_sec = bcd2dec(rtc[0]); m_tm.tm_min = bcd2dec(rtc[1]); m_tm.tm_hour = bcd2dec(rtc[2]); m_tm.tm_wday = bcd2dec(rtc[3])-1; m_tm.tm_mday = bcd2dec(rtc[4]); m_tm.tm_mon = bcd2dec(rtc[5])-1; // tm_mon is 0-11 m_tm.tm_year = bcd2dec(rtc[6]); return &m_tm; } void DS1307::getTime(uint8_t* hour, uint8_t* min, uint8_t* sec) { char rtc[3]; rtc[0] = 0; // second register, 0 int w = m_i2c.write(DS1307_SLAVE_ADDR, rtc, 1); int r = m_i2c.read(DS1307_SLAVE_ADDR, rtc, 3); // Clear clock halt bit from read data //rtc[0] &= ~(_BV(CH_BIT)); if (sec) *sec = bcd2dec(rtc[0]); if (min) *min = bcd2dec(rtc[1]); if (hour) *hour = bcd2dec(rtc[2]); } void DS1307::setTime(time_t t) { struct tm * timeinfo; timeinfo = localtime (&t); setTime(timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); } void DS1307::setTime(uint8_t hour, uint8_t min, uint8_t sec) { write_byte(dec2bcd(sec), 0); write_byte(dec2bcd(min), 1); write_byte(dec2bcd(hour), 2); } void DS1307::setTime(struct tm* tm) { write_byte(dec2bcd(tm->tm_sec), 0); write_byte(dec2bcd(tm->tm_min), 1); write_byte(dec2bcd(tm->tm_hour), 2); write_byte(dec2bcd(tm->tm_wday+1), 3); write_byte(dec2bcd(tm->tm_mday), 4); write_byte(dec2bcd(tm->tm_mon+1), 5); write_byte(dec2bcd(tm->tm_year), 6); } void DS1307::setAlarm(time_t t) { struct tm * timeinfo; timeinfo = localtime (&t); setAlarm(timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); } void DS1307::setAlarm(uint8_t hour, uint8_t min, uint8_t sec) { writeRam(0, hour); // hour writeRam(1, min); // minute writeRam(2, sec); // sec } struct tm* DS1307::getAlarm(void) { struct tm * timeinfo = getTime(); uint8_t hour, min, sec; getAlarm(&hour, &min, &sec); timeinfo->tm_hour = hour; timeinfo->tm_min = min; timeinfo->tm_sec = sec; return timeinfo; } void DS1307::getAlarm(uint8_t* hour, uint8_t* min, uint8_t* sec) { if (hour) *hour = readRam(0); if (min) *min = readRam(1); if (sec) *sec = readRam(2); } bool DS1307::checkAlarm(void) { uint8_t hour = readRam(0); uint8_t min = readRam(1); uint8_t sec = readRam(2); uint8_t cur_hour, cur_min, cur_sec; getTime(&cur_hour, &cur_min, &cur_sec); if (cur_hour == hour && cur_min == min && cur_sec == sec) return true; return false; } void DS1307::SQWEnable(bool enable) { uint8_t offset = 0x07; uint8_t control = read_byte(offset); // read control register if (enable) control |= 0x10; // set SQWE to 1 else control &= ~0x10; // set SQWE to 0 // write control back write_byte(control, offset); } void DS1307::SQWSetFreq(enum RTC_SQW_FREQ freq) { uint8_t offset = 0x07; uint8_t control = read_byte(offset); // read control register control &= ~0x03; // Set to 0 control |= freq; // Set freq bitmask // write control back write_byte(control, offset); } #define CH_BIT (1 << 7) // clock halt bit void DS1307::runClock(bool run) { uint8_t b = read_byte(0x0); if (run) b &= ~(CH_BIT); // clear bit else b |= CH_BIT; // set bit write_byte(b, 0x0); } bool DS1307::isClockRunning(void) { uint8_t b = read_byte(0x0); if (b & CH_BIT) return false; return true; } // --------- // uint8_t DS1307::read_byte(uint8_t offset) { char buf[1]; buf[0] = offset; int w = m_i2c.write(DS1307_SLAVE_ADDR, buf, 1); int r = m_i2c.read(DS1307_SLAVE_ADDR, buf, 1); //error = ((w!=0) || (r!=0)); return buf[0]; } void DS1307::write_byte(uint8_t b, uint8_t offset) { char buf[2]; buf[0] = offset; buf[1] = b; int w = m_i2c.write(DS1307_SLAVE_ADDR, buf, 2); //error=(w!=0); } #define DS1307_SRAM_ADDR 0x08 void DS1307::writeRam(uint8_t addr, uint8_t data) { write_byte(data, DS1307_SRAM_ADDR + addr); } uint8_t DS1307::readRam(uint8_t addr) { return read_byte(DS1307_SRAM_ADDR + addr); }