o-gs / dji-firmware-tools

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

Mavic Air Batteru Cannot Unseal #232

Open Lord-Lucan opened 3 years ago

Lord-Lucan commented 3 years ago

Hi, I've been using the excellent comm_sbs_bqctrl tool with a failed (fully discharged) Mavic Air Battery.

I thought I was doing quite well in recovering the battery but the tool cannot unseal it. The unseal command does not return any errors but the SECURITY_MODE is always 3, even FullAccess it stays at 3. BTW the PF flag is 0 but I cannot get the battery to charge.

So question is Have DJI changed the keys on this battery. I know is a cutom controller and is marked as BQ9003. The tool identifies it as BQ40z307 and is using default keys.

Regards, Paul

mefistotelis commented 3 years ago

In BQ9003 Dji used their modified firmware, not stock TI. The DJI firmware introduces PFF2 flag, separate from "normal" PF. As of now, I didn't implemented that. Browse the issues to find different ways.

For unsealing BQ9003 - I think I did tested that, but can't remember.

Lord-Lucan commented 3 years ago

Thanks for the reply. Do we know which bit this PFF2 flag is and in which status it resides ? Regards, Paul

mefistotelis commented 3 years ago

I didn't worked on batteries for months, I can't remember.

I found this is my notes - clearly smbus packets, probably the ones which I used to lift the flag in my experiments:

17440260407e # ManufacturerBlockAccess.DataFlashAccess 0x4060
174488 # ManufacturerBlockAccess
  4422604002040000006700006b3a00005a4f5700035344490000000000000000000000000060

174422604002040000456700006b3a00005a4f5700035344490000000000000000000000001d # ManufacturerBlockAccess.DataFlashAccess 0x4060 WRITE

17440260407e # ManufacturerBlockAccess.DataFlashAccess 0x4060
174488 # ManufacturerBlockAccess
  4422604002040000456700006b3a00005a4f5700035344490000000000000000000000000002

I probably wrote more about it in previous issues, worth checking them. You will also find the Windows tool which you could sniff to get the fields which are changed.

mefistotelis commented 3 years ago

Oh I also found a comment from WPmeister - he made his own (paid) battery tool. He suggested that besides 0x4064 and 0x4065, there is also a block at 0x4A60 which needs updating. I never verified that though.

howephillip commented 2 years ago

Updating here that unsealing works with the following: When using 'Sealing' you must set the password as it is not standard --i32key 0xCCDF7EE0

Edited to remove the chip flag as it's not necessary.

truncj commented 2 years ago

@howephillip how did you find the key for the Mavic Air? I'm working on trying to unseal a DJI Spark and assumed it was the same key, but it doesn't seem to be working. It executed correctly once using the -c flag, but it still shows sealed.

dji-firmware-tools $ ./comm_sbs_bqctrl.py -vvv --bus "i2c:3" --dev_address 0x0b --chip BQ40z50 sealing Unseal
Opening i2c:3
Importing comm_sbs_chips/BQ40z50.py
Store ManufacturerAccess.SecKeyWord0: 00 WORD=0x414
Write ManufacturerAccess: CMD=00 WORD=14 04
Store ManufacturerAccess.SecKeyWord1: 00 WORD=0x3672
Write ManufacturerAccess: CMD=00 WORD=72 36
Reading write_word_subcommand command at addr=0xb, cmd=0x0, type=uint16, opts={'subcmd': <MANUFACTURER_ACCESS_CMD_BQ40.OperationStatus: 84>}
Query ManufacturerAccess.OperationStatus: 00 WORD=0x54
Write ManufacturerAccess: CMD=00 WORD=54 00
Raw ManufacturerAccess.OperationStatus response: 04 80 77 00 00 14
MA.OperationStatus: 0x00007780  bitfields   Operational Status bits
      SYS_PRESENT_LOW:  0=Inactive  [PRES]  System present input state low
       DSG_FET_STATUS:  0=Inactive  [DSG]   Discharge FET status
       CHG_FET_STATUS:  0=Inactive  [CHG]   Charge FET Status
      PCHG_FET_STATUS:  0=Inactive  [PCHG]  Precharge FET Status
          FUSE_STATUS:  0=Inactive  [FUSE]  FUSE input status
      TRIP_POINT_INTR:  1=Active    [BTPI]  Battery Trip Point Interrupt
        SECURITY_MODE:  3=Sealed    [SEC]   Security Mode
    SHUTDOWN_LOW_VOLT:  1=Active    [SDV]   Shutdown triggered via low pack voltage
        SAFETY_STATUS:  0=Inactive  [SS]    Safety mode status
    PERMANENT_FAILURE:  1=Active    [PF]    Permanent Failure mode status
 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 SMBus command
          LED_DISPLAY:  0=Off   [LED]   LED Display state
         AUTH_ONGOING:  0=Inactive  [AUTH]  Authentication ongoing
   AUTO_CC_OFFS_CALIB:  0=Cal Done  [ACALM] Auto CC offset calibration by SMBus cmd
    RAW_ADC_CC_OUTPUT:  0=Inactive  [CALOC] Raw ADC/CC data calibration output
    RAW_CCOFFS_OUTPUT:  0=Inactive  [CALOO] Raw CC offset data calibration output
     XLOW_SPEED_STATE:  0=Inactive  [XL]    400 kHz transmission SMBus mode
          SLEEP_BY_MA:  0=Inactive  [SLEPM] SLEEP mode activated by SMBus command
     INIT_AFTER_RESET:  0=Inactive  [INIT]  Initialization after full reset
       SMB_CAL_ON_LOW:  0=Not in Cal    [SLCAL] Auto CC calibration when the bus is low
    ADC_MEAS_IN_SLEEP:  0=Inactive  [SLPAD] ADC Measurement in SLEEP mode
     CC_MEAS_IN_SLEEP:  0=Inactive  [SLPCC] Current Check measurement in SLEEP mode
       CELL_BALANCING:  0=Inactive  [CB]    Cell balancing status
   EMERGENCY_SHUTDOWN:  0=Inactive  [EMSHT] Emergency Shutdown
howephillip commented 2 years ago

@truncj That key is specific to MA batteries. I updated to remove the flag as it's not necessary for those batteries. The MA battery is like a weird bq40z50/bq40z307 hybrid for some reason so sometimes each flag can access different data here.

As for your Spark battery, you'll need to use a cp2112 + dji battery killer or UBRT with a 2300. I think you can get low-cost 2300 knockoffs from eBay if you want to go that route, but the first option is much lower cost. I think the thread right above this will get you in the right direction.

truncj commented 2 years ago

@howephillip I appreciate the info! I've got a cp2112 on its way so I'll report back.

Edit: Reporting back.. it worked!

Here are the details of how I got mine to work

Supplies: DJI Spark Battery (0% capacity) DJI Hub Power Supply CP2112 Adapter from Newegg ($15.99) <- requires a soldering iron Dupont wires

I connected the wires according to this youtube walkthrough + pinout diagrams

Since my batteries had 0% charge, I needed to supply ~13v 3.8a in order for the SMBus to recognize it. I don't own a variable power supply so I used the original DJI battery charging hub (can charge 3 batteries at once) and connected alligator clips + dupont wires from the +/- of the charging hub wire to the battery itself (no splicing needed).

Once the battery started showing the charging indicator, I clicked "read info" in DJI Battery Killer, clicked "Unseal" -> "clear PF" -> "clear PF2" -> "Seal"... and that was it!

Side note: I did this on an M1 Mac running Parallels 17 with Windows 11 ARM64. If you get DLL problems, make sure install all versions of the Microsoft Visual C++ Redistributable including x86 & x64, not just the ARM64 version.

Wolkex3 commented 1 year ago

Since my batteries had 0% charge, I needed to supply ~13v 3.8a in order for the SMBus to recognize it. I don't own a variable power supply so I used the original DJI battery charging hub (can charge 3 batteries at once) and connected alligator clips + dupont wires from the +/- of the charging hub wire to the battery itself (no splicing needed).

Hi @truncj , I have the same issue. Could you explain a little bit more how to connect the wires? There 2 + and 2 - pins right? Dont want to make a mistake here.

TIA!

badger200 commented 1 year ago

@Wolkex3 i was able to use a 9V battery to power the bus while I connected it to the cp2112! Revived 4 Spark batteries that way. I think it was the 2 outside pins and then 2 near the middle. A power, a ground, and then the SDA and SCL bus data lines to the CP2112. Obviously attach the power to the +/- but common ground with the CP2112 @truncj

hlyl commented 1 year ago

@badger200 or @truncj - if possible i would love some additional details on the wiring, as i am now waiting for my CP2112 to arrive.

badger200 commented 1 year ago

@hlyl i just used alligator clips with paper clips bent for pins into the connector, using the 4 wires I mentioned immediately above.

iulisan commented 1 year ago

Hello.As I expect my cp2112 to arrive , i want know if there is anybody who knows the telegram cannel to join the chat.Thnaks.

okstuv commented 9 months ago

Updating here that unsealing works with the following: When using 'Sealing' you must set the password as it is not standard --i32key 0xCCDF7EE0

Edited to remove the chip flag as it's not necessary.

Thanks for sharing this unsealing key. It worked to unseal my DJI mini 2 battery. I used this syntax for the unsealing command specifically:

./comm_sbs_bqctrl.py -vvv -a 0x0b sealing --i32key 0xCCDF7EE0 Unseal

Note in the above script that my battery was using the 0x0b i2c address, other people may have a different i2c address for their battery.