laszlodaniel / SmartBatteryHack

Arduino based hacking tool for smart batteries using SMBus.
GNU General Public License v3.0
150 stars 54 forks source link

does this support send command to bq2084 to unseal and unlock the battery? #1

Closed youxiaojie closed 4 years ago

youxiaojie commented 4 years ago

does this support send command to bq2084 to unseal and unlock the battery? I want to try with default key 2084 7A43 and clear PFclear 00 2673 00 1712, is it feasible?

laszlodaniel commented 4 years ago

Yes, use an Arduino Uno or Mega with the provided GUI here and write those words into the right register. Pay attention to word byte-order. Good luck!

youxiaojie commented 4 years ago

do you know the byte oder I should use?and do you have interest to modify it to raspberry pi? or do you know some similiar project for rpi? and do you have precompile binaries of windows side and arduino side?

youxiaojie commented 4 years ago

and I hope to ask you two questions, 1 since the laptop is reading writing info to battery, can I using my laptop to direct writing register? 2 how to know the i2c bus address of the battery in laptop?

laszlodaniel commented 4 years ago

By default the byte-order is reversed both in the Arduino firmware and the Windows GUI. This is the most common setting in fuel gauge ICs so I went with it. If you want to write 0x2673 into the 0x00 register, then just type 2673 into the GUI and the Arduino will first write 0x73 then 0x26.

I have a half-finished Python-code that I used while experimenting with RPi2. I can dig it up if you want. I have no intention to finish it at this point in time and don't know about similar RPi-projects.

The GUI here is compiled into an .exe file and you can find it in the Debug folder in a .zip-file. Arduino code is not compiled. Just load it into the Arduino IDE and upload to your board.

Unfortunately you can't access the battery electronics while plugged in through Windows the way you want it. I know that BIOS and some Windows application do read battery registers but that's a whole different level of programming. For our convenience the battery has to be physically accessed via its SDA/SCL-pins (and GND of course). Or you have to find a way to attach wires to these pins and route them out of your laptop.

There's a button in the GUI labeled as "Scan SMBus" that brute-forces all valid I2C-addresses and list those that respond. Smart batteries usually go with the address 0x0B. This is the default setting in the Arduino code in case you don't run this scan. If it's different for you just select the one that works and click on the "Select Address" button in the GUI and you're set.

youxiaojie commented 4 years ago

thanks!! clearly!"Unfortunately you can't access the battery electronics while plugged in through Windows the way you want it".Is it the same situation in linux to read write smbus? I am not so care of the gui , just a command line is ok to send command and get / set value in linux. I have the datasheet of the chip.I have seen some python code to manipulate smbus, but I am not expert in python.
Are you willing to share your rpi code with me?

laszlodaniel commented 4 years ago

With any operating system you face the same problem that you have to use deep-level programming. The battery is connected to the motherboard through other ICs and they are making interfacing difficult. I think ACPI is the proper way to talk to peripherals. But I have virtually no idea how it works.

I'll push the Python code to the repository tomorrow. It's basically a bunch of functions that you can call to interface the battery. It's not even a command line tool, just a one-shot application that you can fill with your commands. That's where my Python-knowledge ends lol.

youxiaojie commented 4 years ago

thanks for your hard work. is there key for bq8050 to unseal? you said: The old cells or my way of disassembly probably messed up the BQ8050. Both Design Capacity and Full Charge Capacity were dropped from ~48000 mWh to 6588 mWh. how do you deal with it? reset cycle time? rewite battery pack design capacity?

laszlodaniel commented 4 years ago

Both of these cells have 4.2V charging voltage (look up their datasheet). The capacity increase doesn't necessarily increases the charging voltage. The charging voltage is stored in the fuel gauge IC and you can change it if necessary (after unsealing of course).

I didn't manage to finish this project entirely so I didn't find the security keys for BQ8050. With its proprietary Sanyo firmware it's a difficult task. The messed up capacity reading can be dealt with a few charge-discharge cycles but even then there's a maximum FCC increase that the firmware allows. A few thousand perhaps, I don't know for sure. I didn't want to mess with it so I just bought a new aftermarket battery.

youxiaojie commented 4 years ago

what a pity. but after changing the new battery, do you feel the time is much longer than before even though it is shown Both Design Capacity and Full Charge Capacity were dropped from ~48000 mWh to 6588 mWh? in my bios there is battery calibrate item, and how about yours?

laszlodaniel commented 4 years ago

At first Windows shut down after 5 minutes but in BIOS the battery lasted for 1.5 hours, if I remember correctly. Not much longer than the original. There would have been a half hour increase if I was to charge-discharge it a few times. Still the FCC wouldn't be fixed just like that.

I have no battery calibration tool in BIOS. I calibrate it by letting it drain until the battery protection kicks in and cuts off power to the laptop. I think the calibration tool does the same with some sophistication.

youxiaojie commented 4 years ago

http://www.karosium.com/2016/08/hacking-bq8030-with-sanyo-firmware.html does this help for you?

laszlodaniel commented 4 years ago

I'm familiar with this documentation but unfortunately it doesn't work for BQ8050. They don't have the same Sany firmware. Bummer.

youxiaojie commented 4 years ago

dear friend which pin I should connect with? in arduino uno R3? sda sck?

define SDA_PORT PORTD

define SDA_PIN 1

define SCL_PORT PORTD

define SCL_PIN 0

define I2C_SLOWMODE 1 // 25 kHz

include

it seems that you are using portd bit 1 as sda bit 0 as scl, but in uno r3, they are defined as serial port and comunicate with computer?

and where is the header file? softi2cmaster.h? I see the example using wire.h,what is the difference between two lib? is wire.h not compatible with smbus?

laszlodaniel commented 4 years ago

Put this library inside the "arduino-x.x.x\Arduino\libraries\SoftI2CMaster" folder: https://github.com/felias-fogg/SoftI2CMaster

Connect to the usual I2C pins of the Arduino UNO R3 like you would when using hardware I2C (SDA = A4, SCL = A5). Don't forget the ground pin. The I2C-protocol implemented in the Wire-library is not compatible with SMBus. SMBus uses a very I2C-like protocol that the SoftI2CMaster library can handle on any Arduino pins. For convenience we can use the hardware I2C pins.

youxiaojie commented 4 years ago

dear friend which pin I should connect with? in arduino uno R3? sda sck?

define SDA_PORT PORTD

define SDA_PIN 1

define SCL_PORT PORTD

define SCL_PIN 0

define I2C_SLOWMODE 1 // 25 kHz

include

it seems that you are using portd bit 1 as sda bit 0 as scl, but in uno r3, they are defined as serial port and comunicate with computer?

A4A5 equalled to PC4PC5?

laszlodaniel commented 4 years ago

Excuse me, I just realized I used an Arduino Mega for my project... You're right. PC4 and PC5 is what you are looking for.

For Arduino Uno:

define SDA_PORT PORTC

define SDA_PIN 4

define SCL_PORT PORTC

define SCL_PIN 5

I shall make this distinction in a future update so these defines are automatically selected when an Uno or Mega board is active.

youxiaojie commented 4 years ago

really? if it can be select automaticly, it is nice. is it the same pin on the R3 label with sda sck on the up right coner near with usb and down left coner labelled analog in a4a5?

laszlodaniel commented 4 years ago

Yeah, you can make an #ifdef statement and decide between all kinds of boards on what defines to use. Pretty neat feature. But for now use the above defines.

youxiaojie commented 4 years ago

is it the same pin on the R3 label with sda sck on the up right coner near with usb and down left coner labelled analog in a4a5?

laszlodaniel commented 4 years ago

Yes, those are the same pins. You can use either one.

youxiaojie commented 4 years ago

thanks very very much!!!

laszlodaniel commented 4 years ago

You're welcome. Good luck with your battery!

youxiaojie commented 4 years ago

and I see something about avrgcc, is the libarary and c file can be used directly with arduino or need rewrite?

laszlodaniel commented 4 years ago

You can use the library as-is. Just put it in the right folder. The folder-structure should look like this: "arduino-x.x.x\Arduino\libraries\SoftI2CMaster\examples" "arduino-x.x.x\Arduino\libraries\SoftI2CMaster\tests" "arduino-x.x.x\Arduino\libraries\SoftI2CMaster\*.h"

youxiaojie commented 4 years ago

and the c source file? can it be compiled with auduino ide? or with traditional make?

youxiaojie commented 4 years ago

I used aruduino before with some avrgcc style source code in other project , only make and use avrdude to burn it.

laszlodaniel commented 4 years ago

Arduino IDE takes care all of our needs here. It compiles everything and links together in a single .hex-file and it uploads to the board with avrdude. The source-file is the .ino-file itself. You're life is about to get easier lol.

youxiaojie commented 4 years ago

for this project , I see. I want to know generally , can the source code of avrgcc make style compiled with arduino ide?

laszlodaniel commented 4 years ago

I don't understand what you're asking.

youxiaojie commented 4 years ago

https://github.com/tmk/tmk_keyboard/tree/master/converter/xt_usb this is an old xt keyboard to usb converter, I mean is there some ide to write this c files compiled with avrgcc instead of write with vi and compile with avrgcc step by step .

because I see the arduino ide to use avr-gcc to compile *.ino file, so I ask you whether arduino ide can compile this c. I see this type c file has interrupt service function ISR and pointer. seems more complicated.

youxiaojie commented 4 years ago

[INFO] Connecting to COM14

[<-TX] Handshake request (COM14) 3D 00 02 01 00 03

[INFO] Device is not responding at COM14

what's wrong? both connected with battery or without connected with battery. build is ok, uploading is ok. connected with battery when power off power on again. 1metre cable too long?

laszlodaniel commented 4 years ago

This is not the first time it's happened. Somehow Arduino's USB-controller doesn't like the way I try to communicate with it. CP2102 doesn't play this game. Let me debug this once and for all.

Try to comment out this line in the loop: if (design_voltage == 0) design_voltage = read_word(0x19);

It makes the loop hang if the I2C address isn't 0x0B.

youxiaojie commented 4 years ago

[INFO] Connecting to COM14

[<-TX] Handshake request (COM14) 3D 00 02 01 00 03

[INFO] Device is not responding at COM14

what's wrong? both connected with battery or without connected with battery. build is ok, uploading is ok. connected with battery when power off power on again. 1metre cable too long?

fix it! enable internal pull up.

youxiaojie commented 4 years ago

closed? I unsealled battery, but I still could not change the value of remaining capacity 0x0f.

laszlodaniel commented 4 years ago

It automatically closed when I merged your pull request. I completely missed the internal pull-up resistors, good catch!

Well you got farther than I ever will by unsealing your battery controller. At this point you are on your own. I guess the FCC register is writable now. If not try the full access key and then write the FCC register.

The remaining capacity register is never writable. It's a read-only value calculated by the controller. What you are looking for are these registers:

define FullChargeCapacity 0x10

define CycleCount 0x17

define DesignCapacity 0x18

youxiaojie commented 4 years ago

1.yes,default key 2084 7A43 is unseal key.but the 0x10 still can not be writable.maybe need fullaccesskey. I find someone said the key is stored in eeprom, so I search datasheet but only find 2083 7a43 which is wrong.and the several word maked reserved maybe default full access key? among them I find familiar 2673 1712. I want to try direct read/write eeprom. 2.is it posible to show other infomation when connect battery than just voltage when connected to battery?

laszlodaniel commented 4 years ago

Have you tried FFFF FFFF as the full access key? Worth a try. You can display anything you want. Try clicking on the register dump button in the GUI, it shows a few interpreted values. By no means is it complete, though.

youxiaojie commented 4 years ago

[<-TX] SMBus register dump request 3D 00 04 02 03 00 FF 08

[RX->] Device is ready 3D 00 03 80 01 00 84

nothing else show. I mean that when I connect with battery, [INFO] Design voltage: 11.1 V could there be more infomation?such as device type ,firmware version... maybe this should modify windows clients.

laszlodaniel commented 4 years ago

"Device is ready" means Arduino code stuck in a request-loop for more than 4 seconds and the watchdog timer restarted Arduino. That's bad news. Can you read individual registers? I programmed the GUI to only show design voltage like this, because it's needed for capacity calculations (mAh or mWh). Other information should display when you dump all registers. Question is: why does the code hang up for you. You are welcome to modify the source code for your needs.

youxiaojie commented 4 years ago

[INFO] Design voltage: 11.1 V

[<-TX] Select SMBus address 3D 00 03 03 02 0B 13

[RX->] SMBus settings 3D 00 03 83 02 0B 93

[INFO] Current SMBus device address: 0B

[<-TX] Read word data 3D 00 03 04 02 2F 38

[RX->] Word data received 3D 00 05 84 02 2F 06 90 50

[INFO] Reg.: 2F Data: 06 90

[<-TX] Read word data 3D 00 03 04 02 10 19

[RX->] Word data received 3D 00 05 84 02 10 0F C8 72

[INFO] Reg.: 10 Data: 0F C8

[<-TX] Read word data 3D 00 03 04 02 0F 18

[RX->] Word data received 3D 00 05 84 02 0F 0F C8 71

[INFO] Reg.: 0F Data: 0F C8

[<-TX] Read word data 3D 00 03 04 02 0E 17

[RX->] Word data received 3D 00 05 84 02 0E 00 54 ED

[INFO] Reg.: 0E Data: 00 54

[<-TX] SMBus register dump request 3D 00 04 02 03 00 FF 08

[RX->] Device is ready 3D 00 03 80 01 00 84

laszlodaniel commented 4 years ago

Looks good. Try to limit the upper end of the registers. Like 00 - 2F. Important values are in the first segment anyways.

youxiaojie commented 4 years ago

dump 0x0--0x53 0x56--0xFF are ok, 54 55 is bad.

laszlodaniel commented 4 years ago

0x54 (OperationStatus) would be important to read, that's where you can query the sealed / full access status bits. Or do you request this register through 0x00? Weird fuel gauge IC you got there!

youxiaojie commented 4 years ago

hope to have an editable serial protocal from obd scanner documents other than pdf format, to modify for this project. do you think to get a new public version of bqxxxx IC with default config from Ti to replace the old one customized version in the battery , filling in the necessary register. is it feasible? damn cracking.

laszlodaniel commented 4 years ago

Why do you want to modify the serial messaging protocol? By all means it's editable, just modify the source code. My other project and this uses the same code to communicate with the Arduino board.

You are trying to over-complicate things here. You only need to reset those 3 registers I mentioned earlier and let the fuel gauge IC adapt to them. If you have TI-firmware try other applications that have reset feature. They usually need a cheap USB adapter board (like one with CP2102) and you don't have to get messy.

youxiaojie commented 4 years ago

not protocal ,is the document format:) sorry. editable format not pdf. other format of ChryslerCCDSCIScanner_UART_protocol.pdf I have some puzzle with value of data and subdata byte, so hope to view your code and edit such file for future use.

laszlodaniel commented 4 years ago

Ah, I see! Here you go: ChryslerCCDSCIScanner_UART_protocol.docx

The data code byte construction is easier than in ChryslerCCDSCIScanner. Similarly the lower 4 bits are used for the command (0x00-0x0F) and the leftmost bit is a flag (0x80). If the packet is sent by the Arduino to USB then it's set to 1. If the GUI sends a packet then this bit is 0. Three bits between the command bits and flag bit are not used, they always read zero.

DATA CODE byte detail

You can interpret command bits and sub-data code bytes from the source code comments. I didn't feel the need to make a documention. But by all means go for it.