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