Commit 716c3fff authored by DreamSourceLab's avatar DreamSourceLab
Browse files

Merge branch 'add_dso_export' into develop

Add data export(csv only) support @ DSO mode
parents f64c1617 a4a17a79
...@@ -188,6 +188,8 @@ QList<QString> SigSession::getSuportedExportFormats(){ ...@@ -188,6 +188,8 @@ QList<QString> SigSession::getSuportedExportFormats(){
while(*supportedModules){ while(*supportedModules){
if(*supportedModules == NULL) if(*supportedModules == NULL)
break; break;
if (_dev_inst->dev_inst()->mode == DSO && strcmp((*supportedModules)->id, "csv"))
break;
QString format((*supportedModules)->desc); QString format((*supportedModules)->desc);
format.append(" (*."); format.append(" (*.");
format.append((*supportedModules)->id); format.append((*supportedModules)->id);
...@@ -203,12 +205,27 @@ void SigSession::cancelSaveFile(){ ...@@ -203,12 +205,27 @@ void SigSession::cancelSaveFile(){
} }
void SigSession::export_file(const std::string &name, QWidget* parent, const std::string &ext){ void SigSession::export_file(const std::string &name, QWidget* parent, const std::string &ext){
const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots = boost::shared_ptr<pv::data::Snapshot> snapshot;
_logic_data->get_snapshots(); int channel_type;
if(snapshots.empty())
if (_dev_inst->dev_inst()->mode == LOGIC) {
const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_logic_data->get_snapshots();
if(snapshots.empty())
return;
snapshot = snapshots.front();
channel_type = SR_CHANNEL_LOGIC;
} else if (_dev_inst->dev_inst()->mode == DSO) {
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
_dso_data->get_snapshots();
if(snapshots.empty())
return;
snapshot = snapshots.front();
channel_type = SR_CHANNEL_DSO;
} else {
return; return;
const boost::shared_ptr<pv::data::LogicSnapshot> & snapshot = }
snapshots.front();
const struct sr_output_module** supportedModules = sr_output_list(); const struct sr_output_module** supportedModules = sr_output_list();
const struct sr_output_module* outModule = NULL; const struct sr_output_module* outModule = NULL;
while(*supportedModules){ while(*supportedModules){
...@@ -222,10 +239,23 @@ void SigSession::export_file(const std::string &name, QWidget* parent, const std ...@@ -222,10 +239,23 @@ void SigSession::export_file(const std::string &name, QWidget* parent, const std
} }
if(outModule == NULL) if(outModule == NULL)
return; return;
struct sr_output output;
GHashTable *params = g_hash_table_new(g_str_hash, g_str_equal); GHashTable *params = g_hash_table_new(g_str_hash, g_str_equal);
GVariant* filenameGVariant = g_variant_new_string(name.c_str()); GVariant* filenameGVariant = g_variant_new_string(name.c_str());
g_hash_table_insert(params, (char*)"filename", filenameGVariant); g_hash_table_insert(params, (char*)"filename", filenameGVariant);
GVariant* typeGVariant = g_variant_new_int16(channel_type);
g_hash_table_insert(params, (char*)"type", typeGVariant);
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals) {
boost::shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
GVariant* timebaseGVariant = g_variant_new_uint64(dsoSig->get_hDialValue());
g_hash_table_insert(params, (char*)"timebase", timebaseGVariant);
break;
}
}
struct sr_output output;
output.module = (sr_output_module*) outModule; output.module = (sr_output_module*) outModule;
output.sdi = _dev_inst->dev_inst(); output.sdi = _dev_inst->dev_inst();
output.param = NULL; output.param = NULL;
...@@ -234,33 +264,64 @@ void SigSession::export_file(const std::string &name, QWidget* parent, const std ...@@ -234,33 +264,64 @@ void SigSession::export_file(const std::string &name, QWidget* parent, const std
QFile file(name.c_str()); QFile file(name.c_str());
file.open(QIODevice::WriteOnly | QIODevice::Text); file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file); QTextStream out(&file);
QFuture<void> future = QtConcurrent::run([&]{ QFuture<void> future;
saveFileThreadRunning = true; if (_dev_inst->dev_inst()->mode == LOGIC) {
unsigned char* datat = (unsigned char*)snapshot->get_data(); future = QtConcurrent::run([&]{
unsigned int numsamples = snapshot->get_sample_count()*snapshot->unit_size(); saveFileThreadRunning = true;
GString *data_out; unsigned char* datat = (unsigned char*)snapshot->get_data();
int usize = 8192; unsigned int numsamples = snapshot->get_sample_count()*snapshot->unit_size();
int size = usize; GString *data_out;
struct sr_datafeed_logic lp; int usize = 8192;
struct sr_datafeed_packet p; int size = usize;
for(uint64_t i = 0; i < numsamples; i+=usize){ struct sr_datafeed_logic lp;
if(numsamples - i < usize) struct sr_datafeed_packet p;
size = numsamples - i; for(uint64_t i = 0; i < numsamples; i+=usize){
lp.data = &datat[i]; if(numsamples - i < usize)
lp.length = size; size = numsamples - i;
lp.unitsize = snapshot->unit_size(); lp.data = &datat[i];
p.type = SR_DF_LOGIC; lp.length = size;
p.payload = &lp; lp.unitsize = snapshot->unit_size();
outModule->receive(&output, &p, &data_out); p.type = SR_DF_LOGIC;
if(data_out){ p.payload = &lp;
out << (char*) data_out->str; outModule->receive(&output, &p, &data_out);
g_string_free(data_out,TRUE); if(data_out){
out << (char*) data_out->str;
g_string_free(data_out,TRUE);
}
emit progressSaveFileValueChanged(i*100/numsamples);
if(!saveFileThreadRunning)
break;
} }
emit progressSaveFileValueChanged(i*100/numsamples); });
if(!saveFileThreadRunning) } else if (_dev_inst->dev_inst()->mode == DSO) {
break; future = QtConcurrent::run([&]{
} saveFileThreadRunning = true;
}); unsigned char* datat = (unsigned char*)snapshot->get_data();
unsigned int numsamples = snapshot->get_sample_count();
GString *data_out;
int usize = 8192;
int size = usize;
struct sr_datafeed_dso dp;
struct sr_datafeed_packet p;
for(uint64_t i = 0; i < numsamples; i+=usize){
if(numsamples - i < usize)
size = numsamples - i;
dp.data = &datat[i*snapshot->get_channel_num()];
dp.num_samples = size;
p.type = SR_DF_DSO;
p.payload = &dp;
outModule->receive(&output, &p, &data_out);
if(data_out){
out << (char*) data_out->str;
g_string_free(data_out,TRUE);
}
emit progressSaveFileValueChanged(i*100/numsamples);
if(!saveFileThreadRunning)
break;
}
});
}
QFutureWatcher<void> watcher; QFutureWatcher<void> watcher;
Qt::WindowFlags flags = Qt::CustomizeWindowHint; Qt::WindowFlags flags = Qt::CustomizeWindowHint;
QProgressDialog dlg(QString::fromUtf8("Exporting data... It can take a while."), QProgressDialog dlg(QString::fromUtf8("Exporting data... It can take a while."),
......
...@@ -127,14 +127,7 @@ void FileBar::on_actionExport_triggered(){ ...@@ -127,14 +127,7 @@ void FileBar::on_actionExport_triggered(){
msg.setStandardButtons(QMessageBox::Ok); msg.setStandardButtons(QMessageBox::Ok);
msg.setIcon(QMessageBox::Warning); msg.setIcon(QMessageBox::Warning);
msg.exec(); msg.exec();
} else if (_session.get_device()->dev_inst()->mode != LOGIC) { } else {
QMessageBox msg(this);
msg.setText("Export Data");
msg.setInformativeText("DSLogic currently only support exporting logic data to file!");
msg.setStandardButtons(QMessageBox::Ok);
msg.setIcon(QMessageBox::Warning);
msg.exec();
}else {
QList<QString> supportedFormats = _session.getSuportedExportFormats(); QList<QString> supportedFormats = _session.getSuportedExportFormats();
QString filter; QString filter;
for(int i = 0; i < supportedFormats.count();i++){ for(int i = 0; i < supportedFormats.count();i++){
......
...@@ -503,6 +503,8 @@ void Viewport::set_receive_len(quint64 length) ...@@ -503,6 +503,8 @@ void Viewport::set_receive_len(quint64 length)
void Viewport::measure() void Viewport::measure()
{ {
if (_view.session().get_capture_state() == SigSession::Running)
return;
const uint64_t sample_rate = _view.session().get_device()->get_sample_rate(); const uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals()); const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) { BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
......
...@@ -601,6 +601,7 @@ static int set_probes(struct sr_dev_inst *sdi, int num_probes) ...@@ -601,6 +601,7 @@ static int set_probes(struct sr_dev_inst *sdi, int num_probes)
return SR_ERR; return SR_ERR;
if (sdi->mode == DSO) { if (sdi->mode == DSO) {
probe->vdiv = 1000; probe->vdiv = 1000;
probe->vfactor = 1;
probe->vpos = 0; probe->vpos = 0;
probe->coupling = SR_DC_COUPLING; probe->coupling = SR_DC_COUPLING;
probe->trig_value = 0x80; probe->trig_value = 0x80;
......
...@@ -642,6 +642,7 @@ static int set_probes(struct sr_dev_inst *sdi, int num_probes) ...@@ -642,6 +642,7 @@ static int set_probes(struct sr_dev_inst *sdi, int num_probes)
return SR_ERR; return SR_ERR;
if (sdi->mode == DSO) { if (sdi->mode == DSO) {
probe->vdiv = 1000; probe->vdiv = 1000;
probe->vfactor = 1;
probe->coupling = SR_DC_COUPLING; probe->coupling = SR_DC_COUPLING;
probe->trig_value = 0x80; probe->trig_value = 0x80;
} }
......
...@@ -323,7 +323,7 @@ struct sr_datafeed_dso { ...@@ -323,7 +323,7 @@ struct sr_datafeed_dso {
uint64_t mqflags; uint64_t mqflags;
/** The analog value(s). The data is interleaved according to /** The analog value(s). The data is interleaved according to
* the probes list. */ * the probes list. */
float *data; void *data;
}; };
struct sr_datafeed_analog { struct sr_datafeed_analog {
...@@ -559,6 +559,7 @@ struct sr_channel { ...@@ -559,6 +559,7 @@ struct sr_channel {
char *name; char *name;
char *trigger; char *trigger;
uint64_t vdiv; uint64_t vdiv;
uint16_t vfactor;
double vpos; double vpos;
uint8_t coupling; uint8_t coupling;
uint8_t trig_value; uint8_t trig_value;
......
...@@ -33,9 +33,13 @@ struct context { ...@@ -33,9 +33,13 @@ struct context {
char separator; char separator;
gboolean header_done; gboolean header_done;
int *channel_index; int *channel_index;
float *channel_vdiv;
double *channel_vpos;
uint64_t timebase;
uint64_t mask; uint64_t mask;
uint64_t pre_data; uint64_t pre_data;
uint64_t index; uint64_t index;
int type;
}; };
/* /*
...@@ -57,8 +61,6 @@ static int init(struct sr_output *o, GHashTable *options) ...@@ -57,8 +61,6 @@ static int init(struct sr_output *o, GHashTable *options)
GSList *l; GSList *l;
int i; int i;
(void)options;
if (!o || !o->sdi) if (!o || !o->sdi)
return SR_ERR_ARG; return SR_ERR_ARG;
...@@ -67,27 +69,34 @@ static int init(struct sr_output *o, GHashTable *options) ...@@ -67,27 +69,34 @@ static int init(struct sr_output *o, GHashTable *options)
ctx->separator = ','; ctx->separator = ',';
ctx->mask = 0; ctx->mask = 0;
ctx->index = 0; ctx->index = 0;
ctx->type = g_variant_get_int16(g_hash_table_lookup(options, "type"));
ctx->timebase = g_variant_get_uint64(g_hash_table_lookup(options, "timebase"));
/* Get the number of channels, and the unitsize. */ /* Get the number of channels, and the unitsize. */
for (l = o->sdi->channels; l; l = l->next) { for (l = o->sdi->channels; l; l = l->next) {
ch = l->data; ch = l->data;
if (ch->type != SR_CHANNEL_LOGIC) if (ch->type != ctx->type)
continue; continue;
if (!ch->enabled) if (!ch->enabled)
continue; continue;
ctx->num_enabled_channels++; ctx->num_enabled_channels++;
} }
ctx->channel_index = g_malloc(sizeof(int) * ctx->num_enabled_channels); ctx->channel_index = g_malloc(sizeof(int) * ctx->num_enabled_channels);
ctx->channel_vdiv = g_malloc(sizeof(float) * ctx->num_enabled_channels);
ctx->channel_vpos = g_malloc(sizeof(double) * ctx->num_enabled_channels);
/* Once more to map the enabled channels. */ /* Once more to map the enabled channels. */
for (i = 0, l = o->sdi->channels; l; l = l->next) { for (i = 0, l = o->sdi->channels; l; l = l->next) {
ch = l->data; ch = l->data;
if (ch->type != SR_CHANNEL_LOGIC) if (ch->type != ctx->type)
continue; continue;
if (!ch->enabled) if (!ch->enabled)
continue; continue;
ctx->channel_index[i++] = ch->index; ctx->channel_index[i] = ch->index;
ctx->mask |= (1 << ch->index); ctx->mask |= (1 << ch->index);
ctx->channel_vdiv[i] = ch->vdiv * ch->vfactor >= 500 ? ch->vdiv * ch->vfactor / 100.0f : ch->vdiv * ch->vfactor * 10.0f;
ctx->channel_vpos[i] = ch->vdiv * ch->vfactor >= 500 ? ch->vpos / 1000 : ch->vpos;
i++;
} }
return SR_OK; return SR_OK;
...@@ -102,7 +111,6 @@ static GString *gen_header(const struct sr_output *o) ...@@ -102,7 +111,6 @@ static GString *gen_header(const struct sr_output *o)
GSList *l; GSList *l;
time_t t; time_t t;
int num_channels, i; int num_channels, i;
char *samplerate_s;
ctx = o->priv; ctx = o->priv;
header = g_string_sized_new(512); header = g_string_sized_new(512);
...@@ -113,7 +121,10 @@ static GString *gen_header(const struct sr_output *o) ...@@ -113,7 +121,10 @@ static GString *gen_header(const struct sr_output *o)
PACKAGE_STRING, ctime(&t)); PACKAGE_STRING, ctime(&t));
/* Columns / channels */ /* Columns / channels */
num_channels = g_slist_length(o->sdi->channels); if (ctx->type == SR_CHANNEL_LOGIC)
num_channels = g_slist_length(o->sdi->channels);
else
num_channels = ctx->num_enabled_channels;
g_string_append_printf(header, "; Channels (%d/%d)\n", g_string_append_printf(header, "; Channels (%d/%d)\n",
ctx->num_enabled_channels, num_channels); ctx->num_enabled_channels, num_channels);
...@@ -125,19 +136,34 @@ static GString *gen_header(const struct sr_output *o) ...@@ -125,19 +136,34 @@ static GString *gen_header(const struct sr_output *o)
} }
} }
if (ctx->samplerate != 0) { if (ctx->samplerate != 0) {
samplerate_s = sr_samplerate_string(ctx->samplerate); char *samplerate_s = sr_samplerate_string(ctx->samplerate);
g_string_append_printf(header, "; Samplerate: %s\n", samplerate_s); g_string_append_printf(header, "; Sample rate: %s\n", samplerate_s);
g_free(samplerate_s); g_free(samplerate_s);
} }
g_string_append_printf(header, "Time(s),"); if (sr_config_get(o->sdi->driver, o->sdi, NULL, NULL, SR_CONF_LIMIT_SAMPLES,
&gvar) == SR_OK) {
uint64_t depth = g_variant_get_uint64(gvar);
g_variant_unref(gvar);
char *depth_s = sr_samplecount_string(depth);
g_string_append_printf(header, "; Sample count: %s\n", depth_s);
g_free(depth_s);
}
if (ctx->type == SR_CHANNEL_LOGIC)
g_string_append_printf(header, "Time(s),");
for (i = 0, l = o->sdi->channels; l; l = l->next, i++) { for (i = 0, l = o->sdi->channels; l; l = l->next, i++) {
ch = l->data; ch = l->data;
if (ch->type != SR_CHANNEL_LOGIC) if (ch->type != ctx->type)
continue; continue;
if (!ch->enabled) if (!ch->enabled)
continue; continue;
g_string_append_printf(header, " %s,", ch->name); if (ctx->type == SR_CHANNEL_DSO) {
char *unit_s = (ch->vdiv * ch->vfactor) >= 500 ? "V" : "mV";
g_string_append_printf(header, " %s (Unit: %s),", ch->name, unit_s);
} else {
g_string_append_printf(header, " %s,", ch->name);
}
} }
if (o->sdi->channels) if (o->sdi->channels)
/* Drop last separator. */ /* Drop last separator. */
...@@ -152,12 +178,13 @@ static int receive(const struct sr_output *o, const struct sr_datafeed_packet *p ...@@ -152,12 +178,13 @@ static int receive(const struct sr_output *o, const struct sr_datafeed_packet *p
{ {
const struct sr_datafeed_meta *meta; const struct sr_datafeed_meta *meta;
const struct sr_datafeed_logic *logic; const struct sr_datafeed_logic *logic;
const struct sr_datafeed_dso *dso;
const struct sr_config *src; const struct sr_config *src;
GSList *l; GSList *l;
struct context *ctx; struct context *ctx;
int idx; int idx;
uint64_t i, j; uint64_t i, j;
gchar *p, c; unsigned char *p, c;
*out = NULL; *out = NULL;
if (!o || !o->sdi) if (!o || !o->sdi)
...@@ -200,6 +227,28 @@ static int receive(const struct sr_output *o, const struct sr_datafeed_packet *p ...@@ -200,6 +227,28 @@ static int receive(const struct sr_output *o, const struct sr_datafeed_packet *p
ctx->pre_data = (*(uint64_t *)(logic->data + i) & ctx->mask); ctx->pre_data = (*(uint64_t *)(logic->data + i) & ctx->mask);
} }
break; break;
case SR_DF_DSO:
dso = packet->payload;
if (!ctx->header_done) {
*out = gen_header(o);
ctx->header_done = TRUE;
} else {
*out = g_string_sized_new(512);
}
for (i = 0; i < dso->num_samples; i++) {
for (j = 0; j < ctx->num_enabled_channels; j++) {
idx = ctx->channel_index[j];
p = dso->data + i * ctx->num_enabled_channels + idx * ((ctx->num_enabled_channels > 1) ? 1 : 0);
g_string_append_printf(*out, "%0.2f", (128 - *p) * ctx->channel_vdiv[j] / 255 - ctx->channel_vpos[j]);
g_string_append_c(*out, ctx->separator);
}
/* Drop last separator. */
g_string_truncate(*out, (*out)->len - 1);
g_string_append_printf(*out, "\n");
}
break;
} }
return SR_OK; return SR_OK;
......
...@@ -141,6 +141,7 @@ SR_API char *sr_iec_string_u64(uint64_t x, const char *unit); ...@@ -141,6 +141,7 @@ SR_API char *sr_iec_string_u64(uint64_t x, const char *unit);
SR_API char *sr_samplerate_string(uint64_t samplerate); SR_API char *sr_samplerate_string(uint64_t samplerate);
SR_API char *sr_samplecount_string(uint64_t samplecount); SR_API char *sr_samplecount_string(uint64_t samplecount);
SR_API char *sr_period_string(uint64_t frequency); SR_API char *sr_period_string(uint64_t frequency);
SR_API char *sr_time_string(uint64_t time);
SR_API char *sr_voltage_string(uint64_t v_p, uint64_t v_q); SR_API char *sr_voltage_string(uint64_t v_p, uint64_t v_q);
SR_API char **sr_parse_triggerstring(const struct sr_dev_inst *sdi, SR_API char **sr_parse_triggerstring(const struct sr_dev_inst *sdi,
const char *triggerstring); const char *triggerstring);
......
...@@ -211,6 +211,47 @@ SR_API char *sr_period_string(uint64_t frequency) ...@@ -211,6 +211,47 @@ SR_API char *sr_period_string(uint64_t frequency)
return o; return o;
} }
/**
* Convert a numeric time(ns) value to the "natural" string representation
* of its period.
*
* E.g. a value of 3000000 would be converted to "3 ms", 20000 to "20 us".
*
* @param time The time in ns.
*
* @return A g_try_malloc()ed string representation of the time value,
* or NULL upon errors. The caller is responsible to g_free() the
* memory.
*/
SR_API char *sr_time_string(uint64_t time)
{
char *o;
int r;
/* Allocate enough for a uint64_t as string + " ms". */
if (!(o = g_try_malloc0(30 + 1))) {
sr_err("%s: o malloc failed", __func__);
return NULL;
}
if (time >= 1000000000)
r = snprintf(o, 30, "%" PRIu64 " s", time / 1000000000);
else if (time >= 1000000)
r = snprintf(o, 30, "%" PRIu64 " ms", time / 1000000);
else if (time >= 1000)
r = snprintf(o, 30, "%" PRIu64 " us", time / 1000);
else
r = snprintf(o, 30, "%" PRIu64 " ns", time);
if (r < 0) {
/* Something went wrong... */
g_free(o);
return NULL;
}
return o;
}
/** /**
* Convert a numeric voltage value to the "natural" string representation * Convert a numeric voltage value to the "natural" string representation
* of its voltage value. The voltage is specified as a rational number's * of its voltage value. The voltage is specified as a rational number's
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment