예제 #1
0
파일: hex.c 프로젝트: BayLibre/libsigrok
static GString *gen_header(const struct sr_output *o)
{
	struct context *ctx;
	GVariant *gvar;
	GString *header;
	int num_channels;
	char *samplerate_s;

	ctx = o->priv;
	if (ctx->samplerate == 0) {
		if (sr_config_get(o->sdi->driver, o->sdi, NULL, SR_CONF_SAMPLERATE,
				&gvar) == SR_OK) {
			ctx->samplerate = g_variant_get_uint64(gvar);
			g_variant_unref(gvar);
		}
	}

	header = g_string_sized_new(512);
	g_string_printf(header, "%s %s\n", PACKAGE_NAME, SR_PACKAGE_VERSION_STRING);
	num_channels = g_slist_length(o->sdi->channels);
	g_string_append_printf(header, "Acquisition with %d/%d channels",
			ctx->num_enabled_channels, num_channels);
	if (ctx->samplerate != 0) {
		samplerate_s = sr_samplerate_string(ctx->samplerate);
		g_string_append_printf(header, " at %s", samplerate_s);
		g_free(samplerate_s);
	}
	g_string_append_printf(header, "\n");

	return header;
}
예제 #2
0
QString DeviceOptions::print_samplerate(GVariant *const gvar)
{
	char *const s = sr_samplerate_string(
		g_variant_get_uint64(gvar));
	const QString qstring(s);
	g_free(s);
	return qstring;
}
예제 #3
0
static void test_samplerate(uint64_t samplerate, const char *expected)
{
	char *s;

	s = sr_samplerate_string(samplerate);
	fail_unless(s != NULL);
	fail_unless(!strcmp(s, expected),
		    "Invalid result for '%s': %s.", expected, s);
	g_free(s);
}
예제 #4
0
/**
 * Prints out the state of the device as we currently know it.
 *
 * @param config This is the scope configuration.
 * @param state The current scope state to print.
 */
static void scope_state_dump(const struct scope_config *config,
		struct scope_state *state)
{
	unsigned int i;
	char *tmp;

	for (i = 0; i < config->analog_channels; i++) {
		tmp = sr_voltage_string(dlm_vdivs[state->analog_states[i].vdiv][0],
				dlm_vdivs[state->analog_states[i].vdiv][1]);
		sr_info("State of analog channel %d -> %s : %s (coupling) %s (vdiv) %2.2e (offset)",
				i + 1, state->analog_states[i].state ? "On" : "Off",
				(*config->coupling_options)[state->analog_states[i].coupling],
				tmp, state->analog_states[i].vertical_offset);
	}

	for (i = 0; i < config->digital_channels; i++) {
		sr_info("State of digital channel %d -> %s", i,
				state->digital_states[i] ? "On" : "Off");
	}

	for (i = 0; i < config->pods; i++) {
		sr_info("State of digital POD %d -> %s", i,
				state->pod_states[i] ? "On" : "Off");
	}

	tmp = sr_period_string(dlm_timebases[state->timebase][0] *
			dlm_timebases[state->timebase][1]);
	sr_info("Current timebase: %s", tmp);
	g_free(tmp);

	tmp = sr_samplerate_string(state->sample_rate);
	sr_info("Current samplerate: %s", tmp);
	g_free(tmp);

	sr_info("Current samples per acquisition (i.e. frame): %d",
			state->samples_per_frame);

	sr_info("Current trigger: %s (source), %s (slope) %.2f (offset)",
			(*config->trigger_sources)[state->trigger_source],
			dlm_trigger_slopes[state->trigger_slope],
			state->horiz_triggerpos);
}
예제 #5
0
static int zip_create(const struct sr_output *o)
{
	struct out_context *outc;
	struct sr_channel *ch;
	FILE *meta;
	struct zip *zipfile;
	struct zip_source *versrc, *metasrc;
	GVariant *gvar;
	GSList *l;
	int tmpfile, ret;
	char version[1], metafile[32], *s;

	outc = o->priv;
	if (outc->samplerate == 0) {
		if (sr_config_get(o->sdi->driver, o->sdi, NULL, NULL, SR_CONF_SAMPLERATE,
				&gvar) == SR_OK) {
			outc->samplerate = g_variant_get_uint64(gvar);
			g_variant_unref(gvar);
		}
	}

	/* Quietly delete it first, libzip wants replace ops otherwise. */
	unlink(outc->filename);
	if (!(zipfile = zip_open(outc->filename, ZIP_CREATE, &ret)))
		return SR_ERR;

	/* "version" */
	version[0] = '2';
	if (!(versrc = zip_source_buffer(zipfile, version, 1, 0)))
		return SR_ERR;
	if (zip_add(zipfile, "version", versrc) == -1) {
		sr_info("Error saving version into zipfile: %s.",
			zip_strerror(zipfile));
		return SR_ERR;
	}

	/* init "metadata" */
	strcpy(metafile, "sigrok-meta-XXXXXX");
	if ((tmpfile = g_mkstemp(metafile)) == -1)
		return SR_ERR;
	close(tmpfile);
	meta = g_fopen(metafile, "wb");
	fprintf(meta, "[global]\n");
	fprintf(meta, "sigrok version = %s\n", PACKAGE_VERSION);
	fprintf(meta, "[device 1]\ncapturefile = logic-1\n");
	fprintf(meta, "total probes = %d\n", g_slist_length(o->sdi->channels));
	s = sr_samplerate_string(outc->samplerate);
	fprintf(meta, "samplerate = %s\n", s);
	g_free(s);

	for (l = o->sdi->channels; l; l = l->next) {
		ch = l->data;
		if (ch->type != SR_CHANNEL_LOGIC)
			continue;
		if (!ch->enabled)
			continue;
		fprintf(meta, "probe%d = %s\n", ch->index + 1, ch->name);
	}
	fclose(meta);

	if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1))) {
		unlink(metafile);
		return SR_ERR;
	}
	if (zip_add(zipfile, "metadata", metasrc) == -1) {
		unlink(metafile);
		return SR_ERR;
	}

	if ((ret = zip_close(zipfile)) == -1) {
		sr_info("Error saving zipfile: %s.", zip_strerror(zipfile));
		unlink(metafile);
		return SR_ERR;
	}

	unlink(metafile);

	return SR_OK;
}
예제 #6
0
/**
 * Initialize a saved session file.
 *
 * @param filename The name of the filename to save the current session as.
 *                 Must not be NULL.
 * @param samplerate The samplerate to store for this session.
 * @param channels A NULL-terminated array of strings containing the names
 * of all the channels active in this session.
 *
 * @retval SR_OK Success
 * @retval SR_ERR_ARG Invalid arguments
 * @retval SR_ERR Other errors
 *
 * @since 0.3.0
 */
SR_API int sr_session_save_init(const char *filename, uint64_t samplerate,
        char **channels)
{
    FILE *meta;
    struct zip *zipfile;
    struct zip_source *versrc, *metasrc;
    int tmpfile, cnt, ret, i;
    char version[1], metafile[32], *s;

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

    /* Quietly delete it first, libzip wants replace ops otherwise. */
    unlink(filename);
    if (!(zipfile = zip_open(filename, ZIP_CREATE, &ret)))
        return SR_ERR;

    /* "version" */
    version[0] = '2';
    if (!(versrc = zip_source_buffer(zipfile, version, 1, 0)))
        return SR_ERR;
    if (zip_add(zipfile, "version", versrc) == -1) {
        sr_info("error saving version into zipfile: %s",
            zip_strerror(zipfile));
        return SR_ERR;
    }

    /* init "metadata" */
    strcpy(metafile, "sigrok-meta-XXXXXX");
    if ((tmpfile = g_mkstemp(metafile)) == -1)
        return SR_ERR;
    close(tmpfile);
    meta = g_fopen(metafile, "wb");
    fprintf(meta, "[global]\n");
    fprintf(meta, "sigrok version = %s\n", PACKAGE_VERSION);

    /* metadata */
    fprintf(meta, "[device 1]\n");

    /* metadata */
    fprintf(meta, "capturefile = logic-1\n");
    cnt = 0;
    for (i = 0; channels[i]; i++)
        cnt++;
    fprintf(meta, "total probes = %d\n", cnt);
    s = sr_samplerate_string(samplerate);
    fprintf(meta, "samplerate = %s\n", s);
    g_free(s);

    for (i = 0; channels[i]; i++)
        fprintf(meta, "probe%d = %s\n", i + 1, channels[i]);

    fclose(meta);

    if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1))) {
        unlink(metafile);
        return SR_ERR;
    }
    if (zip_add(zipfile, "metadata", metasrc) == -1) {
        unlink(metafile);
        return SR_ERR;
    }

    if ((ret = zip_close(zipfile)) == -1) {
        sr_info("error saving zipfile: %s", zip_strerror(zipfile));
        unlink(metafile);
        return SR_ERR;
    }

    unlink(metafile);

    return SR_OK;
}
예제 #7
0
/**
 * Save the current session to the specified file.
 *
 * @param filename The name of the filename to save the current session as.
 *                 Must not be NULL.
 * @param sdi The device instance from which the data was captured.
 * @param buf The data to be saved.
 * @param unitsize The number of bytes per sample.
 * @param units The number of samples.
 *
 * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or SR_ERR
 *         upon other errors.
 */
SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi,
		unsigned char *buf, int unitsize, int units)
{
    GSList *l;
    GVariant *gvar;
    FILE *meta;
    struct sr_channel *probe;
    struct zip *zipfile;
    struct zip_source *versrc, *metasrc, *logicsrc;
    int tmpfile, ret, probecnt;
    uint64_t samplerate, timeBase, tmp_u64;
    char rawname[16], metafile[32], *s;
    struct sr_status status;

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

	/* Quietly delete it first, libzip wants replace ops otherwise. */
	unlink(filename);
	if (!(zipfile = zip_open(filename, ZIP_CREATE, &ret)))
		return SR_ERR;

    /* init "metadata" */
    strcpy(metafile, "DSView-meta-XXXXXX");
    if ((tmpfile = g_mkstemp(metafile)) == -1)
        return SR_ERR;
    close(tmpfile);
    meta = g_fopen(metafile, "wb");
    fprintf(meta, "[version]\n");
    fprintf(meta, "DSView version = %s\n", PACKAGE_VERSION);

    /* metadata */
    fprintf(meta, "[header]\n");
    if (sdi->driver) {
        fprintf(meta, "driver = %s\n", sdi->driver->name);
        fprintf(meta, "device mode = %d\n", sdi->mode);
    }

    /* metadata */
    fprintf(meta, "capturefile = data\n");
    fprintf(meta, "unitsize = %d\n", unitsize);
    fprintf(meta, "total samples = %d\n", units);
    fprintf(meta, "total probes = %d\n", g_slist_length(sdi->channels));
    if (sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE,
            &gvar) == SR_OK) {
        samplerate = g_variant_get_uint64(gvar);
        s = sr_samplerate_string(samplerate);
        fprintf(meta, "samplerate = %s\n", s);
        g_free(s);
        g_variant_unref(gvar);
    }
    if (sdi->mode == DSO &&
        sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_TIMEBASE, &gvar) == SR_OK) {
        timeBase = g_variant_get_uint64(gvar);
        fprintf(meta, "hDiv = %d\n", timeBase);
        g_variant_unref(gvar);
    }
    probecnt = 1;
    for (l = sdi->channels; l; l = l->next) {
        probe = l->data;
        if (probe->enabled || sdi->mode == DSO) {
            if (probe->name)
                fprintf(meta, "probe%d = %s\n", probe->index, probe->name);
            if (probe->trigger)
                fprintf(meta, " trigger%d = %s\n", probe->index, probe->trigger);
            if (sdi->mode == DSO) {
                fprintf(meta, " enable%d = %d\n", probe->index, probe->enabled);
                fprintf(meta, " coupling%d = %d\n", probe->index, probe->coupling);
                fprintf(meta, " vDiv%d = %d\n", probe->index, probe->vdiv);
                fprintf(meta, " vFactor%d = %d\n", probe->index, probe->vfactor);
                fprintf(meta, " vPos%d = %lf\n", probe->index, probe->vpos);
                if (sr_status_get(sdi, &status, 0, 0) == SR_OK) {
                    if (probe->index == 0) {
                        fprintf(meta, " period%d = %d\n", probe->index, status.ch0_period);
                        fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch0_pcnt);
                        fprintf(meta, " max%d = %d\n", probe->index, status.ch0_max);
                        fprintf(meta, " min%d = %d\n", probe->index, status.ch0_min);
                    } else {
                        fprintf(meta, " period%d = %d\n", probe->index, status.ch1_period);
                        fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch1_pcnt);
                        fprintf(meta, " max%d = %d\n", probe->index, status.ch1_max);
                        fprintf(meta, " min%d = %d\n", probe->index, status.ch1_min);
                    }
                }
            }
            probecnt++;
        }
    }

    if (!(logicsrc = zip_source_buffer(zipfile, buf,
               units * unitsize, FALSE)))
        return SR_ERR;
    snprintf(rawname, 15, "data");
    if (zip_add(zipfile, rawname, logicsrc) == -1)
        return SR_ERR;
    fclose(meta);

    if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1)))
        return SR_ERR;
    if (zip_add(zipfile, "header", metasrc) == -1)
        return SR_ERR;

    if ((ret = zip_close(zipfile)) == -1) {
        sr_info("error saving zipfile: %s", zip_strerror(zipfile));
        return SR_ERR;
    }

    unlink(metafile);

    return SR_OK;
}
예제 #8
0
파일: text.c 프로젝트: haavares/sigrok
SR_PRIV int init(struct sr_output *o, int default_spl, enum outputmode mode)
{
	struct context *ctx;
	struct sr_probe *probe;
	GSList *l;
	uint64_t samplerate;
	int num_probes;
	char *samplerate_s;

	if (!(ctx = g_try_malloc0(sizeof(struct context)))) {
		sr_err("text out: %s: ctx malloc failed", __func__);
		return SR_ERR_MALLOC;
	}

	o->internal = ctx;
	ctx->num_enabled_probes = 0;

	for (l = o->dev->probes; l; l = l->next) {
		probe = l->data;
		if (!probe->enabled)
			continue;
		ctx->probelist[ctx->num_enabled_probes++] = probe->name;
	}

	ctx->probelist[ctx->num_enabled_probes] = 0;
	ctx->unitsize = (ctx->num_enabled_probes + 7) / 8;
	ctx->line_offset = 0;
	ctx->spl_cnt = 0;
	ctx->mark_trigger = -1;
	ctx->mode = mode;

	if (o->param && o->param[0]) {
		ctx->samples_per_line = strtoul(o->param, NULL, 10);
		if (ctx->samples_per_line < 1)
			return SR_ERR;
	} else
		ctx->samples_per_line = default_spl;

	if (!(ctx->header = g_try_malloc0(512))) {
		g_free(ctx);
		sr_err("text out: %s: ctx->header malloc failed", __func__);
		return SR_ERR_MALLOC;
	}

	snprintf(ctx->header, 511, "%s\n", PACKAGE_STRING);
	num_probes = g_slist_length(o->dev->probes);
	if (o->dev->driver || sr_dev_has_hwcap(o->dev, SR_HWCAP_SAMPLERATE)) {
		samplerate = *((uint64_t *) o->dev->driver->dev_info_get(
				o->dev->driver_index, SR_DI_CUR_SAMPLERATE));
		if (!(samplerate_s = sr_samplerate_string(samplerate))) {
			g_free(ctx->header);
			g_free(ctx);
			return SR_ERR;
		}
		snprintf(ctx->header + strlen(ctx->header),
			 511 - strlen(ctx->header),
			 "Acquisition with %d/%d probes at %s\n",
			 ctx->num_enabled_probes, num_probes, samplerate_s);
		g_free(samplerate_s);
	}

	ctx->linebuf_len = ctx->samples_per_line * 2 + 4;
	if (!(ctx->linebuf = g_try_malloc0(num_probes * ctx->linebuf_len))) {
		g_free(ctx->header);
		g_free(ctx);
		sr_err("text out: %s: ctx->linebuf malloc failed", __func__);
		return SR_ERR_MALLOC;
	}
	if (!(ctx->linevalues = g_try_malloc0(num_probes))) {
		g_free(ctx->header);
		g_free(ctx);
		sr_err("text out: %s: ctx->linevalues malloc failed", __func__);
		return SR_ERR_MALLOC;
	}

	return SR_OK;
}
예제 #9
0
파일: mainwindow.cpp 프로젝트: jeras/sigrok
void datafeed_in(struct sr_dev *dev, struct sr_datafeed_packet *packet)
{
	static int num_probes = 0;
	static int logic_probelist[SR_MAX_NUM_PROBES + 1] = { 0 };
	static uint64_t received_samples = 0;
	static int triggered = 0;
	static int unitsize = 0;
	struct sr_probe *probe;
	static struct sr_datafeed_header *header;
	struct sr_datafeed_meta_logic *meta_logic;
	struct sr_datafeed_logic *logic;
	int num_enabled_probes, sample_size, ret;
	uint64_t sample;
	uint64_t filter_out_len;
	uint8_t *filter_out;

	/* If the first packet to come in isn't a header, don't even try. */
	// if (packet->type != SR_DF_HEADER && o == NULL)
	//	return;

	/* TODO: Also check elsewhere? */
	/* TODO: Abort acquisition too, if user pressed cancel. */
	if (progress && progress->wasCanceled())
		return;

	sample_size = -1;

	switch (packet->type) {
	case SR_DF_HEADER:
		qDebug("SR_DF_HEADER");
		header = (struct sr_datafeed_header *)packet->payload;
	case SR_DF_END:
		qDebug("SR_DF_END");
		/* TODO: o */
		sr_session_stop();
		// progress->setValue(received_samples); /* FIXME */
		break;
	case SR_DF_TRIGGER:
		qDebug("SR_DF_TRIGGER");
		/* TODO */
		triggered = 1;
		break;
	case SR_DF_META_LOGIC:
		qDebug("SR_DF_META_LOGIC");
		meta_logic = (struct sr_datafeed_meta_logic *)packet->payload;
		num_probes = meta_logic->num_probes;
		num_enabled_probes = 0;
		for (int i = 0; i < meta_logic->num_probes; ++i) {
			probe = (struct sr_probe *)g_slist_nth_data(dev->probes, i);
			if (probe->enabled)
				logic_probelist[num_enabled_probes++] = probe->index;
		}

		qDebug() << "Acquisition with" << num_enabled_probes << "/"
			 << num_probes << "probes at"
			 << sr_samplerate_string(meta_logic->samplerate)
			 << "starting at" << ctime(&header->starttime.tv_sec)
			 << "(" << limit_samples << "samples)";

		/* TODO: realloc() */
		break;
	case SR_DF_LOGIC:
		logic = (sr_datafeed_logic *)packet->payload;
		qDebug() << "SR_DF_LOGIC (length =" << logic->length
			 << ", unitsize = " << logic->unitsize << ")";
		sample_size = logic->unitsize;

		if (sample_size == -1)
			break;
		
		/* Don't store any samples until triggered. */
		// if (opt_wait_trigger && !triggered)
		// 	return;

		if (received_samples >= limit_samples)
			break;

		/* TODO */
		ret = sr_filter_probes(sample_size, 1 /* unitsize */, logic_probelist,
				       (uint8_t *)logic->data, logic->length,
				       &filter_out, &filter_out_len);
		if (ret != SR_OK)
			break;

		for (uint64_t i = 0; i < filter_out_len; ++i) {
			sample = filter_out[i];
			sample_buffer[i] = (uint8_t)(sample & 0xff); /* FIXME */
			// qDebug("Sample %" PRIu64 ": 0x%x", i, sample);
		}
		received_samples += logic->length / sample_size;

		progress->setValue(received_samples);
		break;
	default:
		qDebug("SR_DF_XXXX, not yet handled");
		break;
	}
}
예제 #10
0
파일: mainwindow.cpp 프로젝트: jeras/sigrok
void MainWindow::on_actionScan_triggered()
{
	QString s;
	GSList *devs = NULL;
	int num_devs, pos;
	struct sr_dev *dev;
	char *di_num_probes, *str;
	struct sr_samplerates *samplerates;
	const static float mult[] = { 2.f, 2.5f, 2.f };

	statusBar()->showMessage(tr("Scanning for logic analyzers..."), 2000);

	sr_dev_scan();
	devs = sr_dev_list();
	num_devs = g_slist_length(devs);

	ui->comboBoxLA->clear();
	for (int i = 0; i < num_devs; ++i) {
		dev = (struct sr_dev *)g_slist_nth_data(devs, i);
		ui->comboBoxLA->addItem(dev->driver->name); /* TODO: Full name */
	}

	if (num_devs == 0) {
		s = tr("No supported logic analyzer found.");
		statusBar()->showMessage(s, 2000);
		return;
	} else if (num_devs == 1) {
		s = tr("Found supported logic analyzer: ");
		s.append(dev->driver->name);
		statusBar()->showMessage(s, 2000);
	} else {
		/* TODO: Allow user to select one of the devices. */
		s = tr("Found multiple logic analyzers: ");
		for (int i = 0; i < num_devs; ++i) {
			dev = (struct sr_dev *)g_slist_nth_data(devs, i);
			s.append(dev->driver->name);
			if (i != num_devs - 1)
				s.append(", ");
		}
		statusBar()->showMessage(s, 2000);
		// return;
	}

	dev = (struct sr_dev *)g_slist_nth_data(devs, 0 /* opt_dev */);

	setCurrentLA(0 /* TODO */);

	di_num_probes = (char *)dev->driver->dev_info_get(
			dev->driver_index, SR_DI_NUM_PROBES);
	if (di_num_probes != NULL) {
		setNumChannels(GPOINTER_TO_INT(di_num_probes));
	} else {
		setNumChannels(8); /* FIXME: Error handling. */
	}

	ui->comboBoxLA->clear();
	ui->comboBoxLA->addItem(dev->driver->name); /* TODO: Full name */

	s = QString(tr("Channels: %1")).arg(getNumChannels());
	ui->labelChannels->setText(s);

	samplerates = (struct sr_samplerates *)dev->driver->dev_info_get(
		      dev->driver_index, SR_DI_SAMPLERATES);
	if (!samplerates) {
		/* TODO: Error handling. */
	}

	/* Populate the combobox with supported samplerates. */
	ui->comboBoxSampleRate->clear();
	if (!samplerates) {
		ui->comboBoxSampleRate->addItem("No samplerate");
		ui->comboBoxSampleRate->setEnabled(false);
	} else if (samplerates->list != NULL) {
		for (int i = 0; samplerates->list[i]; ++i) {
			str = sr_samplerate_string(samplerates->list[i]);
			s = QString(str);
			free(str);
			ui->comboBoxSampleRate->insertItem(0, s,
				QVariant::fromValue(samplerates->list[i]));
		}
		ui->comboBoxSampleRate->setEnabled(true);
	} else {
		pos = 0;
		for (uint64_t r = samplerates->low; r <= samplerates->high; ) {
			str = sr_samplerate_string(r);
			s = QString(str);
			free(str);
			ui->comboBoxSampleRate->insertItem(0, s,
						QVariant::fromValue(r));
			r *= mult[pos++];
			pos %= 3;
		}
		ui->comboBoxSampleRate->setEnabled(true);
	}
	ui->comboBoxSampleRate->setCurrentIndex(0);

	/* FIXME */
	ui->comboBoxNumSamples->clear();
	ui->comboBoxNumSamples->addItem("100", 100); /* For testing... */
	ui->comboBoxNumSamples->addItem("3000000", 3000000);
	ui->comboBoxNumSamples->addItem("2000000", 2000000);
	ui->comboBoxNumSamples->addItem("1000000", 1000000);

	ui->comboBoxNumSamples->setEditable(true);

	if (getCurrentLA() >= 0)
		setupDockWidgets();

	/* Enable all relevant fields now (i.e. make them non-gray). */
	ui->comboBoxNumSamples->setEnabled(true);
	ui->labelChannels->setEnabled(true);
	ui->action_Get_samples->setEnabled(true);
}
예제 #11
0
파일: text.c 프로젝트: poljar/libsigrok
SR_PRIV int init(struct sr_output *o, int default_spl, enum outputmode mode)
{
	struct context *ctx;
	struct sr_probe *probe;
	GSList *l;
	GVariant *gvar;
	uint64_t samplerate;
	int num_probes, ret;
	char *samplerate_s;

	if (!(ctx = g_try_malloc0(sizeof(struct context)))) {
		sr_err("%s: ctx malloc failed", __func__);
		return SR_ERR_MALLOC;
	}

	o->internal = ctx;
	ctx->num_enabled_probes = 0;
	ctx->probenames = NULL;

	for (l = o->sdi->probes; l; l = l->next) {
		probe = l->data;
		if (!probe->enabled)
			continue;
		ctx->probenames = g_slist_append(ctx->probenames, probe->name);
		ctx->num_enabled_probes++;
	}

	ctx->unitsize = (ctx->num_enabled_probes + 7) / 8;
	ctx->line_offset = 0;
	ctx->spl_cnt = 0;
	ctx->mark_trigger = -1;
	ctx->mode = mode;

	ret = SR_OK;
	if (o->param && o->param[0]) {
		ctx->samples_per_line = strtoul(o->param, NULL, 10);
		if (ctx->samples_per_line < 1) {
			ret = SR_ERR;
			goto err;
		}
	} else
		ctx->samples_per_line = default_spl;

	if (!(ctx->header = g_try_malloc0(512))) {
		sr_err("%s: ctx->header malloc failed", __func__);
		ret = SR_ERR_MALLOC;
		goto err;
	}

	snprintf(ctx->header, 511, "%s\n", PACKAGE_STRING);
	num_probes = g_slist_length(o->sdi->probes);
	if (sr_config_get(o->sdi->driver, o->sdi, NULL, SR_CONF_SAMPLERATE,
			&gvar) == SR_OK) {
		samplerate = g_variant_get_uint64(gvar);
		g_variant_unref(gvar);
		if (!(samplerate_s = sr_samplerate_string(samplerate))) {
			ret = SR_ERR;
			goto err;
		}
		snprintf(ctx->header + strlen(ctx->header),
			 511 - strlen(ctx->header),
			 "Acquisition with %d/%d probes at %s\n",
			 ctx->num_enabled_probes, num_probes, samplerate_s);
		g_free(samplerate_s);
	}

	ctx->linebuf_len = ctx->samples_per_line * 2 + 4;
	if (!(ctx->linebuf = g_try_malloc0(num_probes * ctx->linebuf_len))) {
		sr_err("%s: ctx->linebuf malloc failed", __func__);
		ret = SR_ERR_MALLOC;
		goto err;
	}

	if (!(ctx->linevalues = g_try_malloc0(num_probes))) {
		sr_err("%s: ctx->linevalues malloc failed", __func__);
		ret = SR_ERR_MALLOC;
	}

	if (mode == MODE_ASCII &&
			!(ctx->prevsample = g_try_malloc0(num_probes / 8))) {
		sr_err("%s: ctx->prevsample malloc failed", __func__);
		ret = SR_ERR_MALLOC;
	}

err:
	if (ret != SR_OK) {
		g_free(ctx->header);
		g_free(ctx);
	}

	return ret;
}
예제 #12
0
int sr_session_save(const char *filename)
{
	GSList *l, *p, *d;
	FILE *meta;
	struct sr_device *device;
	struct sr_probe *probe;
	struct sr_datastore *ds;
	struct zip *zipfile;
	struct zip_source *versrc, *metasrc, *logicsrc;
	int bufcnt, devcnt, tmpfile, ret, error, probecnt;
	uint64_t samplerate;
	char version[1], rawname[16], metafile[32], *buf, *s;

	/* Quietly delete it first, libzip wants replace ops otherwise. */
	unlink(filename);
	if (!(zipfile = zip_open(filename, ZIP_CREATE, &error)))
		return SR_ERR;

	/* "version" */
	version[0] = '1';
	if (!(versrc = zip_source_buffer(zipfile, version, 1, 0)))
		return SR_ERR;
	if (zip_add(zipfile, "version", versrc) == -1) {
		sr_info("error saving version into zipfile: %s",
			zip_strerror(zipfile));
		return SR_ERR;
	}

	/* init "metadata" */
	strcpy(metafile, "sigrok-meta-XXXXXX");
	if ((tmpfile = g_mkstemp(metafile)) == -1)
		return SR_ERR;
	close(tmpfile);
	meta = g_fopen(metafile, "wb");
	fprintf(meta, "[global]\n");
	fprintf(meta, "sigrok version = %s\n", PACKAGE_VERSION);
	/* TODO: save protocol decoders used */

	/* all datastores in all devices */
	devcnt = 1;
	for (l = session->devices; l; l = l->next) {
		device = l->data;
		/* metadata */
		fprintf(meta, "[device %d]\n", devcnt);
		if (device->plugin)
			fprintf(meta, "driver = %s\n", device->plugin->name);

		ds = device->datastore;
		if (ds) {
			/* metadata */
			fprintf(meta, "capturefile = logic-%d\n", devcnt);
			fprintf(meta, "unitsize = %d\n", ds->ds_unitsize);
			fprintf(meta, "total probes = %d\n", g_slist_length(device->probes));
			if (sr_device_has_hwcap(device, SR_HWCAP_SAMPLERATE)) {
				samplerate = *((uint64_t *) device->plugin->get_device_info(
						device->plugin_index, SR_DI_CUR_SAMPLERATE));
				s = sr_samplerate_string(samplerate);
				fprintf(meta, "samplerate = %s\n", s);
				free(s);
			}
			probecnt = 1;
			for (p = device->probes; p; p = p->next) {
				probe = p->data;
				if (probe->enabled) {
					if (probe->name)
						fprintf(meta, "probe%d = %s\n", probecnt, probe->name);
					if (probe->trigger)
						fprintf(meta, " trigger%d = %s\n", probecnt, probe->trigger);
					probecnt++;
				}
			}

			/* dump datastore into logic-n */
			buf = malloc(ds->num_units * ds->ds_unitsize +
				   DATASTORE_CHUNKSIZE);
			bufcnt = 0;
			for (d = ds->chunklist; d; d = d->next) {
				memcpy(buf + bufcnt, d->data,
				       DATASTORE_CHUNKSIZE);
				bufcnt += DATASTORE_CHUNKSIZE;
			}
			if (!(logicsrc = zip_source_buffer(zipfile, buf,
				       ds->num_units * ds->ds_unitsize, TRUE)))
				return SR_ERR;
			snprintf(rawname, 15, "logic-%d", devcnt);
			if (zip_add(zipfile, rawname, logicsrc) == -1)
				return SR_ERR;
		}
		devcnt++;
	}
	fclose(meta);

	if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1)))
		return SR_ERR;
	if (zip_add(zipfile, "metadata", metasrc) == -1)
		return SR_ERR;

	if ((ret = zip_close(zipfile)) == -1) {
		sr_info("error saving zipfile: %s", zip_strerror(zipfile));
		return SR_ERR;
	}

	unlink(metafile);

	return SR_OK;
}
예제 #13
0
void datafeed_in(struct sr_device *device, struct sr_datafeed_packet *packet)
{
	static int num_probes = 0;
	static int probelist[65] = {0};
	static uint64_t received_samples = 0;
	static int triggered = 0;
	struct sr_probe *probe;
	struct sr_datafeed_header *header;
	struct sr_datafeed_logic *logic;
	int num_enabled_probes, sample_size;
	uint64_t sample;

	/* If the first packet to come in isn't a header, don't even try. */
	// if (packet->type != SR_DF_HEADER && o == NULL)
	//	return;

	/* TODO: Also check elsewhere? */
	/* TODO: Abort acquisition too, if user pressed cancel. */
	if (progress && progress->wasCanceled())
		return;

	sample_size = -1;

	switch (packet->type) {
	case SR_DF_HEADER:
		qDebug("SR_DF_HEADER");
		header = (struct sr_datafeed_header *)packet->payload;
		num_probes = header->num_logic_probes;
		num_enabled_probes = 0;
		for (int i = 0; i < header->num_logic_probes; ++i) {
			probe = (struct sr_probe *)g_slist_nth_data(device->probes, i);
			if (probe->enabled)
				probelist[num_enabled_probes++] = probe->index;
		}

		qDebug() << "Acquisition with" << num_enabled_probes << "/"
			 << num_probes << "probes at"
			 << sr_samplerate_string(header->samplerate)
			 << "starting at" << ctime(&header->starttime.tv_sec)
			 << "(" << limit_samples << "samples)";

		/* TODO: realloc() */
		break;
	case SR_DF_END:
		qDebug("SR_DF_END");
		/* TODO: o */
		sr_session_halt();
		progress->setValue(received_samples); /* FIXME */
		break;
	case SR_DF_TRIGGER:
		qDebug("SR_DF_TRIGGER");
		/* TODO */
		triggered = 1;
		break;
	case SR_DF_LOGIC:
		logic = (sr_datafeed_logic*)packet->payload;
		qDebug() << "SR_DF_LOGIC (length =" << logic->length
			 << ", unitsize = " << logic->unitsize << ")";
		sample_size = logic->unitsize;
		break;
	default:
		qDebug("SR_DF_XXXX, not yet handled");
		break;
	}

	if (sample_size == -1)
		return;
	
	/* Don't store any samples until triggered. */
	// if (opt_wait_trigger && !triggered)
	// 	return;

	if (received_samples >= limit_samples)
		return;

	/* TODO */

	for (uint64_t i = 0; received_samples < limit_samples
			     && i < logic->length; i += sample_size) {
		sample = 0;
		memcpy(&sample, (char *)packet->payload + i, sample_size);
		sample_buffer[i] = (uint8_t)(sample & 0xff); /* FIXME */
		// qDebug("Sample %" PRIu64 ": 0x%x", i, sample);
		received_samples++;
	}

	progress->setValue(received_samples);
}
예제 #14
0
파일: show.c 프로젝트: JenSte/sigrok-cli
void show_dev_detail(void)
{
	struct sr_dev_inst *sdi;
	const struct sr_config_info *srci;
	struct sr_channel *ch;
	struct sr_channel_group *channel_group, *cg;
	GSList *devices, *cgl, *chl;
	GVariant *gvar_opts, *gvar_dict, *gvar_list, *gvar;
	gsize num_opts, num_elements;
	double dlow, dhigh, dcur_low, dcur_high;
	const uint64_t *uint64, p, q, low, high;
	uint64_t cur_low, cur_high;
	const int32_t *int32, *opts;
	unsigned int num_devices, o, i;
	char *tmp_str;
	char *s, c;
	const char **stropts;

	if (!(devices = device_scan())) {
		g_critical("No devices found.");
		return;
	}

	num_devices = g_slist_length(devices);
	if (num_devices > 1) {
		g_critical("%d devices found. Use --scan to show them, "
				"and select one to show.", num_devices);
		return;
	}

	sdi = devices->data;
	print_dev_line(sdi);

	if (sr_dev_open(sdi) != SR_OK) {
		g_critical("Failed to open device.");
		return;
	}

	if ((sr_config_list(sdi->driver, NULL, NULL, SR_CONF_SCAN_OPTIONS,
			&gvar_opts) == SR_OK)) {
		opts = g_variant_get_fixed_array(gvar_opts, &num_elements,
				sizeof(int32_t));
		printf("Supported driver options:\n");
		for (i = 0; i < num_elements; i++) {
			if (!(srci = sr_config_info_get(opts[i])))
				continue;
			printf("    %s\n", srci->id);
		}
		g_variant_unref(gvar_opts);
	}

	/* Selected channels and channel group may affect which options are
	 * returned, or which values for them. */
	select_channels(sdi);
	channel_group = select_channel_group(sdi);

	if ((sr_config_list(sdi->driver, sdi, channel_group, SR_CONF_DEVICE_OPTIONS,
			&gvar_opts)) != SR_OK)
		/* Driver supports no device instance options. */
		return;

	if (sdi->channel_groups) {
		printf("Channel groups:\n");
		for (cgl = sdi->channel_groups; cgl; cgl = cgl->next) {
			cg = cgl->data;
			printf("    %s: channel%s", cg->name,
					g_slist_length(cg->channels) > 1 ? "s" : "");
			for (chl = cg->channels; chl; chl = chl->next) {
				ch = chl->data;
				printf(" %s", ch->name);
			}
			printf("\n");
		}
	}

	printf("Supported configuration options");
	if (sdi->channel_groups) {
		if (!channel_group)
			printf(" across all channel groups");
		else
			printf(" on channel group %s", channel_group->name);
	}
	printf(":\n");
	opts = g_variant_get_fixed_array(gvar_opts, &num_opts, sizeof(int32_t));
	for (o = 0; o < num_opts; o++) {
		if (!(srci = sr_config_info_get(opts[o])))
			continue;

		if (srci->key == SR_CONF_TRIGGER_MATCH) {
			if (sr_config_list(sdi->driver, sdi, channel_group, srci->key,
					&gvar_list) != SR_OK) {
				printf("\n");
				continue;
			}
			int32 = g_variant_get_fixed_array(gvar_list,
					&num_elements, sizeof(int32_t));
			printf("    Supported triggers: ");
			for (i = 0; i < num_elements; i++) {
				switch(int32[i]) {
				case SR_TRIGGER_ZERO:
					c = '0';
					break;
				case SR_TRIGGER_ONE:
					c = '1';
					break;
				case SR_TRIGGER_RISING:
					c = 'r';
					break;
				case SR_TRIGGER_FALLING:
					c = 'f';
					break;
				case SR_TRIGGER_EDGE:
					c = 'e';
					break;
				case SR_TRIGGER_OVER:
					c = 'o';
					break;
				case SR_TRIGGER_UNDER:
					c = 'u';
					break;
				default:
					c = 0;
					break;
				}
				if (c)
					printf("%c ", c);
			}
			printf("\n");
			g_variant_unref(gvar_list);

		} else if (srci->key == SR_CONF_LIMIT_SAMPLES) {
			/* If implemented in config_list(), this denotes the
			 * maximum number of samples a device can send. This
			 * really applies only to logic analyzers, and then
			 * only to those that don't support compression, or
			 * have it turned off by default. The values returned
			 * are the low/high limits. */
			if (sr_config_list(sdi->driver, sdi, channel_group, srci->key,
					&gvar) != SR_OK) {
				continue;
			}
			g_variant_get(gvar, "(tt)", &low, &high);
			g_variant_unref(gvar);
			printf("    Maximum number of samples: %"PRIu64"\n", high);

		} else if (srci->key == SR_CONF_SAMPLERATE) {
			/* Supported samplerates */
			printf("    %s", srci->id);
			if (sr_config_list(sdi->driver, sdi, channel_group, SR_CONF_SAMPLERATE,
					&gvar_dict) != SR_OK) {
				printf("\n");
				continue;
			}
			if ((gvar_list = g_variant_lookup_value(gvar_dict,
					"samplerates", G_VARIANT_TYPE("at")))) {
				uint64 = g_variant_get_fixed_array(gvar_list,
						&num_elements, sizeof(uint64_t));
				printf(" - supported samplerates:\n");
				for (i = 0; i < num_elements; i++) {
					if (!(s = sr_samplerate_string(uint64[i])))
						continue;
					printf("      %s\n", s);
					g_free(s);
				}
				g_variant_unref(gvar_list);
			} else if ((gvar_list = g_variant_lookup_value(gvar_dict,
					"samplerate-steps", G_VARIANT_TYPE("at")))) {
				uint64 = g_variant_get_fixed_array(gvar_list,
						&num_elements, sizeof(uint64_t));
				/* low */
				if (!(s = sr_samplerate_string(uint64[0])))
					continue;
				printf(" (%s", s);
				g_free(s);
				/* high */
				if (!(s = sr_samplerate_string(uint64[1])))
					continue;
				printf(" - %s", s);
				g_free(s);
				/* step */
				if (!(s = sr_samplerate_string(uint64[2])))
					continue;
				printf(" in steps of %s)\n", s);
				g_free(s);
				g_variant_unref(gvar_list);
			}
			g_variant_unref(gvar_dict);

		} else if (srci->key == SR_CONF_BUFFERSIZE) {
			/* Supported buffer sizes */
			printf("    %s", srci->id);
			if (sr_config_list(sdi->driver, sdi, channel_group,
					SR_CONF_BUFFERSIZE, &gvar_list) != SR_OK) {
				printf("\n");
				continue;
			}
			uint64 = g_variant_get_fixed_array(gvar_list,
					&num_elements, sizeof(uint64_t));
			printf(" - supported buffer sizes:\n");
			for (i = 0; i < num_elements; i++)
				printf("      %"PRIu64"\n", uint64[i]);
			g_variant_unref(gvar_list);

		} else if (srci->key == SR_CONF_TIMEBASE) {
			/* Supported time bases */
			printf("    %s", srci->id);
			if (sr_config_list(sdi->driver, sdi, channel_group,
					SR_CONF_TIMEBASE, &gvar_list) != SR_OK) {
				printf("\n");
				continue;
			}
			printf(" - supported time bases:\n");
			num_elements = g_variant_n_children(gvar_list);
			for (i = 0; i < num_elements; i++) {
				gvar = g_variant_get_child_value(gvar_list, i);
				g_variant_get(gvar, "(tt)", &p, &q);
				s = sr_period_string(p * q);
				printf("      %s\n", s);
				g_free(s);
			}
			g_variant_unref(gvar_list);

		} else if (srci->key == SR_CONF_VDIV) {
			/* Supported volts/div values */
			printf("    %s", srci->id);
			if (sr_config_list(sdi->driver, sdi, channel_group,
					SR_CONF_VDIV, &gvar_list) != SR_OK) {
				printf("\n");
				continue;
			}
			printf(" - supported volts/div:\n");
			num_elements = g_variant_n_children(gvar_list);
			for (i = 0; i < num_elements; i++) {
				gvar = g_variant_get_child_value(gvar_list, i);
				g_variant_get(gvar, "(tt)", &p, &q);
				s = sr_voltage_string(p, q);
				printf("      %s\n", s);
				g_free(s);
			}
			g_variant_unref(gvar_list);

		} else if (srci->datatype == SR_T_STRING) {
			printf("    %s: ", srci->id);
			if (sr_config_get(sdi->driver, sdi, channel_group, srci->key,
					&gvar) == SR_OK) {
				tmp_str = g_strdup(g_variant_get_string(gvar, NULL));
				g_variant_unref(gvar);
			} else
				tmp_str = NULL;

			if (sr_config_list(sdi->driver, sdi, channel_group, srci->key,
					&gvar) != SR_OK) {
				printf("\n");
				continue;
			}

			stropts = g_variant_get_strv(gvar, &num_elements);
			for (i = 0; i < num_elements; i++) {
				if (i)
					printf(", ");
				printf("%s", stropts[i]);
				if (tmp_str && !strcmp(tmp_str, stropts[i]))
					printf(" (current)");
			}
			printf("\n");
			g_free(stropts);
			g_free(tmp_str);
			g_variant_unref(gvar);

		} else if (srci->datatype == SR_T_UINT64_RANGE) {
			printf("    %s: ", srci->id);
			if (sr_config_list(sdi->driver, sdi, channel_group, srci->key,
					&gvar_list) != SR_OK) {
				printf("\n");
				continue;
			}

			if (sr_config_get(sdi->driver, sdi, NULL, srci->key, &gvar) == SR_OK) {
				g_variant_get(gvar, "(tt)", &cur_low, &cur_high);
				g_variant_unref(gvar);
			} else {
				cur_low = 0;
				cur_high = 0;
			}

			num_elements = g_variant_n_children(gvar_list);
			for (i = 0; i < num_elements; i++) {
				gvar = g_variant_get_child_value(gvar_list, i);
				g_variant_get(gvar, "(tt)", &low, &high);
				g_variant_unref(gvar);
				if (i)
					printf(", ");
				printf("%"PRIu64"-%"PRIu64, low, high);
				if (low == cur_low && high == cur_high)
					printf(" (current)");
			}
			printf("\n");
			g_variant_unref(gvar_list);

		} else if (srci->datatype == SR_T_BOOL) {
			printf("    %s: ", srci->id);
			if (sr_config_get(sdi->driver, sdi, NULL, srci->key,
					&gvar) == SR_OK) {
				if (g_variant_get_boolean(gvar))
					printf("on (current), off\n");
				else
					printf("on, off (current)\n");
				g_variant_unref(gvar);
			} else
				printf("on, off\n");

		} else if (srci->datatype == SR_T_DOUBLE_RANGE) {
			printf("    %s: ", srci->id);
			if (sr_config_list(sdi->driver, sdi, channel_group, srci->key,
					&gvar_list) != SR_OK) {
				printf("\n");
				continue;
			}

			if (sr_config_get(sdi->driver, sdi, NULL, srci->key, &gvar) == SR_OK) {
				g_variant_get(gvar, "(dd)", &dcur_low, &dcur_high);
				g_variant_unref(gvar);
			} else {
				dcur_low = 0;
				dcur_high = 0;
			}

			num_elements = g_variant_n_children(gvar_list);
			for (i = 0; i < num_elements; i++) {
				gvar = g_variant_get_child_value(gvar_list, i);
				g_variant_get(gvar, "(dd)", &dlow, &dhigh);
				g_variant_unref(gvar);
				if (i)
					printf(", ");
				printf("%.1f-%.1f", dlow, dhigh);
				if (dlow == dcur_low && dhigh == dcur_high)
					printf(" (current)");
			}
			printf("\n");
			g_variant_unref(gvar_list);

		} else {

			/* Everything else */
			printf("    %s\n", srci->id);
		}
	}
	g_variant_unref(gvar_opts);

	sr_dev_close(sdi);
	g_slist_free(devices);

}
예제 #15
0
파일: sigrok-cli.c 프로젝트: jeras/sigrok
static void show_dev_detail(void)
{
	struct sr_dev *dev;
	const struct sr_hwcap_option *hwo;
	const struct sr_samplerates *samplerates;
	struct sr_rational *rationals;
	uint64_t *integers;
	const int *hwcaps;
	int cap, i;
	char *s, *title;
	const char *charopts, **stropts;

	dev = parse_devstring(opt_dev);
	if (!dev) {
		printf("No such device. Use -D to list all devices.\n");
		return;
	}

	print_dev_line(dev);

	if (sr_dev_info_get(dev, SR_DI_TRIGGER_TYPES,
					(const void **)&charopts) == SR_OK) {
		printf("Supported triggers: ");
		while (*charopts) {
			printf("%c ", *charopts);
			charopts++;
		}
		printf("\n");
	}

	title = "Supported options:\n";
	hwcaps = dev->driver->hwcap_get_all();
	for (cap = 0; hwcaps[cap]; cap++) {
		if (!(hwo = sr_hw_hwcap_get(hwcaps[cap])))
			continue;

		if (title) {
			printf("%s", title);
			title = NULL;
		}

		if (hwo->hwcap == SR_HWCAP_PATTERN_MODE) {
			/* Pattern generator modes */
			printf("    %s", hwo->shortname);
			if (sr_dev_info_get(dev, SR_DI_PATTERNS,
					(const void **)&stropts) == SR_OK) {
				printf(" - supported patterns:\n");
				for (i = 0; stropts[i]; i++)
					printf("      %s\n", stropts[i]);
			} else {
				printf("\n");
			}

		} else if (hwo->hwcap == SR_HWCAP_SAMPLERATE) {
			/* Supported samplerates */
			printf("    %s", hwo->shortname);
			if (sr_dev_info_get(dev, SR_DI_SAMPLERATES,
					(const void **)&samplerates) != SR_OK) {
				printf("\n");
				continue;
			}
			if (samplerates->step) {
				/* low */
				if (!(s = sr_samplerate_string(samplerates->low)))
					continue;
				printf(" (%s", s);
				g_free(s);
				/* high */
				if (!(s = sr_samplerate_string(samplerates->high)))
					continue;
				printf(" - %s", s);
				g_free(s);
				/* step */
				if (!(s = sr_samplerate_string(samplerates->step)))
					continue;
				printf(" in steps of %s)\n", s);
				g_free(s);
			} else {
				printf(" - supported samplerates:\n");
				for (i = 0; samplerates->list[i]; i++)
					printf("      %s\n", sr_samplerate_string(samplerates->list[i]));
			}

		} else if (hwo->hwcap == SR_HWCAP_BUFFERSIZE) {
			/* Supported buffer sizes */
			printf("    %s", hwo->shortname);
			if (sr_dev_info_get(dev, SR_DI_BUFFERSIZES,
					(const void **)&integers) != SR_OK) {
				printf("\n");
				continue;
			}
			printf(" - supported buffer sizes:\n");
			for (i = 0; integers[i]; i++)
				printf("      %"PRIu64"\n", integers[i]);

		} else if (hwo->hwcap == SR_HWCAP_TIMEBASE) {
			/* Supported time bases */
			printf("    %s", hwo->shortname);
			if (sr_dev_info_get(dev, SR_DI_TIMEBASES,
					(const void **)&rationals) != SR_OK) {
				printf("\n");
				continue;
			}
			printf(" - supported time bases:\n");
			for (i = 0; rationals[i].p && rationals[i].q; i++)
				printf("      %s\n", sr_period_string(
						rationals[i].p * rationals[i].q));

		} else if (hwo->hwcap == SR_HWCAP_TRIGGER_SOURCE) {
			/* Supported trigger sources */
			printf("    %s", hwo->shortname);
			if (sr_dev_info_get(dev, SR_DI_TRIGGER_SOURCES,
					(const void **)&stropts) != SR_OK) {
				printf("\n");
				continue;
			}
			printf(" - supported trigger sources:\n");
			for (i = 0; stropts[i]; i++)
				printf("      %s\n", stropts[i]);

		} else if (hwo->hwcap == SR_HWCAP_FILTER) {
			/* Supported trigger sources */
			printf("    %s", hwo->shortname);
			if (sr_dev_info_get(dev, SR_DI_FILTERS,
					(const void **)&stropts) != SR_OK) {
				printf("\n");
				continue;
			}
			printf(" - supported filter targets:\n");
			for (i = 0; stropts[i]; i++)
				printf("      %s\n", stropts[i]);

		} else if (hwo->hwcap == SR_HWCAP_VDIV) {
			/* Supported volts/div values */
			printf("    %s", hwo->shortname);
			if (sr_dev_info_get(dev, SR_DI_VDIVS,
					(const void **)&rationals) != SR_OK) {
				printf("\n");
				continue;
			}
			printf(" - supported volts/div:\n");
			for (i = 0; rationals[i].p && rationals[i].q; i++)
				printf("      %s\n", sr_voltage_string(	&rationals[i]));

		} else if (hwo->hwcap == SR_HWCAP_COUPLING) {
			/* Supported coupling settings */
			printf("    %s", hwo->shortname);
			if (sr_dev_info_get(dev, SR_DI_COUPLING,
					(const void **)&stropts) != SR_OK) {
				printf("\n");
				continue;
			}
			printf(" - supported coupling options:\n");
			for (i = 0; stropts[i]; i++)
				printf("      %s\n", stropts[i]);

		} else {
			/* Everything else */
			printf("    %s\n", hwo->shortname);
		}
	}
}