Beispiel #1
0
static void brymen_bm86x_handle_packet(const struct sr_dev_inst *sdi,
                                       unsigned char *buf)
{
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog analog[2];
	struct sr_analog_encoding encoding[2];
	struct sr_analog_meaning meaning[2];
	struct sr_analog_spec spec[2];
	float floatval[2];

	devc = sdi->priv;

	sr_analog_init(&analog[0], &encoding[0], &meaning[0], &spec[0], 0);
	sr_analog_init(&analog[1], &encoding[1], &meaning[1], &spec[1], 0);

	analog[0].meaning->mq = 0;
	analog[0].meaning->mqflags = 0;

	analog[1].meaning->mq = 0;
	analog[1].meaning->mqflags = 0;

	brymen_bm86x_parse(buf, floatval, analog);

	if (analog[0].meaning->mq != 0) {
		/* Got a measurement. */
		analog[0].num_samples = 1;
		analog[0].data = &floatval[0];
		analog[0].meaning->channels = g_slist_append(NULL, sdi->channels->data);
		packet.type = SR_DF_ANALOG;
		packet.payload = &analog[0];
		sr_session_send(sdi, &packet);
		g_slist_free(analog[0].meaning->channels);
	}

	if (analog[1].meaning->mq != 0) {
		/* Got a measurement. */
		analog[1].num_samples = 1;
		analog[1].data = &floatval[1];
		analog[1].meaning->channels = g_slist_append(NULL, sdi->channels->next->data);
		packet.type = SR_DF_ANALOG;
		packet.payload = &analog[1];
		sr_session_send(sdi, &packet);
		g_slist_free(analog[1].meaning->channels);
	}

	if (analog[0].meaning->mq != 0 || analog[1].meaning->mq != 0)
		sr_sw_limits_update_samples_read(&devc->sw_limits, 1);
}
Beispiel #2
0
static void send_sample(struct sr_dev_inst *sdi)
{
	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;

	devc = sdi->priv;

	sr_analog_init(&analog, &encoding, &meaning, &spec, 2);

	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	analog.meaning->channels = sdi->channels;
	analog.num_samples = 1;

	analog.meaning->mq = SR_MQ_VOLTAGE;
	analog.meaning->unit = SR_UNIT_VOLT;
	analog.meaning->mqflags = SR_MQFLAG_DC;
	analog.data = &devc->voltage;
	sr_session_send(sdi, &packet);

	analog.meaning->mq = SR_MQ_CURRENT;
	analog.meaning->unit = SR_UNIT_AMPERE;
	analog.meaning->mqflags = 0;
	analog.data = &devc->current;
	sr_session_send(sdi, &packet);


	sr_sw_limits_update_samples_read(&devc->limits, 1);
}
Beispiel #3
0
static void handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi)
{
    float floatval;
    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;

    devc = sdi->priv;

    sr_analog_init(&analog, &encoding, &meaning, &spec, 0);

    analog.num_samples = 1;
    analog.meaning->mq = 0;

    if (brymen_parse(buf, &floatval, &analog, NULL) != SR_OK)
        return;
    analog.data = &floatval;

    analog.meaning->channels = sdi->channels;

    if (analog.meaning->mq != 0) {
        /* Got a measurement. */
        packet.type = SR_DF_ANALOG;
        packet.payload = &analog;
        sr_session_send(sdi, &packet);
        sr_sw_limits_update_samples_read(&devc->sw_limits, 1);
    }
}
Beispiel #4
0
static void send_data(const struct sr_dev_inst *sdi, float sample)
{
	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;

	devc = sdi->priv;

	sr_analog_init(&analog, &encoding, &meaning, &spec, 1);
	meaning.mq = SR_MQ_SOUND_PRESSURE_LEVEL;
	meaning.mqflags = devc->cur_mqflags;
	meaning.unit = SR_UNIT_DECIBEL_SPL;
	meaning.channels = sdi->channels;
	analog.num_samples = 1;
	analog.data = &sample;
	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	sr_session_send(sdi, &packet);

	devc->num_samples++;
	if (devc->limit_samples && devc->num_samples >= devc->limit_samples)
		sdi->driver->dev_acquisition_stop((struct sr_dev_inst *)sdi);
}
Beispiel #5
0
static void teleinfo_send_value(struct sr_dev_inst *sdi, const char *channel_name,
                                float value, enum sr_mq mq, enum sr_unit unit)
{
	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_channel *ch;

	ch = teleinfo_find_channel(sdi, channel_name);

	if (!ch || !ch->enabled)
		return;

	/* Note: digits/spec_digits is actually really 0 for this device! */
	sr_analog_init(&analog, &encoding, &meaning, &spec, 0);
	analog.meaning->channels = g_slist_append(analog.meaning->channels, ch);
	analog.num_samples = 1;
	analog.meaning->mq = mq;
	analog.meaning->unit = unit;
	analog.data = &value;

	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	sr_session_send(sdi, &packet);
	g_slist_free(analog.meaning->channels);
}
Beispiel #6
0
static void push_samples(const struct sr_dev_inst *sdi, uint8_t *buf, size_t num)
{
	struct dev_context *devc = sdi->priv;
	float *data = devc->samples;
	struct sr_datafeed_analog analog;
	struct sr_analog_encoding encoding;
	struct sr_analog_meaning meaning;
	struct sr_analog_spec spec;
	struct sr_datafeed_packet packet = {
		.type = SR_DF_ANALOG,
		.payload = &analog,
	};
	float factor = devc->factor;

	while (num--)
		data[num] = (buf[num] - 0x80) * factor;

	sr_analog_init(&analog, &encoding, &meaning, &spec, 0);
	analog.meaning->channels = devc->enabled_channel;
	analog.meaning->mq = SR_MQ_VOLTAGE;
	analog.meaning->unit = SR_UNIT_VOLT;
	analog.meaning->mqflags = 0;
	analog.num_samples = num;
	analog.data = data;

	sr_session_send(sdi, &packet);
}
Beispiel #7
0
static int handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi, int idx)
{
	float temperature, humidity;
	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 dev_context *devc;
	GSList *l;
	int ret;

	(void)idx;

	devc = sdi->priv;

	ret = packet_parse((const char *)buf, idx, &temperature, &humidity);
	if (ret < 0) {
		sr_err("Failed to parse packet.");
		return SR_ERR;
	}

	sr_analog_init(&analog, &encoding, &meaning, &spec, 3);

	/* Common values for both channels. */
	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	analog.num_samples = 1;

	/* Temperature. */
	l = g_slist_copy(sdi->channels);
	l = g_slist_remove_link(l, g_slist_nth(l, 1));
	meaning.channels = l;
	meaning.mq = SR_MQ_TEMPERATURE;
	meaning.unit = SR_UNIT_CELSIUS; /* TODO: Use C/F correctly. */
	analog.data = &temperature;
	sr_session_send(sdi, &packet);
	g_slist_free(l);

	/* Humidity. */
	if (mic_devs[idx].has_humidity) {
		l = g_slist_copy(sdi->channels);
		l = g_slist_remove_link(l, g_slist_nth(l, 0));
		meaning.channels = l;
		meaning.mq = SR_MQ_RELATIVE_HUMIDITY;
		meaning.unit = SR_UNIT_PERCENTAGE;
		analog.data = &humidity;
		sr_session_send(sdi, &packet);
		g_slist_free(l);
	}

	devc->num_samples++;

	return SR_OK;
}
Beispiel #8
0
static void maynuo_m97_session_send_value(const struct sr_dev_inst *sdi, struct sr_channel *ch, float value, enum sr_mq mq, enum sr_unit unit)
{
    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;

    sr_analog_init(&analog, &encoding, &meaning, &spec, 0);
    analog.meaning->channels = g_slist_append(NULL, ch);
    analog.num_samples = 1;
    analog.data = &value;
    analog.meaning->mq = mq;
    analog.meaning->unit = unit;
    analog.meaning->mqflags = SR_MQFLAG_DC;

    packet.type = SR_DF_ANALOG;
    packet.payload = &analog;
    sr_session_send(sdi, &packet);
    g_slist_free(analog.meaning->channels);
}
Beispiel #9
0
static void handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi,
			  void *info)
{
	struct dmm_info *dmm;
	float floatval;
	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 dev_context *devc;

	dmm = (struct dmm_info *)sdi->driver;

	log_dmm_packet(buf);
	devc = sdi->priv;

	/* Note: digits/spec_digits will be overridden by the DMM parsers. */
	sr_analog_init(&analog, &encoding, &meaning, &spec, 0);

	analog.meaning->channels = sdi->channels;
	analog.num_samples = 1;
	analog.meaning->mq = 0;

	dmm->packet_parse(buf, &floatval, &analog, info);
	analog.data = &floatval;

	/* If this DMM needs additional handling, call the resp. function. */
	if (dmm->dmm_details)
		dmm->dmm_details(&analog, info);

	if (analog.meaning->mq != 0) {
		/* Got a measurement. */
		packet.type = SR_DF_ANALOG;
		packet.payload = &analog;
		sr_session_send(sdi, &packet);
		sr_sw_limits_update_samples_read(&devc->limits, 1);
	}
}
Beispiel #10
0
/** Send data packets for current measurements. */
static void send_data(struct sr_dev_inst *sdi)
{
	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;
	int i;
	float data[MAX_CHANNELS];

	devc = sdi->priv;
	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;

	sr_analog_init(&analog, &encoding, &meaning, &spec, 0);

	analog.meaning->channels = sdi->channels;
	analog.num_samples = 1;
	analog.meaning->mq = SR_MQ_VOLTAGE;
	analog.meaning->unit = SR_UNIT_VOLT;
	analog.meaning->mqflags = SR_MQFLAG_DC;
	analog.data = data;

	for (i = 0; i < devc->model->num_channels; i++)
		((float *)analog.data)[i] = devc->channel_status[i].output_voltage_last; /* Value always 3.3 or 5 for channel 3, if present! */
	sr_session_send(sdi, &packet);

	analog.meaning->mq = SR_MQ_CURRENT;
	analog.meaning->unit = SR_UNIT_AMPERE;
	analog.meaning->mqflags = 0;
	analog.data = data;
	for (i = 0; i < devc->model->num_channels; i++)
		((float *)analog.data)[i] = devc->channel_status[i].output_current_last; /* Value always 0 for channel 3, if present! */
	sr_session_send(sdi, &packet);

	sr_sw_limits_update_samples_read(&devc->limits, 1);
}
Beispiel #11
0
SR_PRIV void mso_send_data_proc(struct sr_dev_inst *sdi,
	uint8_t *data, size_t length, size_t sample_width)
{
	size_t i;
	struct dev_context *devc;
	struct sr_datafeed_analog analog;
	struct sr_analog_encoding encoding;
	struct sr_analog_meaning meaning;
	struct sr_analog_spec spec;

	(void)sample_width;

	devc = sdi->priv;

	length /= 2;

	/* Send the logic */
	for (i = 0; i < length; i++) {
		devc->logic_buffer[i] = data[i * 2];
		/* Rescale to -10V - +10V from 0-255. */
		devc->analog_buffer[i] = (data[i * 2 + 1] - 128.0f) / 12.8f;
	};

	const struct sr_datafeed_logic logic = {
		.length = length,
		.unitsize = 1,
		.data = devc->logic_buffer
	};

	const struct sr_datafeed_packet logic_packet = {
		.type = SR_DF_LOGIC,
		.payload = &logic
	};

	sr_session_send(sdi, &logic_packet);

	sr_analog_init(&analog, &encoding, &meaning, &spec, 2);
	analog.meaning->channels = devc->enabled_analog_channels;
	analog.meaning->mq = SR_MQ_VOLTAGE;
	analog.meaning->unit = SR_UNIT_VOLT;
	analog.meaning->mqflags = 0 /* SR_MQFLAG_DC */;
	analog.num_samples = length;
	analog.data = devc->analog_buffer;

	const struct sr_datafeed_packet analog_packet = {
		.type = SR_DF_ANALOG,
		.payload = &analog
	};

	sr_session_send(sdi, &analog_packet);
}

SR_PRIV void la_send_data_proc(struct sr_dev_inst *sdi,
	uint8_t *data, size_t length, size_t sample_width)
{
	const struct sr_datafeed_logic logic = {
		.length = length,
		.unitsize = sample_width,
		.data = data
	};

	const struct sr_datafeed_packet packet = {
		.type = SR_DF_LOGIC,
		.payload = &logic
	};

	sr_session_send(sdi, &packet);
}

SR_PRIV void LIBUSB_CALL fx2lafw_receive_transfer(struct libusb_transfer *transfer)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	gboolean packet_has_error = FALSE;
	struct sr_datafeed_packet packet;
	unsigned int num_samples;
	int trigger_offset, cur_sample_count, unitsize;
	int pre_trigger_samples;

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

	/*
	 * If acquisition has already ended, just free any queued up
	 * transfer that come in.
	 */
	if (devc->acq_aborted) {
		free_transfer(transfer);
		return;
	}

	sr_dbg("receive_transfer(): status %s received %d bytes.",
		libusb_error_name(transfer->status), transfer->actual_length);

	/* Save incoming transfer before reusing the transfer struct. */
	unitsize = devc->sample_wide ? 2 : 1;
	cur_sample_count = transfer->actual_length / unitsize;

	switch (transfer->status) {
	case LIBUSB_TRANSFER_NO_DEVICE:
		fx2lafw_abort_acquisition(devc);
		free_transfer(transfer);
		return;
	case LIBUSB_TRANSFER_COMPLETED:
	case LIBUSB_TRANSFER_TIMED_OUT: /* We may have received some data though. */
		break;
	default:
		packet_has_error = TRUE;
		break;
	}

	if (transfer->actual_length == 0 || packet_has_error) {
		devc->empty_transfer_count++;
		if (devc->empty_transfer_count > MAX_EMPTY_TRANSFERS) {
			/*
			 * The FX2 gave up. End the acquisition, the frontend
			 * will work out that the samplecount is short.
			 */
			fx2lafw_abort_acquisition(devc);
			free_transfer(transfer);
		} else {
			resubmit_transfer(transfer);
		}
		return;
	} else {
		devc->empty_transfer_count = 0;
	}
	if (devc->trigger_fired) {
		if (!devc->limit_samples || devc->sent_samples < devc->limit_samples) {
			/* Send the incoming transfer to the session bus. */
			if (devc->limit_samples && devc->sent_samples + cur_sample_count > devc->limit_samples)
				num_samples = devc->limit_samples - devc->sent_samples;
			else
				num_samples = cur_sample_count;

			if (devc->dslogic && devc->trigger_pos > devc->sent_samples
				&& devc->trigger_pos <= devc->sent_samples + num_samples) {
					/* DSLogic trigger in this block. Send trigger position. */
					trigger_offset = devc->trigger_pos - devc->sent_samples;
					/* Pre-trigger samples. */
					devc->send_data_proc(sdi, (uint8_t *)transfer->buffer,
						trigger_offset * unitsize, unitsize);
					devc->sent_samples += trigger_offset;
					/* Trigger position. */
					devc->trigger_pos = 0;
					packet.type = SR_DF_TRIGGER;
					packet.payload = NULL;
					sr_session_send(sdi, &packet);
					/* Post trigger samples. */
					num_samples -= trigger_offset;
					devc->send_data_proc(sdi, (uint8_t *)transfer->buffer
							+ trigger_offset * unitsize, num_samples * unitsize, unitsize);
					devc->sent_samples += num_samples;
			} else {
				devc->send_data_proc(sdi, (uint8_t *)transfer->buffer,
					num_samples * unitsize, unitsize);
				devc->sent_samples += num_samples;
			}
		}
	} else {
		trigger_offset = soft_trigger_logic_check(devc->stl,
			transfer->buffer, transfer->actual_length, &pre_trigger_samples);
		if (trigger_offset > -1) {
			devc->sent_samples += pre_trigger_samples;
			num_samples = cur_sample_count - trigger_offset;
			if (devc->limit_samples &&
					num_samples > devc->limit_samples - devc->sent_samples)
				num_samples = devc->limit_samples - devc->sent_samples;

			devc->send_data_proc(sdi, (uint8_t *)transfer->buffer
					+ trigger_offset * unitsize,
					num_samples * unitsize, unitsize);
			devc->sent_samples += num_samples;

			devc->trigger_fired = TRUE;
		}
	}

	if (devc->limit_samples && devc->sent_samples >= devc->limit_samples) {
		fx2lafw_abort_acquisition(devc);
		free_transfer(transfer);
	} else
		resubmit_transfer(transfer);
}

static unsigned int to_bytes_per_ms(unsigned int samplerate)
{
	return samplerate / 1000;
}

SR_PRIV size_t fx2lafw_get_buffer_size(struct dev_context *devc)
{
	size_t s;

	/*
	 * The buffer should be large enough to hold 10ms of data and
	 * a multiple of 512.
	 */
	s = 10 * to_bytes_per_ms(devc->cur_samplerate);
	return (s + 511) & ~511;
}
Beispiel #12
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_analog_encoding encoding;
	struct sr_analog_meaning meaning;
	struct sr_analog_spec spec;
	struct sr_datafeed_packet packet;

	devc = sdi->priv;

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

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

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

	for (pos = 0; pos < LINE_LENGTH; 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;
	/* TODO: Use proper 'digits' value for this device (and its modes). */
	sr_analog_init(&analog, &encoding, &meaning, &spec, 2);

	/*
	 * 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.meaning->mq = SR_MQ_VOLTAGE;
		break;
	case 1:
		analog.meaning->mq = SR_MQ_CURRENT;	/* 2A */
		break;
	case 2:
		analog.meaning->mq = SR_MQ_RESISTANCE;
		break;
	case 3:
		analog.meaning->mq = SR_MQ_CAPACITANCE;
		break;
	case 4:
		analog.meaning->mq = SR_MQ_TEMPERATURE;
		break;
	case 5:
		analog.meaning->mq = SR_MQ_FREQUENCY;
		break;
	case 6:
		analog.meaning->mq = SR_MQ_CURRENT;	/* 10A */
		break;
	case 7:
		analog.meaning->mq = SR_MQ_GAIN;		/* TODO: Scale factor */
		break;
	case 8:
		analog.meaning->mq = SR_MQ_GAIN;		/* Percentage */
		scale /= 100.0;
		break;
	case 9:
		analog.meaning->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.meaning->unit = SR_UNIT_HERTZ;
		break;
	case 1: /* V TRMS, only type 5 */
		analog.meaning->unit = SR_UNIT_VOLT;
		analog.meaning->mqflags |= (SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS);
		break;
	case 2: /* V AC */
		analog.meaning->unit = SR_UNIT_VOLT;
		analog.meaning->mqflags |= SR_MQFLAG_AC;
		if (devc->type >= 3)
			analog.meaning->mqflags |= SR_MQFLAG_RMS;
		break;
	case 3: /* V DC */
		analog.meaning->unit = SR_UNIT_VOLT;
		analog.meaning->mqflags |= SR_MQFLAG_DC;
		break;
	case 4: /* Ohm */
		analog.meaning->unit = SR_UNIT_OHM;
		break;
	case 5: /* Continuity */
		analog.meaning->unit = SR_UNIT_BOOLEAN;
		analog.meaning->mq = SR_MQ_CONTINUITY;
		/* TODO: Continuity handling is a bit odd in libsigrok. */
		break;
	case 6: /* Degree Celsius */
		analog.meaning->unit = SR_UNIT_CELSIUS;
		break;
	case 7: /* Capacity */
		analog.meaning->unit = SR_UNIT_FARAD;
		break;
	case 8: /* Current DC */
		analog.meaning->unit = SR_UNIT_AMPERE;
		analog.meaning->mqflags |= SR_MQFLAG_DC;
		break;
	case 9: /* Current AC */
		analog.meaning->unit = SR_UNIT_AMPERE;
		analog.meaning->mqflags |= SR_MQFLAG_AC;
		if (devc->type >= 3)
			analog.meaning->mqflags |= SR_MQFLAG_RMS;
		break;
	case 0xa: /* Current TRMS, only type 5 */
		analog.meaning->unit = SR_UNIT_AMPERE;
		analog.meaning->mqflags |= (SR_MQFLAG_AC | SR_MQFLAG_DC | SR_MQFLAG_RMS);
		break;
	case 0xb: /* Diode */
		analog.meaning->unit = SR_UNIT_VOLT;
		analog.meaning->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.meaning->mq == SR_MQ_CONTINUITY) {
		if (flags & 0x20)
			value = 1.0; /* Beep */
		else
			value = 0.0;
	}
	/* 0x10: AVG */
	/* 0x08: Diode */
	if (flags & 0x04) /* REL */
		analog.meaning->mqflags |= SR_MQFLAG_RELATIVE;
	/* 0x02: SHIFT	*/
	if (flags & 0x01) /* % */
		analog.meaning->unit = SR_UNIT_PERCENTAGE;

	/* 14, 15 */
	flags = (xgittoint(devc->buf[14]) << 8) | xgittoint(devc->buf[15]);
	if (!(flags & 0x80))	/* MAN: Manual range */
		analog.meaning->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.meaning->mqflags |= SR_MQFLAG_HOLD;
	/* 0x04: LIMIT	*/
	if (flags & 0x02) 	/* MAX */
		analog.meaning->mqflags |= SR_MQFLAG_MAX;
	if (flags & 0x01) 	/* MIN */
		analog.meaning->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 data 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.meaning->unit == SR_UNIT_VOLT)
			analog.meaning->unit = SR_UNIT_DECIBEL_VOLT;
		else
			analog.meaning->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.meaning->channels = sdi->channels;
	analog.num_samples = 1;
	analog.data = &value;

	memset(&packet, 0, sizeof(struct sr_datafeed_packet));
	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	sr_session_send(sdi, &packet);

	/* Finish processing. */
	sr_sw_limits_update_samples_read(&devc->limits, 1);
	devc->buflen = 0;
}
Beispiel #13
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;
}
Beispiel #14
0
SR_PRIV int gwinstek_gds_800_receive_data(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;
	char command[32];
	char *response;
	float volts_per_division;
	int num_samples, i;
	float samples[MAX_SAMPLES];
	uint32_t sample_rate;
	char *end_ptr;

	(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->state) {
	case START_ACQUISITION:
		if (sr_scpi_send(scpi, ":TRIG:MOD 3") != SR_OK) {
			sr_err("Failed to set trigger mode to SINGLE.");
			sdi->driver->dev_acquisition_stop(sdi);
			return TRUE;
		}
		if (sr_scpi_send(scpi, ":STOP") != SR_OK) {
			sr_err("Failed to put the trigger system into STOP state.");
			sdi->driver->dev_acquisition_stop(sdi);
			return TRUE;
		}
		if (sr_scpi_send(scpi, ":RUN") != SR_OK) {
			sr_err("Failed to put the trigger system into RUN state.");
			sdi->driver->dev_acquisition_stop(sdi);
			return TRUE;
		}

		devc->cur_acq_channel = 0;
		devc->state = START_TRANSFER_OF_CHANNEL_DATA;
		break;
	case START_TRANSFER_OF_CHANNEL_DATA:
		if (((struct sr_channel *)g_slist_nth_data(sdi->channels, devc->cur_acq_channel))->enabled) {
			if (sr_scpi_send(scpi, ":ACQ%d:MEM?", devc->cur_acq_channel+1) != SR_OK) {
				sr_err("Failed to acquire memory.");
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			}
			if (sr_scpi_read_begin(scpi) != SR_OK) {
				sr_err("Could not begin reading SCPI response.");
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			}
			devc->state = WAIT_FOR_TRANSFER_OF_BEGIN_TRANSMISSION_COMPLETE;
			devc->cur_rcv_buffer_position = 0;
		} else {
			/* All channels acquired. */
			if (devc->cur_acq_channel == ANALOG_CHANNELS - 1) {
				sr_spew("All channels acquired.");

				if (devc->cur_acq_frame == devc->frame_limit - 1) {
					/* All frames accquired. */
					sr_spew("All frames acquired.");
					
					sdi->driver->dev_acquisition_stop(sdi);
					return TRUE;
				} else {
					/* Start acquiring next frame. */
					if (devc->df_started) {
						packet.type = SR_DF_FRAME_END;
						sr_session_send(sdi, &packet);
						
						packet.type = SR_DF_FRAME_BEGIN;
						sr_session_send(sdi, &packet);
					}

					devc->cur_acq_frame++;
					devc->state = START_ACQUISITION;
				}
			} else {
				/* Start acquiring next channel. */
				devc->cur_acq_channel++;
			}
		}
		break;
	case WAIT_FOR_TRANSFER_OF_BEGIN_TRANSMISSION_COMPLETE:
		if (read_data(sdi, scpi, devc, 1) == SR_OK) {
			if (devc->rcv_buffer[0] == '#')
				devc->state = WAIT_FOR_TRANSFER_OF_DATA_SIZE_DIGIT_COMPLETE;
		}
		break;
	case WAIT_FOR_TRANSFER_OF_DATA_SIZE_DIGIT_COMPLETE:
		if (read_data(sdi, scpi, devc, 1) == SR_OK) {
			if (devc->rcv_buffer[0] != '4' &&
				devc->rcv_buffer[0] != '5' &&
				devc->rcv_buffer[0] != '6') {
				sr_err("Data size digits is not 4, 5 or 6 but "
				       "'%c'.", devc->rcv_buffer[0]);
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			} else {
				devc->data_size_digits = devc->rcv_buffer[0] - '0';
				devc->state = WAIT_FOR_TRANSFER_OF_DATA_SIZE_COMPLETE;
			}
		}
		break;
	case WAIT_FOR_TRANSFER_OF_DATA_SIZE_COMPLETE:
		if (read_data(sdi, scpi, devc, devc->data_size_digits) == SR_OK) {
			devc->rcv_buffer[devc->data_size_digits] = 0;
			if (sr_atoi(devc->rcv_buffer, &devc->data_size) != SR_OK) {
				sr_err("Could not parse data size '%s'", devc->rcv_buffer);
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			} else
				devc->state = WAIT_FOR_TRANSFER_OF_SAMPLE_RATE_COMPLETE;
		}
		break;
	case WAIT_FOR_TRANSFER_OF_SAMPLE_RATE_COMPLETE:
		if (read_data(sdi, scpi, devc, sizeof(float)) == SR_OK) {
			/*
			 * Contrary to the documentation, this field is
			 * transfered with most significant byte first!
			 */
			sample_rate = RB32(devc->rcv_buffer);
			memcpy(&devc->sample_rate, &sample_rate, sizeof(float));
			devc->state = WAIT_FOR_TRANSFER_OF_CHANNEL_INDICATOR_COMPLETE;

			if (!devc->df_started) {
				std_session_send_df_header(sdi);

				packet.type = SR_DF_FRAME_BEGIN;
				sr_session_send(sdi, &packet);

				devc->df_started = TRUE;
			}
		}
		break;
	case WAIT_FOR_TRANSFER_OF_CHANNEL_INDICATOR_COMPLETE:
		if (read_data(sdi, scpi, devc, 1) == SR_OK)
			devc->state = WAIT_FOR_TRANSFER_OF_RESERVED_DATA_COMPLETE;
		break;
	case WAIT_FOR_TRANSFER_OF_RESERVED_DATA_COMPLETE:
		if (read_data(sdi, scpi, devc, 3) == SR_OK)
			devc->state = WAIT_FOR_TRANSFER_OF_CHANNEL_DATA_COMPLETE;
		break;
	case WAIT_FOR_TRANSFER_OF_CHANNEL_DATA_COMPLETE:
		if (read_data(sdi, scpi, devc, devc->data_size - 8) == SR_OK) {
			/* Fetch data needed for conversion from device. */
			snprintf(command, sizeof(command), ":CHAN%d:SCAL?",
					devc->cur_acq_channel + 1);
			if (sr_scpi_get_string(scpi, command, &response) != SR_OK) {
				sr_err("Failed to get volts per division.");
				sdi->driver->dev_acquisition_stop(sdi);
				return TRUE;
			}
			volts_per_division = g_ascii_strtod(response, &end_ptr);
			if (!strcmp(end_ptr, "mV"))
				volts_per_division *= 1.e-3;
			g_free(response);

			num_samples = (devc->data_size - 8) / 2;
			sr_spew("Received %d number of samples from channel "
				"%d.", num_samples, devc->cur_acq_channel + 1);

			float vbit = volts_per_division * VERTICAL_DIVISIONS / 256.0;
			float vbitlog = log10f(vbit);
			int digits = -(int)vbitlog + (vbitlog < 0.0);

			/* Convert data. */
			for (i = 0; i < num_samples; i++)
				samples[i] = ((float) ((int16_t) (RB16(&devc->rcv_buffer[i*2])))) * vbit;

			/* Fill frame. */
			sr_analog_init(&analog, &encoding, &meaning, &spec, digits);
			analog.meaning->channels = g_slist_append(NULL, g_slist_nth_data(sdi->channels, devc->cur_acq_channel));
			analog.num_samples = num_samples;
			analog.data = samples;
			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);

			/* All channels acquired. */
			if (devc->cur_acq_channel == ANALOG_CHANNELS - 1) {
				sr_spew("All channels acquired.");

				if (devc->cur_acq_frame == devc->frame_limit - 1) {
					/* All frames acquired. */
					sr_spew("All frames acquired.");
					sdi->driver->dev_acquisition_stop(sdi);
					return TRUE;
				} else {
					/* Start acquiring next frame. */
					if (devc->df_started) {
						packet.type = SR_DF_FRAME_END;
						sr_session_send(sdi, &packet);
						
						packet.type = SR_DF_FRAME_BEGIN;
						sr_session_send(sdi, &packet);
					}
					devc->cur_acq_frame++;
					devc->state = START_ACQUISITION;
				}
			} else {
				/* Start acquiring next channel. */
				devc->state = START_TRANSFER_OF_CHANNEL_DATA;
				devc->cur_acq_channel++;
				return TRUE;
			}
		}
		break;
	}

	return TRUE;
}
Beispiel #15
0
static int recv_log(const struct sr_dev_inst *sdi, GMatchInfo *match,
                    const int mqs[], const int units[], const int exponents[],
                    unsigned int num_functions)
{
	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;
	char *mstr;
	unsigned function;
	int value, negative, overload, exponent, alternate_unit, mq, unit;
	int mqflags = 0;
	float fvalue;

	sr_spew("LOG response '%s'.", g_match_info_get_string(match));

	devc = sdi->priv;

	mstr = g_match_info_fetch(match, 2);
	if (sr_atoi(mstr, (int*)&function) != SR_OK || function >= num_functions) {
		g_free(mstr);
		sr_dbg("Invalid function.");
		return SR_ERR;
	}
	g_free(mstr);

	mstr = g_match_info_fetch(match, 3);
	if (sr_atoi(mstr, &value) != SR_OK) {
		g_free(mstr);
		sr_dbg("Invalid value.");
		return SR_ERR;
	}
	g_free(mstr);

	mstr = g_match_info_fetch(match, 1);
	negative = mstr[7] & 2 ? -1 : 1;
	overload = mstr[8] & 4;
	exponent = (mstr[9] & 0xF) + exponents[function];
	alternate_unit = mstr[10] & 1;

	if (mstr[ 8] & 1)  mqflags |= SR_MQFLAG_DC;
	if (mstr[ 8] & 2)  mqflags |= SR_MQFLAG_AC;
	if (mstr[11] & 4)  mqflags |= SR_MQFLAG_RELATIVE;
	if (mstr[12] & 1)  mqflags |= SR_MQFLAG_AVG;
	if (mstr[12] & 2)  mqflags |= SR_MQFLAG_MIN;
	if (mstr[12] & 4)  mqflags |= SR_MQFLAG_MAX;
	if (function == 5) mqflags |= SR_MQFLAG_DIODE | SR_MQFLAG_DC;
	g_free(mstr);

	mq = mqs[function];
	unit = units[function];
	if (alternate_unit) {
		if (mq == SR_MQ_RESISTANCE)
			mq = SR_MQ_CONTINUITY;
		if (unit == SR_UNIT_DECIBEL_MW)
			unit = SR_UNIT_DECIBEL_VOLT;
		if (unit == SR_UNIT_CELSIUS) {
			unit = SR_UNIT_FAHRENHEIT;
			if (devc->profile->model == KEYSIGHT_U1281 ||
			    devc->profile->model == KEYSIGHT_U1282)
				exponent--;
		}
	}

	if (overload)
		fvalue = NAN;
	else
		fvalue = negative * value * powf(10, exponent);

	sr_analog_init(&analog, &encoding, &meaning, &spec, -exponent);
	analog.meaning->mq = mq;
	analog.meaning->unit = unit;
	analog.meaning->mqflags = mqflags;
	analog.meaning->channels = g_slist_append(NULL, devc->cur_channel);
	analog.num_samples = 1;
	analog.data = &fvalue;
	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	sr_session_send(sdi, &packet);
	g_slist_free(analog.meaning->channels);

	sr_sw_limits_update_samples_read(&devc->limits, 1);
	devc->cur_sample++;

	return JOB_LOG;
}
Beispiel #16
0
static void mso_send_data_proc(struct sr_dev_inst *sdi,
	uint8_t *data, size_t length, size_t sample_width)
{
	size_t i;
	struct dev_context *devc;
	struct sr_datafeed_analog analog;
	struct sr_analog_encoding encoding;
	struct sr_analog_meaning meaning;
	struct sr_analog_spec spec;

	(void)sample_width;

	devc = sdi->priv;

	length /= 2;

	/* Send the logic */
	for (i = 0; i < length; i++) {
		devc->logic_buffer[i] = data[i * 2];
		/* Rescale to -10V - +10V from 0-255. */
		devc->analog_buffer[i] = (data[i * 2 + 1] - 128.0f) / 12.8f;
	};

	const struct sr_datafeed_logic logic = {
		.length = length,
		.unitsize = 1,
		.data = devc->logic_buffer
	};

	const struct sr_datafeed_packet logic_packet = {
		.type = SR_DF_LOGIC,
		.payload = &logic
	};

	sr_session_send(sdi, &logic_packet);

	sr_analog_init(&analog, &encoding, &meaning, &spec, 2);
	analog.meaning->channels = devc->enabled_analog_channels;
	analog.meaning->mq = SR_MQ_VOLTAGE;
	analog.meaning->unit = SR_UNIT_VOLT;
	analog.meaning->mqflags = 0 /* SR_MQFLAG_DC */;
	analog.num_samples = length;
	analog.data = devc->analog_buffer;

	const struct sr_datafeed_packet analog_packet = {
		.type = SR_DF_ANALOG,
		.payload = &analog
	};

	sr_session_send(sdi, &analog_packet);
}

static void la_send_data_proc(struct sr_dev_inst *sdi,
	uint8_t *data, size_t length, size_t sample_width)
{
	const struct sr_datafeed_logic logic = {
		.length = length,
		.unitsize = sample_width,
		.data = data
	};

	const struct sr_datafeed_packet packet = {
		.type = SR_DF_LOGIC,
		.payload = &logic
	};

	sr_session_send(sdi, &packet);
}

static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	gboolean packet_has_error = FALSE;
	unsigned int num_samples;
	int trigger_offset, cur_sample_count, unitsize;
	int pre_trigger_samples;

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

	/*
	 * If acquisition has already ended, just free any queued up
	 * transfer that come in.
	 */
	if (devc->acq_aborted) {
		free_transfer(transfer);
		return;
	}

	sr_dbg("receive_transfer(): status %s received %d bytes.",
		libusb_error_name(transfer->status), transfer->actual_length);

	/* Save incoming transfer before reusing the transfer struct. */
	unitsize = devc->sample_wide ? 2 : 1;
	cur_sample_count = transfer->actual_length / unitsize;

	switch (transfer->status) {
	case LIBUSB_TRANSFER_NO_DEVICE:
		fx2lafw_abort_acquisition(devc);
		free_transfer(transfer);
		return;
	case LIBUSB_TRANSFER_COMPLETED:
	case LIBUSB_TRANSFER_TIMED_OUT: /* We may have received some data though. */
		break;
	default:
		packet_has_error = TRUE;
		break;
	}

	if (transfer->actual_length == 0 || packet_has_error) {
		devc->empty_transfer_count++;
		if (devc->empty_transfer_count > MAX_EMPTY_TRANSFERS) {
			/*
			 * The FX2 gave up. End the acquisition, the frontend
			 * will work out that the samplecount is short.
			 */
			fx2lafw_abort_acquisition(devc);
			free_transfer(transfer);
		} else {
			resubmit_transfer(transfer);
		}
		return;
	} else {
		devc->empty_transfer_count = 0;
	}
	if (devc->trigger_fired) {
		if (!devc->limit_samples || devc->sent_samples < devc->limit_samples) {
			/* Send the incoming transfer to the session bus. */
			if (devc->limit_samples && devc->sent_samples + cur_sample_count > devc->limit_samples)
				num_samples = devc->limit_samples - devc->sent_samples;
			else
				num_samples = cur_sample_count;

			devc->send_data_proc(sdi, (uint8_t *)transfer->buffer,
				num_samples * unitsize, unitsize);
			devc->sent_samples += num_samples;
		}
	} else {
		trigger_offset = soft_trigger_logic_check(devc->stl,
			transfer->buffer, transfer->actual_length, &pre_trigger_samples);
		if (trigger_offset > -1) {
			devc->sent_samples += pre_trigger_samples;
			num_samples = cur_sample_count - trigger_offset;
			if (devc->limit_samples &&
					num_samples > devc->limit_samples - devc->sent_samples)
				num_samples = devc->limit_samples - devc->sent_samples;

			devc->send_data_proc(sdi, (uint8_t *)transfer->buffer
					+ trigger_offset * unitsize,
					num_samples * unitsize, unitsize);
			devc->sent_samples += num_samples;

			devc->trigger_fired = TRUE;
		}
	}

	if (devc->limit_samples && devc->sent_samples >= devc->limit_samples) {
		fx2lafw_abort_acquisition(devc);
		free_transfer(transfer);
	} else
		resubmit_transfer(transfer);
}

static int configure_channels(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	const GSList *l;
	int p;
	struct sr_channel *ch;
	uint32_t channel_mask = 0, num_analog = 0;

	devc = sdi->priv;

	g_slist_free(devc->enabled_analog_channels);
	devc->enabled_analog_channels = NULL;

	for (l = sdi->channels, p = 0; l; l = l->next, p++) {
		ch = l->data;
		if ((p <= NUM_CHANNELS) && (ch->type == SR_CHANNEL_ANALOG)
				&& (ch->enabled)) {
			num_analog++;
			devc->enabled_analog_channels =
			    g_slist_append(devc->enabled_analog_channels, ch);
		} else {
			channel_mask |= ch->enabled << p;
		}
	}

	/*
	 * Use wide sampling if either any of the LA channels 8..15 is enabled,
	 * and/or at least one analog channel is enabled.
	 */
	devc->sample_wide = channel_mask > 0xff || num_analog > 0;

	return SR_OK;
}

static unsigned int to_bytes_per_ms(unsigned int samplerate)
{
	return samplerate / 1000;
}

static size_t get_buffer_size(struct dev_context *devc)
{
	size_t s;

	/*
	 * The buffer should be large enough to hold 10ms of data and
	 * a multiple of 512.
	 */
	s = 10 * to_bytes_per_ms(devc->cur_samplerate);
	return (s + 511) & ~511;
}
Beispiel #17
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
    struct dev_context *devc;
    struct sr_dev_inst *sdi;
    struct sr_channel *ch;
    struct sr_channel_group *cg, *acg;
    struct sr_config *src;
    struct analog_gen *ag;
    GSList *l;
    int num_logic_channels, num_analog_channels, pattern, i;
    char channel_name[16];

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

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

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

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

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

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

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

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

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

    sdi->priv = devc;

    return std_scan_complete(di, g_slist_append(NULL, sdi));
}
Beispiel #18
0
static void decode_buf(struct sr_dev_inst *sdi, unsigned char *data)
{
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog2 analog;
	struct sr_analog_encoding encoding;
	struct sr_analog_meaning meaning;
	struct sr_analog_spec spec;
	struct dev_context *devc;
	long factor, ivalue;
	uint8_t digits[4];
	gboolean is_duty, is_continuity, is_diode, is_ac, is_dc, is_auto;
	gboolean is_hold, is_max, is_min, is_relative, minus;
	float fvalue;

	devc = sdi->priv;

	digits[0] = decode_digit(data[12]);
	digits[1] = decode_digit(data[11]);
	digits[2] = decode_digit(data[10]);
	digits[3] = decode_digit(data[9]);

	if (digits[0] == 0x0f && digits[1] == 0x00 && digits[2] == 0x0a &&
			digits[3] == 0x0f)
		/* The "over limit" (OL) display comes through like this */
		ivalue = -1;
	else if (digits[0] > 9 || digits[1] > 9 || digits[2] > 9 || digits[3] > 9)
		/* An invalid digit in any position denotes no value. */
		ivalue = -2;
	else {
		ivalue = digits[0] * 1000;
		ivalue += digits[1] * 100;
		ivalue += digits[2] * 10;
		ivalue += digits[3];
	}

	/* Decimal point position */
	factor = 0;
	switch (data[7] >> 4) {
	case 0x00:
		factor = 0;
		break;
	case 0x02:
		factor = 1;
		break;
	case 0x04:
		factor = 2;
		break;
	case 0x08:
		factor = 3;
		break;
	default:
		sr_err("Unknown decimal point byte: 0x%.2x.", data[7]);
		break;
	}

	/* Minus flag */
	minus = data[2] & 0x01;

	/* Mode detail symbols on the right side of the digits */
	is_duty = is_continuity = is_diode = FALSE;
	switch (data[4]) {
	case 0x00:
		/* None. */
		break;
	case 0x01:
		/* Micro */
		factor += 6;
		break;
	case 0x02:
		/* Milli */
		factor += 3;
		break;
	case 0x04:
		/* Kilo */
		ivalue *= 1000;
		break;
	case 0x08:
		/* Mega */
		ivalue *= 1000000;
		break;
	case 0x10:
		/* Continuity shows up as Ohm + this bit */
		is_continuity = TRUE;
		break;
	case 0x20:
		/* Diode tester is Volt + this bit */
		is_diode = TRUE;
		break;
	case 0x40:
		is_duty = TRUE;
		break;
	case 0x80:
		/* Never seen */
		sr_dbg("Unknown mode right detail: 0x%.2x.", data[4]);
		break;
	default:
		sr_dbg("Unknown/invalid mode right detail: 0x%.2x.", data[4]);
		break;
	}

	/* Scale flags on the right, continued */
	is_max = is_min = FALSE;
	if (data[5] & 0x04)
		is_max = TRUE;
	if (data[5] & 0x08)
		is_min = TRUE;
	if (data[5] & 0x40)
		/* Nano */
		factor += 9;

	/* Mode detail symbols on the left side of the digits */
	is_auto = is_dc = is_ac = is_hold = is_relative = FALSE;
	if (data[6] & 0x04)
		is_auto = TRUE;
	if (data[6] & 0x08)
		is_dc = TRUE;
	if (data[6] & 0x10)
		is_ac = TRUE;
	if (data[6] & 0x20)
		is_relative = TRUE;
	if (data[6] & 0x40)
		is_hold = TRUE;

	fvalue = (float)ivalue / pow(10, factor);
	if (minus)
		fvalue = -fvalue;

	sr_analog_init(&analog, &encoding, &meaning, &spec, 4);

	/* Measurement mode */
	meaning.channels = sdi->channels;
	meaning.mq = 0;
	switch (data[3]) {
	case 0x00:
		if (is_duty) {
			meaning.mq = SR_MQ_DUTY_CYCLE;
			meaning.unit = SR_UNIT_PERCENTAGE;
		} else
			sr_dbg("Unknown measurement mode: %.2x.", data[3]);
		break;
	case 0x01:
		if (is_diode) {
			meaning.mq = SR_MQ_VOLTAGE;
			meaning.unit = SR_UNIT_VOLT;
			meaning.mqflags |= SR_MQFLAG_DIODE;
			if (ivalue < 0)
				fvalue = NAN;
		} else {
			if (ivalue < 0)
				break;
			meaning.mq = SR_MQ_VOLTAGE;
			meaning.unit = SR_UNIT_VOLT;
			if (is_ac)
				meaning.mqflags |= SR_MQFLAG_AC;
			if (is_dc)
				meaning.mqflags |= SR_MQFLAG_DC;
		}
		break;
	case 0x02:
		meaning.mq = SR_MQ_CURRENT;
		meaning.unit = SR_UNIT_AMPERE;
		if (is_ac)
			meaning.mqflags |= SR_MQFLAG_AC;
		if (is_dc)
			meaning.mqflags |= SR_MQFLAG_DC;
		break;
	case 0x04:
		if (is_continuity) {
			meaning.mq = SR_MQ_CONTINUITY;
			meaning.unit = SR_UNIT_BOOLEAN;
			fvalue = ivalue < 0 ? 0.0 : 1.0;
		} else {
			meaning.mq = SR_MQ_RESISTANCE;
			meaning.unit = SR_UNIT_OHM;
			if (ivalue < 0)
				fvalue = INFINITY;
		}
		break;
	case 0x08:
		/* Never seen */
		sr_dbg("Unknown measurement mode: 0x%.2x.", data[3]);
		break;
	case 0x10:
		meaning.mq = SR_MQ_FREQUENCY;
		meaning.unit = SR_UNIT_HERTZ;
		break;
	case 0x20:
		meaning.mq = SR_MQ_CAPACITANCE;
		meaning.unit = SR_UNIT_FARAD;
		break;
	case 0x40:
		meaning.mq = SR_MQ_TEMPERATURE;
		meaning.unit = SR_UNIT_CELSIUS;
		break;
	case 0x80:
		meaning.mq = SR_MQ_TEMPERATURE;
		meaning.unit = SR_UNIT_FAHRENHEIT;
		break;
	default:
		sr_dbg("Unknown/invalid measurement mode: 0x%.2x.", data[3]);
		break;
	}
	if (meaning.mq == 0)
		return;

	if (is_auto)
		meaning.mqflags |= SR_MQFLAG_AUTORANGE;
	if (is_hold)
		meaning.mqflags |= SR_MQFLAG_HOLD;
	if (is_max)
		meaning.mqflags |= SR_MQFLAG_MAX;
	if (is_min)
		meaning.mqflags |= SR_MQFLAG_MIN;
	if (is_relative)
		meaning.mqflags |= SR_MQFLAG_RELATIVE;

	analog.data = &fvalue;
	analog.num_samples = 1;

	packet.type = SR_DF_ANALOG2;
	packet.payload = &analog;
	sr_session_send(devc->cb_data, &packet);

	devc->num_samples++;
}
Beispiel #19
0
SR_PRIV int scpi_pps_receive_data(int fd, int revents, void *cb_data)
{
	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;
	const struct sr_dev_inst *sdi;
	struct sr_channel *next_channel;
	struct sr_scpi_dev_inst *scpi;
	struct pps_channel *pch;
	const struct channel_spec *ch_spec;
	float f;
	int cmd;

	(void)fd;
	(void)revents;

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

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

	scpi = sdi->conn;

	/* Retrieve requested value for this state. */
	if (sr_scpi_get_float(scpi, NULL, &f) == SR_OK) {
		pch = devc->cur_channel->priv;
		ch_spec = &devc->device->channels[pch->hw_output_idx];
		packet.type = SR_DF_ANALOG;
		packet.payload = &analog;
		/* Note: digits/spec_digits will be overridden later. */
		sr_analog_init(&analog, &encoding, &meaning, &spec, 0);
		analog.meaning->channels = g_slist_append(NULL, devc->cur_channel);
		analog.num_samples = 1;
		analog.meaning->mq = pch->mq;
		if (pch->mq == SR_MQ_VOLTAGE) {
			analog.meaning->unit = SR_UNIT_VOLT;
			analog.encoding->digits = ch_spec->voltage[4];
			analog.spec->spec_digits = ch_spec->voltage[3];
		} else if (pch->mq == SR_MQ_CURRENT) {
			analog.meaning->unit = SR_UNIT_AMPERE;
			analog.encoding->digits = ch_spec->current[4];
			analog.spec->spec_digits = ch_spec->current[3];
		} else if (pch->mq == SR_MQ_POWER) {
			analog.meaning->unit = SR_UNIT_WATT;
			analog.encoding->digits = ch_spec->power[4];
			analog.spec->spec_digits = ch_spec->power[3];
		}
		analog.meaning->mqflags = SR_MQFLAG_DC;
		analog.data = &f;
		sr_session_send(sdi, &packet);
		g_slist_free(analog.meaning->channels);
	}

	if (g_slist_length(sdi->channels) > 1) {
		next_channel = sr_next_enabled_channel(sdi, devc->cur_channel);
		if (select_channel(sdi, next_channel) != SR_OK) {
			sr_err("Failed to select channel %s", next_channel->name);
			return FALSE;
		}
	}

	pch = devc->cur_channel->priv;
	if (pch->mq == SR_MQ_VOLTAGE)
		cmd = SCPI_CMD_GET_MEAS_VOLTAGE;
	else if (pch->mq == SR_MQ_FREQUENCY)
		cmd = SCPI_CMD_GET_MEAS_FREQUENCY;
	else if (pch->mq == SR_MQ_CURRENT)
		cmd = SCPI_CMD_GET_MEAS_CURRENT;
	else if (pch->mq == SR_MQ_POWER)
		cmd = SCPI_CMD_GET_MEAS_POWER;
	else
		return SR_ERR;
	scpi_cmd(sdi, devc->device->commands, cmd);

	return TRUE;
}
Beispiel #20
0
static void send_chunk(struct sr_dev_inst *sdi, unsigned char *buf,
		int num_samples)
{
	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 dev_context *devc = sdi->priv;
	GSList *channels = devc->enabled_channels;

	const float ch_bit[] = { RANGE(0) / 255, RANGE(1) / 255 };
	const float ch_center[] = { RANGE(0) / 2, RANGE(1) / 2 };

	sr_analog_init(&analog, &encoding, &meaning, &spec, 0);

	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;

	analog.num_samples = num_samples;
	analog.meaning->mq = SR_MQ_VOLTAGE;
	analog.meaning->unit = SR_UNIT_VOLT;
	analog.meaning->mqflags = 0;

	analog.data = g_try_malloc(num_samples * sizeof(float));
	if (!analog.data) {
		sr_err("Analog data buffer malloc failed.");
		devc->dev_state = STOPPING;
		return;
	}

	for (int ch = 0; ch < 2; ch++) {
		if (!devc->ch_enabled[ch])
			continue;

		float vdivlog = log10f(ch_bit[ch]);
		int digits = -(int)vdivlog + (vdivlog < 0.0);
		analog.encoding->digits = digits;
		analog.spec->spec_digits = digits;
		analog.meaning->channels = g_slist_append(NULL, channels->data);

		for (int i = 0; i < num_samples; i++) {
			/*
			 * The device always sends data for both channels. If a channel
			 * is disabled, it contains a copy of the enabled channel's
			 * data. However, we only send the requested channels to
			 * the bus.
			 *
			 * Voltage values are encoded as a value 0-255, where the
			 * value is a point in the range represented by the vdiv
			 * setting. There are 10 vertical divs, so e.g. 500mV/div
			 * represents 5V peak-to-peak where 0 = -2.5V and 255 = +2.5V.
			 */
			((float *)analog.data)[i] = ch_bit[ch] * *(buf + i * 2 + ch) - ch_center[ch];
		}

		sr_session_send(sdi, &packet);
		g_slist_free(analog.meaning->channels);

		channels = channels->next;
	}
	g_free(analog.data);
}
Beispiel #21
0
static int recv_fetc(const struct sr_dev_inst *sdi, GMatchInfo *match)
{
	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_channel *prev_chan;
	float fvalue;
	const char *s;
	char *mstr;
	int i, exp;

	sr_spew("FETC reply '%s'.", g_match_info_get_string(match));
	devc = sdi->priv;
	i = devc->cur_channel->index;

	if (devc->cur_mq[i] == -1)
		/* This detects when channel P2 is reporting TEMP as an identical
		 * copy of channel P3. In this case, we just skip P2. */
		goto skip_value;

	s = g_match_info_get_string(match);
	if (!strcmp(s, "-9.90000000E+37") || !strcmp(s, "+9.90000000E+37")) {
		/* An invalid measurement shows up on the display as "O.L", but
		 * comes through like this. Since comparing 38-digit floats
		 * is rather problematic, we'll cut through this here. */
		fvalue = NAN;
	} else {
		mstr = g_match_info_fetch(match, 1);
		if (sr_atof_ascii(mstr, &fvalue) != SR_OK) {
			g_free(mstr);
			sr_dbg("Invalid float.");
			return SR_ERR;
		}
		g_free(mstr);
		if (devc->cur_exponent[i] != 0)
			fvalue *= powf(10, devc->cur_exponent[i]);
	}

	if (devc->cur_unit[i] == SR_UNIT_DECIBEL_MW ||
	    devc->cur_unit[i] == SR_UNIT_DECIBEL_VOLT ||
	    devc->cur_unit[i] == SR_UNIT_PERCENTAGE) {
		mstr = g_match_info_fetch(match, 2);
		if (mstr && sr_atoi(mstr, &exp) == SR_OK) {
			devc->cur_digits[i] = MIN(4 - exp, devc->cur_digits[i]);
			devc->cur_encoding[i] = MIN(5 - exp, devc->cur_encoding[i]);
		}
		g_free(mstr);
	}

	sr_analog_init(&analog, &encoding, &meaning, &spec,
	               devc->cur_digits[i] - devc->cur_exponent[i]);
	analog.meaning->mq = devc->cur_mq[i];
	analog.meaning->unit = devc->cur_unit[i];
	analog.meaning->mqflags = devc->cur_mqflags[i];
	analog.meaning->channels = g_slist_append(NULL, devc->cur_channel);
	analog.num_samples = 1;
	analog.data = &fvalue;
	encoding.digits = devc->cur_encoding[i] - devc->cur_exponent[i];
	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	sr_session_send(sdi, &packet);
	g_slist_free(analog.meaning->channels);

	sr_sw_limits_update_samples_read(&devc->limits, 1);

skip_value:
	prev_chan = devc->cur_channel;
	devc->cur_channel = sr_next_enabled_channel(sdi, devc->cur_channel);
	if (devc->cur_channel->index > prev_chan->index)
		return JOB_AGAIN;
	else
		return JOB_FETC;
}