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.

BQ4050: ManufacturerAccess() and ManufacturerBlockAccess()

Part Number: BQ4050
Other Parts Discussed in Thread: BQSTUDIO

Hi,

I have two questions about the TRM of BQ4050 in page 69.

1. Are these typos? I guess we are describing ManufacturerAccess()(0X00) in this paragraph.

2. In the example above, by writing, data sent=00 03 is not in Little Endian. But data read=00 01, is it correct?

In conclusion, my understanding is:

By using ManufacturerBlockAccess(), the command is 0x44, data sent and read are all in Little Endian,

By using ManufacturerAccess(), the command is 0x00, data sent are not in Little Endian, and data read are in Little Endian.

Is it correct?

  • And my customer read DeviceName, LifetimeDataBlock with ManufacturerBlockAccess().

    But the result is not stable, sometimes the result is correct, but sometimes the result is partial correct, with FFFF in the later part of the data read back.

    What's the correct code to read this data?

  • Hi Howard,

    Yes, that looks to be a typo.

    Please disable the scanning when reading the data. Scanning will affect data read with manufacturerblockaccess.

  • Batt,

    neither me nor the customer knows what scanning is. Could you please be more specific?

    The customer's code reading device name and manufacturer name is shown below:

    ////////////////////////////////////////////////////
        memset(buf, 0, sizeof(buf));
        b_len = 8;
        ret = bq4050_i2c_access_by_block(1, gp_bq4050_info->regs[bq4050_reg_mname], 
            &b_len, buf);
        
        if(ret != GAUGE_IC_RET_OK)
            return ret;
    
        if(debug_notify)
            __printk("Mname:%d,%s\r\n", b_len, buf);
    
        memset(buf, 0, sizeof(buf));
        b_len = 20;
        ret = bq4050_i2c_access_by_block(1, gp_bq4050_info->regs[bq4050_reg_dname], 
            &b_len, buf);
        
        if(ret != GAUGE_IC_RET_OK)
            return ret;
    
        if(debug_notify)
            __printk("Dname:%d,%s\r\n", b_len,buf);
    //////////////////////////////////////////////////////
    
    /*Below are the function definition called by the code above.*/
    
    static int bq4050_i2c_access_by_block(unsigned char w_r, unsigned char cmd, unsigned char *len, unsigned char *dat)
    {
        int ret;
        unsigned char buf[128*2+2];
    
        if(gp_bq4050_info == NULL)
            return GAUGE_IC_RET_NO_INITED;
        /*
        if(dat == NULL || *len <= 0 )
            return GAUGE_IC_RET_PARAM_ERR; */
    
        memset(buf, 0, sizeof(buf));
        
        if(w_r)//Read
        {
        
            simple_lock();
            ret = SimI2CReadDataFromAddr(&gp_bq4050_info->sim_i2c_hdl, gp_bq4050_info->slave_addr, cmd, 
                buf, *len+1);//Containing a byte indicating the number of data
            simple_unlock();
    
            gp_bq4050_info->inner_err = ret;
    
            if(debug_notify)
                __printk("$$$R:%d,%d,(%x:%x:%x:%x:%x:%x:%x)\r\n", ret, *len+1, 
                    buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[*len]);
    
            if(ret != *len+1)
                return GAUGE_IC_RET_READ_ERR;
    
            memcpy(dat, &buf[1], buf[0]);
            *len = buf[0];
    
        }
        else
        {
            buf[0] = *len;
            memcpy(&buf[1], dat,  *len);
    
            simple_lock();
            ret = SimI2CWriteDataToAddr(&gp_bq4050_info->sim_i2c_hdl, gp_bq4050_info->slave_addr, cmd, 
                buf, *len+1);
            simple_unlock();
             
            gp_bq4050_info->inner_err = ret;
    
            if(debug_notify)
                __printk("$$$W:%d,%d,(%x:%x:%x:%x:%x:%x:%x)\r\n", ret, *len+1, 
                    buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[*len]);
    
            if(ret != *len+1)
                return GAUGE_IC_RET_WRITE_ERR;
            
        }
        return GAUGE_IC_RET_OK;
    }
    

    Below is the result: we can see that the result we get are different between two times read.

  • Hi Howard,

    I was talking about the customer using bqstudio. In that you have the option of scanning registers from the register tab while communicating with the gauge on the advanced comm tab. Any scan of the registers will change data in the manufacturer access registers, therefore overwriting commands from the advanced comm tab. That's what I meant.

    Please do not overload the i2c bus with comms. You can read it at 1Hz. That's one way to avoid comm errors.

  • The IIC frequency is 33kHz and the reading interval is already longer than 1seconds.

    When they read data like voltage/temperature, the result is always correct.

    But when they read DeviceName/ManufacturerName, the result is unstable.

  • I have tried this with bqstudio and I haven't been able to reproduce the failure. The results here are always consistent. If they are reading other registers on the i2c bus and then reading manufacturer access the last command will overwrite the register.