view rvinterf/etmsync/readcal.c @ 948:d16222179c67

doc/Rvinterf-tools: document rvinterf -v changes
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 06 Jun 2023 23:17:10 +0000
parents e40bb5a6c6b9
children
line wrap: on
line source

/*
 * This utility reads the RF calibration data out of a TI-based GSM device
 * using the L1TM protocol over RVTMUX.  Warning: invasive tms 1 and rfpw 7
 * commands are issued to the target in order to select the band of interest!
 */

#include <sys/types.h>
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include "tm3.h"
#include "l1tm.h"
#include "localtypes.h"
#include "exitcodes.h"

int compal_mode;

extern char *socket_pathname;
extern char *rvinterf_ttyport, *rvinterf_Bopt, *rvinterf_lopt, *rvinterf_wopt;

/* macro for encoding std and band in rfpw 7 command */
#define	RFPW_STD_BAND(std,band)	((std) | ((band) << 8))

static struct band {
	char		*argname;
	char		*filename;
	unsigned	rfpw_std_band;
} bands[] = {
	{"900",   "900",  RFPW_STD_BAND(6, 0)},
	{"1800",  "1800", RFPW_STD_BAND(6, 1)},
	{"1900",  "1900", RFPW_STD_BAND(8, 1)},
	{"850",   "850",  RFPW_STD_BAND(8, 0)},
	{"1900s", "1900", RFPW_STD_BAND(3, 0)},
	{"850s",  "850",  RFPW_STD_BAND(7, 0)},
	{0,       0,      0}
};

static void
write_out_file(filename, data, size)
	char *filename;
	u_char *data;
{
	int fd;

	fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
	if (fd < 0) {
		perror(filename);
		exit(ERROR_UNIX);
	}
	write(fd, data, size);
	close(fd);
}

copy_afcdac()
{
	u16 datum;
	u_char bytes[2];
	int rc;

	rc = do_rfpr(INITIAL_AFC_DAC, &datum);
	if (rc)
		exit(rc);
	datum <<= 3;
	bytes[0] = datum;
	bytes[1] = datum >> 8;
	write_out_file("afcdac", bytes, 2);
}

copy_afcparams()
{
	u_char table[24];
	int rc;

	rc = do_rftr(AFC_PARAMS, table, sizeof table);
	if (rc)
		exit(rc);
	write_out_file("afcparams", table, sizeof table);
}

copy_rx_agcparams(bandname)
	char *bandname;
{
	u_char table[8];
	char filename[32];
	int rc;

	rc = do_rftr(RX_AGC_PARAMS, table, sizeof table);
	if (rc)
		exit(rc);
	sprintf(filename, "rx/agcparams.%s", bandname);
	write_out_file(filename, table, sizeof table);
}

copy_rx_calchan(bandname)
	char *bandname;
{
	u_char table[40];
	char filename[32];
	int rc;

	rc = do_rftr(RX_CAL_CHAN, table, sizeof table);
	if (rc)
		exit(rc);
	sprintf(filename, "rx/calchan.%s", bandname);
	write_out_file(filename, table, sizeof table);
}

copy_tx_levels(bandname)
	char *bandname;
{
	u_char table[128];
	char filename[32];
	int rc;

	rc = do_rftr(TX_LEVELS, table, sizeof table);
	if (rc)
		exit(rc);
	sprintf(filename, "tx/levels.%s", bandname);
	write_out_file(filename, table, sizeof table);
}

copy_tx_calchan(bandname)
	char *bandname;
{
	u_char table[128];
	char filename[32];
	int rc;

	rc = do_rftr(TX_CAL_CHAN, table, sizeof table);
	if (rc)
		exit(rc);
	sprintf(filename, "tx/calchan.%s", bandname);
	write_out_file(filename, table, sizeof table);
}

copy_tx_ramps(bandname)
	char *bandname;
{
	u_char table[512];
	char filename[32];
	int rc, i;

	for (i = 0; i < 16; i++) {
		rc = do_ttr(i, table + i * 32);
		if (rc)
			exit(rc);
	}
	sprintf(filename, "tx/ramps.%s", bandname);
	write_out_file(filename, table, sizeof table);
}

process_band(bandname)
	char *bandname;
{
	int rc;

	rc = host_mkdir("rx");
	if (rc)
		exit(rc);
	copy_rx_agcparams(bandname);
	if (!compal_mode)
		copy_rx_calchan(bandname);
	rc = host_mkdir("tx");
	if (rc)
		exit(rc);
	copy_tx_levels(bandname);
	if (!compal_mode)
		copy_tx_calchan(bandname);
	copy_tx_ramps(bandname);
}

single_op_main(argc, argv)
	char **argv;
{
	int rc;
	char **ap;
	struct band *tp;

	if (argc < 2) {
		fprintf(stderr,
		"usage: fc-readcal [options] output-dir band...\n");
		exit(ERROR_USAGE);
	}
	if (chdir(argv[0]) < 0) {
		perror(argv[0]);
		exit(ERROR_UNIX);
	}
	rc = do_tms(1);
	if (rc)
		exit(rc);
	for (ap = argv + 1; *ap; ap++) {
		if (!strcmp(*ap, "afc")) {
			copy_afcdac();
			copy_afcparams();
			continue;
		}
		for (tp = bands; tp->argname; tp++)
			if (!strcmp(*ap, tp->argname))
				break;
		if (!tp->argname) {
			fprintf(stderr, "error: unknown band name \"%s\"\n",
				*ap);
			exit(ERROR_USAGE);
		}
		rc = do_rfpw(STD_BAND_FLAG, tp->rfpw_std_band);
		if (rc)
			exit(rc);
		process_band(tp->filename);
	}
	exit(0);
}

main(argc, argv)
	char **argv;
{
	extern int optind;
	extern char *optarg;
	int c, sopt = 0;

	while ((c = getopt(argc, argv, "B:cl:p:s:w:")) != EOF)
		switch (c) {
		case 'B':
			rvinterf_Bopt = optarg;
			continue;
		case 'c':
			compal_mode++;
			continue;
		case 'l':
			rvinterf_lopt = optarg;
			continue;
		case 'p':
			rvinterf_ttyport = optarg;
			continue;
		case 's':
			socket_pathname = optarg;
			sopt++;
			continue;
		case 'w':
			rvinterf_wopt = optarg;
			continue;
		case '?':
		default:
			/* error msg already printed */
			exit(ERROR_USAGE);
		}
	if (rvinterf_ttyport) {
		if (sopt) {
			fprintf(stderr,
			"%s error: -p and -s options are mutually exclusive\n",
				argv[0]);
			exit(ERROR_USAGE);
		}
		if (compal_mode && !rvinterf_Bopt)
			rvinterf_Bopt = "57600";
		launch_rvinterf(1);
	} else {
		if (rvinterf_Bopt || rvinterf_lopt || rvinterf_wopt) {
			fprintf(stderr,
"%s error: -B, -l and -w options are meaningful only when launching rvinterf\n",
				argv[0]);
			exit(ERROR_USAGE);
		}
		connect_local_socket();
	}

	return single_op_main(argc - optind, argv + optind);
}