Commit 4de02cad authored by Miguel Gómez Sexto's avatar Miguel Gómez Sexto

tdc: added read function to the library

Signed-off-by: Miguel Gómez Sexto's avatarMiguel Gomez <magomez@igalia.com>
parent 6fab96fe
LIB = libtdc.a
LOBJ := libtdc.o
CFLAGS = -Wall -ggdb -O2 -I..
CFLAGS = -Wall -ggdb -O2 -I.. -I$(ZIO)/include
LDFLAGS = -L. -ltdc
modules all: lib test
......
......@@ -6,6 +6,10 @@
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/select.h>
#include <linux/zio.h>
#include <linux/zio-user.h>
#include "libtdc.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
......@@ -280,3 +284,94 @@ int tdc_get_active_channels(struct tdc_board *b, uint32_t *config)
{
return __tdc_sysfs_get(b, "input_enable", config);
}
static int __tdc_valid_channel(struct tdc_board *b, int chan)
{
if (chan < 0 || chan > 4) {
fprintf(stderr, "%s: Invalid channel: %i\n",
__func__, chan);
errno = EINVAL;
return 0;
}
if (!b->enabled[chan]) {
fprintf(stderr, "%s: Channel not enabled: %i\n",
__func__, chan);
errno = EINVAL;
return 0;
}
return 1;
}
static int __tdc_open_file(struct tdc_board *b, int chan)
{
char fname[128];
/* open file */
if (b->ctrl[chan] <= 0) {
sprintf(fname, "%s-%i-0-ctrl", b->devbase, chan);
b->ctrl[chan] = open(fname, O_RDONLY | O_NONBLOCK);
}
if (b->ctrl[chan] < 0)
fprintf(stderr, "%s: Error opening file: %s\n",
__func__, fname);
return b->ctrl[chan];
}
int tdc_read(struct tdc_board *b, int chan, struct tdc_time *t,
int n, int flags)
{
struct zio_control ctrl;
int fd, i, j;
fd_set set;
if (!__tdc_valid_channel(b, chan))
return -1;
fd = __tdc_open_file(b, chan);
if (fd < 0)
return -1;
for (i = 0; i < n; ) {
j = read(fd, &ctrl, sizeof(ctrl));
if (j < 0 && errno != EAGAIN)
return -1;
if (j == sizeof(ctrl)) {
/* one sample: pick it */
t->utc = ctrl.tstamp.secs;
t->ticks = ctrl.tstamp.ticks;
t->bins = ctrl.tstamp.bins;
i++;
continue;
}
if (j > 0) {
/* some bytes read but not complete structure */
errno = EIO;
return -1;
}
/* so, it's EAGAIN: if we already got something, we are done */
if (i)
return i;
/* EAGAIN at first sample */
if (j < 0 && flags == O_NONBLOCK)
return -1;
/* So, first sample and blocking read. Wait.. */
FD_ZERO(&set);
FD_SET(fd, &set);
if (select(fd+1, &set, NULL, NULL, NULL) < 0)
return -1;
continue;
}
return i;
}
......@@ -14,9 +14,8 @@ struct tdc_board {
struct tdc_time {
uint64_t utc;
uint32_t coarse;
uint32_t frac;
uint32_t channel;
uint64_t ticks;
uint64_t bins;
};
......@@ -45,4 +44,7 @@ extern int tdc_get_timestamp_threshold(struct tdc_board *b, uint32_t *thres);
extern int tdc_set_active_channels(struct tdc_board *b, uint32_t config);
extern int tdc_get_active_channels(struct tdc_board *b, uint32_t *config);
extern int tdc_read(struct tdc_board *b, int chan, struct tdc_time *t,
int n, int flags);
#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