void DecoderStack::decode_data( const int64_t sample_count, const unsigned int unit_size, srd_session *const session) { uint8_t chunk[DecodeChunkLength]; const unsigned int chunk_sample_count = DecodeChunkLength / segment_->unit_size(); for (int64_t i = 0; !interrupt_ && i < sample_count; i += chunk_sample_count) { lock_guard<mutex> decode_lock(global_decode_mutex_); const int64_t chunk_end = min( i + chunk_sample_count, sample_count); segment_->get_samples(chunk, i, chunk_end); if (srd_session_send(session, i, chunk_end, chunk, (chunk_end - i) * unit_size, unit_size) != SRD_OK) { error_message_ = tr("Decoder reported an error"); break; } { lock_guard<mutex> lock(output_mutex_); samples_decoded_ = chunk_end; } if (i % DecodeNotifyPeriod == 0) new_decode_data(); } new_decode_data(); }
void MainWindow::on_actionQUICK_HACK_PD_TEST_triggered() { #define N 500000 struct srd_decoder_inst *di; GHashTable *pd_opthash; uint8_t *buf = (uint8_t *)malloc(N + 1); pd_opthash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); /* Hardcode a specific I2C probe mapping. */ g_hash_table_insert(pd_opthash, g_strdup("scl"), g_strdup("5")); g_hash_table_insert(pd_opthash, g_strdup("sda"), g_strdup("7")); /* * Get data from a hardcoded binary file. * (converted to binary from melexis_mlx90614_5s_24deg.sr. */ QFile file("foo.bin"); int ret = file.open(QIODevice::ReadOnly); ret = file.read((char *)buf, N); // sr_log_loglevel_set(SR_LOG_NONE); // srd_log_loglevel_set(SRD_LOG_NONE); if (!(di = srd_inst_new("i2c", pd_opthash))) { ui->plainTextEdit->appendPlainText("ERROR: srd_inst_new"); return; } if (srd_inst_probe_set_all(di, pd_opthash) != SRD_OK) { ui->plainTextEdit->appendPlainText("ERROR: srd_inst_set_probes"); return; } if (srd_pd_output_callback_add(SRD_OUTPUT_ANN, (srd_pd_output_callback_t)show_pd_annotation, (void *)this) != SRD_OK) { ui->plainTextEdit->appendPlainText("ERROR: srd_pd_output_callback_add"); return; } if (srd_session_start(8, 1, 1000000) != SRD_OK) { ui->plainTextEdit->appendPlainText("ERROR: srd_session_start"); return; } if (srd_session_send(0, buf, N) != SRD_OK) { ui->plainTextEdit->appendPlainText("ERROR: srd_session_send"); return; } }
void datafeed_in(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *packet, void *cb_data) { const struct sr_datafeed_meta *meta; const struct sr_datafeed_logic *logic; const struct sr_datafeed_analog *analog; struct sr_config *src; struct sr_channel *ch; static struct sr_output *o = NULL; static uint64_t rcvd_samples_logic = 0; static uint64_t rcvd_samples_analog = 0; static uint64_t samplerate = 0; static int triggered = 0; static FILE *outfile = NULL; GSList *l; GString *out; GVariant *gvar; uint64_t end_sample; uint64_t input_len; int i; char **channels; (void) cb_data; /* If the first packet to come in isn't a header, don't even try. */ if (packet->type != SR_DF_HEADER && o == NULL) return; switch (packet->type) { case SR_DF_HEADER: g_debug("cli: Received SR_DF_HEADER."); o = setup_output_format(sdi); /* Prepare non-stdout output. */ outfile = stdout; if (opt_output_file) { if (default_output_format) { outfile = NULL; } else { /* saving to a file in whatever format was set * with --format, so all we need is a filehandle */ outfile = g_fopen(opt_output_file, "wb"); } } rcvd_samples_logic = rcvd_samples_analog = 0; if (sr_config_get(sdi->driver, sdi, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { samplerate = g_variant_get_uint64(gvar); g_variant_unref(gvar); } #ifdef HAVE_SRD if (opt_pds) { if (samplerate) { if (srd_session_metadata_set(srd_sess, SRD_CONF_SAMPLERATE, g_variant_new_uint64(samplerate)) != SRD_OK) { g_critical("Failed to configure decode session."); break; } } if (srd_session_start(srd_sess) != SRD_OK) { g_critical("Failed to start decode session."); break; } } #endif break; case SR_DF_META: g_debug("cli: Received SR_DF_META."); meta = packet->payload; for (l = meta->config; l; l = l->next) { src = l->data; switch (src->key) { case SR_CONF_SAMPLERATE: samplerate = g_variant_get_uint64(src->data); g_debug("cli: Got samplerate %"PRIu64" Hz.", samplerate); #ifdef HAVE_SRD if (opt_pds) { if (srd_session_metadata_set(srd_sess, SRD_CONF_SAMPLERATE, g_variant_new_uint64(samplerate)) != SRD_OK) { g_critical("Failed to pass samplerate to decoder."); } } #endif break; case SR_CONF_SAMPLE_INTERVAL: samplerate = g_variant_get_uint64(src->data); g_debug("cli: Got sample interval %"PRIu64" ms.", samplerate); break; default: /* Unknown metadata is not an error. */ break; } } break; case SR_DF_TRIGGER: g_debug("cli: Received SR_DF_TRIGGER."); triggered = 1; break; case SR_DF_LOGIC: logic = packet->payload; g_message("cli: Received SR_DF_LOGIC (%"PRIu64" bytes, unitsize = %d).", logic->length, logic->unitsize); if (logic->length == 0) break; /* Don't store any samples until triggered. */ if (opt_wait_trigger && !triggered) break; if (limit_samples && rcvd_samples_logic >= limit_samples) break; end_sample = rcvd_samples_logic + logic->length / logic->unitsize; /* Cut off last packet according to the sample limit. */ if (limit_samples && end_sample > limit_samples) end_sample = limit_samples; input_len = (end_sample - rcvd_samples_logic) * logic->unitsize; if (opt_output_file && default_output_format) { /* Saving to a session file. */ if (rcvd_samples_logic == 0) { /* First packet with logic data, init session file. */ channels = g_malloc(sizeof(char *) * g_slist_length(sdi->channels)); for (i = 0, l = sdi->channels; l; l = l->next) { ch = l->data; if (ch->enabled && ch->type == SR_CHANNEL_LOGIC) channels[i++] = ch->name; } channels[i] = NULL; sr_session_save_init(opt_output_file, samplerate, channels); g_free(channels); } save_chunk_logic(logic->data, input_len, logic->unitsize); } else { if (opt_pds) { #ifdef HAVE_SRD if (srd_session_send(srd_sess, rcvd_samples_logic, end_sample, logic->data, input_len) != SRD_OK) sr_session_stop(); #endif } } rcvd_samples_logic = end_sample; break; case SR_DF_ANALOG: analog = packet->payload; g_message("cli: Received SR_DF_ANALOG (%d samples).", analog->num_samples); if (analog->num_samples == 0) break; if (limit_samples && rcvd_samples_analog >= limit_samples) break; rcvd_samples_analog += analog->num_samples; break; case SR_DF_FRAME_BEGIN: g_debug("cli: Received SR_DF_FRAME_BEGIN."); break; case SR_DF_FRAME_END: g_debug("cli: Received SR_DF_FRAME_END."); break; default: break; } if (o && outfile && !opt_pds) { if (sr_output_send(o, packet, &out) == SR_OK && out) { fwrite(out->str, 1, out->len, outfile); fflush(outfile); g_string_free(out, TRUE); } } /* SR_DF_END needs to be handled after the output module's receive() * is called, so it can properly clean up that module. */ if (packet->type == SR_DF_END) { g_debug("cli: Received SR_DF_END."); if (o) sr_output_free(o); o = NULL; if (outfile && outfile != stdout) fclose(outfile); if (opt_output_file && default_output_format) /* Flush whatever is left out to the session file. */ save_chunk_logic(NULL, 0, 0); if (limit_samples) { if (rcvd_samples_logic > 0 && rcvd_samples_logic < limit_samples) g_warning("Device only sent %" PRIu64 " samples.", rcvd_samples_logic); else if (rcvd_samples_analog > 0 && rcvd_samples_analog < limit_samples) g_warning("Device only sent %" PRIu64 " samples.", rcvd_samples_analog); } } }
static void datafeed_in(struct sr_dev *dev, struct sr_datafeed_packet *packet) { static struct sr_output *o = NULL; static int logic_probelist[SR_MAX_NUM_PROBES] = { 0 }; static struct sr_probe *analog_probelist[SR_MAX_NUM_PROBES]; static uint64_t received_samples = 0; static int unitsize = 0; static int triggered = 0; static FILE *outfile = NULL; static int num_analog_probes = 0; struct sr_probe *probe; struct sr_datafeed_logic *logic; struct sr_datafeed_meta_logic *meta_logic; struct sr_datafeed_analog *analog; struct sr_datafeed_meta_analog *meta_analog; static int num_enabled_analog_probes = 0; int num_enabled_probes, sample_size, ret, i; uint64_t output_len, filter_out_len; uint8_t *output_buf, *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; sample_size = -1; switch (packet->type) { case SR_DF_HEADER: g_debug("cli: Received SR_DF_HEADER"); /* Initialize the output module. */ if (!(o = g_try_malloc(sizeof(struct sr_output)))) { g_critical("Output module malloc failed."); exit(1); } o->format = output_format; o->dev = dev; o->param = output_format_param; if (o->format->init) { if (o->format->init(o) != SR_OK) { g_critical("Output format initialization failed."); exit(1); } } break; case SR_DF_END: g_debug("cli: Received SR_DF_END"); if (!o) { g_debug("cli: double end!"); break; } if (o->format->event) { o->format->event(o, SR_DF_END, &output_buf, &output_len); if (output_buf) { if (outfile) fwrite(output_buf, 1, output_len, outfile); g_free(output_buf); output_len = 0; } } if (limit_samples && received_samples < limit_samples) g_warning("Device only sent %" PRIu64 " samples.", received_samples); if (opt_continuous) g_warning("Device stopped after %" PRIu64 " samples.", received_samples); sr_session_stop(); if (outfile && outfile != stdout) fclose(outfile); g_free(o); o = NULL; break; case SR_DF_TRIGGER: g_debug("cli: received SR_DF_TRIGGER"); if (o->format->event) o->format->event(o, SR_DF_TRIGGER, &output_buf, &output_len); triggered = 1; break; case SR_DF_META_LOGIC: g_message("cli: Received SR_DF_META_LOGIC"); meta_logic = packet->payload; num_enabled_probes = 0; for (i = 0; i < meta_logic->num_probes; i++) { probe = g_slist_nth_data(dev->probes, i); if (probe->enabled) logic_probelist[num_enabled_probes++] = probe->index; } /* How many bytes we need to store num_enabled_probes bits */ unitsize = (num_enabled_probes + 7) / 8; outfile = stdout; if (opt_output_file) { if (default_output_format) { /* output file is in session format, which means we'll * dump everything in the datastore as it comes in, * and save from there after the session. */ outfile = NULL; ret = sr_datastore_new(unitsize, &(dev->datastore)); if (ret != SR_OK) { printf("Failed to create datastore.\n"); exit(1); } } else { /* saving to a file in whatever format was set * with --format, so all we need is a filehandle */ outfile = g_fopen(opt_output_file, "wb"); } } if (opt_pds) srd_session_start(num_enabled_probes, unitsize, meta_logic->samplerate); break; case SR_DF_LOGIC: logic = packet->payload; g_message("cli: received SR_DF_LOGIC, %"PRIu64" bytes", logic->length); sample_size = logic->unitsize; if (logic->length == 0) break; /* Don't store any samples until triggered. */ if (opt_wait_trigger && !triggered) break; if (limit_samples && received_samples >= limit_samples) break; ret = sr_filter_probes(sample_size, unitsize, logic_probelist, logic->data, logic->length, &filter_out, &filter_out_len); if (ret != SR_OK) break; /* what comes out of the filter is guaranteed to be packed into the * minimum size needed to support the number of samples at this sample * size. however, the driver may have submitted too much -- cut off * the buffer of the last packet according to the sample limit. */ if (limit_samples && (received_samples + logic->length / sample_size > limit_samples * sample_size)) filter_out_len = limit_samples * sample_size - received_samples; if (dev->datastore) sr_datastore_put(dev->datastore, filter_out, filter_out_len, sample_size, logic_probelist); if (opt_output_file && default_output_format) /* saving to a session file, don't need to do anything else * to this data for now. */ goto cleanup; if (opt_pds) { if (srd_session_send(received_samples, (uint8_t*)filter_out, filter_out_len) != SRD_OK) sr_session_stop(); } else { output_len = 0; if (o->format->data && packet->type == o->format->df_type) o->format->data(o, filter_out, filter_out_len, &output_buf, &output_len); if (output_buf) { fwrite(output_buf, 1, output_len, outfile); fflush(outfile); g_free(output_buf); } } cleanup: g_free(filter_out); received_samples += logic->length / sample_size; break; case SR_DF_META_ANALOG: g_message("cli: Received SR_DF_META_ANALOG"); meta_analog = packet->payload; num_analog_probes = meta_analog->num_probes; num_enabled_analog_probes = 0; for (i = 0; i < num_analog_probes; i++) { probe = g_slist_nth_data(dev->probes, i); if (probe->enabled) analog_probelist[num_enabled_analog_probes++] = probe; } outfile = stdout; if (opt_output_file) { if (default_output_format) { /* output file is in session format, which means we'll * dump everything in the datastore as it comes in, * and save from there after the session. */ outfile = NULL; ret = sr_datastore_new(unitsize, &(dev->datastore)); if (ret != SR_OK) { printf("Failed to create datastore.\n"); exit(1); } } else { /* saving to a file in whatever format was set * with --format, so all we need is a filehandle */ outfile = g_fopen(opt_output_file, "wb"); } } break; case SR_DF_ANALOG: analog = packet->payload; g_message("cli: received SR_DF_ANALOG, %d samples", analog->num_samples); if (analog->num_samples == 0) break; if (limit_samples && received_samples >= limit_samples) break; if (o->format->data && packet->type == o->format->df_type) { o->format->data(o, (const uint8_t *)analog->data, analog->num_samples * sizeof(float), &output_buf, &output_len); if (output_buf) { fwrite(output_buf, 1, output_len, outfile); fflush(outfile); g_free(output_buf); } } received_samples += analog->num_samples; break; case SR_DF_FRAME_BEGIN: g_debug("cli: received SR_DF_FRAME_BEGIN"); if (o->format->event) { o->format->event(o, SR_DF_FRAME_BEGIN, &output_buf, &output_len); if (output_buf) { fwrite(output_buf, 1, output_len, outfile); fflush(outfile); g_free(output_buf); } } break; case SR_DF_FRAME_END: g_debug("cli: received SR_DF_FRAME_END"); if (o->format->event) { o->format->event(o, SR_DF_FRAME_END, &output_buf, &output_len); if (output_buf) { fwrite(output_buf, 1, output_len, outfile); fflush(outfile); g_free(output_buf); } } break; default: g_message("received unknown packet type %d", packet->type); } }