view rvinterf/tmsh/l1cmd.c @ 973:7c18eac91457

loadtools: round out support for Intel flash families The three Intel flash families encountered so far in Calypso GSM devices are C3, W30 and W18, sizes from 2 to 8 MiB. Let's support all Intel flash chips from these 3 families across this range of sizes.
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 28 Nov 2023 18:56:40 +0000
parents 92c982f67247
children
line wrap: on
line source

/*
 * In this module we are going to implement commands which send
 * TM3 command packets to the L1TM firmware component: RF calibration
 * and test modes.
 */

#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "pktmux.h"
#include "limits.h"
#include "localtypes.h"
#include "tm3.h"
#include "l1tm.h"
#include "exitcodes.h"

cmd_tminit(argc, argv)
	char **argv;
{
	u_char cmdpkt[3];

	cmdpkt[1] = TM_INIT;
	send_etm_cmd(cmdpkt, 1);
	return(0);
}

cmd_tms(argc, argv)
	char **argv;
{
	u16 arg;
	u_char cmdpkt[5];

	arg = strtoul(argv[1], 0, 0);
	cmdpkt[1] = TM_MODE_SET;
	cmdpkt[2] = arg;
	cmdpkt[3] = arg >> 8;
	send_etm_cmd(cmdpkt, 3);
	return(0);
}

cmd_tm3ver(argc, argv)
	char **argv;
{
	u16 arg;
	u_char cmdpkt[5];

	arg = strtoul(argv[1], 0, 16);
	cmdpkt[1] = VERSION_GET;
	cmdpkt[2] = arg;
	cmdpkt[3] = arg >> 8;
	send_etm_cmd(cmdpkt, 3);
	return(0);
}

static
is_num_string(argstr)
	char *argstr;
{
	char *cp = argstr;

	if (!isdigit(*cp++))
		return(0);
	while (*cp) {
		if (!isdigit(*cp++))
			return(0);
	}
	return(1);
}

struct kwtab {
	char	*kw;
	int	val;
};

static
keyword_or_num(argstr, kwtab, valp)
	char *argstr;
	struct kwtab *kwtab;
	u16 *valp;
{
	struct kwtab *tp;

	if (is_num_string(argstr)) {
		*valp = atoi(argstr);
		return(0);
	}
	for (tp = kwtab; tp->kw; tp++) {
		if (!strcmp(tp->kw, argstr)) {
			*valp = tp->val;
			return(0);
		}
	}
	printf("error: non-numeric argument not understood\n");
	return(ERROR_USAGE);
}

static struct kwtab rfe_arg[] = {
	{"stop-all", STOP_ALL},
	{"rx-tch", RX_TCH},
	{"tx-tch", TX_TCH},
	{"rx-tx-tch", RX_TX_TCH},
	{"rx-tx-pdtch", RX_TX_PDTCH},
	{"rx-tch-cont", RX_TCH_CONT},
	{"tx-tch-cont", TX_TCH_CONT},
	{"bcch-loop", BCCH_LOOP},
	{"sb-loop", SB_LOOP},
	{"fb1-loop", FB1_LOOP},
	{"fb0-loop", FB0_LOOP},
	{"single-pm", SINGLE_PM},
	{"rx-tx-pdtch-mon", RX_TX_PDTCH_MON},
	{"rx-tx-mon-tch", RX_TX_MON_TCH},
	{"rx-tx-mon", RX_TX_MON},
	{0, 0}
};

cmd_rfe(argc, argv)
	char **argv;
{
	u16 arg;
	u_char cmdpkt[5];

	if (keyword_or_num(argv[1], rfe_arg, &arg))
		return(ERROR_USAGE);
	cmdpkt[1] = RF_ENABLE;
	cmdpkt[2] = arg;
	cmdpkt[3] = arg >> 8;
	send_etm_cmd(cmdpkt, 3);
	return(0);
}

static struct kwtab stats_config_arg[] = {
	{"loops", LOOPS},
	{"auto-result-loops", AUTO_RESULT_LOOPS},
	{"auto-reset-loops", AUTO_RESET_LOOPS},
	{"stat-gprs-slots", STAT_GPRS_SLOTS},
	{"stat-type", STAT_TYPE},
	{"stat-bitmask", STAT_BITMASK},
	{0, 0}
};

cmd_scw(argc, argv)
	char **argv;
{
	u16 index, value;
	u_char cmdpkt[7];

	if (keyword_or_num(argv[1], stats_config_arg, &index))
		return(ERROR_USAGE);
	value = strtoul(argv[2], 0, 0);
	cmdpkt[1] = STATS_CONFIG_WRITE;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	cmdpkt[4] = value;
	cmdpkt[5] = value >> 8;
	send_etm_cmd(cmdpkt, 5);
	return(0);
}

cmd_scr(argc, argv)
	char **argv;
{
	u16 index;
	u_char cmdpkt[5];

	if (keyword_or_num(argv[1], stats_config_arg, &index))
		return(ERROR_USAGE);
	cmdpkt[1] = STATS_CONFIG_READ;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	send_etm_cmd(cmdpkt, 3);
	return(0);
}

static struct kwtab stats_read_arg[] = {
	{"accum", ACCUMULATED_RX_STATS},
	{"most-recent", MOST_RECENT_RX_STATS},
	{0, 0}
};

cmd_sr(argc, argv)
	char **argv;
{
	u16 type, bitmask;
	u_char cmdpkt[7];

	if (keyword_or_num(argv[1], stats_read_arg, &type))
		return(ERROR_USAGE);
	bitmask = strtoul(argv[2], 0, 16);
	cmdpkt[1] = STATS_READ;
	cmdpkt[2] = type;
	cmdpkt[3] = type >> 8;
	cmdpkt[4] = bitmask;
	cmdpkt[5] = bitmask >> 8;
	send_etm_cmd(cmdpkt, 5);
	return(0);
}

static struct kwtab rf_param_arg[] = {
	{"bcch-arfcn", BCCH_ARFCN},
	{"tch-arfcn", TCH_ARFCN},
	{"mon-arfcn", MON_ARFCN},
	{"pdtch-arfcn", PDTCH_ARFCN},
	{"std-band", STD_BAND_FLAG},
	{"afc-enable", AFC_ENA_FLAG},
	{"afc-dac-val", AFC_DAC_VALUE},
	{"init-afc-dac", INITIAL_AFC_DAC},
	{"multislot-class", MULTISLOT_CLASS},
	{0, 0}
};

cmd_rfpw2(argc, argv)
	char **argv;
{
	u16 index, value;
	u_char cmdpkt[7];

	if (keyword_or_num(argv[1], rf_param_arg, &index))
		return(ERROR_USAGE);
	value = strtol(argv[2], 0, 0);
	cmdpkt[1] = RF_PARAM_WRITE;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	cmdpkt[4] = value;
	cmdpkt[5] = value >> 8;
	send_etm_cmd(cmdpkt, 5);
	return(0);
}

cmd_rfpw3(argc, argv)
	char **argv;
{
	u16 index;
	u8 val1, val2;
	u_char cmdpkt[7];

	if (keyword_or_num(argv[1], rf_param_arg, &index))
		return(ERROR_USAGE);
	val1 = strtoul(argv[2], 0, 0);
	val2 = strtoul(argv[3], 0, 0);
	cmdpkt[1] = RF_PARAM_WRITE;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	cmdpkt[4] = val1;
	cmdpkt[5] = val2;
	send_etm_cmd(cmdpkt, 5);
	return(0);
}

cmd_rfpw(argc, argv)
	char **argv;
{
	switch (argc) {
	case 3:
		return cmd_rfpw2(argc, argv);
	case 4:
		return cmd_rfpw3(argc, argv);
	default:
		fprintf(stderr, "BUG: wrong argc in cmd_rfpw()\n");
		return(ERROR_BUG);
	}
}

cmd_rfpr(argc, argv)
	char **argv;
{
	u16 index;
	u_char cmdpkt[5];

	if (keyword_or_num(argv[1], rf_param_arg, &index))
		return(ERROR_USAGE);
	cmdpkt[1] = RF_PARAM_READ;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	send_etm_cmd(cmdpkt, 3);
	return(0);
}

static struct kwtab rf_table_arg[] = {
	{"rx-agc-table", RX_AGC_TABLE},
	{"afcparams", AFC_PARAMS},
	{"rx-agc-global-params", RX_AGC_GLOBAL_PARAMS},
	{"rx-il2agc-max", RX_IL_2_AGC_MAX},
	{"rx-il2agc-pwr", RX_IL_2_AGC_PWR},
	{"rx-il2agc-av", RX_IL_2_AGC_AV},
	{"tx-levels", TX_LEVELS},
	{"tx-calchan", TX_CAL_CHAN},
	{"tx-caltemp", TX_CAL_TEMP},
	{"tx-cal-extreme", TX_CAL_EXTREME},
	{"rx-calchan", RX_CAL_CHAN},
	{"rx-caltemp", RX_CAL_TEMP},
	{"rx-cal-level", RX_CAL_LEVEL},
	{"rx-agcparams", RX_AGC_PARAMS},
	{"rx-agcparams-pcs", RX_AGC_PARAMS_PCS},
	{"tx-data-buffer", TX_DATA_BUFFER},
	{"rlc-tx-buffer-cs1", RLC_TX_BUFFER_CS1},
	{"rlc-tx-buffer-cs2", RLC_TX_BUFFER_CS2},
	{"rlc-tx-buffer-cs3", RLC_TX_BUFFER_CS3},
	{"rlc-tx-buffer-cs4", RLC_TX_BUFFER_CS4},
	{0, 0}
};

cmd_rftw(argc, argv)
	char **argv;
{
	u16 index;
	u_char cmdpkt[MAX_RF_TABLE_SIZE + 4];
	int rc;
	char *format;
	unsigned size;

	if (keyword_or_num(argv[1], rf_table_arg, &index))
		return(ERROR_USAGE);
	cmdpkt[1] = RF_TABLE_WRITE;
	cmdpkt[2] = index;
	rc = read_rf_table_ext(argv[2], cmdpkt + 3, 0, &format, &size);
	if (rc)
		return(rc);
	if (argc > 3) {
		if (strcmp(argv[3], "force")) {
			printf("error: unexpected 3rd argument\n");
			return(ERROR_USAGE);
		}
	} else {
		rc = rftw_index_format_check(index, format);
		if (rc)
			return(rc);
	}
	send_etm_cmd(cmdpkt, size + 2);
	return(0);
}

cmd_rftr(argc, argv)
	char **argv;
{
	u16 index;
	u_char cmdpkt[4];

	if (keyword_or_num(argv[1], rf_table_arg, &index))
		return(ERROR_USAGE);
	cmdpkt[1] = RF_TABLE_READ;
	cmdpkt[2] = index;
	send_etm_cmd(cmdpkt, 2);
	return(0);
}

static struct kwtab rx_param_arg[] = {
	{"agc-gain", RX_AGC_GAIN},
	{"timeslot", RX_TIMESLOT},
	{"agc-enable", RX_AGC_ENA_FLAG},
	{"pm-enable", RX_PM_ENABLE},
	{"front-delay", RX_FRONT_DELAY},
	{"flags-cal", RX_FLAGS_CAL},
	{"flags-platform", RX_FLAGS_PLATFORM},
	{"flags-iq-swap", RX_FLAGS_IQ_SWAP},
	{"flags-all", RX_FLAGS_ALL},
	{"gprs-slots", RX_GPRS_SLOTS},
	{"gprs-coding", RX_GPRS_CODING},
	{0, 0}
};

cmd_rxpw(argc, argv)
	char **argv;
{
	u16 index, value;
	u_char cmdpkt[7];

	if (keyword_or_num(argv[1], rx_param_arg, &index))
		return(ERROR_USAGE);
	value = strtol(argv[2], 0, 0);
	cmdpkt[1] = RX_PARAM_WRITE;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	cmdpkt[4] = value;
	cmdpkt[5] = value >> 8;
	send_etm_cmd(cmdpkt, 5);
	return(0);
}

cmd_rxpr(argc, argv)
	char **argv;
{
	u16 index;
	u_char cmdpkt[5];

	if (keyword_or_num(argv[1], rx_param_arg, &index))
		return(ERROR_USAGE);
	cmdpkt[1] = RX_PARAM_READ;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	send_etm_cmd(cmdpkt, 3);
	return(0);
}

static struct kwtab tx_param_arg[] = {
	{"pwr-level", TX_PWR_LEVEL},
	{"apc-dac", TX_APC_DAC},
	{"ramp-template", TX_RAMP_TEMPLATE},
	{"chan-cal-table", TX_CHAN_CAL_TABLE},
	{"burst-type", TX_BURST_TYPE},
	{"burst-data", TX_BURST_DATA},
	{"timing-advance", TX_TIMING_ADVANCE},
	{"training-seq", TX_TRAINING_SEQ},
	{"pwr-skip", TX_PWR_SKIP},
	{"flags-cal", TX_FLAGS_CAL},
	{"flags-platform", TX_FLAGS_PLATFORM},
	{"flags-iq-swap", TX_FLAGS_IQ_SWAP},
	{"flags-all", TX_FLAGS_ALL},
	{"gprs-power0", TX_GPRS_POWER0},
	{"gprs-power1", TX_GPRS_POWER1},
	{"gprs-power2", TX_GPRS_POWER2},
	{"gprs-power3", TX_GPRS_POWER3},
	{"gprs-power4", TX_GPRS_POWER4},
	{"gprs-power5", TX_GPRS_POWER5},
	{"gprs-power6", TX_GPRS_POWER6},
	{"gprs-power7", TX_GPRS_POWER7},
	{"gprs-slots", TX_GPRS_SLOTS},
	{"gprs-coding", TX_GPRS_CODING},
	{0, 0}
};

cmd_txpw(argc, argv)
	char **argv;
{
	u16 index, value;
	u_char cmdpkt[7];

	if (keyword_or_num(argv[1], tx_param_arg, &index))
		return(ERROR_USAGE);
	value = strtol(argv[2], 0, 0);
	cmdpkt[1] = TX_PARAM_WRITE;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	cmdpkt[4] = value;
	cmdpkt[5] = value >> 8;
	send_etm_cmd(cmdpkt, 5);
	return(0);
}

cmd_txpr(argc, argv)
	char **argv;
{
	u16 index;
	u_char cmdpkt[5];

	if (keyword_or_num(argv[1], tx_param_arg, &index))
		return(ERROR_USAGE);
	cmdpkt[1] = TX_PARAM_READ;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	send_etm_cmd(cmdpkt, 3);
	return(0);
}

cmd_ttw(argc, argv)
	char **argv;
{
	unsigned index;
	u_char cmdpkt[36];
	int rc;

	index = strtoul(argv[1], 0, 0);
	if (index >= 16) {
		printf("error: index out of range\n");
		return(ERROR_USAGE);
	}
	cmdpkt[1] = TX_TEMPLATE_WRITE;
	cmdpkt[2] = index;
	rc = read_tx_ramp_template(argv[2], cmdpkt + 3);
	if (rc)
		return(rc);
	send_etm_cmd(cmdpkt, 34);
	return(0);
}

cmd_ttr(argc, argv)
	char **argv;
{
	unsigned index;
	u_char cmdpkt[4];

	index = strtoul(argv[1], 0, 0);
	if (index >= 16) {
		printf("error: index out of range\n");
		return(ERROR_USAGE);
	}
	cmdpkt[1] = TX_TEMPLATE_READ;
	cmdpkt[2] = index;
	send_etm_cmd(cmdpkt, 2);
	return(0);
}

static struct kwtab misc_param_arg[] = {
	{"adc-interval", ADC_INTERVAL},
	{"adc-enable", ADC_ENA_FLAG},
	{"converted-adc0", CONVERTED_ADC0},
	{"converted-adc1", CONVERTED_ADC1},
	{"converted-adc2", CONVERTED_ADC2},
	{"converted-adc3", CONVERTED_ADC3},
	{"converted-adc4", CONVERTED_ADC4},
	{"converted-adc5", CONVERTED_ADC5},
	{"converted-adc6", CONVERTED_ADC6},
	{"converted-adc7", CONVERTED_ADC7},
	{"converted-adc8", CONVERTED_ADC8},
	{"raw-adc0", RAW_ADC0},
	{"raw-adc1", RAW_ADC1},
	{"raw-adc2", RAW_ADC2},
	{"raw-adc3", RAW_ADC3},
	{"raw-adc4", RAW_ADC4},
	{"raw-adc5", RAW_ADC5},
	{"raw-adc6", RAW_ADC6},
	{"raw-adc7", RAW_ADC7},
	{"raw-adc8", RAW_ADC8},
	{"adc0-coeff-a", ADC0_COEFF_A},
	{"adc1-coeff-a", ADC1_COEFF_A},
	{"adc2-coeff-a", ADC2_COEFF_A},
	{"adc3-coeff-a", ADC3_COEFF_A},
	{"adc4-coeff-a", ADC4_COEFF_A},
	{"adc5-coeff-a", ADC5_COEFF_A},
	{"adc6-coeff-a", ADC6_COEFF_A},
	{"adc7-coeff-a", ADC7_COEFF_A},
	{"adc8-coeff-a", ADC8_COEFF_A},
	{"adc0-coeff-b", ADC0_COEFF_B},
	{"adc1-coeff-b", ADC1_COEFF_B},
	{"adc2-coeff-b", ADC2_COEFF_B},
	{"adc3-coeff-b", ADC3_COEFF_B},
	{"adc4-coeff-b", ADC4_COEFF_B},
	{"adc5-coeff-b", ADC5_COEFF_B},
	{"adc6-coeff-b", ADC6_COEFF_B},
	{"adc7-coeff-b", ADC7_COEFF_B},
	{"adc8-coeff-b", ADC8_COEFF_B},
	{"sleep-mode", SLEEP_MODE},
	{"current-tm-mode", CURRENT_TM_MODE},
	{0, 0}
};

cmd_mpw(argc, argv)
	char **argv;
{
	u16 index, value;
	u_char cmdpkt[7];

	if (keyword_or_num(argv[1], misc_param_arg, &index))
		return(ERROR_USAGE);
	value = strtol(argv[2], 0, 0);
	cmdpkt[1] = MISC_PARAM_WRITE;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	cmdpkt[4] = value;
	cmdpkt[5] = value >> 8;
	send_etm_cmd(cmdpkt, 5);
	return(0);
}

cmd_mpr(argc, argv)
	char **argv;
{
	u16 index;
	u_char cmdpkt[5];

	if (keyword_or_num(argv[1], misc_param_arg, &index))
		return(ERROR_USAGE);
	cmdpkt[1] = MISC_PARAM_READ;
	cmdpkt[2] = index;
	cmdpkt[3] = index >> 8;
	send_etm_cmd(cmdpkt, 3);
	return(0);
}

static struct kwtab me_arg[] = {
	{"mkdirs", CFG_WRITE_MKDIRS},
	{"save-rf-cal", CFG_WRITE_RF_CAL},
	{"save-rf-cfg", CFG_WRITE_RF_CFG},
	{"save-tx-cal", CFG_WRITE_TX_CAL},
	{"save-tx-cfg", CFG_WRITE_TX_CFG},
	{"save-rx-cal", CFG_WRITE_RX_CAL},
	{"save-rx-cfg", CFG_WRITE_RX_CFG},
	{"save-sys-cal", CFG_WRITE_SYS_CAL},
	{"save-sys-cfg", CFG_WRITE_SYS_CFG},
	{0, 0}
};

cmd_me(argc, argv)
	char **argv;
{
	u16 arg;
	u_char cmdpkt[5];

	if (keyword_or_num(argv[1], me_arg, &arg))
		return(ERROR_USAGE);
	cmdpkt[1] = MISC_ENABLE;
	cmdpkt[2] = arg;
	cmdpkt[3] = arg >> 8;
	send_etm_cmd(cmdpkt, 3);
	return(0);
}