Realtime clock library for DS1307 and DS3231m

Dependents:   vfd_modular_clock_mbed

Committer:
perjg
Date:
Mon Aug 10 03:16:52 2015 +0000
Revision:
2:6119507e6713
Parent:
0:1602fdac44ec
Fixed compile error

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Backstrom 0:1602fdac44ec 1 /*
Backstrom 0:1602fdac44ec 2 * RTC library - mbed
Backstrom 0:1602fdac44ec 3 * (C) 2011-15 Akafugu Corporation
Backstrom 0:1602fdac44ec 4 *
Backstrom 0:1602fdac44ec 5 * This program is free software; you can redistribute it and/or modify it under the
Backstrom 0:1602fdac44ec 6 * terms of the GNU General Public License as published by the Free Software
Backstrom 0:1602fdac44ec 7 * Foundation; either version 2 of the License, or (at your option) any later
Backstrom 0:1602fdac44ec 8 * version.
Backstrom 0:1602fdac44ec 9 *
Backstrom 0:1602fdac44ec 10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
Backstrom 0:1602fdac44ec 11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
Backstrom 0:1602fdac44ec 12 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
Backstrom 0:1602fdac44ec 13 *
Backstrom 0:1602fdac44ec 14 */
Backstrom 0:1602fdac44ec 15
Backstrom 0:1602fdac44ec 16 #include "ds1307.h"
Backstrom 0:1602fdac44ec 17
Backstrom 0:1602fdac44ec 18 #define DS1307_SLAVE_ADDR 0xD0
Backstrom 0:1602fdac44ec 19
Backstrom 0:1602fdac44ec 20 DS1307::DS1307(I2C& i2c)
Backstrom 0:1602fdac44ec 21 : RTC()
Backstrom 0:1602fdac44ec 22 , m_i2c(i2c)
Backstrom 0:1602fdac44ec 23 {
Backstrom 0:1602fdac44ec 24 //m_i2c.frequency(100000);
Backstrom 0:1602fdac44ec 25 }
Backstrom 0:1602fdac44ec 26
Backstrom 0:1602fdac44ec 27 void DS1307::begin()
Backstrom 0:1602fdac44ec 28 {
Backstrom 0:1602fdac44ec 29 }
Backstrom 0:1602fdac44ec 30
Backstrom 0:1602fdac44ec 31
Backstrom 0:1602fdac44ec 32 time_t DS1307::time()
Backstrom 0:1602fdac44ec 33 {
Backstrom 0:1602fdac44ec 34 return m_time;
Backstrom 0:1602fdac44ec 35 }
Backstrom 0:1602fdac44ec 36
Backstrom 0:1602fdac44ec 37 struct tm* DS1307::getTime()
Backstrom 0:1602fdac44ec 38 {
Backstrom 0:1602fdac44ec 39 char rtc[7];
Backstrom 0:1602fdac44ec 40
Backstrom 0:1602fdac44ec 41 rtc[0] = 0; // second register, 0
Backstrom 0:1602fdac44ec 42 int w = m_i2c.write(DS1307_SLAVE_ADDR, rtc, 1);
Backstrom 0:1602fdac44ec 43 int r = m_i2c.read(DS1307_SLAVE_ADDR, rtc, 7);
Backstrom 0:1602fdac44ec 44
Backstrom 0:1602fdac44ec 45 // Clear clock halt bit from read data
Backstrom 0:1602fdac44ec 46 //rtc[0] &= ~(_BV(CH_BIT));
Backstrom 0:1602fdac44ec 47
Backstrom 0:1602fdac44ec 48 m_tm.tm_sec = bcd2dec(rtc[0]);
Backstrom 0:1602fdac44ec 49 m_tm.tm_min = bcd2dec(rtc[1]);
Backstrom 0:1602fdac44ec 50 m_tm.tm_hour = bcd2dec(rtc[2]);
Backstrom 0:1602fdac44ec 51 m_tm.tm_wday = bcd2dec(rtc[3])-1;
Backstrom 0:1602fdac44ec 52 m_tm.tm_mday = bcd2dec(rtc[4]);
Backstrom 0:1602fdac44ec 53 m_tm.tm_mon = bcd2dec(rtc[5])-1; // tm_mon is 0-11
Backstrom 0:1602fdac44ec 54 m_tm.tm_year = bcd2dec(rtc[6]);
Backstrom 0:1602fdac44ec 55
Backstrom 0:1602fdac44ec 56 return &m_tm;
Backstrom 0:1602fdac44ec 57 }
Backstrom 0:1602fdac44ec 58
Backstrom 0:1602fdac44ec 59 void DS1307::getTime(uint8_t* hour, uint8_t* min, uint8_t* sec)
Backstrom 0:1602fdac44ec 60 {
Backstrom 0:1602fdac44ec 61 char rtc[3];
Backstrom 0:1602fdac44ec 62
Backstrom 0:1602fdac44ec 63 rtc[0] = 0; // second register, 0
Backstrom 0:1602fdac44ec 64 int w = m_i2c.write(DS1307_SLAVE_ADDR, rtc, 1);
Backstrom 0:1602fdac44ec 65 int r = m_i2c.read(DS1307_SLAVE_ADDR, rtc, 3);
Backstrom 0:1602fdac44ec 66
Backstrom 0:1602fdac44ec 67 // Clear clock halt bit from read data
Backstrom 0:1602fdac44ec 68 //rtc[0] &= ~(_BV(CH_BIT));
Backstrom 0:1602fdac44ec 69
Backstrom 0:1602fdac44ec 70 if (sec) *sec = bcd2dec(rtc[0]);
Backstrom 0:1602fdac44ec 71 if (min) *min = bcd2dec(rtc[1]);
Backstrom 0:1602fdac44ec 72 if (hour) *hour = bcd2dec(rtc[2]);
Backstrom 0:1602fdac44ec 73 }
Backstrom 0:1602fdac44ec 74
Backstrom 0:1602fdac44ec 75 void DS1307::setTime(time_t t)
Backstrom 0:1602fdac44ec 76 {
Backstrom 0:1602fdac44ec 77 struct tm * timeinfo;
Backstrom 0:1602fdac44ec 78 timeinfo = localtime (&t);
Backstrom 0:1602fdac44ec 79 setTime(timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
Backstrom 0:1602fdac44ec 80 }
Backstrom 0:1602fdac44ec 81
Backstrom 0:1602fdac44ec 82 void DS1307::setTime(uint8_t hour, uint8_t min, uint8_t sec)
Backstrom 0:1602fdac44ec 83 {
Backstrom 0:1602fdac44ec 84 write_byte(dec2bcd(sec), 0);
Backstrom 0:1602fdac44ec 85 write_byte(dec2bcd(min), 1);
Backstrom 0:1602fdac44ec 86 write_byte(dec2bcd(hour), 2);
Backstrom 0:1602fdac44ec 87 }
Backstrom 0:1602fdac44ec 88
Backstrom 0:1602fdac44ec 89 void DS1307::setTime(struct tm* tm)
Backstrom 0:1602fdac44ec 90 {
Backstrom 0:1602fdac44ec 91 write_byte(dec2bcd(tm->tm_sec), 0);
Backstrom 0:1602fdac44ec 92 write_byte(dec2bcd(tm->tm_min), 1);
Backstrom 0:1602fdac44ec 93 write_byte(dec2bcd(tm->tm_hour), 2);
Backstrom 0:1602fdac44ec 94 write_byte(dec2bcd(tm->tm_wday+1), 3);
Backstrom 0:1602fdac44ec 95 write_byte(dec2bcd(tm->tm_mday), 4);
Backstrom 0:1602fdac44ec 96 write_byte(dec2bcd(tm->tm_mon+1), 5);
Backstrom 0:1602fdac44ec 97 write_byte(dec2bcd(tm->tm_year), 6);
Backstrom 0:1602fdac44ec 98 }
Backstrom 0:1602fdac44ec 99
Backstrom 0:1602fdac44ec 100 void DS1307::setAlarm(time_t t)
Backstrom 0:1602fdac44ec 101 {
Backstrom 0:1602fdac44ec 102 struct tm * timeinfo;
Backstrom 0:1602fdac44ec 103 timeinfo = localtime (&t);
Backstrom 0:1602fdac44ec 104 setAlarm(timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
Backstrom 0:1602fdac44ec 105 }
Backstrom 0:1602fdac44ec 106
Backstrom 0:1602fdac44ec 107 void DS1307::setAlarm(uint8_t hour, uint8_t min, uint8_t sec)
Backstrom 0:1602fdac44ec 108 {
Backstrom 0:1602fdac44ec 109 writeRam(0, hour); // hour
Backstrom 0:1602fdac44ec 110 writeRam(1, min); // minute
Backstrom 0:1602fdac44ec 111 writeRam(2, sec); // sec
Backstrom 0:1602fdac44ec 112 }
Backstrom 0:1602fdac44ec 113
Backstrom 0:1602fdac44ec 114 struct tm* DS1307::getAlarm(void)
Backstrom 0:1602fdac44ec 115 {
Backstrom 0:1602fdac44ec 116 struct tm * timeinfo = getTime();
Backstrom 0:1602fdac44ec 117 uint8_t hour, min, sec;
Backstrom 0:1602fdac44ec 118
Backstrom 0:1602fdac44ec 119 getAlarm(&hour, &min, &sec);
Backstrom 0:1602fdac44ec 120 timeinfo->tm_hour = hour;
Backstrom 0:1602fdac44ec 121 timeinfo->tm_min = min;
Backstrom 0:1602fdac44ec 122 timeinfo->tm_sec = sec;
Backstrom 0:1602fdac44ec 123 return timeinfo;
Backstrom 0:1602fdac44ec 124 }
Backstrom 0:1602fdac44ec 125
Backstrom 0:1602fdac44ec 126 void DS1307::getAlarm(uint8_t* hour, uint8_t* min, uint8_t* sec)
Backstrom 0:1602fdac44ec 127 {
Backstrom 0:1602fdac44ec 128 if (hour) *hour = readRam(0);
Backstrom 0:1602fdac44ec 129 if (min) *min = readRam(1);
Backstrom 0:1602fdac44ec 130 if (sec) *sec = readRam(2);
Backstrom 0:1602fdac44ec 131 }
Backstrom 0:1602fdac44ec 132
Backstrom 0:1602fdac44ec 133 bool DS1307::checkAlarm(void)
Backstrom 0:1602fdac44ec 134 {
Backstrom 0:1602fdac44ec 135 uint8_t hour = readRam(0);
Backstrom 0:1602fdac44ec 136 uint8_t min = readRam(1);
Backstrom 0:1602fdac44ec 137 uint8_t sec = readRam(2);
Backstrom 0:1602fdac44ec 138
Backstrom 0:1602fdac44ec 139 uint8_t cur_hour, cur_min, cur_sec;
Backstrom 0:1602fdac44ec 140 getTime(&cur_hour, &cur_min, &cur_sec);
Backstrom 0:1602fdac44ec 141
Backstrom 0:1602fdac44ec 142 if (cur_hour == hour && cur_min == min && cur_sec == sec)
Backstrom 0:1602fdac44ec 143 return true;
Backstrom 0:1602fdac44ec 144 return false;
Backstrom 0:1602fdac44ec 145 }
Backstrom 0:1602fdac44ec 146
Backstrom 0:1602fdac44ec 147 void DS1307::SQWEnable(bool enable)
Backstrom 0:1602fdac44ec 148 {
Backstrom 0:1602fdac44ec 149 uint8_t offset = 0x07;
Backstrom 0:1602fdac44ec 150 uint8_t control = read_byte(offset); // read control register
Backstrom 0:1602fdac44ec 151 if (enable)
Backstrom 0:1602fdac44ec 152 control |= 0x10; // set SQWE to 1
Backstrom 0:1602fdac44ec 153 else
Backstrom 0:1602fdac44ec 154 control &= ~0x10; // set SQWE to 0
Backstrom 0:1602fdac44ec 155
Backstrom 0:1602fdac44ec 156 // write control back
Backstrom 0:1602fdac44ec 157 write_byte(control, offset);
Backstrom 0:1602fdac44ec 158 }
Backstrom 0:1602fdac44ec 159
Backstrom 0:1602fdac44ec 160 void DS1307::SQWSetFreq(enum RTC_SQW_FREQ freq)
Backstrom 0:1602fdac44ec 161 {
Backstrom 0:1602fdac44ec 162 uint8_t offset = 0x07;
Backstrom 0:1602fdac44ec 163 uint8_t control = read_byte(offset); // read control register
Backstrom 0:1602fdac44ec 164
Backstrom 0:1602fdac44ec 165 control &= ~0x03; // Set to 0
Backstrom 0:1602fdac44ec 166 control |= freq; // Set freq bitmask
Backstrom 0:1602fdac44ec 167
Backstrom 0:1602fdac44ec 168 // write control back
Backstrom 0:1602fdac44ec 169 write_byte(control, offset);
Backstrom 0:1602fdac44ec 170 }
Backstrom 0:1602fdac44ec 171
Backstrom 0:1602fdac44ec 172 #define CH_BIT (1 << 7) // clock halt bit
Backstrom 0:1602fdac44ec 173
Backstrom 0:1602fdac44ec 174 void DS1307::runClock(bool run)
Backstrom 0:1602fdac44ec 175 {
Backstrom 0:1602fdac44ec 176 uint8_t b = read_byte(0x0);
Backstrom 0:1602fdac44ec 177
Backstrom 0:1602fdac44ec 178 if (run)
Backstrom 0:1602fdac44ec 179 b &= ~(CH_BIT); // clear bit
Backstrom 0:1602fdac44ec 180 else
Backstrom 0:1602fdac44ec 181 b |= CH_BIT; // set bit
Backstrom 0:1602fdac44ec 182
Backstrom 0:1602fdac44ec 183 write_byte(b, 0x0);
Backstrom 0:1602fdac44ec 184 }
Backstrom 0:1602fdac44ec 185
Backstrom 0:1602fdac44ec 186 bool DS1307::isClockRunning(void)
Backstrom 0:1602fdac44ec 187 {
Backstrom 0:1602fdac44ec 188 uint8_t b = read_byte(0x0);
Backstrom 0:1602fdac44ec 189
Backstrom 0:1602fdac44ec 190 if (b & CH_BIT) return false;
Backstrom 0:1602fdac44ec 191 return true;
Backstrom 0:1602fdac44ec 192 }
Backstrom 0:1602fdac44ec 193
Backstrom 0:1602fdac44ec 194 // --------- //
Backstrom 0:1602fdac44ec 195
Backstrom 0:1602fdac44ec 196
Backstrom 0:1602fdac44ec 197 uint8_t DS1307::read_byte(uint8_t offset)
Backstrom 0:1602fdac44ec 198 {
Backstrom 0:1602fdac44ec 199 char buf[1];
Backstrom 0:1602fdac44ec 200 buf[0] = offset;
Backstrom 0:1602fdac44ec 201
Backstrom 0:1602fdac44ec 202 int w = m_i2c.write(DS1307_SLAVE_ADDR, buf, 1);
Backstrom 0:1602fdac44ec 203 int r = m_i2c.read(DS1307_SLAVE_ADDR, buf, 1);
Backstrom 0:1602fdac44ec 204 //error = ((w!=0) || (r!=0));
Backstrom 0:1602fdac44ec 205
Backstrom 0:1602fdac44ec 206 return buf[0];
Backstrom 0:1602fdac44ec 207 }
Backstrom 0:1602fdac44ec 208
Backstrom 0:1602fdac44ec 209 void DS1307::write_byte(uint8_t b, uint8_t offset)
Backstrom 0:1602fdac44ec 210 {
Backstrom 0:1602fdac44ec 211 char buf[2];
Backstrom 0:1602fdac44ec 212 buf[0] = offset;
Backstrom 0:1602fdac44ec 213 buf[1] = b;
Backstrom 0:1602fdac44ec 214
Backstrom 0:1602fdac44ec 215 int w = m_i2c.write(DS1307_SLAVE_ADDR, buf, 2);
Backstrom 0:1602fdac44ec 216 //error=(w!=0);
Backstrom 0:1602fdac44ec 217 }
Backstrom 0:1602fdac44ec 218
Backstrom 0:1602fdac44ec 219
Backstrom 0:1602fdac44ec 220 #define DS1307_SRAM_ADDR 0x08
Backstrom 0:1602fdac44ec 221
Backstrom 0:1602fdac44ec 222 void DS1307::writeRam(uint8_t addr, uint8_t data)
Backstrom 0:1602fdac44ec 223 {
Backstrom 0:1602fdac44ec 224 write_byte(data, DS1307_SRAM_ADDR + addr);
Backstrom 0:1602fdac44ec 225 }
Backstrom 0:1602fdac44ec 226
Backstrom 0:1602fdac44ec 227 uint8_t DS1307::readRam(uint8_t addr)
Backstrom 0:1602fdac44ec 228 {
Backstrom 0:1602fdac44ec 229 return read_byte(DS1307_SRAM_ADDR + addr);
Backstrom 0:1602fdac44ec 230 }