示例#1
0
文件: api.c 项目: pagaille/libsigrok
/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
{
    struct dev_context *devc;
    struct sr_usb_dev_inst *usb;
    struct sr_datafeed_packet packet;

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

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

    usb = sdi->conn;
    analyzer_reset(usb->devhdl);
    /* TODO: Need to cancel and free any queued up transfers. */

    return SR_OK;
}
示例#2
0
static int handle_packet(const uint8_t *buf, struct sr_dev_inst *sdi, int idx)
{
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog_old analog;
	struct dev_context *devc;
	struct center_info info;
	GSList *l;
	int i, ret;

	devc = sdi->priv;

	memset(&analog, 0, sizeof(struct sr_datafeed_analog_old));
	memset(&info, 0, sizeof(struct center_info));

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

	/* Common values for all 4 channels. */
	packet.type = SR_DF_ANALOG_OLD;
	packet.payload = &analog;
	analog.mq = SR_MQ_TEMPERATURE;
	analog.unit = (info.celsius) ? SR_UNIT_CELSIUS : SR_UNIT_FAHRENHEIT;
	analog.num_samples = 1;

	/* Send the values for T1 - T4. */
	for (i = 0; i < NUM_CHANNELS; i++) {
		l = NULL;
		l = g_slist_append(l, g_slist_nth_data(sdi->channels, i));
		analog.channels = l;
		analog.data = &(info.temp[i]);
		sr_session_send(sdi, &packet);
		g_slist_free(l);
	}

	devc->num_samples++;

	return SR_OK;
}
示例#3
0
文件: csv.c 项目: russdill/libsigrok
static int send_samples(const struct sr_dev_inst *sdi, uint8_t *buffer,
			gsize buffer_size, gsize count)
{
	int res;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_logic logic;
	gsize i;

	packet.type = SR_DF_LOGIC;
	packet.payload = &logic;
	logic.unitsize = buffer_size;
	logic.length = buffer_size;
	logic.data = buffer;

	for (i = 0; i < count; i++) {
		if ((res = sr_session_send(sdi, &packet)) != SR_OK)
			return res;
	}

	return SR_OK;
}
示例#4
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);
}
示例#5
0
文件: std.c 项目: vpalatin/libsigrok
/**
 * Standard API helper for sending an SR_DF_END packet.
 *
 * @param sdi The device instance to use. Must not be NULL.
 *
 * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
 *         SR_ERR upon other errors.
 */
SR_PRIV int std_session_send_df_end(const struct sr_dev_inst *sdi)
{
	const char *prefix = (sdi->driver) ? sdi->driver->name : "unknown";
	int ret;
	struct sr_datafeed_packet packet;

	if (!sdi)
		return SR_ERR_ARG;

	sr_dbg("%s: Sending SR_DF_END packet.", prefix);

	packet.type = SR_DF_END;
	packet.payload = NULL;

	if ((ret = sr_session_send(sdi, &packet)) < 0) {
		sr_err("%s: Failed to send SR_DF_END packet: %d.", prefix, ret);
		return ret;
	}

	return SR_OK;
}
示例#6
0
文件: demo.c 项目: DeeJay/libsigrok
static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
{
	struct dev_context *devc;
	struct sr_datafeed_packet packet;

	(void)cb_data;

	devc = sdi->priv;
	sr_dbg("Stopping acquisition.");

	sr_session_source_remove_channel(devc->channel);
	g_io_channel_shutdown(devc->channel, FALSE, NULL);
	g_io_channel_unref(devc->channel);
	devc->channel = NULL;

	/* Send last packet. */
	packet.type = SR_DF_END;
	sr_session_send(sdi, &packet);

	return SR_OK;
}
示例#7
0
/**
 * Standard sr_session_stop() API helper.
 *
 * This function can be used to simplify most (serial port based) driver's
 * dev_acquisition_stop() API callback.
 *
 * @param sdi The device instance for which acquisition should stop.
 *            Must not be NULL.
 * @param cb_data Opaque 'cb_data' pointer. Must not be NULL.
 * @param dev_close_fn Function pointer to the driver's dev_close().
 *               	  Must not be NULL.
 * @param serial The serial device instance (struct serial_dev_inst *).
 *               Must not be NULL.
 * @param[in] prefix A driver-specific prefix string used for log messages.
 *               Must not be NULL. An empty string is allowed.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid arguments.
 * @retval SR_ERR_DEV_CLOSED Device is closed.
 * @retval SR_ERR Other errors.
 */
SR_PRIV int std_serial_dev_acquisition_stop(struct sr_dev_inst *sdi,
			void *cb_data, dev_close_callback dev_close_fn,
			struct sr_serial_dev_inst *serial, const char *prefix)
{
	int ret;
	struct sr_datafeed_packet packet;

	if (!prefix) {
		sr_err("Invalid prefix.");
		return SR_ERR_ARG;
	}

	if (sdi->status != SR_ST_ACTIVE) {
		sr_err("%s: Device inactive, can't stop acquisition.", prefix);
		return SR_ERR_DEV_CLOSED;
	}

	sr_dbg("%s: Stopping acquisition.", prefix);

	if ((ret = serial_source_remove(sdi->session, serial)) < 0) {
		sr_err("%s: Failed to remove source: %d.", prefix, ret);
		return ret;
	}

	if ((ret = dev_close_fn(sdi)) < 0) {
		sr_err("%s: Failed to close device: %d.", prefix, ret);
		return ret;
	}

	/* Send SR_DF_END packet to the session bus. */
	sr_dbg("%s: Sending SR_DF_END packet.", prefix);
	packet.type = SR_DF_END;
	packet.payload = NULL;
	if ((ret = sr_session_send(cb_data, &packet)) < 0) {
		sr_err("%s: Failed to send SR_DF_END packet: %d.", prefix, ret);
		return ret;
	}

	return SR_OK;
}
示例#8
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);
	}
}
示例#9
0
文件: std.c 项目: vpalatin/libsigrok
/**
 * Standard API helper for sending an SR_DF_HEADER packet.
 *
 * This function can be used to simplify most driver's
 * dev_acquisition_start() API callback.
 *
 * @param sdi The device instance to use.
 *
 * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
 *         SR_ERR upon other errors.
 */
SR_PRIV int std_session_send_df_header(const struct sr_dev_inst *sdi)
{
	const char *prefix = (sdi->driver) ? sdi->driver->name : "unknown";
	int ret;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_header header;

	sr_dbg("%s: Starting acquisition.", prefix);

	/* Send header packet to the session bus. */
	sr_dbg("%s: Sending SR_DF_HEADER packet.", prefix);
	packet.type = SR_DF_HEADER;
	packet.payload = (uint8_t *)&header;
	header.feed_version = 1;
	gettimeofday(&header.starttime, NULL);

	if ((ret = sr_session_send(sdi, &packet)) < 0) {
		sr_err("%s: Failed to send header packet: %d.", prefix, ret);
		return ret;
	}

	return SR_OK;
}
示例#10
0
static void appa_55ii_live_data(struct sr_dev_inst *sdi, const uint8_t *buf)
{
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_analog analog;
	struct sr_channel *ch;
	float values[APPA_55II_NUM_CHANNELS], *val_ptr;
	int i;

	devc = sdi->priv;

	if (devc->data_source != DATA_SOURCE_LIVE)
		return;

	val_ptr = values;
	memset(&analog, 0, sizeof(analog));
	analog.num_samples = 1;
	analog.mq = SR_MQ_TEMPERATURE;
	analog.unit = SR_UNIT_CELSIUS;
	analog.mqflags = appa_55ii_flags(buf);
	analog.data = values;

	for (i = 0; i < APPA_55II_NUM_CHANNELS; i++) {
		ch = g_slist_nth_data(sdi->channels, i);
		if (!ch->enabled)
			continue;
		analog.channels = g_slist_append(analog.channels, ch);
		*val_ptr++ = appa_55ii_temp(buf, i);
	}

	packet.type = SR_DF_ANALOG;
	packet.payload = &analog;
	sr_session_send(devc->session_cb_data, &packet);
	g_slist_free(analog.channels);

	devc->num_samples++;
}
示例#11
0
文件: api.c 项目: anatol/libsigrok
static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
{
	struct dev_context *devc;
	struct sr_datafeed_packet packet;

	(void)cb_data;

	packet.type = SR_DF_END;
	packet.payload = NULL;
	sr_session_send(sdi, &packet);

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

	devc = sdi->priv;

	devc->num_frames = 0;
	g_slist_free(devc->enabled_channels);
	devc->enabled_channels = NULL;

	sr_scpi_source_remove(sdi->session, sdi->conn);

	return SR_OK;
}
示例#12
0
/* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
static int hw_dev_acquisition_stop(int dev_index, void *cb_data)
{
	struct sr_datafeed_packet packet;
	struct sr_dev_inst *sdi;
	struct context *ctx;

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

	if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
		sr_err("zp: %s: sdi was NULL", __func__);
		return SR_ERR_BUG;
	}

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

	analyzer_reset(ctx->usb->devhdl);
	/* TODO: Need to cancel and free any queued up transfers. */

	return SR_OK;
}
示例#13
0
文件: api.c 项目: tschutter/libsigrok
static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
				    void *cb_data)
{
	struct sr_datafeed_packet *packet;
	struct sr_datafeed_header *header;
	struct dev_context *devc;
	int ret = SR_ERR;

	devc = sdi->priv;

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

	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;

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

	if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
		sr_err("Datafeed packet malloc failed.");
		return SR_ERR_MALLOC;
	}

	if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
		sr_err("Datafeed header malloc failed.");
		g_free(packet);
		return SR_ERR_MALLOC;
	}

	packet->type = SR_DF_HEADER;
	packet->payload = (unsigned char *)header;
	header->feed_version = 1;
	gettimeofday(&header->starttime, NULL);
	sr_session_send(cb_data, packet);

	g_free(header);
	g_free(packet);

	return SR_OK;
}
示例#14
0
static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi)
{
	struct sr_dev_inst *sdi;
	struct session_vdev *vdev;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_logic logic;
    struct sr_datafeed_dso dso;
    struct sr_datafeed_analog analog;
	GSList *l;
	int ret, got_data;
	(void)fd;
	(void)revents;

	sr_dbg("Feed chunk.");

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

        ret = zip_fread(vdev->capfile, vdev->buf, CHUNKSIZE);
		if (ret > 0) {
			got_data = TRUE;
            if (sdi->mode == DSO) {
                packet.type = SR_DF_DSO;
                packet.payload = &dso;
                dso.num_samples = ret / vdev->unitsize;
                dso.data = vdev->buf;
                dso.probes = sdi->channels;
                dso.mq = SR_MQ_VOLTAGE;
                dso.unit = SR_UNIT_VOLT;
                dso.mqflags = SR_MQFLAG_AC;
            } else if (sdi->mode == ANALOG){
                packet.type = SR_DF_ANALOG;
                packet.payload = &analog;
                analog.probes = sdi->channels;
                analog.num_samples = ret / vdev->unitsize;
                analog.mq = SR_MQ_VOLTAGE;
                analog.unit = SR_UNIT_VOLT;
                analog.mqflags = SR_MQFLAG_AC;
                analog.data = vdev->buf;
            } else {
                packet.type = SR_DF_LOGIC;
                packet.payload = &logic;
                logic.length = ret;
                logic.unitsize = vdev->unitsize;
                logic.data = vdev->buf;
            }
			vdev->bytes_read += ret;
			sr_session_send(cb_sdi, &packet);
		} else {
			/* done with this capture file */
			zip_fclose(vdev->capfile);
            //g_free(vdev->capturefile);
            //g_free(vdev);
            //sdi->priv = NULL;
		}
	}

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

	return TRUE;
}
示例#15
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_old analog;
	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(cb_data, &packet);
				sdi->driver->dev_acquisition_stop(sdi, cb_data);
				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(cb_data, &packet);
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
		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;
		analog.channels = g_slist_append(NULL, ch);
		analog.num_samples = len;
		analog.data = devc->data;
		analog.mq = SR_MQ_VOLTAGE;
		analog.unit = SR_UNIT_VOLT;
		analog.mqflags = 0;
		packet.type = SR_DF_ANALOG_OLD;
		packet.payload = &analog;
		sr_session_send(cb_data, &packet);
		g_slist_free(analog.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(cb_data, &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(cb_data, &packet);
			sdi->driver->dev_acquisition_stop(sdi, cb_data);
			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(cb_data, &packet);

		if (++devc->num_frames == devc->limit_frames) {
			/* Last frame, stop capture. */
			sdi->driver->dev_acquisition_stop(sdi, cb_data);
		} 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(cb_data, &packet);
		}
	}

	return TRUE;
}
示例#16
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_old analog;
	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);

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

			/* Fill frame. */
			analog.channels = g_slist_append(NULL, g_slist_nth_data(sdi->channels, devc->cur_acq_channel));
			analog.num_samples = num_samples;
			analog.data = samples;
			analog.mq = SR_MQ_VOLTAGE;
			analog.unit = SR_UNIT_VOLT;
			analog.mqflags = 0;
			packet.type = SR_DF_ANALOG_OLD;
			packet.payload = &analog;
			sr_session_send(sdi, &packet);
			g_slist_free(analog.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;
}
示例#17
0
SR_PRIV int hmo_receive_data(int fd, int revents, void *cb_data)
{
	struct sr_channel *ch;
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	GArray *data;
	struct sr_datafeed_analog analog;
	struct sr_datafeed_logic logic;

	(void)fd;

	data = NULL;

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

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

	if (revents != G_IO_IN)
		return TRUE;

	ch = devc->current_channel->data;

	switch (ch->type) {
	case SR_CHANNEL_ANALOG:
		if (sr_scpi_get_floatv(sdi->conn, NULL, &data) != SR_OK) {
			if (data)
				g_array_free(data, TRUE);

			return TRUE;
		}

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

		analog.channels = g_slist_append(NULL, ch);
		analog.num_samples = data->len;
		analog.data = (float *) data->data;
		analog.mq = SR_MQ_VOLTAGE;
		analog.unit = SR_UNIT_VOLT;
		analog.mqflags = 0;
		packet.type = SR_DF_ANALOG;
		packet.payload = &analog;
		sr_session_send(cb_data, &packet);
		g_slist_free(analog.channels);
		g_array_free(data, TRUE);
		data = NULL;
		break;
	case SR_CHANNEL_LOGIC:
		if (sr_scpi_get_uint8v(sdi->conn, NULL, &data) != SR_OK) {
			g_free(data);
			return TRUE;
		}

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

		logic.length = data->len;
		logic.unitsize = 1;
		logic.data = data->data;
		packet.type = SR_DF_LOGIC;
		packet.payload = &logic;
		sr_session_send(cb_data, &packet);
		g_array_free(data, TRUE);
		data = NULL;
		break;
	default:
		sr_err("Invalid channel type.");
		break;
	}

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

	if (devc->current_channel->next) {
		devc->current_channel = devc->current_channel->next;
		hmo_request_data(sdi);
	} else if (++devc->num_frames == devc->frame_limit) {
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
	} else {
		devc->current_channel = devc->enabled_channels;
		hmo_request_data(sdi);
	}

	return TRUE;
}
示例#18
0
static int handle_event(int fd, int revents, void *cb_data)
{
	const struct sr_dev_inst *sdi;
	struct sr_datafeed_packet packet;
	struct timeval tv;
	struct dev_context *devc;
	struct drv_context *drvc = di->priv;
	int num_probes;
	uint32_t trigger_offset;
	uint8_t capturestate;

	(void)fd;
	(void)revents;

	sdi = cb_data;
	devc = sdi->priv;
	if (devc->dev_state == STOPPING) {
		/* We've been told to wind up the acquisition. */
		sr_dbg("Stopping acquisition.");
		/*
		 * TODO: Doesn't really cancel pending transfers so they might
		 * come in after SR_DF_END is sent.
		 */
		usb_source_remove(drvc->sr_ctx);

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

		devc->dev_state = IDLE;

		return TRUE;
	}

	/* Always handle pending libusb events. */
	tv.tv_sec = tv.tv_usec = 0;
	libusb_handle_events_timeout(drvc->sr_ctx->libusb_ctx, &tv);

	/* TODO: ugh */
	if (devc->dev_state == NEW_CAPTURE) {
		if (dso_capture_start(sdi) != SR_OK)
			return TRUE;
		if (dso_enable_trigger(sdi) != SR_OK)
			return TRUE;
//		if (dso_force_trigger(sdi) != SR_OK)
//			return TRUE;
		sr_dbg("Successfully requested next chunk.");
		devc->dev_state = CAPTURE;
		return TRUE;
	}
	if (devc->dev_state != CAPTURE)
		return TRUE;

	if ((dso_get_capturestate(sdi, &capturestate, &trigger_offset)) != SR_OK)
		return TRUE;

	sr_dbg("Capturestate %d.", capturestate);
	sr_dbg("Trigger offset 0x%.6x.", trigger_offset);
	switch (capturestate) {
	case CAPTURE_EMPTY:
		if (++devc->capture_empty_count >= MAX_CAPTURE_EMPTY) {
			devc->capture_empty_count = 0;
			if (dso_capture_start(sdi) != SR_OK)
				break;
			if (dso_enable_trigger(sdi) != SR_OK)
				break;
//			if (dso_force_trigger(sdi) != SR_OK)
//				break;
			sr_dbg("Successfully requested next chunk.");
		}
		break;
	case CAPTURE_FILLING:
		/* No data yet. */
		break;
	case CAPTURE_READY_8BIT:
		/* Remember where in the captured frame the trigger is. */
		devc->trigger_offset = trigger_offset;

		num_probes = (devc->ch1_enabled && devc->ch2_enabled) ? 2 : 1;
		/* TODO: Check malloc return value. */
		devc->framebuf = g_try_malloc(devc->framesize * num_probes * 2);
		devc->samp_buffered = devc->samp_received = 0;

		/* Tell the scope to send us the first frame. */
		if (dso_get_channeldata(sdi, receive_transfer) != SR_OK)
			break;

		/*
		 * Don't hit the state machine again until we're done fetching
		 * the data we just told the scope to send.
		 */
		devc->dev_state = FETCH_DATA;

		/* Tell the frontend a new frame is on the way. */
		packet.type = SR_DF_FRAME_BEGIN;
		sr_session_send(sdi, &packet);
		break;
	case CAPTURE_READY_9BIT:
		/* TODO */
		sr_err("Not yet supported.");
		break;
	case CAPTURE_TIMEOUT:
		/* Doesn't matter, we'll try again next time. */
		break;
	default:
		sr_dbg("Unknown capture state: %d.", capturestate);
		break;
	}

	return TRUE;
}
示例#19
0
文件: demo.c 项目: DeeJay/libsigrok
/* Callback handling data */
static int prepare_data(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_logic logic;
	struct sr_channel_group *cg;
	struct analog_gen *ag;
	GSList *l;
	uint64_t logic_todo, analog_todo, expected_samplenum, analog_samples, sending_now;
	int64_t time, elapsed;

	(void)fd;
	(void)revents;

	sdi = cb_data;
	devc = sdi->priv;

	/* How many "virtual" samples should we have collected by now? */
	time = g_get_monotonic_time();
	elapsed = time - devc->starttime;
	expected_samplenum = elapsed * devc->cur_samplerate / 1000000;

	/* Of those, how many do we still have to send? */
	logic_todo = MIN(expected_samplenum, devc->limit_samples) - devc->logic_counter;
	analog_todo = MIN(expected_samplenum, devc->limit_samples) - devc->analog_counter;

	while (logic_todo || analog_todo) {
		/* Logic */
		if (devc->num_logic_channels > 0 && logic_todo > 0) {
			sending_now = MIN(logic_todo,
					LOGIC_BUFSIZE / devc->logic_unitsize);
			logic_generator(sdi, sending_now * devc->logic_unitsize);
			packet.type = SR_DF_LOGIC;
			packet.payload = &logic;
			logic.length = sending_now * devc->logic_unitsize;
			logic.unitsize = devc->logic_unitsize;
			logic.data = devc->logic_data;
			sr_session_send(sdi, &packet);
			logic_todo -= sending_now;
			devc->logic_counter += sending_now;
		}

		/* Analog, one channel at a time */
		if (devc->num_analog_channels > 0 && analog_todo > 0) {
			sending_now = 0;
			for (l = devc->analog_channel_groups; l; l = l->next) {
				cg = l->data;
				ag = cg->priv;
				packet.type = SR_DF_ANALOG;
				packet.payload = &ag->packet;

				/* FIXME we should make sure we output a whole
				 * period of data before we send out again the
				 * beginning of our buffer. A ring buffer would
				 * help here as well */

				analog_samples = MIN(analog_todo, ag->num_samples);
				/* Whichever channel group gets there first. */
				sending_now = MAX(sending_now, analog_samples);
				ag->packet.num_samples = analog_samples;
				sr_session_send(sdi, &packet);
			}
			analog_todo -= sending_now;
			devc->analog_counter += sending_now;
		}
	}

	if (devc->logic_counter >= devc->limit_samples &&
			devc->analog_counter >= devc->limit_samples) {
		sr_dbg("Requested number of samples reached.");
		dev_acquisition_stop(sdi, cb_data);
		return TRUE;
	}

	return TRUE;
}
示例#20
0
SR_PRIV int bl_acme_receive_data(int fd, int revents, void *cb_data)
{
	uint32_t cur_time, elapsed_time;
	uint64_t nrexpiration;
	struct sr_datafeed_packet packet, framep;
	struct sr_datafeed_analog analog;
	struct sr_dev_inst *sdi;
	struct sr_channel *ch;
	struct channel_priv *chp;
	struct dev_context *devc;
	GSList *chl, chonly;
	unsigned i;

	(void)fd;
	(void)revents;

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

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

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

	if (read(devc->timer_fd, &nrexpiration, sizeof(nrexpiration)) < 0) {
		sr_warn("Failed to read timer information");
		return TRUE;
	}

	/*
	 * We were not able to process the previous timer expiration, we are
	 * overloaded.
	 */
	if (nrexpiration > 1)
		devc->samples_missed += nrexpiration - 1;

	/*
	 * XXX This is a nasty workaround...
	 *
	 * At high sampling rates and maximum channels we are not able to
	 * acquire samples fast enough, even though frontends still think
	 * that samples arrive on time. This causes shifts in frontend
	 * plots.
	 *
	 * To compensate for the delay we check if any clock events were
	 * missed and - if so - don't really read the next value, but send
	 * the same sample as fast as possible. We do it until we are back
	 * on schedule.
	 *
	 * At high sampling rate this doesn't seem to visibly reduce the
	 * accuracy.
	 */
	for (i = 0; i < nrexpiration; i++) {
		framep.type = SR_DF_FRAME_BEGIN;
		sr_session_send(cb_data, &framep);

		/*
		 * Due to different units used in each channel we're sending
		 * samples one-by-one.
		 */
		for (chl = sdi->channels; chl; chl = chl->next) {
			ch = chl->data;
			chp = ch->priv;

			if (!ch->enabled)
				continue;
			chonly.next = NULL;
			chonly.data = ch;
			analog.channels = &chonly;
			analog.num_samples = 1;
			analog.mq = channel_to_mq(chl->data);
			analog.unit = channel_to_unit(ch);

			if (i < 1)
				chp->val = read_sample(ch);

			analog.data = &chp->val;
			sr_session_send(cb_data, &packet);
		}

		framep.type = SR_DF_FRAME_END;
		sr_session_send(cb_data, &framep);
	}

	devc->samples_read++;
	if (devc->limit_samples > 0 &&
	    devc->samples_read >= devc->limit_samples) {
		sr_info("Requested number of samples reached.");
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
		devc->last_sample_fin = g_get_monotonic_time();
		return TRUE;
	} else if (devc->limit_msec > 0) {
		cur_time = g_get_monotonic_time();
		elapsed_time = cur_time - devc->start_time;

		if (elapsed_time >= devc->limit_msec) {
			sr_info("Sampling time limit reached.");
			sdi->driver->dev_acquisition_stop(sdi, cb_data);
			devc->last_sample_fin = g_get_monotonic_time();
			return TRUE;
		}
	}

	devc->last_sample_fin = g_get_monotonic_time();
	return TRUE;
}
示例#21
0
/*
 * Called by libusb (as triggered by handle_event()) when a transfer comes in.
 * Only channel data comes in asynchronously, and all transfers for this are
 * queued up beforehand, so this just needs to chuck the incoming data onto
 * the libsigrok session bus.
 */
static void receive_transfer(struct libusb_transfer *transfer)
{
	struct sr_datafeed_packet packet;
	struct sr_dev_inst *sdi;
	struct dev_context *devc;
	int num_samples, pre;

	sdi = transfer->user_data;
	devc = sdi->priv;
	sr_spew("receive_transfer(): status %d received %d bytes.",
		   transfer->status, transfer->actual_length);

	if (transfer->actual_length == 0)
		/* Nothing to send to the bus. */
		return;

	num_samples = transfer->actual_length / 2;

	sr_spew("Got %d-%d/%d samples in frame.", devc->samp_received + 1,
		   devc->samp_received + num_samples, devc->framesize);

	/*
	 * The device always sends a full frame, but the beginning of the frame
	 * doesn't represent the trigger point. The offset at which the trigger
	 * happened came in with the capture state, so we need to start sending
	 * from there up the session bus. The samples in the frame buffer
	 * before that trigger point came after the end of the device's frame
	 * buffer was reached, and it wrapped around to overwrite up until the
	 * trigger point.
	 */
	if (devc->samp_received < devc->trigger_offset) {
		/* Trigger point not yet reached. */
		if (devc->samp_received + num_samples < devc->trigger_offset) {
			/* The entire chunk is before the trigger point. */
			memcpy(devc->framebuf + devc->samp_buffered * 2,
					transfer->buffer, num_samples * 2);
			devc->samp_buffered += num_samples;
		} else {
			/*
			 * This chunk hits or overruns the trigger point.
			 * Store the part before the trigger fired, and
			 * send the rest up to the session bus.
			 */
			pre = devc->trigger_offset - devc->samp_received;
			memcpy(devc->framebuf + devc->samp_buffered * 2,
					transfer->buffer, pre * 2);
			devc->samp_buffered += pre;

			/* The rest of this chunk starts with the trigger point. */
			sr_dbg("Reached trigger point, %d samples buffered.",
				   devc->samp_buffered);

			/* Avoid the corner case where the chunk ended at
			 * exactly the trigger point. */
			if (num_samples > pre)
				send_chunk(sdi, transfer->buffer + pre * 2,
						num_samples - pre);
		}
	} else {
		/* Already past the trigger point, just send it all out. */
		send_chunk(sdi, transfer->buffer,
				num_samples);
	}

	devc->samp_received += num_samples;

	/* Everything in this transfer was either copied to the buffer or
	 * sent to the session bus. */
	g_free(transfer->buffer);
	libusb_free_transfer(transfer);

	if (devc->samp_received >= devc->framesize) {
		/* That was the last chunk in this frame. Send the buffered
		 * pre-trigger samples out now, in one big chunk. */
		sr_dbg("End of frame, sending %d pre-trigger buffered samples.",
			   devc->samp_buffered);
		send_chunk(sdi, devc->framebuf, devc->samp_buffered);

		/* Mark the end of this frame. */
		packet.type = SR_DF_FRAME_END;
		sr_session_send(devc->cb_data, &packet);

		if (devc->limit_frames && ++devc->num_frames == devc->limit_frames) {
			/* Terminate session */
			devc->dev_state = STOPPING;
		} else {
			devc->dev_state = NEW_CAPTURE;
		}
	}
}
示例#22
0
文件: protocol.c 项目: jhol/libsigrok
SR_PRIV void send_block_to_session_bus(struct dev_context *devc, int block)
{
	int i;
	uint8_t sample, expected_sample;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_logic logic;
	int trigger_point; /* Relative trigger point (in this block). */

	/* Note: No sanity checks on devc/block, caller is responsible. */

	/* Check if we can find the trigger condition in this block. */
	trigger_point = -1;
	expected_sample = devc->trigger_pattern & devc->trigger_mask;
	for (i = 0; i < BS; i++) {
		/* Don't continue if the trigger was found previously. */
		if (devc->trigger_found)
			break;

		/*
		 * Also, don't continue if triggers are "don't care", i.e. if
		 * no trigger conditions were specified by the user. In that
		 * case we don't want to send an SR_DF_TRIGGER packet at all.
		 */
		if (devc->trigger_mask == 0x00)
			break;

		sample = *(devc->final_buf + (block * BS) + i);

		if ((sample & devc->trigger_mask) == expected_sample) {
			trigger_point = i;
			devc->trigger_found = 1;
			break;
		}
	}

	/* If no trigger was found, send one SR_DF_LOGIC packet. */
	if (trigger_point == -1) {
		/* Send an SR_DF_LOGIC packet to the session bus. */
		sr_spew("Sending SR_DF_LOGIC packet (%d bytes) for "
		        "block %d.", BS, block);
		packet.type = SR_DF_LOGIC;
		packet.payload = &logic;
		logic.length = BS;
		logic.unitsize = 1;
		logic.data = devc->final_buf + (block * BS);
		sr_session_send(devc->session_dev_id, &packet);
		return;
	}

	/*
	 * We found the trigger, so some special handling is needed. We have
	 * to send an SR_DF_LOGIC packet with the samples before the trigger
	 * (if any), then the SD_DF_TRIGGER packet itself, then another
	 * SR_DF_LOGIC packet with the samples after the trigger (if any).
	 */

	/* TODO: Send SR_DF_TRIGGER packet before or after the actual sample? */

	/* If at least one sample is located before the trigger... */
	if (trigger_point > 0) {
		/* Send pre-trigger SR_DF_LOGIC packet to the session bus. */
		sr_spew("Sending pre-trigger SR_DF_LOGIC packet, "
			"start = %d, length = %d.", block * BS, trigger_point);
		packet.type = SR_DF_LOGIC;
		packet.payload = &logic;
		logic.length = trigger_point;
		logic.unitsize = 1;
		logic.data = devc->final_buf + (block * BS);
		sr_session_send(devc->session_dev_id, &packet);
	}

	/* Send the SR_DF_TRIGGER packet to the session bus. */
	sr_spew("Sending SR_DF_TRIGGER packet, sample = %d.",
		(block * BS) + trigger_point);
	packet.type = SR_DF_TRIGGER;
	packet.payload = NULL;
	sr_session_send(devc->session_dev_id, &packet);

	/* If at least one sample is located after the trigger... */
	if (trigger_point < (BS - 1)) {
		/* Send post-trigger SR_DF_LOGIC packet to the session bus. */
		sr_spew("Sending post-trigger SR_DF_LOGIC packet, "
			"start = %d, length = %d.",
			(block * BS) + trigger_point, BS - trigger_point);
		packet.type = SR_DF_LOGIC;
		packet.payload = &logic;
		logic.length = BS - trigger_point;
		logic.unitsize = 1;
		logic.data = devc->final_buf + (block * BS) + trigger_point;
		sr_session_send(devc->session_dev_id, &packet);
	}
}
示例#23
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;
}
示例#24
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;
}
示例#25
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;
}
示例#26
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;
}
示例#27
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 (configure_channels(sdi) != SR_OK) {
		sr_err("Failed to configure channels.");
		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;
	}

	if (!(buf = g_try_malloc(PACKET_SIZE))) {
		sr_err("Packet buffer malloc failed.");
		return SR_ERR_MALLOC;
	}

	/* 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;
}
示例#28
0
文件: csv.c 项目: russdill/libsigrok
static int loadfile(struct sr_input *in, const char *filename)
{
	int res;
	struct context *ctx;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_config *cfg;
	GIOStatus status;
	gboolean read_new_line;
	gsize term_pos;
	char **columns;
	gsize num_columns;
	int max_columns;

	(void)filename;

	ctx = in->internal;

	/* Send header packet to the session bus. */
	std_session_send_df_header(in->sdi, LOG_PREFIX);

	if (ctx->samplerate) {
		packet.type = SR_DF_META;
		packet.payload = &meta;
		cfg = sr_config_new(SR_CONF_SAMPLERATE,
			g_variant_new_uint64(ctx->samplerate));
		meta.config = g_slist_append(NULL, cfg);
		sr_session_send(in->sdi, &packet);
		sr_config_free(cfg);
	}

	read_new_line = FALSE;

	/* Limit the number of columns to parse. */
	if (ctx->multi_column_mode)
		max_columns = ctx->num_probes;
	else
		max_columns = 1;

	while (TRUE) {
		/*
		 * Skip reading a new line for the first time if the last read
		 * line was not a header because the sample data is not parsed
		 * yet.
		 */
		if (read_new_line || ctx->header) {
			ctx->line_number++;
			status = g_io_channel_read_line_string(ctx->channel,
				ctx->buffer, &term_pos, NULL);

			if (status == G_IO_STATUS_EOF)
				break;

			if (status != G_IO_STATUS_NORMAL) {
				sr_err("Error while reading line %zu.",
					ctx->line_number);
				free_context(ctx);
				return SR_ERR;
			}

			/* Remove line termination character(s). */
			g_string_truncate(ctx->buffer, term_pos);
		}

		read_new_line = TRUE;

		if (!ctx->buffer->len) {
			sr_spew("Blank line %zu skipped.", ctx->line_number);
			continue;
		}

		/* Remove trailing comment. */
		strip_comment(ctx->buffer, ctx->comment);

		if (!ctx->buffer->len) {
			sr_spew("Comment-only line %zu skipped.",
				ctx->line_number);
			continue;
		}

		if (!(columns = parse_line(ctx, max_columns))) {
			sr_err("Error while parsing line %zu.",
				ctx->line_number);
			free_context(ctx);
			return SR_ERR;
		}

		num_columns = g_strv_length(columns);

		/* Ensure that the first column is not out of bounds. */
		if (!num_columns) {
			sr_err("Column %zu in line %zu is out of bounds.",
				ctx->first_column, ctx->line_number);
			g_strfreev(columns);
			free_context(ctx);
			return SR_ERR;
		}

		/*
		 * Ensure that the number of probes does not exceed the number
		 * of columns in multi column mode.
		 */
		if (ctx->multi_column_mode && num_columns < ctx->num_probes) {
			sr_err("Not enough columns for desired number of probes in line %zu.",
				ctx->line_number);
			g_strfreev(columns);
			free_context(ctx);
			return SR_ERR;
		}

		if (ctx->multi_column_mode)
			res = parse_multi_columns(columns, ctx);
		else
			res = parse_single_column(columns[0], ctx);

		if (res != SR_OK) {
			g_strfreev(columns);
			free_context(ctx);
			return SR_ERR;
		}

		g_strfreev(columns);

		/*
		 * TODO: Parse sample numbers / timestamps and use it for
		 * decompression.
		 */

		/* Send sample data to the session bus. */
		res = send_samples(in->sdi, ctx->sample_buffer,
			ctx->sample_buffer_size, 1);

		if (res != SR_OK) {
			sr_err("Sending samples failed.");
			free_context(ctx);
			return SR_ERR;
		}
	}

	/* Send end packet to the session bus. */
	packet.type = SR_DF_END;
	sr_session_send(in->sdi, &packet);

	free_context(ctx);

	return SR_OK;
}
示例#29
0
文件: wav.c 项目: anatol/libsigrok
static int process_buffer(struct sr_input *in)
{
	struct context *inc;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_meta meta;
	struct sr_config *src;
	int offset, chunk_samples, total_samples, processed, max_chunk_samples;
	int num_samples, i;
	char channelname[8];

	inc = in->priv;
	if (!inc->started) {
		for (i = 0; i < inc->num_channels; i++) {
			snprintf(channelname, 8, "CH%d", i + 1);
			sr_channel_new(in->sdi, i, SR_CHANNEL_ANALOG, TRUE, channelname);
		}

		std_session_send_df_header(in->sdi, LOG_PREFIX);

		packet.type = SR_DF_META;
		packet.payload = &meta;
		src = sr_config_new(SR_CONF_SAMPLERATE, g_variant_new_uint64(inc->samplerate));
		meta.config = g_slist_append(NULL, src);
		sr_session_send(in->sdi, &packet);
		sr_config_free(src);

		inc->started = TRUE;
	}

	if (!inc->found_data) {
		/* Skip past size of 'fmt ' chunk. */
		i = 20 + RL32(in->buf->str + 16);
		offset = find_data_chunk(in->buf, i);
		if (offset < 0) {
			if (in->buf->len > MAX_DATA_CHUNK_OFFSET) {
				sr_err("Couldn't find data chunk.");
				return SR_ERR;
			}
		}
		inc->found_data = TRUE;
	} else
		offset = 0;

	/* Round off up to the last channels * unitsize boundary. */
	chunk_samples = (in->buf->len - offset) / inc->num_channels / inc->unitsize;
	max_chunk_samples = CHUNK_SIZE / inc->num_channels / inc->unitsize;
	processed = 0;
	total_samples = chunk_samples;
	while (processed < total_samples) {
		if (chunk_samples > max_chunk_samples)
			num_samples = max_chunk_samples;
		else
			num_samples = chunk_samples;
		send_chunk(in, offset, num_samples);
		offset += num_samples * inc->unitsize;
		chunk_samples -= num_samples;
		processed += num_samples;
	}

	if ((unsigned int)offset < in->buf->len) {
		/*
		 * The incoming buffer wasn't processed completely. Stash
		 * the leftover data for next time.
		 */
		g_string_erase(in->buf, 0, offset);
	} else
		g_string_truncate(in->buf, 0);

	return SR_OK;
}
示例#30
0
SR_PRIV void cv_send_block_to_session_bus(struct dev_context *devc, int block)
{
	int i, idx;
	uint8_t sample, expected_sample, tmp8;
	struct sr_datafeed_packet packet;
	struct sr_datafeed_logic logic;
	int trigger_point; /* Relative trigger point (in this block). */

	/* Note: Caller ensures devc/devc->ftdic != NULL and block > 0. */

	/* TODO: Implement/test proper trigger support for the LA16. */

	/* Check if we can find the trigger condition in this block. */
	trigger_point = -1;
	expected_sample = devc->trigger_pattern & devc->trigger_mask;
	for (i = 0; i < BS; i++) {
		/* Don't continue if the trigger was found previously. */
		if (devc->trigger_found)
			break;

		/*
		 * Also, don't continue if triggers are "don't care", i.e. if
		 * no trigger conditions were specified by the user. In that
		 * case we don't want to send an SR_DF_TRIGGER packet at all.
		 */
		if (devc->trigger_mask == 0x0000)
			break;

		sample = *(devc->final_buf + (block * BS) + i);

		if ((sample & devc->trigger_mask) == expected_sample) {
			trigger_point = i;
			devc->trigger_found = 1;
			break;
		}
	}

	/* Swap low and high bytes of the 16-bit LA16 samples. */
	if (devc->prof->model == CHRONOVU_LA16) {
		for (i = 0; i < BS; i += 2) {
			idx = (block * BS) + i;
			tmp8 = devc->final_buf[idx];
			devc->final_buf[idx] = devc->final_buf[idx + 1];
			devc->final_buf[idx + 1] = tmp8;
		}
	}

	/* If no trigger was found, send one SR_DF_LOGIC packet. */
	if (trigger_point == -1) {
		/* Send an SR_DF_LOGIC packet to the session bus. */
		sr_spew("Sending SR_DF_LOGIC packet (%d bytes) for "
		        "block %d.", BS, block);
		packet.type = SR_DF_LOGIC;
		packet.payload = &logic;
		logic.length = BS;
		logic.unitsize = devc->prof->num_channels / 8;
		logic.data = devc->final_buf + (block * BS);
		sr_session_send(devc->cb_data, &packet);
		return;
	}

	/*
	 * We found the trigger, so some special handling is needed. We have
	 * to send an SR_DF_LOGIC packet with the samples before the trigger
	 * (if any), then the SD_DF_TRIGGER packet itself, then another
	 * SR_DF_LOGIC packet with the samples after the trigger (if any).
	 */

	/* TODO: Send SR_DF_TRIGGER packet before or after the actual sample? */

	/* If at least one sample is located before the trigger... */
	if (trigger_point > 0) {
		/* Send pre-trigger SR_DF_LOGIC packet to the session bus. */
		sr_spew("Sending pre-trigger SR_DF_LOGIC packet, "
			"start = %d, length = %d.", block * BS, trigger_point);
		packet.type = SR_DF_LOGIC;
		packet.payload = &logic;
		logic.length = trigger_point;
		logic.unitsize = devc->prof->num_channels / 8;
		logic.data = devc->final_buf + (block * BS);
		sr_session_send(devc->cb_data, &packet);
	}

	/* Send the SR_DF_TRIGGER packet to the session bus. */
	sr_spew("Sending SR_DF_TRIGGER packet, sample = %d.",
		(block * BS) + trigger_point);
	packet.type = SR_DF_TRIGGER;
	packet.payload = NULL;
	sr_session_send(devc->cb_data, &packet);

	/* If at least one sample is located after the trigger... */
	if (trigger_point < (BS - 1)) {
		/* Send post-trigger SR_DF_LOGIC packet to the session bus. */
		sr_spew("Sending post-trigger SR_DF_LOGIC packet, "
			"start = %d, length = %d.",
			(block * BS) + trigger_point, BS - trigger_point);
		packet.type = SR_DF_LOGIC;
		packet.payload = &logic;
		logic.length = BS - trigger_point;
		logic.unitsize = devc->prof->num_channels / 8;
		logic.data = devc->final_buf + (block * BS) + trigger_point;
		sr_session_send(devc->cb_data, &packet);
	}
}