Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of bq27210 by
Revision 3:1b12fa9dc673, committed 2017-07-31
- Comitter:
- loopsva
- Date:
- Mon Jul 31 19:12:28 2017 +0000
- Parent:
- 2:d52fb7ef7429
- Commit message:
- Working code. On hold for now. Moving to BQ34Z100-G1
Changed in this revision
| bq27220.cpp | Show annotated file Show diff for this revision Revisions of this file |
| bq27220.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/bq27220.cpp Wed Jun 21 19:56:02 2017 +0000
+++ b/bq27220.cpp Mon Jul 31 19:12:28 2017 +0000
@@ -1,12 +1,22 @@
#include "mbed.h"
+#include "rtos.h"
#include "bq27220.h"
+extern RawSerial pc;
+
#define i2c_Buf dataSTR.i2c_Bufx
+
BQ27220::BQ27220(PinName p_sda, PinName p_scl) :
_i2c(p_sda, p_scl)
{
- _i2c.frequency(400000);
+ _i2c.frequency(100000);
+}
+
+BQ27220::BQ27220(PinName p_sda, PinName p_scl, int freq) :
+ _i2c(p_sda, p_scl)
+{
+ _i2c.frequency(freq);
}
void BQ27220::default_init(BQ27220_TypeDef& dataSTR)
@@ -19,14 +29,453 @@
return(0);
}
+uint16_t BQ27220::get_sub_cmmd(BQ27220_TypeDef& dataSTR, uint16_t cmmd)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[2] = cmmd >> 8;
+ i2c_Buf[1] = cmmd & 255;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ Thread::wait(5); // needs large delay here
+ //pc.printf("sub-a: %02x %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2], i2c_Buf[3]);
+ int i = 0;
+ for(i = 0; i < 100; i++) {
+ wait_us(66);
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 4, false);
+ //pc.printf("sub-b: %02x %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2], i2c_Buf[3]);
+ if((i2c_Buf[0]== 0xa5) && (i2c_Buf[1] == 0xff)) break;
+ }
+ wait_us(66);
+ if(i > 98) pc.printf("sub-b: ERROR \r\n");
+ return (i2c_Buf[0] << 8) | i2c_Buf[1];
+}
+
+uint16_t BQ27220::get_sub_cmmd_s(BQ27220_TypeDef& dataSTR, uint16_t cmmd)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[2] = cmmd >> 8;
+ i2c_Buf[1] = cmmd & 255;
+ //pc.printf("sub-a: %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2]);
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(1066);
+ i2c_Buf[0] = BQ_MACDATA;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 2, false);
+ wait_us(66);
+ //pc.printf("sub-b: %04x \r\n", (i2c_Buf[0] << 8) | i2c_Buf[1]);
+ return (i2c_Buf[0] << 8) | i2c_Buf[1];
+}
+
+uint16_t BQ27220::get_reg_2B(BQ27220_TypeDef& dataSTR, uint8_t reg)
+{
+ i2c_Buf[0] = reg;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 2, false);
+ //pc.printf("sub-b: %02x %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2], i2c_Buf[3]);
+ wait_us(66);
+ //Thread::wait(2);
+ return (i2c_Buf[1] << 8) | i2c_Buf[0];
+}
+
+void BQ27220::enter_cfg_update(BQ27220_TypeDef& dataSTR)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = 0x90;
+ i2c_Buf[2] = 0x00;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(66);
+ Thread::wait(1500);
+}
+
+void BQ27220::exitCfgUpdateExit(BQ27220_TypeDef& dataSTR)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = BQ_EXIT_CFG_UPDATE & 255;
+ i2c_Buf[2] = BQ_EXIT_CFG_UPDATE >> 8;
+ pc.printf("exitCfg_cmmd: -> ");
+ for(int i = 0; i < 3; i++) pc.printf("%02x ",i2c_Buf[i]);
+ pc.printf("\r\n");
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(66);
+ Thread::wait(5);
+}
+
+void BQ27220::exitCfgUpdateReInit(BQ27220_TypeDef& dataSTR)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = BQ_EXIT_CFG_UPDATE_REINIT & 255;
+ i2c_Buf[2] = BQ_EXIT_CFG_UPDATE_REINIT >> 8;
+ pc.printf("exitInit_cmmd: -> ");
+ for(int i = 0; i < 3; i++) pc.printf("%02x ",i2c_Buf[i]);
+ pc.printf("\r\n");
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(66);
+ Thread::wait(5);
+}
+
+
+void BQ27220::reset(BQ27220_TypeDef& dataSTR)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = BQ_RESET & 255;
+ i2c_Buf[2] = BQ_RESET >> 8;
+ pc.printf("reset_cmmd: -> ");
+ for(int i = 0; i < 3; i++) pc.printf("%02x ",i2c_Buf[i]);
+ pc.printf("\r\n");
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(66);
+ Thread::wait(5);
+}
+
+void BQ27220::useProfile_1(BQ27220_TypeDef& dataSTR)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = BQ_SET_PROFILE_1 >> 8;
+ i2c_Buf[2] = BQ_SET_PROFILE_1 & 255;;
+ pc.printf("Profile_1_cmmd: -> ");
+ for(int i = 0; i < 3; i++) pc.printf("%02x ",i2c_Buf[i]);
+ pc.printf("\r\n");
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(66);
+ Thread::wait(200);
+}
+
+uint16_t BQ27220::get_cs_len(BQ27220_TypeDef& dataSTR, bool pf)
+{
+ i2c_Buf[0] = BQ_MACDATASUM;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 1, false);
+ wait_us(66);
+ //Thread::wait(5);
+ uint16_t csl = i2c_Buf[0];
+
+ i2c_Buf[0] = BQ_MACDATALEN;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 1, false);
+ wait_us(66);
+ //Thread::wait(5);
+ csl = (csl << 8) | i2c_Buf[0];
+ if(pf) pc.printf("get_cs: %02x\r\n", csl >> 8);
+ if(pf) pc.printf("get_ln: %02x\r\n", csl & 255);
+ return(csl);
+}
+
+uint8_t BQ27220::calc_checksum_rx(BQ27220_TypeDef& dataSTR, int length)
+{
+ uint8_t cs = 0;
+ //pc.printf("c_csum_rx_len: %02x -> ", length);
+ i2c_Buf[0] = BQ_SUB;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 34, false);
+ wait_us(66);
+ Thread::wait(5);
+ for(int i = 0; i < length + 2; i++) {
+ cs += i2c_Buf[i];
+ //pc.printf("b: %02x cs: %02x ", i2c_Buf[i], cs);
+ }
+ cs = 255 - cs;
+ //pc.printf("cs_rx:%02x \r\n", cs);
+ return (cs);
+}
+
+uint8_t BQ27220::calc_checksum_tx(BQ27220_TypeDef& dataSTR, int length)
+{
+ uint8_t cs = 0;
+ pc.printf("cs_tx_len: %02x -> ", length);
+ for(int i = 0; i < length + 2; i++) {
+ cs += i2c_Buf[i + 1];
+ //pc.printf("i2c: %02x cs: %02x ", i2c_Buf[i + 1], cs);
+ pc.printf("%02x ", i2c_Buf[i + 1]);
+ }
+ cs = 255 - cs;
+ pc.printf("\r\ncs_tx: %02x\r\n", cs);
+ return (cs);
+}
+
+uint32_t BQ27220::get_data_32(BQ27220_TypeDef& dataSTR, uint16_t sub_cmmd, int length)
+{
+ i2c_Buf[0] = BQ_SUB;
+ i2c_Buf[2] = sub_cmmd >> 8;
+ i2c_Buf[1] = sub_cmmd & 255;
+ dataSTR.subReg = sub_cmmd;
+ //pc.printf("dat-32a: %02x %02x %02x \r\n", i2c_Buf[0], i2c_Buf[1], i2c_Buf[2]);
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(3066);
+ //Thread::wait(3); //needs to be at least 2
+
+ dataSTR.checksum = calc_checksum_rx(dataSTR, length);
+
+ uint16_t cslen = get_cs_len(dataSTR, false);
+ dataSTR.macSumReg = cslen >> 8;
+ dataSTR.macLenReg = cslen & 255;
+
+ i2c_Buf[0] = BQ_MACDATA;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, length, false);
+ wait_us(5066);
+ //Thread::wait(5); //seems to work down to 1
+ for(int i = 0; i < length; i++) {
+ dataSTR.macData[i] = dataSTR.i2c_Bufx[i];
+ pc.printf("%02x,", dataSTR.macData[i]);
+ }
+ pc.printf("\r\n");
+ //pc.printf(" mdl: %02x, mdcs: %02x, ccs: %02x\r\n", dataSTR.macLenReg, dataSTR.macSumReg, dataSTR.checksum);
+ return ((uint32_t)dataSTR.subReg);
+}
+
+//#define BQ_SHORT 1
+
+void BQ27220::change_ram_1_2_4(BQ27220_TypeDef& dataSTR, uint16_t sub_cmmd, uint32_t value, int qty, bool pre)
+{
+ if(pre) {
+#ifndef BQ_SHORT
+ pc.printf("ram124_a: %04x -> ", sub_cmmd);
+ get_data_32(dataSTR, sub_cmmd, 32);
+#endif
+
+ if(qty == 1) {
+ dataSTR.macData[0] = value & 255;
+#ifdef BQ_SHORT
+ dataSTR.macData[1] = 0;
+ dataSTR.macData[2] = 0;
+ dataSTR.macData[3] = 0;
+#endif
+ } else
+ if(qty == 2) {
+ dataSTR.macData[0] = (value >> 8) & 255;
+ dataSTR.macData[1] = value & 255;
+#ifdef BQ_SHORT
+ dataSTR.macData[2] = 0;
+ dataSTR.macData[3] = 0;
+#endif
+ } else
+ if(qty == 4) {
+ dataSTR.macData[0] = (value >> 24) & 255;
+ dataSTR.macData[1] = (value >> 16) & 255;
+ dataSTR.macData[2] = (value >> 8) & 255;
+ dataSTR.macData[3] = value & 255;
+ } else {
+ pc.printf("ram124_q_error\r\n");
+ return;
+ }
+ }
+
+ i2c_Buf[0] = BQ_SUB;
+ i2c_Buf[1] = sub_cmmd >> 8;
+ i2c_Buf[2] = sub_cmmd & 255;
+ if(pre) {
+ i2c_Buf[3] = dataSTR.macData[0];
+ i2c_Buf[4] = dataSTR.macData[1];
+ i2c_Buf[5] = dataSTR.macData[2];
+ i2c_Buf[6] = dataSTR.macData[3];
+ }
+ pc.printf("ram124_cmmd: -> ");
+ int i = 0;
+#ifdef BQ_SHORT
+ for(i = 0; i < qty + 3; i++) pc.printf("%02x ",i2c_Buf[i]);
+ pc.printf("\r\n");
+ uint8_t x = calc_checksum_tx(dataSTR, qty);
+ _i2c.write(BQ27220_ADDR, i2c_Buf, qty + 3, false);
+#else
+ for(i = 0; i < 32; i++) i2c_Buf[i + 3] = dataSTR.macData[i];
+ for(i = 0; i < 35; i++) pc.printf("%02x ",i2c_Buf[i]);
+ pc.printf("\r\n");
+ uint8_t x = calc_checksum_tx(dataSTR, 32);
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 35, false);
+#endif
+ wait_us(66);
+ //Thread::wait(5);
+
+ i2c_Buf[0] = BQ_MACDATASUM;
+ i2c_Buf[1] = x;
+#ifndef BQ_SHORT
+ i2c_Buf[1] -= 0x20; //why is this???? !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ if((sub_cmmd >= 0x91e0) && (sub_cmmd < BQ_CONFIG_TAPER_CURR)) i2c_Buf[1]--;
+#endif
+ pc.printf("ram124_cs: -> ");
+ for(i = 0; i < 2; i++) pc.printf("%02x ",i2c_Buf[i]);
+ pc.printf("\r\n");
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 2, false);
+ wait_us(66);
+ //Thread::wait(5);
+
+ i2c_Buf[0] = BQ_MACDATALEN;
+#ifdef BQ_SHORT
+ i2c_Buf[1] = qty + 4;
+#else
+ i2c_Buf[1] = 36;
+#endif
+ pc.printf("ram124_len: -> ");
+ for(i = 0; i < 2; i++) pc.printf("%02x ",i2c_Buf[i]);
+ pc.printf("\r\n");
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 2, false);
+ wait_us(5066);
+ //Thread::wait(200);
+
+ get_cs_len(dataSTR, true);
+ //pc.printf("\r\n");
+
+#ifndef BQ_SHORT
+ pc.printf("ram124_x: %04x -> ", sub_cmmd);
+ get_data_32(dataSTR, sub_cmmd, 32);
+ pc.printf("\r\n");
+#endif
+}
+
+uint16_t BQ27220::get_16(BQ27220_TypeDef& dataSTR, uint16_t cmmd)
+{
+ get_sub_cmmd_s(dataSTR, cmmd);
+ i2c_Buf[0] = BQ_MACDATA;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 2, false);
+ wait_us(66);
+ return (i2c_Buf[0] << 8) | i2c_Buf[1];
+}
+
+uint8_t BQ27220::get_8(BQ27220_TypeDef& dataSTR, uint16_t cmmd)
+{
+ //pc.printf("get_8: %04x\r\n", cmmd);
+ get_sub_cmmd_s(dataSTR, cmmd);
+ i2c_Buf[0] = BQ_MACDATA;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 1, false);
+ wait_us(66);
+ return i2c_Buf[0];
+}
+
+void BQ27220::seal(BQ27220_TypeDef& dataSTR)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = 0x30;
+ i2c_Buf[2] = 0x00;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(66);
+ wait_ms(5);
+ //Thread::wait(5);
+}
+
+void BQ27220::unseal(BQ27220_TypeDef& dataSTR)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = 0x14;
+ i2c_Buf[2] = 0x04;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(66);
+ wait_ms(5);
+ //Thread::wait(5);
+
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = 0x72;
+ i2c_Buf[2] = 0x36;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_ms(5);
+ //Thread::wait(5);
+}
+
+void BQ27220::full_access(BQ27220_TypeDef& dataSTR)
+{
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = 0xff;
+ i2c_Buf[2] = 0xff;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(66);
+ wait_ms(5);
+ //Thread::wait(5);
+
+ i2c_Buf[0] = BQ_CNTL;
+ i2c_Buf[1] = 0xff;
+ i2c_Buf[2] = 0xff;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 3, false);
+ wait_us(66);
+ wait_ms(5);
+ //Thread::wait(5);
+}
+
+uint32_t BQ27220::get_dev_id(BQ27220_TypeDef& dataSTR)
+{
+ uint16_t dat = get_sub_cmmd(dataSTR, BQ_DEVICE_NUMBER);
+ //pc.printf("dat-idq: %04x \r\n", dat);
+ if(dat != 0xa5ff) return(dat);
+ i2c_Buf[0] = BQ_SUB;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 4, false);
+ uint32_t id = (i2c_Buf[0] << 24) | (i2c_Buf[1] << 16) | (i2c_Buf[2] << 8) | i2c_Buf[3];
+ //pc.printf("dat-idq: %08x \r\n", id);
+ wait_us(66);
+ return(id) ;
+}
+
+uint32_t BQ27220::get_fw_rev(BQ27220_TypeDef& dataSTR)
+{
+ uint16_t dat = get_sub_cmmd(dataSTR, BQ_FW_VERSION);
+ //pc.printf("dat-fwq: %04x \r\n", dat);
+ if(dat != 0xa5ff) return(dat);
+ i2c_Buf[0] = BQ_SUB;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 34, false);
+ wait_us(66);
+ return (i2c_Buf[0] << 24) | (i2c_Buf[1] << 16) | (i2c_Buf[2] << 8) | i2c_Buf[3];
+}
+
+uint32_t BQ27220::get_hw_rev(BQ27220_TypeDef& dataSTR)
+{
+ uint16_t dat = get_sub_cmmd(dataSTR, BQ_HW_VERSION);
+ //pc.printf("dat-fwq: %04x \r\n", dat);
+ if(dat != 0xa5ff) return(dat);
+ i2c_Buf[0] = BQ_SUB;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 34, false);
+ wait_us(66);
+ return (i2c_Buf[0] << 24) | (i2c_Buf[1] << 16) | (i2c_Buf[2] << 8) | i2c_Buf[3];
+}
+
+void BQ27220::set_ntc_as_sensor(BQ27220_TypeDef& dataSTR, bool ntc)
+{
+ uint16_t res = get_16(dataSTR, BQ_CONFIG_OP_CONFIG_A);
+ pc.printf("s_ntc: %04x ", res);
+
+ if(!(ntc)) {
+ pc.printf(" N ");
+ res &= ~BQ_BIT_OCA_TEMPS;
+ res |= BQ_BIT_OCA_BIE;
+
+ } else {
+ pc.printf(" L ");
+ res &= ~BQ_BIT_OCA_BIE;
+ res |= BQ_BIT_OCA_TEMPS;
+ }
+
+ pc.printf("new: %04x\r\n", res);
+ change_ram_1_2_4(dataSTR, BQ_CONFIG_OP_CONFIG_A - 0x20, (uint32_t)res, 2, true);
+}
+/*
+void BQ27220::set_reg(BQ27220_TypeDef& dataSTR, uint16_t reg, uint16_t da, int byt)
+{
+ uint16_t res = get_16(dataSTR, reg);
+ change_ram_1_2_4(dataSTR, reg, (uint32_t)da, byt, true);
+}
+*/
+/*
+uint16_t BQ27220::get_OS_reg(BQ27220_TypeDef& dataSTR)
+{
+ i2c_Buf[0] = BQ_OS;
+ _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 2, false);
+ wait_us(66);
+ dataSTR.osReg = (i2c_Buf[1] << 8) | i2c_Buf[0];
+ return(dataSTR.osReg);
+}
+*/
+
int BQ27220::read_registers(BQ27220_TypeDef& dataSTR)
{
i2c_Buf[0] = BQ_CNTL;
- int result = _i2c.write((int)BQ27220_ADDR, i2c_Buf, 1, true);
+ int result = _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
if(result) return(result + 0x10);
- _i2c.read((int)BQ27220_ADDR + 1, i2c_Buf, 32, false);
+ result = _i2c.read(BQ27220_ADDR + 1, i2c_Buf, 32, false);
wait_us(66);
if(result) return(result + 0x18);
+ //Thread::wait(1);
dataSTR.cntlReg = (i2c_Buf[BQ_CNTL - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_CNTL - BQ_CNTL];
dataSTR.arReg = (i2c_Buf[BQ_AR - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_AR - BQ_CNTL];
@@ -46,11 +495,12 @@
dataSTR.mliReg = (i2c_Buf[BQ_MLI - BQ_CNTL + 1] << 8) | i2c_Buf[BQ_MLI - BQ_CNTL];
i2c_Buf[0] = BQ_MLTTE;
- result = _i2c.write((int)BQ27220_ADDR, i2c_Buf, 1, true);
- if(result) return(result + 0x20);
- result =_i2c.read((int)BQ27220_ADDR + 1, i2c_Buf, 32, false);
+ result = _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ //if(result) return(result + 0x20);
+ result =_i2c.read(BQ27220_ADDR + 1, i2c_Buf, 32, false);
wait_us(66);
- if(result) return(result + 0x28);
+ //Thread::wait(1);
+ //if(result) return(result + 0x28);
dataSTR.mltteReg = (i2c_Buf[BQ_MLTTE - BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_MLTTE - BQ_MLTTE];
dataSTR.rawccReg = (i2c_Buf[BQ_RCC - BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_RCC - BQ_MLTTE];
@@ -66,24 +516,27 @@
dataSTR.btpcReg = (i2c_Buf[BQ_BTPC - BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_BTPC - BQ_MLTTE];
dataSTR.osReg = (i2c_Buf[BQ_OS - BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_OS - BQ_MLTTE];
dataSTR.dcReg = (i2c_Buf[BQ_DC - BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_DC - BQ_MLTTE];
+ dataSTR.subReg = (i2c_Buf[BQ_SUB - BQ_MLTTE + 1] << 8) | i2c_Buf[BQ_SUB - BQ_MLTTE];
i2c_Buf[0] = BQ_MACDATA;
- result = _i2c.write((int)BQ27220_ADDR, i2c_Buf, 1, true);
- if(result) return(result + 0x30);
- result =_i2c.read((int)BQ27220_ADDR + 1, i2c_Buf, 32, false);
+ result = _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ //if(result) return(result + 0x30);
+ result =_i2c.read(BQ27220_ADDR + 1, i2c_Buf, 32, false);
wait_us(66);
- if(result) return(result + 0x38);
+ //Thread::wait(1);
+ //if(result) return(result + 0x38);
for(int i = 0; i < 32; i++) {
dataSTR.macData[i] = i2c_Buf[i];
}
i2c_Buf[0] = BQ_MACDATASUM;
- result = _i2c.write((int)BQ27220_ADDR, i2c_Buf, 1, true);
- if(result) return(result + 0x40);
- result =_i2c.read((int)BQ27220_ADDR + 1, i2c_Buf, 32, false);
+ result = _i2c.write(BQ27220_ADDR, i2c_Buf, 1, true);
+ //if(result) return(result + 0x40);
+ result =_i2c.read(BQ27220_ADDR + 1, i2c_Buf, 32, false);
wait_us(66);
- if(result) return(result + 0x48);
+ //Thread::wait(1);
+ //if(result) return(result + 0x48);
dataSTR.macSumReg = (i2c_Buf[BQ_MACDATASUM - BQ_MACDATASUM + 1] << 8) | i2c_Buf[BQ_MACDATASUM - BQ_MACDATASUM];
dataSTR.macLenReg = (i2c_Buf[BQ_MACDATALEN - BQ_MACDATASUM + 1] << 8) | i2c_Buf[BQ_MACDATALEN - BQ_MACDATASUM];
@@ -94,6 +547,3 @@
return(0);
}
-
-
-
--- a/bq27220.h Wed Jun 21 19:56:02 2017 +0000
+++ b/bq27220.h Mon Jul 31 19:12:28 2017 +0000
@@ -40,6 +40,7 @@
#define BQ_OS 0x3A
#define BQ_DC 0x3C
+#define BQ_SUB 0x3E
#define BQ_MACDATA 0x40
@@ -55,6 +56,7 @@
#define BQ_CNTL_STAT 0x0000
#define BQ_DEVICE_NUMBER 0x0001
#define BQ_FW_VERSION 0x0002
+#define BQ_HW_VERSION 0x0003
#define BQ_BOARD_OFFSET 0x0009
#define BQ_CC_OFFSET 0x000A
@@ -76,7 +78,10 @@
#define BQ_SET_SEALED 0x0030
-#define BQ_RESET 0x0040
+#define BQ_RESET 0x0041
+
+#define BQ_OP_STATUS 0x0054
+#define BQ_GAUGE_STATUS 0x0056
#define BQ_EXIT_CAL 0x0080
#define BQ_ENTER_CAL 0x0081
@@ -87,6 +92,79 @@
#define BQ_RETURN_TO_ROM 0x0F00
+// Configuration parameters
+#define BQ_CONFIG_CC_GAIN 0x9184 //float
+
+#define BQ_CONFIG_CHG_INH_LO 0x91f5 //int16_t
+#define BQ_CONFIG_CHG_INH_HI 0x91f7 //int16_t
+#define BQ_CONFIG_CHG_INH_HYST 0x91f9 //int16_t
+#define BQ_CONFIG_CHG_CURR 0x91fb //int16_t
+#define BQ_CONFIG_CHG_VOLT 0x91fd //int16_t
+
+#define BQ_CONFIG_TAPER_CURR 0x9201 //int16_t
+#define BQ_CONFIG_OP_CONFIG_A 0x9206 //uint16_t
+#define BQ_CONFIG_OP_CONFIG_B 0x9208 //uint16_t
+#define BQ_CONFIG_SOC_DELTA 0x920b //uint8_t
+#define BQ_CONFIG_CLK_CTRL 0x920c //uint8_t
+#define BQ_CONFIG_IO_CONFIG 0x920d //uint8_t
+#define BQ_CONFIG_INIT_DIS_SET 0x920e //int16_t
+#define BQ_CONFIG_INIT_CHG_SET 0x9210 //int16_t
+#define BQ_CONFIG_DEVICE_TYPE 0x9212 //uint16_t
+
+#define BQ_CONFIG_SLEEP_CURR 0x9217 //int16_t
+#define BQ_CONFIG_BUS_LO_TIME 0x9219 //uint8_t
+#define BQ_CONFIG_OC_INH_T_LO 0x921a //int16_t
+#define BQ_CONFIG_OC_INH_T_HI 0x921c //int16_t
+#define BQ_CONFIG_SLEEP_V_TIME 0x921e //uint8_t
+#define BQ_CONFIG_SLEEP_C_TIME 0x921f //uint8_t
+
+#define BQ_CONFIG_DIS_DET_THRES 0x9228 //int16_t
+#define BQ_CONFIG_CHG_DET_THRES 0x922a //int16_t
+#define BQ_CONFIG_QUIT_CURR 0x922c //int16_t
+#define BQ_CONFIG_DIS_RELAX_TI 0x922e //uint16_t
+
+#define BQ_CONFIG_CHG_RELAX_TI 0x9230 //uint8_t
+#define BQ_CONFIG_QUIT_RELAX_TI 0x9231 //uint8_t
+
+#define BQ_CONFIG_OT_CHG 0x9232 //int16_t
+#define BQ_CONFIG_OT_CHG_TIME 0x9234 //uint8_t
+#define BQ_CONFIG_OT_CGH_RECOV 0x9235 //int16_t
+#define BQ_CONFIG_OT_DSG 0x9237 //int16_t
+#define BQ_CONFIG_OT_DSG_TIME 0x9239 //uint8_t
+#define BQ_CONFIG_OT_DSG_RECOV 0x923a //int16_t
+#define BQ_CONFIG_INIT_STBY 0x923c //int8_t
+
+#define BQ_CONFIG_SYSD_S_VTHRS 0x9240 //int16_t
+#define BQ_CONFIG_SYSD_S_VTIME 0x9242 //uint8_t
+#define BQ_CONFIG_SYSD_C_VTHRS 0x9243 //int16_t
+
+#define BQ_GG_SMOOTHING_CONFIG 0x9271 //uint8_t
+#define BQ_CONFIG_FLAG_CONFIG_A 0x927f //uint16_t
+#define BQ_CONFIG_FLAG_CONFIG_B 0x9281 //uint8_t
+
+#define BQ_CONFIG_BATTERY_ID 0x929a //uint8_t
+
+// Gas Gauge parameters
+#define BQ_GG_CEDVp1_GAUGE_CONF 0x929b //uint16_t
+#define BQ_GG_CEDVp1_FULLC_CAP 0x929d //int16_t 15 bits
+#define BQ_GG_CEDVp1_DESIGN_CAP 0x929f //int16_t 15 bits
+#define BQ_GG_CEDVp1_DESIGN_V 0x92a3 //int16_t 15 bits
+#define BQ_GG_CEDVp1_CHG_TERM_V 0x92a5 //int16_t
+#define BQ_GG_CEDVp1_EMF 0x92a7 //uint16_t
+#define BQ_GG_CEDVp1_C0 0x92a9 //uint16_t
+#define BQ_GG_CEDVp1_R0 0x92ab //uint16_t
+#define BQ_GG_CEDVp1_T0 0x92ad //uint16_t
+#define BQ_GG_CEDVp1_R1 0x92af //uint16_t
+#define BQ_GG_CEDVp1_TC 0x92b1 //uint8_t
+#define BQ_GG_CEDVp1_C1 0x92b2 //uint8_t
+#define BQ_GG_CEDVp1_AGE_FACTOR 0x92b3 //uint8_t
+#define BQ_GG_CEDVp1_FIXED_EDV0 0x92b4 //int16_t
+#define BQ_GG_CEDVp1_HOLDT_EDV0 0x92b6 //uint8_t
+#define BQ_GG_CEDVp1_FIXED_EDV1 0x92b7 //int16_t
+#define BQ_GG_CEDVp1_HOLDT_EDV1 0x92b9 //uint8_t
+#define BQ_GG_CEDVp1_FIXED_EDV2 0x92ba //int16_t
+#define BQ_GG_CEDVp1_HOLDT_EDV2 0x92bc //uint8_t
+
// CNTL_STAT register bit equates
#define BQ_BIT_CS_CCA 0x0020
#define BQ_BIT_CS_BCA 0x0010
@@ -94,20 +172,36 @@
#define BQ_BIT_CS_BAT_ID2 0x0004
#define BQ_BIT_CS_BAT_ID1 0x0002
#define BQ_BIT_CS_BAT_ID0 0x0001
+#define BQ_BIT_CS_BAT_ID (BQ_BIT_CS_BAT_ID2 | BQ_BIT_CS_BAT_ID1 | BQ_BIT_CS_BAT_ID0)
-//GaugingStatus register bit equates
+// Gauging Status register bit equates
#define BQ_BIT_GS_VDQ 0x8000
#define BQ_BIT_GS_EDV2 0x4000
#define BQ_BIT_GS_EDV1 0x2000
+#define BQ_BIT_GS_RSVD1 0x1000
+#define BQ_BIT_GS_RSVD2 0x0800
#define BQ_BIT_GS_FCCX 0x0400
+#define BQ_BIT_GS_RSVD3 0x0200
+#define BQ_BIT_GS_RSVD4 0x0100
#define BQ_BIT_GS_CF 0x0080
#define BQ_BIT_GS_DSG 0x0040
#define BQ_BIT_GS_EDV 0x0020
+#define BQ_BIT_GS_RSVD5 0x0010
#define BQ_BIT_GS_TC 0x0008
#define BQ_BIT_GS_TD 0x0004
#define BQ_BIT_GS_FC 0x0002
#define BQ_BIT_GS_FD 0x0001
+// CEDV Gauging Configuration register bit equates
+#define BQ_BIT_GC_SME0 0x1000
+#define BQ_BIT_GC_IGNORE_SD 0x0800
+#define BQ_BIT_GC_FC_FOR_VDQ 0x0400
+#define BQ_BIT_GC_FCC_LIMIT 0x0100
+#define BQ_BIT_GC_FIXED_EDV0 0x0020
+#define BQ_BIT_GC_SC 0x0010
+#define BQ_BIT_GC_EDV_CMP 0x0008
+#define BQ_BIT_GC_CSYNC 0x0002
+#define BQ_BIT_GC_CCT 0x0001
// FLAGS register bit equates
#define BQ_BIT_F_FD 0x8000
@@ -136,6 +230,74 @@
#define BQ_BIT_OS_SEC1 0x0004
#define BQ_BIT_OS_SEC0 0x0002
#define BQ_BIT_OS_CALMD 0x0001
+
+// Operation Config Reg A bit equates
+#define BQ_BIT_OCA_TEMPS 0x8000
+#define BQ_BIT_OCA_RSVD1 0x4000
+#define BQ_BIT_OCA_BATG_POL 0x2000
+#define BQ_BIT_OCA_BATG_EN 0x1000
+#define BQ_BIT_OCA_RSVD2 0x0800
+#define BQ_BIT_OCA_SLEEP 0x0400
+#define BQ_BIT_OCA_SLPWAKECHG 0x0200
+#define BQ_BIT_OCA_WRTEMP 0x0100
+#define BQ_BIT_OCA_BIE 0x0080
+#define BQ_BIT_OCA_RSVD3 0x0040
+#define BQ_BIT_OCA_BI_PUP_EN 0x0020
+#define BQ_BIT_OCA_PFC_CFG1 0x0010
+#define BQ_BIT_OCA_PFC_CFG0 0x0008
+#define BQ_BIT_OCA_WAKE_EN 0x0004
+#define BQ_BIT_OCA_WK_TH1 0x0002
+#define BQ_BIT_OCA_WK_TH0 0x0001
+
+// Operation Config Reg B bit equates
+#define BQ_BIT_OCB_RSVD1 0x8000
+#define BQ_BIT_OCB_RSVD2 0x4000
+#define BQ_BIT_OCB_RSVD3 0x2000
+#define BQ_BIT_OCB_RSVD4 0x1000
+#define BQ_BIT_OCB_DEF_SEAL 0x0800
+#define BQ_BIT_OCB_NR 0x0400
+#define BQ_BIT_OCB_RSVD5 0x0200
+#define BQ_BIT_OCB_RSVD6 0x0100
+#define BQ_BIT_OCB_INT_BREM 0x0080
+#define BQ_BIT_OCB_INT_BATL 0x0040
+#define BQ_BIT_OCB_INT_STATE 0x0020
+#define BQ_BIT_OCB_INT_OCV 0x0010
+#define BQ_BIT_OCB_RSVD7 0x0008
+#define BQ_BIT_OCB_INT_OT 0x0004
+#define BQ_BIT_OCB_INT_POL 0x0002
+#define BQ_BIT_OCB_INT_FOCV 0x0001
+
+// SOC Flags Reg A bit equates
+#define BQ_BIT_SOCFA_TCSETVCT 0x0800
+#define BQ_BIT_SOCFA_FCSETVCT 0x0400
+#define BQ_BIT_SOCFA_TCCLEARRSOC 0x0080
+#define BQ_BIT_SOCFA_TCSETRSOC 0x0040
+#define BQ_BIT_SOCFA_TCCLEARV 0x0020
+#define BQ_BIT_SOCFA_TCSETV 0x0010
+#define BQ_BIT_SOCFA_TDCLEARRSOC 0x0008
+#define BQ_BIT_SOCFA_TDSETRSOC 0x0004
+#define BQ_BIT_SOCFA_TDCLEARV 0x0002
+#define BQ_BIT_SOCFA_TDSETV 0x0001
+
+// SOC Flags Reg B bit equates
+#define BQ_BIT_SOCFB_FCCLEARRSOC 0x0080
+#define BQ_BIT_SOCFB_FCSETRSOC 0x0040
+#define BQ_BIT_SOCFB_FCCLEARV 0x0020
+#define BQ_BIT_SOCFB_FCSETV 0x0010
+#define BQ_BIT_SOCFB_FDCLEARRSOC 0x0008
+#define BQ_BIT_SOCFB_FDSETRSOC 0x0004
+#define BQ_BIT_SOCFB_FDCCLEARV 0x0002
+#define BQ_BIT_SOCFB_FDSETV 0x0001
+
+// IO Config bit equates
+#define BQ_BIT_IOCFG_BtpIntPol 0x0002
+#define BQ_BIT_SOCFB_BTpIntEn 0x0001
+
+// Smoothing Config bit equates
+#define BQ_BIT_SMOC_SMOOTH_EOC_EN 0x0008
+#define BQ_BIT_SMOC_CMEXT 0x0004
+#define BQ_BIT_SMOC_VAVG 0x0002
+#define BQ_BIT_SMOC_SMEN 0x0001
class BQ27220
{
@@ -146,26 +308,26 @@
**/
typedef struct {
uint16_t cntlReg; /*!< CNTL register */
- uint16_t arReg; /*!< AR register */
+ int16_t arReg; /*!< AR register */
uint16_t artteReg; /*!< ARTTE register */
uint16_t tempReg; /*!< TEMP register */
uint16_t voltReg; /*!< VOLT register */
uint16_t flagsReg; /*!< FLAGS register */
- uint16_t currentReg; /*!< CURRENT register */
+ int16_t currentReg; /*!< CURRENT register */
uint16_t rmReg; /*!< RM register */
uint16_t fccReg; /*!< FCC register */
uint16_t aiReg; /*!< AI register */
uint16_t tteReg; /*!< TTE register */
uint16_t ttfReg; /*!< TTF register */
- uint16_t siReg; /*!< SI register */
+ int16_t siReg; /*!< SI register */
uint16_t stteReg; /*!< STTE register */
- uint16_t mliReg; /*!< MLI register */
+ int16_t mliReg; /*!< MLI register */
uint16_t mltteReg; /*!< MLTTE register */
uint16_t rawccReg; /*!< RCC register */
- uint16_t apReg; /*!< AP register */
+ int16_t apReg; /*!< AP register */
uint16_t intTempReg; /*!< INTTEMP register */
uint16_t cycReg; /*!< CYC register */
@@ -178,17 +340,20 @@
uint16_t btpcReg; /*!< BTPC register */
uint16_t osReg; /*!< OS register */
uint16_t dcReg; /*!< DC register */
+ uint16_t subReg; /*!< SUB command register */
char macData[32]; /*!< MAC Data array */
- uint16_t macSumReg; /*!< MAC Data Sum register */
+ uint8_t macSumReg; /*!< MAC Data Sum register */
- uint16_t macLenReg; /*!< MAC Data Len register */
+ uint8_t macLenReg; /*!< MAC Data Len register */
uint8_t anacReg; /*!< Analog Count register */
uint16_t rawcReg; /*!< RAWC register */
uint16_t rawvReg; /*!< RAWV register */
uint16_t rawtReg; /*!< RAWT register */
+
+ uint8_t checksum; /*!< calculated checksum result */
- int16_t shunt_res; /*!< Shunt Resistor value * 1000, 20 = 0.020 ohm */
- char i2c_Bufx[32]; /*!< i2c buffer */
+ int16_t shunt_res; /*!< Shunt Resistor value / 1000 */
+ char i2c_Bufx[48]; /*!< i2c buffer */
} BQ27220_TypeDef;
/** Configure data pin
@@ -197,7 +362,7 @@
**/
//BQ27220(PinName p_sda, PinName p_scl, PinName p_pgrm);
BQ27220(PinName p_sda, PinName p_scl);
-
+ BQ27220(PinName p_sda, PinName p_scl, int freq);
/** Write default values for CNTL register and shunt resistor * 1000
* @param I2c pins
@@ -206,12 +371,87 @@
*/
void default_init(BQ27220_TypeDef& dataSTR);
+ uint16_t get_OS_reg(BQ27220_TypeDef& dataSTR);
+
/** Read all bq registers and put them into the data structure
* @param pointer to data structure
* @return i2c error, 0 = no error
*/
int read_registers(BQ27220_TypeDef& dataSTR);
+ /** Send sub-command and read data and/or result from sub-command
+ * @param pointer to data structure
+ * @return result and/or data
+ */
+ uint16_t get_sub_cmmd(BQ27220_TypeDef& dataSTR, uint16_t cmmd);
+
+ /** Like above, without extra delays
+ * @param pointer to data structure
+ * @return result and/or data
+ */
+ uint16_t get_sub_cmmd_s(BQ27220_TypeDef& dataSTR, uint16_t cmmd);
+
+ void change_cfg_OT_chg_time(BQ27220_TypeDef& dataSTR, uint8_t newtime);
+ void change_ram_1_2_4(BQ27220_TypeDef& dataSTR, uint16_t sub_cmmd, uint32_t value, int qty, bool pre);
+ void change_cfg_6_1(BQ27220_TypeDef& dataSTR);
+ uint16_t get_cs_len(BQ27220_TypeDef& dataSTR, bool pf);
+ void exitCfgUpdateReInit(BQ27220_TypeDef& dataSTR);
+ void exitCfgUpdateExit(BQ27220_TypeDef& dataSTR);
+ void set_reg(BQ27220_TypeDef& dataSTR, uint16_t reg, uint16_t da, int byt);
+
+ uint16_t get_reg_2B(BQ27220_TypeDef& dataSTR, uint8_t reg);
+
+ void unseal(BQ27220_TypeDef& dataSTR);
+ void full_access(BQ27220_TypeDef& dataSTR);
+ void enter_cfg_update(BQ27220_TypeDef& dataSTR);
+ void seal(BQ27220_TypeDef& dataSTR);
+ void useProfile_1(BQ27220_TypeDef& dataSTR);
+ void reset(BQ27220_TypeDef& dataSTR);
+
+ /** Send sub-command to get device ID
+ * @param pointer to data structure
+ * @return sub-command + device id
+ */
+ uint32_t get_dev_id(BQ27220_TypeDef& dataSTR);
+
+ /** Send sub-command to get firmware revision
+ * @param pointer to data structure
+ * @return revision
+ */
+ uint32_t get_fw_rev(BQ27220_TypeDef& dataSTR);
+
+ /** Send sub-command to get firmware revision
+ * @param pointer to data structure
+ * @return revision
+ */
+ uint32_t get_hw_rev(BQ27220_TypeDef& dataSTR);
+
+ uint8_t calc_checksum_rx(BQ27220_TypeDef& dataSTR, int length);
+ uint8_t calc_checksum_tx(BQ27220_TypeDef& dataSTR, int length);
+
+ /** Send sub-command to get 32 bytes data
+ * @param pointer to data structure
+ * @param sub-command
+ * @return 32 bytes in macData
+ */
+ uint32_t get_data_32(BQ27220_TypeDef& dataSTR, uint16_t sub_cmmd, int length);
+
+ /** Get signed 16 bit value
+ * @param pointer to data structure
+ * @param sub-command
+ * @return 16 bit signed value
+ */
+ uint16_t get_16(BQ27220_TypeDef& dataSTR, uint16_t cmmd);
+
+ /** Get unsigned 8 bit value
+ * @param pointer to data structure
+ * @param sub-command
+ * @return 8 bit signed value
+ */
+ uint8_t get_8(BQ27220_TypeDef& dataSTR, uint16_t cmmd);
+
+ void set_ntc_as_sensor(BQ27220_TypeDef& dataSTR, bool ntc);
+
/** Initialize SoC for a new battery
* @param pointer to data structure
* @return error, 0 = no error
