FreeCalypso > hg > freecalypso-hwlab
changeset 0:be4cbc0efb7e
ee2232-gen program written
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 05 Apr 2018 10:06:14 +0000 |
parents | |
children | 2312f270fe62 |
files | ee2232/ee2232-gen.c |
diffstat | 1 files changed, 171 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ee2232/ee2232-gen.c Thu Apr 05 10:06:14 2018 +0000 @@ -0,0 +1,171 @@ +#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_short usb_version = 0x0200; + +u_short eeprom[64]; +unsigned eeprom_string_ptr = 0x0B; + +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, "usbver")) + usb_version = 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; + + 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] = 0x0500; + eeprom[4] = (byte09 << 8) | byte08; + eeprom[5] = 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] = 0x46; +} + +do_checksum() +{ + u_short chksum; + 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); +}