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 16:45:51 2014 +0000
Revision:
0:c12a004a9113
Child:
1:17f606b5b59b
initial revision

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xeta05 0:c12a004a9113 1 #include "mbed.h"
xeta05 0:c12a004a9113 2 #include "Rtc_bq32k.h"
xeta05 0:c12a004a9113 3
xeta05 0:c12a004a9113 4
xeta05 0:c12a004a9113 5
xeta05 0:c12a004a9113 6
xeta05 0:c12a004a9113 7 const char *Rtc_bq32k::m_weekDays[] = { "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
xeta05 0:c12a004a9113 8
xeta05 0:c12a004a9113 9
xeta05 0:c12a004a9113 10 Rtc_bq32k::Rtc_bq32k(PinName sda, PinName scl)
xeta05 0:c12a004a9113 11 {
xeta05 0:c12a004a9113 12 // Create a new I2C object
xeta05 0:c12a004a9113 13 m_rtc = new I2C(sda, scl);
xeta05 0:c12a004a9113 14
xeta05 0:c12a004a9113 15 // Set the frequency to standard 100kHz
xeta05 0:c12a004a9113 16 m_rtc->frequency(100000);
xeta05 0:c12a004a9113 17
xeta05 0:c12a004a9113 18 }
xeta05 0:c12a004a9113 19
xeta05 0:c12a004a9113 20 Rtc_bq32k::~Rtc_bq32k()
xeta05 0:c12a004a9113 21 {
xeta05 0:c12a004a9113 22 if (m_rtc != NULL)
xeta05 0:c12a004a9113 23 delete m_rtc;
xeta05 0:c12a004a9113 24 }
xeta05 0:c12a004a9113 25
xeta05 0:c12a004a9113 26 bool Rtc_bq32k::setTime(Time_rtc& time, bool start )
xeta05 0:c12a004a9113 27 {
xeta05 0:c12a004a9113 28 char buffer[7];
xeta05 0:c12a004a9113 29
xeta05 0:c12a004a9113 30 if (!read(0,buffer,7)) {return false;}
xeta05 0:c12a004a9113 31
xeta05 0:c12a004a9113 32 // Now update only the time part (saving the existing flags)
xeta05 0:c12a004a9113 33 if (start) { buffer[0] &= 0x7F; }
xeta05 0:c12a004a9113 34 else { buffer[0] |= 0x80; }
xeta05 0:c12a004a9113 35
xeta05 0:c12a004a9113 36 buffer[0] = (buffer[0]&0x80) | (decimalToBcd(time.sec)&0x7f);
xeta05 0:c12a004a9113 37 buffer[1] = (decimalToBcd(time.min) &0x7f); //This way i am surethat OF bit i cleared
xeta05 0:c12a004a9113 38 buffer[2] = (buffer[2]& 0xC0) | (decimalToBcd(time.hour) & 0x3F);// 24 hours format
xeta05 0:c12a004a9113 39 buffer[3] = time.wday;
xeta05 0:c12a004a9113 40 buffer[4] = decimalToBcd(time.date);
xeta05 0:c12a004a9113 41 buffer[5] = decimalToBcd(time.mon);
xeta05 0:c12a004a9113 42 buffer[6] = decimalToBcd(time.year-2000);
xeta05 0:c12a004a9113 43 if (!write(0, buffer, 7) ) {return false;}
xeta05 0:c12a004a9113 44 return true;
xeta05 0:c12a004a9113 45 }
xeta05 0:c12a004a9113 46
xeta05 0:c12a004a9113 47 bool Rtc_bq32k::getTime(Time_rtc& time)
xeta05 0:c12a004a9113 48 {
xeta05 0:c12a004a9113 49 char buffer[7];
xeta05 0:c12a004a9113 50 if (!read(0, buffer, 7) ) {return false;}
xeta05 0:c12a004a9113 51
xeta05 0:c12a004a9113 52 time.sec = bcdToDecimal(buffer[0]&0x7F);
xeta05 0:c12a004a9113 53 time.min = bcdToDecimal(buffer[1]&0x7F);
xeta05 0:c12a004a9113 54 time.hour = bcdToDecimal(buffer[2]&0x3F);
xeta05 0:c12a004a9113 55 time.wday = buffer[3];
xeta05 0:c12a004a9113 56 time.date = bcdToDecimal(buffer[4]&0x3F);
xeta05 0:c12a004a9113 57 time.mon = bcdToDecimal(buffer[5]&0x1F);
xeta05 0:c12a004a9113 58 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 59
xeta05 0:c12a004a9113 60 return true;
xeta05 0:c12a004a9113 61 }
xeta05 0:c12a004a9113 62
xeta05 0:c12a004a9113 63 bool Rtc_bq32k::startClock()
xeta05 0:c12a004a9113 64 {
xeta05 0:c12a004a9113 65 char strtStop;
xeta05 0:c12a004a9113 66
xeta05 0:c12a004a9113 67 if (!read(0, &strtStop, 1)) {return false;}
xeta05 0:c12a004a9113 68 strtStop &= 0x7F;//pon el bit stop a 0 oscilando
xeta05 0:c12a004a9113 69 if (!write(0, &strtStop, 1)) {return false;}
xeta05 0:c12a004a9113 70 return true;
xeta05 0:c12a004a9113 71 }
xeta05 0:c12a004a9113 72
xeta05 0:c12a004a9113 73 bool Rtc_bq32k::oscStatus()
xeta05 0:c12a004a9113 74 {
xeta05 0:c12a004a9113 75 char status;
xeta05 0:c12a004a9113 76 if (!read(1, &status, 1)) {return false;}
xeta05 0:c12a004a9113 77 if (status &= 0x80){return false;}
xeta05 0:c12a004a9113 78 else{return true;}
xeta05 0:c12a004a9113 79 }
xeta05 0:c12a004a9113 80
xeta05 0:c12a004a9113 81 bool Rtc_bq32k::stopClock()
xeta05 0:c12a004a9113 82 {
xeta05 0:c12a004a9113 83 char strtStop;
xeta05 0:c12a004a9113 84 if (!read(0, &strtStop, 1)) {return false;}
xeta05 0:c12a004a9113 85 strtStop |= 0x80;
xeta05 0:c12a004a9113 86 if (!write(0, &strtStop, 1)) {return false;}
xeta05 0:c12a004a9113 87 return true;
xeta05 0:c12a004a9113 88 }
xeta05 0:c12a004a9113 89
xeta05 0:c12a004a9113 90 bool Rtc_bq32k::setSquareWaveOutput(bool ena, SqwRateSelect_t rs)
xeta05 0:c12a004a9113 91 {
xeta05 0:c12a004a9113 92 char buffer[3],Cal_cfg1;
xeta05 0:c12a004a9113 93 if (!read(BQ32000_CAL_CFG1, &Cal_cfg1, 1)) {return false;}
xeta05 0:c12a004a9113 94 if (ena)
xeta05 0:c12a004a9113 95 {
xeta05 0:c12a004a9113 96 // Setting the frequency is a bit complicated on the BQ32000:
xeta05 0:c12a004a9113 97 buffer[0]=BQ32000_SFKEY1_VAL;
xeta05 0:c12a004a9113 98 buffer[1]=BQ32000_SFKEY2_VAL;
xeta05 0:c12a004a9113 99 buffer[2]=rs;
xeta05 0:c12a004a9113 100 if (!write(BQ32000_SFKEY1, buffer, 3)){return false; }
xeta05 0:c12a004a9113 101 Cal_cfg1=Cal_cfg1|0x40; //preserve the OUT,S and Calibration bits while setting the FT bit.
xeta05 0:c12a004a9113 102 }
xeta05 0:c12a004a9113 103 else{ Cal_cfg1=Cal_cfg1&0xBF;} //preserve the OUT,S and Calibration bits while clearing the FT bit.
xeta05 0:c12a004a9113 104 if (!write(BQ32000_CAL_CFG1, &Cal_cfg1, 1)) {return false;}
xeta05 0:c12a004a9113 105 return true;
xeta05 0:c12a004a9113 106 }
xeta05 0:c12a004a9113 107 bool Rtc_bq32k::setIRQLevel(bool level)
xeta05 0:c12a004a9113 108 {
xeta05 0:c12a004a9113 109 char Cal_cfg1;
xeta05 0:c12a004a9113 110 if (!read(BQ32000_CAL_CFG1, &Cal_cfg1, 1)){return false;}
xeta05 0:c12a004a9113 111 if (level)
xeta05 0:c12a004a9113 112 {
xeta05 0:c12a004a9113 113 Cal_cfg1|=0x80;//set the Out bit
xeta05 0:c12a004a9113 114 }
xeta05 0:c12a004a9113 115 else
xeta05 0:c12a004a9113 116 {
xeta05 0:c12a004a9113 117 Cal_cfg1&=0x7F;//clear the Out bit
xeta05 0:c12a004a9113 118 }
xeta05 0:c12a004a9113 119 if (!write(BQ32000_CAL_CFG1, &Cal_cfg1, 1)){return false;}
xeta05 0:c12a004a9113 120 return true;
xeta05 0:c12a004a9113 121 }
xeta05 0:c12a004a9113 122 bool Rtc_bq32k::setCalibration(int8_t value)
xeta05 0:c12a004a9113 123 {
xeta05 0:c12a004a9113 124
xeta05 0:c12a004a9113 125 char Cal_cfg1;
xeta05 0:c12a004a9113 126 if (value > 31) value = 31;//be sure to be inside the limits
xeta05 0:c12a004a9113 127 if (value < -31) value = -31;
xeta05 0:c12a004a9113 128 value = ((char) (value < 0) ? -value | (1<<BQ32000__CAL_S) : value);//generate the calibration plus sign bit
xeta05 0:c12a004a9113 129
xeta05 0:c12a004a9113 130 if (!read(BQ32000_CAL_CFG1, &Cal_cfg1, 1)){return false;}
xeta05 0:c12a004a9113 131 //and write only the calibration plus sign bits
xeta05 0:c12a004a9113 132 Cal_cfg1 |= (Cal_cfg1 & 0xC0)|value;
xeta05 0:c12a004a9113 133 if (!write(BQ32000_CAL_CFG1, &Cal_cfg1, 1)){return false; }
xeta05 0:c12a004a9113 134 return true;
xeta05 0:c12a004a9113 135 }
xeta05 0:c12a004a9113 136 void Rtc_bq32k::setCharger(int state)
xeta05 0:c12a004a9113 137 {
xeta05 0:c12a004a9113 138 char value;
xeta05 0:c12a004a9113 139 // First disable charger regardless of state (prevents it from
xeta05 0:c12a004a9113 140 // possible starting up in the high voltage mode when the low
xeta05 0:c12a004a9113 141 // voltage mode is requested):
xeta05 0:c12a004a9113 142 value=0;
xeta05 0:c12a004a9113 143 write(BQ32000_TCH2, &value, 1);
xeta05 0:c12a004a9113 144 write(BQ32000_CFG2, &value, 1);
xeta05 0:c12a004a9113 145 if (state <= 0 || state > 2) return;
xeta05 0:c12a004a9113 146
xeta05 0:c12a004a9113 147 value=BQ32000_CHARGE_ENABLE;//TCHE bits written
xeta05 0:c12a004a9113 148
xeta05 0:c12a004a9113 149 if (state == 2)
xeta05 0:c12a004a9113 150 {
xeta05 0:c12a004a9113 151 // High voltage charge enable:
xeta05 0:c12a004a9113 152 value|=1<<BQ32000__TCFE_BIT;
xeta05 0:c12a004a9113 153 }
xeta05 0:c12a004a9113 154
xeta05 0:c12a004a9113 155 write(BQ32000_CFG2, &value, 1);
xeta05 0:c12a004a9113 156 // Now enable charger:
xeta05 0:c12a004a9113 157 value=(1 << BQ32000__TCH2_BIT);
xeta05 0:c12a004a9113 158 write(BQ32000_TCH2, &value, 1);
xeta05 0:c12a004a9113 159
xeta05 0:c12a004a9113 160 }
xeta05 0:c12a004a9113 161
xeta05 0:c12a004a9113 162 bool Rtc_bq32k::read(int address, char *buffer, int len)
xeta05 0:c12a004a9113 163 {
xeta05 0:c12a004a9113 164 char buffer2[2] = {(char)address, 0};
xeta05 0:c12a004a9113 165
xeta05 0:c12a004a9113 166 // m_rtc->start();
xeta05 0:c12a004a9113 167 if (m_rtc->write(0xd0, buffer2, 1) != 0) {
xeta05 0:c12a004a9113 168 m_rtc->stop();
xeta05 0:c12a004a9113 169 return false;
xeta05 0:c12a004a9113 170 }
xeta05 0:c12a004a9113 171 if (m_rtc->read(0xd0, buffer, len) != 0) {return false;}
xeta05 0:c12a004a9113 172 m_rtc->stop();
xeta05 0:c12a004a9113 173 return true;
xeta05 0:c12a004a9113 174 }
xeta05 0:c12a004a9113 175
xeta05 0:c12a004a9113 176 bool Rtc_bq32k::write(int address, char *buffer, int len)
xeta05 0:c12a004a9113 177 {
xeta05 0:c12a004a9113 178 char buffer2[10];
xeta05 0:c12a004a9113 179 buffer2[0] = address&0xFF;
xeta05 0:c12a004a9113 180 for (int i = 0 ; i < len ; i++)
xeta05 0:c12a004a9113 181 buffer2[i+1] = buffer[i];
xeta05 0:c12a004a9113 182
xeta05 0:c12a004a9113 183 // m_rtc->start();
xeta05 0:c12a004a9113 184 if (m_rtc->write(0xd0, buffer2, len+1) != 0)
xeta05 0:c12a004a9113 185 {
xeta05 0:c12a004a9113 186 m_rtc->stop();
xeta05 0:c12a004a9113 187 return false;
xeta05 0:c12a004a9113 188 }
xeta05 0:c12a004a9113 189 m_rtc->stop();
xeta05 0:c12a004a9113 190 return true;
xeta05 0:c12a004a9113 191 }
xeta05 0:c12a004a9113 192