Commit f813f1e7 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

test: full test program suite

parent b7eab1d2
......@@ -2,7 +2,7 @@
.PHONY: all clean modules install modules_install
.PHONY: gitmodules prereq prereq_install prereq_install_warn
DIRS = kernel lib
DIRS = kernel lib test
all clean modules install modules_install: gitmodules
for d in $(DIRS); do $(MAKE) -C $$d $@ || exit 1; done
......
TESTS = fmctdc-list \
fmctdc-term \
fmctdc-read \
fmctdc-acquisition \
fmctdc-temperature \
fmctdc-time
CFLAGS = -I. -I../lib -I../kernel -Wall -ggdb3
TESTS = fmctdc-list fmctdc-term fmctdc-read fmctdc-acquisition
COMMON_SRCS = test-common.c
LDFLAGS = -L../lib -lfmctdc
......
......@@ -16,34 +16,36 @@
int main(int argc, char **argv)
{
init (argc, argv);
check_help(argc, argv, 2,
"[-h] <device> [on/off]",
"Enables or disables acquisition (that is, all inputs simultaneosly). Disabling acquisition\n"
"also empties the timestamp buffers.",
"");
open_board(argv[1]);
if (argc == 2)
{
printf("board %s: acquisition is %s\n", argv[1], fmctdc_get_acquisition(brd) ? "on" : "off" );
} else if (argc > 2) {
int on;
if(!strcmp(argv[2], "on"))
on = 1;
else if(!strcmp(argv[2], "off"))
on = 0;
else {
fprintf(stderr,"%s: on/off expected.\n", argv[0]);
return -1;
}
init(argc, argv);
check_help(argc, argv, 2,
"[-h] <device> [on/off]",
"Enables or disables acquisition (that is, all inputs simultaneosly). Disabling acquisition\n"
"also empties the timestamp buffers.", "");
open_board(argv[1]);
if (argc == 2) {
printf("board %s: acquisition is %s\n", argv[1],
fmctdc_get_acquisition(brd) ? "on" : "off");
} else if (argc > 2) {
int on;
if( fmctdc_set_acquisition(brd, on) < 0);
return -1;
}
if (!strcmp(argv[2], "on"))
on = 1;
else if (!strcmp(argv[2], "off"))
on = 0;
else {
fprintf(stderr, "%s: on/off expected.\n", argv[0]);
return -1;
}
if (fmctdc_set_acquisition(brd, on) < 0) {
perror("fmctdc_set_acquisition()");
return -1;
}
}
return 0;
}
\ No newline at end of file
return 0;
}
......@@ -16,25 +16,22 @@
int main(int argc, char **argv)
{
int i;
int i;
init(argc, argv);
init(argc, argv);
check_help(argc, argv, 1,
"[-h]",
"lists all installed fmc-tdc boards.",
"");
check_help(argc, argv, 1,
"[-h]", "lists all installed fmc-tdc boards.", "");
printf("Found %i board(s): \n", n_boards);
printf("Found %i board(s): \n", n_boards);
for (i = 0; i < n_boards; i++)
{
struct __fmctdc_board *b;
struct fmctdc_board *ub;
for (i = 0; i < n_boards; i++) {
struct __fmctdc_board *b;
struct fmctdc_board *ub;
ub = fmctdc_open(i, -1);
b = (typeof(b))ub;
printf("%04x, %s, %s\n", b->dev_id, b->devbase, b->sysbase);
}
return 0;
}
\ No newline at end of file
ub = fmctdc_open(i, -1);
b = (typeof(b)) ub;
printf("%04x, %s, %s\n", b->dev_id, b->devbase, b->sysbase);
}
return 0;
}
......@@ -13,130 +13,136 @@
#include "test-common.h"
void dump_timestamp(struct fmctdc_time ts, int channel, int fmt_wr)
{
if (fmt_wr)
printf("channel %d seq %-12u ts %10llu:%09u:%04u\n", channel,
ts.seq_id, ts.seconds, ts.coarse, ts.frac);
else {
uint64_t picoseconds =
(uint64_t) ts.coarse * 8000ULL +
(uint64_t) ts.frac * 8000ULL / 4096ULL;
printf
("channel %d seq %-12u ts %10llu.%03llu,%03llu,%03llu,%03llu ps\n",
channel, ts.seq_id, ts.seconds,
picoseconds / 1000000000ULL,
(picoseconds / 1000000ULL) % 1000ULL,
(picoseconds / 1000ULL) % 1000ULL, picoseconds % 1000ULL);
}
}
int main(int argc, char **argv)
{
int channels [FMCTDC_NUM_CHANNELS];
int chan_count = 0, i, n;
int non_block = 0;
int n_samples = -1;
int fmt_wr = 0;
char opt;
fd_set rfds;
int channels[FMCTDC_NUM_CHANNELS];
int chan_count = 0, i, n;
int non_block = 0;
int n_samples = -1;
int fmt_wr = 0;
int stop = 0;
char opt;
fd_set rfds;
init (argc, argv);
init(argc, argv);
check_help(argc, argv, 2,
"[options] <device> [channels]",
"reads timestamps from the selected fmc-tdc channels. No [channels] means all channels.",
"Options are:\n"
" -n: non-blocking mode\n"
" -s n_samples: keep reading until n_samples timestamps\n"
" -w: dump timestamps in hardware (White Rabbit) format\n"
" -h: print this message\n"
);
while ((opt = getopt(argc, argv, "wns:")) != -1) {
switch(opt)
{
case 's':
sscanf(optarg,"%i", &n_samples);
break;
case 'n':
non_block = 1;
break;
case 'w':
fmt_wr = 1;
break;
"[options] <device> [channels]",
"reads timestamps from the selected fmc-tdc channels. No [channels] means all channels.",
"Options are:\n"
" -n: non-blocking mode\n"
" -s n_samples: keep reading until n_samples timestamps\n"
" -w: dump timestamps in hardware (White Rabbit) format\n"
" -h: print this message\n");
while ((opt = getopt(argc, argv, "wns:")) != -1) {
switch (opt) {
case 's':
sscanf(optarg, "%i", &n_samples);
break;
case 'n':
non_block = 1;
break;
case 'w':
fmt_wr = 1;
break;
}
}
}
if(optind >= argc)
{
fprintf(stderr,"%s: device ID expected\n", argv[0]);
return -1;
}
if (optind >= argc) {
fprintf(stderr, "%s: device ID expected\n", argv[0]);
return -1;
}
open_board(argv[optind++]);
open_board(argv[optind++]);
memset(channels, 0, sizeof(channels));
memset(channels, 0, sizeof(channels));
/* parse channel list */
while(optind < argc)
{
int ch = atoi(argv[optind]);
/* parse channel list */
while (optind < argc) {
int ch = atoi(argv[optind]);
if(ch < FMCTDC_CH_1 || ch > FMCTDC_CH_LAST)
{
fprintf(stderr,"%s: invalid channel.\n", argv[0]);
return -1;
}
optind++;
channels[ch - FMCTDC_CH_1] = fmctdc_fileno_channel(brd, ch);
chan_count++;
}
if (ch < FMCTDC_CH_1 || ch > FMCTDC_CH_LAST) {
fprintf(stderr, "%s: invalid channel.\n", argv[0]);
return -1;
}
optind++;
channels[ch - FMCTDC_CH_1] = fmctdc_fileno_channel(brd, ch);
if(!chan_count)
{
for(i = FMCTDC_CH_1; i <= FMCTDC_CH_LAST; i++)
channels[i - FMCTDC_CH_1] = fmctdc_fileno_channel(brd, i);
chan_count = FMCTDC_NUM_CHANNELS;
}
chan_count++;
}
n = 0;
if (!chan_count) {
for (i = FMCTDC_CH_1; i <= FMCTDC_CH_LAST; i++)
channels[i - FMCTDC_CH_1] =
fmctdc_fileno_channel(brd, i);
chan_count = FMCTDC_NUM_CHANNELS;
}
while(n < n_samples || n_samples < 0)
{
struct fmctdc_time ts;
struct timeval tv = {0, 0};
n = 0;
FD_ZERO(&rfds);
while (!stop) {
struct fmctdc_time ts;
stop = 1;
for(i = FMCTDC_CH_1; i <= FMCTDC_CH_LAST; i++)
{
int fd = channels [i - FMCTDC_CH_1];
if( fd < 0)
{
fprintf(stderr, "Can't open channel %d\n", i);
return -1;
}
if( fd > 0)
FD_SET(fd, &rfds);
}
FD_ZERO(&rfds);
if( select (FMCTDC_NUM_CHANNELS + 1, &rfds, NULL, NULL, non_block ? &tv : NULL) <= 0)
{
if(non_block)
break;
else
continue;
}
for(i = FMCTDC_CH_1; i <= FMCTDC_CH_LAST; i++)
{
int fd = channels[i - FMCTDC_CH_1];
if( fd && FD_ISSET(fd, &rfds) && fmctdc_read (brd, i, &ts, 1, 0) == 1)
{
if(fmt_wr)
printf("channel %d seq %-12u ts %10llu:%09u:%04u\n", i, ts.seq_id, ts.seconds, ts.coarse, ts.frac);
else
{
uint64_t picoseconds = (uint64_t) ts.coarse * 8000ULL + (uint64_t) ts.frac * 8000ULL / 4096ULL;
printf("channel %d seq %-12u ts %10llu.%03llu,%03llu,%03llu,%03llu ps\n", i, ts.seq_id, ts.seconds,
picoseconds / 1000000000ULL,
(picoseconds / 1000000ULL) % 1000ULL,
(picoseconds / 1000ULL) % 1000ULL,
picoseconds % 1000ULL
);
for (i = FMCTDC_CH_1; i <= FMCTDC_CH_LAST; i++) {
int fd = channels[i - FMCTDC_CH_1];
if (fd < 0) {
fprintf(stderr, "Can't open channel %d\n", i);
return -1;
} else if (fd > 0)
FD_SET(fd, &rfds);
}
n++;
if(n == n_samples)
break;
}
/* non-blocking mode: do nothing, otherwise wait until one of the channels becomes active */
if (!non_block
&& select(FMCTDC_NUM_CHANNELS + 1, &rfds, NULL, NULL,
NULL) <= 0)
continue;
for (i = FMCTDC_CH_1; i <= FMCTDC_CH_LAST; i++) {
int fd = channels[i - FMCTDC_CH_1];
if (fd > 0) {
int got_data = 0;
if (non_block || FD_ISSET(fd, &rfds))
got_data =
fmctdc_read(brd, i, &ts, 1,
non_block ? O_NONBLOCK :
0) == 1;
if (got_data) {
dump_timestamp(ts, i, fmt_wr);
n++;
if (n < n_samples || n_samples <= 0)
stop = 0;
}
}
}
}
}
return 0;
return 0;
}
/*
* The fmc-tdc (a.k.a. FmcTdc1ns5cha) library test program.
*
* Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*
* fmctdc-time: read board temperature
*/
#include "test-common.h"
int main(int argc, char **argv)
{
init(argc, argv);
check_help(argc, argv, 2,
"[-h] <device>",
"Displays current temperature of the mezzanine.\n", "");
open_board(argv[1]);
printf("%.1f deg C\n", fmctdc_read_temperature(brd));
return 0;
}
......@@ -15,54 +15,51 @@
int main(int argc, char **argv)
{
init (argc, argv);
init(argc, argv);
check_help(argc, argv, 2,
"[-h] <device> <channel> [on/off]",
"Enables or disables the 50 Ohm termination of a given input channel.\n"
"No on/off command returns the current state of termination resistor.",
"");;
check_help(argc, argv, 2,
"[-h] <device> <channel> [on/off]",
"Enables or disables the 50 Ohm termination of a given input channel.\n"
"No on/off command returns the current state of termination resistor.",
"");;
open_board(argv[1]);
open_board(argv[1]);
if (argc == 2)
{
int i;
for(i = FMCTDC_CH_1; i <= FMCTDC_CH_LAST; i++)
printf("channel %d: 50 Ohm termination is %s\n", i,
fmctdc_get_termination(brd, i) ? "on" : "off");
return 0;
}
int channel = atoi(argv[2]);
if (argc == 2) {
int i;
for (i = FMCTDC_CH_1; i <= FMCTDC_CH_LAST; i++)
printf("channel %d: 50 Ohm termination is %s\n", i,
fmctdc_get_termination(brd, i) ? "on" : "off");
return 0;
}
if(channel < FMCTDC_CH_1 || channel > FMCTDC_CH_LAST)
{
fprintf(stderr,"%s: invalid channel.\n", argv[0]);
return -1;
}
int channel = atoi(argv[2]);
if(argc >= 4)
{
int term_on;
if(!strcasecmp(argv[3],"on"))
term_on = 1;
else if(!strcasecmp(argv[3],"off"))
term_on = 0;
else {
fprintf(stderr,"%s: invalid command.\n", argv[0]);
return -1;
if (channel < FMCTDC_CH_1 || channel > FMCTDC_CH_LAST) {
fprintf(stderr, "%s: invalid channel.\n", argv[0]);
return -1;
}
if( fmctdc_set_termination(brd, channel, term_on) < 0)
{
fprintf(stderr,"%s: error setting termination: %s\n", argv[0], strerror(errno));
return -1;
if (argc >= 4) {
int term_on;
if (!strcasecmp(argv[3], "on"))
term_on = 1;
else if (!strcasecmp(argv[3], "off"))
term_on = 0;
else {
fprintf(stderr, "%s: invalid command.\n", argv[0]);
return -1;
}
if (fmctdc_set_termination(brd, channel, term_on) < 0) {
fprintf(stderr, "%s: error setting termination: %s\n",
argv[0], strerror(errno));
return -1;
}
}
}
printf("channel %d: 50 Ohm termination is %s\n", channel,
fmctdc_get_termination(brd, channel) ? "on" : "off");
printf("channel %d: 50 Ohm termination is %s\n", channel,
fmctdc_get_termination(brd, channel) ? "on" : "off");
return 0;
return 0;
}
/*
* The fmc-tdc (a.k.a. FmcTdc1ns5cha) library test program.
*
* Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libgen.h>
#define FMCTDC_INTERNAL /* hack... */
#include "fmctdc-lib.h"
int n_boards;
struct fmctdc_board *brd;
int go_identify(int argc, char **argv);
int go_list(int argc, char **argv);
int go_read(int argc, char **argv);
int go_time(int argc, char **argv);
int go_termination(int argc, char **argv);
int go_test(int argc, char **argv);
static struct subprogram {
char *name;
int (*go)(int argc, char **argv);
} subprograms[] = {
{ "fmctdc-identify", go_identify },
{ "fmctdc-list", go_list },
{ NULL, NULL },
} ;
void usage_msg(const char *name, const char *msg)
{
printf("usage: %s %s\n", name, msg);
exit(0);
}
int open_board(char *dev_id_str)
{
unsigned int dev_id;
if(sscanf(dev_id_str, "%04x", &dev_id) != 1)
return -1;
brd = fmctdc_open(-1, dev_id);
if(!brd)
{
fprintf(stderr, "can't open device %s: %s\n", dev_id_str, strerror(errno));
return -1;
}
return 0;
}
int check_help(int argc, char **argv, int min_args, char *usage, char *desc, char *options)
{
if (argc >= 2 && !strcmp(argv[1], "-h"))
{
printf("%s: %s\n", argv[0], desc);
printf("usage: %s %s\n", argv[0], usage);
printf("%s\n", options);
return 1;
} else if(argc < min_args)
{
printf("usage: %s %s\n", argv[0], usage);
return 1;
}
return 0;
}
int go_identify(int argc, char **argv)
{
if(check_help(argc, argv, 2,
"[-h] <device>",
"identifies a given fmc-tdc device in a crate by blinking its status LEDs.",
""))
return 0;
if(open_board(argv[1]) < 0)
return -1;
printf("Blinking the status LEDs. Press Enter to stop.\n");
fmctdc_identify_card(brd, 1);
getchar();
fmctdc_identify_card(brd, 0);
return 0;
}
int go_list(int argc, char **argv)
{
int i;
if(check_help(argc, argv, 1,
"[-h]",
"lists all installed fmc-tdc boards.",
""))
return 0;
printf("Found %i board(s): \n", n_boards);
for (i = 0; i < n_boards; i++)
{
struct __fmctdc_board *b;
struct fmctdc_board *ub;
ub = fmctdc_open(i, -1);
b = (typeof(b))ub;
printf("%04x, %s, %s\n", b->dev_id, b->devbase, b->sysbase);
}
return 0;
}
int go_read(int argc, char **argv)
{
int non_block = 0;
if(check_help(argc, argv, 3,
"[-h] [-n] <channels> <n_samples>",
"reads timestamps from the selected fmc-tdc channels.",
" -n: non-blocking mode\n"
"When n_samples == 0, program will keep reading samples until interrupted."
))
return 0;
if(!strcmp(argv[1], "-n"))
non_block = 1;
return 0;
}
int main(int argc, char **argv)
{
int rv = 0;
struct subprogram *sp;
n_boards = fmctdc_init();
if (n_boards < 0) {
fprintf(stderr, "%s: fdelay_init(): %s\n", argv[0],
strerror(errno));
exit(1);
}
for(sp = subprograms; sp->name; sp++)
if (!strcmp(sp->name, basename(argv[0]))) {
rv = sp->go(argc, argv);
break;
}
// rv = go_test(argc, argv);
fmctdc_exit();
return rv;
}
\ No newline at end of file
/*
* The fmc-tdc (a.k.a. FmcTdc1ns5cha) library test program.
*
* Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2 as published by the Free Software Foundation or, at your
* option, any later version.
*
* fmctdc-time: get/set board time
*/
#include "test-common.h"
int main(int argc, char **argv)
{
struct fmctdc_time ts;
char *cmd;
init(argc, argv);
check_help(argc, argv, 3,
"[-h] <device> <command> [timeval]",
"Gets/sets the mezzanine TAI time.",
"Commands are:"
"get - prints current TAI time"
"set <seconds> - sets TAI time"
"host - sets TAI time to current host time");
open_board(argv[1]);
cmd = argv[2];
if (!strcmp(cmd, "get")) {
if (fmctdc_get_time(brd, &ts) < 0) {
perror("fmctdc_get_time()");
return -1;
}
printf("Current TAI time is %lld.%09d s\n", ts.seconds,
ts.coarse * 8);
} else if (!strcmp(cmd, "set")) {
if (argc < 4) {
fprintf(stderr, "%s: time value expected\n", argv[0]);
}
ts.coarse = 0;
ts.seconds = atoi(argv[3]);
if (fmctdc_set_time(brd, &ts) < 0) {
perror("fmctdc_set_time()");
fprintf(stderr,
"Hint: are trying to change time while acquisition is enabled?\n");
return -1;
}
} else if (!strcmp(cmd, "host")) {
if (fmctdc_set_host_time(brd) < 0) {
perror("fmctdc_set_host_time()");
fprintf(stderr,
"Hint: are trying to change time while acquisition is enabled?\n");
return -1;
}
} else {
fprintf(stderr, "%s: unrecognized command.\n", cmd);
return -1;
}
return 0;
}
......@@ -14,60 +14,60 @@
#include "test-common.h"
int n_boards;
struct fmctdc_board *brd;
struct fmctdc_board *brd = NULL;
void usage_msg(const char *name, const char *msg)
{
printf("usage: %s %s\n", name, msg);
exit(0);
printf("usage: %s %s\n", name, msg);
exit(0);
}
void open_board(char *dev_id_str)
{
unsigned int dev_id;
if(sscanf(dev_id_str, "%04x", &dev_id) != 1)
{
fprintf(stderr, "Error parsing device ID %s\n", dev_id_str);
exit(-1);
if (sscanf(dev_id_str, "%04x", &dev_id) != 1) {
fprintf(stderr, "Error parsing device ID %s\n", dev_id_str);
exit(-1);
}
brd = fmctdc_open(-1, dev_id);
if(!brd)
{
fprintf(stderr, "Can't open device %s: %s\n", dev_id_str, strerror(errno));
if (!brd) {
fprintf(stderr, "Can't open device %s: %s\n", dev_id_str,
strerror(errno));
exit(-1);
}
}
void check_help(int argc, char **argv, int min_args, char *usage, char *desc, char *options)
void check_help(int argc, char **argv, int min_args, char *usage, char *desc,
char *options)
{
if (argc >= 2 && !strcmp(argv[1], "-h"))
{
if (argc >= 2 && !strcmp(argv[1], "-h")) {
printf("%s: %s\n", argv[0], desc);
printf("usage: %s %s\n", argv[0], usage);
printf("%s\n", options);
exit(0);
} else if(argc < min_args)
{
} else if (argc < min_args) {
printf("usage: %s %s\n", argv[0], usage);
exit(0);
}
}
}
static void cleanup()
{
fmctdc_exit();
if (brd)
fmctdc_close(brd);
fmctdc_exit();
}
void init(int argc, char *argv[])
{
n_boards = fmctdc_init();
if (n_boards < 0) {
fprintf(stderr, "%s: fmctdc_init(): %s\n", argv[0],
strerror(errno));
exit(1);
}
n_boards = fmctdc_init();
if (n_boards < 0) {
fprintf(stderr, "%s: fmctdc_init(): %s\n", argv[0],
strerror(errno));
exit(1);
}
atexit(cleanup);
atexit(cleanup);
}
......@@ -20,18 +20,20 @@
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
#include "fmctdc-lib.h"
#include "fmctdc-lib-private.h" /* for some extra debugging stuff */
#include "fmctdc-lib-private.h" /* for some extra debugging stuff */
extern int n_boards;
extern struct fmctdc_board *brd;
void usage_msg(const char *name, const char *msg);
void open_board(char *dev_id_str);
void check_help(int argc, char **argv, int min_args, char *usage, char *desc, char *options);
void check_help(int argc, char **argv, int min_args, char *usage, char *desc,
char *options);
void init(int argc, char *argv[]);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment