2 * This file is part of the sigrok-cli project.
4 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "sigrok-cli.h"
25 extern gint opt_loglevel
;
26 extern gchar
*opt_pds
;
28 static gint
sort_inputs(gconstpointer a
, gconstpointer b
)
30 const struct sr_input_format
*ia
= a
, *ib
= b
;
32 return strcmp(ia
->id
, ib
->id
);
35 static gint
sort_outputs(gconstpointer a
, gconstpointer b
)
37 const struct sr_output_format
*oa
= a
, *ob
= b
;
39 return strcmp(oa
->id
, ob
->id
);
42 static gint
sort_drivers(gconstpointer a
, gconstpointer b
)
44 const struct sr_dev_driver
*sdda
= a
, *sddb
= b
;
46 return strcmp(sdda
->name
, sddb
->name
);
49 static gint
sort_pds(gconstpointer a
, gconstpointer b
)
51 const struct srd_decoder
*sda
= a
, *sdb
= b
;
53 return strcmp(sda
->id
, sdb
->id
);
56 void show_version(void)
58 struct sr_dev_driver
**drivers
, *driver
;
59 struct sr_input_format
**inputs
, *input
;
60 struct sr_output_format
**outputs
, *output
;
65 struct srd_decoder
*dec
;
68 printf("sigrok-cli %s\n\n", VERSION
);
70 printf("Using libsigrok %s (lib version %s).\n",
71 sr_package_version_string_get(), sr_lib_version_string_get());
73 printf("Using libsigrokdecode %s (lib version %s).\n\n",
74 srd_package_version_string_get(), srd_lib_version_string_get());
77 printf("Supported hardware drivers:\n");
78 drivers
= sr_driver_list();
79 for (sl
= NULL
, i
= 0; drivers
[i
]; i
++)
80 sl
= g_slist_append(sl
, drivers
[i
]);
81 sl
= g_slist_sort(sl
, sort_drivers
);
82 for (l
= sl
; l
; l
= l
->next
) {
84 printf(" %-20s %s\n", driver
->name
, driver
->longname
);
89 printf("Supported input formats:\n");
90 inputs
= sr_input_list();
91 for (sl
= NULL
, i
= 0; inputs
[i
]; i
++)
92 sl
= g_slist_append(sl
, inputs
[i
]);
93 sl
= g_slist_sort(sl
, sort_inputs
);
94 for (l
= sl
; l
; l
= l
->next
) {
96 printf(" %-20s %s\n", input
->id
, input
->description
);
101 printf("Supported output formats:\n");
102 outputs
= sr_output_list();
103 for (sl
= NULL
, i
= 0; outputs
[i
]; i
++)
104 sl
= g_slist_append(sl
, outputs
[i
]);
105 sl
= g_slist_sort(sl
, sort_outputs
);
106 for (l
= sl
; l
; l
= l
->next
) {
108 printf(" %-20s %s\n", output
->id
, output
->description
);
114 if (srd_init(NULL
) == SRD_OK
) {
115 printf("Supported protocol decoders:\n");
116 srd_decoder_load_all();
117 sl
= g_slist_copy((GSList
*)srd_decoder_list());
118 sl
= g_slist_sort(sl
, sort_pds
);
119 for (l
= sl
; l
; l
= l
->next
) {
121 printf(" %-20s %s\n", dec
->id
, dec
->longname
);
122 /* Print protocol description upon "-l 3" or higher. */
123 if (opt_loglevel
>= SR_LOG_INFO
)
124 printf(" %-20s %s\n", "", dec
->desc
);
133 static gint
sort_channels(gconstpointer a
, gconstpointer b
)
135 const struct sr_channel
*pa
= a
, *pb
= b
;
137 return pa
->index
- pb
->index
;
140 static void print_dev_line(const struct sr_dev_inst
*sdi
)
142 struct sr_channel
*ch
;
147 s
= g_string_sized_new(128);
148 g_string_assign(s
, sdi
->driver
->name
);
149 if (sr_config_get(sdi
->driver
, sdi
, NULL
, SR_CONF_CONN
, &gvar
) == SR_OK
) {
150 g_string_append(s
, ":conn=");
151 g_string_append(s
, g_variant_get_string(gvar
, NULL
));
152 g_variant_unref(gvar
);
154 g_string_append(s
, " - ");
155 if (sdi
->vendor
&& sdi
->vendor
[0])
156 g_string_append_printf(s
, "%s ", sdi
->vendor
);
157 if (sdi
->model
&& sdi
->model
[0])
158 g_string_append_printf(s
, "%s ", sdi
->model
);
159 if (sdi
->version
&& sdi
->version
[0])
160 g_string_append_printf(s
, "%s ", sdi
->version
);
162 if (g_slist_length(sdi
->channels
) == 1) {
163 ch
= sdi
->channels
->data
;
164 g_string_append_printf(s
, "with 1 channel: %s", ch
->name
);
166 sl
= g_slist_sort(g_slist_copy(sdi
->channels
), sort_channels
);
167 g_string_append_printf(s
, "with %d channels:", g_slist_length(sl
));
168 for (l
= sl
; l
; l
= l
->next
) {
170 g_string_append_printf(s
, " %s", ch
->name
);
175 g_string_append_printf(s
, "\n");
176 printf("%s", s
->str
);
177 g_string_free(s
, TRUE
);
181 void show_dev_list(void)
183 struct sr_dev_inst
*sdi
;
186 if (!(devices
= device_scan()))
189 printf("The following devices were found:\n");
190 for (l
= devices
; l
; l
= l
->next
) {
194 g_slist_free(devices
);
198 void show_dev_detail(void)
200 struct sr_dev_inst
*sdi
;
201 const struct sr_config_info
*srci
;
202 struct sr_channel
*ch
;
203 struct sr_channel_group
*channel_group
, *cg
;
204 GSList
*devices
, *cgl
, *chl
;
205 GVariant
*gvar_opts
, *gvar_dict
, *gvar_list
, *gvar
;
206 gsize num_opts
, num_elements
;
207 double dlow
, dhigh
, dcur_low
, dcur_high
;
208 const uint64_t *uint64
, p
, q
, low
, high
;
209 uint64_t cur_low
, cur_high
;
211 unsigned int num_devices
, o
, i
;
214 const char *charopts
, **stropts
;
216 if (!(devices
= device_scan())) {
217 g_critical("No devices found.");
221 num_devices
= g_slist_length(devices
);
222 if (num_devices
> 1) {
223 g_critical("%d devices found. Use --scan to show them, "
224 "and select one to show.", num_devices
);
231 if (sr_dev_open(sdi
) != SR_OK
) {
232 g_critical("Failed to open device.");
236 if ((sr_config_list(sdi
->driver
, NULL
, NULL
, SR_CONF_SCAN_OPTIONS
,
237 &gvar_opts
) == SR_OK
)) {
238 opts
= g_variant_get_fixed_array(gvar_opts
, &num_elements
,
240 printf("Supported driver options:\n");
241 for (i
= 0; i
< num_elements
; i
++) {
242 if (!(srci
= sr_config_info_get(opts
[i
])))
244 printf(" %s\n", srci
->id
);
246 g_variant_unref(gvar_opts
);
249 /* Selected channels and channel group may affect which options are
250 * returned, or which values for them. */
251 select_channels(sdi
);
252 channel_group
= select_channel_group(sdi
);
254 if ((sr_config_list(sdi
->driver
, sdi
, channel_group
, SR_CONF_DEVICE_OPTIONS
,
255 &gvar_opts
)) != SR_OK
)
256 /* Driver supports no device instance options. */
259 if (sdi
->channel_groups
) {
260 printf("Channel groups:\n");
261 for (cgl
= sdi
->channel_groups
; cgl
; cgl
= cgl
->next
) {
263 printf(" %s: channel%s", cg
->name
,
264 g_slist_length(cg
->channels
) > 1 ? "s" : "");
265 for (chl
= cg
->channels
; chl
; chl
= chl
->next
) {
267 printf(" %s", ch
->name
);
273 printf("Supported configuration options");
274 if (sdi
->channel_groups
) {
276 printf(" across all channel groups");
278 printf(" on channel group %s", channel_group
->name
);
281 opts
= g_variant_get_fixed_array(gvar_opts
, &num_opts
, sizeof(int32_t));
282 for (o
= 0; o
< num_opts
; o
++) {
283 if (!(srci
= sr_config_info_get(opts
[o
])))
286 if (srci
->key
== SR_CONF_TRIGGER_TYPE
) {
287 if (sr_config_list(sdi
->driver
, sdi
, channel_group
, srci
->key
,
292 charopts
= g_variant_get_string(gvar
, NULL
);
293 printf(" Supported triggers: ");
295 printf("%c ", *charopts
);
299 g_variant_unref(gvar
);
301 } else if (srci
->key
== SR_CONF_LIMIT_SAMPLES
) {
302 /* If implemented in config_list(), this denotes the
303 * maximum number of samples a device can send. This
304 * really applies only to logic analyzers, and then
305 * only to those that don't support compression, or
306 * have it turned off by default. The values returned
307 * are the low/high limits. */
308 if (sr_config_list(sdi
->driver
, sdi
, channel_group
, srci
->key
,
312 g_variant_get(gvar
, "(tt)", &low
, &high
);
313 g_variant_unref(gvar
);
314 printf(" Maximum number of samples: %"PRIu64
"\n", high
);
316 } else if (srci
->key
== SR_CONF_SAMPLERATE
) {
317 /* Supported samplerates */
318 printf(" %s", srci
->id
);
319 if (sr_config_list(sdi
->driver
, sdi
, channel_group
, SR_CONF_SAMPLERATE
,
320 &gvar_dict
) != SR_OK
) {
324 if ((gvar_list
= g_variant_lookup_value(gvar_dict
,
325 "samplerates", G_VARIANT_TYPE("at")))) {
326 uint64
= g_variant_get_fixed_array(gvar_list
,
327 &num_elements
, sizeof(uint64_t));
328 printf(" - supported samplerates:\n");
329 for (i
= 0; i
< num_elements
; i
++) {
330 if (!(s
= sr_samplerate_string(uint64
[i
])))
335 g_variant_unref(gvar_list
);
336 } else if ((gvar_list
= g_variant_lookup_value(gvar_dict
,
337 "samplerate-steps", G_VARIANT_TYPE("at")))) {
338 uint64
= g_variant_get_fixed_array(gvar_list
,
339 &num_elements
, sizeof(uint64_t));
341 if (!(s
= sr_samplerate_string(uint64
[0])))
346 if (!(s
= sr_samplerate_string(uint64
[1])))
351 if (!(s
= sr_samplerate_string(uint64
[2])))
353 printf(" in steps of %s)\n", s
);
355 g_variant_unref(gvar_list
);
357 g_variant_unref(gvar_dict
);
359 } else if (srci
->key
== SR_CONF_BUFFERSIZE
) {
360 /* Supported buffer sizes */
361 printf(" %s", srci
->id
);
362 if (sr_config_list(sdi
->driver
, sdi
, channel_group
,
363 SR_CONF_BUFFERSIZE
, &gvar_list
) != SR_OK
) {
367 uint64
= g_variant_get_fixed_array(gvar_list
,
368 &num_elements
, sizeof(uint64_t));
369 printf(" - supported buffer sizes:\n");
370 for (i
= 0; i
< num_elements
; i
++)
371 printf(" %"PRIu64
"\n", uint64
[i
]);
372 g_variant_unref(gvar_list
);
374 } else if (srci
->key
== SR_CONF_TIMEBASE
) {
375 /* Supported time bases */
376 printf(" %s", srci
->id
);
377 if (sr_config_list(sdi
->driver
, sdi
, channel_group
,
378 SR_CONF_TIMEBASE
, &gvar_list
) != SR_OK
) {
382 printf(" - supported time bases:\n");
383 num_elements
= g_variant_n_children(gvar_list
);
384 for (i
= 0; i
< num_elements
; i
++) {
385 gvar
= g_variant_get_child_value(gvar_list
, i
);
386 g_variant_get(gvar
, "(tt)", &p
, &q
);
387 s
= sr_period_string(p
* q
);
391 g_variant_unref(gvar_list
);
393 } else if (srci
->key
== SR_CONF_VDIV
) {
394 /* Supported volts/div values */
395 printf(" %s", srci
->id
);
396 if (sr_config_list(sdi
->driver
, sdi
, channel_group
,
397 SR_CONF_VDIV
, &gvar_list
) != SR_OK
) {
401 printf(" - supported volts/div:\n");
402 num_elements
= g_variant_n_children(gvar_list
);
403 for (i
= 0; i
< num_elements
; i
++) {
404 gvar
= g_variant_get_child_value(gvar_list
, i
);
405 g_variant_get(gvar
, "(tt)", &p
, &q
);
406 s
= sr_voltage_string(p
, q
);
410 g_variant_unref(gvar_list
);
412 } else if (srci
->datatype
== SR_T_CHAR
) {
413 printf(" %s: ", srci
->id
);
414 if (sr_config_get(sdi
->driver
, sdi
, channel_group
, srci
->key
,
416 tmp_str
= g_strdup(g_variant_get_string(gvar
, NULL
));
417 g_variant_unref(gvar
);
421 if (sr_config_list(sdi
->driver
, sdi
, channel_group
, srci
->key
,
427 stropts
= g_variant_get_strv(gvar
, &num_elements
);
428 for (i
= 0; i
< num_elements
; i
++) {
431 printf("%s", stropts
[i
]);
432 if (tmp_str
&& !strcmp(tmp_str
, stropts
[i
]))
433 printf(" (current)");
438 g_variant_unref(gvar
);
440 } else if (srci
->datatype
== SR_T_UINT64_RANGE
) {
441 printf(" %s: ", srci
->id
);
442 if (sr_config_list(sdi
->driver
, sdi
, channel_group
, srci
->key
,
443 &gvar_list
) != SR_OK
) {
448 if (sr_config_get(sdi
->driver
, sdi
, NULL
, srci
->key
, &gvar
) == SR_OK
) {
449 g_variant_get(gvar
, "(tt)", &cur_low
, &cur_high
);
450 g_variant_unref(gvar
);
456 num_elements
= g_variant_n_children(gvar_list
);
457 for (i
= 0; i
< num_elements
; i
++) {
458 gvar
= g_variant_get_child_value(gvar_list
, i
);
459 g_variant_get(gvar
, "(tt)", &low
, &high
);
460 g_variant_unref(gvar
);
463 printf("%"PRIu64
"-%"PRIu64
, low
, high
);
464 if (low
== cur_low
&& high
== cur_high
)
465 printf(" (current)");
468 g_variant_unref(gvar_list
);
470 } else if (srci
->datatype
== SR_T_BOOL
) {
471 printf(" %s: ", srci
->id
);
472 if (sr_config_get(sdi
->driver
, sdi
, NULL
, srci
->key
,
474 if (g_variant_get_boolean(gvar
))
475 printf("on (current), off\n");
477 printf("on, off (current)\n");
478 g_variant_unref(gvar
);
482 } else if (srci
->datatype
== SR_T_DOUBLE_RANGE
) {
483 printf(" %s: ", srci
->id
);
484 if (sr_config_list(sdi
->driver
, sdi
, channel_group
, srci
->key
,
485 &gvar_list
) != SR_OK
) {
490 if (sr_config_get(sdi
->driver
, sdi
, NULL
, srci
->key
, &gvar
) == SR_OK
) {
491 g_variant_get(gvar
, "(dd)", &dcur_low
, &dcur_high
);
492 g_variant_unref(gvar
);
498 num_elements
= g_variant_n_children(gvar_list
);
499 for (i
= 0; i
< num_elements
; i
++) {
500 gvar
= g_variant_get_child_value(gvar_list
, i
);
501 g_variant_get(gvar
, "(dd)", &dlow
, &dhigh
);
502 g_variant_unref(gvar
);
505 printf("%.1f-%.1f", dlow
, dhigh
);
506 if (dlow
== dcur_low
&& dhigh
== dcur_high
)
507 printf(" (current)");
510 g_variant_unref(gvar_list
);
514 /* Everything else */
515 printf(" %s\n", srci
->id
);
518 g_variant_unref(gvar_opts
);
521 g_slist_free(devices
);
526 void show_pd_detail(void)
529 struct srd_decoder
*dec
;
530 struct srd_decoder_option
*o
;
531 char **pdtokens
, **pdtok
, *optsep
, **ann
, *val
, *doc
;
533 struct srd_decoder_annotation_row
*r
;
535 pdtokens
= g_strsplit(opt_pds
, ",", -1);
536 for (pdtok
= pdtokens
; *pdtok
; pdtok
++) {
538 if ((optsep
= strchr(*pdtok
, ':')))
540 if (!(dec
= srd_decoder_get_by_id(*pdtok
))) {
541 g_critical("Protocol decoder %s not found.", *pdtok
);
544 printf("ID: %s\nName: %s\nLong name: %s\nDescription: %s\n",
545 dec
->id
, dec
->name
, dec
->longname
, dec
->desc
);
546 printf("License: %s\n", dec
->license
);
547 printf("Annotation classes:\n");
548 if (dec
->annotations
) {
549 for (l
= dec
->annotations
; l
; l
= l
->next
) {
551 printf("- %s: %s\n", ann
[0], ann
[1]);
556 printf("Annotation rows:\n");
557 if (dec
->annotation_rows
) {
558 for (l
= dec
->annotation_rows
; l
; l
= l
->next
) {
560 printf("- %s (%s): ", r
->id
, r
->desc
);
561 for (ll
= r
->ann_classes
; ll
; ll
= ll
->next
)
562 printf("%d ", GPOINTER_TO_INT(ll
->data
));
568 printf("Required probes:\n");
570 for (l
= dec
->probes
; l
; l
= l
->next
) {
572 printf("- %s (%s): %s\n",
573 p
->id
, p
->name
, p
->desc
);
578 printf("Optional probes:\n");
579 if (dec
->opt_probes
) {
580 for (l
= dec
->opt_probes
; l
; l
= l
->next
) {
582 printf("- %s (%s): %s\n",
583 p
->id
, p
->name
, p
->desc
);
588 printf("Options:\n");
590 for (l
= dec
->options
; l
; l
= l
->next
) {
592 printf("- %s: %s (", o
->id
, o
->desc
);
593 for (ol
= o
->values
; ol
; ol
= ol
->next
) {
594 val
= g_variant_print(ol
->data
, FALSE
);
598 val
= g_variant_print(o
->def
, FALSE
);
599 printf("default %s)\n", val
);
605 if ((doc
= srd_decoder_doc_get(dec
))) {
606 printf("Documentation:\n%s\n",
607 doc
[0] == '\n' ? doc
+ 1 : doc
);
612 g_strfreev(pdtokens
);