diff fteeprom/ftee-gen232r.c @ 0:11b8a30333b3

fteeprom: initial import from freecalypso-hwlab
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 03 Sep 2023 18:08:22 +0000
parents
children b2c891299e83
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fteeprom/ftee-gen232r.c	Sun Sep 03 18:08:22 2023 +0000
@@ -0,0 +1,190 @@
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+u_short vid = 0x0403, pid = 0x6001;
+char *manuf, *product;
+u_char byte00 = 0x00, byte01 = 0x40;
+u_char byte08 = 0x80, byte0A = 0x00, byte0B = 0x00;
+unsigned maxpower = 90;
+u_short usb_version = 0x0200;
+u_char cbusconf[5] = {3, 2, 0, 1, 5};
+
+u_short eeprom[64];
+unsigned eeprom_string_ptr = 0x0C;
+
+read_config_file(filename)
+	char *filename;
+{
+	FILE *inf;
+	char linebuf[1024];
+	int lineno;
+	char *cp, *np;
+
+	inf = fopen(filename, "r");
+	if (!inf) {
+		perror(filename);
+		exit(1);
+	}
+	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
+		cp = index(linebuf, '\n');
+		if (!cp) {
+			fprintf(stderr,
+				"%s line %d: too long or unterminated\n",
+				filename, lineno);
+			exit(1);
+		}
+		*cp = '\0';
+		for (cp = linebuf; isspace(*cp); cp++)
+			;
+		if (*cp == '\0' || *cp == '#')
+			continue;
+		for (np = cp; *cp && !isspace(*cp); cp++)
+			;
+		if (*cp)
+			*cp++ = '\0';
+		while (isspace(*cp))
+			cp++;
+		if (*cp == '\0' || *cp == '#') {
+			fprintf(stderr,
+				"%s line %d: \"%s\" setting without argument\n",
+				filename, lineno, np);
+			exit(1);
+		}
+		if (!strcmp(np, "vid"))
+			vid = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "pid"))
+			pid = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "manuf"))
+			manuf = strdup(cp);
+		else if (!strcmp(np, "product"))
+			product = strdup(cp);
+		else if (!strcmp(np, "byte00"))
+			byte00 = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "byte01"))
+			byte01 = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "byte08"))
+			byte08 = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "byte0A"))
+			byte0A = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "byte0B"))
+			byte0B = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "maxpower"))
+			maxpower = strtoul(cp, 0, 10);
+		else if (!strcmp(np, "usbver"))
+			usb_version = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "cbus0"))
+			cbusconf[0] = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "cbus1"))
+			cbusconf[1] = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "cbus2"))
+			cbusconf[2] = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "cbus3"))
+			cbusconf[3] = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "cbus4"))
+			cbusconf[4] = strtoul(cp, 0, 16);
+		else {
+			fprintf(stderr, "%s line %d: unknown \"%s\" setting\n",
+				filename, lineno, np);
+			exit(1);
+		}
+	}
+	fclose(inf);
+	if (!manuf) {
+		fprintf(stderr, "error: manuf not set in %s\n", filename);
+		exit(1);
+	}
+	if (!product) {
+		fprintf(stderr, "error: product not set in %s\n", filename);
+		exit(1);
+	}
+}
+
+write_string(str)
+	char *str;
+{
+	unsigned longlen, startptr;
+
+	if (63 - eeprom_string_ptr < strlen(str) + 1) {
+		fprintf(stderr, "error: strings are too long\n");
+		exit(1);
+	}
+	longlen = strlen(str) * 2 + 2;
+	startptr = eeprom_string_ptr;
+	eeprom[eeprom_string_ptr++] = 0x0300 | longlen;
+	while (*str)
+		eeprom[eeprom_string_ptr++] = *str++;
+	return (longlen << 8) | 0x80 | (startptr << 1);
+}
+
+fill_eeprom(serial)
+	char *serial;
+{
+	u_char byte09;
+
+	if (serial)
+		byte0A |= 0x08;
+	else
+		byte0A &= 0xF7;
+	byte09 = maxpower / 2;
+	eeprom[0] = (byte01 << 8) | byte00;
+	eeprom[1] = vid;
+	eeprom[2] = pid;
+	eeprom[3] = 0x0600;
+	eeprom[4] = (byte09 << 8) | byte08;
+	eeprom[5] = (byte0B << 8) | byte0A;
+	eeprom[6] = usb_version;
+	eeprom[7] = write_string(manuf);
+	eeprom[8] = write_string(product);
+	if (serial)
+		eeprom[9] = write_string(serial);
+	else
+		eeprom[9] = 0;
+	eeprom[10] = (cbusconf[3] << 12) | (cbusconf[2] << 8) |
+			(cbusconf[1] << 4) | cbusconf[0];
+	eeprom[11] = cbusconf[4];
+}
+
+do_checksum()
+{
+	u_short chksum = 0xAAAA;
+	unsigned n;
+
+	for (n = 0; n < 63; n++) {
+		chksum ^= eeprom[n];
+		chksum = (chksum << 1) | (chksum >> 15);
+	}
+	eeprom[63] = chksum;
+}
+
+emit_output()
+{
+	unsigned n, col;
+
+	for (n = 0; n < 64; n++) {
+		col = n & 7;
+		if (col == 0)
+			printf("%02X:", n * 2);
+		printf(" %04X", eeprom[n]);
+		if (col == 7)
+			putchar('\n');
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	if (argc < 2 || argc > 3) {
+		fprintf(stderr, "usage: %s config-file [serial-num]\n",
+			argv[0]);
+		exit(1);
+	}
+	read_config_file(argv[1]);
+	fill_eeprom(argv[2]);
+	do_checksum();
+	emit_output();
+	exit(0);
+}