diff fteeprom/ftee-gen2232h.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-gen2232h.c	Sun Sep 03 18:08:22 2023 +0000
@@ -0,0 +1,220 @@
+#include <sys/types.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+char *configfile, *serial;
+
+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[128];
+u_char eeprom_chip = 0x46;
+unsigned eeprom_size, eeprom_string_ptr;
+
+process_cmdline(argc, argv)
+	char **argv;
+{
+	int c;
+	extern int optind;
+
+	while ((c = getopt(argc, argv, "bB")) != EOF) {
+		switch (c) {
+		case 'b':
+			eeprom_chip = 0x56;
+			continue;
+		case 'B':
+			eeprom_chip = 0x66;
+			continue;
+		default:
+			/* error msg already printed */
+			exit(1);
+		}
+	}
+	if (argc < optind + 1 || argc > optind + 2) {
+		fprintf(stderr,
+			"usage: %s [options] config-file [serial-num]\n",
+			argv[0]);
+		exit(1);
+	}
+	configfile = argv[optind];
+	serial = argv[optind+1];
+}
+
+init_eeprom_size()
+{
+	if (eeprom_chip == 0x46) {
+		eeprom_size = 64;
+		eeprom_string_ptr = 0x0D;
+	} else {
+		eeprom_size = 128;
+		eeprom_string_ptr = 0x4D;
+	}
+}
+
+read_config_file()
+{
+	FILE *inf;
+	char linebuf[1024];
+	int lineno;
+	char *cp, *np;
+
+	inf = fopen(configfile, "r");
+	if (!inf) {
+		perror(configfile);
+		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",
+				configfile, 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",
+				configfile, 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",
+				configfile, lineno, np);
+			exit(1);
+		}
+	}
+	fclose(inf);
+	if (!manuf) {
+		fprintf(stderr, "error: manuf not set in %s\n", configfile);
+		exit(1);
+	}
+	if (!product) {
+		fprintf(stderr, "error: product not set in %s\n", configfile);
+		exit(1);
+	}
+}
+
+write_string(str)
+	char *str;
+{
+	unsigned longlen, startptr;
+
+	if (eeprom_size - 1 - 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()
+{
+	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] = eeprom_chip;
+}
+
+do_checksum()
+{
+	u_short chksum = 0xAAAA;
+	unsigned n;
+
+	for (n = 0; n < eeprom_size - 1; n++) {
+		chksum ^= eeprom[n];
+		chksum = (chksum << 1) | (chksum >> 15);
+	}
+	eeprom[n] = chksum;
+}
+
+emit_output()
+{
+	unsigned n, col;
+
+	for (n = 0; n < eeprom_size; 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;
+{
+	process_cmdline(argc, argv);
+	read_config_file();
+	init_eeprom_size();
+	fill_eeprom();
+	do_checksum();
+	emit_output();
+	exit(0);
+}