#include <ftdi.h>
#include <glib.h>
#include <string.h>
-#include "sigrok.h"
-#include "sigrok-internal.h"
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
#include "driver.h"
-static GSList *dev_insts = NULL;
+SR_PRIV struct sr_dev_driver chronovu_la8_driver_info;
+static struct sr_dev_driver *cdi = &chronovu_la8_driver_info;
+
+/*
+ * The ChronoVu LA8 can have multiple PIDs. Older versions shipped with
+ * a standard FTDI USB VID/PID of 0403:6001, newer ones have 0403:8867.
+ */
+static const uint16_t usb_pids[] = {
+ 0x6001,
+ 0x8867,
+};
/* Function prototypes. */
static int hw_dev_acquisition_stop(int dev_index, void *cb_data);
-static int hw_init(const char *devinfo)
+static int hw_init(void)
+{
+
+ /* Nothing to do. */
+
+ return SR_OK;
+}
+
+static int hw_scan(void)
{
int ret;
struct sr_dev_inst *sdi;
struct context *ctx;
-
- /* Avoid compiler errors. */
- (void)devinfo;
+ unsigned int i;
/* Allocate memory for our private driver context. */
if (!(ctx = g_try_malloc(sizeof(struct context)))) {
ctx->done = 0;
ctx->block_counter = 0;
ctx->divcount = 0; /* 10ns sample period == 100MHz samplerate */
+ ctx->usb_pid = 0;
/* Allocate memory where we'll store the de-mangled data. */
if (!(ctx->final_buf = g_try_malloc(SDRAM_SIZE))) {
}
/* Check for the device and temporarily open it. */
- if ((ret = ftdi_usb_open_desc(ctx->ftdic, USB_VENDOR_ID,
- USB_PRODUCT_ID, USB_DESCRIPTION, NULL)) < 0) {
- (void) la8_close_usb_reset_sequencer(ctx); /* Ignore errors. */
- goto err_free_ftdic;
+ for (i = 0; i < ARRAY_SIZE(usb_pids); i++) {
+ sr_dbg("la8: Probing for VID/PID %04x:%04x.", USB_VENDOR_ID,
+ usb_pids[i]);
+ ret = ftdi_usb_open_desc(ctx->ftdic, USB_VENDOR_ID,
+ usb_pids[i], USB_DESCRIPTION, NULL);
+ if (ret == 0) {
+ sr_dbg("la8: Found LA8 device (%04x:%04x).",
+ USB_VENDOR_ID, usb_pids[i]);
+ ctx->usb_pid = usb_pids[i];
+ }
}
- sr_dbg("la8: Found LA8 device (%04x:%04x).", USB_VENDOR_ID,
- USB_PRODUCT_ID);
+
+ if (ctx->usb_pid == 0)
+ goto err_free_ftdic;
/* Register the device with libsigrok. */
sdi = sr_dev_inst_new(0, SR_ST_INITIALIZING,
sdi->priv = ctx;
- dev_insts = g_slist_append(dev_insts, sdi);
+ cdi->instances = g_slist_append(cdi->instances, sdi);
sr_spew("la8: Device init successful.");
struct sr_dev_inst *sdi;
struct context *ctx;
- if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+ if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
sr_err("la8: %s: sdi was NULL", __func__);
return SR_ERR_BUG;
}
}
sr_dbg("la8: Opening LA8 device (%04x:%04x).", USB_VENDOR_ID,
- USB_PRODUCT_ID);
+ ctx->usb_pid);
/* Open the device. */
if ((ret = ftdi_usb_open_desc(ctx->ftdic, USB_VENDOR_ID,
- USB_PRODUCT_ID, USB_DESCRIPTION, NULL)) < 0) {
+ ctx->usb_pid, USB_DESCRIPTION, NULL)) < 0) {
sr_err("la8: %s: ftdi_usb_open_desc: (%d) %s",
__func__, ret, ftdi_get_error_string(ctx->ftdic));
(void) la8_close_usb_reset_sequencer(ctx); /* Ignore errors. */
struct sr_dev_inst *sdi;
struct context *ctx;
- if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+ if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
sr_err("la8: %s: sdi was NULL", __func__);
return SR_ERR_BUG;
}
int ret = SR_OK;
/* Properly close all devices. */
- for (l = dev_insts; l; l = l->next) {
+ for (l = cdi->instances; l; l = l->next) {
if (!(sdi = l->data)) {
/* Log error, but continue cleaning up the rest. */
sr_err("la8: %s: sdi was NULL, continuing", __func__);
}
sr_dev_inst_free(sdi); /* Returns void. */
}
- g_slist_free(dev_insts); /* Returns void. */
- dev_insts = NULL;
+ g_slist_free(cdi->instances); /* Returns void. */
+ cdi->instances = NULL;
return ret;
}
struct context *ctx;
const void *info;
- if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+ if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
sr_err("la8: %s: sdi was NULL", __func__);
return NULL;
}
sr_spew("la8: %s: Returning samplerates.", __func__);
break;
case SR_DI_TRIGGER_TYPES:
- info = (char *)TRIGGER_TYPES;
+ info = TRIGGER_TYPES;
sr_spew("la8: %s: Returning trigger types: %s.", __func__,
TRIGGER_TYPES);
break;
{
struct sr_dev_inst *sdi;
- if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+ if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
sr_err("la8: %s: sdi was NULL, device not found", __func__);
return SR_ST_NOT_FOUND;
}
struct sr_dev_inst *sdi;
struct context *ctx;
- if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+ if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
sr_err("la8: %s: sdi was NULL", __func__);
return SR_ERR_BUG;
}
uint8_t buf[4];
int bytes_written;
- if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+ if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
sr_err("la8: %s: sdi was NULL", __func__);
return SR_ERR_BUG;
}
sr_dbg("la8: Stopping acquisition.");
- if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
+ if (!(sdi = sr_dev_inst_get(cdi->instances, dev_index))) {
sr_err("la8: %s: sdi was NULL", __func__);
return SR_ERR_BUG;
}
.api_version = 1,
.init = hw_init,
.cleanup = hw_cleanup,
+ .scan = hw_scan,
.dev_open = hw_dev_open,
.dev_close = hw_dev_close,
.dev_info_get = hw_dev_info_get,
.dev_config_set = hw_dev_config_set,
.dev_acquisition_start = hw_dev_acquisition_start,
.dev_acquisition_stop = hw_dev_acquisition_stop,
+ .instances = NULL,
};