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.

BQ35100: Writing to dataflash, capacity

Part Number: BQ35100

Dear forum users,

I have some trouble writing to the data flash of the BQ35100.
Since writing to the config A register works, I'm trying to use the same order and code of Config A to write the battery capacity.

This is the code i'm using to set the battery capacity:

uint8_t writeToDataFlash(uint16_t writeRegister, uint16_t data, uint8_t dataSize )
{
    if ( !dataSize ) return FAIL;

    uint8_t check[2] = { 0 };
    uint16_t checkBuffer = 0;
    uint8_t pData[4] = { 0 };

    pData[0] = writeRegister;
    pData[1] = writeRegister >> 8;
    pData[2] = data >> 8;
    pData[3] = data;

    if ( I2cWriteBuffer( &I2c, c_BQ35100I2CAddr, c_ManufacturerAccessControlAddr, pData, 2 + dataSize ) == FAIL )
    {
        printf( llerror, "writetodataflash: Write register + data failed" );
        return FAIL;
    }
    DelayMs( 100 );

    //calculate checksum and write to MacDataSum + MacDataLen
    for ( uint8_t i = 0; i <= 2+dataSize; i++ )
    {
        checkBuffer += pData[i];
    }
    check[0] = ~checkBuffer;
    check[2] = 4 + dataSize;

    //The next write function auto increments!
    I2cWriteBuffer( &I2c, c_BQ35100I2CAddr, c_ManufacturerAccessControlDataSumAddr, check, 2);


    DelayMs( 100 );
    return SUCCESS;
}

The data I want to send is the capacity of 17Ah (0x4268) to register 0x41FE:

 writeToDataFlash(0x41fe, 0x4268, 2);  

Reading the capacity always gives the default value, which is 2200mAh.

What am I doing wrong?

Thanks for helping me out!

Greets Jorg

  • Hello Jorg,

    Please follow the gas gauge communications applications note. There is an example of how to do that. You are using direct writes, we use subclass/offset for the bq35100.

  • It looks like you use the wrong index for check[]:

        check[0] = ~checkBuffer;
        check[2] = 4 + dataSize;

    Why is the second index 2 and not 1?

        uint8_t check[2] = { 0 };

    "check" is an uint8_t array of size 2 so the maximum allowable index is 1, not 2.

  • Hello Kang Kang,

    I'm actually trying to use the TRM, because slua801 is not written for the BQ35100.
    It is very confusing, as the subclasses are different for both devices.

    In the TRM (sluubh1c) it says the following:

    12.1.1 Write to DF Example

    Assume data1 is located at address 0x4000 and data2 is located at address 0x4002, and both data1 and data2 are U2 type. To update data1 and data2 to 0x1234 and 0x5678, respectively, do the following:
    • Write 0x00 0x40 (DF address in little endian format) to ManufacturerAccessControl(0x3E, 0x3F).
    • Write 0x12 0x34 0x56 0x78 (data in big endian format) to MACData(0x40–0x43). The writes to ManufacturerAccessControl() and MACData() can be performed in a single transaction.
    • Write 0xAB (complement of the sum of the ManufacturerAccessControl() and MACData() bytes) to MACDataSum(0x60).
    • Write 0x08 (4 + length of MACData() bytes) to MACDataLen(0x61).
    • The data flash write will execute when the MACDataSum() and MACDataLen() are written in order (word write) and are verified to be correct.

    In slua801 it says the following, which seems the same?:

    4.2 Addressing Data Memory

    Reading and writing data memory follows this sequence:
    1. Write the subclass number to the subclass command (0x3E).
    2. Write the data block number to the data block command (0x3F).
    3. Read or write the data block (up to 32 bytes) starting at block data command (0x40).
    4. (Write only): Calculate the check sum and write it to the check sum command (0x60).

    Which means I have the wrong subclass for the battery capacity?

    Thank you for the help!

    ====================================

    uint8_t writeToDataFlash(uint16_t writeRegister, uint16_t data, uint8_t dataSize )
    {
        if ( !dataSize ) return FAIL;
    
        uint8_t check[2] = { 0 };
        uint16_t checkBuffer = 0;
        uint8_t pData[2] = { 0 };
    
        pData[0] = writeRegister >> 8;
        pData[1] = writeRegister;
    
    
    
        //subclass number 41 to 0x3e and datablock command 0xFE to 0x3F.
        if ( I2cWriteBuffer( &I2c, c_BQ35100I2CAddr, c_ManufacturerAccessControlAddr, pData, 2) == FAIL )
        {
            printf( llerror, "writetodataflash: manufactureraccescontroladdr write failed" );
            return FAIL;
        }
        DelayMs( 100 );
    
    
        pData[0] = data;                    //data in big endian order
        pData[1] = data >> 8;
    
        //writing data starting with data block command starting with block data command (0x40)
        if (I2cWriteBuffer( &I2c, c_BQ35100I2CAddr, c_ManufacturerAccessControlDataAddr, pData, 2  ) == FAIL )
        {
            printf( llerror, "writetodataflash: data write failed" );
            return FAIL;
        }
        DelayMs( 100 );
    
    
        //calculate checksum and write to MacDataSum + MacDataLen
        for ( uint8_t i = 0; i <= 2+dataSize; i++ )
        {
            checkBuffer += pData[i];
        }
        check[0] = ~checkBuffer;
        check[1] = 4 + dataSize;
    
        //The next write function auto increments!
        if (I2cWriteBuffer( &I2c, c_BQ35100I2CAddr, c_ManufacturerAccessControlDataSumAddr, check, 2) == FAIL)
        {
            abelDebugMessage( llerror, "writetodataflash: Write sum + len failed" );
            return FAIL;
        }
        DelayMs( 100 );
        return SUCCESS;
    }

    Still no succes...

  • Hello Dominik,

    Oops... I changed it to check[1].
    Unfortunately it still wont´t work.

    Thanks for the help! 

  • Hey Dominik,

    For some reason, the first time I fixed the wrong index it still did not work, but now after trying a lot of codes and trying the first code again it does!
    For people with the same problem, using my first attempt works "if you use the right check index".

    Thank you again!