changeset 7:8a386263dd51

fc-mcsi-rxtx skeleton put together
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 28 Oct 2024 01:44:28 +0000
parents a10657f8024e
children ee14dd81bba1
files .hgignore sw/mcsi-rxtx/Makefile sw/mcsi-rxtx/main.c sw/mcsi-rxtx/mainloop.c sw/mcsi-rxtx/rx_samples.c sw/mcsi-rxtx/ttymagic.c sw/mcsi-rxtx/usercmd.c
diffstat 7 files changed, 349 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sat Oct 12 19:42:19 2024 +0000
+++ b/.hgignore	Mon Oct 28 01:44:28 2024 +0000
@@ -8,3 +8,4 @@
 \.rpt$
 
 ^sw/mcsi-rx/fc-mcsi-rx$
+^sw/mcsi-rxtx/fc-mcsi-rxtx$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/mcsi-rxtx/Makefile	Mon Oct 28 01:44:28 2024 +0000
@@ -0,0 +1,21 @@
+CC=	gcc
+CFLAGS=	-O2
+PROG=	fc-mcsi-rxtx
+OBJS=	main.o mainloop.o rx_samples.o ttymagic.o usercmd.o
+LIBS=	../libserial/libserial.a
+
+INSTALL_PREFIX=	/opt/freecalypso
+
+INSTBIN=${INSTALL_PREFIX}/bin
+
+all:	${PROG}
+
+${PROG}:	${OBJS} ${LIBS}
+	${CC} ${CFLAGS} -o $@ ${OBJS} ${LIBS}
+
+install:
+	mkdir -p ${INSTBIN}
+	install -c ${PROG} ${INSTBIN}
+
+clean:
+	rm -f *.o ${PROG}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/mcsi-rxtx/main.c	Mon Oct 28 01:44:28 2024 +0000
@@ -0,0 +1,36 @@
+/*
+ * Main module for fc-mcsi-rxtx program: interactive, modeled after fc-shell.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int ttyhacks, dflag;
+
+main(argc, argv)
+	char **argv;
+{
+	extern int optind;
+	int c;
+
+	while ((c = getopt(argc, argv, "d")) != EOF) {
+		switch (c) {
+		case 'd':
+			dflag++;
+			continue;
+		default:
+		usage:
+			fprintf(stderr, "usage: %s [-d] ttyport\n", argv[0]);
+			exit(1);
+		}
+	}
+	if (argc != optind + 1)
+		goto usage;
+	open_serial_port(argv[optind]);
+	set_serial_baudrate(187500);
+	init_serial_flush();
+	ttyhacks = isatty(0) && !dflag;
+	tty_init();
+	main_loop();		/* does not return */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/mcsi-rxtx/mainloop.c	Mon Oct 28 01:44:28 2024 +0000
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+main_loop()
+{
+	fd_set fds;
+	struct timeval tv;
+	u_char buf[320];
+	unsigned off;
+	int cc, is_active;
+
+	is_active = 0;
+	off = 0;
+	for (;;) {
+		FD_ZERO(&fds);
+		FD_SET(0, &fds);
+		FD_SET(target_fd, &fds);
+		if (is_active) {
+			tv.tv_sec = 0;
+			tv.tv_usec = 100000;
+			cc = select(target_fd+1, &fds, 0, 0, &tv);
+		} else
+			cc = select(target_fd+1, &fds, 0, 0, 0);
+		if (cc < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select");
+			exit(1);
+		}
+		if (cc == 0) {
+			is_active = 0;
+			printf("Rx stream stopped, buffer dribble = %u\n", off);
+			off = 0;
+			continue;
+		}
+		if (FD_ISSET(0, &fds))
+			handle_tty_input();
+		if (FD_ISSET(target_fd, &fds)) {
+			cc = read(target_fd, buf + off, sizeof(buf) - off);
+			if (cc < 0) {
+				perror("serial port read");
+				exit(1);
+			}
+			if (cc == 0) {
+				fprintf(stderr, "read EOF from serial port\n");
+				exit(1);
+			}
+			if (!is_active) {
+				printf("Rx stream started\n");
+				is_active = 1;
+			}
+			off += cc;
+			if (off >= sizeof(buf)) {
+				process_rx_block(buf);
+				off = 0;
+			}
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/mcsi-rxtx/rx_samples.c	Mon Oct 28 01:44:28 2024 +0000
@@ -0,0 +1,21 @@
+/*
+ * In this module we handle PCM samples received from MCSI via the FPGA.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+
+u_short rx_pcm_samples[160];
+
+process_rx_block(buf)
+	u_char *buf;
+{
+	unsigned n, samp;
+	u_char *sp;
+
+	sp = buf;
+	for (n = 0; n < 160; n++) {
+		samp = ((unsigned) sp[1] << 8) | ((unsigned) sp[0]);
+		rx_pcm_samples[n] = samp;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/mcsi-rxtx/ttymagic.c	Mon Oct 28 01:44:28 2024 +0000
@@ -0,0 +1,113 @@
+/*
+ * This module contains the tty "magic" code for fc-mcsi-rxtx,
+ * copied from fc-shell and fc-tmsh.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+
+extern int ttyhacks;
+
+static struct termios orig_termios, our_termios;
+
+#define	MAX_USER_CMD	78
+char usercmd[MAX_USER_CMD+1];
+int usercmd_len;
+
+void
+tty_init()
+{
+	if (!ttyhacks)
+		return;
+	tcgetattr(0, &orig_termios);
+	bcopy(&orig_termios, &our_termios, sizeof(struct termios));
+	our_termios.c_oflag &= ~(OCRNL | ONOCR | ONLRET);
+	our_termios.c_lflag &= ~(ICANON | ECHO);
+	our_termios.c_cc[VMIN] = 1;
+	our_termios.c_cc[VTIME] = 0;
+	tcsetattr(0, TCSAFLUSH, &our_termios);
+	putchar('>');
+	fflush(stdout);
+}
+
+void
+tty_cleanup()
+{
+	if (!ttyhacks)
+		return;
+	tcsetattr(0, TCSAFLUSH, &orig_termios);
+}
+
+void
+handle_tty_input()
+{
+	char buf[256];
+	int i, c, cc;
+
+	cc = read(0, buf, sizeof buf);
+	if (cc <= 0) {
+		tty_cleanup();
+		exit(0);
+	}
+	for (i = 0; i < cc; i++) {
+		c = buf[i];
+		if (c >= ' ' && c <= '~') {
+			if (usercmd_len >= MAX_USER_CMD)
+				continue;
+			usercmd[usercmd_len++] = c;
+			if (ttyhacks)
+				putchar(c);	/* echo */
+			continue;
+		}
+		switch (c) {
+		case '\b':
+		case 0x7F:
+			if (!usercmd_len)
+				continue;
+			usercmd_len--;
+			if (ttyhacks) {
+				putchar('\b');
+				putchar(' ');
+				putchar('\b');
+			}
+			continue;
+		case '\n':
+		case '\r':
+			usercmd[usercmd_len] = '\0';
+			if (ttyhacks)
+				putchar('\n');	/* echo */
+			dispatch_user_cmd();
+			usercmd_len = 0;
+			if (ttyhacks)
+				putchar('>');	/* new prompt */
+		}
+	}
+}
+
+void
+async_msg_output(msg)
+	char *msg;
+{
+	int msglen, i;
+
+	msglen = strlen(msg);
+	if (ttyhacks)
+		putchar('\r');
+	fputs(msg, stdout);
+	if (ttyhacks)
+		for (i = msglen; i < usercmd_len + 1; i++)
+			putchar(' ');
+	putchar('\n');
+	if (!ttyhacks)
+		return;
+	/* reprint the input line */
+	putchar('>');
+	if (!usercmd_len)
+		return;
+	fwrite(usercmd, 1, usercmd_len, stdout);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sw/mcsi-rxtx/usercmd.c	Mon Oct 28 01:44:28 2024 +0000
@@ -0,0 +1,87 @@
+/*
+ * This module implements fc-mcsi-rxtx user command dispatch.
+ */
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+
+extern char usercmd[];
+
+static void
+cmd_exit()
+{
+	tty_cleanup();
+	exit(0);
+}
+
+static struct cmdtab {
+	char *cmd;
+	int minargs;
+	int maxargs;
+	void (*func)();
+} cmdtab[] = {
+	{"exit", 0, 0, cmd_exit},
+	{"quit", 0, 0, cmd_exit},
+	{0, 0, 0, 0}
+};
+
+void
+dispatch_user_cmd()
+{
+	char *argv[10];
+	char *cp, **ap;
+	struct cmdtab *tp;
+
+	for (cp = usercmd; isspace(*cp); cp++)
+		;
+	if (!*cp || *cp == '#')
+		return;
+	argv[0] = cp;
+	while (*cp && !isspace(*cp))
+		cp++;
+	if (*cp)
+		*cp++ = '\0';
+	for (tp = cmdtab; tp->cmd; tp++)
+		if (!strcmp(tp->cmd, argv[0]))
+			break;
+	if (!tp->func) {
+		printf("error: no such command\n");
+		return;
+	}
+	for (ap = argv + 1; ; ) {
+		while (isspace(*cp))
+			cp++;
+		if (!*cp || *cp == '#')
+			break;
+		if (ap - argv - 1 >= tp->maxargs) {
+			printf("error: too many arguments\n");
+			return;
+		}
+		if (*cp == '"') {
+			*ap++ = ++cp;
+			while (*cp && *cp != '"')
+				cp++;
+			if (*cp != '"') {
+				printf("error: unterminated quoted string\n");
+				return;
+			}
+			*cp++ = '\0';
+		} else {
+			*ap++ = cp;
+			while (*cp && !isspace(*cp))
+				cp++;
+			if (*cp)
+				*cp++ = '\0';
+		}
+	}
+	if (ap - argv - 1 < tp->minargs) {
+		printf("error: too few arguments\n");
+		return;
+	}
+	*ap = 0;
+	tp->func(ap - argv, argv);
+}