Commit b45c54a1 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Federico Vaga

tools: clean up fmc-tdc-perftest a bit

Signed-off-by: Tomasz Wlostowski's avatarTomasz Wlostowski <tomasz.wlostowski@cern.ch>
parent 3f262454
......@@ -29,7 +29,8 @@ char git_version[] = "git_version: " GIT_VERSION;
/* Previous time stamp for each channel */
static unsigned int stop = 0;
enum tstamp_print_format {
enum tstamp_print_format
{
TSTAMP_FMT_PS = 0,
TSTAMP_FMT_WR,
};
......@@ -42,9 +43,8 @@ enum tstamp_print_format {
*/
static inline void print_ts_wr(struct fmctdc_time ts)
{
fprintf(stderr, "%10"PRIu64":%09u:%04u seq %-10d",
ts.seconds, ts.coarse, ts.frac, ts.seq_id);
fprintf(stderr, "%10" PRIu64 ":%09u:%04u seq %-10d",
ts.seconds, ts.coarse, ts.frac, ts.seq_id);
}
/**
......@@ -57,7 +57,7 @@ static void help(char *name)
"%s -D <device> -c <channel> -n <number_of_samples>\n",
basename(name));
fprintf(stderr,
"reads timestamps from fmc-tdc channels, measures the readout performance & correctness.\n\n");
"reads timestamps from fmc-tdc channels, measures the readout performance & correctness.\n\n");
}
/**
......@@ -77,7 +77,8 @@ uint64_t delta_max = 0;
double avg_acc = 0.0;
int misses = 0;
typedef struct {
typedef struct
{
int repeat;
uint64_t start_tics;
uint64_t timeout;
......@@ -97,7 +98,7 @@ int tmo_init(timeout_t *tmo, uint32_t milliseconds, int repeat)
{
tmo->repeat = repeat;
tmo->start_tics = get_monotonic_us();
tmo->timeout = (uint64_t) milliseconds * 1000ULL;
tmo->timeout = (uint64_t)milliseconds * 1000ULL;
return 0;
}
......@@ -119,65 +120,111 @@ int tmo_expired(timeout_t *tmo)
return expired;
}
int64_t max_span = 2000;
static int prev_fine = 0;
static int64_t avg_delta_d = 0;
static int delta_stab_count = 0;
static const int64_t max_delta_span = 2000;
static int delta_stable = 0;
void process_timestamps( struct fmctdc_time *ts, int n_ts )
void process_timestamps(struct fmctdc_time *ts, int n_ts)
{
int i;
for(i = 0; i < n_ts; i++)
{
if ( ts->seq_id < 3 ) // skip first few ts, just to be sure the buffer has been flushed
for (i = 0; i < n_ts; i++) {
int fine = ts[i].debug & 0x1fff;
if (ts->seq_id < 10) /* skip first few ts, just to be sure
the buffer has been flushed */
continue;
if (total_samples > 0)
{
struct fmctdc_time delta;
delta = ts[i];
fmctdc_ts_sub( &delta, &prev_ts );
fmctdc_ts_sub(&delta, &prev_ts);
int64_t ps = fmctdc_ts_ps(&delta);
//printf("ps: %lld seq:%d\n", ps, ts[i].seq_id);
if ( prev_ts.seq_id + 1 != ts[i].seq_id )
{
fprintf(stderr, "\n\nSuspicious timestamps (gap in seq ids):\n");
fprintf(stderr,"Prev: "); print_ts_wr( prev_ts ); fprintf(stderr, "\n");
fprintf(stderr,"Curr: "); print_ts_wr( ts[i] ); fprintf(stderr, "\n");
if ( (prev_ts.seq_id + 1) != ts[i].seq_id) {
fprintf(stderr,
"\n\nSuspicious timestamps (gap in sequence ids):\n");
fprintf(stderr,"Previous : ");
print_ts_wr( prev_ts );
fprintf(stderr, "\n");
fprintf(stderr,"Current : ");
print_ts_wr( ts[i] );
fprintf(stderr, "\n");
misses++;
} else {
if(ps < delta_min)
delta_min = ps;
else if(ps > delta_max)
delta_max = ps;
int64_t span = delta_max - delta_min;
if( span > max_span )
{
fprintf(stderr, "\n\nSuspicious timestamps (span exceeded):\n");
max_span = span;
fprintf(stderr,"Prev: "); print_ts_wr( prev_ts ); fprintf(stderr, "\n");
fprintf(stderr,"Curr: "); print_ts_wr( ts[i] ); fprintf(stderr, "\n");
int64_t avg_delta = (int64_t)((1e12 * avg_acc) / (double)total_samples);
int64_t delta_diff = abs(ps - avg_delta);
int curr_f_stable = (double)abs(avg_delta_d - avg_delta) < (double)(avg_delta / 100000.0);
if (curr_f_stable && delta_stab_count < 10000)
delta_stab_count++;
else if (!curr_f_stable && delta_stab_count > 10)
delta_stab_count-=10;
delta_stable = delta_stab_count > 8000;
avg_delta_d = avg_delta;
if( delta_stable ) {
if (ps < delta_min)
delta_min = ps;
else if (ps > delta_max)
delta_max = ps;
avg_delta_d = avg_delta;
if (delta_diff > max_delta_span) {
int frac_prev_from_acam = (prev_fine * 81 * 4096 / 8000) % 4096;
int frac_curr_from_acam = (fine * 81 * 4096 / 8000) % 4096;
int err_prev = frac_prev_from_acam - prev_ts.frac;
int err_curr = frac_curr_from_acam - ts[i].frac;
fprintf(stderr,
"\n\nSuspicious timestamps (span exceeded: current-previous = %"PRIi64" ps, average = %"PRIi64" ps, error = %"PRIi64" ps, threshold = %"PRIi64" ps):\n",
ps, avg_delta, delta_diff,
max_delta_span);
fprintf(stderr, "Previous : ");
print_ts_wr(prev_ts);
fprintf(stderr,
", ACAM bins: %d (DMA timestamp vs RAW ACAM readout error: %d)\n",
prev_fine, err_prev);
fprintf(stderr, "Currrent : ");
print_ts_wr(ts[i]);
fprintf(stderr,
", ACAM bins: %d (DMA timestamp vs RAW ACAM readout error: %d)\n",
fine, err_curr);
}
}
avg_acc += (double) ps / 1e12;
avg_acc += (double)ps / 1e12;
}
//printf("Miss: %d %d\n\n", i, total_samples);
}
prev_ts = ts[i];
prev_fine = fine;
total_samples++;
}
}
void display_stats()
{
fprintf(stderr,"Got %d timestamps so far (rate %.1f Hz, misses : %d, dmin %"PRId64" dmax %"PRId64" span %"PRId64")... \r", total_samples, 1.0/ (avg_acc/(double) total_samples), misses, delta_min, delta_max, delta_max - delta_min );
if( delta_stable )
fprintf(stderr,
"Got %d timestamps so far (rate %.1f Hz, misses : %d, dmin %"PRIi64" dmax %"PRIi64" span %"PRIi64")... \r",
total_samples, 1.0 / (avg_acc / (double)total_samples),
misses, delta_min, delta_max, delta_max - delta_min);
else
fprintf(stderr,
"Got %d timestamps so far (input frequency UNSTABLE)... \r",
total_samples);
}
static timeout_t refresh_timeout;
......@@ -196,29 +243,32 @@ int main(int argc, char **argv)
/* Set up the structure to specify the new action. */
new_action.sa_handler = termination_handler;
sigemptyset (&new_action.sa_mask);
sigemptyset(&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGINT, NULL, &old_action);
sigaction(SIGINT, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN)
sigaction (SIGINT, &new_action, NULL);
sigaction(SIGINT, &new_action, NULL);
atexit(fmctdc_exit);
/* Initialize FMC TDC library */
n_boards = fmctdc_init();
if (n_boards < 0) {
if (n_boards < 0)
{
fprintf(stderr, "%s: fmctdc_init(): %s\n", argv[0],
strerror(errno));
strerror(errno));
exit(1);
}
/* Parse Options */
while ((opt = getopt(argc, argv, "D:c:n:h")) != -1) {
switch (opt) {
while ((opt = getopt(argc, argv, "D:c:n:h")) != -1)
{
switch (opt)
{
case 'D':
ret = sscanf(optarg, "0x%04x", &dev_id);
if (!ret) {
if (!ret)
{
help(argv[0]);
exit(EXIT_SUCCESS);
}
......@@ -232,7 +282,6 @@ int main(int argc, char **argv)
sscanf(optarg, "%d", &nsamples);
break;
case 'c':
sscanf(optarg, "%d", &channel);
break;
......@@ -241,22 +290,23 @@ int main(int argc, char **argv)
/* Open FMC TDC device */
brd = fmctdc_open(-1, dev_id); /* look for dev_id form the beginning */
if (!brd) {
if (!brd)
{
if (dev_id == 0xFFFFFFFF)
fprintf(stderr, "Missing device identifier\n");
else
fprintf(stderr, "Can't open device 0x%x: %s\n", dev_id,
strerror(errno));
strerror(errno));
exit(EXIT_FAILURE);
}
if( channel < 0 )
if (channel < 0)
{
fprintf(stderr, "Channel number expected\n");
exit(EXIT_FAILURE);
}
if( nsamples < 0 )
if (nsamples < 0)
{
fprintf(stderr, "Number of samples expected\n");
exit(EXIT_FAILURE);
......@@ -265,38 +315,39 @@ int main(int argc, char **argv)
ret = fmctdc_flush(brd, channel);
if (ret)
fprintf(stderr,
"fmc-tdc-tstamp: failed to flush channel %d: %s\n",
FMCTDC_NUM_CHANNELS, fmctdc_strerror(errno));
"fmc-tdc-tstamp: failed to flush channel %d: %s\n",
FMCTDC_NUM_CHANNELS, fmctdc_strerror(errno));
fd = fmctdc_fileno_channel(brd, channel);
ret = fmctdc_channel_enable(brd, channel);
if (ret)
fprintf(stderr,
"%s: chan %d: cannot enable acquisition: %s.\n",
argv[0], channel, fmctdc_strerror(errno));
/* Read Time-Stamps */
ts = calloc(ts_buf_size, sizeof(*ts));
if (!ts) {
if (!ts)
{
fprintf(stderr, "%s: cannot allocate memory\n", argv[0]);
goto out;
}
tmo_init(&refresh_timeout, 1000, 1) ;
fprintf(stderr,"Reading & checking %d samples...\n", nsamples);
while (nsamples > 0) {
tmo_init(&refresh_timeout, 1000, 1);
fprintf(stderr,
"WARNING!!! Please connect a pulse source of a stable frequency to the selected input.\n\n");
fprintf(stderr,
"Reading & checking %d samples...\n",
nsamples);
while (nsamples > 0)
{
int to_read = nsamples > ts_buf_size ? ts_buf_size : nsamples;
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN | POLLERR;
if(stop)
if (stop)
break;
ret = poll(&pfd, 1, 10);
......@@ -306,23 +357,22 @@ int main(int argc, char **argv)
if (!(pfd.revents & POLLIN))
continue;
int n_ts = fmctdc_read(brd, channel, ts, to_read, 0 );
int n_ts = fmctdc_read(brd, channel, ts, to_read, 0);
if (n_ts == 0) /* no timestamp */
continue;
// fprintf(stderr,"Got %d\n", n_ts);
process_timestamps( ts, n_ts );
process_timestamps(ts, n_ts);
if( tmo_expired(&refresh_timeout) )
if (tmo_expired(&refresh_timeout))
{
display_stats();
}
nsamples -= n_ts;
}
fprintf(stderr,"\n");
fprintf(stderr, "\n");
free(ts);
......
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