#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);
/*
* 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,
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. */
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.
*/