Dennis Smith / Mbed 2 deprecated NixieClock800Max

Dependencies:   PCF8583_rtc mbed

Revision:
1:a8b9fb95696b
Parent:
0:f09cf90def53
diff -r f09cf90def53 -r a8b9fb95696b PCF8583_rtc.cpp
--- a/PCF8583_rtc.cpp	Sun Feb 09 00:25:21 2014 +0000
+++ b/PCF8583_rtc.cpp	Thu Feb 13 21:46:08 2014 +0000
@@ -15,7 +15,6 @@
  * 09.02.14    converted to C++ and ported to mBed LPC812
  *
  * TODO
- *       write function is still to be tested
  *       WriteNVram function is still to be tested
  *       ReadNVram function is still to be tested
  *       FormatDateTime needs am/pm, 12/24 hour parsing
@@ -27,9 +26,10 @@
 
 //-----------------------------------------------------------------------------
 // constructor -- accepts an I2c object to use for connection with the rtc
-PCF8583rtc::PCF8583rtc(I2C *i2c)
+PCF8583rtc::PCF8583rtc(I2C *i2c, char I2cAddress)
 {
    _i2c = i2c;
+   _I2cAddress = I2cAddress;
       
   ShortDateFormat = "d,m,yy";
   LongDateFormat  = "dddd dd mmmm yyyy";
@@ -55,85 +55,87 @@
   LongDayNames[5]  = "Saturday";
   LongDayNames[6]  = "Sunday";
 
-  ShortMonthNames[0] = "Jan";
-  ShortMonthNames[1] = "Feb";
-  ShortMonthNames[2] = "Mar";
-  ShortMonthNames[3] = "Apr";
-  ShortMonthNames[4] = "May";
-  ShortMonthNames[5] = "Jun";
-  ShortMonthNames[6] = "Jul";
-  ShortMonthNames[7] = "Aug";
-  ShortMonthNames[8] = "Sep";
-  ShortMonthNames[9] = "Oct";
+  ShortMonthNames[0]  = "Jan";
+  ShortMonthNames[1]  = "Feb";
+  ShortMonthNames[2]  = "Mar";
+  ShortMonthNames[3]  = "Apr";
+  ShortMonthNames[4]  = "May";
+  ShortMonthNames[5]  = "Jun";
+  ShortMonthNames[6]  = "Jul";
+  ShortMonthNames[7]  = "Aug";
+  ShortMonthNames[8]  = "Sep";
+  ShortMonthNames[9]  = "Oct";
   ShortMonthNames[10] = "Nov";
   ShortMonthNames[11] = "Dec";
 
-  LongMonthNames[0]  = "January";
-  LongMonthNames[1]  = "February";
-  LongMonthNames[2]  = "March";
-  LongMonthNames[3]  = "April";
-  LongMonthNames[4]  = "May";
-  LongMonthNames[5]  = "June";
-  LongMonthNames[6]  = "July";
-  LongMonthNames[7]  = "August";
-  LongMonthNames[8]  = "September";
-  LongMonthNames[9]  = "October";
+  LongMonthNames[0]   = "January";
+  LongMonthNames[1]   = "February";
+  LongMonthNames[2]   = "March";
+  LongMonthNames[3]   = "April";
+  LongMonthNames[4]   = "May";
+  LongMonthNames[5]   = "June";
+  LongMonthNames[6]   = "July";
+  LongMonthNames[7]   = "August";
+  LongMonthNames[8]   = "September";
+  LongMonthNames[9]   = "October";
   LongMonthNames[10]  = "November";
   LongMonthNames[11]  = "December";
 };
 
-void PCF8583rtc::write(const char address)
+void PCF8583rtc::write(const char address, struct DateTime_t dti)
 {
+    char tmp[8];
+
     pauseCounting();    //Must stop counting before initialising Date/time
 
-    _i2c->start();                                                 // Issue start signal
-    _i2c->write(Write_addr);                                       // Address PCF8583, see PCF8583 datasheet
-    _i2c->write(address);                                          // Address is 1 for Time or 10 for Alarm
-    _i2c->write(dt.time.hundreds);                                 // Hundredths of a second
-    _i2c->write(dt.time.seconds);                                  // Seconds
-    _i2c->write(dt.time.minutes);                                  // Minutes
-    _i2c->write(dt.time.hours);                                    // Hours
-    _i2c->write(dt.date.day & 0x3F);                               // Always set the 3 year bits to 0
+    tmp[0] = address;                                               // Address is 1 for Time or 10 for Alarm
+    
+    //Values must be in BCD form
+    tmp[1] = dti.time.hundreds;                                     // Hundredths of a second
+    tmp[2] = dti.time.seconds;                                      // Seconds
+    tmp[3] = dti.time.minutes;                                      // Minutes
+    tmp[4] = dti.time.hours;                                        // Hours
+    tmp[5] = dti.date.day & 0x3F;                                   // Always set the 3 year bits to 0
 
     if(address == TIME)
-        _i2c->write(((dt.date.weekday & 7) << 5 )| dt.date.month); // Weekday/month
+        tmp[6] = (((dti.date.weekday & 7) << 5 ) | dti.date.month); // Weekday/month
     else
-        _i2c->write(dt.date.month & 0x1f);                         // No Weekday for alarm
+        tmp[6] = dti.date.month & 0x1f;                             // No Weekday for alarm
 
-    _i2c->stop();                                                  // Issue stop signal
+    _i2c->write(_I2cAddress, tmp, 7);                              // Address PCF8583, see PCF8583 datasheet
 
     if(address == TIME) {
-        writeByte(CENTURY_REG, dt.date.century);                 // Store the full 4 digit year in NV Ram
-        writeByte(YEAR_REG, dt.date.year);
+        writeByte(CENTURY_REG, dti.date.century);                   // Store the full 4 digit year in NV Ram
+        writeByte(YEAR_REG, dti.date.year);
     };
 
     enableCounting();
 };
 
 //--------------------- Reads time and date information from RTC (PCF8583)
-void PCF8583rtc::read(const char address)
+struct DateTime_t PCF8583rtc::read(const char address)
 {
     char tmp[8];
-    char year_bits = 0;                // To test for year change
+    char year_bits = 0;                   // To test for year change
 
     tmp[0] = address;
-    _i2c->write(PCF8583_addr, tmp, 1); // Address PCF8583, see PCF8583 datasheet
-    _i2c->read(PCF8583_addr, tmp, 6);  // Address PCF8583 for reading R/W=1
+    _i2c->write(_I2cAddress, tmp, 1);     // Address PCF8583, see PCF8583 datasheet
+    _i2c->read(_I2cAddress | 1, tmp, 6);  // Address PCF8583 for reading R/W=1
     
-    dt.time.hundreds   = ((tmp[0] & 0xF0) >> 4) * 10 + (tmp[0] & 0x0F);   // Transform hundredths of seconds
-    dt.time.seconds    = ((tmp[1] & 0xF0) >> 4) * 10 + (tmp[1] & 0x0F);   // Transform seconds
-    dt.time.minutes    = ((tmp[2] & 0xF0) >> 4) * 10 + (tmp[2] & 0x0F);   // Transform minutes
-    dt.time.hours      = ((tmp[3] & 0x30) >> 4) * 10 + (tmp[3] & 0x0F);   // Transform hours
-    dt.time.fmt_hours  =  (tmp[3] & 0x80);                                // 12/24 hour format
-    dt.time.am_pm_flag =  (tmp[3] & 0x40);                                // Am/Pm flag
-    dt.date.day        = ((tmp[4] & 0x30) >> 4) * 10  + (tmp[4] & 0x0F);  // Transform day
+    dt.time.hundreds   = tmp[0];
+    dt.time.seconds    = tmp[1];
+    dt.time.minutes    = tmp[2];
+    dt.time.hours      = tmp[3] & 0x3F;
+    dt.time.fmt_hours  = tmp[3] & 0x80;   // 12/24 hour format
+    dt.time.am_pm_flag = tmp[3] & 0x40;   // Am/Pm flag
+    dt.date.day        = tmp[4] & 0x3F;   // Day of the Month
+    dt.date.month      = tmp[5] & 0x1F;
 
     if(address == TIME)
         year_bits = (tmp[4] & 0xC0) >> 6;
     else
         dt.date.year = 0;                                              // No year for alarm
 
-    dt.date.month   = ((tmp[5] & 0x10)  >> 4) * 10 + (tmp[5] & 0x0F);  // Transform month
 
     if(address == TIME)
         dt.date.weekday =  tmp[5] >> 5;
@@ -152,33 +154,14 @@
             writeByte(5, dt.date.day & 0x3F);                          // Clear the year bits but preserve the date
         }
     }
+   
+    return dt;
 };
 
-struct DateTime_t PCF8583rtc::GetDateTime(void)
-{
-  return dt;    
-}
- 
-struct DateTime_t PCF8583rtc::GetDateTimeBCD(void)
-{
-    struct DateTime_t dtb;
-    
-    dtb = dt;
-    dtb.time.hours    = bin2bcd(dt.time.hours);
-    dtb.time.minutes  = bin2bcd(dt.time.minutes);
-    dtb.time.seconds  = bin2bcd(dt.time.seconds);
-    dtb.time.hundreds = bin2bcd(dt.time.hundreds);
-
-    dtb.date.day      = bin2bcd(dt.date.day);
-    dtb.date.month    = bin2bcd(dt.date.month);
-    dtb.date.year     = bin2bcd(dt.date.year);
-    dtb.date.century  = bin2bcd(dt.date.century);
-  
-    return dtb;
-}
-
 void PCF8583rtc::FormatDateTime(char *dest, char *f)
 {
+    int i;
+    
     if(f != 0 && *f != 0) {   //If the format param is empty then do a default 'c'
         while(*f != 0) {        //expect null terminated string (we hope)
             switch(*f) {
@@ -186,44 +169,44 @@
                     break;
                 case 'd':
                     if(*(f+1) != 'd') {            //'d' - Day with no leading zero
-                        dest += Bcd2Char(dest, dt.date.day, FALSE);
+                        dest += Bcd2Char(dest, dt.date.day, false);
                     } else {
                         f++;
                         if(*(f+1) != 'd')            //'dd' - Day with leading zero
-                            dest += Bcd2Char(dest, dt.date.day, TRUE);
+                            dest += Bcd2Char(dest, dt.date.day, true);
                         else {
                             f++;
                             if(*(f+1) != 'd') {        //'ddd' - Short day name
-//                                i = 0;
-//                                while(ShortDayNames[dt.date.weekday][i] != 0)
-//                                    *dest++ = ShortDayNames[dt.date.weekday][i++];
+                                i = 0;
+                                while(ShortDayNames[dt.date.weekday][i] != 0)
+                                    *dest++ = ShortDayNames[dt.date.weekday][i++];
                             } else {
                                 f++;
-//                                i = 0;
-//                                while(LongDayNames[dt.date.weekday][i] != 0)
-//                                    *dest++ = LongDayNames[dt.date.weekday][i++];
+                                i = 0;
+                                while(LongDayNames[dt.date.weekday][i] != 0)
+                                    *dest++ = LongDayNames[dt.date.weekday][i++];
                             }
                         }
                     }
                     break;
                 case 'm':
                     if(*(f+1) != 'm') {            //'m' - Month with no leading zero
-                        dest += Bcd2Char(dest, dt.date.month, FALSE);
+                        dest += Bcd2Char(dest, dt.date.month, false);
                     } else {
                         f++;
                         if(*(f+1) != 'm')            //'mm' - Month with leading zero
-                            dest += Bcd2Char(dest, dt.date.month, TRUE);
+                            dest += Bcd2Char(dest, dt.date.month, true);
                         else {
                             f++;
                             if(*(f+1) != 'm') {        //'mmm' - Short month name
-//                                i = 0;
-//                                while(ShortMonthNames[dt.date.month - 1][i] != 0)
-//                                    *dest++ = ShortMonthNames[dt.date.month - 1][i++];
+                                i = 0;
+                                while(ShortMonthNames[dt.date.month - 1][i] != 0)
+                                    *dest++ = ShortMonthNames[dt.date.month - 1][i++];
                             } else {
                                 f++;
-//                                i = 0;
-//                                while(LongMonthNames[dt.date.month - 1][i] != 0)
-//                                    *dest++ = LongMonthNames[dt.date.month - 1][i++];
+                                i = 0;
+                                while(LongMonthNames[dt.date.month - 1][i] != 0)
+                                    *dest++ = LongMonthNames[dt.date.month - 1][i++];
                             }
                         }
                     }
@@ -232,42 +215,42 @@
                     if(*(f+1) == 'y') {
                         f++;                                 //We have at least a 'yy'
                         if(*(f+1) == 'y' && *(f+2) == 'y') { //'yyyy' - 4 digit year
-                            dest += Bcd2Char(dest, dt.date.century, TRUE);
+                            dest += Bcd2Char(dest, dt.date.century, true);
                             f += 2;
                         }
-                        dest += Bcd2Char(dest, dt.date.year, TRUE);
+                        dest += Bcd2Char(dest, dt.date.year, true);
                     }
                     break;
                 case 'h':
                     if(*(f+1) != 'h') {            //'h' - Hour with no leading zero
-                        dest += Bcd2Char(dest, dt.time.hours, FALSE);
+                        dest += Bcd2Char(dest, dt.time.hours, false);
                     } else {
                         f++;
-                        dest += Bcd2Char(dest, dt.time.hours, TRUE);
+                        dest += Bcd2Char(dest, dt.time.hours, true);
                     }
                     break;
                 case 'n':
                     if(*(f+1) != 'n') {            //'m' - Minutes with no leading zero
-                        dest += Bcd2Char(dest, dt.time.minutes, FALSE);
+                        dest += Bcd2Char(dest, dt.time.minutes, false);
                     } else {
                         f++;
-                        dest += Bcd2Char(dest, dt.time.minutes, TRUE);
+                        dest += Bcd2Char(dest, dt.time.minutes, true);
                     }
                     break;
                 case 's':
                     if(*(f+1) != 's') {            //'s' - Seconds with no leading zero
-                        dest += Bcd2Char(dest, dt.time.seconds, FALSE);
+                        dest += Bcd2Char(dest, dt.time.seconds, false);
                     } else {
                         f++;
-                        dest += Bcd2Char(dest, dt.time.seconds, TRUE);
+                        dest += Bcd2Char(dest, dt.time.seconds, true);
                     }
                     break;
                 case 'z':
                     if(*(f+1) != 'z') {            //'z' - Hundredths with no leading zero
-                        dest += Bcd2Char(dest, dt.time.hundreds, FALSE);
+                        dest += Bcd2Char(dest, dt.time.hundreds, false);
                     } else {
                         f++;
-                        dest += Bcd2Char(dest, dt.time.hundreds, TRUE);
+                        dest += Bcd2Char(dest, dt.time.hundreds, true);
                     }
                     break;
                 case '/':
@@ -294,17 +277,17 @@
     if((address < USER_REG) || (num == 0))       // dont allow overwriting first 2 user bytes
         return false;
     
-    _i2c->write(PCF8583_addr, &address, 1); // set the rom address
-    return _i2c->write(PCF8583_addr, value, num);  // write the data
+    _i2c->write(_I2cAddress, &address, 1); // set the rom address
+    return _i2c->write(_I2cAddress, value, num);  // write the data
 };
 
 bool PCF8583rtc::ReadNVram(char address, char * dest, char num)
 {
-    if((address < USER_REG) || (num == 0))       // dont allow overwriting first 2 user bytes
+    if((address < USER_REG) || (num == 0))     // dont allow overwriting first 2 user bytes
         return false;
     
-    _i2c->write(PCF8583_addr, &address, 1); // set the rom address
-    _i2c->read(PCF8583_addr, dest, num);    // read the data
+    _i2c->write(_I2cAddress, &address, 1);     // set the rom address
+    _i2c->read(_I2cAddress | 1, dest, num);    // read the data
     
     return true;
 };
@@ -317,7 +300,7 @@
 {
     char  n = 0;
 
-    if(WantLeadZero == TRUE || (val / 10) != 0) {
+    if(WantLeadZero == true || (val / 10) != 0) {
         *d++ = (val / 10) + 48;
         n++;
     }
@@ -326,9 +309,9 @@
 }
 
 //----------------------------------------------
-// This function converts an 8 bit binary value to a 2 byte BCD value.
+// This function converts an 8 bit binary value to a 1 byte BCD value.
 // The input range must be from 0 to 99.
-int PCF8583rtc::bin2bcd(char value)
+char PCF8583rtc::bin2bcd(char value)
 {
     int tmp = 0;
 
@@ -348,42 +331,32 @@
 
 void PCF8583rtc::writeByte(char address, char d)
 {
-    _i2c->start();
-    _i2c->write(Write_addr);
-    _i2c->write(address);
-    _i2c->write(d);
-    _i2c->stop();
+    char buf[2];
+
+    buf[0] = address;
+    buf[1] = d;
+    _i2c->write(_I2cAddress, buf, 2);                              // Address PCF8583, see PCF8583 datasheet
 }
 
 void PCF8583rtc::configureControlReg(char control)
 {
-    _i2c->start();
-    _i2c->write(Write_addr);
-    _i2c->write(0x00);
-    _i2c->write(control);
-    _i2c->stop();
+    writeByte(0, control);
 }
 
 void PCF8583rtc::configureAlarmReg(char alarm)
 {
-    _i2c->start();
-    _i2c->write(Write_addr);
-    _i2c->write(0x08);
-    _i2c->write(alarm);
-    _i2c->stop();
+    writeByte(0x08, alarm);
 }
 
 char PCF8583rtc::readByte(char address)
 {
-    char var;
-    _i2c->start();
-    _i2c->write(Write_addr);
-    _i2c->write(address);
-    _i2c->start();
-    _i2c->write(Read_addr);
-    var = _i2c->read(0) ;
-    _i2c->stop();
-    return var;
+    char buf[2];
+
+    buf[0] = address;
+    _i2c->write(_I2cAddress, buf, 1);
+    _i2c->read(_I2cAddress | 1, buf, 1);
+
+    return buf[0];
 }
 
 void PCF8583rtc::pauseCounting()