FreeCalypso > hg > fc-magnetite
diff src/cs/layer1/cfile/l1_drive.c @ 69:50a15a54801e
src/cs/layer1: import from tcs211-l1-reconst project
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 01 Oct 2016 23:45:38 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/layer1/cfile/l1_drive.c Sat Oct 01 23:45:38 2016 +0000 @@ -0,0 +1,2125 @@ +/************* Revision Controle System Header ************* + * GSM Layer 1 software + * L1_DRIVE.C + * + * Filename l1_drive.c + * Copyright 2003 (C) Texas Instruments + * + ************* Revision Controle System Header *************/ + +#define L1_DRIVE_C + +#include "l1_confg.h" + +#if (RF_FAM == 61) +#include "apc.h" +#endif + +#define W_A_DSP_PR20037 1 /* FreeCalypso */ + +#if ((L1M_WAIT_DSP_RESTART_AFTER_VOCODER_ENABLE ==1)&&(W_A_DSP_PR20037 == 1)) + #include "nucleus.h" +#endif +#include "l1_macro.h" +#if (CODE_VERSION == SIMULATION) + #include <string.h> + #include "l1_types.h" + #include "sys_types.h" + #include "l1_const.h" + #include "l1_time.h" + #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 +//ADDED FOR AAC + #if (L1_AAC == 1) + #include "l1aac_defty.h" + #endif + #include "l1_defty.h" + #include "l1_varex.h" + #include "cust_os.h" + #include "l1_msgty.h" + #if TESTMODE + #include "l1tm_varex.h" + #endif + #if L2_L3_SIMUL + #include "hw_debug.h" + #endif + + #if L1_GPRS + #include "l1p_cons.h" + #include "l1p_msgt.h" + #include "l1p_deft.h" + #include "l1p_vare.h" + #include "l1p_sign.h" + #endif + + #include <stdio.h> + #include "sim_cfg.h" + #include "sim_cons.h" + #include "sim_def.h" + #include "sim_var.h" + + #include "l1_ctl.h" + +#else + + #include <string.h> + #include "l1_types.h" + #include "sys_types.h" + #include "l1_const.h" + #include "l1_time.h" + #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 +//ADDED FOR AAC + #if (L1_AAC == 1) + #include "l1aac_defty.h" + #endif + #include "l1_defty.h" + #include "l1_varex.h" + #include "cust_os.h" + #include "l1_msgty.h" + #if TESTMODE + #include "l1tm_varex.h" + #endif + #if L2_L3_SIMUL + #include "hw_debug.h" + #endif + #include "tpudrv.h" + + #if L1_GPRS + #include "l1p_cons.h" + #include "l1p_msgt.h" + #include "l1p_deft.h" + #include "l1p_vare.h" + #include "l1p_sign.h" + #endif + + #include "l1_ctl.h" + +#endif + +#if (RF_FAM == 61) + #include "tpudrv61.h" +#endif + + + +/* + * Prototypes of external functions used in this file. + * + * FreeCalypso change: removed all those prototypes which appear + * in tpudrv.h, and kept only the additional ones. + */ + +#if ((REL99 == 1) && (FF_BHO == 1)) +#if (L1_MADC_ON == 1) + void l1dmacro_rx_fbsb (SYS_UWORD16 radio_freq,UWORD8 adc_active); +#else + void l1dmacro_rx_fbsb (SYS_UWORD16 radio_freq); +#endif +#endif//#if ((REL99 == 1) && (FF_BHO == 1)) + +void Cust_get_ramp_tab(API *a_ramp, UWORD8 txpwr_ramp_up, UWORD8 txpwr_ramp_down, UWORD16 radio_freq); +#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 + ); +#endif + +#if L1_GPRS + void l1ps_reset_db_mcu_to_dsp(T_DB_MCU_TO_DSP_GPRS *page_ptr); +#endif + +/*-------------------------------------------------------*/ +/* l1ddsp_load_info() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_load_info(UWORD32 task, API *info_ptr, UWORD8 *data) +{ + if(task == RACH_DSP_TASK) + // RACH info. format is only 2 words... + { + info_ptr[0] = ((API)(data[0])) | ((API)(data[1])<<8); + } + else + // Fill mcu-dsp comm. buffer. + { + UWORD8 i,j; + + // Fill data block Header... + info_ptr[0] = (1 << B_BLUD); // 1st word: Set B_BLU bit. + info_ptr[1] = 0; // 2nd word: cleared. + info_ptr[2] = 0; // 3rd word: cleared. + + if((info_ptr == l1s_dsp_com.dsp_ndb_ptr->a_du_0) || + (info_ptr == l1s_dsp_com.dsp_ndb_ptr->a_du_1)) + // DATA traffic buffers: size of buffer is 260 bit -> 17 words but DATA traffic uses + // only a max of 240 bit (30 bytes) -> 15 words. + { + for (i=0, j=(3+0); j<(3+15); j++) + { + info_ptr[j] = ((API)(data[i])) | ((API)(data[i+1]) << 8); + i += 2; + } + #if (TRACE_TYPE==3) + if (l1_stats.type == PLAY_UL) + { + for (i=0, j=(3+0); j<(3+17); j++) + { + info_ptr[j] = ((API)(data[i])) | + ((API)(data[i]) << 8); + i ++; + } + } + #endif + } + else + // Data block for control purpose is 184 bit length: 23 bytes: 12 words (16 bit/word). + { + // Copy first 22 bytes in the first 11 words after header. + for (i=0, j=(3+0); j<(3+11); j++) + { + info_ptr[j] = ((API)(data[i])) | ((API)(data[i+1]) << 8); + i += 2; + } + + // Copy last UWORD8 (23rd) in the 12th word after header. + info_ptr[14] = data[22]; + } + } +} + +/*-------------------------------------------------------*/ +/* l1ddsp_load_monit_task() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_load_monit_task(API monit_task, API fb_mode) +{ + l1s_dsp_com.dsp_db_w_ptr->d_task_md = monit_task; // Write number of measurements + + if(l1a_l1s_com.mode == CS_MODE) + l1s_dsp_com.dsp_ndb_ptr->d_fb_mode = fb_mode; // Write FB detection algo. mode. + else + l1s_dsp_com.dsp_ndb_ptr->d_fb_mode = 1; +} + + +/* --------------------------------------------------- */ + +/* Locosto Changes....*/ + +// Parameters: UWORD16 afcval +// Return :Void +//Functionality: TPU to accept the afcvalue from the MCU and copy it +//to the mem_xtal before triggering of AFC Script in DRP + +#if(RF_FAM == 61) +void l1dtpu_load_afc(UWORD16 afc) +{ + l1dmacro_afc(afc, 0); +} + +/* --------------------------------------------------- */ + +/* Locosto Changes....*/ + +/* Parameters: API dco_algo_ctl_sb */ +/* Functionality: Loads the API d_dco_ctl_algo_sb in the API + This should be called after updating the value in the API via cust_Get_dco_algo_ctl(...) */ + +/* --------------------------------------------------- */ + +void l1ddsp_load_dco_ctl_algo_sb (UWORD16 dco_ctl_algo) +{ +#if (DSP == 38) || (DSP == 39) + l1s_dsp_com.dsp_db_common_w_ptr->d_dco_algo_ctrl_sb = (API) dco_ctl_algo; +#endif +} + +/* --------------------------------------------------- */ + +/* Locosto Changes....*/ + +/* Parameters: API dco_algo_ctl_nb */ +/* Functionality: Loads the API d_dco_ctl_algo_nb in the API + This should be called after updating the value in the API via cust_Get_dco_algo_ctl(...) */ + +/* --------------------------------------------------- */ + +void l1ddsp_load_dco_ctl_algo_nb (UWORD16 dco_ctl_algo) +{ +#if (DSP == 38) || (DSP == 39) + l1s_dsp_com.dsp_db_common_w_ptr->d_dco_algo_ctrl_nb = (API) dco_ctl_algo; +#endif + +} +/* --------------------------------------------------- */ + +/* Locosto Changes....*/ + +/* Parameters: API dco_algo_ctl_pw */ +/* Functionality: Loads the API d_dco_ctl_algo_pw in the API + This should be called after updating the value in the API via cust_Get_dco_algo_ctl(...) */ + +/* --------------------------------------------------- */ + +void l1ddsp_load_dco_ctl_algo_pw (UWORD16 dco_ctl_algo) +{ +#if (DSP == 38) || (DSP == 39) + l1s_dsp_com.dsp_db_common_w_ptr->d_dco_algo_ctrl_pw = (API) dco_ctl_algo; +#endif +} + +#endif + +/*-------------------------------------------------------*/ +/* l1ddsp_load_afc() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_load_afc(API afc) +{ +#if (L1_EOTD==1) + // NEW !!! For EOTD measurements in IDLE mode only, cut AFC updates.... + #if (L1_GPRS) + if ( (l1a_l1s_com.nsync.eotd_meas_session == FALSE) || + (l1a_l1s_com.mode == DEDIC_MODE)|| + (l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED)) + #else + if ( (l1a_l1s_com.nsync.eotd_meas_session == FALSE) || + (l1a_l1s_com.mode == DEDIC_MODE)) + #endif + + { +#endif + //######################## For DSP Rom ################################# + l1s_dsp_com.dsp_db_w_ptr->d_afc = afc; // Write new afc command. + #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61)) + // NOTE: In Locosto AFC loading is w.r.t DRP not in ABB + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_abb |= (1 << B_AFC); // Validate new afc value. + #endif + #if (L1_EOTD==1) + } +#endif + +} + +/*-------------------------------------------------------*/ +/* l1ddsp_load_txpwr() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*Notes: + +While Programming APC Ramp always Program the APCDEL also +Cal+: +APCDEL1: LSB Dwn(9:5):Up(4:0) +APCDEL2: MSB Dwn(9:5):Up(4:0) + +Locosto: +APCDEL1: LSB Dwn(9:5):Up(4:0) +APCDEL2: MSB Dwn(9:5):Up(4:0) +----- +Cal+ +APCRAM : Dwn(51:11)Up(10:6)Forced(0) +Locosto: +APCRAM: Dwn(9:5)Up(4:0) + +For AFC, APCDEL1, APCDEL2, APCRAMP the Control word d_ctl_abb is checked +i f they are reqd to be updated. + +For AUXAPC (Cal+), the last bit = 1 would mean the DSP would pick it at Tx +For APCLEV (Loc), it is picked at every Tx, for dummy burst DSP would make it 0 +*/ + +/*-------------------------------------------------------*/ +void l1ddsp_load_txpwr(UWORD8 txpwr, UWORD16 radio_freq) +{ + #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (RF_FAM == 61)) + UWORD16 pwr_data; + #endif + + //config + if (l1_config.tx_pwr_code ==0) + { + // Fixed TXPWR. + l1s_dsp_com.dsp_db_w_ptr->d_power_ctl = l1_config.params.fixed_txpwr; // GSM management disabled: Fixed TXPWR used. + + + #if(RF_FAM == 61) + //Locosto has new API for Ramp + #if (DSP == 38) || (DSP == 39) + Cust_get_ramp_tab(l1s_dsp_com.dsp_ndb_ptr->a_drp_ramp, txpwr, txpwr, radio_freq); + #endif + #else + #if (CODE_VERSION != SIMULATION) + /*** Reference to real ramp array (GSM: 15 power levels, 5-19, DCS: 16 power levels, 0-15) ***/ + Cust_get_ramp_tab(l1s_dsp_com.dsp_ndb_ptr->a_ramp, txpwr, txpwr, radio_freq); + #endif + #endif + + #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3)) + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_abb |= ( (1 << B_RAMP) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2)); + #endif + + #if(RF_FAM == 61) + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_abb |= ( (1 << B_RAMP) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2)); + #endif + + } + else + { + static UWORD8 last_used_freq_band = 0; + UWORD8 freq_band; + +#if (L1_FF_MULTIBAND == 0) + // Check whether band has changed + // This will be used to reload ramps + if ((l1_config.std.id == DUAL) || + (l1_config.std.id == DUALEXT) || + (l1_config.std.id == DUAL_US)) + { + if (radio_freq < l1_config.std.first_radio_freq_band2) + freq_band = BAND1; + else + freq_band = BAND2; + } + else + freq_band = BAND1; +#else + +freq_band = l1_multiband_radio_freq_convert_into_effective_band_id(radio_freq); + +#endif + + // Note: txpwr = NO_TXPWR is reserved for forcing the transmitter off + // ----- (to suppress SACCH during handover, for example) + + /*** Check to see if the TXPWR is to be suppressed (txpwr = NO_TXPWR) ***/ + + if(txpwr == NO_TXPWR) + { + /*** No transmit ***/ + #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3)) + l1s_dsp_com.dsp_db_w_ptr->d_power_ctl = 0x12; // AUXAPC initialization addr 9 pg 0 Omega + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_abb |= ( (1 << B_RAMP) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2)); + #endif + + #if(RF_FAM == 61 ) //Locosto without Syren Format + l1s_dsp_com.dsp_db_w_ptr->d_power_ctl = (API) 0; // APCLEV + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_abb |= ( (1 << B_RAMP) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2)); + #endif + + l1s.last_used_txpwr = NO_TXPWR; + return; + } + else + { + /*** Get power data according to clipped TXPWR ***/ + pwr_data = Cust_get_pwr_data(txpwr, radio_freq + #if(REL99 && FF_PRF) + ,1 + #endif + ); + + /*** Load power control level adding the APC address register ***/ + #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3)) + l1s_dsp_com.dsp_db_w_ptr->d_power_ctl = ((pwr_data << 6) | 0x12); + // AUXAPC initialization addr 9 pg 0 Omega + #endif + + #if(RF_FAM == 61) + l1s_dsp_com.dsp_db_w_ptr->d_power_ctl = (API)(pwr_data); + #endif + } + + #if TESTMODE + #if(RF_FAM == 61) + // Currently for RF_FAM=61 Enabling APC-Ramp, APCDEL1 and APCDEL2 writing always i.e. in every TDMA frame + // TODO: Check whether this is okay + if ((l1_config.TestMode) && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK)) + #else + if ((l1_config.TestMode) && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK) && + ((l1s.last_used_txpwr != txpwr) || (l1_config.tmode.rf_params.reload_ramps_flag))) + #endif + { + #if(RF_FAM == 61) + #if (DSP == 38) || (DSP == 39) + Cust_get_ramp_tab(l1s_dsp_com.dsp_ndb_ptr->a_drp_ramp, txpwr, txpwr, radio_freq); + #endif + #else + #if (CODE_VERSION != SIMULATION) + Cust_get_ramp_tab(l1s_dsp_com.dsp_ndb_ptr->a_ramp, txpwr, txpwr, radio_freq); + #endif + #endif + + #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3)) + // Setting bit 3 of this register causes DSP to write to APCDEL1 register in Omega. However, + // we are controlling this register from MCU through the SPI. Therefore, set it to 0. + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_abb |= ( (1 << B_RAMP) | (0 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2)); + #endif + + #if (RF_FAM == 61) + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_abb |= ( (1 << B_RAMP) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2)); + #endif + + l1s.last_used_txpwr = txpwr; + l1_config.tmode.rf_params.reload_ramps_flag = 0; + } + else + #endif + + if ((l1s.last_used_txpwr != txpwr) || (last_used_freq_band != freq_band)) + { + /*** Power level or band has changed, so update the ramp, and trigger the data send to ABB ***/ + + l1s.last_used_txpwr = txpwr; + last_used_freq_band = freq_band; + + /*** Reference to real ramp array (GSM: 15 power levels, 5-19, DCS: 16 power levels, 0-15) ***/ + #if(RF_FAM == 61) + #if (DSP == 38) || (DSP == 39) + Cust_get_ramp_tab(l1s_dsp_com.dsp_ndb_ptr->a_drp_ramp, txpwr, txpwr, radio_freq); + #endif + #else + #if (CODE_VERSION != SIMULATION) + Cust_get_ramp_tab(l1s_dsp_com.dsp_ndb_ptr->a_ramp, txpwr, txpwr, radio_freq); + #endif + #endif + + #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) ||(RF_FAM == 61)) + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_abb |= ( (1 << B_RAMP) | (1 << B_BULRAMPDEL) | (1 << B_BULRAMPDEL2)); + #endif + } + } +} + +#if (FF_L1_FAST_DECODING == 1) +/*-------------------------------------------------------*/ +/* l1ddsp_load_fp_task() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_load_fast_dec_task(API task, UWORD8 burst_id) +{ + if (l1s_check_fast_decoding_authorized(task)) + { + //l1s_dsp_com.dsp_db_w_ptr->d_fast_paging_ctrl = 0x0001 + l1s_dsp_com.dsp_db_common_w_ptr->d_fast_paging_ctrl = 0x00001; + if(burst_id == BURST_1) + { + l1s_dsp_com.dsp_db_common_w_ptr->d_fast_paging_ctrl |= 0x8000; + } + } +} +#endif /* FF_L1_FAST_DECODING */ + +/*-------------------------------------------------------*/ +/* l1ddsp_load_rx_task() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_load_rx_task(API rx_task, UWORD8 burst_id, UWORD8 tsq) +{ + l1s_dsp_com.dsp_db_w_ptr->d_task_d = rx_task; // Write RX task Identifier. + l1s_dsp_com.dsp_db_w_ptr->d_burst_d = burst_id; // Write RX burst Identifier. + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsq << B_TSQ; // Write end of task DSP state. +} + +/*-------------------------------------------------------*/ +/* l1ddsp_load_tx_task() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_load_tx_task(API tx_task, UWORD8 burst_id, UWORD8 tsq) +{ + l1s_dsp_com.dsp_db_w_ptr->d_task_u = tx_task; // write TX task Identifier. + l1s_dsp_com.dsp_db_w_ptr->d_burst_u = burst_id; // write TX burst Identifier. + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= tsq << B_TSQ; // Write end of task DSP state. +} + +/*-------------------------------------------------------*/ +/* l1ddsp_load_ra_task() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_load_ra_task(API ra_task) +{ + l1s_dsp_com.dsp_db_w_ptr->d_task_ra = ra_task; // write RA task Identifier. +} + +/*-------------------------------------------------------*/ +/* l1ddsp_load_tch_mode() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_load_tch_mode(UWORD8 dai_mode, BOOL dtx_allowed) +{ + // TCH mode register. + // bit[0] -> b_eotd. + // bit[1] -> b_audio_async only for WCP + // bit [2] -> b_dtx. + // bit[3] -> play_ul when set to 1 + // bit[4] -> play_dl when set to 1 + // bit[5] -> DTX selection for voice memo + // bit[6] -> Reserved for ciphering debug + // bit[7..10] -> Reserved for ramp up control + // bit[11] -> Reserved for analog device selection + + #if (DSP == 32) + UWORD16 mask = 0xfffb; + #else // NO OP_WCP + UWORD16 mask = 0xfff8; + #endif + + l1s_dsp_com.dsp_ndb_ptr->d_tch_mode = (l1s_dsp_com.dsp_ndb_ptr->d_tch_mode & mask) + | (dtx_allowed<<2); +#if (L1_EOTD == 1) + l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= B_EOTD; +#endif +} + +#if (AMR == 1) + /*-------------------------------------------------------*/ + /* l1ddsp_load_tch_param() */ + /*-------------------------------------------------------*/ + /* Parameters : */ + /* Return : */ + /* Functionality : */ + /*-------------------------------------------------------*/ +#if (FF_L1_TCH_VOCODER_CONTROL == 1) + void l1ddsp_load_tch_param(T_TIME_INFO *next_time, UWORD8 chan_mode, + UWORD8 chan_type, UWORD8 subchannel, + UWORD8 tch_loop, UWORD8 sync_tch, + UWORD8 sync_amr, + UWORD8 reset_sacch, + #if !FF_L1_IT_DSP_DTX + UWORD8 vocoder_on) + #else + UWORD8 vocoder_on, + BOOL dtx_dsp_interrupt) + #endif +#else + void l1ddsp_load_tch_param(T_TIME_INFO *next_time, UWORD8 chan_mode, + UWORD8 chan_type, UWORD8 subchannel, + UWORD8 tch_loop, UWORD8 sync_tch, + #if !FF_L1_IT_DSP_DTX + UWORD8 sync_amr) + #else + UWORD8 sync_amr, BOOL dtx_dsp_interrupt) + #endif +#endif + { + UWORD32 count_0; + UWORD32 count_1; + UWORD32 d_ctrl_tch; + UWORD32 d_fn; + + // d_ctrl_tch + // ---------- + // bit [0..3] -> b_chan_mode + // bit [4..7] -> b_chan_type + // bit [8] -> b_sync_tch_ul + // bit [9] -> b_sync_amr + // bit [10] -> b_stop_tch_ul + // bit [11] -> b_stop_tch_dl + // bit [12..14] -> b_tch_loop + // bit [15] -> b_subchannel + #if (FF_L1_TCH_VOCODER_CONTROL == 1) + d_ctrl_tch = (chan_mode<<B_CHAN_MODE) | (chan_type<<B_CHAN_TYPE) | (subchannel<<B_SUBCHANNEL) | + (sync_tch<<B_SYNC_TCH_UL) | (sync_amr<<B_SYNC_AMR) | + (tch_loop<<B_TCH_LOOP) | (reset_sacch<<B_RESET_SACCH) | (vocoder_on<<B_VOCODER_ON); + #else + d_ctrl_tch = (chan_mode<<B_CHAN_MODE) | (chan_type<<B_CHAN_TYPE) | (subchannel<<B_SUBCHANNEL) | + (sync_tch<<B_SYNC_TCH_UL) | (sync_amr<<B_SYNC_AMR) | + (tch_loop<<B_TCH_LOOP); + #endif + + // d_fn + // ---- + // bit [0..7] -> b_fn_report + // bit [8..15] -> b_fn_sid + d_fn = (next_time->fn_in_report) | ((next_time->fn%104)<<8); + + // a_a5fn + // ------ + // count_0 (a_a5fn[0]), bit [0..4] -> T2. + // count_0 (a_a5fn[1]), bit [5..10] -> T3. + // count_1 (a_a5fn[0]), bit [0..10] -> T1. + count_0 = ((UWORD16)next_time->t3 << 5) | (next_time->t2); + count_1 = (next_time->t1); + + l1s_dsp_com.dsp_db_w_ptr->d_fn = d_fn; // write both Fn_sid, Fn_report. + l1s_dsp_com.dsp_db_w_ptr->a_a5fn[0] = count_0; // cyphering FN part 1. + l1s_dsp_com.dsp_db_w_ptr->a_a5fn[1] = count_1; // cyphering FN part 2. + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_tch = d_ctrl_tch; // Channel config. + #if FF_L1_IT_DSP_DTX + // ### TBD: report this block below in the other instance of this function + // DTX interrupt request is latched by DSP in TDMA3 (TCH-AFS, TCH-AHS0) or TDMA0 (TCH-AHS1) + if ((chan_mode == TCH_AFS_MODE) || (chan_mode == TCH_AHS_MODE)) + { + if (((next_time->fn_mod13_mod4 == 3) && + ((chan_mode == TCH_AFS_MODE) || ((subchannel == 0)))) || + ((next_time->fn_mod13_mod4 == 0) && + ((chan_mode == TCH_AHS_MODE) && (subchannel == 1))) + ) + { + if (dtx_dsp_interrupt) + l1s_dsp_com.dsp_ndb_ptr->d_fast_dtx_enable=1; + else + l1s_dsp_com.dsp_ndb_ptr->d_fast_dtx_enable=0; + + } + } + // Fast DTX not supported + else + { + // No interrupt genaration + l1s_dsp_com.dsp_ndb_ptr->d_fast_dtx_enable=0; + } + #endif + } +#else + /*-------------------------------------------------------*/ + /* l1ddsp_load_tch_param() */ + /*-------------------------------------------------------*/ + /* Parameters : */ + /* Return : */ + /* Functionality : */ + /*-------------------------------------------------------*/ +#if (FF_L1_TCH_VOCODER_CONTROL == 1) + void l1ddsp_load_tch_param(T_TIME_INFO *next_time, UWORD8 chan_mode, + UWORD8 chan_type, UWORD8 subchannel, + UWORD8 tch_loop, UWORD8 sync_tch, + #if !FF_L1_IT_DSP_DTX + UWORD8 reset_sacch, UWORD8 vocoder_on) + #else + UWORD8 reset_sacch, UWORD8 vocoder_on, + BOOL dtx_dsp_interrupt) + #endif +#else + void l1ddsp_load_tch_param(T_TIME_INFO *next_time, UWORD8 chan_mode, + UWORD8 chan_type, UWORD8 subchannel, + #if !FF_L1_IT_DSP_DTX + UWORD8 tch_loop, UWORD8 sync_tch) + #else + UWORD8 tch_loop, UWORD8 sync_tch, + BOOL dtx_dsp_interrupt) + #endif +#endif + { + UWORD32 count_0; + UWORD32 count_1; + UWORD32 d_ctrl_tch; + UWORD32 d_fn; + + // d_ctrl_tch + // ---------- + // bit [0..3] -> b_chan_mode + // bit [4..7] -> b_chan_type + // bit [8] -> b_sync_tch_ul + // bit [9] -> b_sync_tch_dl + // bit [10] -> b_stop_tch_ul + // bit [11] -> b_stop_tch_dl + // bit [12..14] -> b_tch_loop + // bit [15] -> b_subchannel + #if (FF_L1_TCH_VOCODER_CONTROL == 1) + d_ctrl_tch = (chan_mode<<B_CHAN_MODE) | (chan_type<<B_CHAN_TYPE) | (subchannel<<B_SUBCHANNEL) | + (sync_tch<<B_SYNC_TCH_UL) | (sync_tch<<B_SYNC_TCH_DL) | + (tch_loop<<B_TCH_LOOP) | (reset_sacch<<B_RESET_SACCH) | (vocoder_on<<B_VOCODER_ON); + #else + d_ctrl_tch = (chan_mode<<B_CHAN_MODE) | (chan_type<<B_CHAN_TYPE) | (subchannel<<B_SUBCHANNEL) | + (sync_tch<<B_SYNC_TCH_UL) | (sync_tch<<B_SYNC_TCH_DL) | + (tch_loop<<B_TCH_LOOP); + #endif + + // d_fn + // ---- + // bit [0..7] -> b_fn_report + // bit [8..15] -> b_fn_sid + d_fn = (next_time->fn_in_report) | ((next_time->fn%104)<<8); + + // a_a5fn + // ------ + // count_0 (a_a5fn[0]), bit [0..4] -> T2. + // count_0 (a_a5fn[1]), bit [5..10] -> T3. + // count_1 (a_a5fn[0]), bit [0..10] -> T1. + count_0 = ((UWORD16)next_time->t3 << 5) | (next_time->t2); + count_1 = (next_time->t1); + + l1s_dsp_com.dsp_db_w_ptr->d_fn = d_fn; // write both Fn_sid, Fn_report. + l1s_dsp_com.dsp_db_w_ptr->a_a5fn[0] = count_0; // cyphering FN part 1. + l1s_dsp_com.dsp_db_w_ptr->a_a5fn[1] = count_1; // cyphering FN part 2. + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_tch = d_ctrl_tch; // Channel config. + } +#endif + +#if (L1_VOCODER_IF_CHANGE == 0) +// TODO: to be moved in API file (see BUG3093) +BOOL enable_tch_vocoder(BOOL vocoder) +{ + #if (FF_L1_TCH_VOCODER_CONTROL == 1) + // To enable the vocoder, we set the trigger => then handled in l1s_dedicated_mode_manager + #if (W_A_DSP_PR20037 == 1) + if ((vocoder==TRUE) && (l1a_l1s_com.dedic_set.start_vocoder == TCH_VOCODER_DISABLED)) + { + l1a_l1s_com.dedic_set.start_vocoder = TCH_VOCODER_ENABLE_REQ; + + #if ( L1M_WAIT_DSP_RESTART_AFTER_VOCODER_ENABLE ==1) + NU_Sleep(DSP_VOCODER_ON_TRANSITION); // DSP transition + #endif + } + // When vocoder_on = FALSE, vocoder module is not executed + else if ((vocoder==FALSE) && (l1a_l1s_com.dedic_set.start_vocoder == TCH_VOCODER_ENABLED)) + { + l1a_l1s_com.dedic_set.start_vocoder = TCH_VOCODER_DISABLE_REQ; + } + #else // W_A_DSP_PR20037 == 0 + if (vocoder) + { + l1a_l1s_com.dedic_set.start_vocoder = TRUE; + } + // When vocoder_on = FALSE, vocoder module is not executed + else + { + l1a_l1s_com.dedic_set.vocoder_on = FALSE; + } + #endif // W_A_DSP_PR20037 + + return TRUE; + #else + return FALSE; + #endif + } +#endif // L1_VOCODER_IF_CHANGE +BOOL l1_select_mcsi_port(UWORD8 port) +{ + #if ( (CHIPSET == 12) && (RF_FAM != 61) ) + l1s_dsp_com.dsp_ndb_ptr->d_mcsi_select = (API)port; + return TRUE; + #else + return FALSE; + #endif +} + +// TODO: to be moved in API file + +/*-------------------------------------------------------*/ +/* l1ddsp_load_ciph_param() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_load_ciph_param(UWORD8 a5mode, + T_ENCRYPTION_KEY *ciph_key) +{ + // Store ciphering mode (0 for no ciphering) in MCU-DSP com. + l1s_dsp_com.dsp_ndb_ptr->d_a5mode = a5mode; // A5 algorithm (0 for none). + // Store ciphering key. + +#if (L1_A5_3 == 1) + + if(a5mode == 3) + { + #if(OP_L1_STANDALONE != 1) + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[0] = (ciph_key->A[0]) | (ciph_key->A[1] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[1] = (ciph_key->A[2]) | (ciph_key->A[3] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[2] = (ciph_key->A[4]) | (ciph_key->A[5] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[3] = (ciph_key->A[6]) | (ciph_key->A[7] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[4] = (ciph_key->A[8]) | (ciph_key->A[9] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[5] = (ciph_key->A[10]) | (ciph_key->A[11] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[6] = (ciph_key->A[12]) | (ciph_key->A[13] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[7] = (ciph_key->A[14]) | (ciph_key->A[15] << 8); + #else // (OP_L1_STANDALONE == 1) + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[0] = (ciph_key->A[0]) | (ciph_key->A[1] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[1] = (ciph_key->A[2]) | (ciph_key->A[3] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[2] = (ciph_key->A[4]) | (ciph_key->A[5] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[3] = (ciph_key->A[6]) | (ciph_key->A[7] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[4] = (ciph_key->A[8]) | (ciph_key->A[1] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[5] = (ciph_key->A[10]) | (ciph_key->A[3] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[6] = (ciph_key->A[12]) | (ciph_key->A[5] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[7] = (ciph_key->A[14]) | (ciph_key->A[7] << 8); + #endif + } + else // a5mode == 1 or 2 + { + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[0] = (ciph_key->A[0]) | (ciph_key->A[1] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[1] = (ciph_key->A[2]) | (ciph_key->A[3] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[2] = (ciph_key->A[4]) | (ciph_key->A[5] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_a5_kc[3] = (ciph_key->A[6]) | (ciph_key->A[7] << 8); + } + +#else + + l1s_dsp_com.dsp_ndb_ptr->a_kc[0] = (ciph_key->A[0]) | (ciph_key->A[1] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_kc[1] = (ciph_key->A[2]) | (ciph_key->A[3] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_kc[2] = (ciph_key->A[4]) | (ciph_key->A[5] << 8); + l1s_dsp_com.dsp_ndb_ptr->a_kc[3] = (ciph_key->A[6]) | (ciph_key->A[7] << 8); + +#endif +} + +/*-------------------------------------------------------*/ +/* l1ddsp_stop_tch() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_stop_tch(void) +{ + // Tch channel description. + // bit [10] -> b_stop_tch_ul, stop TCH/UL. + // bit [11] -> b_stop_tch_dl, stop TCH/DL. + + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_tch |= 3 << B_STOP_TCH_UL; +} + +/*-------------------------------------------------------*/ +/* l1ddsp_meas_read() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_meas_read(UWORD8 nbmeas, UWORD8 *pm) +{ + UWORD8 i; + + for (i= 0; i < nbmeas; i++) + { + pm[i] = ((l1s_dsp_com.dsp_db_r_ptr->a_pm[i] & 0xffff) >> 5); + } + + #if TESTMODE + if(l1_config.TestMode) + l1tm.tmode_stats.pm_recent = l1s_dsp_com.dsp_db_r_ptr->a_pm[0] & 0xffff; + #endif +} + +#if (AMR == 1) + /*-------------------------------------------------------*/ + /* l1ddsp_load_amr_param() */ + /*-------------------------------------------------------*/ + /* Parameters : AMR configuration */ + /* Return : none */ + /* Functionality : Download the AMR configuration to the */ + /* DSP via API */ + /*-------------------------------------------------------*/ + void l1ddsp_load_amr_param(T_AMR_CONFIGURATION amr_param, UWORD8 cmip) + { + // Clear the AMR API buffer + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[0] = (API)0; + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[1] = (API)0; + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[2] = (API)0; + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[3] = (API)0; + + // Set the AMR parameters + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[NSCB_INDEX] |= (API)((amr_param.noise_suppression_bit & NSCB_MASK ) << NSCB_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[ICMUL_INDEX] |= (API)((amr_param.initial_codec_mode & ICM_MASK ) << ICMUL_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[ICMDL_INDEX] |= (API)((amr_param.initial_codec_mode & ICM_MASK ) << ICMDL_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[ICMIUL_INDEX] |= (API)((amr_param.initial_codec_mode_indicator & ICMI_MASK ) << ICMIUL_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[ICMIDL_INDEX] |= (API)((amr_param.initial_codec_mode_indicator & ICMI_MASK ) << ICMIDL_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[ACSUL_INDEX] |= (API)((amr_param.active_codec_set & ACS_MASK ) << ACSUL_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[ACSDL_INDEX] |= (API)((amr_param.active_codec_set & ACS_MASK ) << ACSDL_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[THR1_INDEX] |= (API)((amr_param.threshold[0] & THR_MASK ) << THR1_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[THR2_INDEX] |= (API)((amr_param.threshold[1] & THR_MASK ) << THR2_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[THR3_INDEX] |= (API)((amr_param.threshold[2] & THR_MASK ) << THR3_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[HYST1_INDEX] |= (API)((amr_param.hysteresis[0] & HYST_MASK ) << HYST1_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[HYST2_INDEX] |= (API)((amr_param.hysteresis[1] & HYST_MASK ) << HYST2_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[HYST3_INDEX] |= (API)((amr_param.hysteresis[2] & HYST_MASK ) << HYST3_SHIFT); + l1s_dsp_com.dsp_ndb_ptr->a_amr_config[CMIP_INDEX] |= (API)((cmip & CMIP_MASK ) << CMIP_SHIFT); + } +#endif + +#if (L1_SAIC != 0) + /*-------------------------------------------------------*/ + /* l1ddsp_load_swh_flag() */ + /*-------------------------------------------------------*/ + /* Parameters : SWH (Spatial Whitening) Flag */ + /* Return : none */ + /* Functionality : To write the d_swh_ApplyWhitening flag*/ + /*-------------------------------------------------------*/ + void l1ddsp_load_swh_flag (UWORD16 SWH_flag, UWORD16 SAIC_flag) + { + + if(SAIC_flag) + { + l1s_dsp_com.dsp_db_common_w_ptr->d_swh_ctrl_db = SAIC_ENABLE_DB; + if(SWH_flag) + { + l1s_dsp_com.dsp_db_common_w_ptr->d_swh_ctrl_db |= (0x01<< B_SWH_DB); + } + } + else + { + l1s_dsp_com.dsp_db_common_w_ptr->d_swh_ctrl_db = 0; + } + } +#endif + +/*-------------------------------------------------------*/ +/* l1ddsp_end_scenario() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1ddsp_end_scenario(UWORD8 type) +{ + #if (CODE_VERSION == SIMULATION) + #if (AUDIO_SIMULATION) + switch(type) + { + case GSM_CTL: + case GSM_MISC_CTL: + // a DSP control for a GSM task or + // a DSP control for a GSM and a MISC tasks + //----------------------------- + { + // set DSP_ENB and DSP_PAG for communication interrupt + l1s_tpu_com.reg_cmd->dsp_pag_bit = l1s_dsp_com.dsp_w_page; + l1s_tpu_com.reg_cmd->dsp_enb_bit = ON; + + // change DSP page pointer for next controle + l1s_dsp_com.dsp_w_page ^= 1; + } + break; + + case MISC_CTL: + // a DSP control for a MISC task + //------------------------------ + { + // set only MISC task and reset MISC page + // (don't change GSM PAGE). + // set DSP communication Interrupt. + // set DSP_ENB and the same DSP_PAG for communication interrupt + l1s_tpu_com.reg_cmd->dsp_pag_bit = l1s_dsp_com.dsp_w_page^1; + l1s_tpu_com.reg_cmd->dsp_enb_bit = ON; + } + break; + } + #else // NO AUDIO_SIMULATION + // set DSP_ENB and DSP_PAG for communication interrupt + l1s_tpu_com.reg_cmd->dsp_pag_bit = l1s_dsp_com.dsp_w_page; + l1s_tpu_com.reg_cmd->dsp_enb_bit = ON; + + // change DSP page pointer for next control + l1s_dsp_com.dsp_w_page ^= 1; + #endif // AUDIO_SIMULATION + + #else // NOT_SIMULATION + UWORD32 dsp_task; + switch(type) + { + case GSM_CTL: + // a DSP control for a GSM task + //----------------------------- + { + // set only GSM task and GSM page + dsp_task = B_GSM_TASK | l1s_dsp_com.dsp_w_page; + // change DSP page pointer for next controle + l1s_dsp_com.dsp_w_page ^= 1; + } + break; + + case MISC_CTL: + // a DSP control for a MISC task + //------------------------------ + { + UWORD32 previous_page = l1s_dsp_com.dsp_w_page ^ 1; + + // set only MISC task and reset MISC page + // (don't change GSM PAGE). + // set DSP communication Interrupt. + dsp_task = B_MISC_TASK | previous_page; + + // Rem: DSP makes the DB header feedback even in case + // of MISC task (like TONES). This created some + // side effect which are "work-around" passing + // the correct DB page to the DSP. + } + break; + + case GSM_MISC_CTL: + // a DSP control for a GSM and a MISC tasks + //----------------------------------------- + { + // set GSM task, MISC task and GSM page bit..... + dsp_task = B_GSM_TASK | B_MISC_TASK | l1s_dsp_com.dsp_w_page; + // change DSP page pointer for next controle + l1s_dsp_com.dsp_w_page ^= 1; + } + break; + + #if 0 /* enable this after TCS211 reconstruction */ + default: + dsp_task = 0; + #endif + } + + // write dsp tasks..... + #if (DSP >= 33) + l1s_dsp_com.dsp_ndb_ptr->d_dsp_page = (API) dsp_task; + #else + l1s_dsp_com.dsp_param_ptr->d_dsp_page = (API) dsp_task; + #endif + + // Enable frame IT on next TDMA + l1dmacro_set_frame_it(); + + #if (DSP >= 38) + // DSP CPU load measurement - write logic (provide TDMA frame number to DSP) + (*((volatile UWORD16 *)(DSP_CPU_LOAD_MCU_W_TDMA_FN))) = (API)l1s.actual_time.fn_mod42432; + #endif + + #endif // NOT_SIMULATION +} + +/*-------------------------------------------------------*/ +/* l1dtpu_meas() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ + +/* Locosto : should take additional Param of task */ + +/*-------------------------------------------------------*/ +void l1dtpu_meas(UWORD16 radio_freq, + WORD8 agc, + UWORD8 lna_off, + UWORD16 win_id, + UWORD16 tpu_synchro, UWORD8 adc_active +#if(RF_FAM == 61) + ,UWORD8 afc_mode + ,UWORD8 if_ctl +#endif + ) + +{ + + WORD16 offset; + WORD16 when; + UWORD16 offset_chg; + + #if TESTMODE + if (!l1_config.agc_enable) + { + // AGC gain can only be controlled in 2dB steps as the bottom bit (bit zero) + // corresponds to the lna_off bit + agc = l1_config.tmode.rx_params.agc; + lna_off = l1_config.tmode.rx_params.lna_off; + } + #endif // TESTMODE + + // Compute offset + offset_chg = ((win_id * BP_DURATION) >> BP_SPLIT_PW2); + offset = tpu_synchro + offset_chg; + if(offset >= TPU_CLOCK_RANGE) offset -= TPU_CLOCK_RANGE; + + // Compute offset change timing + when = offset_chg + PROVISION_TIME - (l1_config.params.rx_synth_setup_time + EPSILON_OFFS); + if(when < 0) when += TPU_CLOCK_RANGE; + + // Program TPU scenario + l1dmacro_offset (offset, when); // change TPU offset according to win_id + l1dmacro_rx_synth (radio_freq); // pgme SYNTH. + if(adc_active == ACTIVE) + l1dmacro_adc_read_rx(); // pgme ADC measurement + + l1dmacro_agc (radio_freq, agc,lna_off + #if (RF_FAM == 61) + ,if_ctl + #endif + ); // pgme AGC. + #if (CODE_VERSION == SIMULATION) + l1dmacro_rx_ms (radio_freq, 0); // pgm PWR acquisition. + #else + #if (L1_MADC_ON == 1) + #if (RF_FAM == 61) + l1dmacro_rx_ms (radio_freq,adc_active); // pgm PWR acquisition. + #endif + #else + l1dmacro_rx_ms (radio_freq); // pgm PWR acquisition. + #endif + #endif + l1dmacro_offset (tpu_synchro, IMM); // restore offset + + //Locosto + #if(RF_FAM == 61) + // L1_AFC_SCRIPT_MODE - This is specific to Locosto to make AFC script run after + // the second power measurement during FBNEW + if ((win_id == 0) || (afc_mode == L1_AFC_SCRIPT_MODE)) + #else + if (win_id == 0) + #endif + { + #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3)) + // NOTE: In Locosto AFC is in DRP not in triton + l1ddsp_load_afc(l1s.afc); + #endif + + //Locosto + #if(RF_FAM == 61) + if(afc_mode != L1_AFC_NONE) + { + if(afc_mode == L1_AFC_SCRIPT_MODE) + { + l1dtpu_load_afc(l1s.afc); //Load the Initial afc value to the TPU. TPU would copy it to the DRP Wrapper Mem. + } + else + { + l1ddsp_load_afc(l1s.afc); + } + } + #endif + // end Locosto + } +} + +/*-------------------------------------------------------*/ +/* l1dtpu_neig_fb() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1dtpu_neig_fb(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off) +{ + #if TESTMODE + if (!l1_config.agc_enable) + { + // AGC gain can only be controlled in 2dB steps as the bottom bit (bit zero) + // corresponds to the lna_off bit + agc = l1_config.tmode.rx_params.agc; + lna_off = l1_config.tmode.rx_params.lna_off; + } + #endif + + l1dmacro_rx_synth (radio_freq); // pgme SYNTH. + l1dmacro_agc (radio_freq,agc, lna_off + #if (RF_FAM == 61) + ,IF_120KHZ_DSP + #endif + ); // pgme AGC. +#if (L1_MADC_ON == 1) +#if (RF_FAM == 61) + l1dmacro_rx_fb (radio_freq,INACTIVE); // pgm FB acquisition. +#endif +#else + l1dmacro_rx_fb (radio_freq); // pgm FB acquisition. +#endif +} + +/*-------------------------------------------------------*/ +/* l1dtpu_neig_fb26() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1dtpu_neig_fb26(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off, UWORD32 offset_serv) +{ + WORD16 offset; + + #if TESTMODE + if (!l1_config.agc_enable) + { + // AGC gain can only be controlled in 2dB steps as the bottom bit (bit zero) + // corresponds to the lna_off bit + agc = l1_config.tmode.rx_params.agc; + lna_off = l1_config.tmode.rx_params.lna_off; + } + #endif + + // Compute offset + offset = offset_serv + l1_config.params.fb26_anchoring_time; + if(offset >= TPU_CLOCK_RANGE) offset -= TPU_CLOCK_RANGE; + + // Program TPU scenario + l1dmacro_offset (offset, l1_config.params.fb26_change_offset_time); + l1dmacro_rx_synth (radio_freq); // pgme SYNTH. + l1dmacro_agc (radio_freq,agc, lna_off + #if (RF_FAM == 61) + ,IF_120KHZ_DSP + #endif + ); // pgme AGC. +#if (L1_MADC_ON == 1) +#if (RF_FAM == 61) + l1dmacro_rx_fb26 (radio_freq, INACTIVE); // pgm FB acquisition. +#endif +#else + l1dmacro_rx_fb26 (radio_freq); // pgm FB acquisition. +#endif + l1dmacro_offset (offset_serv, IMM); // restore offset +} + +/*-------------------------------------------------------*/ +/* l1dtpu_neig_sb() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1dtpu_neig_sb(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off, + UWORD32 time_alignmt, UWORD32 offset_serv, UWORD8 reload_flag, + UWORD8 attempt + #if (RF_FAM == 61) + ,UWORD8 if_ctl + #endif + ) +{ + UWORD16 offset_neigh; + + #if TESTMODE + if (!l1_config.agc_enable) + { + // AGC gain can only be controlled in 2dB steps as the bottom bit (bit zero) + // corresponds to the lna_off bit + agc = l1_config.tmode.rx_params.agc; + lna_off = l1_config.tmode.rx_params.lna_off; + } + #endif + + // compute offset neighbour... + offset_neigh = offset_serv + time_alignmt; + if(offset_neigh >= TPU_CLOCK_RANGE) offset_neigh -= TPU_CLOCK_RANGE; + + // load OFFSET with NEIGHBOUR value. + l1dmacro_offset (offset_neigh, l1_config.params.rx_change_offset_time); + + // Insert 1 NOP to correct the EPSILON_SYNC side effect. + if(attempt != 2) + if(time_alignmt >= (TPU_CLOCK_RANGE - EPSILON_SYNC)) + l1dmacro_offset (offset_neigh, 0); // load OFFSET with NEIGHBOUR value. + + l1dmacro_rx_synth(radio_freq); // pgme SYNTH. + l1dmacro_agc (radio_freq, agc, lna_off +#if (RF_FAM == 61) + ,if_ctl +#endif + ); // pgme AGC. + #if (L1_MADC_ON == 1) + #if (RF_FAM == 61) + l1dmacro_rx_sb (radio_freq,INACTIVE); // pgm SB acquisition. + #endif + #else + l1dmacro_rx_sb (radio_freq); // pgm SB acquisition. + #endif + + // Restore offset with serving value. + if(reload_flag == TRUE) + { + l1dmacro_offset (offset_serv, IMM); + } +} +/*-------------------------------------------------------*/ +/* l1dtpu_neig_fbsb() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +#if ((REL99 == 1) && (FF_BHO == 1)) +/*void l1dtpu_neig_fbsb(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off + #if (RF_FAM == 61) + ,UWORD8 if_ctl + #endif + )*/ +void l1dtpu_neig_fbsb(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off) +{ +#if TESTMODE + if (!l1_config.agc_enable) + { + // AGC gain can only be controlled in 2dB steps as the bottom bit (bit zero) + // corresponds to the lna_off bit + agc = l1_config.tmode.rx_params.agc; + lna_off = l1_config.tmode.rx_params.lna_off; + } +#endif // TESTMODE + + l1dmacro_rx_synth (radio_freq); // pgme SYNTH. + /*l1dmacro_agc(radio_freq, agc, lna_off + #if (RF_FAM == 61) + ,if_ctl + #endif + ); // pgme AGC. + */ + l1dmacro_agc (radio_freq,agc, lna_off + #if (RF_FAM == 61) + ,L1_CTL_LOW_IF + #endif + ); // pgme AGC. +#if (L1_MADC_ON == 1) +#if (RF_FAM == 61) + l1dmacro_rx_fbsb(radio_freq,INACTIVE); // pgm FB acquisition. +#endif +#else + l1dmacro_rx_fbsb(radio_freq); // pgm FB acquisition.- sajal commented +#endif +} +#endif // #if ((REL99 == 1) && (FF_BHO == 1)) +/*-------------------------------------------------------*/ +/* l1dtpu_neig_sb26() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1dtpu_neig_sb26(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off, UWORD32 time_alignmt, + UWORD32 fn_offset, UWORD32 offset_serv + #if (RF_FAM == 61) + ,UWORD8 if_ctl + #endif + ) +{ + UWORD16 offset_neigh; + + #if TESTMODE + if (!l1_config.agc_enable) + { + // AGC gain can only be controlled in 2dB steps as the bottom bit (bit zero) + // corresponds to the lna_off bit + agc = l1_config.tmode.rx_params.agc; + lna_off = l1_config.tmode.rx_params.lna_off; + } + #endif + + // compute offset neighbour... + offset_neigh = offset_serv + time_alignmt; + if(offset_neigh >= TPU_CLOCK_RANGE) offset_neigh -= TPU_CLOCK_RANGE; + + if(fn_offset != 0) + l1dmacro_offset (offset_neigh, 0); // 1 NOP in some case + else + l1dmacro_offset (offset_neigh, l1_config.params.fb26_change_offset_time); + + l1dmacro_rx_synth(radio_freq); // pgme SYNTH. + l1dmacro_agc(radio_freq, agc, lna_off + #if (RF_FAM == 61) + ,if_ctl + #endif + ); // pgme AGC. +#if (L1_MADC_ON == 1) +#if (RF_FAM == 61) + l1dmacro_rx_sb (radio_freq, INACTIVE); // pgm SB acquisition. +#endif +#else + l1dmacro_rx_sb (radio_freq); // pgm SB acquisition. +#endif + l1dmacro_offset (offset_serv, IMM); // Restore offset with serving value. +} + +/*-------------------------------------------------------*/ +/* l1dtpu_serv_rx_nb() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1dtpu_serv_rx_nb(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off, + UWORD32 synchro_serv,UWORD32 new_offset,BOOL change_offset, + UWORD8 adc_active + #if(RF_FAM == 61) + , UWORD8 csf_filter_choice + , UWORD8 if_ctl + #endif + #if (NEW_SNR_THRESHOLD == 1) + , UWORD8 saic_flag + #endif/* NEW_SNR_THRESHOLD == 1*/ + ) +{ + + #if (CODE_VERSION == SIMULATION) + UWORD32 tpu_w_page; + + if (hw.tpu_r_page==0) + tpu_w_page=1; + else + tpu_w_page=0; + + // Give the Ts related to the L1s + hw.rx_id[tpu_w_page][0]= ((TPU_CLOCK_RANGE+new_offset-synchro_serv)%TPU_CLOCK_RANGE)/TN_WIDTH; + hw.num_rx[tpu_w_page][0]=1; + hw.rx_group_id[tpu_w_page]=1; + #endif + + #if TESTMODE + if (!l1_config.agc_enable) + { + // AGC gain can only be controlled in 2dB steps as the bottom bit (bit zero) + // corresponds to the lna_off bit + agc = l1_config.tmode.rx_params.agc; + lna_off = l1_config.tmode.rx_params.lna_off; + } + #endif + + l1dmacro_synchro (l1_config.params.rx_change_synchro_time, synchro_serv); // Adjust serving OFFSET. + + #if L2_L3_SIMUL + #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET) + buffer_trace(3, 0x43, synchro_serv,l1s.actual_time.fn,0); + #endif + #endif + + // Need to slide offset to cope with the new synchro. + if(change_offset) + l1dmacro_offset(new_offset, l1_config.params.rx_change_offset_time); + + l1dmacro_rx_synth(radio_freq); // load SYNTH. + if(adc_active == ACTIVE) + l1dmacro_adc_read_rx(); // pgme ADC measurement + + l1dmacro_agc (radio_freq, agc, lna_off + #if (RF_FAM == 61) + ,if_ctl + #endif + ); + + #if TESTMODE && (CODE_VERSION != SIMULATION) + // Continuous mode: Rx continuous scenario only on START_RX state. + if ((l1_config.TestMode) && + (l1_config.tmode.rf_params.tmode_continuous == TM_START_RX_CONTINUOUS)) + #if (L1_MADC_ON == 1) + #if (RF_FAM == 61) + l1dmacro_rx_cont (FALSE, radio_freq,adc_active,csf_filter_choice + #if (NEW_SNR_THRESHOLD == 1) + ,saic_flag + #endif /* NEW_SNR_THRESHOLD*/ + ); + #endif /* RF_FAM == 61*/ + #else /* L1_MADC_ON == 1 */ + #if (RF_FAM == 61) + l1dmacro_rx_cont (FALSE, radio_freq,csf_filter_choice); + #else + l1dmacro_rx_cont (FALSE, radio_freq); + #endif + #endif + //TBD Danny New MAcro for Cont Tx reqd, to use only External Trigger + else + #endif + #if ( L1_MADC_ON == 1) + #if (RF_FAM == 61) + l1dmacro_rx_nb (radio_freq, adc_active, csf_filter_choice + #if (NEW_SNR_THRESHOLD == 1) + ,saic_flag + #endif /* NEW_SNR_THRESHOLD*/ + ); // RX window for NB. + #endif /* RF_FAM == 61*/ + #else /* L1_MADC_ON == 1*/ + #if (RF_FAM == 61) + l1dmacro_rx_nb (radio_freq, csf_filter_choice); // RX window for NB. + #else + l1dmacro_rx_nb (radio_freq); // RX window for NB. + #endif + #endif + + #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3)) + l1ddsp_load_afc(l1s.afc); + #endif + #if (RF_FAM == 61) + l1dtpu_load_afc(l1s.afc); + #endif + + + if(change_offset) + l1dmacro_offset(synchro_serv, IMM); // Restore offset. +} + +/*-------------------------------------------------------*/ +/* l1dtpu_serv_tx_nb() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1dtpu_serv_tx_nb(UWORD16 radio_freq, UWORD8 timing_advance, + UWORD32 offset_serv, UWORD8 txpwr, UWORD8 adc_active) +{ + WORD32 time; + UWORD32 offset_tx; + UWORD32 timing_advance_in_qbit = (UWORD32)timing_advance << 2; + + #if (CODE_VERSION == SIMULATION) + UWORD32 tpu_w_page; + + if (hw.tpu_r_page==0) + tpu_w_page=1; + else + tpu_w_page=0; + + hw.tx_id[tpu_w_page][0]=3;// MS synchronized on TN=0 for RX => TN=3 for TX + hw.num_tx[tpu_w_page][0]=1; + hw.tx_group_id[tpu_w_page]=1; + #endif + + // Reset timing advance if TA_ALGO not enabled. + #if !TA_ALGO + timing_advance_in_qbit = 0; + #endif + + // Compute offset value for TX. + // PRG_TX has become variable, no longer contained in TIME_OFFSET_TX ! + offset_tx = (offset_serv + TIME_OFFSET_TX-l1_config.params.prg_tx_gsm - timing_advance_in_qbit) ; + if (offset_tx >= TPU_CLOCK_RANGE) offset_tx -= TPU_CLOCK_RANGE; + + // Check that RX controle has been already installed. + // Offset for TX must be set an immediately if RX is there else + // it must be performed EPSILON_SYNC before current offset time. + if( l1s.tpu_ctrl_reg & CTRL_RX ) + time = l1_config.params.tx_change_offset_time - l1_config.params.prg_tx_gsm; + else + time = TPU_CLOCK_RANGE - EPSILON_SYNC; + + l1dmacro_offset (offset_tx, time); // load OFFSET for TX before each burst. + + #if L2_L3_SIMUL + #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET) + buffer_trace(2, offset_tx,l1s.actual_time.fn,0,0); + #endif + #endif + + l1dmacro_tx_synth(radio_freq); // load SYNTH. + #if TESTMODE && (CODE_VERSION != SIMULATION) + // Continuous mode: Tx continuous scenario only on START_TX state. + #if (RF_FAM != 61) + if ((l1_config.TestMode) && + (l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS)) + l1dmacro_tx_cont (radio_freq, txpwr); // TX window for NB. + else + #endif // RF_FAM != 61 + #if (RF_FAM == 61) + // NOTE: In Test Mode and in TX Continuous, APC control is in manual mode + // This is done in l1tm_async.c + if ((l1_config.TestMode) && + (l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS)) + { + // NOTE: APC is set in manual mode from l1tm_async.c + l1dmacro_tx_cont (radio_freq, txpwr); // TX window for NB. + } + else + #endif // RF_FAM == 61 + #endif + l1dmacro_tx_nb (radio_freq, txpwr, adc_active); // TX window for NB. + // TX window for NB. + l1dmacro_offset (offset_serv, IMM); // Restore offset with serving value. + + #if L2_L3_SIMUL + #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET) + buffer_trace(2, offset_serv,l1s.actual_time.fn,0,0); + #endif + #endif +} + +/*-------------------------------------------------------*/ +/* l1dtpu_neig_rx_nb() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1dtpu_neig_rx_nb(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off, + UWORD32 time_alignmt, UWORD32 offset_serv, UWORD8 reload_flag, + UWORD8 nop + #if (RF_FAM == 61) + ,UWORD8 if_ctl + #endif +#if (NEW_SNR_THRESHOLD == 1) + ,UWORD8 saic_flag +#endif /* NEW_SNR_THRESHOLD*/ + ) +{ + UWORD32 offset_neigh; +#if (RF_FAM == 61) + // By default we choose the hardware filter for neighbour Normal Bursts + UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER; +#endif + + #if TESTMODE + if (!l1_config.agc_enable) + { + // AGC gain can only be controlled in 2dB steps as the bottom bit (bit zero) + // corresponds to the lna_off bit + agc = l1_config.tmode.rx_params.agc; + lna_off = l1_config.tmode.rx_params.lna_off; + } + #endif + + // compute offset neighbour... + offset_neigh = (offset_serv + time_alignmt) ; + if (offset_neigh >= TPU_CLOCK_RANGE) offset_neigh -= TPU_CLOCK_RANGE; + + l1dmacro_offset (offset_neigh, l1_config.params.rx_change_offset_time); // load OFFSET with NEIGHBOUR value. + // Insert 1 NOP to correct the EPSILON_SYNC side effect + if (nop ==1) l1dmacro_offset (offset_neigh,0); + + + l1dmacro_rx_synth(radio_freq); // load SYNTH. + l1dmacro_agc (radio_freq, agc, lna_off + #if (RF_FAM == 61) + ,if_ctl + #endif + ); +#if (L1_MADC_ON == 1) +#if (RF_FAM == 61) + l1dmacro_rx_nb (radio_freq, INACTIVE, csf_filter_choice +#if (NEW_SNR_THRESHOLD == 1) + ,saic_flag +#endif /* NEW_SNR_THRESHOLD*/ + ) ; // RX window for NB. +#endif /* RF_FAM == 61*/ +#else /* L1_MADC_ON == 1*/ + #if (RF_FAM == 61) + l1dmacro_rx_nb (radio_freq, csf_filter_choice); // RX window for NB. + #else + l1dmacro_rx_nb (radio_freq); // RX window for NB. + #endif +#endif + + // Restore offset with serving value. + if(reload_flag == TRUE) + l1dmacro_offset (offset_serv, IMM); + +} + +/*-------------------------------------------------------*/ +/* l1dtpu_serv_tx_ra() */ +/*-------------------------------------------------------*/ +/* Parameters : "burst_id" gives the burst identifier */ +/* which is used for offset management. */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1dtpu_serv_tx_ra(UWORD16 radio_freq, UWORD32 offset_serv, UWORD8 txpwr, UWORD8 adc_active) +{ + WORD32 time; + UWORD32 offset_tx; + + // Compute offset value for TX. + // Rem: Timing Advance is always 0 for a RA. + // PRG_TX has become variable, no longer contained in TIME_OFFSET_TX ! + offset_tx = (offset_serv + TIME_OFFSET_TX-l1_config.params.prg_tx_gsm); + if (offset_tx >= TPU_CLOCK_RANGE) offset_tx -= TPU_CLOCK_RANGE; + + // Check that RX controle has been already installed. + // Offset for TX must be set an immediately if RX is there else + // it must be performed EPSILON_SYNC before current offset time. + if( l1s.tpu_ctrl_reg & CTRL_RX ) + time = l1_config.params.tx_change_offset_time - l1_config.params.prg_tx_gsm; + else + time = TPU_CLOCK_RANGE - EPSILON_SYNC; + + l1dmacro_offset (offset_tx, time); // load OFFSET for TX before each burst. + #if L2_L3_SIMUL + #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET) + buffer_trace(2, offset_tx,l1s.actual_time.fn,0,0); + #endif + #endif + l1dmacro_tx_synth(radio_freq); // load SYNTH. + l1dmacro_tx_ra (radio_freq, txpwr,adc_active); // TX window for RA. + l1dmacro_offset (offset_serv, IMM); // Restore offset with serving value. + #if L2_L3_SIMUL + #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET) + buffer_trace(2, offset_serv,l1s.actual_time.fn,0,0); + #endif + #endif +} + +/*-------------------------------------------------------*/ +/* l1dtpu_end_scenario() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1dtpu_end_scenario(void) +{ + + // write IDLE at end of TPU page + // TPU_ENB and TPU_PAG are set in L1DMACRO_IDLE(). The TPU change + // is executed by the TPU itself and the TPU pointer is reset to + // start of page by l1dmacro_idle(); + l1dmacro_idle(); + + #if (CODE_VERSION == SIMULATION) + #if LOGTPU_TRACE + log_macro(); + #endif + #endif + // init pointer within new TPU page at 1st line + #if (CODE_VERSION == SIMULATION) + // set TPU_ENB, TPU_PAG for communication interrupt + l1s_tpu_com.reg_cmd->tpu_pag_bit = l1s_tpu_com.tpu_w_page; + l1s_tpu_com.reg_cmd->tpu_enb_bit = ON; + + // change TPU and DSP page pointer for next control + l1s_tpu_com.tpu_w_page ^= 1; + + // points on new "write TPU page"... + l1s_tpu_com.tpu_page_ptr=&(tpu.buf[l1s_tpu_com.tpu_w_page].line[0]); + + #endif + +} + +/*-------------------------------------------------------*/ +/* l1d_reset_hw() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1d_reset_hw(UWORD32 offset_value) +{ + #if (CODE_VERSION == SIMULATION) + // Reset DSP write/read page, Reset TPU write page, reset "used" flag. + l1s_dsp_com.dsp_w_page = 0; + l1s_dsp_com.dsp_r_page = 0; + l1s_tpu_com.tpu_w_page = 0; + l1s_dsp_com.dsp_r_page_used = 0; + + // Reset communication pointers. + l1s_dsp_com.dsp_ndb_ptr = &(buf.ndb); // MCU<->DSP comm. read/write (Non Double Buffered comm. memory). + l1s_dsp_com.dsp_db_r_ptr = &(buf.mcu_rd[l1s_dsp_com.dsp_r_page]); // MCU<->DSP comm. read page (Double Buffered comm. memory). + l1s_dsp_com.dsp_db_w_ptr = &(buf.mcu_wr[l1s_dsp_com.dsp_w_page]); // MCU<->DSP comm. write page (Double Buffered comm. memory). + + // Reset task commands. + l1s_dsp_com.dsp_db_w_ptr->d_task_d = NO_DSP_TASK; // Init. RX task to NO TASK. + l1s_dsp_com.dsp_db_w_ptr->d_task_u = NO_DSP_TASK; // Init. TX task to NO TASK. + l1s_dsp_com.dsp_db_w_ptr->d_task_ra = NO_DSP_TASK; // Init. RA task to NO TASK. + l1s_dsp_com.dsp_db_w_ptr->d_task_md = NO_DSP_TASK; // Init. MONITORING task to NO TASK. + + + //Reset the TCH channel description + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_tch = 0; + + #if (L1_GPRS) + // Reset communication pointers. + l1ps_dsp_com.pdsp_db_r_ptr = &(buf.mcu_rd_gprs[l1s_dsp_com.dsp_r_page]); + l1ps_dsp_com.pdsp_db_w_ptr = &(buf.mcu_wr_gprs[l1s_dsp_com.dsp_w_page]); + + // Reset MCU->DSP page. + l1ps_reset_db_mcu_to_dsp(l1ps_dsp_com.pdsp_db_w_ptr); + #endif // L1_GPRS + + // Direct access to TPU_RESET_BIT. + l1s_tpu_com.reg_cmd->tpu_reset_bit = ON; // Reset TPU. + + // Reset TPU_ENB, DSP_ENB and TPU_PAG, DSP_PAG for communication interrupt + l1s_tpu_com.reg_cmd->tpu_pag_bit = 0; + l1s_tpu_com.reg_cmd->dsp_pag_bit = 0; + l1s_tpu_com.reg_cmd->tpu_enb_bit = OFF; + l1s_tpu_com.reg_cmd->dsp_enb_bit = OFF; + + // Init pointer within TPU page 0 at 1st line + l1s_tpu_com.tpu_page_ptr = &(tpu.buf[0].line[0]); + + // Load offset register according to serving cell. + l1dmacro_offset(offset_value, IMM); + + #else // NOT_SIMULATION + + // Reset DSP write/read page, Reset TPU write page, reset "used" flag. + l1s_dsp_com.dsp_w_page = 0; + l1s_dsp_com.dsp_r_page = 0; + l1s_tpu_com.tpu_w_page = 0; + l1s_dsp_com.dsp_r_page_used = 0; + + // Reset communication pointers. + l1s_dsp_com.dsp_ndb_ptr = (T_NDB_MCU_DSP *) NDB_ADR; // MCU<->DSP comm. read/write (Non Double Buffered comm. memory). + l1s_dsp_com.dsp_db_r_ptr = (T_DB_DSP_TO_MCU *) DB_R_PAGE_0; // MCU<->DSP comm. read page (Double Buffered comm. memory). + l1s_dsp_com.dsp_db_w_ptr = (T_DB_MCU_TO_DSP *) DB_W_PAGE_0; // MCU<->DSP comm. write page (Double Buffered comm. memory). + l1s_dsp_com.dsp_param_ptr= (T_PARAM_MCU_DSP *) PARAM_ADR; + + #if (DSP == 38) || (DSP == 39) + l1s_dsp_com.dsp_db_common_w_ptr = (T_DB_COMMON_MCU_TO_DSP *) DB_COMMON_W_PAGE_0; + #endif + + // Reset task commands. + l1s_dsp_com.dsp_db_w_ptr->d_task_d = NO_DSP_TASK; // Init. RX task to NO TASK. + l1s_dsp_com.dsp_db_w_ptr->d_task_u = NO_DSP_TASK; // Init. TX task to NO TASK. + l1s_dsp_com.dsp_db_w_ptr->d_task_ra = NO_DSP_TASK; // Init. RA task to NO TASK. + l1s_dsp_com.dsp_db_w_ptr->d_task_md = NO_DSP_TASK; // Init. MONITORING task to NO TASK. + + //Reset the TCH channel description + l1s_dsp_com.dsp_db_w_ptr->d_ctrl_tch = 0; + + // Clear DSP_PAG bit + #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39) + l1s_dsp_com.dsp_ndb_ptr->d_dsp_page = 0; + #else + l1s_dsp_com.dsp_param_ptr->d_dsp_page = 0; + #endif + + #if (L1_GPRS) + // Reset communication pointers. + l1ps_dsp_com.pdsp_ndb_ptr = (T_NDB_MCU_DSP_GPRS *) NDB_ADR_GPRS; + l1ps_dsp_com.pdsp_db_r_ptr = (T_DB_DSP_TO_MCU_GPRS *) DB_R_PAGE_0_GPRS; + l1ps_dsp_com.pdsp_db_w_ptr = (T_DB_MCU_TO_DSP_GPRS *) DB_W_PAGE_0_GPRS; + l1ps_dsp_com.pdsp_param_ptr= (T_PARAM_MCU_DSP_GPRS *) PARAM_ADR_GPRS; + + // Reset MCU->DSP page. + l1ps_reset_db_mcu_to_dsp(l1ps_dsp_com.pdsp_db_w_ptr); + #endif // L1_GPRS + + #if (DSP_DEBUG_TRACE_ENABLE == 1) + l1s_dsp_com.dsp_db2_current_r_ptr = (T_DB2_DSP_TO_MCU *) DB2_R_PAGE_0; + l1s_dsp_com.dsp_db2_other_r_ptr = (T_DB2_DSP_TO_MCU *) DB2_R_PAGE_1; + #endif + + // Reset TPU and Reload offset register with Serving value. + // Clear TPU_PAG + l1dmacro_reset_hw(offset_value); + #endif // NOT_SIMULATION +} + + +#if(RF_FAM == 61) + +/*-------------------------------------------------------*/ +/* l1apc_init_ramp_tables() */ +/*-------------------------------------------------------*/ +/* Parameters : void */ +/* Return : void */ +/* Functionality : This would copy the Ramp table */ +/* values to the MCU DSP API */ +/*-------------------------------------------------------*/ +void l1dapc_init_ramp_tables(void) +{ + +#if (CODE_VERSION == SIMULATION) +// Do Nothing there is no APC task + #else + #if ( DSP == 38) || (DSP == 39) + // Load RAMP up/down in NDB memory... + if (l1_config.tx_pwr_code == 0) + { + Cust_get_ramp_tab( l1s_dsp_com.dsp_ndb_ptr->a_drp_ramp, + 0 /* not used */, + 0 /* not used */, + 1 /* arbitrary value for arfcn*/); + + } + else + { + Cust_get_ramp_tab( l1s_dsp_com.dsp_ndb_ptr->a_drp_ramp, + 5 /* arbitrary value working in any case */, + 5 /* arbitrary value working in any case */, + 1 /* arbitrary value for arfcn*/); + } + #endif + // Is it required to load ramptables for GPRS a_drp2_ramp_gprs + +#endif + +} + + + +/*-------------------------------------------------------*/ +/* l1ddsp_apc_load_apcctrl2 */ +/*-------------------------------------------------------*/ +/* Parameters : void */ +/* Return : void */ +/* Functionality : This would copy the Ramp table */ +/* values to the MCU DSP API */ +/*-------------------------------------------------------*/ +void l1ddsp_apc_load_apcctrl2(UWORD16 apcctrl2) +{ + l1s_dsp_com.dsp_ndb_ptr->d_apcctrl2 = ((apcctrl2) | (0x8000)); +} + +/*-------------------------------------------------------*/ +/* l1ddsp_apc_set_manual_mode */ +/*-------------------------------------------------------*/ +/* Parameters : void */ +/* Return : void */ +/* Functionality : This would set the APC in manual */ +/* OR external trigger mode */ +/*-------------------------------------------------------*/ +void l1ddsp_apc_set_manual_mode(void) +{ + l1s_dsp_com.dsp_ndb_ptr->d_apcctrl2 |= ((APC_APC_MODE) | (0x8000)); +} + +/*-------------------------------------------------------*/ +/* l1ddsp_apc_set_automatic_mode */ +/*-------------------------------------------------------*/ +/* Parameters : void */ +/* Return : void */ +/* Functionality : This would set APC in automatic */ +/* OR internal sequencer mode */ +/*-------------------------------------------------------*/ +void l1ddsp_apc_set_automatic_mode(void) +{ + l1s_dsp_com.dsp_ndb_ptr->d_apcctrl2 &= ~(APC_APC_MODE); + l1s_dsp_com.dsp_ndb_ptr->d_apcctrl2 |= (0x8000); +} + +#ifdef TESTMODE + +/*-------------------------------------------------------*/ +/* l1ddsp_apc_load_apclev */ +/*-------------------------------------------------------*/ +/* Parameters : void */ +/* Return : void */ +/* Functionality : This function writes the apclev */ +/* val into the APCLEV register via DSP */ +/* NOTE: Used only in TESTMODE and only when */ +/* l1_config.tmode.rf_params.down_up == TMODE_UPLINK; */ +/*-------------------------------------------------------*/ +void l1ddsp_apc_load_apclev(UWORD16 apclev) +{ + l1s_dsp_com.dsp_ndb_ptr->d_apclev = ((apclev) | (0x8000)); +} + + +#endif // TESTMODE + +#endif +#if FF_L1_IT_DSP_DTX +/*-------------------------------------------------------*/ +/* l1ddsp_dtx_interrupt_pending() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : DTX interrupt status */ +/* Functionality : Test and clear the DTX IT pending */ +/* flag for DSP ISR screening purpose */ +/*-------------------------------------------------------*/ +BOOL l1ddsp_dtx_interrupt_pending(void) +{ + if (l1s_dsp_com.dsp_ndb_ptr->d_dsp_hint_flag & (2 << B_DTX_HINT_ISSUED)) + { + // Flag HISR to be scheduled + l1a_apihisr_com.dtx.pending = TRUE; + // Clear API ISR condition + l1s_dsp_com.dsp_ndb_ptr->d_dsp_hint_flag &= ~(2 << B_DTX_HINT_ISSUED); + return TRUE; + } + else + return FALSE; +} +#endif + + +#define L1_DEBUG_IQ_DUMP 0 + +#if (L1_DEBUG_IQ_DUMP == 1) + +#define IQ_DUMP_MAX_LOG_SIZE (400) /* i.e. 200 I-Q Sample Pair */ +#define IQ_DUMP_BUFFER_SIZE (1280) +#define L1_DSP_DUMP_IQ_BUFFER_PAGE0 (0xFFD00000 + ((0x2000 - 0x800)*2)) +#define L1_DSP_DUMP_IQ_BUFFER_PAGE1 (0xFFD00000 + ((0x2190 - 0x800)*2)) + +typedef struct +{ + UWORD8 task; + UWORD8 hole; + UWORD16 size; + UWORD16 fn_mod42432; + UWORD16 iq_sample[IQ_DUMP_MAX_LOG_SIZE]; +}T_IQ_LOG_BUFFER; + +#pragma DATA_SECTION(iq_dump_buffer,".debug_data"); +T_IQ_LOG_BUFFER iq_dump_buffer[IQ_DUMP_BUFFER_SIZE]; + +UWORD32 iq_dump_buffer_log_index = 0; +UWORD32 iq_overflow_ind=0; + +void l1ddsp_read_iq_dump(UWORD8 task) +{ + UWORD16 *p_dsp_iq_buffer_ptr; + UWORD16 size; + int i; + + /* get the page logic*/ + p_dsp_iq_buffer_ptr = (UWORD16 *)(L1_DSP_DUMP_IQ_BUFFER_PAGE0); + if(l1s_dsp_com.dsp_r_page){ + p_dsp_iq_buffer_ptr = (UWORD16 *)(L1_DSP_DUMP_IQ_BUFFER_PAGE1); + } + + /* */ + size = *p_dsp_iq_buffer_ptr; + + if(size == 0) + return; + + /* size given by DSP is in units of I-Q sample pair */ + if(size > (IQ_DUMP_MAX_LOG_SIZE /2)){ + size = (IQ_DUMP_MAX_LOG_SIZE/2); + } + + /* make size as zero again */ + *p_dsp_iq_buffer_ptr++ = 0; + + if(iq_dump_buffer_log_index >= IQ_DUMP_BUFFER_SIZE){ + iq_overflow_ind=1; + iq_dump_buffer_log_index = 0; + } + + iq_dump_buffer[iq_dump_buffer_log_index].task = task; + iq_dump_buffer[iq_dump_buffer_log_index].hole = 0; + iq_dump_buffer[iq_dump_buffer_log_index].size = size; + iq_dump_buffer[iq_dump_buffer_log_index].fn_mod42432 = l1s.actual_time.fn_mod42432; + + memcpy(&iq_dump_buffer[iq_dump_buffer_log_index].iq_sample[0], + p_dsp_iq_buffer_ptr, + size*2*2); /* size * 2 (as size is in IQsample pair) * 2 (to convert to bytes) */ + + iq_dump_buffer_log_index = iq_dump_buffer_log_index + 1; +} +#endif