Library for DS3231 RTC

Dependents:   ard2pmod DS3231demo DS3231demo_COM_Port_Output MAXREFDES99_RTC_Display ... more

DS3231 Component Page

Committer:
j3
Date:
Thu Nov 20 00:03:27 2014 +0000
Revision:
2:4e6e761c60f2
Parent:
1:c814af60fdbf
Child:
3:312589d8185c
initial implementation of member functions

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 * seconds, minutes and hours
j3 0:b00c4699ae6f 85 *
j3 0:b00c4699ae6f 86 * On Exit:
j3 0:b00c4699ae6f 87 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 88 *
j3 0:b00c4699ae6f 89 * Example:
j3 0:b00c4699ae6f 90 * @code
j3 0:b00c4699ae6f 91 *
j3 0:b00c4699ae6f 92 * //instantiate rtc object
j3 1:c814af60fdbf 93 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 94 *
j3 0:b00c4699ae6f 95 * ds3231_time_t time = {0, 0, 0} // time = 0:0:0 24hr format
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 0:b00c4699ae6f 147 * @param[in] calendar - struct cotaining calendar data;
j3 0:b00c4699ae6f 148 * day, date, month, year
j3 0:b00c4699ae6f 149 *
j3 0:b00c4699ae6f 150 * On Exit:
j3 0:b00c4699ae6f 151 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 152 *
j3 0:b00c4699ae6f 153 * Example:
j3 0:b00c4699ae6f 154 * @code
j3 0:b00c4699ae6f 155 *
j3 0:b00c4699ae6f 156 * //instantiate rtc object
j3 1:c814af60fdbf 157 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 158 *
j3 0:b00c4699ae6f 159 * //see datasheet for calendar format
j3 0:b00c4699ae6f 160 * ds3231_calendar_t calendar = {1, 1, 1, 0};
j3 0:b00c4699ae6f 161 * uint16_t rtn_val;
j3 0:b00c4699ae6f 162 *
j3 0:b00c4699ae6f 163 * rtn_val = rtc.set_calendar(calendar);
j3 0:b00c4699ae6f 164 *
j3 0:b00c4699ae6f 165 * @endcode
j3 0:b00c4699ae6f 166 **************************************************************/
j3 0:b00c4699ae6f 167 uint16_t Ds3231::set_calendar(ds3231_calendar_t calendar)
j3 0:b00c4699ae6f 168 {
j3 2:4e6e761c60f2 169 uint8_t data[] = {0,0,0,0,0};
j3 2:4e6e761c60f2 170 uint8_t data_length = 0;
j3 2:4e6e761c60f2 171
j3 2:4e6e761c60f2 172 data[data_length++] = DAY;
j3 2:4e6e761c60f2 173 data[data_length++] = uchar_2_bcd(calendar.day);
j3 2:4e6e761c60f2 174 data[data_length++] = uchar_2_bcd(calendar.date);
j3 2:4e6e761c60f2 175 data[data_length++] = uchar_2_bcd(calendar.month);
j3 2:4e6e761c60f2 176 data[data_length++] = uchar_2_bcd(calendar.year);
j3 0:b00c4699ae6f 177
j3 2:4e6e761c60f2 178 //users responsibility to make sure calendar is logical
j3 2:4e6e761c60f2 179 return(write(w_adrs,(const char*) data, data_length));
j3 0:b00c4699ae6f 180 }
j3 0:b00c4699ae6f 181
j3 0:b00c4699ae6f 182
j3 0:b00c4699ae6f 183 /**********************************************************//**
j3 0:b00c4699ae6f 184 * Set either Alarm1 or Alarm2 of DS3231
j3 0:b00c4699ae6f 185 *
j3 0:b00c4699ae6f 186 * On Entry:
j3 0:b00c4699ae6f 187 * @param[in] alarm - struct cotaining alarm data
j3 0:b00c4699ae6f 188 * seconds, minutes, hours, day, date
j3 0:b00c4699ae6f 189 * seconds used on Alarm1 only
j3 0:b00c4699ae6f 190 * @param[in] one_r_two - TRUE for Alarm1 and FALSE for
j3 0:b00c4699ae6f 191 * Alarm2
j3 0:b00c4699ae6f 192 *
j3 0:b00c4699ae6f 193 * On Exit:
j3 0:b00c4699ae6f 194 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 195 *
j3 0:b00c4699ae6f 196 * Example:
j3 0:b00c4699ae6f 197 * @code
j3 0:b00c4699ae6f 198 *
j3 0:b00c4699ae6f 199 * //instantiate rtc object
j3 1:c814af60fdbf 200 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 201 *
j3 0:b00c4699ae6f 202 * //see datasheet for alarm format
j3 0:b00c4699ae6f 203 * ds3231_alrm_t alarm = {0, 0, 0, 0, 0};
j3 0:b00c4699ae6f 204 * uint16_t rtn_val;
j3 0:b00c4699ae6f 205 *
j3 0:b00c4699ae6f 206 * rtn_val = rtc.set_alarm(alarm, FALSE);
j3 0:b00c4699ae6f 207 *
j3 0:b00c4699ae6f 208 * @endcode
j3 0:b00c4699ae6f 209 **************************************************************/
j3 0:b00c4699ae6f 210 uint16_t Ds3231::set_alarm(ds3231_alrm_t alarm, bool one_r_two)
j3 0:b00c4699ae6f 211 {
j3 2:4e6e761c60f2 212 uint8_t data[] = {0,0,0,0,0};
j3 2:4e6e761c60f2 213 uint8_t data_length = 0;
j3 2:4e6e761c60f2 214 uint8_t max_hour = 24;
j3 2:4e6e761c60f2 215 uint8_t mask_var = 0;
j3 2:4e6e761c60f2 216
j3 2:4e6e761c60f2 217 //setting alarm 1 or 2?
j3 2:4e6e761c60f2 218 if(one_r_two)
j3 2:4e6e761c60f2 219 {
j3 2:4e6e761c60f2 220 data[data_length++] = ALRM1_SECONDS;
j3 2:4e6e761c60f2 221
j3 2:4e6e761c60f2 222 //config seconds register
j3 2:4e6e761c60f2 223 if(alarm.am1)
j3 2:4e6e761c60f2 224 {
j3 2:4e6e761c60f2 225 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 226 }
j3 2:4e6e761c60f2 227 data[data_length++] = (mask_var | uchar_2_bcd(alarm.seconds));
j3 2:4e6e761c60f2 228 mask_var = 0;
j3 2:4e6e761c60f2 229
j3 2:4e6e761c60f2 230 //config minutes register
j3 2:4e6e761c60f2 231 if(alarm.am2)
j3 2:4e6e761c60f2 232 {
j3 2:4e6e761c60f2 233 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 234 }
j3 2:4e6e761c60f2 235 data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes));
j3 2:4e6e761c60f2 236 mask_var = 0;
j3 2:4e6e761c60f2 237
j3 2:4e6e761c60f2 238 //config hours register
j3 2:4e6e761c60f2 239 if(alarm.am3)
j3 2:4e6e761c60f2 240 {
j3 2:4e6e761c60f2 241 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 242 }
j3 2:4e6e761c60f2 243 if(alarm.mode)
j3 2:4e6e761c60f2 244 {
j3 2:4e6e761c60f2 245 max_hour = max_hour/2;
j3 2:4e6e761c60f2 246 mask_var |= MODE;
j3 2:4e6e761c60f2 247 if(alarm.am_pm)
j3 2:4e6e761c60f2 248 {
j3 2:4e6e761c60f2 249 mask_var |= AM_PM;
j3 2:4e6e761c60f2 250 }
j3 2:4e6e761c60f2 251 }
j3 2:4e6e761c60f2 252 else
j3 2:4e6e761c60f2 253 {
j3 2:4e6e761c60f2 254 max_hour = max_hour - 1;
j3 2:4e6e761c60f2 255 }
j3 2:4e6e761c60f2 256 data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours));
j3 2:4e6e761c60f2 257 mask_var = 0;
j3 2:4e6e761c60f2 258
j3 2:4e6e761c60f2 259 //config day/date register
j3 2:4e6e761c60f2 260 if(alarm.am4)
j3 2:4e6e761c60f2 261 {
j3 2:4e6e761c60f2 262 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 263 }
j3 2:4e6e761c60f2 264 if(alarm.dy_dt)
j3 2:4e6e761c60f2 265 {
j3 2:4e6e761c60f2 266 mask_var |= DY_DT;
j3 2:4e6e761c60f2 267 data[data_length++] = (mask_var | uchar_2_bcd(alarm.day));
j3 2:4e6e761c60f2 268 }
j3 2:4e6e761c60f2 269 else
j3 2:4e6e761c60f2 270 {
j3 2:4e6e761c60f2 271 data[data_length++] = (mask_var | uchar_2_bcd(alarm.date));
j3 2:4e6e761c60f2 272 }
j3 2:4e6e761c60f2 273 mask_var = 0;
j3 2:4e6e761c60f2 274 }
j3 2:4e6e761c60f2 275 else
j3 2:4e6e761c60f2 276 {
j3 2:4e6e761c60f2 277 data[data_length++] = ALRM2_MINUTES;
j3 2:4e6e761c60f2 278
j3 2:4e6e761c60f2 279 //config minutes register
j3 2:4e6e761c60f2 280 if(alarm.am2)
j3 2:4e6e761c60f2 281 {
j3 2:4e6e761c60f2 282 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 283 }
j3 2:4e6e761c60f2 284 data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes));
j3 2:4e6e761c60f2 285 mask_var = 0;
j3 2:4e6e761c60f2 286
j3 2:4e6e761c60f2 287 //config hours register
j3 2:4e6e761c60f2 288 if(alarm.am3)
j3 2:4e6e761c60f2 289 {
j3 2:4e6e761c60f2 290 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 291 }
j3 2:4e6e761c60f2 292 if(alarm.mode)
j3 2:4e6e761c60f2 293 {
j3 2:4e6e761c60f2 294 max_hour = max_hour/2;
j3 2:4e6e761c60f2 295 mask_var |= MODE;
j3 2:4e6e761c60f2 296 if(alarm.am_pm)
j3 2:4e6e761c60f2 297 {
j3 2:4e6e761c60f2 298 mask_var |= AM_PM;
j3 2:4e6e761c60f2 299 }
j3 2:4e6e761c60f2 300 }
j3 2:4e6e761c60f2 301 else
j3 2:4e6e761c60f2 302 {
j3 2:4e6e761c60f2 303 max_hour = max_hour - 1;
j3 2:4e6e761c60f2 304 }
j3 2:4e6e761c60f2 305 data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours));
j3 2:4e6e761c60f2 306 mask_var = 0;
j3 2:4e6e761c60f2 307
j3 2:4e6e761c60f2 308 //config day/date register
j3 2:4e6e761c60f2 309 if(alarm.am4)
j3 2:4e6e761c60f2 310 {
j3 2:4e6e761c60f2 311 mask_var |= ALRM_MASK;
j3 2:4e6e761c60f2 312 }
j3 2:4e6e761c60f2 313 if(alarm.dy_dt)
j3 2:4e6e761c60f2 314 {
j3 2:4e6e761c60f2 315 mask_var |= DY_DT;
j3 2:4e6e761c60f2 316 data[data_length++] = (mask_var | uchar_2_bcd(alarm.day));
j3 2:4e6e761c60f2 317 }
j3 2:4e6e761c60f2 318 else
j3 2:4e6e761c60f2 319 {
j3 2:4e6e761c60f2 320 data[data_length++] = (mask_var | uchar_2_bcd(alarm.date));
j3 2:4e6e761c60f2 321 }
j3 2:4e6e761c60f2 322 mask_var = 0;
j3 2:4e6e761c60f2 323 }
j3 2:4e6e761c60f2 324
j3 2:4e6e761c60f2 325 //Test for good data.
j3 2:4e6e761c60f2 326 if((alarm.seconds > 59) || (alarm.minutes > 59) || (alarm.hours > max_hour) || (alarm.day > 7) || (alarm.date > 31))
j3 2:4e6e761c60f2 327 {
j3 2:4e6e761c60f2 328 return(1);
j3 2:4e6e761c60f2 329 }
j3 2:4e6e761c60f2 330 else
j3 2:4e6e761c60f2 331 {
j3 2:4e6e761c60f2 332 return(write(w_adrs,(const char*) data, data_length));
j3 2:4e6e761c60f2 333 }
j3 0:b00c4699ae6f 334 }
j3 0:b00c4699ae6f 335
j3 0:b00c4699ae6f 336
j3 0:b00c4699ae6f 337 /**********************************************************//**
j3 0:b00c4699ae6f 338 * Set control and status registers of DS3231
j3 0:b00c4699ae6f 339 *
j3 0:b00c4699ae6f 340 * On Entry:
j3 0:b00c4699ae6f 341 * @param[in] data - Struct containing control and status
j3 0:b00c4699ae6f 342 * register data
j3 0:b00c4699ae6f 343 *
j3 0:b00c4699ae6f 344 * On Exit:
j3 0:b00c4699ae6f 345 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 346 *
j3 0:b00c4699ae6f 347 * Example:
j3 0:b00c4699ae6f 348 * @code
j3 0:b00c4699ae6f 349 *
j3 0:b00c4699ae6f 350 * //instantiate rtc object
j3 1:c814af60fdbf 351 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 352 *
j3 0:b00c4699ae6f 353 * //do not use 0xAA, see datasheet for appropriate data
j3 0:b00c4699ae6f 354 * ds3231_cntl_stat_t data = {0xAA, 0xAA};
j3 0:b00c4699ae6f 355 *
j3 0:b00c4699ae6f 356 * rtn_val = rtc.set_cntl_stat_reg(data);
j3 0:b00c4699ae6f 357 *
j3 0:b00c4699ae6f 358 * @endcode
j3 0:b00c4699ae6f 359 **************************************************************/
j3 0:b00c4699ae6f 360 uint16_t Ds3231::set_cntl_stat_reg(ds3231_cntl_stat_t data)
j3 0:b00c4699ae6f 361 {
j3 2:4e6e761c60f2 362 uint8_t local_data[] = {0,0,0};
j3 2:4e6e761c60f2 363 uint8_t data_length = 0;
j3 2:4e6e761c60f2 364
j3 2:4e6e761c60f2 365 local_data[data_length++] = CONTROL;
j3 2:4e6e761c60f2 366 local_data[data_length++] = data.control;
j3 2:4e6e761c60f2 367 local_data[data_length++] = data.status;
j3 0:b00c4699ae6f 368
j3 2:4e6e761c60f2 369 //users responsibility to make sure data is logical
j3 2:4e6e761c60f2 370 return(write(w_adrs,(const char*) local_data, data_length));
j3 0:b00c4699ae6f 371 }
j3 0:b00c4699ae6f 372
j3 0:b00c4699ae6f 373
j3 0:b00c4699ae6f 374 /**********************************************************//**
j3 0:b00c4699ae6f 375 * Gets the time on DS3231
j3 0:b00c4699ae6f 376 *
j3 0:b00c4699ae6f 377 * On Entry:
j3 2:4e6e761c60f2 378 * @param[in] time - pointer to struct for storing time
j3 2:4e6e761c60f2 379 * data; seconds, minutes and hours
j3 0:b00c4699ae6f 380 *
j3 0:b00c4699ae6f 381 * On Exit:
j3 2:4e6e761c60f2 382 * @param[out] time - contains current integrer rtc time
j3 2:4e6e761c60f2 383 * data
j3 0:b00c4699ae6f 384 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 385 *
j3 0:b00c4699ae6f 386 * Example:
j3 0:b00c4699ae6f 387 * @code
j3 0:b00c4699ae6f 388 *
j3 0:b00c4699ae6f 389 * //instantiate rtc object
j3 1:c814af60fdbf 390 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 391 *
j3 0:b00c4699ae6f 392 * ds3231_time_t time = {0, 0, 0} // time = 0:0:0 24hr format
j3 0:b00c4699ae6f 393 * uint16_t rtn_val;
j3 0:b00c4699ae6f 394 *
j3 0:b00c4699ae6f 395 * rtn_val = rtc.get_time(time);
j3 0:b00c4699ae6f 396 *
j3 0:b00c4699ae6f 397 * @endcode
j3 0:b00c4699ae6f 398 **************************************************************/
j3 2:4e6e761c60f2 399 uint16_t Ds3231::get_time(ds3231_time_t* time)
j3 0:b00c4699ae6f 400 {
j3 2:4e6e761c60f2 401 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 402 uint8_t data[3];
j3 2:4e6e761c60f2 403
j3 2:4e6e761c60f2 404 data[0] = SECONDS;
j3 2:4e6e761c60f2 405 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 406
j3 2:4e6e761c60f2 407 if(!rtn_val)
j3 2:4e6e761c60f2 408 {
j3 2:4e6e761c60f2 409 rtn_val = read(r_adrs,(char *) data, 3);
j3 2:4e6e761c60f2 410
j3 2:4e6e761c60f2 411 time->seconds = bcd_2_uchar(data[0]);
j3 2:4e6e761c60f2 412 time->minutes = bcd_2_uchar(data[1]);
j3 2:4e6e761c60f2 413 time->hours = bcd_2_uchar((data[2]&0x1F));
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 2:4e6e761c60f2 425 * calendar data;
j3 0:b00c4699ae6f 426 * day, date, month, year
j3 0:b00c4699ae6f 427 *
j3 0:b00c4699ae6f 428 * On Exit:
j3 2:4e6e761c60f2 429 * @param[out] calendar - contains current integer rtc
j3 2:4e6e761c60f2 430 * calendar data
j3 0:b00c4699ae6f 431 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 432 *
j3 0:b00c4699ae6f 433 * Example:
j3 0:b00c4699ae6f 434 * @code
j3 0:b00c4699ae6f 435 *
j3 0:b00c4699ae6f 436 * //instantiate rtc object
j3 1:c814af60fdbf 437 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 438 *
j3 0:b00c4699ae6f 439 * //see datasheet for calendar format
j3 0:b00c4699ae6f 440 * ds3231_calendar_t calendar = {1, 1, 1, 0};
j3 0:b00c4699ae6f 441 * uint16_t rtn_val;
j3 0:b00c4699ae6f 442 *
j3 0:b00c4699ae6f 443 * rtn_val = rtc.get_calendar(calendar);
j3 0:b00c4699ae6f 444 *
j3 0:b00c4699ae6f 445 * @endcode
j3 0:b00c4699ae6f 446 **************************************************************/
j3 2:4e6e761c60f2 447 uint16_t Ds3231::get_calendar(ds3231_calendar_t* calendar)
j3 0:b00c4699ae6f 448 {
j3 2:4e6e761c60f2 449 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 450 uint8_t data[4];
j3 2:4e6e761c60f2 451
j3 2:4e6e761c60f2 452 data[0] = DAY;
j3 2:4e6e761c60f2 453 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 454
j3 2:4e6e761c60f2 455 if(!rtn_val)
j3 2:4e6e761c60f2 456 {
j3 2:4e6e761c60f2 457 rtn_val = read(r_adrs,(char *) data, 4);
j3 2:4e6e761c60f2 458
j3 2:4e6e761c60f2 459 calendar->day = bcd_2_uchar(data[0]);
j3 2:4e6e761c60f2 460 calendar->date = bcd_2_uchar(data[1]);
j3 2:4e6e761c60f2 461 calendar->month = bcd_2_uchar((data[2]&0x1F));
j3 2:4e6e761c60f2 462 calendar->year = bcd_2_uchar(data[3]);
j3 2:4e6e761c60f2 463 }
j3 2:4e6e761c60f2 464
j3 2:4e6e761c60f2 465 return(rtn_val);
j3 0:b00c4699ae6f 466 }
j3 0:b00c4699ae6f 467
j3 0:b00c4699ae6f 468
j3 0:b00c4699ae6f 469 /**********************************************************//**
j3 0:b00c4699ae6f 470 * Get either Alarm1 or Alarm2 of DS3231
j3 0:b00c4699ae6f 471 *
j3 0:b00c4699ae6f 472 * On Entry:
j3 2:4e6e761c60f2 473 * @param[in] alarm - pointer to struct for storing alarm
j3 2:4e6e761c60f2 474 * data;
j3 0:b00c4699ae6f 475 * seconds, minutes, hours, day, date
j3 0:b00c4699ae6f 476 * seconds used on Alarm1 only
j3 2:4e6e761c60f2 477 *
j3 0:b00c4699ae6f 478 * @param[in] one_r_two - TRUE for Alarm1 and FALSE for
j3 0:b00c4699ae6f 479 * Alarm2
j3 0:b00c4699ae6f 480 *
j3 0:b00c4699ae6f 481 * On Exit:
j3 2:4e6e761c60f2 482 * @param[out] alarm - contains integer alarm data
j3 0:b00c4699ae6f 483 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 484 *
j3 0:b00c4699ae6f 485 * Example:
j3 0:b00c4699ae6f 486 * @code
j3 0:b00c4699ae6f 487 *
j3 0:b00c4699ae6f 488 * //instantiate rtc object
j3 1:c814af60fdbf 489 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 490 *
j3 0:b00c4699ae6f 491 * //see datasheet for alarm format
j3 0:b00c4699ae6f 492 * ds3231_alrm_t alarm = {0, 0, 0, 0, 0};
j3 0:b00c4699ae6f 493 * uint16_t rtn_val;
j3 0:b00c4699ae6f 494 *
j3 0:b00c4699ae6f 495 * rtn_val = rtc.get_alarm(alarm, FALSE);
j3 0:b00c4699ae6f 496 *
j3 0:b00c4699ae6f 497 * @endcode
j3 0:b00c4699ae6f 498 **************************************************************/
j3 2:4e6e761c60f2 499 uint16_t Ds3231::get_alarm(ds3231_alrm_t* alarm, bool one_r_two)
j3 0:b00c4699ae6f 500 {
j3 2:4e6e761c60f2 501 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 502 uint8_t data[4];
j3 2:4e6e761c60f2 503
j3 2:4e6e761c60f2 504 if(one_r_two)
j3 2:4e6e761c60f2 505 {
j3 2:4e6e761c60f2 506 data[0] = ALRM1_SECONDS;
j3 2:4e6e761c60f2 507 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 508
j3 2:4e6e761c60f2 509 if(!rtn_val)
j3 2:4e6e761c60f2 510 {
j3 2:4e6e761c60f2 511 rtn_val = read(r_adrs,(char *) data, 4);
j3 2:4e6e761c60f2 512
j3 2:4e6e761c60f2 513 alarm->seconds = bcd_2_uchar(data[0]&0x7F);
j3 2:4e6e761c60f2 514 alarm->minutes = bcd_2_uchar(data[1]&0x7F);
j3 2:4e6e761c60f2 515 alarm->hours = bcd_2_uchar(data[2]&0x1F);
j3 2:4e6e761c60f2 516
j3 2:4e6e761c60f2 517 if(data[3] & DY_DT)
j3 2:4e6e761c60f2 518 {
j3 2:4e6e761c60f2 519 alarm->day = bcd_2_uchar(data[3]&0x0F);
j3 2:4e6e761c60f2 520 }
j3 2:4e6e761c60f2 521 else
j3 2:4e6e761c60f2 522 {
j3 2:4e6e761c60f2 523 alarm->date = bcd_2_uchar(data[3]&0x3F);
j3 2:4e6e761c60f2 524 }
j3 2:4e6e761c60f2 525 }
j3 2:4e6e761c60f2 526 }
j3 2:4e6e761c60f2 527 else
j3 2:4e6e761c60f2 528 {
j3 2:4e6e761c60f2 529 data[0] = ALRM2_MINUTES;
j3 2:4e6e761c60f2 530 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 531
j3 2:4e6e761c60f2 532 if(!rtn_val)
j3 2:4e6e761c60f2 533 {
j3 2:4e6e761c60f2 534 rtn_val = read(r_adrs,(char *) data, 4);
j3 2:4e6e761c60f2 535
j3 2:4e6e761c60f2 536 alarm->minutes = bcd_2_uchar(data[0]&0x7F);
j3 2:4e6e761c60f2 537 alarm->hours = bcd_2_uchar(data[1]&0x1F);
j3 2:4e6e761c60f2 538
j3 2:4e6e761c60f2 539 if(data[3] & DY_DT)
j3 2:4e6e761c60f2 540 {
j3 2:4e6e761c60f2 541 alarm->day = bcd_2_uchar(data[2]&0x0F);
j3 2:4e6e761c60f2 542 }
j3 2:4e6e761c60f2 543 else
j3 2:4e6e761c60f2 544 {
j3 2:4e6e761c60f2 545 alarm->date = bcd_2_uchar(data[2]&0x3F);
j3 2:4e6e761c60f2 546 }
j3 2:4e6e761c60f2 547 }
j3 2:4e6e761c60f2 548 }
j3 2:4e6e761c60f2 549
j3 2:4e6e761c60f2 550 return(rtn_val);
j3 0:b00c4699ae6f 551 }
j3 0:b00c4699ae6f 552
j3 0:b00c4699ae6f 553
j3 0:b00c4699ae6f 554 /**********************************************************//**
j3 0:b00c4699ae6f 555 * Get control and status registers of DS3231
j3 0:b00c4699ae6f 556 *
j3 0:b00c4699ae6f 557 * On Entry:
j3 2:4e6e761c60f2 558 * @param[in] data - pointer to struct for storing control
j3 2:4e6e761c60f2 559 * nd status register data
j3 0:b00c4699ae6f 560 *
j3 0:b00c4699ae6f 561 * On Exit:
j3 0:b00c4699ae6f 562 * @param[out] data - contains control and status registers
j3 0:b00c4699ae6f 563 * data
j3 0:b00c4699ae6f 564 * @return return value = 0 on success, non-0 on failure
j3 0:b00c4699ae6f 565 *
j3 0:b00c4699ae6f 566 * Example:
j3 0:b00c4699ae6f 567 * @code
j3 0:b00c4699ae6f 568 *
j3 0:b00c4699ae6f 569 * //instantiate rtc object
j3 1:c814af60fdbf 570 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 571 *
j3 0:b00c4699ae6f 572 * //do not use 0xAA, see datasheet for appropriate data
j3 0:b00c4699ae6f 573 * ds3231_cntl_stat_t data = {0xAA, 0xAA};
j3 0:b00c4699ae6f 574 *
j3 0:b00c4699ae6f 575 * rtn_val = rtc.get_cntl_stat_reg(data);
j3 0:b00c4699ae6f 576 *
j3 0:b00c4699ae6f 577 * @endcode
j3 0:b00c4699ae6f 578 **************************************************************/
j3 2:4e6e761c60f2 579 uint16_t Ds3231::get_cntl_stat_reg(ds3231_cntl_stat_t* data)
j3 0:b00c4699ae6f 580 {
j3 2:4e6e761c60f2 581 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 582 uint8_t local_data[2];
j3 2:4e6e761c60f2 583
j3 2:4e6e761c60f2 584 local_data[0] = CONTROL;
j3 2:4e6e761c60f2 585 rtn_val = write(w_adrs, (const char*) local_data, 1);
j3 2:4e6e761c60f2 586
j3 2:4e6e761c60f2 587 if(!rtn_val)
j3 2:4e6e761c60f2 588 {
j3 2:4e6e761c60f2 589 rtn_val = read(r_adrs,(char *) local_data, 2);
j3 2:4e6e761c60f2 590
j3 2:4e6e761c60f2 591 data->control = local_data[0];
j3 2:4e6e761c60f2 592 data->status = local_data[1];
j3 2:4e6e761c60f2 593 }
j3 2:4e6e761c60f2 594
j3 2:4e6e761c60f2 595 return(rtn_val);
j3 0:b00c4699ae6f 596 }
j3 0:b00c4699ae6f 597
j3 0:b00c4699ae6f 598
j3 0:b00c4699ae6f 599 /**********************************************************//**
j3 0:b00c4699ae6f 600 * Get temperature data of DS3231
j3 0:b00c4699ae6f 601 *
j3 0:b00c4699ae6f 602 * On Entry:
j3 0:b00c4699ae6f 603 *
j3 0:b00c4699ae6f 604 * On Exit:
j3 2:4e6e761c60f2 605 * @return return value = raw temperature data
j3 0:b00c4699ae6f 606 *
j3 0:b00c4699ae6f 607 * Example:
j3 0:b00c4699ae6f 608 * @code
j3 0:b00c4699ae6f 609 *
j3 0:b00c4699ae6f 610 * //instantiate rtc object
j3 1:c814af60fdbf 611 * Ds3231 rtc(D14, D15);
j3 0:b00c4699ae6f 612 *
j3 0:b00c4699ae6f 613 * uint16_t temp;
j3 0:b00c4699ae6f 614 *
j3 2:4e6e761c60f2 615 * temp = rtc.get_temperature();
j3 0:b00c4699ae6f 616 *
j3 0:b00c4699ae6f 617 * @endcode
j3 0:b00c4699ae6f 618 **************************************************************/
j3 2:4e6e761c60f2 619 uint16_t Ds3231::get_temperature(void)
j3 0:b00c4699ae6f 620 {
j3 2:4e6e761c60f2 621 uint16_t rtn_val = 1;
j3 2:4e6e761c60f2 622 uint8_t data[2];
j3 2:4e6e761c60f2 623
j3 2:4e6e761c60f2 624 data[0] = MSB_TEMP;
j3 2:4e6e761c60f2 625 rtn_val = write(w_adrs, (const char*) data, 1);
j3 2:4e6e761c60f2 626
j3 2:4e6e761c60f2 627 if(!rtn_val)
j3 2:4e6e761c60f2 628 {
j3 2:4e6e761c60f2 629 read(r_adrs,(char *) data, 2);
j3 2:4e6e761c60f2 630
j3 2:4e6e761c60f2 631 rtn_val = data[0] << 8;
j3 2:4e6e761c60f2 632 rtn_val |= data[1];
j3 2:4e6e761c60f2 633 }
j3 2:4e6e761c60f2 634
j3 2:4e6e761c60f2 635 return(rtn_val);
j3 0:b00c4699ae6f 636 }
j3 0:b00c4699ae6f 637
j3 2:4e6e761c60f2 638
j3 2:4e6e761c60f2 639 /**********************************************************//**
j3 2:4e6e761c60f2 640 * Private mmber fx, converts unsigned char to BCD
j3 2:4e6e761c60f2 641 *
j3 2:4e6e761c60f2 642 * On Entry:
j3 2:4e6e761c60f2 643 * @param[in] data - 0-255
j3 2:4e6e761c60f2 644 *
j3 2:4e6e761c60f2 645 * On Exit:
j3 2:4e6e761c60f2 646 * @return bcd_result = BCD representation of data
j3 2:4e6e761c60f2 647 *
j3 2:4e6e761c60f2 648 **************************************************************/
j3 2:4e6e761c60f2 649 uint16_t Ds3231::uchar_2_bcd(uint8_t data)
j3 2:4e6e761c60f2 650 {
j3 2:4e6e761c60f2 651 uint16_t bcd_result = 0;
j3 2:4e6e761c60f2 652
j3 2:4e6e761c60f2 653 //Get hundreds
j3 2:4e6e761c60f2 654 bcd_result |= ((data/100) << 8);
j3 2:4e6e761c60f2 655 data = (data - (data/100)*100);
j3 2:4e6e761c60f2 656
j3 2:4e6e761c60f2 657 //Get tens
j3 2:4e6e761c60f2 658 bcd_result |= ((data/10) << 4);
j3 2:4e6e761c60f2 659 data = (data - (data/10)*10);
j3 2:4e6e761c60f2 660
j3 2:4e6e761c60f2 661 //Get ones
j3 2:4e6e761c60f2 662 bcd_result |= data;
j3 2:4e6e761c60f2 663
j3 2:4e6e761c60f2 664 return(bcd_result);
j3 2:4e6e761c60f2 665 }
j3 2:4e6e761c60f2 666
j3 2:4e6e761c60f2 667
j3 2:4e6e761c60f2 668 /**********************************************************//**
j3 2:4e6e761c60f2 669 * Private mmber fx, converts BCD to a uint8_t
j3 2:4e6e761c60f2 670 *
j3 2:4e6e761c60f2 671 * On Entry:
j3 2:4e6e761c60f2 672 * @param[in] bcd - 0-99
j3 2:4e6e761c60f2 673 *
j3 2:4e6e761c60f2 674 * On Exit:
j3 2:4e6e761c60f2 675 * @return rtn_val = integer rep. of BCD
j3 2:4e6e761c60f2 676 *
j3 2:4e6e761c60f2 677 **************************************************************/
j3 2:4e6e761c60f2 678 uint8_t Ds3231::bcd_2_uchar(uint8_t bcd)
j3 2:4e6e761c60f2 679 {
j3 2:4e6e761c60f2 680 uint8_t rtn_val = 0;
j3 2:4e6e761c60f2 681
j3 2:4e6e761c60f2 682 rtn_val += ((bcd&0xf0)>>4)*10;
j3 2:4e6e761c60f2 683 rtn_val += (bcd&0x000f);
j3 2:4e6e761c60f2 684
j3 2:4e6e761c60f2 685 return rtn_val;
j3 2:4e6e761c60f2 686 }
j3 2:4e6e761c60f2 687
j3 2:4e6e761c60f2 688