Working Version of the Real Time Clock module DS1307.

Fork of RTC-DS1307 by Henry Leinen

Committer:
leihen
Date:
Wed Jun 05 20:42:37 2013 +0000
Revision:
2:ee81f2c5a706
Parent:
1:64274190e842
Child:
3:e89d63f3342e
Fully working Version.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
leihen 0:3940f0ad2ca5 1 /* Rtc_Ds1307.cpp */
leihen 0:3940f0ad2ca5 2
leihen 0:3940f0ad2ca5 3 #include "Rtc_Ds1307.h"
leihen 0:3940f0ad2ca5 4
leihen 1:64274190e842 5 #define _DEBUG 1
leihen 0:3940f0ad2ca5 6
leihen 0:3940f0ad2ca5 7
leihen 0:3940f0ad2ca5 8 #if (_DEBUG && !defined(TARGET_LPC11U24))
leihen 0:3940f0ad2ca5 9 #define INFO(x, ...) std::printf("[Rtc_Ds1307 : INFO]"x"\r\n", ##__VA_ARGS__);
leihen 0:3940f0ad2ca5 10 #define WARN(x, ...) std::printf("[Rtc_Ds1307 : WARN]"x"\r\n", ##__VA_ARGS__);
leihen 0:3940f0ad2ca5 11 #define ERR(x, ...) std::printf("[Rtc_Ds1307 : ERR]"x"\r\n", ##__VA_ARGS__);
leihen 0:3940f0ad2ca5 12 #else
leihen 0:3940f0ad2ca5 13 #define INFO(x, ...)
leihen 0:3940f0ad2ca5 14 #define WARN(x, ...)
leihen 0:3940f0ad2ca5 15 #define ERR(x, ...)
leihen 0:3940f0ad2ca5 16 #endif
leihen 0:3940f0ad2ca5 17
leihen 1:64274190e842 18 const char *Rtc_Ds1307::m_weekDays[] = { "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
leihen 0:3940f0ad2ca5 19
leihen 0:3940f0ad2ca5 20
leihen 0:3940f0ad2ca5 21 Rtc_Ds1307::Rtc_Ds1307(PinName sda, PinName scl)
leihen 0:3940f0ad2ca5 22 {
leihen 0:3940f0ad2ca5 23 // Create a new I2C object
leihen 0:3940f0ad2ca5 24 m_rtc = new I2C(sda, scl);
leihen 0:3940f0ad2ca5 25 if (m_rtc == NULL)
leihen 0:3940f0ad2ca5 26 error("Rtc_Ds1307");
leihen 1:64274190e842 27
leihen 1:64274190e842 28 // Set the frequency to standard 100kHz
leihen 1:64274190e842 29 m_rtc->frequency(100000);
leihen 0:3940f0ad2ca5 30 }
leihen 0:3940f0ad2ca5 31
leihen 0:3940f0ad2ca5 32 Rtc_Ds1307::~Rtc_Ds1307()
leihen 0:3940f0ad2ca5 33 {
leihen 0:3940f0ad2ca5 34 if (m_rtc != NULL)
leihen 0:3940f0ad2ca5 35 delete m_rtc;
leihen 0:3940f0ad2ca5 36 }
leihen 0:3940f0ad2ca5 37
leihen 1:64274190e842 38 bool Rtc_Ds1307::setTime(Time& time, bool start, bool thm)
leihen 0:3940f0ad2ca5 39 {
leihen 2:ee81f2c5a706 40 char buffer[7];
leihen 2:ee81f2c5a706 41 INFO("reading clock registers to write the new time : %d:%d:%d\n", time.hour, time.min, time.sec);
leihen 2:ee81f2c5a706 42 if (!read(0,buffer,7)) {
leihen 2:ee81f2c5a706 43 ERR("Failed to read from RTC\n");
leihen 2:ee81f2c5a706 44 return false;
leihen 2:ee81f2c5a706 45 }
leihen 2:ee81f2c5a706 46 // Now update only the time part (saving the existing flags)
leihen 2:ee81f2c5a706 47 if (start) { buffer[0] &= 0x7F; } else { buffer[0] |= 0x80; }
leihen 2:ee81f2c5a706 48 buffer[0] = (buffer[0]&0x80) | (decimalToBcd(time.sec)& 0x7f);
leihen 2:ee81f2c5a706 49 buffer[1] = decimalToBcd(time.min);
leihen 2:ee81f2c5a706 50 if (thm) {
leihen 2:ee81f2c5a706 51 // AM PM format
leihen 2:ee81f2c5a706 52 buffer[2] = (buffer[2]& 196) | (time.hour>12 ? (0x20 | ((decimalToBcd(time.hour-12)))) : decimalToBcd(time.hour));
leihen 2:ee81f2c5a706 53 }
leihen 2:ee81f2c5a706 54 else {
leihen 2:ee81f2c5a706 55 // 24 hours format
leihen 2:ee81f2c5a706 56 buffer[2] = (buffer[2]& 196) | (decimalToBcd(time.hour) & 0x3F);
leihen 2:ee81f2c5a706 57 }
leihen 2:ee81f2c5a706 58 buffer[3] = time.wday;
leihen 2:ee81f2c5a706 59 buffer[4] = decimalToBcd(time.date);
leihen 2:ee81f2c5a706 60 buffer[5] = decimalToBcd(time.mon);
leihen 2:ee81f2c5a706 61 buffer[6] = decimalToBcd(time.year-2000);
leihen 2:ee81f2c5a706 62 INFO("Writing new time and date data to RTC\n");
leihen 2:ee81f2c5a706 63 if (!write(0, buffer, 7) ) {
leihen 2:ee81f2c5a706 64 ERR("Failed to write the data to RTC!\n");
leihen 2:ee81f2c5a706 65 return false;
leihen 2:ee81f2c5a706 66 }
leihen 0:3940f0ad2ca5 67 return true;
leihen 0:3940f0ad2ca5 68 }
leihen 0:3940f0ad2ca5 69
leihen 1:64274190e842 70 bool Rtc_Ds1307::getTime(Time& time)
leihen 0:3940f0ad2ca5 71 {
leihen 1:64274190e842 72 char buffer[7];
leihen 1:64274190e842 73 bool thm = false;
leihen 1:64274190e842 74
leihen 1:64274190e842 75 INFO("Getting time from RTC\n");
leihen 2:ee81f2c5a706 76 if (!read(0, buffer, 7) ) {
leihen 1:64274190e842 77 // Failed to read
leihen 1:64274190e842 78 ERR("Failed to read from RTC\n");
leihen 1:64274190e842 79 return false;
leihen 1:64274190e842 80 }
leihen 1:64274190e842 81 thm = ((buffer[2] & 64) == 64);
leihen 1:64274190e842 82 time.sec = bcdToDecimal(buffer[0]&0x7F);
leihen 1:64274190e842 83 time.min = bcdToDecimal(buffer[1]);
leihen 1:64274190e842 84 if (thm) {
leihen 1:64274190e842 85 // in 12-hour-mode, we need to add 12 hours if PM bit is set
leihen 1:64274190e842 86 time.hour = Rtc_Ds1307::bcdToDecimal( buffer[2] & 31 );
leihen 1:64274190e842 87 if ((buffer[2] & 32) == 32)
leihen 1:64274190e842 88 time.hour += 12;
leihen 1:64274190e842 89 }
leihen 1:64274190e842 90 else {
leihen 1:64274190e842 91 time.hour = Rtc_Ds1307::bcdToDecimal( buffer[2] & 63 );
leihen 1:64274190e842 92 }
leihen 1:64274190e842 93 time.wday = buffer[3];
leihen 1:64274190e842 94 time.date = Rtc_Ds1307::bcdToDecimal( buffer[4]);
leihen 1:64274190e842 95 time.mon = Rtc_Ds1307::bcdToDecimal( buffer[5]);
leihen 2:ee81f2c5a706 96 time.year = Rtc_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
leihen 2:ee81f2c5a706 97
leihen 2:ee81f2c5a706 98 return true;
leihen 2:ee81f2c5a706 99 }
leihen 2:ee81f2c5a706 100
leihen 2:ee81f2c5a706 101
leihen 2:ee81f2c5a706 102 bool Rtc_Ds1307::startClock()
leihen 2:ee81f2c5a706 103 {
leihen 2:ee81f2c5a706 104 char strtStop;
leihen 2:ee81f2c5a706 105
leihen 2:ee81f2c5a706 106 INFO ("Reading clock start/stop register value\n");
leihen 2:ee81f2c5a706 107 if (!read(0, &strtStop, 1)) {
leihen 2:ee81f2c5a706 108 ERR("Failed to read clock start stop register !\n");
leihen 2:ee81f2c5a706 109 return false;
leihen 2:ee81f2c5a706 110 }
leihen 2:ee81f2c5a706 111
leihen 2:ee81f2c5a706 112 strtStop &= 0x7F;
leihen 2:ee81f2c5a706 113
leihen 2:ee81f2c5a706 114 INFO("Writing back start/stop register value\n");
leihen 2:ee81f2c5a706 115 if (!write(0, &strtStop, 1)) {
leihen 2:ee81f2c5a706 116 ERR("Failed to write the start stop register !\n");
leihen 2:ee81f2c5a706 117 return false;
leihen 2:ee81f2c5a706 118 }
leihen 2:ee81f2c5a706 119
leihen 2:ee81f2c5a706 120 INFO("Start/stop register value successfully written\n");
leihen 2:ee81f2c5a706 121 return true;
leihen 2:ee81f2c5a706 122 }
leihen 2:ee81f2c5a706 123
leihen 2:ee81f2c5a706 124 bool Rtc_Ds1307::stopClock()
leihen 2:ee81f2c5a706 125 {
leihen 2:ee81f2c5a706 126 char strtStop;
leihen 2:ee81f2c5a706 127
leihen 2:ee81f2c5a706 128 INFO ("Reading clock start/stop register value\n");
leihen 2:ee81f2c5a706 129 if (!read(0, &strtStop, 1)) {
leihen 2:ee81f2c5a706 130 ERR("Failed to read clock start stop register !\n");
leihen 2:ee81f2c5a706 131 return false;
leihen 2:ee81f2c5a706 132 }
leihen 1:64274190e842 133
leihen 2:ee81f2c5a706 134 strtStop |= 0x80;
leihen 2:ee81f2c5a706 135
leihen 2:ee81f2c5a706 136 INFO("Writing back start/stop register value\n");
leihen 2:ee81f2c5a706 137 if (!write(0, &strtStop, 1)) {
leihen 2:ee81f2c5a706 138 ERR("Failed to write the start stop register !\n");
leihen 2:ee81f2c5a706 139 return false;
leihen 2:ee81f2c5a706 140 }
leihen 2:ee81f2c5a706 141
leihen 2:ee81f2c5a706 142 INFO("Start/stop register value successfully written\n");
leihen 2:ee81f2c5a706 143 return true;
leihen 0:3940f0ad2ca5 144 }
leihen 1:64274190e842 145
leihen 2:ee81f2c5a706 146 bool Rtc_Ds1307::setSquareWaveOutput(bool ena, RateSelect_t rs)
leihen 2:ee81f2c5a706 147 {
leihen 2:ee81f2c5a706 148 char reg;
leihen 2:ee81f2c5a706 149 INFO("Reading register value first\n");
leihen 2:ee81f2c5a706 150
leihen 2:ee81f2c5a706 151 if (!read(7,&reg, 1)) {
leihen 2:ee81f2c5a706 152 ERR("Failed to read register value !\n");
leihen 2:ee81f2c5a706 153 return false;
leihen 2:ee81f2c5a706 154 }
leihen 2:ee81f2c5a706 155 INFO("[Reg:0x07] = %02x\n", reg);
leihen 2:ee81f2c5a706 156
leihen 2:ee81f2c5a706 157 // preserve the OUT control bit while writing the frequency and enable bits
leihen 2:ee81f2c5a706 158 reg = (reg & 0x80) | (ena ? 0x10 : 0) | ((char)rs & 0x03);
leihen 2:ee81f2c5a706 159
leihen 2:ee81f2c5a706 160 INFO("Writing back register value\n");
leihen 2:ee81f2c5a706 161 INFO("[Reg:0x07] = %02x\n", reg);
leihen 2:ee81f2c5a706 162
leihen 2:ee81f2c5a706 163 if (!write(7, &reg, 1)) {
leihen 2:ee81f2c5a706 164 ERR("Failed to write register value !\n");
leihen 2:ee81f2c5a706 165 return false;
leihen 2:ee81f2c5a706 166 }
leihen 2:ee81f2c5a706 167
leihen 2:ee81f2c5a706 168 INFO("Successfully changed the square wave output.\n");
leihen 2:ee81f2c5a706 169 return true;
leihen 2:ee81f2c5a706 170 }
leihen 2:ee81f2c5a706 171
leihen 2:ee81f2c5a706 172
leihen 1:64274190e842 173
leihen 1:64274190e842 174 bool Rtc_Ds1307::read(int address, char *buffer, int len)
leihen 1:64274190e842 175 {
leihen 1:64274190e842 176 char buffer2[2] = {(char)address, 0};
leihen 1:64274190e842 177
leihen 2:ee81f2c5a706 178 // m_rtc->start();
leihen 1:64274190e842 179 if (m_rtc->write(0xd0, buffer2, 1) != 0) {
leihen 1:64274190e842 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) {
leihen 1:64274190e842 185 ERR("Failed to read register !\n");
leihen 1:64274190e842 186 return false;
leihen 1:64274190e842 187 }
leihen 1:64274190e842 188 m_rtc->stop();
leihen 1:64274190e842 189
leihen 1:64274190e842 190 INFO("Successfully read %d registers from RTC\n", len);
leihen 1:64274190e842 191 return true;
leihen 1:64274190e842 192 }
leihen 1:64274190e842 193
leihen 1:64274190e842 194 bool Rtc_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
leihen 2:ee81f2c5a706 201 // m_rtc->start();
leihen 1:64274190e842 202 if (m_rtc->write(0xd0, buffer2, len+1) != 0) {
leihen 1:64274190e842 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 1:64274190e842 209 }