Realtime clock library for DS1307 and DS3231m

Dependents:   vfd_modular_clock_mbed

Committer:
Backstrom
Date:
Wed Feb 11 05:30:48 2015 +0000
Revision:
0:1602fdac44ec
Child:
1:3fe5649f1e02
Initial commit

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 0:1602fdac44ec 194 uint8_t DS3231M::read_byte(uint8_t offset)
Backstrom 0:1602fdac44ec 195 {
Backstrom 0:1602fdac44ec 196 char buf[1];
Backstrom 0:1602fdac44ec 197 buf[0] = offset;
Backstrom 0:1602fdac44ec 198
Backstrom 0:1602fdac44ec 199 int w = m_i2c.write(DS3231M_SLAVE_ADDR, buf, 1);
Backstrom 0:1602fdac44ec 200 int r = m_i2c.read(DS3231M_SLAVE_ADDR, buf, 1);
Backstrom 0:1602fdac44ec 201 //error = ((w!=0) || (r!=0));
Backstrom 0:1602fdac44ec 202
Backstrom 0:1602fdac44ec 203 return buf[0];
Backstrom 0:1602fdac44ec 204 }
Backstrom 0:1602fdac44ec 205
Backstrom 0:1602fdac44ec 206 void DS3231M::write_byte(uint8_t b, uint8_t offset)
Backstrom 0:1602fdac44ec 207 {
Backstrom 0:1602fdac44ec 208 char buf[2];
Backstrom 0:1602fdac44ec 209 buf[0] = offset;
Backstrom 0:1602fdac44ec 210 buf[1] = b;
Backstrom 0:1602fdac44ec 211
Backstrom 0:1602fdac44ec 212 int w = m_i2c.write(DS3231M_SLAVE_ADDR, buf, 2);
Backstrom 0:1602fdac44ec 213 //error=(w!=0);
Backstrom 0:1602fdac44ec 214 }
Backstrom 0:1602fdac44ec 215
Backstrom 0:1602fdac44ec 216 void DS3231M::write_addr(uint8_t addr)
Backstrom 0:1602fdac44ec 217 {
Backstrom 0:1602fdac44ec 218 /*
Backstrom 0:1602fdac44ec 219 Wire.beginTransmission(RTC_ADDR);
Backstrom 0:1602fdac44ec 220 Wire.write(addr);
Backstrom 0:1602fdac44ec 221 Wire.endTransmission();
Backstrom 0:1602fdac44ec 222 */
Backstrom 0:1602fdac44ec 223 }
Backstrom 0:1602fdac44ec 224