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.

Committer:
xeta05
Date:
Thu Nov 27 17:05:53 2014 +0000
Revision:
1:17f606b5b59b
Parent:
0:c12a004a9113
Initial Revision

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xeta05 1:17f606b5b59b 1 /* Rtc_bq32k.cpp */
xeta05 1:17f606b5b59b 2 /*2014/11/27 Oskar Lopez de Gamboa
xeta05 1:17f606b5b59b 3 */
xeta05 1:17f606b5b59b 4 /* Copyright (c) <2014> <Oskar Lopez de Gamboa>, MIT License
xeta05 1:17f606b5b59b 5 *
xeta05 1:17f606b5b59b 6 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
xeta05 1:17f606b5b59b 7 * and associated documentation files (the "Software"), to deal in the Software without restriction,
xeta05 1:17f606b5b59b 8 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
xeta05 1:17f606b5b59b 9 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
xeta05 1:17f606b5b59b 10 * furnished to do so, subject to the following conditions:
xeta05 1:17f606b5b59b 11 *
xeta05 1:17f606b5b59b 12 * The above copyright notice and this permission notice shall be included in all copies or
xeta05 1:17f606b5b59b 13 * substantial portions of the Software.
xeta05 1:17f606b5b59b 14 *
xeta05 1:17f606b5b59b 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
xeta05 1:17f606b5b59b 16 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
xeta05 1:17f606b5b59b 17 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
xeta05 1:17f606b5b59b 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
xeta05 1:17f606b5b59b 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
xeta05 1:17f606b5b59b 20 */
xeta05 1:17f606b5b59b 21
xeta05 0:c12a004a9113 22 #include "mbed.h"
xeta05 0:c12a004a9113 23 #include "Rtc_bq32k.h"
xeta05 0:c12a004a9113 24
xeta05 0:c12a004a9113 25 const char *Rtc_bq32k::m_weekDays[] = { "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
xeta05 0:c12a004a9113 26
xeta05 0:c12a004a9113 27
xeta05 0:c12a004a9113 28 Rtc_bq32k::Rtc_bq32k(PinName sda, PinName scl)
xeta05 0:c12a004a9113 29 {
xeta05 0:c12a004a9113 30 // Create a new I2C object
xeta05 0:c12a004a9113 31 m_rtc = new I2C(sda, scl);
xeta05 0:c12a004a9113 32
xeta05 0:c12a004a9113 33 // Set the frequency to standard 100kHz
xeta05 0:c12a004a9113 34 m_rtc->frequency(100000);
xeta05 0:c12a004a9113 35
xeta05 0:c12a004a9113 36 }
xeta05 0:c12a004a9113 37
xeta05 0:c12a004a9113 38 Rtc_bq32k::~Rtc_bq32k()
xeta05 0:c12a004a9113 39 {
xeta05 0:c12a004a9113 40 if (m_rtc != NULL)
xeta05 0:c12a004a9113 41 delete m_rtc;
xeta05 0:c12a004a9113 42 }
xeta05 0:c12a004a9113 43
xeta05 0:c12a004a9113 44 bool Rtc_bq32k::setTime(Time_rtc& time, bool start )
xeta05 0:c12a004a9113 45 {
xeta05 0:c12a004a9113 46 char buffer[7];
xeta05 0:c12a004a9113 47
xeta05 0:c12a004a9113 48 if (!read(0,buffer,7)) {return false;}
xeta05 0:c12a004a9113 49
xeta05 0:c12a004a9113 50 // Now update only the time part (saving the existing flags)
xeta05 0:c12a004a9113 51 if (start) { buffer[0] &= 0x7F; }
xeta05 0:c12a004a9113 52 else { buffer[0] |= 0x80; }
xeta05 0:c12a004a9113 53
xeta05 0:c12a004a9113 54 buffer[0] = (buffer[0]&0x80) | (decimalToBcd(time.sec)&0x7f);
xeta05 0:c12a004a9113 55 buffer[1] = (decimalToBcd(time.min) &0x7f); //This way i am surethat OF bit i cleared
xeta05 0:c12a004a9113 56 buffer[2] = (buffer[2]& 0xC0) | (decimalToBcd(time.hour) & 0x3F);// 24 hours format
xeta05 0:c12a004a9113 57 buffer[3] = time.wday;
xeta05 0:c12a004a9113 58 buffer[4] = decimalToBcd(time.date);
xeta05 0:c12a004a9113 59 buffer[5] = decimalToBcd(time.mon);
xeta05 0:c12a004a9113 60 buffer[6] = decimalToBcd(time.year-2000);
xeta05 0:c12a004a9113 61 if (!write(0, buffer, 7) ) {return false;}
xeta05 0:c12a004a9113 62 return true;
xeta05 0:c12a004a9113 63 }
xeta05 0:c12a004a9113 64
xeta05 0:c12a004a9113 65 bool Rtc_bq32k::getTime(Time_rtc& time)
xeta05 0:c12a004a9113 66 {
xeta05 0:c12a004a9113 67 char buffer[7];
xeta05 0:c12a004a9113 68 if (!read(0, buffer, 7) ) {return false;}
xeta05 0:c12a004a9113 69
xeta05 0:c12a004a9113 70 time.sec = bcdToDecimal(buffer[0]&0x7F);
xeta05 0:c12a004a9113 71 time.min = bcdToDecimal(buffer[1]&0x7F);
xeta05 0:c12a004a9113 72 time.hour = bcdToDecimal(buffer[2]&0x3F);
xeta05 0:c12a004a9113 73 time.wday = buffer[3];
xeta05 0:c12a004a9113 74 time.date = bcdToDecimal(buffer[4]&0x3F);
xeta05 0:c12a004a9113 75 time.mon = bcdToDecimal(buffer[5]&0x1F);
xeta05 0:c12a004a9113 76 time.year = bcdToDecimal(buffer[6]) + 2000; // plus hundret is because RTC is giving the years since 2000, but std c struct tm needs years since 1900
xeta05 0:c12a004a9113 77
xeta05 0:c12a004a9113 78 return true;
xeta05 0:c12a004a9113 79 }
xeta05 0:c12a004a9113 80
xeta05 0:c12a004a9113 81 bool Rtc_bq32k::startClock()
xeta05 0:c12a004a9113 82 {
xeta05 0:c12a004a9113 83 char strtStop;
xeta05 0:c12a004a9113 84
xeta05 0:c12a004a9113 85 if (!read(0, &strtStop, 1)) {return false;}
xeta05 0:c12a004a9113 86 strtStop &= 0x7F;//pon el bit stop a 0 oscilando
xeta05 0:c12a004a9113 87 if (!write(0, &strtStop, 1)) {return false;}
xeta05 0:c12a004a9113 88 return true;
xeta05 0:c12a004a9113 89 }
xeta05 0:c12a004a9113 90
xeta05 0:c12a004a9113 91 bool Rtc_bq32k::oscStatus()
xeta05 0:c12a004a9113 92 {
xeta05 0:c12a004a9113 93 char status;
xeta05 0:c12a004a9113 94 if (!read(1, &status, 1)) {return false;}
xeta05 0:c12a004a9113 95 if (status &= 0x80){return false;}
xeta05 0:c12a004a9113 96 else{return true;}
xeta05 0:c12a004a9113 97 }
xeta05 0:c12a004a9113 98
xeta05 0:c12a004a9113 99 bool Rtc_bq32k::stopClock()
xeta05 0:c12a004a9113 100 {
xeta05 0:c12a004a9113 101 char strtStop;
xeta05 0:c12a004a9113 102 if (!read(0, &strtStop, 1)) {return false;}
xeta05 0:c12a004a9113 103 strtStop |= 0x80;
xeta05 0:c12a004a9113 104 if (!write(0, &strtStop, 1)) {return false;}
xeta05 0:c12a004a9113 105 return true;
xeta05 0:c12a004a9113 106 }
xeta05 0:c12a004a9113 107
xeta05 0:c12a004a9113 108 bool Rtc_bq32k::setSquareWaveOutput(bool ena, SqwRateSelect_t rs)
xeta05 0:c12a004a9113 109 {
xeta05 0:c12a004a9113 110 char buffer[3],Cal_cfg1;
xeta05 0:c12a004a9113 111 if (!read(BQ32000_CAL_CFG1, &Cal_cfg1, 1)) {return false;}
xeta05 0:c12a004a9113 112 if (ena)
xeta05 0:c12a004a9113 113 {
xeta05 0:c12a004a9113 114 // Setting the frequency is a bit complicated on the BQ32000:
xeta05 0:c12a004a9113 115 buffer[0]=BQ32000_SFKEY1_VAL;
xeta05 0:c12a004a9113 116 buffer[1]=BQ32000_SFKEY2_VAL;
xeta05 0:c12a004a9113 117 buffer[2]=rs;
xeta05 0:c12a004a9113 118 if (!write(BQ32000_SFKEY1, buffer, 3)){return false; }
xeta05 0:c12a004a9113 119 Cal_cfg1=Cal_cfg1|0x40; //preserve the OUT,S and Calibration bits while setting the FT bit.
xeta05 0:c12a004a9113 120 }
xeta05 0:c12a004a9113 121 else{ Cal_cfg1=Cal_cfg1&0xBF;} //preserve the OUT,S and Calibration bits while clearing the FT bit.
xeta05 0:c12a004a9113 122 if (!write(BQ32000_CAL_CFG1, &Cal_cfg1, 1)) {return false;}
xeta05 0:c12a004a9113 123 return true;
xeta05 0:c12a004a9113 124 }
xeta05 0:c12a004a9113 125 bool Rtc_bq32k::setIRQLevel(bool level)
xeta05 0:c12a004a9113 126 {
xeta05 0:c12a004a9113 127 char Cal_cfg1;
xeta05 0:c12a004a9113 128 if (!read(BQ32000_CAL_CFG1, &Cal_cfg1, 1)){return false;}
xeta05 0:c12a004a9113 129 if (level)
xeta05 0:c12a004a9113 130 {
xeta05 0:c12a004a9113 131 Cal_cfg1|=0x80;//set the Out bit
xeta05 0:c12a004a9113 132 }
xeta05 0:c12a004a9113 133 else
xeta05 0:c12a004a9113 134 {
xeta05 0:c12a004a9113 135 Cal_cfg1&=0x7F;//clear the Out bit
xeta05 0:c12a004a9113 136 }
xeta05 0:c12a004a9113 137 if (!write(BQ32000_CAL_CFG1, &Cal_cfg1, 1)){return false;}
xeta05 0:c12a004a9113 138 return true;
xeta05 0:c12a004a9113 139 }
xeta05 0:c12a004a9113 140 bool Rtc_bq32k::setCalibration(int8_t value)
xeta05 0:c12a004a9113 141 {
xeta05 0:c12a004a9113 142
xeta05 0:c12a004a9113 143 char Cal_cfg1;
xeta05 0:c12a004a9113 144 if (value > 31) value = 31;//be sure to be inside the limits
xeta05 0:c12a004a9113 145 if (value < -31) value = -31;
xeta05 0:c12a004a9113 146 value = ((char) (value < 0) ? -value | (1<<BQ32000__CAL_S) : value);//generate the calibration plus sign bit
xeta05 0:c12a004a9113 147
xeta05 0:c12a004a9113 148 if (!read(BQ32000_CAL_CFG1, &Cal_cfg1, 1)){return false;}
xeta05 0:c12a004a9113 149 //and write only the calibration plus sign bits
xeta05 0:c12a004a9113 150 Cal_cfg1 |= (Cal_cfg1 & 0xC0)|value;
xeta05 0:c12a004a9113 151 if (!write(BQ32000_CAL_CFG1, &Cal_cfg1, 1)){return false; }
xeta05 0:c12a004a9113 152 return true;
xeta05 0:c12a004a9113 153 }
xeta05 0:c12a004a9113 154 void Rtc_bq32k::setCharger(int state)
xeta05 0:c12a004a9113 155 {
xeta05 0:c12a004a9113 156 char value;
xeta05 0:c12a004a9113 157 // First disable charger regardless of state (prevents it from
xeta05 0:c12a004a9113 158 // possible starting up in the high voltage mode when the low
xeta05 0:c12a004a9113 159 // voltage mode is requested):
xeta05 0:c12a004a9113 160 value=0;
xeta05 0:c12a004a9113 161 write(BQ32000_TCH2, &value, 1);
xeta05 0:c12a004a9113 162 write(BQ32000_CFG2, &value, 1);
xeta05 0:c12a004a9113 163 if (state <= 0 || state > 2) return;
xeta05 0:c12a004a9113 164
xeta05 0:c12a004a9113 165 value=BQ32000_CHARGE_ENABLE;//TCHE bits written
xeta05 0:c12a004a9113 166
xeta05 0:c12a004a9113 167 if (state == 2)
xeta05 0:c12a004a9113 168 {
xeta05 0:c12a004a9113 169 // High voltage charge enable:
xeta05 0:c12a004a9113 170 value|=1<<BQ32000__TCFE_BIT;
xeta05 0:c12a004a9113 171 }
xeta05 0:c12a004a9113 172
xeta05 0:c12a004a9113 173 write(BQ32000_CFG2, &value, 1);
xeta05 0:c12a004a9113 174 // Now enable charger:
xeta05 0:c12a004a9113 175 value=(1 << BQ32000__TCH2_BIT);
xeta05 0:c12a004a9113 176 write(BQ32000_TCH2, &value, 1);
xeta05 0:c12a004a9113 177
xeta05 0:c12a004a9113 178 }
xeta05 0:c12a004a9113 179
xeta05 0:c12a004a9113 180 bool Rtc_bq32k::read(int address, char *buffer, int len)
xeta05 0:c12a004a9113 181 {
xeta05 0:c12a004a9113 182 char buffer2[2] = {(char)address, 0};
xeta05 0:c12a004a9113 183
xeta05 0:c12a004a9113 184 // m_rtc->start();
xeta05 1:17f606b5b59b 185 if (m_rtc->write(BQ32000_ADDRESS, buffer2, 1) != 0) {
xeta05 0:c12a004a9113 186 m_rtc->stop();
xeta05 0:c12a004a9113 187 return false;
xeta05 0:c12a004a9113 188 }
xeta05 1:17f606b5b59b 189 if (m_rtc->read(BQ32000_ADDRESS, buffer, len) != 0) {return false;}
xeta05 0:c12a004a9113 190 m_rtc->stop();
xeta05 0:c12a004a9113 191 return true;
xeta05 0:c12a004a9113 192 }
xeta05 0:c12a004a9113 193
xeta05 0:c12a004a9113 194 bool Rtc_bq32k::write(int address, char *buffer, int len)
xeta05 0:c12a004a9113 195 {
xeta05 0:c12a004a9113 196 char buffer2[10];
xeta05 0:c12a004a9113 197 buffer2[0] = address&0xFF;
xeta05 0:c12a004a9113 198 for (int i = 0 ; i < len ; i++)
xeta05 0:c12a004a9113 199 buffer2[i+1] = buffer[i];
xeta05 0:c12a004a9113 200
xeta05 0:c12a004a9113 201 // m_rtc->start();
xeta05 1:17f606b5b59b 202 if (m_rtc->write(BQ32000_ADDRESS, buffer2, len+1) != 0)
xeta05 0:c12a004a9113 203 {
xeta05 0:c12a004a9113 204 m_rtc->stop();
xeta05 0:c12a004a9113 205 return false;
xeta05 0:c12a004a9113 206 }
xeta05 0:c12a004a9113 207 m_rtc->stop();
xeta05 0:c12a004a9113 208 return true;
xeta05 0:c12a004a9113 209 }
xeta05 0:c12a004a9113 210