]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/asix-sigma/protocol.c
asix-sigma: rephrase firmware dependent param upload at acquisition start
[libsigrok.git] / src / hardware / asix-sigma / protocol.c
index 60970a8d89d498755959ae8575b0d0756bfe6617..2aec141a691345ac56879dfac98d35a881f96b84 100644 (file)
@@ -37,7 +37,7 @@
  * few discrete values, while setter routines accept any user specified
  * rate that is supported by the hardware.
  */
-SR_PRIV const uint64_t samplerates[] = {
+static const uint64_t samplerates[] = {
        /* 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),
@@ -46,7 +46,10 @@ SR_PRIV const uint64_t samplerates[] = {
        SR_MHZ(100), SR_MHZ(200),
 };
 
-SR_PRIV const size_t samplerates_count = ARRAY_SIZE(samplerates);
+SR_PRIV GVariant *sigma_get_samplerates_list(void)
+{
+       return std_gvar_samplerates(samplerates, ARRAY_SIZE(samplerates));
+}
 
 static const char *firmware_files[] = {
        [SIGMA_FW_50MHZ] = "asix-sigma-50.fw", /* 50MHz, 8bit divider. */
@@ -58,6 +61,119 @@ static const char *firmware_files[] = {
 
 #define SIGMA_FIRMWARE_SIZE_LIMIT (256 * 1024)
 
+static int sigma_ftdi_open(const struct sr_dev_inst *sdi)
+{
+       struct dev_context *devc;
+       int vid, pid;
+       const char *serno;
+       int ret;
+
+       devc = sdi->priv;
+       if (!devc)
+               return SR_ERR_ARG;
+
+       if (devc->ftdi.is_open)
+               return SR_OK;
+
+       vid = devc->id.vid;
+       pid = devc->id.pid;
+       serno = sdi->serial_num;
+       if (!vid || !pid || !serno || !*serno)
+               return SR_ERR_ARG;
+
+       ret = ftdi_init(&devc->ftdi.ctx);
+       if (ret < 0) {
+               sr_err("Cannot initialize FTDI context (%d): %s.",
+                       ret, ftdi_get_error_string(&devc->ftdi.ctx));
+               return SR_ERR_IO;
+       }
+       ret = ftdi_usb_open_desc_index(&devc->ftdi.ctx,
+               vid, pid, NULL, serno, 0);
+       if (ret < 0) {
+               sr_err("Cannot open device (%d): %s.",
+                       ret, ftdi_get_error_string(&devc->ftdi.ctx));
+               return SR_ERR_IO;
+       }
+       devc->ftdi.is_open = TRUE;
+
+       return SR_OK;
+}
+
+static int sigma_ftdi_close(struct dev_context *devc)
+{
+       int ret;
+
+       ret = ftdi_usb_close(&devc->ftdi.ctx);
+       devc->ftdi.is_open = FALSE;
+       devc->ftdi.must_close = FALSE;
+       ftdi_deinit(&devc->ftdi.ctx);
+
+       return ret == 0 ? SR_OK : SR_ERR_IO;
+}
+
+SR_PRIV int sigma_check_open(const struct sr_dev_inst *sdi)
+{
+       struct dev_context *devc;
+       int ret;
+
+       if (!sdi)
+               return SR_ERR_ARG;
+       devc = sdi->priv;
+       if (!devc)
+               return SR_ERR_ARG;
+
+       if (devc->ftdi.is_open)
+               return SR_OK;
+
+       ret = sigma_ftdi_open(sdi);
+       if (ret != SR_OK)
+               return ret;
+       devc->ftdi.must_close = TRUE;
+
+       return ret;
+}
+
+SR_PRIV int sigma_check_close(struct dev_context *devc)
+{
+       int ret;
+
+       if (!devc)
+               return SR_ERR_ARG;
+
+       if (devc->ftdi.must_close) {
+               ret = sigma_ftdi_close(devc);
+               if (ret != SR_OK)
+                       return ret;
+               devc->ftdi.must_close = FALSE;
+       }
+
+       return SR_OK;
+}
+
+SR_PRIV int sigma_force_open(const struct sr_dev_inst *sdi)
+{
+       struct dev_context *devc;
+       int ret;
+
+       if (!sdi)
+               return SR_ERR_ARG;
+       devc = sdi->priv;
+       if (!devc)
+               return SR_ERR_ARG;
+
+       ret = sigma_ftdi_open(sdi);
+       if (ret != SR_OK)
+               return ret;
+       devc->ftdi.must_close = FALSE;
+
+       return SR_OK;
+}
+
+SR_PRIV int sigma_force_close(struct dev_context *devc)
+{
+       return sigma_ftdi_close(devc);
+}
+
 /*
  * BEWARE! Error propagation is important, as are kinds of return values.
  *
@@ -77,10 +193,10 @@ static int sigma_read_raw(struct dev_context *devc, void *buf, size_t size)
 {
        int ret;
 
-       ret = ftdi_read_data(&devc->ftdic, (unsigned char *)buf, size);
+       ret = ftdi_read_data(&devc->ftdi.ctx, (unsigned char *)buf, size);
        if (ret < 0) {
                sr_err("USB data read failed: %s",
-                       ftdi_get_error_string(&devc->ftdic));
+                       ftdi_get_error_string(&devc->ftdi.ctx));
        }
 
        return ret;
@@ -90,10 +206,10 @@ static int sigma_write_raw(struct dev_context *devc, const void *buf, size_t siz
 {
        int ret;
 
-       ret = ftdi_write_data(&devc->ftdic, buf, size);
+       ret = ftdi_write_data(&devc->ftdi.ctx, buf, size);
        if (ret < 0) {
                sr_err("USB data write failed: %s",
-                       ftdi_get_error_string(&devc->ftdic));
+                       ftdi_get_error_string(&devc->ftdi.ctx));
        } else if ((size_t)ret != size) {
                sr_err("USB data write length mismatch.");
        }
@@ -342,10 +458,13 @@ SR_PRIV int sigma_write_trigger_lut(struct dev_context *devc,
                wrptr = buf;
                write_u8_inc(&wrptr, tmp[0]);
                write_u8_inc(&wrptr, tmp[1]);
-               ret = sigma_write_register(devc, WRITE_TRIGGER_SELECT, buf, wrptr - buf);
+               ret = sigma_write_register(devc, WRITE_TRIGGER_SELECT,
+                       buf, wrptr - buf);
                if (ret != SR_OK)
                        return ret;
-               ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, 0x30 | i);
+               ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2,
+                       TRGSEL2_RESET | TRGSEL2_LUT_WRITE |
+                       (i & TRGSEL2_LUT_ADDR_MASK));
                if (ret != SR_OK)
                        return ret;
        }
@@ -459,7 +578,7 @@ static int sigma_fpga_init_bitbang_once(struct dev_context *devc)
        if (ret != SR_OK)
                return ret;
        g_usleep(10 * 1000);
-       ftdi_usb_purge_buffers(&devc->ftdic);
+       ftdi_usb_purge_buffers(&devc->ftdi.ctx);
 
        /*
         * Wait until the FPGA asserts INIT_B. Check in a maximum number
@@ -677,16 +796,16 @@ static int upload_firmware(struct sr_context *ctx, struct dev_context *devc,
        devc->state.state = SIGMA_CONFIG;
 
        /* Set the cable to bitbang mode. */
-       ret = ftdi_set_bitmode(&devc->ftdic, BB_PINMASK, BITMODE_BITBANG);
+       ret = ftdi_set_bitmode(&devc->ftdi.ctx, BB_PINMASK, BITMODE_BITBANG);
        if (ret < 0) {
                sr_err("Could not setup cable mode for upload: %s",
-                       ftdi_get_error_string(&devc->ftdic));
+                       ftdi_get_error_string(&devc->ftdi.ctx));
                return SR_ERR;
        }
-       ret = ftdi_set_baudrate(&devc->ftdic, BB_BITRATE);
+       ret = ftdi_set_baudrate(&devc->ftdi.ctx, BB_BITRATE);
        if (ret < 0) {
                sr_err("Could not setup bitrate for upload: %s",
-                       ftdi_get_error_string(&devc->ftdic));
+                       ftdi_get_error_string(&devc->ftdi.ctx));
                return SR_ERR;
        }
 
@@ -714,13 +833,13 @@ static int upload_firmware(struct sr_context *ctx, struct dev_context *devc,
        }
 
        /* Leave bitbang mode and discard pending input data. */
-       ret = ftdi_set_bitmode(&devc->ftdic, 0, BITMODE_RESET);
+       ret = ftdi_set_bitmode(&devc->ftdi.ctx, 0, BITMODE_RESET);
        if (ret < 0) {
                sr_err("Could not setup cable mode after upload: %s",
-                       ftdi_get_error_string(&devc->ftdic));
+                       ftdi_get_error_string(&devc->ftdi.ctx));
                return SR_ERR;
        }
-       ftdi_usb_purge_buffers(&devc->ftdic);
+       ftdi_usb_purge_buffers(&devc->ftdi.ctx);
        while (sigma_read_raw(devc, &pins, sizeof(pins)) > 0)
                ;
 
@@ -851,6 +970,13 @@ SR_PRIV int sigma_normalize_samplerate(uint64_t want_rate, uint64_t *have_rate)
        return SR_ERR_ARG;
 }
 
+SR_PRIV uint64_t sigma_get_samplerate(const struct sr_dev_inst *sdi)
+{
+       /* TODO Retrieve value from hardware. */
+       (void)sdi;
+       return samplerates[0];
+}
+
 SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
@@ -1676,7 +1802,7 @@ static void add_trigger_function(enum triggerop oper, enum triggerfunc func,
 SR_PRIV int sigma_build_basic_trigger(struct dev_context *devc,
        struct triggerlut *lut)
 {
-       int i,j;
+       int i, j;
        uint16_t masks[2];
 
        memset(lut, 0, sizeof(*lut));