library to control, set and read time and date from Hotboards rtcc board, wich contains the Microchip MCP7941x real time clock
Dependents: Hotboards_rtcc_manual_timedate Hotboards_rtcc_timeSpan Hotboards_rtcc_alarm Hotboards_rtcc_compiler_timedate ... more
Revision 0:3a2ad459941a, committed 2016-02-02
- Comitter:
- Hotboards
- Date:
- Tue Feb 02 04:11:32 2016 +0000
- Child:
- 1:0790bcaf8b8f
- Commit message:
- first release
Changed in this revision
| Hotboards_rtcc.cpp | Show annotated file Show diff for this revision Revisions of this file |
| Hotboards_rtcc.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Hotboards_rtcc.cpp Tue Feb 02 04:11:32 2016 +0000
@@ -0,0 +1,368 @@
+/*
+ Hotboards_rtcc.cpp - Library to read, write and control the real time clock MCP7941x included in rtc board.
+ http://hotboards.org
+ adapted and taken from https://github.com/adafruit/RTClib
+ Released into the public domain.
+*/
+
+#include "Hotboards_rtcc.h"
+
+
+#define RTC_ADDR (uint8_t)(0xDE >> 1)
+#define EEPROM_ADDR (uint8_t)(0xAE >> 1)
+#define RTC_STARTADDR (uint8_t)0x00
+#define ALARM_STARTADDR (uint8_t)0x0A
+#define CTRL_STARTADDR (uint8_t)0x07
+#define SRAM_SARTADDR (uint8_t)0x20
+#define EEPROM_SARTADDR (uint8_t)0x00
+#define PEEPROM_SARTADDR (uint8_t)0xF0
+
+#define SECONDS_FROM_1970_TO_2000 946684800
+
+const uint8_t daysInMonth[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
+
+// number of days since 2000/01/01, valid for 2001..2099
+static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d)
+{
+ if (y >= 2000)
+ y -= 2000;
+ uint16_t days = d;
+ for (uint8_t i = 1; i < m; ++i)
+ days += daysInMonth[i - 1];
+ if (m > 2 && y % 4 == 0)
+ ++days;
+ return days + 365 * y + (y + 3) / 4 - 1;
+}
+
+static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s)
+{
+ return ((days * 24L + h) * 60 + m) * 60 + s;
+}
+
+static uint8_t conv2d(const char* p)
+{
+ uint8_t v = 0;
+ if ('0' <= *p && *p <= '9')
+ v = *p - '0';
+ return 10 * v + *++p - '0';
+}
+
+/*
+ * Constructor that use time in a 32 bit variable
+ */
+DateTime::DateTime( uint32_t t )
+{
+ t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970
+ ss = t % 60;
+ t /= 60;
+ mm = t % 60;
+ t /= 60;
+ hh = t % 24;
+ uint16_t days = t / 24;
+ uint8_t leap;
+ for( yOff = 0 ; ; ++yOff )
+ {
+ leap = yOff % 4 == 0;
+ if (days < 365 + leap)
+ {
+ break;
+ }
+ days -= 365 + leap;
+ }
+ for (m = 1; ; ++m)
+ {
+ uint8_t daysPerMonth = daysInMonth[m - 1];
+ if (leap && m == 2)
+ {
+ ++daysPerMonth;
+ }
+ if (days < daysPerMonth)
+ {
+ break;
+ }
+ days -= daysPerMonth;
+ }
+ d = days + 1;
+}
+
+/*
+ * Constructor that use time variables for each element in decimal
+ */
+DateTime::DateTime( uint16_t year, uint8_t month, uint8_t day,
+ uint8_t hour, uint8_t min, uint8_t sec, uint8_t dweek )
+{
+ if( year >= 2000 )
+ {
+ year -= 2000;
+ }
+ yOff = year;
+ m = month;
+ d = day;
+ hh = hour;
+ mm = min;
+ ss = sec;
+ dw = dweek;
+}
+
+/*
+ * Constructor tcreate a copy of DateTime object
+ */
+DateTime::DateTime (const DateTime& copy):
+ yOff(copy.yOff),
+ m(copy.m),
+ d(copy.d),
+ hh(copy.hh),
+ mm(copy.mm),
+ ss(copy.ss)
+{}
+
+
+/*
+ * A convenient constructor for using "the compiler's time":
+ DateTime now (__DATE__, __TIME__);
+ */
+DateTime::DateTime( const char* date, const char* time )
+{
+ // sample input: date = "Dec 26 2009", time = "12:34:56"
+ yOff = conv2d(date + 9);
+ // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
+ switch( date[0] )
+ {
+ case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break;
+ case 'F': m = 2; break;
+ case 'A': m = date[2] == 'r' ? 4 : 8; break;
+ case 'M': m = date[2] == 'r' ? 3 : 5; break;
+ case 'S': m = 9; break;
+ case 'O': m = 10; break;
+ case 'N': m = 11; break;
+ case 'D': m = 12; break;
+ }
+ d = conv2d( date + 4 );
+ hh = conv2d( time );
+ mm = conv2d( time + 3 );
+ ss = conv2d( time + 6 );
+}
+
+uint8_t DateTime::dayOfTheWeek( void ) const
+{
+ uint16_t day = date2days( yOff, m, d );
+
+ return ( day + 6 ) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6
+}
+
+uint32_t DateTime::unixtime( void ) const
+{
+ uint32_t t;
+ uint16_t days = date2days( yOff, m, d );
+
+ t = time2long(days, hh, mm, ss);
+ t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000
+
+ return t;
+}
+
+uint32_t DateTime::secondstime( void ) const
+{
+ uint32_t t;
+ uint16_t days = date2days( yOff, m, d );
+
+ t = time2long( days, hh, mm, ss );
+ return t;
+}
+
+
+
+
+DateTime DateTime::operator+(const TimeSpan& span)
+{
+ return DateTime(unixtime()+span.totalseconds());
+}
+
+DateTime DateTime::operator-(const TimeSpan& span)
+{
+ return DateTime(unixtime()-span.totalseconds());
+}
+
+TimeSpan DateTime::operator-(const DateTime& right)
+{
+ return TimeSpan(unixtime()-right.unixtime());
+}
+
+
+
+TimeSpan::TimeSpan (int32_t seconds):
+ _seconds(seconds)
+{}
+
+TimeSpan::TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds):
+ _seconds((int32_t)days*86400L + (int32_t)hours*3600 + (int32_t)minutes*60 + seconds)
+{}
+
+TimeSpan::TimeSpan (const TimeSpan& copy):
+ _seconds(copy._seconds)
+{}
+
+TimeSpan TimeSpan::operator+(const TimeSpan& right)
+{
+ return TimeSpan(_seconds+right._seconds);
+}
+
+TimeSpan TimeSpan::operator-(const TimeSpan& right)
+{
+ return TimeSpan(_seconds-right._seconds);
+}
+
+
+
+Hotboards_rtcc::Hotboards_rtcc( I2C &i2c )
+ : _i2c(i2c)
+{
+ on_off = 0;
+}
+/*
+ * enable internal oscilator if this is disable (start the clock)
+ */
+void Hotboards_rtcc::begin( void )
+{
+ if( isrunning( ) == 0 )
+ {
+ writeReg( RTC_STARTADDR, 0x80 );
+ }
+}
+
+/*
+ * set a new time and date
+ */
+void Hotboards_rtcc::adjust( const DateTime &dt )
+{
+ char buffer[8];
+
+ buffer[0] = RTC_STARTADDR;
+ buffer[1] = bin2bcd(dt.second()) | 0x80;
+ buffer[2] = bin2bcd(dt.minute());
+ buffer[3] = bin2bcd(dt.hour());
+ buffer[4] = bin2bcd(dt.dayOfTheWeek()) | on_off;
+ buffer[5] = bin2bcd(dt.day());
+ buffer[6] = bin2bcd(dt.month());
+ buffer[7] = bin2bcd(dt.year() - 2000);
+
+ stop();
+ _i2c.write( RTC_ADDR, buffer, 8 );
+}
+
+/*
+ * return an DateTime object with the actual time and date
+ */
+DateTime Hotboards_rtcc::now( void )
+{
+ char buffer[7];
+
+ buffer[0] = RTC_STARTADDR;
+ _i2c.write(RTC_ADDR, buffer, 1, true);
+ _i2c.read(RTC_ADDR, buffer, 7, false);
+
+ uint8_t ss = bcd2bin( buffer[0] & 0x7F );
+ uint8_t mm = bcd2bin( buffer[1] );
+ uint8_t hh = bcd2bin( buffer[2] );
+ uint8_t dw = buffer[3] & 0x07;
+ uint8_t d = bcd2bin( buffer[4] );
+ uint8_t m = bcd2bin( buffer[5] & 0xDF );
+ uint16_t y = bcd2bin( buffer[6] ) + 2000;
+
+ return DateTime( y, m, d, hh, mm, ss, dw );
+}
+
+/*
+ * return a true if the rtcc is running
+ */
+uint8_t Hotboards_rtcc::isrunning( void )
+{
+ uint8_t running = readReg( RTC_STARTADDR + 3 ) & 0x20;
+ return running >> 5;
+}
+
+/*
+ * stop the internal rtcc clock
+ */
+void Hotboards_rtcc::stop( void )
+{
+ writeReg( RTC_STARTADDR, 0x00 );
+ while( isrunning( ) == 1 );
+}
+
+void Hotboards_rtcc::setVBAT( uint8_t OnOff )
+{
+ on_off = ( OnOff & 0x01 ) << 3;
+}
+
+void Hotboards_rtcc::setAlarm( const DateTime &dt, uint8_t alarm )
+{
+ char buffer[8];
+
+ buffer[0] = ALARM_STARTADDR;
+ buffer[1] = bin2bcd(dt.second()) | 0x80;
+ buffer[2] = bin2bcd(dt.minute());
+ buffer[3] = bin2bcd(dt.hour());
+ buffer[4] = bin2bcd(dt.dayOfTheWeek()) | on_off;
+ buffer[5] = bin2bcd(dt.day());
+ buffer[6] = bin2bcd(dt.month());
+ buffer[7] = bin2bcd(dt.year() - 2000);
+
+ _i2c.write( RTC_ADDR, buffer, 8 );
+}
+
+uint8_t Hotboards_rtcc::getAlarmStatus( uint8_t alarm )
+{
+ uint8_t status = readReg( ALARM_STARTADDR + 3 );
+ return ( status >> 3 ) & 0x01;
+}
+
+void Hotboards_rtcc::clearAlarm( uint8_t alarm )
+{
+ uint8_t status = readReg( ALARM_STARTADDR + 3 );
+ writeReg( ALARM_STARTADDR + 3, (status & 0xF7) );
+}
+
+void Hotboards_rtcc::turnOnAlarm( uint8_t alarm )
+{
+ uint8_t ctrl = readReg( CTRL_STARTADDR );
+ writeReg( CTRL_STARTADDR, ctrl | 0x10 );
+}
+
+void Hotboards_rtcc::turnOffAlarm( uint8_t alarm )
+{
+ uint8_t ctrl = readReg( CTRL_STARTADDR );
+ writeReg( CTRL_STARTADDR, ctrl & 0xEF );
+}
+
+uint8_t Hotboards_rtcc::readReg( uint8_t address )
+{
+ char buffer[1];
+
+ buffer[0] = address;
+ _i2c.write(RTC_ADDR, buffer, 1, true);
+ _i2c.read(RTC_ADDR, buffer, 1, false);
+
+ return buffer[0];
+}
+
+void Hotboards_rtcc::writeReg( uint8_t address, uint8_t val )
+{
+ char buffer[2];
+
+ buffer[0] = address;
+ buffer[1] = val;
+
+ _i2c.write( RTC_ADDR, buffer, 2 );
+}
+
+uint8_t Hotboards_rtcc::bcd2bin( uint8_t val )
+{
+ return val - 6 * ( val >> 4 );
+}
+
+uint8_t Hotboards_rtcc::bin2bcd( uint8_t val )
+{
+ return val + 6 * ( val / 10 );
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Hotboards_rtcc.h Tue Feb 02 04:11:32 2016 +0000
@@ -0,0 +1,93 @@
+/*
+ Hotboards_rtcc.cpp - Library to read, write and control the real time clock MCP7941x included in rtc board.
+ http://hotboards.org
+ adapted and Taken from https://github.com/adafruit/RTClib
+ Released into the public domain.
+*/
+
+#ifndef Hotboards_rtcc_h
+#define Hotboards_rtcc_h
+
+#include "mbed.h"
+
+class TimeSpan;
+
+class DateTime
+{
+ public:
+ DateTime( uint32_t t = 0 );
+ DateTime( uint16_t year, uint8_t month, uint8_t day,
+ uint8_t hour = 0, uint8_t min = 0, uint8_t sec = 0, uint8_t dweek = 0 );
+ DateTime( const DateTime& copy );
+ DateTime( const char* date, const char* time );
+ uint16_t year() const { return 2000 + yOff; }
+ uint8_t month() const { return m; }
+ uint8_t day() const { return d; }
+ uint8_t hour() const { return hh; }
+ uint8_t minute() const { return mm; }
+ uint8_t second() const { return ss; }
+ uint8_t dweek( void ) const { return ss; }
+ uint8_t dayOfTheWeek( void ) const;
+ // 32-bit times as seconds since 1/1/2000
+ uint32_t secondstime( void ) const;
+ // 32-bit times as seconds since 1/1/1970
+ uint32_t unixtime( void ) const;
+ DateTime operator+(const TimeSpan& span);
+ DateTime operator-(const TimeSpan& span);
+ TimeSpan operator-(const DateTime& right);
+
+
+ protected:
+ uint8_t yOff, m, d, dw, hh, mm, ss;
+};
+
+// Timespan which can represent changes in time with seconds accuracy.
+class TimeSpan
+{
+public:
+ TimeSpan (int32_t seconds = 0);
+ TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds);
+ TimeSpan (const TimeSpan& copy);
+ int16_t days() const { return _seconds / 86400L; }
+ int8_t hours() const { return _seconds / 3600 % 24; }
+ int8_t minutes() const { return _seconds / 60 % 60; }
+ int8_t seconds() const { return _seconds % 60; }
+ int32_t totalseconds() const { return _seconds; }
+
+ TimeSpan operator+(const TimeSpan& right);
+ TimeSpan operator-(const TimeSpan& right);
+
+protected:
+ int32_t _seconds;
+};
+
+class Hotboards_rtcc
+{
+ public:
+ Hotboards_rtcc( I2C &i2c );
+ void begin( void );
+ void adjust( const DateTime &dt );
+ DateTime now( void );
+ uint8_t isrunning( void );
+ void setVBAT( uint8_t OnOff );
+ void setAlarm( const DateTime &dt, uint8_t alarm = 0 );
+ uint8_t getAlarmStatus( uint8_t alarm = 0 );
+ void clearAlarm( uint8_t alarm = 0 );
+ void turnOnAlarm( uint8_t alarm = 0 );
+ void turnOffAlarm( uint8_t alarm = 0 );
+
+ protected:
+ I2C _i2c;
+ uint8_t on_off;
+
+ void stop( void );
+ uint8_t readReg( uint8_t address );
+ void writeReg( uint8_t address, uint8_t val );
+ uint8_t bcd2bin( uint8_t val );
+ uint8_t bin2bcd( uint8_t val );
+
+};
+
+
+#endif
+
\ No newline at end of file
Hotboards RTCC