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; }
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; }
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); }
/** * 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); }
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; }
/** * 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; }
/** * 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; }
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; }
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; } }
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); }
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; }
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; }
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); }
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); }
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); } } }