FreeCalypso > hg > freecalypso-sw
diff gsm-fw/L1/cfile/l1_afunc.c @ 544:96a96ec34139
gsm-fw/L1/cfile: initial import from LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 03 Aug 2014 06:06:45 +0000 |
parents | |
children | c7e53436c451 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/L1/cfile/l1_afunc.c Sun Aug 03 06:06:45 2014 +0000 @@ -0,0 +1,1166 @@ +/************* Revision Controle System Header ************* + * GSM Layer 1 software + * L1_AFUNC.C + * + * Filename l1_afunc.c + * Copyright 2003 (C) Texas Instruments + * + ************* Revision Controle System Header *************/ + +#define L1_AFUNC_C + +#include "l1_macro.h" +#include "l1_confg.h" + +#if (CODE_VERSION == SIMULATION) + #include <string.h> + #include "l1_types.h" + #include "sys_types.h" + #include "l1_const.h" + #include "l1_signa.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_MIDI == 1) + #include "l1midi_defty.h" + #endif + #if (L1_MP3 == 1) + #include "l1mp3_defty.h" + #endif +//ADDED FOR AAC + #if (L1_AAC == 1) + #include "l1aac_defty.h" + #endif + #include "l1_defty.h" + #include "cust_os.h" + #include "l1_msgty.h" + #include "l1_varex.h" + #include "l1_proto.h" + #include "l1_tabs.h" + #include "l1_time.h" + #if L1_GPRS + #include "l1p_cons.h" + #include "l1p_msgt.h" + #include "l1p_deft.h" + #include "l1p_vare.h" + #endif +#else + #include <string.h> + #include "l1_types.h" + #include "sys_types.h" + #include "l1_const.h" + #include "l1_signa.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 "cust_os.h" + #include "l1_msgty.h" + #include "l1_varex.h" + #include "l1_proto.h" + #include "l1_tabs.h" + #if L1_GPRS + #include "l1p_cons.h" + #include "l1p_msgt.h" + #include "l1p_deft.h" + #include "l1p_vare.h" + #endif +#if (GSM_IDLE_RAM > 1) +#if (OP_L1_STANDALONE == 1) + #include "csmi_simul.h" +#else +#include "csmi/csmi.h" +#endif +#endif +#endif + + +#if (OP_L1_STANDALONE == 1) +#if (ANLG_FAM == 11) +#include "bspTwl3029_Madc.h" +#endif +#endif + +#if (L1_MADC_ON == 1) +#if (OP_L1_STANDALONE == 1) +#if (RF_FAM == 61) +#include "drp_api.h" +#include "l1_rf61.h" +#include <string.h> +extern T_DRP_SRM_API* drp_srm_api; +#endif +#if (ANLG_FAM == 11) +BspTwl3029_MadcResults l1_madc_results; +void l1a_madc_callback(void); +#endif +#endif +#endif //L1_MADC_ON + + + +/*-------------------------------------------------------*/ +/* l1a_reset_ba_list() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* This function resets the BA list content. */ +/* */ +/*-------------------------------------------------------*/ +void l1a_reset_ba_list() +{ + UWORD8 i; + + // Rem: this reset function do not touch the "ba_id", "nbr_carrier" and + // "radio_freq" fields. + + //!!! remove this initialization when BA list handling changed for dedic mode + if(l1a_l1s_com.mode != I_MODE) + { + l1a_l1s_com.ba_list.next_to_ctrl = 0; // Carrier for next power measurement control. + l1a_l1s_com.ba_list.next_to_read = 0; // Carrier for next power measurement result. + l1a_l1s_com.ba_list.first_index = 0; // First BA index measured in current session. + } + + // Reset of "ms_ctrl, ms_ctrl_d, msctrl_dd" is done at L1 startup + // and when SYNCHRO task is executed. + + l1a_l1s_com.ba_list.np_ctrl = 0; // PCH burst number. + + + for(i=0; i<C_BA_PM_MEAS; i++) // 2 measurements / PCH frame... + { + l1a_l1s_com.ba_list.used_il [i] = l1_config.params.il_min; // IL used in CTRL phase for AGC setting. + l1a_l1s_com.ba_list.used_il_d [i] = l1_config.params.il_min; // ... 1 frame delay. + l1a_l1s_com.ba_list.used_il_dd[i] = l1_config.params.il_min; // ... 2 frames delay, used in READ phase. + + l1a_l1s_com.ba_list.used_lna [i] = FALSE; // LNA used in CTRL phase for AGC setting. + l1a_l1s_com.ba_list.used_lna_d [i] = FALSE; // ... 1 frame delay. + l1a_l1s_com.ba_list.used_lna_dd[i] = FALSE; // ... 2 frames delay, used in READ phase. + } + + for(i=0; i<32+1; i++) + { + l1a_l1s_com.ba_list.A[i].acc = 0; // Reset IL accumulation. + } +} + +/*-------------------------------------------------------*/ +/* l1a_reset_full_list() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* This function resets the FULL list content. */ +/* */ +/*-------------------------------------------------------*/ +void l1a_reset_full_list() +{ + UWORD16 i; + + // Init power measurement multi_session process + l1a_l1s_com.full_list.meas_1st_pass_ctrl = 1; // Set 1st pass flag for power measurement session in ctrl. + l1a_l1s_com.full_list.meas_1st_pass_read = 1; // Set 1st pass flag for power measurement session in read. + l1a_l1s_com.full_list.nbr_sat_carrier_ctrl = 0; // Clear number of saturated carrier in ctrl. + l1a_l1s_com.full_list.nbr_sat_carrier_read = 0; // Clear number of saturated carrier in read. + + // Set global parameters for full list measurement. + l1a_l1s_com.full_list.next_to_ctrl = 0; // Set next carrier to control to 1st one. + l1a_l1s_com.full_list.next_to_read = 0; // Set next carrier to control to 1st one. + + // Reset Pipeline + // Note: l1a_l1s_com.full_list.ms_ctrl_d is reset at the end of l1_meas_manager() + l1a_l1s_com.full_list.ms_ctrl_dd = 0; + l1a_l1s_com.full_list.ms_ctrl_d = 0; + + // Reset the FULL LIST. + #if (L1_FF_MULTIBAND == 0) + for(i=0; i<l1_config.std.nbmax_carrier; i++) + #else + for(i=0; i< NBMAX_CARRIER; i++) + #endif + { + l1a_l1s_com.full_list.sat_flag[i] = 0; // Reset sat_flag + } + + #if L1_GPRS + // Reset PPCH burst ctrl indication + l1pa_l1ps_com.cr_freq_list.pnp_ctrl = 0; + #endif +} + +#if ((L1_EOTD == 1) && (L1_EOTD_QBIT_ACC == 1)) +/*-------------------------------------------------------*/ +/* l1a_add_time_delta() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* This function shifts a given cell timing (given as a */ +/* couple [time_alignmt, fn_offset]) by adding */ +/* a specified new time_alignmt offset (+ve or -ve */ +/* between -4999 and +4999 qb) */ +/* to that timing. */ +/* */ +/*-------------------------------------------------------*/ +void l1a_add_time_delta(UWORD32 * time_alignmt, UWORD32 * fn_offset, WORD32 delta) +{ + WORD32 new_time_alignmt = *time_alignmt + delta; + UWORD32 new_fn_offset = *fn_offset; + + if(new_time_alignmt < 0) + { + new_time_alignmt += TPU_CLOCK_RANGE; + new_fn_offset = (new_fn_offset + 1) % MAX_FN; + } + else if(new_time_alignmt >= TPU_CLOCK_RANGE) + { + new_time_alignmt -= TPU_CLOCK_RANGE; + new_fn_offset = (new_fn_offset - 1 + MAX_FN) % MAX_FN; + } + + *time_alignmt = new_time_alignmt; + *fn_offset = new_fn_offset; +} + +/*-------------------------------------------------------*/ +/* l1a_compensate_sync_ind() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* Attempts to modify the time_alignmt and fn_offset */ +/* fields of an MPHC_NCELL_SYNC_IND message based on */ +/* E-OTD cross-correlation information in order to */ +/* post-correct the result. This can be used to form a */ +/* quater-bit alignment with slow drifting neighbours */ +/* */ +/*-------------------------------------------------------*/ +void l1a_compensate_sync_ind(T_MPHC_NCELL_SYNC_IND * msg) +{ + + // This process can only be applied to SBCONF messages + // with good SCH decodes and valid EOTD results. + // + // a_eotd_crosscor [0] [1] [2] [3] [4] [5] [6] [7] [8] + // + // <------ Peak Range -----> + // + // As long as the cross-correlation peak lies in the range + // [1] to [7] then we can examine the slope of the correlation + // points on either side of the peak in order to perform a + // positive or negative QB shift. + + if((msg->sb_flag) && (msg->eotd_data_valid)) + { + WORD16 peak_index = msg->d_eotd_max - msg->d_eotd_first; + + if((peak_index >= 1) && (peak_index <= 7)) + { + UWORD32 a_power[9]; + UWORD32 pre_power, post_power, thresh_power; + UWORD32 i; + WORD32 shift = 0; + + // Calculate the normalised power of the cross-correlation samples + // in a_eotd_crosscor. This could be improved to only calculate + // the terms for [peak_index-1] [peak_index] [peak_index+1] if + // the algorithm proves viable in the long term. + + // Normalised power[i] = real[i]^2 + imag[i]^2 + + for(i=0; i<9; ++i) + { + // + // Awkward looking code to square values as our compiler / assembler + // gets the following construct wrong. Very strange... + // + // UWORD32 real = ... + // real *= real; <-- Assembler allocates registers incorrectly here + // + + UWORD32 real = msg->a_eotd_crosscor[2*i] * msg->a_eotd_crosscor[2*i]; + UWORD32 imag = msg->a_eotd_crosscor[(2*i)+1] * msg->a_eotd_crosscor[(2*i)+1]; + + // Sum of the squares... + + a_power[i] = real + imag; + } + + // By inspection of practical examples, it appears that (peak power/3) + // is a good threshold on which to compare the shape of the slope. + + thresh_power = a_power[peak_index] / 3; + pre_power = a_power[peak_index-1]; + post_power = a_power[peak_index+1]; + + // Decision on whether the gradient of the slope of the crosscor points + // on either side of the peak is large enough to cause a (max) +/- 1QB shift + // to the time_alignmt field. + + if( (pre_power < thresh_power) && (post_power > thresh_power) ) + { + // Right skew on the cross corrrelation - shift time_alignmt + // to be one greater + + shift = 1; + } + else if ( (pre_power > thresh_power) && (post_power < thresh_power) ) + { + // Left skew on the cross correlation - shift time_alignmt + // to be one less + + shift = -1; + } + + l1a_add_time_delta( &(msg->time_alignmt), + &(msg->fn_offset), + shift ); + + } + } +} +#endif + +/*-------------------------------------------------------*/ +/* l1a_add_time_for_nb() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* This function shift a given cell timing (given as a */ +/* couple [time_alignmt, fn_offset]) by adding */ +/* "SB_MARGIN - NB_MARGIN" */ +/* to that timing. */ +/* */ +/*-------------------------------------------------------*/ +void l1a_add_time_for_nb(UWORD32 *time_alignmt, UWORD32 *fn_offset) +{ + // Add "SB_MARGIN - NB_MARGIN" qbit to "fn_offset" and "time_alignmt". + // Pay attention to the modulos. + + *time_alignmt += (SB_MARGIN - NB_MARGIN); + if(*time_alignmt >= TPU_CLOCK_RANGE) + { + *time_alignmt -= TPU_CLOCK_RANGE; + *fn_offset = (*fn_offset + MAX_FN - 1) % MAX_FN; + } +} + +/*-------------------------------------------------------*/ +/* l1a_add_timeslot() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* This function shift a given cell timing (given as a */ +/* couple [time_alignmt, fn_offset]) by adding a number */ +/* of TIMESLOT (given as "tn") to that timing. */ +/* */ +/*-------------------------------------------------------*/ +void l1a_add_timeslot(UWORD32 *time_alignmt, UWORD32 *fn_offset, UWORD8 tn) +{ + // Add "tn" timeslot to "fn_offset" and "time_alignmt". + // Pay attention to the modulos. + + *time_alignmt += tn * BP_DURATION; + if(*time_alignmt >= TPU_CLOCK_RANGE) + { + *time_alignmt -= TPU_CLOCK_RANGE; + *fn_offset = (*fn_offset + MAX_FN - 1) % MAX_FN; + } +} + +/*-------------------------------------------------------*/ +/* l1a_sub_time_for_nb() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* This function shift a given cell timing (given as a */ +/* couple [time_alignmt, fn_offset]) by substacting */ +/* "SB_MARGIN - NB_MARGIN" */ +/* to that timing. */ +/* */ +/*-------------------------------------------------------*/ +void l1a_sub_time_for_nb(UWORD32 *time_alignmt, UWORD32 *fn_offset) +{ + WORD32 new_time_alignmt; + + // Sub "SB_MARGIN - NB_MARGIN" qbit to "fn_offset" and "time_alignmt". + // Pay attention to the modulos. + + new_time_alignmt = *time_alignmt - (SB_MARGIN - NB_MARGIN); + if(new_time_alignmt < 0) + { + new_time_alignmt += TPU_CLOCK_RANGE; + *fn_offset = (*fn_offset + 1) % MAX_FN; + } + *time_alignmt = new_time_alignmt; +} + +/*-------------------------------------------------------*/ +/* l1a_sub_timeslot() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* This function shift a given cell timing (given as a */ +/* couple [time_alignmt, fn_offset]) by substracting a */ +/* number of TIMESLOT (given as "tn") to that timing. */ +/* */ +/*-------------------------------------------------------*/ +void l1a_sub_timeslot(UWORD32 *time_alignmt, UWORD32 *fn_offset, UWORD8 tn) +{ + WORD32 new_time_alignmt; + + // Sub "tn" timeslot to "fn_offset" and "time_alignmt". + // Pay attention to the modulos. + new_time_alignmt = *time_alignmt - (tn * BP_DURATION); + if(new_time_alignmt < 0) + { + new_time_alignmt += TPU_CLOCK_RANGE; + *fn_offset = (*fn_offset + 1) % MAX_FN; + } + *time_alignmt = new_time_alignmt; +} + +/*-------------------------------------------------------*/ +/* l1a_correct_timing() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* */ +/*-------------------------------------------------------*/ +#if (L1_12NEIGH == 1) +void l1a_correct_timing (UWORD8 neigh_id,UWORD32 time_alignmt,UWORD32 fn_offset) +{ + // Save timing information in case of future handovers. + l1a_l1s_com.nsync.list[neigh_id].time_alignmt_mem = time_alignmt; + l1a_l1s_com.nsync.list[neigh_id].fn_offset_mem = fn_offset; + + // Sub the serving cell timeslot number to the Neigh./Serving timing + // difference to format it for L1S use. + l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn); + l1a_sub_time_for_nb(&time_alignmt, &fn_offset); + + // Save neighbor information in the neighbor confirmation cell structure. + l1a_l1s_com.nsync.list[neigh_id].time_alignmt = time_alignmt; + l1a_l1s_com.nsync.list[neigh_id].fn_offset = fn_offset; +} +#endif + +/*-------------------------------------------------------*/ +/* l1a_compute_Eotd_data() */ +/*-------------------------------------------------------*/ +/* */ +/* Description: */ +/* ------------ */ +/* */ +/*-------------------------------------------------------*/ +#if ((L1_12NEIGH ==1) && (L1_EOTD == 1)) +void l1a_compute_Eotd_data( UWORD8 *first_scell, UWORD8 neigh_id, UWORD32 SignalCode, xSignalHeaderRec *msg) +{ + WORD32 ta_sb_neigh; + UWORD32 fn_sb_neigh; + WORD16 d_eotd_first; + WORD32 toa_correction; + UWORD32 timetag; + + // SB case ..... + if (SignalCode == L1C_SB_INFO) + { + fn_sb_neigh = ((T_L1C_SB_INFO *)(msg->SigP))->fn_sb_neigh; + d_eotd_first= ((T_L1C_SB_INFO *)(msg->SigP))->d_eotd_first; + toa_correction = ((T_L1C_SB_INFO *)(msg->SigP))->toa_correction; + } + // SBCONF case ..... + else + { + fn_sb_neigh = ((T_L1C_SBCONF_INFO *)(msg->SigP))->fn_sb_neigh; + d_eotd_first= ((T_L1C_SBCONF_INFO *)(msg->SigP))->d_eotd_first; + toa_correction = ((T_L1C_SBCONF_INFO *)(msg->SigP))->toa_correction; + } + + // compute the true Serving/Neighbor time difference. + // 1) update time_alignmt with (23bit - d_eotd_first) delta + // 2) Add the serving cell timeslot number to the Serving/Neighbor time difference. + ta_sb_neigh = l1a_l1s_com.nsync.list[neigh_id].time_alignmt; + ta_sb_neigh += (d_eotd_first - (23))*4 + + (l1a_l1s_com.dl_tn * 625); + + // for Serving cell, timetag reference is 0 + if (*first_scell == TRUE) + { + l1a_l1s_com.nsync.fn_sb_serv = fn_sb_neigh; + l1a_l1s_com.nsync.ta_sb_serv = ta_sb_neigh; + + timetag = 0; + } + else + { + UWORD32 delta_fn; + WORD32 delta_qbit; + + delta_fn = (fn_sb_neigh - l1a_l1s_com.nsync.fn_sb_serv + MAX_FN)%MAX_FN; + delta_qbit = ta_sb_neigh - l1a_l1s_com.nsync.ta_sb_serv; + + // Set timetag + timetag = (delta_fn*5000) + (WORD32)(delta_qbit) + toa_correction; + + #if (CODE_VERSION == SIMULATION) + #if (TRACE_TYPE==5) + ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->delta_fn = delta_fn; + ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->delta_qbit = delta_qbit; + #endif + #endif + } + // Set timetag + ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->timetag = timetag; + +} +#endif + +/*-------------------------------------------------------*/ +/* l1a_get_free_dedic_set() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +T_DEDIC_SET *l1a_get_free_dedic_set() +{ + T_DEDIC_SET *fset; + UWORD8 i; + + // Get free set pointer. + if(l1a_l1s_com.dedic_set.aset == &(l1a_l1s_com.dedic_set.set[0])) + fset = &(l1a_l1s_com.dedic_set.set[1]); + else + fset = &(l1a_l1s_com.dedic_set.set[0]); + + // Clear free set. + fset->achan_ptr = NULL; + fset->chan1.desc.channel_type = INVALID_CHANNEL; + fset->chan1.desc_bef_sti.channel_type = INVALID_CHANNEL; + fset->chan2.desc.channel_type = INVALID_CHANNEL; + fset->chan2.desc_bef_sti.channel_type = INVALID_CHANNEL; + + fset->ma.alist_ptr = NULL; + fset->ma.freq_list.rf_chan_cnt = 0; + fset->ma.freq_list_bef_sti.rf_chan_cnt = 0; + + // Starting time. + fset->serv_sti_fn = -1; + fset->neig_sti_fn = -1; + + // Frequency redefinition flag. + fset->freq_redef_flag = FALSE; + + // Timing Advance + fset->timing_advance = 0; + fset->new_timing_advance = 0; + + // TXPWR + fset->new_target_txpwr = NO_TXPWR; + + // Cell Information + l1a_reset_cell_info(&(fset->cell_desc)); + + // Cipering. + fset->a5mode = 0; // Ciphering OFF. + + // Clear O&M test variables. + fset->dai_mode = 0; // No DAI test. + fset->chan1.tch_loop = 0; // No TCH loop on chan1. + fset->chan2.tch_loop = 0; // No TCH loop on chan2. + + // For handover... + fset->ho_acc = 0; + fset->ho_acc_to_send = 0; + fset->t3124 = 0; + +#if ((REL99 == 1) && (FF_BHO == 1)) + // For blind handover... + fset->report_time_diff = FALSE; + fset->nci = FALSE; + fset->report_time_diff = FALSE; + fset->real_time_difference = 0; + fset->HO_SignalCode = 0; +#endif + + // Reset DPAGC fifo + for(i=0;i<DPAGC_FIFO_LEN;i++) + { + fset->G_all[i] = 200; + fset->G_DTX[i] = 200; + } + + // Reset DTX_ALLOWED field. + fset->dtx_allowed = FALSE; + + #if IDS + // clear ids_mode: default value = speech mode + fset->ids_mode = 0; + #endif + +#if (AMR == 1) + // Clear the AMR ver 1.0 network settings + fset->amr_configuration.noise_suppression_bit = FALSE; + fset->amr_configuration.initial_codec_mode_indicator = FALSE; + fset->amr_configuration.initial_codec_mode = 0; + fset->amr_configuration.active_codec_set = 0; + fset->amr_configuration.threshold[0] = 0; + fset->amr_configuration.threshold[1] = 0; + fset->amr_configuration.threshold[2] = 0; + fset->amr_configuration.hysteresis[0] = 0; + fset->amr_configuration.hysteresis[1] = 0; + fset->amr_configuration.hysteresis[2] = 0; + fset->cmip = C_AMR_CMIP_DEFAULT; +#endif + return(fset); +} + +/*-------------------------------------------------------*/ +/* l1a_fill_bef_sti_param() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1a_fill_bef_sti_param(T_DEDIC_SET *set_ptr, BOOL start_time_present) +{ + if(start_time_present == TRUE) + // There is a STARTING TIME field... + { + if((set_ptr->ma.freq_list_bef_sti.rf_chan_cnt != 0) || + (set_ptr->chan1.desc_bef_sti.channel_type != INVALID_CHANNEL) || + (set_ptr->chan2.desc_bef_sti.channel_type != INVALID_CHANNEL)) + // There is at least one "bef_sti" parameter given for this channel. + // Other empty parameters must be filled with the according "AFTER STARTING TIME" parameters. + { + // Fill "chan1.desc_bef_sti" + if(set_ptr->chan1.desc_bef_sti.channel_type == INVALID_CHANNEL) + set_ptr->chan1.desc_bef_sti = set_ptr->chan1.desc; + + // Fill "chan2.desc_bef_sti" + if(set_ptr->chan2.desc_bef_sti.channel_type == INVALID_CHANNEL) + set_ptr->chan2.desc_bef_sti = set_ptr->chan2.desc; + + // Fill "freq_list_bef_sti" + if(set_ptr->ma.freq_list_bef_sti.rf_chan_cnt == 0) + set_ptr->ma.freq_list_bef_sti = set_ptr->ma.freq_list; + } + } +} + +/*-------------------------------------------------------*/ +/* l1a_decode_starting_time() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +WORD32 l1a_decode_starting_time(T_STARTING_TIME coded_starting_time) +{ + WORD32 starting_time; + + if(coded_starting_time.start_time_present == TRUE ) + // A starting time is present. + // --------------------------- + { + WORD32 tp1 = coded_starting_time.start_time.n32; + WORD32 t2 = coded_starting_time.start_time.n26; + WORD32 t3 = coded_starting_time.start_time.n51; + + // Compute STI. + starting_time = 51*((26 + t3 - t2) % 26) + t3 + (51*26*tp1) ; + } + else + { + starting_time = -1; + } + + return(starting_time); +} + +/*-------------------------------------------------------*/ +/* l1a_reset_cell_info() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1a_reset_cell_info(T_CELL_INFO *cell_info) +{ + cell_info->bsic = 0; + cell_info->fn_offset = 0; + cell_info->time_alignmt = 0; + cell_info->meas.acc = 0; + cell_info->meas.nbr_meas = 0; + cell_info->attempt_count = 0; + cell_info->si_bit_map = 0; + + cell_info->traffic_meas.input_level = l1_config.params.il_min; + cell_info->traffic_meas_beacon.input_level = l1_config.params.il_min; + cell_info->traffic_meas.lna_off = FALSE; + cell_info->traffic_meas_beacon.lna_off = FALSE; + + cell_info->buff_beacon[0] = cell_info->buff_beacon[1] = cell_info->buff_beacon[2] = + cell_info->buff_beacon[3] = l1_config.params.il_min; + + #if L1_GPRS + cell_info->transfer_meas.input_level = l1_config.params.il_min; + cell_info->transfer_meas.lna_off = FALSE; + cell_info->pb = 0; + #endif +} + +/*-------------------------------------------------------*/ +/* l1a_send_confirmation() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1a_send_confirmation(UWORD32 SignalCode, UWORD8 queue_type) +{ + xSignalHeaderRec *msg; + + msg = os_alloc_sig(0); + DEBUGMSG(status,NU_ALLOC_ERR) + msg->SignalCode = (int)SignalCode; + + #if (TRACE_TYPE==1) || (TRACE_TYPE==4) + l1_trace_message(msg); + #endif + + + #if (OP_L1_STANDALONE == 1) + os_send_sig(msg, queue_type); + #else + os_send_sig(msg, ((T_ENUM_OS_QUEUE)queue_type)); //omaps00090550 + #endif + + + DEBUGMSG(status,NU_SEND_QUEUE_ERR) +} + +/*-------------------------------------------------------*/ +/* l1a_send_result() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1a_send_result(UWORD32 SignalCode, xSignalHeaderRec *msg, UWORD8 queue) +{ + // Set flag to avoid the FREE(msg) in L1ASYNC. + l1a.l1_msg_forwarded = TRUE; + + msg->SignalCode = (int)SignalCode; + + // May not be necessary -> to check + + #if (GSM_IDLE_RAM > 1) + if (!READ_TRAFFIC_CONT_STATE) + { + CSMI_TrafficControllerOn(); + } + #endif + + #if (TRACE_TYPE==1) || (TRACE_TYPE==4) + l1_trace_message(msg); + #endif + + #if (OP_L1_STANDALONE == 1) + os_send_sig(msg, queue); + #else +os_send_sig(msg, ((T_ENUM_OS_QUEUE)queue)); //omaps00090550 + #endif + + + DEBUGMSG(status,NU_SEND_QUEUE_ERR) +} + +/*-------------------------------------------------------*/ +/* l1a_encode_rxqual() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +UWORD8 l1a_encode_rxqual (UWORD32 inlevel) +{ + enum qual_thr + { + thr_0_2 = 4, + thr_0_4 = 8, + thr_0_8 = 16, + thr_1_6 = 32, + thr_3_2 = 64, + thr_6_4 = 128, + thr_12_8 = 256 + }; + + UWORD8 rxqual; + + if (inlevel < thr_0_2) rxqual = 0; + else + if (inlevel < thr_0_4) rxqual = 1; + else + if (inlevel < thr_0_8) rxqual = 2; + else + if (inlevel < thr_1_6) rxqual = 3; + else + if (inlevel < thr_3_2) rxqual = 4; + else + if (inlevel < thr_6_4) rxqual = 5; + else + if (inlevel < thr_12_8) rxqual = 6; + else rxqual = 7; + + return((UWORD8) rxqual); +} + +/*-------------------------------------------------------*/ +/* l1a_report_failling_ncell_sync() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +void l1a_report_failling_ncell_sync(UWORD32 SignalCode, UWORD8 neigh_id) +{ + xSignalHeaderRec *msg; + + // Send MPHC_NCELL_SYNC_IND message to L3 with a FAILLURE indication. + msg = os_alloc_sig(sizeof(T_MPHC_NCELL_SYNC_IND)); + DEBUGMSG(status,NU_ALLOC_ERR) + + msg->SignalCode = SignalCode; + ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->sb_flag = FALSE; + ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->radio_freq = l1a_l1s_com.nsync.list[neigh_id].radio_freq; + ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->bsic = 0; + ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->fn_offset = 0; + ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->time_alignmt = 0; + + // For trace/debug only + ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->neigh_id = neigh_id; + + #if (TRACE_TYPE==1) || (TRACE_TYPE==4) + l1_trace_message(msg); + #endif + + os_send_sig(msg, RRM1_QUEUE); + DEBUGMSG(status,NU_SEND_QUEUE_ERR) +} + + +/*-------------------------------------------------------*/ +/* l1a_clip_txpwr() */ +/*-------------------------------------------------------*/ +/* Parameters : */ +/* Return : */ +/* Functionality : */ +/*-------------------------------------------------------*/ +#if (L1_FF_MULTIBAND == 0) + +UWORD8 l1a_clip_txpwr (UWORD8 supplied_txpwr, UWORD16 radio_freq) +{ + #define txpwr_to_compare(pwr) ((pwr<=l1_config.std.txpwr_turning_point)? pwr+32:pwr) + + switch(l1_config.std.id) + { + case GSM: + case GSM_E: + { + // Clip LOW according to powerclass_band1. + if ( supplied_txpwr < MIN_TXPWR_GSM[l1a_l1s_com.powerclass_band1]) + return(MIN_TXPWR_GSM[l1a_l1s_com.powerclass_band1]); + + // Clip HIGH according to GSM spec. 05.05. + if ( supplied_txpwr > l1_config.std.max_txpwr_band1) + return(l1_config.std.max_txpwr_band1); + } + break; + + case PCS1900: + { + // Clip LOW according to powerclass_band1. + if ( txpwr_to_compare(supplied_txpwr) < + txpwr_to_compare(MIN_TXPWR_PCS[l1a_l1s_com.powerclass_band1]) ) + return(MIN_TXPWR_PCS[l1a_l1s_com.powerclass_band1]); + + // Clip HIGH according to GSM spec. 05.05. + if ( txpwr_to_compare(supplied_txpwr) > + txpwr_to_compare(l1_config.std.max_txpwr_band1) ) + return(l1_config.std.max_txpwr_band1); + } + break; + + case DCS1800: + { + // Clip LOW according to powerclass_band1. + if ( txpwr_to_compare(supplied_txpwr) < + txpwr_to_compare(MIN_TXPWR_DCS[l1a_l1s_com.powerclass_band1]) ) + return(MIN_TXPWR_DCS[l1a_l1s_com.powerclass_band1]); + + // Clip HIGH according to GSM spec. 05.05. + if ( txpwr_to_compare(supplied_txpwr) > + txpwr_to_compare(l1_config.std.max_txpwr_band1) ) + return(l1_config.std.max_txpwr_band1); + } + break; + + case GSM850: + { + // Clip LOW according to powerclass_band1. + if ( txpwr_to_compare(supplied_txpwr) < + txpwr_to_compare(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass_band1]) ) + return(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass_band1]); + + // Clip HIGH according to GSM spec. 05.05. + if ( txpwr_to_compare(supplied_txpwr) > + txpwr_to_compare(l1_config.std.max_txpwr_band1) ) + return(l1_config.std.max_txpwr_band1); + } + break; + + case DUAL: + case DUALEXT: + { + // Test which Band is used: GSM or DCS 1800 + if (radio_freq >= l1_config.std.first_radio_freq_band2) + { + // Clip LOW according to powerclass_band1. + if ( txpwr_to_compare(supplied_txpwr) < + txpwr_to_compare(MIN_TXPWR_DCS[l1a_l1s_com.powerclass_band2]) ) + return(MIN_TXPWR_DCS[l1a_l1s_com.powerclass_band2]); + + // Clip HIGH according to GSM spec. 05.05. + if ( txpwr_to_compare(supplied_txpwr) > + txpwr_to_compare(l1_config.std.max_txpwr_band2) ) + return(l1_config.std.max_txpwr_band2); + } + else + { + // Clip LOW according to powerclass_band1. + if ( supplied_txpwr < MIN_TXPWR_GSM[l1a_l1s_com.powerclass_band1]) + return(MIN_TXPWR_GSM[l1a_l1s_com.powerclass_band1]); + + // Clip HIGH according to GSM spec. 05.05. + if ( supplied_txpwr > l1_config.std.max_txpwr_band1) + return(l1_config.std.max_txpwr_band1); + } + } + break; + + + case DUAL_US: + { + // Test which Band is used: GSM 850 or PCS1900 + if (radio_freq >= l1_config.std.first_radio_freq_band2) + { + // Clip LOW according to powerclass_band1. + if ( txpwr_to_compare(supplied_txpwr) < + txpwr_to_compare(MIN_TXPWR_PCS[l1a_l1s_com.powerclass_band2]) ) + return(MIN_TXPWR_PCS[l1a_l1s_com.powerclass_band2]); + + // Clip HIGH according to GSM spec. 05.05. + if ( txpwr_to_compare(supplied_txpwr) > + txpwr_to_compare(l1_config.std.max_txpwr_band2) ) + return(l1_config.std.max_txpwr_band2); + } + else + { + // Clip LOW according to powerclass_band1. + if ( supplied_txpwr < MIN_TXPWR_GSM850[l1a_l1s_com.powerclass_band1]) + return(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass_band1]); + + // Clip HIGH according to GSM spec. 05.05. + if ( supplied_txpwr > l1_config.std.max_txpwr_band1) + return(l1_config.std.max_txpwr_band1); + } + } + break; + + + default: // should never occur + { + return(supplied_txpwr); + } + // omaps00090550 break; + } + return(supplied_txpwr); +} + +#else /*L1_FF_MULTIBAND = 1 below */ + +UWORD8 l1a_clip_txpwr (UWORD8 supplied_txpwr, UWORD16 radio_freq) +{ + + + UWORD8 physical_band_id = 0; + physical_band_id = l1_multiband_radio_freq_convert_into_physical_band_id(radio_freq); + #define txpwr_to_compare(pwr) ((pwr<= multiband_rf[physical_band_id].tx_turning_point)? pwr+32:pwr) + switch(multiband_rf[physical_band_id].gsm_band_identifier) + { + case RF_GSM900: + { + + // Clip LOW according to powerclass_band1. + if ( supplied_txpwr < MIN_TXPWR_GSM[l1a_l1s_com.powerclass[physical_band_id]]) + return(MIN_TXPWR_GSM[l1a_l1s_com.powerclass[physical_band_id]]); + + // Clip HIGH according to GSM spec. 05.05. + if ( supplied_txpwr > multiband_rf[physical_band_id].max_txpwr) + return(multiband_rf[physical_band_id].max_txpwr); + break; + }/*case GSM900*/ + + case RF_PCS1900: + { + // Clip LOW according to powerclass_band1. + if ( txpwr_to_compare(supplied_txpwr) < + txpwr_to_compare(MIN_TXPWR_PCS[l1a_l1s_com.powerclass[physical_band_id]]) ) + return(MIN_TXPWR_PCS[l1a_l1s_com.powerclass[physical_band_id]]); + + // Clip HIGH according to GSM spec. 05.05. + if ( txpwr_to_compare(supplied_txpwr) > + txpwr_to_compare(multiband_rf[physical_band_id].max_txpwr) ) + return(multiband_rf[physical_band_id].max_txpwr); + break; + }/*case PCS1900*/ + + case RF_DCS1800: + { + // Clip LOW according to powerclass_band1. + if ( txpwr_to_compare(supplied_txpwr) < + txpwr_to_compare(MIN_TXPWR_DCS[l1a_l1s_com.powerclass[physical_band_id]]) ) + return(MIN_TXPWR_DCS[l1a_l1s_com.powerclass[physical_band_id]]); + + // Clip HIGH according to GSM spec. 05.05. + if ( txpwr_to_compare(supplied_txpwr) > + txpwr_to_compare(multiband_rf[physical_band_id].max_txpwr) ) + return(multiband_rf[physical_band_id].max_txpwr); + break; + }/*case DCS1800*/ + + case RF_GSM850: + { + // Clip LOW according to powerclass_band1. + if ( txpwr_to_compare(supplied_txpwr) < + txpwr_to_compare(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass[physical_band_id]]) ) + return(MIN_TXPWR_GSM850[l1a_l1s_com.powerclass[physical_band_id]]); + + // Clip HIGH according to GSM spec. 05.05. + if ( txpwr_to_compare(supplied_txpwr) > + txpwr_to_compare(multiband_rf[physical_band_id].max_txpwr) ) + return(multiband_rf[physical_band_id].max_txpwr); + break; + }/*case GSM850*/ + + default: // should never occur + { + l1_multiband_error_handler(); + return(supplied_txpwr); + break; + } /*default*/ + + }/*switch(multiband_rfphysical_band_id].gsm_band_identifier)*/ + return(supplied_txpwr); + +} + +#endif /*L1_FF_MULTIBAND */ + + +//MADC + +#if (L1_MADC_ON == 1) +#if (OP_L1_STANDALONE == 1) +#if (ANLG_FAM == 11) +void l1a_madc_callback(void) +{ + char str[40]; + + + + xSignalHeaderRec *adc_msg; + UWORD16 *adc_result; + UWORD16 *madc_results; + volatile UWORD16 *drp_temp_results; + +#if (RF_FAM == 61) + drp_temp_results =(volatile UWORD16 *) (&drp_srm_api->inout.temperature.output); //omaps00090550 +#endif + +#if 0 + sprintf(str, "Temp Measure %x ", drp_temp_results); + + //L1_trace_string ("Temp Meas\n"); + L1_trace_string(str); +#endif + +#if 0 + int i; + + adc_msg = os_alloc_sig(sizeof(BspTwl3029_MadcResults) + sizeof(UWORD16)); + adc_result = &((BspTwl3029_MadcResults*)(adc_msg->SigP))->adc1; + madc_results =& l1_madc_results.adc1; + + //TEMP_MEAS: DRP +#if (RF_FAM == 61) + drp_temp_results =& (drp_srm_api->inout.temperature.output); +#endif + + //copy the measured values into the the message structure. + memcpy(adc_result,madc_results,11*sizeof(UWORD16));//11 madc + adc_result[11] = *drp_temp_results; // 1 temp meas + /* + for (i=0;i<11;i++) + adc_result[i] = madc_results[i]; + */ + //Send the message + adc_msg->SignalCode = CST_ADC_RESULT; + os_send_sig(adc_msg, RRM1_QUEUE); +#endif +} +#endif // ANLG_FAM == 11 +#endif //OP_L1_STANDALONE +#endif // L1_MADC_ON + +//============================================================================================== +