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