changeset 294:1416fe200069

c1xx-calextr started
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 18 Nov 2017 17:12:20 +0000
parents f8eac2de9a5c
children 79434b9de159
files .hgignore ffstools/caltools/Makefile ffstools/caltools/c1xx-calextr.c
diffstat 3 files changed, 163 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sat Nov 18 07:39:23 2017 +0000
+++ b/.hgignore	Sat Nov 18 17:12:20 2017 +0000
@@ -6,6 +6,7 @@
 \.srec$
 
 ^ffstools/cal2text/fc-cal2text$
+^ffstools/caltools/c1xx-calextr$
 ^ffstools/caltools/fc-cal2bin$
 ^ffstools/tiaud/compile$
 ^ffstools/tiaud/decomp$
--- a/ffstools/caltools/Makefile	Sat Nov 18 07:39:23 2017 +0000
+++ b/ffstools/caltools/Makefile	Sat Nov 18 17:12:20 2017 +0000
@@ -1,14 +1,21 @@
 CC=	gcc
 CFLAGS=	-O2
-PROGS=	fc-cal2bin
+PROGS=	c1xx-calextr fc-cal2bin
 INSTBIN=/opt/freecalypso/bin
 
 all:	${PROGS}
 
 LIBRFTAB=	../../librftab/librftab.a
 
-fc-cal2bin:	fc-cal2bin.o ${LIBRFTAB}
-	${CC} ${CFLAGS} -o $@ fc-cal2bin.o ${LIBRFTAB}
+CAL2BIN_OBJS=	fc-cal2bin.o ${LIBRFTAB}
+
+CALEXTR_OBJS=	c1xx-calextr.o
+
+fc-cal2bin:	${CAL2BIN_OBJS}
+	${CC} ${CFLAGS} -o $@ ${CAL2BIN_OBJS}
+
+c1xx-calextr:	${CALEXTR_OBJS}
+	${CC} ${CFLAGS} -o $@ ${CALEXTR_OBJS}
 
 install:
 	mkdir -p ${INSTBIN}
--- /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);
+}