un programa que prueba que el DS3231 funciona bien en una FRDMKL25Z

Files at this revision

API Documentation at this revision

Comitter:
j3
Date:
Thu Nov 20 00:03:27 2014 +0000
Parent:
1:c814af60fdbf
Child:
3:312589d8185c
Commit message:
initial implementation of member functions

Changed in this revision

ds3231.cpp Show annotated file Show diff for this revision Revisions of this file
ds3231.h Show annotated file Show diff for this revision Revisions of this file
--- 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;
+}
+
+
--- a/ds3231.h	Wed Nov 19 04:16:33 2014 +0000
+++ b/ds3231.h	Thu Nov 20 00:03:27 2014 +0000
@@ -57,9 +57,10 @@
 #define I2C_WRITE 0
 #define I2C_READ  1
 
-#define AM_PM       (1 << 5)
-#define TIME_FORMAT (1 << 6)
-#define DY_DT       (1 << 6)
+#define AM_PM     (1 << 5) 
+#define MODE      (1 << 6)
+#define DY_DT     (1 << 6)
+#define ALRM_MASK (1 << 7)
 
 //control register bit masks
 #define A1IE  (1 << 0)
@@ -69,7 +70,7 @@
 #define RS2   (1 << 4)
 #define CONV  (1 << 5)
 #define BBSQW (1 << 6)
-#define EOSC (1 << 7)
+#define EOSC  (1 << 7)
 
 //status register bit masks
 #define A1F     (1 << 0)
@@ -108,6 +109,8 @@
     uint8_t seconds;
     uint8_t minutes;
     uint8_t hours;
+    bool am_pm; //TRUE for PM, same logic as datasheet
+    bool mode; //TRUE for 12 hour, same logic as datasheet
 }ds3231_time_t;
 
 
@@ -127,6 +130,13 @@
     uint8_t hours;
     uint8_t day;
     uint8_t date;
+    bool am1; //not used for alarm 2
+    bool am2;
+    bool am3;
+    bool am4;
+    bool am_pm; //TRUE for PM, same logic as datasheet
+    bool mode; //TRUE for 12 hour, same logic as datasheet
+    bool dy_dt; //TRUE for Day, same logic as datasheet
 }ds3231_alrm_t;
 
 
@@ -144,6 +154,31 @@
 {
     uint8_t w_adrs, r_adrs;
     
+    /**********************************************************//**
+    * 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 uchar_2_bcd(uint8_t data);
+    
+    
+    /**********************************************************//**
+    * 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 bcd_2_uchar(uint8_t bcd);
+    
     public:
         /**********************************************************//**
         * Constructor for Ds3231 Class
@@ -168,6 +203,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; 
@@ -194,6 +231,8 @@
         
         /**********************************************************//**
         * Sets the calendar on DS3231
+        * Struct data is in integrer format, not BCD.  Fx will convert
+        * to BCD for you.
         *
         * On Entry:
         *     @param[in] calendar - struct cotaining calendar data; 
@@ -221,6 +260,8 @@
         
         /**********************************************************//**
         * Set either Alarm1 or Alarm2 of DS3231
+        * Struct data is in integrer format, not BCD.  Fx will convert
+        * to BCD for you.
         *
         * On Entry:
         *     @param[in] alarm - struct cotaining alarm data 
@@ -279,11 +320,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:
@@ -299,18 +341,20 @@
         *
         * @endcode
         **************************************************************/
-        uint16_t get_time(ds3231_time_t time);
+        uint16_t get_time(ds3231_time_t* time);
         
         
         /**********************************************************//**
         * 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:
@@ -327,21 +371,23 @@
         *
         * @endcode
         **************************************************************/
-        uint16_t get_calendar(ds3231_calendar_t calendar);
+        uint16_t get_calendar(ds3231_calendar_t* calendar);
         
         
         /**********************************************************//**
         * 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:
@@ -358,15 +404,15 @@
         *
         * @endcode
         **************************************************************/
-        uint16_t get_alarm(ds3231_alrm_t alarm, bool one_r_two);
+        uint16_t get_alarm(ds3231_alrm_t* alarm, bool one_r_two);
         
         
         /**********************************************************//**
         * 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
@@ -386,18 +432,16 @@
         *
         * @endcode
         **************************************************************/
-        uint16_t get_cntl_stat_reg(ds3231_cntl_stat_t data);
+        uint16_t get_cntl_stat_reg(ds3231_cntl_stat_t* data);
         
         
         /**********************************************************//**
         * 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
@@ -405,14 +449,13 @@
         * //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 get_temperature(uint16_t temp);
+        uint16_t get_temperature(void);
         
 };
 #endif /* DS3231_H*/