changeset 22:b112c2df6c43

sw: simtrace3-sniff-rx program written, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 22 Aug 2023 06:16:44 +0000
parents c4346cdc9641
children abb72a74f27a
files .hgignore sw/sniff-rx/Makefile sw/sniff-rx/byteproc.c sw/sniff-rx/datetime.c sw/sniff-rx/initflush.c sw/sniff-rx/main.c sw/sniff-rx/mainloop.c
diffstat 7 files changed, 222 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Tue Aug 22 02:44:23 2023 +0000
+++ b/.hgignore	Tue Aug 22 06:16:44 2023 +0000
@@ -18,3 +18,5 @@
 
 ^boards/sim-fpc-pasv/pcb/gerbers\.
 ^boards/sim-fpc-pasv/src/elements\.pcb$
+
+^sw/sniff-rx/simtrace3-sniff-rx$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/sniff-rx/Makefile	Tue Aug 22 06:16:44 2023 +0000
@@ -0,0 +1,13 @@
+CC=	gcc
+CFLAGS=	-O2
+PROG=	simtrace3-sniff-rx
+OBJS=	byteproc.o datetime.o initflush.o main.o mainloop.o
+LIBS=	../libserial/libserial.a
+
+all:	${PROG}
+
+${PROG}:	${OBJS} ${LIBS}
+	${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS}
+
+clean:
+	rm -f *.o ${PROG}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/sniff-rx/byteproc.c	Tue Aug 22 06:16:44 2023 +0000
@@ -0,0 +1,42 @@
+/*
+ * In this module we implement byte-level processing of the serial stream
+ * coming from the sniffer FPGA.
+ */
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+extern FILE *main_outf;
+extern int logfile_flag;
+extern struct timeval curtime;
+extern struct tm *cur_tm;
+
+static int byte_pending_flag, byte_pending_val;
+
+void
+rx_byte_in(new_byte)
+{
+	if (!byte_pending_flag) {
+		byte_pending_flag = 1;
+		byte_pending_val = new_byte;
+		return;
+	}
+	/* received complete 2-byte message from the FPGA */
+	fprintf(main_outf, "[%02d:%02d:%02d.%06u] %02X%02X\n", cur_tm->tm_hour,
+		cur_tm->tm_min, cur_tm->tm_sec, (unsigned) curtime.tv_usec,
+		new_byte, byte_pending_val);
+	byte_pending_flag = 0;
+	if (logfile_flag && (new_byte & 0x80))
+		printf("SIM RST is %s\n", new_byte & 0x40 ? "high" : "low");
+}
+
+void
+flush_pending_byte()
+{
+	if (!byte_pending_flag)
+		return;
+	printf("BAD BAD BAD: loss of byte sync with FPGA source!\n");
+	byte_pending_flag = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/sniff-rx/datetime.c	Tue Aug 22 06:16:44 2023 +0000
@@ -0,0 +1,30 @@
+/*
+ * Some date and time handling functions for simtrace3-sniff-rx.
+ */
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+
+extern FILE *main_outf;
+extern struct timeval curtime;
+
+struct tm *cur_tm;
+
+static struct tm last_tm;
+
+void
+current_date_time()
+{
+	cur_tm = gmtime(&curtime.tv_sec);
+	if (cur_tm->tm_year != last_tm.tm_year ||
+	    cur_tm->tm_mon != last_tm.tm_mon ||
+	    cur_tm->tm_mday != last_tm.tm_mday)
+		fprintf(main_outf, "%d-%02d-%02d (gmtime):\n",
+			cur_tm->tm_year + 1900, cur_tm->tm_mon + 1,
+			cur_tm->tm_mday);
+	bcopy(cur_tm, &last_tm, sizeof(struct tm));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/sniff-rx/initflush.c	Tue Aug 22 06:16:44 2023 +0000
@@ -0,0 +1,41 @@
+/*
+ * FTDI chip+driver combo (specifically the combination of FTDI chips and
+ * ftdi_sio driver in Linux, not sure who is the actual culprit) exhibits
+ * this unpleasant behaviour: even though we request "please flush all
+ * previous input" when we set our termios params, old accumulated serial
+ * Rx bytes still remain in some buffer somewhere, and a newly started
+ * serial application receives this stale garbage.  As a workaround,
+ * we do an additional flush of our own: we put the fd in non-blocking mode
+ * and keep reading and discarding data until we get EAGAIN or EWOULDBLOCK.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern int target_fd;
+
+void
+init_serial_flush()
+{
+	u_char buf[512];
+	int cc;
+
+	set_serial_nonblock(1);
+	for (;;) {
+		cc = read(target_fd, buf, sizeof buf);
+		if (cc <= 0)
+			break;
+	}
+	if (cc == 0) {
+		fprintf(stderr,
+			"read EOF from serial port during initial flush\n");
+		exit(1);
+	}
+	if (errno == EAGAIN || errno == EWOULDBLOCK)
+		return;		/* success */
+	perror("serial port read");
+	exit(1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/sniff-rx/main.c	Tue Aug 22 06:16:44 2023 +0000
@@ -0,0 +1,33 @@
+/*
+ * Main module for simtrace3-sniff-rx program.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+FILE *main_outf;
+int logfile_flag;
+
+main(argc, argv)
+	char **argv;
+{
+	if (argc < 2 || argc > 3) {
+		fprintf(stderr, "usage: %s ttyport [logfile]\n", argv[0]);
+		exit(1);
+	}
+	open_serial_port(argv[1]);
+	set_serial_baudrate(3000000);
+	init_serial_flush();
+	if (argv[2]) {
+		main_outf = fopen(argv[2], "a");
+		if (!main_outf) {
+			perror(argv[2]);
+			exit(1);
+		}
+		logfile_flag = 1;
+	} else {
+		main_outf = stdout;
+		logfile_flag = 0;
+	}
+	main_loop();		/* does not return */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/sniff-rx/mainloop.c	Tue Aug 22 06:16:44 2023 +0000
@@ -0,0 +1,61 @@
+/*
+ * This module holds our main loop code, factored out into a separate
+ * function that is called from main() after initialization.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern int target_fd;
+extern FILE *main_outf;
+
+struct timeval curtime;
+
+main_loop()
+{
+	fd_set fds;
+	struct timeval tv;
+	u_char buf[512];
+	int cc, i, is_active;
+
+	for (is_active = 0; ; ) {
+		FD_ZERO(&fds);
+		FD_SET(target_fd, &fds);
+		if (is_active) {
+			tv.tv_sec = 1;
+			tv.tv_usec = 0;
+			cc = select(target_fd+1, &fds, 0, 0, &tv);
+		} else
+			cc = select(target_fd+1, &fds, 0, 0, 0);
+		gettimeofday(&curtime, 0);
+		if (cc < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select");
+			exit(1);
+		}
+		if (cc == 0) {
+			is_active = 0;
+			fflush(main_outf);
+			flush_pending_byte();
+			continue;
+		}
+		cc = read(target_fd, buf, sizeof buf);
+		if (cc < 0) {
+			perror("serial port read");
+			exit(1);
+		}
+		if (cc == 0) {
+			fprintf(stderr, "read EOF from serial port\n");
+			exit(1);
+		}
+		current_date_time();
+		for (i = 0; i < cc; i++)
+			rx_byte_in(buf[i]);
+		is_active = 1;
+	}
+}