예제 #1
0
파일: api.c 프로젝트: anatol/libsigrok
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
{
	GSList *l;
	gboolean digital_added;
	struct sr_channel *ch;
	struct dev_context *devc;
	struct sr_scpi_dev_inst *scpi;

	(void)cb_data;

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

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

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

	for (l = sdi->channels; l; l = l->next) {
		ch = l->data;
		if (!ch->enabled)
			continue;
		/* Only add a single digital channel. */
		if (ch->type != SR_CHANNEL_LOGIC || !digital_added) {
			devc->enabled_channels = g_slist_append(
				devc->enabled_channels, ch);
			if (ch->type == SR_CHANNEL_LOGIC)
				digital_added = TRUE;
		}
	}

	if (!devc->enabled_channels)
		return SR_ERR;

	if (dlm_check_channels(devc->enabled_channels) != SR_OK) {
		sr_err("Invalid channel configuration specified!");
		return SR_ERR_NA;
	}

	if (dlm_setup_channels(sdi) != SR_OK) {
		sr_err("Failed to setup channel configuration!");
		return SR_ERR;
	}

	/* Request data for the first enabled channel. */
	devc->current_channel = devc->enabled_channels;
	dlm_channel_data_request(sdi);

	/* Call our callback when data comes in or after 5ms. */
	sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 5,
			dlm_data_receive, (void *)sdi);

	return SR_OK;
}
예제 #2
0
/**
 * Attempts to query sample data from the oscilloscope in order to send it
 * to the session bus for further processing.
 *
 * @param fd The file descriptor used as the event source.
 * @param revents The received events.
 * @param cb_data Callback data, in this case our device instance.
 *
 * @return TRUE in case of success or a recoverable error,
 *         FALSE when a fatal error was encountered.
 */
SR_PRIV int dlm_data_receive(int fd, int revents, void *cb_data)
{
	struct sr_dev_inst *sdi;
	struct scope_state *model_state;
	struct dev_context *devc;
	struct sr_channel *ch;
	struct sr_datafeed_packet packet;
	int chunk_len, num_bytes;
	static GArray *data = NULL;

	(void)fd;
	(void)revents;

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

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

	if (!(model_state = (struct scope_state*)devc->model_state))
		return FALSE;

	/* Are we waiting for a response from the device? */
	if (!devc->data_pending)
		return TRUE;

	/* Check if a new query response is coming our way. */
	if (!data) {
		if (sr_scpi_read_begin(sdi->conn) == SR_OK)
			/* The 16 here accounts for the header and EOL. */
			data = g_array_sized_new(FALSE, FALSE, sizeof(uint8_t),
					16 + model_state->samples_per_frame);
		else
			return TRUE;
	}

	/* Store incoming data. */
	chunk_len = sr_scpi_read_data(sdi->conn, devc->receive_buffer,
			RECEIVE_BUFFER_SIZE);
	if (chunk_len < 0) {
		sr_err("Error while reading data: %d", chunk_len);
		goto fail;
	}
	g_array_append_vals(data, devc->receive_buffer, chunk_len);

	/* Read the entire query response before processing. */
	if (!sr_scpi_read_complete(sdi->conn))
		return TRUE;

	/* We finished reading and are no longer waiting for data. */
	devc->data_pending = FALSE;

	/* Signal the beginning of a new frame if this is the first channel. */
	if (devc->current_channel == devc->enabled_channels) {
		packet.type = SR_DF_FRAME_BEGIN;
		sr_session_send(sdi, &packet);
	}

	if (dlm_block_data_header_process(data, &num_bytes) != SR_OK) {
		sr_err("Encountered malformed block data header.");
		goto fail;
	}

	if (num_bytes == 0) {
		sr_warn("Zero-length waveform data packet received. " \
				"Live mode not supported yet, stopping " \
				"acquisition and retrying.");
		/* Don't care about return value here. */
		dlm_acquisition_stop(sdi->conn);
		g_array_free(data, TRUE);
		dlm_channel_data_request(sdi);
		return TRUE;
	}

	ch = devc->current_channel->data;
	switch (ch->type) {
	case SR_CHANNEL_ANALOG:
		if (dlm_analog_samples_send(data,
				&model_state->analog_states[ch->index],
				sdi) != SR_OK)
			goto fail;
		break;
	case SR_CHANNEL_LOGIC:
		if (dlm_digital_samples_send(data, sdi) != SR_OK)
			goto fail;
		break;
	default:
		sr_err("Invalid channel type encountered.");
		break;
	}

	g_array_free(data, TRUE);
	data = NULL;

	/*
	 * Signal the end of this frame if this was the last enabled channel
	 * and set the next enabled channel. Then, request its data.
	 */
	if (!devc->current_channel->next) {
		packet.type = SR_DF_FRAME_END;
		sr_session_send(sdi, &packet);
		devc->current_channel = devc->enabled_channels;

		/*
		 * As of now we only support importing the current acquisition
		 * data so we're going to stop at this point.
		 */
		sdi->driver->dev_acquisition_stop(sdi, cb_data);
		return TRUE;
	} else
		devc->current_channel = devc->current_channel->next;

	if (dlm_channel_data_request(sdi) != SR_OK) {
		sr_err("Failed to request acquisition data.");
		goto fail;
	}

	return TRUE;

fail:
	if (data) {
		g_array_free(data, TRUE);
		data = NULL;
	}

	return FALSE;
}