view autocal/txcalchan.c @ 116:4ce87a30383f

fc-rfcal-txband: channel calibration implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 13 Feb 2018 06:22:32 +0000
parents 3f63e71b6422
children 4c3f4231a021
line wrap: on
line source

/*
 * This module contains the code for handling Tx calchan tables.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <endian.h>
#include <rvinterf/l1tm.h>
#include <rvinterf/exitcodes.h>
#include "txband.h"
#include "txcalchan.h"

extern double tx_power_meas();
extern vout_t dbm_to_vout();

extern struct txcal_band *txcal_band;
extern struct tx_level tx_levels[MAX_TX_LEVELS];

unsigned tx_calchan_values[TX_CALCHAN_TABLES][TX_CALCHAN_ENTRIES];

init_tx_calchan()
{
	unsigned i, j;

	for (i = 0; i < TX_CALCHAN_TABLES; i++)
		for (j = 0; j < TX_CALCHAN_ENTRIES; j++)
			tx_calchan_values[i][j] = 128;
	return(0);
}

tx_calchan_one_table(tblnum)
	unsigned tblnum;
{
	vout_t vout[TX_CALCHAN_ENTRIES];
	char cmd[80];
	unsigned n, arfcn, plidx;
	double meas;
	int nanflag = 0;
	int apc_delta;
	unsigned apc_wanted;

	printf("Calibrating Tx channel correction table %u (PL #%u)\n", tblnum,
		txcal_band->calchan_plnum[tblnum]);
	do_txpw(TX_PWR_LEVEL, txcal_band->calchan_plnum[tblnum]);
	plidx = txcal_band->calchan_plnum[tblnum] - txcal_band->start_plnum;
	printf("Starting RF Tx on the DUT\n");
	do_rfe(RX_TX_TCH);
	for (n = 0; n < TX_CALCHAN_ENTRIES; n++) {
		arfcn = txcal_band->calchan_ranges[n].test_arfcn;
		sprintf(cmd, "txpwr-cal-channel %u\n", arfcn);
		tsid_command(cmd);
		do_rfpw(TCH_ARFCN, arfcn);
		usleep(20000);
		meas = tx_power_meas();
		printf("ARFCN=%u: %.2f dBm\n", arfcn, meas);
		if (isnan(meas))
			nanflag = 1;
		vout[n] = dbm_to_vout(meas);
	}
	printf("Stopping RF Tx on the DUT\n");
	do_rfe(STOP_ALL);
	if (nanflag) {
		printf("Error: got NaN power measurement, aborting\n");
		exit(ERROR_RFFAIL);
	}

	for (n = 0; n < TX_CALCHAN_ENTRIES; n++) {
		apc_delta = (vout[txcal_band->ref_subband] - vout[n]) /
				tx_levels[plidx].slope;
		apc_wanted = tx_levels[plidx].apc + apc_delta;
		tx_calchan_values[tblnum][n] = (apc_wanted * 128) /
				tx_levels[plidx].apc;
		printf("ARFCN %u-%u: correction=%u\n",
			txcal_band->calchan_ranges[n].lower_bound,
			txcal_band->calchan_ranges[n].upper_bound,
			tx_calchan_values[tblnum][n]);
	}
}

calibrate_tx_calchan()
{
	unsigned tblnum;

	for (tblnum = 0; tblnum < TX_CALCHAN_TABLES; tblnum++)
		tx_calchan_one_table(tblnum);
}

upload_tx_calchan()
{
	unsigned i, j;
	struct tx_calchan_entry l1_table[TX_CALCHAN_TABLES][TX_CALCHAN_ENTRIES];

	for (i = 0; i < TX_CALCHAN_TABLES; i++) {
		for (j = 0; j < TX_CALCHAN_ENTRIES; j++) {
			l1_table[i][j].arfcn_limit =
			    htole16(txcal_band->calchan_ranges[j].upper_bound);
			l1_table[i][j].chan_cal =
				htole16(tx_calchan_values[i][j]);
		}
	}
	do_rftw(TX_CAL_CHAN, l1_table, sizeof l1_table);
	return(0);
}