a copy of PCF8583_rtc lib with some modification
Fork of PCF8583_rtc by
PCF8583_rtc.cpp@3:c267167e379e, 2016-10-19 (annotated)
- Committer:
- pedro_C
- Date:
- Wed Oct 19 10:26:18 2016 +0000
- Revision:
- 3:c267167e379e
- Parent:
- 2:3291c1f0b986
my test
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dennyem | 1:eaba89d6e5d8 | 1 | /* |
dennyem | 0:7b654820260e | 2 | ******************************************************************************** |
dennyem | 0:7b654820260e | 3 | * An mbed class to control the PCF8583 Real time Clock/Calender |
dennyem | 0:7b654820260e | 4 | * Copyright (c) 2014 Dennis (Denny) Smith - dennyem |
dennyem | 0:7b654820260e | 5 | * |
dennyem | 0:7b654820260e | 6 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
dennyem | 0:7b654820260e | 7 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
dennyem | 0:7b654820260e | 8 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
dennyem | 0:7b654820260e | 9 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
dennyem | 0:7b654820260e | 10 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
dennyem | 0:7b654820260e | 11 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
dennyem | 0:7b654820260e | 12 | * THE SOFTWARE. |
dennyem | 0:7b654820260e | 13 | * |
dennyem | 1:eaba89d6e5d8 | 14 | * 13.01.14 DWS initial design for PIC devices using PICC compiler |
dennyem | 1:eaba89d6e5d8 | 15 | * 21.01.14 DWS ported to mBed LPC1768 in 'C' |
dennyem | 1:eaba89d6e5d8 | 16 | * 09.02.14 DWS converted to C++ and ported to mBed LPC812 |
dennyem | 0:7b654820260e | 17 | * |
dennyem | 0:7b654820260e | 18 | * TODO |
dennyem | 0:7b654820260e | 19 | * FormatDateTime needs am/pm, 12/24 hour parsing |
dennyem | 0:7b654820260e | 20 | * Alarm functions not yet implemented |
dennyem | 0:7b654820260e | 21 | */ |
dennyem | 0:7b654820260e | 22 | |
dennyem | 0:7b654820260e | 23 | #include <mbed.h> |
dennyem | 0:7b654820260e | 24 | #include <PCF8583_rtc.h> |
dennyem | 0:7b654820260e | 25 | |
dennyem | 0:7b654820260e | 26 | //----------------------------------------------------------------------------- |
dennyem | 0:7b654820260e | 27 | // constructor -- accepts an I2c object to use for connection with the rtc |
dennyem | 0:7b654820260e | 28 | PCF8583rtc::PCF8583rtc(I2C *i2c, char I2cAddress) |
dennyem | 0:7b654820260e | 29 | { |
dennyem | 0:7b654820260e | 30 | _i2c = i2c; |
dennyem | 0:7b654820260e | 31 | _I2cAddress = I2cAddress; |
dennyem | 0:7b654820260e | 32 | |
dennyem | 0:7b654820260e | 33 | ShortDateFormat = "d,m,yy"; |
dennyem | 0:7b654820260e | 34 | LongDateFormat = "dddd dd mmmm yyyy"; |
dennyem | 0:7b654820260e | 35 | ShortTimeFormat = "d:m:yy"; |
dennyem | 0:7b654820260e | 36 | LongTimeFormat = "dd:nn:yyyy"; |
dennyem | 0:7b654820260e | 37 | |
dennyem | 0:7b654820260e | 38 | DateSeparator = '/'; |
dennyem | 0:7b654820260e | 39 | TimeSeparator = ':'; |
dennyem | 0:7b654820260e | 40 | |
dennyem | 0:7b654820260e | 41 | ShortDayNames[0] = "Mon"; |
dennyem | 0:7b654820260e | 42 | ShortDayNames[1] = "Tue"; |
dennyem | 0:7b654820260e | 43 | ShortDayNames[2] = "Wed"; |
dennyem | 0:7b654820260e | 44 | ShortDayNames[3] = "Thu"; |
dennyem | 0:7b654820260e | 45 | ShortDayNames[4] = "Fri"; |
dennyem | 0:7b654820260e | 46 | ShortDayNames[5] = "Sat"; |
dennyem | 0:7b654820260e | 47 | ShortDayNames[6] = "Sun"; |
dennyem | 0:7b654820260e | 48 | |
dennyem | 0:7b654820260e | 49 | LongDayNames[0] = "Monday"; |
dennyem | 0:7b654820260e | 50 | LongDayNames[1] = "Tuesday"; |
dennyem | 0:7b654820260e | 51 | LongDayNames[2] = "Wednesday"; |
dennyem | 0:7b654820260e | 52 | LongDayNames[3] = "Thursday"; |
dennyem | 0:7b654820260e | 53 | LongDayNames[4] = "Friday"; |
dennyem | 0:7b654820260e | 54 | LongDayNames[5] = "Saturday"; |
dennyem | 0:7b654820260e | 55 | LongDayNames[6] = "Sunday"; |
dennyem | 0:7b654820260e | 56 | |
dennyem | 0:7b654820260e | 57 | ShortMonthNames[0] = "Jan"; |
dennyem | 0:7b654820260e | 58 | ShortMonthNames[1] = "Feb"; |
dennyem | 0:7b654820260e | 59 | ShortMonthNames[2] = "Mar"; |
dennyem | 0:7b654820260e | 60 | ShortMonthNames[3] = "Apr"; |
dennyem | 0:7b654820260e | 61 | ShortMonthNames[4] = "May"; |
dennyem | 0:7b654820260e | 62 | ShortMonthNames[5] = "Jun"; |
dennyem | 0:7b654820260e | 63 | ShortMonthNames[6] = "Jul"; |
dennyem | 0:7b654820260e | 64 | ShortMonthNames[7] = "Aug"; |
dennyem | 0:7b654820260e | 65 | ShortMonthNames[8] = "Sep"; |
dennyem | 0:7b654820260e | 66 | ShortMonthNames[9] = "Oct"; |
dennyem | 0:7b654820260e | 67 | ShortMonthNames[10] = "Nov"; |
dennyem | 0:7b654820260e | 68 | ShortMonthNames[11] = "Dec"; |
dennyem | 0:7b654820260e | 69 | |
dennyem | 0:7b654820260e | 70 | LongMonthNames[0] = "January"; |
dennyem | 0:7b654820260e | 71 | LongMonthNames[1] = "February"; |
dennyem | 0:7b654820260e | 72 | LongMonthNames[2] = "March"; |
dennyem | 0:7b654820260e | 73 | LongMonthNames[3] = "April"; |
dennyem | 0:7b654820260e | 74 | LongMonthNames[4] = "May"; |
dennyem | 0:7b654820260e | 75 | LongMonthNames[5] = "June"; |
dennyem | 0:7b654820260e | 76 | LongMonthNames[6] = "July"; |
dennyem | 0:7b654820260e | 77 | LongMonthNames[7] = "August"; |
dennyem | 0:7b654820260e | 78 | LongMonthNames[8] = "September"; |
dennyem | 0:7b654820260e | 79 | LongMonthNames[9] = "October"; |
dennyem | 0:7b654820260e | 80 | LongMonthNames[10] = "November"; |
dennyem | 0:7b654820260e | 81 | LongMonthNames[11] = "December"; |
dennyem | 0:7b654820260e | 82 | }; |
dennyem | 0:7b654820260e | 83 | |
dennyem | 0:7b654820260e | 84 | void PCF8583rtc::write(const char address, struct DateTime_t dti) |
dennyem | 0:7b654820260e | 85 | { |
dennyem | 0:7b654820260e | 86 | char tmp[8]; |
dennyem | 0:7b654820260e | 87 | |
dennyem | 0:7b654820260e | 88 | pauseCounting(); //Must stop counting before initialising Date/time |
dennyem | 0:7b654820260e | 89 | |
dennyem | 0:7b654820260e | 90 | tmp[0] = address; // Address is 1 for Time or 10 for Alarm |
dennyem | 0:7b654820260e | 91 | |
dennyem | 0:7b654820260e | 92 | //Values must be in BCD form |
dennyem | 0:7b654820260e | 93 | tmp[1] = dti.time.hundreds; // Hundredths of a second |
dennyem | 0:7b654820260e | 94 | tmp[2] = dti.time.seconds; // Seconds |
dennyem | 0:7b654820260e | 95 | tmp[3] = dti.time.minutes; // Minutes |
dennyem | 0:7b654820260e | 96 | tmp[4] = dti.time.hours; // Hours |
dennyem | 0:7b654820260e | 97 | tmp[5] = dti.date.day & 0x3F; // Always set the 3 year bits to 0 |
dennyem | 0:7b654820260e | 98 | |
dennyem | 0:7b654820260e | 99 | if(address == TIME) |
dennyem | 0:7b654820260e | 100 | tmp[6] = (((dti.date.weekday & 7) << 5 ) | dti.date.month); // Weekday/month |
dennyem | 0:7b654820260e | 101 | else |
dennyem | 0:7b654820260e | 102 | tmp[6] = dti.date.month & 0x1f; // No Weekday for alarm |
dennyem | 0:7b654820260e | 103 | |
dennyem | 0:7b654820260e | 104 | _i2c->write(_I2cAddress, tmp, 7); // Address PCF8583, see PCF8583 datasheet |
dennyem | 0:7b654820260e | 105 | _i2c->stop(); |
dennyem | 0:7b654820260e | 106 | |
dennyem | 0:7b654820260e | 107 | if(address == TIME) { |
dennyem | 0:7b654820260e | 108 | writeByte(CENTURY_REG, dti.date.century); // Store the full 4 digit year in NV Ram |
dennyem | 0:7b654820260e | 109 | writeByte(YEAR_REG, dti.date.year); |
dennyem | 0:7b654820260e | 110 | }; |
dennyem | 0:7b654820260e | 111 | |
dennyem | 0:7b654820260e | 112 | enableCounting(); |
dennyem | 0:7b654820260e | 113 | }; |
dennyem | 0:7b654820260e | 114 | |
dennyem | 0:7b654820260e | 115 | //--------------------- Reads time and date information from RTC (PCF8583) |
dennyem | 0:7b654820260e | 116 | struct DateTime_t PCF8583rtc::read(const char address) |
dennyem | 0:7b654820260e | 117 | { |
dennyem | 0:7b654820260e | 118 | char tmp[8]; |
dennyem | 0:7b654820260e | 119 | char year_bits = 0; // To test for year change |
dennyem | 0:7b654820260e | 120 | |
dennyem | 0:7b654820260e | 121 | tmp[0] = address; |
dennyem | 0:7b654820260e | 122 | _i2c->write(_I2cAddress, tmp, 1); // Address PCF8583, see PCF8583 datasheet |
dennyem | 0:7b654820260e | 123 | _i2c->read(_I2cAddress | 1, tmp, 6); // Address PCF8583 for reading R/W=1 |
dennyem | 0:7b654820260e | 124 | _i2c->stop(); |
dennyem | 0:7b654820260e | 125 | |
dennyem | 0:7b654820260e | 126 | dt.time.hundreds = tmp[0]; |
dennyem | 0:7b654820260e | 127 | dt.time.seconds = tmp[1]; |
dennyem | 0:7b654820260e | 128 | dt.time.minutes = tmp[2]; |
dennyem | 0:7b654820260e | 129 | dt.time.hours = tmp[3] & 0x3F; |
dennyem | 0:7b654820260e | 130 | dt.time.fmt_hours = tmp[3] & 0x80; // 12/24 hour format |
dennyem | 0:7b654820260e | 131 | dt.time.am_pm_flag = tmp[3] & 0x40; // Am/Pm flag |
dennyem | 0:7b654820260e | 132 | dt.date.day = tmp[4] & 0x3F; // Day of the Month |
dennyem | 0:7b654820260e | 133 | dt.date.month = tmp[5] & 0x1F; |
dennyem | 0:7b654820260e | 134 | |
dennyem | 0:7b654820260e | 135 | if(address == TIME) |
dennyem | 0:7b654820260e | 136 | year_bits = (tmp[4] & 0xC0) >> 6; |
dennyem | 0:7b654820260e | 137 | else |
dennyem | 0:7b654820260e | 138 | dt.date.year = 0; // No year for alarm |
dennyem | 0:7b654820260e | 139 | |
dennyem | 0:7b654820260e | 140 | |
dennyem | 0:7b654820260e | 141 | if(address == TIME) |
dennyem | 0:7b654820260e | 142 | dt.date.weekday = tmp[5] >> 5; |
dennyem | 0:7b654820260e | 143 | else |
dennyem | 0:7b654820260e | 144 | dt.date.weekday = 0; // No weekday for alarm |
dennyem | 0:7b654820260e | 145 | |
dennyem | 0:7b654820260e | 146 | if(address == TIME) { |
dennyem | 0:7b654820260e | 147 | tmp[0] = readByte(CENTURY_REG); |
dennyem | 0:7b654820260e | 148 | dt.date.century = ((tmp[0] & 0xF0) >> 4) * 10 + (tmp[0] & 0x0F); |
dennyem | 0:7b654820260e | 149 | tmp[0] = readByte(YEAR_REG); |
dennyem | 0:7b654820260e | 150 | dt.date.year = ((tmp[0] & 0xF0) >> 4) * 10 + (tmp[0] & 0x0F); |
dennyem | 0:7b654820260e | 151 | |
dennyem | 0:7b654820260e | 152 | if(year_bits > 0) { // Midnight on new years eve? |
dennyem | 0:7b654820260e | 153 | dt.date.year += 1; // Increment the year |
dennyem | 0:7b654820260e | 154 | writeByte(YEAR_REG, dt.date.year); // Save the new year value to NV Ram |
dennyem | 0:7b654820260e | 155 | writeByte(5, dt.date.day & 0x3F); // Clear the year bits but preserve the date |
dennyem | 0:7b654820260e | 156 | } |
dennyem | 0:7b654820260e | 157 | } |
dennyem | 0:7b654820260e | 158 | |
dennyem | 0:7b654820260e | 159 | return dt; |
dennyem | 0:7b654820260e | 160 | }; |
dennyem | 0:7b654820260e | 161 | |
dennyem | 0:7b654820260e | 162 | void PCF8583rtc::FormatDateTime(char *dest, char *f) |
dennyem | 0:7b654820260e | 163 | { |
dennyem | 0:7b654820260e | 164 | int i; |
dennyem | 0:7b654820260e | 165 | |
dennyem | 0:7b654820260e | 166 | if(f != 0 && *f != 0) { //If the format param is empty then do a default 'c' |
dennyem | 0:7b654820260e | 167 | while(*f != 0) { //expect null terminated string (we hope) |
dennyem | 0:7b654820260e | 168 | switch(*f) { |
dennyem | 0:7b654820260e | 169 | case 'c': |
dennyem | 0:7b654820260e | 170 | break; |
dennyem | 0:7b654820260e | 171 | case 'd': |
dennyem | 0:7b654820260e | 172 | if(*(f+1) != 'd') { //'d' - Day with no leading zero |
dennyem | 0:7b654820260e | 173 | dest += Bcd2Char(dest, dt.date.day, false); |
dennyem | 0:7b654820260e | 174 | } else { |
dennyem | 0:7b654820260e | 175 | f++; |
dennyem | 0:7b654820260e | 176 | if(*(f+1) != 'd') //'dd' - Day with leading zero |
dennyem | 0:7b654820260e | 177 | dest += Bcd2Char(dest, dt.date.day, true); |
dennyem | 0:7b654820260e | 178 | else { |
dennyem | 0:7b654820260e | 179 | f++; |
dennyem | 0:7b654820260e | 180 | if(*(f+1) != 'd') { //'ddd' - Short day name |
dennyem | 0:7b654820260e | 181 | i = 0; |
dennyem | 0:7b654820260e | 182 | while(ShortDayNames[dt.date.weekday][i] != 0) |
dennyem | 0:7b654820260e | 183 | *dest++ = ShortDayNames[dt.date.weekday][i++]; |
dennyem | 0:7b654820260e | 184 | } else { |
dennyem | 0:7b654820260e | 185 | f++; |
dennyem | 0:7b654820260e | 186 | i = 0; |
dennyem | 0:7b654820260e | 187 | while(LongDayNames[dt.date.weekday][i] != 0) |
dennyem | 0:7b654820260e | 188 | *dest++ = LongDayNames[dt.date.weekday][i++]; |
dennyem | 0:7b654820260e | 189 | } |
dennyem | 0:7b654820260e | 190 | } |
dennyem | 0:7b654820260e | 191 | } |
dennyem | 0:7b654820260e | 192 | break; |
dennyem | 0:7b654820260e | 193 | case 'm': |
dennyem | 0:7b654820260e | 194 | if(*(f+1) != 'm') { //'m' - Month with no leading zero |
dennyem | 0:7b654820260e | 195 | dest += Bcd2Char(dest, dt.date.month, false); |
dennyem | 0:7b654820260e | 196 | } else { |
dennyem | 0:7b654820260e | 197 | f++; |
dennyem | 0:7b654820260e | 198 | if(*(f+1) != 'm') //'mm' - Month with leading zero |
dennyem | 0:7b654820260e | 199 | dest += Bcd2Char(dest, dt.date.month, true); |
dennyem | 0:7b654820260e | 200 | else { |
dennyem | 0:7b654820260e | 201 | f++; |
dennyem | 0:7b654820260e | 202 | if(*(f+1) != 'm') { //'mmm' - Short month name |
dennyem | 0:7b654820260e | 203 | i = 0; |
dennyem | 0:7b654820260e | 204 | while(ShortMonthNames[dt.date.month - 1][i] != 0) |
dennyem | 0:7b654820260e | 205 | *dest++ = ShortMonthNames[dt.date.month - 1][i++]; |
dennyem | 0:7b654820260e | 206 | } else { |
dennyem | 0:7b654820260e | 207 | f++; |
dennyem | 0:7b654820260e | 208 | i = 0; |
dennyem | 0:7b654820260e | 209 | while(LongMonthNames[dt.date.month - 1][i] != 0) |
dennyem | 0:7b654820260e | 210 | *dest++ = LongMonthNames[dt.date.month - 1][i++]; |
dennyem | 0:7b654820260e | 211 | } |
dennyem | 0:7b654820260e | 212 | } |
dennyem | 0:7b654820260e | 213 | } |
dennyem | 0:7b654820260e | 214 | break; |
dennyem | 0:7b654820260e | 215 | case 'y': |
dennyem | 0:7b654820260e | 216 | if(*(f+1) == 'y') { |
dennyem | 0:7b654820260e | 217 | f++; //We have at least a 'yy' |
dennyem | 0:7b654820260e | 218 | if(*(f+1) == 'y' && *(f+2) == 'y') { //'yyyy' - 4 digit year |
dennyem | 0:7b654820260e | 219 | dest += Bcd2Char(dest, dt.date.century, true); |
dennyem | 0:7b654820260e | 220 | f += 2; |
dennyem | 0:7b654820260e | 221 | } |
dennyem | 0:7b654820260e | 222 | dest += Bcd2Char(dest, dt.date.year, true); |
dennyem | 0:7b654820260e | 223 | } |
dennyem | 0:7b654820260e | 224 | break; |
dennyem | 0:7b654820260e | 225 | case 'h': |
dennyem | 0:7b654820260e | 226 | if(*(f+1) != 'h') { //'h' - Hour with no leading zero |
dennyem | 0:7b654820260e | 227 | dest += Bcd2Char(dest, dt.time.hours, false); |
dennyem | 0:7b654820260e | 228 | } else { |
dennyem | 0:7b654820260e | 229 | f++; |
dennyem | 0:7b654820260e | 230 | dest += Bcd2Char(dest, dt.time.hours, true); |
dennyem | 0:7b654820260e | 231 | } |
dennyem | 0:7b654820260e | 232 | break; |
dennyem | 0:7b654820260e | 233 | case 'n': |
dennyem | 0:7b654820260e | 234 | if(*(f+1) != 'n') { //'m' - Minutes with no leading zero |
dennyem | 0:7b654820260e | 235 | dest += Bcd2Char(dest, dt.time.minutes, false); |
dennyem | 0:7b654820260e | 236 | } else { |
dennyem | 0:7b654820260e | 237 | f++; |
dennyem | 0:7b654820260e | 238 | dest += Bcd2Char(dest, dt.time.minutes, true); |
dennyem | 0:7b654820260e | 239 | } |
dennyem | 0:7b654820260e | 240 | break; |
dennyem | 0:7b654820260e | 241 | case 's': |
dennyem | 0:7b654820260e | 242 | if(*(f+1) != 's') { //'s' - Seconds with no leading zero |
dennyem | 0:7b654820260e | 243 | dest += Bcd2Char(dest, dt.time.seconds, false); |
dennyem | 0:7b654820260e | 244 | } else { |
dennyem | 0:7b654820260e | 245 | f++; |
dennyem | 0:7b654820260e | 246 | dest += Bcd2Char(dest, dt.time.seconds, true); |
dennyem | 0:7b654820260e | 247 | } |
dennyem | 0:7b654820260e | 248 | break; |
dennyem | 0:7b654820260e | 249 | case 'z': |
dennyem | 0:7b654820260e | 250 | if(*(f+1) != 'z') { //'z' - Hundredths with no leading zero |
dennyem | 0:7b654820260e | 251 | dest += Bcd2Char(dest, dt.time.hundreds, false); |
dennyem | 0:7b654820260e | 252 | } else { |
dennyem | 0:7b654820260e | 253 | f++; |
dennyem | 0:7b654820260e | 254 | dest += Bcd2Char(dest, dt.time.hundreds, true); |
dennyem | 0:7b654820260e | 255 | } |
dennyem | 0:7b654820260e | 256 | break; |
dennyem | 0:7b654820260e | 257 | case '/': |
dennyem | 0:7b654820260e | 258 | *dest++ = DateSeparator; |
dennyem | 0:7b654820260e | 259 | break; |
dennyem | 0:7b654820260e | 260 | case ':': |
dennyem | 0:7b654820260e | 261 | *dest++ = TimeSeparator; |
dennyem | 0:7b654820260e | 262 | break; |
dennyem | 0:7b654820260e | 263 | case 39 : |
dennyem | 0:7b654820260e | 264 | while(*++f != 0 && *f != 39) *dest++ = *f; |
dennyem | 0:7b654820260e | 265 | break; //Ignore the first ' |
dennyem | 0:7b654820260e | 266 | default: |
dennyem | 0:7b654820260e | 267 | *dest++ = *f; |
dennyem | 0:7b654820260e | 268 | break; //Anything we don't recognise, return it |
dennyem | 0:7b654820260e | 269 | } |
dennyem | 0:7b654820260e | 270 | f++; |
dennyem | 0:7b654820260e | 271 | } |
dennyem | 0:7b654820260e | 272 | } |
dennyem | 0:7b654820260e | 273 | *dest = 0; //Null terminate |
dennyem | 0:7b654820260e | 274 | }; |
dennyem | 0:7b654820260e | 275 | |
dennyem | 0:7b654820260e | 276 | bool PCF8583rtc::WriteNVram(char address, char *value, char num) |
dennyem | 0:7b654820260e | 277 | { |
dennyem | 0:7b654820260e | 278 | char buf[252]; |
dennyem | 0:7b654820260e | 279 | |
dennyem | 0:7b654820260e | 280 | buf[0] = address; |
dennyem | 0:7b654820260e | 281 | memcpy(&buf[1], value, num); |
dennyem | 0:7b654820260e | 282 | |
dennyem | 0:7b654820260e | 283 | if((address < USER_REG) || (num == 0)) // dont allow overwriting first 2 bytes |
dennyem | 0:7b654820260e | 284 | return false; |
dennyem | 0:7b654820260e | 285 | |
dennyem | 0:7b654820260e | 286 | _i2c->write(_I2cAddress, buf, num + 1); // write the data |
dennyem | 0:7b654820260e | 287 | _i2c->stop(); |
dennyem | 0:7b654820260e | 288 | |
dennyem | 0:7b654820260e | 289 | return true; |
dennyem | 0:7b654820260e | 290 | }; |
dennyem | 0:7b654820260e | 291 | |
dennyem | 0:7b654820260e | 292 | bool PCF8583rtc::ReadNVram(char address, char * dest, char num) |
dennyem | 0:7b654820260e | 293 | { |
dennyem | 0:7b654820260e | 294 | char buf[2]; |
dennyem | 0:7b654820260e | 295 | |
dennyem | 0:7b654820260e | 296 | if((address < USER_REG) || (num == 0)) // dont allow overwriting first 2 user bytes |
dennyem | 0:7b654820260e | 297 | return false; |
dennyem | 0:7b654820260e | 298 | |
dennyem | 0:7b654820260e | 299 | buf[0] = address; |
dennyem | 0:7b654820260e | 300 | _i2c->write(_I2cAddress, buf, 1); // set the rom address |
dennyem | 0:7b654820260e | 301 | _i2c->read(_I2cAddress | 1, dest, num); // read the data |
dennyem | 0:7b654820260e | 302 | _i2c->stop(); |
dennyem | 0:7b654820260e | 303 | |
dennyem | 0:7b654820260e | 304 | return true; |
dennyem | 0:7b654820260e | 305 | }; |
dennyem | 0:7b654820260e | 306 | |
dennyem | 0:7b654820260e | 307 | /*****************************************************************************/ |
dennyem | 0:7b654820260e | 308 | /************************** Private Functions ********************************/ |
dennyem | 0:7b654820260e | 309 | /*****************************************************************************/ |
dennyem | 0:7b654820260e | 310 | |
dennyem | 0:7b654820260e | 311 | char PCF8583rtc::Bcd2Char(char *d, char val, char WantLeadZero) |
dennyem | 0:7b654820260e | 312 | { |
dennyem | 0:7b654820260e | 313 | char n = 0; |
dennyem | 0:7b654820260e | 314 | |
dennyem | 0:7b654820260e | 315 | if(WantLeadZero == true || (val / 10) != 0) { |
dennyem | 0:7b654820260e | 316 | *d++ = (val / 10) + 48; |
dennyem | 0:7b654820260e | 317 | n++; |
dennyem | 0:7b654820260e | 318 | } |
dennyem | 0:7b654820260e | 319 | *d = (val % 10) + 48; |
dennyem | 0:7b654820260e | 320 | return(n + 1); |
dennyem | 0:7b654820260e | 321 | } |
dennyem | 0:7b654820260e | 322 | |
dennyem | 0:7b654820260e | 323 | //---------------------------------------------- |
dennyem | 0:7b654820260e | 324 | // This function converts an 8 bit binary value to a 1 byte BCD value. |
dennyem | 0:7b654820260e | 325 | // The input range must be from 0 to 99. |
dennyem | 0:7b654820260e | 326 | char PCF8583rtc::bin2bcd(char value) |
dennyem | 0:7b654820260e | 327 | { |
dennyem | 0:7b654820260e | 328 | int tmp = 0; |
dennyem | 0:7b654820260e | 329 | |
dennyem | 0:7b654820260e | 330 | while(1) { |
dennyem | 0:7b654820260e | 331 | // Get the tens digit by doing multiple subtraction |
dennyem | 0:7b654820260e | 332 | // of 10 from the binary value. |
dennyem | 0:7b654820260e | 333 | if(value >= 10) { |
dennyem | 0:7b654820260e | 334 | value -= 10; |
dennyem | 0:7b654820260e | 335 | tmp += 0x10; |
dennyem | 0:7b654820260e | 336 | } else { // Get the ones digit by adding the remainder. |
dennyem | 0:7b654820260e | 337 | tmp += value; |
dennyem | 0:7b654820260e | 338 | break; |
dennyem | 0:7b654820260e | 339 | } |
dennyem | 0:7b654820260e | 340 | } |
dennyem | 0:7b654820260e | 341 | return tmp; |
dennyem | 0:7b654820260e | 342 | } |
dennyem | 0:7b654820260e | 343 | |
dennyem | 0:7b654820260e | 344 | void PCF8583rtc::configureControlReg(char control) |
dennyem | 0:7b654820260e | 345 | { |
dennyem | 0:7b654820260e | 346 | writeByte(0, control); |
dennyem | 0:7b654820260e | 347 | } |
dennyem | 0:7b654820260e | 348 | |
dennyem | 0:7b654820260e | 349 | void PCF8583rtc::configureAlarmReg(char alarm) |
dennyem | 0:7b654820260e | 350 | { |
dennyem | 0:7b654820260e | 351 | writeByte(0x08, alarm); |
dennyem | 0:7b654820260e | 352 | } |
dennyem | 0:7b654820260e | 353 | |
dennyem | 0:7b654820260e | 354 | void PCF8583rtc::writeByte(char address, char d) |
dennyem | 0:7b654820260e | 355 | { |
dennyem | 0:7b654820260e | 356 | char buf[2]; |
dennyem | 0:7b654820260e | 357 | |
dennyem | 0:7b654820260e | 358 | buf[0] = address; |
dennyem | 0:7b654820260e | 359 | buf[1] = d; |
dennyem | 2:3291c1f0b986 | 360 | _i2c->write(_I2cAddress, buf, 2); |
dennyem | 0:7b654820260e | 361 | _i2c->stop(); |
dennyem | 0:7b654820260e | 362 | } |
dennyem | 0:7b654820260e | 363 | |
dennyem | 0:7b654820260e | 364 | char PCF8583rtc::readByte(char address) |
dennyem | 0:7b654820260e | 365 | { |
dennyem | 0:7b654820260e | 366 | char buf[2]; |
dennyem | 0:7b654820260e | 367 | |
dennyem | 0:7b654820260e | 368 | buf[0] = address; |
dennyem | 0:7b654820260e | 369 | _i2c->write(_I2cAddress, buf, 1); |
dennyem | 0:7b654820260e | 370 | _i2c->read(_I2cAddress | 1, buf, 1); |
dennyem | 0:7b654820260e | 371 | _i2c->stop(); |
dennyem | 0:7b654820260e | 372 | |
dennyem | 0:7b654820260e | 373 | return buf[0]; |
dennyem | 0:7b654820260e | 374 | } |
dennyem | 0:7b654820260e | 375 | |
dennyem | 0:7b654820260e | 376 | void PCF8583rtc::pauseCounting() |
dennyem | 0:7b654820260e | 377 | { |
dennyem | 0:7b654820260e | 378 | char tmp; |
dennyem | 0:7b654820260e | 379 | tmp = readByte(0); |
dennyem | 0:7b654820260e | 380 | tmp = tmp | 0x80; |
dennyem | 0:7b654820260e | 381 | writeByte(0, tmp); |
dennyem | 0:7b654820260e | 382 | } |
dennyem | 0:7b654820260e | 383 | |
dennyem | 0:7b654820260e | 384 | void PCF8583rtc::enableCounting() |
dennyem | 0:7b654820260e | 385 | { |
dennyem | 0:7b654820260e | 386 | char tmp; |
dennyem | 0:7b654820260e | 387 | tmp = readByte(0); |
dennyem | 0:7b654820260e | 388 | tmp = tmp ^ 0x80; |
dennyem | 0:7b654820260e | 389 | writeByte(0, tmp); |
dennyem | 0:7b654820260e | 390 | } |