diff rvinterf/etmsync/pirmagnetite.c @ 15:5cc0791a6eb6

Pirelli etmsync hacks absorbed into fc-fsio
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 03 Oct 2016 07:18:09 +0000
parents rvinterf/etmsync/pirhackinit.c@e7502631a0f9
children a3763707317f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/etmsync/pirmagnetite.c	Mon Oct 03 07:18:09 2016 +0000
@@ -0,0 +1,167 @@
+/*
+ * This pirelli-magnetite-init special command should ONLY be run
+ * against FreeCalypso Magnetite firmware running on the Pirelli target.
+ * It initializes the FFS for FC Magnetite (essentially TCS211)
+ * appropriately for the Pirelli target, copying the IMEI and the
+ * RF calibration values from Pirelli's factory data block.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "etm.h"
+#include "ffs.h"
+#include "tmffs2.h"
+#include "localtypes.h"
+#include "exitcodes.h"
+
+extern u_char pirelli_imeisv[8];
+
+static
+write_pcm_imei()
+{
+	static char destfile[] = "/pcm/IMEI";
+	u_char swapped[8];
+	int i, d1, d2;
+
+	printf("Writing %s\n", destfile);
+	for (i = 0; i < 8; i++) {
+		d1 = pirelli_imeisv[i] >> 4;
+		d2 = pirelli_imeisv[i] & 0xF;
+		swapped[i] = (d2 << 4) | d1;
+	}
+	return do_short_fwrite(destfile, swapped, 8);
+}
+
+static
+read_mem_region(memaddr, databuf, total_bytes)
+	u32 memaddr;
+	u_char *databuf;
+{
+	int chunk, remain, rc;
+
+	for (remain = total_bytes; remain; remain -= chunk) {
+		chunk = remain;
+		if (chunk > MAX_MEMREAD_BYTES)
+			chunk = MAX_MEMREAD_BYTES;
+		rc = do_memory_read(memaddr, databuf, chunk);
+		if (rc)
+			return(rc);
+		memaddr += chunk;
+		databuf += chunk;
+	}
+	return(0);
+}
+
+static
+write_buf_to_file(pathname, data, datalen)
+	char *pathname;
+	u_char *data;
+{
+	int tfd, rc, chunk, remain;
+
+	if (datalen <= max_short_file_write(pathname))
+		return do_short_fwrite(pathname, data, datalen);
+	/* do it the long way */
+	rc = fd_open(pathname, FFS_O_WRONLY | FFS_O_CREATE | FFS_O_TRUNC, &tfd);
+	if (rc)
+		return(rc);
+	for (remain = datalen; remain; remain -= chunk) {
+		chunk = remain;
+		if (chunk > 240)
+			chunk = 240;
+		rc = fd_write(tfd, data, chunk);
+		if (rc) {
+			fd_close(tfd);
+			return(rc);
+		}
+		data += chunk;
+	}
+	return fd_close(tfd);
+}
+
+static
+copy_calib_record(memaddr, pathname, size)
+	u32 memaddr;
+	char *pathname;
+	int size;
+{
+	u_char *buf;
+	int rc;
+
+	buf = malloc(size);
+	if (!buf) {
+		perror("malloc");
+		exit(ERROR_UNIX);
+	}
+	rc = read_mem_region(memaddr, buf, size);
+	if (rc) {
+		free(buf);
+		return(rc);
+	}
+	rc = write_buf_to_file(pathname, buf, size);
+	free(buf);
+	return(rc);
+}
+
+static struct calmap {
+	u32	offset;
+	int	size;
+	char	*ti_equiv;
+} pirelli_cal_map[] = {
+	{0x06E5, 36,  "/sys/adccal"},
+	{0x072B, 512, "/gsm/rf/tx/ramps.900"},
+	{0x092C, 128, "/gsm/rf/tx/levels.900"},
+	{0x09AD, 128, "/gsm/rf/tx/calchan.900"},
+	{0x0A2E, 512, "/gsm/rf/tx/ramps.1800"},
+	{0x0C2F, 128, "/gsm/rf/tx/levels.1800"},
+	{0x0CB0, 128, "/gsm/rf/tx/calchan.1800"},
+	{0x0D31, 512, "/gsm/rf/tx/ramps.1900"},
+	{0x0F32, 128, "/gsm/rf/tx/levels.1900"},
+	{0x0FB3, 128, "/gsm/rf/tx/calchan.1900"},
+	{0x10AF, 40,  "/gsm/rf/rx/calchan.900"},
+	{0x10D8, 8,   "/gsm/rf/rx/agcparams.900"},
+	{0x10E1, 40,  "/gsm/rf/rx/calchan.1800"},
+	{0x110A, 8,   "/gsm/rf/rx/agcparams.1800"},
+	{0x1113, 40,  "/gsm/rf/rx/calchan.1900"},
+	{0x113C, 8,   "/gsm/rf/rx/agcparams.1900"},
+	{0, 0, 0}
+};
+
+static
+copy_calib_data()
+{
+	struct calmap *tp;
+	int rc;
+
+	printf("Copying calibration records to FFS\n");
+	for (tp = pirelli_cal_map; tp->size; tp++) {
+		rc = copy_calib_record(0x027F0000 + tp->offset, tp->ti_equiv,
+					tp->size);
+		if (rc)
+			return(rc);
+	}
+	return(0);
+}
+
+pirelli_magnetite_init()
+{
+	int rc;
+
+	rc = get_pirelli_imei();
+	if (rc)
+		return(rc);
+	printf("Creating TCS211 file system directories\n");
+	rc = create_std_dirs();
+	if (rc)
+		return(rc);
+	rc = write_pcm_imei();
+	if (rc)
+		return(rc);
+	rc = copy_calib_data();
+	if (rc)
+		return(rc);
+	return set_rfcap("tri900");
+}