Ejemplo n.º 1
0
/**
 * Start a session.
 *
 * When this function returns with a status code indicating success, the
 * session is running. Use sr_session_stopped_callback_set() to receive
 * notification upon completion, or call sr_session_run() to block until
 * the session stops.
 *
 * Session events will be processed in the context of the current thread.
 * If a thread-default GLib main context has been set, and is not owned by
 * any other thread, it will be used. Otherwise, libsigrok will create its
 * own main context for the current thread.
 *
 * @param session The session to use. Must not be NULL.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid session passed.
 * @retval SR_ERR Other error.
 *
 * @since 0.4.0
 */
SR_API int sr_session_start(struct sr_session *session)
{
	struct sr_dev_inst *sdi;
	struct sr_channel *ch;
	GSList *l, *c, *lend;
	int ret;

	if (!session) {
		sr_err("%s: session was NULL", __func__);
		return SR_ERR_ARG;
	}

	if (!session->devs) {
		sr_err("%s: session->devs was NULL; a session "
		       "cannot be started without devices.", __func__);
		return SR_ERR_ARG;
	}

	if (session->running) {
		sr_err("Cannot (re-)start session while it is still running.");
		return SR_ERR;
	}

	if (session->trigger) {
		ret = verify_trigger(session->trigger);
		if (ret != SR_OK)
			return ret;
	}

	/* Check enabled channels and commit settings of all devices. */
	for (l = session->devs; l; l = l->next) {
		sdi = l->data;
		for (c = sdi->channels; c; c = c->next) {
			ch = c->data;
			if (ch->enabled)
				break;
		}
		if (!c) {
			sr_err("%s device %s has no enabled channels.",
				sdi->driver->name, sdi->connection_id);
			return SR_ERR;
		}

		ret = sr_config_commit(sdi);
		if (ret != SR_OK) {
			sr_err("Failed to commit %s device %s settings "
				"before starting acquisition.",
				sdi->driver->name, sdi->connection_id);
			return ret;
		}
	}

	ret = set_main_context(session);
	if (ret != SR_OK)
		return ret;

	sr_info("Starting.");

	session->running = TRUE;

	/* Have all devices start acquisition. */
	for (l = session->devs; l; l = l->next) {
		sdi = l->data;
		ret = sdi->driver->dev_acquisition_start(sdi, sdi);
		if (ret != SR_OK) {
			sr_err("Could not start %s device %s acquisition.",
				sdi->driver->name, sdi->connection_id);
			break;
		}
	}

	if (ret != SR_OK) {
		/* If there are multiple devices, some of them may already have
		 * started successfully. Stop them now before returning. */
		lend = l->next;
		for (l = session->devs; l != lend; l = l->next) {
			sdi = l->data;
			if (sdi->driver->dev_acquisition_stop)
				sdi->driver->dev_acquisition_stop(sdi, sdi);
		}
		/* TODO: Handle delayed stops. Need to iterate the event
		 * sources... */
		session->running = FALSE;

		unset_main_context(session);
		return ret;
	}

	if (g_hash_table_size(session->event_sources) == 0)
		stop_check_later(session);

	return SR_OK;
}
Ejemplo n.º 2
0
/**
 * Start a session.
 *
 * When this function returns with a status code indicating success, the
 * session is running. Use sr_session_stopped_callback_set() to receive
 * notification upon completion, or call sr_session_run() to block until
 * the session stops.
 *
 * Session events will be processed in the context of the current thread.
 * If a thread-default GLib main context has been set, and is not owned by
 * any other thread, it will be used. Otherwise, libsigrok will create its
 * own main context for the current thread.
 *
 * @param session The session to use. Must not be NULL.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid session passed.
 * @retval SR_ERR Other error.
 *
 * @since 0.4.0
 */
SR_API int sr_session_start(struct sr_session *session)
{
	struct sr_dev_inst *sdi;
	struct sr_channel *ch;
	GSList *l, *c, *lend;
	int ret;

	if (!session) {
		sr_err("%s: session was NULL", __func__);
		return SR_ERR_ARG;
	}

	if (!session->devs) {
		sr_err("%s: session->devs was NULL; a session "
		       "cannot be started without devices.", __func__);
		return SR_ERR_ARG;
	}

	if (session->running) {
		sr_err("Cannot (re-)start session while it is still running.");
		return SR_ERR;
	}

	if (session->trigger) {
	        ret = verify_trigger(session->trigger);
		if (ret != SR_OK)
			return ret;
	}

	/* Check enabled channels and commit settings of all devices. */
	for (l = session->devs; l; l = l->next) {
		sdi = l->data;
		for (c = sdi->channels; c; c = c->next) {
			ch = c->data;
			if (ch->enabled)
				break;
		}
		if (!c) {
			sr_err("%s device %s has no enabled channels.",
				sdi->driver->name, sdi->connection_id);
			return SR_ERR;
		}

		ret = sr_config_commit(sdi);
		if (ret != SR_OK) {
			sr_err("Failed to commit %s device %s settings "
				"before starting acquisition.",
				sdi->driver->name, sdi->connection_id);
			return ret;
		}
	}

	ret = set_main_context(session);
	if (ret != SR_OK)
		return ret;

	sr_info("Starting.");

	session->running = TRUE;

	/* Have all devices start acquisition. */
	for (l = session->devs; l; l = l->next) {
            sdi = l->data;
            ret = sdi->driver->dev_acquisition_start(sdi, sdi);
            if (ret != SR_OK) {
                sr_err("Could not start %s device %s acquisition.", sdi->driver->name, sdi->connection_id);
                break;
            } else {
                sr_info("Device started.");
            }
	}

	/* Have all devices fire. */
	for (l = session->devs; l; l = l->next) {
            sdi = l->data;
            ret = sdi->driver->dev_acquisition_trigger(sdi);
            if (ret != SR_OK) {
                sr_err("Could not fire %s device %s acquisition.", sdi->driver->name, sdi->connection_id);
                break;
            } else {
                sr_info("Device fired.");
            }
	}

	return SR_OK;
}
Ejemplo n.º 3
0
/**
 * Start a session.
 *
 * @param session The session to use. Must not be NULL.
 *
 * @retval SR_OK Success.
 * @retval SR_ERR_ARG Invalid session passed.
 *
 * @since 0.4.0
 */
SR_API int sr_session_start(struct sr_session *session)
{
	struct sr_dev_inst *sdi;
	struct sr_channel *ch;
	GSList *l, *c;
	int enabled_channels, ret;

	if (!session) {
		sr_err("%s: session was NULL", __func__);
		return SR_ERR_ARG;
	}

	if (!session->devs) {
		sr_err("%s: session->devs was NULL; a session "
		       "cannot be started without devices.", __func__);
		return SR_ERR_ARG;
	}

	if (session->trigger && verify_trigger(session->trigger) != SR_OK)
		return SR_ERR;

	ret = set_main_context(session);
	if (ret != SR_OK)
		return ret;

	session->running = TRUE;

	sr_info("Starting.");

	for (l = session->devs; l; l = l->next) {
		sdi = l->data;
		enabled_channels = 0;
		for (c = sdi->channels; c; c = c->next) {
			ch = c->data;
			if (ch->enabled) {
				enabled_channels++;
				break;
			}
		}
		if (enabled_channels == 0) {
			ret = SR_ERR;
			sr_err("%s using connection %s has no enabled channels!",
					sdi->driver->name, sdi->connection_id);
			break;
		}

		if ((ret = sr_config_commit(sdi)) != SR_OK) {
			sr_err("Failed to commit device settings before "
			       "starting acquisition (%s)", sr_strerror(ret));
			break;
		}
		if ((ret = sdi->driver->dev_acquisition_start(sdi, sdi)) != SR_OK) {
			sr_err("%s: could not start an acquisition "
			       "(%s)", __func__, sr_strerror(ret));
			break;
		}
	}

	if (ret != SR_OK) {
		unset_main_context(session);
		session->running = FALSE;
	}
	/* TODO: What if there are multiple devices? Which return code? */

	return ret;
}