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.

some questions about Bq34z110

Other Parts Discussed in Thread: BQ34Z110, BQEVSW

hello everyone ,

When I use STM32F103 chip communicate with Bq34z110 chip through i2c , it comes a strange phenomenon: I get different datas from address 0x00 and 0x01 , and these data is changeing every few minutes,and the data from address 0x00 is always as same as the data from  address 0x01. I follow the step in page 28 of slusb55b.pdf, here is the waveform about i2c communication . Is there something wrong with my i2c communication ?

  • Stefan,

    Your process looks correct. Could you have some other polling for the bq34z110 on occurring on the bus? Data from the Control register can change as the firmware is running. The firmware uses this register in addition to it being the port for the Control Subcommands. Here is a document that covers communications to the device and it has an example of reading the ChemID. Have you tried using the EV2300 and bqEVSW to read the ChemID?

    Tom

    1641.bq34z100 DF access.pdf

  • Tom,
    I have used EV2300, and it's working,and I have read the document you provided . In the read mode, after send CMD(0xAB) there's no ack response , do you know why ?
  • There should be an ACK after the AB address and no ACK after the last data byte returned. I see this in the waveforms that you sent. Does the correct data get returned when using the EV2300? (It was not clear which case was not working in the previous response.)
  • Tom,

    I use EV2300 communicate with bq34z110 again ,and the data get returned correctly, I'm sure there is something wrong with my I2C interface, I put my code here, could you please check the logical steps for me?

    Is there any rule about SCL and SDA when there are in idle condition ?

    I2C.c
    void IIC_Start(void)
    {
    	SDA_OUT(); 
        
    	IIC_SDA_1;
     	Delay_us(i2c_delayus_num);
    	
    	IIC_SCL_1;
    	Delay_us(i2c_delayus_num);
    	
    	IIC_SDA_0;
     	Delay_us(i2c_delayus_num);
    	
    	IIC_SCL_0;
    	Delay_us(i2c_delayus_num);
    }	  
    
    void IIC_Stop(void)
    {
    	SDA_OUT();
    
    	IIC_SCL_0;
    	IIC_SDA_0;
     	Delay_us(i2c_delayus_num);
    	
    	IIC_SCL_1;
    	Delay_us(i2c_delayus_num);
    	
    	IIC_SDA_1;
    	Delay_us(i2c_delayus_num*2);
    }
     
    void IIC_Send_Byte(u8 txd)
    {                        
    	u8 t,ack=0,temp; 
    	
    	SDA_OUT(); 	    
    	IIC_SCL_0;
    	temp=txd;
    	t=0x08;
    	while(t!=0)
    	{
    		if (temp & 0x80)                        
    			IIC_SDA_1;                               
    		else
    			IIC_SDA_0;                              
    		Delay_us(i2c_delayus_num);                          
    		IIC_SCL_1;                                 
    		Delay_us(i2c_delayus_num);            
    		temp = (temp << 1);             
    		IIC_SCL_0;                           
    		t = (t - 1);
    	}
    	IIC_SDA_0;
    	Delay_us(i2c_delayus_num);
    	IIC_Ack();
    } 
    
    u8 IIC_Read_Byte(unsigned char ack)
    {
    	unsigned char i,receive=0;
    	
    	SDA_IN();
    	for(i=0;i<8;i++ )
    	{
    		IIC_SCL_0; 
    		Delay_us(i2c_delayus_num);
    		IIC_SCL_1;
    		receive<<=1;
    		if(READ_SDA)receive++;   
    		Delay_us(i2c_delayus_num); 
    	}
    	SDA_OUT();
    	if(ack)	
    		IIC_SDA_0;
    	else
    		IIC_SDA_1;
    	IIC_SCL_0; 
    	Delay_us(i2c_delayus_num);		
    	IIC_SCL_1; 
    	Delay_us(i2c_delayus_num);	
    	IIC_SCL_0; 
    	IIC_SDA_1;
    	Delay_us(i2c_delayus_num);
    	return receive;
    }
    
    u8 IIC_Ack(void)
    {
    	u8 ack=0;
    	
    	IIC_SCL_1;
    	Delay_us(i2c_delayus_num);
    	IIC_SCL_0;
    	Delay_us(i2c_delayus_num/2);
    	SDA_IN();
    	ack=READ_SDA;
    	Delay_us(i2c_delayus_num/4);
    	if (ack)                      
    		return (1);
    	else
    		return (0);
    }
    	    
    void IIC_NAck(void)
    {
    	SDA_OUT();
    	IIC_SCL_0;
    	IIC_SDA_0;
    	Delay_us(i2c_delayus_num);
    	IIC_SCL_1;
    	IIC_SDA_1;
    	Delay_us(i2c_delayus_num);
    	IIC_SCL_0;
    	Delay_us(i2c_delayus_num/2);
    	IIC_SDA_0;
    }		
    u8 I2C_ReadData(u8 command)  
    {                   
    	u8 temp=0;                                                                                   
    
    	IIC_Start();              //S	
    	IIC_Send_Byte(0xaa);      //ADDR[6:0][0](A) 
    	IIC_Send_Byte(command);   //CMD[7:0](A)
    	IIC_Stop();               //Sr_p
    	IIC_Start();              //Sr_S
    	IIC_Send_Byte(0xab);      //ADDR[6:0][1](A)
    	temp=IIC_Read_Byte(1);    //DATA[7:0]	
    //	IIC_NAck();
    	IIC_Stop();
    	 
    	return temp;  
    } 
      
    void I2C_WriteData(u8 command, u8 DataToWrite)  
    {                                                                                              
    	IIC_Start();                 //S
    	IIC_Send_Byte(0xaa);         //ADDR[6:0][0](A)
    	IIC_Send_Byte(command);      //CMD[7:0](A)
    	IIC_Send_Byte(DataToWrite);  //DATA[7:0](A)
    //	IIC_NAck();
    	IIC_Stop();                  //P 
    	Delay_ms(1);       
    }

  • Stefan,

    I am not a programmer, but I looked at your code. The read and write routines at the end of the file look correct. I would just have to compare the waveforms from that controller to those from the EV2300.

    Tom

  • Tom,

    I can read data from the address of 0x7e / 0x7f, which is 0x00 / 0x01 . But I can't read the correct data form 0x00 / 0x01 after I write 0x00/0x08, the data always be 0x05, I use EV2300 to read it ,and it return 0x05 either .

    Why should keep SCL and SDA low for a while ,after send 0xAB,and also after read the first data?

  • The gauge will hold the clock low until it is ready to respond. I2C controllers are able to support clock stretching. This will lead to communications problems, if your controller cannot support it.
  • Tom,
    Thanks for your reply , now I can read Voltage() from address:0x08/0x09 , and Internal_Temp() from address :0x2a/0x2b , but how can I initialise the chip ?

  • The procedure is the same to read all three parameters and I verified this on the bench. Have you checked to see whether you are able to read the Temperature() using the EV2300?

  • Tom,
    Now I am trying to change some settings in the data flash and there is a question.
    Change PackConfiguration() to 0x951:
    The steps :
    1. Read PackConfiguration() : 0x961 .
    2. Write 0x00 to the BlockDataControl() command .
    3. Write 64(subclass ID) to the DataFlashClass() command .
    4. Write 0x00(Offset) to the DataFlashBlock() command .
    5. Read BlockDataCheckSum() , Authenticate()/BlockData() , calculate new CheckSum = old CheckSum + BlockData from read - BlockData to write .
    6. Write 0x09 to command 0x40 and 0x51 to command 0x41.
    7. Write new CheckSum to the BlockDataCheckSum() command .
    8. Read PackConfiguration() , here is the question , I read it but it is not the data I set .And I delay for a while, it is still wrong .
    9. Read PackConfiguration() again , the data is correct , !!? , I am confused, did I do something wrong ?
  • Here are the steps that I used :

    1. Read PackConfiguration() : 0x961 .
    2. Write 0x00 to 61
    3. Write 40H (64 subclass ID) to 3E
    4. Write 0x00 (Offset) to 3F
    5. Read 20 bytes of data from 40
    6. Read the checksum from 60. I read 97H.
    7. Calculate new checksum. I calculated it to be A7.
    8. Write 0x00 to 61
    9. Write 40H (64 subclass ID) to 3E
    10. Write 0x00(Offset) to 3F
    11. Write 20 bytes of data to 40. I changed the Pack Cfg A from 961 to 951
    12. Write A7H to 60.
    13. Read the Pack Cfg A and it was 951.

  • Tom,

    I follow the steps you provide , and I'm sure the data has been writen to the flash , but I can not read data from Pack configuration() with reading data from 0x60 , and the data is correct after third read .

    Another question I want set Number of Serious cells to 0x0c , so I change offset to 7 , am I right ?

  • Tom,
    I can not change the data of Number of Serious cells, can you show me the steps?
  • Stefan,

    You do not read the Pack Configuration register from 0x60. That is the register where you write the checksum. There is an Extended I2C command available to read the Pack Configuration register. See page 35 of the datasheet. I do not understand the comment about changing the "Number of Serious cells to 0x0c , so I change offset to 7" You can use the bqEVSW to change the Number of Series cells in the Data Flash. Just enter the number that you desire and press <enter>. The value should change and you will need to reset the device for it to take effect.

    Tom

  • Tom,
    if the flash data larger than the 32-byte block size, in my understanding,Write 0x01 (Offset) to 3F,and the exceed data should write from 0x40 , right ?
  • Yes, data is stored in 32 byte pages. You select the page that you want to access with the Offset (3F) and 32 bytes at 40 will get transferred to that block.
  • Tom ,

    In bqEVSW, there's a Calibrate mode with 4 steps that we can calibrate accuracy of Bq34z110 , and I want to do the calibration process by my MCU.

    1. Write 0x0081 to command Control() .

    2. set number of series cells (12), set VOLTSEL bit of configuration Register Bits to 1 .

    3.?

    so can you show me what's the next steps?

    And I want to know the instantaneous current ,after I write 0x0018 to command Control() , and how can I read it , which command should I read ?

  • Stefan,

    There is a Host side calibration document that was published by another group, but it is applicable to the bq34z110. It provides examples and code and it can be downloaded from the TI website. Search for SLUA640A. There is an error on page 4.The Analog Conversion Counter is at 0x79.

    Tom

  • Tom,

    In Calbrate mode , pack current calibation , how to calculate the CC Gain and CC Delta?

    I read CC Gain from data flash :0x82 0x4 0x78 0x8c(high to low), and  CC Delta :0x96 0x16 0xb8 0xee(high to low). 

     The bqEVSW shows:CC Gain is 2.304, CC Delta is 2.299.

    How bqEVSW translates 0x82 0x4 0x78 0x8c(high to low) into 2.304 and translates 0x96 0x16 0xb8 0xee(high to low) into 2.299 ?

    And even I  calculate the CC Gain and CC Delta , how to translate them to 4 bytes in data flash ?

    By the way , I try to translate them by C language logic,but faled.

  • There are conversion factors for these parameters on page 42 of the datasheet.