view src/cs/layer1/cfile/l1_afunc.c @ 303:f76436d19a7a default tip

!GPRS config: fix long-standing AT+COPS chance hanging bug There has been a long-standing bug in FreeCalypso going back years: sometimes in the AT command bring-up sequence of an ACI-only MS, the AT+COPS command would produce only a power scan followed by cessation of protocol stack activity (only L1 ADC traces), instead of the expected network search sequence. This behaviour was seen in different FC firmware versions going back to Citrine, and seemed to follow some law of chance, not reliably repeatable. This bug has been tracked down and found to be specific to !GPRS configuration, stemming from our TCS2/TCS3 hybrid and reconstruction of !GPRS support that was bitrotten in TCS3.2/LoCosto version. ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3 version and had to be pulled from TCS2 - but as it turns out, there is a new field in the MMR_REG_REQ primitive that needs to be set correctly, and that psa_mms.c module is the place where this initialization needed to be added.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 08 Jun 2023 08:23:37 +0000
parents 4e78acac3d88
children
line wrap: on
line source

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

//==============================================================================================