From 9fc2b0854fcd442c54af9e5ef2182db430694657 Mon Sep 17 00:00:00 2001 From: Uwe Hermann Date: Wed, 26 Jun 2019 22:29:56 +0200 Subject: [PATCH] [WIP] Add initial OUTPUT_LOGIC support for decoders. --- decode.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 6 ++++ options.c | 4 +++ show.c | 10 +++++++ sigrok-cli.h | 3 ++ 5 files changed, 102 insertions(+) diff --git a/decode.c b/decode.c index 225162a..fc47936 100644 --- a/decode.c +++ b/decode.c @@ -27,6 +27,7 @@ static GHashTable *pd_ann_visible = NULL; static GHashTable *pd_meta_visible = NULL; static GHashTable *pd_binary_visible = NULL; +static GHashTable *pd_logic_visible = NULL; static GHashTable *pd_channel_maps = NULL; extern struct srd_session *srd_sess; @@ -473,6 +474,55 @@ int setup_pd_binary(char *opt_pd_binary) return 0; } +int setup_pd_logic(char *opt_pd_logic) +{ + GSList *l; + struct srd_decoder *dec; + int logic_class; + char **pds, **pdtok, **keyval, **logic_name; + + pd_logic_visible = g_hash_table_new_full(g_str_hash, g_int_equal, + g_free, NULL); + pds = g_strsplit(opt_pd_logic, ",", 0); + for (pdtok = pds; *pdtok && **pdtok; pdtok++) { + keyval = g_strsplit(*pdtok, "=", 0); + if (!(dec = srd_decoder_get_by_id(keyval[0]))) { + g_critical("Protocol decoder '%s' not found.", keyval[0]); + return 1; + } + if (!dec->logic_output_channels) { + g_critical("Protocol decoder '%s' has no logic output channels.", keyval[0]); + return 1; + } + logic_class = 0; + if (g_strv_length(keyval) == 2) { + for (l = dec->logic_output_channels; l; l = l->next, logic_class++) { + logic_name = l->data; + if (!strcmp(logic_name[0], keyval[1])) + /* Found it. */ + break; + } + if (!l) { + g_critical("logic output channel '%s' not found " + "for protocol decoder '%s'.", keyval[1], keyval[0]); + return 1; + } + g_debug("cli: Showing protocol decoder %s logic class " + "%d (%s).", keyval[0], logic_class, logic_name[0]); + } else { + /* No class specified: output all of them. */ + logic_class = -1; + g_debug("cli: Showing all logic classes for protocol " + "decoder %s.", keyval[0]); + } + g_hash_table_insert(pd_logic_visible, g_strdup(keyval[0]), GINT_TO_POINTER(logic_class)); + g_strfreev(keyval); + } + g_strfreev(pds); + + return 0; +} + void show_pd_annotations(struct srd_proto_data *pdata, void *cb_data) { struct srd_decoder *dec; @@ -594,4 +644,33 @@ void show_pd_binary(struct srd_proto_data *pdata, void *cb_data) fwrite(pdb->data, pdb->size, 1, stdout); fflush(stdout); } + +void show_pd_logic(struct srd_proto_data *pdata, void *cb_data) +{ + struct srd_proto_data_logic *pdl; + gpointer classp; + int classi; + size_t i; + uint64_t samplenum; + + (void)cb_data; + + if (!g_hash_table_lookup_extended(pd_logic_visible, + pdata->pdo->di->decoder->id, NULL, (void **)&classp)) + /* Not in the list of PDs whose logic output channels we're showing. */ + return; + + classi = GPOINTER_TO_INT(classp); + pdl = pdata->data; + if (classi != -1 && classi != pdl->logic_class) + /* Not showing this logic class. */ + return; + + samplenum = pdata->start_sample; + + /* TODO */ + for (i = 0; i < pdl->size; i++) + printf("#%" PRIu64 " %d!\n", samplenum++, pdl->data[i]); + fflush(stdout); +} #endif diff --git a/main.c b/main.c index 829492f..af5ab3b 100644 --- a/main.c +++ b/main.c @@ -245,6 +245,12 @@ int main(int argc, char **argv) if (srd_pd_output_callback_add(srd_sess, SRD_OUTPUT_BINARY, show_pd_binary, NULL) != SRD_OK) goto done; + } else if (opt_pd_logic) { + if (setup_pd_logic(opt_pd_logic) != 0) + goto done; + if (srd_pd_output_callback_add(srd_sess, SRD_OUTPUT_LOGIC, + show_pd_logic, NULL) != SRD_OK) + goto done; } else if (opt_pd_meta) { if (setup_pd_meta(opt_pd_meta) != 0) goto done; diff --git a/options.c b/options.c index 5a6f948..6ac42f9 100644 --- a/options.c +++ b/options.c @@ -40,6 +40,7 @@ gchar **opt_pds = NULL; gchar *opt_pd_annotations = NULL; gchar *opt_pd_meta = NULL; gchar *opt_pd_binary = NULL; +gchar *opt_pd_logic = NULL; gboolean opt_pd_samplenum = FALSE; #endif gchar *opt_input_format = NULL; @@ -89,6 +90,7 @@ CHECK_ONCE(opt_triggers) CHECK_ONCE(opt_pd_annotations) CHECK_ONCE(opt_pd_meta) CHECK_ONCE(opt_pd_binary) +CHECK_ONCE(opt_pd_logic) #endif CHECK_ONCE(opt_time) CHECK_ONCE(opt_samples) @@ -140,6 +142,8 @@ static const GOptionEntry optargs[] = { "Protocol decoder meta output to show", NULL}, {"protocol-decoder-binary", 'B', 0, G_OPTION_ARG_CALLBACK, &check_opt_pd_binary, "Protocol decoder binary output to show", NULL}, + {"protocol-decoder-logic", 0, 0, G_OPTION_ARG_CALLBACK, &check_opt_pd_logic, + "Protocol decoder logic output to show", NULL}, {"protocol-decoder-samplenum", 0, 0, G_OPTION_ARG_NONE, &opt_pd_samplenum, "Show sample numbers in decoder output", NULL}, #endif diff --git a/show.c b/show.c index 6086987..0fc223d 100644 --- a/show.c +++ b/show.c @@ -826,6 +826,7 @@ static void show_pd_detail_single(const char *pd) struct srd_decoder_option *o; struct srd_channel *pdch; struct srd_decoder_annotation_row *r; + struct srd_decoder_logic_output_channel *lg; GSList *l, *ll, *ol; int idx; char **pdtokens, **pdtok, *optsep, **ann, **bin, *val, *doc, *str; @@ -904,6 +905,15 @@ static void show_pd_detail_single(const char *pd) } else { printf("None.\n"); } + printf("Logic classes:\n"); + if (dec->logic_output_channels) { + for (l = dec->logic_output_channels; l; l = l->next) { + lg = l->data; + printf("- %s (%s): (%" PRIu64 " Hz)\n", lg->id, lg->desc, lg->samplerate); + } + } else { + printf("None.\n"); + } printf("Required channels:\n"); if (dec->channels) { for (l = dec->channels; l; l = l->next) { diff --git a/sigrok-cli.h b/sigrok-cli.h index 7def741..022752c 100644 --- a/sigrok-cli.h +++ b/sigrok-cli.h @@ -88,9 +88,11 @@ int register_pds(gchar **all_pds, char *opt_pd_annotations); int setup_pd_annotations(char *opt_pd_annotations); int setup_pd_meta(char *opt_pd_meta); int setup_pd_binary(char *opt_pd_binary); +int setup_pd_logic(char *opt_pd_logic); void show_pd_annotations(struct srd_proto_data *pdata, void *cb_data); void show_pd_meta(struct srd_proto_data *pdata, void *cb_data); void show_pd_binary(struct srd_proto_data *pdata, void *cb_data); +void show_pd_logic(struct srd_proto_data *pdata, void *cb_data); void map_pd_channels(struct sr_dev_inst *sdi); #endif @@ -128,6 +130,7 @@ extern gchar **opt_pds; extern gchar *opt_pd_annotations; extern gchar *opt_pd_meta; extern gchar *opt_pd_binary; +extern gchar *opt_pd_logic; extern gboolean opt_pd_samplenum; #endif extern gchar *opt_input_format;