Library for DS3231 RTC

Dependents:   ard2pmod DS3231demo DS3231demo_COM_Port_Output MAXREFDES99_RTC_Display ... more

DS3231 Component Page

Committer:
j3
Date:
Thu Nov 20 22:16:15 2014 +0000
Revision:
4:0beb5e9ac927
Parent:
3:312589d8185c
Child:
5:61dfe2690360
added support for bool data types in get_time and get_alarm.; fixed some comments too.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
j3 0:b00c4699ae6f 1 /******************************************************************//**
j3 0:b00c4699ae6f 2 * @file ds3231.cpp
j3 0:b00c4699ae6f 3 *
j3 0:b00c4699ae6f 4 * @author Justin Jordan
j3 0:b00c4699ae6f 5 *
j3 0:b00c4699ae6f 6 * @version 0.0
j3 0:b00c4699ae6f 7 *
j3 0:b00c4699ae6f 8 * Started: 11NOV14
j3 0:b00c4699ae6f 9 *
j3 0:b00c4699ae6f 10 * Updated:
j3 0:b00c4699ae6f 11 *
j3 0:b00c4699ae6f 12 * @brief Source file for DS3231 class
j3 0:b00c4699ae6f 13 *
j3 0:b00c4699ae6f 14 ***********************************************************************
j3 0:b00c4699ae6f 15 *
j3 0:b00c4699ae6f 16 * @copyright
j3 0:b00c4699ae6f 17 * Copyright (C) 2013 Maxim Integrated Products, Inc., All Rights Reserved.
j3 0:b00c4699ae6f 18 *
j3 0:b00c4699ae6f 19 * Permission is hereby granted, free of charge, to any person obtaining a
j3 0:b00c4699ae6f 20 * copy of this software and associated documentation files (the "Software"),
j3 0:b00c4699ae6f 21 * to deal in the Software without restriction, including without limitation
j3 0:b00c4699ae6f 22 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
j3 0:b00c4699ae6f 23 * and/or sell copies of the Software, and to permit persons to whom the
j3 0:b00c4699ae6f 24 * Software is furnished to do so, subject to the following conditions:
j3 0:b00c4699ae6f 25 *
j3 0:b00c4699ae6f 26 * The above copyright notice and this permission notice shall be included
j3 0:b00c4699ae6f 27 * in all copies or substantial portions of the Software.
j3 0:b00c4699ae6f 28 *
j3 0:b00c4699ae6f 29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
j3 0:b00c4699ae6f 30 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
j3 0:b00c4699ae6f 31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
j3 0:b00c4699ae6f 32 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
j3 0:b00c4699ae6f 33 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
j3 0:b00c4699ae6f 34 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
j3 0:b00c4699ae6f 35 * OTHER DEALINGS IN THE SOFTWARE.
j3 0:b00c4699ae6f 36 *
j3 0:b00c4699ae6f 37 * Except as contained in this notice, the name of Maxim Integrated
j3 0:b00c4699ae6f 38 * Products, Inc. shall not be used except as stated in the Maxim Integrated
j3 0:b00c4699ae6f 39 * Products, Inc. Branding Policy.
j3 0:b00c4699ae6f 40 *
j3 0:b00c4699ae6f 41 * The mere transfer of this software does not imply any licenses
j3 0:b00c4699ae6f 42 * of trade secrets, proprietary technology, copyrights, patents,
j3 0:b00c4699ae6f 43 * trademarks, maskwork rights, or any other form of intellectual
j3 0:b00c4699ae6f 44 * property whatsoever. Maxim Integrated Products, Inc. retains all
j3 0:b00c4699ae6f 45 * ownership rights.
j3 0:b00c4699ae6f 46 **********************************************************************/
j3 0:b00c4699ae6f 47
j3 0:b00c4699ae6f 48
j3 0:b00c4699ae6f 49 #include "ds3231.h"
j3 0:b00c4699ae6f 50
j3 0:b00c4699ae6f 51
j3 0:b00c4699ae6f 52 /**********************************************************//**
j3 0:b00c4699ae6f 53 * Constructor for Ds3231 Class
j3 0:b00c4699ae6f 54 *
j3 0:b00c4699ae6f 55 * On Entry:
j3 1:c814af60fdbf 56 * @param[in] sda - sda pin of I2C bus
j3 1:c814af60fdbf 57 * @param[in] scl - scl pin of I2C bus
j3 0:b00c4699ae6f 58 *
j3 0:b00c4699ae6f 59 * On Exit:
j3 0:b00c4699ae6f 60 * @return none
j3 0:b00c4699ae6f 61 *
j3 0:b00c4699ae6f 62 * Example:
j3 0:b00c4699ae6f 63 * @code
j3 0:b00c4699ae6f 64 *
j3 0:b00c4699ae6f 65 * //instantiate rtc object
j3 1:c814af60fdbf 66 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 67 *
j3 0:b00c4699ae6f 68 * @endcode
j3 0:b00c4699ae6f 69 **************************************************************/
j3 1:c814af60fdbf 70 Ds3231::Ds3231(PinName sda, PinName scl) : I2C(sda, scl)
j3 0:b00c4699ae6f 71 {
j3 0:b00c4699ae6f 72 w_adrs = ((DS3231_I2C_ADRS << 1) | I2C_WRITE);
j3 0:b00c4699ae6f 73 r_adrs = ((DS3231_I2C_ADRS << 1) | I2C_READ);
j3 0:b00c4699ae6f 74 }
j3 0:b00c4699ae6f 75
j3 0:b00c4699ae6f 76
j3 0:b00c4699ae6f 77 /**********************************************************//**
j3 0:b00c4699ae6f 78 * Sets the time on DS3231
j3 2:4e6e761c60f2 79 * Struct data is in integrer format, not BCD. Fx will convert
j3 2:4e6e761c60f2 80 * to BCD for you.
j3 0:b00c4699ae6f 81 *
j3 0:b00c4699ae6f 82 * On Entry:
j3 0:b00c4699ae6f 83 * @param[in] time - struct cotaining time data;
j3 0:b00c4699ae6f 84 *
j3 0:b00c4699ae6f 85 * On Exit:
j3 0:b00c4699ae6f 86 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 87 *
j3 0:b00c4699ae6f 88 * Example:
j3 0:b00c4699ae6f 89 * @code
j3 0:b00c4699ae6f 90 *
j3 0:b00c4699ae6f 91 * //instantiate rtc object
j3 1:c814af60fdbf 92 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 93 *
j3 4:0beb5e9ac927 94 * //time = 12:00:00 AM 12hr mode
j3 4:0beb5e9ac927 95 * ds3231_time_t time = {12, 0, 0, 0, 1}
j3 0:b00c4699ae6f 96 * uint16_t rtn_val;
j3 0:b00c4699ae6f 97 *
j3 0:b00c4699ae6f 98 * rtn_val = rtc.set_time(time);
j3 0:b00c4699ae6f 99 *
j3 0:b00c4699ae6f 100 * @endcode
j3 0:b00c4699ae6f 101 **************************************************************/
j3 0:b00c4699ae6f 102 uint16_t Ds3231::set_time(ds3231_time_t time)
j3 0:b00c4699ae6f 103 {
j3 2:4e6e761c60f2 104 uint8_t data[] = {0,0,0,0};
j3 2:4e6e761c60f2 105 uint8_t data_length = 0;
j3 2:4e6e761c60f2 106 uint8_t max_hour = 24;
j3 0:b00c4699ae6f 107
j3 2:4e6e761c60f2 108 data[data_length++] = SECONDS;
j3 2:4e6e761c60f2 109 data[data_length++] = uchar_2_bcd(time.seconds);
j3 2:4e6e761c60f2 110 data[data_length++] = uchar_2_bcd(time.minutes);
j3 2:4e6e761c60f2 111
j3 2:4e6e761c60f2 112 //format Hours register
j3 2:4e6e761c60f2 113 data[data_length] = uchar_2_bcd(time.hours);
j3 2:4e6e761c60f2 114 if(time.mode)
j3 2:4e6e761c60f2 115 {
j3 2:4e6e761c60f2 116 max_hour = max_hour/2;
j3 2:4e6e761c60f2 117
j3 2:4e6e761c60f2 118 data[data_length] |= MODE;
j3 2:4e6e761c60f2 119 if(time.am_pm)
j3 2:4e6e761c60f2 120 {
j3 2:4e6e761c60f2 121 data[data_length] |= AM_PM;
j3 2:4e6e761c60f2 122 }
j3 2:4e6e761c60f2 123
j3 2:4e6e761c60f2 124 }
j3 2:4e6e761c60f2 125 else
j3 2:4e6e761c60f2 126 {
j3 2:4e6e761c60f2 127 max_hour = max_hour - 1;
j3 2:4e6e761c60f2 128 }
j3 2:4e6e761c60f2 129 data_length++;
j3 2:4e6e761c60f2 130
j3 2:4e6e761c60f2 131 //Test for good data.
j3 2:4e6e761c60f2 132 if((time.seconds > 59) || (time.minutes > 59) || (time.hours > max_hour))
j3 2:4e6e761c60f2 133 {
j3 2:4e6e761c60f2 134 return(1);
j3 2:4e6e761c60f2 135 }
j3 2:4e6e761c60f2 136 else
j3 2:4e6e761c60f2 137 {
j3 2:4e6e761c60f2 138 return(write(w_adrs,(const char*) data, data_length));
j3 2:4e6e761c60f2 139 }
j3 0:b00c4699ae6f 140 }
j3 0:b00c4699ae6f 141
j3 0:b00c4699ae6f 142
j3 0:b00c4699ae6f 143 /**********************************************************//**
j3 0:b00c4699ae6f 144 * Sets the calendar on DS3231
j3 0:b00c4699ae6f 145 *
j3 0:b00c4699ae6f 146 * On Entry:
j3 3:312589d8185c 147 * @param[in] calendar - struct cotaining calendar data
j3 0:b00c4699ae6f 148 *
j3 0:b00c4699ae6f 149 * On Exit:
j3 0:b00c4699ae6f 150 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 151 *
j3 0:b00c4699ae6f 152 * Example:
j3 0:b00c4699ae6f 153 * @code
j3 0:b00c4699ae6f 154 *
j3 0:b00c4699ae6f 155 * //instantiate rtc object
j3 1:c814af60fdbf 156 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 157 *
j3 0:b00c4699ae6f 158 * //see datasheet for calendar format
j3 0:b00c4699ae6f 159 * ds3231_calendar_t calendar = {1, 1, 1, 0};
j3 0:b00c4699ae6f 160 * uint16_t rtn_val;
j3 0:b00c4699ae6f 161 *
j3 0:b00c4699ae6f 162 * rtn_val = rtc.set_calendar(calendar);
j3 0:b00c4699ae6f 163 *
j3 0:b00c4699ae6f 164 * @endcode
j3 0:b00c4699ae6f 165 **************************************************************/
j3 0:b00c4699ae6f 166 uint16_t Ds3231::set_calendar(ds3231_calendar_t calendar)
j3 0:b00c4699ae6f 167 {
j3 2:4e6e761c60f2 168 uint8_t data[] = {0,0,0,0,0};
j3 2:4e6e761c60f2 169 uint8_t data_length = 0;
j3 2:4e6e761c60f2 170
j3 2:4e6e761c60f2 171 data[data_length++] = DAY;
j3 2:4e6e761c60f2 172 data[data_length++] = uchar_2_bcd(calendar.day);
j3 2:4e6e761c60f2 173 data[data_length++] = uchar_2_bcd(calendar.date);
j3 2:4e6e761c60f2 174 data[data_length++] = uchar_2_bcd(calendar.month);
j3 2:4e6e761c60f2 175 data[data_length++] = uchar_2_bcd(calendar.year);
j3 0:b00c4699ae6f 176
j3 2:4e6e761c60f2 177 //users responsibility to make sure calendar is logical
j3 2:4e6e761c60f2 178 return(write(w_adrs,(const char*) data, data_length));
j3 0:b00c4699ae6f 179 }
j3 0:b00c4699ae6f 180
j3 0:b00c4699ae6f 181
j3 0:b00c4699ae6f 182 /**********************************************************//**
j3 0:b00c4699ae6f 183 * Set either Alarm1 or Alarm2 of DS3231
j3 0:b00c4699ae6f 184 *
j3 0:b00c4699ae6f 185 * On Entry:
j3 0:b00c4699ae6f 186 * @param[in] alarm - struct cotaining alarm data
j3 3:312589d8185c 187 *
j3 0:b00c4699ae6f 188 * @param[in] one_r_two - TRUE for Alarm1 and FALSE for
j3 0:b00c4699ae6f 189 * Alarm2
j3 0:b00c4699ae6f 190 *
j3 0:b00c4699ae6f 191 * On Exit:
j3 0:b00c4699ae6f 192 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 193 *
j3 0:b00c4699ae6f 194 * Example:
j3 0:b00c4699ae6f 195 * @code
j3 0:b00c4699ae6f 196 *
j3 0:b00c4699ae6f 197 * //instantiate rtc object
j3 1:c814af60fdbf 198 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 199 *
j3 4:0beb5e9ac927 200 * //see ds3231.h for .members and datasheet for alarm format
j3 4:0beb5e9ac927 201 * ds3231_alrm_t alarm;
j3 0:b00c4699ae6f 202 * uint16_t rtn_val;
j3 0:b00c4699ae6f 203 *
j3 0:b00c4699ae6f 204 * rtn_val = rtc.set_alarm(alarm, FALSE);
j3 0:b00c4699ae6f 205 *
j3 0:b00c4699ae6f 206 * @endcode
j3 0:b00c4699ae6f 207 **************************************************************/
j3 0:b00c4699ae6f 208 uint16_t Ds3231::set_alarm(ds3231_alrm_t alarm, bool one_r_two)
j3 0:b00c4699ae6f 209 {
j3 2:4e6e761c60f2 210 uint8_t data[] = {0,0,0,0,0};
j3 2:4e6e761c60f2 211 uint8_t data_length = 0;
j3 2:4e6e761c60f2 212 uint8_t max_hour = 24;
j3 2:4e6e761c60f2 213 uint8_t mask_var = 0;
j3 2:4e6e761c60f2 214
j3 2:4e6e761c60f2 215 //setting alarm 1 or 2?
j3 2:4e6e761c60f2 216 if(one_r_two)
j3 2:4e6e761c60f2 217 {
j3 2:4e6e761c60f2 218 data[data_length++] = ALRM1_SECONDS;
j3 2:4e6e761c60f2 219
j3 2:4e6e761c60f2 220 //config seconds register
j3 2:4e6e761c60f2 221 if(alarm.am1)
j3 2:4e6e761c60f2 222 {
j3 2:4e6e761c60f2 223 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 224 }
j3 2:4e6e761c60f2 225 data[data_length++] = (mask_var | uchar_2_bcd(alarm.seconds));
j3 2:4e6e761c60f2 226 mask_var = 0;
j3 2:4e6e761c60f2 227
j3 2:4e6e761c60f2 228 //config minutes register
j3 2:4e6e761c60f2 229 if(alarm.am2)
j3 2:4e6e761c60f2 230 {
j3 2:4e6e761c60f2 231 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 232 }
j3 2:4e6e761c60f2 233 data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes));
j3 2:4e6e761c60f2 234 mask_var = 0;
j3 2:4e6e761c60f2 235
j3 2:4e6e761c60f2 236 //config hours register
j3 2:4e6e761c60f2 237 if(alarm.am3)
j3 2:4e6e761c60f2 238 {
j3 2:4e6e761c60f2 239 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 240 }
j3 2:4e6e761c60f2 241 if(alarm.mode)
j3 2:4e6e761c60f2 242 {
j3 2:4e6e761c60f2 243 max_hour = max_hour/2;
j3 2:4e6e761c60f2 244 mask_var |= MODE;
j3 2:4e6e761c60f2 245 if(alarm.am_pm)
j3 2:4e6e761c60f2 246 {
j3 2:4e6e761c60f2 247 mask_var |= AM_PM;
j3 2:4e6e761c60f2 248 }
j3 2:4e6e761c60f2 249 }
j3 2:4e6e761c60f2 250 else
j3 2:4e6e761c60f2 251 {
j3 2:4e6e761c60f2 252 max_hour = max_hour - 1;
j3 2:4e6e761c60f2 253 }
j3 2:4e6e761c60f2 254 data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours));
j3 2:4e6e761c60f2 255 mask_var = 0;
j3 2:4e6e761c60f2 256
j3 2:4e6e761c60f2 257 //config day/date register
j3 2:4e6e761c60f2 258 if(alarm.am4)
j3 2:4e6e761c60f2 259 {
j3 2:4e6e761c60f2 260 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 261 }
j3 2:4e6e761c60f2 262 if(alarm.dy_dt)
j3 2:4e6e761c60f2 263 {
j3 2:4e6e761c60f2 264 mask_var |= DY_DT;
j3 2:4e6e761c60f2 265 data[data_length++] = (mask_var | uchar_2_bcd(alarm.day));
j3 2:4e6e761c60f2 266 }
j3 2:4e6e761c60f2 267 else
j3 2:4e6e761c60f2 268 {
j3 2:4e6e761c60f2 269 data[data_length++] = (mask_var | uchar_2_bcd(alarm.date));
j3 2:4e6e761c60f2 270 }
j3 2:4e6e761c60f2 271 mask_var = 0;
j3 2:4e6e761c60f2 272 }
j3 2:4e6e761c60f2 273 else
j3 2:4e6e761c60f2 274 {
j3 2:4e6e761c60f2 275 data[data_length++] = ALRM2_MINUTES;
j3 2:4e6e761c60f2 276
j3 2:4e6e761c60f2 277 //config minutes register
j3 2:4e6e761c60f2 278 if(alarm.am2)
j3 2:4e6e761c60f2 279 {
j3 2:4e6e761c60f2 280 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 281 }
j3 2:4e6e761c60f2 282 data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes));
j3 2:4e6e761c60f2 283 mask_var = 0;
j3 2:4e6e761c60f2 284
j3 2:4e6e761c60f2 285 //config hours register
j3 2:4e6e761c60f2 286 if(alarm.am3)
j3 2:4e6e761c60f2 287 {
j3 2:4e6e761c60f2 288 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 289 }
j3 2:4e6e761c60f2 290 if(alarm.mode)
j3 2:4e6e761c60f2 291 {
j3 2:4e6e761c60f2 292 max_hour = max_hour/2;
j3 2:4e6e761c60f2 293 mask_var |= MODE;
j3 2:4e6e761c60f2 294 if(alarm.am_pm)
j3 2:4e6e761c60f2 295 {
j3 2:4e6e761c60f2 296 mask_var |= AM_PM;
j3 2:4e6e761c60f2 297 }
j3 2:4e6e761c60f2 298 }
j3 2:4e6e761c60f2 299 else
j3 2:4e6e761c60f2 300 {
j3 2:4e6e761c60f2 301 max_hour = max_hour - 1;
j3 2:4e6e761c60f2 302 }
j3 2:4e6e761c60f2 303 data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours));
j3 2:4e6e761c60f2 304 mask_var = 0;
j3 2:4e6e761c60f2 305
j3 2:4e6e761c60f2 306 //config day/date register
j3 2:4e6e761c60f2 307 if(alarm.am4)
j3 2:4e6e761c60f2 308 {
j3 2:4e6e761c60f2 309 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 310 }
j3 2:4e6e761c60f2 311 if(alarm.dy_dt)
j3 2:4e6e761c60f2 312 {
j3 2:4e6e761c60f2 313 mask_var |= DY_DT;
j3 2:4e6e761c60f2 314 data[data_length++] = (mask_var | uchar_2_bcd(alarm.day));
j3 2:4e6e761c60f2 315 }
j3 2:4e6e761c60f2 316 else
j3 2:4e6e761c60f2 317 {
j3 2:4e6e761c60f2 318 data[data_length++] = (mask_var | uchar_2_bcd(alarm.date));
j3 2:4e6e761c60f2 319 }
j3 2:4e6e761c60f2 320 mask_var = 0;
j3 2:4e6e761c60f2 321 }
j3 2:4e6e761c60f2 322
j3 2:4e6e761c60f2 323 //Test for good data.
j3 2:4e6e761c60f2 324 if((alarm.seconds > 59) || (alarm.minutes > 59) || (alarm.hours > max_hour) || (alarm.day > 7) || (alarm.date > 31))
j3 2:4e6e761c60f2 325 {
j3 2:4e6e761c60f2 326 return(1);
j3 2:4e6e761c60f2 327 }
j3 2:4e6e761c60f2 328 else
j3 2:4e6e761c60f2 329 {
j3 2:4e6e761c60f2 330 return(write(w_adrs,(const char*) data, data_length));
j3 2:4e6e761c60f2 331 }
j3 0:b00c4699ae6f 332 }
j3 0:b00c4699ae6f 333
j3 0:b00c4699ae6f 334
j3 0:b00c4699ae6f 335 /**********************************************************//**
j3 0:b00c4699ae6f 336 * Set control and status registers of DS3231
j3 0:b00c4699ae6f 337 *
j3 0:b00c4699ae6f 338 * On Entry:
j3 0:b00c4699ae6f 339 * @param[in] data - Struct containing control and status
j3 0:b00c4699ae6f 340 * register data
j3 0:b00c4699ae6f 341 *
j3 0:b00c4699ae6f 342 * On Exit:
j3 0:b00c4699ae6f 343 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 344 *
j3 0:b00c4699ae6f 345 * Example:
j3 0:b00c4699ae6f 346 * @code
j3 0:b00c4699ae6f 347 *
j3 0:b00c4699ae6f 348 * //instantiate rtc object
j3 1:c814af60fdbf 349 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 350 *
j3 0:b00c4699ae6f 351 * //do not use 0xAA, see datasheet for appropriate data
j3 0:b00c4699ae6f 352 * ds3231_cntl_stat_t data = {0xAA, 0xAA};
j3 0:b00c4699ae6f 353 *
j3 0:b00c4699ae6f 354 * rtn_val = rtc.set_cntl_stat_reg(data);
j3 0:b00c4699ae6f 355 *
j3 0:b00c4699ae6f 356 * @endcode
j3 0:b00c4699ae6f 357 **************************************************************/
j3 0:b00c4699ae6f 358 uint16_t Ds3231::set_cntl_stat_reg(ds3231_cntl_stat_t data)
j3 0:b00c4699ae6f 359 {
j3 2:4e6e761c60f2 360 uint8_t local_data[] = {0,0,0};
j3 2:4e6e761c60f2 361 uint8_t data_length = 0;
j3 2:4e6e761c60f2 362
j3 2:4e6e761c60f2 363 local_data[data_length++] = CONTROL;
j3 2:4e6e761c60f2 364 local_data[data_length++] = data.control;
j3 2:4e6e761c60f2 365 local_data[data_length++] = data.status;
j3 0:b00c4699ae6f 366
j3 2:4e6e761c60f2 367 //users responsibility to make sure data is logical
j3 2:4e6e761c60f2 368 return(write(w_adrs,(const char*) local_data, data_length));
j3 0:b00c4699ae6f 369 }
j3 0:b00c4699ae6f 370
j3 0:b00c4699ae6f 371
j3 0:b00c4699ae6f 372 /**********************************************************//**
j3 0:b00c4699ae6f 373 * Gets the time on DS3231
j3 0:b00c4699ae6f 374 *
j3 0:b00c4699ae6f 375 * On Entry:
j3 4:0beb5e9ac927 376 * @param[in] time - pointer to struct for storing time data
j3 0:b00c4699ae6f 377 *
j3 0:b00c4699ae6f 378 * On Exit:
j3 2:4e6e761c60f2 379 * @param[out] time - contains current integrer rtc time
j3 2:4e6e761c60f2 380 * data
j3 0:b00c4699ae6f 381 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 382 *
j3 0:b00c4699ae6f 383 * Example:
j3 0:b00c4699ae6f 384 * @code
j3 0:b00c4699ae6f 385 *
j3 0:b00c4699ae6f 386 * //instantiate rtc object
j3 1:c814af60fdbf 387 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 388 *
j3 4:0beb5e9ac927 389 * //time = 12:00:00 AM 12hr mode
j3 4:0beb5e9ac927 390 * ds3231_time_t time = {12, 0, 0, 0, 1}
j3 0:b00c4699ae6f 391 * uint16_t rtn_val;
j3 0:b00c4699ae6f 392 *
j3 3:312589d8185c 393 * rtn_val = rtc.get_time(&time);
j3 0:b00c4699ae6f 394 *
j3 0:b00c4699ae6f 395 * @endcode
j3 0:b00c4699ae6f 396 **************************************************************/
j3 2:4e6e761c60f2 397 uint16_t Ds3231::get_time(ds3231_time_t* time)
j3 0:b00c4699ae6f 398 {
j3 2:4e6e761c60f2 399 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 400 uint8_t data[3];
j3 2:4e6e761c60f2 401
j3 2:4e6e761c60f2 402 data[0] = SECONDS;
j3 2:4e6e761c60f2 403 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 404
j3 2:4e6e761c60f2 405 if(!rtn_val)
j3 2:4e6e761c60f2 406 {
j3 2:4e6e761c60f2 407 rtn_val = read(r_adrs,(char *) data, 3);
j3 2:4e6e761c60f2 408
j3 2:4e6e761c60f2 409 time->seconds = bcd_2_uchar(data[0]);
j3 2:4e6e761c60f2 410 time->minutes = bcd_2_uchar(data[1]);
j3 2:4e6e761c60f2 411 time->hours = bcd_2_uchar((data[2]&0x1F));
j3 4:0beb5e9ac927 412 time->am_pm = (data[2]&AM_PM);
j3 4:0beb5e9ac927 413 time->mode = (data[2]&MODE);
j3 2:4e6e761c60f2 414 }
j3 2:4e6e761c60f2 415
j3 2:4e6e761c60f2 416 return(rtn_val);
j3 0:b00c4699ae6f 417 }
j3 0:b00c4699ae6f 418
j3 0:b00c4699ae6f 419
j3 0:b00c4699ae6f 420 /**********************************************************//**
j3 0:b00c4699ae6f 421 * Gets the calendar on DS3231
j3 0:b00c4699ae6f 422 *
j3 0:b00c4699ae6f 423 * On Entry:
j3 2:4e6e761c60f2 424 * @param[in] calendar - pointer to struct for storing
j3 4:0beb5e9ac927 425 * calendar data
j3 0:b00c4699ae6f 426 *
j3 0:b00c4699ae6f 427 * On Exit:
j3 2:4e6e761c60f2 428 * @param[out] calendar - contains current integer rtc
j3 2:4e6e761c60f2 429 * calendar data
j3 0:b00c4699ae6f 430 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 431 *
j3 0:b00c4699ae6f 432 * Example:
j3 0:b00c4699ae6f 433 * @code
j3 0:b00c4699ae6f 434 *
j3 0:b00c4699ae6f 435 * //instantiate rtc object
j3 1:c814af60fdbf 436 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 437 *
j3 0:b00c4699ae6f 438 * //see datasheet for calendar format
j3 0:b00c4699ae6f 439 * ds3231_calendar_t calendar = {1, 1, 1, 0};
j3 0:b00c4699ae6f 440 * uint16_t rtn_val;
j3 0:b00c4699ae6f 441 *
j3 3:312589d8185c 442 * rtn_val = rtc.get_calendar(&calendar);
j3 0:b00c4699ae6f 443 *
j3 0:b00c4699ae6f 444 * @endcode
j3 0:b00c4699ae6f 445 **************************************************************/
j3 2:4e6e761c60f2 446 uint16_t Ds3231::get_calendar(ds3231_calendar_t* calendar)
j3 0:b00c4699ae6f 447 {
j3 2:4e6e761c60f2 448 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 449 uint8_t data[4];
j3 2:4e6e761c60f2 450
j3 2:4e6e761c60f2 451 data[0] = DAY;
j3 2:4e6e761c60f2 452 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 453
j3 2:4e6e761c60f2 454 if(!rtn_val)
j3 2:4e6e761c60f2 455 {
j3 2:4e6e761c60f2 456 rtn_val = read(r_adrs,(char *) data, 4);
j3 2:4e6e761c60f2 457
j3 2:4e6e761c60f2 458 calendar->day = bcd_2_uchar(data[0]);
j3 2:4e6e761c60f2 459 calendar->date = bcd_2_uchar(data[1]);
j3 2:4e6e761c60f2 460 calendar->month = bcd_2_uchar((data[2]&0x1F));
j3 2:4e6e761c60f2 461 calendar->year = bcd_2_uchar(data[3]);
j3 2:4e6e761c60f2 462 }
j3 2:4e6e761c60f2 463
j3 2:4e6e761c60f2 464 return(rtn_val);
j3 0:b00c4699ae6f 465 }
j3 0:b00c4699ae6f 466
j3 0:b00c4699ae6f 467
j3 0:b00c4699ae6f 468 /**********************************************************//**
j3 0:b00c4699ae6f 469 * Get either Alarm1 or Alarm2 of DS3231
j3 0:b00c4699ae6f 470 *
j3 0:b00c4699ae6f 471 * On Entry:
j3 2:4e6e761c60f2 472 * @param[in] alarm - pointer to struct for storing alarm
j3 2:4e6e761c60f2 473 * data;
j3 2:4e6e761c60f2 474 *
j3 0:b00c4699ae6f 475 * @param[in] one_r_two - TRUE for Alarm1 and FALSE for
j3 0:b00c4699ae6f 476 * Alarm2
j3 0:b00c4699ae6f 477 *
j3 0:b00c4699ae6f 478 * On Exit:
j3 2:4e6e761c60f2 479 * @param[out] alarm - contains integer alarm data
j3 0:b00c4699ae6f 480 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 481 *
j3 0:b00c4699ae6f 482 * Example:
j3 0:b00c4699ae6f 483 * @code
j3 0:b00c4699ae6f 484 *
j3 0:b00c4699ae6f 485 * //instantiate rtc object
j3 1:c814af60fdbf 486 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 487 *
j3 4:0beb5e9ac927 488 * //see ds3231.h for .members and datasheet for alarm format
j3 4:0beb5e9ac927 489 * ds3231_alrm_t alarm;
j3 0:b00c4699ae6f 490 * uint16_t rtn_val;
j3 0:b00c4699ae6f 491 *
j3 3:312589d8185c 492 * rtn_val = rtc.get_alarm(&alarm, FALSE);
j3 0:b00c4699ae6f 493 *
j3 0:b00c4699ae6f 494 * @endcode
j3 0:b00c4699ae6f 495 **************************************************************/
j3 2:4e6e761c60f2 496 uint16_t Ds3231::get_alarm(ds3231_alrm_t* alarm, bool one_r_two)
j3 0:b00c4699ae6f 497 {
j3 2:4e6e761c60f2 498 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 499 uint8_t data[4];
j3 2:4e6e761c60f2 500
j3 2:4e6e761c60f2 501 if(one_r_two)
j3 2:4e6e761c60f2 502 {
j3 2:4e6e761c60f2 503 data[0] = ALRM1_SECONDS;
j3 2:4e6e761c60f2 504 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 505
j3 2:4e6e761c60f2 506 if(!rtn_val)
j3 2:4e6e761c60f2 507 {
j3 2:4e6e761c60f2 508 rtn_val = read(r_adrs,(char *) data, 4);
j3 2:4e6e761c60f2 509
j3 2:4e6e761c60f2 510 alarm->seconds = bcd_2_uchar(data[0]&0x7F);
j3 4:0beb5e9ac927 511 alarm->am1 = (data[0]&ALRM_MASK);
j3 2:4e6e761c60f2 512 alarm->minutes = bcd_2_uchar(data[1]&0x7F);
j3 4:0beb5e9ac927 513 alarm->am2 = (data[1]&ALRM_MASK);
j3 2:4e6e761c60f2 514 alarm->hours = bcd_2_uchar(data[2]&0x1F);
j3 4:0beb5e9ac927 515 alarm->am3 = (data[2]&ALRM_MASK);
j3 4:0beb5e9ac927 516 alarm->am_pm = (data[2]&AM_PM);
j3 4:0beb5e9ac927 517 alarm->mode = (data[2]&MODE);
j3 2:4e6e761c60f2 518
j3 2:4e6e761c60f2 519 if(data[3] & DY_DT)
j3 2:4e6e761c60f2 520 {
j3 4:0beb5e9ac927 521 alarm->dy_dt = 1;
j3 2:4e6e761c60f2 522 alarm->day = bcd_2_uchar(data[3]&0x0F);
j3 2:4e6e761c60f2 523 }
j3 2:4e6e761c60f2 524 else
j3 2:4e6e761c60f2 525 {
j3 2:4e6e761c60f2 526 alarm->date = bcd_2_uchar(data[3]&0x3F);
j3 2:4e6e761c60f2 527 }
j3 4:0beb5e9ac927 528 alarm->am4 = (data[3]&ALRM_MASK);
j3 2:4e6e761c60f2 529 }
j3 2:4e6e761c60f2 530 }
j3 2:4e6e761c60f2 531 else
j3 2:4e6e761c60f2 532 {
j3 2:4e6e761c60f2 533 data[0] = ALRM2_MINUTES;
j3 2:4e6e761c60f2 534 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 535
j3 2:4e6e761c60f2 536 if(!rtn_val)
j3 2:4e6e761c60f2 537 {
j3 2:4e6e761c60f2 538 rtn_val = read(r_adrs,(char *) data, 4);
j3 2:4e6e761c60f2 539
j3 2:4e6e761c60f2 540 alarm->minutes = bcd_2_uchar(data[0]&0x7F);
j3 4:0beb5e9ac927 541 alarm->am2 = (data[0]&ALRM_MASK);
j3 2:4e6e761c60f2 542 alarm->hours = bcd_2_uchar(data[1]&0x1F);
j3 4:0beb5e9ac927 543 alarm->am3 = (data[1]&ALRM_MASK);
j3 4:0beb5e9ac927 544 alarm->am_pm = (data[1]&AM_PM);
j3 4:0beb5e9ac927 545 alarm->mode = (data[1]&MODE);
j3 2:4e6e761c60f2 546
j3 4:0beb5e9ac927 547 if(data[2] & DY_DT)
j3 2:4e6e761c60f2 548 {
j3 4:0beb5e9ac927 549 alarm->dy_dt = 1;
j3 2:4e6e761c60f2 550 alarm->day = bcd_2_uchar(data[2]&0x0F);
j3 2:4e6e761c60f2 551 }
j3 2:4e6e761c60f2 552 else
j3 2:4e6e761c60f2 553 {
j3 2:4e6e761c60f2 554 alarm->date = bcd_2_uchar(data[2]&0x3F);
j3 2:4e6e761c60f2 555 }
j3 4:0beb5e9ac927 556 alarm->am4 = (data[2]&ALRM_MASK);
j3 2:4e6e761c60f2 557 }
j3 2:4e6e761c60f2 558 }
j3 2:4e6e761c60f2 559
j3 2:4e6e761c60f2 560 return(rtn_val);
j3 0:b00c4699ae6f 561 }
j3 0:b00c4699ae6f 562
j3 0:b00c4699ae6f 563
j3 0:b00c4699ae6f 564 /**********************************************************//**
j3 0:b00c4699ae6f 565 * Get control and status registers of DS3231
j3 0:b00c4699ae6f 566 *
j3 0:b00c4699ae6f 567 * On Entry:
j3 2:4e6e761c60f2 568 * @param[in] data - pointer to struct for storing control
j3 4:0beb5e9ac927 569 * and status register data
j3 0:b00c4699ae6f 570 *
j3 0:b00c4699ae6f 571 * On Exit:
j3 0:b00c4699ae6f 572 * @param[out] data - contains control and status registers
j3 0:b00c4699ae6f 573 * data
j3 0:b00c4699ae6f 574 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 575 *
j3 0:b00c4699ae6f 576 * Example:
j3 0:b00c4699ae6f 577 * @code
j3 0:b00c4699ae6f 578 *
j3 0:b00c4699ae6f 579 * //instantiate rtc object
j3 1:c814af60fdbf 580 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 581 *
j3 0:b00c4699ae6f 582 * //do not use 0xAA, see datasheet for appropriate data
j3 0:b00c4699ae6f 583 * ds3231_cntl_stat_t data = {0xAA, 0xAA};
j3 0:b00c4699ae6f 584 *
j3 3:312589d8185c 585 * rtn_val = rtc.get_cntl_stat_reg(&data);
j3 0:b00c4699ae6f 586 *
j3 0:b00c4699ae6f 587 * @endcode
j3 0:b00c4699ae6f 588 **************************************************************/
j3 2:4e6e761c60f2 589 uint16_t Ds3231::get_cntl_stat_reg(ds3231_cntl_stat_t* data)
j3 0:b00c4699ae6f 590 {
j3 2:4e6e761c60f2 591 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 592 uint8_t local_data[2];
j3 2:4e6e761c60f2 593
j3 2:4e6e761c60f2 594 local_data[0] = CONTROL;
j3 2:4e6e761c60f2 595 rtn_val = write(w_adrs, (const char*) local_data, 1);
j3 2:4e6e761c60f2 596
j3 2:4e6e761c60f2 597 if(!rtn_val)
j3 2:4e6e761c60f2 598 {
j3 2:4e6e761c60f2 599 rtn_val = read(r_adrs,(char *) local_data, 2);
j3 2:4e6e761c60f2 600
j3 2:4e6e761c60f2 601 data->control = local_data[0];
j3 2:4e6e761c60f2 602 data->status = local_data[1];
j3 2:4e6e761c60f2 603 }
j3 2:4e6e761c60f2 604
j3 2:4e6e761c60f2 605 return(rtn_val);
j3 0:b00c4699ae6f 606 }
j3 0:b00c4699ae6f 607
j3 0:b00c4699ae6f 608
j3 0:b00c4699ae6f 609 /**********************************************************//**
j3 0:b00c4699ae6f 610 * Get temperature data of DS3231
j3 0:b00c4699ae6f 611 *
j3 0:b00c4699ae6f 612 * On Entry:
j3 0:b00c4699ae6f 613 *
j3 0:b00c4699ae6f 614 * On Exit:
j3 2:4e6e761c60f2 615 * @return return value = raw temperature data
j3 0:b00c4699ae6f 616 *
j3 0:b00c4699ae6f 617 * Example:
j3 0:b00c4699ae6f 618 * @code
j3 0:b00c4699ae6f 619 *
j3 0:b00c4699ae6f 620 * //instantiate rtc object
j3 1:c814af60fdbf 621 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 622 *
j3 0:b00c4699ae6f 623 * uint16_t temp;
j3 0:b00c4699ae6f 624 *
j3 2:4e6e761c60f2 625 * temp = rtc.get_temperature();
j3 0:b00c4699ae6f 626 *
j3 0:b00c4699ae6f 627 * @endcode
j3 0:b00c4699ae6f 628 **************************************************************/
j3 2:4e6e761c60f2 629 uint16_t Ds3231::get_temperature(void)
j3 0:b00c4699ae6f 630 {
j3 2:4e6e761c60f2 631 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 632 uint8_t data[2];
j3 2:4e6e761c60f2 633
j3 2:4e6e761c60f2 634 data[0] = MSB_TEMP;
j3 2:4e6e761c60f2 635 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 636
j3 2:4e6e761c60f2 637 if(!rtn_val)
j3 2:4e6e761c60f2 638 {
j3 2:4e6e761c60f2 639 read(r_adrs,(char *) data, 2);
j3 2:4e6e761c60f2 640
j3 2:4e6e761c60f2 641 rtn_val = data[0] << 8;
j3 2:4e6e761c60f2 642 rtn_val |= data[1];
j3 2:4e6e761c60f2 643 }
j3 2:4e6e761c60f2 644
j3 2:4e6e761c60f2 645 return(rtn_val);
j3 0:b00c4699ae6f 646 }
j3 0:b00c4699ae6f 647
j3 2:4e6e761c60f2 648
j3 2:4e6e761c60f2 649 /**********************************************************//**
j3 2:4e6e761c60f2 650 * Private mmber fx, converts unsigned char to BCD
j3 2:4e6e761c60f2 651 *
j3 2:4e6e761c60f2 652 * On Entry:
j3 2:4e6e761c60f2 653 * @param[in] data - 0-255
j3 2:4e6e761c60f2 654 *
j3 2:4e6e761c60f2 655 * On Exit:
j3 2:4e6e761c60f2 656 * @return bcd_result = BCD representation of data
j3 2:4e6e761c60f2 657 *
j3 2:4e6e761c60f2 658 **************************************************************/
j3 2:4e6e761c60f2 659 uint16_t Ds3231::uchar_2_bcd(uint8_t data)
j3 2:4e6e761c60f2 660 {
j3 2:4e6e761c60f2 661 uint16_t bcd_result = 0;
j3 2:4e6e761c60f2 662
j3 2:4e6e761c60f2 663 //Get hundreds
j3 2:4e6e761c60f2 664 bcd_result |= ((data/100) << 8);
j3 2:4e6e761c60f2 665 data = (data - (data/100)*100);
j3 2:4e6e761c60f2 666
j3 2:4e6e761c60f2 667 //Get tens
j3 2:4e6e761c60f2 668 bcd_result |= ((data/10) << 4);
j3 2:4e6e761c60f2 669 data = (data - (data/10)*10);
j3 2:4e6e761c60f2 670
j3 2:4e6e761c60f2 671 //Get ones
j3 2:4e6e761c60f2 672 bcd_result |= data;
j3 2:4e6e761c60f2 673
j3 2:4e6e761c60f2 674 return(bcd_result);
j3 2:4e6e761c60f2 675 }
j3 2:4e6e761c60f2 676
j3 2:4e6e761c60f2 677
j3 2:4e6e761c60f2 678 /**********************************************************//**
j3 2:4e6e761c60f2 679 * Private mmber fx, converts BCD to a uint8_t
j3 2:4e6e761c60f2 680 *
j3 2:4e6e761c60f2 681 * On Entry:
j3 2:4e6e761c60f2 682 * @param[in] bcd - 0-99
j3 2:4e6e761c60f2 683 *
j3 2:4e6e761c60f2 684 * On Exit:
j3 2:4e6e761c60f2 685 * @return rtn_val = integer rep. of BCD
j3 2:4e6e761c60f2 686 *
j3 2:4e6e761c60f2 687 **************************************************************/
j3 2:4e6e761c60f2 688 uint8_t Ds3231::bcd_2_uchar(uint8_t bcd)
j3 2:4e6e761c60f2 689 {
j3 2:4e6e761c60f2 690 uint8_t rtn_val = 0;
j3 2:4e6e761c60f2 691
j3 2:4e6e761c60f2 692 rtn_val += ((bcd&0xf0)>>4)*10;
j3 2:4e6e761c60f2 693 rtn_val += (bcd&0x000f);
j3 2:4e6e761c60f2 694
j3 2:4e6e761c60f2 695 return rtn_val;
j3 2:4e6e761c60f2 696 }
j3 2:4e6e761c60f2 697
j3 2:4e6e761c60f2 698