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.
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 12 2022 23:14:19 by
1.7.2
