FreeCalypso > hg > freecalypso-sw
view gsm-fw/L1/cust1/l1_cust.c @ 923:10b4bed10192
gsm-fw/L1: fix for the DSP patch corruption bug
The L1 code we got from the LoCosto fw contains a feature for DSP CPU load
measurement. This feature is a LoCosto-ism, i.e., not applicable to earlier
DBB chips (Calypso) with their respective earlier DSP ROMs. Most of the
code dealing with that feature is conditionalized as #if (DSP >= 38),
but one spot was missed, and the MCU code was writing into an API word
dealing with this feature. In TCS211 this DSP API word happens to be
used by the DSP code patch, hence that write was corrupting the patched
DSP code.
author | Mychaela Falconia <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 19 Oct 2015 17:13:56 +0000 |
parents | eafadfee35b2 |
children |
line wrap: on
line source
/************* Revision Controle System Header ************* * GSM Layer 1 software * L1_CUST.C * * Filename l1_cust.c * Copyright 2003 (C) Texas Instruments * ************* Revision Controle System Header *************/ //#define GLOBAL #include "l1sw.cfg" #include "l1_types.h" #include "string.h" #include "l1_confg.h" #include "l1_const.h" #include "ulpd.h" #include "tm_defs.h" #include "l1_types.h" #include "l1_time.h" #include "l1_trace.h" #include "sys_types.h" #include "l1_macro.h" #if (OP_L1_STANDALONE == 1) #include "serialswitch_core.h" #else #include "uart/serialswitch.h" #endif #include "abb.h" #if(OP_L1_STANDALONE == 0) #include "buzzer/buzzer.h" // for BZ_KeyBeep_OFF function #include "sim/sim.h" #endif #if TESTMODE #include "l1tm_defty.h" #endif #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 #if (L1_MP3 == 1) #include "l1mp3_defty.h" #endif #if (L1_MIDI == 1) #include "l1midi_defty.h" #endif #include "l1_defty.h" #include "l1_msgty.h" #include "l1_tabs.h" #include "l1_varex.h" #include "l1_proto.h" #if (VCXO_ALGO == 1) #include "l1_ctl.h" #endif #if (RF_FAM == 61) #include "drp_drive.h" #include "tpudrv61.h" #include "l1_rf61.h" #include "l1_rf61.c" #endif #if (RF_FAM == 60 ) #include "drp_drive.h" #include "tpudrv60.h" #include "l1_rf60.h" #include "l1_rf60.c" //#include "rf60.h" #endif #if (RF_FAM == 43) #include "tpudrv43.h" #include "l1_rf43.h" #include "l1_rf43.c" #endif #if (RF_FAM == 35) #include "tpudrv35.h" #include "l1_rf35.h" #include "l1_rf35.c" #endif #if (RF_FAM == 12) #include "tpudrv12.h" #include "l1_rf12.h" #include "l1_rf12.c" #endif #if (RF_FAM == 10) #include "tpudrv10.h" #include "l1_rf10.h" #include "l1_rf10.c" #endif #if (RF_FAM == 8) #include "tpudrv8.h" #include "l1_rf8.h" #include "l1_rf8.c" #endif #if (RF_FAM == 2) #include "l1_rf2.h" #include "l1_rf2.c" #endif #if (DRP_FW_EXT == 1) #include "l1_drp_inc.h" #include "l1_ver.h" #endif // Nucleus functions extern INT TMD_Timer_State; extern UWORD32 TMD_Timer; // for big sleep extern UWORD32 TCD_Priority_Groups; extern VOID *TCD_Current_Thread; extern TC_HCB *TCD_Active_HISR_Heads[TC_HISR_PRIORITIES]; extern TC_HCB *TCD_Active_HISR_Tails[TC_HISR_PRIORITIES]; extern TC_PROTECT TCD_System_Protect; #if (L2_L3_SIMUL == 0) #define FFS_WORKAROUND 0 #else #define FFS_WORKAROUND 0 #endif #if (FFS_WORKAROUND == 1) #include "ffs/ffs.h" #else /* typedef signed int int32; typedef signed char effs_t;*/ typedef signed int filesize_t; effs_t ffs_fwrite(const char *name, void *addr, filesize_t size); #if (DRP_FW_EXT == 0) effs_t ffs_fread(const char *name, void *addr, filesize_t size); #endif #endif // Import band configuration from Flash module (need to replace by an access function) //extern UWORD8 std; extern T_L1_CONFIG l1_config; extern T_L1S_GLOBAL l1s; #if(OP_L1_STANDALONE == 0) extern SYS_BOOL cama_sleep_status(void); #endif #if (CODE_VERSION != SIMULATION) // Import serial switch configuration #if (CHIPSET == 12) extern char ser_cfg_info[3]; #else extern char ser_cfg_info[2]; #endif #endif #if(REL99 && FF_PRF) T_TX_LEVEL *Cust_get_uplink_apc_power_reduction(UWORD8 band, UWORD8 number_uplink_timeslot, T_TX_LEVEL *p_tx_level); #endif void get_cal_from_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id); UWORD8 save_cal_in_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id); void config_rf_rw_band(char type, UWORD8 read); void config_rf_read(char type); void config_rf_write(char type); #if (RF_FAM == 61) #include "drp_api.h" extern T_DRP_SW_DATA drp_sw_data_init; extern T_DRP_SW_DATA drp_sw_data_calib; extern T_DRP_SW_DATA drp_sw_data_calib_saved; #endif enum { RF_ID = 0, ADC_ID = 1 }; #if (L1_FF_MULTIBAND == 0) /*-------------------------------------------------------*/ /* Parameters: none */ /* Return: none */ /* Functionality: Defines the location of rf-struct */ /* for each std. */ /*-------------------------------------------------------*/ //omaps00090550 #83 warinng removal static const T_BAND_CONFIG band_config[] = { /*ffs name, default addr, max carrier, min tx pwr */ {"",(T_RF_BAND *) 0,0,0},//undefined {"900", (T_RF_BAND *)&rf_900, 174, 19 },//EGSM {"1800",(T_RF_BAND *)&rf_1800, 374, 15 },//DCS {"1900",(T_RF_BAND *)&rf_1900, 299, 15 },//PCS {"850", (T_RF_BAND *)&rf_850, 124, 19 },//GSM850 #if (RF_FAM == 10) {"1900_us",(T_RF_BAND *)&rf_1900, 299, 15 },//usdual 1900 rf tables are the same as 3band 1900 rf tables at the moment #endif {"900", (T_RF_BAND *)&rf_900, 124, 19 } //GSM, this should be last entry }; /*-------------------------------------------------------*/ /* Parameters: none */ /* Return: none */ /* Functionality: Defines the indices into band_config */ /* for each std. */ /*-------------------------------------------------------*/ const T_STD_CONFIG std_config[] = { /* band1 index, band2 index, txpwr turning point, first arfcn*/ { 0, 0, 0, 0 }, // std = 0 not used { BAND_GSM900, BAND_NONE, 0, 1 }, // std = 1 GSM { BAND_EGSM900, BAND_NONE, 0, 1 }, // std = 2 EGSM { BAND_PCS1900, BAND_NONE, 21, 512 }, // std = 3 PCS { BAND_DCS1800, BAND_NONE, 28, 512 }, // std = 4 DCS { BAND_GSM900, BAND_DCS1800, 28, 1 }, // std = 5 DUAL { BAND_EGSM900, BAND_DCS1800, 28, 1 }, // std = 6 DUALEXT { BAND_GSM850, BAND_NONE, 0, 128 }, // std = 7 850 #if (RF_FAM == 10) { BAND_GSM850, BAND_PCS1900_US, 21, 1 } // std = 8 850/1900 #else { BAND_GSM850, BAND_PCS1900, 21, 1 } // std = 8 850/1900 #endif }; #endif //if (L1_FF_MULTIBAND == 0) /*-------------------------------------------------------*/ /* Prototypes of external functions used in this file. */ /*-------------------------------------------------------*/ void l1_initialize(T_MMI_L1_CONFIG *mmi_l1_config); #if (L1_FF_MULTIBAND == 0) WORD16 Convert_l1_radio_freq (UWORD16 radio_freq); #endif /*-------------------------------------------------------*/ /* Cust_recover_Os() */ /*-------------------------------------------------------*/ /* */ /* Description: adjust OS from sleep duration */ /* ------------ */ /* This function fix the : */ /* - system clock */ /* - Nucleus timers */ /* - xxxxxx (customer dependant) */ /*-------------------------------------------------------*/ UWORD8 Cust_recover_Os(void) { #if (CODE_VERSION != SIMULATION) if (l1_config.pwr_mngt == PWR_MNGT) { UWORD32 current_system_clock; /***************************************************/ // Fix System clock and Nucleus Timers if any.... */ /***************************************************/ // Fix System clock .... current_system_clock = NU_Retrieve_Clock(); current_system_clock += l1s.pw_mgr.sleep_duration; NU_Set_Clock(current_system_clock); // Fix Nucleus timer (if needed) .... if (TMD_Timer_State == TM_ACTIVE) { TMD_Timer -= l1s.pw_mgr.sleep_duration; if (!TMD_Timer) TMD_Timer_State = TM_EXPIRED; } /***************************************************/ // Cust dependant part ... */ /***************************************************/ //............. //............. //.............. return(TRUE); } #endif return(TRUE); //omaps00090550 } /*-------------------------------------------------------*/ /* Cust_check_system() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* GSM 1.5 : */ /* - authorize UWIRE clock to be stopped */ /* and write value in l1s.pw_mgr.modules_status. */ /* - authorize ARMIO clock to be stopped if the light is */ /* off and write value in l1s.pw_mgr.modules_status. */ /* - check if SIM clock have been stopped */ /* before allowing DEEP SLEEP. */ /* - check if UARTs are ready to enter deep sleep */ /* - choose the sleep mode */ /* */ /* Return: */ /* ------- */ /* DO_NOT_SLEEP, FRAME_STOP or CLOCK_STOP */ /*-------------------------------------------------------*/ UWORD8 Cust_check_system(void) { #if (CODE_VERSION != SIMULATION) if (l1_config.pwr_mngt == PWR_MNGT) { #if (L2_L3_SIMUL == 0) // Forbid deep sleep if the light is on if(LT_Status()) { //cut ARMIO and UWIRE clocks in big sleep l1s.pw_mgr.modules_status = ARMIO_CLK_CUT | UWIRE_CLK_CUT ; l1s.pw_mgr.why_big_sleep = BIG_SLEEP_DUE_TO_LIGHT_ON; return(FRAME_STOP); // BIG sleep } #if (OP_L1_STANDALONE == 0) // Forbid deep sleep if the camera is working if(!cama_sleep_status()) { l1s.pw_mgr.why_big_sleep = BIG_SLEEP_DUE_TO_CAMERA; return(FRAME_STOP); // BIG sleep } // Forbid deep sleep if the SIM and UARTs not ready #if (REQUIRED_FOR_ESAMPLE_LOCOSTO) // Forbid deep sleep if the SIM and UARTs not ready if(SIM_SleepStatus()) #endif { #endif #endif if(SER_UartSleepStatus()) { return(CLOCK_STOP); // DEEP sleep } else l1s.pw_mgr.why_big_sleep = BIG_SLEEP_DUE_TO_UART; #if (L2_L3_SIMUL == 0) #if (OP_L1_STANDALONE == 0) } // Forbid deep sleep if the SIM and UARTs not ready #if (REQUIRED_FOR_ESAMPLE_LOCOSTO) else l1s.pw_mgr.why_big_sleep = BIG_SLEEP_DUE_TO_SIM; #endif #endif #endif // cut ARMIO and UWIRE clocks in big sleep l1s.pw_mgr.modules_status = ARMIO_CLK_CUT | UWIRE_CLK_CUT ; return(FRAME_STOP); // BIG sleep } #else // Simulation part return(CLOCK_STOP); // DEEP sleep #endif return(CLOCK_STOP); // omaps00090550 } /*-------------------------------------------------------*/ /* Parameters: none */ /* Return: none */ /* Functionality: Read the RF configuration, tables etc. */ /* from FFS files. */ /*-------------------------------------------------------*/ //omaps00090550 #83-d warnimg removal static const T_CONFIG_FILE config_files_common[] = { #if (CODE_VERSION != SIMULATION) // The first char is NOT part of the filename. It is used for // categorizing the ffs file contents: // f=rf-cal, F=rf-config, // t=tx-cal, T=tx-config, // r=rx-cal, R=rx-config, // s=sys-cal, S=sys-config, "f/gsm/rf/afcdac", &rf.afc.eeprom_afc, sizeof(rf.afc.eeprom_afc), "F/gsm/rf/stdmap", &rf.radio_band_support, sizeof(rf.radio_band_support), #if (VCXO_ALGO == 1) "F/gsm/rf/afcparams", &rf.afc.psi_sta_inv, 4 * sizeof(UWORD32) + 4 * sizeof(WORD16), #else "F/gsm/rf/afcparams", &rf.afc.psi_sta_inv, 4 * sizeof(UWORD32), #endif "R/gsm/rf/rx/agcglobals", &rf.rx.agc, 4 * sizeof(UWORD16), "R/gsm/rf/rx/il2agc", &rf.rx.agc.il2agc_pwr[0], 3 * sizeof(rf.rx.agc.il2agc_pwr), "R/gsm/rf/rx/agcwords", &AGC_TABLE, sizeof(AGC_TABLE), "s/sys/adccal", &adc_cal, sizeof(adc_cal), "S/sys/abb", &abb, sizeof(abb), "S/sys/uartswitch", &ser_cfg_info, sizeof(ser_cfg_info), #if (RF_FAM ==61) "S/sys/drp_wrapper", & drp_wrapper, sizeof(drp_wrapper), #if (DRP_FW_EXT == 0) "S/sys/drp_calibration", & drp_sw_data_calib, sizeof(drp_sw_data_calib), #endif #endif #endif NULL, 0, 0 // terminator }; /*-------------------------------------------------------*/ /* Parameters: none */ /* Return: none */ /* Functionality: Read the RF configurations for */ /* each band from FFS files. These files */ /* are defined for one band, and and used */ /* for all bands. */ /*-------------------------------------------------------*/ //omaps00090550 #83 warning removal static const T_CONFIG_FILE config_files_band[] = { // The first char is NOT part of the filename. It is used for // categorizing the ffs file contents: // f=rf-cal, F=rf-config, // t=tx-cal, T=tx-config, // r=rx-cal, R=rx-config, // s=sys-cal, S=sys-config, // generic for all bands // band[0] is used as template for all bands. "t/gsm/rf/tx/ramps", &rf_band[0].tx.ramp_tables, sizeof(rf_band[0].tx.ramp_tables), "t/gsm/rf/tx/levels", &rf_band[0].tx.levels, sizeof(rf_band[0].tx.levels), "t/gsm/rf/tx/calchan", &rf_band[0].tx.chan_cal_table, sizeof(rf_band[0].tx.chan_cal_table), "T/gsm/rf/tx/caltemp", &rf_band[0].tx.temp, sizeof(rf_band[0].tx.temp), "r/gsm/rf/rx/calchan", &rf_band[0].rx.agc_bands, sizeof(rf_band[0].rx.agc_bands), "R/gsm/rf/rx/caltemp", &rf_band[0].rx.temp, sizeof(rf_band[0].rx.temp), "r/gsm/rf/rx/agcparams", &rf_band[0].rx.rx_cal_params, sizeof(rf_band[0].rx.rx_cal_params), NULL, 0, 0 // terminator }; void config_ffs_read(char type) { config_rf_read(type); config_rf_rw_band(type, 1); } void config_ffs_write(char type) { config_rf_write(type); config_rf_rw_band(type, 0); } void config_rf_read(char type) { const T_CONFIG_FILE *file = config_files_common; while (file->name != NULL) { if (type == '*' || type == file->name[0]) { ffs_fread(&file->name[1], file->addr, file->size); } file++; } } void config_rf_write(char type) { const T_CONFIG_FILE *file = config_files_common; while (file->name != NULL) { if (type == '*' || type == file->name[0]) { ffs_fwrite(&file->name[1], file->addr, file->size); } file++; } } void config_rf_rw_band(char type, UWORD8 read) { const T_CONFIG_FILE *f1 = config_files_band; UWORD8 i; WORD32 offset; char name[64]; char *p; #if (L1_FF_MULTIBAND == 0) UWORD8 std = l1_config.std.id; #endif #if FFS_WORKAROUND == 1 struct stat_s stat; UWORD16 time; #endif #if (L1_FF_MULTIBAND == 0) for (i=0; i< GSM_BANDS; i++) { if(std_config[std].band[i] !=0 ) { #else for (i = 0; i < RF_NB_SUPPORTED_BANDS; i++) { #endif /*if (L1_FF_MULTIBAND == 0) */ f1 = &config_files_band[0]; while (f1->name != NULL) { offset = (WORD32) f1->addr - (WORD32) &rf_band[0]; //offset in bytes p = ((char *) &rf_band[i]) + offset; if (type == '*' || type == f1->name[0]) { strcpy(name, &f1->name[1]); strcat(name, "."); #if (L1_FF_MULTIBAND == 0) strcat(name, band_config[std_config[std].band[i]].name); #else strcat(name, multiband_rf[i].name); #endif /*if (L1_FF_MULTIBAND == 0)*/ if (read == 1) ffs_fread(name, p, f1->size); else //write == 0 { ffs_fwrite(name, p, f1->size); // wait until ffs write has finished #if FFS_WORKAROUND == 1 stat.inode = 0; time = 0; do { rvf_delay(10); // in milliseconds time += 10; ffs_stat(name, &stat); } while (stat.inode == 0 && time < 500); #endif } } f1++; } } #if (L1_FF_MULTIBAND == 0) } #endif } /*-------------------------------------------------------*/ /* Cust_init_std() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : Init Standard variable configuration */ /*-------------------------------------------------------*/ void Cust_init_std(void) #if (L1_FF_MULTIBAND == 0) { UWORD8 std = l1_config.std.id; UWORD8 band1, band2; T_RF_BAND *pt1, *pt2; band1 = std_config[std].band[0]; band2 = std_config[std].band[1]; //get these from std pt1 = band_config[band1].addr; pt2 = band_config[band2].addr; // copy rf-struct from default flash to ram memcpy(&rf_band[0], pt1, sizeof(T_RF_BAND)); if(std_config[std].band[1] != BAND_NONE ) memcpy(&rf_band[1], pt2, sizeof(T_RF_BAND)); // Read all RF and system configuration from FFS *before* we copy any of // the rf structure variables to other places, like L1. config_ffs_read('*'); l1_config.std.first_radio_freq = std_config[std].first_arfcn; if(band2!=0) l1_config.std.first_radio_freq_band2 = band_config[band1].max_carrier + 1; else l1_config.std.first_radio_freq_band2 = 0; //band1 carrier + 1 else 0 // if band2 is not used it is initialised with zeros l1_config.std.nbmax_carrier = band_config[band1].max_carrier; if(band2!=0) l1_config.std.nbmax_carrier += band_config[band2].max_carrier; l1_config.std.max_txpwr_band1 = band_config[band1].max_txpwr; l1_config.std.max_txpwr_band2 = band_config[band2].max_txpwr; l1_config.std.txpwr_turning_point = std_config[std].txpwr_tp; l1_config.std.cal_freq1_band1 = 0; l1_config.std.cal_freq1_band2 = 0; l1_config.std.g_magic_band1 = rf_band[MULTI_BAND1].rx.rx_cal_params.g_magic; l1_config.std.lna_att_band1 = rf_band[MULTI_BAND1].rx.rx_cal_params.lna_att; l1_config.std.lna_switch_thr_low_band1 = rf_band[MULTI_BAND1].rx.rx_cal_params.lna_switch_thr_low; l1_config.std.lna_switch_thr_high_band1 = rf_band[MULTI_BAND1].rx.rx_cal_params.lna_switch_thr_high; l1_config.std.swap_iq_band1 = rf_band[MULTI_BAND1].swap_iq; l1_config.std.g_magic_band2 = rf_band[MULTI_BAND2].rx.rx_cal_params.g_magic; l1_config.std.lna_att_band2 = rf_band[MULTI_BAND2].rx.rx_cal_params.lna_att; l1_config.std.lna_switch_thr_low_band2 = rf_band[MULTI_BAND2].rx.rx_cal_params.lna_switch_thr_low; l1_config.std.lna_switch_thr_high_band2 = rf_band[MULTI_BAND2].rx.rx_cal_params.lna_switch_thr_high; l1_config.std.swap_iq_band2 = rf_band[MULTI_BAND2].swap_iq; l1_config.std.radio_freq_index_offset = l1_config.std.first_radio_freq-1; // init variable indicating which radio bands are supported by the chosen RF l1_config.std.radio_band_support = rf.radio_band_support; //TBD: DRP Calib: Currently the Calib Data are only used for the routines, TBD add to l1_config. from saved Calibration // on a need basis ? } #else { UWORD8 i; for (i = 0; i < RF_NB_SUPPORTED_BANDS; i++) { switch(multiband_rf[i].gsm_band_identifier) { case RF_GSM900: rf_band[i]=rf_900; break; case RF_GSM850: rf_band[i]=rf_850; break; case RF_DCS1800: rf_band[i]=rf_1800; break; case RF_PCS1900: rf_band[i]=rf_1900; break; default: break; } } config_ffs_read('*'); } #endif // if (L1_FF_MULTIBAND == 0) /*-------------------------------------------------------*/ /* Cust_init_params() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : Init RF dependent paramters (AGC, TX) */ /*-------------------------------------------------------*/ void Cust_init_params(void) { #if (CODE_VERSION==SIMULATION) extern UWORD16 simu_RX_SYNTH_SETUP_TIME; // set in xxx.txt l3 scenario file extern UWORD16 simu_TX_SYNTH_SETUP_TIME; // set in xxx.txt l3 scenario file l1_config.params.rx_synth_setup_time = simu_RX_SYNTH_SETUP_TIME; l1_config.params.tx_synth_setup_time = simu_TX_SYNTH_SETUP_TIME; #else l1_config.params.rx_synth_setup_time = RX_SYNTH_SETUP_TIME; l1_config.params.tx_synth_setup_time = TX_SYNTH_SETUP_TIME; #endif // Convert SYNTH_SETUP_TIME into SPLIT. // We have kept a margin of 20qbit (EPSILON_MEAS) to cover offset change and Scenario closing time + margin. l1_config.params.rx_synth_load_split = 1L + (l1_config.params.rx_synth_setup_time + EPSILON_MEAS) / (BP_DURATION/BP_SPLIT); l1_config.params.tx_synth_load_split = 1L + (l1_config.params.tx_synth_setup_time + EPSILON_MEAS) / (BP_DURATION/BP_SPLIT); l1_config.params.rx_synth_start_time = TPU_CLOCK_RANGE + PROVISION_TIME - l1_config.params.rx_synth_setup_time; l1_config.params.tx_synth_start_time = TPU_CLOCK_RANGE - l1_config.params.tx_synth_setup_time; l1_config.params.rx_change_synchro_time = l1_config.params.rx_synth_start_time - EPSILON_SYNC; l1_config.params.rx_change_offset_time = l1_config.params.rx_synth_start_time - EPSILON_OFFS; l1_config.params.tx_change_offset_time = TIME_OFFSET_TX - TA_MAX - l1_config.params.tx_synth_setup_time - EPSILON_OFFS; // TX duration = ramp up time + burst duration (data + tail bits) l1_config.params.tx_nb_duration = UL_ABB_DELAY + rf.tx.guard_bits*4 + NB_BURST_DURATION_UL; l1_config.params.tx_ra_duration = UL_ABB_DELAY + rf.tx.guard_bits*4 + RA_BURST_DURATION; l1_config.params.tx_nb_load_split = 1L + (l1_config.params.tx_nb_duration - rf.tx.prg_tx - NB_MARGIN) / (BP_DURATION/BP_SPLIT); l1_config.params.tx_ra_load_split = 1L + (l1_config.params.tx_ra_duration - rf.tx.prg_tx - NB_MARGIN) / (BP_DURATION/BP_SPLIT); // time for the end of RX and TX TPU scenarios l1_config.params.rx_tpu_scenario_ending = RX_TPU_SCENARIO_ENDING; l1_config.params.tx_tpu_scenario_ending = TX_TPU_SCENARIO_ENDING; // FB26 anchoring time is computed backward to leave only 6 qbit margin between // FB26 window and next activity (RX time tracking). // This margin is used as follow: // Serving offset restore: 1 qbit (SERV_OFFS_REST_LOAD) // Tpu Sleep: 2 qbit (TPU_SLEEP_LOAD) // --------- // Total: 3 qbit l1_config.params.fb26_anchoring_time = (l1_config.params.rx_synth_start_time - #if (CODE_VERSION == SIMULATION) // simulator: end of scenario not included in window (no serialization) 1 - #else // RF dependent end of RX TPU scenario l1_config.params.rx_tpu_scenario_ending - #endif EPSILON_SYNC - TPU_SLEEP_LOAD - SERV_OFFS_REST_LOAD - FB26_ACQUIS_DURATION - PROVISION_TIME + TPU_CLOCK_RANGE) % TPU_CLOCK_RANGE; l1_config.params.fb26_change_offset_time = l1_config.params.fb26_anchoring_time + PROVISION_TIME - l1_config.params.rx_synth_setup_time - EPSILON_OFFS; l1_config.params.guard_bits = rf.tx.guard_bits; l1_config.params.prg_tx_gsm = rf.tx.prg_tx; l1_config.params.prg_tx_dcs = rf.tx.prg_tx; //delay for dual band not implemented yet 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; l1_config.params.il_min = IL_MIN; l1_config.params.fixed_txpwr = FIXED_TXPWR; l1_config.params.eeprom_afc = rf.afc.eeprom_afc; l1_config.params.setup_afc_and_rf = SETUP_AFC_AND_RF; l1_config.params.rf_wakeup_tpu_scenario_duration = l1_config.params.setup_afc_and_rf + 1; //directly dependent of l1dmacro_RF_wakeup implementation 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 == SIMULATION) #if (VCXO_ALGO == 1) l1_config.params.afc_algo = ALGO_AFC_LQG_PREDICTOR; // VCXO|VCTCXO - Choosing AFC algorithm #endif #else #if (VCXO_ALGO == 1) l1_config.params.afc_dac_center = rf.afc.dac_center; // VCXO - assuming DAC linearity l1_config.params.afc_dac_min = rf.afc.dac_min; // VCXO - assuming DAC linearity l1_config.params.afc_dac_max = rf.afc.dac_max; // VCXO - assuming DAC linearity #if (NEW_SNR_THRESHOLD == 0) l1_config.params.afc_snr_thr = rf.afc.snr_thr; // VCXO - SNR threshold #else l1_config.params.afc_snr_thr = L1_TOA_SNR_THRESHOLD; #endif /* NEW_SNR_THRESHOLD */ l1_config.params.afc_algo = ALGO_AFC_LQG_PREDICTOR; // VCXO|VCTCXO - Choosing AFC algorithm l1_config.params.afc_win_avg_size_M = C_WIN_AVG_SIZE_M; // VCXO - Average psi values with this value l1_config.params.rgap_algo = ALGO_AFC_RXGAP; // VCXO - Choosing Reception Gap algorithm l1_config.params.rgap_bad_snr_count_B = C_RGAP_BAD_SNR_COUNT_B; // VCXO - Prediction SNR count #endif #endif #if DCO_ALGO #if (RF_FAM == 10) // Enable DCO algorithm for direct conversion RFs l1_config.params.dco_enabled = TRUE; #else l1_config.params.dco_enabled = FALSE; #endif #endif #if (ANLG_FAM == 1) l1_config.params.debug1 = C_DEBUG1; // Enable f_tx delay of 400000 cyc DEBUG l1_config.params.afcctladd = abb[ABB_AFCCTLADD]; // Value at reset l1_config.params.vbuctrl = abb[ABB_VBUCTRL]; // Uplink gain amp 0dB, Sidetone gain to mute l1_config.params.vbdctrl = abb[ABB_VBDCTRL]; // Downlink gain amp 0dB, Volume control 0 dB l1_config.params.bbctrl = abb[ABB_BBCTRL]; // value at reset l1_config.params.apcoff = abb[ABB_APCOFF]; // value at reset l1_config.params.bulioff = abb[ABB_BULIOFF]; // value at reset l1_config.params.bulqoff = abb[ABB_BULQOFF]; // value at reset l1_config.params.dai_onoff = abb[ABB_DAI_ON_OFF]; // value at reset l1_config.params.auxdac = abb[ABB_AUXDAC]; // value at reset l1_config.params.vbctrl = abb[ABB_VBCTRL]; // VULSWITCH=0, VDLAUX=1, VDLEAR=1 l1_config.params.apcdel1 = abb[ABB_APCDEL1]; // value at reset #endif #if (ANLG_FAM == 2) l1_config.params.debug1 = C_DEBUG1; // Enable f_tx delay of 400000 cyc DEBUG l1_config.params.afcctladd = abb[ABB_AFCCTLADD]; // Value at reset l1_config.params.vbuctrl = abb[ABB_VBUCTRL]; // Uplink gain amp 0dB, Sidetone gain to mute l1_config.params.vbdctrl = abb[ABB_VBDCTRL]; // Downlink gain amp 0dB, Volume control 0 dB l1_config.params.bbctrl = abb[ABB_BBCTRL]; // value at reset l1_config.params.bulgcal = abb[ABB_BULGCAL]; // value at reset l1_config.params.apcoff = abb[ABB_APCOFF]; // value at reset l1_config.params.bulioff = abb[ABB_BULIOFF]; // value at reset l1_config.params.bulqoff = abb[ABB_BULQOFF]; // value at reset l1_config.params.dai_onoff = abb[ABB_DAI_ON_OFF]; // value at reset l1_config.params.auxdac = abb[ABB_AUXDAC]; // value at reset l1_config.params.vbctrl1 = abb[ABB_VBCTRL1]; // VULSWITCH=0, VDLAUX=1, VDLEAR=1 l1_config.params.vbctrl2 = abb[ABB_VBCTRL2]; // MICBIASEL=0, VDLHSO=0, MICAUX=0 l1_config.params.apcdel1 = abb[ABB_APCDEL1]; // value at reset l1_config.params.apcdel2 = abb[ABB_APCDEL2]; // value at reset #endif #if (ANLG_FAM == 3) l1_config.params.debug1 = C_DEBUG1; // Enable f_tx delay of 400000 cyc DEBUG l1_config.params.afcctladd = abb[ABB_AFCCTLADD]; // Value at reset l1_config.params.vbuctrl = abb[ABB_VBUCTRL]; // Uplink gain amp 0dB, Sidetone gain to mute l1_config.params.vbdctrl = abb[ABB_VBDCTRL]; // Downlink gain amp 0dB, Volume control 0 dB l1_config.params.bbctrl = abb[ABB_BBCTRL]; // value at reset l1_config.params.bulgcal = abb[ABB_BULGCAL]; // value at reset l1_config.params.apcoff = abb[ABB_APCOFF]; // X2 Slope 128 and APCSWP disabled l1_config.params.bulioff = abb[ABB_BULIOFF]; // value at reset l1_config.params.bulqoff = abb[ABB_BULQOFF]; // value at reset l1_config.params.dai_onoff = abb[ABB_DAI_ON_OFF]; // value at reset l1_config.params.auxdac = abb[ABB_AUXDAC]; // value at reset l1_config.params.vbctrl1 = abb[ABB_VBCTRL1]; // VULSWITCH=0 l1_config.params.vbctrl2 = abb[ABB_VBCTRL2]; // MICBIASEL=0, VDLHSO=0, MICAUX=0 l1_config.params.apcdel1 = abb[ABB_APCDEL1]; // value at reset l1_config.params.apcdel2 = abb[ABB_APCDEL2]; // value at reset l1_config.params.vbpop = abb[ABB_VBPOP]; // HSOAUTO enabled l1_config.params.vau_delay_init = abb[ABB_VAUDINITD]; // 2 TDMA Frames between VDL "ON" and VDLHSO "ON" l1_config.params.vaud_cfg = abb[ABB_VAUDCTRL]; // value at reset l1_config.params.vauo_onoff = abb[ABB_VAUOCTRL]; // speech on AUX and EAR l1_config.params.vaus_vol = abb[ABB_VAUSCTRL]; // value at reset l1_config.params.vaud_pll = abb[ABB_VAUDPLL]; // value at reset #endif #if (RF_FAM == 61) l1_config.params.apcctrl2 = drp_wrapper[DRP_WRAPPER_APCCTRL2]; l1_config.params.apcdel1 = drp_wrapper[DRP_WRAPPER_APCDEL1]; l1_config.params.apcdel2 = drp_wrapper[DRP_WRAPPER_APCDEL2]; #endif #if (ANLG_FAM == 11) l1_config.params.vulgain = abb[ABB_VULGAIN]; l1_config.params.vdlgain = abb[ABB_VDLGAIN]; l1_config.params.sidetone = abb[ABB_SIDETONE]; l1_config.params.ctrl1 = abb[ABB_CTRL1]; l1_config.params.ctrl2 = abb[ABB_CTRL2]; l1_config.params.ctrl3 = abb[ABB_CTRL3]; l1_config.params.ctrl4 = abb[ABB_CTRL4]; l1_config.params.ctrl5 = abb[ABB_CTRL5]; l1_config.params.ctrl6 = abb[ABB_CTRL6]; l1_config.params.popauto = abb[ABB_POPAUTO]; l1_config.params.outen1 = abb[ABB_OUTEN1]; l1_config.params.outen2 = abb[ABB_OUTEN2]; l1_config.params.outen3 = abb[ABB_OUTEN3]; l1_config.params.aulga = abb[ABB_AULGA]; l1_config.params.aurga = abb[ABB_AURGA]; #endif } /************************************/ /* Automatic Gain Control */ /************************************/ /*-------------------------------------------------------*/ /* Cust_get_agc_from_IL() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : returns agc value */ /*-------------------------------------------------------*/ WORD8 Cust_get_agc_from_IL(UWORD16 radio_freq, UWORD16 agc_index, UWORD8 table_id,UWORD8 lna_off_val) { UWORD16 agc_index_temp; // radio_freq currently not used // this parameter is passed in order to allow band dependent tables for specific RFs // (e.g. dual band RF with separate AGC H/W blocks for GSM and DCS) agc_index_temp = (agc_index<<1) + (lna_off_val * l1ctl_get_lna_att(radio_freq)); agc_index= agc_index_temp>>1; if (agc_index > 120) agc_index = 120; // Clip agc_index switch (table_id) { case MAX_ID: return(rf.rx.agc.il2agc_max[agc_index]); case AV_ID: return(rf.rx.agc.il2agc_av[agc_index]); case PWR_ID: return(rf.rx.agc.il2agc_pwr[agc_index]); } return (0);//omaps00090550 } /*-------------------------------------------------------*/ /* Cust_get_agc_band */ /*-------------------------------------------------------*/ /* Parameters : radio_freq */ /* Return : band number */ /* Functionality : Computes the band for RF calibration */ /*-------------------------------------------------------*/ /*---------------------------------------------*/ UWORD8 band_number; #if (CODE_VERSION == SIMULATION) UWORD16 Cust_get_agc_band(UWORD16 arfcn, UWORD8 gsm_band) #else UWORD16 inline Cust_get_agc_band(UWORD16 arfcn, UWORD8 gsm_band) #endif { // WORD32 i =0 ; //omaps00090550 for (band_number=0;band_number<RF_RX_CAL_CHAN_SIZE;band_number++) { if (arfcn <= rf_band[gsm_band].rx.agc_bands[band_number].upper_bound) return(band_number); } // Should never happen! return(0); } #if (L1_FF_MULTIBAND == 0) /*-------------------------------------------------------*/ /* Cust_is_band_high */ /*-------------------------------------------------------*/ /* Parameters : arfcn */ /* Return : 0 if low band */ /* 1 if high band */ /* Functionality : Generic function which return 1 if */ /* arfcn is in the high band */ /*-------------------------------------------------------*/ UWORD8 Cust_is_band_high(UWORD16 radio_freq) { UWORD16 max_carrier; UWORD8 std = l1_config.std.id; max_carrier = band_config[std_config[std].band[0]].max_carrier; return(((radio_freq >= l1_config.std.first_radio_freq) && (radio_freq < (l1_config.std.first_radio_freq + max_carrier))) ? MULTI_BAND1 : MULTI_BAND2); } #endif /*-------------------------------------------------------*/ /* l1ctl_encode_delta2() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ WORD8 l1ctl_encode_delta2(UWORD16 radio_freq) { WORD8 delta2_freq; UWORD16 i; UWORD16 arfcn; #if (L1_FF_MULTIBAND == 0) UWORD8 band; band = Cust_is_band_high(radio_freq); arfcn = Convert_l1_radio_freq(radio_freq); #else WORD8 band; // Corrected for input being rf_freq and not l1_freq arfcn = rf_convert_l1freq_to_arfcn_rfband(rf_convert_rffreq_to_l1freq(radio_freq), &band); #endif i = Cust_get_agc_band(arfcn,band); // delta2_freq = rf_band[band].rx.agc_bands[i].agc_calib; //temperature compensation for (i=0;i<RF_RX_CAL_TEMP_SIZE;i++) { if ((WORD16)adc.converted[ADC_RFTEMP] <= rf_band[band].rx.temp[i].temperature) { delta2_freq += rf_band[band].rx.temp[i].agc_calib; break; } } return(delta2_freq); } #if (L1_FF_MULTIBAND == 0) #else /*-------------------------------------------------------*/ /* l1ctl_get_g_magic() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ UWORD16 l1ctl_get_g_magic(UWORD16 radio_freq) { // Corrected for input being rf_freq and not l1_freq return (rf_band[rf_subband2band[rf_convert_rffreq_to_l1subband(radio_freq)]].rx.rx_cal_params.g_magic); } /*-------------------------------------------------------*/ /* l1ctl_get_lna_att() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ UWORD16 l1ctl_get_lna_att(UWORD16 radio_freq) { // The function is provided with rf_freq as input so // convert rf_freq to l1_subband then convert l1_subband to rf_band and index into rf_band return( rf_band[rf_subband2band[rf_convert_rffreq_to_l1subband(radio_freq)]].rx.rx_cal_params.lna_att); // return (rf_band[rf_convert_l1freq_to_rf_band_idx(radio_freq)].rx.rx_cal_params.lna_att); } /*-------------------------------------------------------*/ /* l1ctl_encode_delta1() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ WORD8 l1ctl_encode_delta1(UWORD16 radio_freq) { return 0; } /*-------------------------------------------------------*/ /* l1ctl_encode_lna() */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ void l1ctl_encode_lna( UWORD8 input_level, UWORD8 *lna_state, UWORD16 radio_freq) { /*** LNA Hysteresis is implemented as following : | On|---<>----+-------+ | | | LNA | | | | ^ v | | | | | | Off| +-------+----<>----- +-------------------------------- 50 40 30 20 input_level /-dBm THR_HIGH THR_LOW ***/ WORD8 band; // Corrected for input to be rf_freq and not l1_freq band = rf_subband2band[rf_convert_rffreq_to_l1subband(radio_freq)]; if ( input_level > rf_band[band].rx.rx_cal_params.lna_switch_thr_high) // < -44dBm ? { *lna_state = LNA_ON; // lna_off = FALSE } else if ( input_level < rf_band[band].rx.rx_cal_params.lna_switch_thr_low) // > -40dBm ? { *lna_state = LNA_OFF; // lna off = TRUE } } UWORD8 l1ctl_get_iqswap(UWORD16 rf_freq) { return(rf_band[rf_subband2band[rf_convert_rffreq_to_l1subband(rf_freq)]].swap_iq); } #endif //if L1_FF_MULTIBAND == 0) /************************************/ /* TX Management */ /************************************/ /*-------------------------------------------------------*/ /* Cust_get_ramp_tab */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : Notes: Cal+ APCRAM : Dwn(15:11)Up(10:6)Forced(0) Locosto: APCRAM: Dwn(15:8)Up(7:0) */ /*-------------------------------------------------------*/ void Cust_get_ramp_tab(API *a_ramp, UWORD8 txpwr_ramp_up, UWORD8 txpwr_ramp_down, UWORD16 radio_freq) { UWORD16 index_up, index_down,j, arfcn; #if (L1_FF_MULTIBAND == 0) UWORD8 band; band = Cust_is_band_high(radio_freq); arfcn = Convert_l1_radio_freq(radio_freq); #else WORD8 band; // Corrected for input being rf_freq and not l1_freq arfcn = rf_convert_l1freq_to_arfcn_rfband(rf_convert_rffreq_to_l1freq(radio_freq), &band); #endif //if( L1_FF_MULTIBAND == 0) index_up = rf_band[band].tx.levels[txpwr_ramp_up].ramp_index; index_down = rf_band[band].tx.levels[txpwr_ramp_down].ramp_index; #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3)) for (j=0; j<16; j++) { a_ramp[j]=((rf_band[band].tx.ramp_tables[index_down].ramp_down[j])<<11) | ((rf_band[band].tx.ramp_tables[index_up].ramp_up[j]) << 6) | 0x14; } #endif #if (RF_FAM == 61) // 20 Coeff each 8 (RampDown) + 8 (RampUp) for (j=0; j<20; j++) { a_ramp[j]=( (255 - (rf_band[band].tx.ramp_tables[index_down].ramp_down[j]) ) <<8) | ((rf_band[band].tx.ramp_tables[index_up].ramp_up[j])) ; } #endif } /*-------------------------------------------------------*/ /* get_pwr_data */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : */ /*-------------------------------------------------------*/ #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61)) UWORD16 Cust_get_pwr_data(UWORD8 txpwr, UWORD16 radio_freq #if (REL99 && FF_PRF) , UWORD8 number_uplink_timeslot #endif ) { UWORD16 i,j; UWORD16 arfcn; T_TX_LEVEL *a_tx_levels; #if (APC_VBAT_COMP == 1) static UWORD16 apc_max_value = APC_MAX_VALUE; #endif #if(ORDER2_TX_TEMP_CAL==1) WORD16 pwr_data; #else UWORD16 pwr_data; #endif #if (L1_FF_MULTIBAND == 0) UWORD8 band; band = Cust_is_band_high(radio_freq); arfcn = Convert_l1_radio_freq(radio_freq); #else WORD8 band; // Corrected for input being rf_freq and not l1_freq arfcn = rf_convert_l1freq_to_arfcn_rfband(rf_convert_rffreq_to_l1freq(radio_freq), &band); #endif //if( L1_FF_MULTIBAND == 0) // band = Cust_is_band_high(radio_freq); // arfcn = Convert_l1_radio_freq(radio_freq); a_tx_levels = &(rf_band[band].tx.levels[txpwr]); // get pointer to rf tx structure #if REL99 #if FF_PRF // uplink power reduction feature which decrease power level in case of uplink multislot a_tx_levels = Cust_get_uplink_apc_power_reduction(band, number_uplink_timeslot, a_tx_levels); #endif #endif // get uncalibrated apc pwr_data = a_tx_levels->apc; i = a_tx_levels->chan_cal_index; // get index for channel compensation j=0; while (arfcn > rf_band[band].tx.chan_cal_table[i][j].arfcn_limit) j++; // channel calibrate apc pwr_data = ((UWORD32) (pwr_data * rf_band[band].tx.chan_cal_table[i][j].chan_cal))/128; // temperature compensate apc { T_TX_TEMP_CAL *pt; pt = rf_band[band].tx.temp; while (((WORD16)adc.converted[ADC_RFTEMP] > pt->temperature) && ((pt-rf_band[band].tx.temp) < (RF_TX_CAL_TEMP_SIZE-1))) pt++; #if(ORDER2_TX_TEMP_CAL==1) pwr_data += (txpwr*(pt->a*txpwr + pt->b) + pt->c) / 64; //delta apc = ax^2+bx+c if(pwr_data < 0) pwr_data = 0; #else pwr_data += pt->apc_calib; #endif } // Vbat compensate apc #if (APC_VBAT_COMP == 1) if (adc.converted[ADC_VBAT] < VBAT_LOW_THRESHOLD) apc_max_value = APC_MAX_VALUE_LOW_BAT; else if (adc.converted[ADC_VBAT] > VBAT_HIGH_THRESHOLD) apc_max_value = APC_MAX_VALUE; // else do nothing as Vbat is staying between VBAT_LOW_THRESHOLD and // VBAT_HIGH_THRESHOLD -> max APC value is still the same than previous one if (pwr_data > apc_max_value) pwr_data = apc_max_value; #endif // APC_VBAT_COMP == 1 return(pwr_data); } #endif #if(REL99 && FF_PRF) /*-------------------------------------------------------*/ /* Cust_get_uplink_apc_power_reduction */ /*-------------------------------------------------------*/ /* Parameters : */ /* - frenquency band */ /* - modulation type */ /* - number of uplink timeslot */ /* - pointer to radio power control structure */ /* Return : */ /* - pointer to radio power control structure */ /* */ /* Functionality : This function returns a pointer to */ /* the radio power control structure after power */ /* reduction processing. */ /* Depending of the number of uplink timeslot, the */ /* analogue power control (apc) value can be reduced */ /* in order to limit effect of terminal heat */ /* dissipation due to power amplifier. */ /*-------------------------------------------------------*/ T_TX_LEVEL *Cust_get_uplink_apc_power_reduction(UWORD8 band, UWORD8 number_uplink_timeslot, T_TX_LEVEL *p_tx_level) { T_TX_LEVEL *p_power_reduction_tx_level; #if TESTMODE if ((l1_config.TestMode == TRUE) && (l1_config.tmode.tx_params.power_reduction_enable == FALSE)) return p_tx_level ; // return without any power reduction #endif if ((number_uplink_timeslot >= 1) && (number_uplink_timeslot <= MAX_UPLINK_TIME_SLOT)) { number_uplink_timeslot--; // index start from 0 } else { return p_tx_level; // abnormal case we do not apply any power reduction } p_power_reduction_tx_level = &(rf_band[band].tx.levels_power_reduction[number_uplink_timeslot]); // We select the lowest power level in order to apply power reduction #if (CODE_VERSION != SIMULATION) if (p_tx_level->apc > p_power_reduction_tx_level->apc) // higher apc value means higher transmit power #else if (p_tx_level->apc < p_power_reduction_tx_level->apc) // ! for simulation rf apc tables are inverted so comparaison is the reverse #endif return p_power_reduction_tx_level; else return p_tx_level; } #endif /*-------------------------------------------------------*/ /* Cust_Init_Layer1 */ /*-------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : Load and boot the DSP */ /* Initialize shared memory and L1 data structures */ /*-------------------------------------------------------*/ void Cust_Init_Layer1(void) { T_MMI_L1_CONFIG cfg; // Get the current band configuration from the flash #if (OP_WCP==1) && (OP_L1_STANDALONE!=1) extern unsigned char ffs_GetBand(); cfg.std = ffs_GetBand(); #else // NO OP_WCP // cfg.std = std; cfg.std = STD; #endif // OP_WCP cfg.tx_pwr_code = 1; // sleep management configuration #if(L1_POWER_MGT == 0) cfg.pwr_mngt = 0; cfg.pwr_mngt_mode_authorized = NO_SLEEP; //Sleep mode cfg.pwr_mngt_clocks = 0x5ff; // list of clocks cut in Big Sleep #endif #if(L1_POWER_MGT == 1) cfg.pwr_mngt = 1; cfg.pwr_mngt_mode_authorized = ALL_SLEEP; //Sleep mode cfg.pwr_mngt_clocks = 0x5ff; // list of clocks cut in Big Sleep #endif #if (CODE_VERSION != SIMULATION) cfg.dwnld = DWNLD; //external define from makefile #endif l1_initialize(&cfg); //add below line for CSR 174476 trace_info.current_config->l1_dyn_trace = 0; //disable L1 trace after L1 init get_cal_from_nvmem((UWORD8 *)&rf, sizeof(rf), RF_ID); get_cal_from_nvmem((UWORD8 *)&adc_cal, sizeof(adc_cal), ADC_ID); } /*****************************************************************************************/ /*************************** TESTMODE functions **********************************/ /*****************************************************************************************/ /*------------------------------------------------------*/ /* madc_hex_2_physical */ /*------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : Function to convert MAD hexadecimal */ /* values into physical values */ /*------------------------------------------------------*/ void madc_hex_2_physical (UWORD16 *adc_hex, T_ADC *adc_phy) { WORD16 i; UWORD16 y; WORD16 Smin = 0, Smax = TEMP_TABLE_SIZE-1; WORD16 index = (TEMP_TABLE_SIZE-1)/2; /* y is the adc code after compensation of ADC slope error introduced by VREF error */ //store raw ADC values memcpy(&adc.raw[0], adc_hex, sizeof(adc.raw)); // Convert Vbat [mV] : direct equation with slope and offset compensation for (i = ADC_VBAT; i<ADC_RFTEMP; i++) adc.converted[i] = (((UWORD32)(adc_cal.a[i] * adc.raw[i])) >>10) + adc_cal.b[i]; /*Convert RF Temperature [Celsius]: binsearch into a table*/ y = ((UWORD32)(adc_cal.a[ADC_RFTEMP] * adc.raw[ADC_RFTEMP]))>>8; /* rf.tempcal is the calibration of VREF*/ while((Smax-Smin) > 1 ) { if(y < temperature[index].adc) Smax=index; else Smin=index; index = (Smax+Smin)/2; } adc.converted[ADC_RFTEMP] = temperature[index].temp; for (i = ADC_RFTEMP+1; i<ADC_INDEX_END; i++) adc.converted[i] = (((UWORD32)(adc_cal.a[i] * adc.raw[i])) >>10) + adc_cal.b[i]; //store converted ADC values memcpy(adc_phy, &adc.converted[0], sizeof(adc.raw)); } /*------------------------------------------------------*/ /* get_cal_from_nvmem */ /*------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : Copy calibrated parameter to */ /* calibration structure in RAM */ /*------------------------------------------------------*/ void get_cal_from_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id) { } /*------------------------------------------------------*/ /* save_cal_from_nvmem */ /*------------------------------------------------------*/ /* Parameters : */ /* Return : */ /* Functionality : Copy calibrated structure from RAM */ /* into NV memory */ /*------------------------------------------------------*/ UWORD8 save_cal_in_nvmem (UWORD8 *ptr, UWORD16 len, UWORD8 id) { return (0); } #if (TRACE_TYPE == 4) /*------------------------------------------------------*/ /* l1_cst_l1_parameters */ /*------------------------------------------------------*/ /* Parameters : s: pointer on configuration string */ /* Return : nothing: global var are set */ /* Functionality : Set global L1 vars for dynamic trace */ /* and configuration */ /* */ /* This function is called when a CST message is sent */ /* from the Condat Panel. */ /*------------------------------------------------------*/ void l1_cst_l1_parameters(char *s) { /* a sample command string can be: L1_PARAMS=<1,2,3,4,5> or L1_PARAMS=<1,23,3E32,4,5> with n parameters (here: 5 params); n>=1 parameters are decoded as hexadecimal unsigned integers (UWORD16) */ UWORD8 uNParams = 0; /* Number of parameters */ UWORD32 aParam[10]; /* Parameters array */ UWORD8 uIndex = 0; /* *** retrieve all parameters *** */ while (s[uIndex] != '<') uIndex++; uIndex++; aParam[0] = 0; /* uIndex points on 1st parameter */ while (s[uIndex] != '>') { if (s[uIndex] == ',') { uNParams++; aParam[uNParams] = 0; } else { /* uIndex points on a parameter char */ UWORD8 uChar = s[uIndex]; aParam[uNParams] = aParam[uNParams] << 4; /* shift 4 bits left */ if ((uChar>='0') && (uChar<='9')) aParam[uNParams] += (uChar - '0'); /* retrieve value */ else if ((uChar>='A') && (uChar<='F')) aParam[uNParams] += (10 + uChar - 'A'); /* retrieve value */ else if ((uChar>='a') && (uChar<='f')) aParam[uNParams] += (10 + uChar - 'a'); /* retrieve value */ } uIndex++; /* go to next char */ } /* increment number of params */ uNParams++; /* *** handle parameters *** */ /* 1st param: command type 2nd param: argument for command type */ switch (aParam[0]) { case 0: /* Trace setting */ /* The 2nd parameter contains the trace bitmap*/ if (uNParams >=2) trace_info.current_config->l1_dyn_trace = aParam[1]; else trace_info.current_config->l1_dyn_trace = 0; /* error case: disable all trace */ Trace_dyn_trace_change(); break; default: /* ignore it */ break; } // switch } #endif #if ((CHIPSET == 2) || (CHIPSET == 3) || (CHIPSET == 4) || \ (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || \ (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || \ (CHIPSET == 11) || (CHIPSET == 12)) /*-------------------------------------------------------*/ /* power_down_config() : temporary implementation !!! */ /*-------------------------------------------------------*/ /* Parameters : sleep_mode (NO, SMALL, BIG, DEEP or ALL) */ /* clocks to be cut in BIG sleep */ /* Return : */ /* Functionality : set the l1s variables */ /* l1s.pw_mgr.mode_authorized and l1s.pw_mgr.clocks */ /* according to the desired mode. */ /*-------------------------------------------------------*/ void power_down_config(UWORD8 sleep_mode, UWORD16 clocks) { #if (OP_L1_STANDALONE == 1) if(sleep_mode != NO_SLEEP) #endif { l1_config.pwr_mngt = PWR_MNGT; l1s.pw_mgr.mode_authorized = sleep_mode; l1s.pw_mgr.clocks = clocks; } #if (OP_L1_STANDALONE == 0) l1s.pw_mgr.enough_gaug = FALSE; #endif } #endif //added for L1 standalone DRP calibration- this will overwrite the previous data #if (OP_L1_STANDALONE == 1) #pragma DATA_SECTION(drp_l1_standalone_calib_data, ".drp_l1_standalone_calib_data"); T_DRP_SW_DATA drp_l1_standalone_calib_data; #pragma DATA_SECTION(valid_dro_standalone_calib_data_flag , ".valid_dro_standalone_calib_data_flag"); UWORD32 valid_dro_standalone_calib_data_flag; //const T_DRP_SW_DATA drp_sw_data_init = { (UINT16) sizeof(T_DRP_CALIB), } -this needs to be filled by CCS //added for L1 standalone DRP calibration- ends #endif // for DRP Calibration /*-------------------------------------------------------*/ /* Cust_init_params_drp() */ /*-------------------------------------------------------*/ /* Parameters : none */ /* Return : none */ /* Functionality : Intialization of DRP calibration. */ /*-------------------------------------------------------*/ #if (L1_DRP == 1) void Cust_init_params_drp(void) { #if (DRP_FW_EXT==1) l1s.boot_result=drp_sw_data_calib_upload_from_ffs(&drp_sw_data_calib); drp_copy_sw_data_to_drpsrm(&drp_sw_data_calib); #else // DRP_FW_EXT==0 volatile UINT16 indx, strsize; volatile UINT8 *ptrsrc, *ptrdst; #if (OP_L1_STANDALONE == 0) if(drp_sw_data_calib.length != drp_sw_data_init.length) { #endif // For the 1st time FFS might have garbage, if so use the above as check to ensure //and copy from the .drp_sw_data_init structure. // Copy drp_sw_data_init into drp_sw_data_calib strsize = sizeof(T_DRP_SW_DATA); ptrsrc = (UINT8 *)(&drp_sw_data_init); ptrdst = (UINT8 *)(&drp_sw_data_calib); for(indx=0;indx < strsize;indx++) *ptrdst++ = *ptrsrc++; #if (OP_L1_STANDALONE == 0) } #endif drp_copy_sw_data_to_drpsrm(&drp_sw_data_calib); //added for L1 standalone DRP calibration- this will overwrite the previous data #if (OP_L1_STANDALONE == 1) if(valid_dro_standalone_calib_data_flag == 0xDEADBEAF ) //indicates down the data via CCS drp_copy_sw_data_to_drpsrm(&drp_l1_standalone_calib_data); #endif //added for L1 standalone DRP calibration- ends #endif // DRP_FW_EXT } #endif #if (DRP_FW_EXT==1) void l1_get_boot_result_and_version(T_L1_BOOT_VERSION_CODE * p_version) { if(! p_version) { return; } p_version->dsp_code_version = l1s_dsp_com.dsp_ndb_ptr->d_version_number1; p_version->dsp_patch_version = l1s_dsp_com.dsp_ndb_ptr->d_version_number2; p_version->mcu_tcs_program_release = PROGRAM_RELEASE_VERSION; p_version->mcu_tcs_internal = INTERNAL_VERSION; p_version->mcu_tcs_official = OFFICIAL_VERSION; p_version->drp_maj_ver = drp_ref_sw_ver; p_version->drp_min_ver = drp_ref_sw_tag; p_version->boot_result = l1s.boot_result; } #endif /* DRP_FW_EXT */