Skip to content

Commit

Permalink
Add readout / checking for FEC/VMM3 data.
Browse files Browse the repository at this point in the history
  • Loading branch information
bl0x committed Feb 6, 2023
1 parent 5fb9e5b commit df0770a
Show file tree
Hide file tree
Showing 9 changed files with 416 additions and 34 deletions.
134 changes: 119 additions & 15 deletions apps/srscli/main.c
Original file line number Diff line number Diff line change
@@ -1,28 +1,79 @@
#include <stdio.h>
#include <fec.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
struct Config
{
struct Fec *fec;
uint8_t hybrid;
(void)argc;
(void)argv;
printf("srscli\n");
int do_start_acq;
int do_stop_acq;
int do_help;
int do_test_mode;
int verbosity;
};

struct Config *parse_args(int , char **);
void do_start_acq(struct Fec *);
void do_stop_acq(struct Fec *);
void do_test_mode(struct Fec *);
void usage(const char *);

struct Config *
parse_args(int argc, char **argv)
{
struct Config *c = (struct Config *)calloc(sizeof(struct Config), 1);
char *argp = NULL;

fec = fec_new();
if (argc == 1) {
c->do_test_mode = 1;
goto parse_ok;
}

fec_add_vmm3_hybrid(fec, 0);
fec_add_vmm3_hybrid(fec, 1);
fec_add_vmm3_hybrid(fec, 2);
fec_add_vmm3_hybrid(fec, 3);
argp = argv[1];

#define TEST_ARG(name) (strncmp(argp, name, strlen(name)) == 0)
while (argc--) {
if (TEST_ARG("--acq-on")) {
c->do_start_acq = 1;
}
else if (TEST_ARG("--acq-off")) {
c->do_stop_acq = 1;
}
else if (TEST_ARG("--help")) {
c->do_help = 1;
}
else if (TEST_ARG("--verbose")) {
c->verbosity += 1;
}
}

fec_configure(fec);
fec_open(fec, FEC_DEFAULT_IP, FEC_DEFAULT_FEC_PORT);
parse_ok:

fec_debug(fec, 1);
return c;
}

void
usage(const char *name)
{
printf("srscli - A minimal wrapper around libsrs\n");
printf("\n");
printf(" Usage: %s [options]\n", name);
printf("\n\n");
printf("Options:\n");
printf("\t--acq-on Start data acquisition.\n");
printf("\t--acq-off Stop data acquisition.\n");
printf("\t--help Show this help.\n");
printf("\t--verbose Increase verbosity level.\n");
printf("\n");
}

void
do_test_mode(struct Fec *fec)
{
uint8_t hybrid;

printf("### TEST MODE BEGIN ###\n");
printf("Resetting the FEC.\n");
fec_write_reset(fec);
sleep(1);
Expand Down Expand Up @@ -72,6 +123,57 @@ main(int argc, char *argv[])

fec_write_acq_off(fec);
fec_read_link_status(fec);
printf("### TEST MODE END ###\n");
}

void
do_start_acq(struct Fec *fec)
{
fec_write_acq_on(fec);
}

void
do_stop_acq(struct Fec *fec)
{
fec_write_acq_off(fec);
}

int
main(int argc, char *argv[])
{
struct Fec *fec;
struct Config *c;

printf("srscli\n");

c = parse_args(argc, argv);

fec = fec_new();

fec_add_vmm3_hybrid(fec, 0);
fec_add_vmm3_hybrid(fec, 1);
fec_add_vmm3_hybrid(fec, 2);
fec_add_vmm3_hybrid(fec, 3);

fec_configure(fec);
fec_open(fec);

fec_debug(fec, c->verbosity);

if (c->do_help) {
usage(argv[0]);
}
if (c->do_test_mode) {
do_test_mode(fec);
} else if (c->do_start_acq) {
do_start_acq(fec);
} else if (c->do_stop_acq) {
do_stop_acq(fec);
} else {
printf("No action requested. Exiting.\n");
}



/*
* does not work with all FEC firmwares.
Expand All @@ -81,5 +183,7 @@ main(int argc, char *argv[])
fec_close(fec);
fec_destroy(fec);

free(c);

return 0;
}
197 changes: 193 additions & 4 deletions apps/srsread/main.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,36 @@
#include <stdio.h>
#include <assert.h>
#include <fec.h>
#include <string.h>

#include <vmm3_srs_hit.h>
#include <vmm3_srs_header.h>
#include <vmm3_common_data.h>
#include <udp_socket.h>
#include <util.h>

int read_loop(struct Fec *);
void handle_data(struct Fec *);
size_t handle_vmm3(struct Fec *);
size_t handle_vmm3_srs(struct Fec *);
int parse_header_vmm3_srs(struct Fec *, const struct VMM3SRSHeader *);
int parse_hit_vmm3_srs(const struct VMM3SRSHit *, uint8_t);
void print_stats(void);

struct Data
{
struct VMM3CommonData common;
} data;

struct Stats
{
size_t n_frames;
size_t n_hits;
double start_time;
double last_stat_time;
double now;
} stats;


int
main(int argc, char *argv[])
Expand All @@ -12,13 +40,30 @@ main(int argc, char *argv[])
(void)argv;
printf("srsread\n");

fec = fec_new();
stats.start_time = time_double();

fec = fec_new();
fec_configure(fec);
fec_open(fec, FEC_DEFAULT_IP, fec->daq.port);

fec->config.break_on_pkt_cnt_mismatch = 0;
fec->config.connection.port = fec->config.connection.daq_port;

fec_open(fec);

memset(&data, 0, sizeof(struct Data));
memset(&stats, 0, sizeof(struct Stats));

while (1) {
double now;

read_loop(fec);

now = time_double();
if(now > stats.last_stat_time + 1) {
stats.now = now;
print_stats();
stats.last_stat_time = now;
}
}

fec_close(fec);
Expand All @@ -27,10 +72,152 @@ main(int argc, char *argv[])
}

void
handle_data(struct Fec *fec)
print_stats()
{
printf("t: %.0f, f: %lu, hits: %lu\n",
stats.now, stats.n_frames, stats.n_hits);
}

size_t
handle_vmm3(struct Fec *fec)
{
(void)fec;
printf("handle_data.\n");
printf(" handle_vmm3.\n");
return 0;
}

size_t
handle_vmm3_srs(struct Fec *fec)
{
size_t n_hits = 0;
struct UdpSocket *socket = fec->socket;
size_t size = (size_t)socket->receivedlen;
uint8_t *p = socket->recvbuf;
uint8_t *end = socket->recvbuf + size;
int rc;

const struct VMM3SRSHeader *h;
const struct VMM3SRSHit *hit;

/* printf(" handle_vmm3_srs.\n"); */

if (size < 4) {
printf("Received only %lu words. Too few!\n", size);
goto vmm3_srs_done;
}

h = (const struct VMM3SRSHeader *)p;
rc = parse_header_vmm3_srs(fec, h);
if (rc != 0) {
goto vmm3_srs_fail;
}

p += VMM3SRSHeaderSize;
hit = (struct VMM3SRSHit *)p;

while ((const uint8_t *)hit < end) {
rc = parse_hit_vmm3_srs(hit, fec->id);
if (rc == 1) {
n_hits++;
}
/* TODO: Data overflow ? */
hit++;
}

data.common.last_frame_counter = data.common.frame_counter;

vmm3_srs_done:
return n_hits;

vmm3_srs_fail:
print_hex(socket->recvbuf,
(socket->receivedlen>64) ? 64 : (size_t)socket->receivedlen,
"handle_vmm3_srs", "<<<");
return 0;
}

int
parse_header_vmm3_srs(struct Fec *fec, const struct VMM3SRSHeader *h) {
uint32_t fc_diff;
size_t payload_size;
struct UdpSocket *socket = fec->socket;
size_t size = (size_t)socket->receivedlen;

data.common.frame_counter = ntohl(h->frame_counter);
if (data.common.frame_counter == FEC_DATA_END_OF_FRAME) {
printf("End of frame.\n");
goto parse_header_done;
}

fc_diff = data.common.frame_counter
- data.common.last_frame_counter;
if (fc_diff > 1) {
printf("Lost frame(s), frame counter now: %u, prev: %u,"
" diff: %u\n", data.common.frame_counter,
data.common.last_frame_counter, fc_diff);
/* TODO: handle */
}

if (size < VMM3SRSMinimumPayload) {
printf("Payload too small: %lu < %lu\n",
size, VMM3SRSMinimumPayload);
goto parse_header_fail;
}

data.common.data_id = ntohl(h->data_id);
if ((data.common.data_id & 0xffffff00) != FEC_DATA_ID) {
printf("Unknown data id 0x%8x.\n", data.common.data_id);
goto parse_header_fail;
}

data.common.fec_id = (data.common.data_id >> 4) & 0xf;
if (fec->id != data.common.fec_id) {
printf("FEC ID mismatch: expected %u, got %u\n", fec->id,
data.common.fec_id);
goto parse_header_fail;
}

data.common.udp_timestamp = ntohl(h->udp_timestamp);
data.common.offset_overflow = ntohl(h->offset_overflow);

assert(size < 0xffffffff);
payload_size = size - VMM3SRSHeaderSize;
if ((size % VMM3SRSHitSize) != 0) {
printf("Invalid payload_size: %lu\n", payload_size);
goto parse_header_fail;
}

parse_header_done:
return 0;

parse_header_fail:
return -1;
}

int
parse_hit_vmm3_srs(const struct VMM3SRSHit *hit, uint8_t fec_id)
{
(void)hit;
(void)fec_id;
return 1;
}

void
handle_data(struct Fec *fec)
{
size_t n_hits;

/* printf("handle_data.\n"); */
if (fec->config.clock_source <= 1) {
n_hits = handle_vmm3(fec);
} else {
n_hits = handle_vmm3_srs(fec);
}

stats.n_hits += n_hits;
stats.n_frames++;

/* printf("Got frame with %lu hits\n", n_hits); */
}

int
Expand All @@ -40,6 +227,8 @@ read_loop(struct Fec *fec)
rc = fec_rw(fec, 0, NULL, handle_data);
if (rc == FEC_RW_NO_DATA) {
printf("No data from FEC. Acquisition on and signals coming?\n");
} else if (rc == FEC_RW_PACKET_COUNT_MISMATCH) {
/* this is fine */
} else {
printf("Received data from FEC.\n");
}
Expand Down
Loading

0 comments on commit df0770a

Please sign in to comment.