o-gs / dji-firmware-tools

Tools for handling firmwares of DJI products, with focus on quadcopters.
GNU General Public License v3.0
1.51k stars 416 forks source link

Battery firmware #17

Open notsolowki opened 7 years ago

notsolowki commented 7 years ago

i notice the battery firmware is not encrypted. i wonder what could be done to the battery controller so aftermarket batteries could be connected

mefistotelis commented 3 years ago

Is it 100kbps here is equivalent to 100kHz clock frequency typically used for Smbus devices?

Yes. SMBus transfers one bit per clock, I guess that's why config option in Linux kernel is "baudrate" instead of clock frequency.

Does ev2300 use 66k to read those registers?

Yes. But I haven't seen such requirement in spec. Anything between 10k and 100k should work.

Me have used different hardware like Cypress EZ-USB and Silabs CP2112 as usb-to-smbus adapters at 100kHz and they work with bq30z55 just fine.

Yeah, I have a feeling the issue is with the I2C interface built into RPI. It must be using a strange clock divider. The method with my script and simple I2C bus will be cheap, but looks like it won't be as reliable as ev2300 or Cypres/Silabs SMBus devices.

Thank you for the info of FW versions vs spec - that does explain what I see.

mefistotelis commented 3 years ago

Well that's interesting. The "Unseal" documentation in spec seem to contain intentional errors and omissions. It says:

  1. Generate SHA-1 input block B1 of 512 bytes (total input =128-bit unseal/full access key KD + 160 bit message M + 1 + 159 0s + 100100000).

Now, "512 bytes" should be 512 bits, ofcourse. But even if you knew that, try adding the bits in brackets to receive 512 bits. To make it work you need to know that while the single "1" represents a single bit, "100100000" doesn't represent 9 bits, but 64-bit integer.

0r10nV commented 3 years ago

Yes, their TRMs are plenty of errors which are repeated even in revised editions. Have noticed a lot of them in different paragraphs for various devices.

pawelsky commented 3 years ago

@mefistotelis Well, the documentation actually does specify that the number is 64-bit integer in the SHA-1 generic description paragraph (9.2) image So while the bits vs bytes thing is an obvious mistake, I would not call these errors intentional.

rsrmdp commented 3 years ago

https://e2e.ti.com/support/power-management/f/196/t/677057

mefistotelis commented 3 years ago

Oh I see now.. the added data at end is within the FIPS 180-2 standard, which is used by all SHA-1 computation tools. So if using either Python hashlib or command line shasum, only the key-related parts of the data should be provided (the 288 bits). The rest will be automatically appended at end, by the libraries.

For example:

 $ echo -n 00000000000000000000000000000000c82ca3ca10dec7268e070a7cf0d1fe8220aad3b8 | xxd -r -p | shasum -b | awk '{print $1}'
ebf44e83d792151c8be508bb6d517c69b331c0ce

..gives the same value which is displayed as an example within SLUA389A.PDF How to Implement SHA-1/HMAC Authentication

mefistotelis commented 3 years ago

Unseal is now working on my script:

$ ./comm_sbs_bqctrl.py -vvv --bus "smbus:1" --dev_address 0x0b  --sealing Unseal
Opening smbus:1
Raw FirmwareVersion response: 0d 05 50 00 36 00 34 00 03 80 00 01 00 03 c5
Auto-selected chip: BQ30z55, Texas Instruments BQ30z55 chip
Raw ManufacturerAccess.UnSealDevice response: 14 07 19 b6 e1 b1 3e 12 12 03 07 5c c1 1b b1 49 12 11 02 06 e2 e1
Prepared ManufacturerAccess.UnSealDevice B1=0123456789abcdeffedcba9876543210e20602111249b11bc15c070312123eb1e1b61907
Comupted ManufacturerAccess.UnSealDevice HMAC1=696916244ab88bfdd9f0955763948a13e7ab108b
Comupted ManufacturerAccess.UnSealDevice HMAC2=2b1b8c1f1af553b35d96b8f396d98c21fccca248
Write ManufacturerAccess.UnSealDevice: 2f BLOCK=48 a2 cc fc 21 8c d9 96 f3 b8 96 5d b3 53 f5 1a 1f 8c 1b 2b

Reading manufacturer_access_subcommand command at addr=0xb, cmd=0x0, type=uint16, opts={'subcmd_str': 'OperationStatus'}
Query ManufacturerAccess.OperationStatus: 00 WORD=0x54
Raw ManufacturerAccess.OperationStatus response: 04 00 72 10 00 b2
ManufacturerAccess:     0x107200        bitfields       Optional command, is implementation specific
      SYS_PRESENT_LOW:  0=Inactive      [PRES]  System present input state low
       DSG_FET_STATUS:  0=Inactive      [DSG]   DSG FET status
       CHG_FET_STATUS:  0=Inactive      [CHG]   CHG FET Status
      PCHG_FET_STATUS:  0=Inactive      [PCHG]  PCHG FET Status
      GPOD_FET_STATUS:  0=Inactive      [GPOD]  GPOD FET Status
          FUSE_STATUS:  0=Inactive      [FUSE]  FUSE input status
       CELL_BALANCING:  0=Inactive      [CB]    Cell Balancing
           LED_ENABLE:  0=Inactive      [LED]   LED Enable
        SECURITY_MODE:  2=Unsealed      [SEC]   Security Mode           <<<*****************
       CAL_RAW_ADC_CC:  0=Inactive      [CAL]   Calibration Raw ADC/CC output active
        SAFETY_STATUS:  0=Inactive      [SS]    Safety Status
    PERMANENT_FAILURE:  1=Active        [PF]    Permanent Failure
 DISCHARGING_DISABLED:  1=Active        [XDSG]  Discharging Disabled
    CHARGING_DISABLED:  1=Active        [XCHG]  Charging Disabled
           SLEEP_MODE:  0=Inactive      [SLEEP] Sleep mode condition met
       SHUTDOWN_BY_MA:  0=Inactive      [SDM]   Shutdown activated by ManufacturerAccess()
      SHIP_MODE_BY_MA:  0=Inactive      [SHPM]  SHIP mode activated with ManufacturerAccess()
         AUTH_ONGOING:  0=Inactive      [AUTH]  Authentication ongoing
    AFE_WATCHDOG_FAIL:  0=Inactive      [AWD]   AFE Watchdog failure
    FAST_VOLTAGE_SAMP:  1=Active        [FVS]   Fast Voltage Sampling
    RAW_ADC_CC_OUTPUT:  0=Inactive      [CALO]  Raw ADC/CC offset calibration output
  SHUTDOWN_BY_VOLTAGE:  0=Inactive      [SDV]   SHUTDOWN activated by voltage
          SLEEP_BY_MA:  0=Inactive      [SLEEPM]        SLEEP mode activated by ManufacturerAccess()
     INIT_AFTER_RESET:  0=Inactive      [INIT]  Initialization after full reset
    SM_BAT_CAL_ON_LOW:  0=Cal starts    [SMBLCAL]       Auto CC offset calibration on low
 QMAX_UPDATE_IN_SLEEP:  0=Inactive      [SLEEPQM]       QMax update in SLEEP mode
 CURRENT_CHK_IN_SLEEP:  0=Inactive      [SLEEPC]        Checking current in SLEEP mode
     XLOW_SPEED_STATE:  0=Inactive      [XLSBS] Fast Mode
vmiceli commented 3 years ago

Unseal is now working on my script:

That is veeeery good!!! Is this approach possible on the Inspire 1 battery chipset?

Thank!!

E.

mefistotelis commented 3 years ago

Is this approach possible on the Inspire 1 battery chipset?

If you implement unsealing for that chip - then sure.

svarteld commented 3 years ago

@mefistotelis, wow, great work, impressive. If there's anything I can try on TB47/48 if you decide to implement that, let me know and I'll do what I can.

vmiceli commented 3 years ago

It looks like a few of us have access to TB47 and TB48 boards and also the TI software to connect to the battery controller. Should we put in the extra effort to unseal the batteries and reprogram them so that larger cells can be used?

mefistotelis commented 3 years ago

I'm still getting random I/O errors, usually when reading OperationStatus. Not sure if I should fine tune my I2C speed, or is that normal: print_flags_random_io_error

(Also, I added '--short' format for flags, so they look like in BQEVSW) The tool is published there until is useable enough to be pushed to dji-firmware-tools: https://github.com/mefistotelis/smart-battery-system-bq-experiments

pawelsky commented 3 years ago

I'm still getting random I/O errors

Did you check the I2C pull up resistance?

mefistotelis commented 3 years ago

From RPI documentation, GPIO 2/3 (which can also be used as I2C bus 1) have 1k8 external pulls to 3V3. There is another I2C (bus 0) on the pi board, without any pulls (GPIO 18/19). I didn't tried to use that.

I would expect the pulls on battery side to be higher, didn't tried to measure though.

pawelsky commented 3 years ago

Since these pullups are in parallel the equivalent resistance will be lower (so the pullup will be stronger), I would compare with the bus 0 (the one without pullups) to see if it makes any difference.

0r10nV commented 3 years ago

I'm still getting random I/O errors

Try to isolate msp430 uC from the SMBUS. Me have experienced interference from its side especially on M.Pro batteries. You need to temporary cut this wire. And recheck whether read errors still occurs.

Dji_MavicPro_msp430_isolate

mefistotelis commented 3 years ago

I've seen that msp430 communication. It happens when you press the button, or every 45 minutes. Or when you turn on the battery - then the messages are constantly exchanged.

If the battery is off, and you don't touch the button - there's mostly silence on the line, except that one second every 45 minutes.

0r10nV commented 3 years ago

when battery is Off then msp430 puts its pull-up line to the ground, and ev2300's SCL and SDA high level state drops from 3.3 to 2.8v and communication is also become broken. That's why me normally isolate msp430 to recover normal communication while reprogramming bq30z55. For just Sbs parameters read it's not so critical, but sometimes it's even not possible to read anything with battery Off.

p.s what is interesting that some boards are free from this issue.

mefistotelis commented 3 years ago

I see. That makes sense. But why are you cutting only 1 wire? The one you cut seem to be SCL, though it goes through 3 resistors before reaching the BQ chip. So cutting SCL will recover SDA? Maybe only SCL is being shorted by msp430?

mefistotelis commented 3 years ago

Another question: My BQ tool can now successfully reset PF flags, but this still keeps XCHG and XDSG flags tripped within OperationStatus(). Is there a way to clear these with "standard" commands, without writing to CHGFET in Data Flash?

rufiooo commented 3 years ago

In my case (BQ30Z55 in P4) cleared PF with tripped XCHG and XDSG didn't block charging and discharging.

mefistotelis commented 3 years ago

You're right - the battery still charges. And it's not like charging just clears that flag - XCHG is still set after charging. Looks like I just misinterpreted what the flag does.

0r10nV commented 3 years ago

But why are you cutting only 1 wire? The one you cut seem to be SCL

The wire shown on the picture is not SCL. It's common Smbus Pull-up for both SCL and SDA. It goes to GPIO on msp430 and pulled low to high depending on whether CPU sleeps or runs. Something like Smbus_Enable feature. It's used for transition of bq30z55 into sleep mode on low bus.

My BQ tool can now successfully reset PF flags, but this still keeps XCHG and XDSG flags

This is because battery is Off by pushbutton. And as such PRESENT signal controlled by msp430 is high. You should drive it low by jumper from PRES to GND points or just switch On the battery and read the registers in multimaster mode (at pauses between msp communication).

XCHG or XDSG flags could also be set at Full Charge or Full Discharge events detected, even PF is cleared and PRES is low.

svarteld commented 3 years ago

Don't know if you find this useful, but I noticed Inspire 1 FC firmware parameters contains settable battery "raw" parameters, whatever that means. Among them, design capacity, mentioned before. Found these:

g_raw.battery_info.average_current_0 g_raw.battery_info.capacity_percentage_0 g_raw.battery_info.cell_voltage[0]_0 g_raw.battery_info.cell_voltage[1]_0 g_raw.battery_info.cell_voltage[2]_0 g_raw.battery_info.cell_voltage[3]_0 g_raw.battery_info.cell_voltage[4]_0 g_raw.battery_info.cell_voltage[5]_0 g_raw.battery_info.current_0 g_raw.battery_info.cycle_count_0 g_raw.battery_info.design_capacity_0 g_raw.battery_info.error_count_0 g_raw.battery_info.full_charge_capacity_0 g_raw.battery_info.life_percentage_0 g_raw.battery_info.n_discharge_times_0 g_raw.battery_info.pack_voltage_0 g_raw.battery_info.remaining_capacity_0 g_raw.battery_info.right_0 g_raw.battery_info.serial_number_0 g_raw.battery_info.temperature_0

None of those are defined since first to last FW. Other FC battery parameters do impact battery, such as:

g_config.bat_limit.limit_bat_current_after_overflow_0 g_config.bat_limit.limit_delt_vol.max_0 g_config.bat_limit.limit_delt_vol.min_0 g_config.bat_limit.limit_delt_vol.weight_0 g_config.bat_limit.limit_down_rate_0 g_config.bat_limit.limit_max_power.max_0 g_config.bat_limit.limit_max_power.min_0 g_config.bat_limit.limit_max_power.weight_0 g_config.bat_limit.limit_power_rate_capacity.max_0 g_config.bat_limit.limit_power_rate_capacity.min_0 g_config.bat_limit.limit_power_rate_capacity.weight_0 g_config.bat_limit.limit_power_rate_temp.max_0 g_config.bat_limit.limit_power_rate_temp.min_0 g_config.bat_limit.limit_power_rate_temp.weight_0 g_config.bat_limit.limit_scale.max_0 g_config.bat_limit.limit_scale.min_0 g_config.bat_limit.limit_scale.weight_0 g_config.bat_limit.limit_temp.max_0 g_config.bat_limit.limit_temp.min_0 g_config.bat_limit.limit_temp.weight_0 g_config.bat_limit.limit_up_rate_0 g_config.bat_limit.limit_vol.max_0 g_config.bat_limit.limit_vol.min_0 g_config.bat_limit.limit_vol.weight_0 g_config.voltage.level_1_protect_0 g_config.voltage.level_1_protect_type_0 g_config.voltage.level_2_protect_0 g_config.voltage.level_2_protect_type_0 g_config.voltage.line_loss_0 g_config.voltage2.judge_smart_battery_communite_0 g_config.voltage2.level_1_function_0 g_config.voltage2.level_1_voltage_0 g_config.voltage2.level_2_function_0 g_config.voltage2.level_2_voltage_0 g_config.voltage2.level1_smart_battert_gohome_0 g_config.voltage2.level2_smart_battert_land_0 g_config.voltage2.user_set_smart_bat_0 g_config.voltage2.vol_ceof_0

mefistotelis commented 3 years ago

These are FC parameters. I don't know whether writing to them will actually result in FC sending write request to battery. That's interesting - if these are updated within BQ chip on write, that would mean the battery uC can unseal the BQ chip.

Also worth mentioning that not all of these params even have an equivalent within Smart Battery.

svarteld commented 3 years ago

True. I'll define those next time I make a FC firmware, and see if anything happens when inserting a battery with new cells.

rokz12 commented 3 years ago

Wow just joined and must admit you guys are really persistent and wish i had your knowledge on this...As i have about 300 dji TB47/48 batteries i would like to re cell and change capacity.been in touch with a few people who claim they can do but a bit dubious !

rokz12 commented 3 years ago

If you need any boards please do not hesitate

mefistotelis commented 3 years ago

I guess I could add support of BQ78350 to the comm_sbs_bqctrl.py, if you send me an example board. Assuming the unseal key isn't changed from default. But this will help you only if you know how to use this script, and which parameters to change.

mefistotelis commented 3 years ago

Made a video to popularize my SBS script. https://www.youtube.com/watch?v=P5PNOO2GebY

rokz12 commented 3 years ago

Thank you so much so nice finding someone that speaks good english and with such knowledge as well...i am good at learning maybe a bit slow as getting older.I can send board ...your address please

Keep safe

Dave

On Thu, Feb 18, 2021 at 1:19 AM mefistotelis notifications@github.com wrote:

Made a video to popularize my SBS script. https://www.youtube.com/watch?v=P5PNOO2GebY

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/o-gs/dji-firmware-tools/issues/17#issuecomment-780967007, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHXC56Q6RBMGGLUBZ3PEIGTS7RTIJANCNFSM4C7QHINQ .

mefistotelis commented 3 years ago

@rokz12 Write me an email, address is available in commit messages.

svarteld commented 3 years ago

If there's anything you'd like me to try, let me know; I've got 5x TB47 desoldered boards lying around here.

rokz12 commented 3 years ago

Great as i have an idea !.Your brains and i have loads batteries with 0 volts !.Possible replace cells with high capacity 18650.Change chemistry with ev2300...ie capacity and resistance !.Would end up with the best tb47-48 flight times available to sell !!!!.

On Fri, Feb 19, 2021 at 10:35 AM svarteld notifications@github.com wrote:

If there's anything you'd like me to try, let me know; I've got 5x TB47 desoldered boards lying around here.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/o-gs/dji-firmware-tools/issues/17#issuecomment-781989730, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHXC56SPLIPXVHG3HFQEYCTS7Y5H3ANCNFSM4C7QHINQ .

rokz12 commented 3 years ago

I HAVE BEEN SELLING ON EBAY..... https://www.ebay.co.uk/itm/133645883660

On Fri, Feb 19, 2021 at 10:40 AM David Flanagan davidflanagan65@gmail.com wrote:

Great as i have an idea !.Your brains and i have loads batteries with 0 volts !.Possible replace cells with high capacity 18650.Change chemistry with ev2300...ie capacity and resistance !.Would end up with the best tb47-48 flight times available to sell !!!!.

On Fri, Feb 19, 2021 at 10:35 AM svarteld notifications@github.com wrote:

If there's anything you'd like me to try, let me know; I've got 5x TB47 desoldered boards lying around here.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/o-gs/dji-firmware-tools/issues/17#issuecomment-781989730, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHXC56SPLIPXVHG3HFQEYCTS7Y5H3ANCNFSM4C7QHINQ .

csuwipeout commented 3 years ago

I have a P4 battery that i forgot i had and it discharged to the permeant failure flag state. I used my normal racing quad charger to bring the P4 battery up to 15V. I was nervous about charging unbalanced but I did it slow and checked the cells with my multimeter fairly often. The cells are all close and I've gone through and reset the PF flag but I am still unable to turn the battery on as well as I can't get it to take a charge with the OEM P4 charger as well as my aftermarket YT/PowerExtra charger. Am I missing something here?

PF Cleared

mefistotelis commented 3 years ago

No idea. Tried turning it on before connecting the charger?

I don't think DJI introduced their own PF state in any BQ30z55 batteries, that came later with BQ40z307. So if there's no additional lock, any issues must be due to the uC - maybe it remembers the PF?

EDIT: I see that the PF functionality is disabled in ManufacturingStatus. Did you disabled it, or was it disabled from the start?

mefistotelis commented 3 years ago

Mavic Mini battery (BQ40z307) doesn't work at 66kbit baud rate like BQ30z55. I had to reduce the frequency to 20-33kbit. EV2300 locks at 30kbit when talking to that chip.

ciasteekk commented 3 years ago

Hey, Will it work with Dji spark batteries 🔋? have 4, and all of them are dead :_ Chip - BQ9003

mefistotelis commented 3 years ago

Currently, the supported chips are: BQ30z50, BQ30z55 and BQ30z554. For all other chips, only basic SBS commands will work (ie. reading voltages or discharge current).

The chip marked as BQ9003 and identified as BQ40z307, which is used for Spark and Mini, isn't currently supported. I'm considering preparing the support, we'll see.

ciasteekk commented 3 years ago

Uh so now I can only pray, that You’ll find time to make it ;D

anyway.. thanks for quick response

mefistotelis commented 3 years ago

Which is a best public chip to treat as base for BQ40z307? Maybe BQ28z610? Or BQ40z80?

pawelsky commented 3 years ago

Did you try playing with UBRT2300? It does support BQ40z307/BQ9003, and the free version does allow you to read some basic data. You may also consider crowdfunding purchase of the UBRT2300 Red_Label_DJI license...

mefistotelis commented 3 years ago

Took a quick peek at it, UBRT doesn't seem to contain data which are directly usable as documentation. On a first look, everything there seem encrypted. So it would be a project by itself.

What I need now is a PDF which best match for BQ40z307. My current choice is BQ40z50.

pawelsky commented 3 years ago

I was more thinking of analyzing the SBUS traffic and adding basic support (at least seal/unseal and PF clearing) for this popular chip to your script based on that.

mefistotelis commented 3 years ago

@0r10nV

Me have used different hardware like Cypress EZ-USB and Silabs CP2112 as usb-to-smbus adapters at 100kHz

Do you know it there is any premade project / example which turns Cypress into I2C-USB bridge? I have no problem finding logic analyzer examples and keyboard/mouse simulator HIDs, but can't find any I2C bridge. Just bought a small cy7c68013a board.

0r10nV commented 3 years ago

yes, check Karosium project, he developed smbus library and flasher tool especially for TI and Renesas battery gauges using Cypress EZ-USB dev-board. https://github.com/karosium/smbusb

mefistotelis commented 3 years ago

The standard seal / unseal / pf reset is now working for BQ40z307. It looks like when the DJIs PF2 is set, a few values change in Data Flash of the chip. Will it be as simple as re-setting them back? I need some more test subjects, but it doesn't seem to be very complicated.

0r10nV commented 3 years ago

yes, resetting it should work... until they release new battery update) you know DJI carefully monitors all public resources on the subject of their products hacks and mods and release patches with new drone updates to close security and commercial holes found by amateurs. Some of updates even has anti-rollback options. Initially they did not care about battery PF option at all (DJI P2, I1, Osmo batteries). Since P3 they started to use it but luckily according to TI standard which was quite easy to recover. Since Spark they introduced new PFF2 which is not documented as well as custom chip now used in new design batteries. They change its functionality from release to release. It looks like now they introduced new "feature" in the Mavic Mini batteries preventing changing 18650 cells for new ones or larger capacity, even they replaced by proper hot-swap method. After recelling battery become locked for charging and locked for flying while it is still unlocked for discharging. Probably now they have new PFF3 there.

mefistotelis commented 3 years ago

Yeah, few years ago I was actually impressed when they released a new FW less than 2 weeks after we discussed a leftover debug functionality. Though I didn't know they put so much care to batteries in particular.