*Rewritten working version of* Working Version of the Real Time Clock module DS1307.

Dependents:   Nucleo_praktyki

Fork of RTC-DS1307 by Henry Leinen

Committer:
amateusz
Date:
Wed Jan 31 11:50:07 2018 +0000
Revision:
10:8c0c306cee03
Parent:
Rtc_Ds1307.cpp@9:5627b407e097
Oh yeah, I changed something. The idea behind was it to be more uniform or something.. Sorry. I'm hoping this commit is my private as I only want to publish a program.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
leihen 5:30531f2121a2 1 #include "mbed.h"
amateusz 10:8c0c306cee03 2 #include "DS1307.h"
leihen 7:dca20be3ef38 3
leihen 5:30531f2121a2 4 #ifndef DEBUG
leihen 9:5627b407e097 5 //#define DEBUG
leihen 5:30531f2121a2 6 #endif
amateusz 10:8c0c306cee03 7 //#include "debug.h"
leihen 0:3940f0ad2ca5 8
amateusz 10:8c0c306cee03 9 const char *DS1307::m_weekDays[] = { "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
leihen 0:3940f0ad2ca5 10
leihen 0:3940f0ad2ca5 11
amateusz 10:8c0c306cee03 12 DS1307::DS1307(I2C * i2c)
leihen 0:3940f0ad2ca5 13 {
leihen 0:3940f0ad2ca5 14 // Create a new I2C object
amateusz 10:8c0c306cee03 15 m_rtc = i2c;
leihen 0:3940f0ad2ca5 16 if (m_rtc == NULL)
leihen 0:3940f0ad2ca5 17 error("Rtc_Ds1307");
amateusz 10:8c0c306cee03 18
leihen 1:64274190e842 19 // Set the frequency to standard 100kHz
leihen 1:64274190e842 20 m_rtc->frequency(100000);
leihen 0:3940f0ad2ca5 21 }
leihen 0:3940f0ad2ca5 22
amateusz 10:8c0c306cee03 23 DS1307::~DS1307()
leihen 0:3940f0ad2ca5 24 {
amateusz 10:8c0c306cee03 25 // if (m_rtc != NULL)
amateusz 10:8c0c306cee03 26 // delete m_rtc;
leihen 0:3940f0ad2ca5 27 }
leihen 0:3940f0ad2ca5 28
amateusz 10:8c0c306cee03 29 bool DS1307::setTime(Time_rtc& time, bool start, bool thm)
leihen 0:3940f0ad2ca5 30 {
leihen 2:ee81f2c5a706 31 char buffer[7];
amateusz 10:8c0c306cee03 32 // INFO("reading clock registers to write the new time : %d:%d:%d\n", time.hour, time.min, time.sec);
leihen 2:ee81f2c5a706 33 if (!read(0,buffer,7)) {
amateusz 10:8c0c306cee03 34 // ERR("Failed to read from RTC\n");
leihen 2:ee81f2c5a706 35 return false;
leihen 2:ee81f2c5a706 36 }
leihen 2:ee81f2c5a706 37 // Now update only the time part (saving the existing flags)
amateusz 10:8c0c306cee03 38 if (start) {
amateusz 10:8c0c306cee03 39 buffer[0] &= 0x7F;
amateusz 10:8c0c306cee03 40 } else {
amateusz 10:8c0c306cee03 41 buffer[0] |= 0x80;
amateusz 10:8c0c306cee03 42 }
leihen 2:ee81f2c5a706 43 buffer[0] = (buffer[0]&0x80) | (decimalToBcd(time.sec)& 0x7f);
leihen 2:ee81f2c5a706 44 buffer[1] = decimalToBcd(time.min);
leihen 2:ee81f2c5a706 45 if (thm) {
leihen 2:ee81f2c5a706 46 // AM PM format
leihen 2:ee81f2c5a706 47 buffer[2] = (buffer[2]& 196) | (time.hour>12 ? (0x20 | ((decimalToBcd(time.hour-12)))) : decimalToBcd(time.hour));
amateusz 10:8c0c306cee03 48 } else {
leihen 2:ee81f2c5a706 49 // 24 hours format
leihen 2:ee81f2c5a706 50 buffer[2] = (buffer[2]& 196) | (decimalToBcd(time.hour) & 0x3F);
leihen 2:ee81f2c5a706 51 }
leihen 2:ee81f2c5a706 52 buffer[3] = time.wday;
leihen 2:ee81f2c5a706 53 buffer[4] = decimalToBcd(time.date);
leihen 2:ee81f2c5a706 54 buffer[5] = decimalToBcd(time.mon);
leihen 2:ee81f2c5a706 55 buffer[6] = decimalToBcd(time.year-2000);
amateusz 10:8c0c306cee03 56 // INFO("Writing new time and date data to RTC\n");
leihen 2:ee81f2c5a706 57 if (!write(0, buffer, 7) ) {
amateusz 10:8c0c306cee03 58 // ERR("Failed to write the data to RTC!\n");
leihen 2:ee81f2c5a706 59 return false;
leihen 2:ee81f2c5a706 60 }
leihen 0:3940f0ad2ca5 61 return true;
leihen 0:3940f0ad2ca5 62 }
leihen 0:3940f0ad2ca5 63
amateusz 10:8c0c306cee03 64 bool DS1307::getTime(Time_rtc& time)
leihen 0:3940f0ad2ca5 65 {
leihen 1:64274190e842 66 char buffer[7];
leihen 1:64274190e842 67 bool thm = false;
amateusz 10:8c0c306cee03 68
amateusz 10:8c0c306cee03 69 // INFO("Getting time from RTC\n");
leihen 2:ee81f2c5a706 70 if (!read(0, buffer, 7) ) {
leihen 1:64274190e842 71 // Failed to read
amateusz 10:8c0c306cee03 72 // ERR("Failed to read from RTC\n");
leihen 1:64274190e842 73 return false;
leihen 1:64274190e842 74 }
leihen 1:64274190e842 75 thm = ((buffer[2] & 64) == 64);
leihen 1:64274190e842 76 time.sec = bcdToDecimal(buffer[0]&0x7F);
leihen 1:64274190e842 77 time.min = bcdToDecimal(buffer[1]);
leihen 1:64274190e842 78 if (thm) {
leihen 1:64274190e842 79 // in 12-hour-mode, we need to add 12 hours if PM bit is set
amateusz 10:8c0c306cee03 80 time.hour = DS1307::bcdToDecimal( buffer[2] & 31 );
leihen 1:64274190e842 81 if ((buffer[2] & 32) == 32)
leihen 1:64274190e842 82 time.hour += 12;
amateusz 10:8c0c306cee03 83 } else {
amateusz 10:8c0c306cee03 84 time.hour = DS1307::bcdToDecimal( buffer[2] & 63 );
leihen 1:64274190e842 85 }
amateusz 10:8c0c306cee03 86 time.wday = buffer[3];
amateusz 10:8c0c306cee03 87 time.date = DS1307::bcdToDecimal( buffer[4]);
amateusz 10:8c0c306cee03 88 time.mon = DS1307::bcdToDecimal( buffer[5]);
amateusz 10:8c0c306cee03 89 time.year = DS1307::bcdToDecimal(buffer[6]) + 2000; // plus hundret is because RTC is giving the years since 2000, but std c struct tm needs years since 1900
amateusz 10:8c0c306cee03 90
leihen 2:ee81f2c5a706 91 return true;
leihen 2:ee81f2c5a706 92 }
leihen 2:ee81f2c5a706 93
leihen 2:ee81f2c5a706 94
amateusz 10:8c0c306cee03 95 bool DS1307::startClock()
leihen 2:ee81f2c5a706 96 {
leihen 2:ee81f2c5a706 97 char strtStop;
amateusz 10:8c0c306cee03 98
amateusz 10:8c0c306cee03 99 // INFO ("Reading clock start/stop register value\n");
leihen 2:ee81f2c5a706 100 if (!read(0, &strtStop, 1)) {
amateusz 10:8c0c306cee03 101 // ERR("Failed to read clock start stop register !\n");
leihen 2:ee81f2c5a706 102 return false;
leihen 2:ee81f2c5a706 103 }
amateusz 10:8c0c306cee03 104
leihen 2:ee81f2c5a706 105 strtStop &= 0x7F;
amateusz 10:8c0c306cee03 106
amateusz 10:8c0c306cee03 107 // INFO("Writing back start/stop register value\n");
leihen 2:ee81f2c5a706 108 if (!write(0, &strtStop, 1)) {
amateusz 10:8c0c306cee03 109 // ERR("Failed to write the start stop register !\n");
leihen 2:ee81f2c5a706 110 return false;
leihen 2:ee81f2c5a706 111 }
amateusz 10:8c0c306cee03 112
amateusz 10:8c0c306cee03 113 // INFO("Start/stop register value successfully written\n");
leihen 2:ee81f2c5a706 114 return true;
leihen 2:ee81f2c5a706 115 }
leihen 2:ee81f2c5a706 116
amateusz 10:8c0c306cee03 117 bool DS1307::stopClock()
leihen 2:ee81f2c5a706 118 {
leihen 2:ee81f2c5a706 119 char strtStop;
amateusz 10:8c0c306cee03 120
amateusz 10:8c0c306cee03 121 // INFO ("Reading clock start/stop register value\n");
leihen 2:ee81f2c5a706 122 if (!read(0, &strtStop, 1)) {
amateusz 10:8c0c306cee03 123 // ERR("Failed to read clock start stop register !\n");
leihen 2:ee81f2c5a706 124 return false;
leihen 2:ee81f2c5a706 125 }
amateusz 10:8c0c306cee03 126
leihen 2:ee81f2c5a706 127 strtStop |= 0x80;
amateusz 10:8c0c306cee03 128
amateusz 10:8c0c306cee03 129 // INFO("Writing back start/stop register value\n");
leihen 2:ee81f2c5a706 130 if (!write(0, &strtStop, 1)) {
amateusz 10:8c0c306cee03 131 // ERR("Failed to write the start stop register !\n");
leihen 2:ee81f2c5a706 132 return false;
leihen 2:ee81f2c5a706 133 }
amateusz 10:8c0c306cee03 134
amateusz 10:8c0c306cee03 135 // INFO("Start/stop register value successfully written\n");
leihen 2:ee81f2c5a706 136 return true;
leihen 0:3940f0ad2ca5 137 }
leihen 1:64274190e842 138
amateusz 10:8c0c306cee03 139 bool DS1307::setSquareWaveOutput(bool ena, SqwRateSelect_t rs)
leihen 2:ee81f2c5a706 140 {
leihen 2:ee81f2c5a706 141 char reg;
amateusz 10:8c0c306cee03 142 // INFO("Reading register value first\n");
amateusz 10:8c0c306cee03 143
leihen 2:ee81f2c5a706 144 if (!read(7,&reg, 1)) {
amateusz 10:8c0c306cee03 145 // ERR("Failed to read register value !\n");
leihen 2:ee81f2c5a706 146 return false;
leihen 2:ee81f2c5a706 147 }
amateusz 10:8c0c306cee03 148 // INFO("[Reg:0x07] = %02x\n", reg);
amateusz 10:8c0c306cee03 149
leihen 2:ee81f2c5a706 150 // preserve the OUT control bit while writing the frequency and enable bits
leihen 2:ee81f2c5a706 151 reg = (reg & 0x80) | (ena ? 0x10 : 0) | ((char)rs & 0x03);
leihen 2:ee81f2c5a706 152
amateusz 10:8c0c306cee03 153 // INFO("Writing back register value\n");
amateusz 10:8c0c306cee03 154 // INFO("[Reg:0x07] = %02x\n", reg);
amateusz 10:8c0c306cee03 155
leihen 2:ee81f2c5a706 156 if (!write(7, &reg, 1)) {
amateusz 10:8c0c306cee03 157 // ERR("Failed to write register value !\n");
leihen 2:ee81f2c5a706 158 return false;
leihen 2:ee81f2c5a706 159 }
amateusz 10:8c0c306cee03 160
amateusz 10:8c0c306cee03 161 // INFO("Successfully changed the square wave output.\n");
leihen 2:ee81f2c5a706 162 return true;
leihen 2:ee81f2c5a706 163 }
leihen 2:ee81f2c5a706 164
amateusz 10:8c0c306cee03 165 void DS1307::setLocalTime()
amateusz 10:8c0c306cee03 166 {
amateusz 10:8c0c306cee03 167 Time_rtc t; // query time from device
amateusz 10:8c0c306cee03 168 getTime(t); // sync the time with MBED RTC
amateusz 10:8c0c306cee03 169 struct tm now = {t.sec, t.min, t.hour, t.date, t.mon-1, t.year-1900};
amateusz 10:8c0c306cee03 170 time_t epoch = mktime(&now);
amateusz 10:8c0c306cee03 171 set_time(epoch);
amateusz 10:8c0c306cee03 172 }
leihen 1:64274190e842 173
amateusz 10:8c0c306cee03 174 bool DS1307::read(int address, char *buffer, int len)
leihen 1:64274190e842 175 {
leihen 1:64274190e842 176 char buffer2[2] = {(char)address, 0};
amateusz 10:8c0c306cee03 177
leihen 2:ee81f2c5a706 178 // m_rtc->start();
leihen 1:64274190e842 179 if (m_rtc->write(0xd0, buffer2, 1) != 0) {
amateusz 10:8c0c306cee03 180 // ERR("Failed to write register address on rtv!\n");
leihen 1:64274190e842 181 m_rtc->stop();
leihen 1:64274190e842 182 return false;
leihen 1:64274190e842 183 }
leihen 1:64274190e842 184 if (m_rtc->read(0xd0, buffer, len) != 0) {
amateusz 10:8c0c306cee03 185 // ERR("Failed to read register !\n");
leihen 1:64274190e842 186 return false;
leihen 1:64274190e842 187 }
leihen 1:64274190e842 188 m_rtc->stop();
amateusz 10:8c0c306cee03 189
amateusz 10:8c0c306cee03 190 // INFO("Successfully read %d registers from RTC\n", len);
leihen 1:64274190e842 191 return true;
leihen 1:64274190e842 192 }
leihen 1:64274190e842 193
amateusz 10:8c0c306cee03 194 bool DS1307::write(int address, char *buffer, int len)
leihen 1:64274190e842 195 {
leihen 1:64274190e842 196 char buffer2[10];
leihen 1:64274190e842 197 buffer2[0] = address&0xFF;
leihen 1:64274190e842 198 for (int i = 0 ; i < len ; i++)
leihen 1:64274190e842 199 buffer2[i+1] = buffer[i];
leihen 1:64274190e842 200
amateusz 10:8c0c306cee03 201 // m_rtc->start();
leihen 1:64274190e842 202 if (m_rtc->write(0xd0, buffer2, len+1) != 0) {
amateusz 10:8c0c306cee03 203 // ERR("Failed to write data to rtc\n");
leihen 1:64274190e842 204 m_rtc->stop();
leihen 1:64274190e842 205 return false;
leihen 1:64274190e842 206 }
leihen 1:64274190e842 207 m_rtc->stop();
leihen 1:64274190e842 208 return true;
leihen 7:dca20be3ef38 209 }
leihen 7:dca20be3ef38 210
leihen 7:dca20be3ef38 211
leihen 7:dca20be3ef38 212
leihen 7:dca20be3ef38 213
amateusz 10:8c0c306cee03 214 RtcCls::RtcCls(I2C * i2c, PinName sqw, bool bUseSqw)
amateusz 10:8c0c306cee03 215 : DS1307(i2c), m_sqw(sqw), m_bUseSqw(bUseSqw), m_bAlarmEnabled(false), m_alarmfunc(NULL)
leihen 7:dca20be3ef38 216 {
leihen 9:5627b407e097 217 Time_rtc t;
leihen 9:5627b407e097 218 // query time from device
leihen 9:5627b407e097 219 getTime(t);
leihen 9:5627b407e097 220 // sync the time with MBED RTC
leihen 9:5627b407e097 221 struct tm now = {t.sec, t.min, t.hour, t.date, t.mon-1, t.year-1900};
leihen 9:5627b407e097 222 m_time = mktime(&now);
leihen 9:5627b407e097 223 set_time(m_time);
amateusz 10:8c0c306cee03 224
leihen 7:dca20be3ef38 225 // Only register the callback and start the SQW if requested to do so. Otherwise the system
leihen 7:dca20be3ef38 226 // will use the MBED built-in RTC.
leihen 7:dca20be3ef38 227 if (m_bUseSqw) {
leihen 7:dca20be3ef38 228 // start the wave
leihen 7:dca20be3ef38 229 setSquareWaveOutput(true, RS1Hz);
leihen 7:dca20be3ef38 230 // register callback from now on the time will be maintained by the square wave input
leihen 7:dca20be3ef38 231 m_sqw.rise(this, &RtcCls::_callback);
leihen 7:dca20be3ef38 232 }
leihen 7:dca20be3ef38 233 }
leihen 7:dca20be3ef38 234
leihen 7:dca20be3ef38 235 void RtcCls::_callback(void)
leihen 7:dca20be3ef38 236 {
leihen 8:d0e66fa78e79 237 // INFO("Tick!");
leihen 7:dca20be3ef38 238 // Simply increase the number of seconds
leihen 7:dca20be3ef38 239 m_time++;
leihen 8:d0e66fa78e79 240 // if (m_bAlarmEnabled && (m_time == m_alarmTime)) {
leihen 8:d0e66fa78e79 241 // if (m_alarmfunc != NULL)
leihen 8:d0e66fa78e79 242 // m_alarmfunc();
leihen 8:d0e66fa78e79 243 // m_bAlarmEnabled = false;
leihen 8:d0e66fa78e79 244 // }
leihen 7:dca20be3ef38 245 }
leihen 7:dca20be3ef38 246
leihen 7:dca20be3ef38 247 time_t RtcCls::getTime()
leihen 7:dca20be3ef38 248 {
leihen 7:dca20be3ef38 249 // when not using the HW support, we have to query the RTC chip. Other wise we can just return out stored value
leihen 7:dca20be3ef38 250 if (!m_bUseSqw) {
leihen 7:dca20be3ef38 251 Time_rtc t;
leihen 7:dca20be3ef38 252 getTime(t);
leihen 8:d0e66fa78e79 253 struct tm now = {t.sec, t.min, t.hour, t.date, t.mon-1, t.year-1900};
leihen 7:dca20be3ef38 254 m_time = mktime(&now);
amateusz 10:8c0c306cee03 255 // INFO("getting time %02d.%02d.%04d %02d:%02d:%02d Ticks=%08lx", t.date, t.mon, t.year, t.hour, t.min, t.sec, m_time);
amateusz 10:8c0c306cee03 256 } else {
amateusz 10:8c0c306cee03 257 // INFO("getting time Ticks=%08lx", m_time);
leihen 7:dca20be3ef38 258 }
leihen 7:dca20be3ef38 259 return m_time;
leihen 7:dca20be3ef38 260 }
leihen 7:dca20be3ef38 261
leihen 7:dca20be3ef38 262 void RtcCls::setTime(time_t t)
leihen 7:dca20be3ef38 263 {
leihen 7:dca20be3ef38 264 Time_rtc tim;
leihen 7:dca20be3ef38 265 struct tm *now;
leihen 7:dca20be3ef38 266 now = localtime(&t);
leihen 7:dca20be3ef38 267
leihen 7:dca20be3ef38 268 tim.sec = now->tm_sec;
leihen 7:dca20be3ef38 269 tim.min = now->tm_min;
leihen 7:dca20be3ef38 270 tim.hour = now->tm_hour;
leihen 7:dca20be3ef38 271 tim.date = now->tm_mday;
leihen 8:d0e66fa78e79 272 tim.mon = now->tm_mon+1;
leihen 7:dca20be3ef38 273 tim.year = now->tm_year + 1900;
leihen 7:dca20be3ef38 274 tim.wday = now->tm_wday +1;
leihen 7:dca20be3ef38 275
leihen 7:dca20be3ef38 276 setTime( tim, true, true);
leihen 8:d0e66fa78e79 277 set_time(t);
leihen 7:dca20be3ef38 278 }