X-Git-Url: https://sigrok.org/gitweb/?p=sigrok-cli.git;a=blobdiff_plain;f=sigrok-cli.c;h=1b967814508ed76d906a9474faecd75e84df9ae1;hp=bcdeb3e9fb7151771f6376383b1329eb0b89116c;hb=19c3e1f40ab6e86017bf9771006a1711b4c496ff;hpb=37d5ccc11cb29dd65c9a550eb5c5dea55006bc74 diff --git a/sigrok-cli.c b/sigrok-cli.c index bcdeb3e..1b96781 100644 --- a/sigrok-cli.c +++ b/sigrok-cli.c @@ -36,15 +36,13 @@ #define DEFAULT_OUTPUT_FORMAT "bits:width=64" -extern struct sr_hwcap_option sr_drvopts[]; -extern struct sr_hwcap_option sr_hwcap_options[]; - static uint64_t limit_samples = 0; static uint64_t limit_frames = 0; static struct sr_output_format *output_format = NULL; static int default_output_format = FALSE; static char *output_format_param = NULL; static GHashTable *pd_ann_visible = NULL; +static struct sr_datastore *singleds = NULL; static gboolean opt_version = FALSE; static gint opt_loglevel = SR_LOG_WARN; /* Show errors+warnings per default. */ @@ -115,7 +113,7 @@ static GOptionEntry optargs[] = { /* Convert driver options hash to GSList of struct sr_hwopt. */ static GSList *hash_to_hwopt(GHashTable *hash) { - struct sr_hwcap_option *ho; + const struct sr_hwcap_option *hwo; struct sr_hwopt *hwopt; GList *gl, *keys; GSList *opts; @@ -125,20 +123,15 @@ static GSList *hash_to_hwopt(GHashTable *hash) opts = NULL; for (gl = keys; gl; gl = gl->next) { key = gl->data; - for (ho = sr_drvopts; ho->shortname; ho++) { - if (!strcmp(key, ho->shortname)) { - hwopt = g_try_malloc(sizeof(struct sr_hwopt)); - hwopt->hwopt = ho->hwcap; - value = g_hash_table_lookup(hash, key); - hwopt->value = g_strdup(value); - opts = g_slist_append(opts, hwopt); - break; - } - } - if (!ho->shortname) { + if (!(hwo = sr_drvopt_name_get(key))) { g_critical("Unknown option %s", key); return NULL; } + hwopt = g_try_malloc(sizeof(struct sr_hwopt)); + hwopt->hwopt = hwo->hwcap; + value = g_hash_table_lookup(hash, key); + hwopt->value = g_strdup(value); + opts = g_slist_append(opts, hwopt); } g_list_free(keys); @@ -345,7 +338,7 @@ static void show_dev_detail(void) return; for (cap = 0; hwcaps[cap]; cap++) { - if (!(hwo = sr_hw_hwcap_get(hwcaps[cap]))) + if (!(hwo = sr_devopt_get(hwcaps[cap]))) continue; if (title) { @@ -486,7 +479,7 @@ static void show_pd_detail(void) pdtokens = g_strsplit(opt_pds, ",", -1); for (pdtok = pdtokens; *pdtok; pdtok++) { if (!(dec = srd_decoder_get_by_id(*pdtok))) { - printf("Protocol decoder %s not found.\n", *pdtok); + g_critical("Protocol decoder %s not found.", *pdtok); return; } printf("ID: %s\nName: %s\nLong name: %s\nDescription: %s\n", @@ -536,7 +529,7 @@ static void datafeed_in(const struct sr_dev_inst *sdi, struct sr_datafeed_packet *packet) { static struct sr_output *o = NULL; - static int logic_probelist[SR_MAX_NUM_PROBES] = { 0 }; + static int logic_probelist[SR_MAX_NUM_PROBES] = { -1 }; static struct sr_probe *analog_probelist[SR_MAX_NUM_PROBES]; static uint64_t received_samples = 0; static int unitsize = 0; @@ -598,7 +591,6 @@ static void datafeed_in(const struct sr_dev_inst *sdi, if (opt_continuous) g_warning("Device stopped after %" PRIu64 " samples.", received_samples); - sr_session_stop(); if (outfile && outfile != stdout) fclose(outfile); g_free(o); @@ -622,6 +614,7 @@ static void datafeed_in(const struct sr_dev_inst *sdi, if (probe->enabled) logic_probelist[num_enabled_probes++] = probe->index; } + logic_probelist[num_enabled_probes] = -1; /* How many bytes we need to store num_enabled_probes bits */ unitsize = (num_enabled_probes + 7) / 8; @@ -632,9 +625,9 @@ static void datafeed_in(const struct sr_dev_inst *sdi, * 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)); + ret = sr_datastore_new(unitsize, &singleds); if (ret != SR_OK) { - printf("Failed to create datastore.\n"); + g_critical("Failed to create datastore."); exit(1); } } else { @@ -663,8 +656,8 @@ static void datafeed_in(const struct sr_dev_inst *sdi, break; ret = sr_filter_probes(sample_size, unitsize, logic_probelist, - logic->data, logic->length, - &filter_out, &filter_out_len); + logic->data, logic->length, + &filter_out, &filter_out_len); if (ret != SR_OK) break; @@ -677,9 +670,9 @@ static void datafeed_in(const struct sr_dev_inst *sdi, 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 (singleds) + sr_datastore_put(singleds, 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 @@ -724,9 +717,9 @@ static void datafeed_in(const struct sr_dev_inst *sdi, * 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)); + ret = sr_datastore_new(unitsize, &singleds); if (ret != SR_OK) { - printf("Failed to create datastore.\n"); + g_critical("Failed to create datastore."); exit(1); } } else { @@ -1142,7 +1135,7 @@ static void load_input_file_format(void) char *fmtspec = NULL; if (opt_input_format) { - fmtargs = parse_generic_arg(opt_input_format); + fmtargs = parse_generic_arg(opt_input_format, TRUE); fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key"); } @@ -1151,7 +1144,7 @@ static void load_input_file_format(void) /* The exact cause was already logged. */ return; } -; + if (fmtargs) g_hash_table_remove(fmtargs, "sigrok_key"); @@ -1188,7 +1181,7 @@ static void load_input_file_format(void) input_format->loadfile(in, opt_input_file); if (opt_output_file && default_output_format) { - if (sr_session_save(opt_output_file) != SR_OK) + if (sr_session_save(opt_output_file, in->sdi, singleds) != SR_OK) g_critical("Failed to save session."); } sr_session_destroy(); @@ -1215,77 +1208,71 @@ static void load_input_file(void) static int set_dev_options(struct sr_dev_inst *sdi, GHashTable *args) { + const struct sr_hwcap_option *hwo; GHashTableIter iter; gpointer key, value; - int ret, i; + int ret; float tmp_float; uint64_t tmp_u64; struct sr_rational tmp_rat; gboolean tmp_bool; - gboolean found; void *val; g_hash_table_iter_init(&iter, args); while (g_hash_table_iter_next(&iter, &key, &value)) { - found = FALSE; - for (i = 0; sr_hwcap_options[i].hwcap; i++) { - if (strcmp(sr_hwcap_options[i].shortname, key)) - continue; - if ((value == NULL) && - (sr_hwcap_options[i].type != SR_T_BOOL)) { - g_critical("Option '%s' needs a value.", (char *)key); - return SR_ERR; - } - found = TRUE; - val = NULL; - switch (sr_hwcap_options[i].type) { - case SR_T_UINT64: - ret = sr_parse_sizestring(value, &tmp_u64); - if (ret != SR_OK) - break; - val = &tmp_u64; - break; - case SR_T_CHAR: - val = value; - break; - case SR_T_BOOL: - if (!value) - tmp_bool = TRUE; - else - tmp_bool = sr_parse_boolstring(value); - val = &tmp_bool; - break; - case SR_T_FLOAT: - tmp_float = strtof(value, NULL); - val = &tmp_float; - break; - case SR_T_RATIONAL_PERIOD: - if ((ret = sr_parse_period(value, &tmp_rat)) != SR_OK) - break; - val = &tmp_rat; - break; - case SR_T_RATIONAL_VOLT: - if ((ret = sr_parse_voltage(value, &tmp_rat)) != SR_OK) - break; - val = &tmp_rat; + if (!(hwo = sr_devopt_name_get(key))) { + g_critical("Unknown device option '%s'.", (char *) key); + return SR_ERR; + } + + if ((value == NULL) && + (hwo->type != SR_T_BOOL)) { + g_critical("Option '%s' needs a value.", (char *)key); + return SR_ERR; + } + val = NULL; + switch (hwo->type) { + case SR_T_UINT64: + ret = sr_parse_sizestring(value, &tmp_u64); + if (ret != SR_OK) break; - default: - ret = SR_ERR; - } - if (val) - ret = sdi->driver->dev_config_set(sdi, - sr_hwcap_options[i].hwcap, val); - if (ret != SR_OK) { - g_critical("Failed to set device option '%s'.", (char *)key); - return ret; - } + val = &tmp_u64; + break; + case SR_T_CHAR: + val = value; + break; + case SR_T_BOOL: + if (!value) + tmp_bool = TRUE; else + tmp_bool = sr_parse_boolstring(value); + val = &tmp_bool; + break; + case SR_T_FLOAT: + tmp_float = strtof(value, NULL); + val = &tmp_float; + break; + case SR_T_RATIONAL_PERIOD: + if ((ret = sr_parse_period(value, &tmp_rat)) != SR_OK) break; + val = &tmp_rat; + break; + case SR_T_RATIONAL_VOLT: + if ((ret = sr_parse_voltage(value, &tmp_rat)) != SR_OK) + break; + val = &tmp_rat; + break; + default: + ret = SR_ERR; } - if (!found) { - g_critical("Unknown device option '%s'.", (char *) key); - return SR_ERR; + if (val) + ret = sr_dev_config_set(sdi, hwo->hwcap, val); + if (ret != SR_OK) { + g_critical("Failed to set device option '%s'.", (char *)key); + return ret; } + else + break; } return SR_OK; @@ -1304,8 +1291,7 @@ static int set_limit_time(const struct sr_dev_inst *sdi) } if (sr_driver_hwcap_exists(sdi->driver, SR_HWCAP_LIMIT_MSEC)) { - if (sdi->driver->dev_config_set(sdi, - SR_HWCAP_LIMIT_MSEC, &time_msec) != SR_OK) { + if (sr_dev_config_set(sdi, SR_HWCAP_LIMIT_MSEC, &time_msec) != SR_OK) { g_critical("Failed to configure time limit."); sr_session_destroy(); return SR_ERR; @@ -1327,8 +1313,8 @@ static int set_limit_time(const struct sr_dev_inst *sdi) return SR_ERR; } - if (sdi->driver->dev_config_set(sdi, - SR_HWCAP_LIMIT_SAMPLES, &limit_samples) != SR_OK) { + if (sr_dev_config_set(sdi, SR_HWCAP_LIMIT_SAMPLES, + &limit_samples) != SR_OK) { g_critical("Failed to configure time-based sample limit."); sr_session_destroy(); return SR_ERR; @@ -1340,73 +1326,67 @@ static int set_limit_time(const struct sr_dev_inst *sdi) static void run_session(void) { - GSList *devices, *l; + GSList *devices; GHashTable *devargs; struct sr_dev_inst *sdi; int max_probes, i; - char **probelist; - - sr_session_new(); - sr_session_datafeed_callback_add(datafeed_in); + char **triggerlist; devices = device_scan(); - for (l = devices; l; l = l->next) { - sdi = l->data; - printf("found %s %s\n", sdi->vendor, sdi->model); - - devargs = NULL; - if (opt_dev) { - /* TODO: this applies the same options to every device */ - devargs = parse_generic_arg(opt_dev, FALSE); - if (devargs) { - if (set_dev_options(sdi, devargs) != SR_OK) { - return; - } - g_hash_table_destroy(devargs); - } - } + if (!devices) { + g_critical("No devices found."); + return; + } + if (g_slist_length(devices) > 1) { + g_critical("sigrok-cli only supports one device for capturing."); + return; + } + sdi = devices->data; - if (sr_session_dev_add(sdi) != SR_OK) { - g_critical("Failed to use device."); - sr_session_destroy(); - return; - } + sr_session_new(); + sr_session_datafeed_callback_add(datafeed_in); - if (select_probes(sdi) != SR_OK) - return; + if (sr_session_dev_add(sdi) != SR_OK) { + g_critical("Failed to use device."); + sr_session_destroy(); + return; + } - if (opt_continuous) { - if (!sr_driver_hwcap_exists(sdi->driver, SR_HWCAP_CONTINUOUS)) { - g_critical("This device does not support continuous sampling."); - sr_session_destroy(); + if (opt_dev) { + if ((devargs = parse_generic_arg(opt_dev, FALSE))) { + if (set_dev_options(sdi, devargs) != SR_OK) return; - } + g_hash_table_destroy(devargs); } + } - if (opt_triggers) { - probelist = sr_parse_triggerstring(sdi, opt_triggers); - if (!probelist) { - sr_session_destroy(); - return; - } + if (select_probes(sdi) != SR_OK) { + g_critical("Failed to set probes."); + sr_session_destroy(); + return; + } - max_probes = g_slist_length(sdi->probes); - for (i = 0; i < max_probes; i++) { - if (probelist[i]) { - sr_dev_trigger_set(sdi, i, probelist[i]); - g_free(probelist[i]); - } + if (opt_triggers) { + if (!(triggerlist = sr_parse_triggerstring(sdi, opt_triggers))) { + sr_session_destroy(); + return; + } + max_probes = g_slist_length(sdi->probes); + for (i = 0; i < max_probes; i++) { + if (triggerlist[i]) { + sr_dev_trigger_set(sdi, i, triggerlist[i]); + g_free(triggerlist[i]); } - g_free(probelist); } + g_free(triggerlist); + } - if (sdi->driver->dev_config_set(sdi, SR_HWCAP_PROBECONFIG, - (char *)sdi->probes) != SR_OK) { - g_critical("Failed to configure probes."); + if (opt_continuous) { + if (!sr_driver_hwcap_exists(sdi->driver, SR_HWCAP_CONTINUOUS)) { + g_critical("This device does not support continuous sampling."); sr_session_destroy(); return; } - } if (opt_time) { @@ -1418,7 +1398,7 @@ static void run_session(void) if (opt_samples) { if ((sr_parse_sizestring(opt_samples, &limit_samples) != SR_OK) - || (sdi->driver->dev_config_set(sdi, SR_HWCAP_LIMIT_SAMPLES, + || (sr_dev_config_set(sdi, SR_HWCAP_LIMIT_SAMPLES, &limit_samples) != SR_OK)) { g_critical("Failed to configure sample limit."); sr_session_destroy(); @@ -1428,9 +1408,9 @@ static void run_session(void) if (opt_frames) { if ((sr_parse_sizestring(opt_frames, &limit_frames) != SR_OK) - || (sdi->driver->dev_config_set(sdi, - SR_HWCAP_LIMIT_FRAMES, &limit_frames) != SR_OK)) { - printf("Failed to configure frame limit.\n"); + || (sr_dev_config_set(sdi, SR_HWCAP_LIMIT_FRAMES, + &limit_frames) != SR_OK)) { + g_critical("Failed to configure frame limit."); sr_session_destroy(); return; } @@ -1451,7 +1431,7 @@ static void run_session(void) clear_anykey(); if (opt_output_file && default_output_format) { - if (sr_session_save(opt_output_file) != SR_OK) + if (sr_session_save(opt_output_file, sdi, singleds) != SR_OK) g_critical("Failed to save session."); } sr_session_destroy(); @@ -1525,10 +1505,10 @@ int main(int argc, char **argv) show_version(); else if (opt_list_devs) show_dev_list(); + else if (opt_pds && opt_show) + show_pd_detail(); else if (opt_show) show_dev_detail(); - else if (opt_pds) - show_pd_detail(); else if (opt_input_file) load_input_file(); else if (opt_samples || opt_time || opt_frames || opt_continuous)