3 * sis33 interactive test-program
5 * Copyright (c) 2009-2010 Emilio G. Cota <cota@braap.org>
6 * Released under the GPL v2. (and only v2, not any later version)
12 #include <general_usr.h> /* for handy definitions (mperr etc..) */
19 #define SIS33T_MAX_NR_SEGMENTS 8
21 int use_builtin_cmds
= 0;
22 char xmlfile
[128] = "cvorg.xml";
24 static uint32_t channel_nr
= 0;
25 static uint32_t nr_events
[SIS33T_MAX_NR_SEGMENTS
];
26 static uint32_t nr_samples
[SIS33T_MAX_NR_SEGMENTS
];
27 static struct sis33_acq_list acq_list
[SIS33T_MAX_NR_SEGMENTS
];
28 static int sis33fd
= -1;
29 static int curr_index
;
30 static int curr_segment
;
31 static char gnuplot
[4096];
33 static struct timespec
my_us_to_timespec(const unsigned int us
)
38 return (struct timespec
) {0, 0};
39 ts
.tv_sec
= us
/ 1000000;
40 ts
.tv_nsec
= (us
% 1000000) * 1000;
44 static int round_uint(int index
, const char *name
, unsigned int *roundme
, enum sis33_round round
)
50 n
= sis33dev_get_nr_items(index
, name
);
53 array
= calloc(n
, sizeof(*array
));
57 ret
= sis33dev_get_items_uint(index
, name
, array
, n
);
60 *roundme
= sis33dev_round_uint(array
, n
, *roundme
, round
);
66 #define MY_FILE_LEN 64
68 static char *write_file(const char *prefix
, struct sis33_acq_list
*list
, int segment
, int event
)
71 struct sis33_acq
*acq
= &list
->acqs
[event
];
72 static char filename
[MY_FILE_LEN
];
75 snprintf(filename
, MY_FILE_LEN
- 1, "/tmp/%s.ch%d.seg%d.ev%d.dat",
76 prefix
, list
->channel
, segment
, event
);
77 filename
[MY_FILE_LEN
- 1] = '\0';
78 filp
= fopen(filename
, "w");
83 fprintf(filp
, "# segment %d event %d\n", segment
, event
);
84 for (i
= 0; i
< acq
->nr_samples
; i
++)
85 fprintf(filp
, "0x%x\n", acq
->data
[i
]);
88 printf("Data written to %s.\n", filename
);
92 static int h_attr(const struct atom
*atoms
, const char *param
)
98 if (atoms
->type
== Numeric
) {
99 ret
= sis33dev_set_attr_int(curr_index
, param
, atoms
->val
);
102 return -TST_ERR_SYSCALL
;
105 ret
= sis33dev_get_attr_int(curr_index
, param
, &val
);
114 static int h_uattr(const struct atom
*atoms
, const char *param
)
120 if (atoms
->type
== Numeric
) {
122 ret
= sis33dev_set_attr_uint(curr_index
, param
, val
);
124 mperr("set_attr_uint");
125 return -TST_ERR_SYSCALL
;
128 ret
= sis33dev_get_attr_uint(curr_index
, param
, &val
);
130 mperr("get_attr_uint");
137 int h_start_auto(struct cmd_desc
*cmdd
, struct atom
*atoms
)
139 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
140 printf("%s - Get/set Autostart\n"
142 cmdd
->name
, cmdd
->name
);
145 return h_attr(atoms
, "start_auto");
148 int h_trig_ext(struct cmd_desc
*cmdd
, struct atom
*atoms
)
150 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
151 printf("%s - Enable/Disable external trigger\n"
153 cmdd
->name
, cmdd
->name
);
156 return h_attr(atoms
, "trigger_external_enable");
159 int h_start_delay(struct cmd_desc
*cmdd
, struct atom
*atoms
)
161 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
162 printf("%s - Get/Set Start delay\n"
164 "\tdelay: start input delay of n clock ticks\n"
165 "\tNote: this has no effect on software-driven start\n"
166 "\t(valid range for the sis3320: [0-8K]\n",
167 cmdd
->name
, cmdd
->name
);
170 return h_attr(atoms
, "start_delay");
174 int h_stop_delay(struct cmd_desc
*cmdd
, struct atom
*atoms
)
176 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
177 printf("%s - Get/Set Stop delay\n"
179 "\tdelay: stop input delay of n clock ticks\n"
180 "\tNote: this has no effect on software-driven stop\n"
181 "\t(valid range for the sis3320: [0-8K]\n",
182 cmdd
->name
, cmdd
->name
);
185 return h_attr(atoms
, "stop_delay");
188 static int show_chan_offset_all(void)
190 char attr
[SIS33_PATH_MAX
];
196 n_channels
= sis33dev_get_nr_subattrs(curr_index
, "channels");
200 for (i
= 0; i
< n_channels
; i
++) {
201 snprintf(attr
, sizeof(attr
) - 1, "channels/channel%d/offset", i
);
202 attr
[sizeof(attr
) - 1] = '\0';
203 ret
= sis33dev_get_attr_uint(curr_index
, attr
, &val
);
206 printf("%d\t0x%-8x (%d)\n", i
, val
, val
);
211 static int set_offset(int offset
, int channel
)
213 char attr
[SIS33_PATH_MAX
];
219 n_channels
= sis33dev_get_nr_subattrs(curr_index
, "channels");
229 for (i
= init
; i
< end
; i
++) {
230 snprintf(attr
, sizeof(attr
) - 1, "channels/channel%d/offset", i
);
231 attr
[sizeof(attr
) - 1] = '\0';
232 ret
= sis33dev_set_attr_int(curr_index
, attr
, offset
);
235 return -TST_ERR_SYSCALL
;
241 int h_offset(struct cmd_desc
*cmdd
, struct atom
*atoms
)
247 n_channels
= sis33dev_get_nr_subattrs(curr_index
, "channels");
251 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
252 printf("%s - Configure Input Offset\n"
253 "%s channel_nr value\n"
254 "\tchannel_nr: [0-%d]. -1 to select all channels\n"
255 "\value: 16 bits (max. 0xffff.)\n",
256 cmdd
->name
, cmdd
->name
, n_channels
- 1);
261 if (atoms
->type
== Terminator
)
262 return show_chan_offset_all();
264 if (atoms
->type
!= Numeric
)
265 return -TST_ERR_WRONG_ARG
;
266 if (!WITHIN_RANGE(-1, atoms
->val
, n_channels
- 1))
267 return -TST_ERR_WRONG_ARG
;
268 channel
= atoms
->val
;
271 if (atoms
->type
!= Numeric
)
272 return -TST_ERR_WRONG_ARG
;
273 ret
= set_offset(atoms
->val
, channel
);
277 printf("Updated:\n");
278 return show_chan_offset_all();
281 int h_clksrc(struct cmd_desc
*cmdd
, struct atom
*atoms
)
286 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
287 printf("%s - Configure Clock Source\n"
289 "\tsource: 0 (internal), 1 (external)\n",
290 cmdd
->name
, cmdd
->name
);
295 if (atoms
->type
== Numeric
) {
296 ret
= sis33dev_set_attr_int(curr_index
, "clock_source", atoms
->val
);
298 mperr("set_attr clock_source");
299 return -TST_ERR_SYSCALL
;
302 ret
= sis33dev_get_attr_int(curr_index
, "clock_source", &clksrc
);
304 mperr("get_attr clock_source");
307 if (clksrc
== SIS33_CLKSRC_INTERNAL
)
309 else if (clksrc
== SIS33_CLKSRC_EXTERNAL
)
317 int h_clkfreq(struct cmd_desc
*cmdd
, struct atom
*atoms
)
319 int show_available
= 0;
323 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
324 printf("%s - Get/Set Clock Frequency\n"
326 "\tHz: clock frequency, in Hz.\n",
327 cmdd
->name
, cmdd
->name
);
331 if (atoms
->type
== Terminator
)
333 else if (atoms
->type
== Numeric
) {
335 if (round_uint(curr_index
, "available_clock_frequencies", &val
, SIS33_ROUND_NEAREST
) < 0)
336 return -TST_ERR_SYSCALL
;
337 ret
= sis33dev_set_attr_int(curr_index
, "clock_frequency", val
);
340 return -TST_ERR_SYSCALL
;
343 ret
= sis33dev_get_attr_uint(curr_index
, "clock_frequency", &val
);
349 if (show_available
) {
352 ret
= sis33dev_get_attr(curr_index
, "available_clock_frequencies", clkfreqs
, sizeof(clkfreqs
));
354 mperr("get_attr available_clock_frequencies");
357 printf("Available clock frequencies: %s\n", clkfreqs
);
362 int h_stop_auto(struct cmd_desc
*cmdd
, struct atom
*atoms
)
364 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
365 printf("%s - Get/Set Autostop\n"
367 "Stop sampling for each event after the "
368 "specified number of samples have been collected.\n",
369 cmdd
->name
, cmdd
->name
);
372 return h_attr(atoms
, "stop_auto");
375 int h_ch(struct cmd_desc
*cmdd
, struct atom
*atoms
)
379 n_channels
= sis33dev_get_nr_subattrs(curr_index
, "channels");
383 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
384 printf("%s - Get/Set Channel\n"
386 "\tchannel_nr: 0-%d\n",
387 cmdd
->name
, cmdd
->name
, n_channels
- 1);
392 if (atoms
->type
== Terminator
) {
393 printf("%d\n", channel_nr
);
397 if (atoms
->type
!= Numeric
|| !WITHIN_RANGE(0, atoms
->val
, n_channels
- 1))
398 return -TST_ERR_WRONG_ARG
;
400 channel_nr
= atoms
->val
;
405 int h_ch_next(struct cmd_desc
*cmdd
, struct atom
*atoms
)
409 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
410 printf("%s - Select Next Channel\n", cmdd
->name
);
413 n_channels
= sis33dev_get_nr_subattrs(curr_index
, "channels");
416 if (channel_nr
+ 1 < n_channels
)
422 static void remove_trailing_chars(char *str
, char c
)
429 while (len
> 0 && str
[len
- 1] == c
)
433 static char *mydatetime(const struct timeval
*tv
)
435 static char datetime
[26]; /* length imposed by ctime_r */
439 ctime_r(&time
, datetime
);
440 datetime
[sizeof(datetime
) - 1] = '\0';
441 remove_trailing_chars(datetime
, '\n');
445 static void print_prevticks(const struct sis33_acq
*acqs
, int n
)
451 if (sis33dev_get_attr_int(curr_index
, "event_timestamping_support", &supported
) < 0) {
452 mperr("get_attr event_timestamping_support");
456 printf("This device doesn't support event timestamping\n");
460 for (i
= 0; i
< n
; i
++)
461 printf("%4u 0x%8llx\n", i
, (unsigned long long)acqs
[i
].prevticks
);
462 if (sis33dev_get_attr_int(curr_index
, "event_timestamping_max_ticks_log2", &log2
) < 0) {
463 mperr("get_attr event_timestamping_max_ticks_log2");
466 printf("Note that this counter overflows every 2**%d (0x%llx) ticks\n", log2
, (unsigned long long)1 << log2
);
469 int h_fetch(struct cmd_desc
*cmdd
, struct atom
*atoms
)
471 struct timespec timestart
, timeswap
, timeend
;
473 struct sis33_acq_list
*list
;
474 unsigned int segment
;
478 int show_tstamps
= 0;
481 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
482 printf("%s - Fetch Acquired Data\n"
483 "%s [segment] [timeout_us] [show_tstamps]\n"
484 "\tsegment: segment number. -1 for current (default).\n"
485 "\ttimeout_us: 0 - blocking wait until the acquisition finishes\n"
486 "\t\tn > 0 - blocking wait with timeout equal to n us\n"
487 "\tshow_tstamps: 1 to show all the events' timestamps. Default: 0\n"
488 "Note: If no timeout is provided, no blocking wait is done\n",
489 cmdd
->name
, cmdd
->name
);
494 segment
= curr_segment
;
495 flags
= SIS33_ACQF_DONTWAIT
;
496 if (atoms
->type
== Terminator
)
498 if (atoms
->type
== Numeric
&& atoms
->val
!= -1) {
499 segment
= atoms
->val
;
500 if (segment
< 0 || segment
>= SIS33T_MAX_NR_SEGMENTS
)
501 return -TST_ERR_WRONG_ARG
;
504 if (atoms
->type
== Terminator
)
506 if (atoms
->type
== Numeric
) {
507 if (atoms
->val
> 0) {
508 ts
= my_us_to_timespec(atoms
->val
);
509 flags
= SIS33_ACQF_TIMEOUT
;
510 } else if (atoms
->val
== 0) {
515 if (atoms
->type
== Terminator
)
517 if (atoms
->type
== Numeric
&& atoms
->val
)
520 if (!nr_samples
[segment
] || !nr_events
[segment
]) {
521 fprintf(stderr
, "segment %d: No acquisitions done yet\n", segment
);
522 return -TST_ERR_WRONG_ARG
;
525 list
= &acq_list
[segment
];
526 /* free the complete list in case there's some data already */
528 sis33acq_free(list
->acqs
, list
->n_acqs
);
530 memset(list
, 0, sizeof(*list
));
532 list
->acqs
= sis33acq_zalloc(nr_events
[segment
], nr_samples
[segment
]);
533 if (list
->acqs
== NULL
) {
534 ret
= TST_ERR_SYSCALL
;
537 list
->n_acqs
= nr_events
[segment
];
538 list
->segment
= segment
;
539 list
->channel
= channel_nr
;
542 list
->endtime
.tv_sec
= 0;
543 list
->endtime
.tv_usec
= 0;
545 /* fetch the samples */
546 if (clock_gettime(CLOCK_REALTIME
, ×tart
)) {
547 mperr("clock_gettime() failed for timestart");
548 ret
= -TST_ERR_SYSCALL
;
551 acq_events
= ioctl(sis33fd
, SIS33_IOC_FETCH
, list
);
552 if (acq_events
< 0) {
554 ret
= -TST_ERR_IOCTL
;
557 if (acq_events
< nr_events
[segment
]) {
558 fprintf(stderr
, "Acquired only %d out of %d event%s\n",
559 acq_events
, nr_events
[segment
], nr_events
[segment
] > 1 ? "s" : "");
561 if (clock_gettime(CLOCK_REALTIME
, ×wap
)) {
562 mperr("clock_gettime() failed for timestart");
563 ret
= -TST_ERR_SYSCALL
;
567 if (sis33acq_list_normalize(list
, acq_events
)) {
568 mperr("sis33acq_list_normalize failed");
569 ret
= -TST_ERR_SYSCALL
;
573 if (clock_gettime(CLOCK_REALTIME
, &timeend
)) {
574 mperr("clock_gettime() failed for timestart");
575 ret
= -TST_ERR_SYSCALL
;
579 printf("Acquisition datetime: %s +%06luus\n",
580 mydatetime(&list
->endtime
), list
->endtime
.tv_usec
);
581 delta
= (double)(timeswap
.tv_sec
- timestart
.tv_sec
) * 1000000 +
582 (double)(timeswap
.tv_nsec
- timestart
.tv_nsec
) / 1000.;
583 printf("Acquisition CPU time: %g us\n", delta
);
584 delta
= (double)(timeend
.tv_sec
- timeswap
.tv_sec
) * 1000000 +
585 (double)(timeend
.tv_nsec
- timeswap
.tv_nsec
) / 1000.;
586 printf("swap CPU time: %g us\n", delta
);
588 print_prevticks(list
->acqs
, acq_events
);
594 int exec_trigger(uint32_t trigger
)
598 ret
= sis33dev_set_attr_int(curr_index
, "trigger", trigger
);
600 mperr("set_attr trigger");
601 return -TST_ERR_SYSCALL
;
606 int h_acq(struct cmd_desc
*cmdd
, struct atom
*atoms
)
608 struct sis33_acq_desc desc
;
609 struct timespec timestart
, timeend
;
612 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
613 printf("%s - Start Acquisition\n"
614 "%s segment nr_events ev_length [timeout_us]\n"
615 "\tsegment: segment number [0..%d]\n"
616 "\tnr_events: number of events\n"
617 "\tev_length: number of samples per event\n"
618 "\ttimeout_us: 0 - blocking wait until the acquisition finishes\n"
619 "\t\tn > 0 - blocking wait with timeout equal to n us\n"
620 "Note: If no timeout is provided, no blocking wait is done\n",
621 cmdd
->name
, cmdd
->name
, SIS33T_MAX_NR_SEGMENTS
- 1);
624 memset(&desc
, 0, sizeof(desc
));
626 if (atoms
->type
!= Numeric
)
627 return -TST_ERR_WRONG_ARG
;
628 if (atoms
->val
< 0 || atoms
->val
>= SIS33T_MAX_NR_SEGMENTS
)
629 return -TST_ERR_WRONG_ARG
;
630 desc
.segment
= atoms
->val
;
632 if (atoms
->type
!= Numeric
)
633 return -TST_ERR_WRONG_ARG
;
634 desc
.nr_events
= atoms
->val
;
636 if (atoms
->type
!= Numeric
)
637 return -TST_ERR_WRONG_ARG
;
638 desc
.ev_length
= atoms
->val
;
639 if (round_uint(curr_index
, "available_event_lengths",
640 &desc
.ev_length
, SIS33_ROUND_NEAREST
) < 0)
641 return -TST_ERR_SYSCALL
;
643 if (atoms
->type
== Numeric
) {
644 if (atoms
->val
> 0) {
645 desc
.timeout
= my_us_to_timespec(atoms
->val
);
646 desc
.flags
= SIS33_ACQF_TIMEOUT
;
647 } else if (atoms
->val
== 0)
650 desc
.flags
= SIS33_ACQF_DONTWAIT
;
652 desc
.flags
= SIS33_ACQF_DONTWAIT
;
654 if (clock_gettime(CLOCK_REALTIME
, ×tart
)) {
655 mperr("clock_gettime() failed for timestart");
656 return -TST_ERR_SYSCALL
;
659 if (ioctl(sis33fd
, SIS33_IOC_ACQUIRE
, &desc
) < 0) {
661 return -TST_ERR_IOCTL
;
664 if (clock_gettime(CLOCK_REALTIME
, &timeend
)) {
665 mperr("clock_gettime() failed for timeend");
666 return -TST_ERR_SYSCALL
;
669 curr_segment
= desc
.segment
;
670 nr_events
[curr_segment
] = desc
.nr_events
;
671 nr_samples
[curr_segment
] = desc
.ev_length
;
673 delta
= (double)(timeend
.tv_sec
- timestart
.tv_sec
) * 1000000 +
674 (double)(timeend
.tv_nsec
- timestart
.tv_nsec
) / 1000.;
676 printf("events: %d\nev_length: %d\n", nr_events
[curr_segment
], nr_samples
[curr_segment
]);
677 printf("acquisition: time elapsed: %g us\n", delta
);
682 int h_cancel(struct cmd_desc
*cmdd
, struct atom
*atoms
)
686 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
687 printf("%s - Cancel Acquisition\n", cmdd
->name
);
691 ret
= sis33dev_set_attr_int(curr_index
, "acq_cancel", 1);
693 mperr("set_attr acq_cancel");
694 return -TST_ERR_SYSCALL
;
699 int h_start(struct cmd_desc
*cmdd
, struct atom
*atoms
)
701 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
702 printf("%s - Start Sampling\n", cmdd
->name
);
705 return exec_trigger(SIS33_TRIGGER_START
);
708 int h_stop(struct cmd_desc
*cmdd
, struct atom
*atoms
)
710 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
711 printf("%s - Stop Sampling\n", cmdd
->name
);
714 return exec_trigger(SIS33_TRIGGER_STOP
);
717 static void gnuplot_append(const char *string
)
719 strncat(gnuplot
, string
, sizeof(gnuplot
) - strlen(gnuplot
));
720 gnuplot
[sizeof(gnuplot
) - 1] = '\0';
723 static void gnuplot_init(int sis33_index
)
728 if (sis33dev_get_attr(sis33_index
, "n_bits", value
, sizeof(value
))) {
729 fprintf(stderr
, "Warning: Cannot get n_bits of device %u\n", sis33_index
);
731 int n_bits
= strtol(value
, NULL
, 0);
734 snprintf(str
, sizeof(str
), "set yrange [0:%d]; ", 1 << n_bits
);
735 str
[sizeof(str
) - 1] = '\0';
740 static int write_samp_data_to_disk(int segment
)
743 const char *filename
;
744 unsigned long acq_samples
;
747 if (!nr_events
[segment
] || !nr_samples
[segment
]) {
748 fprintf(stderr
, "Error: not acquired any data.\n");
749 return -TST_ERR_WRONG_ARG
;
752 if (sis33dev_get_devname(curr_index
, devname
, sizeof(devname
)) < 0) {
753 mperr("sis33dev_get_devname");
754 return -TST_ERR_SYSCALL
;
756 gnuplot_init(curr_index
);
758 for (i
= 0; i
< acq_list
[segment
].n_acqs
; i
++) {
759 if (acq_list
[segment
].acqs
[i
].nr_samples
== 0)
761 filename
= write_file(devname
, &acq_list
[segment
], segment
, i
);
762 /* we don't get the error back. Assume it's SYSCALL */
763 if (filename
== NULL
)
764 return -TST_ERR_SYSCALL
;
766 gnuplot_append("plot ");
768 gnuplot_append(", ");
770 gnuplot_append(filename
);
771 gnuplot_append("' with linespoints");
772 acq_samples
+= acq_list
[segment
].acqs
[i
].nr_samples
;
774 if (acq_samples
== 0)
775 fprintf(stderr
, "No samples were acquired on segment %d\n", segment
);
779 int h_wf(struct cmd_desc
*cmdd
, struct atom
*atoms
)
781 int segment
= curr_segment
;
783 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
784 printf("%s [segment] - Write acquired data to a file\n"
785 "segment: segment number. Leave empty for current.\n"
786 "Note. The file will be located at /tmp/<curr_device>.ev<n>.<channel>.dat\n",
791 if (atoms
->type
== Terminator
)
793 if (atoms
->type
!= Numeric
)
794 return -TST_ERR_WRONG_ARG
;
795 if (atoms
->val
< 0 || atoms
->val
>= SIS33T_MAX_NR_SEGMENTS
)
796 return -TST_ERR_WRONG_ARG
;
797 segment
= atoms
->val
;
800 return write_samp_data_to_disk(segment
);
803 static void show_devices(void)
811 ndevs
= sis33dev_get_nr_devices();
814 indexes
= calloc(ndevs
, sizeof(*indexes
));
815 if (indexes
== NULL
) {
819 if (sis33dev_get_device_list(indexes
, ndevs
) < 0) {
820 mperr("sis33dev_get_device_list");
824 for (i
= 0; i
< ndevs
; i
++) {
826 int index
= indexes
[i
];
828 if (index
== curr_index
)
833 printf("\t%2d", index
);
834 if (sis33dev_get_devname(index
, devname
, sizeof(devname
)) < 0) {
835 fprintf(stderr
, "dev%d: retrieval of 'devname' failed\n", index
);
838 printf("\t%8s", devname
);
840 if (sis33dev_get_attr(index
, "description", value
, sizeof(value
))) {
841 fprintf(stderr
, "dev%d: retrieval of 'description' failed\n", index
);
844 printf("\t%s", value
);
846 n_channels
= sis33dev_get_nr_subattrs(index
, "channels");
847 if (n_channels
< 0) {
848 fprintf(stderr
, "dev%d: retrieval of 'n_channels' failed\n", index
);
851 printf("\t%2d", n_channels
);
853 if (sis33dev_get_attr(index
, "n_bits", value
, sizeof(value
))) {
854 fprintf(stderr
, "dev%d: retrieval of 'n_bits' failed\n", index
);
857 printf("\t%2s", value
);
865 static int __h_device(int index
)
867 char file
[SIS33_PATH_MAX
];
870 if (!sis33dev_device_exists(index
)) {
871 fprintf(stderr
, "Device with index %d doesn't exist\n", index
);
872 return -TST_ERR_WRONG_ARG
;
881 if (sis33dev_get_devname(index
, devname
, sizeof(devname
)) < 0) {
882 mperr("sis33dev_get_devname");
883 return -TST_ERR_SYSCALL
;
885 snprintf(file
, sizeof(file
), "/dev/%s", devname
);
886 file
[sizeof(file
) - 1] = '\0';
887 sis33fd
= open(file
, O_RDWR
, 0);
890 return -TST_ERR_SYSCALL
;
898 int h_device(struct cmd_desc
*cmdd
, struct atom
*atoms
)
900 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
901 printf("%s - Set device\n"
902 "%s - Show available devices\n"
904 "curr\tindex\tdev_name\tdetailed_name\tn_channels\tn_bits\n"
906 "\tindex: set device to that given by the index\n",
907 cmdd
->name
, cmdd
->name
, cmdd
->name
);
912 if (atoms
->type
== Terminator
) {
917 if (atoms
->type
!= Numeric
)
918 return -TST_ERR_WRONG_ARG
;
920 return __h_device(atoms
->val
);
923 int h_device_next(struct cmd_desc
*cmdd
, struct atom
*atoms
)
930 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
931 printf("%s - Set next available device\n", cmdd
->name
);
935 ndevs
= sis33dev_get_nr_devices();
938 indexes
= calloc(ndevs
, sizeof(*indexes
));
939 if (indexes
== NULL
) {
941 return -TST_ERR_SYSCALL
;
943 if (sis33dev_get_device_list(indexes
, ndevs
) < 0) {
944 mperr("sis33dev_get_device_list");
945 ret
= -TST_ERR_SYSCALL
;
949 for (i
= 0; i
< ndevs
; i
++) {
950 if (indexes
[i
] == curr_index
)
954 fprintf(stderr
, "curr_index %d not in the devices' list. Has it been removed?\n", curr_index
);
955 ret
= -TST_ERR_WRONG_ARG
;
961 ret
= __h_device(indexes
[i
+ 1]);
967 int h_plot(struct cmd_desc
*cmdd
, struct atom
*atoms
)
969 char cmd
[sizeof(gnuplot
) + 128];
970 int segment
= curr_segment
;
974 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
975 printf("%s [segment] [term] - Plot acquired data\n"
976 "Note: the data must have previously been written to disk\n"
977 "segment: segment number (-1 for current, default)\n"
979 "\t0: Use 'dumb' terminal. Default.\n"
980 "\t1: Use 'X11' terminal.\n",
986 if (atoms
->type
== Terminator
)
988 if (atoms
->type
!= Numeric
)
989 return -TST_ERR_WRONG_ARG
;
990 if (atoms
->val
< -1 || atoms
->val
>= SIS33T_MAX_NR_SEGMENTS
)
991 return -TST_ERR_WRONG_ARG
;
993 segment
= atoms
->val
;
996 if (atoms
->type
== Numeric
) {
997 if (atoms
->val
!= 0 && atoms
->val
!= 1) {
998 fprintf(stderr
, "Invalid terminal type %d\n", atoms
->val
);
999 return -TST_ERR_WRONG_ARG
;
1001 term
= !!atoms
->val
;
1004 /* we need the data on disk in order to plot it */
1005 ret
= write_samp_data_to_disk(segment
);
1008 if (gnuplot
[0] == '\0') {
1009 fprintf(stderr
, "No data available\n");
1013 snprintf(cmd
, sizeof(cmd
), "echo \"%s%s\" | gnuplot -persist",
1014 term
? "set term x11; " : "set term dumb; ", gnuplot
);
1015 cmd
[sizeof(cmd
) - 1] = '\0';
1021 int h_segments(struct cmd_desc
*cmdd
, struct atom
*atoms
)
1023 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
1024 printf("%s [segment_nr] - Get/Set number of segments\n"
1025 "segment_nr: segment number to be set\n", cmdd
->name
);
1028 return h_uattr(atoms
, "n_segments");
1031 int h_ts_divider(struct cmd_desc
*cmdd
, struct atom
*atoms
)
1036 if (atoms
== (struct atom
*)VERBOSE_HELP
) {
1037 printf("%s [value] - Get/Set event timestamping clock divider\n"
1038 "value: desired divider value\n", cmdd
->name
);
1041 ret
= h_attr(atoms
, "event_timestamping_divider");
1044 ret
= sis33dev_get_attr_int(curr_index
, "event_timestamping_divider_max", &val
);
1049 printf("max: %d\n", val
);
1053 int main(int argc
, char *argv
[], char *envp
[])
1055 char file
[SIS33_PATH_MAX
];
1060 /* try to control the first device */
1061 ndevs
= sis33dev_get_nr_devices();
1064 indexes
= calloc(ndevs
, sizeof(*indexes
));
1065 if (indexes
== NULL
) {
1069 if (sis33dev_get_device_list(indexes
, ndevs
) < 0) {
1070 mperr("sis33dev_get_device_list");
1073 if (sis33dev_get_devname(indexes
[0], devname
, sizeof(devname
)) < 0) {
1074 mperr("sis33dev_get_devname");
1077 snprintf(file
, sizeof(file
), "/dev/%s", devname
);
1078 file
[sizeof(file
) - 1] = '\0';
1079 sis33fd
= open(file
, O_RDWR
, 0);
1083 curr_index
= indexes
[0];
1087 return extest_init(argc
, argv
);
1115 struct cmd_desc user_cmds
[] = {
1116 { 1, CmdACQ
, "acq", "Start Acquisition", "segment nr_events ev_length [timeout_us]", 0,
1118 { 1, CmdCANCEL
, "cancel", "Cancel Acquisition", "", 0,
1121 { 1, CmdCH
, "ch", "Get/Set Channel", "[0,n-1]", 0,
1123 { 1, CmdCH_NEXT
, "ch_next", "Next Channel", "", 0,
1126 { 1, CmdCLKSRC
, "clksrc", "Clock Source", "[src]", 0,
1128 { 1, CmdCLKFREQ
, "clkfreq", "Clock Frequency", "[Hz]", 0,
1131 { 1, CmdDEVICE
, "device", "Set device", "[index]", 0,
1133 { 1, CmdDEVICE_NEXT
, "device_next", "Set next device", "", 0,
1136 { 1, CmdFETCH
, "fetch", "Fetch Acquired Data", "[segment] [timeout_us] [show_tstamps]", 0,
1139 { 1, CmdOFFSET
, "offset", "Input Offset", "channel value", 0,
1142 { 1, CmdPLOT
, "plot", "Plot sampled data", "[segment] [term]", 0,
1145 { 1, CmdSEGMENTS
, "segments", "Get/Set number of segments", "[nr_segments]", 0,
1148 { 1, CmdSTART
, "start", "Start Sampling", "", 0,
1150 { 1, CmdSTART_AUTO
, "start_auto", "Get/Set Autostart", "bool", 0,
1152 { 1, CmdSTART_DELAY
, "start_delay", "Start delay", "val", 0,
1155 { 1, CmdSTOP
, "stop", "Stop Sampling", "", 0,
1157 { 1, CmdSTOP_AUTO
, "stop_auto", "Enable Autostop", "bool", 0,
1159 { 1, CmdSTOP_DELAY
, "stop_delay", "Stop delay", "val", 0,
1162 { 1, CmdTRIG_EXT
, "trig_ext", "En/Disable external trigger", "bool", 0,
1165 { 1, CmdTS_DIVIDER
, "ts_divider", "Get/Set the timestamp divider", "[value]", 0,
1168 { 1, CmdWF
, "wf", "Write File", "[segment]", 0,