Driver for Texas Instruments' battery state-of-charge estimator.

Dependents:   BQ34Z100G1-Utils BQ34Z100G1-ChemIDMeasurer

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BQ34Z100.h Source File

BQ34Z100.h

00001 /*
00002    USCRPL
00003    BQ34Z100-G1 Sensor Driver
00004 
00005    Reads the current state of the main battery, can determine charge remaining inside
00006    as well as read instantaneous voltage, current, or temperature.
00007 
00008    Datasheet: http://www.ti.com/lit/ds/symlink/bq34z100-g1.pdf
00009    Existing arduino code to reference from unknown author: https://github.com/Ralim/BQ34Z100
00010    Partial library from TI that may be useful: http://www.ti.com/lit/an/slua801/slua801.pdf
00011  */
00012 
00013 #ifndef BQ34Z100_H
00014 #define BQ34Z100_H
00015 
00016 #include <cstdint>
00017 
00018 //Definitions
00019 #define GAUGE_ADDRESS 0xAA
00020 
00021 //Battery configuration settings
00022 //Stored in flash: run flashSettings() then reset sensor to save
00023 #define DESIGNCAP 1400 //mAh, per cell (Page 48, offset 11)
00024 #define DESIGNENERGY 5180 //mWh, per cell (Page 48, offset 14)
00025 #define CELLCOUNT 0x04 //number of series cells (Page 65, offset 7)
00026 #define LEDCONFIG 0x4b //5-LED Expander with I2C host comm (Page 64, offset 4)
00027 #define VOLTSEL true //Switches to an external battery voltage divider
00028 #define ZEROCHARGEVOLT 3375 //mV, charge cut-off voltage/Cell terminate voltages
00029 #define FLASH_UPDATE_OK_VOLT 2800 // mV, below this voltage per cell flash writes will not go through
00030 
00031 #define QMAX0 1400 //mAh, datasheet says to use c-rate current
00032 
00033 //The voltage divider works by this formula: Gain = (TOP LEG R/BOTTOM LEG R)*1000
00034 //Top leg: 294Kohm and bottom leg: 16.5Kohm
00035 //This only works if you enable the external voltage divider (VOLTSEL) option for the sensor
00036 //Note: requires calibration after setting in flash
00037 #define VOLTAGEGAIN 17818
00038 #define LOADSELECT 0x01 // "Load Select defines the type of power or current model to be used to compute load-compensated capacity in the Impedance Track algorithm"
00039 #define LOADMODE 0x00 // "Load Mode is used to select either the constant current or constant power model for the Impedance Track algorithm"
00040 #define RESETVOLTAGE 22200 //mV, voltage to reset to after unsuccessful voltage calibration
00041 
00042 //Sense resistor value
00043 #define SENSE_RES 5.0f //mOhms, value of guage sense resistor
00044 
00045 #define USE_EXTERNAL_THERMISTOR 0 // If 1, use an external thermistor connected to the IT pin.  If 0, use the internal temp sensor.
00046 
00047 #include "mbed.h"
00048 
00049 class BQ34Z100
00050 {
00051     // Top-level commands - the first byte that you can send on an I2C transaction
00052     enum class Command : uint8_t
00053     {
00054         Control = 0x0,
00055         StateOfCharge = 0x2,
00056         MaxError = 0x3,
00057         RemainingCapacity = 0x4,
00058         FullChargeCapacity = 0x6,
00059         Voltage = 0x8,
00060         AverageCurrent = 0xA,
00061         Temperature = 0xC,
00062         Flags = 0xE,
00063         Current = 0x10,
00064         FlagsB = 0x12,
00065         // ...
00066         SerialNumber = 0x28,
00067         InternalTemperature = 0x2A,
00068         CycleCount = 0x2C,
00069         StateOfHealth = 0x2E,
00070         // ...
00071         DataFlashClass = 0x3E,
00072         DataFlashBlock = 0x3F,
00073         BlockData = 0x40,
00074         // ...
00075         BlockDataCheckSum = 0x60,
00076         BlockDataControl = 0x61
00077     };
00078 
00079     // subcommands for Control command
00080     enum class Control : uint16_t
00081     {
00082         CONTROL_STATUS = 0x0,
00083         DEVICE_TYPE = 0x1,
00084         FW_VERSION = 0x02,
00085         HW_VERSION = 0x03,
00086         RESET_DATA = 0x5,
00087         PREV_MACWRITE = 0x7,
00088         CHEM_ID = 0x8,
00089         BOARD_OFFSET = 0x9,
00090         CC_OFFSET = 0xA,
00091         CC_OFFSET_SAVE = 0xB,
00092         DF_VERSION = 0xC,
00093         SET_FULLSLEEP = 0x10,
00094         STATIC_CHEM_CHECKSUM = 0x17,
00095         SEALED = 0x20,
00096         IT_ENABLE = 0x21,
00097         CAL_ENABLE = 0x2D,
00098         RESET = 0x41,
00099         EXIT_CAL = 0x80,
00100         ENTER_CAL = 0x81,
00101         OFFSET_CAL = 0x82,
00102 
00103         // unseal key, from datasheet p.21
00104         UNSEAL_KEY1 = 0x0414,
00105         UNSEAL_KEY2 = 0x3672
00106     };
00107 
00108 public:
00109         /** Create an GQ34Z100-G1 object connected to the specified I2C pins
00110          *
00111          * @param sda The I2C data pin.
00112          * @param scl The I2C clock pin.
00113          * @param hz The I2C bus frequency (400kHz acc. to datasheet).
00114          */
00115         BQ34Z100(PinName sda, PinName scl, int hz = 400000);
00116 
00117         //returs status of key features
00118         uint16_t getStatus();
00119 
00120         //Allows use of the entry and exit functions to the CALIBRATION mode
00121         //Use before enterCal or exitCal()
00122         void enableCal();
00123 
00124         //Enables CALIBRATION mode
00125         void enterCal();
00126 
00127         //Exits CALIBRATION mode
00128         void exitCal();
00129 
00130         //Allows the sensor to begin the Impednance Track algorithm (learns about
00131         //the battery and begins to find the SOC)
00132         void ITEnable();
00133 
00134         //Returns the predicted remaining battery capacity expressed as a percentage
00135         //From 0% to 100%
00136         uint8_t getSOC();
00137 
00138         //Returns the expected margin of error in the SOC calculation ranging from
00139         //1% to 100%. The value is updated continuously internally in increments
00140         //of 0.05%
00141         uint16_t getError();
00142 
00143         //Estimated remaining battery capacity (1 mAH per bit)
00144         uint16_t getRemaining();
00145 
00146         //Returns the measured battery voltage in mV (0 to 65535 mV)
00147         uint16_t getVoltage();
00148 
00149         //Returns measured current flow through the sense resistor (mA)
00150         int16_t getCurrent();
00151 
00152         //Returns internal sensor temperature in units of celsius
00153         double getTemperature();
00154 
00155         //Returns the current ChemID configured inside the chip.
00156         // Returns as a hex number, e.g. programming ID 2109 would cause
00157         // this function to return 8457 = 0x2109
00158         uint16_t getChemID();
00159 
00160         //Returns a percent from 0 to 100 that is the ratio of the predicted FCC over the design capacity
00161         //FCC = the full charge capacity
00162         //For example, an old battery will not be able to charge fully to its design capacity
00163         //This sensor can tell us if we should throw the battery away because its worn out! Cool!
00164         uint16_t getStateOfHealth();
00165 
00166         //Returns the pack serial number programmed in the data flash
00167         int getSerial();
00168 
00169         //Instructs the fuel gauge to perform a full reset. This command is only
00170         //available when the fuel gauge is UNSEALED
00171         void reset();
00172 
00173         //Unseal some registers, allowing writing (recommended before writing to flash)
00174         void unseal();
00175 
00176         //Reverse unseal command, do not recommend ever using this
00177         void seal();
00178 
00179         //Data flash functions
00180 
00181         //Changes to a different register in BlockData()
00182         void changePage(char subclass, uint16_t offset);
00183 
00184         //Reads the checksum and updates it using the flashbytes array
00185         //Required by the sensor to save changes to the flash
00186         void updateChecksum();
00187 
00188         //Reads the blockData in the current page and saves it to
00189         //flashbytes array
00190         void readFlash();
00191 
00192         //Writes a specific index in the page to a given value
00193         //given the length of the property
00194         void writeFlash(uint8_t index, uint32_t value, int len);
00195 
00196         //Returns array (pointer) to flashbytes internal array
00197         //which stores the last updated page in flash
00198         uint8_t* getFlashBytes();
00199 
00200         //The following functions change different pages
00201         //The number is the subClass ID that is being changed
00202         //Each page has different properties that are in those registers
00203         void changePage48();
00204         void changePage64();
00205         void changePage80();
00206         void changePage82();
00207 
00208         //Calibrates the Voltage Divider register (run at least 3 times sequentially)
00209         // NOTE: Voltage divider changes seem to require a chip reset to take effect.
00210         // So you must reset the chip between each calibration.
00211         uint16_t calibrateVoltage(uint16_t currentVoltage);
00212 
00213         //If a problem arises with the voltage divider calibration,
00214         //reset the register with this function
00215         void setVoltageDivider(uint16_t newVoltage = RESETVOLTAGE);
00216 
00217         //Calibrate CCGain and CCOffset registers, which control current shunt
00218         //and therefore affect the current and voltage readouts
00219         void calibrateShunt(int16_t calCurrent);
00220 
00221         //Set the Chem ID in the flash
00222         void setChemID();
00223 
00224         //Set sense resistor - Calibrate shunt also works, but that requires and external
00225         //current measurement.
00226         void setSenseResistor();
00227 
00228         // Read the device type.  Should be 0x100 for the BQ34Z100.
00229         uint16_t readDeviceType();
00230 
00231         // reads the contents of the SW and HW version registers.
00232         uint16_t readFWVersion();
00233         uint16_t readHWVersion();
00234 
00235         // Convert float value to Xemics floating point used on the BQZ.
00236         // Documented in this app note: http://www.ti.com/lit/pdf/slva148
00237         static uint32_t floatToXemics(float value);
00238         static float xemicsToFloat(uint32_t xemics);
00239 
00240         // Read the update status register from flash.
00241         // This gives the status of the Impedance Track algorithm and learning process.
00242         uint8_t getUpdateStatus();
00243 
00244         /**
00245          * Use the Flags and FlagsB commands to get the contents of the Gas Gauge Status Register.
00246          * @return
00247          */
00248         std::pair<uint16_t, uint16_t> getFlags();
00249 
00250 private:
00251         I2C _i2c;
00252         uint8_t currFlashPage = 0; // current flash page that we have read
00253         uint8_t currFlashBlockIndex = 0; // 32 bit block index into current flash page
00254         uint8_t flashbytes[32]; //Stores page in flash memory on Hamster
00255 
00256         //Internal commands for writing/reading i2c
00257 
00258         // Send a control command and return the result
00259         void sendControlCommand(Control control);
00260 
00261         uint16_t readControlCommand(Control control);
00262 
00263         void write(Command command, const uint8_t cmd); //1 byte only
00264         void write(Command command, const uint8_t cmd1, const uint8_t cmd2); //2 bytes
00265         uint32_t read(Command command, const uint8_t length);
00266 
00267         // Calculate the checksum of the current flashbytes
00268         uint8_t calcChecksum();
00269 };
00270 #endif