X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fasix-sigma%2Fprotocol.c;h=02b4b658bd7c2c91a81bf13393f252106f8a519d;hb=7fe1f91f7550d63ea4a09c0f0e1ce5b88c59c6fb;hp=60970a8d89d498755959ae8575b0d0756bfe6617;hpb=88a5f9eabe72113d70c29d45dc12eabc0add9c49;p=libsigrok.git diff --git a/src/hardware/asix-sigma/protocol.c b/src/hardware/asix-sigma/protocol.c index 60970a8d..02b4b658 100644 --- a/src/hardware/asix-sigma/protocol.c +++ b/src/hardware/asix-sigma/protocol.c @@ -58,6 +58,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 +190,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 +203,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."); } @@ -459,7 +572,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 +790,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 +827,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) ;