diff frbl/test/frbl2.c @ 324:43c92df87ac6

frbl2test: meat filled in
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 06 Mar 2020 00:30:18 +0000
parents cefa700d1b8f
children 7df08926a4e7
line wrap: on
line diff
--- a/frbl/test/frbl2.c	Thu Mar 05 22:05:01 2020 +0000
+++ b/frbl/test/frbl2.c	Fri Mar 06 00:30:18 2020 +0000
@@ -1,12 +1,19 @@
 #include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/errno.h>
+#include <ctype.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
+#include <termios.h>
 #include <unistd.h>
 #include "srecreader.h"
 
+extern int errno;
+
 extern char *target_ttydev;
 extern int target_fd;
 extern struct srecreader srimage;
@@ -17,6 +24,16 @@
 static unsigned codeimage_len;
 static uint32_t loadaddr;
 
+static u_char beacon_cmd[3] = {0xAA, 0x01, 0xDD};
+static u_char fluid_baudrate_cmd[2] = {0x00, 0x07};
+static u_char fluid_version_cmd[1] = {'V'};
+static u_char fluid_chipquery_cmd[2] = {'Q', 'C'};
+static u_char fluid_download_cmd[7] = {'L'};
+
+#define	BEACON_INTERVAL		13	/* ms between beacons */
+#define	INTERMEDIATE_TIMEOUT	500	/* ms to wait for responses */
+#define	SERIAL_FLUSH_DELAY	200	/* also in ms */
+
 read_srec_image()
 {
 	u_char *writep;
@@ -111,8 +128,149 @@
 	return(0);
 }
 
+static void
+fill_download_cmd()
+{
+	unsigned nwords;
+
+	nwords = codeimage_len >> 1;
+	fluid_download_cmd[1] = loadaddr >> 24;
+	fluid_download_cmd[2] = loadaddr >> 16;
+	fluid_download_cmd[3] = loadaddr >> 8;
+	fluid_download_cmd[4] = loadaddr;
+	fluid_download_cmd[5] = nwords >> 8;
+	fluid_download_cmd[6] = nwords;
+}
+
+static int
+expect_beacon_response(timeout)
+{
+	u_char buf;
+	fd_set fds;
+	struct timeval tv;
+	int cc;
+
+	for (;;) {
+		FD_ZERO(&fds);
+		FD_SET(target_fd, &fds);
+		tv.tv_sec = 0;
+		tv.tv_usec = timeout * 1000;
+		cc = select(target_fd+1, &fds, NULL, NULL, &tv);
+		if (cc < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select");
+			exit(1);
+		}
+		if (cc < 1)
+			return(0);
+		cc = read(target_fd, &buf, 1);
+		if (cc <= 0) {
+			perror("read after successful select");
+			exit(1);
+		}
+		if (buf == 'H')
+			return(1);
+	}
+}
+
+static
+send_beacons()
+{
+	printf("Sending beacons to %s\n", target_ttydev);
+	do
+		write(target_fd, beacon_cmd, sizeof beacon_cmd);
+	while (!expect_beacon_response(BEACON_INTERVAL));
+	return 0;
+}
+
+static int
+expect_add_response(buf, expect_bytes, timeout)
+	u_char *buf;
+{
+	fd_set fds;
+	struct timeval tv;
+	int pass, cc;
+
+	for (pass = 0; pass < expect_bytes; ) {
+		FD_ZERO(&fds);
+		FD_SET(target_fd, &fds);
+		tv.tv_sec = 0;
+		tv.tv_usec = timeout * 1000;
+		cc = select(target_fd+1, &fds, NULL, NULL, &tv);
+		if (cc < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select");
+			exit(1);
+		}
+		if (cc < 1)
+			return(-1);
+		cc = read(target_fd, buf + pass, expect_bytes - pass);
+		if (cc <= 0) {
+			perror("read after successful select");
+			exit(1);
+		}
+		pass += cc;
+	}
+	return(0);
+}
+
+perform_frbl2_protocol()
+{
+	u_char respbuf[4];
+	static int zero = 0;
+
+	ioctl(target_fd, FIONBIO, &zero);
+	send_beacons();
+	printf("Got beacon response, attempting FLUID protocol\n");
+	write(target_fd, fluid_baudrate_cmd, sizeof fluid_baudrate_cmd);
+	usleep(SERIAL_FLUSH_DELAY * 1000);
+	tcflush(target_fd, TCIFLUSH);
+	write(target_fd, fluid_version_cmd, sizeof fluid_version_cmd);
+	if (expect_add_response(respbuf, 1, INTERMEDIATE_TIMEOUT) < 0) {
+		fprintf(stderr, "no response to version query\n");
+		exit(1);
+	}
+	if (!isdigit(respbuf[0])) {
+		fprintf(stderr, "bad response to version query: 0x%02X\n",
+			respbuf[0]);
+		exit(1);
+	}
+	printf("Version response: %d\n", respbuf[0] - '0');
+	write(target_fd, fluid_chipquery_cmd, sizeof fluid_chipquery_cmd);
+	if (expect_add_response(respbuf, 4, INTERMEDIATE_TIMEOUT) < 0) {
+		fprintf(stderr, "no response to chip ID query\n");
+		exit(1);
+	}
+	if (respbuf[2] || respbuf[3]) {
+		fprintf(stderr,
+			"bad response to chip ID query: %02X %02X %02X %02X\n",
+			respbuf[0], respbuf[1], respbuf[2], respbuf[3]);
+		exit(1);
+	}
+	printf("Chip ID response: %04X\n", (respbuf[1] << 8) | respbuf[0]);
+	printf("Sending download command\n");
+	write(target_fd, fluid_download_cmd, sizeof fluid_download_cmd);
+	if (expect_add_response(respbuf, 1, INTERMEDIATE_TIMEOUT) < 0) {
+		fprintf(stderr, "no response to download command\n");
+		exit(1);
+	}
+	if (respbuf[0] != 'R') {
+		fprintf(stderr, "bad response to download command: 0x%02X\n",
+			respbuf[0]);
+		exit(1);
+	}
+	if (write(target_fd, codeimage, codeimage_len) != codeimage_len) {
+		perror("write of download image bulk");
+		exit(1);
+	}
+	printf("Code image sent!\n");
+}
+
 frbl_test_main()
 {
 	read_srec_image();
-	/* remainder to be implemented */
+	fill_download_cmd();
+	perform_frbl2_protocol();
 }