Realtime clock library for DS1307 and DS3231m
Dependents: vfd_modular_clock_mbed
ds1307.cpp@2:6119507e6713, 2015-08-10 (annotated)
- 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?
User | Revision | Line number | New 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 | } |