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: ard2pmod DS3231_Alarm_Demo MAXREFDES130_131_Demo MAXREFDES130_Demo
Fork of ds3231 by
ds3231.cpp
00001 /******************************************************************//** 00002 * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 **********************************************************************/ 00032 00033 00034 #include "ds3231.h" 00035 00036 00037 #define DS3231_I2C_ADRS 0x68 00038 #define I2C_WRITE 0 00039 #define I2C_READ 1 00040 00041 #define AM_PM (1 << 5) 00042 #define MODE (1 << 6) 00043 #define DY_DT (1 << 6) 00044 #define ALRM_MASK (1 << 7) 00045 00046 //control register bit masks 00047 #define A1IE (1 << 0) 00048 #define A2IE (1 << 1) 00049 #define INTCN (1 << 2) 00050 #define RS1 (1 << 3) 00051 #define RS2 (1 << 4) 00052 #define CONV (1 << 5) 00053 #define BBSQW (1 << 6) 00054 #define EOSC (1 << 7) 00055 00056 //status register bit masks 00057 #define A1F (1 << 0) 00058 #define A2F (1 << 1) 00059 #define BSY (1 << 2) 00060 #define EN32KHZ (1 << 3) 00061 #define OSF (1 << 7) 00062 00063 00064 //********************************************************************* 00065 Ds3231::Ds3231(PinName sda, PinName scl) 00066 :_p_i2c(new I2C(sda, scl)), _i2c_owner(true), _w_adrs((DS3231_I2C_ADRS << 1) | I2C_WRITE), 00067 _r_adrs((DS3231_I2C_ADRS << 1) | I2C_READ) 00068 { 00069 } 00070 00071 00072 //********************************************************************* 00073 Ds3231::Ds3231(I2C & i2c_bus) 00074 :_p_i2c(&i2c_bus), _i2c_owner(false), _w_adrs((DS3231_I2C_ADRS << 1) | I2C_WRITE), 00075 _r_adrs((DS3231_I2C_ADRS << 1) | I2C_READ) 00076 { 00077 } 00078 00079 00080 //********************************************************************* 00081 Ds3231::~Ds3231() 00082 { 00083 if(_i2c_owner) 00084 { 00085 delete _p_i2c; 00086 } 00087 } 00088 00089 00090 //********************************************************************* 00091 uint16_t Ds3231::set_time(ds3231_time_t time) 00092 { 00093 uint8_t data[] = {0,0,0,0}; 00094 uint8_t data_length = 0; 00095 uint8_t max_hour = 24; 00096 00097 data[data_length++] = SECONDS; 00098 data[data_length++] = uchar_2_bcd(time.seconds); 00099 data[data_length++] = uchar_2_bcd(time.minutes); 00100 00101 //format Hours register 00102 data[data_length] = uchar_2_bcd(time.hours); 00103 if(time.mode) 00104 { 00105 max_hour = max_hour/2; 00106 00107 data[data_length] |= MODE; 00108 if(time.am_pm) 00109 { 00110 data[data_length] |= AM_PM; 00111 } 00112 00113 } 00114 else 00115 { 00116 max_hour = max_hour - 1; 00117 } 00118 data_length++; 00119 00120 //Make sure data is within range. 00121 if((time.seconds > 59) || (time.minutes > 59) || (time.hours > max_hour)) 00122 { 00123 return(1); 00124 } 00125 else 00126 { 00127 return(_p_i2c->write(_w_adrs,(const char*) data, data_length)); 00128 } 00129 } 00130 00131 00132 //********************************************************************* 00133 uint16_t Ds3231::set_calendar(ds3231_calendar_t calendar) 00134 { 00135 uint8_t data[] = {0,0,0,0,0}; 00136 uint8_t data_length = 0; 00137 00138 data[data_length++] = DAY; 00139 data[data_length++] = uchar_2_bcd(calendar.day); 00140 data[data_length++] = uchar_2_bcd(calendar.date); 00141 data[data_length++] = uchar_2_bcd(calendar.month); 00142 data[data_length++] = uchar_2_bcd(calendar.year); 00143 00144 //Make sure data is within range. 00145 if(((calendar.day < 1) || (calendar.day > 7)) || 00146 ((calendar.date < 1) || (calendar.date > 31)) || 00147 ((calendar.month < 1) || (calendar.month > 12)) || 00148 (calendar.year > 99)) 00149 { 00150 return(1); 00151 } 00152 else 00153 { 00154 return(_p_i2c->write(_w_adrs,(const char*) data, data_length)); 00155 } 00156 } 00157 00158 00159 //********************************************************************* 00160 uint16_t Ds3231::set_alarm(ds3231_alrm_t alarm, bool one_r_two) 00161 { 00162 uint8_t data[] = {0,0,0,0,0}; 00163 uint8_t data_length = 0; 00164 uint8_t max_hour = 24; 00165 uint8_t mask_var = 0; 00166 00167 //setting alarm 1 or 2? 00168 if(one_r_two) 00169 { 00170 data[data_length++] = ALRM1_SECONDS; 00171 00172 //config seconds register 00173 if(alarm.am1) 00174 { 00175 mask_var |= ALRM_MASK; 00176 } 00177 data[data_length++] = (mask_var | uchar_2_bcd(alarm.seconds)); 00178 mask_var = 0; 00179 00180 //config minutes register 00181 if(alarm.am2) 00182 { 00183 mask_var |= ALRM_MASK; 00184 } 00185 data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes)); 00186 mask_var = 0; 00187 00188 //config hours register 00189 if(alarm.am3) 00190 { 00191 mask_var |= ALRM_MASK; 00192 } 00193 if(alarm.mode) 00194 { 00195 max_hour = max_hour/2; 00196 mask_var |= MODE; 00197 if(alarm.am_pm) 00198 { 00199 mask_var |= AM_PM; 00200 } 00201 } 00202 else 00203 { 00204 max_hour = max_hour - 1; 00205 } 00206 data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours)); 00207 mask_var = 0; 00208 00209 //config day/date register 00210 if(alarm.am4) 00211 { 00212 mask_var |= ALRM_MASK; 00213 } 00214 if(alarm.dy_dt) 00215 { 00216 mask_var |= DY_DT; 00217 data[data_length++] = (mask_var | uchar_2_bcd(alarm.day)); 00218 } 00219 else 00220 { 00221 data[data_length++] = (mask_var | uchar_2_bcd(alarm.date)); 00222 } 00223 mask_var = 0; 00224 } 00225 else 00226 { 00227 data[data_length++] = ALRM2_MINUTES; 00228 00229 //config minutes register 00230 if(alarm.am2) 00231 { 00232 mask_var |= ALRM_MASK; 00233 } 00234 data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes)); 00235 mask_var = 0; 00236 00237 //config hours register 00238 if(alarm.am3) 00239 { 00240 mask_var |= ALRM_MASK; 00241 } 00242 if(alarm.mode) 00243 { 00244 max_hour = max_hour/2; 00245 mask_var |= MODE; 00246 if(alarm.am_pm) 00247 { 00248 mask_var |= AM_PM; 00249 } 00250 } 00251 else 00252 { 00253 max_hour = max_hour - 1; 00254 } 00255 data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours)); 00256 mask_var = 0; 00257 00258 //config day/date register 00259 if(alarm.am4) 00260 { 00261 mask_var |= ALRM_MASK; 00262 } 00263 if(alarm.dy_dt) 00264 { 00265 mask_var |= DY_DT; 00266 data[data_length++] = (mask_var | uchar_2_bcd(alarm.day)); 00267 } 00268 else 00269 { 00270 data[data_length++] = (mask_var | uchar_2_bcd(alarm.date)); 00271 } 00272 mask_var = 0; 00273 } 00274 00275 //Make sure data is within range. 00276 if((alarm.seconds > 59) || (alarm.minutes > 59) || (alarm.hours > max_hour) || 00277 ((alarm.day < 1) || (alarm.day > 7)) || 00278 ((alarm.date < 1) || (alarm.date > 31))) 00279 { 00280 return(1); 00281 } 00282 else 00283 { 00284 return(_p_i2c->write(_w_adrs,(const char*) data, data_length)); 00285 } 00286 } 00287 00288 00289 //********************************************************************* 00290 uint16_t Ds3231::set_cntl_stat_reg(ds3231_cntl_stat_t data) 00291 { 00292 uint8_t local_data[] = {0,0,0}; 00293 uint8_t data_length = 0; 00294 00295 local_data[data_length++] = CONTROL; 00296 local_data[data_length++] = data.control; 00297 local_data[data_length++] = data.status; 00298 00299 //users responsibility to make sure data is logical 00300 return(_p_i2c->write(_w_adrs,(const char*) local_data, data_length)); 00301 } 00302 00303 00304 //********************************************************************* 00305 uint16_t Ds3231::get_time(ds3231_time_t* time) 00306 { 00307 uint16_t rtn_val = 1; 00308 uint8_t data[3]; 00309 00310 data[0] = SECONDS; 00311 rtn_val = _p_i2c->write(_w_adrs, (const char*) data, 1); 00312 00313 if(!rtn_val) 00314 { 00315 rtn_val = _p_i2c->read(_r_adrs,(char *) data, 3); 00316 00317 time->seconds = bcd_2_uchar(data[0]); 00318 time->minutes = bcd_2_uchar(data[1]); 00319 time->am_pm = (data[2]&AM_PM); 00320 time->mode = (data[2]&MODE); 00321 00322 if(time->mode) 00323 { 00324 time->hours = bcd_2_uchar((data[2]&0x1F)); 00325 } 00326 else 00327 { 00328 time->hours = bcd_2_uchar((data[2]&0x3F)); 00329 } 00330 } 00331 00332 return(rtn_val); 00333 } 00334 00335 00336 //********************************************************************* 00337 uint16_t Ds3231::get_calendar(ds3231_calendar_t* calendar) 00338 { 00339 uint16_t rtn_val = 1; 00340 uint8_t data[4]; 00341 00342 data[0] = DAY; 00343 rtn_val = _p_i2c->write(_w_adrs, (const char*) data, 1); 00344 00345 if(!rtn_val) 00346 { 00347 rtn_val = _p_i2c->read(_r_adrs,(char *) data, 4); 00348 00349 calendar->day = bcd_2_uchar(data[0]); 00350 calendar->date = bcd_2_uchar(data[1]); 00351 calendar->month = bcd_2_uchar((data[2]&0x1F)); 00352 calendar->year = bcd_2_uchar(data[3]); 00353 } 00354 00355 return(rtn_val); 00356 } 00357 00358 00359 //********************************************************************* 00360 uint16_t Ds3231::get_alarm(ds3231_alrm_t* alarm, bool one_r_two) 00361 { 00362 uint16_t rtn_val = 1; 00363 uint8_t data[4]; 00364 00365 if(one_r_two) 00366 { 00367 data[0] = ALRM1_SECONDS; 00368 rtn_val = _p_i2c->write(_w_adrs, (const char*) data, 1); 00369 00370 if(!rtn_val) 00371 { 00372 rtn_val = _p_i2c->read(_r_adrs,(char *) data, 4); 00373 00374 alarm->seconds = bcd_2_uchar(data[0]&0x7F); 00375 alarm->am1 = (data[0]&ALRM_MASK); 00376 alarm->minutes = bcd_2_uchar(data[1]&0x7F); 00377 alarm->am2 = (data[1]&ALRM_MASK); 00378 alarm->am3 = (data[2]&ALRM_MASK); 00379 alarm->am_pm = (data[2]&AM_PM); 00380 alarm->mode = (data[2]&MODE); 00381 00382 if(alarm->mode) 00383 { 00384 alarm->hours = bcd_2_uchar((data[2]&0x1F)); 00385 } 00386 else 00387 { 00388 alarm->hours = bcd_2_uchar((data[2]&0x3F)); 00389 } 00390 00391 if(data[3] & DY_DT) 00392 { 00393 alarm->dy_dt = 1; 00394 alarm->day = bcd_2_uchar(data[3]&0x0F); 00395 } 00396 else 00397 { 00398 alarm->date = bcd_2_uchar(data[3]&0x3F); 00399 } 00400 alarm->am4 = (data[3]&ALRM_MASK); 00401 } 00402 } 00403 else 00404 { 00405 data[0] = ALRM2_MINUTES; 00406 rtn_val = _p_i2c->write(_w_adrs, (const char*) data, 1); 00407 00408 if(!rtn_val) 00409 { 00410 rtn_val = _p_i2c->read(_r_adrs,(char *) data, 4); 00411 00412 alarm->minutes = bcd_2_uchar(data[0]&0x7F); 00413 alarm->am2 = (data[0]&ALRM_MASK); 00414 alarm->am3 = (data[1]&ALRM_MASK); 00415 alarm->am_pm = (data[1]&AM_PM); 00416 alarm->mode = (data[1]&MODE); 00417 00418 if(alarm->mode) 00419 { 00420 alarm->hours = bcd_2_uchar((data[1]&0x1F)); 00421 } 00422 else 00423 { 00424 alarm->hours = bcd_2_uchar((data[1]&0x3F)); 00425 } 00426 00427 if(data[2] & DY_DT) 00428 { 00429 alarm->dy_dt = 1; 00430 alarm->day = bcd_2_uchar(data[2]&0x0F); 00431 } 00432 else 00433 { 00434 alarm->date = bcd_2_uchar(data[2]&0x3F); 00435 } 00436 alarm->am4 = (data[2]&ALRM_MASK); 00437 } 00438 } 00439 00440 return(rtn_val); 00441 } 00442 00443 00444 //********************************************************************* 00445 uint16_t Ds3231::get_cntl_stat_reg(ds3231_cntl_stat_t* data) 00446 { 00447 uint16_t rtn_val = 1; 00448 uint8_t local_data[2]; 00449 00450 local_data[0] = CONTROL; 00451 rtn_val = _p_i2c->write(_w_adrs, (const char*) local_data, 1); 00452 00453 if(!rtn_val) 00454 { 00455 rtn_val = _p_i2c->read(_r_adrs,(char *) local_data, 2); 00456 00457 data->control = local_data[0]; 00458 data->status = local_data[1]; 00459 } 00460 00461 return(rtn_val); 00462 } 00463 00464 00465 //********************************************************************* 00466 uint16_t Ds3231::get_temperature(void) 00467 { 00468 uint16_t rtn_val = 1; 00469 uint8_t data[2]; 00470 00471 data[0] = MSB_TEMP; 00472 rtn_val = _p_i2c->write(_w_adrs, (const char*) data, 1); 00473 00474 if(!rtn_val) 00475 { 00476 _p_i2c->read(_r_adrs,(char *) data, 2); 00477 00478 rtn_val = data[0] << 8; 00479 rtn_val |= data[1]; 00480 } 00481 00482 return(rtn_val); 00483 } 00484 00485 00486 //********************************************************************* 00487 time_t Ds3231::get_epoch(void) 00488 { 00489 //system vars 00490 struct tm sys_time; 00491 00492 //RTC vars 00493 ds3231_time_t rtc_time = {0,0,0,0,0}; 00494 ds3231_calendar_t rtc_calendar = {0,0,0,0}; 00495 00496 get_calendar(&rtc_calendar); 00497 get_time(&rtc_time); 00498 00499 sys_time.tm_wday = rtc_calendar.day - 1; 00500 sys_time.tm_mday = rtc_calendar.date; 00501 sys_time.tm_mon = rtc_calendar.month - 1; 00502 sys_time.tm_year = rtc_calendar.year + 100; 00503 00504 //check for 12hr or 24hr mode 00505 if(rtc_time.mode) 00506 { 00507 //check am/pm 00508 if(rtc_time.am_pm && (rtc_time.hours != 12)) 00509 { 00510 sys_time.tm_hour = rtc_time.hours + 12; 00511 } 00512 else 00513 { 00514 sys_time.tm_hour = rtc_time.hours; 00515 } 00516 00517 } 00518 else 00519 { 00520 //24hr mode 00521 sys_time.tm_hour = rtc_time.hours; 00522 } 00523 00524 sys_time.tm_min = rtc_time.minutes; 00525 sys_time.tm_sec = rtc_time.seconds; 00526 00527 //make epoch time 00528 return(mktime(&sys_time)); 00529 } 00530 00531 00532 //********************************************************************* 00533 uint16_t Ds3231::uchar_2_bcd(uint8_t data) 00534 { 00535 uint16_t bcd_result = 0; 00536 00537 //Get hundreds 00538 bcd_result |= ((data/100) << 8); 00539 data = (data - (data/100)*100); 00540 00541 //Get tens 00542 bcd_result |= ((data/10) << 4); 00543 data = (data - (data/10)*10); 00544 00545 //Get ones 00546 bcd_result |= data; 00547 00548 return(bcd_result); 00549 } 00550 00551 00552 //********************************************************************* 00553 uint8_t Ds3231::bcd_2_uchar(uint8_t bcd) 00554 { 00555 uint8_t rtn_val = 0; 00556 00557 rtn_val += ((bcd&0xf0)>>4)*10; 00558 rtn_val += (bcd&0x000f); 00559 00560 return rtn_val; 00561 } 00562 00563
Generated on Tue Jul 19 2022 03:39:33 by
