annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
65
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * This program reads an FTDI EEPROM image from a file (or from stdin)
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * and performs some basic decoding on it. Only the part of the EEPROM
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 * structure that is common for all chips is looked at, and only very
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * shallow decoding is performed, without differentiating by FTDI chip
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 * type. Compared to simply studying EEPROM images in raw hex, the main
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 * utility of this program is decoding and displaying the three textual
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 * ID strings.
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 */
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <sys/types.h>
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <string.h>
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <strings.h>
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include <stdio.h>
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include <stdlib.h>
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 extern unsigned eeprom_size;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 extern u_short eeprom[256];
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 static unsigned useful_size;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 static int
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 verify_eeprom_chksum()
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 u_short chksum = 0xAAAA;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 unsigned n;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 for (n = 0; n < useful_size; n++) {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 chksum ^= eeprom[n];
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 chksum = (chksum << 1) | (chksum >> 15);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 }
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 return (chksum == 0);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 }
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 static void
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 show_string_desc(headline, ptr_word)
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 char *headline;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 unsigned ptr_word;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 unsigned start_byte, desc_len;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 unsigned start_word, total_words;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 unsigned head_word, nchars;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 u_short *sp;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 unsigned n, uni;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 if (!ptr_word) {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 printf("%s NULL\n", headline);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 return;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 }
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 if (ptr_word & 0x0101) {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 inv: printf("%s INVALID\n", headline);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 return;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 }
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 start_byte = ptr_word & 0xFF;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 desc_len = ptr_word >> 8;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 if (useful_size == 64)
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 start_byte &= 0x7F;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 start_word = start_byte >> 1;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 total_words = desc_len >> 1;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 if (start_word < 10)
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 goto inv;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 if (total_words < 1)
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 goto inv;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 if (start_word + total_words >= useful_size)
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 goto inv;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 head_word = eeprom[start_word];
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 if ((head_word & 0xFF) != desc_len)
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 goto inv;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 if ((head_word >> 8) != 0x03)
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 goto inv;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 nchars = total_words - 1;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 printf("%s \"", headline);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 sp = eeprom + start_word + 1;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 for (n = 0; n < nchars; n++) {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 uni = *sp++;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 if (uni < 0x20 || uni > 0x7E) {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 printf("\\u%04X", uni);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 continue;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 }
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 if (uni == '"' || uni == '\\')
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 putchar('\\');
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 putchar(uni);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 }
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 putchar('"');
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 putchar('\n');
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 }
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 main(argc, argv)
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 char **argv;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 if (argc != 2) {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 fprintf(stderr, "usage: %s eeprom-image-file\n", argv[0]);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 exit(1);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 }
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 if (strcmp(argv[1], "-"))
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 read_eeprom_from_file(argv[1]);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 else
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 read_eeprom_from_stdin();
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 switch (eeprom_size) {
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 case 64:
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 printf("EEPROM size: 128 bytes (93C46 or FT232R)\n");
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 useful_size = 64;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 break;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 case 128:
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 printf("EEPROM size: 256 bytes (93C56)\n");
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 useful_size = 128;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 break;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 case 256:
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 printf("EEPROM size: 512 bytes (93C66)\n");
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 useful_size = 128;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 break;
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 default:
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 fprintf(stderr,
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 "BUG: invalid EEPROM size not caught earlier\n");
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 exit(1);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 }
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 printf("EEPROM checksum is %s\n",
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 verify_eeprom_chksum() ? "good" : "BAD!");
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119 printf("FTDI byte 00: 0x%02X\n", eeprom[0] & 0xFF);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 printf("FTDI byte 01: 0x%02X\n", eeprom[0] >> 8);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121 printf("idVendor: 0x%04X\n", eeprom[1]);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 printf("idProduct: 0x%04X\n", eeprom[2]);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
123 printf("bcdDevice: 0x%04X\n", eeprom[3]);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
124 printf("bmAttributes: 0x%02X\n", eeprom[4] & 0xFF);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
125 printf("bMaxPower: %u mA\n", (eeprom[4] >> 8) * 2);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
126 printf("FTDI byte 0A: 0x%02X\n", eeprom[5] & 0xFF);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
127 printf("FTDI byte 0B: 0x%02X\n", eeprom[5] >> 8);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
128 printf("bcdUSB word: 0x%04X\n", eeprom[6]);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
129 show_string_desc("Manuf string: ", eeprom[7]);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
130 show_string_desc("Product string:", eeprom[8]);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
131 show_string_desc("Serial# string:", eeprom[9]);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
132 exit(0);
225dc1d9f2f1 ftee-decode program written, compiles
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
133 }