`scons.py` - misorders `extra_args` to `dfu-util`
benagricola opened this issue · 11 comments
Trying to program a pico-ice using apio upload
, triggering dfu-util
and receiving the following error:
(base) ➜ fpga git:(main) ✗ apio upload
[Mon Apr 29 20:42:46 2024] Processing pico-ice
---
dfu-util -d 1209:b1c0 -a 0 -D --reset hardware.bin
Error: Unexpected argument: hardware.bin
Usage: dfu-util [options] ...
This is because the --reset
argument is inserted between the -D
arg and the build file.
My quick fix for this locally was to put the extra_args
block above the args
block but I don't know if this would cause issues with other programmers.
@zapta I've given you rights to manage pull request and issues. Now you should be able to close issues opened by others. Thanks a lot for your work. You are on fire! :-)
I'm still getting this error - I installed with pip install apio
. Do I need a workaround or is there a fix in the works?
❯ apio upload
[Mon Sep 30 19:38:20 2024] Processing pico-ice
---------------------------------------------------------------------------------------------------------------
dfu-util -d 1209:b1c0 -a 0 -D --reset hardware.bin
Error: Unexpected argument: hardware.bin
Usage: dfu-util [options] ...
-h --help Print this help message
-V --version Print the version number
-v --verbose Print verbose debug statements
-l --list List currently attached DFU capable devices
-e --detach Detach currently attached DFU capable devices
-E --detach-delay seconds Time to wait before reopening a device after detach
-d --device <vendor>:<product>[,<vendor_dfu>:<product_dfu>]
Specify Vendor/Product ID(s) of DFU device
-n --devnum <dnum> Match given device number (devnum from --list)
-p --path <bus-port. ... .port> Specify path to DFU device
-c --cfg <config_nr> Specify the Configuration of DFU device
-i --intf <intf_nr> Specify the DFU Interface number
-S --serial <serial_string>[,<serial_string_dfu>]
Specify Serial String of DFU device
-a --alt <alt> Specify the Altsetting of the DFU Interface
by name or by number
-t --transfer-size <size> Specify the number of bytes per USB Transfer
-U --upload <file> Read firmware from device into <file>
-Z --upload-size <bytes> Specify the expected upload size in bytes
-D --download <file> Write firmware from <file> into device
-R --reset Issue USB Reset signalling once we're finished
-w --wait Wait for device to appear
-s --dfuse-address address<:...> ST DfuSe mode string, specifying target
address for raw file download or upload (not
applicable for DfuSe file (.dfu) downloads).
Add more DfuSe options separated with ':'
leave Leave DFU mode (jump to application)
mass-erase Erase the whole device (requires "force")
unprotect Erase read protected device (requires "force")
will-reset Expect device to reset (e.g. option bytes write)
force You really know what you are doing!
<length> Length of firmware to upload from device
scons: *** [upload] Error 64
========================================= [ ERROR ] Took 0.10 seconds =========================================
Hi @znmeb, The fix will be included in the next stable release. Meanwhile, here is a workaround that will allow you to work with your board.
- Locate the pip packages directory.
Type pip show apio
and identify the packages directory marked as Location:
. Change to that directory and you will find there a directory called apio
- Remove the
--reset
from the board definition.
Edit the file apio/resources/boards.json
and remove the extra args
line for your board. To test, run apio upload
and make sure the --reset
is not gone from the dfu command.
apio/apio/resources/boards.json
Line 603 in 160aae7
- Add the "--reset" at the end of the generated programmer command.
Edit the file apio/resources/ice40/SConstruct
and change the upload target line
apio/apio/resources/ice40/SConstruct
Line 178 in a4b839e
from
upload_target = env.Alias('upload', bitstream_target, '{0} $SOURCE'.format(PROG))
to (adding --reset
after $SOURCE
)
upload_target = env.Alias('upload', bitstream_target, '{0} $SOURCE --reset'.format(PROG))
To undo the patch run pip uninstall apio
and then pip install apio
. Let us know if any have any questions.
OK ... it's working as far as I can tell. There is an apparently spurious error at the end; it looks like it's resetting twice when it only needs to reset once:
❯ apio build --top-module top
Warning! No TOP-MODULE in apio.ini
[Thu Oct 3 14:59:08 2024] Processing pico-ice
---------------------------------------------------------------------------------------------------------------
yosys -p "synth_ice40 -top top -json hardware.json" -q top.v
nextpnr-ice40 --up5k --package sg48 --json hardware.json --asc hardware.asc --pcf up5k.pcf -q
icepack hardware.asc hardware.bin
========================================= [SUCCESS] Took 0.86 seconds =========================================
❯ apio upload --top-module top
Warning! No TOP-MODULE in apio.ini
[Thu Oct 3 14:59:20 2024] Processing pico-ice
---------------------------------------------------------------------------------------------------------------
dfu-util -d 1209:b1c0 -a 0 -D hardware.bin --reset
dfu-util 0.11-dev
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
dfu-util: Warning: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release
Opening DFU capable USB device...
Device ID 1209:b1c0
Run-Time device DFU version 0101
Claiming USB DFU Interface...
Setting Alternate Interface #0 ...
Determining device status...
DFU state(2) = dfuIDLE, status(0) = No error condition is present
DFU mode device DFU version 0101
Device returned transfer size 256
Copying data from PC to DFU device
Download [=========================] 100% 104090 bytes
Download done.
DFU state(7) = dfuMANIFEST, status(0) = No error condition is present
DFU state(8) = dfuMANIFEST-WAIT-RESET, status(0) = No error condition is present
Resetting USB to switch back to runtime mode
Done!
Resetting USB to switch back to Run-Time mode
dfu-util: error resetting after download: LIBUSB_ERROR_OTHER
scons: *** [upload] Error 74
========================================= [ ERROR ] Took 3.52 seconds =========================================
Thanks all for taking care of the maintenance of the dfu-util
invocation!
The double-reset does not seem to be an APIO bug.
-
The first reset is because
dfu-util
detects that the board is in "waiting reset" mode:
https://sourceforge.net/p/dfu-util/dfu-util/ci/master/tree/src/dfu_load.c#l204 -
The second reset because
dfu-util
was asked to reset the board explicitly:
https://sourceforge.net/p/dfu-util/dfu-util/ci/master/tree/src/main.c#l780
It might not be required to reset the board twice though.
Not sure why this was not working before... The MANIFEST_SYNC
DFU status tells the host that the transfer is done, and was there since a long time.
The board is likely up and running despite the error message.
Yes, the board is definitely up and running - I verified that with both of the "ice_apio" examples.
Thanks for the update. What is the conclusion regarding that board, does it require the --reset at the end or is it better without it?
https://github.com/FPGAwars/apio/blob/develop/apio/resources/boards.json#L610
Thanks for the update. What is the conclusion regarding that board, does it require the --reset at the end or is it better without it?
Sorry for the long delay, we were preparing an event and now it is over.
Maybe it is good to keep the --reset
for now. Then we may be able to tests on several platforms again at next release to be sure that it is not required at all.
Thank you all for investigating this situation!