j
Fork of ds3231 by
Diff: ds3231.cpp
- Revision:
- 2:4e6e761c60f2
- Parent:
- 1:c814af60fdbf
- Child:
- 3:312589d8185c
diff -r c814af60fdbf -r 4e6e761c60f2 ds3231.cpp --- a/ds3231.cpp Wed Nov 19 04:16:33 2014 +0000 +++ b/ds3231.cpp Thu Nov 20 00:03:27 2014 +0000 @@ -76,6 +76,8 @@ /**********************************************************//** * Sets the time on DS3231 +* Struct data is in integrer format, not BCD. Fx will convert +* to BCD for you. * * On Entry: * @param[in] time - struct cotaining time data; @@ -99,8 +101,42 @@ **************************************************************/ uint16_t Ds3231::set_time(ds3231_time_t time) { + uint8_t data[] = {0,0,0,0}; + uint8_t data_length = 0; + uint8_t max_hour = 24; - return 0; + data[data_length++] = SECONDS; + data[data_length++] = uchar_2_bcd(time.seconds); + data[data_length++] = uchar_2_bcd(time.minutes); + + //format Hours register + data[data_length] = uchar_2_bcd(time.hours); + if(time.mode) + { + max_hour = max_hour/2; + + data[data_length] |= MODE; + if(time.am_pm) + { + data[data_length] |= AM_PM; + } + + } + else + { + max_hour = max_hour - 1; + } + data_length++; + + //Test for good data. + if((time.seconds > 59) || (time.minutes > 59) || (time.hours > max_hour)) + { + return(1); + } + else + { + return(write(w_adrs,(const char*) data, data_length)); + } } @@ -130,8 +166,17 @@ **************************************************************/ uint16_t Ds3231::set_calendar(ds3231_calendar_t calendar) { + uint8_t data[] = {0,0,0,0,0}; + uint8_t data_length = 0; + + data[data_length++] = DAY; + data[data_length++] = uchar_2_bcd(calendar.day); + data[data_length++] = uchar_2_bcd(calendar.date); + data[data_length++] = uchar_2_bcd(calendar.month); + data[data_length++] = uchar_2_bcd(calendar.year); - return 0; + //users responsibility to make sure calendar is logical + return(write(w_adrs,(const char*) data, data_length)); } @@ -164,8 +209,128 @@ **************************************************************/ uint16_t Ds3231::set_alarm(ds3231_alrm_t alarm, bool one_r_two) { - - return 0; + uint8_t data[] = {0,0,0,0,0}; + uint8_t data_length = 0; + uint8_t max_hour = 24; + uint8_t mask_var = 0; + + //setting alarm 1 or 2? + if(one_r_two) + { + data[data_length++] = ALRM1_SECONDS; + + //config seconds register + if(alarm.am1) + { + mask_var |= ALRM_MASK; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.seconds)); + mask_var = 0; + + //config minutes register + if(alarm.am2) + { + mask_var |= ALRM_MASK; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes)); + mask_var = 0; + + //config hours register + if(alarm.am3) + { + mask_var |= ALRM_MASK; + } + if(alarm.mode) + { + max_hour = max_hour/2; + mask_var |= MODE; + if(alarm.am_pm) + { + mask_var |= AM_PM; + } + } + else + { + max_hour = max_hour - 1; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours)); + mask_var = 0; + + //config day/date register + if(alarm.am4) + { + mask_var |= ALRM_MASK; + } + if(alarm.dy_dt) + { + mask_var |= DY_DT; + data[data_length++] = (mask_var | uchar_2_bcd(alarm.day)); + } + else + { + data[data_length++] = (mask_var | uchar_2_bcd(alarm.date)); + } + mask_var = 0; + } + else + { + data[data_length++] = ALRM2_MINUTES; + + //config minutes register + if(alarm.am2) + { + mask_var |= ALRM_MASK; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.minutes)); + mask_var = 0; + + //config hours register + if(alarm.am3) + { + mask_var |= ALRM_MASK; + } + if(alarm.mode) + { + max_hour = max_hour/2; + mask_var |= MODE; + if(alarm.am_pm) + { + mask_var |= AM_PM; + } + } + else + { + max_hour = max_hour - 1; + } + data[data_length++] = (mask_var | uchar_2_bcd(alarm.hours)); + mask_var = 0; + + //config day/date register + if(alarm.am4) + { + mask_var |= ALRM_MASK; + } + if(alarm.dy_dt) + { + mask_var |= DY_DT; + data[data_length++] = (mask_var | uchar_2_bcd(alarm.day)); + } + else + { + data[data_length++] = (mask_var | uchar_2_bcd(alarm.date)); + } + mask_var = 0; + } + + //Test for good data. + if((alarm.seconds > 59) || (alarm.minutes > 59) || (alarm.hours > max_hour) || (alarm.day > 7) || (alarm.date > 31)) + { + return(1); + } + else + { + return(write(w_adrs,(const char*) data, data_length)); + } } @@ -194,8 +359,15 @@ **************************************************************/ uint16_t Ds3231::set_cntl_stat_reg(ds3231_cntl_stat_t data) { + uint8_t local_data[] = {0,0,0}; + uint8_t data_length = 0; + + local_data[data_length++] = CONTROL; + local_data[data_length++] = data.control; + local_data[data_length++] = data.status; - return 0; + //users responsibility to make sure data is logical + return(write(w_adrs,(const char*) local_data, data_length)); } @@ -203,11 +375,12 @@ * Gets the time on DS3231 * * On Entry: -* @param[in] time - struct for storing time data; -* seconds, minutes and hours +* @param[in] time - pointer to struct for storing time +* data; seconds, minutes and hours * * On Exit: -* @param[out] time - contains current rtc time data +* @param[out] time - contains current integrer rtc time +* data * @return return value = 0 on success, non-0 on failure * * Example: @@ -223,10 +396,24 @@ * * @endcode **************************************************************/ -uint16_t Ds3231::get_time(ds3231_time_t time) +uint16_t Ds3231::get_time(ds3231_time_t* time) { - - return 0; + uint16_t rtn_val = 1; + uint8_t data[3]; + + data[0] = SECONDS; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) data, 3); + + time->seconds = bcd_2_uchar(data[0]); + time->minutes = bcd_2_uchar(data[1]); + time->hours = bcd_2_uchar((data[2]&0x1F)); + } + + return(rtn_val); } @@ -234,11 +421,13 @@ * Gets the calendar on DS3231 * * On Entry: -* @param[in] calendar - struct for storing calendar data; +* @param[in] calendar - pointer to struct for storing +* calendar data; * day, date, month, year * * On Exit: -* @param[out] calendar - contains current rtc calendar +* @param[out] calendar - contains current integer rtc +* calendar data * @return return value = 0 on success, non-0 on failure * * Example: @@ -255,10 +444,25 @@ * * @endcode **************************************************************/ -uint16_t Ds3231::get_calendar(ds3231_calendar_t calendar) +uint16_t Ds3231::get_calendar(ds3231_calendar_t* calendar) { - - return 0; + uint16_t rtn_val = 1; + uint8_t data[4]; + + data[0] = DAY; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) data, 4); + + calendar->day = bcd_2_uchar(data[0]); + calendar->date = bcd_2_uchar(data[1]); + calendar->month = bcd_2_uchar((data[2]&0x1F)); + calendar->year = bcd_2_uchar(data[3]); + } + + return(rtn_val); } @@ -266,14 +470,16 @@ * Get either Alarm1 or Alarm2 of DS3231 * * On Entry: -* @param[in] alarm - struct for storing alarm data +* @param[in] alarm - pointer to struct for storing alarm +* data; * seconds, minutes, hours, day, date * seconds used on Alarm1 only +* * @param[in] one_r_two - TRUE for Alarm1 and FALSE for * Alarm2 * * On Exit: -* @param[out] alarm - contains alarm register data +* @param[out] alarm - contains integer alarm data * @return return value = 0 on success, non-0 on failure * * Example: @@ -290,10 +496,58 @@ * * @endcode **************************************************************/ -uint16_t Ds3231::get_alarm(ds3231_alrm_t alarm, bool one_r_two) +uint16_t Ds3231::get_alarm(ds3231_alrm_t* alarm, bool one_r_two) { - - return 0; + uint16_t rtn_val = 1; + uint8_t data[4]; + + if(one_r_two) + { + data[0] = ALRM1_SECONDS; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) data, 4); + + alarm->seconds = bcd_2_uchar(data[0]&0x7F); + alarm->minutes = bcd_2_uchar(data[1]&0x7F); + alarm->hours = bcd_2_uchar(data[2]&0x1F); + + if(data[3] & DY_DT) + { + alarm->day = bcd_2_uchar(data[3]&0x0F); + } + else + { + alarm->date = bcd_2_uchar(data[3]&0x3F); + } + } + } + else + { + data[0] = ALRM2_MINUTES; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) data, 4); + + alarm->minutes = bcd_2_uchar(data[0]&0x7F); + alarm->hours = bcd_2_uchar(data[1]&0x1F); + + if(data[3] & DY_DT) + { + alarm->day = bcd_2_uchar(data[2]&0x0F); + } + else + { + alarm->date = bcd_2_uchar(data[2]&0x3F); + } + } + } + + return(rtn_val); } @@ -301,8 +555,8 @@ * Get control and status registers of DS3231 * * On Entry: -* @param[in] data - Struct for storing control and status -* register data +* @param[in] data - pointer to struct for storing control +* nd status register data * * On Exit: * @param[out] data - contains control and status registers @@ -322,10 +576,23 @@ * * @endcode **************************************************************/ -uint16_t Ds3231::get_cntl_stat_reg(ds3231_cntl_stat_t data) +uint16_t Ds3231::get_cntl_stat_reg(ds3231_cntl_stat_t* data) { - - return 0; + uint16_t rtn_val = 1; + uint8_t local_data[2]; + + local_data[0] = CONTROL; + rtn_val = write(w_adrs, (const char*) local_data, 1); + + if(!rtn_val) + { + rtn_val = read(r_adrs,(char *) local_data, 2); + + data->control = local_data[0]; + data->status = local_data[1]; + } + + return(rtn_val); } @@ -333,11 +600,9 @@ * Get temperature data of DS3231 * * On Entry: -* @param[in] temp - Integer for storing temperature data * * On Exit: -* @param[out] temp - contains temperature data -* @return return value = 0 on success, non-0 on failure +* @return return value = raw temperature data * * Example: * @code @@ -345,16 +610,79 @@ * //instantiate rtc object * Ds3231 rtc(D14, D15); * -* //do not use 0xAA, see datasheet for appropriate data * uint16_t temp; * -* rtn_val = rtc.get_temperature(temp); +* temp = rtc.get_temperature(); * * @endcode **************************************************************/ -uint16_t Ds3231::get_temperature(uint16_t temp) +uint16_t Ds3231::get_temperature(void) { - - return 0; + uint16_t rtn_val = 1; + uint8_t data[2]; + + data[0] = MSB_TEMP; + rtn_val = write(w_adrs, (const char*) data, 1); + + if(!rtn_val) + { + read(r_adrs,(char *) data, 2); + + rtn_val = data[0] << 8; + rtn_val |= data[1]; + } + + return(rtn_val); } + +/**********************************************************//** +* Private mmber fx, converts unsigned char to BCD +* +* On Entry: +* @param[in] data - 0-255 +* +* On Exit: +* @return bcd_result = BCD representation of data +* +**************************************************************/ +uint16_t Ds3231::uchar_2_bcd(uint8_t data) +{ + uint16_t bcd_result = 0; + + //Get hundreds + bcd_result |= ((data/100) << 8); + data = (data - (data/100)*100); + + //Get tens + bcd_result |= ((data/10) << 4); + data = (data - (data/10)*10); + + //Get ones + bcd_result |= data; + + return(bcd_result); +} + + +/**********************************************************//** +* Private mmber fx, converts BCD to a uint8_t +* +* On Entry: +* @param[in] bcd - 0-99 +* +* On Exit: +* @return rtn_val = integer rep. of BCD +* +**************************************************************/ +uint8_t Ds3231::bcd_2_uchar(uint8_t bcd) +{ + uint8_t rtn_val = 0; + + rtn_val += ((bcd&0xf0)>>4)*10; + rtn_val += (bcd&0x000f); + + return rtn_val; +} + +