greatscottgadgets / pyfwup

Python FirmWare UPgrader -- a DFU (and similar) utility for python
BSD 3-Clause "New" or "Revised" License
22 stars 7 forks source link

Commit 15d2a91 breaks update via dfu-stub #10

Closed lancelot666de closed 1 month ago

lancelot666de commented 1 month ago

The commit 15d2a91 breaks the firmware update via dfu stub:

greatfet_fw -d --dfu-stub flash_stub.bin -w firmware.bin 
Traceback (most recent call last):
  File "/tmp/venv/bin/greatfet_fw", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/tmp/venv/lib/python3.11/site-packages/greatfet/commands/greatfet_firmware.py", line 192, in main
    load_dfu_stub(dfu_stub_path)
  File "/tmp/venv/lib/python3.11/site-packages/greatfet/commands/greatfet_firmware.py", line 112, in load_dfu_stub
    dfu_target.program(dfu_stub)
  File "/tmp/venv/lib/python3.11/site-packages/fwup/lpc43xx.py", line 59, in program
    super(LPC43xxTarget, self).program(program_data, status_callback)
  File "/tmp/venv/lib/python3.11/site-packages/fwup/dfu.py", line 278, in program
    self.__raw_write_page(page_address, data_to_program)
  File "/tmp/venv/lib/python3.11/site-packages/fwup/dfu.py", line 248, in __raw_write_page
    self.__dfu_out_request(self.DFU_DOWNLOAD, block_number, data)
  File "/tmp/venv/lib/python3.11/site-packages/fwup/dfu.py", line 191, in __dfu_out_request
    self.device.ctrl_transfer(self.USB_CLASS_OUT_REQUEST_TO_INTERFACE, request, value,
  File "/tmp/venv/lib/python3.11/site-packages/usb/core.py", line 1082, in ctrl_transfer
    ret = self._ctx.backend.ctrl_transfer(
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib/python3.11/site-packages/usb/backend/libusb1.py", line 893, in ctrl_transfer
    ret = _check(self.lib.libusb_control_transfer(
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/venv/lib/python3.11/site-packages/usb/backend/libusb1.py", line 604, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 32] Pipe error

With the previous commit e61b9c6 the update via dfu stub works.

mossmann commented 1 month ago

I happened to see the exact same error with an older Saturn-V earlier today. I resolved it by upgrading Saturn-V. git bisect tells me that this was fixed for Saturn-V in: https://github.com/greatscottgadgets/saturn-v/pull/7/commits/f0d674dbf4431ba3873cfa2dd2f1c7fd30d053d7

mossmann commented 1 month ago

In GreatFET's case, this is an interaction between the NXP DFU bootloader (in ROM) and pyfwup. I have reproduced the error with HackRF One which has the same bootloader.

I notice that the DFU interface descriptor indicates that it is in run-time mode, but otherwise it acts as if it is in DFU mode. So I think the root cause of the error is a bug in the NXP DFU bootloader, but we need to work around it.

mossmann commented 1 month ago

I reproduced the error by putting a GreatFET One in DFU mode and then: gf fw -d --autoflash

mossmann commented 1 month ago

@lancelot666de Can you please test #11 to confirm that it fixes your problem?

lancelot666de commented 1 month ago

@mossmann #11 fixes this issue. I could flash the firmware:

greatfet_fw -d --dfu-stub flash_stub.bin -w firmware.bin 
Trying to find a GreatFET device...
libgreat compatible board in flash-stub mode found. (Serial number: 0000909469e6362158e3)
Writing data to SPI flash...

Write complete!
Resetting GreatFET...
Reset complete!

Thank you!