static void clear_helper(struct dev_context *devc)
{
- ftdi_deinit(&devc->ftdic);
+ (void)sigma_force_close(devc);
}
static int dev_clear(const struct sr_dev_driver *di)
devc->id.serno = serno_num;
devc->id.prefix = serno_pre;
devc->id.type = dev_type;
- devc->samplerate = samplerates[0];
sr_sw_limits_init(&devc->cfg_limits);
- devc->firmware_idx = SIGMA_FW_NONE;
devc->capture_ratio = 50;
devc->use_triggers = 0;
+
+ /* TODO Retrieve some of this state from hardware? */
+ devc->firmware_idx = SIGMA_FW_NONE;
+ devc->samplerate = samplerates[0];
}
libusb_free_device_list(devlist, 1);
g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free);
static int dev_open(struct sr_dev_inst *sdi)
{
struct dev_context *devc;
- long vid, pid;
- const char *serno;
- int ret;
devc = sdi->priv;
sr_err("OMEGA support is not implemented yet.");
return SR_ERR_NA;
}
- vid = devc->id.vid;
- pid = devc->id.pid;
- serno = sdi->serial_num;
-
- ret = ftdi_init(&devc->ftdic);
- if (ret < 0) {
- sr_err("Cannot initialize FTDI context (%d): %s.",
- ret, ftdi_get_error_string(&devc->ftdic));
- return SR_ERR_IO;
- }
- ret = ftdi_usb_open_desc_index(&devc->ftdic, vid, pid, NULL, serno, 0);
- if (ret < 0) {
- sr_err("Cannot open device (%d): %s.",
- ret, ftdi_get_error_string(&devc->ftdic));
- return SR_ERR_IO;
- }
- return SR_OK;
+ return sigma_force_open(sdi);
}
static int dev_close(struct sr_dev_inst *sdi)
{
struct dev_context *devc;
- int ret;
devc = sdi->priv;
- ret = ftdi_usb_close(&devc->ftdic);
- ftdi_deinit(&devc->ftdic);
-
- return (ret == 0) ? SR_OK : SR_ERR;
+ return sigma_force_close(devc);
}
static int config_get(uint32_t key, GVariant **data,
#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.
*
{
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;
{
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.");
}
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
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;
}
}
/* 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)
;
uint16_t prefix;
enum asix_device_type type;
} id;
- struct ftdi_context ftdic;
+ struct {
+ struct ftdi_context ctx;
+ gboolean is_open, must_close;
+ } ftdi;
uint64_t samplerate;
struct sr_sw_limits cfg_limits; /* Configured limits (user specified). */
struct sr_sw_limits acq_limits; /* Acquisition limits (internal use). */
extern SR_PRIV const uint64_t samplerates[];
extern SR_PRIV const size_t samplerates_count;
+/* "Automatic" and forced USB connection open/close support. */
+SR_PRIV int sigma_check_open(const struct sr_dev_inst *sdi);
+SR_PRIV int sigma_check_close(struct dev_context *devc);
+SR_PRIV int sigma_force_open(const struct sr_dev_inst *sdi);
+SR_PRIV int sigma_force_close(struct dev_context *devc);
+
SR_PRIV int sigma_write_register(struct dev_context *devc,
uint8_t reg, uint8_t *data, size_t len);
SR_PRIV int sigma_set_register(struct dev_context *devc,