student_with_profs_snec / DS_3231
Revision:
0:d801ad2b1422
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS_3231.cpp	Sun Mar 06 14:21:57 2022 +0000
@@ -0,0 +1,314 @@
+#include "DS_3231.h"
+
+//Constructeur avec 2 broches i2c
+DS_3231::DS_3231(PinName SDA, PinName SCL): i2c(SDA,SCL)
+{
+    w_adrs = ((DS3231_I2C_ADRS << 1) | I2C_WRITE);
+    r_adrs = ((DS3231_I2C_ADRS << 1) | I2C_READ);
+}
+
+// ecrire l'horaire dans le composant
+// arguments : structure de type horaire
+// cette fonction renvoie 0 si opération OK,1  si capteur absent
+/*
+* Example:
+* @code
+*
+* //instantiate rtc object
+* DS_3231 horloge(D14, D15);
+*
+* //time = 12:00:00 AM 12hr mode
+* ds3231_time_t time = {12, 0, 0, 0, 1}
+* uint16_t rtn_val;
+*
+* rtn_val = rtc.set_time(time);
+*
+* @endcode
+**************************************************************/
+uint16_t DS_3231::set_time(DS_3231_time_t time)
+{
+    uint8_t data[] = {0,0,0,0};
+    uint8_t data_length = 0;
+    uint8_t max_hour = 24;
+
+    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++;
+
+    //Make sure data is within range.
+    if((time.seconds > 59) || (time.minutes > 59) || (time.hours > max_hour)) {
+        return(1);
+    } else {
+        return(i2c.write(w_adrs,(const char*) data, data_length));
+    }
+}
+
+
+
+/**********************************************************//**
+* Lire l'horaire sur l'horloge
+*
+// arguments : pointeur vers une structure de type horaire
+// cette fonction renvoie 0 si opération OK,1  si capteur absent
+
+* Example:
+* @code
+*
+* //instantiate rtc object
+* Ds3231 rtc(D14, D15);
+*
+* //time = 12:00:00 AM 12hr mode
+* ds3231_time_t time = {12, 0, 0, 0, 1}
+* uint16_t rtn_val;
+*
+* rtn_val = rtc.get_time(&time);
+*
+* @endcode
+**************************************************************/
+uint16_t DS_3231::get_time(DS_3231_time_t* time)
+{
+    uint16_t rtn_val = 1;
+    uint8_t data[3];
+    data[0] = SECONDS;
+    rtn_val = i2c.write(w_adrs, (const char*) data, 1);
+    if(!rtn_val) {
+        rtn_val = i2c.read(r_adrs,(char *) data, 3);
+        time->seconds = bcd_2_uchar(data[0]);
+        time->minutes = bcd_2_uchar(data[1]);
+        time->am_pm = (data[2]&AM_PM);
+        time->mode = (data[2]&MODE);
+        if(time->mode) {
+            time->hours = bcd_2_uchar((data[2]&0x1F));
+        } else {
+            time->hours = bcd_2_uchar((data[2]&0x3F));
+        }
+    }
+    return(rtn_val);
+}
+
+// programmer une alarme sur l'horloge
+// arguments : structure de type alarme, numero de la voie alarme 0/1 pour alrm1/2
+// cette fonction renvoie 0 si opération OK,1  si capteur absent
+uint16_t DS_3231::set_alarm(DS_3231_alrm_t alarm, bool one_r_two)
+{
+    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;
+    }  
+    
+    //Make sure data is within range.
+    if((alarm.seconds > 59) || (alarm.minutes > 59) || (alarm.hours > max_hour) || 
+       ((alarm.day < 1) || (alarm.day > 7)) || 
+       ((alarm.date < 1) || (alarm.date > 31)))
+    {
+        return(1);
+    }
+    else
+    {
+        return(i2c.write(w_adrs,(const char*) data, data_length));
+    }    
+    }
+
+// programmer les registres d'etat et de controle sur l'horloge
+// arguments : structure de type registre de controle/etat
+// cette fonction renvoie 0 si opération OK,1  si pb
+// Example:
+        /* //do not use 0xAA, see datasheet for appropriate data 
+        * ds3231_cntl_stat_t data = {0xAA, 0xAA}; 
+        *
+        * rtn_val = rtc.set_cntl_stat_reg(data);
+        *
+        * @endcode
+        **************************************************************/
+uint16_t DS_3231::set_cntl_stat_reg(DS_3231_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;
+
+    //users responsibility to make sure data is logical
+    return(i2c.write(w_adrs,(const char*) local_data, data_length));
+}
+
+// raz flag alarme
+
+char DS_3231::raz_alm1()
+    {
+    char buffer_envoi[2]={0x0F,0x00}; 
+    char data;
+    char test = i2c.write(w_adrs,buffer_envoi,1);
+    test = i2c.read(r_adrs,&data,1);
+    data=data&&0xFE;
+    buffer_envoi[1]=data;
+    test = i2c.write(w_adrs,buffer_envoi,2);    
+    return test;
+            }
+            
+
+
+
+
+/**********************************************************//**
+* Conversion d'un uint8_t en bcd
+* argument: valeur de la valeur à convertir en BDC (0 à 255)
+* valeur retournée :  = valeur convertie en BCD
+* par exemple unint16_t toto = uchar_2_bcd(323); => toto = 0x323
+**************************************************************/
+uint16_t DS_3231::uchar_2_bcd(uint8_t data)
+{
+    uint16_t bcd_result = 0;
+
+    //Obtention des centaines
+    bcd_result |= ((data/100) << 8);
+    data = (data - (data/100)*100);
+
+    //Obtention des dizaines
+    bcd_result |= ((data/10) << 4);
+    data = (data - (data/10)*10);
+
+    //Obtention des unites
+    bcd_result |= data;
+    return(bcd_result);
+}
+
+/**********************************************************//**
+* Conversion d'un bcd en uint8_t
+* argument: valeur de la valeur à convertir en BCD
+* valeur retournée :  = valeur convertie en uint8
+* par exemple :
+**************************************************************/
+uint8_t DS_3231::bcd_2_uchar(uint8_t bcd)
+{
+    uint8_t rtn_val = 0;
+
+    rtn_val += ((bcd&0xf0)>>4)*10;
+    rtn_val += (bcd&0x000f);   
+
+    return rtn_val;
+}
\ No newline at end of file