FreeCalypso > hg > fc-magnetite
view src/cs/layer1/tm_cust0/l1tm_cust.c @ 600:8f50b202e81f
board preprocessor conditionals: prep for more FC hw in the future
This change eliminates the CONFIG_TARGET_FCDEV3B preprocessor symbol and
all preprocessor conditionals throughout the code base that tested for it,
replacing them with CONFIG_TARGET_FCFAM or CONFIG_TARGET_FCMODEM. These
new symbols are specified as follows:
CONFIG_TARGET_FCFAM is intended to cover all hardware designs created by
Mother Mychaela under the FreeCalypso trademark. This family will include
modem products (repackagings of the FCDEV3B, possibly with RFFE or even
RF transceiver changes), and also my desired FreeCalypso handset product.
CONFIG_TARGET_FCMODEM is intended to cover all FreeCalypso modem products
(which will be firmware-compatible with the FCDEV3B if they use TI Rita
transceiver, or will require a different fw build if we switch to one of
Silabs Aero transceivers), but not the handset product. Right now this
CONFIG_TARGET_FCMODEM preprocessor symbol is used to conditionalize
everything dealing with MCSI.
At the present moment the future of FC hardware evolution is still unknown:
it is not known whether we will ever have any beyond-FCDEV3B hardware at all
(contingent on uncertain funding), and if we do produce further FC hardware
designs, it is not known whether they will retain the same FIC modem core
(triband), if we are going to have a quadband design that still retains the
classic Rita transceiver, or if we are going to switch to Silabs Aero II
or some other transceiver. If we produce a quadband modem that still uses
Rita, it will run exactly the same fw as the FCDEV3B thanks to the way we
define TSPACT signals for the RF_FAM=12 && CONFIG_TARGET_FCFAM combination,
and the current fcdev3b build target will be renamed to fcmodem. OTOH, if
that putative quadband modem will be Aero-based, then it will require a
different fw build target, the fcdev3b target will stay as it is, and the
two targets will both define CONFIG_TARGET_FCFAM and CONFIG_TARGET_FCMODEM,
but will have different RF_FAM numbers. But no matter which way we are
going to evolve, it is not right to have conditionals on CONFIG_TARGET_FCDEV3B
in places like ACI, and the present change clears the way for future
evolution.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 01 Apr 2019 01:05:24 +0000 |
parents | b870b6a44d31 |
children |
line wrap: on
line source
/************* Revision Controle System Header ************* * GSM Layer 1 software * L1TM_CUST.C * * Filename %M% * Version %I% * Date %G% * ************* Revision Controle System Header *************/ #include "l1_confg.h" #if TESTMODE #include "tm_defs.h" #include "l1_const.h" #include "l1_types.h" #include "l1tm_defty.h" #include "l1tm_cust.h" #if (AUDIO_TASK == 1) #include "l1audio_const.h" #include "l1audio_cust.h" #include "l1audio_defty.h" #endif #if (L1_GTT == 1) #include "l1gtt_const.h" #include "l1gtt_defty.h" #endif #include "l1_defty.h" #include "l1_msgty.h" #include "l1_tabs.h" #include "l1tm_msgty.h" #include "l1tm_varex.h" #include "abb.h" #if (RF==35) #include "tpudrv35.h" #include "l1_rf35.h" #endif #if (RF==12) #include "tpudrv12.h" #include "l1_rf12.h" #endif #if (RF==10) #include "tpudrv10.h" #include "l1_rf10.h" #endif #if (RF==8) #include "tpudrv8.h" #include "l1_rf8.h" #endif #if (RF==2) #include "l1_rf2.h" #endif #include <string.h> // Import band configuration from Flash module (need to replace by an access function) //extern UWORD8 std; extern T_L1_CONFIG l1_config; extern T_RF rf; extern T_RF_BAND rf_band[GSM_BANDS]; extern UWORD16 AGC_TABLE[AGC_TABLE_SIZE]; extern T_ADC adc; extern T_ADCCAL adc_cal; extern UWORD16 TM_ul_data[16]; //Uplink data to be stored into ABB Uplink buffer extern T_STD_CONFIG std_config[]; static UWORD8 tm_band = 0; // External function prototypes void get_cal_from_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id); UWORD8 save_cal_in_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id); void Cust_init_std(void); void l1_tpu_init_light(void); enum { TM_RF_ID = 0, TM_ADC_ID = 1 }; typedef signed char effs_t; // external FFS function prototypes effs_t ffs_mkdir(const char *pathname); void config_ffs_write(char type); /***********************************************************************/ /* TESTMODE 4.X */ /***********************************************************************/ /*----------------------------------------------------------*/ /* Cust_tm_init() */ /*----------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : Init default configuration for TM params */ /*----------------------------------------------------------*/ void Cust_tm_init(void) { UWORD32 i; l1_config.adc_enable = ADC_ENABLE; // ADC readings enabled l1_config.agc_enable = AGC_ENABLE; // AGC algo enabled l1_config.afc_enable = AFC_ENABLE; // AFC algo enabled l1_config.tmode.rf_params.bcch_arfcn = TM_BCCH_ARFCN; l1_config.tmode.rf_params.tch_arfcn = TM_TCH_ARFCN; l1_config.tmode.rf_params.mon_arfcn = TM_MON_ARFCN; l1_config.tmode.rf_params.channel_type = TM_CHAN_TYPE; // TCH_F l1_config.tmode.rf_params.subchannel = TM_SUB_CHAN; l1_config.tmode.rf_params.reload_ramps_flag = 0; l1_config.tmode.rf_params.tmode_continuous = TM_NO_CONTINUOUS; l1_config.tmode.rx_params.slot_num = TM_SLOT_NUM; // Time Slot l1_config.tmode.rx_params.agc = TM_AGC_VALUE; //This may be outside the range of the RF chip used l1_config.tmode.rx_params.pm_enable = TM_PM_ENABLE; l1_config.tmode.rx_params.lna_off = TM_LNA_OFF; l1_config.tmode.rx_params.number_of_measurements = TM_NUM_MEAS; l1_config.tmode.rx_params.place_of_measurement = TM_WIN_MEAS; l1_config.tmode.tx_params.txpwr = TM_TXPWR; // Min power level for GSM900 l1_config.tmode.tx_params.txpwr_skip = TM_TXPWR_SKIP; l1_config.tmode.tx_params.timing_advance = TM_TA; l1_config.tmode.tx_params.burst_type = TM_BURST_TYPE; // default is normal up-link burst l1_config.tmode.tx_params.burst_data = TM_BURST_DATA; // default is all zeros l1_config.tmode.tx_params.tsc = TM_TSC; // Training Sequence ("BCC" on BSS) #if (CODE_VERSION != SIMULATION) l1_config.tmode.stats_config.num_loops = TM_NUM_LOOPS; // 0 actually means infinite #else l1_config.tmode.stats_config.num_loops = 4; // 0 actually means infinite #endif l1_config.tmode.stats_config.auto_result_loops = TM_AUTO_RESULT_LOOPS; // 0 actually means infinite l1_config.tmode.stats_config.auto_reset_loops = TM_AUTO_RESET_LOOPS; // 0 actually means infinite l1_config.tmode.stats_config.stat_type = TM_STAT_TYPE; l1_config.tmode.stats_config.stat_bitmask = TM_STAT_BITMASK; #if (CODE_VERSION != SIMULATION) // Initialize APCDEL1 register of Omega ABB_Write_Register_on_page(PAGE0, APCDEL1, (C_APCDEL1 - 0x0004) >> 6); #endif l1tm.tm_msg_received = FALSE; for (i=0;i<16;i++) TM_ul_data[i]=0; #if L1_GPRS l1_config.tmode.rf_params.pdtch_arfcn = TM_PDTCH_ARFCN; l1_config.tmode.rf_params.multislot_class = TM_MULTISLOT_CLASS; l1_config.tmode.stats_config.stat_gprs_slots = TM_STAT_GPRS_SLOTS; l1_config.tmode.rx_params.timeslot_alloc = TM_RX_ALLOCATION; l1_config.tmode.rx_params.coding_scheme = TM_RX_CODING_SCHEME; l1_config.tmode.tx_params.timeslot_alloc = TM_TX_ALLOCATION; l1_config.tmode.tx_params.coding_scheme = TM_TX_CODING_SCHEME; for (i=0; i<8; i++) l1_config.tmode.tx_params.txpwr_gprs[i] = TM_TXPWR_GPRS; for (i=0; i<27; i++) l1_config.tmode.tx_params.rlc_buffer[i] = 0; #endif } /**********************************************************************/ /* Test mode functions used for RF calibration */ /**********************************************************************/ void Cust_tm_rf_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value) { switch (index) { case STD_BAND_FLAG: { UWORD8 std_temp, band_temp; std_temp = value & 0xff; // tm_band = b7..0 of value band_temp = value >> 8; // band = b15..8 of value // get define //if (sizeof(std_config)/sizeof(T_STD_CONFIG) <= std_temp) if (9 <= std_temp) // std max { tm_return->status = E_BADINDEX; break; } else if ( GSM_BANDS <= band_temp) { tm_return->status = E_BADINDEX; break; } else if ( BAND_NONE == std_config[std_temp].band[band_temp]) { tm_return->status = E_BADINDEX; break; } else { l1_config.std.id = std_temp; tm_band = band_temp; // update RAM struct with either default or ffs Cust_init_std(); l1_tpu_init_light(); tm_return->status = E_OK; break; } } case INITIAL_AFC_DAC: { rf.afc.eeprom_afc = (WORD16) value << 3; // shift to put into F13.3 format l1_config.params.eeprom_afc = rf.afc.eeprom_afc; tm_return->status = E_OK; break; } default: { tm_return->status = E_BADINDEX; break; } } // end switch } void Cust_tm_rf_param_read(T_TM_RETURN *tm_return, WORD16 index) { volatile UWORD16 value; switch (index) { case STD_BAND_FLAG: { value = ((tm_band << 8) | (l1_config.std.id) ); // return global std, tm_band (intel format) break; } case INITIAL_AFC_DAC: { value = rf.afc.eeprom_afc >> 3; // returned as F13.3 break; } default: { tm_return->size = 0; tm_return->status = E_BADINDEX; return; } } // end switch memcpy(tm_return->result, (UWORD8 *)&value, 2); tm_return->size = 2; tm_return->status = E_OK; } void Cust_tm_rf_table_write(T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[]) { UWORD8 band=0; tm_return->index = index; // store index before it gets modified tm_return->size = 0; switch (index) { case RX_AGC_TABLE: { if (size != sizeof(AGC_TABLE)) { tm_return->status = E_BADSIZE; break; } memcpy(&AGC_TABLE[0], table, size); tm_return->status = E_OK; break; } case AFC_PARAMS: { #if (VCXO_ALGO == 1) if (size != 24) // 4 UWORD32 + 4 WORD16 values #else if (size != 16) // 4 UWORD32 values #endif { tm_return->status = E_BADSIZE; break; } memcpy(&rf.afc.psi_sta_inv, table, size); l1_config.params.psi_sta_inv = rf.afc.psi_sta_inv; l1_config.params.psi_st = rf.afc.psi_st; l1_config.params.psi_st_32 = rf.afc.psi_st_32; l1_config.params.psi_st_inv = rf.afc.psi_st_inv; #if (CODE_VERSION == NOT_SIMULATION) #if (VCXO_ALGO == 1) l1_config.params.afc_dac_center = rf.afc.dac_center; l1_config.params.afc_dac_min = rf.afc.dac_min; l1_config.params.afc_dac_max = rf.afc.dac_max; l1_config.params.afc_snr_thr = rf.afc.snr_thr; #endif #endif tm_return->status = E_OK; break; } case RX_AGC_GLOBAL_PARAMS: { if (size != 8) // 4 UWORD16 values { tm_return->status = E_BADSIZE; break; } memcpy(&rf.rx.agc.low_agc_noise_thr, table, size); l1_config.params.low_agc_noise_thr = rf.rx.agc.low_agc_noise_thr; l1_config.params.high_agc_sat_thr = rf.rx.agc.high_agc_sat_thr; l1_config.params.low_agc = rf.rx.agc.low_agc; l1_config.params.high_agc = rf.rx.agc.high_agc; tm_return->status = E_OK; break; } case RX_IL_2_AGC_MAX: { if (size != sizeof(rf.rx.agc.il2agc_max)) { tm_return->status = E_BADSIZE; break; } memcpy(&rf.rx.agc.il2agc_max[0], table, size); tm_return->status = E_OK; break; } case RX_IL_2_AGC_PWR: { if (size != sizeof(rf.rx.agc.il2agc_pwr)) { tm_return->status = E_BADSIZE; break; } memcpy(&rf.rx.agc.il2agc_pwr[0], table, size); tm_return->status = E_OK; break; } case RX_IL_2_AGC_AV: { if (size != sizeof(rf.rx.agc.il2agc_av)) { tm_return->status = E_BADSIZE; break; } memcpy(&rf.rx.agc.il2agc_av[0], table, size); tm_return->status = E_OK; break; } case TX_LEVELS: { if (size != sizeof(rf_band[tm_band].tx.levels)) { tm_return->status = E_BADSIZE; break; } memcpy(&rf_band[tm_band].tx.levels[0], table, size); tm_return->status = E_OK; break; } case TX_CAL_CHAN: // generic for all bands { if (size != sizeof(rf_band[tm_band].tx.chan_cal_table)) { tm_return->status = E_BADSIZE; break; } memcpy(&rf_band[tm_band].tx.chan_cal_table[0][0], table, size); tm_return->status = E_OK; break; } case TX_CAL_TEMP: // generic for all bands { if (size != sizeof(rf_band[tm_band].tx.temp)) { tm_return->status = E_BADSIZE; break; } memcpy(&rf_band[tm_band].tx.temp[0], table, size); tm_return->status = E_OK; break; } case RX_CAL_CHAN: // generic for all bands { if (size != sizeof(rf_band[tm_band].rx.agc_bands)) { tm_return->status = E_BADSIZE; break; } memcpy(&rf_band[tm_band].rx.agc_bands[0], table, size); tm_return->status = E_OK; break; } case RX_CAL_TEMP: // generic for all bands { if (size != sizeof(rf_band[tm_band].rx.temp)) { tm_return->status = E_BADSIZE; break; } memcpy(&rf_band[tm_band].rx.temp[0], table, size); tm_return->status = E_OK; break; } case RX_AGC_PARAMS: { if (size != sizeof(rf_band[tm_band].rx.rx_cal_params)) { tm_return->status = E_BADSIZE; break; } memcpy(&rf_band[tm_band].rx.rx_cal_params, table, size); if (tm_band == 0) { l1_config.std.g_magic_band1 = rf_band[tm_band].rx.rx_cal_params.g_magic; l1_config.std.lna_att_band1 = rf_band[tm_band].rx.rx_cal_params.lna_att; l1_config.std.lna_switch_thr_low_band1 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_low; l1_config.std.lna_switch_thr_high_band1 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_high; } else if (tm_band == 1) { l1_config.std.g_magic_band2 = rf_band[tm_band].rx.rx_cal_params.g_magic; l1_config.std.lna_att_band2 = rf_band[tm_band].rx.rx_cal_params.lna_att; l1_config.std.lna_switch_thr_low_band2 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_low; l1_config.std.lna_switch_thr_high_band2 = rf_band[tm_band].rx.rx_cal_params.lna_switch_thr_high; } else { tm_return->status = E_INVAL; break; } tm_return->status = E_OK; break; } case TX_CAL_EXTREME: case RX_CAL_LEVEL: { tm_return->status = E_NOSUBSYS; break; } #if L1_GPRS case RLC_TX_BUFFER_CS1: case RLC_TX_BUFFER_CS2: case RLC_TX_BUFFER_CS3: case RLC_TX_BUFFER_CS4: { UWORD8 i, buffer_size; tm_return->index = index; // store index before it gets modified tm_return->size = 0; buffer_size = size/2 + size%2; // bytes will be concatenated into UWORD16 if (buffer_size > 27) //max. number of data bytes { tm_return->status = E_BADSIZE; break; } // make sure that last byte is zero in case of odd number of bytes table[size] = 0; // init the whole buffer before downloading new data for (i=0; i<27; i++) l1_config.tmode.tx_params.rlc_buffer[i] = 0; for (i=0; i<buffer_size; i++) { l1_config.tmode.tx_params.rlc_buffer[i] = (table[2*i+1] << 8) | table[2*i]; } l1_config.tmode.tx_params.rlc_buffer_size = buffer_size; tm_return->status = E_OK; break; } #endif case TX_DATA_BUFFER: { UWORD8 i; tm_return->index = index; // store index before it gets modified tm_return->size = 0; if (size != 32) // 16 UWORD16 (containing 10 data bits each) { tm_return->status = E_BADSIZE; break; } memcpy(&TM_ul_data, table, size); for (i=0; i<16; i++) { TM_ul_data[i] = TM_ul_data[i] << 6; } tm_return->status = E_OK; break; } default: { tm_return->status = E_BADINDEX; break; } } // end switch } void Cust_tm_rf_table_read(T_TM_RETURN *tm_return, WORD8 index) { switch (index) { case RX_AGC_TABLE: { tm_return->size = sizeof(AGC_TABLE); memcpy(tm_return->result, &AGC_TABLE[0], tm_return->size); break; } case AFC_PARAMS: { #if (VCXO_ALGO == 1) tm_return->size = 24; // 4 UWORD32's + 4 WORD16 #else tm_return->size = 16; // 4 UWORD32's #endif memcpy(tm_return->result, &rf.afc.psi_sta_inv, tm_return->size); break; } case RX_AGC_GLOBAL_PARAMS: { tm_return->size = 8; // 4 UWORD16's memcpy(tm_return->result, &rf.rx.agc.low_agc_noise_thr, tm_return->size); break; } case RX_IL_2_AGC_MAX: { tm_return->size = sizeof(rf.rx.agc.il2agc_max); memcpy(tm_return->result, &rf.rx.agc.il2agc_max[0], tm_return->size); break; } case RX_IL_2_AGC_PWR: { tm_return->size = sizeof(rf.rx.agc.il2agc_pwr); memcpy(tm_return->result, &rf.rx.agc.il2agc_pwr[0], tm_return->size); break; } case RX_IL_2_AGC_AV: { tm_return->size = sizeof(rf.rx.agc.il2agc_av); memcpy(tm_return->result, &rf.rx.agc.il2agc_av[0], tm_return->size); break; } case TX_LEVELS: { tm_return->size = sizeof(rf_band[tm_band].tx.levels); memcpy(tm_return->result, &rf_band[tm_band].tx.levels[0], tm_return->size); break; } case TX_CAL_CHAN: // generic for all bands { tm_return->size = sizeof(rf_band[tm_band].tx.chan_cal_table); memcpy(tm_return->result, &rf_band[tm_band].tx.chan_cal_table[0][0], tm_return->size); break; } case TX_CAL_TEMP: // generic for all bands { tm_return->size = sizeof(rf_band[tm_band].tx.temp); memcpy(tm_return->result, &rf_band[tm_band].tx.temp[0], tm_return->size); break; } case RX_CAL_CHAN: // generic for all bands { tm_return->size = sizeof(rf_band[tm_band].rx.agc_bands); memcpy(tm_return->result, &rf_band[tm_band].rx.agc_bands[0], tm_return->size); break; } case RX_CAL_TEMP: // generic for all bands { tm_return->size = sizeof(rf_band[tm_band].rx.temp); memcpy(tm_return->result, &rf_band[tm_band].rx.temp[0], tm_return->size); break; } case RX_AGC_PARAMS: { // WARNING: sizeof(rf.rx.rx_cal_params[band]) returns 12 because of alignment tm_return->size = 10; // five UWORD16's memcpy(tm_return->result, &rf_band[tm_band].rx.rx_cal_params, tm_return->size); break; } case TX_CAL_EXTREME: case RX_CAL_LEVEL: { tm_return->size = 0; tm_return->status = E_NOSUBSYS; return; } #if L1_GPRS case RLC_TX_BUFFER_CS1: case RLC_TX_BUFFER_CS2: case RLC_TX_BUFFER_CS3: case RLC_TX_BUFFER_CS4: { tm_return->size = l1_config.tmode.tx_params.rlc_buffer_size * 2; // UWORD16's memcpy(tm_return->result, &l1_config.tmode.tx_params.rlc_buffer[0], tm_return->size); break; } #endif case TX_DATA_BUFFER: { UWORD8 i; for (i=0; i<16; i++) { tm_return->result[2*i]=(TM_ul_data[i] >> 6) & 0x00FF; tm_return->result[2*i+1]=(TM_ul_data[i] >> 14) & 0x0003; } tm_return->size = 32; //16*UWORD16 break; } #if (RF==35) case RX_PLL_TUNING_TABLE: { tm_return->size = sizeof(pll_tuning); //6*UWORD16 memcpy(tm_return->result, &pll_tuning, tm_return->size); pll_tuning.enable = 0; break; } #endif default: { tm_return->size = 0; tm_return->status = E_BADINDEX; return; } } // end switch tm_return->index = index; tm_return->status = E_OK; } void Cust_tm_rx_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value) { switch (index) { case RX_FRONT_DELAY: { //delay for dual band not implemented yet rf.tx.prg_tx = value; l1_config.params.prg_tx_gsm = rf.tx.prg_tx; l1_config.params.prg_tx_dcs = rf.tx.prg_tx; tm_return->status = E_OK; break; } default: { tm_return->status = E_BADINDEX; break; } } // end switch } void Cust_tm_rx_param_read(T_TM_RETURN *tm_return, WORD16 index) { volatile UWORD16 value; switch (index) { case RX_FRONT_DELAY: { value = rf.tx.prg_tx; break; } default: { tm_return->status = E_BADINDEX; tm_return->size = 0; return; } } // end switch memcpy(tm_return->result, (UWORD8 *)&value, 2); tm_return->size = 2; tm_return->status = E_OK; } void Cust_tm_tx_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value, UWORD8 band) { switch (index) { case TX_APC_DAC: { // generic for all bands rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].apc = value; tm_return->status = E_OK; break; } case TX_RAMP_TEMPLATE: { if (value >= sizeof(rf_band[tm_band].tx.ramp_tables)/sizeof(rf_band[tm_band].tx.ramp_tables[0])) // [0..15] { tm_return->status = E_INVAL; break; } // generic for all bands rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].ramp_index = value; tm_return->status = E_OK; l1_config.tmode.rf_params.reload_ramps_flag = 1; break; } case TX_CHAN_CAL_TABLE: { if (value >= sizeof(rf_band[tm_band].tx.chan_cal_table)/sizeof(rf_band[tm_band].tx.chan_cal_table[0])) { tm_return->status = E_INVAL; break; } // generic for all bands rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].chan_cal_index = value; tm_return->status = E_OK; break; } case TX_BURST_TYPE: { if (value > 1) // [0..1] { tm_return->status = E_INVAL; break; } l1_config.tmode.tx_params.burst_type = value; tm_return->status = E_OK; break; } case TX_BURST_DATA: { // range is [0..10], currently we support [0..13] at the moment if (value > 13) { tm_return->status = E_INVAL; break; } l1_config.tmode.tx_params.burst_data = value; tm_return->status = E_OK; break; } case TX_TRAINING_SEQ: { if (value > 7) // [0..7] { tm_return->status = E_INVAL; break; } l1_config.tmode.tx_params.tsc = value; tm_return->status = E_OK; break; } default: { tm_return->status = E_BADINDEX; break; } } // end switch } void Cust_tm_tx_param_read(T_TM_RETURN *tm_return, WORD16 index, UWORD8 band) { volatile UWORD16 value; switch (index) { case TX_PWR_LEVEL: { value = l1_config.tmode.tx_params.txpwr; break; } case TX_APC_DAC: { value = rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].apc; break; } case TX_RAMP_TEMPLATE: { value = rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].ramp_index; break; } case TX_CHAN_CAL_TABLE: { value = rf_band[tm_band].tx.levels[l1_config.tmode.tx_params.txpwr].chan_cal_index; break; } case TX_BURST_TYPE: { value = l1_config.tmode.tx_params.burst_type; break; } case TX_BURST_DATA: { value = l1_config.tmode.tx_params.burst_data; break; } case TX_TIMING_ADVANCE: { value = l1_config.tmode.tx_params.timing_advance; break; } case TX_TRAINING_SEQ: { value = l1_config.tmode.tx_params.tsc; break; } case TX_PWR_SKIP: { value = l1_config.tmode.tx_params.txpwr_skip; break; } #if L1_GPRS case TX_GPRS_POWER0: case TX_GPRS_POWER1: case TX_GPRS_POWER2: case TX_GPRS_POWER3: case TX_GPRS_POWER4: case TX_GPRS_POWER5: case TX_GPRS_POWER6: case TX_GPRS_POWER7: { value = l1_config.tmode.tx_params.txpwr_gprs[index - TX_GPRS_POWER0]; break; } case TX_GPRS_SLOTS: { value = l1_config.tmode.tx_params.timeslot_alloc; break; } case TX_GPRS_CODING: { value = l1_config.tmode.tx_params.coding_scheme; break; } #endif default: { tm_return->status = E_BADINDEX; tm_return->size = 0; return; } } // end switch memcpy(tm_return->result, (UWORD8 *)&value, 2); tm_return->size = 2; tm_return->status = E_OK; } void Cust_tm_tx_template_write(T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[]) { if (index >= sizeof(rf_band[tm_band].tx.ramp_tables)/sizeof(T_TX_RAMP)) { tm_return->status = E_BADINDEX; } else if (size != sizeof(T_TX_RAMP)) { // We are writing both the up and down ramps; size must be exact. tm_return->status = E_BADSIZE; } else { memcpy(rf_band[tm_band].tx.ramp_tables[index].ramp_up, &table[0], size/2); memcpy(rf_band[tm_band].tx.ramp_tables[index].ramp_down, &table[size/2], size/2); tm_return->status = E_OK; l1_config.tmode.rf_params.reload_ramps_flag = 1; } tm_return->index = index; tm_return->size = 0; } void Cust_tm_tx_template_read(T_TM_RETURN *tm_return, WORD8 index) { tm_return->index = index; if (index >= sizeof(rf_band[tm_band].tx.ramp_tables)/sizeof(T_TX_RAMP)) { tm_return->status = E_BADINDEX; tm_return->size = 0; return; } memcpy(&tm_return->result[0], rf_band[tm_band].tx.ramp_tables[index].ramp_up, sizeof(rf_band[tm_band].tx.ramp_tables[index].ramp_up)); memcpy(&tm_return->result[sizeof(rf_band[tm_band].tx.ramp_tables[index].ramp_up)], rf_band[tm_band].tx.ramp_tables[index].ramp_down, sizeof(rf_band[tm_band].tx.ramp_tables[index].ramp_down)); tm_return->size = sizeof(rf_band[tm_band].tx.ramp_tables[index]); tm_return->status = E_OK; } void Cust_tm_misc_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value) { switch (index) { case GPIOSTATE0: case GPIODIR0: case GPIOSTATE1: case GPIODIR1: case GPIOSTATE0P: case GPIODIR0P: case GPIOSTATE1P: case GPIODIR1P: { tm_return->status = E_NOSUBSYS; break; } case CONVERTED_ADC0: case CONVERTED_ADC1: case CONVERTED_ADC2: case CONVERTED_ADC3: case CONVERTED_ADC4: case CONVERTED_ADC5: case CONVERTED_ADC6: case CONVERTED_ADC7: case CONVERTED_ADC8: { adc.converted[index - CONVERTED_ADC0] = value; tm_return->status = E_OK; break; } case RAW_ADC0: case RAW_ADC1: case RAW_ADC2: case RAW_ADC3: case RAW_ADC4: case RAW_ADC5: case RAW_ADC6: case RAW_ADC7: case RAW_ADC8: { adc.raw[index - RAW_ADC0] = value; tm_return->status = E_OK; break; } case ADC0_COEFF_A: case ADC1_COEFF_A: case ADC2_COEFF_A: case ADC3_COEFF_A: case ADC4_COEFF_A: case ADC5_COEFF_A: case ADC6_COEFF_A: case ADC7_COEFF_A: case ADC8_COEFF_A: { adc_cal.a[index - ADC0_COEFF_A] = value; tm_return->status = E_OK; break; } case ADC0_COEFF_B: case ADC1_COEFF_B: case ADC2_COEFF_B: case ADC3_COEFF_B: case ADC4_COEFF_B: case ADC5_COEFF_B: case ADC6_COEFF_B: case ADC7_COEFF_B: case ADC8_COEFF_B: { adc_cal.b[index - ADC0_COEFF_B] = value; tm_return->status = E_OK; break; } case SLEEP_MODE: { tm_return->status = E_NOSUBSYS; break; } default: { tm_return->status = E_BADINDEX; break; } } // end switch } void Cust_tm_misc_param_read(T_TM_RETURN *tm_return, WORD16 index) { volatile UWORD16 value; switch (index) { case GPIOSTATE0: case GPIODIR0: case GPIOSTATE1: case GPIODIR1: case GPIOSTATE0P: case GPIODIR0P: case GPIOSTATE1P: case GPIODIR1P: { tm_return->status = E_NOSUBSYS; tm_return->size = 0; return; } case CONVERTED_ADC0: case CONVERTED_ADC1: case CONVERTED_ADC2: case CONVERTED_ADC3: case CONVERTED_ADC4: case CONVERTED_ADC5: case CONVERTED_ADC6: case CONVERTED_ADC7: case CONVERTED_ADC8: { value = adc.converted[index - CONVERTED_ADC0]; break; } case RAW_ADC0: case RAW_ADC1: case RAW_ADC2: case RAW_ADC3: case RAW_ADC4: case RAW_ADC5: case RAW_ADC6: case RAW_ADC7: case RAW_ADC8: { value = adc.raw[index - RAW_ADC0]; break; } case ADC0_COEFF_A: case ADC1_COEFF_A: case ADC2_COEFF_A: case ADC3_COEFF_A: case ADC4_COEFF_A: case ADC5_COEFF_A: case ADC6_COEFF_A: case ADC7_COEFF_A: case ADC8_COEFF_A: { value = adc_cal.a[index - ADC0_COEFF_A]; break; } case ADC0_COEFF_B: case ADC1_COEFF_B: case ADC2_COEFF_B: case ADC3_COEFF_B: case ADC4_COEFF_B: case ADC5_COEFF_B: case ADC6_COEFF_B: case ADC7_COEFF_B: case ADC8_COEFF_B: { value = adc_cal.b[index - ADC0_COEFF_B]; break; } case SLEEP_MODE: { tm_return->status = E_NOSUBSYS; tm_return->size = 0; return; } default: { tm_return->status = E_BADINDEX; tm_return->size = 0; return; } } // end switch memcpy(tm_return->result, (UWORD8 *)&value, 2); tm_return->size = 2; tm_return->status = E_OK; } void Cust_tm_misc_enable(T_TM_RETURN *tm_return, WORD16 action) { UWORD8 status; // FIXME: This enum really should go into testmode header file. enum ME_CFG_WRITE_E { CFG_WRITE_MKDIRS = 100, CFG_WRITE_RF_CAL = 102, CFG_WRITE_RF_CFG = 103, CFG_WRITE_TX_CAL = 104, CFG_WRITE_TX_CFG = 105, CFG_WRITE_RX_CAL = 106, CFG_WRITE_RX_CFG = 107, CFG_WRITE_SYS_CAL = 108, CFG_WRITE_SYS_CFG = 109 }; tm_return->size = 0; tm_return->index = action; tm_return->status = E_OK; // FIXME: This code should actually be in misc_enable() switch(action) { case CFG_WRITE_MKDIRS: ffs_mkdir("/gsm"); ffs_mkdir("/pcm"); ffs_mkdir("/sys"); ffs_mkdir("/mmi"); ffs_mkdir("/vos"); ffs_mkdir("/var"); ffs_mkdir("/gsm/rf"); ffs_mkdir("/gsm/com"); ffs_mkdir("/vos/vm"); ffs_mkdir("/vos/vrm"); ffs_mkdir("/vos/vrp"); ffs_mkdir("/var/log"); ffs_mkdir("/var/tst"); ffs_mkdir("/gsm/rf/tx"); ffs_mkdir("/gsm/rf/rx"); break; case CFG_WRITE_RF_CAL: config_ffs_write('f'); break; case CFG_WRITE_RF_CFG: config_ffs_write('F'); break; case CFG_WRITE_TX_CAL: config_ffs_write('t'); break; case CFG_WRITE_TX_CFG: config_ffs_write('T'); break; case CFG_WRITE_RX_CAL: config_ffs_write('r'); break; case CFG_WRITE_RX_CFG: config_ffs_write('R'); break; case CFG_WRITE_SYS_CAL: config_ffs_write('s'); break; case CFG_WRITE_SYS_CFG: config_ffs_write('S'); break; default: tm_return->status = E_BADINDEX; } } void Cust_tm_special_param_write(T_TM_RETURN *tm_return, WORD16 index, UWORD16 value) { tm_return->size = 0; tm_return->index = index; tm_return->status = E_NOSYS; } void Cust_tm_special_param_read(T_TM_RETURN *tm_return, WORD16 index) { tm_return->size = 0; tm_return->index = index; tm_return->status = E_NOSYS; } void Cust_tm_special_table_write(T_TM_RETURN *tm_return, WORD8 index, UWORD8 size, UWORD8 table[]) { tm_return->size = 0; tm_return->index = index; tm_return->status = E_NOSYS; } void Cust_tm_special_table_read(T_TM_RETURN *tm_return, WORD8 index) { tm_return->size = 0; tm_return->index = index; tm_return->status = E_NOSYS; } void Cust_tm_special_enable(T_TM_RETURN *tm_return, WORD16 action) { tm_return->size = 0; tm_return->index = action; tm_return->status = E_NOSYS; } #endif // TESTMODE