Library for Maxim DS3232M super-accurate, I2C based Real Time Clock chip with 234 bytes of user RAM. Library includes user RAM read/write operations along with CRC routines for accessing the user RAM area.

Dependents:   ds3232m_HelloWorld

ds3232m.h

Committer:
loopsva
Date:
2016-03-11
Revision:
6:968b8efe3ca0
Parent:
2:a9a8027a7cb2

File content as of revision 6:968b8efe3ca0:

#ifndef DS3232M_H
#define DS3232M_H

/*
Maxim Integrated DS3232M, fully integrated Real Time Clock chip.  The
chip contains an I2C interface, compatable time-base registers to 
the DS1307 and M11T41, a super-accurate internal oscillator, 2 alarms
and 236 bytes of user defined battery-backed RAM.
*/

//possible error returns from getUserRAM()
#define DS3232_NOERROR          0x00        //ok, no error   
#define DS3232_OVERFLOWERROR    0x01        //length + offset is over the highest user RAM location
#define DS3232_OFFSETERROR      0x02        //offset < 0x14, those registers are not in the user RAM area
#define DS3232_LENZEROERROR     0x04        //length = 0
#define DS3232_CRCERROR         0x08        //crc error

/** Class ds3232m implements the real time clock
 *
 *
 */
 
class ds3232m {
    
public:
    /** Structure which is used to exchange the time and date
     */
    typedef struct {
        int sec;        /*!< seconds [0..59] */
        int min;        /*!< minutes {0..59] */
        int hour;       /*!< hours [0..23] */
        int wday;       /*!< weekday [1..7, where 1 = sunday, 2 = monday, ... */
        int date;       /*!< day of month [0..31] */
        int mon;        /*!< month of year [1..12] */
        int year;       /*!< year [2000..2255] */
        uint16_t s_crc; /*!< stored crc value in RTC RAM */
        uint16_t c_crc; /*!< calculated crc value */
        char RTCbuffer[256]; /*!< ds3232 ram buffer */
    } Time_rtc;

protected:
    I2C*    _i2c_;

//    static const char *m_weekDays[];

public:
    /**
     * Constructor with default i2c clock speed
     * - Fixed at I2C address 0x80
     * - I2C speed set to 400KHz
     *
     * @param sda - mbed I2C interface pin
     * @param scl - mbed I2C interface pin
     */
    ds3232m(PinName sda, PinName scl);
    
    /**
     * Constructor with i2c clock setting option
     * - Fixed at I2C address 0x80
     * - I2C speed set by user
     *
     * @param sda - mbed I2C interface pin
     * @param scl - mbed I2C interface pin
     * @param set_I2C_frequency
     */
    ds3232m(PinName sda, PinName scl, int i2cFrequency);
    
    /**
     * Destructor
     *
     * @param --none--
     */
    ~ds3232m();
    
    /**
     * See if temperature conversion is busy or not
     * 
     * @param pointer to Time_rtc DS3232 data structure
     *
     * @return busy_flag - Temperature Conversion is busy
     *  - true = busy
     *  - false = ready
    */  
    bool checkTempBusy(Time_rtc& dsSTR);
    
    /**
     * Start a temperature conversion cycle
     *  - Note: only 1 conversion per second allowed
     * 
     * @param pointer to Time_rtc DS3232 data structure
     *
     * @return busy_flag Temperature Conversion is Busy
     *  - true = started new conversion
     *  - false = already busy from previous converstion start
    */ 
    bool startTempCycle(Time_rtc& dsSTR);
    
    /**
     * Get the chip temperature from the DS3232M
     * 
     * @param pointer to Time_rtc DS3232 data structure
     *
     * @return Temperature 0.25degC accuracy
     * @return 255.0 if temperature conversion not complete (still busy)
    */ 
    float getTemperature(Time_rtc& dsSTR);
    
    /**
     * Get seconds register from DS3232M
     * 
     * @param pointer to Time_rtc DS3232 data structure
     *
     * @return BCD-to-decimal corrected seconds register
    */ 
    uint8_t getSeconds(Time_rtc& dsSTR);
    
    /**
     * Get day-of-the-week register from DS3232M
     * 
     * @param pointer to Time_rtc DS3232 data structure
     *
     * @return BCD-to-decimal corrected day of week register (1-7)
    */ 
    uint8_t getDayOfWeek(Time_rtc& dsSTR);
    
    /**
     * Set the day-of-the-week register in the DS3232M
     *
     * @param pointer to Time_rtc DS3232 data structure 
     * @param uint8_t dow3232 day_of_the_week (1=Mon....7=Sun)
     *
     * @return --none--
    */ 
    void putDayOfWeek(Time_rtc& dsSTR, uint8_t dow3232);
    
    /**
     * Clear out all 236 bytes of user RAM, from address 0x14 to 0xff
     *  - 00h is put in all user RAM area
     * 
     * @param pointer to Time_rtc DS3232 data structure 
     *
     * @return --none--
    */ 
    void clearRAM(Time_rtc& dsSTR);
    
    /**
     * Retrieve data from DS3232M's user RAM area
     *  - addresses range 0x14 - 0xfa
     *  - CRC is checked of entire RAM contents
     * 
     * @param pointer to I2C data buffer
     * @param pointer to Time_rtc DS3232 data structure 
     * @param int offset into DS3232M's RAM (range 0x14 = 0xfa)
     * @param int length number of bytes to get
     *
     * @return 00 = no error
     * @return 01 = length + offset is over the highest user RAM location
     * @return 02 = offset < 0x14
     * @return 04 = length = 0 
     * @return 08 = crc error occured from LoadRTCRam()
    */
    uint8_t getUserRAM(char *buffer, Time_rtc& dsSTR, int offset, int length);
    
    /**
     * Store data DS3232M's user RAM area
     *  - addresses range 0x14 - 0xfa
     *  - CRC is added to the last 2 locations using addCRC16()
     * 
     * @param pointer to I2C data buffer
     * @param pointer to Time_rtc DS3232 data structure 
     * @param int offset into DS3232M's RAM (range 0x14 = 0xfa)
     * @param int length number of bytes to store
     *
     * @return 00 = no error
     * @return 01 = length + offset is over the highest user RAM location
     * @return 02 = offset < 0x14
     * @return 04 = length = 0 
    */
    uint8_t putUserRAM(char *buffer, Time_rtc& dsSTR, int offset, int length);
    
    /**
     * Calculate CRC16
     * 
     * @param pointer to I2C data buffer
     * @param pointer to Time_rtc DS3232 data structure 
     * @param int offset into buffer
     * @param int length number of bytes to calculate
     *
     * @return uint16_t CRC16 value
    */
    uint16_t calculateCRC16(char input[], Time_rtc& dsSTR, int offset, int length);
    
    /**
     * Turn on/off the 32KHz output pin 
     *  - with option to keep 32KHz output ON during battery backup
     *  - This pin is push-pull, no pullup is required
     * 
     * @param pointer to Time_rtc DS3232 data structure 
     * @param bool ena
     *  - true = enable during normal operation
     *  - false = disable 32KHz output pin during normal operation
     * @param bool batt
     *  - true = enable 32KHz output pin during battery backup mode
     *  - false = disable 32KHz output pin during battery backup mode
     *  - Note: "ena" must be true or else batt is ignored
     *
     * @return --none--
    */ 
    void set32KhzOutput(Time_rtc& dsSTR, bool ena, bool batt);
    
    /**
     * Turn on/off the 1Hz output pin
     *  - with option to keep 1Hz output ON during battery backup
     *  - This pin is open-drain
     *  - Requires a pullup resistor to Vcc or the backup battery
     * 
     * @param pointer to Time_rtc DS3232 data structure 
     * @param ena  
     *  - true = enable 1Hz output pin during normal operation
     *  - false = disable 1Hz output pin during normal operation
     * @param batt
     *  - true = enable 1Hz output pin during battery backup mode
     *  - false = disable 1Hz output pin during battery backup mode
     *  - Note: "ena" must be true or else batt is ignored
     *
     * @return --none--
    */
    void set1hzOutput(Time_rtc& dsSTR, bool ena, bool batt);
    
    /**
     * Turn on/off the main oscillator during battery backup mode
     *  - The oscillator always runs when Vcc is valid
     * 
     * @param pointer to Time_rtc DS3232 data structure 
     * @param batt 
     *  - true = enable the oscillator during battery backup mode
     *  - false = disable the oscillator during battery backup mode
     *
     * @return --none--
    */
    void enableBattClock(Time_rtc& dsSTR, bool batt);
    
    /** 
     * Read all of the current time registers from the DS3232M
     *
     * @param pointer to Time_rtc DS3232 data structure
     *
     * @returns --none--
     */
    void getTime(Time_rtc& dsSTR);
    
    /** 
     * Write all of the current time registers into the DS3232M
     *
     * @param pointer to Time_rtc DS3232 data structure
     *
     * @returns --none--
     */
    void setTime(Time_rtc& dsSTR);
    
    /** 
     * Load the entire contents of the DS3232M into dedicated buffer RTCbuffer[]
     *   - includes time registers, alarm registers and user RAM
     *
     * @param pointer to Time_rtc DS3232 data structure
     *
     * @return CRC_Status - pass/fail of CRC readback of user RAM data
     *  - true = CRC is ok
     *  - false = CRC failed
     */
    bool LoadRTCRam(Time_rtc& dsSTR);

private:
    void getControlStatusRegs(Time_rtc& dsSTR);
    char RtcCtlReg;
    char RtcStatReg;
    void addCRC16(Time_rtc& dsSTR);

// BCD-Decimal Conversions, hacked from Henry Leinen's RTC-DS1307 library
    static int BCDToDec(int dat) {
        return ((dat & 0xF0) >> 4) * 10 + (dat & 0x0F);
    }

    static int DecToBCD(int dat) {
        return (dat % 10) + ((dat / 10) << 4);
    }
};

#endif // DS3232M_H