FreeCalypso > hg > fc-usbser-tools
diff fteeprom/ftee-decode.c @ 65:225dc1d9f2f1
ftee-decode program written, compiles
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 12 Sep 2023 22:23:30 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fteeprom/ftee-decode.c Tue Sep 12 22:23:30 2023 +0000 @@ -0,0 +1,133 @@ +/* + * This program reads an FTDI EEPROM image from a file (or from stdin) + * and performs some basic decoding on it. Only the part of the EEPROM + * structure that is common for all chips is looked at, and only very + * shallow decoding is performed, without differentiating by FTDI chip + * type. Compared to simply studying EEPROM images in raw hex, the main + * utility of this program is decoding and displaying the three textual + * ID strings. + */ + +#include <sys/types.h> +#include <string.h> +#include <strings.h> +#include <stdio.h> +#include <stdlib.h> + +extern unsigned eeprom_size; +extern u_short eeprom[256]; + +static unsigned useful_size; + +static int +verify_eeprom_chksum() +{ + u_short chksum = 0xAAAA; + unsigned n; + + for (n = 0; n < useful_size; n++) { + chksum ^= eeprom[n]; + chksum = (chksum << 1) | (chksum >> 15); + } + return (chksum == 0); +} + +static void +show_string_desc(headline, ptr_word) + char *headline; + unsigned ptr_word; +{ + unsigned start_byte, desc_len; + unsigned start_word, total_words; + unsigned head_word, nchars; + u_short *sp; + unsigned n, uni; + + if (!ptr_word) { + printf("%s NULL\n", headline); + return; + } + if (ptr_word & 0x0101) { +inv: printf("%s INVALID\n", headline); + return; + } + start_byte = ptr_word & 0xFF; + desc_len = ptr_word >> 8; + if (useful_size == 64) + start_byte &= 0x7F; + start_word = start_byte >> 1; + total_words = desc_len >> 1; + if (start_word < 10) + goto inv; + if (total_words < 1) + goto inv; + if (start_word + total_words >= useful_size) + goto inv; + head_word = eeprom[start_word]; + if ((head_word & 0xFF) != desc_len) + goto inv; + if ((head_word >> 8) != 0x03) + goto inv; + nchars = total_words - 1; + printf("%s \"", headline); + sp = eeprom + start_word + 1; + for (n = 0; n < nchars; n++) { + uni = *sp++; + if (uni < 0x20 || uni > 0x7E) { + printf("\\u%04X", uni); + continue; + } + if (uni == '"' || uni == '\\') + putchar('\\'); + putchar(uni); + } + putchar('"'); + putchar('\n'); +} + +main(argc, argv) + char **argv; +{ + if (argc != 2) { + fprintf(stderr, "usage: %s eeprom-image-file\n", argv[0]); + exit(1); + } + if (strcmp(argv[1], "-")) + read_eeprom_from_file(argv[1]); + else + read_eeprom_from_stdin(); + switch (eeprom_size) { + case 64: + printf("EEPROM size: 128 bytes (93C46 or FT232R)\n"); + useful_size = 64; + break; + case 128: + printf("EEPROM size: 256 bytes (93C56)\n"); + useful_size = 128; + break; + case 256: + printf("EEPROM size: 512 bytes (93C66)\n"); + useful_size = 128; + break; + default: + fprintf(stderr, + "BUG: invalid EEPROM size not caught earlier\n"); + exit(1); + } + printf("EEPROM checksum is %s\n", + verify_eeprom_chksum() ? "good" : "BAD!"); + printf("FTDI byte 00: 0x%02X\n", eeprom[0] & 0xFF); + printf("FTDI byte 01: 0x%02X\n", eeprom[0] >> 8); + printf("idVendor: 0x%04X\n", eeprom[1]); + printf("idProduct: 0x%04X\n", eeprom[2]); + printf("bcdDevice: 0x%04X\n", eeprom[3]); + printf("bmAttributes: 0x%02X\n", eeprom[4] & 0xFF); + printf("bMaxPower: %u mA\n", (eeprom[4] >> 8) * 2); + printf("FTDI byte 0A: 0x%02X\n", eeprom[5] & 0xFF); + printf("FTDI byte 0B: 0x%02X\n", eeprom[5] >> 8); + printf("bcdUSB word: 0x%04X\n", eeprom[6]); + show_string_desc("Manuf string: ", eeprom[7]); + show_string_desc("Product string:", eeprom[8]); + show_string_desc("Serial# string:", eeprom[9]); + exit(0); +}