FreeCalypso > hg > freecalypso-tools
view 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 source
/* * 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); }