comparison ffstools/caltools/c1xx-calextr.c @ 294:1416fe200069

c1xx-calextr started
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 18 Nov 2017 17:12:20 +0000
parents
children 77d561735b07
comparison
equal deleted inserted replaced
293:f8eac2de9a5c 294:1416fe200069
1 /*
2 * This program parses Compal's proprietary data structure that contains
3 * the factory RF calibration values among other data, locates those RF
4 * calibration records, extracts their essential content (Rx GMagic and
5 * Tx APC values) and writes this calibration out in the form of FreeCalypso
6 * ASCII RF tables.
7 */
8
9 #include <sys/types.h>
10 #include <sys/file.h>
11 #include <string.h>
12 #include <strings.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16
17 #define COMPAL_SECTOR_LENGTH 0x2000
18
19 u_char sector[COMPAL_SECTOR_LENGTH];
20 u_char endmarker[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
21 u_char record_magic[4] = {0xAA, 0x00, 0x00, 0x00};
22
23 struct band {
24 char *name;
25 unsigned compal_record_id;
26 unsigned record_length;
27 unsigned magic2_offset;
28 unsigned start_plnum;
29 unsigned end_plnum;
30 } bands[] = {
31 {"900", 0x00, 0x94, 0x54, 5, 19},
32 {"1800", 0x01, 0xC8, 0x74, 0, 15},
33 {"1900", 0x02, 0xB4, 0x68, 0, 15},
34 {"850", 0x18, 0x88, 0x4C, 5, 19},
35 };
36
37 read_binfile(filename, offset_arg)
38 char *filename, *offset_arg;
39 {
40 int fd, cc;
41 u_long offset;
42 char *endp;
43
44 fd = open(filename, O_RDONLY);
45 if (fd < 0) {
46 perror(filename);
47 exit(1);
48 }
49 offset = strtoul(offset_arg, &endp, 0);
50 if (*endp) {
51 fprintf(stderr, "error: invalid offset argument \"%s\"\n",
52 offset_arg);
53 exit(1);
54 }
55 lseek(fd, offset, SEEK_SET);
56 cc = read(fd, sector, COMPAL_SECTOR_LENGTH);
57 if (cc != COMPAL_SECTOR_LENGTH) {
58 fprintf(stderr,
59 "error: unable to read Compal sector of %d bytes from %s at offset %s\n",
60 COMPAL_SECTOR_LENGTH, filename, offset_arg);
61 exit(1);
62 }
63 close(fd);
64 }
65
66 process_band_record(band, offset)
67 struct band *band;
68 unsigned offset;
69 {
70 u_char *record;
71
72 record = sector + offset + 8;
73 if (bcmp(record, record_magic, 4)) {
74 printf("bad magic1, skipping\n");
75 return(-1);
76 }
77 if (bcmp(record + band->magic2_offset, record_magic, 4)) {
78 printf("bad magic2, skipping\n");
79 return(-1);
80 }
81 if (bcmp(record + band->magic2_offset + 8, record_magic, 4)) {
82 printf("bad magic3, skipping\n");
83 return(-1);
84 }
85 /* Rx GMagic and Tx levels extraction to be filled */
86 return(0);
87 }
88
89 main(argc, argv)
90 char **argv;
91 {
92 unsigned offset, next_offset;
93 u_char *header;
94 unsigned hdr_words[4];
95 struct band *band;
96 int i;
97
98 if (argc != 3) {
99 fprintf(stderr, "usage: %s binfile offset\n", argv[0]);
100 exit(1);
101 }
102 read_binfile(argv[1], argv[2]);
103 for (offset = 0; ; offset = next_offset) {
104 if (offset > COMPAL_SECTOR_LENGTH - 12)
105 break;
106 header = sector + offset;
107 if (!bcmp(header, endmarker, 8))
108 break;
109 for (i = 0; i < 4; i++)
110 hdr_words[i] = header[i*2] | (header[i*2+1] << 8);
111 if (!hdr_words[3]) {
112 fprintf(stderr,
113 "error at offset 0x%X: rounded record length word is 0\n",
114 offset);
115 exit(1);
116 }
117 if (hdr_words[3] & 3) {
118 fprintf(stderr,
119 "error at offset 0x%X: rounded record length word is not aligned to 4\n",
120 offset);
121 exit(1);
122 }
123 if (hdr_words[3] > COMPAL_SECTOR_LENGTH - offset - 8) {
124 fprintf(stderr,
125 "error at offset 0x%X: rounded record length spills past end of sector\n",
126 offset);
127 exit(1);
128 }
129 if (hdr_words[2] > hdr_words[3]) {
130 fprintf(stderr,
131 "error at offset 0x%X: native record length is greater than rounded\n",
132 offset);
133 exit(1);
134 }
135 next_offset = offset + 8 + hdr_words[3];
136 if (hdr_words[0] != 0x000C)
137 continue;
138 for (band = bands; band->name; band++)
139 if (hdr_words[1] == band->compal_record_id)
140 break;
141 if (!band->name)
142 continue;
143 printf("Found %s MHz calibration record at offset 0x%X\n",
144 band->name, offset);
145 if (hdr_words[2] != band->record_length) {
146 printf("Oops, wrong length, skipping\n");
147 continue;
148 }
149 process_band_record(band, offset);
150 }
151 exit(0);
152 }