This is a class for using the BQ32000 Real Time Clock chip from TI.

BQ32000

This is a class for using the BQ32000 Real Time Clock chip from TI.This is supossed to be pin and code compatible with the most usual DS1307. It is pin compatible as you can see:

/media/uploads/xeta05/bq32000.jpg

On the code side it is almost compatible, with some advanced functions added (trickle charge, calibration) and minor differences in the registers, For example is only capable of generating 1 Hz and 512 Hz square wave.

This library is based on the DS1307 library by Henry Leinen http://developer.mbed.org/users/leihen/code/RTC-DS1307/file/ee81f2c5a706

The trickle charge and calibration are included in the code but not tested against the chip.

Rtc_bq32k.h

Committer:
xeta05
Date:
2014-11-27
Revision:
1:17f606b5b59b
Parent:
0:c12a004a9113

File content as of revision 1:17f606b5b59b:

/* Rtc_bq32k.h */
/*2014/11/27 Oskar Lopez de Gamboa
*/
/* Copyright (c) <2014> <Oskar Lopez de Gamboa>, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
#ifndef __Rtc_bq32k_H__
#define __Rtc_bq32k_H__

#define BQ32000_ADDRESS         0xD0
// BQ32000 register addresses:
#define BQ32000_CAL_CFG1        0x07
#define BQ32000_TCH2            0x08
#define BQ32000_CFG2            0x09
#define BQ32000_SFKEY1          0x20
#define BQ32000_SFKEY2          0x21
#define BQ32000_SFR             0x22
// BQ32000 config bits:
#define BQ32000__OUT            0x07 // CAL_CFG1 - IRQ active state
#define BQ32000__FT             0x06 // CAL_CFG1 - IRQ square wave enable
#define BQ32000__CAL_S          0x05 // CAL_CFG1 - Calibration sign
#define BQ32000__TCH2_BIT       0x05 // TCH2 - Trickle charger switch 2
#define BQ32000__TCFE_BIT       0x06 // CFG2 - Trickle FET control
// BQ32000 config values:
#define BQ32000_CHARGE_ENABLE   0x05 // CFG2 - Trickle charger switch 1 enable
#define BQ32000_SFKEY1_VAL      0x5E
#define BQ32000_SFKEY2_VAL      0xC7


/** Class Rtc_bq32k implements the real time clock module bq32000 from TI
 *
 * You can read the clock and set a new time and date.
 * It is also possible to start and stop the clock, config the IRQ, set calibration, enable trickle Charger.
 * 
 */
class Rtc_bq32k
{
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] */
    } Time_rtc;


    /** RateSelect specifies the valid frequency values for the square wave output
     */
    typedef enum {
        RS512Hz = 0,
        RS1Hz = 1
    } SqwRateSelect_t;

protected:
    I2C*    m_rtc;

    static const char *m_weekDays[];

public:
    /** public constructor which creates the real time clock object
     *
     * @param sda : specifies the pin for the SDA communication line.
     *
     * @param scl : the pin for the serial clock
     *
     */
    Rtc_bq32k(PinName sda, PinName scl);

    ~Rtc_bq32k();

    /** Read the current time from RTC chip
     *
     * @param time : reference to a struct tm which will be filled with the time from rtc
     *
     * @returns true if successful, otherwise an acknowledge error occured
     */
    virtual bool getTime(Time_rtc& time);

    /** Write the given time onto the RTC chip
     *
     * @param time : reference to a struct which contains valid date and time information
     *
     * @param start : contains true if the clock shall start (or keep on running).
     *
     * @returns true if successful, otherwise an acknowledge error occured
     */
    virtual bool setTime(Time_rtc& time, bool start);

    /** Look for the status of the Oscillator fail flag OF. 
     *
     * @returns true if No failure was detected , false if a failure was detected (at least
     * four consecutive dropped pulses)or a communication error occured.
     */
    bool oscStatus();
    
    /** Start the clock. Please note that the seconds register need to be read and
     * written in order to start or stop the clock. This can lead to an error
     * in the time value. The recommended way of starting and stoping the clock is
     * to write the actual date and time and set the start bit accordingly.
     *
     * @returns true if the clock was started, false if a communication error occured
     */
    bool startClock();
    
    /** Stop the clock. Please note that the seconds register need to be read and
     * written in order to start or stop the clock. This can lead to an error
     * in the time value. The recommended way of starting and stoping the clock is
     * to write the actual date and time and set the start bit accordingly.
     *
     * @returns true if the clock was stopped, false if a communication error occured
     */
    bool stopClock();

    /** Service function to convert a weekday into a string representation
     *
     * @param wday : day of week to convert (starting with sunday = 1, monday = 2, ..., saturday = 7
     *
     * @returns the corresponding string representation
     */
    const char* weekdayToString( int wday ) {
        return m_weekDays[wday%7];
    }

    /** Enable Square Wave output. The function enables or disables the square wave output
     * of the module and sets the desired frequency.
     *
     * @param ena : if set to true, the square wave output is enabled.
     *
     * @param rs : rate select, can be either one of the two values defined by type /c RateSelect_t
     *
     * @return true if the operation was successful or false otherwise
     */
    bool setSquareWaveOutput(bool ena, SqwRateSelect_t rs);
    
    /**  Set IRQ output level to LOW or HIGH. when IRQ square wave output is disabled 
     *
     * @param level : if set to true, the IRQ will be HIGH else it will be LOW.
     *
     * @return true if the operation was successful or false otherwise
     */
    bool setIRQLevel(bool level);
    /* Sets the calibration value to given value in the range -31 - 31, which
     * corresponds to -126ppm - +63ppm; see table 13 in th BQ32000 datasheet.
     *
     *@param value:the signed value of the calibration desired
     *
     *@return true if the operation was successful or false otherwise
     */
    bool setCalibration(int8_t value);
   
    /** If using a super capacitor instead of a battery for backup power, use this
     * method to set the state of the trickle charger: In low-voltage charge mode, the super cap is
     * charged through a diode with a voltage drop of about 0.5V, so it will charge
     * up to VCC-0.5V. In high-voltage charge mode the diode is bypassed and the super
     * cap will be charged up to VCC (make sure the charge voltage does not exceed your
     * super cap's voltage rating!!).
     *
     *
     * *@param state:0=disabled, 1=low-voltage charge, 2=high-voltage charge. 
     */ 
     void setCharger(int state);   


private:
    bool read(int address, char* buffer, int len);
    bool write(int address, char* buffer, int len);

    static int bcdToDecimal(int bcd) {
        return ((bcd&0xF0)>>4)*10 + (bcd&0x0F);
    }

    static int decimalToBcd(int dec) {
        return (dec%10) + ((dec/10)<<4);
    }
};


#endif // __Rtc_bq32k_H__