FreeCalypso > hg > freecalypso-tools
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ffstools/caltools/c1xx-calextr.c Sat Nov 18 17:12:20 2017 +0000 @@ -0,0 +1,152 @@ +/* + * This program parses Compal's proprietary data structure that contains + * the factory RF calibration values among other data, locates those RF + * calibration records, extracts their essential content (Rx GMagic and + * Tx APC values) and writes this calibration out in the form of FreeCalypso + * ASCII RF tables. + */ + +#include <sys/types.h> +#include <sys/file.h> +#include <string.h> +#include <strings.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#define COMPAL_SECTOR_LENGTH 0x2000 + +u_char sector[COMPAL_SECTOR_LENGTH]; +u_char endmarker[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +u_char record_magic[4] = {0xAA, 0x00, 0x00, 0x00}; + +struct band { + char *name; + unsigned compal_record_id; + unsigned record_length; + unsigned magic2_offset; + unsigned start_plnum; + unsigned end_plnum; +} bands[] = { + {"900", 0x00, 0x94, 0x54, 5, 19}, + {"1800", 0x01, 0xC8, 0x74, 0, 15}, + {"1900", 0x02, 0xB4, 0x68, 0, 15}, + {"850", 0x18, 0x88, 0x4C, 5, 19}, +}; + +read_binfile(filename, offset_arg) + char *filename, *offset_arg; +{ + int fd, cc; + u_long offset; + char *endp; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + perror(filename); + exit(1); + } + offset = strtoul(offset_arg, &endp, 0); + if (*endp) { + fprintf(stderr, "error: invalid offset argument \"%s\"\n", + offset_arg); + exit(1); + } + lseek(fd, offset, SEEK_SET); + cc = read(fd, sector, COMPAL_SECTOR_LENGTH); + if (cc != COMPAL_SECTOR_LENGTH) { + fprintf(stderr, +"error: unable to read Compal sector of %d bytes from %s at offset %s\n", + COMPAL_SECTOR_LENGTH, filename, offset_arg); + exit(1); + } + close(fd); +} + +process_band_record(band, offset) + struct band *band; + unsigned offset; +{ + u_char *record; + + record = sector + offset + 8; + if (bcmp(record, record_magic, 4)) { + printf("bad magic1, skipping\n"); + return(-1); + } + if (bcmp(record + band->magic2_offset, record_magic, 4)) { + printf("bad magic2, skipping\n"); + return(-1); + } + if (bcmp(record + band->magic2_offset + 8, record_magic, 4)) { + printf("bad magic3, skipping\n"); + return(-1); + } + /* Rx GMagic and Tx levels extraction to be filled */ + return(0); +} + +main(argc, argv) + char **argv; +{ + unsigned offset, next_offset; + u_char *header; + unsigned hdr_words[4]; + struct band *band; + int i; + + if (argc != 3) { + fprintf(stderr, "usage: %s binfile offset\n", argv[0]); + exit(1); + } + read_binfile(argv[1], argv[2]); + for (offset = 0; ; offset = next_offset) { + if (offset > COMPAL_SECTOR_LENGTH - 12) + break; + header = sector + offset; + if (!bcmp(header, endmarker, 8)) + break; + for (i = 0; i < 4; i++) + hdr_words[i] = header[i*2] | (header[i*2+1] << 8); + if (!hdr_words[3]) { + fprintf(stderr, + "error at offset 0x%X: rounded record length word is 0\n", + offset); + exit(1); + } + if (hdr_words[3] & 3) { + fprintf(stderr, +"error at offset 0x%X: rounded record length word is not aligned to 4\n", + offset); + exit(1); + } + if (hdr_words[3] > COMPAL_SECTOR_LENGTH - offset - 8) { + fprintf(stderr, +"error at offset 0x%X: rounded record length spills past end of sector\n", + offset); + exit(1); + } + if (hdr_words[2] > hdr_words[3]) { + fprintf(stderr, + "error at offset 0x%X: native record length is greater than rounded\n", + offset); + exit(1); + } + next_offset = offset + 8 + hdr_words[3]; + if (hdr_words[0] != 0x000C) + continue; + for (band = bands; band->name; band++) + if (hdr_words[1] == band->compal_record_id) + break; + if (!band->name) + continue; + printf("Found %s MHz calibration record at offset 0x%X\n", + band->name, offset); + if (hdr_words[2] != band->record_length) { + printf("Oops, wrong length, skipping\n"); + continue; + } + process_band_record(band, offset); + } + exit(0); +}