example using DS3234 RTC connected to BBC micro:bit using SPI

Dependencies:   microbit

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SparkFunDS3234RTC.cpp Source File

SparkFunDS3234RTC.cpp

00001 /******************************************************************************
00002 SparkFunDS3234RTC.cpp
00003 Jim Lindblom @ SparkFun Electronics
00004 original creation date: October 2, 2016
00005 https://github.com/sparkfun/SparkFun_DS3234_RTC_Arduino_Library
00006 
00007 Implementation of DS3234 real time clock functions
00008 
00009 Resources:
00010 SPI.h - Arduino I2C Library
00011 
00012 Development environment specifics:
00013 Arduino 1.6.8
00014 SparkFun RedBoard
00015 SparkFun Real Time Clock Module (v14)
00016 
00017 Updated 16 October 2016 by Vassilis Serasidis <avrsite@yahoo.gr>
00018 - Added readFromSRAM' and 'writeToSRAM' functions
00019 
00020 ******************************************************************************/
00021 
00022 #include "SparkFunDS3234RTC.h"
00023 
00024 // Parse the __DATE__ predefined macro to generate date defaults:
00025 // __Date__ Format: MMM DD YYYY (First D may be a space if <10)
00026 // <MONTH>
00027 #define BUILD_MONTH_JAN ((__DATE__[0] == 'J') && (__DATE__[1] == 'a')) ? 1 : 0
00028 #define BUILD_MONTH_FEB (__DATE__[0] == 'F') ? 2 : 0
00029 #define BUILD_MONTH_MAR ((__DATE__[0] == 'M') && (__DATE__[1] == 'a') && (__DATE__[2] == 'r')) ? 3 : 0
00030 #define BUILD_MONTH_APR ((__DATE__[0] == 'A') && (__DATE__[1] == 'p')) ? 4 : 0
00031 #define BUILD_MONTH_MAY ((__DATE__[0] == 'M') && (__DATE__[1] == 'a') && (__DATE__[2] == 'y')) ? 5 : 0
00032 #define BUILD_MONTH_JUN ((__DATE__[0] == 'J') && (__DATE__[1] == 'u') && (__DATE__[2] == 'n')) ? 6 : 0
00033 #define BUILD_MONTH_JUL ((__DATE__[0] == 'J') && (__DATE__[1] == 'u') && (__DATE__[2] == 'l')) ? 7 : 0
00034 #define BUILD_MONTH_AUG ((__DATE__[0] == 'A') && (__DATE__[1] == 'u')) ? 8 : 0
00035 #define BUILD_MONTH_SEP (__DATE__[0] == 'S') ? 9 : 0
00036 #define BUILD_MONTH_OCT (__DATE__[0] == 'O') ? 10 : 0
00037 #define BUILD_MONTH_NOV (__DATE__[0] == 'N') ? 11 : 0
00038 #define BUILD_MONTH_DEC (__DATE__[0] == 'D') ? 12 : 0
00039 #define BUILD_MONTH BUILD_MONTH_JAN | BUILD_MONTH_FEB | BUILD_MONTH_MAR | \
00040                     BUILD_MONTH_APR | BUILD_MONTH_MAY | BUILD_MONTH_JUN | \
00041                     BUILD_MONTH_JUL | BUILD_MONTH_AUG | BUILD_MONTH_SEP | \
00042                     BUILD_MONTH_OCT | BUILD_MONTH_NOV | BUILD_MONTH_DEC
00043 // <DATE>
00044 #define BUILD_DATE_0 ((__DATE__[4] == ' ') ? 0 : (__DATE__[4] - 0x30))
00045 #define BUILD_DATE_1 (__DATE__[5] - 0x30)
00046 #define BUILD_DATE ((BUILD_DATE_0 * 10) + BUILD_DATE_1)
00047 // <YEAR>
00048 #define BUILD_YEAR (((__DATE__[7] - 0x30) * 1000) + ((__DATE__[8] - 0x30) * 100) + \
00049                     ((__DATE__[9] - 0x30) * 10)  + ((__DATE__[10] - 0x30) * 1))
00050 
00051 // Parse the __TIME__ predefined macro to generate time defaults:
00052 // __TIME__ Format: HH:MM:SS (First number of each is padded by 0 if <10)
00053 // <HOUR>
00054 #define BUILD_HOUR_0 ((__TIME__[0] == ' ') ? 0 : (__TIME__[0] - 0x30))
00055 #define BUILD_HOUR_1 (__TIME__[1] - 0x30)
00056 #define BUILD_HOUR ((BUILD_HOUR_0 * 10) + BUILD_HOUR_1)
00057 // <MINUTE>
00058 #define BUILD_MINUTE_0 ((__TIME__[3] == ' ') ? 0 : (__TIME__[3] - 0x30))
00059 #define BUILD_MINUTE_1 (__TIME__[4] - 0x30)
00060 #define BUILD_MINUTE ((BUILD_MINUTE_0 * 10) + BUILD_MINUTE_1)
00061 // <SECOND>
00062 #define BUILD_SECOND_0 ((__TIME__[6] == ' ') ? 0 : (__TIME__[6] - 0x30))
00063 #define BUILD_SECOND_1 (__TIME__[7] - 0x30)
00064 #define BUILD_SECOND ((BUILD_SECOND_0 * 10) + BUILD_SECOND_1)
00065 
00066 // DS3234 SPI Settings:
00067 #define DS3234_MAX_SCLK 4000000 // 4MHz max SPI clock rate
00068 //SPISettings DS3234SPISettings(DS3234_MAX_SCLK, MSBFIRST, SPI_MODE3);
00069 
00070 SPI spi(MICROBIT_PIN_P15, MICROBIT_PIN_P14, MICROBIT_PIN_P13); // mosi, miso, sclk
00071 
00072 // Constructor -- Initialize class variables to 0
00073 DS3234::DS3234()
00074 {
00075     for (int i=0; i<TIME_ARRAY_LENGTH; i++)
00076     {
00077         _time[i] = 0;
00078     }
00079     _pm = false;
00080 }
00081 
00082 // Begin -- Initialize SPI interface
00083 void DS3234::begin(MicroBitPin* csPin, MicroBit* uBit)
00084 {
00085     _csPin = csPin;
00086     _uBit = uBit;
00087     
00088     _csPin->setDigitalValue(1);
00089     
00090     spi.format(8,3);
00091     spi.frequency(DS3234_MAX_SCLK);
00092 }
00093 
00094 // setTime -- Set time and date/day registers of DS3234
00095 void DS3234::setTime(uint8_t sec, uint8_t min, uint8_t hour, uint8_t day, uint8_t date, uint8_t month, uint8_t year)
00096 {
00097     _time[TIME_SECONDS] = DECtoBCD(sec);
00098     _time[TIME_MINUTES] = DECtoBCD(min);
00099     _time[TIME_HOURS] = DECtoBCD(hour);
00100     _time[TIME_DAY] = DECtoBCD(day);
00101     _time[TIME_DATE] = DECtoBCD(date);
00102     _time[TIME_MONTH] = DECtoBCD(month);
00103     _time[TIME_YEAR] = DECtoBCD(year);
00104     
00105     setTime(_time, TIME_ARRAY_LENGTH);
00106 }
00107 
00108 void DS3234::setTime(uint8_t sec, uint8_t min, uint8_t hour12, bool pm, uint8_t day, uint8_t date, uint8_t month, uint8_t year)
00109 {
00110     _time[TIME_SECONDS] = DECtoBCD(sec);
00111     _time[TIME_MINUTES] = DECtoBCD(min);
00112     _time[TIME_HOURS] = DECtoBCD(hour12);
00113     _time[TIME_HOURS] |= TWELVE_HOUR_MODE;
00114     if (pm)
00115         _time[TIME_HOURS] |= TWELVE_HOUR_PM;
00116     _time[TIME_DAY] = DECtoBCD(day);
00117     _time[TIME_DATE] = DECtoBCD(date);
00118     _time[TIME_MONTH] = DECtoBCD(month);
00119     _time[TIME_YEAR] = DECtoBCD(year);
00120     
00121     setTime(_time, TIME_ARRAY_LENGTH);
00122 }
00123 
00124 // setTime -- Set time and date/day registers of DS3234 (using data array)
00125 void DS3234::setTime(uint8_t * time, uint8_t len)
00126 {
00127     if (len != TIME_ARRAY_LENGTH)
00128         return;
00129     
00130     spiWriteBytes(DS3234_REGISTER_BASE, time, TIME_ARRAY_LENGTH);
00131 }
00132 
00133 // autoTime -- Fill DS3234 time registers with compiler time/date
00134 bool DS3234::autoTime()
00135 {
00136     _time[TIME_SECONDS] = DECtoBCD(BUILD_SECOND);
00137     _time[TIME_MINUTES] = DECtoBCD(BUILD_MINUTE);
00138     _time[TIME_HOURS] = BUILD_HOUR;
00139     // Convert hour to 12-hour if the DS3234 is in 12-hour mode:
00140     if (is12Hour())
00141     {
00142         uint8_t pmBit = 0;
00143         if (_time[TIME_HOURS] <= 11)
00144         {
00145             if (_time[TIME_HOURS] == 0)
00146                 _time[TIME_HOURS] = 12;
00147         }
00148         else
00149         {
00150             pmBit = TWELVE_HOUR_PM;
00151             if (_time[TIME_HOURS] >= 13)
00152                 _time[TIME_HOURS] -= 12;
00153         }
00154         DECtoBCD(_time[TIME_HOURS]);
00155         _time[TIME_HOURS] |= pmBit;
00156         _time[TIME_HOURS] |= TWELVE_HOUR_MODE;
00157     }
00158     else
00159     {
00160         _time[TIME_HOURS] = DECtoBCD(_time[TIME_HOURS]);
00161     }
00162     
00163     _time[TIME_MONTH] = DECtoBCD(BUILD_MONTH);
00164     _time[TIME_DATE] = DECtoBCD(BUILD_DATE);
00165     _time[TIME_YEAR] = DECtoBCD(BUILD_YEAR - 2000); //! Not Y2K (or Y2.1K)-proof :\
00166     
00167     // Calculate weekday (from here: http://stackoverflow.com/a/21235587)
00168     // Result: 0 = Sunday, 6 = Saturday
00169     int d = BUILD_DATE;
00170     int m = BUILD_MONTH;
00171     int y = BUILD_YEAR;
00172     int weekday = (d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7;
00173     weekday += 1; // Library defines Sunday=1, Saturday=7
00174     _time[TIME_DAY] = DECtoBCD(weekday);
00175     
00176     
00177     setTime(_time, TIME_ARRAY_LENGTH);
00178 }
00179 
00180 // update -- Read all time/date registers and update the _time array
00181 void DS3234::update(void)
00182 {
00183     uint8_t rtcReads[TIME_ARRAY_LENGTH];
00184     
00185     spiReadBytes(DS3234_REGISTER_BASE, rtcReads, TIME_ARRAY_LENGTH);
00186     
00187     for (int i=0; i<TIME_ARRAY_LENGTH; i++)
00188     {
00189         _time[i] = rtcReads[i];
00190     }
00191     
00192     if (_time[TIME_HOURS] & TWELVE_HOUR_MODE)
00193     {
00194         if (_time[TIME_HOURS] & TWELVE_HOUR_PM)
00195             _pm = true;
00196         else
00197             _pm = false;
00198         
00199         _time[TIME_HOURS] &= 0x1F; // Mask out 24-hour bit, am/pm from hours
00200     }
00201     else
00202     {
00203         _time[TIME_HOURS] &= 0x3F; // Mask out 24-hour bit from hours
00204     }
00205 }
00206 
00207 // getSecond -- read/return seconds register of DS3234
00208 uint8_t DS3234::getSecond(void)
00209 {
00210     _time[TIME_SECONDS] = spiReadByte(DS3234_REGISTER_SECONDS);
00211     
00212     return BCDtoDEC(_time[TIME_SECONDS]);
00213 }
00214 
00215 // getMinute -- read/return minutes register of DS3234
00216 uint8_t DS3234::getMinute(void)
00217 {
00218     _time[TIME_MINUTES] = spiReadByte(DS3234_REGISTER_MINUTES);
00219 
00220     return BCDtoDEC(_time[TIME_MINUTES]);   
00221 }
00222 
00223 // getHour -- read/return hour register of DS3234
00224 uint8_t DS3234::getHour(void)
00225 {
00226     uint8_t hourRegister = spiReadByte(DS3234_REGISTER_HOURS);
00227     
00228     if (hourRegister & TWELVE_HOUR_MODE)
00229         hourRegister &= 0x1F; // Mask out am/pm, 24-hour bit
00230     _time[TIME_HOURS] = hourRegister;
00231 
00232     return BCDtoDEC(_time[TIME_HOURS]);
00233 }
00234 
00235 // getDay -- read/return day register of DS3234
00236 uint8_t DS3234::getDay(void)
00237 {
00238     _time[TIME_DAY] = spiReadByte(DS3234_REGISTER_DAY);
00239 
00240     return BCDtoDEC(_time[TIME_DAY]);       
00241 }
00242 
00243 // getDate -- read/return date register of DS3234
00244 uint8_t DS3234::getDate(void)
00245 {
00246     _time[TIME_DATE] = spiReadByte(DS3234_REGISTER_DATE);
00247 
00248     return BCDtoDEC(_time[TIME_DATE]);      
00249 }
00250 
00251 // getMonth -- read/return month register of DS3234
00252 uint8_t DS3234::getMonth(void)
00253 {
00254     _time[TIME_MONTH] = spiReadByte(DS3234_REGISTER_MONTH);
00255     _time[TIME_MONTH] &= 0x7F; // Mask out century bit
00256 
00257     return BCDtoDEC(_time[TIME_MONTH]); 
00258 }
00259 
00260 // getYear -- read/return year register of DS3234
00261 uint8_t DS3234::getYear(void)
00262 {
00263     _time[TIME_YEAR] = spiReadByte(DS3234_REGISTER_YEAR);
00264 
00265     return BCDtoDEC(_time[TIME_YEAR]);      
00266 }
00267 
00268 // setSecond -- set the second register of the DS3234
00269 void DS3234::setSecond(uint8_t s)
00270 {
00271     if (s <= 59)
00272     {
00273         uint8_t _s = DECtoBCD(s);
00274         spiWriteByte(DS3234_REGISTER_SECONDS, _s);
00275     }
00276 }
00277 
00278 // setMinute -- set the minute register of the DS3234
00279 void DS3234::setMinute(uint8_t m)
00280 {
00281     if (m <= 59)
00282     {
00283         uint8_t _m = DECtoBCD(m);
00284         spiWriteByte(DS3234_REGISTER_MINUTES, _m);      
00285     }
00286 }
00287 
00288 // setHour -- set the hour register of the DS3234
00289 void DS3234::setHour(uint8_t h)
00290 {
00291     //! Check if 24-hour mode, am/pm
00292     if (h <= 23)
00293     {
00294         uint8_t _h = DECtoBCD(h);
00295         spiWriteByte(DS3234_REGISTER_HOURS, _h);
00296     }
00297 }
00298 
00299 // setDay -- set the day register of the DS3234
00300 void DS3234::setDay(uint8_t d)
00301 {
00302     if ((d >= 1) && (d <= 7))
00303     {
00304         uint8_t _d = DECtoBCD(d); //! Unecessary?
00305         return spiWriteByte(DS3234_REGISTER_DAY, _d);
00306     }
00307 }
00308 
00309 // setDate -- set the date register of the DS3234
00310 void DS3234::setDate(uint8_t d)
00311 {
00312     if (d <= 31)
00313     {
00314         uint8_t _d = DECtoBCD(d);
00315         spiWriteByte(DS3234_REGISTER_DATE, _d);
00316     }
00317 }
00318 
00319 // setMonth -- set the month register of the DS3234
00320 void DS3234::setMonth(uint8_t mo)
00321 {
00322     if ((mo >= 1) && (mo <= 12))
00323     {
00324         uint8_t _mo = DECtoBCD(mo);
00325         spiWriteByte(DS3234_REGISTER_MONTH, _mo);
00326     }
00327 }
00328 
00329 // setYear -- set the year register of the DS3234
00330 void DS3234::setYear(uint8_t y)
00331 {
00332     if (y <= 99)
00333     {
00334         uint8_t _y = DECtoBCD(y);
00335         spiWriteByte(DS3234_REGISTER_YEAR, _y);
00336     }
00337 }
00338 
00339 // set12Hour -- set (or not) to 12-hour mode) | enable12 defaults to  true
00340 void DS3234::set12Hour(bool enable12)
00341 {
00342     if (enable12)
00343         set24Hour(false);
00344     else
00345         set24Hour(true);
00346 }
00347 
00348 // set24Hour -- set (or not) to 24-hour mode) | enable24 defaults to  true
00349 void DS3234::set24Hour(bool enable24)
00350 {
00351     uint8_t hourRegister = spiReadByte(DS3234_REGISTER_HOURS);
00352     
00353     bool hour12 = hourRegister & TWELVE_HOUR_MODE;
00354     if ((hour12 && !enable24) || (!hour12 && enable24))
00355         return;
00356     
00357     uint8_t oldHour;
00358     uint8_t newHour;
00359     
00360     if (enable24)
00361     {
00362         oldHour = hourRegister & 0x1F; // Mask out am/pm and 12-hour mode
00363         oldHour = BCDtoDEC(oldHour); // Convert to decimal
00364         newHour = oldHour;
00365         
00366         bool hourPM = hourRegister & TWELVE_HOUR_PM;
00367         if ((hourPM) && (oldHour >= 1)) newHour += 12;
00368         else if (!(hourPM) && (oldHour == 12)) newHour = 0;
00369         newHour = DECtoBCD(newHour);
00370     }
00371     else
00372     {
00373         oldHour = hourRegister & 0x3F; // Mask out am/pm and 12-hour mode
00374         oldHour = BCDtoDEC(oldHour); // Convert to decimal
00375         newHour = oldHour;
00376         
00377         if (oldHour == 0) 
00378             newHour = 12;
00379         else if (oldHour >= 13)
00380             newHour -= 12;
00381         
00382         newHour = DECtoBCD(newHour);
00383         newHour |= TWELVE_HOUR_MODE; // Set bit 6 to set 12-hour mode
00384         if (oldHour >= 12)
00385             newHour |= TWELVE_HOUR_PM; // Set PM bit if necessary
00386     }
00387     
00388     return spiWriteByte(DS3234_REGISTER_HOURS, newHour);
00389 }
00390 
00391 // is12Hour -- check if the DS3234 is in 12-hour mode
00392 bool DS3234::is12Hour(void)
00393 {
00394     uint8_t hourRegister = spiReadByte(DS3234_REGISTER_HOURS);
00395     
00396     return hourRegister & TWELVE_HOUR_MODE;
00397 }
00398 
00399 // pm -- Check if 12-hour state is AM or PM
00400 bool DS3234::pm(void)
00401 {
00402     uint8_t hourRegister = spiReadByte(DS3234_REGISTER_HOURS);
00403     
00404     return hourRegister & TWELVE_HOUR_PM;   
00405 }
00406 
00407 // enable -- enable the DS3234's oscillator.
00408 void DS3234::enable(void)
00409 {
00410     uint8_t controlRegister = spiReadByte(DS3234_REGISTER_CONTROL);
00411     
00412     controlRegister &= ~(1<<7);
00413     
00414     spiWriteByte(DS3234_REGISTER_CONTROL, controlRegister);
00415 }
00416 
00417 // disable -- disable the DS3234's oscillator
00418 //  (Only effects chip when powered by battery.)
00419 void DS3234::disable(void)
00420 {
00421     uint8_t controlRegister = spiReadByte(DS3234_REGISTER_CONTROL);
00422     
00423     controlRegister |= (1<<7);
00424     
00425     spiWriteByte(DS3234_REGISTER_CONTROL, controlRegister);
00426 }
00427 
00428 // setAlarm1 -- Alarm 1 can be set to trigger on seconds, minutes, hours, and/or date/day.
00429 // Any of those can be masked out -- ignored for an alarm match. By setting
00430 // If a value is set to 255, the library will mask out that data.
00431 // By default the "date" value is the day-of-month (1-31)
00432 // The "day" boolean changes the "date" value to a day (between 1-7).
00433 void DS3234::setAlarm1(uint8_t second, uint8_t minute, uint8_t hour, uint8_t date, bool day)
00434 {
00435     uint8_t alarmRegister[4];
00436     uint8_t timeValue[4] = {second, minute, hour, date};
00437     uint8_t timeMin[4] = {0, 0, 0, 1};
00438     uint8_t timeMax[4] = {59, 59, 23, 31};
00439     if (day)
00440         timeMax[3] = 7;
00441     
00442     spiReadBytes(DS3234_REGISTER_A1SEC, alarmRegister, 4); // Read current alarm values
00443     
00444     // Run through all four alarm values and set their register values:
00445     for (int i=0; i<4; i++)
00446     {
00447         if (timeValue[i] == 255) // If 255, disable the check on that value
00448             alarmRegister[i] |= ALARM_MODE_BIT;
00449         else if ((timeValue[i] >= timeMin[i]) && (timeValue[i] <= timeMax[i]))
00450             alarmRegister[i] = DECtoBCD(timeValue[i]);
00451     }
00452     if (day) 
00453         alarmRegister[3] |= ALARM_DAY_BIT;
00454     
00455     spiWriteBytes(DS3234_REGISTER_A1SEC, alarmRegister, 4); // Write the values
00456 }
00457 
00458 // setAlarm1 (12-hour mode)
00459 void DS3234::setAlarm1(uint8_t second, uint8_t minute, uint8_t hour12, bool pm, uint8_t date, bool day)
00460 {
00461     uint8_t alarmRegister[4];
00462     uint8_t timeValue[4] = {second, minute, hour12, date};
00463     uint8_t timeMin[4] = {0, 0, 0, 1};
00464     uint8_t timeMax[4] = {59, 59, 23, 31};
00465     if (day)
00466         timeMax[3] = 7;
00467     
00468     spiReadBytes(DS3234_REGISTER_A1SEC, alarmRegister, 4); // Read current alarm values
00469     
00470     // Run through all four alarm values and set their register values:
00471     for (int i=0; i<4; i++)
00472     {
00473         if (timeValue[i] == 255) // If 255, disable the check on that value
00474             alarmRegister[i] |= ALARM_MODE_BIT;
00475         else if ((timeValue[i] >= timeMin[i]) && (timeValue[i] <= timeMax[i]))
00476             alarmRegister[i] = DECtoBCD(timeValue[i]);
00477     }
00478     if (day) 
00479         alarmRegister[3] |= ALARM_DAY_BIT;
00480     alarmRegister[2] |= TWELVE_HOUR_MODE;
00481     if (pm) alarmRegister[2] |= TWELVE_HOUR_PM;
00482     
00483     spiWriteBytes(DS3234_REGISTER_A1SEC, alarmRegister, 4); // Write the values
00484 }
00485 
00486 // setAlarm2 -- Alarm 2 can be set to trigger on minutes, hours, and/or date/day.
00487 // Any of those can be masked out -- ignored for an alarm match. By setting
00488 // If a value is set to 255, the library will mask out that data.
00489 // By default the "date" value is the day-of-month (1-31)
00490 // The "day" boolean changes the "date" value to a day (between 1-7).
00491 void DS3234::setAlarm2(uint8_t minute, uint8_t hour, uint8_t date, bool day)
00492 {
00493     uint8_t alarmRegister[3];
00494     uint8_t timeValue[3] = {minute, hour, date};
00495     uint8_t timeMin[3] = {0, 0, 1};
00496     uint8_t timeMax[3] = {59, 23, 31};
00497     if (day)
00498         timeMax[2] = 7;
00499     
00500     spiReadBytes(DS3234_REGISTER_A2MIN, alarmRegister, 3); // Read all alarm 2 registers
00501     
00502     for (int i=0; i<3; i++)
00503     {
00504         if (timeValue[i] == 255) // If a value is 255, disable that alarm check
00505             alarmRegister[i] |= ALARM_MODE_BIT;
00506         else if ((timeValue[i] >= timeMin[i]) && (timeValue[i] <= timeMax[i]))
00507             alarmRegister[i] = DECtoBCD(timeValue[i]);
00508     }
00509     if (day) 
00510         alarmRegister[2] |= ALARM_DAY_BIT;
00511     
00512     spiWriteBytes(DS3234_REGISTER_A2MIN, alarmRegister, 3);
00513 }
00514 
00515 // setAlarm2 (12-hour mode)
00516 void DS3234::setAlarm2(uint8_t minute, uint8_t hour12, bool pm, uint8_t date, bool day)
00517 {   
00518     uint8_t alarmRegister[3];
00519     uint8_t timeValue[3] = {minute, hour12, date};
00520     uint8_t timeMin[3] = {0, 0, 1};
00521     uint8_t timeMax[3] = {59, 23, 31};
00522     if (day)
00523         timeMax[2] = 7;
00524     
00525     spiReadBytes(DS3234_REGISTER_A2MIN, alarmRegister, 3); // Read all alarm 2 registers
00526     
00527     for (int i=0; i<3; i++)
00528     {
00529         if (timeValue[i] == 255) // If a value is 255, disable that alarm check
00530             alarmRegister[i] |= ALARM_MODE_BIT;
00531         else if ((timeValue[i] >= timeMin[i]) && (timeValue[i] <= timeMax[i]))
00532             alarmRegister[i] = DECtoBCD(timeValue[i]);
00533     }
00534     if (day) 
00535         alarmRegister[1] |= ALARM_DAY_BIT;
00536     alarmRegister[1] |= TWELVE_HOUR_MODE;
00537     if (pm) alarmRegister[1] |= TWELVE_HOUR_PM;
00538     
00539     spiWriteBytes(DS3234_REGISTER_A2MIN, alarmRegister, 3);
00540 }
00541 
00542 // alarm1 -- Check the alarm 1 flag in the status register
00543 bool DS3234::alarm1(bool clear)
00544 {
00545     uint8_t statusRegister = spiReadByte(DS3234_REGISTER_STATUS);
00546     
00547     if (statusRegister & ALARM_1_FLAG_BIT)
00548     {
00549         if (clear)
00550         {
00551             statusRegister &= ~(ALARM_1_FLAG_BIT);
00552             spiWriteByte(DS3234_REGISTER_STATUS, statusRegister);
00553         }
00554         return true;
00555     }
00556     
00557     return false;
00558 }
00559 
00560 // alarm2 -- Check the alarm 2 flag in the status register
00561 bool DS3234::alarm2(bool clear)
00562 {
00563     uint8_t statusRegister = spiReadByte(DS3234_REGISTER_STATUS);
00564     
00565     if (statusRegister & ALARM_2_FLAG_BIT)
00566     {
00567         if (clear)
00568         {
00569             statusRegister &= ~(ALARM_2_FLAG_BIT);
00570             spiWriteByte(DS3234_REGISTER_STATUS, statusRegister);
00571         }
00572         return true;    
00573     }
00574     
00575     return false;
00576 }
00577 
00578 // enableAlarmInterrupt -- Enable the SQW interrupt output on one, or both, alarms
00579 void DS3234::enableAlarmInterrupt(bool alarm1, bool alarm2)
00580 {
00581     uint8_t controlRegister = spiReadByte(DS3234_REGISTER_CONTROL);
00582     controlRegister |= ALARM_INTCN_BIT;
00583     if (alarm1) 
00584         controlRegister |= (1<<0);
00585     if (alarm2)
00586         controlRegister |= (1<<1);
00587     spiWriteByte(DS3234_REGISTER_CONTROL, controlRegister);
00588 }
00589 
00590 // writeSQW -- Set the SQW pin high, low, or to one of the square wave frequencies
00591 void DS3234::writeSQW(sqw_rate value)
00592 {
00593     uint8_t controlRegister = spiReadByte(DS3234_REGISTER_CONTROL);
00594     
00595     controlRegister &= SQW_CONTROL_MASK; // Mask out RS1, RS2 bits (bits 3 and 4)
00596     controlRegister |= (value << 3); // Add rate bits, shift left 3
00597     controlRegister &= ~(SQW_ENABLE_BIT); // Clear INTCN bit to enable SQW output
00598     spiWriteByte(DS3234_REGISTER_CONTROL, controlRegister);
00599 }
00600 
00601 // temperature -- Read the DS3234's die-temperature. 
00602 //  Value is produced in multiples of 0.25 deg C
00603 float DS3234::temperature(void)
00604 {
00605     float retVal = 0;
00606     int8_t integer;
00607     uint8_t tempRegister[2];
00608     spiReadBytes(DS3234_REGISTER_TEMPM, tempRegister, 2);
00609     
00610     integer = tempRegister[0];
00611     tempRegister[1] = tempRegister[1] >> 6;
00612     retVal = integer + ((float) tempRegister[1] * 0.25);
00613     
00614     return retVal;
00615 }
00616 
00617 // BCDtoDEC -- convert binary-coded decimal (BCD) to decimal
00618 uint8_t DS3234::BCDtoDEC(uint8_t val)
00619 {
00620     return ( ( val / 0x10) * 10 ) + ( val % 0x10 );
00621 }
00622 
00623 // BCDtoDEC -- convert decimal to binary-coded decimal (BCD)
00624 uint8_t DS3234::DECtoBCD(uint8_t val)
00625 {
00626     return ( ( val / 10 ) * 0x10 ) + ( val % 10 );
00627 }
00628 
00629 // spiWriteBytes -- write a set number of bytes to an SPI device, incrementing from a register
00630 void DS3234::spiWriteBytes(DS3234_registers reg, uint8_t * values, uint8_t len)
00631 {
00632     uint8_t writeReg = reg | 0x80;
00633     
00634     _csPin->setDigitalValue(0);
00635     spi.write(writeReg);
00636     for (int i=0; i<len; i++)
00637     {
00638         spi.write(values[i]);
00639     }
00640     _csPin->setDigitalValue(1);
00641 }
00642 
00643 // spiWriteBytes -- write a byte value to an spi device's register
00644 void DS3234::spiWriteByte(DS3234_registers reg, uint8_t value)
00645 {
00646     uint8_t writeReg = reg | 0x80;
00647     
00648     _csPin->setDigitalValue(0);
00649     spi.write(writeReg);
00650     spi.write(value);
00651     _csPin->setDigitalValue(1);
00652 }
00653 
00654 // spiWriteBytes -- read a byte from an spi device's register
00655 uint8_t DS3234::spiReadByte(DS3234_registers reg)
00656 {
00657     uint8_t retVal = 0;
00658     
00659     _csPin->setDigitalValue(0);
00660     
00661     spi.write(reg);
00662     retVal = spi.write(0x00);
00663     
00664     _csPin->setDigitalValue(1);
00665     
00666     return retVal;
00667 }
00668 
00669 // spiWriteBytes -- read a set number of bytes from an spi device, incrementing from a register
00670 void DS3234::spiReadBytes(DS3234_registers reg, uint8_t * dest, uint8_t len)
00671 {
00672     _csPin->setDigitalValue(0);
00673     spi.write(reg);
00674     for (int i=0; i<len; i++)
00675     {
00676         dest[i] = spi.write(0x00);
00677     }
00678     _csPin->setDigitalValue(1);
00679 }
00680 
00681 void DS3234::writeToSRAM(uint8_t address, uint8_t data){
00682   spiWriteByte(DS3234_REGISTER_SRAMA, address);
00683   spiWriteByte(DS3234_REGISTER_SRAMD, data);
00684 }
00685 
00686 uint8_t DS3234::readFromSRAM(uint8_t address){
00687   spiWriteByte(DS3234_REGISTER_SRAMA, address);
00688   return spiReadByte(DS3234_REGISTER_SRAMD);
00689 }
00690 
00691 
00692 DS3234 rtc; // Use rtc in sketches