diff fteeprom/ftee-gen2232h.c @ 40:d150d4704ff5

fteeprom: ftee-gen2232h program written, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 22 Apr 2019 00:05:32 +0000
parents
children 6a2886f9943e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fteeprom/ftee-gen2232h.c	Mon Apr 22 00:05:32 2019 +0000
@@ -0,0 +1,181 @@
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+u_short vid = 0x0403, pid = 0x6010;
+char *manuf, *product;
+u_char byte00 = 0x08, byte01 = 0x08;
+u_char byte08 = 0x80, byte0A = 0x00;
+unsigned maxpower = 100;
+u_char group0, group1, group2, group3;
+
+u_short eeprom[64];
+unsigned eeprom_string_ptr = 0x0D;
+
+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, "maxpower"))
+			maxpower = strtoul(cp, 0, 10);
+		else if (!strcmp(np, "group0"))
+			group0 = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "group1"))
+			group1 = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "group2"))
+			group2 = strtoul(cp, 0, 16);
+		else if (!strcmp(np, "group3"))
+			group3 = 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] = 0x0700;
+	eeprom[4] = (byte09 << 8) | byte08;
+	eeprom[5] = byte0A;
+	eeprom[6] = (group3 << 12) | (group2 << 8) | (group1 << 4) | group0;
+	eeprom[7] = write_string(manuf);
+	eeprom[8] = write_string(product);
+	if (serial)
+		eeprom[9] = write_string(serial);
+	else
+		eeprom[9] = 0;
+	eeprom[12] = 0x46;
+}
+
+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);
+}