# HG changeset patch # User Mychaela Falconia # Date 1730079868 0 # Node ID 8a386263dd51b0dbbbd2515f7d4fcbdcc5489b95 # Parent a10657f8024ec966479fb0884051f3b3d622ec83 fc-mcsi-rxtx skeleton put together diff -r a10657f8024e -r 8a386263dd51 .hgignore --- 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$ diff -r a10657f8024e -r 8a386263dd51 sw/mcsi-rxtx/Makefile --- /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} diff -r a10657f8024e -r 8a386263dd51 sw/mcsi-rxtx/main.c --- /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 +#include +#include + +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 */ +} diff -r a10657f8024e -r 8a386263dd51 sw/mcsi-rxtx/mainloop.c --- /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 +#include +#include +#include +#include +#include + +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; + } + } + } +} diff -r a10657f8024e -r 8a386263dd51 sw/mcsi-rxtx/rx_samples.c --- /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 +#include + +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; + } +} diff -r a10657f8024e -r 8a386263dd51 sw/mcsi-rxtx/ttymagic.c --- /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 +#include +#include +#include +#include +#include +#include + +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); +} diff -r a10657f8024e -r 8a386263dd51 sw/mcsi-rxtx/usercmd.c --- /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 +#include +#include +#include +#include +#include + +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); +}