student_with_profs_snec / DS_3231

Files at this revision

API Documentation at this revision

Comitter:
snec_student
Date:
Sun Mar 06 14:21:57 2022 +0000
Commit message:
fonctionne depart arret HTR; ;

Changed in this revision

DS_3231.cpp Show annotated file Show diff for this revision Revisions of this file
DS_3231.h Show annotated file Show diff for this revision Revisions of this file
--- /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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS_3231.h	Sun Mar 06 14:21:57 2022 +0000
@@ -0,0 +1,167 @@
+#include "mbed.h"
+
+#ifndef DS_3231_H
+#define DS_3211_H
+
+
+
+#define DS3231_I2C_ADRS 0x68
+#define I2C_WRITE 0
+#define I2C_READ  1
+
+#define AM_PM     (1 << 5)
+#define MODE      (1 << 6)
+#define DY_DT     (1 << 6)
+#define ALRM_MASK (1 << 7)
+
+/** definition d'une structure de type temps
+* DS_3231_time_t - Structure permettant de cntenir un temps
+* Membres:
+* - uint32_t seconds - Use decimal value. Member fx's convert to BCD
+* - uint32_t minutes - Use decimal value. Member fx's convert to BCD
+* - uint32_t hours   - Use decimal value. Member fx's convert to BCD
+* - bool am_pm      - TRUE for PM, same logic as datashee
+* - bool mode       - TRUE for 12 hour, same logic as datasheet */
+typedef struct { //
+    uint32_t seconds;       //valeur des secondes
+    uint32_t minutes;       //valeur des minutes
+    uint32_t hours;         //valeur des heures
+    bool am_pm;             // 0 pour AM, 1 pour PM
+    bool mode;              // 0 pour format 24 heures, 1 pour format 12 heures
+} DS_3231_time_t;
+
+/**definition d'une structure de type alarme
+* Members:
+* - uint32_t seconds - Use decimal value. Member fx's convert to BCD 
+* - uint32_t minutes - Use decimal value. Member fx's convert to BCD 
+* - uint32_t hours   - Use decimal value. Member fx's convert to BCD 
+* - uint32_t day     - Use decimal value. Member fx's convert to BCD 
+* - uint32_t date    - Use decimal value. Member fx's convert to BCD 
+* - bool am1        - Flag for setting alarm rate
+* - bool am2        - Flag for setting alarm rate
+* - bool am3        - Flag for setting alarm rate
+* - bool am4        - Flag for setting alarm rate
+* - 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
+*/
+typedef struct
+{
+    //Seconds and am1 not used for alarm2
+    uint32_t seconds; 
+    uint32_t minutes; 
+    uint32_t hours; 
+    uint32_t day; 
+    uint32_t date; 
+    bool am1; 
+    bool am2;
+    bool am3;
+    bool am4;
+    bool am_pm; 
+    bool mode; 
+    bool dy_dt;
+}DS_3231_alrm_t;
+
+/**Definition des registres de configuration et d'etat
+* Members:
+* - uint8_t control - Binary data for read/write of control register 
+* - uint8_t status  - Binary data  for read/write of status register 
+*/
+typedef struct
+{
+    uint8_t control; 
+    uint8_t status; 
+}DS_3231_cntl_stat_t;
+        
+
+/******************************************************************//**
+* Ds3231 Class
+**********************************************************************/
+class DS_3231
+{
+    uint8_t w_adrs, r_adrs; // declaration des adresses I2C en ecriture et en lecture
+public :
+
+    /**
+     * ds3231_regs_t - enumerated DS3231 registers
+     */
+    typedef enum {
+        SECONDS,
+        MINUTES,
+        HOURS,
+        DAY,
+        DATE,
+        MONTH,
+        YEAR,
+        ALRM1_SECONDS,
+        ALRM1_MINUTES,
+        ALRM1_HOURS,
+        ALRM1_DAY_DATE,
+        ALRM2_MINUTES,
+        ALRM2_HOURS,
+        ALRM2_DAY_DATE,
+        CONTROL,
+        STATUS,
+        AGING_OFFSET, //don't touch this register
+        MSB_TEMP,
+        LSB_TEMP
+    } DS3231_regs_t;
+
+// constructeur avec 2 broches I2C
+    DS_3231 (PinName SDA, PinName SCL);
+
+// ecrire l'horaire sur l'horloge
+// arguments : structure de type horaire
+// cette fonction renvoie 0 si opération OK,1  si capteur absent
+    uint16_t set_time(DS_3231_time_t time);
+
+// 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
+    uint16_t get_time(DS_3231_time_t* time);
+
+// 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 set_alarm(DS_3231_alrm_t alarm, bool one_r_two);
+    
+// 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 set_cntl_stat_reg(DS_3231_cntl_stat_t data);
+
+// raz flag alarme
+
+        char raz_alm1();
+
+
+private :
+    /**********************************************************//**
+    * 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 uchar_2_bcd(uint8_t data);
+    // la classe possede en interne :
+    I2C i2c; // un composant I2C que l'on nommera i2c
+    // unsigned char adr_I2C=0x32; // une adresse I2C
+
+
+/**********************************************************//**
+* 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 bcd_2_uchar(uint8_t bcd);
+};
+#endif