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.

BQ27Z561: Problem with write and read standard command using i2c

Part Number: BQ27Z561

I have used slua801 to get response of standard command.

As per SLUUBO7. we need to write 2-byte standard commands

write(Fd_file, pData, 2);


But below function write one byte command and though it respond correct data.

Why this respond correctly ? i want to know where is mistake ?


int FuelCheck::gauge_read(int &Fd_file, unsigned char nRegister, unsigned char  *pData, unsigned char nLength)
{
    int n = 0;

    if (nLength< 1)
        return 0;

    pData[0]= nRegister;

    n = write(Fd_file, pData, 1);
#if BOARD
    if(n == -1)
    {
#ifdef QDEBUG_ENABLE
        pMainApp.ObjSettings.DebugStation("Failed to write fuel gauge register address");
#endif
    }
#endif

    n = read(Fd_file, pData, nLength);

    usleep(200);

#if BOARD
    if((n == -1) || (n == 0))
    {
#ifdef QDEBUG_ENABLE
        pMainApp.ObjSettings.DebugStation("Failed to read fuel gauge register address");
#endif
    }
#endif

    return n;
}
  • Mangal,

    This is because the commands in the gauge are register addresses. Each command is two bytes long because generally each data value returned need two bytes to provide the correct information. When reading from the gauge the function tells the gauge the starting address from the device to read from (which is one byte, and the lowest address in the two-byte command), and then reads two bytes.

  • Means to read data i need to 

    1] write starting address of command 

    2] read 2 byte data

    and to write data at register address i need to

    1] write register address with data

    Am i correct ? is this right for any command read and write ?

  • Mangal,

    Yes, this is correct.

  • Can you let me why below 2 byte register written in example ?

    To read back the written data, you need to trigger the "Random address read" sequence (decribed in figure 29 of DS10925 as well).

    This can be achieved using an ioctl(filehande, I2C_RDWR, &payload);

    payload being an i2c_rdwr_ioctl_data structure with 2 partial messages:

    • a write of 2 bytes for the memory address
    • Chained with a read of 1 byte (without re-presenting the device address)

     

    Code extracted from Drivers/BSP/Linux/st25dv-i2c_linux.c

     struct i2c_msg messages[2] = {

        {

          .addr = DevAddr >>1,

          .buf = regAddr,

          .len = 2,

          .flags = 0,

        },

        {

          .addr = DevAddr >>1,

          .buf = pData,

          .len = Length,

          .flags = I2C_M_RD | I2C_M_NOSTART,

        }

      };

     

     struct i2c_rdwr_ioctl_data payload = {

        .msgs = messages,

        .nmsgs = 2,

      };

     

      ret = ioctl(filehandle, I2C_RDWR, &payload);

      if (ret < 0) {

        ret = -errno;

        printf("\r\nError %d while reading @%X (devAddr=%X)\r\n", ret,Reg,DevAddr);

        return ret;

      }

  • Mangal,

    I'm not familiar with the device since it's not our product, but I would guess that the memory addresses are 2 bytes long which is why you need to write two bytes for the address. The BQ27Z561 only needs one byte for the address.

  • Dear Albert,         I want to know from where i can find bq27z561 memory address are of 1 byte long ?                                                             

  • Mangal,

    This is found in the TRM. The addresses are formatted as 0xNN, as opposed to 0xNNNN (where the N's are any hexadecimal digit). The former implies that the addresses are one byte long, and the latter implies that they're two bytes long.