FreeCalypso > hg > fc-usbser-tools
view fteeprom/ftee-decode.c @ 68:5cbde3c80c24
fteeprom-{erase,prog}: detach logic: change to detach by default
As it turns out, detaching all ttyUSB interfaces of a multichannel device
does not require outside knowledge of how many channels there are, as in
our previous -d option design that is being removed here - instead we can
read the bNumInterfaces constant from the USB device's config descriptor
and thus know how many interfaces there are in total. Based on this
discovery, change the design of fteeprom-{erase,prog} as follows:
* remove -d option;
* flip the default to where we detach all interfaces by default;
* add -n option to NOT detach any interfaces.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 13 Sep 2023 06:37:03 +0000 |
parents | 225dc1d9f2f1 |
children |
line wrap: on
line source
/* * 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); }