diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2016-04-14 04:26:47 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2016-04-19 14:58:13 -0400 |
commit | 5f991a921a08279f573fa5ecf84261a3a6fac0cc (patch) | |
tree | 03a33955b0dc98110f0fb4a16ea98bd90968b73c | |
parent | 0e6f6871a1591f4bb0971809c45bc91a991f1967 (diff) |
iio: tools: generic_buffer: auto-enable channels
If no channels are enabled when we run generic_buffer on a
device, add a command-line option to just enable all of them,
run the sampling and disable them all again afterwards.
This is extremely useful when I'm low-level testing my
sensors with interrupts and triggers, sample session:
root@Ux500:/ lsiio
Device 000: lsm303dlh_accel
Device 001: lis331dl_accel
Device 002: l3g4200d
Device 003: lsm303dlh_magn
Device 004: lps001wp
Trigger 000: lsm303dlh_accel-trigger
Trigger 001: lis331dl_accel-trigger
Trigger 002: l3g4200d-trigger
root@Ux500:/ generic_buffer -a -c 10 -n l3g4200d
iio device number being used is 2
iio trigger number being used is 2
No channels are enabled, enabling all channels
Enabling: in_anglvel_x_en
Enabling: in_anglvel_y_en
Enabling: in_anglvel_z_en
Enabling: in_timestamp_en
/sys/bus/iio/devices/iio:device2 l3g4200d-trigger
-3.593664 -0.713133 4.870143 946684863662292480
3.225546 0.867357 -4.945878 946684863671875000
-0.676413 0.127296 0.106641 946684863681488037
-0.661113 0.110160 0.128826 946684863690673828
-0.664173 0.113067 0.123471 946684863700683593
-0.664938 0.109395 0.124848 946684863710144042
-0.664173 0.110619 0.130203 946684863719512939
-0.666162 0.111231 0.132651 946684863729125976
-0.668610 0.111690 0.130662 946684863738739013
-0.660501 0.110466 0.131733 946684863748565673
Disabling: in_anglvel_x_en
Disabling: in_anglvel_y_en
Disabling: in_anglvel_z_en
Disabling: in_timestamp_en
Pure awesomeness. If some channels have been enabled through
scripts or manual interaction, nothing happens.
Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
Acked-by: Daniel Baluta <daniel.baluta@intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r-- | tools/iio/generic_buffer.c | 102 | ||||
-rw-r--r-- | tools/iio/iio_utils.h | 7 |
2 files changed, 105 insertions, 4 deletions
diff --git a/tools/iio/generic_buffer.c b/tools/iio/generic_buffer.c index c42b7f836b48..2429c78de940 100644 --- a/tools/iio/generic_buffer.c +++ b/tools/iio/generic_buffer.c | |||
@@ -35,6 +35,15 @@ | |||
35 | #include "iio_utils.h" | 35 | #include "iio_utils.h" |
36 | 36 | ||
37 | /** | 37 | /** |
38 | * enum autochan - state for the automatic channel enabling mechanism | ||
39 | */ | ||
40 | enum autochan { | ||
41 | AUTOCHANNELS_DISABLED, | ||
42 | AUTOCHANNELS_ENABLED, | ||
43 | AUTOCHANNELS_ACTIVE, | ||
44 | }; | ||
45 | |||
46 | /** | ||
38 | * size_from_channelarray() - calculate the storage size of a scan | 47 | * size_from_channelarray() - calculate the storage size of a scan |
39 | * @channels: the channel info array | 48 | * @channels: the channel info array |
40 | * @num_channels: number of channels | 49 | * @num_channels: number of channels |
@@ -191,10 +200,51 @@ void process_scan(char *data, | |||
191 | printf("\n"); | 200 | printf("\n"); |
192 | } | 201 | } |
193 | 202 | ||
203 | static int enable_disable_all_channels(char *dev_dir_name, int enable) | ||
204 | { | ||
205 | const struct dirent *ent; | ||
206 | char scanelemdir[256]; | ||
207 | DIR *dp; | ||
208 | int ret; | ||
209 | |||
210 | snprintf(scanelemdir, sizeof(scanelemdir), | ||
211 | FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name); | ||
212 | scanelemdir[sizeof(scanelemdir)-1] = '\0'; | ||
213 | |||
214 | dp = opendir(scanelemdir); | ||
215 | if (!dp) { | ||
216 | fprintf(stderr, "Enabling/disabling channels: can't open %s\n", | ||
217 | scanelemdir); | ||
218 | return -EIO; | ||
219 | } | ||
220 | |||
221 | ret = -ENOENT; | ||
222 | while (ent = readdir(dp), ent) { | ||
223 | if (iioutils_check_suffix(ent->d_name, "_en")) { | ||
224 | printf("%sabling: %s\n", | ||
225 | enable ? "En" : "Dis", | ||
226 | ent->d_name); | ||
227 | ret = write_sysfs_int(ent->d_name, scanelemdir, | ||
228 | enable); | ||
229 | if (ret < 0) | ||
230 | fprintf(stderr, "Failed to enable/disable %s\n", | ||
231 | ent->d_name); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | if (closedir(dp) == -1) { | ||
236 | perror("Enabling/disabling channels: " | ||
237 | "Failed to close directory"); | ||
238 | return -errno; | ||
239 | } | ||
240 | return 0; | ||
241 | } | ||
242 | |||
194 | void print_usage(void) | 243 | void print_usage(void) |
195 | { | 244 | { |
196 | fprintf(stderr, "Usage: generic_buffer [options]...\n" | 245 | fprintf(stderr, "Usage: generic_buffer [options]...\n" |
197 | "Capture, convert and output data from IIO device buffer\n" | 246 | "Capture, convert and output data from IIO device buffer\n" |
247 | " -a Auto-activate all available channels\n" | ||
198 | " -c <n> Do n conversions\n" | 248 | " -c <n> Do n conversions\n" |
199 | " -e Disable wait for event (new data)\n" | 249 | " -e Disable wait for event (new data)\n" |
200 | " -g Use trigger-less mode\n" | 250 | " -g Use trigger-less mode\n" |
@@ -225,12 +275,16 @@ int main(int argc, char **argv) | |||
225 | int scan_size; | 275 | int scan_size; |
226 | int noevents = 0; | 276 | int noevents = 0; |
227 | int notrigger = 0; | 277 | int notrigger = 0; |
278 | enum autochan autochannels = AUTOCHANNELS_DISABLED; | ||
228 | char *dummy; | 279 | char *dummy; |
229 | 280 | ||
230 | struct iio_channel_info *channels; | 281 | struct iio_channel_info *channels; |
231 | 282 | ||
232 | while ((c = getopt(argc, argv, "c:egl:n:t:w:")) != -1) { | 283 | while ((c = getopt(argc, argv, "ac:egl:n:t:w:")) != -1) { |
233 | switch (c) { | 284 | switch (c) { |
285 | case 'a': | ||
286 | autochannels = AUTOCHANNELS_ENABLED; | ||
287 | break; | ||
234 | case 'c': | 288 | case 'c': |
235 | errno = 0; | 289 | errno = 0; |
236 | num_loops = strtoul(optarg, &dummy, 10); | 290 | num_loops = strtoul(optarg, &dummy, 10); |
@@ -340,12 +394,47 @@ int main(int argc, char **argv) | |||
340 | "diag %s\n", dev_dir_name); | 394 | "diag %s\n", dev_dir_name); |
341 | goto error_free_triggername; | 395 | goto error_free_triggername; |
342 | } | 396 | } |
343 | if (!num_channels) { | 397 | if (num_channels && autochannels == AUTOCHANNELS_ENABLED) { |
398 | fprintf(stderr, "Auto-channels selected but some channels " | ||
399 | "are already activated in sysfs\n"); | ||
400 | fprintf(stderr, "Proceeding without activating any channels\n"); | ||
401 | } | ||
402 | |||
403 | if (!num_channels && autochannels == AUTOCHANNELS_ENABLED) { | ||
404 | fprintf(stderr, | ||
405 | "No channels are enabled, enabling all channels\n"); | ||
406 | |||
407 | ret = enable_disable_all_channels(dev_dir_name, 1); | ||
408 | if (ret) { | ||
409 | fprintf(stderr, "Failed to enable all channels\n"); | ||
410 | goto error_free_triggername; | ||
411 | } | ||
412 | |||
413 | /* This flags that we need to disable the channels again */ | ||
414 | autochannels = AUTOCHANNELS_ACTIVE; | ||
415 | |||
416 | ret = build_channel_array(dev_dir_name, &channels, | ||
417 | &num_channels); | ||
418 | if (ret) { | ||
419 | fprintf(stderr, "Problem reading scan element " | ||
420 | "information\n" | ||
421 | "diag %s\n", dev_dir_name); | ||
422 | goto error_disable_channels; | ||
423 | } | ||
424 | if (!num_channels) { | ||
425 | fprintf(stderr, "Still no channels after " | ||
426 | "auto-enabling, giving up\n"); | ||
427 | goto error_disable_channels; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | if (!num_channels && autochannels == AUTOCHANNELS_DISABLED) { | ||
344 | fprintf(stderr, | 432 | fprintf(stderr, |
345 | "No channels are enabled, we have nothing to scan.\n"); | 433 | "No channels are enabled, we have nothing to scan.\n"); |
346 | fprintf(stderr, "Enable channels manually in " | 434 | fprintf(stderr, "Enable channels manually in " |
347 | FORMAT_SCAN_ELEMENTS_DIR | 435 | FORMAT_SCAN_ELEMENTS_DIR |
348 | "/*_en and try again.\n", dev_dir_name); | 436 | "/*_en or pass -a to autoenable channels and " |
437 | "try again.\n", dev_dir_name); | ||
349 | ret = -ENOENT; | 438 | ret = -ENOENT; |
350 | goto error_free_triggername; | 439 | goto error_free_triggername; |
351 | } | 440 | } |
@@ -479,7 +568,12 @@ error_free_channels: | |||
479 | error_free_triggername: | 568 | error_free_triggername: |
480 | if (datardytrigger) | 569 | if (datardytrigger) |
481 | free(trigger_name); | 570 | free(trigger_name); |
482 | 571 | error_disable_channels: | |
572 | if (autochannels == AUTOCHANNELS_ACTIVE) { | ||
573 | ret = enable_disable_all_channels(dev_dir_name, 0); | ||
574 | if (ret) | ||
575 | fprintf(stderr, "Failed to disable all channels\n"); | ||
576 | } | ||
483 | error_free_dev_dir_name: | 577 | error_free_dev_dir_name: |
484 | free(dev_dir_name); | 578 | free(dev_dir_name); |
485 | 579 | ||
diff --git a/tools/iio/iio_utils.h b/tools/iio/iio_utils.h index e3503bfe538b..780f2014f8fa 100644 --- a/tools/iio/iio_utils.h +++ b/tools/iio/iio_utils.h | |||
@@ -52,6 +52,13 @@ struct iio_channel_info { | |||
52 | unsigned location; | 52 | unsigned location; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static inline int iioutils_check_suffix(const char *str, const char *suffix) | ||
56 | { | ||
57 | return strlen(str) >= strlen(suffix) && | ||
58 | strncmp(str+strlen(str)-strlen(suffix), | ||
59 | suffix, strlen(suffix)) == 0; | ||
60 | } | ||
61 | |||
55 | int iioutils_break_up_name(const char *full_name, char **generic_name); | 62 | int iioutils_break_up_name(const char *full_name, char **generic_name); |
56 | int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, | 63 | int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, |
57 | unsigned *shift, uint64_t *mask, unsigned *be, | 64 | unsigned *shift, uint64_t *mask, unsigned *be, |