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:
1:3fe5649f1e02
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 "ds3231m.h"
Backstrom 0:1602fdac44ec 17
Backstrom 0:1602fdac44ec 18 #define DS3231M_SLAVE_ADDR 0xD0
Backstrom 0:1602fdac44ec 19
Backstrom 0:1602fdac44ec 20 DS3231M::DS3231M(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 DS3231M::begin()
Backstrom 0:1602fdac44ec 28 {
Backstrom 0:1602fdac44ec 29 }
Backstrom 0:1602fdac44ec 30
Backstrom 0:1602fdac44ec 31 time_t DS3231M::time()
Backstrom 0:1602fdac44ec 32 {
Backstrom 0:1602fdac44ec 33 return m_time;
Backstrom 0:1602fdac44ec 34 }
Backstrom 0:1602fdac44ec 35
Backstrom 0:1602fdac44ec 36 struct tm* DS3231M::getTime()
Backstrom 0:1602fdac44ec 37 {
Backstrom 0:1602fdac44ec 38 char rtc[7];
Backstrom 0:1602fdac44ec 39
Backstrom 0:1602fdac44ec 40 rtc[0] = 0; // second register, 0
Backstrom 0:1602fdac44ec 41 int w = m_i2c.write(DS3231M_SLAVE_ADDR, rtc, 1);
Backstrom 0:1602fdac44ec 42 int r = m_i2c.read(DS3231M_SLAVE_ADDR, rtc, 7);
Backstrom 0:1602fdac44ec 43
Backstrom 0:1602fdac44ec 44 // Clear clock halt bit from read data
Backstrom 0:1602fdac44ec 45 //rtc[0] &= ~(_BV(CH_BIT));
Backstrom 0:1602fdac44ec 46
Backstrom 0:1602fdac44ec 47 m_tm.tm_sec = bcd2dec(rtc[0]);
Backstrom 0:1602fdac44ec 48 m_tm.tm_min = bcd2dec(rtc[1]);
Backstrom 0:1602fdac44ec 49 m_tm.tm_hour = bcd2dec(rtc[2]);
Backstrom 0:1602fdac44ec 50 m_tm.tm_wday = bcd2dec(rtc[3])-1;
Backstrom 0:1602fdac44ec 51 m_tm.tm_mday = bcd2dec(rtc[4]);
Backstrom 0:1602fdac44ec 52 m_tm.tm_mon = bcd2dec(rtc[5])-1; // tm_mon is 0-11
Backstrom 0:1602fdac44ec 53 m_tm.tm_year = bcd2dec(rtc[6]);
Backstrom 0:1602fdac44ec 54
Backstrom 0:1602fdac44ec 55 return &m_tm;
Backstrom 0:1602fdac44ec 56 }
Backstrom 0:1602fdac44ec 57
Backstrom 0:1602fdac44ec 58 void DS3231M::getTime(uint8_t* hour, uint8_t* min, uint8_t* sec)
Backstrom 0:1602fdac44ec 59 {
Backstrom 0:1602fdac44ec 60 char rtc[3];
Backstrom 0:1602fdac44ec 61
Backstrom 0:1602fdac44ec 62 rtc[0] = 0; // second register, 0
Backstrom 0:1602fdac44ec 63 int w = m_i2c.write(DS3231M_SLAVE_ADDR, rtc, 1);
Backstrom 0:1602fdac44ec 64 int r = m_i2c.read(DS3231M_SLAVE_ADDR, rtc, 3);
Backstrom 0:1602fdac44ec 65
Backstrom 0:1602fdac44ec 66 // Clear clock halt bit from read data
Backstrom 0:1602fdac44ec 67 //rtc[0] &= ~(_BV(CH_BIT));
Backstrom 0:1602fdac44ec 68
Backstrom 0:1602fdac44ec 69 if (sec) *sec = bcd2dec(rtc[0]);
Backstrom 0:1602fdac44ec 70 if (min) *min = bcd2dec(rtc[1]);
Backstrom 0:1602fdac44ec 71 if (hour) *hour = bcd2dec(rtc[2]);
Backstrom 0:1602fdac44ec 72 }
Backstrom 0:1602fdac44ec 73
Backstrom 0:1602fdac44ec 74 void DS3231M::setTime(time_t t)
Backstrom 0:1602fdac44ec 75 {
Backstrom 0:1602fdac44ec 76 struct tm * timeinfo;
Backstrom 0:1602fdac44ec 77 timeinfo = localtime (&t);
Backstrom 0:1602fdac44ec 78 setTime(timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
Backstrom 0:1602fdac44ec 79 }
Backstrom 0:1602fdac44ec 80
Backstrom 0:1602fdac44ec 81 void DS3231M::setTime(uint8_t hour, uint8_t min, uint8_t sec)
Backstrom 0:1602fdac44ec 82 {
Backstrom 0:1602fdac44ec 83 write_byte(dec2bcd(sec), 0);
Backstrom 0:1602fdac44ec 84 write_byte(dec2bcd(min), 1);
Backstrom 0:1602fdac44ec 85 write_byte(dec2bcd(hour), 2);
Backstrom 0:1602fdac44ec 86 }
Backstrom 0:1602fdac44ec 87
Backstrom 0:1602fdac44ec 88 void DS3231M::setTime(struct tm* tm)
Backstrom 0:1602fdac44ec 89 {
Backstrom 0:1602fdac44ec 90 write_byte(dec2bcd(tm->tm_sec), 0);
Backstrom 0:1602fdac44ec 91 write_byte(dec2bcd(tm->tm_min), 1);
Backstrom 0:1602fdac44ec 92 write_byte(dec2bcd(tm->tm_hour), 2);
Backstrom 0:1602fdac44ec 93 write_byte(dec2bcd(tm->tm_wday+1), 3);
Backstrom 0:1602fdac44ec 94 write_byte(dec2bcd(tm->tm_mday), 4);
Backstrom 0:1602fdac44ec 95 write_byte(dec2bcd(tm->tm_mon+1), 5);
Backstrom 0:1602fdac44ec 96 write_byte(dec2bcd(tm->tm_year), 6);
Backstrom 0:1602fdac44ec 97 }
Backstrom 0:1602fdac44ec 98
Backstrom 0:1602fdac44ec 99 void DS3231M::setAlarm(time_t t)
Backstrom 0:1602fdac44ec 100 {
Backstrom 0:1602fdac44ec 101 struct tm * timeinfo;
Backstrom 0:1602fdac44ec 102 timeinfo = localtime (&t);
Backstrom 0:1602fdac44ec 103 setAlarm(timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
Backstrom 0:1602fdac44ec 104 }
Backstrom 0:1602fdac44ec 105
Backstrom 0:1602fdac44ec 106 void DS3231M::setAlarm(uint8_t hour, uint8_t min, uint8_t sec)
Backstrom 0:1602fdac44ec 107 {
Backstrom 0:1602fdac44ec 108 /*
Backstrom 0:1602fdac44ec 109 * 07h: A1M1:0 Alarm 1 seconds
Backstrom 0:1602fdac44ec 110 * 08h: A1M2:0 Alarm 1 minutes
Backstrom 0:1602fdac44ec 111 * 09h: A1M3:0 Alarm 1 hour (bit6 is am/pm flag in 12h mode)
Backstrom 0:1602fdac44ec 112 * 0ah: A1M4:1 Alarm 1 day/date (bit6: 1 for day, 0 for date)
Backstrom 0:1602fdac44ec 113 * Sets alarm to fire when hour, minute and second matches
Backstrom 0:1602fdac44ec 114 */
Backstrom 0:1602fdac44ec 115 write_byte(dec2bcd(sec), 0x07); // second
Backstrom 0:1602fdac44ec 116 write_byte(dec2bcd(min), 0x08); // minute
Backstrom 0:1602fdac44ec 117 write_byte(dec2bcd(hour), 0x09); // hour
Backstrom 0:1602fdac44ec 118 write_byte(0x81, 0x0a); // day (upper bit must be set)
Backstrom 0:1602fdac44ec 119
Backstrom 0:1602fdac44ec 120 // clear alarm flag
Backstrom 0:1602fdac44ec 121 uint8_t val = read_byte(0x0f);
Backstrom 0:1602fdac44ec 122 write_byte(val & ~0x01, 0x0f);
Backstrom 0:1602fdac44ec 123 }
Backstrom 0:1602fdac44ec 124
Backstrom 0:1602fdac44ec 125
Backstrom 0:1602fdac44ec 126 struct tm* DS3231M::getAlarm(void)
Backstrom 0:1602fdac44ec 127 {
Backstrom 0:1602fdac44ec 128 struct tm * timeinfo = getTime();
Backstrom 0:1602fdac44ec 129 uint8_t hour, min, sec;
Backstrom 0:1602fdac44ec 130
Backstrom 0:1602fdac44ec 131 getAlarm(&hour, &min, &sec);
Backstrom 0:1602fdac44ec 132 timeinfo->tm_hour = hour;
Backstrom 0:1602fdac44ec 133 timeinfo->tm_min = min;
Backstrom 0:1602fdac44ec 134 timeinfo->tm_sec = sec;
Backstrom 0:1602fdac44ec 135 return timeinfo;
Backstrom 0:1602fdac44ec 136 }
Backstrom 0:1602fdac44ec 137
Backstrom 0:1602fdac44ec 138 void DS3231M::getAlarm(uint8_t* hour, uint8_t* min, uint8_t* sec)
Backstrom 0:1602fdac44ec 139 {
Backstrom 0:1602fdac44ec 140 *sec = bcd2dec(read_byte(0x07) & ~0x80);
Backstrom 0:1602fdac44ec 141 *min = bcd2dec(read_byte(0x08) & ~0x80);
Backstrom 0:1602fdac44ec 142 *hour = bcd2dec(read_byte(0x09) & ~0x80);
Backstrom 0:1602fdac44ec 143 }
Backstrom 0:1602fdac44ec 144
Backstrom 0:1602fdac44ec 145 bool DS3231M::checkAlarm(void)
Backstrom 0:1602fdac44ec 146 {
Backstrom 0:1602fdac44ec 147 // Alarm 1 flag (A1F) in bit 0
Backstrom 0:1602fdac44ec 148 uint8_t val = read_byte(0x0f);
Backstrom 0:1602fdac44ec 149
Backstrom 0:1602fdac44ec 150 // clear flag when set
Backstrom 0:1602fdac44ec 151 if (val & 1)
Backstrom 0:1602fdac44ec 152 write_byte(val & ~0x01, 0x0f);
Backstrom 0:1602fdac44ec 153
Backstrom 0:1602fdac44ec 154 return val & 1 ? 1 : 0;
Backstrom 0:1602fdac44ec 155 }
Backstrom 0:1602fdac44ec 156
Backstrom 0:1602fdac44ec 157 void DS3231M::SQWEnable(bool enable)
Backstrom 0:1602fdac44ec 158 {
Backstrom 0:1602fdac44ec 159 uint8_t control = read_byte(0x0E); // read control register
Backstrom 0:1602fdac44ec 160 if (enable) {
Backstrom 0:1602fdac44ec 161 control |= 0x40; // set BBSQW to 1
Backstrom 0:1602fdac44ec 162 control &= ~0x04; // set INTCN to 0
Backstrom 0:1602fdac44ec 163 }
Backstrom 0:1602fdac44ec 164 else {
Backstrom 0:1602fdac44ec 165 control &= ~0x40; // set BBSQW to 0
Backstrom 0:1602fdac44ec 166 }
Backstrom 0:1602fdac44ec 167 // write control back
Backstrom 0:1602fdac44ec 168 write_byte(control, 0x0E);
Backstrom 0:1602fdac44ec 169 }
Backstrom 0:1602fdac44ec 170
Backstrom 0:1602fdac44ec 171 void DS3231M::SQWSetFreq(enum RTC_SQW_FREQ freq)
Backstrom 0:1602fdac44ec 172 {
Backstrom 0:1602fdac44ec 173 uint8_t control = read_byte(0x0E); // read control register
Backstrom 0:1602fdac44ec 174 control &= ~0x18; // Set to 0
Backstrom 0:1602fdac44ec 175 control |= (freq << 4); // Set freq bitmask
Backstrom 0:1602fdac44ec 176
Backstrom 0:1602fdac44ec 177 // write control back
Backstrom 0:1602fdac44ec 178 write_byte(control, 0x0E);
Backstrom 0:1602fdac44ec 179 }
Backstrom 0:1602fdac44ec 180
Backstrom 0:1602fdac44ec 181 void DS3231M::Osc32kHzEnable(bool enable)
Backstrom 0:1602fdac44ec 182 {
Backstrom 0:1602fdac44ec 183 uint8_t status = read_byte(0x0F); // read status
Backstrom 0:1602fdac44ec 184
Backstrom 0:1602fdac44ec 185 if (enable)
Backstrom 0:1602fdac44ec 186 status |= 0x08; // set to 1
Backstrom 0:1602fdac44ec 187 else
Backstrom 0:1602fdac44ec 188 status &= ~0x08; // Set to 0
Backstrom 0:1602fdac44ec 189
Backstrom 0:1602fdac44ec 190 // write status back
Backstrom 0:1602fdac44ec 191 write_byte(status, 0x0F);
Backstrom 0:1602fdac44ec 192 }
Backstrom 0:1602fdac44ec 193
Backstrom 1:3fe5649f1e02 194 void DS3231M::getTemp(int8_t* i, uint8_t* f)
Backstrom 1:3fe5649f1e02 195 {
Backstrom 1:3fe5649f1e02 196 char data[2]; // msb, lsb
Backstrom 1:3fe5649f1e02 197
Backstrom 1:3fe5649f1e02 198 *i = 0;
Backstrom 1:3fe5649f1e02 199 *f = 0;
Backstrom 1:3fe5649f1e02 200
Backstrom 1:3fe5649f1e02 201 data[0] = 0x11;
Backstrom 1:3fe5649f1e02 202 int w = m_i2c.write(DS3231M_SLAVE_ADDR, data, 1);
Backstrom 1:3fe5649f1e02 203 int r = m_i2c.read(DS3231M_SLAVE_ADDR, data, 2);
Backstrom 1:3fe5649f1e02 204
Backstrom 1:3fe5649f1e02 205 // integer part in entire byte
Backstrom 1:3fe5649f1e02 206 *i = (uint8_t)data[0];
Backstrom 1:3fe5649f1e02 207 // fractional part in top two bits (increments of 0.25)
Backstrom 1:3fe5649f1e02 208 *f = ((uint8_t)data[1] >> 6) * 25;
Backstrom 1:3fe5649f1e02 209
Backstrom 1:3fe5649f1e02 210 // float value can be read like so:
Backstrom 1:3fe5649f1e02 211 // float temp = ((((short)data[0] << 8) | (short)data[1]) >> 6) / 4.0f;
Backstrom 1:3fe5649f1e02 212 }
Backstrom 1:3fe5649f1e02 213
Backstrom 1:3fe5649f1e02 214 void DS3231M::forceTempConversion(uint8_t block)
Backstrom 1:3fe5649f1e02 215 {
Backstrom 1:3fe5649f1e02 216 // read control register (0x0E)
Backstrom 1:3fe5649f1e02 217 uint8_t control = read_byte(0x0E); // read control register
Backstrom 1:3fe5649f1e02 218 control |= 0x20; // Set CONV bit
Backstrom 1:3fe5649f1e02 219
Backstrom 1:3fe5649f1e02 220 // write new control register value
Backstrom 1:3fe5649f1e02 221 write_byte(control, 0x0E);
Backstrom 1:3fe5649f1e02 222
Backstrom 1:3fe5649f1e02 223 if (!block) return;
Backstrom 1:3fe5649f1e02 224
Backstrom 1:3fe5649f1e02 225 uint8_t data;
Backstrom 1:3fe5649f1e02 226 // Temp conversion is ready when control register becomes 0
Backstrom 1:3fe5649f1e02 227 do {
Backstrom 1:3fe5649f1e02 228 // Block until CONV is 0
Backstrom 1:3fe5649f1e02 229 data = read_byte(0x0E);
Backstrom 1:3fe5649f1e02 230 } while ((data & 0x20) != 0);
Backstrom 1:3fe5649f1e02 231 }
Backstrom 1:3fe5649f1e02 232
Backstrom 1:3fe5649f1e02 233
Backstrom 0:1602fdac44ec 234 uint8_t DS3231M::read_byte(uint8_t offset)
Backstrom 0:1602fdac44ec 235 {
Backstrom 0:1602fdac44ec 236 char buf[1];
Backstrom 0:1602fdac44ec 237 buf[0] = offset;
Backstrom 0:1602fdac44ec 238
Backstrom 0:1602fdac44ec 239 int w = m_i2c.write(DS3231M_SLAVE_ADDR, buf, 1);
Backstrom 0:1602fdac44ec 240 int r = m_i2c.read(DS3231M_SLAVE_ADDR, buf, 1);
Backstrom 0:1602fdac44ec 241 //error = ((w!=0) || (r!=0));
Backstrom 0:1602fdac44ec 242
Backstrom 0:1602fdac44ec 243 return buf[0];
Backstrom 0:1602fdac44ec 244 }
Backstrom 0:1602fdac44ec 245
Backstrom 0:1602fdac44ec 246 void DS3231M::write_byte(uint8_t b, uint8_t offset)
Backstrom 0:1602fdac44ec 247 {
Backstrom 0:1602fdac44ec 248 char buf[2];
Backstrom 0:1602fdac44ec 249 buf[0] = offset;
Backstrom 0:1602fdac44ec 250 buf[1] = b;
Backstrom 0:1602fdac44ec 251
Backstrom 0:1602fdac44ec 252 int w = m_i2c.write(DS3231M_SLAVE_ADDR, buf, 2);
Backstrom 0:1602fdac44ec 253 //error=(w!=0);
Backstrom 0:1602fdac44ec 254 }
Backstrom 0:1602fdac44ec 255
Backstrom 0:1602fdac44ec 256 void DS3231M::write_addr(uint8_t addr)
Backstrom 0:1602fdac44ec 257 {
Backstrom 0:1602fdac44ec 258 /*
Backstrom 0:1602fdac44ec 259 Wire.beginTransmission(RTC_ADDR);
Backstrom 0:1602fdac44ec 260 Wire.write(addr);
Backstrom 0:1602fdac44ec 261 Wire.endTransmission();
Backstrom 0:1602fdac44ec 262 */
Backstrom 0:1602fdac44ec 263 }
Backstrom 0:1602fdac44ec 264