tillitis / tillitis-key1

Board designs, FPGA verilog, firmware for TKey, the flexible and open USB security key 🔑
https://www.tillitis.se
386 stars 24 forks source link

cannot program again after aborting with ctrl-c #110

Closed quite closed 1 year ago

quite commented 1 year ago

If I run tillitis-iceprog, and abort it using ctrl-c, then i cannot run it again -- it hangs after saying it has raw power. It does not matter if there is a usb stick sitting in the jig or not. The programmer has to be re-plugged to get it working again.

quite commented 1 year ago

I think this regression is since we went raw_usb

cibomahto commented 1 year ago

This is probably because the usb device isn't released properly when the program is interrupted by SIGINT.

I think the correct way to fix that is (in rpi_pico_interface.c) to install a signal handler after iceprog claims the device, something like this:

void close_on_sigint(int unused) {
    close(); // Call the close routine to release the USB device
}

And register the handler before printing the 'raw power' message :

signal(SIGINT, close_on_sigint);

The previous communication protocol used HID, and this might have been handled automatically by the hidapi library, or might not have been needed if it used the kernel HID interface instead of the USB interface.

quite commented 1 year ago

Sounded very plausible. But I investigated a bit more now, and see that it doesn't actually hang. Instead, things go very slowly. Every pin_set_direction takes 1s or so. Eventually after maybe 30s it prints erase 64kB sector at 0x000000.. and is still ongoing.

quite commented 1 year ago

doing the close() on SIGINT also does not help.

quite commented 1 year ago

Can you reproduce? Maybe this is on my AMD laptop, that also did not benefit from any speed increase by raw_usb heh

quite commented 1 year ago

Seems ctrl-c:ing does not cause problems on Intel laptop

quite commented 1 year ago

seems a call to flash_release_reset() was what was needed. But I think i'm gonna catch SIGINT in main, let the handler set a gobal bool to true and let while/for loops stop when that is true. And if interrupted probably exit the program with code 1.

cibomahto commented 1 year ago

Hmm, if it's related to the SPI interface and not the USB interface, then the root cause is probably the SPI/CS/RESET initialization routine expecting a certain state (and not working correctly otherwise).

Trapping the sigint and putting the programmer back into a known state is a kind thing to do for the next program that uses it, so if that sidesteps the deficiency in the initialization, it seems reasonable.

quite commented 1 year ago

I implemented the ctrl-c bailout that solves the issue (since there was no issue when iceprog is allowed to run without interruption).