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.

BQ34Z100 - Data Flash read acts odd. Specification does not match

Dear Support,

I see strange behaviour when reading out the Data Flash.

Please see the screenshots below. What I'd like to show is an example from reading Subclass 80 (0x50) aka. IT Cfg.

Data Flash Class is set to 0x50, Offset is set to 0.

You see 33 bytes that where read from the gasgauge (32 bytes + Checksum byte). The first byte does not react on changes, made by the EVM Software (when manipulating "Load Select", but the Checksum updates correctly.

The second byte "Load Mode" reacts to changes correctly, means that when I change the Value of Load Mode via the EVM software, I see the changing bit also in the debugger of my MCU.

I verified, that reading from address 0x40 (start of Data Flash Block) gives the same result in the EVM-software (i2C-read).

I even tried the same software on a second EVM-module I bought, but I get the same strange behaviout. I am out of ideas! Need help urgently! Thanks a lot

 

  • After two days some of the problems are solved. Thanks to some other comment from a user I investigated that a timing issue caused the problem.

    I am very dissatisfied about the quality of the manual. I hat to read the manual of other gas gauges to find out more about this issue! Here's some of my code used on STM32F10x (STOM32F107VC) to read, modify and write a data flash page.

    What I still did not manage is to read out the Device Type (Subcommand 0001). Maybe someone can point out how to...Thanks and best regards

    Tobias

    THE CODE BELOW WORKS ON STM32F10x!!

    /* excerpt from cyclic task */

    /* Lot of wait cycles, thus very unoptimized but working after two days of struggel */

               

                GG_Send_Byte(GG_BlockDataControl,0x00); // Transfer data flash location(s) to the command register

                for (Dummy1=0;Dummy1<=0xfffa;Dummy1++);  

                GG_Send_Byte(GG_DataFlashClass,BSW_C_Dataflash_Class); // Select Data Flash Class

                for (Dummy1=0;Dummy1<=0xfffa;Dummy1++);  

                GG_Send_Byte(GG_DataFlashBlock,BSW_C_Dataflash_Block); // Select Data Flash Offset within Class

                for (Dummy1=0;Dummy1<=0xfffa;Dummy1++);  

                GG_Receive_nBytes(GG_Authentificate_or_BlockData, 33, BSW_M_GG_RX_Data_Flash_Block); // Read 32Bytes + Offset

                for (Dummy1=0;Dummy1<=0xfffa;Dummy1++);  

     

                if (BSW_C_S_WriteBlockData)      

                {

                            BSW_C_S_WriteBlockData=0;       

                            for (CC=0;CC<=31;CC++)    

                            {

                                        GG_Send_Byte(GG_Authentificate_or_BlockData+CC,BSW_M_GG_RX_Data_Flash_Block[CC]);

                                       for (Dummy1=0;Dummy1<=0xff;Dummy1++);

                            }

                            for (Dummy1=0;Dummy1<=0xfffa;Dummy1++);  

                            GG_Receive_nBytes(GG_Authentificate_or_BlockData, 32, BSW_M_GG_RX_Data_Flash_Block);

                            for (Dummy1=0;Dummy1<=0xfffa;Dummy1++);

                            BSW_C_BlockData_Checksum=GG_CalculateCheckSum(BSW_M_GG_RX_Data_Flash_Block);

     

                            for (Dummy1=0;Dummy1<=0xfffa;Dummy1++);

                            GG_Send_Byte(GG_BlockDataCheckSum,BSW_C_BlockData_Checksum);    

                            for (Dummy1=0;Dummy1<=0xfffa;Dummy1++);

                }

               

     

               

     

    /**********************************************/

    /*  Receive n Bytes from Gasggauge                                      */

    /**********************************************/

     

    void GG_Receive_nBytes(UInt8 Address, UInt8 NumberOfBytes, UInt8* RxArray)

    {         

                volatile UInt8 I2C_RX_Buffer[33];

                volatile UInt8 I2C_TX_Buffer[33];

                Enable_I2C_GPIO();

     

                I2C_TX_Buffer[0] = Address;

     

                I2C_Master_BufferWrite(I2C1, I2C_TX_Buffer,1,Polling, 0xAA);

                I2C_Master_BufferRead(I2C1,RxArray,NumberOfBytes,Polling, 0xAB);

     

     

                Disable_I2C_GPIO();

     

    }         

               

               

    /**********************************************/

    /*  Send Command 1 Byte */

    /**********************************************/

    UInt16 GG_Send_Byte(UInt8 Address, UInt8 Value)

    {         

                volatile UInt8 I2C_RX_Buffer[33];

                volatile UInt8 I2C_TX_Buffer[33];

                UInt16 Return_Value=0;

               

                Enable_I2C_GPIO();

     

                I2C_TX_Buffer[0] = Address;

                I2C_TX_Buffer[1] = Value;

                I2C_Master_BufferWrite(I2C1, I2C_TX_Buffer,2,Polling, 0xAA);

     

                Disable_I2C_GPIO();

     

                return Return_Value;

    }

               

               

               

    /***************************************************

    1. Add all 32 bytes in a data row together.

    2. Do an "integer divide" by 256 on the sum to get the most significant byte of the result.

    3. Subtract out the most significant byte from the total sum, leaving only the least significant byte

    4. Invert the result in #3, which can be done by subtracting it from 255.

    ********************************************************/

    UInt8 GG_CalculateCheckSum(UInt8 * Dataflash_Block)

    {

                int i=0;

                static UInt16 sum;

                static UInt16 MSB;

                static UInt16 LSB;

                sum=0;

                LSB=0;

                MSB=0;

                for (i=0;i<=31;i=i++)

                {

                            sum=sum+Dataflash_Block[i];

                }

                LSB=(UInt8)(sum);

                sum=LSB;

                sum=255-sum;

                return (UInt8)sum;

    }

  • This was already on the forum, but repeated here for your convenience:

     

    READING SUBCOMMANDS IN bq34Z100

    Here is how you can read the instantaneous current. Its a four step process - two byte writes, followed by two byte reads. In I2C, it all comes down to bytes.

    1. Send the least significant subcommand byte to location 0. For example:

    lerror = I2C_Write_Byte (0, 0x18, 0xAA)  // Where first arg is the address, second is the data, third is the device address.

    2. Send the most significant subcommand byte to location 1:

    lerror = I2C_Write_Byte (1, 0, 0xAA)

    3. Read the least significant byte of the response:

    lerror = I2C_Read_Byte (0, yLS, 0xAA)  // yLS is the least significant byte of the returned current in mA.

    4. Read the most significant byte of the response:

    lerror = I2C_Read_Byte (1, yMS, 0xAA)  //  Note that the result is a bipolar two's complement number.

    Using a different order of operation can cause erroneous results.

     

  • Thanks to some other comment from a user I investigated that a timing issue caused the problem. . . .Could you please post the link to this post that you are referring to 


    Regards

    Abhay