X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fasix-sigma%2Fprotocol.c;h=80e60706085fd110bf75befda024ae5b46180118;hb=b65649f6b9dca28829e4f242ae79c75db767fdfa;hp=9819e892508632e73bb2c8a7326b083acefed5c6;hpb=80e717b3cfac82d63c98614fe6179fb0e4fdaf8d;p=libsigrok.git diff --git a/src/hardware/asix-sigma/protocol.c b/src/hardware/asix-sigma/protocol.c index 9819e892..80e60706 100644 --- a/src/hardware/asix-sigma/protocol.c +++ b/src/hardware/asix-sigma/protocol.c @@ -27,22 +27,22 @@ #include "protocol.h" /* - * The ASIX Sigma supports arbitrary integer frequency divider in - * the 50MHz mode. The divider is in range 1...256 , allowing for - * very precise sampling rate selection. This driver supports only - * a subset of the sampling rates. + * The ASIX SIGMA hardware supports fixed 200MHz and 100MHz sample rates + * (by means of separate firmware images). As well as 50MHz divided by + * an integer divider in the 1..256 range (by the "typical" firmware). + * Which translates to a strict lower boundary of around 195kHz. + * + * This driver "suggests" a subset of the available rates by listing a + * few discrete values, while setter routines accept any user specified + * rate that is supported by the hardware. */ SR_PRIV const uint64_t samplerates[] = { - SR_KHZ(200), /* div=250 */ - SR_KHZ(250), /* div=200 */ - SR_KHZ(500), /* div=100 */ - SR_MHZ(1), /* div=50 */ - SR_MHZ(5), /* div=10 */ - SR_MHZ(10), /* div=5 */ - SR_MHZ(25), /* div=2 */ - SR_MHZ(50), /* div=1 */ - SR_MHZ(100), /* Special FW needed */ - SR_MHZ(200), /* Special FW needed */ + /* 50MHz and integer divider. 1/2/5 steps (where possible). */ + SR_KHZ(200), SR_KHZ(500), + SR_MHZ(1), SR_MHZ(2), SR_MHZ(5), + SR_MHZ(10), SR_MHZ(25), SR_MHZ(50), + /* 100MHz/200MHz, fixed rates in special firmware. */ + SR_MHZ(100), SR_MHZ(200), }; SR_PRIV const size_t samplerates_count = ARRAY_SIZE(samplerates); @@ -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. */