From: Gerhard Sittig Date: Tue, 12 May 2020 05:59:54 +0000 (+0200) Subject: asix-sigma: improve robustness of firmware download, delay and retry X-Git-Url: http://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=c749d1ca5755fe8b7f3e3fd914655b1a1d1e3a71 asix-sigma: improve robustness of firmware download, delay and retry Running several firmware uploads in quick repetition sometimes failed. It's essential to stop the active netlist from preventing the FPGA's getting reconfigured (FTDI to FPGA pins are so few, and shared). Delays in a single iteration of the initiation sequence improves reliability. Retries of the sequence are belt and suspenders on top of that. Before the change, failure to configure was roughly one in ten. After the change, several thousand reconfigurations passed without failure. --- diff --git a/src/hardware/asix-sigma/protocol.c b/src/hardware/asix-sigma/protocol.c index 9819e892..68bb83e5 100644 --- a/src/hardware/asix-sigma/protocol.c +++ b/src/hardware/asix-sigma/protocol.c @@ -313,10 +313,16 @@ SR_PRIV int sigma_write_trigger_lut(struct triggerlut *lut, struct dev_context * /* * Initiate slave serial mode for configuration download. Which is done * by pulsing PROG_B and sensing INIT_B. Make sure CCLK is idle before - * initiating the configuration download. Run a "suicide sequence" first - * to terminate the regular FPGA operation before reconfiguration. + * initiating the configuration download. + * + * Run a "suicide sequence" first to terminate the regular FPGA operation + * before reconfiguration. The FTDI cable is single channel, and shares + * pins which are used for data communication in FIFO mode with pins that + * are used for FPGA configuration in bitbang mode. Hardware defaults for + * unconfigured hardware, and runtime conditions after FPGA configuration + * need to cooperate such that re-configuration of the FPGA can start. */ -static int sigma_fpga_init_bitbang(struct dev_context *devc) +static int sigma_fpga_init_bitbang_once(struct dev_context *devc) { uint8_t suicide[] = { BB_PIN_D7 | BB_PIN_D2, @@ -348,9 +354,11 @@ static int sigma_fpga_init_bitbang(struct dev_context *devc) sigma_write(suicide, sizeof(suicide), devc); sigma_write(suicide, sizeof(suicide), devc); sigma_write(suicide, sizeof(suicide), devc); + g_usleep(10 * 1000); /* Section 2. part 2), pulse PROG. */ sigma_write(init_array, sizeof(init_array), devc); + g_usleep(10 * 1000); ftdi_usb_purge_buffers(&devc->ftdic); /* Wait until the FPGA asserts INIT_B. */ @@ -367,6 +375,27 @@ static int sigma_fpga_init_bitbang(struct dev_context *devc) return SR_ERR_TIMEOUT; } +/* + * This is belt and braces. Re-run the bitbang initiation sequence a few + * times should first attempts fail. Failure is rare but can happen (was + * observed during driver development). + */ +static int sigma_fpga_init_bitbang(struct dev_context *devc) +{ + size_t retries; + int ret; + + retries = 10; + while (retries--) { + ret = sigma_fpga_init_bitbang_once(devc); + if (ret == SR_OK) + return ret; + if (ret != SR_ERR_TIMEOUT) + return ret; + } + return ret; +} + /* * Configure the FPGA for logic-analyzer mode. */