Пример #1
0
static int dev_open(struct sr_dev_inst *sdi)
{
    struct sr_dev_driver *di = sdi->driver;
    struct dev_context *devc;
    struct drv_context *drvc;
    struct sr_usb_dev_inst *usb;
    libusb_device **devlist, *dev;
    int device_count, ret, i;
    char connection_id[64];

    drvc = di->context;
    usb = sdi->conn;

    if (!(devc = sdi->priv)) {
        sr_err("%s: sdi->priv was NULL", __func__);
        return SR_ERR_ARG;
    }

    device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx,
                                          &devlist);
    if (device_count < 0) {
        sr_err("Failed to retrieve device list.");
        return SR_ERR;
    }

    dev = NULL;
    for (i = 0; i < device_count; i++) {
        usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
        if (!strcmp(sdi->connection_id, connection_id)) {
            dev = devlist[i];
            break;
        }
    }
    if (!dev) {
        sr_err("Device on %d.%d (logical) / %s (physical) disappeared!",
               usb->bus, usb->address, sdi->connection_id);
        return SR_ERR;
    }

    if (!(ret = libusb_open(dev, &(usb->devhdl)))) {
        sdi->status = SR_ST_ACTIVE;
        sr_info("Opened device on %d.%d (logical) / %s (physical) interface %d.",
                usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
    } else {
        sr_err("Failed to open device: %s.", libusb_error_name(ret));
        return SR_ERR;
    }

    ret = libusb_set_configuration(usb->devhdl, USB_CONFIGURATION);
    if (ret < 0) {
        sr_err("Unable to set USB configuration %d: %s.",
               USB_CONFIGURATION, libusb_error_name(ret));
        return SR_ERR;
    }

    ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE);
    if (ret != 0) {
        sr_err("Unable to claim interface: %s.",
               libusb_error_name(ret));
        return SR_ERR;
    }

    /* Set default configuration after power on. */
    if (analyzer_read_status(usb->devhdl) == 0)
        analyzer_configure(usb->devhdl);

    analyzer_reset(usb->devhdl);
    analyzer_initialize(usb->devhdl);

    //analyzer_set_memory_size(MEMORY_SIZE_512K);
    // analyzer_set_freq(g_freq, g_freq_scale);
    analyzer_set_trigger_count(1);
    // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
    // * get_memory_size(g_memory_size)) / 100) >> 2);

#if 0
    if (g_double_mode == 1)
        analyzer_set_compression(COMPRESSION_DOUBLE);
    else if (g_compression == 1)
        analyzer_set_compression(COMPRESSION_ENABLE);
    else
#endif
        analyzer_set_compression(COMPRESSION_NONE);

    if (devc->cur_samplerate == 0) {
        /* Samplerate hasn't been set. Default to 1MHz. */
        analyzer_set_freq(1, FREQ_SCALE_MHZ);
        devc->cur_samplerate = SR_MHZ(1);
    }

    if (devc->cur_threshold == 0)
        set_voltage_threshold(devc, 1.5);

    return SR_OK;
}
Пример #2
0
static int receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct session_vdev *vdev;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_logic logic;
	struct zip_stat zs;
	GSList *l;
	int ret, got_data;
	char capturefile[16];
	void *buf;

	(void)fd;
	(void)revents;

	got_data = FALSE;
	for (l = dev_insts; l; l = l->next) {
		sdi = l->data;
		if (!(vdev = sdi->priv))
			/* Already done with this instance. */
			continue;

		if (!(buf = g_try_malloc(CHUNKSIZE))) {
			sr_err("%s: buf malloc failed", __func__);
			return FALSE;
		}

		if (!vdev->capfile) {
			/* No capture file opened yet, or finished with the last
			 * chunked one. */
			if (vdev->cur_chunk == 0) {
				/* capturefile is always the unchunked base name. */
				if (zip_stat(vdev->archive, vdev->capturefile, 0, &zs) != -1) {
					/* No chunks, just a single capture file. */
					vdev->cur_chunk = 0;
					if (!(vdev->capfile = zip_fopen(vdev->archive,
							vdev->capturefile, 0)))
						return FALSE;
						sr_dbg("Opened %s.", vdev->capturefile);
				} else {
					/* Try as first chunk filename. */
					snprintf(capturefile, 15, "%s-1", vdev->capturefile);
					if (zip_stat(vdev->archive, capturefile, 0, &zs) != -1) {
						vdev->cur_chunk = 1;
						if (!(vdev->capfile = zip_fopen(vdev->archive,
								capturefile, 0)))
							return FALSE;
						sr_dbg("Opened %s.", capturefile);
					} else {
						sr_err("No capture file '%s' in " "session file '%s'.",
								vdev->capturefile, vdev->sessionfile);
						return FALSE;
					}
				}
			} else {
				/* Capture data is chunked, advance to the next chunk. */
				vdev->cur_chunk++;
				snprintf(capturefile, 15, "%s-%d", vdev->capturefile,
						vdev->cur_chunk);
				if (zip_stat(vdev->archive, capturefile, 0, &zs) != -1) {
					if (!(vdev->capfile = zip_fopen(vdev->archive,
							capturefile, 0)))
						return FALSE;
					sr_dbg("Opened %s.", capturefile);
				} else {
					/* We got all the chunks, finish up. */
					g_free(vdev->capturefile);
					g_free(vdev);
					sdi->priv = NULL;
					continue;
				}
			}
		}

		ret = zip_fread(vdev->capfile, buf, CHUNKSIZE);
		if (ret > 0) {
			got_data = TRUE;
			packet.type = SR_DF_LOGIC;
			packet.payload = &logic;
			logic.length = ret;
			logic.unitsize = vdev->unitsize;
			logic.data = buf;
			vdev->bytes_read += ret;
			sr_session_send(cb_data, &packet);
		} else {
			/* done with this capture file */
			zip_fclose(vdev->capfile);
			vdev->capfile = NULL;
			if (vdev->cur_chunk == 0) {
				/* It was the only file. */
				g_free(vdev->capturefile);
				g_free(vdev);
				sdi->priv = NULL;
			} else {
				/* There might be more chunks, so don't fall through
				 * to the SR_DF_END here. */
				return TRUE;
			}
		}
	}

	if (!got_data) {
		packet.type = SR_DF_END;
		sr_session_send(cb_data, &packet);
		sr_session_source_remove(-1);
	}

	return TRUE;
}
Пример #3
0
/**
 * Create a new output instance using the specified output module.
 *
 * <code>options</code> is a *HashTable with the keys corresponding with
 * the module options' <code>id</code> field. The values should be GVariant
 * pointers with sunk * references, of the same GVariantType as the option's
 * default value.
 *
 * The sr_dev_inst passed in can be used by the instance to determine
 * channel names, samplerate, and so on.
 *
 * @since 0.4.0
 */
SR_API const struct sr_output *sr_output_new(const struct sr_output_module *omod,
		GHashTable *options, const struct sr_dev_inst *sdi,
		const char *filename)
{
	struct sr_output *op;
	const struct sr_option *mod_opts;
	const GVariantType *gvt;
	GHashTable *new_opts;
	GHashTableIter iter;
	gpointer key, value;
	int i;

	op = g_malloc(sizeof(struct sr_output));
	op->module = omod;
	op->sdi = sdi;
	op->filename = g_strdup(filename);

	new_opts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
			(GDestroyNotify)g_variant_unref);
	if (omod->options) {
		mod_opts = omod->options();
		for (i = 0; mod_opts[i].id; i++) {
			if (options && g_hash_table_lookup_extended(options,
					mod_opts[i].id, &key, &value)) {
				/* Pass option along. */
				gvt = g_variant_get_type(mod_opts[i].def);
				if (!g_variant_is_of_type(value, gvt)) {
					sr_err("Invalid type for '%s' option.",
						(char *)key);
					g_free(op);
					return NULL;
				}
				g_hash_table_insert(new_opts, g_strdup(mod_opts[i].id),
						g_variant_ref(value));
			} else {
				/* Option not given: insert the default value. */
				g_hash_table_insert(new_opts, g_strdup(mod_opts[i].id),
						g_variant_ref(mod_opts[i].def));
			}
		}

		/* Make sure no invalid options were given. */
		if (options) {
			g_hash_table_iter_init(&iter, options);
			while (g_hash_table_iter_next(&iter, &key, &value)) {
				if (!g_hash_table_lookup(new_opts, key)) {
					sr_err("Output module '%s' has no option '%s'",
						omod->id, (char *)key);
					g_hash_table_destroy(new_opts);
					g_free(op);
					return NULL;
				}
			}
		}
	}

	if (op->module->init && op->module->init(op, new_opts) != SR_OK) {
		g_free(op);
		op = NULL;
	}
	if (new_opts)
		g_hash_table_destroy(new_opts);

	return op;
}
Пример #4
0
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
		const struct sr_channel_group *cg)
{
	struct dev_context *devc;
	struct sr_channel *ch;
	const char *tmp_str;
	uint64_t samplerate;
	int analog_channel = -1;
	float smallest_diff = INFINITY;
	int idx = -1;
	unsigned i;

	if (!sdi)
		return SR_ERR_ARG;

	devc = sdi->priv;

	/* If a channel group is specified, it must be a valid one. */
	if (cg && !g_slist_find(sdi->channel_groups, cg)) {
		sr_err("Invalid channel group specified.");
		return SR_ERR;
	}

	if (cg) {
		ch = g_slist_nth_data(cg->channels, 0);
		if (!ch)
			return SR_ERR;
		if (ch->type == SR_CHANNEL_ANALOG) {
			if (ch->name[2] < '1' || ch->name[2] > '4')
				return SR_ERR;
			analog_channel = ch->name[2] - '1';
		}
	}

	switch (key) {
	case SR_CONF_NUM_HDIV:
		*data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
		break;
	case SR_CONF_NUM_VDIV:
		*data = g_variant_new_int32(devc->num_vdivs);
		break;
	case SR_CONF_DATA_SOURCE:
		if (devc->data_source == DATA_SOURCE_LIVE)
			*data = g_variant_new_string("Live");
		else if (devc->data_source == DATA_SOURCE_MEMORY)
			*data = g_variant_new_string("Memory");
		else
			*data = g_variant_new_string("Segmented");
		break;
	case SR_CONF_SAMPLERATE:
		if (devc->data_source == DATA_SOURCE_LIVE) {
			samplerate = analog_frame_size(sdi) /
				(devc->timebase * devc->model->series->num_horizontal_divs);
			*data = g_variant_new_uint64(samplerate);
		} else {
			sr_dbg("Unknown data source: %d.", devc->data_source);
			return SR_ERR_NA;
		}
		break;
	case SR_CONF_TRIGGER_SOURCE:
		if (!strcmp(devc->trigger_source, "ACL"))
			tmp_str = "AC Line";
		else if (!strcmp(devc->trigger_source, "CHAN1"))
			tmp_str = "CH1";
		else if (!strcmp(devc->trigger_source, "CHAN2"))
			tmp_str = "CH2";
		else if (!strcmp(devc->trigger_source, "CHAN3"))
			tmp_str = "CH3";
		else if (!strcmp(devc->trigger_source, "CHAN4"))
			tmp_str = "CH4";
		else
			tmp_str = devc->trigger_source;
		*data = g_variant_new_string(tmp_str);
		break;
	case SR_CONF_TRIGGER_SLOPE:
		if (!strncmp(devc->trigger_slope, "POS", 3)) {
			tmp_str = "r";
		} else if (!strncmp(devc->trigger_slope, "NEG", 3)) {
			tmp_str = "f";
		} else {
			sr_dbg("Unknown trigger slope: '%s'.", devc->trigger_slope);
			return SR_ERR_NA;
		}
		*data = g_variant_new_string(tmp_str);
		break;
	case SR_CONF_TRIGGER_LEVEL:
		*data = g_variant_new_double(devc->trigger_level);
		break;
	case SR_CONF_TIMEBASE:
		for (i = 0; i < devc->num_timebases; i++) {
			float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
			float diff = fabs(devc->timebase - tb);
			if (diff < smallest_diff) {
				smallest_diff = diff;
				idx = i;
			}
		}
		if (idx < 0) {
			sr_dbg("Negative timebase index: %d.", idx);
			return SR_ERR_NA;
		}
		*data = g_variant_new("(tt)", devc->timebases[idx][0],
		                              devc->timebases[idx][1]);
		break;
	case SR_CONF_VDIV:
		if (analog_channel < 0) {
			sr_dbg("Negative analog channel: %d.", analog_channel);
			return SR_ERR_NA;
		}
		for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
			float vdiv = (float)vdivs[i][0] / vdivs[i][1];
			float diff = fabs(devc->vdiv[analog_channel] - vdiv);
			if (diff < smallest_diff) {
				smallest_diff = diff;
				idx = i;
			}
		}
		if (idx < 0) {
			sr_dbg("Negative vdiv index: %d.", idx);
			return SR_ERR_NA;
		}
		*data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
		break;
	case SR_CONF_COUPLING:
		if (analog_channel < 0) {
			sr_dbg("Negative analog channel: %d.", analog_channel);
			return SR_ERR_NA;
		}
		*data = g_variant_new_string(devc->coupling[analog_channel]);
		break;
	case SR_CONF_PROBE_FACTOR:
		if (analog_channel < 0) {
			sr_dbg("Negative analog channel: %d.", analog_channel);
			return SR_ERR_NA;
		}
		*data = g_variant_new_uint64(devc->attenuation[analog_channel]);
		break;
	default:
		return SR_ERR_NA;
	}

	return SR_OK;
}
Пример #5
0
static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
		const struct sr_channel_group *cg)
{
	GVariant *tuple, *rational[2];
	GVariantBuilder gvb;
	unsigned int i;
	struct dev_context *devc = NULL;

	if (key == SR_CONF_SCAN_OPTIONS) {
		*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
				scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
		return SR_OK;
	} else if (key == SR_CONF_DEVICE_OPTIONS && !cg) {
		*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
				devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
		return SR_OK;
	}

	/* Every other option requires a valid device instance. */
	if (!sdi)
		return SR_ERR_ARG;
	devc = sdi->priv;

	/* If a channel group is specified, it must be a valid one. */
	if (cg && !g_slist_find(sdi->channel_groups, cg)) {
		sr_err("Invalid channel group specified.");
		return SR_ERR;
	}

	switch (key) {
	case SR_CONF_DEVICE_OPTIONS:
		if (!cg) {
			sr_err("No channel group specified.");
			return SR_ERR_CHANNEL_GROUP;
		}
		if (cg == devc->digital_group) {
			*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
				NULL, 0, sizeof(uint32_t));
			return SR_OK;
		} else {
			for (i = 0; i < devc->model->analog_channels; i++) {
				if (cg == devc->analog_groups[i]) {
					*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
						analog_devopts, ARRAY_SIZE(analog_devopts), sizeof(uint32_t));
					return SR_OK;
				}
			}
			return SR_ERR_NA;
		}
		break;
	case SR_CONF_COUPLING:
		if (!cg) {
			sr_err("No channel group specified.");
			return SR_ERR_CHANNEL_GROUP;
		}
		*data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
		break;
	case SR_CONF_PROBE_FACTOR:
		if (!cg) {
			sr_err("No channel group specified.");
			return SR_ERR_CHANNEL_GROUP;
		}
		*data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT64,
			probe_factor, ARRAY_SIZE(probe_factor), sizeof(uint64_t));
		break;
	case SR_CONF_VDIV:
		if (!devc)
			/* Can't know this until we have the exact model. */
			return SR_ERR_ARG;
		if (!cg) {
			sr_err("No channel group specified.");
			return SR_ERR_CHANNEL_GROUP;
		}
		g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
		for (i = 0; i < devc->num_vdivs; i++) {
			rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
			rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
			tuple = g_variant_new_tuple(rational, 2);
			g_variant_builder_add_value(&gvb, tuple);
		}
		*data = g_variant_builder_end(&gvb);
		break;
	case SR_CONF_TIMEBASE:
		if (!devc)
			/* Can't know this until we have the exact model. */
			return SR_ERR_ARG;
		if (devc->num_timebases <= 0)
			return SR_ERR_NA;
		g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
		for (i = 0; i < devc->num_timebases; i++) {
			rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
			rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
			tuple = g_variant_new_tuple(rational, 2);
			g_variant_builder_add_value(&gvb, tuple);
		}
		*data = g_variant_builder_end(&gvb);
		break;
	case SR_CONF_TRIGGER_SOURCE:
		if (!devc)
			/* Can't know this until we have the exact model. */
			return SR_ERR_ARG;
		*data = g_variant_new_strv(trigger_sources,
				devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
		break;
	case SR_CONF_TRIGGER_SLOPE:
		*data = g_variant_new_strv(trigger_slopes, ARRAY_SIZE(trigger_slopes));
		break;
	case SR_CONF_DATA_SOURCE:
		if (!devc)
			/* Can't know this until we have the exact model. */
			return SR_ERR_ARG;
		switch (devc->model->series->protocol) {
		case PROTOCOL_V1:
			*data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
			break;
		case PROTOCOL_V2:
			*data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
			break;
		default:
			*data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
			break;
		}
		break;
	default:
		return SR_ERR_NA;
	}

	return SR_OK;
}
Пример #6
0
/* USB output transfer completion callback.
 */
static void LIBUSB_CALL transfer_out_completed(struct libusb_transfer *transfer)
{
	const struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct acquisition_state *acq;

	sdi  = transfer->user_data;
	devc = sdi->priv;
	acq  = devc->acquisition;

	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
		sr_err("Transfer to device failed (state %d): %s.",
		       devc->state, libusb_error_name(transfer->status));
		devc->transfer_error = TRUE;
		return;
	}

	/* If this was a read request, wait for the response. */
	if ((devc->state & STATE_EXPECT_RESPONSE) != 0) {
		submit_transfer(devc, acq->xfer_in);
		return;
	}
	if (acq->reg_seq_pos < acq->reg_seq_len)
		acq->reg_seq_pos++; /* register write completed */

	/* Repeat until all queued registers have been written. */
	if (acq->reg_seq_pos < acq->reg_seq_len && !devc->cancel_requested) {
		next_reg_write(acq);
		submit_transfer(devc, acq->xfer_out);
		return;
	}

	switch (devc->state) {
	case STATE_START_CAPTURE:
		sr_info("Acquisition started.");

		if (!devc->cancel_requested)
			devc->state = STATE_STATUS_WAIT;
		else
			submit_request(sdi, STATE_STOP_CAPTURE);
		break;
	case STATE_STOP_CAPTURE:
		if (!devc->cancel_requested)
			submit_request(sdi, STATE_LENGTH_REQUEST);
		else
			devc->state = STATE_IDLE;
		break;
	case STATE_READ_PREPARE:
		if (acq->mem_addr_next < acq->mem_addr_stop && !devc->cancel_requested)
			submit_request(sdi, STATE_READ_REQUEST);
		else
			submit_request(sdi, STATE_READ_FINISH);
		break;
	case STATE_READ_FINISH:
		devc->state = STATE_IDLE;
		break;
	default:
		sr_err("Unexpected device state %d.", devc->state);
		devc->transfer_error = TRUE;
		break;
	}
}
Пример #7
0
static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
		const struct sr_channel_group *cg)
{
	struct dev_context *devc;
	uint64_t tmp_u64, low, high;
	unsigned int i;
	int tmp, ret;
	const char *tmp_str;

	(void)cg;

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	if (!(devc = sdi->priv)) {
		sr_err("sdi->priv was NULL.");
		return SR_ERR_BUG;
	}

	ret = SR_OK;
	switch (key) {
	case SR_CONF_LIMIT_SAMPLES:
		tmp_u64 = g_variant_get_uint64(data);
		devc->limit_samples = tmp_u64;
		ret = SR_OK;
		break;
	case SR_CONF_DATALOG:
		ret = cem_dt_885x_recording_set(sdi, g_variant_get_boolean(data));
		break;
	case SR_CONF_SPL_WEIGHT_FREQ:
		tmp_str = g_variant_get_string(data, NULL);
		if (!strcmp(tmp_str, "A"))
			ret = cem_dt_885x_weight_freq_set(sdi,
					SR_MQFLAG_SPL_FREQ_WEIGHT_A);
		else if (!strcmp(tmp_str, "C"))
			ret = cem_dt_885x_weight_freq_set(sdi,
					SR_MQFLAG_SPL_FREQ_WEIGHT_C);
		else
			return SR_ERR_ARG;
		break;
	case SR_CONF_SPL_WEIGHT_TIME:
		tmp_str = g_variant_get_string(data, NULL);
		if (!strcmp(tmp_str, "F"))
			ret = cem_dt_885x_weight_time_set(sdi,
					SR_MQFLAG_SPL_TIME_WEIGHT_F);
		else if (!strcmp(tmp_str, "S"))
			ret = cem_dt_885x_weight_time_set(sdi,
					SR_MQFLAG_SPL_TIME_WEIGHT_S);
		else
			return SR_ERR_ARG;
		break;
	case SR_CONF_HOLD_MAX:
		tmp = g_variant_get_boolean(data) ? SR_MQFLAG_MAX : 0;
		ret = cem_dt_885x_holdmode_set(sdi, tmp);
		break;
	case SR_CONF_HOLD_MIN:
		tmp = g_variant_get_boolean(data) ? SR_MQFLAG_MIN : 0;
		ret = cem_dt_885x_holdmode_set(sdi, tmp);
		break;
	case SR_CONF_SPL_MEASUREMENT_RANGE:
		g_variant_get(data, "(tt)", &low, &high);
		ret = SR_ERR_ARG;
		for (i = 0; i < ARRAY_SIZE(meas_ranges); i++) {
			if (meas_ranges[i][0] == low && meas_ranges[i][1] == high) {
				ret = cem_dt_885x_meas_range_set(sdi, low, high);
				break;
			}
		}
		break;
	case SR_CONF_POWER_OFF:
		if (g_variant_get_boolean(data))
			ret = cem_dt_885x_power_off(sdi);
		break;
	case SR_CONF_DATA_SOURCE:
		tmp_str = g_variant_get_string(data, NULL);
		if (!strcmp(tmp_str, "Live"))
			devc->cur_data_source = DATA_SOURCE_LIVE;
		else if (!strcmp(tmp_str, "Memory"))
			devc->cur_data_source = DATA_SOURCE_MEMORY;
		else
			return SR_ERR;
		devc->enable_data_source_memory = devc->cur_data_source == DATA_SOURCE_MEMORY;
		break;
	default:
		ret = SR_ERR_NA;
	}

	return ret;
}
Пример #8
0
/**
 * Process received line. It consists of 20 hex digits + \\r\\n,
 * e.g. '08100400018100400000'.
 */
static void nma_process_line(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	int pos, flags;
	int vt, range;	/* Measurement value type, range in device format */
	int mmode, devstat;	/* Measuring mode, device status */
	float value;	/* Measured value */
	float scale;	/* Scaling factor depending on range and function */
	struct sr_datafeed_analog analog;
	struct sr_datafeed_packet packet;

	devc = sdi->priv;

	devc->buf[20] = '\0';

	sr_spew("Received line '%s'.", devc->buf);

	/* Check line. */
	if (strlen((const char *)devc->buf) != 20) {
		sr_err("line: Invalid status '%s', must be 20 hex digits.",
		       devc->buf);
		devc->buflen = 0;
		return;
	}

	for (pos = 0; pos < 20; pos++) {
		if (!isxdigit(devc->buf[pos])) {
			sr_err("line: Expected hex digit in '%s' at pos %d!",
				devc->buf, pos);
			devc->buflen = 0;
			return;
		}
	}

	/* Start decoding. */
	value = 0.0;
	scale = 1.0;
	memset(&analog, 0, sizeof(analog));

	/*
	 * The numbers are hex digits, starting from 0.
	 * 0: Keyboard status, currently not interesting.
	 * 1: Central switch status, currently not interesting.
	 * 2: Type of measured value.
	 */
	vt = xgittoint(devc->buf[2]);
	switch (vt) {
	case 0:
		analog.mq = SR_MQ_VOLTAGE;
		break;
	case 1:
		analog.mq = SR_MQ_CURRENT;	/* 2A */
		break;
	case 2:
		analog.mq = SR_MQ_RESISTANCE;
		break;
	case 3:
		analog.mq = SR_MQ_CAPACITANCE;
		break;
	case 4:
		analog.mq = SR_MQ_TEMPERATURE;
		break;
	case 5:
		analog.mq = SR_MQ_FREQUENCY;
		break;
	case 6:
		analog.mq = SR_MQ_CURRENT;	/* 10A */
		break;
	case 7:
		analog.mq = SR_MQ_GAIN;		/* TODO: Scale factor */
		break;
	case 8:
		analog.mq = SR_MQ_GAIN;		/* Percentage */
		scale /= 100.0;
		break;
	case 9:
		analog.mq = SR_MQ_GAIN;		/* dB */
		scale /= 100.0;
		break;
	default:
		sr_err("Unknown value type: 0x%02x.", vt);
		break;
	}

	/* 3: Measurement range for measured value */
	range = xgittoint(devc->buf[3]);
	switch (vt) {
	case 0: /* V */
		scale *= pow(10.0, range - 5);
		break;
	case 1: /* A */
		scale *= pow(10.0, range - 7);
		break;
	case 2: /* Ω */
		scale *= pow(10.0, range - 2);
		break;
	case 3: /* F */
		scale *= pow(10.0, range - 12);
		break;
	case 4: /* °C */
		scale *= pow(10.0, range - 1);
		break;
	case 5: /* Hz */
		scale *= pow(10.0, range - 2);
		break;
	// No default, other value types have fixed display format.
	}

	/* 5: Sign and 1st digit */
	flags = xgittoint(devc->buf[5]);
	value = (flags & 0x03);
	if (flags & 0x04)
		scale *= -1;

	/* 6-9: 2nd-4th digit */
	for (pos = 6; pos < 10; pos++)
		value = value * 10 + xgittoint(devc->buf[pos]);
	value *= scale;

	/* 10: Display counter */
	mmode = xgittoint(devc->buf[10]);
	switch (mmode) {
	case 0: /* Frequency */
		analog.unit = SR_UNIT_HERTZ;
		break;
	case 1: /* V TRMS, only type 5 */
		analog.unit = SR_UNIT_VOLT;
		analog.mqflags |= (SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS);
		break;
	case 2: /* V AC */
		analog.unit = SR_UNIT_VOLT;
		analog.mqflags |= SR_MQFLAG_AC;
		if (devc->type >= 3)
			analog.mqflags |= SR_MQFLAG_RMS;
		break;
	case 3: /* V DC */
		analog.unit = SR_UNIT_VOLT;
		analog.mqflags |= SR_MQFLAG_DC;
		break;
	case 4: /* Ohm */
		analog.unit = SR_UNIT_OHM;
		break;
	case 5: /* Continuity */
		analog.unit = SR_UNIT_BOOLEAN;
		analog.mq = SR_MQ_CONTINUITY;
		/* TODO: Continuity handling is a bit odd in libsigrok. */
		break;
	case 6: /* Degree Celsius */
		analog.unit = SR_UNIT_CELSIUS;
		break;
	case 7: /* Capacity */
		analog.unit = SR_UNIT_FARAD;
		break;
	case 8: /* Current DC */
		analog.unit = SR_UNIT_AMPERE;
		analog.mqflags |= SR_MQFLAG_DC;
		break;
	case 9: /* Current AC */
		analog.unit = SR_UNIT_AMPERE;
		analog.mqflags |= SR_MQFLAG_AC;
		if (devc->type >= 3)
			analog.mqflags |= SR_MQFLAG_RMS;
		break;
	case 0xa: /* Current TRMS, only type 5 */
		analog.unit = SR_UNIT_AMPERE;
		analog.mqflags |= (SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS);
		break;
	case 0xb: /* Diode */
		analog.unit = SR_UNIT_VOLT;
		analog.mqflags |= (SR_MQFLAG_DIODE | SR_MQFLAG_DC);
		break;
	default:
		sr_err("Unknown mmode: 0x%02x.", mmode);
		break;
	}

	/* 11: Device status */
	devstat = xgittoint(devc->buf[11]);

	switch (devstat) {
	case 1: /* Normal measurement */
		break;
	case 2: /* Input loop (limit, reference values) */
		break;
	case 3: /* TRANS/SENS */
		break;
	case 4: /* Error */
		sr_err("Device error. Fuse?"); /* TODO: Really abort? */
		devc->buflen = 0;
		return;	/* Cannot continue. */
	default:
		sr_err("Unknown device status: 0x%02x", devstat);
		break;
	}

	/* 12-19: Flags and display symbols */
	/* 12, 13 */
	flags = (xgittoint(devc->buf[12]) << 8) | xgittoint(devc->buf[13]);
	/* 0x80: PRINT TODO: Stop polling when discovered? */
	/* 0x40: EXTR */
	if (analog.mq == SR_MQ_CONTINUITY) {
		if (flags & 0x20)
			value = 1.0; /* Beep */
		else
			value = 0.0;
	}
	/* 0x10: AVG */
	/* 0x08: Diode */
	if (flags & 0x04) /* REL */
		analog.mqflags |= SR_MQFLAG_RELATIVE;
	/* 0x02: SHIFT	*/
	if (flags & 0x01) /* % */
		analog.unit = SR_UNIT_PERCENTAGE;

	/* 14, 15 */
	flags = (xgittoint(devc->buf[14]) << 8) | xgittoint(devc->buf[15]);
	if (!(flags & 0x80))	/* MAN: Manual range */
		analog.mqflags |= SR_MQFLAG_AUTORANGE;
	if (flags & 0x40) /* LOBATT1: Low battery, measurement still within specs */
		devc->lowbatt = 1;
	/* 0x20: PEAK */
	/* 0x10: COUNT */
	if (flags & 0x08)	/* HOLD */
		analog.mqflags |= SR_MQFLAG_HOLD;
	/* 0x04: LIMIT	*/
	if (flags & 0x02) 	/* MAX */
		analog.mqflags |= SR_MQFLAG_MAX;
	if (flags & 0x01) 	/* MIN */
		analog.mqflags |= SR_MQFLAG_MIN;

	/* 16, 17 */
	flags = (xgittoint(devc->buf[16]) << 8) | xgittoint(devc->buf[17]);
	/* 0xe0: undefined */
	if (flags & 0x10) { /* LOBATT2: Low battery, measurement inaccurate */
		devc->lowbatt = 2;
		sr_warn("Low battery, measurement quality degraded!");
	}
	/* 0x08: SCALED */
	/* 0x04: RATE (=lower resolution, allows higher rata rate up to 10/s. */
	/* 0x02: Current clamp */
	if (flags & 0x01) { /* dB */
		/*
		 * TODO: The Norma has an adjustable dB reference value. If
		 * changed from default, this is not correct.
		 */
		if (analog.unit == SR_UNIT_VOLT)
			analog.unit = SR_UNIT_DECIBEL_VOLT;
		else
			analog.unit = SR_UNIT_UNITLESS;
	}

	/* 18, 19 */
	/* flags = (xgittoint(devc->buf[18]) << 8) | xgittoint(devc->buf[19]); */
	/* 0x80: Undefined. */
	/* 0x40: Remote mode, keyboard locked */
	/* 0x38: Undefined. */
	/* 0x04: MIN > MAX */
	/* 0x02: Measured value < Min */
	/* 0x01: Measured value > Max */

	/* 4: Flags. Evaluating this after setting value! */
	flags = xgittoint(devc->buf[4]);
	if (flags & 0x04) /* Invalid value */
	    value = NAN;
	else if (flags & 0x01) /* Overload */
	    value =  INFINITY;
	if (flags & 0x02) { /* Duplicate value, has been sent before. */
	    sr_spew("Duplicate value, dismissing!");
	    devc->buflen = 0;
	    return;
	}

	sr_spew("range=%d/scale=%f/value=%f", range,
		(double)scale, (double)value);

	/* Finish and send packet. */
	analog.probes = sdi->probes;
	analog.num_samples = 1;
	analog.data = &value;

	memset(&packet, 0, sizeof(packet));
	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	sr_session_send(devc->cb_data, &packet);

	/* Finish processing. */
	devc->num_samples++;
	devc->buflen = 0;
}
Пример #9
0
static GSList *scan(GSList *options)
{
	struct sr_dev_inst *sdi;
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_config *src;
	struct sr_channel *ch;
	struct sr_serial_dev_inst *serial;
	GSList *l, *devices;
	int len, i;
	const char *conn, *serialcomm;
	char *buf, **tokens;

	drvc = di->priv;
	drvc->instances = NULL;

	devices = NULL;
	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;

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

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

	serial_flush(serial);
	if (serial_write_blocking(serial, "*IDN?\r\n", 7, SERIAL_WRITE_TIMEOUT_MS) < 7) {
		sr_err("Unable to send identification string.");
		return NULL;
	}

	len = 128;
	if (!(buf = g_try_malloc(len))) {
		sr_err("Serial buffer malloc failed.");
		return NULL;
	}
	serial_readline(serial, &buf, &len, 250);
	if (!len)
		return NULL;

	tokens = g_strsplit(buf, ",", 4);
	if (!strcmp("Agilent Technologies", tokens[0])
			&& tokens[1] && tokens[2] && tokens[3]) {
		for (i = 0; supported_agdmm[i].model; i++) {
			if (strcmp(supported_agdmm[i].modelname, tokens[1]))
				continue;
			sdi = g_malloc0(sizeof(struct sr_dev_inst));
			sdi->status = SR_ST_INACTIVE;
			sdi->vendor = g_strdup("Agilent");
			sdi->model = g_strdup(tokens[1]);
			sdi->version = g_strdup(tokens[3]);
			devc = g_malloc0(sizeof(struct dev_context));
			devc->profile = &supported_agdmm[i];
			devc->cur_mq = -1;
			sdi->inst_type = SR_INST_SERIAL;
			sdi->conn = serial;
			sdi->priv = devc;
			sdi->driver = di;
			ch = sr_channel_new(0, SR_CHANNEL_ANALOG, TRUE, "P1");
			sdi->channels = g_slist_append(sdi->channels, ch);
			drvc->instances = g_slist_append(drvc->instances, sdi);
			devices = g_slist_append(devices, sdi);
			break;
		}
	}
	g_strfreev(tokens);
	g_free(buf);

	serial_close(serial);
	if (!devices)
		sr_serial_dev_inst_free(serial);

	return devices;
}
Пример #10
0
static int dev_open(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	int ret;

	devc = sdi->priv;

	/* Select interface A, otherwise communication will fail. */
	ret = ftdi_set_interface(devc->ftdic, INTERFACE_A);
	if (ret < 0) {
		sr_err("Failed to set FTDI interface A (%d): %s", ret,
		       ftdi_get_error_string(devc->ftdic));
		return SR_ERR;
	}
	sr_dbg("FTDI chip interface A set successfully.");

	/* Open the device. */
	ret = ftdi_usb_open_desc(devc->ftdic, USB_VENDOR_ID, USB_DEVICE_ID,
				 USB_IPRODUCT, NULL);
	if (ret < 0) {
		sr_err("Failed to open device (%d): %s", ret,
		       ftdi_get_error_string(devc->ftdic));
		return SR_ERR;
	}
	sr_dbg("FTDI device opened successfully.");

	/* Purge RX/TX buffers in the FTDI chip. */
	if ((ret = ftdi_usb_purge_buffers(devc->ftdic)) < 0) {
		sr_err("Failed to purge FTDI RX/TX buffers (%d): %s.",
		       ret, ftdi_get_error_string(devc->ftdic));
		goto err_dev_open_close_ftdic;
	}
	sr_dbg("FTDI chip buffers purged successfully.");

	/* Reset the FTDI bitmode. */
	ret = ftdi_set_bitmode(devc->ftdic, 0xff, BITMODE_RESET);
	if (ret < 0) {
		sr_err("Failed to reset the FTDI chip bitmode (%d): %s.",
		       ret, ftdi_get_error_string(devc->ftdic));
		goto err_dev_open_close_ftdic;
	}
	sr_dbg("FTDI chip bitmode reset successfully.");

	/* Set FTDI bitmode to "sync FIFO". */
	ret = ftdi_set_bitmode(devc->ftdic, 0xff, BITMODE_SYNCFF);
	if (ret < 0) {
		sr_err("Failed to put FTDI chip into sync FIFO mode (%d): %s.",
		       ret, ftdi_get_error_string(devc->ftdic));
		goto err_dev_open_close_ftdic;
	}
	sr_dbg("FTDI chip sync FIFO mode entered successfully.");

	/* Set the FTDI latency timer to 2. */
	ret = ftdi_set_latency_timer(devc->ftdic, 2);
	if (ret < 0) {
		sr_err("Failed to set FTDI latency timer (%d): %s.",
		       ret, ftdi_get_error_string(devc->ftdic));
		goto err_dev_open_close_ftdic;
	}
	sr_dbg("FTDI chip latency timer set successfully.");

	/* Set the FTDI read data chunk size to 64kB. */
	ret = ftdi_read_data_set_chunksize(devc->ftdic, 64 * 1024);
	if (ret < 0) {
		sr_err("Failed to set FTDI read data chunk size (%d): %s.",
		       ret, ftdi_get_error_string(devc->ftdic));
		goto err_dev_open_close_ftdic;
	}
	sr_dbg("FTDI chip read data chunk size set successfully.");

	/* Get the ScanaPLUS device ID from the FTDI EEPROM. */
	if ((ret = scanaplus_get_device_id(devc)) < 0) {
		sr_err("Failed to get ScanaPLUS device ID: %d.", ret);
		goto err_dev_open_close_ftdic;
	}
	sr_dbg("Received ScanaPLUS device ID successfully: %02x %02x %02x.",
	       devc->devid[0], devc->devid[1], devc->devid[2]);

	sdi->status = SR_ST_ACTIVE;

	return SR_OK;

err_dev_open_close_ftdic:
	scanaplus_close(devc);
	return SR_ERR;
}
Пример #11
0
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;
}
Пример #12
0
/**
 * Set serial parameters for the specified serial port.
 *
 * @param serial Previously initialized serial port structure.
 * @param baudrate The baudrate to set.
 * @param bits The number of data bits to use.
 * @param parity The parity setting to use (0 = none, 1 = even, 2 = odd).
 * @param stopbits The number of stop bits to use (1 or 2).
 * @param flowcontrol The flow control settings to use (0 = none, 1 = RTS/CTS,
 *                    2 = XON/XOFF).
 *
 * @return SR_OK upon success, SR_ERR upon failure.
 */
SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate,
			      int bits, int parity, int stopbits,
			      int flowcontrol, int rts, int dtr)
{
	int ret;
	char *error;
	struct sp_port_config *config;

	if (!serial) {
		sr_dbg("Invalid serial port.");
		return SR_ERR;
	}

	if (serial->fd == -1) {
		sr_dbg("Cannot configure unopened serial port %s (fd %d).",
		       serial->port, serial->fd);
		return SR_ERR;
	}

	sr_spew("Setting serial parameters on port %s (fd %d).", serial->port,
		serial->fd);

	sp_new_config(&config);
	sp_set_config_baudrate(config, baudrate);
	sp_set_config_bits(config, bits);
	switch (parity) {
	case 0:
		sp_set_config_parity(config, SP_PARITY_NONE);
		break;
	case 1:
		sp_set_config_parity(config, SP_PARITY_EVEN);
		break;
	case 2:
		sp_set_config_parity(config, SP_PARITY_ODD);
		break;
	default:
		return SR_ERR_ARG;
	}
	sp_set_config_stopbits(config, stopbits);
	sp_set_config_rts(config, flowcontrol == 1 ? SP_RTS_FLOW_CONTROL : rts);
	sp_set_config_cts(config, flowcontrol == 1 ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE);
	sp_set_config_dtr(config, dtr);
	sp_set_config_dsr(config, SP_DSR_IGNORE);
	sp_set_config_xon_xoff(config, flowcontrol == 2 ? SP_XONXOFF_INOUT : SP_XONXOFF_DISABLED);

	ret = sp_set_config(serial->data, config);
	sp_free_config(config);

	switch (ret) {
	case SP_ERR_ARG:
		sr_err("Invalid arguments for setting serial port parameters.");
		return SR_ERR_ARG;
	case SP_ERR_FAIL:
		error = sp_last_error_message();
		sr_err("Error setting serial port parameters: %s.", error);
		sp_free_error_message(error);
		return SR_ERR;
	}

	return SR_OK;
}
Пример #13
0
static int dev_acquisition_start(const struct sr_dev_inst *sdi,
                                 void *cb_data)
{
    struct dev_context *devc;
    struct sr_usb_dev_inst *usb;
    struct sr_datafeed_packet packet;
    struct sr_datafeed_logic logic;
    unsigned int samples_read;
    int res;
    unsigned int packet_num, n;
    unsigned char *buf;
    unsigned int status;
    unsigned int stop_address;
    unsigned int now_address;
    unsigned int trigger_address;
    unsigned int trigger_offset;
    unsigned int triggerbar;
    unsigned int ramsize_trigger;
    unsigned int memory_size;
    unsigned int valid_samples;
    unsigned int discard;
    int trigger_now;

    if (sdi->status != SR_ST_ACTIVE)
        return SR_ERR_DEV_CLOSED;

    if (!(devc = sdi->priv)) {
        sr_err("%s: sdi->priv was NULL", __func__);
        return SR_ERR_ARG;
    }

    if (analyzer_add_triggers(sdi) != SR_OK) {
        sr_err("Failed to configure triggers.");
        return SR_ERR;
    }

    usb = sdi->conn;

    set_triggerbar(devc);

    /* Push configured settings to device. */
    analyzer_configure(usb->devhdl);

    analyzer_start(usb->devhdl);
    sr_info("Waiting for data.");
    analyzer_wait_data(usb->devhdl);

    status = analyzer_read_status(usb->devhdl);
    stop_address = analyzer_get_stop_address(usb->devhdl);
    now_address = analyzer_get_now_address(usb->devhdl);
    trigger_address = analyzer_get_trigger_address(usb->devhdl);

    triggerbar = analyzer_get_triggerbar_address();
    ramsize_trigger = analyzer_get_ramsize_trigger_address();

    n = get_memory_size(devc->memory_size);
    memory_size = n / 4;

    sr_info("Status = 0x%x.", status);
    sr_info("Stop address       = 0x%x.", stop_address);
    sr_info("Now address        = 0x%x.", now_address);
    sr_info("Trigger address    = 0x%x.", trigger_address);
    sr_info("Triggerbar address = 0x%x.", triggerbar);
    sr_info("Ramsize trigger    = 0x%x.", ramsize_trigger);
    sr_info("Memory size        = 0x%x.", memory_size);

    /* Send header packet to the session bus. */
    std_session_send_df_header(cb_data, LOG_PREFIX);

    /* Check for empty capture */
    if ((status & STATUS_READY) && !stop_address) {
        packet.type = SR_DF_END;
        sr_session_send(cb_data, &packet);
        return SR_OK;
    }

    buf = g_malloc(PACKET_SIZE);

    /* Check if the trigger is in the samples we are throwing away */
    trigger_now = now_address == trigger_address ||
                  ((now_address + 1) % memory_size) == trigger_address;

    /*
     * STATUS_READY doesn't clear until now_address advances past
     * addr 0, but for our logic, clear it in that case
     */
    if (!now_address)
        status &= ~STATUS_READY;

    analyzer_read_start(usb->devhdl);

    /* Calculate how much data to discard */
    discard = 0;
    if (status & STATUS_READY) {
        /*
         * We haven't wrapped around, we need to throw away data from
         * our current position to the end of the buffer.
         * Additionally, the first two samples captured are always
         * bogus.
         */
        discard += memory_size - now_address + 2;
        now_address = 2;
    }

    /* If we have more samples than we need, discard them */
    valid_samples = (stop_address - now_address) % memory_size;
    if (valid_samples > ramsize_trigger + triggerbar) {
        discard += valid_samples - (ramsize_trigger + triggerbar);
        now_address += valid_samples - (ramsize_trigger + triggerbar);
    }

    sr_info("Need to discard %d samples.", discard);

    /* Calculate how far in the trigger is */
    if (trigger_now)
        trigger_offset = 0;
    else
        trigger_offset = (trigger_address - now_address) % memory_size;

    /* Recalculate the number of samples available */
    valid_samples = (stop_address - now_address) % memory_size;

    /* Send the incoming transfer to the session bus. */
    samples_read = 0;
    for (packet_num = 0; packet_num < n / PACKET_SIZE; packet_num++) {
        unsigned int len;
        unsigned int buf_offset;

        res = analyzer_read_data(usb->devhdl, buf, PACKET_SIZE);
        sr_info("Tried to read %d bytes, actually read %d bytes.",
                PACKET_SIZE, res);

        if (discard >= PACKET_SIZE / 4) {
            discard -= PACKET_SIZE / 4;
            continue;
        }

        len = PACKET_SIZE - discard * 4;
        buf_offset = discard * 4;
        discard = 0;

        /* Check if we've read all the samples */
        if (samples_read + len / 4 >= valid_samples)
            len = (valid_samples - samples_read) * 4;
        if (!len)
            break;

        if (samples_read < trigger_offset &&
                samples_read + len / 4 > trigger_offset) {
            /* Send out samples remaining before trigger */
            packet.type = SR_DF_LOGIC;
            packet.payload = &logic;
            logic.length = (trigger_offset - samples_read) * 4;
            logic.unitsize = 4;
            logic.data = buf + buf_offset;
            sr_session_send(cb_data, &packet);
            len -= logic.length;
            samples_read += logic.length / 4;
            buf_offset += logic.length;
        }

        if (samples_read == trigger_offset) {
            /* Send out trigger */
            packet.type = SR_DF_TRIGGER;
            packet.payload = NULL;
            sr_session_send(cb_data, &packet);
        }

        /* Send out data (or data after trigger) */
        packet.type = SR_DF_LOGIC;
        packet.payload = &logic;
        logic.length = len;
        logic.unitsize = 4;
        logic.data = buf + buf_offset;
        sr_session_send(cb_data, &packet);
        samples_read += len / 4;
    }
    analyzer_read_stop(usb->devhdl);
    g_free(buf);

    packet.type = SR_DF_END;
    sr_session_send(cb_data, &packet);

    return SR_OK;
}
Пример #14
0
static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
                       const struct sr_channel_group *cg)
{
    struct dev_context *devc;
    GVariant *gvar, *grange[2];
    GVariantBuilder gvb;
    double v;
    GVariant *range[2];

    (void)cg;

    switch (key) {
    case SR_CONF_DEVICE_OPTIONS:
        *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
                                          devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
        break;
    case SR_CONF_SAMPLERATE:
        devc = sdi->priv;
        g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
        if (devc->prof->max_sampling_freq == 100) {
            gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"),
                                             samplerates_100, ARRAY_SIZE(samplerates_100),
                                             sizeof(uint64_t));
        } else if (devc->prof->max_sampling_freq == 200) {
            gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"),
                                             samplerates_200, ARRAY_SIZE(samplerates_200),
                                             sizeof(uint64_t));
        } else {
            sr_err("Internal error: Unknown max. samplerate: %d.",
                   devc->prof->max_sampling_freq);
            return SR_ERR_ARG;
        }
        g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar);
        *data = g_variant_builder_end(&gvb);
        break;
    case SR_CONF_TRIGGER_MATCH:
        *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
                                          trigger_matches, ARRAY_SIZE(trigger_matches),
                                          sizeof(int32_t));
        break;
    case SR_CONF_VOLTAGE_THRESHOLD:
        g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
        for (v = -6.0; v <= 6.0; v += 0.1) {
            range[0] = g_variant_new_double(v);
            range[1] = g_variant_new_double(v);
            gvar = g_variant_new_tuple(range, 2);
            g_variant_builder_add_value(&gvb, gvar);
        }
        *data = g_variant_builder_end(&gvb);
        break;
    case SR_CONF_LIMIT_SAMPLES:
        if (!sdi)
            return SR_ERR_ARG;
        devc = sdi->priv;
        grange[0] = g_variant_new_uint64(0);
        grange[1] = g_variant_new_uint64(devc->max_sample_depth);
        *data = g_variant_new_tuple(grange, 2);
        break;
    default:
        return SR_ERR_NA;
    }

    return SR_OK;
}
Пример #15
0
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
{
	struct dev_context *devc;
	int ret = SR_ERR;

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	devc = sdi->priv;

	if (mso_configure_probes(sdi) != SR_OK) {
		sr_err("Failed to configure probes.");
		return SR_ERR;
	}

	/* FIXME: No need to do full reconfigure every time */
//      ret = mso_reset_fsm(sdi);
//      if (ret != SR_OK)
//              return ret;

	/* FIXME: ACDC Mode */
	devc->ctlbase1 &= 0x7f;
//      devc->ctlbase1 |= devc->acdcmode;

	ret = mso_configure_rate(sdi, devc->cur_rate);
	if (ret != SR_OK)
		return ret;

	/* set dac offset */
	ret = mso_dac_out(sdi, devc->dac_offset);
	if (ret != SR_OK)
		return ret;

	ret = mso_configure_threshold_level(sdi);
	if (ret != SR_OK)
		return ret;

	ret = mso_configure_trigger(sdi);
	if (ret != SR_OK)
		return ret;

	/* END of config hardware part */
	ret = mso_arm(sdi);
	if (ret != SR_OK)
		return ret;

	/* Start acquisition on the device. */
	mso_check_trigger(devc->serial, &devc->trigger_state);
	ret = mso_check_trigger(devc->serial, NULL);
	if (ret != SR_OK)
		return ret;

	/* Reset trigger state. */
	devc->trigger_state = 0x00;

	/* Send header packet to the session bus. */
	std_session_send_df_header(cb_data, LOG_PREFIX);

	/* Our first probe is analog, the other 8 are of type 'logic'. */
	/* TODO. */

	sr_source_add(devc->serial->fd, G_IO_IN, -1, mso_receive_data, cb_data);

	return SR_OK;
}
Пример #16
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	GSList *devices, *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;

	devices = NULL;
	conn = NULL;
	serialcomm = NULL;
	drvc = di->context;
	drvc->instances = 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_kdxxxxp_send_cmd(serial, "*IDN?") < 0))
		return NULL;

	/* i is used here for debug purposes only. */
	if ((i = korad_kdxxxxp_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", models[model_id].vendor, models[model_id].name);

	/* 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;
	sdi->driver = di;

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

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

	/* Get current status of device. */
	if (korad_kdxxxxp_get_all_values(serial, devc) < 0)
		goto exit_err;
	drvc->instances = g_slist_append(drvc->instances, sdi);
	devices = g_slist_append(devices, sdi);

	serial_close(serial);
	if (!devices)
		sr_serial_dev_inst_free(serial);

	return devices;

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

	return NULL;
}
Пример #17
0
static GSList *scan(GSList *options)
{
	int i;
	GSList *devices = NULL;
	const char *conn = NULL;
	const char *serialcomm = NULL;
	GSList *l;
	struct sr_config *src;
	struct udev *udev;
	int ptype;

	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)
		conn = SERIALCONN;
	if (serialcomm == NULL)
		serialcomm = SERIALCOMM;

	udev = udev_new();
	if (!udev) {
		sr_err("Failed to initialize udev.");
	}

	struct udev_enumerate *enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "usb-serial");
	udev_enumerate_scan_devices(enumerate);
	struct udev_list_entry *devs = udev_enumerate_get_list_entry(enumerate);
	struct udev_list_entry *dev_list_entry;
	for (dev_list_entry = devs;
	     dev_list_entry != NULL;
	     dev_list_entry = udev_list_entry_get_next(dev_list_entry)) {
		const char *syspath = udev_list_entry_get_name(dev_list_entry);
		struct udev_device *dev =
		    udev_device_new_from_syspath(udev, syspath);
		const char *sysname = udev_device_get_sysname(dev);
		struct udev_device *parent =
		    udev_device_get_parent_with_subsystem_devtype(dev, "usb",
								  "usb_device");

		if (!parent) {
			sr_err("Unable to find parent usb device for %s",
			       sysname);
			continue;
		}

		const char *idVendor =
		    udev_device_get_sysattr_value(parent, "idVendor");
		const char *idProduct =
		    udev_device_get_sysattr_value(parent, "idProduct");
		if (strcmp(USB_VENDOR, idVendor)
		    || strcmp(USB_PRODUCT, idProduct))
			continue;

		const char *iSerial =
		    udev_device_get_sysattr_value(parent, "serial");
		const char *iProduct =
		    udev_device_get_sysattr_value(parent, "product");

		char path[32];
		snprintf(path, sizeof(path), "/dev/%s", sysname);
		conn = path;

		size_t s = strcspn(iProduct, " ");
		char product[32];
		char manufacturer[32];
		if (s > sizeof(product) ||
		    strlen(iProduct) - s > sizeof(manufacturer)) {
			sr_err("Could not parse iProduct: %s.", iProduct);
			continue;
		}
		strncpy(product, iProduct, s);
		product[s] = 0;
		strcpy(manufacturer, iProduct + s + 1);

		//Create the device context and set its params
		struct dev_context *devc;
		if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
			sr_err("Device context malloc failed.");
			return devices;
		}

		if (mso_parse_serial(iSerial, iProduct, devc) != SR_OK) {
			sr_err("Invalid iSerial: %s.", iSerial);
			g_free(devc);
			return devices;
		}

		char hwrev[32];
		sprintf(hwrev, "r%d", devc->hwrev);
		devc->ctlbase1 = 0;
		devc->protocol_trigger.spimode = 0;
		for (i = 0; i < 4; i++) {
			devc->protocol_trigger.word[i] = 0;
			devc->protocol_trigger.mask[i] = 0xff;
		}

		if (!(devc->serial = sr_serial_dev_inst_new(conn, serialcomm))) {
			g_free(devc);
			return devices;
		}

		struct sr_dev_inst *sdi = sr_dev_inst_new(0, SR_ST_INACTIVE,
						manufacturer, product, hwrev);

		if (!sdi) {
			sr_err("Unable to create device instance for %s",
			       sysname);
			sr_dev_inst_free(sdi);
			g_free(devc);
			return devices;
		}

		sdi->driver = di;
		sdi->priv = devc;

		for (i = 0; i < NUM_PROBES; i++) {
			struct sr_probe *probe;
			ptype = (i == 0) ? SR_PROBE_ANALOG : SR_PROBE_LOGIC;
			if (!(probe = sr_probe_new(i, ptype, TRUE,
						   mso19_probe_names[i])))
				return 0;
			sdi->probes = g_slist_append(sdi->probes, probe);
		}

		//Add the driver
		struct drv_context *drvc = di->priv;
		drvc->instances = g_slist_append(drvc->instances, sdi);
		devices = g_slist_append(devices, sdi);
	}

	return devices;
}
Пример #18
0
static GSList *scan(GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_config *src;
	struct sr_channel *ch;
	GSList *devices, *l;
	const char *conn, *serialcomm;
	struct sr_serial_dev_inst *serial;

	drvc = di->priv;
	drvc->instances = NULL;

	devices = NULL;

	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));

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

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

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

	sdi->priv = devc;
	sdi->driver = di;
	ch = sr_channel_new(0, SR_CHANNEL_ANALOG, TRUE, "P1");
	sdi->channels = g_slist_append(sdi->channels, ch);
	drvc->instances = g_slist_append(drvc->instances, sdi);
	devices = g_slist_append(devices, sdi);

	return devices;
}
Пример #19
0
/* Set up the acquisition state record.
 */
static int init_acquisition_state(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct sr_usb_dev_inst *usb;
	struct acquisition_state *acq;

	devc = sdi->priv;
	usb  = sdi->conn;

	if (devc->acquisition) {
		sr_err("Acquisition still in progress?");
		return SR_ERR;
	}
	if (devc->cfg_clock_source == CLOCK_INTERNAL && devc->samplerate == 0) {
		sr_err("Samplerate not set.");
		return SR_ERR;
	}

	acq = g_try_malloc0(sizeof(struct acquisition_state));
	if (!acq)
		return SR_ERR_MALLOC;

	acq->xfer_in = libusb_alloc_transfer(0);
	if (!acq->xfer_in) {
		g_free(acq);
		return SR_ERR_MALLOC;
	}
	acq->xfer_out = libusb_alloc_transfer(0);
	if (!acq->xfer_out) {
		libusb_free_transfer(acq->xfer_in);
		g_free(acq);
		return SR_ERR_MALLOC;
	}

	libusb_fill_bulk_transfer(acq->xfer_out, usb->devhdl, EP_COMMAND,
				  (unsigned char *)acq->xfer_buf_out, 0,
				  &transfer_out_completed,
				  (struct sr_dev_inst *)sdi, USB_TIMEOUT_MS);

	libusb_fill_bulk_transfer(acq->xfer_in, usb->devhdl, EP_REPLY,
				  (unsigned char *)acq->xfer_buf_in,
				  sizeof(acq->xfer_buf_in),
				  &transfer_in_completed,
				  (struct sr_dev_inst *)sdi, USB_TIMEOUT_MS);

	if (devc->limit_msec > 0) {
		acq->duration_max = devc->limit_msec;
		sr_info("Acquisition time limit %" PRIu64 " ms.",
			devc->limit_msec);
	} else
		acq->duration_max = MAX_LIMIT_MSEC;

	if (devc->limit_samples > 0) {
		acq->samples_max = devc->limit_samples;
		sr_info("Acquisition sample count limit %" PRIu64 ".",
			devc->limit_samples);
	} else
		acq->samples_max = MAX_LIMIT_SAMPLES;

	if (devc->cfg_clock_source == CLOCK_INTERNAL) {
		sr_info("Internal clock, samplerate %" PRIu64 ".",
			devc->samplerate);
		/* Ramp up clock speed to enable samplerates above 100 MS/s. */
		acq->clock_boost = (devc->samplerate > SR_MHZ(100));

		/* If only one of the limits is set, derive the other one. */
		if (devc->limit_msec == 0 && devc->limit_samples > 0)
			acq->duration_max = devc->limit_samples
					* 1000 / devc->samplerate + 1;
		else if (devc->limit_samples == 0 && devc->limit_msec > 0)
			acq->samples_max = devc->limit_msec
					* devc->samplerate / 1000;
	} else {
		acq->clock_boost = TRUE;

		if (devc->cfg_clock_edge == EDGE_POSITIVE)
			sr_info("External clock, rising edge.");
		else
			sr_info("External clock, falling edge.");
	}

	acq->rle_enabled = devc->cfg_rle;
	devc->acquisition = acq;

	return SR_OK;
}
Пример #20
0
SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct sr_scpi_dev_inst *scpi;
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog analog;
	struct sr_analog_encoding encoding;
	struct sr_analog_meaning meaning;
	struct sr_analog_spec spec;
	struct sr_datafeed_logic logic;
	double vdiv, offset;
	int len, i, vref;
	struct sr_channel *ch;
	gsize expected_data_bytes;

	(void)fd;

	if (!(sdi = cb_data))
		return TRUE;

	if (!(devc = sdi->priv))
		return TRUE;

	scpi = sdi->conn;

	if (!(revents == G_IO_IN || revents == 0))
		return TRUE;

	switch (devc->wait_event) {
	case WAIT_NONE:
		break;
	case WAIT_TRIGGER:
		if (rigol_ds_trigger_wait(sdi) != SR_OK)
			return TRUE;
		if (rigol_ds_channel_start(sdi) != SR_OK)
			return TRUE;
		return TRUE;
	case WAIT_BLOCK:
		if (rigol_ds_block_wait(sdi) != SR_OK)
			return TRUE;
		break;
	case WAIT_STOP:
		if (rigol_ds_stop_wait(sdi) != SR_OK)
			return TRUE;
		if (rigol_ds_check_stop(sdi) != SR_OK)
			return TRUE;
		if (rigol_ds_channel_start(sdi) != SR_OK)
			return TRUE;
		return TRUE;
	default:
		sr_err("BUG: Unknown event target encountered");
		break;
	}

	ch = devc->channel_entry->data;

	expected_data_bytes = ch->type == SR_CHANNEL_ANALOG ?
			devc->analog_frame_size : devc->digital_frame_size;

	if (devc->num_block_bytes == 0) {
		if (devc->model->series->protocol >= PROTOCOL_V4) {
			if (sr_scpi_send(sdi->conn, ":WAV:START %d",
					devc->num_channel_bytes + 1) != SR_OK)
				return TRUE;
			if (sr_scpi_send(sdi->conn, ":WAV:STOP %d",
					MIN(devc->num_channel_bytes + ACQ_BLOCK_SIZE,
						devc->analog_frame_size)) != SR_OK)
				return TRUE;
		}

		if (devc->model->series->protocol >= PROTOCOL_V3)
			if (sr_scpi_send(sdi->conn, ":WAV:DATA?") != SR_OK)
				return TRUE;

		if (sr_scpi_read_begin(scpi) != SR_OK)
			return TRUE;

		if (devc->format == FORMAT_IEEE488_2) {
			sr_dbg("New block header expected");
			len = rigol_ds_read_header(sdi);
			if (len == 0)
				/* Still reading the header. */
				return TRUE;
			if (len == -1) {
				sr_err("Read error, aborting capture.");
				packet.type = SR_DF_FRAME_END;
				sr_session_send(sdi, &packet);
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			}
			/* At slow timebases in live capture the DS2072
			 * sometimes returns "short" data blocks, with
			 * apparently no way to get the rest of the data.
			 * Discard these, the complete data block will
			 * appear eventually.
			 */
			if (devc->data_source == DATA_SOURCE_LIVE
					&& (unsigned)len < expected_data_bytes) {
				sr_dbg("Discarding short data block");
				sr_scpi_read_data(scpi, (char *)devc->buffer, len + 1);
				return TRUE;
			}
			devc->num_block_bytes = len;
		} else {
			devc->num_block_bytes = expected_data_bytes;
		}
		devc->num_block_read = 0;
	}

	len = devc->num_block_bytes - devc->num_block_read;
	if (len > ACQ_BUFFER_SIZE)
		len = ACQ_BUFFER_SIZE;
	sr_dbg("Requesting read of %d bytes", len);

	len = sr_scpi_read_data(scpi, (char *)devc->buffer, len);

	if (len == -1) {
		sr_err("Read error, aborting capture.");
		packet.type = SR_DF_FRAME_END;
		sr_session_send(sdi, &packet);
		sdi->driver->dev_acquisition_stop(sdi);
		return TRUE;
	}

	sr_dbg("Received %d bytes.", len);

	devc->num_block_read += len;

	if (ch->type == SR_CHANNEL_ANALOG) {
		vref = devc->vert_reference[ch->index];
		vdiv = devc->vdiv[ch->index] / 25.6;
		offset = devc->vert_offset[ch->index];
		if (devc->model->series->protocol >= PROTOCOL_V3)
			for (i = 0; i < len; i++)
				devc->data[i] = ((int)devc->buffer[i] - vref) * vdiv - offset;
		else
			for (i = 0; i < len; i++)
				devc->data[i] = (128 - devc->buffer[i]) * vdiv - offset;
		sr_analog_init(&analog, &encoding, &meaning, &spec, 0);
		analog.meaning->channels = g_slist_append(NULL, ch);
		analog.num_samples = len;
		analog.data = devc->data;
		analog.meaning->mq = SR_MQ_VOLTAGE;
		analog.meaning->unit = SR_UNIT_VOLT;
		analog.meaning->mqflags = 0;
		packet.type = SR_DF_ANALOG;
		packet.payload = &analog;
		sr_session_send(sdi, &packet);
		g_slist_free(analog.meaning->channels);
	} else {
		logic.length = len;
		// TODO: For the MSO1000Z series, we need a way to express that
		// this data is in fact just for a single channel, with the valid
		// data for that channel in the LSB of each byte.
		logic.unitsize = devc->model->series->protocol == PROTOCOL_V4 ? 1 : 2;
		logic.data = devc->buffer;
		packet.type = SR_DF_LOGIC;
		packet.payload = &logic;
		sr_session_send(sdi, &packet);
	}

	if (devc->num_block_read == devc->num_block_bytes) {
		sr_dbg("Block has been completed");
		if (devc->model->series->protocol >= PROTOCOL_V3) {
			/* Discard the terminating linefeed */
			sr_scpi_read_data(scpi, (char *)devc->buffer, 1);
		}
		if (devc->format == FORMAT_IEEE488_2) {
			/* Prepare for possible next block */
			devc->num_header_bytes = 0;
			devc->num_block_bytes = 0;
			if (devc->data_source != DATA_SOURCE_LIVE)
				rigol_ds_set_wait_event(devc, WAIT_BLOCK);
		}
		if (!sr_scpi_read_complete(scpi)) {
			sr_err("Read should have been completed");
			packet.type = SR_DF_FRAME_END;
			sr_session_send(sdi, &packet);
			sdi->driver->dev_acquisition_stop(sdi);
			return TRUE;
		}
		devc->num_block_read = 0;
	} else {
		sr_dbg("%" PRIu64 " of %" PRIu64 " block bytes read",
			devc->num_block_read, devc->num_block_bytes);
	}

	devc->num_channel_bytes += len;

	if (devc->num_channel_bytes < expected_data_bytes)
		/* Don't have the full data for this channel yet, re-run. */
		return TRUE;

	/* End of data for this channel. */
	if (devc->model->series->protocol == PROTOCOL_V3) {
		/* Signal end of data download to scope */
		if (devc->data_source != DATA_SOURCE_LIVE)
			/*
			 * This causes a query error, without it switching
			 * to the next channel causes an error. Fun with
			 * firmware...
			 */
			rigol_ds_config_set(sdi, ":WAV:END");
	}

	if (devc->channel_entry->next) {
		/* We got the frame for this channel, now get the next channel. */
		devc->channel_entry = devc->channel_entry->next;
		rigol_ds_channel_start(sdi);
	} else {
		/* Done with this frame. */
		packet.type = SR_DF_FRAME_END;
		sr_session_send(sdi, &packet);

		if (++devc->num_frames == devc->limit_frames) {
			/* Last frame, stop capture. */
			sdi->driver->dev_acquisition_stop(sdi);
		} else {
			/* Get the next frame, starting with the first channel. */
			devc->channel_entry = devc->enabled_channels;

			rigol_ds_capture_start(sdi);

			/* Start of next frame. */
			packet.type = SR_DF_FRAME_BEGIN;
			sr_session_send(sdi, &packet);
		}
	}

	return TRUE;
}
Пример #21
0
static GSList *scan_port(GSList *devices, struct sr_dev_driver *di,
			 struct parport *port)
{
	struct sr_dev_inst *sdi;
	struct sr_channel *ch;
	struct sr_channel_group *cg;
	struct dev_context *devc;
	struct drv_context *drvc;
	int i;

	if (ieee1284_open(port, 0, &i) != E1284_OK) {
		sr_err("Can't open parallel port %s", port->name);
		goto fail1;
	}

	if ((i & (CAP1284_RAW | CAP1284_BYTE)) != (CAP1284_RAW | CAP1284_BYTE)) {
		sr_err("Parallel port %s does not provide low-level bidirection access",
		       port->name);
		goto fail2;
	}

	if (ieee1284_claim(port) != E1284_OK) {
		sr_err("Parallel port %s already in use", port->name);
		goto fail2;
	}

	if (!hung_chang_dso_2100_check_id(port))
		goto fail3;

	sdi = g_malloc0(sizeof(struct sr_dev_inst));
	sdi->status = SR_ST_INACTIVE;
	sdi->vendor = g_strdup("Hung-Chang");
	sdi->model = g_strdup("DSO-2100");
	sdi->driver = di;
	drvc = di->context;
	sdi->inst_type = 0; /* FIXME */
	sdi->conn = port;
	ieee1284_ref(port);

	for (i = 0; i < NUM_CHANNELS; i++) {
		cg = g_malloc0(sizeof(struct sr_channel_group));
		cg->name = g_strdup(trigger_sources[i]);
		ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, FALSE, trigger_sources[i]);
		cg->channels = g_slist_append(cg->channels, ch);
		sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
	}

	devc = g_malloc0(sizeof(struct dev_context));
	devc->enabled_channel = g_slist_append(NULL, NULL);
	devc->channel = 0;
	devc->rate = 0;
	devc->probe[0] = 10;
	devc->probe[1] = 10;
	devc->cctl[0] = 0x31; /* 1V/div, DC coupling, trigger on channel A*/
	devc->cctl[1] = 0x31; /* 1V/div, DC coupling, no tv sync trigger */
	devc->edge = 0;
	devc->tlevel = 0x80;
	devc->pos[0] = 0x80;
	devc->pos[1] = 0x80;
	devc->offset[0] = 0x80;
	devc->offset[1] = 0x80;
	devc->gain[0] = 0x80;
	devc->gain[1] = 0x80;
	devc->frame_limit = 0;
	devc->last_step = 0; /* buffersize = 1000 */
	sdi->priv = devc;

	drvc->instances = g_slist_append(drvc->instances, sdi);
	devices = g_slist_append(devices, sdi);

fail3:
	ieee1284_release(port);
fail2:
	ieee1284_close(port);
fail1:
	return devices;
}
Пример #22
0
/**
 * Load the session from the specified filename.
 *
 * @param ctx The context in which to load the session.
 * @param filename The name of the session file to load.
 * @param session The session to load the file into.
 *
 * @retval SR_OK Success
 * @retval SR_ERR_MALLOC Memory allocation error
 * @retval SR_ERR_DATA Malformed session file
 * @retval SR_ERR This is not a session file
 */
SR_API int sr_session_load(struct sr_context *ctx, const char *filename,
		struct sr_session **session)
{
	GKeyFile *kf;
	GError *error;
	struct zip *archive;
	struct zip_stat zs;
	struct sr_dev_inst *sdi;
	struct sr_channel *ch;
	int ret, i, j;
	uint64_t tmp_u64;
	int total_channels, total_analog, k;
	GSList *l;
	int unitsize;
	char **sections, **keys, *val;
	char channelname[SR_MAX_CHANNELNAME_LEN + 1];
	gboolean file_has_logic;

	if ((ret = sr_sessionfile_check(filename)) != SR_OK)
		return ret;

	if (!(archive = zip_open(filename, 0, NULL)))
		return SR_ERR;

	if (zip_stat(archive, "metadata", 0, &zs) < 0) {
		zip_discard(archive);
		return SR_ERR;
	}
	kf = sr_sessionfile_read_metadata(archive, &zs);
	zip_discard(archive);
	if (!kf)
		return SR_ERR_DATA;

	if ((ret = sr_session_new(ctx, session)) != SR_OK) {
		g_key_file_free(kf);
		return ret;
	}

	total_channels = 0;

	error = NULL;
	ret = SR_OK;
	file_has_logic = FALSE;
	sections = g_key_file_get_groups(kf, NULL);
	for (i = 0; sections[i] && ret == SR_OK; i++) {
		if (!strcmp(sections[i], "global"))
			/* nothing really interesting in here yet */
			continue;
		if (!strncmp(sections[i], "device ", 7)) {
			/* device section */
			sdi = NULL;
			keys = g_key_file_get_keys(kf, sections[i], NULL, NULL);

			/* File contains analog data if there are analog channels. */
			total_analog = g_key_file_get_integer(kf, sections[i],
					"total analog",	&error);
			if (total_analog > 0 && !error)
				sdi = sr_session_prepare_sdi(filename, session);
			g_clear_error(&error);

			/* File contains logic data if a capturefile is set. */
			val = g_key_file_get_string(kf, sections[i],
				"capturefile", &error);
			if (val && !error) {
				if (!sdi)
					sdi = sr_session_prepare_sdi(filename, session);
				sr_config_set(sdi, NULL, SR_CONF_CAPTUREFILE,
						g_variant_new_string(val));
				g_free(val);
				file_has_logic = TRUE;
			}
			g_clear_error(&error);

			for (j = 0; keys[j]; j++) {
				if (!strcmp(keys[j], "samplerate")) {
					val = g_key_file_get_string(kf, sections[i],
							keys[j], &error);
					if (!sdi || !val || sr_parse_sizestring(val,
								&tmp_u64) != SR_OK) {
						g_free(val);
						ret = SR_ERR_DATA;
						break;
					}
					g_free(val);
					sr_config_set(sdi, NULL, SR_CONF_SAMPLERATE,
							g_variant_new_uint64(tmp_u64));
				} else if (!strcmp(keys[j], "unitsize") && file_has_logic) {
					unitsize = g_key_file_get_integer(kf, sections[i],
							keys[j], &error);
					if (!sdi || unitsize <= 0 || error) {
						ret = SR_ERR_DATA;
						break;
					}
					sr_config_set(sdi, NULL, SR_CONF_CAPTURE_UNITSIZE,
							g_variant_new_uint64(unitsize));
				} else if (!strcmp(keys[j], "total probes")) {
					total_channels = g_key_file_get_integer(kf,
							sections[i], keys[j], &error);
					if (!sdi || total_channels < 0 || error) {
						ret = SR_ERR_DATA;
						break;
					}
					sr_config_set(sdi, NULL, SR_CONF_NUM_LOGIC_CHANNELS,
							g_variant_new_int32(total_channels));
					for (k = 0; k < total_channels; k++) {
						g_snprintf(channelname, sizeof(channelname),
								"%d", k);
						sr_channel_new(sdi, k, SR_CHANNEL_LOGIC,
								FALSE, channelname);
					}
				} else if (!strcmp(keys[j], "total analog")) {
					total_analog = g_key_file_get_integer(kf,
							sections[i], keys[j], &error);
					if (!sdi || total_analog < 0 || error) {
						ret = SR_ERR_DATA;
						break;
					}
					sr_config_set(sdi, NULL, SR_CONF_NUM_ANALOG_CHANNELS,
							g_variant_new_int32(total_analog));
					for (k = total_channels; k < (total_channels + total_analog); k++) {
						g_snprintf(channelname, sizeof(channelname),
								"%d", k);
						sr_channel_new(sdi, k, SR_CHANNEL_ANALOG,
								FALSE, channelname);
					}
				} else if (!strncmp(keys[j], "probe", 5)) {
					tmp_u64 = g_ascii_strtoull(keys[j] + 5, NULL, 10);
					if (!sdi || tmp_u64 == 0 || tmp_u64 > G_MAXINT) {
						ret = SR_ERR_DATA;
						break;
					}
					ch = g_slist_nth_data(sdi->channels, tmp_u64 - 1);
					if (!ch) {
						ret = SR_ERR_DATA;
						break;
					}
					val = g_key_file_get_string(kf, sections[i],
							keys[j], &error);
					if (!val) {
						ret = SR_ERR_DATA;
						break;
					}
					/* sr_session_save() */
					sr_dev_channel_name_set(ch, val);
					g_free(val);
					sr_dev_channel_enable(ch, TRUE);
				} else if (!strncmp(keys[j], "analog", 6)) {
					tmp_u64 = g_ascii_strtoull(keys[j]+6, NULL, 10);
					if (!sdi || tmp_u64 == 0 || tmp_u64 > G_MAXINT) {
						ret = SR_ERR_DATA;
						break;
					}
					ch = NULL;
					for (l = sdi->channels; l; l = l->next) {
						ch = l->data;
						if ((guint64)ch->index == tmp_u64 - 1)
							break;
						else
							ch = NULL;
					}
					if (!ch) {
						ret = SR_ERR_DATA;
						break;
					}
					val = g_key_file_get_string(kf, sections[i],
							keys[j], &error);
					if (!val) {
						ret = SR_ERR_DATA;
						break;
					}
					/* sr_session_save() */
					sr_dev_channel_name_set(ch, val);
					g_free(val);
					sr_dev_channel_enable(ch, TRUE);
				}
			}
			g_strfreev(keys);
		}
	}
	g_strfreev(sections);
	g_key_file_free(kf);

	if (error) {
		sr_err("Failed to parse metadata: %s", error->message);
		g_error_free(error);
	}
	return ret;
}
Пример #23
0
static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
		const struct sr_channel_group *cg)
{
	struct dev_context *devc;
	uint64_t p, q;
	double t_dbl;
	unsigned int i, j;
	int ret;
	const char *tmp_str;
	char buffer[16];

	devc = sdi->priv;

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	/* If a channel group is specified, it must be a valid one. */
	if (cg && !g_slist_find(sdi->channel_groups, cg)) {
		sr_err("Invalid channel group specified.");
		return SR_ERR;
	}

	ret = SR_OK;
	switch (key) {
	case SR_CONF_LIMIT_FRAMES:
		devc->limit_frames = g_variant_get_uint64(data);
		break;
	case SR_CONF_TRIGGER_SLOPE:
		tmp_str = g_variant_get_string(data, NULL);

		if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r')) {
			sr_err("Unknown trigger slope: '%s'.",
			       (tmp_str) ? tmp_str : "NULL");
			return SR_ERR_ARG;
		}

		g_free(devc->trigger_slope);
		devc->trigger_slope = g_strdup((tmp_str[0] == 'r') ? "POS" : "NEG");
		ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
		break;
	case SR_CONF_HORIZ_TRIGGERPOS:
		t_dbl = g_variant_get_double(data);
		if (t_dbl < 0.0 || t_dbl > 1.0) {
			sr_err("Invalid horiz. trigger position: %g.", t_dbl);
			return SR_ERR;
		}
		devc->horiz_triggerpos = t_dbl;
		/* We have the trigger offset as a percentage of the frame, but
		 * need to express this in seconds. */
		t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
		g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
		ret = rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
		break;
	case SR_CONF_TRIGGER_LEVEL:
		t_dbl = g_variant_get_double(data);
		g_ascii_formatd(buffer, sizeof(buffer), "%.3f", t_dbl);
		ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:LEV %s", buffer);
		if (ret == SR_OK)
			devc->trigger_level = t_dbl;
		break;
	case SR_CONF_TIMEBASE:
		g_variant_get(data, "(tt)", &p, &q);
		for (i = 0; i < devc->num_timebases; i++) {
			if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
				devc->timebase = (float)p / q;
				g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
				                devc->timebase);
				ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
				break;
			}
		}
		if (i == devc->num_timebases) {
			sr_err("Invalid timebase index: %d.", i);
			ret = SR_ERR_ARG;
		}
		break;
	case SR_CONF_TRIGGER_SOURCE:
		tmp_str = g_variant_get_string(data, NULL);
		for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
			if (!strcmp(trigger_sources[i], tmp_str)) {
				g_free(devc->trigger_source);
				devc->trigger_source = g_strdup(trigger_sources[i]);
				if (!strcmp(devc->trigger_source, "AC Line"))
					tmp_str = "ACL";
				else if (!strcmp(devc->trigger_source, "CH1"))
					tmp_str = "CHAN1";
				else if (!strcmp(devc->trigger_source, "CH2"))
					tmp_str = "CHAN2";
				else if (!strcmp(devc->trigger_source, "CH3"))
					tmp_str = "CHAN3";
				else if (!strcmp(devc->trigger_source, "CH4"))
					tmp_str = "CHAN4";
				else
					tmp_str = (char *)devc->trigger_source;
				ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
				break;
			}
		}
		if (i == ARRAY_SIZE(trigger_sources)) {
			sr_err("Invalid trigger source index: %d.", i);
			ret = SR_ERR_ARG;
		}
		break;
	case SR_CONF_VDIV:
		if (!cg) {
			sr_err("No channel group specified.");
			return SR_ERR_CHANNEL_GROUP;
		}
		g_variant_get(data, "(tt)", &p, &q);
		for (i = 0; i < devc->model->analog_channels; i++) {
			if (cg == devc->analog_groups[i]) {
				for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
					if (vdivs[j][0] != p || vdivs[j][1] != q)
						continue;
					devc->vdiv[i] = (float)p / q;
					g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
					                devc->vdiv[i]);
					return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
							buffer);
				}
				sr_err("Invalid vdiv index: %d.", j);
				return SR_ERR_ARG;
			}
		}
		sr_dbg("Didn't set vdiv, unknown channel(group).");
		return SR_ERR_NA;
	case SR_CONF_COUPLING:
		if (!cg) {
			sr_err("No channel group specified.");
			return SR_ERR_CHANNEL_GROUP;
		}
		tmp_str = g_variant_get_string(data, NULL);
		for (i = 0; i < devc->model->analog_channels; i++) {
			if (cg == devc->analog_groups[i]) {
				for (j = 0; j < ARRAY_SIZE(coupling); j++) {
					if (!strcmp(tmp_str, coupling[j])) {
						g_free(devc->coupling[i]);
						devc->coupling[i] = g_strdup(coupling[j]);
						return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
								devc->coupling[i]);
					}
				}
				sr_err("Invalid coupling index: %d.", j);
				return SR_ERR_ARG;
			}
		}
		sr_dbg("Didn't set coupling, unknown channel(group).");
		return SR_ERR_NA;
	case SR_CONF_PROBE_FACTOR:
		if (!cg) {
			sr_err("No channel group specified.");
			return SR_ERR_CHANNEL_GROUP;
		}
		p = g_variant_get_uint64(data);
		for (i = 0; i < devc->model->analog_channels; i++) {
			if (cg == devc->analog_groups[i]) {
				for (j = 0; j < ARRAY_SIZE(probe_factor); j++) {
					if (p == probe_factor[j]) {
						devc->attenuation[i] = p;
						ret = rigol_ds_config_set(sdi, ":CHAN%d:PROB %"PRIu64,
						                          i + 1, p);
						if (ret == SR_OK)
							rigol_ds_get_dev_cfg_vertical(sdi);
						return ret;
					}
				}
				sr_err("Invalid probe factor: %"PRIu64".", p);
				return SR_ERR_ARG;
			}
		}
		sr_dbg("Didn't set probe factor, unknown channel(group).");
		return SR_ERR_NA;
	case SR_CONF_DATA_SOURCE:
		tmp_str = g_variant_get_string(data, NULL);
		if (!strcmp(tmp_str, "Live"))
			devc->data_source = DATA_SOURCE_LIVE;
		else if (devc->model->series->protocol >= PROTOCOL_V2
			&& !strcmp(tmp_str, "Memory"))
			devc->data_source = DATA_SOURCE_MEMORY;
		else if (devc->model->series->protocol >= PROTOCOL_V3
			 && !strcmp(tmp_str, "Segmented"))
			devc->data_source = DATA_SOURCE_SEGMENTED;
		else {
			sr_err("Unknown data source: '%s'.", tmp_str);
			return SR_ERR;
		}
		break;
	default:
		return SR_ERR_NA;
	}

	return ret;
}
Пример #24
0
/** @private */
SR_PRIV void sr_zip_discard(struct zip *archive)
{
	if (zip_unchange_all(archive) < 0 || zip_close(archive) < 0)
		sr_err("Failed to discard ZIP archive: %s", zip_strerror(archive));
}
Пример #25
0
static int dev_acquisition_start(const struct sr_dev_inst *sdi)
{
	struct sr_scpi_dev_inst *scpi;
	struct dev_context *devc;
	struct sr_channel *ch;
	struct sr_datafeed_packet packet;
	gboolean some_digital;
	GSList *l;

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	scpi = sdi->conn;
	devc = sdi->priv;

	devc->num_frames = 0;

	some_digital = FALSE;
	for (l = sdi->channels; l; l = l->next) {
		ch = l->data;
		sr_dbg("handling channel %s", ch->name);
		if (ch->type == SR_CHANNEL_ANALOG) {
			if (ch->enabled)
				devc->enabled_channels = g_slist_append(
						devc->enabled_channels, ch);
			if (ch->enabled != devc->analog_channels[ch->index]) {
				/* Enabled channel is currently disabled, or vice versa. */
				if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", ch->index + 1,
						ch->enabled ? "ON" : "OFF") != SR_OK)
					return SR_ERR;
				devc->analog_channels[ch->index] = ch->enabled;
			}
		} else if (ch->type == SR_CHANNEL_LOGIC) {
			/* Only one list entry for DS1000D series. All channels are retrieved
			 * together when this entry is processed. */
			if (ch->enabled && (
						devc->model->series->protocol > PROTOCOL_V2 ||
						!some_digital))
				devc->enabled_channels = g_slist_append(
						devc->enabled_channels, ch);
			if (ch->enabled) {
				some_digital = TRUE;
				/* Turn on LA module if currently off. */
				if (!devc->la_enabled) {
					if (rigol_ds_config_set(sdi,
							devc->model->series->protocol >= PROTOCOL_V4 ?
								":LA:STAT ON" : ":LA:DISP ON") != SR_OK)
						return SR_ERR;
					devc->la_enabled = TRUE;
				}
			}
			if (ch->enabled != devc->digital_channels[ch->index]) {
				/* Enabled channel is currently disabled, or vice versa. */
				if (rigol_ds_config_set(sdi,
						devc->model->series->protocol >= PROTOCOL_V4 ?
							":LA:DIG%d:DISP %s" : ":DIG%d:TURN %s", ch->index,
						ch->enabled ? "ON" : "OFF") != SR_OK)
					return SR_ERR;
				devc->digital_channels[ch->index] = ch->enabled;
			}
		}
	}

	if (!devc->enabled_channels)
		return SR_ERR;

	/* Turn off LA module if on and no digital channels selected. */
	if (devc->la_enabled && !some_digital)
		if (rigol_ds_config_set(sdi,
				devc->model->series->protocol >= PROTOCOL_V4 ?
					":LA:STAT OFF" : ":LA:DISP OFF") != SR_OK)
			return SR_ERR;

	/* Set memory mode. */
	if (devc->data_source == DATA_SOURCE_SEGMENTED) {
		sr_err("Data source 'Segmented' not yet supported");
		return SR_ERR;
	}

	devc->analog_frame_size = analog_frame_size(sdi);
	devc->digital_frame_size = digital_frame_size(sdi);

	switch (devc->model->series->protocol) {
	case PROTOCOL_V2:
		if (rigol_ds_config_set(sdi, ":ACQ:MEMD LONG") != SR_OK)
			return SR_ERR;
		break;
	case PROTOCOL_V3:
		/* Apparently for the DS2000 the memory
		 * depth can only be set in Running state -
		 * this matches the behaviour of the UI. */
		if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
			return SR_ERR;
		if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
					devc->analog_frame_size) != SR_OK)
			return SR_ERR;
		if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
			return SR_ERR;
		break;
	default:
		break;
	}

	if (devc->data_source == DATA_SOURCE_LIVE)
		if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
			return SR_ERR;

	sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50,
			rigol_ds_receive, (void *)sdi);

	std_session_send_df_header(sdi);

	devc->channel_entry = devc->enabled_channels;

	if (rigol_ds_capture_start(sdi) != SR_OK)
		return SR_ERR;

	/* Start of first frame. */
	packet.type = SR_DF_FRAME_BEGIN;
	sr_session_send(sdi, &packet);

	return SR_OK;
}
Пример #26
0
static struct sr_datafeed_analog *handle_qm_v2(const struct sr_dev_inst *sdi,
		char **tokens)
{
	struct sr_datafeed_analog *analog;
	float fvalue;
	char *eptr;

	(void)sdi;

	fvalue = strtof(tokens[0], &eptr);
	if (fvalue == 0.0 && eptr == tokens[0]) {
		sr_err("Invalid float.");
		return NULL;
	}

	/* TODO: Check malloc return value. */
	analog = g_try_malloc0(sizeof(struct sr_datafeed_analog));
	analog->num_samples = 1;
	/* TODO: Check malloc return value. */
	analog->data = g_try_malloc(sizeof(float));
	*analog->data = fvalue;
	analog->mq = -1;

	if (!strcmp(tokens[1], "VAC") || !strcmp(tokens[1], "VDC")) {
		analog->mq = SR_MQ_VOLTAGE;
		analog->unit = SR_UNIT_VOLT;
		if (!strcmp(tokens[2], "NORMAL")) {
			if (tokens[1][1] == 'A') {
				analog->mqflags |= SR_MQFLAG_AC;
				analog->mqflags |= SR_MQFLAG_RMS;
			} else
				analog->mqflags |= SR_MQFLAG_DC;
		} else if (!strcmp(tokens[2], "OL") || !strcmp(tokens[2], "OL_MINUS")) {
			*analog->data = NAN;
		} else
			analog->mq = -1;
	} else if (!strcmp(tokens[1], "dBV") || !strcmp(tokens[1], "dBm")) {
		analog->mq = SR_MQ_VOLTAGE;
		if (tokens[1][2] == 'm')
			analog->unit = SR_UNIT_DECIBEL_MW;
		else
			analog->unit = SR_UNIT_DECIBEL_VOLT;
		analog->mqflags |= SR_MQFLAG_AC | SR_MQFLAG_RMS;
	} else if (!strcmp(tokens[1], "CEL") || !strcmp(tokens[1], "FAR")) {
		if (!strcmp(tokens[2], "NORMAL")) {
			analog->mq = SR_MQ_TEMPERATURE;
			if (tokens[1][0] == 'C')
				analog->unit = SR_UNIT_CELSIUS;
			else
				analog->unit = SR_UNIT_FAHRENHEIT;
		}
	} else if (!strcmp(tokens[1], "OHM")) {
		if (!strcmp(tokens[3], "NONE")) {
			analog->mq = SR_MQ_RESISTANCE;
			analog->unit = SR_UNIT_OHM;
			if (!strcmp(tokens[2], "OL") || !strcmp(tokens[2], "OL_MINUS")) {
				*analog->data = INFINITY;
			} else if (strcmp(tokens[2], "NORMAL"))
				analog->mq = -1;
		} else if (!strcmp(tokens[3], "OPEN_CIRCUIT")) {
			analog->mq = SR_MQ_CONTINUITY;
			analog->unit = SR_UNIT_BOOLEAN;
			*analog->data = 0.0;
		} else if (!strcmp(tokens[3], "SHORT_CIRCUIT")) {
			analog->mq = SR_MQ_CONTINUITY;
			analog->unit = SR_UNIT_BOOLEAN;
			*analog->data = 1.0;
		}
	} else if (!strcmp(tokens[1], "F")
			&& !strcmp(tokens[2], "NORMAL")
			&& !strcmp(tokens[3], "NONE")) {
		analog->mq = SR_MQ_CAPACITANCE;
		analog->unit = SR_UNIT_FARAD;
	} else if (!strcmp(tokens[1], "AAC") || !strcmp(tokens[1], "ADC")) {
		analog->mq = SR_MQ_CURRENT;
		analog->unit = SR_UNIT_AMPERE;
		if (!strcmp(tokens[2], "NORMAL")) {
			if (tokens[1][1] == 'A') {
				analog->mqflags |= SR_MQFLAG_AC;
				analog->mqflags |= SR_MQFLAG_RMS;
			} else
				analog->mqflags |= SR_MQFLAG_DC;
		} else if (!strcmp(tokens[2], "OL") || !strcmp(tokens[2], "OL_MINUS")) {
			*analog->data = NAN;
		} else
			analog->mq = -1;
	} if (!strcmp(tokens[1], "Hz") && !strcmp(tokens[2], "NORMAL")) {
		analog->mq = SR_MQ_FREQUENCY;
		analog->unit = SR_UNIT_HERTZ;
	} else if (!strcmp(tokens[1], "PCT") && !strcmp(tokens[2], "NORMAL")) {
		analog->mq = SR_MQ_DUTY_CYCLE;
		analog->unit = SR_UNIT_PERCENTAGE;
	} else if (!strcmp(tokens[1], "S") && !strcmp(tokens[2], "NORMAL")) {
		analog->mq = SR_MQ_PULSE_WIDTH;
		analog->unit = SR_UNIT_SECOND;
	} else if (!strcmp(tokens[1], "SIE") && !strcmp(tokens[2], "NORMAL")) {
		analog->mq = SR_MQ_CONDUCTANCE;
		analog->unit = SR_UNIT_SIEMENS;
	}

	if (analog->mq == -1) {
		/* Not a valid measurement. */
		g_free(analog->data);
		g_free(analog);
		analog = NULL;
	}

	return analog;
}
Пример #27
0
/**
 * Try to find a valid packet in a serial data stream.
 *
 * @param serial Previously initialized serial port structure.
 * @param buf Buffer containing the bytes to write.
 * @param buflen Size of the buffer.
 * @param[in] packet_size Size, in bytes, of a valid packet.
 * @param is_valid Callback that assesses whether the packet is valid or not.
 * @param[in] timeout_ms The timeout after which, if no packet is detected, to
 *                   abort scanning.
 * @param[in] baudrate The baudrate of the serial port. This parameter is not
 *                 critical, but it helps fine tune the serial port polling
 *                 delay.
 *
 * @retval SR_OK Valid packet was found within the given timeout.
 * @retval SR_ERR Failure.
 *
 * @private
 */
SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial,
				 uint8_t *buf, size_t *buflen,
				 size_t packet_size,
				 packet_valid_callback is_valid,
				 uint64_t timeout_ms, int baudrate)
{
	uint64_t start, time, byte_delay_us;
	size_t ibuf, i, maxlen;
	ssize_t len;

	maxlen = *buflen;

	sr_dbg("Detecting packets on %s (timeout = %" PRIu64
	       "ms, baudrate = %d).", serial->port, timeout_ms, baudrate);

	if (maxlen < (packet_size / 2) ) {
		sr_err("Buffer size must be at least twice the packet size.");
		return SR_ERR;
	}

	/* Assume 8n1 transmission. That is 10 bits for every byte. */
	byte_delay_us = 10 * ((1000 * 1000) / baudrate);
	start = g_get_monotonic_time();

	i = ibuf = len = 0;
	while (ibuf < maxlen) {
		len = serial_read_nonblocking(serial, &buf[ibuf], 1);
		if (len > 0) {
			ibuf += len;
		} else if (len == 0) {
			/* No logging, already done in serial_read(). */
		} else {
			/* Error reading byte, but continuing anyway. */
		}

		time = g_get_monotonic_time() - start;
		time /= 1000;

		if ((ibuf - i) >= packet_size) {
			/* We have at least a packet's worth of data. */
			if (is_valid(&buf[i])) {
				sr_spew("Found valid %zu-byte packet after "
					"%" PRIu64 "ms.", (ibuf - i), time);
				*buflen = ibuf;
				return SR_OK;
			} else {
				sr_spew("Got %zu bytes, but not a valid "
					"packet.", (ibuf - i));
			}
			/* Not a valid packet. Continue searching. */
			i++;
		}
		if (time >= timeout_ms) {
			/* Timeout */
			sr_dbg("Detection timed out after %" PRIu64 "ms.", time);
			break;
		}
		if (len < 1)
			g_usleep(byte_delay_us);
	}

	*buflen = ibuf;

	sr_err("Didn't find a valid packet (read %zu bytes).", *buflen);

	return SR_ERR;
}
Пример #28
0
static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
{
	int ret;
	struct dev_context *devc;
	uint64_t num_samples, slope;
	int trigger_pos;
	double pos;

	devc = sdi->priv;

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR_DEV_CLOSED;

	switch (id) {
	case SR_CONF_SAMPLERATE:
		// FIXME
		return mso_configure_rate(sdi, g_variant_get_uint64(data));
		ret = SR_OK;
		break;
	case SR_CONF_LIMIT_SAMPLES:
		num_samples = g_variant_get_uint64(data);
		if (num_samples != 1024) {
			sr_err("Only 1024 samples are supported.");
			ret = SR_ERR_ARG;
		} else {
			devc->limit_samples = num_samples;
			sr_dbg("setting limit_samples to %i\n",
			       num_samples);
			ret = SR_OK;
		}
		break;
	case SR_CONF_CAPTURE_RATIO:
		ret = SR_OK;
		break;
	case SR_CONF_TRIGGER_SLOPE:
		slope = g_variant_get_uint64(data);
		if (slope != SLOPE_NEGATIVE && slope != SLOPE_POSITIVE) {
			sr_err("Invalid trigger slope");
			ret = SR_ERR_ARG;
		} else {
			devc->trigger_slope = slope;
			ret = SR_OK;
		}
		break;
	case SR_CONF_HORIZ_TRIGGERPOS:
		pos = g_variant_get_double(data);
		if (pos < 0 || pos > 255) {
			sr_err("Trigger position (%f) should be between 0 and 255.", pos);
			ret = SR_ERR_ARG;
		} else {
			trigger_pos = (int)pos;
			devc->trigger_holdoff[0] = trigger_pos & 0xff;
			ret = SR_OK;
		}
		break;
	case SR_CONF_RLE:
		ret = SR_OK;
		break;
	default:
		ret = SR_ERR_NA;
		break;
	}

	return ret;
}
Пример #29
0
static int dev_open(struct sr_dev_inst *sdi)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_usb_dev_inst *usb;
	uint8_t buffer[PACKET_LENGTH];
	int ret;

	if (!(drvc = di->priv)) {
		sr_err("Driver was not initialized.");
		return SR_ERR;
	}

	usb = sdi->conn;
	devc = sdi->priv;

	if (sr_usb_open(drvc->sr_ctx->libusb_ctx, usb) != SR_OK)
		return SR_ERR;

	/*
	 * Determine if a kernel driver is active on this interface and, if so,
	 * detach it.
	 */
	if (libusb_kernel_driver_active(usb->devhdl, USB_INTERFACE) == 1) {
		ret = libusb_detach_kernel_driver(usb->devhdl, USB_INTERFACE);
		if (ret < 0) {
			sr_err("Failed to detach kernel driver: %s.",
				libusb_error_name(ret));
			return SR_ERR;
		}
	}

	if ((ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE)) < 0) {
		sr_err("Failed to claim interface: %s.",
			libusb_error_name(ret));
		return SR_ERR;
	}

	libusb_fill_control_transfer(devc->xfer_in, usb->devhdl,
		devc->xfer_buf_in, sl2_receive_transfer_in,
		sdi, USB_TIMEOUT);

	libusb_fill_control_transfer(devc->xfer_out, usb->devhdl,
		devc->xfer_buf_out, sl2_receive_transfer_out,
		sdi, USB_TIMEOUT);

	memset(buffer, 0, sizeof(buffer));

	buffer[0] = CMD_RESET;
	if ((ret = sl2_transfer_out(usb->devhdl, buffer)) != PACKET_LENGTH) {
		sr_err("Device reset failed: %s.", libusb_error_name(ret));
		return SR_ERR;
	}

	/*
	 * Set the device to idle state. If the device is not in idle state it
	 * possibly will reset itself after a few seconds without being used
	 * and thereby close the connection.
	 */
	buffer[0] = CMD_IDLE;
	if ((ret = sl2_transfer_out(usb->devhdl, buffer)) != PACKET_LENGTH) {
		sr_err("Failed to set device in idle state: %s.",
			libusb_error_name(ret));
		return SR_ERR;
	}

	sdi->status = SR_ST_ACTIVE;

	return SR_OK;
}
Пример #30
0
static GSList *scan(GSList *options)
{
	struct sr_dev_inst *sdi;
	struct sr_probe *probe;
	struct drv_context *drvc;
	struct dev_context *devc;
	GSList *devices;
	unsigned int i;
	int ret;

	(void)options;

	drvc = di->priv;

	devices = NULL;

	/* Allocate memory for our private device context. */
	if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
		sr_err("Device context malloc failed.");
		goto err_free_nothing;
	}

	/* Set some sane defaults. */
	devc->ftdic = NULL;
	devc->cur_samplerate = SR_MHZ(100); /* 100MHz == max. samplerate */
	devc->limit_msec = 0;
	devc->limit_samples = 0;
	devc->cb_data = NULL;
	memset(devc->mangled_buf, 0, BS);
	devc->final_buf = NULL;
	devc->trigger_pattern = 0x00; /* Value irrelevant, see trigger_mask. */
	devc->trigger_mask = 0x00; /* All probes are "don't care". */
	devc->trigger_timeout = 10; /* Default to 10s trigger timeout. */
	devc->trigger_found = 0;
	devc->done = 0;
	devc->block_counter = 0;
	devc->divcount = 0; /* 10ns sample period == 100MHz samplerate */
	devc->usb_pid = 0;

	/* Allocate memory where we'll store the de-mangled data. */
	if (!(devc->final_buf = g_try_malloc(SDRAM_SIZE))) {
		sr_err("final_buf malloc failed.");
		goto err_free_devc;
	}

	/* Allocate memory for the FTDI context (ftdic) and initialize it. */
	if (!(devc->ftdic = ftdi_new())) {
		sr_err("%s: ftdi_new failed.", __func__);
		goto err_free_final_buf;
	}

	/* Check for the device and temporarily open it. */
	for (i = 0; i < ARRAY_SIZE(usb_pids); i++) {
		sr_dbg("Probing for VID/PID %04x:%04x.", USB_VENDOR_ID,
		       usb_pids[i]);
		ret = ftdi_usb_open_desc(devc->ftdic, USB_VENDOR_ID,
					 usb_pids[i], USB_DESCRIPTION, NULL);
		if (ret == 0) {
			sr_dbg("Found LA8 device (%04x:%04x).",
			       USB_VENDOR_ID, usb_pids[i]);
			devc->usb_pid = usb_pids[i];
		}
	}

	if (devc->usb_pid == 0)
		goto err_free_ftdic;

	/* Register the device with libsigrok. */
	sdi = sr_dev_inst_new(0, SR_ST_INITIALIZING,
			USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
	if (!sdi) {
		sr_err("%s: sr_dev_inst_new failed.", __func__);
		goto err_close_ftdic;
	}
	sdi->driver = di;
	sdi->priv = devc;

	for (i = 0; chronovu_la8_probe_names[i]; i++) {
		if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
					   chronovu_la8_probe_names[i])))
			return NULL;
		sdi->probes = g_slist_append(sdi->probes, probe);
	}

	devices = g_slist_append(devices, sdi);
	drvc->instances = g_slist_append(drvc->instances, sdi);

	/* Close device. We'll reopen it again when we need it. */
	(void) la8_close(devc); /* Log, but ignore errors. */

	return devices;

err_close_ftdic:
	(void) la8_close(devc); /* Log, but ignore errors. */
err_free_ftdic:
	ftdi_free(devc->ftdic); /* NOT free() or g_free()! */
err_free_final_buf:
	g_free(devc->final_buf);
err_free_devc:
	g_free(devc);
err_free_nothing:

	return NULL;
}