Quantcast
Channel: Power management forum - Recent Threads
Viewing all articles
Browse latest Browse all 35901

Bq34z110: Transfer data to flash problem using micro controller in C, followed instructions SLUA66

$
0
0

After many hours of trying, I still cannot change the bz34z110 flash content .

The idea was to start with something easy like changing the serial number, as one can read it back to verify that the flash has indeed changed. I reset the hardware etc, but the flash always stays the same.

(Brand new bz34z110, never programmed before, as from the factory)

Reading subclass 48  (serial number at 15 & 16)

 subclass ? 48
( 48)0x30
  0164   00B0   070A   F6D0   0CFE   3100   0000   0100   0000   8403   A00F   401F   70FE   085A   09CA   0D92
   356    176   1802  63184   3326  12544      0    256      0  33795  40975  16415  28926   2138   2506   3474
 64 01  B0 00  0A 07  D0 F6  FE 0C  00 31  00 00  00 01  00 00  03 84  0F A0  1F 40  FE 70  5A 08  CA 09  92 0D Sum32=0x08FF

 SUM 32 Bytes     =0x08FF
 bq_read_checksum =0x0D
 bq_calc_checksum =0x00  read_standard=(0D) > return 0

if I add all 32 Bytes I get 0x08FF.

If I read the checksum I get 0x0d.. I can do this for subclass 64 for instance the last byte is also the checksum read 

 subclass ? 64
( 64)0x40
  FF61   0030   0000   0006   0014   0000   0000   0000   0000   0000   0000   0000   0000   0000   0000   4C00
 65377     48      0      6     20      0      0      0      0      0      0      0      0      0      0  19456
 61 FF  30 00  00 00  06 00  14 00  00 00  00 00  00 00  00 00  00 00  00 00  00 00  00 00  00 00  00 00  00 4C Sum32=0x01F6

 SUM 32 Bytes     =0x01F6
 bq_read_checksum =0x4C
 bq_calc_checksum =0x09  read_standard=(4C) > return 0

 subclass ? 104
(104)0x68
  2071   945C   9808   FAC0   007B   0000   4E00   0020   0000   0000   0000   0000   0000   0000   0000   BC00
  8305  37980  38920  64192    123      0  19968     32      0      0      0      0      0      0      0  48128
 71 20  5C 94  08 98  C0 FA  7B 00  00 00  00 4E  20 00  00 00  00 00  00 00  00 00  00 00  00 00  00 00  00 BC Sum32=0x0580

 SUM 32 Bytes     =0x0580
 bq_read_checksum =0xBC
 bq_calc_checksum =0x7F  read_standard=(BC) > return 0

My checksum function

UINT_8 bq_read_checksum (void){
    //calc checksum
    UINT_8         address = BQ34Z100_ADDRESS; // 0xAA
    UINT_8         read_data [1];
    
    // write checksum to the special block checksum address
    read_data[0] = BQ_BLOCK_DATA_CHECKSUM;   // 0x60

    // send the register to the device
    if (i2cwrite(address , read_data, 1, 1) == 1 ) { // no stop
      if (i2cread(address , read_data, 1, 0) == 1) // stop
          return read_data[0];
      else
         gprintf (TTL,"Err: bq_read_checksum::Read ? \n");
       } else  
       gprintf (TTL,"Err:bq_read_checksum::Write ? \n");
       return 0;   
}

I calculate the checksum as follows

UINT_8 bq_calc_checksum (const bool update_flash){
    //calc checksum
    int            i, chkSum = 0, chkSumTemp;
    UINT_8         address = BQ34Z100_ADDRESS; // AA
    UINT_8         write_data [2];
    UINT_8         status;
    
    // add all up
    for (i = 0; i < 31; i++){
        chkSum += flash_data[i];
    }
    chkSumTemp = chkSum / 256;
    chkSum = chkSum - (chkSumTemp * 256);  
    chkSum = 255 - chkSum;
    
    chkSumTemp = 0;
    // add all up
    for (i = 0; i < 32; i++){
        chkSumTemp += flash_data[i];
    }
    gprintf (TTL, "Sum32=0x%04X\n", chkSumTemp);
    
    if (update_flash == true){
      //write checksum to the special block checksum address
      write_data[0] = BQ_BLOCK_DATA_CHECKSUM;   // 0x60
      write_data[1] = (chkSum & 0x00FF);

      // send the register and checksum to the device
      status = i2cwrite(address , write_data, 2, 0); // issue a stop

      if (status == 2 ){
        return true;
      }
      else {
        gprintf (TTL,
                 "ERR: could not write checksum 0x%02X Ret(%d)\n",
                 write_data[1], status);
        return false;
       }
    } else{
       return chkSum;
   }
}

But I could not get this to change my serial number, note I have a global array (flash_data) that holds the 32 flash data bytes

New serial number always fails at bq_calc_checksum(true), or the value in flash stay unchanged, however I can use my read_standard to read the voltage currents etc, so I think I read the default serial number as one.

bool new_serial_number (const UINT_16  value)
{
    UINT_8    serialH, serialL;
    UINT_8    subclass = 48;
    UINT_8  * ptr = NULL;

    serialH = msb(value);
    serialL = lsb(value);

    if (readFlash(subclass, false, false, 0, ptr))
    {
        // Note :: The endian is different, the default serial number is at the wrong index
        if (changeFlash(15,serialL,1))
        {
            //gprintf (TTL,"OK :changeFlash serialH\n");
            if (changeFlash(16,serialH,1))
            {
                //gprintf (TTL,"OK :changeFlash serialL\n");
                dump_flash ();
                if (bq_calc_checksum(true))
                {
                   gprintf (TTL,"OK :bq_calc_checksum 4\n");
                   wait_ms(200);
                   if (readFlash(subclass, false, false, 0, ptr))
                   {
                      gprintf (TTL, "OK :new_serial_number: Wr 0x%04X \n", value);
                      dump_flash ();
                      return true;
                   } else
                    gprintf (TTL,"ERR:new_serial_number 5\n");
                } else
                    gprintf (TTL,"ERR:new_serial_number 4\n");
            } else
            gprintf (TTL,"ERR:new_serial_number 3\n");
        } else
        gprintf (TTL,"ERR:new_serial_number 2\n");
    } else
    gprintf (TTL, "ERR:new_serial_number 1\n");
    return false;
 }

My read flash is as follows

bool readFlash (const UINT_8    sub_class,
                const bool      dump,
                const bool      remote_control,
                const UINT_32   index,
                UINT_8        * answer
               )
{
    static UINT_8  read_data  [2]  = {0};
    UINT_8         write_data [2], i;
    UINT_8         address = BQ34Z100_ADDRESS;
    
    // default answer
    answer = NULL;
    
    // enable flash transfer
    write_data[0] = BQ_BLOCK_DATA_CONTROL ; // 0x61;
    write_data[1] = 0x00;  // transfer code = 0
    
    // send the register to be read write
    if (i2cwrite(address , write_data, 2, 0) == 2 ) // stop
    {
        // specify sub class
        write_data[0] = 0x3e;
        write_data[1] = sub_class;//  & 0x7f;
        // send the register to be read write
        if (i2cwrite(address , write_data, 2, 0) == 2 ) // stop
        {
            // enable general purpose block
            if (index < 32)
            {
                write_data[0] = 0x3f;
                write_data[1] = 0;
            } else
            {
                write_data[0] = 0x3f;
                write_data[1] = index % 32;  // modulo   index 48 => 48 mod 32 = 16 (0x10)
            }
            // send the register to be read write
            if (i2cwrite(address , write_data, 2, 0) == 2 ) // stop
            {
                write_data[0] = BQ_BLOCK_DATA;   // 0x40
                write_data[1] = 0;
                // send the register to be read write
                if (i2cwrite(address , write_data, 1, 0) == 1 ) // no stop
                {
                  for (i = 0; i < 32; i++)
                  {
                      if (i2cread (address, read_data, 1, 0) == 1) // stop
                       {
                            // global
                            flash_data[i] = read_data[0];
                       }
                       else
                       {
                            gprintf (1,"4.Error reading flash [%d] \n", sub_class );
                            return false;
                       }
                     }
                }
                // save the global on success, only used when we dump the flash
                last_read_subclass = sub_class;
            } else
            {
                gprintf (1,"3.Error reading flash [%d] \n", sub_class );
                return false;
            }
        }
        else
        {
            gprintf (1,"2.Error reading flash [%d] \n", sub_class );
            return false;
        }
    } else
    {
        gprintf (1,"1.Error reading flash [%d] \n", sub_class );
        return false;
    }

//SLUA66

//Going to Production With the bq34z1xx

//PRODUCTION STEP 3: Update any Individual Flash Locations, such as Serial Number,Lot Code, and Date.Other than
//the Voltage Divider value, there will usually be some data that is unique to each battery pack, or group
//of packs such as serial number, date of manufacture, etc. This data can be written using the technique below in
//Figure 8.

Function UpdateSerialNumber (iSerialNum As Integer) As Long
  Dim lError         As Long
  Dim iSubClass      As Integer
  Dim iTransferCode  As Integer
  Dim yRo  wData(32) As Byte
  Dim iChecksum      As Integer
  Dim iTmp           As Integer
  Dim i              As Integer
 
  iSubClass = 48 '// subclass for configuration data
  iTransferCode = 0
  '//ENABLE FLASH TRANSFER
  lError = WriteI2CByte(&H61, iTransferCode, &HAA)
  '//SPECIFY SUBCLASS
  lError = WriteI2CByte(&H3E, iSubClass, &HAA)
  '//ENABLE GENERAL PURPOSE BLOCK
   lError = WriteI2CByte(&H3F, iTransferCode, &HAA)
  '//
  READ 32 BYTE BLOCK
  lError = ReadI2CByteArray(&H40, yRowData, 32, &HAA)
  '// REPLACE SERIAL NUMBER RAM. ROW OFFSETS ARE FOUND IN THE DATASHEET
  yRowData(15) = (iSerialNum\256) '//MSByte
  yRowData(16) = iSerialNum -(yRowData(0) * 256) '//LSByte
  '//CALCULATE THE CHECKSUM BYTE AND INVERT IT
  For i = 0 To 31
      iChecksum = iChecksum + yRowData(i)
  Next i
  iTmp = iChecksum\256 '//Integer divide
  iChecksum = iChecksum -(iTmp * 256)
  iChecksum = 255 - iChecksum
  '// MOVE THE SERIAL NUMBER INTO THE FUEL GAUGE BUFFER
  lError = WriteI2CByte(&H40 + 15, CInt(yRowData(15)), &HAA)
  lError = WriteI2CByte(&H40 + 16, CInt(yRowData(16)), &HAA)
  '// TRANSFER TO FLASH USING THE CHECKSUM
  lError = WriteI2CByte(&H60, iChecksum, &HAA)
  DoDelay 0.2 '// Wait 0.2 second
En Function


Viewing all articles
Browse latest Browse all 35901

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>