SLUAA11B February   2020  – August 2021 BQ769142 , BQ76922 , BQ76942 , BQ76952

 

  1.   Trademarks
  2. 1Direct Commands
    1. 1.1 Alarm Enable - 0x66
    2. 1.2 Cell 1 Voltage - 0x14
    3. 1.3 Internal Temperature - 0x68
    4. 1.4 CC2 Current - 0x3A
  3. 2Subcommands
    1. 2.1 DEVICE_NUMBER - 0x0001
    2. 2.2 MANUFACTURING STATUS - 0x0057
    3. 2.3 FET_ENABLE - 0x0022
    4. 2.4 RESET - 0x0012
  4. 3Reading and Writing RAM Registers
    1. 3.1 Read 'Enabled Protections A'
    2. 3.2 Enter CONFIG_UPDATE Mode
    3. 3.3 Write 'Enabled Protections A'
    4. 3.4 Write 'VCell Mode'
    5. 3.5 Exit CONFIG_UPDATE Mode
  5. 4I2C With CRC
  6. 5SPI With CRC Examples
    1. 5.1 Direct Command Example: Alarm Enable - 0x66
    2. 5.2 Direct Command Example: Cell 1 Voltage - 0x14
    3. 5.3 Subcommand Example: Device Number - 0x0001
    4. 5.4 Subcommand Example: FET_ENABLE - 0x0022
    5. 5.5 Subcommand Example: RESET - 0x0012
    6. 5.6 RAM Register Read Example: Enabled Protections A
    7. 5.7 RAM Register Write Example: Enabled Protections A
  7. 6Simple Code Examples
  8. 7References
  9. 8Revision History

Simple Code Examples

The following example code is written in Python and designed to communicate to the BQ769x2 device from a PC through an EV2400 module or through the USB connector on the BQ76942 or BQ76952 Evaluation Module. The code shows the creation of simple I2C Read and Write functions, a DataRAM_Read function, (which can also be used to execute subcommands since these follow the same format), and a DataRAM_Write function that shows the calculation of checksum and length. The main section of the code goes through all of the examples covered in the first three sections of this document.

This simple code example is intended to illustrate the basic command structure for I2C commands. Microcontroller code examples are also available for I2C and SPI. The link to the microcontroller code is provided in Section 7.

'''
/* BQ769x2 example Program demonstrates examples for direct commands, subcommands, and writing / reading from device RAM.
'''
import pywinusb
import bqcomm
import sys
import time
from time import sleep
import sets
I2C_ADDR = 0x10  # BQ769x2 slave address
numCells = 10    # Set to 10 for BQ76942
####################################################
## Check to see if EV2400 is connected
####################################################
try:
    a = bqcomm.Adapter()  # This will use the first found Aardvark or EV2400
except:
    print "No EV2400 Available"
    sys.exit(1)
######################################################
## Define some command functions
######################################################
def I2C_Read(device_addr, reg_addr, length):
    '''
    Uses global I2C address and returns value read
    '''
    try:
        value = a.i2c_read_block(device_addr, reg_addr, length)
    except:
        print "Nack received"
        return
    return value
def I2C_Write(device_addr, reg_addr, block):
    '''
    Uses global I2C address
    '''
    try:
        a.i2c_write_block(device_addr, reg_addr, block)
    except:
        print "Nack received"
    return 
def DataRAM_Read(addr, length):
    '''
    Write address location to 0x3E and read back from 0x40
    Used to read configuration registers and for subcommands
    '''
    addressBlock = [(addr%256), (addr/256)]
    I2C_Write(I2C_ADDR, 0x3E, addressBlock)
    value = I2C_Read(I2C_ADDR, 0x40,length)
    return value
def DataRAM_Write(addr, block):
    '''
    Write address location to 0x3E and Checksum,length to 0x60
    Used to write configuration registers
    '''
    addressBlock = [(addr%256), (addr/256)]
    wholeBlock = addressBlock + block
    I2C_Write(I2C_ADDR, 0x3E, wholeBlock)             # Write Data Block
    # Write Data Checksum and length to 0x60, required for RAM writes
    I2C_Write(I2C_ADDR, 0x60, [~sum(wholeBlock) & 0xff, len(wholeBlock)+2])
    return        
def crc8(b,key):
    crc = 0
    ptr = 0
    for j in range(len(b),0,-1):
        for k in range(8):
            i = 128 / (2**k)
            if ((crc & 0x80) != 0):
                crc = crc * 2
                crc = crc ^ key
            else:
                crc = crc * 2
            if ((b[ptr] & i) != 0):
                crc = crc ^ key
        ptr = ptr + 1
    return crc
##########################################
#  Start of Main Script
##########################################
################ Direct Command Examples ################
#Write Alarm Enable to 0xF082
I2C_Write(I2C_ADDR, 0x66, [0x82, 0xF0])
#Read Voltage on Cell #1
result = I2C_Read(I2C_ADDR, 0x14, 2)
print "Cell 1 = ", (result[1]*256 + result[0]), " mV"
#Read Internal Temperature
result = I2C_Read(I2C_ADDR, 0x68, 2)
print "Internal Temp = ", ((result[1]*256 + result[0])/10 - 273.15), "degrees C"
#Read CC2 Current Measurement
result = I2C_Read(I2C_ADDR, 0x3A, 2)
print "CC2 = ", (result[1]*256 + result[0]), " mA"
################ Subcommand Examples ################
#Read Device Number
b = DataRAM_Read(0x0001,6)
print "Device_Number = " '{0:04X}'.format(b[1]*256+b[0])
#Read Manufacturing Status
b = DataRAM_Read(0x0057,2)
print "Manufacturing Status = " '{0:04X}'.format(b[0]+256*b[1])
## Command-only Subcomands ##
#FET_ENABLE
I2C_Write(I2C_ADDR, 0x3E, [0x22, 0x00])
#RESET - returns device to default settings
I2C_Write(I2C_ADDR, 0x3E, [0x12, 0x00])
sleep(1)
############ Reading and Writing to RAM Registers ##########
# Read 'Enabled Protections A' RAM register 0x9261
b = DataRAM_Read(0x9261,1)
print "Enabled Protections A = 0x" '{0:02X}'.format(b[0])
#Set CONFIG_UPDATE Mode (RAM registers should be written while in
#CONFIG_UPDATE mode and will take effect after exiting CONFIG_UPDATE mode
I2C_Write(I2C_ADDR, 0x3E, [0x90, 0x00])
#Write to 'Enabled Protections A' RAM register to enable CUV protection
DataRAM_Write(0x9261, [0x8C])
#Write to 'VCell Mode' RAM register to configure for a 9-cell battery
DataRAM_Write(0x9304, [0x03, 0x7f])
#Exit CONFIG_UPDATE Mode
I2C_Write(I2C_ADDR, 0x3E, [0x92, 0x00])
# CRC8 Example Calculation
TestValue = [0x10, 0x14, 0x11, 0x68]
crcKey = 0x107
check = 0xff & crc8(TestValue,crcKey)
print "crc8 check = 0x" '{0:02X}'.format(check)

The output from running the example Python script on a BQ76942 Evaluation Module follows.

Cell 1 =  3700  mV
Internal Temp =  25.05 degrees C
CC2 = 7  mA
Device_Number = 7694
Manufacturing Status = 0040
Enabled Protections A = 0x88
crc8 check = 0x33