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
Diff: PCF8583_rtc.cpp
- 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()