Working Version of the Real Time Clock module DS1307.
Fork of RTC-DS1307 by
Rtc_Ds1307.cpp@2:ee81f2c5a706, 2013-06-05 (annotated)
- 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?
User | Revision | Line number | New 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,®, 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, ®, 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 | } |