line source
/************* 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