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.

BQ20Z45: BQ20Z45 BootROM mode, how to upload firmware/file?

Part Number: BQ20Z45
Other Parts Discussed in Thread: BQ20Z40, BQ20Z80, BQEVSW

A friend of mine repairs accu packs. He replaces the old Lion batteries with new ones
and (re)programs the BQ20Z45 BMS. This works very well, albeit that his 'production
procedure' is very cumbersome, irritating and complicated.

To help him, I wrote software to automate the whole (re)programming process, i.e.:

Place the pack in the charger, the software does its thing and after succesfully
(re)programming the BMS, morse code 'R' (.-. for 'roger') sounds, after which the
pack may/can be removed. This works perfectly.

The issue I have, is that my friend insists uploading a 'clean' (or 'known to work
properly') firmware file to the pack first, and then (re)program the BMS with his
proven parameters (such as design capacity etc, and a serial number).

In the BQ20Z40/BQ20Z45 Technical Reference (TR) document I read on p53 the
device can be put in BootROM mode. Unfortunately no more information is
given in this document.

After some googling I found some issues concerning BootROM mode here.
However, as far as I could ascertain, it only deals with the TI Battery Tool.

Before I enter the I2C-sniffing mode, is there a document where this BootROM mode
and/or protocol description is explained?

What I want to know is:

1. After entering BootROM mode exactly what to send to the device to accept a
long datastring (i.e. firmware file) and what the format has to be (of course hex or bin,
but is there a need for a length word, etc etc)

2. After the firmware has been uploaded what is the response of the device
(if there is any) and how to enter normal mode (I read something about addr 0x0D).

Kind regards & thanks in advance

  • I found a similar issue on this forum concerning the BQ20Z80 and its
    'Application Book' (slua380.pdf).
    On pages 218 - 220 the required information is given.

    Bluntly assuming that there is 'not much difference' (of course there is!)
    I just wrote a routine to read the ROM contents from 0x200 and on,
    knowing that my friends 'Golden Pack' filesize is 2048 bytes (0x0800).

    I get a nice hex dump in 32 byte bursts (max i2c block size) and the
    device switches back to normal mode after sending 0x08 to the SMBus.

    Promising!

    The only thing to figure out is whether start address 0x200 is correct for the BQ20Z45.

    If anyone can confirm this, or has the proper address, I'll tick 'This resolved my issue' ; -)
  • Remco,

    Unfortunately we can't confirm fw updating procedures as they are meant only for manufacturers. However, the path that you are on will lead you to the answer.
  • Ok, good and bad news ...

    The good news is I found a more appropriate document titled:
    "Data Flash Programming and Calibrating the bq20zxx Family of Gas Gauges"
    (slua379e.pdf), written by TI-employee Jackie Hui (whose name I saw in some posts on this forum!)

    So the first good news is, is there is at least somebody here exactly and fully 'in charge' of the matter!
    (fingers crossed he reads this thread ; -)

    Second good news is that my assumption concerning the 'offset address' (I mistakenly wrote 'ROM contents' ...) (0x0200) for the BQ20Z45 was ok, albeit (at the time of writing of my previous posting) I got the value from a BQ20Z80 document.
    In fact the flash address is 0x0200 << 5 , thus starting at 0x4000.
    Anyway ... I'm able to succesfully read the flash contents.

    In the aforementioned document it appears that the 'flash size' is 0x0700 bytes,
    instead of 0x0800 (which is the length of the 'Golden File' my friend uploads to all his refurbished packs first and subsequently alters the variables matching his new batteries. His packs work very well ... interesting ...)

    The bad news is that I almost certainly bricked a BMS in one of my test packs. Almost 100% sure this is due to (certainly my interpretation and/or in my opinion) (ambiguous) information in documents slua380 and slua379e.
    If I'm incorrect, please correct me ; -)

    slua380 p220 describes how flash can be uploaded to the BMS.
    Basically the 'flash file' is chunked into 32 byte blocks. After putting the BMS into BootROM mode the appropriate 32 byte block/chunk inside the BMS is erased and subsequently programmed.
    This repeats until the end of the flash file is completely uploaded.

    However, after reading slua379e (and assuming that this document is more relevant because it's more recent) things became confusing to me.

    slua379e p4 describes how to upload a flash file to a bq20zxx.

    What confused/s me is the following:

    Dim yDataFlashImage(&H700) As Byte <-- seemingly compliant with slua380

    *snip*

    '// FOR CLARITY, WITHOUT USING CONSTANTS
    iNumberOfRows = &H60 \ 32 '54 Rows <-- not 0x0700 and 0x60 / 32 is not 54 (?)

    *snip*

    '// ERASE DATA FLASH, ROWS ARE ERASED IN PAIRS <-- pairs ?
    For iRow = 0 To iNumberOfRows - 1 Step 2
    1Error = WriteSMBusInteger (&H11, iRow) <-- what is written to 0x11? (0x00iRow or 0x[iRow+1,iRow] ?)
    DoDelay 0.04
    Next iRow

    (yes, I am not into VB at all ; -)

    Because I interpreted the WriteSMBusInteger (&H11, iRow) routine as a routine which writes a (16 bits) word to 0x11 I wrote 0x[iRow+1,iRow] to 0x11, being:
    word = iRow | (iRow+1) << 8 ;

    Well, that (100% certainly) was my fatal mistake ... ?

    So, what to write exactly to the device in order not to brick another pack?

    PS. I am just into the BMS world for a week and want to help my friend.
  • For those interested, this is my working flash_read & hexdump routine:

  • @Batt: thanks for your sign of life (... and (moral) support) ! \o/

    I'm not into discussions about what is 'a manufacturer' or ... not (maybe a '(re)manufacturing refurbisher' ?)

    I'm asking questions concerning TI's documents and how to interpret 'information' in these documents.

    Gateway of the last resort is sniffing the i2c/SM-bus to find out what (really) happens.
  • Remco,

    That was funny! Yeah, it's unfortunate that I can't confirm or deny what you state. But you are close. Please go ahead and sniff the line, better way to do that would be to sniff the line when bqevsw is doing the programming following the fw update command.
  • @Batt: thanks for neither 'acking' or 'nacking' my musings. At least I know someone is sniffing me ; -)

    Concerning 'hardware sniffing', my friend uses a working (albeit very cumbersome) procedure to
    'manufacture' his packs. So, a few days ago, prior to my 'membership' here, I already took the mental
    junction to sniff the bus before he uploads his 'Golden File' into his battery packs. My hope was that
    posting my questions here would facilitate my journey, i.e. not going into the hazzle of sniffing.

    PS I reckon when I succeed I'm not allowed to post the solution here?
  • Btw, I discovered each time I download flash/fw-contents
    (or perhaps the device is put into BootROM mode?),
    the 'partial reset' counter (ResetData, 0x57) is increased by one.
    Is this nominal?
  • Yeah, reset increases with each flash. It's unfortunate that I can't comment on your steps, but you are on track.
  • Bratt, can you / are you allowed to comment/elaborate on the picture below?


    My question: Is the information on p85 and p86 of sluaa313a CORRECT in

    the following senses:

    1. the absolute values of the slave address(es), being 0x16 and/or 0x17 ?

    2. that one has to deliberately use a slave address which is +1 higher for some operations ?

    In other words, my BQ20Z45 pack uses 0X0B as slave address, does this mean when the

    information in the picture is CORRECT I've to write to a slave address (0x0B + 1 = 0X0C) which is

    non-detectable using a normal i2c_start-condition?

    Or ... is the information on p85 and p86 wrong?

  • Busy times here due to "Sinterklaas" (not to be confused with Santa Claus!) here in The Netherlands.

    Ok, what to say ...

    First of all there was no reaction or response to my posting above.
    (which in itself is 'information' . . .)

    Two days ago I learned that there are two I2C-worlds: a 7-bit and 8-bit world.
    TI lives in the 8-bit world, thus 0x16 has to be interpreted as 0x0b << 1.
    Increasing the 8-bit address with 1, sets the read bit.
    This is mostly done when a repeated start is wanted.
    So that makes sense, in that sense that this part of the information in the
    picture above is correct.

    However, following the sequence of actions in the above picture I was not able to
    write a SubClass ID block in flash.

    It took me some hours with low level I2C-debugging (not on the level of a
    logic analyzer yet) to find out what was exactly happening.

    Result is that I am now able to succesfully alter flash content with my own code.
    Based on my code there are (at least) two conclusions:

    1. My approach is so ingenious that I invented a new way to program flash contents.
    2. Parts of the information in the picture above is incorrect.

  • Remco,

    Unfortunately while I'm not able to confirm your actions, I'm happy that you are able to progress on this issue here.
  • Hi Batt,

    I feel we both have 'mixed feelings' concerning 'answers' in this thread. I really appreciate your response(s).
    (that's why I did NOT hit the 'This did NOT resolve my issue'-button)

    So, I won't go into a semantic discussion concerning 'not able' vs 'allowed' (noting I'm not a native
    English/American speaker, but I've been taught 'the Queens English' nor 'what is the definition of a 'manufacturer')

    My reality is that I'm now able to help my friend with increasing his 'manufacturing/production/refurbishing'
    process with an efficiency of (old) ca. 180 seconds vs. (new) ca. 3 seconds, using a simple Arduino Nano.

    . . . . Remco
  • Hi Remco,

    I really did want to be able to say something about your checkouts but was not allowed to because of policy. You're right, it's not a question of ability, it's a question of permission to do something. But, I'm really happy that you were able to figure something out. I hope this thread is of use to others. Your technical prowess has my respect.
  • I received a message from 'Igor', but when I click on it I can't see it here, but I received a copy via email as well.

    @Igor: your message is crystal clear to me, as I already posted myself concerning the 'definition' of
    I2C-addresses. Before this project I didn't dive too much into I2C, but now I had to. People saying that
    I2C is a 'simple' protocol are -in my opinion- wrong. When you've to strip down the protocol down to logic
    levels and timings, it's not 'so simple'. (RS232 or SPI is easier ; -)

    When I was confronted with semantic discussions concerning how to interpret 'I2C addresses' and how to
    communicate this / write this down, it's a confirmation for me that the protocol is not 'so simple'.

    Reading the 'formal' documents about I2C one speaks of 7-bit 'addresses' (there is also a 10-bit mode, but
    I leave that out here). For whatever reason this 'address' has to be shifted left to obtain the 'real address'
    where the LSB indicaties a read or write option. This is a choice. . . but why did Philips (and mind you, I am
    from The Netherlands, Philips is a Dutch company ; -) not decide to leave the 'address' alone and use the
    MSB (7th bit) to indicate a read or write operation? (to mention another perspective ; -)

    In short (sorry Batt I am NOT into bashing your employer nor the hospitality of this forum), when one writes:

    "SMB slave address (0x16)"

    *snip*

    "SMB slave address (0x17)"

    this is in my opinion de facto confusing. It should read / be written as (for example):

    C 1.4 Example
    7-bit I2C addresses are shifted left one position. The SMBus address 0X0B therefore
    should appear as 0X16 on the I2C-bus.

    *snip*

    "Address the device"

    *snip*

    "Address the device with read bit set"

    Anyway . . .

    The incentive of this thread was that I was not able to alter flash contents (SubClasses and Offsets etc).
    Giving information on this to non 'manufacturers' appears to rub with policy issues.

    Using a different way than described in the datasheet / technical reference document
    I am now able to alter desired flash contents, so I solved my own issue ; -)
  • OK, to Batt and all readers, and to 'finish' this thread:

    Recently I managed to flash the chip with an entire Golden Image.

    I had to sniff the I2C-/SMBus and bricked four chips to discover
    a 'sneaky issue' in the protocol and . . . that timing is important!

    The Arduino tool is now fully operational and used to process
    large batches of packs.

  • Bravo, and congratulations! Thank you Remco.