karosium / smbusb

USB SMBus Interface
GNU Lesser General Public License v2.1
141 stars 42 forks source link

writing program to bq8030 doesn't work #10

Closed jalr closed 4 years ago

jalr commented 6 years ago
  1. I'm having trouble flashing the program. Normally I would blame my hardware for this but I played around with two batteries and both showed the same issue. One is now bricked but the other works so I can still try things out ;)

  2. In your blog you mentioned that Error -11 means LIBUSB_ERROR_NO_MEM. I tried to understand why that would happen and came across the writeProgramBlock function where you return status-2. If I understood that correctly SMBWriteBlock returns the size written successfully or alternatively a negative number in case of an error. If that is correct you should return (status > 0 ? status-2 : status); in writeProgramBlock and the same for writeEepromBlock. I'll send you a PR if you confirm this.

smbusb_bq8030flasher -f prg.bin --confirm-delete
------------------------------------
        smbusb_bq8030flasher
------------------------------------
SMBusb Firmware Version: 1.0.1
PEC is ENABLED
TI Boot ROM version 3.2
------------------------------------
Erasing program flash
Done
Flashing program flash
Error:-11

writing the eeprom works like a charm:

smbusb_bq8030flasher -w eep.bin --confirm-delete
------------------------------------
        smbusb_bq8030flasher
------------------------------------
SMBusb Firmware Version: 1.0.1
PEC is ENABLED
TI Boot ROM version 3.2
------------------------------------
Erasing eeprom(data) flash
Done
Flashing eeprom(data) flash
................................................................
Done!
Verifying
................................................................
Verified OK!
karosium commented 6 years ago

Hi,

Ah, that explains it! Confirmed, feel free to send the PR.

So it was actually LIBUSB_ERROR_PIPE (-9) then... more realistic but still doesn't tell me much. However I am wondering whether increasing the usleep delay in writeProgramBlock() would have any effect. It was a totally arbitrary number I settled on because it seemed to work for me. I've successfully reflashed a bq8030 program flash a total number of 2 times which was the extent of the testing I did on this but 2000uS might be cutting it too close for writing the program flash blocks (and usleep might not be that consistent across systems either).

Could you try it with usleep 5000, 10000, 100000 in writeProgramBlock()?

Thanks

jalr commented 6 years ago

OK I debugged a little further and found out that first 64 bytes are transferred in the SMBWriteBlock function. Then after attempting to transfer the remainder the error -9 is returned. So in my case the usleep() never gets called. Documentation says LIBUSB_ERROR_PIPE is returned if the control request was not supported by the device.

jalr commented 6 years ago

I just wanted to check if the first 64 bytes are written to the flash but no. Instead if I dump the program memory I see the repeating pattern ff ff 3f. The pattern repeats until the address 0x11040. From there on it is filled up with ff.

karosium commented 6 years ago

ff ff 3f is NOP in CoolRISC. It's what the program flash blocks are erased to so basically it's blank.

If the first call goes through and you get the error on the second then the delay could still be at fault. If the chip is still writing the first block when the command to write the second comes in it could mess things up and possibly even block the write that's in progress so I would still try with increased delays.

If it's not that then unfortunately I have no clue.

jalr commented 6 years ago

Yes! Thanks, that was the right hint. I fixed it with a usleep(10000000) after eraseProgramFlash(). Do you have any ideas how we could do this properly instead of relying on the correct timing?

karosium commented 6 years ago

Nice, glad you could get it to work!

Yeah, the delays were always a hack. The right way would be to read the correct status register through the TI BootRom interface that says whether the flash is busy or not and keep reading it until it isn't. Someone would need to find the correct command(s) in one of the many TI PDFs and implement it.

So it's either that or bumping up sleep(1) in eraseProgramFlash(). I'm guessing 10 seconds is probably overkill so if you could test it at second intervals and then double the lowest that works for you that'd probably be fine.

I'm fine with merging a pull request with either approach ;-)

0r10nV commented 5 years ago

we can implement variable time delay in respect to data block length to be written, I've seen this approach in TI sample code in slua801.pdf ("Gauge communication and flashstream examples", p.14, 'gauge.c')

n = atoi(pBuf); usleep(n * 1000);

p.s. as was observed usleep() is not really doing what it should do, especially with small delays, I have not managed to make it precision micro delays om my system (Win7 32bit), for a range of arguments from 1 to 16000 it gives constant delay of 16ms, but usleep(100000) gives unexplainable 0ms, so no delay at all!

karosium commented 5 years ago

Good find 0r10nV, best-practices from TI would be great to adopt. Unfortunately I can't really work on this anytime soon besides quickly skimming and merging PRs so someone would need to add and test the improvements and submit one.

karosium commented 4 years ago

I've attempted to mitigate this in c223f2042 by raising the delay to 200mS and adding a macro for usleep() to use Sleep() on Windows. 200mS should be plenty because I'm pretty sure the code never waited anywhere near that long for me and it still worked so I'm thinking if we can get that delay reliably across platforms it should be fine.

This issue is open to anyone who experiences program flash write errors with this tool for the next 6 months or so, if no new comments appear I will be closing it.