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.
Dependents: Hotboards_rtcc_manual_timedate Hotboards_rtcc_timeSpan Hotboards_rtcc_alarm Hotboards_rtcc_compiler_timedate ... more
Hotboards_rtcc.cpp
00001 /* 00002 Hotboards_rtcc.cpp - Library to read, write and control the real time clock MCP7941x included in rtc board. 00003 http://hotboards.org 00004 adapted and taken from https://github.com/adafruit/RTClib 00005 Released into the public domain. 00006 */ 00007 00008 #include "Hotboards_rtcc.h" 00009 00010 00011 #define RTC_ADDR (uint8_t)(0xDE) 00012 #define EEPROM_ADDR (uint8_t)(0xAE) 00013 #define RTC_STARTADDR (uint8_t)0x00 00014 #define ALARM_STARTADDR (uint8_t)0x0A 00015 #define CTRL_STARTADDR (uint8_t)0x07 00016 #define SRAM_SARTADDR (uint8_t)0x20 00017 #define EEPROM_SARTADDR (uint8_t)0x00 00018 #define PEEPROM_SARTADDR (uint8_t)0xF0 00019 00020 #define SECONDS_FROM_1970_TO_2000 946684800 00021 00022 const uint8_t daysInMonth[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; 00023 00024 // number of days since 2000/01/01, valid for 2001..2099 00025 static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) 00026 { 00027 if (y >= 2000) 00028 y -= 2000; 00029 uint16_t days = d; 00030 for (uint8_t i = 1; i < m; ++i) 00031 days += daysInMonth[i - 1]; 00032 if (m > 2 && y % 4 == 0) 00033 ++days; 00034 return days + 365 * y + (y + 3) / 4 - 1; 00035 } 00036 00037 static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) 00038 { 00039 return ((days * 24L + h) * 60 + m) * 60 + s; 00040 } 00041 00042 static uint8_t conv2d(const char* p) 00043 { 00044 uint8_t v = 0; 00045 if ('0' <= *p && *p <= '9') 00046 v = *p - '0'; 00047 return 10 * v + *++p - '0'; 00048 } 00049 00050 /* 00051 * Constructor that use time in a 32 bit variable 00052 */ 00053 DateTime::DateTime( uint32_t t ) 00054 { 00055 t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970 00056 ss = t % 60; 00057 t /= 60; 00058 mm = t % 60; 00059 t /= 60; 00060 hh = t % 24; 00061 uint16_t days = t / 24; 00062 uint8_t leap; 00063 for( yOff = 0 ; ; ++yOff ) 00064 { 00065 leap = yOff % 4 == 0; 00066 if (days < 365 + leap) 00067 { 00068 break; 00069 } 00070 days -= 365 + leap; 00071 } 00072 for (m = 1; ; ++m) 00073 { 00074 uint8_t daysPerMonth = daysInMonth[m - 1]; 00075 if (leap && m == 2) 00076 { 00077 ++daysPerMonth; 00078 } 00079 if (days < daysPerMonth) 00080 { 00081 break; 00082 } 00083 days -= daysPerMonth; 00084 } 00085 d = days + 1; 00086 } 00087 00088 /* 00089 * Constructor that use time variables for each element in decimal 00090 */ 00091 DateTime::DateTime( uint16_t year, uint8_t month, uint8_t day, 00092 uint8_t hour, uint8_t min, uint8_t sec, uint8_t dweek ) 00093 { 00094 if( year >= 2000 ) 00095 { 00096 year -= 2000; 00097 } 00098 yOff = year; 00099 m = month; 00100 d = day; 00101 hh = hour; 00102 mm = min; 00103 ss = sec; 00104 dw = dweek; 00105 } 00106 00107 /* 00108 * Constructor tcreate a copy of DateTime object 00109 */ 00110 DateTime::DateTime (const DateTime& copy): 00111 yOff(copy.yOff), 00112 m(copy.m), 00113 d(copy.d), 00114 hh(copy.hh), 00115 mm(copy.mm), 00116 ss(copy.ss) 00117 {} 00118 00119 00120 /* 00121 * A convenient constructor for using "the compiler's time": 00122 DateTime now (__DATE__, __TIME__); 00123 */ 00124 DateTime::DateTime( const char* date, const char* time ) 00125 { 00126 // sample input: date = "Dec 26 2009", time = "12:34:56" 00127 yOff = conv2d(date + 9); 00128 // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 00129 switch( date[0] ) 00130 { 00131 case 'J': m = date[1] == 'a' ? 1 : m = date[2] == 'n' ? 6 : 7; break; 00132 case 'F': m = 2; break; 00133 case 'A': m = date[2] == 'r' ? 4 : 8; break; 00134 case 'M': m = date[2] == 'r' ? 3 : 5; break; 00135 case 'S': m = 9; break; 00136 case 'O': m = 10; break; 00137 case 'N': m = 11; break; 00138 case 'D': m = 12; break; 00139 } 00140 d = conv2d( date + 4 ); 00141 hh = conv2d( time ); 00142 mm = conv2d( time + 3 ); 00143 ss = conv2d( time + 6 ); 00144 } 00145 00146 uint8_t DateTime::dayOfTheWeek( void ) const 00147 { 00148 uint16_t day = date2days( yOff, m, d ); 00149 00150 return ( day + 6 ) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6 00151 } 00152 00153 uint32_t DateTime::unixtime( void ) const 00154 { 00155 uint32_t t; 00156 uint16_t days = date2days( yOff, m, d ); 00157 00158 t = time2long(days, hh, mm, ss); 00159 t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000 00160 00161 return t; 00162 } 00163 00164 uint32_t DateTime::secondstime( void ) const 00165 { 00166 uint32_t t; 00167 uint16_t days = date2days( yOff, m, d ); 00168 00169 t = time2long( days, hh, mm, ss ); 00170 return t; 00171 } 00172 00173 00174 00175 00176 DateTime DateTime::operator+(const TimeSpan& span) 00177 { 00178 return DateTime(unixtime()+span.totalseconds()); 00179 } 00180 00181 DateTime DateTime::operator-(const TimeSpan& span) 00182 { 00183 return DateTime(unixtime()-span.totalseconds()); 00184 } 00185 00186 TimeSpan DateTime::operator-(const DateTime& right) 00187 { 00188 return TimeSpan(unixtime()-right.unixtime()); 00189 } 00190 00191 00192 00193 TimeSpan::TimeSpan (int32_t seconds): 00194 _seconds(seconds) 00195 {} 00196 00197 TimeSpan::TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds): 00198 _seconds((int32_t)days*86400L + (int32_t)hours*3600 + (int32_t)minutes*60 + seconds) 00199 {} 00200 00201 TimeSpan::TimeSpan (const TimeSpan& copy): 00202 _seconds(copy._seconds) 00203 {} 00204 00205 TimeSpan TimeSpan::operator+(const TimeSpan& right) 00206 { 00207 return TimeSpan(_seconds+right._seconds); 00208 } 00209 00210 TimeSpan TimeSpan::operator-(const TimeSpan& right) 00211 { 00212 return TimeSpan(_seconds-right._seconds); 00213 } 00214 00215 00216 00217 Hotboards_rtcc::Hotboards_rtcc( I2C &i2c ) 00218 : _i2c(i2c) 00219 { 00220 on_off = 0; 00221 } 00222 /* 00223 * enable internal oscilator if this is disable (start the clock) 00224 */ 00225 void Hotboards_rtcc::begin( void ) 00226 { 00227 if( isrunning( ) == 0 ) 00228 { 00229 writeReg( RTC_STARTADDR, 0x80 ); 00230 } 00231 } 00232 00233 /* 00234 * set a new time and date 00235 */ 00236 void Hotboards_rtcc::adjust( const DateTime &dt ) 00237 { 00238 char buffer[8]; 00239 00240 buffer[0] = RTC_STARTADDR; 00241 buffer[1] = bin2bcd(dt.second()) | 0x80; 00242 buffer[2] = bin2bcd(dt.minute()); 00243 buffer[3] = bin2bcd(dt.hour()); 00244 buffer[4] = bin2bcd(dt.dayOfTheWeek()) | on_off; 00245 buffer[5] = bin2bcd(dt.day()); 00246 buffer[6] = bin2bcd(dt.month()); 00247 buffer[7] = bin2bcd(dt.year() - 2000); 00248 00249 stop(); 00250 _i2c.write( RTC_ADDR, buffer, 8 ); 00251 } 00252 00253 /* 00254 * return an DateTime object with the actual time and date 00255 */ 00256 DateTime Hotboards_rtcc::now( void ) 00257 { 00258 char buffer[7]; 00259 00260 buffer[0] = RTC_STARTADDR; 00261 _i2c.write(RTC_ADDR, buffer, 1, true); 00262 _i2c.read(RTC_ADDR, buffer, 7, false); 00263 00264 uint8_t ss = bcd2bin( buffer[0] & 0x7F ); 00265 uint8_t mm = bcd2bin( buffer[1] ); 00266 uint8_t hh = bcd2bin( buffer[2] ); 00267 uint8_t dw = buffer[3] & 0x07; 00268 uint8_t d = bcd2bin( buffer[4] ); 00269 uint8_t m = bcd2bin( buffer[5] & 0xDF ); 00270 uint16_t y = bcd2bin( buffer[6] ) + 2000; 00271 00272 return DateTime( y, m, d, hh, mm, ss, dw ); 00273 } 00274 00275 /* 00276 * return a true if the rtcc is running 00277 */ 00278 uint8_t Hotboards_rtcc::isrunning( void ) 00279 { 00280 uint8_t running = readReg( RTC_STARTADDR + 3 ) & 0x20; 00281 return running >> 5; 00282 } 00283 00284 /* 00285 * stop the internal rtcc clock 00286 */ 00287 void Hotboards_rtcc::stop( void ) 00288 { 00289 writeReg( RTC_STARTADDR, 0x00 ); 00290 while( isrunning( ) == 1 ); 00291 } 00292 00293 void Hotboards_rtcc::setVBAT( uint8_t OnOff ) 00294 { 00295 on_off = ( OnOff & 0x01 ) << 3; 00296 } 00297 00298 void Hotboards_rtcc::setAlarm( const DateTime &dt, uint8_t alarm ) 00299 { 00300 char buffer[8]; 00301 00302 buffer[0] = ALARM_STARTADDR; 00303 buffer[1] = bin2bcd(dt.second()) | 0x80; 00304 buffer[2] = bin2bcd(dt.minute()); 00305 buffer[3] = bin2bcd(dt.hour()); 00306 buffer[4] = bin2bcd(dt.dayOfTheWeek()) | on_off; 00307 buffer[5] = bin2bcd(dt.day()); 00308 buffer[6] = bin2bcd(dt.month()); 00309 buffer[7] = bin2bcd(dt.year() - 2000); 00310 00311 _i2c.write( RTC_ADDR, buffer, 8 ); 00312 } 00313 00314 uint8_t Hotboards_rtcc::getAlarmStatus( uint8_t alarm ) 00315 { 00316 uint8_t status = readReg( ALARM_STARTADDR + 3 ); 00317 return ( status >> 3 ) & 0x01; 00318 } 00319 00320 void Hotboards_rtcc::clearAlarm( uint8_t alarm ) 00321 { 00322 uint8_t status = readReg( ALARM_STARTADDR + 3 ); 00323 writeReg( ALARM_STARTADDR + 3, (status & 0xF7) ); 00324 } 00325 00326 void Hotboards_rtcc::turnOnAlarm( uint8_t alarm ) 00327 { 00328 uint8_t ctrl = readReg( CTRL_STARTADDR ); 00329 writeReg( CTRL_STARTADDR, ctrl | 0x10 ); 00330 } 00331 00332 void Hotboards_rtcc::turnOffAlarm( uint8_t alarm ) 00333 { 00334 uint8_t ctrl = readReg( CTRL_STARTADDR ); 00335 writeReg( CTRL_STARTADDR, ctrl & 0xEF ); 00336 } 00337 00338 uint8_t Hotboards_rtcc::readReg( uint8_t address ) 00339 { 00340 char buffer[1]; 00341 00342 buffer[0] = address; 00343 _i2c.write(RTC_ADDR, buffer, 1, true); 00344 _i2c.read(RTC_ADDR, buffer, 1, false); 00345 00346 return buffer[0]; 00347 } 00348 00349 void Hotboards_rtcc::writeReg( uint8_t address, uint8_t val ) 00350 { 00351 char buffer[2]; 00352 00353 buffer[0] = address; 00354 buffer[1] = val; 00355 00356 _i2c.write( RTC_ADDR, buffer, 2 ); 00357 } 00358 00359 uint8_t Hotboards_rtcc::bcd2bin( uint8_t val ) 00360 { 00361 return val - 6 * ( val >> 4 ); 00362 } 00363 00364 uint8_t Hotboards_rtcc::bin2bcd( uint8_t val ) 00365 { 00366 return val + 6 * ( val / 10 ); 00367 00368 }
Generated on Sat Jul 16 2022 02:47:13 by
1.7.2
Hotboards RTCC