This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BQ27425-G2 Sample code

Other Parts Discussed in Thread: BQ27510-G3, BQ27425-G2A

Hello,

Someone could please send a sample code for communicating with the component BQ27425-G2 with I2C?

Thank you,

Ido

  • Did you get some sample code to communicate with the part over I2C? I am looking for one too.

  • There is sample code for the Fuel Tank BoosterPack for TI's development boards. It uses a bq27510-G3 gauge which is different from the bq27425-G2A. However, it should still provide a good starting point for interfacing with the gauge. Even if you're using, say, an Arduino, the basic process of using I2C will be the same.

    http://www.element14.com/community/docs/DOC-55618#anchor3

    If I have time, I might write up some more specific code to interface with the bq27425.

  • Hello,
    I did not get the code for BQ27425 component, so I began to write it by myself (I'm pretty new in writing software but I hope it can help).
    Meanwhile I was able to activate most functions except:
    FuelGauge_set_Block_Data ()
    Because I could not calculate the CheckSum properly.
    I would be happy if you can help and fix the attached code.

    Thank you,
    Ido

    6378.hal_fuelgauge.c
    /**************************************************************************************************
      Filename:       hal_fulegauge.c
    
    
    /* ------------------------------------------------------------------------------------------------
    *                                          Includes
    * ------------------------------------------------------------------------------------------------
    */
    #include "hal_fuelgauge.h"
    #include "hal_i2c.h"
    #include "hal_sensor.h"
    #include "hal_wait.h"
    
    /* ------------------------------------------------------------------------------------------------
    *                                           Constants
    * ------------------------------------------------------------------------------------------------
    */
    
    /* Slave address */
    #define BQ27425_I2C_ADDRESS              0x55
    
    /* BQ27425 register addresses */
    #define BQ27425_REG_CNTL	0x00    // N/A
    #define BQ27425_REG_TEMP	0x02    // 0.1K
    #define BQ27425_REG_VOLT	0x04    // mV
    #define BQ27425_REG_FLAGS	0x06    // N/A
    #define BQ27425_REG_NAC		0x08    // mAh
    #define BQ27425_REG_FAC		0x0A    // mAh
    #define BQ27425_REG_RM		0x0C    // mAh
    #define BQ27425_REG_FCC		0x0E    // mAh
    #define BQ27425_REG_AC		0x10    // mA
    #define BQ27425_REG_DEBUG1      0x16    // num
    #define BQ27425_REG_AP		0x18    // mW
    #define BQ27425_REG_SOC		0x1C    // %
    #define BQ27425_REG_ITEMP	0x1E    // 0.1K
    #define BQ27425_REG_SOH		0x20    // %
    #define BQ27425_REG_DEBUG2      0x2C    // num
    #define BQ27425_REG_DEBUG3      0x32    // num
    #define BQ27425_REG_OPCONFIG    0x3A    // N/A
    #define BQ27425_REG_DESIGN_CAP  0x3C    // mAh
    
    //#define BQ27425_REG_SI		0x12
    //#define BQ27425_REG_MLI		0x14
    
    /* BQ27425 register values */
    #define BQ27425_SUBCMD_CTNL_STATUS  		0x0000
    #define BQ27425_SUBCMD_DEVCIE_TYPE		0x0001
    #define BQ27425_SUBCMD_FW_VER			0x0002
    #define BQ27425_SUBCMD_PREV_MACWRITE	        0x0007
    #define BQ27425_SUBCMD_CHEM_ID                  0x0008
    #define BQ27425_SUBCMD_BAT_INSERT		0x000C
    #define BQ27425_SUBCMD_BAT_REMOVE		0x000D
    #define BQ27425_SUBCMD_SET_HIBERNATE		0x0011
    #define BQ27425_SUBCMD_CLEAR_HIBERNATE	        0x0012
    #define BQ27425_SUBCMD_SET_CFGUPDATE	        0x0013
    #define BQ27425_SUBCMD_SEALED			0x0020
    #define BQ27425_SUBCMD_RESET			0x0041
    #define BQ27425_SUBCMD_SOFT_RESET		0x0042
    
    //#define BQ27425_SUBCMD_HW_VER  		0x03
    //#define BQ27425_SUBCMD_SET_FULLSLEEP		0x10
    
    /* BQ27425 register values */
    #define BQ27425_VAL_MANF_ID              0x0425  // Manufacturer ID
    
    /* Extended commands */
    #define BQ27425_EXTCMD_OPCFG		        0x3A
    #define BQ27425_EXTCMD_DCAP		        0x3C
    #define BQ27425_EXTCMD_DFCLS		        0x3E
    #define BQ27425_EXTCMD_DFBLK		        0x3F
    #define BQ27425_EXTCMD_BLOCKDATA                0x40
    #define BQ27425_EXTCMD_BLOCKCHECKSUM	        0x60
    #define BQ27425_EXTCMD_BLOCKDATACONTROL         0x61
    #define BQ27425_EXTCMD_DNAMELEN	                0x62
    #define BQ27425_EXTCMD_DNAME		        0x63
    
    /* Register length */
    #define FUEL_GAUGE_REG_LEN                  2
    
    
    /* ------------------------------------------------------------------------------------------------
    *                                           Local Functions
    * ------------------------------------------------------------------------------------------------
    */
    static void HalFuelGaugeSelect(void);
    
    
    /* ------------------------------------------------------------------------------------------------
    *                                           Local Variables
    * ------------------------------------------------------------------------------------------------
    */
    static FuelGauge_States_t fulegaugetSensorState = BQ27425_OFF;
    
    
    /* ------------------------------------------------------------------------------------------------
    *                                           Public functions
    * -------------------------------------------------------------------------------------------------
    */
    
    /**************************************************************************************************
     * @fn          HALFuelGaugeInit
     *
     * @brief       Initialise the temperature sensor driver
     *
     * @return      none
     **************************************************************************************************/
    void HALFuelGaugeInit(void)
    {
    	;
    }
    
    
    /**************************************************************************************************
     * @fn          HalFuelGaugeTest
     *
     * @brief       Run a sensor self-test
     *
     * @return      TRUE if passed, FALSE if failed
     **************************************************************************************************/
    bool HalFuelGaugeTest(void)
    {
      uint16 val = 0;
      uint8 data[2];
      // Select this sensor on the I2C bus
      HalFuelGaugeSelect();
    
      // Reset sensor
      FuelGauge_reset_soc();
      
      // Check manufacturer ID
      data[0] = BQ27425_SUBCMD_DEVCIE_TYPE;
      data[1] = ((BQ27425_SUBCMD_DEVCIE_TYPE) >> 8);
      HalSensorWriteReg(BQ27425_REG_CNTL    , &data[0], 1);
      HalSensorWriteReg(BQ27425_REG_CNTL + 1, &data[1], 1);
      HalSensorReadReg(BQ27425_REG_CNTL, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
      val = (HI_UINT16(val) << 8) | LO_UINT16(val);
    
      val = FuelGauge_get_temperature();
    
      HalSensorReadReg(BQ27425_REG_VOLT, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
      val = (HI_UINT16(val) << 8) | LO_UINT16(val);  
    
      HalSensorReadReg(BQ27425_REG_NAC, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
      val = (HI_UINT16(val) << 8) | LO_UINT16(val);
    
      HalSensorReadReg(BQ27425_REG_DESIGN_CAP, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
      val = (HI_UINT16(val) << 8) | LO_UINT16(val);
        
      HalSensorReadReg(BQ27425_REG_SOC, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
      val = (HI_UINT16(val) << 8) | LO_UINT16(val);
      
      val = FuelGauge_get_FullAviCap();
    
      val = FuelGauge_get_RemCap();
     
      val = FuelGauge_get_AveCurrent();
     
      return TRUE;
    }
    
    /* ------------------------------------------------------------------------------------------------
    *                                           Private functions
    * -------------------------------------------------------------------------------------------------
    */
    
    /**************************************************************************************************
     * @fn          HalfuelgaugeSelect
     *
     * @brief       Select the BQ27425 slave and set the I2C bus speed
     *
     * @return      none
     **************************************************************************************************/
    static void HalFuelGaugeSelect(void)
    {
      // Select slave and set clock rate
      HalI2CInit(BQ27425_I2C_ADDRESS, i2cClock_267KHZ);
    }
    
    /**************************************************************************************************
     * @fn         FuelGauge_get_temperature
     *
     * @brief      Get the Battery temp
     *
     * @return     val - battery temp
     **************************************************************************************************/
    uint16 FuelGauge_get_temperature(void)
    {
      uint16 val;
    		
      HalSensorReadReg(BQ27425_REG_FAC, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
      if(val <= 0)
      {
        return (-1);
      }
      else
      {
        return val;
      }
    }
    
    /**************************************************************************************************
     * @fn         FuelGauge_get_FullAviCap
     *
     * @brief      This read-only command pair returns the uncompensated (less than C/20 load) 
     *             capacity of the battery when fully charged. Units are mAh. 
     *             FullAvailableCapacity( ) is updated at regular intervals, 
     *             as specified by the IT algorithm.
     *
     * @return     val - Full Available 
     **************************************************************************************************/
    uint16 FuelGauge_get_FullAviCap(void)
    {
      uint16 val;
    		
      HalSensorReadReg(BQ27425_REG_FAC, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
      if(val <= 0)
      {
        return (-1);
      }
      else
      {
        return val;
      }
    }
    
    /**************************************************************************************************
     * @fn         FuelGauge_get_RemCap
     *
     * @brief      This read-only command pair returns the compensated battery capacity remaining.
     *             Units are mAh
     *
     * @return     val - Remaining Capacity
     **************************************************************************************************/
    uint16 FuelGauge_get_RemCap(void)
    {
      uint16 val;
    		
      HalSensorReadReg(BQ27425_REG_RM, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
      if(val <= 0)
      {
        return (false);
      }
      else
      {
        return val;
      }
    }
    
    /**************************************************************************************************
     * @fn         FuelGauge_get_AveCurrent
     *
     * @brief      This read-only command pair returns a signed integer value that is the average
     *             current flow through the sense resistor. In NORMAL mode, it is updated once per
     *             second and is calculated by dividing the 1 second change in coulomb counter data
     *             by 1 second. Large current spikes of short duration will be averaged out in
     *             this measurement. Units are mA.
     *
     * @return     val - AverageCurrenty
     **************************************************************************************************/
    uint16 FuelGauge_get_AveCurrent(void)
    {
      uint16 val;
    		
      HalSensorReadReg(BQ27425_REG_AC, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
    
      return val;
    }
    
    /**************************************************************************************************
     * @fn         FuelGauge_set_unsealmode
     *
     * @brief      Unsealed the fuel gauge for battry and memory update
     *             The Bq27425 code for unsealed its: 0x36720414
     *
     * @return     Pass / Fail
     **************************************************************************************************/
    bool FuelGauge_set_unsealmode(void)
    {
      uint8 data[2];
      uint16 val = 0x0000;
      
      data[0] = 0x14;
      data[1] = 0x04;
      HalSensorWriteReg(BQ27425_REG_CNTL, &data[0], 1);
      HalSensorWriteReg(BQ27425_REG_CNTL + 1, &data[1], 1);
    
      data[0] = 0x72;
      data[1] = 0x36;
      HalSensorWriteReg(BQ27425_REG_CNTL, &data[0], 1);
      HalSensorWriteReg(BQ27425_REG_CNTL + 1, &data[1], 1);
    
      // Check unsealed = successful
      data[0] = BQ27425_SUBCMD_CTNL_STATUS;
      data[1] = ((BQ27425_SUBCMD_CTNL_STATUS) >> 8);
      HalSensorWriteReg(BQ27425_REG_CNTL, &data[0], 1);
      HalSensorWriteReg(BQ27425_REG_CNTL + 1, &data[1], 1);
      HalSensorReadReg(BQ27425_REG_CNTL, (uint8 *)&val, FUEL_GAUGE_REG_LEN);
      if (val & 0x4000)
      {
        return 0;
      }
      else
      {
        return 1;
      }
    }
    
    /**************************************************************************************************
     * @fn         FuelGauge_reset_soc
     *
     * @brief      This command instructs the fuel gauge to perform a full device reset
     *             and reinitialize RAM data to the default values from ROM.
     *             The gauge sets the Flags[ITPOR] bit and enters the INITIALIZE mode.
     *             This command is only available when the fuel gauge is UNSEALED
     *
     * @return     Pass / Fail
     **************************************************************************************************/
    bool FuelGauge_reset_soc(void)
    {
      uint8 data[2];
      
      data[0] = 0x41;
      data[1] = 0x00;
      HalSensorWriteReg(BQ27425_REG_CNTL, &data[0], 1);
      HalSensorWriteReg(BQ27425_REG_CNTL + 1, &data[1], 1);
    
      halMcuWaitMs(3000); 
    
      return 1;
    }
    
    /**************************************************************************************************
     * @fn         FuelGauge_get_Block_Data
     *
     * @brief      This data block is the remainder of the 32 byte data block when accessing
     *             general block data.
     *
     * @return     Pass / Fail
     **************************************************************************************************/
    uint8 FuelGauge_get_Block_Data(void)
    {
      uint8 data[32];
      uint8 raw_data[2];
      raw_data[0] = 0x52;
      raw_data[1] = 0x00;
      uint8 CheckSum[2] = {0,0};
      uint16 ret, val ;
      uint8 i = 0;
      uint8 Test[2] = {0, };
    
      FuelGauge_set_unsealmode();
      halMcuWaitMs(200);
      
      HalSensorWriteReg(BQ27425_EXTCMD_DFCLS, &raw_data[0], 1);
      HalSensorWriteReg(BQ27425_EXTCMD_DFBLK, &raw_data[1], 1);
      for (i = 0 ; i < 32 ; i++)
      {
        HalSensorReadReg(BQ27425_EXTCMD_BLOCKDATA + i, (uint8 *)&data[i], 1);
      }
      CheckSum[1] = 0x00;   // Writing 0x00 to this command enables BlockData( ) to access NVM and RAM
    
      HalSensorReadReg(BQ27425_EXTCMD_BLOCKDATA + 0x12, (uint8 *)&Test[0], 1);
      HalSensorReadReg(BQ27425_EXTCMD_BLOCKDATA + 0x13, (uint8 *)&Test[1], 1);
    
      HalSensorWriteReg(BQ27425_EXTCMD_BLOCKDATACONTROL, (uint8 *)&CheckSum[1], 1);  
      HalSensorReadReg(BQ27425_EXTCMD_BLOCKCHECKSUM, (uint8 *)&CheckSum[0], 1);  
    
      HalSensorReadReg(BQ27425_EXTCMD_DCAP, (uint8 *)&val, 2);
      
      ret = (data[1]<<8) + (data[0]);
    
      //bq27425_set_sealmode();
    
      return ret;
    }
    
    /**************************************************************************************************
     * @fn         FuelGauge_set_Block_Data (SET_CFGUPDATE: 0x0013)
     *
     * @brief      Instructs the fuel gauge to set the Flags[CFGUPMODE] bit to 1 and enter
     *             CONFIG UPDATE mode. This command is only available when the fuel gauge 
     *             is UNSEALED. Note: A SOFT_RESET subcommand is typically used to exit 
     *             CONFIG UPDATE mode to resume normal gauging.
     *
     * @return     Pass / Fail
     **************************************************************************************************/
    uint8 FuelGauge_set_Block_Data(void)
    {
      uint8 data[32];
      uint8 offset[2];
      uint8 cntl_data[2];
      uint8 ret;
      uint8 check_sum = 0x79; //0x5F 
      uint8 dtt = 0xff;
      uint32 i ;
    
      data[0] = 0x00;
      data[1] = 0x00;
      data[2] = 0x34;
      data[3] = 0x00;
      data[4] = 0x00;
      data[5] = 0x89;
      data[6] = 0xF8;
      data[7] = 0x81;
      data[8] = 0x0E;
      data[9] = 0xE6;
      data[10] = 0x0E;
      data[11] = 0xA4;
      data[12] = 0x03;
      data[13] = 0xE8;
      data[14] = 0x0E;
      data[15] = 0xD8;
      data[16] = 0x15;
      data[17] = 0xCC;
      data[18] = 0x0C;
      data[19] = 0x80;
      data[20] = 0x00;
      data[21] = 0xC8;
      data[22] = 0x00;
      data[23] = 0x32;
      data[24] = 0x00;
      data[25] = 0x14;
      data[26] = 0x03;
      data[27] = 0xE8;
      data[28] = 0x00;
      data[29] = 0x01;
      data[30] = 0x00;
      data[31] = 0x4B;
    
      offset[0] = 0x52;
      offset[1] = 0x00;
    
      cntl_data[0] = 0x13;
      cntl_data[1] = 0x00;
    
      FuelGauge_set_unsealmode();
      
    //////  /*Access data flash*/
    //////  HalSensorWriteReg(BQ27425_REG_CNTL, &cntl_data[0], 1);
    //////  HalSensorWriteReg(BQ27425_REG_CNTL + 1, &cntl_data[1], 1);
    //////
    //////  /*Prepare to write data*/
    //////  HalSensorWriteReg(BQ27425_EXTCMD_DFCLS, &offset[0], 1);
    //////  HalSensorWriteReg(BQ27425_EXTCMD_DFBLK, &offset[1], 1);
    //////
    //////  /*Write data to cfg*/
    //////  for (i = 0 ; i < 32 ; i++)
    //////  {
    //////    HalSensorWriteReg(BQ27425_EXTCMD_BLOCKDATA + i, (uint8 *)&data[i], 1);
    //////  }
    //////  
    //////  /*check sum*/
    //////  ret = HalSensorWriteReg(BQ27425_EXTCMD_DFBDCS, (uint8 *)&check_sum, 1);
    //////
    //////  bq27425_read_reg_mid(client, 0x61, &dtt);
    //////
    //////  if (ret == 0x00) {
    //////          pr_info("%s[BATT]sucess write data\n", __func__);
    //////          return 1 ;
    //////  } else {
    //////          pr_info("%s[BATT]fail write data\n", __func__);
    //////  }
    
      return 0;
    
    }
    
    
    /*********************************************************************
    *********************************************************************/

  • Could you please also share the files of:

    #include "hal_fuelgauge.h"
    #include "hal_i2c.h"
    #include "hal_sensor.h"
    #include "hal_wait.h"

    and its .c files? Thank you.

  • Jason,

    Unfortunately the bg27510 is different enough from the bq27425 that the sample code does not answer my question. Put simply, I do not understand how to send a command that involves a subcommand. Pg 26 of the bq27425 spec gives the basic structure.
    What I am looking for is a bit more detail. For instance to send a Control() / CONTROL_STATUS/read, I think I would send the following three "bursts."
    S/ADDR/A/1ST byte of COMMAND CODE=0x00/A/Upper byte of CNTL_DATA=0x00/A/P/66us
    S/ADDR/A/2nd byte of COMMAND CODE=0x01/A/Lower byte of CNTL_DATA=0x00/A/P/66us
    S/ADDR/A/No. of Bytes to read=0x02/A/Sr/ADDR/1/A/Returned DATA/A/Returned DATA/N/P/66us

    Is the above representation correct for reading the CONTROL_STATUS register?