示例#1
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_old analog;
	int i;
	float data[MAX_CHANNELS];

	devc = sdi->priv;
	packet.type = SR_DF_ANALOG_OLD;
	packet.payload = &analog;
	analog.channels = sdi->channels;
	analog.num_samples = 1;

	analog.mq = SR_MQ_VOLTAGE;
	analog.unit = SR_UNIT_VOLT;
	analog.mqflags = SR_MQFLAG_DC;
	analog.data = data;
	for (i = 0; i < devc->model->num_channels; i++)
		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.mq = SR_MQ_CURRENT;
	analog.unit = SR_UNIT_AMPERE;
	analog.mqflags = 0;
	analog.data = data;
	for (i = 0; i < devc->model->num_channels; i++)
		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);
}
示例#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);
}
示例#3
0
static void send_sample(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog_old analog;

	devc = sdi->priv;

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

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

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


	sr_sw_limits_update_samples_read(&devc->limits, 1);
}
示例#4
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_old analog;

	devc = sdi->priv;

	analog.num_samples = 1;
	analog.mq = -1;

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

	analog.channels = sdi->channels;

	if (analog.mq != -1) {
		/* Got a measurement. */
		packet.type = SR_DF_ANALOG_OLD;
		packet.payload = &analog;
		sr_session_send(sdi, &packet);
		sr_sw_limits_update_samples_read(&devc->sw_limits, 1);
	}
}
示例#5
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);
    }
}
示例#6
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);
}
示例#7
0
static void handle_qm_19x_data(const struct sr_dev_inst *sdi, char **tokens)
{
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog_old analog;
	float fvalue;

	if (!strcmp(tokens[0], "9.9E+37")) {
		/* An invalid measurement shows up on the display as "OL", but
		 * comes through like this. Since comparing 38-digit floats
		 * is rather problematic, we'll cut through this here. */
		fvalue = NAN;
	} else {
		if (sr_atof_ascii(tokens[0], &fvalue) != SR_OK || fvalue == 0.0) {
			sr_err("Invalid float '%s'.", tokens[0]);
			return;
		}
	}

	devc = sdi->priv;
	if (devc->mq == -1 || devc->unit == -1)
		/* Don't have valid metadata yet. */
		return;

	if (devc->mq == SR_MQ_RESISTANCE && isnan(fvalue))
		fvalue = INFINITY;
	else if (devc->mq == SR_MQ_CONTINUITY) {
		if (isnan(fvalue))
			fvalue = 0.0;
		else
			fvalue = 1.0;
	}

	analog.channels = sdi->channels;
	analog.num_samples = 1;
	analog.data = &fvalue;
	analog.mq = devc->mq;
	analog.unit = devc->unit;
	analog.mqflags = 0;
	packet.type = SR_DF_ANALOG_OLD;
	packet.payload = &analog;
	sr_session_send(sdi, &packet);

	sr_sw_limits_update_samples_read(&devc->limits, 1);
}
示例#8
0
SR_PRIV int maynuo_m97_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_modbus_dev_inst *modbus;
	struct sr_datafeed_packet packet;
	uint16_t registers[4];

	(void)fd;
	(void)revents;

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

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

	devc->expecting_registers = 0;
	if (sr_modbus_read_holding_registers(modbus, -1, 4, registers) == SR_OK) {
		packet.type = SR_DF_FRAME_BEGIN;
		sr_session_send(sdi, &packet);

		maynuo_m97_session_send_value(sdi, sdi->channels->data,
		                              RBFL(registers + 0),
		                              SR_MQ_VOLTAGE, SR_UNIT_VOLT);
		maynuo_m97_session_send_value(sdi, sdi->channels->next->data,
		                              RBFL(registers + 2),
		                              SR_MQ_CURRENT, SR_UNIT_AMPERE);

		packet.type = SR_DF_FRAME_END;
		sr_session_send(sdi, &packet);
		sr_sw_limits_update_samples_read(&devc->limits, 1);
	}

	if (sr_sw_limits_check(&devc->limits)) {
		sdi->driver->dev_acquisition_stop(sdi);
		return TRUE;
	}

	maynuo_m97_capture_start(sdi);
	return TRUE;
}
示例#9
0
static void teleinfo_handle_measurement(struct sr_dev_inst *sdi,
		const char *label, const char *data, char *optarif)
{
	struct dev_context *devc;
	int v = atoi(data);

	if (!sdi || !(devc = sdi->priv)) {
		if (optarif && !strcmp(label, "OPTARIF"))
			strcpy(optarif, data);
		return;
	}

	if (!strcmp(label, "ADCO")) {
		sr_sw_limits_update_samples_read(&devc->sw_limits, 1);
	} else if (!strcmp(label, "BASE")) {
		teleinfo_send_value(sdi, "BASE", v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "HCHP")) {
		teleinfo_send_value(sdi, "HP"  , v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "HCHC")) {
		teleinfo_send_value(sdi, "HC"  , v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "EJPHN")) {
		teleinfo_send_value(sdi, "HN"  , v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "EJPHPM")) {
		teleinfo_send_value(sdi, "HPM" , v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "BBRHPJB")) {
		teleinfo_send_value(sdi, "HPJB", v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "BBRHPJW")) {
		teleinfo_send_value(sdi, "HPJW", v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "BBRHPJR")) {
		teleinfo_send_value(sdi, "HPJR", v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "BBRHCJB")) {
		teleinfo_send_value(sdi, "HCJB", v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "BBRHCJW")) {
		teleinfo_send_value(sdi, "HCJW", v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "BBRHCJR")) {
		teleinfo_send_value(sdi, "HCJR", v, SR_MQ_POWER, SR_UNIT_WATT_HOUR);
	} else if (!strcmp(label, "IINST")) {
		teleinfo_send_value(sdi, "IINST", v, SR_MQ_CURRENT, SR_UNIT_AMPERE);
	} else if (!strcmp(label, "PAPP")) {
		teleinfo_send_value(sdi, "PAPP", v, SR_MQ_POWER, SR_UNIT_VOLT_AMPERE);
	}
}
示例#10
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);
	}
}
示例#11
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;
}
示例#12
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;
}
示例#13
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;
}
示例#14
0
static void handle_line(const struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct sr_serial_dev_inst *serial;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog_old *analog;
	int num_tokens, n, i;
	char cmd[16], **tokens;

	devc = sdi->priv;
	serial = sdi->conn;
	sr_spew("Received line '%s' (%d).", devc->buf, devc->buflen);

	if (devc->buflen == 1) {
		if (devc->buf[0] != '0') {
			/* Not just a CMD_ACK from the query command. */
			sr_dbg("Got CMD_ACK '%c'.", devc->buf[0]);
			devc->expect_response = FALSE;
		}
		devc->buflen = 0;
		return;
	}

	analog = NULL;
	tokens = g_strsplit(devc->buf, ",", 0);
	if (tokens[0]) {
		if (devc->profile->model == FLUKE_187 || devc->profile->model == FLUKE_189) {
			devc->expect_response = FALSE;
			analog = handle_qm_18x(sdi, tokens);
		} else if (devc->profile->model == FLUKE_287 || devc->profile->model == FLUKE_289) {
			devc->expect_response = FALSE;
			analog = handle_qm_28x(sdi, tokens);
		} else if (devc->profile->model == FLUKE_190) {
			devc->expect_response = FALSE;
			for (num_tokens = 0; tokens[num_tokens]; num_tokens++);
			if (num_tokens >= 7) {
				/* Response to QM: this is a comma-separated list of
				 * fields with metadata about the measurement. This
				 * format can return multiple sets of metadata,
				 * split into sets of 7 tokens each. */
				devc->meas_type = 0;
				for (i = 0; i < num_tokens; i += 7)
					handle_qm_19x_meta(sdi, tokens + i);
				if (devc->meas_type) {
					/* Slip the request in now, before the main
					 * timer loop asks for metadata again. */
					n = sprintf(cmd, "QM %d\r", devc->meas_type);
					if (serial_write_blocking(serial, cmd, n, SERIAL_WRITE_TIMEOUT_MS) < 0)
						sr_err("Unable to send QM (measurement).");
				}
			} else {
				/* Response to QM <n> measurement request. */
				handle_qm_19x_data(sdi, tokens);
			}
		}
	}
	g_strfreev(tokens);
	devc->buflen = 0;

	if (analog) {
		/* Got a measurement. */
		packet.type = SR_DF_ANALOG_OLD;
		packet.payload = analog;
		sr_session_send(sdi, &packet);
		sr_sw_limits_update_samples_read(&devc->limits, 1);
		g_free(analog->data);
		g_free(analog);
	}

}
示例#15
0
static void decode_buf(struct sr_dev_inst *sdi, unsigned char *data)
{
	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;
	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_ANALOG;
	packet.payload = &analog;
	sr_session_send(sdi, &packet);

	sr_sw_limits_update_samples_read(&devc->limits, 1);
}