示例#1
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(GSList *options, int idx)
{
	struct sr_config *src;
	GSList *l, *devices;
	const char *conn, *serialcomm;

	conn = serialcomm = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;

	if (serialcomm) {
		/* Use the provided comm specs. */
		devices = center_scan(conn, serialcomm, idx);
	} else {
		/* Try the default. */
		devices = center_scan(conn, center_devs[idx].conn, idx);
	}

	return std_scan_complete(center_devs[idx].di, devices);
}
示例#2
0
文件: api.c 项目: abraxa/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	GSList *l;
	const char *conn, *serialcomm;

	conn = serialcomm = NULL;

	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = SERIALCOMM;

	/*
	 * We cannot scan for this device because it is write-only.
	 * So just check that the port parameters are valid and assume that
	 * the device is there.
	 */

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		return NULL;

	serial_flush(serial);
	serial_close(serial);

	sr_spew("Conrad DIGI 35 CPU assumed at %s.", conn);

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup("Conrad");
	sdi->model = g_strdup("DIGI 35 CPU");
	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;
	sdi->priv = devc;
	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1");

	return std_scan_complete(di, g_slist_append(NULL, sdi));
}
示例#3
0
文件: api.c 项目: abraxa/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	struct sr_dev_inst *sdi;
	GSList *l, *devices;
	gint64 start;
	const char *conn;
	unsigned char c;

	conn = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		if (src->key == SR_CONF_CONN)
			conn = g_variant_get_string(src->data, NULL);
	}
	if (!conn)
		return NULL;

	serial = sr_serial_dev_inst_new(conn, SERIALCOMM);

	if (serial_open(serial, SERIAL_RDONLY) != SR_OK)
		return NULL;

	devices = NULL;
	start = g_get_monotonic_time();
	while (g_get_monotonic_time() - start < MAX_SCAN_TIME_US) {
		if (serial_read_nonblocking(serial, &c, 1) == 1 && c == 0xa5) {
			/* Found one. */
			sdi = g_malloc0(sizeof(struct sr_dev_inst));
			sdi->status = SR_ST_INACTIVE;
			sdi->vendor = g_strdup("CEM");
			sdi->model = g_strdup("DT-885x");
			devc = g_malloc0(sizeof(struct dev_context));
			devc->cur_mqflags = 0;
			devc->recording = -1;
			devc->cur_meas_range = 0;
			devc->cur_data_source = DATA_SOURCE_LIVE;
			devc->enable_data_source_memory = FALSE;
			sdi->conn = sr_serial_dev_inst_new(conn, SERIALCOMM);
			sdi->inst_type = SR_INST_SERIAL;
			sdi->priv = devc;
			sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "SPL");
			devices = g_slist_append(devices, sdi);
			break;
		}
		/* It takes about 1ms for a byte to come in. */
		g_usleep(1000);
	}

	serial_close(serial);

	return std_scan_complete(di, devices);
}
示例#4
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	GSList *l;
	const char *conn, *serialcomm;
	struct sr_serial_dev_inst *serial;

	conn = serialcomm = NULL;
	for (l = options; l; l = l->next) {
		if (!(src = l->data)) {
			sr_err("Invalid option data, skipping.");
			continue;
		}
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		default:
			sr_err("Unknown option %d, skipping.", src->key);
			break;
		}
	}
	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = SERIALCOMM;

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup("Tondaj");
	sdi->model = g_strdup("SL-814");
	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		return NULL;

	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;

	sdi->priv = devc;
	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1");

	return std_scan_complete(di, g_slist_append(NULL, sdi));
}
示例#5
0
文件: api.c 项目: vpalatin/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	GSList *usb_devices, *devices, *l;
	unsigned int i;
	const char *conn;

	drvc = di->context;

	conn = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;

	devices = NULL;
	if ((usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn))) {
		/* We have a list of sr_usb_dev_inst matching the connection
		 * string. Wrap them in sr_dev_inst and we're done. */
		for (l = usb_devices; l; l = l->next) {
			sdi = g_malloc0(sizeof(struct sr_dev_inst));
			sdi->status = SR_ST_INACTIVE;
			sdi->vendor = g_strdup(VENDOR);
			sdi->model = g_strdup(MODEL);
			sdi->inst_type = SR_INST_USB;
			sdi->conn = l->data;
			for (i = 0; i < ARRAY_SIZE(channel_names); i++)
				sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
						channel_names[i]);
			devc = g_malloc0(sizeof(struct dev_context));
			sdi->priv = devc;
			devc->limit_samples = 0;
			devc->data_source = DEFAULT_DATA_SOURCE;
			devices = g_slist_append(devices, sdi);
		}
		g_slist_free(usb_devices);
	} else
		g_slist_free_full(usb_devices, g_free);

	return std_scan_complete(di, devices);
}
示例#6
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	GSList *usb_devices, *devices, *l;
	char *model;

	(void)options;

	drvc = di->context;

	devices = NULL;
	if ((usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, USB_CONN))) {
		/* We have a list of sr_usb_dev_inst matching the connection
		 * string. Wrap them in sr_dev_inst and we're done. */
		for (l = usb_devices; l; l = l->next) {
			if (scan_kecheng(di, l->data, &model) != SR_OK)
				continue;
			sdi = g_malloc0(sizeof(struct sr_dev_inst));
			sdi->status = SR_ST_INACTIVE;
			sdi->vendor = g_strdup(VENDOR);
			sdi->model = model; /* Already g_strndup()'d. */
			sdi->inst_type = SR_INST_USB;
			sdi->conn = l->data;
			sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "SPL");
			devc = g_malloc0(sizeof(struct dev_context));
			sdi->priv = devc;
			devc->limit_samples = 0;
			/* The protocol provides no way to read the current
			 * settings, so we'll enforce these. */
			devc->sample_interval = DEFAULT_SAMPLE_INTERVAL;
			devc->alarm_low = DEFAULT_ALARM_LOW;
			devc->alarm_high = DEFAULT_ALARM_HIGH;
			devc->mqflags = DEFAULT_WEIGHT_TIME | DEFAULT_WEIGHT_FREQ;
			devc->data_source = DEFAULT_DATA_SOURCE;
			devc->config_dirty = FALSE;

			/* TODO: Set date/time? */

			devices = g_slist_append(devices, sdi);
		}
		g_slist_free(usb_devices);
	} else
		g_slist_free_full(usb_devices, g_free);

	return std_scan_complete(di, devices);
}
示例#7
0
文件: api.c 项目: abraxa/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct parport_list ports;
	struct sr_config *src;
	const char *conn = NULL;
	GSList *devices, *option;
	gboolean port_found;
	int i;


	for (option = options; option; option = option->next) {
		src = option->data;
		if (src->key == SR_CONF_CONN) {
			conn = g_variant_get_string(src->data, NULL);
			break;
		}
	}

	if (!conn)
		return NULL;

	if (ieee1284_find_ports(&ports, 0) != E1284_OK)
		return NULL;

	devices = NULL;
	port_found = FALSE;
	for (i = 0; i < ports.portc; i++)
		if (!strcmp(ports.portv[i]->name, conn)) {
			port_found = TRUE;
			devices = scan_port(devices, ports.portv[i]);
		}

	if (!port_found) {
		sr_err("Parallel port %s not found. Valid names are:", conn);
		for (i = 0; i < ports.portc; i++)
			sr_err("\t%s", ports.portv[i]->name);
	}

	ieee1284_free_ports(&ports);

	return std_scan_complete(di, devices);
}
示例#8
0
文件: api.c 项目: abraxa/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	struct sr_dev_inst *sdi;
	GSList *l;
	const char *conn;

	conn = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		if (src->key == SR_CONF_CONN)
			conn = g_variant_get_string(src->data, NULL);
	}
	if (!conn)
		return NULL;

	serial = sr_serial_dev_inst_new(conn, SERIALCOMM);

	if (serial_open(serial, SERIAL_RDONLY) != SR_OK)
		return NULL;

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup("PCE");
	sdi->model = g_strdup("PCE-322A");
	devc = g_malloc0(sizeof(struct dev_context));
	devc->cur_mqflags = SR_MQFLAG_SPL_TIME_WEIGHT_F | SR_MQFLAG_SPL_FREQ_WEIGHT_A;
	sdi->conn = sr_serial_dev_inst_new(conn, SERIALCOMM);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->priv = devc;
	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "SPL");

	serial_close(serial);

	return std_scan_complete(di, g_slist_append(NULL, sdi));
}
示例#9
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	GSList *l;
	const char *conn, *serialcomm;

	conn = serialcomm = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = SERIALCOMM;

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup("Colead");
	sdi->model = g_strdup("SL-5868P");
	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);
	sdi->conn = sr_serial_dev_inst_new(conn, serialcomm);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->priv = devc;
	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1");

	return std_scan_complete(di, g_slist_append(NULL, sdi));
}
示例#10
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct dev_context *devc;
	GSList *l;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	const char *conn, *serialcomm;
	struct sr_serial_dev_inst *serial;
	char reply[50];
	int i, model_id;
	unsigned int len;

	conn = NULL;
	serialcomm = NULL;

	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		default:
			sr_err("Unknown option %d, skipping.", src->key);
			break;
		}
	}

	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = "9600/8n1";

	serial = sr_serial_dev_inst_new(conn, serialcomm);
	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		return NULL;

	serial_flush(serial);

	/* Get the device model. */
	len = 0;
	for (i = 0; models[i].id; i++) {
		if (strlen(models[i].id) > len)
			len = strlen(models[i].id);
	}
	memset(&reply, 0, sizeof(reply));
	sr_dbg("Want max %d bytes.", len);
	if ((korad_kaxxxxp_send_cmd(serial, "*IDN?") < 0))
		return NULL;

	/* i is used here for debug purposes only. */
	if ((i = korad_kaxxxxp_read_chars(serial, len, reply)) < 0)
		return NULL;
	sr_dbg("Received: %d, %s", i, reply);
	model_id = -1;
	for (i = 0; models[i].id; i++) {
		if (!strcmp(models[i].id, reply))
			model_id = i;
	}
	if (model_id < 0) {
		sr_err("Unknown model ID '%s' detected, aborting.", reply);
		return NULL;
	}
	sr_dbg("Found: %s %s (idx %d, ID '%s').", models[model_id].vendor,
		models[model_id].name, model_id, models[model_id].id);

	/* Init device instance, etc. */
	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup(models[model_id].vendor);
	sdi->model = g_strdup(models[model_id].name);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;

	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1");

	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);
	devc->model = &models[model_id];
	devc->reply[5] = 0;
	devc->req_sent_at = 0;
	sdi->priv = devc;

	/* Get current status of device. */
	if (korad_kaxxxxp_get_all_values(serial, devc) < 0)
		goto exit_err;

	serial_close(serial);

	return std_scan_complete(di, g_slist_append(NULL, sdi));

exit_err:
	sr_dev_inst_free(sdi);
	g_free(devc);
	sr_dbg("Scan failed.");

	return NULL;
}
示例#11
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct sr_dev_inst *sdi;
	struct drv_context *drvc;
	struct sr_usb_dev_inst *usb;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	GSList *devices;
	char connection_id[64];
	size_t i;
	int r;

	(void)options;

	drvc = di->context;

	devices = NULL;

	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);

	for (i = 0; devlist[i]; i++) {
		libusb_get_device_descriptor(devlist[i], &des);

		if (des.idVendor != LOGICSTUDIO16_VID)
			continue;

		usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));

		usb = NULL;

		switch (des.idProduct) {
		case LOGICSTUDIO16_PID_HAVE_FIRMWARE:
			usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
				libusb_get_device_address(devlist[i]), NULL);

			sdi = create_device(usb, SR_ST_INACTIVE, 0);
			break;
		case LOGICSTUDIO16_PID_LACK_FIRMWARE:
			r = ezusb_upload_firmware(drvc->sr_ctx, devlist[i],
				USB_CONFIGURATION, FX2_FIRMWARE);
			if (r != SR_OK) {
				/*
				 * An error message has already been logged by
				 * ezusb_upload_firmware().
				 */
				continue;
			}

			/*
			 * Put unknown as the address so that we know we still
			 * need to get the proper address after the device
			 * renumerates.
			 */
			usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
				UNKNOWN_ADDRESS, NULL);

			sdi = create_device(usb, SR_ST_INITIALIZING,
				g_get_monotonic_time());
			break;
		default:
			break;
		}

		/* Cannot handle this device? */
		if (!usb)
			continue;

		sdi->connection_id = g_strdup(connection_id);

		devices = g_slist_append(devices, sdi);
	}

	libusb_free_device_list(devlist, 1);

	return std_scan_complete(di, devices);
}
示例#12
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	unsigned int i;
	int ret;

	(void)options;

	/* Allocate memory for our private device context. */
	devc = g_malloc0(sizeof(struct dev_context));

	/* Allocate memory for the incoming compressed samples. */
	if (!(devc->compressed_buf = g_try_malloc0(COMPRESSED_BUF_SIZE))) {
		sr_err("compressed_buf malloc failed.");
		goto err_free_devc;
	}

	/* Allocate memory for the uncompressed samples. */
	if (!(devc->sample_buf = g_try_malloc0(SAMPLE_BUF_SIZE))) {
		sr_err("sample_buf malloc failed.");
		goto err_free_compressed_buf;
	}

	/* Allocate memory for the FTDI context (ftdic) and initialize it. */
	if (!(devc->ftdic = ftdi_new())) {
		sr_err("Failed to initialize libftdi.");
		goto err_free_sample_buf;
	}

	/* Check for the device and temporarily open it. */
	ret = ftdi_usb_open_desc(devc->ftdic, USB_VENDOR_ID, USB_DEVICE_ID,
				 USB_IPRODUCT, NULL);
	if (ret < 0) {
		/* Log errors, except for -3 ("device not found"). */
		if (ret != -3)
			sr_err("Failed to open device (%d): %s", ret,
			       ftdi_get_error_string(devc->ftdic));
		goto err_free_ftdic;
	}

	/* Register the device with libsigrok. */
	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup(USB_VENDOR_NAME);
	sdi->model = g_strdup(USB_MODEL_NAME);
	sdi->priv = devc;

	for (i = 0; i < ARRAY_SIZE(channel_names); i++)
		sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_names[i]);

	/* Close device. We'll reopen it again when we need it. */
	scanaplus_close(devc);

	return std_scan_complete(di, g_slist_append(NULL, sdi));

	scanaplus_close(devc);
err_free_ftdic:
	ftdi_free(devc->ftdic); /* NOT free() or g_free()! */
err_free_sample_buf:
	g_free(devc->sample_buf);
err_free_compressed_buf:
	g_free(devc->compressed_buf);
err_free_devc:
	g_free(devc);

	return NULL;
}
示例#13
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct scale_info *scale;
	struct sr_config *src;
	GSList *l, *devices;
	const char *conn, *serialcomm;
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int ret;
	size_t len;
	uint8_t buf[128];

	scale = (struct scale_info *)di;

	conn = serialcomm = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;

	if (!serialcomm)
		serialcomm = scale->conn;

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		return NULL;

	sr_info("Probing serial port %s.", conn);

	devices = NULL;
	serial_flush(serial);

	sr_spew("Set O1 mode (continuous values, stable and unstable ones).");
	if (serial_write_nonblocking(serial, "O1\r\n", 4) != 4)
		goto scan_cleanup;
	/* Device replies with "A00\r\n" (OK) or "E01\r\n" (Error). Ignore. */

	/* Let's get a bit of data and see if we can find a packet. */
	len = sizeof(buf);
	ret = serial_stream_detect(serial, buf, &len, scale->packet_size,
				   scale->packet_valid, 3000, scale->baudrate);
	if (ret != SR_OK)
		goto scan_cleanup;

	sr_info("Found device on port %s.", conn);

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup(scale->vendor);
	sdi->model = g_strdup(scale->device);
	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;
	sdi->priv = devc;
	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "Mass");
	devices = g_slist_append(devices, sdi);

scan_cleanup:
	serial_close(serial);

	return std_scan_complete(di, devices);
}
示例#14
0
文件: api.c 项目: abraxa/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	int i, model_id;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	GSList *l;
	const char *conn, *serialcomm;
	struct sr_serial_dev_inst *serial;
	char reply[50], **tokens, *dummy;

	conn = NULL;
	serialcomm = NULL;
	devc = NULL;

	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		default:
			sr_err("Unknown option %d, skipping.", src->key);
			break;
		}
	}

	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = "9600/8n1";

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		return NULL;

	serial_flush(serial);

	sr_info("Probing serial port %s.", conn);

	/* Get the device model. */
	memset(&reply, 0, sizeof(reply));
	if ((hcs_send_cmd(serial, "GMOD\r") < 0) ||
	    (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0))
		return NULL;
	tokens = g_strsplit((const gchar *)&reply, "\r", 2);

	model_id = -1;
	for (i = 0; models[i].id != NULL; i++) {
		if (!strcmp(models[i].id, tokens[0]))
			model_id = i;
	}
	if (model_id < 0) {
		sr_err("Unknown model ID '%s' detected, aborting.", tokens[0]);
		g_strfreev(tokens);
		return NULL;
	}
	g_strfreev(tokens);

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup("Manson");
	sdi->model = g_strdup(models[model_id].name);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;

	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "CH1");

	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);
	devc->model = &models[model_id];

	sdi->priv = devc;

	/* Get current voltage, current, status. */
	if ((hcs_send_cmd(serial, "GETD\r") < 0) ||
	    (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0))
		goto exit_err;
	tokens = g_strsplit((const gchar *)&reply, "\r", 2);
	if (hcs_parse_volt_curr_mode(sdi, tokens) < 0) {
		g_strfreev(tokens);
		goto exit_err;
	}
	g_strfreev(tokens);

	/* Get max. voltage and current. */
	if ((hcs_send_cmd(serial, "GMAX\r") < 0) ||
	    (hcs_read_reply(serial, 2, reply, sizeof(reply)) < 0))
		goto exit_err;
	tokens = g_strsplit((const gchar *)&reply, "\r", 2);
	devc->current_max_device = g_strtod(&tokens[0][3], &dummy) * devc->model->current[2];
	tokens[0][3] = '\0';
	devc->voltage_max_device = g_strtod(tokens[0], &dummy) * devc->model->voltage[2];
	g_strfreev(tokens);

	serial_close(serial);

	return std_scan_complete(di, g_slist_append(NULL, sdi));

exit_err:
	sr_dev_inst_free(sdi);
	g_free(devc);

	return NULL;
}
示例#15
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	struct sr_channel_group *cg;
	struct sr_channel *ch;
	GSList *l;
	int ret, len;
	const char *conn, *serialcomm;
	char buf[100];
	char *bufptr;
	double version;

	conn = serialcomm = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = SERIALCOMM;

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		return NULL;

	serial_flush(serial);

	if (serial_write_blocking(serial, CMD_VERSION,
			strlen(CMD_VERSION), serial_timeout(serial,
			strlen(CMD_VERSION))) < (int)strlen(CMD_VERSION)) {
		sr_dbg("Unable to write while probing for hardware.");
		serial_close(serial);
		return NULL;
	}

	memset(buf, 0, sizeof(buf));
	bufptr = buf;
	len = sizeof(buf);
	ret = serial_readline(serial, &bufptr, &len, 3000);

	if (ret < 0 || len < 9 || strncmp((const char *)&buf, "version ", 8)) {
		sr_dbg("Unable to probe version number.");
		serial_close(serial);
		return NULL;
	}

	version = g_ascii_strtod(buf + 8, NULL);
	if (version < 1.10) {
		sr_info("Firmware >= 1.10 required (got %1.2f).", version);
		serial_close(serial);
		return NULL;
	}

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup("Arachnid Labs");
	sdi->model = g_strdup("Re:load Pro");
	sdi->version = g_strdup(buf + 8);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;

	cg = g_malloc0(sizeof(struct sr_channel_group));
	cg->name = g_strdup("1");
	sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);

	ch = sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "V");
	cg->channels = g_slist_append(cg->channels, ch);

	ch = sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "I");
	cg->channels = g_slist_append(cg->channels, ch);

	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);
	sdi->priv = devc;

	serial_close(serial);

	return std_scan_complete(di, g_slist_append(NULL, sdi));
}
示例#16
0
/**
 * Scan for Metrahit 2x in a bidirectional mode using Gossen Metrawatt
 * 'BD 232' interface.
 */
static GSList *scan_2x_bd232(struct sr_dev_driver *di, GSList *options)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	GSList *l, *devices;
	const char *conn, *serialcomm;
	int cnt, byte;
	gint64 timeout_us;

	sdi = NULL;
	devc = NULL;
	conn = serialcomm = NULL;
	devices = NULL;

	sr_spew("scan_2x_bd232() called!");

	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = SERIALCOMM_2X;

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		goto exit_err;

	devc = g_malloc0(sizeof(struct dev_context));

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup(VENDOR_GMC);
	sdi->priv = devc;

	/* Send message 03 "Query multimeter version and status" */
	sdi->conn = serial;
	if (req_stat14(sdi, TRUE) != SR_OK)
		goto exit_err;

	/* Wait for reply from device(s) for up to 2s. */
	timeout_us = g_get_monotonic_time() + (2 * 1000 * 1000);

	while (timeout_us > g_get_monotonic_time()) {
		/* Receive reply (14 bytes) */
		devc->buflen = 0;
		for (cnt = 0; cnt < GMC_REPLY_SIZE; cnt++) {
			byte = read_byte(serial, timeout_us);
			if (byte != -1)
				devc->buf[devc->buflen++] = (byte & MASK_6BITS);
		}

		if (devc->buflen != GMC_REPLY_SIZE)
			continue;

		devc->addr = devc->buf[0];
		process_msg14(sdi);
		devc->buflen = 0;

		if (devc->model != METRAHIT_NONE) {
			sr_spew("%s %s detected!", VENDOR_GMC, gmc_model_str(devc->model));
			sr_sw_limits_init(&devc->limits);
			sdi->model = g_strdup(gmc_model_str(devc->model));
			sdi->version = g_strdup_printf("Firmware %d.%d", devc->fw_ver_maj, devc->fw_ver_min);
			sdi->conn = serial;
			sdi->priv = devc;
			sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1");
			devices = g_slist_append(devices, sdi);
			devc = g_malloc0(sizeof(struct dev_context));
			sdi = g_malloc0(sizeof(struct sr_dev_inst));
			sdi->status = SR_ST_INACTIVE;
			sdi->vendor = g_strdup(VENDOR_GMC);
		}
	};

	/* Free last alloc if no device found */
	if (devc->model == METRAHIT_NONE) {
		g_free(devc);
		sr_dev_inst_free(sdi);
	}

	return std_scan_complete(di, devices);

exit_err:
	sr_info("scan_2x_bd232(): Error!");

	sr_serial_dev_inst_free(serial);
	g_free(devc);
	sr_dev_inst_free(sdi);

	return NULL;
}
示例#17
0
/**
 * Scan for Metrahit 1x and Metrahit 2x in send mode using Gossen Metrawatt
 * 'RS232' interface.
 *
 * The older 1x models use 8192 baud and the newer 2x 9600 baud.
 * The DMM usually sends up to about 20 messages per second. However, depending
 * on configuration and measurement mode the intervals can be much larger and
 * then the detection might not work.
 */
static GSList *scan_1x_2x_rs232(struct sr_dev_driver *di, GSList *options)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_serial_dev_inst *serial;
	GSList *l, *devices;
	const char *conn, *serialcomm;
	enum model model;
	gboolean serialcomm_given;

	devices = NULL;
	conn = serialcomm = NULL;
	serialcomm_given = FALSE;

	sr_spew("scan_1x_2x_rs232() called!");

	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			serialcomm_given = TRUE;
			break;
		}
	}
	if (!conn)
		return NULL;
	if (!serialcomm)
		serialcomm = SERIALCOMM_2X_RS232;

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK) {
		sr_serial_dev_inst_free(serial);
		return NULL;
	}

	serial_flush(serial);

	model = scan_model_sm(serial);

	/*
	 * If detection failed and no user-supplied parameters,
	 * try second baud rate.
	 */
	if ((model == METRAHIT_NONE) && !serialcomm_given) {
		serialcomm = SERIALCOMM_1X_RS232;
		g_free(serial->serialcomm);
		serial->serialcomm = g_strdup(serialcomm);
		if (serial_set_paramstr(serial, serialcomm) == SR_OK) {
			serial_flush(serial);
			model = scan_model_sm(serial);
		}
	}

	if (model != METRAHIT_NONE) {
		sr_spew("%s %s detected!", VENDOR_GMC, gmc_model_str(model));
		sdi = g_malloc0(sizeof(struct sr_dev_inst));
		sdi->status = SR_ST_INACTIVE;
		sdi->vendor = g_strdup(VENDOR_GMC);
		sdi->model = g_strdup(gmc_model_str(model));
		devc = g_malloc0(sizeof(struct dev_context));
		sr_sw_limits_init(&devc->limits);
		devc->model = model;
		devc->settings_ok = FALSE;
		sdi->conn = serial;
		sdi->priv = devc;
		sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1");
		devices = g_slist_append(devices, sdi);
	}

	return std_scan_complete(di, devices);
}
示例#18
0
文件: api.c 项目: vpalatin/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
    struct dev_context *devc;
    struct sr_dev_inst *sdi;
    struct sr_channel *ch;
    struct sr_channel_group *cg, *acg;
    struct sr_config *src;
    struct analog_gen *ag;
    GSList *l;
    int num_logic_channels, num_analog_channels, pattern, i;
    char channel_name[16];

    num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS;
    num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS;
    for (l = options; l; l = l->next) {
        src = l->data;
        switch (src->key) {
        case SR_CONF_NUM_LOGIC_CHANNELS:
            num_logic_channels = g_variant_get_int32(src->data);
            break;
        case SR_CONF_NUM_ANALOG_CHANNELS:
            num_analog_channels = g_variant_get_int32(src->data);
            break;
        }
    }

    sdi = g_malloc0(sizeof(struct sr_dev_inst));
    sdi->status = SR_ST_INACTIVE;
    sdi->model = g_strdup("Demo device");

    devc = g_malloc0(sizeof(struct dev_context));
    devc->cur_samplerate = SR_KHZ(200);
    devc->num_logic_channels = num_logic_channels;
    devc->logic_unitsize = (devc->num_logic_channels + 7) / 8;
    devc->logic_pattern = PATTERN_SIGROK;
    devc->num_analog_channels = num_analog_channels;

    if (num_logic_channels > 0) {
        /* Logic channels, all in one channel group. */
        cg = g_malloc0(sizeof(struct sr_channel_group));
        cg->name = g_strdup("Logic");
        for (i = 0; i < num_logic_channels; i++) {
            sprintf(channel_name, "D%d", i);
            ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
            cg->channels = g_slist_append(cg->channels, ch);
        }
        sdi->channel_groups = g_slist_append(NULL, cg);
    }

    /* Analog channels, channel groups and pattern generators. */
    if (num_analog_channels > 0) {
        pattern = 0;
        /* An "Analog" channel group with all analog channels in it. */
        acg = g_malloc0(sizeof(struct sr_channel_group));
        acg->name = g_strdup("Analog");
        sdi->channel_groups = g_slist_append(sdi->channel_groups, acg);

        devc->ch_ag = g_hash_table_new(g_direct_hash, g_direct_equal);
        for (i = 0; i < num_analog_channels; i++) {
            snprintf(channel_name, 16, "A%d", i);
            ch = sr_channel_new(sdi, i + num_logic_channels, SR_CHANNEL_ANALOG,
                                TRUE, channel_name);
            acg->channels = g_slist_append(acg->channels, ch);

            /* Every analog channel gets its own channel group as well. */
            cg = g_malloc0(sizeof(struct sr_channel_group));
            cg->name = g_strdup(channel_name);
            cg->channels = g_slist_append(NULL, ch);
            sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);

            /* Every channel gets a generator struct. */
            ag = g_malloc(sizeof(struct analog_gen));
            ag->amplitude = DEFAULT_ANALOG_AMPLITUDE;
            sr_analog_init(&ag->packet, &ag->encoding, &ag->meaning, &ag->spec, 2);
            ag->packet.meaning->channels = cg->channels;
            ag->packet.meaning->mq = 0;
            ag->packet.meaning->mqflags = 0;
            ag->packet.meaning->unit = SR_UNIT_VOLT;
            ag->packet.data = ag->pattern_data;
            ag->pattern = pattern;
            ag->avg_val = 0.0f;
            ag->num_avgs = 0;
            g_hash_table_insert(devc->ch_ag, ch, ag);

            if (++pattern == ARRAY_SIZE(analog_pattern_str))
                pattern = 0;
        }
    }

    sdi->priv = devc;

    return std_scan_complete(di, g_slist_append(NULL, sdi));
}
示例#19
0
文件: api.c 项目: abraxa/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_usb_dev_inst *usb;
	struct sr_channel *ch;
	struct sr_channel_group *cg;
	struct sr_config *src;
	const struct fx2lafw_profile *prof;
	GSList *l, *devices, *conn_devices;
	gboolean has_firmware;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	struct libusb_device_handle *hdl;
	int ret, i, j;
	int num_logic_channels = 0, num_analog_channels = 0;
	const char *conn;
	char manufacturer[64], product[64], serial_num[64], connection_id[64];
	char channel_name[16];

	drvc = di->context;

	conn = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (conn)
		conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn);
	else
		conn_devices = NULL;

	/* Find all fx2lafw compatible devices and upload firmware to them. */
	devices = NULL;
	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
	for (i = 0; devlist[i]; i++) {
		if (conn) {
			usb = NULL;
			for (l = conn_devices; l; l = l->next) {
				usb = l->data;
				if (usb->bus == libusb_get_bus_number(devlist[i])
					&& usb->address == libusb_get_device_address(devlist[i]))
					break;
			}
			if (!l)
				/* This device matched none of the ones that
				 * matched the conn specification. */
				continue;
		}

		libusb_get_device_descriptor( devlist[i], &des);

		if (!is_plausible(&des))
			continue;

		if ((ret = libusb_open(devlist[i], &hdl)) < 0) {
			sr_warn("Failed to open potential device with "
				"VID:PID %04x:%04x: %s.", des.idVendor,
				des.idProduct, libusb_error_name(ret));
			continue;
		}

		if (des.iManufacturer == 0) {
			manufacturer[0] = '\0';
		} else if ((ret = libusb_get_string_descriptor_ascii(hdl,
				des.iManufacturer, (unsigned char *) manufacturer,
				sizeof(manufacturer))) < 0) {
			sr_warn("Failed to get manufacturer string descriptor: %s.",
				libusb_error_name(ret));
			continue;
		}

		if (des.iProduct == 0) {
			product[0] = '\0';
		} else if ((ret = libusb_get_string_descriptor_ascii(hdl,
				des.iProduct, (unsigned char *) product,
				sizeof(product))) < 0) {
			sr_warn("Failed to get product string descriptor: %s.",
				libusb_error_name(ret));
			continue;
		}

		if (des.iSerialNumber == 0) {
			serial_num[0] = '\0';
		} else if ((ret = libusb_get_string_descriptor_ascii(hdl,
				des.iSerialNumber, (unsigned char *) serial_num,
				sizeof(serial_num))) < 0) {
			sr_warn("Failed to get serial number string descriptor: %s.",
				libusb_error_name(ret));
			continue;
		}

		libusb_close(hdl);

		if (usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)) < 0)
			continue;

		prof = NULL;
		for (j = 0; supported_fx2[j].vid; j++) {
			if (des.idVendor == supported_fx2[j].vid &&
					des.idProduct == supported_fx2[j].pid &&
					(!supported_fx2[j].usb_manufacturer ||
					 !strcmp(manufacturer, supported_fx2[j].usb_manufacturer)) &&
					(!supported_fx2[j].usb_product ||
					 !strcmp(product, supported_fx2[j].usb_product))) {
				prof = &supported_fx2[j];
				break;
			}
		}

		if (!prof)
			continue;

		sdi = g_malloc0(sizeof(struct sr_dev_inst));
		sdi->status = SR_ST_INITIALIZING;
		sdi->vendor = g_strdup(prof->vendor);
		sdi->model = g_strdup(prof->model);
		sdi->version = g_strdup(prof->model_version);
		sdi->serial_num = g_strdup(serial_num);
		sdi->connection_id = g_strdup(connection_id);

		/* Fill in channellist according to this device's profile. */
		num_logic_channels = prof->dev_caps & DEV_CAPS_16BIT ? 16 : 8;
		num_analog_channels = prof->dev_caps & DEV_CAPS_AX_ANALOG ? 1 : 0;

		/* Logic channels, all in one channel group. */
		cg = g_malloc0(sizeof(struct sr_channel_group));
		cg->name = g_strdup("Logic");
		for (j = 0; j < num_logic_channels; j++) {
			sprintf(channel_name, "D%d", j);
			ch = sr_channel_new(sdi, j, SR_CHANNEL_LOGIC,
						TRUE, channel_name);
			cg->channels = g_slist_append(cg->channels, ch);
		}
		sdi->channel_groups = g_slist_append(NULL, cg);

		for (j = 0; j < num_analog_channels; j++) {
			snprintf(channel_name, 16, "A%d", j);
			ch = sr_channel_new(sdi, j + num_logic_channels,
					SR_CHANNEL_ANALOG, TRUE, channel_name);

			/* Every analog channel gets its own channel group. */
			cg = g_malloc0(sizeof(struct sr_channel_group));
			cg->name = g_strdup(channel_name);
			cg->channels = g_slist_append(NULL, ch);
			sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
		}

		devc = fx2lafw_dev_new();
		devc->profile = prof;
		sdi->priv = devc;
		devices = g_slist_append(devices, sdi);

		devc->samplerates = samplerates;
		devc->num_samplerates = ARRAY_SIZE(samplerates);
		has_firmware = usb_match_manuf_prod(devlist[i],
				"sigrok", "fx2lafw");

		if (has_firmware) {
			/* Already has the firmware, so fix the new address. */
			sr_dbg("Found an fx2lafw device.");
			sdi->status = SR_ST_INACTIVE;
			sdi->inst_type = SR_INST_USB;
			sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
					libusb_get_device_address(devlist[i]), NULL);
		} else {
			if (ezusb_upload_firmware(drvc->sr_ctx, devlist[i],
					USB_CONFIGURATION, prof->firmware) == SR_OK) {
				/* Store when this device's FW was updated. */
				devc->fw_updated = g_get_monotonic_time();
			} else {
				sr_err("Firmware upload failed for "
				       "device %d.%d (logical), name %s.",
				       libusb_get_bus_number(devlist[i]),
				       libusb_get_device_address(devlist[i]),
				       prof->firmware);
			}
			sdi->inst_type = SR_INST_USB;
			sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
					0xff, NULL);
		}
	}
	libusb_free_device_list(devlist, 1);
	g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free);

	return std_scan_complete(di, devices);
}
示例#20
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct dmm_info *dmm;
	struct sr_config *src;
	GSList *l, *devices;
	const char *conn, *serialcomm;
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	int dropped, ret;
	size_t len;
	uint8_t buf[128];

	dmm = (struct dmm_info *)di;

	conn = serialcomm = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		switch (src->key) {
		case SR_CONF_CONN:
			conn = g_variant_get_string(src->data, NULL);
			break;
		case SR_CONF_SERIALCOMM:
			serialcomm = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (!conn)
		return NULL;

	if (!serialcomm)
		serialcomm = dmm->conn;

	serial = sr_serial_dev_inst_new(conn, serialcomm);

	if (serial_open(serial, SERIAL_RDWR) != SR_OK)
		return NULL;

	sr_info("Probing serial port %s.", conn);

	devices = NULL;
	serial_flush(serial);

	/* Request a packet if the DMM requires this. */
	if (dmm->packet_request) {
		if ((ret = dmm->packet_request(serial)) < 0) {
			sr_err("Failed to request packet: %d.", ret);
			return FALSE;
		}
	}

	/*
	 * There's no way to get an ID from the multimeter. It just sends data
	 * periodically (or upon request), so the best we can do is check if
	 * the packets match the expected format.
	 */

	/* Let's get a bit of data and see if we can find a packet. */
	len = sizeof(buf);
	ret = serial_stream_detect(serial, buf, &len, dmm->packet_size,
				   dmm->packet_valid, 3000,
				   dmm->baudrate);
	if (ret != SR_OK)
		goto scan_cleanup;

	/*
	 * If we dropped more than two packets worth of data, something is
	 * wrong. We shouldn't quit however, since the dropped bytes might be
	 * just zeroes at the beginning of the stream. Those can occur as a
	 * combination of the nonstandard cable that ships with some devices
	 * and the serial port or USB to serial adapter.
	 */
	dropped = len - dmm->packet_size;
	if (dropped > 2 * dmm->packet_size)
		sr_warn("Had to drop too much data.");

	sr_info("Found device on port %s.", conn);

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup(dmm->vendor);
	sdi->model = g_strdup(dmm->device);
	devc = g_malloc0(sizeof(struct dev_context));
	sr_sw_limits_init(&devc->limits);
	sdi->inst_type = SR_INST_SERIAL;
	sdi->conn = serial;
	sdi->priv = devc;
	sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE, "P1");
	devices = g_slist_append(devices, sdi);

scan_cleanup:
	serial_close(serial);

	return std_scan_complete(di, devices);
}
示例#21
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_usb_dev_inst *usb;
	struct sr_config *src;
	const struct hantek_6xxx_profile *prof;
	GSList *l, *devices, *conn_devices;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	int i, j;
	const char *conn;
	char connection_id[64];

	drvc = di->context;

	devices = 0;

	conn = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		if (src->key == SR_CONF_CONN) {
			conn = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (conn)
		conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn);
	else
		conn_devices = NULL;

	/* Find all Hantek 60xx devices and upload firmware to all of them. */
	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
	for (i = 0; devlist[i]; i++) {
		if (conn) {
			usb = NULL;
			for (l = conn_devices; l; l = l->next) {
				usb = l->data;
				if (usb->bus == libusb_get_bus_number(devlist[i])
					&& usb->address == libusb_get_device_address(devlist[i]))
					break;
			}
			if (!l)
				/* This device matched none of the ones that
				 * matched the conn specification. */
				continue;
		}

		libusb_get_device_descriptor(devlist[i], &des);

		usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));

		prof = NULL;
		for (j = 0; dev_profiles[j].orig_vid; j++) {
			if (des.idVendor == dev_profiles[j].orig_vid
				&& des.idProduct == dev_profiles[j].orig_pid) {
				/* Device matches the pre-firmware profile. */
				prof = &dev_profiles[j];
				sr_dbg("Found a %s %s.", prof->vendor, prof->model);
				sdi = hantek_6xxx_dev_new(prof);
				sdi->connection_id = g_strdup(connection_id);
				devices = g_slist_append(devices, sdi);
				devc = sdi->priv;
				if (ezusb_upload_firmware(drvc->sr_ctx, devlist[i],
						USB_CONFIGURATION, prof->firmware) == SR_OK)
					/* Remember when the firmware on this device was updated. */
					devc->fw_updated = g_get_monotonic_time();
				else
					sr_err("Firmware upload failed.");
				/* Dummy USB address of 0xff will get overwritten later. */
				sdi->conn = sr_usb_dev_inst_new(
						libusb_get_bus_number(devlist[i]), 0xff, NULL);
				break;
			} else if (des.idVendor == dev_profiles[j].fw_vid
				&& des.idProduct == dev_profiles[j].fw_pid
				&& des.bcdDevice == dev_profiles[j].fw_prod_ver) {
				/* Device matches the post-firmware profile. */
				prof = &dev_profiles[j];
				sr_dbg("Found a %s %s.", prof->vendor, prof->model);
				sdi = hantek_6xxx_dev_new(prof);
				sdi->connection_id = g_strdup(connection_id);
				sdi->status = SR_ST_INACTIVE;
				devices = g_slist_append(devices, sdi);
				sdi->inst_type = SR_INST_USB;
				sdi->conn = sr_usb_dev_inst_new(
						libusb_get_bus_number(devlist[i]),
						libusb_get_device_address(devlist[i]), NULL);
				break;
			}
		}
		if (!prof)
			/* Not a supported VID/PID. */
			continue;
	}
	libusb_free_device_list(devlist, 1);

	return std_scan_complete(di, devices);
}
示例#22
0
文件: api.c 项目: BayLibre/libsigrok
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	GSList *usb_devices, *devices, *l;
	struct drv_context *drvc;
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_usb_dev_inst *usb;
	struct device_info dev_info;
	unsigned int i;
	int ret;

	(void)options;

	devices = NULL;
	drvc = di->context;

	usb_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, USB_VID_PID);

	if (!usb_devices)
		return NULL;

	for (l = usb_devices; l; l = l->next) {
		usb = l->data;

		if ((ret = sl2_get_device_info(di, *usb, &dev_info)) < 0) {
			sr_warn("Failed to get device information: %d.", ret);
			sr_usb_dev_inst_free(usb);
			continue;
		}

		devc = g_malloc0(sizeof(struct dev_context));

		if (!(devc->xfer_in = libusb_alloc_transfer(0))) {
			sr_err("Transfer malloc failed.");
			sr_usb_dev_inst_free(usb);
			g_free(devc);
			continue;
		}

		if (!(devc->xfer_out = libusb_alloc_transfer(0))) {
			sr_err("Transfer malloc failed.");
			sr_usb_dev_inst_free(usb);
			libusb_free_transfer(devc->xfer_in);
			g_free(devc);
			continue;
		}

		sdi = g_malloc0(sizeof(struct sr_dev_inst));
		sdi->status = SR_ST_INACTIVE;
		sdi->vendor = g_strdup(VENDOR_NAME);
		sdi->model = g_strdup(MODEL_NAME);
		sdi->version = g_strdup_printf("%u.%u", dev_info.fw_ver_major, dev_info.fw_ver_minor);
		sdi->serial_num = g_strdup_printf("%d", dev_info.serial);
		sdi->priv = devc;
		sdi->inst_type = SR_INST_USB;
		sdi->conn = usb;

		for (i = 0; i < ARRAY_SIZE(channel_names); i++)
			devc->channels[i] = sr_channel_new(sdi, i,
				SR_CHANNEL_LOGIC, TRUE, channel_names[i]);

		devc->state = STATE_IDLE;
		devc->next_state = STATE_IDLE;

		/* Set default samplerate. */
		sl2_set_samplerate(sdi, DEFAULT_SAMPLERATE);

		/* Set default capture ratio. */
		devc->capture_ratio = 0;

		/* Set default after trigger delay. */
		devc->after_trigger_delay = 0;

		memset(devc->xfer_buf_in, 0, LIBUSB_CONTROL_SETUP_SIZE +
			PACKET_LENGTH);
		memset(devc->xfer_buf_out, 0, LIBUSB_CONTROL_SETUP_SIZE +
			PACKET_LENGTH);

		libusb_fill_control_setup(devc->xfer_buf_in,
			USB_REQUEST_TYPE_IN, USB_HID_GET_REPORT,
			USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE,
			PACKET_LENGTH);
		libusb_fill_control_setup(devc->xfer_buf_out,
			USB_REQUEST_TYPE_OUT, USB_HID_SET_REPORT,
			USB_HID_REPORT_TYPE_FEATURE, USB_INTERFACE,
			PACKET_LENGTH);

		devc->xfer_data_in = devc->xfer_buf_in +
			LIBUSB_CONTROL_SETUP_SIZE;
		devc->xfer_data_out = devc->xfer_buf_out +
			LIBUSB_CONTROL_SETUP_SIZE;

		devices = g_slist_append(devices, sdi);
	}

	g_slist_free(usb_devices);

	return std_scan_complete(di, devices);
}