diff src/cs/layer1/cfile/l1_ctl.c @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cs/layer1/cfile/l1_ctl.c	Fri Oct 16 06:23:26 2020 +0000
@@ -0,0 +1,3266 @@
+/************* Revision Controle System Header *************
+ *                  GSM Layer 1 software
+ * L1_CTL.C
+ *
+ *        Filename l1_ctl.c
+ *  Copyright 2003 (C) Texas Instruments
+ *
+ ************* Revision Controle System Header *************/
+
+#define  L1_CTL_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_time.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_signa.h"
+    #include "l1audio_defty.h"
+    #include "l1audio_msgty.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_mftab.h"
+  #include "l1_tabs.h"
+  #include "l1_ver.h"
+  #if L2_L3_SIMUL
+    #include "hw_debug.h"
+  #endif
+
+  #if TESTMODE
+    #include "l1tm_msgty.h"
+    #include "l1tm_varex.h"
+  #endif
+
+  #include "l1_ctl.h"
+
+  #ifdef _INLINE
+    #define INLINE static inline // Inline functions when -v option is set
+  #else                          // when the compiler is ivoked.
+    #define INLINE
+  #endif
+#else
+  #include <string.h>
+  #include "l1_types.h"
+  #include "sys_types.h"
+  #include "l1_const.h"
+  #include "l1_time.h"
+  #include "l1_signa.h"
+
+  #if (RF_FAM == 61)
+      #include "tpudrv61.h"
+  #endif
+
+  #if TESTMODE
+    #include "l1tm_defty.h"
+  #endif
+  #if (AUDIO_TASK == 1)
+    #include "l1audio_const.h"
+    #include "l1audio_cust.h"
+    #include "l1audio_defty.h"
+  #endif
+  #if (L1_GTT == 1)
+    #include "l1gtt_const.h"
+    #include "l1gtt_defty.h"
+  #endif
+  #if (L1_MP3 == 1)
+    #include "l1mp3_defty.h"
+  #endif
+  #if (L1_MIDI == 1)
+    #include "l1midi_defty.h"
+  #endif
+//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_ctl.h"
+  #if L2_L3_SIMUL
+    #include "hw_debug.h"
+  #endif
+
+  #if TESTMODE
+    #include "l1tm_msgty.h"
+    #include "l1tm_varex.h"
+  #endif
+  #ifdef _INLINE
+    #define INLINE static inline // Inline functions when -v option is set
+  #else                          // when the compiler is ivoked.
+    #define INLINE
+  #endif
+#endif
+
+#if(RF_FAM == 61)
+  #include "l1_rf61.h"
+#endif
+
+#if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+  #include "l1_trace.h"
+#endif
+
+extern SYS_UWORD16 Convert_l1_radio_freq(SYS_UWORD16 radio_freq);
+#if(RF_FAM == 61)
+extern WORD16 drp_gain_correction(UWORD16 arfcn, UWORD8 lna_off, UWORD16 agc);
+#endif
+
+#define LNA_OFF  1
+#define LNA_ON   0
+
+
+
+
+/************************************/
+/* Automatic frequency compensation */
+/************************************/
+
+/*
+ * FreeCalypso TCS211 reconstruction: the following 3 functions
+ * have been added in the LoCosto version of this module.
+ * We have conditioned them out in order to match the original
+ * TCS211 object; their uses have been conditioned out as well.
+ *
+ * These functions will need to re-enabled when their uses are
+ * re-enabled.
+ */
+
+#if 0
+
+#define L1_WORD16_POS_MAX (32767)
+#define L1_WORD16_NEG_MAX (-32768)
+#define L1_WORD32_POS_MAX ((unsigned long)(1<<31)-1)
+#define L1_WORD32_NEG_MAX (-(unsigned long)(1<<31))
+
+INLINE WORD16 Add_Sat_sign_16b(WORD16 val1, WORD16 val2)
+{
+  WORD32 temp;
+  WORD16 result;
+
+  temp = (WORD32)((WORD32)val1 + (WORD32)val2);
+  if(temp > L1_WORD16_POS_MAX)
+  {
+    temp = L1_WORD16_POS_MAX;
+  }
+  if(temp < L1_WORD16_NEG_MAX)
+  {
+    temp = L1_WORD16_NEG_MAX;
+  }
+  result = (WORD16)((temp)&(0x0000FFFF));
+  return(result);
+}
+
+INLINE WORD32 Add_Sat_sign_32b(WORD32 val1, WORD32 val2)
+{
+  WORD32 temp_high_high;
+  UWORD32 temp_low_low;
+  UWORD16 carry;
+  WORD32 result;
+  WORD16  high_val1, high_val2;
+  UWORD16 low_val1, low_val2;
+
+  high_val1 = (WORD16)(val1>>16);
+  high_val2 = (WORD16)(val2>>16);
+  low_val1  = (UWORD16)(val1&0x0000FFFF);
+  low_val2  = (UWORD16)(val2&0x0000FFFF);
+
+  temp_high_high = (WORD32)high_val1 + (WORD32)high_val2;
+  temp_low_low   = (UWORD32)low_val1 + (UWORD32)low_val2;
+  carry = (UWORD16)(temp_low_low >> 16);
+  temp_high_high = temp_high_high + (UWORD32)(carry);
+
+
+  result = val1 + val2;
+  if(temp_high_high >  L1_WORD16_POS_MAX)
+  {
+    result = L1_WORD32_POS_MAX;
+  }
+  if(temp_high_high < L1_WORD16_NEG_MAX)
+  {
+    result = L1_WORD32_NEG_MAX;
+  }
+
+  return(result);
+}
+
+INLINE WORD32 Sat_Mult_20sign_16unsign(WORD32 val1, UWORD32 val2)
+{
+  WORD32 result;
+
+  result = val1 * val2;
+  if(val1>0) /*  val2 is > 0*/
+  {
+    if(result < 0) /* overflow */
+    {
+      result = L1_WORD32_POS_MAX;
+    }
+  }
+  if(val1<0) /*  val2 is > 0*/
+  {
+    if(result > 0) /* overflow */
+    {
+      result = L1_WORD32_NEG_MAX;
+    }
+  }
+  return(result);
+}
+#endif
+
+INLINE WORD32 Add_40b( WORD32 guard1guard2, WORD32 lvar1, WORD32 lvar2, WORD16 *guardout )
+{
+  WORD32  result, temp, carry, Lvar1, Lvar2;
+  WORD16  guard1,guard2;
+
+  guard1=(WORD16) ((WORD32) guard1guard2>>16);
+  guard2=(WORD16) guard1guard2;
+
+  /* lvar1 and lvar2 are both 48 bits variables              */
+  /* We 1st add the low parts of lvar1 and lvar2 and we give */
+  /* a 32 bits result and a carry if needed                  */
+  Lvar1 = (UWORD16)lvar1;
+  Lvar2 = (UWORD16)lvar2;
+
+  temp = Lvar1 + Lvar2;
+
+  carry = temp >> 16;
+
+  result = temp & 0x0000ffffL;
+
+  /* We now add the two high parts of var1 and var2 (scaled */
+  /* to a 16 bits format) and carry (if any) and we give a  */
+  /* 48 bits results.                                       */
+  Lvar1 = (UWORD32)lvar1 >> 16;
+  Lvar2 = (UWORD32)lvar2 >> 16;
+
+  temp = Lvar1 + Lvar2 + carry;
+
+  carry = (UWORD32)temp >> 16;
+
+  temp = (UWORD32)temp << 16;
+
+  result = result | temp;
+
+  temp = guard1 + guard2 + carry;
+
+  *guardout = (WORD16)temp;
+
+  return( result );
+}
+
+
+INLINE WORD32 Mult_40b(WORD32 var1, WORD16 var2, WORD16 *guardout)
+{
+  WORD32   mult,guard1guard2;
+  WORD32   aux1;
+  UWORD32  aux2;
+  WORD16   neg_flag=0;
+  WORD32   var1_low_nosign,var2_nosign;
+
+  if (var2<0)
+  {
+    var2=-var2;
+    neg_flag=1;
+  }
+
+  /*aux1  = AccHigh(var1)*var2 */
+  aux1 = (WORD32)(var1>>16) * (WORD32)var2;
+                   /* 16 bits * 16 bits -> 32 bits result */
+
+  /*aux2  = AccLow(var1)*var2  (unsigned multiplication)  */
+  /* Performs the sign suppression of the words           */
+  var1_low_nosign  = (UWORD16)var1;
+  var2_nosign      = (UWORD16) var2;
+
+  aux2 = (UWORD32)var1_low_nosign * (UWORD32)var2_nosign;
+
+  /*Shift aux1=F48 of 16 bit left */
+  guard1guard2=aux1&0xFFFF0000L;/*guard1=(WORD16)(aux1>>16)*/
+                                /*guard2=0x0000           */
+  aux1=aux1<<16;
+
+
+  /* ((var1_high*var2)<<16) +(var1_low*var2) = aux1 + aux2 */
+  /* aux1 and aux2 are both 48 bits variables              */
+  /* We first add the low pats of aux1 and aux2 and we give*/
+  /* a 32 bits result and a carry if needed                */
+  mult=Add_40b(guard1guard2,aux1,aux2,guardout );
+
+  if (neg_flag)
+  {
+   mult=-mult;
+   if (*guardout!=0)
+    *guardout=-(*guardout)-1;
+   else
+    *guardout=-1;
+  }
+
+  return(mult);
+}
+
+
+/***********************************************************************/
+/* This function allows to multiply a WORD32 and a WORD16, both POSITIVE, */
+/* variables. Result is WORD32.                                          */
+/***********************************************************************/
+INLINE WORD32 UMult_40b(WORD32 var1, WORD16 var2, WORD16 *guardout)
+{
+  WORD32   mult,guard1guard2;
+  UWORD32  aux1,aux2;
+  WORD32   var1_high_nosign,var1_low_nosign,var2_nosign;
+
+
+  /*aux1  = AccHigh(var1)*var2  (unsigned multiplication) */
+  /* Performs the sign suppression of the words           */
+  var1_high_nosign = (UWORD32)var1>>16;
+  var2_nosign      = (UWORD16) var2;
+
+  aux1 = (UWORD32)var1_high_nosign * (UWORD32)var2_nosign;
+
+  /*aux2  = AccLow(var1)*var2  (unsigned multiplication)  */
+  /* Performs the sign suppression of the words           */
+  var1_low_nosign  = (WORD32)((UWORD16)var1);
+
+  aux2 = (UWORD32)var1_low_nosign * (UWORD32)var2_nosign;
+
+  /*Shift aux1=F48 of 16 bit left */
+  guard1guard2=aux1&0xFFFF0000L;/*guard1=(WORD16)(aux1>>16)*/
+                                /*guard2=0x0000           */
+  aux1=aux1<<16;
+
+
+  /* ((var1_high*var2)<<16) +(var1_low*var2) = aux1 + aux2 */
+  mult=Add_40b(guard1guard2,aux1,aux2,guardout);
+
+  return(mult);
+}
+
+
+/*-------------------------------------------------------*/
+/* l1ctl_afc()                                           */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+#if (VCXO_ALGO == 0)
+WORD16 l1ctl_afc (UWORD8 phase, UWORD32 *frame_count, WORD16 angle, WORD32 snr, UWORD16 radio_freq)
+#else
+WORD16 l1ctl_afc (UWORD8 phase, UWORD32 *frame_count, WORD16 angle, WORD32 snr, UWORD16 radio_freq, UWORD32 l1_mode)
+#endif
+{
+ /*************************/
+ /* Variables declaration */
+ /*************************/
+        WORD16  i=0;
+        UWORD32 denom;             /* F12.20 */
+        WORD32  var_32,num,Phi_32=0,var1,var2,guard1guard2;
+ static UWORD32 P=C_cov_start;             /* F12.20 */
+ static WORD32  Psi=0;                     /* F13.19 */
+ static WORD16  Psi_quant[C_N_del+1];      /* F13.3  */
+        WORD16  var_16;
+        WORD16  Phi=0;                     /* F1.15  */
+        WORD16  quotient,guard1,guard2,guardout;
+        UWORD32 LGuard;
+        WORD16  denomH,denomH_3msb;
+        UWORD32 K=0;                           /* algo 1 */
+
+ static WORD16  old_Psi_quant[C_N_del+1];
+ static WORD32  old_Psi=0;
+
+#if (VCXO_ALGO == 1)
+    static WORD32  psi_past[C_N_del+1];        /* F13.19 */
+    static WORD16  psi_quant;                  /* F13.3  */
+    static WORD16  quant_avg;
+    static UWORD32 M_Count;
+    static WORD32  psi_avg[C_PSI_AVG_SIZE_D+1]; // Data history array
+    static WORD16  B_Count;                     // Counter for consecutive SNR below C_thr_snr
+    #if 0	/* LoCosto added var */
+      UWORD16 L = 10433;                          // Gain algo2
+    #endif
+    static UWORD16 first_avg;
+    static UWORD16 good_snr;
+
+    /* to be able to keep in memory the old AFC variables in case of spurious
+       FB detection */
+    static WORD32  old_psi_past[C_N_del+1];        /* F13.19 */
+    static WORD16  old_psi_quant;                  /* F13.3  */
+
+#endif
+#if (L1_FF_MULTIBAND == 1)
+    UWORD8 physical_band_id;
+#endif
+
+#if 0	/* LoCosto added var init */
+//Set AFC close loop gain for ALGO_AFC_LQG_PREDICTOR.
+if(l1_mode==I_MODE)//MS is in Idle mode
+L = 41732; //F0.20 L=41732/2^20 = 0.04
+else //All other modes than Idle
+L = 10433; //F0.20 L=10433/2^20 = 0.01
+#endif
+
+#if (L1_FF_MULTIBAND == 0)
+
+    if (((l1_config.std.id == DUAL) || (l1_config.std.id == DUALEXT) || (l1_config.std.id == DUAL_US)) &&
+#if (VCXO_ALGO == 1)
+        ((phase != AFC_INIT_CENTER) || (phase != AFC_INIT_MIN) || (phase != AFC_INIT_MAX)))
+#else
+         (phase != AFC_INIT))
+#endif
+ {
+    if (radio_freq >= l1_config.std.first_radio_freq_band2)
+    {
+      angle = (angle + 1) >> 1;
+    }
+ }
+
+    else if (((l1_config.std.id == DCS1800) || (l1_config.std.id == PCS1900)) &&
+#if (VCXO_ALGO == 1)
+        ((phase != AFC_INIT_CENTER) || (phase != AFC_INIT_MIN) || (phase != AFC_INIT_MAX)))
+#else
+         (phase != AFC_INIT))
+#endif
+ {
+   angle = (angle + 1) >> 1;
+ }
+
+#else // L1_FF_MULTIBAND = 1 below
+
+#if (VCXO_ALGO == 1)
+     if((phase != AFC_INIT_CENTER) || (phase != AFC_INIT_MIN) || (phase != AFC_INIT_MAX))
+#else
+     if(phase != AFC_INIT)
+#endif
+    {
+      physical_band_id = l1_multiband_radio_freq_convert_into_physical_band_id(radio_freq);
+
+      if( (multiband_rf[physical_band_id].gsm_band_identifier == DCS1800) || (multiband_rf[physical_band_id].gsm_band_identifier == PCS1900))
+      {
+         angle = (angle + 1) >> 1;
+      }
+    }
+
+#endif // #if (L1_FF_MULTIBAND == 1) else 
+
+
+
+ /*********************************/
+ /* frequency offset compensation */
+ /*********************************/
+ /* Initialization */
+
+#if (VCXO_ALGO == 1)
+ switch (l1_config.params.afc_algo)
+ {
+
+   /* algo1 only: */
+   case ALGO_AFC_KALMAN:
+   {
+#endif
+#if (VCXO_ALGO == 0)
+     if (phase==AFC_INIT)
+     {
+         // WARNING
+       // In this case, "angle" variable contains EEPROM_AFC initialization value
+       // directly loaded from EEPROM, and "snr" variable is not meaningful.
+       /* Static variables initialisation */
+       P=C_cov_start;
+       Psi=0;
+       if (angle>C_max_step)
+          Psi_quant[C_N_del]=C_max_step;
+       else
+          if(angle<C_min_step)
+            Psi_quant[C_N_del]=C_min_step;
+          else Psi_quant[C_N_del]=angle;
+
+       Psi=l1_config.params.psi_st*Psi_quant[C_N_del];         /* F0.16 * F13.3 = F13.19 */
+     } /* end AFC_INIT*/
+     else
+     {
+       if (phase==AFC_OPEN_LOOP)
+       {
+         /* delay line for Psi_quant values */
+         for (i=1;i<=C_N_del;i++)
+           Psi_quant[i-1]=Psi_quant[i];
+
+         var_32=(WORD32)((WORD32)angle*l1_config.params.psi_sta_inv)<<4;
+                                 /*(F16.0 * F1.15 = F17.15) << 4 = F13.19 */
+
+#if(RF_FAM == 61)
+         /* In order to implement the NINT function for a F16.0, we check */
+         /* if var_32 + 0.5*2**18 is a multiple of 2**18                  */
+         quotient=(WORD16)((WORD32)(((WORD32)(var_32+(1<<17)))/(1<<18)));
+         var_16=quotient*4;
+#else
+         /* In order to implement the NINT function for a F16.0, we check */
+         /* if var_32 + 0.5*2**19 is a multiple of 2**19                  */
+         quotient=(WORD16)((WORD32)(((WORD32)(var_32+(1<<18)))/(1<<19)));
+         var_16=quotient*8;
+#endif
+           if (var_16>C_max_step)
+		    Psi_quant[C_N_del]=Add_Sat_sign_16b(Psi_quant[C_N_del],C_max_step);
+		  else
+		    if(var_16<C_min_step)
+		      Psi_quant[C_N_del]=Add_Sat_sign_16b(Psi_quant[C_N_del],C_min_step);
+		    else Psi_quant[C_N_del]=Add_Sat_sign_16b(Psi_quant[C_N_del],var_16);     /* F13.3                  */
+
+		     Psi=l1_config.params.psi_st*Psi_quant[C_N_del];       /* F0.16 * F13.3 = F13.19 */
+	   }/*end if AFC_OPEN_LOOP*/
+
+       else
+       {
+         /* delay line for Psi_quant values */
+         for (i=1;i<=C_N_del;i++)
+           Psi_quant[i-1]=Psi_quant[i];
+
+         /********************/
+         /* Filter algorithm */
+         /********************/
+
+         /* Covariance error is increased of C_Q */
+         P=P+(*frame_count)*C_Q;
+
+         /* Clipping of P */
+         if (P>C_thr_P) P=C_thr_P;
+
+         if (snr>=C_thr_snr)
+         {
+           /* Clipping of error angle */
+           if (angle>C_thr_phi)
+            angle=C_thr_phi;
+           if (angle<-C_thr_phi)
+            angle=-C_thr_phi;
+
+           /* Kalman gain                             */
+           /*K=P*(1/(P+C_a0_kalman+(C_g_kalman*RNS))) */
+           /*C_a0_kalman=0.01                         */
+           /*C_g_kalman =0.05                         */
+           num=(C_g_kalman/snr)+P+C_a0_kalman;
+                         /* (F2.30 / F6.10) = F 12.20 */
+
+           /* denom = P << 19 = F 1.39                                */
+           /* extension of denom=P to a 40 bits variable              */
+           /* denom (F12.20) << 16 = F 4.36                           */
+           guard1=(WORD16)((WORD32)P>>16);
+           /* denom = P<<16 = (F4.36) << 3 = F 1.39                   */
+           denomH=(UWORD16)P;
+           /* Low part of denom is equal to 0, because P has been 16  */
+           /* bits left shifted previously.                           */
+           denomH_3msb=(denomH>>13)&0x0007;
+           guard1=(guard1<<3)|denomH_3msb;
+           denomH<<=3;
+           denom=(UWORD32)denomH<<16;
+           /* num + guard1 are a 40 bits representation of P          */
+           /* In order to compute P(F1.39)/num, we sample P in guard1 */
+           /* (scaled to a 32 bits number) and num (32 bits number)   */
+           /* K = ((guard1<<24)/num)<<8 + (denom/num)                 */
+           var1=(WORD32)guard1<<24;
+           var1=var1/num;
+           var1=(WORD32)var1<<8;
+           /* var2 is an unsigned variable, var1 contains signed guard*/
+           /* bits.                                                   */
+           var2=denom/num;
+           K = (var1+var2)<<1;             /* F1.39 / F12.20 = F13.19 */
+                                           /* F13.19 << 1 = F12.20    */
+
+           /* Clipping of the Kalman gain  */
+           if (K>=C_thr_K)
+             K=C_thr_K;
+
+           /*******************************************************/
+           /* P=(1-K)*P = 0.8 * 0.5 at maximum                    */
+           /*******************************************************/
+           /* Perform a positive variable F12.20 multiplication by*/
+           /* positive variable F12.20                            */
+           var_16=(WORD16)(1048576L-K);   /* acclow(1-K) = F12.20  */
+           guard1=0;                     /* positive variable     */
+           var1=UMult_40b(P,var_16,&guard1);
+           var_16=(WORD16)((1048576L-K)>>16);
+                                         /* acchigh(1-K) = F12.20 */
+           var2=P*var_16;                /* var2 = 0x80000 * 0xc  */
+                                         /* at maximum, so result */
+                                         /* is 32 bits WORD32 and   */
+                                         /* equal 0x600000        */
+           /* extension of var2 to a 40 bits variable : var2<<16  */
+           guard2=(WORD16)((WORD32)var2>>16);
+           guard1guard2=((WORD32)guard1<<16) |((WORD32) guard2&0x0000FFFFL);
+           var2=var2<<16;
+           var_32=Add_40b(guard1guard2,var1,var2,&guardout);
+           /* var_32 (F8.40) >> 16 = F8.24  */
+           LGuard=(WORD32)guardout<<16;
+           var1=(UWORD32)var_32>>16;
+           /* var_32 >> 4 = F12.20          */
+           P=(var1+LGuard)>>4;
+
+           Phi_32=Mult_40b(l1_config.params.psi_st_32,Psi_quant[0],&guardout);
+                                       /* F0.32 * F13.3 = F5.35    */
+           LGuard=(WORD32)guardout<<16;  /* var_32 (F5.35) >> 16     */
+                                       /* F13.19                   */
+           var1=(UWORD32)Phi_32>>16;
+           Phi_32=Psi-(LGuard+var1);   /* F13.19                   */
+
+           /*Phi=angle-Phi_32*/
+           Phi_32=((WORD32)angle<<4)-Phi_32;
+                                        /* F1.15 * 4 = F13.19       */
+           Phi=(WORD16)(Phi_32>>4);      /* F17.15                   */
+           /*var1=K*Phi                    F12.20 * F1.15 = 13.35   */
+           guard1=0;
+           var1=Mult_40b(K,Phi,&guard1);
+                                        /* var1 (F13.35) >> 16      */
+                                        /* F13.19                   */
+           LGuard=(WORD32)guard1<<16;
+           var1=(UWORD32)var1>>16;
+           Psi+=var1+LGuard;
+           }/*if snr */
+
+           var_32=Mult_40b(Psi,l1_config.params.psi_st_inv,&guardout);
+                                        /* F13.19 * C      = F13.19 */
+
+#if(RF_FAM == 61)
+           /* In order to implement the NINT function for a F13.3, we check */
+           /* if var_32 + 0.5*2**18 is a multiple of 2**18                  */
+           quotient=(WORD16)((WORD32)(((WORD32)(var_32+(1<<17)))/(1<<18)));
+           var_16=quotient*4;
+#else
+           /* In order to implement the NINT function for a F13.3, we check */
+           /* if var_32 + 0.5*2**19 is a multiple of 2**19                  */
+           quotient=(WORD16)((WORD32)(((WORD32)(var_32+(1<<18)))/(1<<19)));
+           var_16=quotient*8;
+#endif
+           if (var_16>C_max_step)
+             Psi_quant[C_N_del]=C_max_step;
+           else
+             if(var_16<C_min_step)
+               Psi_quant[C_N_del]=C_min_step;
+             else Psi_quant[C_N_del]=var_16; /* F13.3                 */
+
+       }/*end AFC_CLOSE_LOOP*/
+     } /* end else AFC_INIT*/
+
+     *frame_count=0;
+     return(Psi_quant[C_N_del]>>3); /* F16.0 */
+
+#else
+
+    } /* end case algo 1 */
+
+
+    /* algo2 + init + estimator/predictor */
+    case ALGO_AFC_LQG_PREDICTOR:
+    {
+        /******************************************************************/
+        /* (New) VCXO Algorithm                                           */
+        /******************************************************************/
+
+        switch (phase) {
+            case AFC_INIT_CENTER  :
+            case AFC_INIT_MAX     :
+            case AFC_INIT_MIN     :
+            quant_avg = 0;
+            M_Count = 0;
+#if 0	/* present in LoCosto but not in TCS211 */
+            for (i = 0; i <= C_PSI_AVG_SIZE_D ; i++)  //omaps00090550
+                psi_avg[i] = 0;
+#endif
+            first_avg = 1;
+            good_snr = 0;
+
+            // DAC search algorithm is as follows - up to 12 attempts are made
+            // DAC search algorithm uses three values : DAC_center -> DAC_max -> DAC_min ->
+            // The first four attempts are made on DAC_center
+            // The next four attempts are made on DAC_max
+            // The last four attempts are made on DAC_min
+            // There are statistical reasons for trying four times
+
+            switch (phase)
+            {
+                case AFC_INIT_CENTER:
+                    psi_quant = l1_config.params.afc_dac_center;
+                    break;
+                case AFC_INIT_MAX:
+                    psi_quant = l1_config.params.afc_dac_max;
+                    break;
+                case AFC_INIT_MIN:
+                    psi_quant = l1_config.params.afc_dac_min;
+                    break;
+                default :
+                  break;
+            }
+
+            /* F0.32 * F13.3 = F5.35    */
+            psi_past[C_N_del]=Mult_40b(l1_config.params.psi_st_32,psi_quant, &guardout);
+            /*  (F13.3<<16 )+(F5.35>>16) = F13.19 */
+            psi_past[C_N_del]=((WORD32)guardout<<16)+((UWORD32)psi_past[C_N_del]>>16);
+
+            break;
+
+            case AFC_OPEN_LOOP  :
+            {
+              /* VCXO changes for spurious FB detection */
+              if (l1s.spurious_fb_detected == TRUE)
+              {
+                psi_quant = old_psi_quant;
+
+                for(i=0;i<C_N_del+1;i++)
+                  psi_past[i] = old_psi_past[i];
+
+                /* reset the spurious_fb_detected_flag */
+                l1s.spurious_fb_detected = FALSE;
+              } /* end of spuriousFB detected */
+
+            /* save in memory the old AFC related values */
+            old_psi_quant = psi_quant;
+
+            for(i=0;i<C_N_del+1;i++)
+              old_psi_past[i] = psi_past[i];
+
+            /* delay line for psi_quant values */
+            for (i = 1; i <= C_N_del; i++)
+                psi_past[i-1] = psi_past[i];
+
+                /* (F16.0 * F1.15 = F17.15) << 4 = F13.19 */
+                var_32 = (WORD32) ((WORD32)angle * l1_config.params.psi_sta_inv) << 4;
+
+#if(RF_FAM == 61)
+                /* In order to implement the NINT function for a F16.0,*/
+                /*we check if var_32 + 0.5*2**18 is a multiple of 2**18 */
+                var_16 = (WORD16)
+                    ((WORD32) (((WORD32)(var_32 + (1<<17))) / (1<<18)));
+                var_16 = var_16 * 4;
+#else
+                /* In order to implement the NINT function for a F16.0,*/
+                /*we check if var_32 + 0.5*2**19 is a multiple of 2**19 */
+                var_16 = (WORD16)
+                    ((WORD32) (((WORD32)(var_32 + (1<<18))) / (1<<19)));
+                var_16 = var_16 * 8;
+#endif
+
+              #if 0	/* LoCosto code with saturation */
+                if (var_16 > C_max_step)
+                    psi_quant = Add_Sat_sign_16b(psi_quant,C_max_step);
+                else if (var_16 < C_min_step)
+                    psi_quant = Add_Sat_sign_16b(psi_quant,C_min_step);
+                else psi_quant = Add_Sat_sign_16b(psi_quant,var_16); /* F13.3 */
+              #else	/* matching TCS211 */
+                if (var_16 > C_max_step)
+                    psi_quant += C_max_step;
+                else if (var_16 < C_min_step)
+                    psi_quant += C_min_step;
+                else psi_quant += var_16; /* F13.3 */
+              #endif
+
+                /* F0.32 * F13.3 = F5.35    */
+                psi_past[C_N_del]=Mult_40b(l1_config.params.psi_st_32,psi_quant, &guardout);
+                /*  (F13.3<<16 )+(F5.35>>16) = F13.19 */
+                psi_past[C_N_del]=((WORD32)guardout<<16)+((UWORD32)psi_past[C_N_del]>>16);
+
+            }
+            break;
+
+            case AFC_CLOSED_LOOP :
+
+                /* delay line for psi_quant values */
+                for (i = 1; i <= C_N_del; i++)
+                    psi_past[i-1] = psi_past[i];
+
+                /************************************/
+                /*         Estimation               */
+                /************************************/
+                if ( (l1_config.params.rgap_algo != 0) &&
+                     ((l1_mode==CON_EST_MODE2)||(l1_mode==DEDIC_MODE)
+                  #if L1_GPRS
+                      || l1_mode==PACKET_TRANSFER_MODE
+                  #endif
+                  ))
+                {
+
+                    M_Count += *frame_count;
+                    if (snr >= l1_config.params.afc_snr_thr) {
+                        // Accumulate average over N TDMA frames
+                        psi_avg[0] += psi_past[C_N_del];
+                        // Count number of good snr's within window_avg_size chunks
+                        good_snr++;
+            }
+                    // M_Count >= M ?
+                    if (M_Count >= l1_config.params.afc_win_avg_size_M) {
+                        // M_Count counts how far we have reached in the window_avg_size blocks
+
+                        // Scale estimate relative to good snr - Don't divide by zero in case of bad measurements
+                        if (good_snr > 0)
+                            psi_avg[0] /= good_snr;
+
+                        // We now have an estimation over window_avg_size TDMA frames in psi_avg[0]
+                        if (first_avg == 1) {
+                            first_avg = 0;
+                            // Use first estimation as best guess for the other avg values
+                            // This is used both at initialisation and when returning from reception gap
+                            for (i = 1; i <= C_PSI_AVG_SIZE_D ; i++)
+                                psi_avg[i] = psi_avg[0];
+                }
+
+                        // Estimation 1st order
+                        // Use biggest window to reduce noise effects signal in psi values
+                        // NOTE: Due to performance issues division by MSIZE is in predictor
+                        if (l1_config.params.rgap_algo >= 1) {
+                            quant_avg = (WORD16) (psi_avg[0] - psi_avg[C_PSI_AVG_SIZE_D]);
+                        }
+
+                        for (i = C_PSI_AVG_SIZE_D - 1; i >= 0 ; i--)
+                            psi_avg[i+1] = psi_avg[i];
+                        psi_avg[0] = 0;
+                        M_Count = 0;
+                        good_snr = 0;
+                    }
+
+                } else {
+                        // No estmation when in Idle mode (DEEP or BIG SLEEP) => Reset!
+                        first_avg  = 1;
+                        M_Count  = 0;
+                        good_snr   = 0;
+                        psi_avg[0] = 0;
+                }
+
+                if (snr >= l1_config.params.afc_snr_thr) {
+                    /********************/
+                    /* Filter algorithm */
+                    /********************/
+
+                    /* No prediction during normal operation */
+                    B_Count= 0;
+
+                    /* Clip error angle */
+                    if (angle > C_thr_phi)
+                        angle = C_thr_phi;
+                    if (angle < -C_thr_phi)
+                        angle = -C_thr_phi;
+
+                    Phi_32 = psi_past[C_N_del] - psi_past[0];   /* F13.19 */
+                    /* Phi = angle - Phi_32*/
+                    Phi_32 = ((WORD32) angle << 4) - Phi_32;
+                    /* F1.15 * 4 = F13.19 */
+                    #if 0	/* LoCosto code */
+                      Phi = (WORD16)((WORD32)((WORD32)(Phi_32 + (1<<3)))/ (1<<4)); /* F17.15 */
+                    #else	/* TCS211 reconstruction */
+                      Phi = Phi_32 >> 4;
+                    #endif
+                    /* (F0.20 * F1.15) >> 16 = F13.19 */
+                    #if 0	/* LoCosto code with saturation and L */
+                      var_32 = (L * Phi + (1<<15)) >> 16;
+                      psi_past[C_N_del] = Add_Sat_sign_32b(psi_past[C_N_del],var_32);
+                    #else	/* matching TCS211 */
+                      psi_past[C_N_del] += (10433 * Phi) >> 16;
+                    #endif
+
+                }
+                else
+                {
+                    /************************************/
+                    /*         Prediction               */
+                    /************************************/
+
+                    // Only predict in dedicated mode
+                    // NO prediction in idle mode
+                    //   l1a_l1s_com.dedic_set.SignalCode = NULL
+                    if ( (l1_config.params.rgap_algo != 0) &&
+                        ((l1_mode==CON_EST_MODE2)||(l1_mode==DEDIC_MODE)
+                        #if L1_GPRS
+                        || l1_mode==PACKET_TRANSFER_MODE
+                        #endif
+                        ))
+                    {
+                      /* Prediction of psi during reception gaps */
+                      B_Count
+                          += *frame_count;
+
+                        /* Predict psi ONLY when we have sufficient measurements available                   */
+                        /* If we don't have enough measurements we don't do anything (= 0th order estimation)*/
+
+                        // Was the consecutive bad SNRs threshold value exceeded?
+                        if (B_Count>= l1_config.params.rgap_bad_snr_count_B) {
+
+                            // Predict with 0th order estimation is the default
+
+                            // Predict with 1st order estimation
+                            if (l1_config.params.rgap_algo >= 1)
+                            {
+                            #if 0	/* LoCosto code with saturation */
+                                 psi_past[C_N_del] = Add_Sat_sign_32b(psi_past[C_N_del],
+                                     ((quant_avg * (l1_config.params.rgap_bad_snr_count_B))/(C_MSIZE))
+                                     );
+                            #else	/* matching TCS211 */
+                                 psi_past[C_N_del] +=
+                                     ((quant_avg * (l1_config.params.rgap_bad_snr_count_B))/(C_MSIZE));
+                            #endif
+                            }
+
+                            B_Count= B_Count - l1_config.params.rgap_bad_snr_count_B;
+
+                            // Indicate by raising first_avg flag that a reception gap has occurred
+                            // I.e. the psi_avg table must be reinitialised after leaving reception gap
+                            first_avg = 1;
+
+                            // Counters in estimation part must also be reset
+                            M_Count  = 0;
+                            good_snr   = 0;
+                            psi_avg[0] = 0;
+                      }
+                    }
+                }
+
+                /* Quantize psi value */
+
+                /* F0.19 * 16.0 = F16.19 */
+                #if 0	/* LoCosto code */
+                  var_32 = Sat_Mult_20sign_16unsign(psi_past[C_N_del],l1_config.params.psi_st_inv);
+                #else	/* TCS211 reconstruction */
+		  var_32 = psi_past[C_N_del] * l1_config.params.psi_st_inv;
+                #endif
+
+#if(RF_FAM == 61)
+                /* In order to implement the NINT function for a F13.3,*/
+                /*we check if var_32 + 0.5*2**18 is a multiple of 2**18 */
+                var_16 = (WORD16)
+                    ((WORD32)((WORD32)(var_32 + (1<<17))) / (1<<18));
+                var_16 = var_16 * 4;
+#else
+                /* In order to implement the NINT function for a F13.3,*/
+                /*we check if var_32 + 0.5*2**19 is a multiple of 2**19 */
+                var_16 = (WORD16)
+                    ((WORD32)((WORD32)(var_32 + (1<<18))) / (1<<19));
+                var_16 = var_16 * 8;
+#endif
+                if (var_16 > C_max_step)
+                    psi_quant = C_max_step;
+                else if (var_16 < C_min_step)
+                    psi_quant = C_min_step;
+                else
+                    psi_quant = var_16; /* F13.3 */
+         break;
+         } // switch phase
+
+        *frame_count = 0;
+
+        return (psi_quant >> 3); /* F16.0 */
+    } /* end case algo 2 */
+
+    /* algo1 + init + estimator/predictor */
+    case ALGO_AFC_KALMAN_PREDICTOR:
+    {
+      if ((phase==AFC_INIT_CENTER) || (phase==AFC_INIT_MAX) || (phase==AFC_INIT_MIN))
+      {
+        // WARNING
+        // In this case, "angle" variable contains EEPROM_AFC initialization value
+        // directly loaded from EEPROM, and "snr" variable is not meaningful.
+        /* Static variables initialisation */
+
+        quant_avg = 0;
+        M_Count = 0;
+#if 0	/* present in LoCosto but not in TCS211 */
+        for (i = 0; i <=C_PSI_AVG_SIZE_D ; i++)   //omaps00090550
+            psi_avg[i] = 0;
+#endif
+        first_avg = 1;
+        good_snr = 0;
+
+        // DAC search algorithm is as follows - up to 12 attempts are made
+        // DAC search algorithm uses three values : DAC_center -> DAC_max -> DAC_min ->
+        // The first four attempts are made on DAC_center
+        // The next four attempts are made on DAC_max
+        // The last four attempts are made on DAC_min
+        // There are statistical reasons for trying four times
+
+        switch (phase) {
+        case AFC_INIT_CENTER:
+            Psi_quant[C_N_del] = l1_config.params.afc_dac_center;
+            break;
+        case AFC_INIT_MAX:
+            Psi_quant[C_N_del] = l1_config.params.afc_dac_max;
+            break;
+        case AFC_INIT_MIN:
+            Psi_quant[C_N_del] = l1_config.params.afc_dac_min;
+            break;
+        default :
+          break;
+        }
+
+        P=C_cov_start;
+        Psi=0;
+        if (angle>C_max_step)
+           Psi_quant[C_N_del]=C_max_step;
+        else
+           if(angle<C_min_step)
+             Psi_quant[C_N_del]=C_min_step;
+           else Psi_quant[C_N_del]=angle;
+
+               /* F0.32 * F13.3 = F5.35    */
+        Psi=Mult_40b(l1_config.params.psi_st_32,Psi_quant[C_N_del], &guardout);
+        /*  (F13.3<<16 )+(F5.35>>16) = F13.19 */
+        Psi=((WORD32)guardout<<16)+((UWORD32)Psi>>16);
+
+      } /* end AFC_INIT*/
+      else
+      {
+        if (phase==AFC_OPEN_LOOP)
+        {
+          /* relaod last good values in the ALGO */
+          if (l1s.spurious_fb_detected == TRUE)
+          {
+            for(i=0;i<C_N_del+1;i++)
+              Psi_quant[i] = old_Psi_quant[i];
+
+            Psi = old_Psi;
+            l1s.spurious_fb_detected = FALSE;
+          }
+
+          /* Save the old values in memory */
+          for(i=0;i<C_N_del+1;i++)
+            old_Psi_quant[i] = Psi_quant[i];
+          old_Psi = Psi;
+
+          /* delay line for Psi_quant values */
+          for (i=1;i<=C_N_del;i++)
+            Psi_quant[i-1]=Psi_quant[i];
+
+          var_32=(WORD32)((WORD32)angle*l1_config.params.psi_sta_inv)<<4;
+                                 /*(F16.0 * F1.15 = F17.15) << 4 = F13.19 */
+
+#if(RF_FAM == 61)
+          /* In order to implement the NINT function for a F16.0, we check */
+          /* if var_32 + 0.5*2**18 is a multiple of 2**18                  */
+          quotient=(WORD16)((WORD32)(((WORD32)(var_32+(1<<17)))/(1<<18)));
+          var_16=quotient*4;
+#else
+          /* In order to implement the NINT function for a F16.0, we check */
+          /* if var_32 + 0.5*2**19 is a multiple of 2**19                  */
+          quotient=(WORD16)((WORD32)(((WORD32)(var_32+(1<<18)))/(1<<19)));
+          var_16=quotient*8;
+#endif
+
+#if 0	/* LoCosto code with saturation */
+          if (var_16>C_max_step)
+            Psi_quant[C_N_del]=Add_Sat_sign_16b(Psi_quant[C_N_del],C_max_step);
+          else if (var_16<C_min_step)
+            Psi_quant[C_N_del]=Add_Sat_sign_16b(Psi_quant[C_N_del],C_min_step);
+          else Psi_quant[C_N_del]=Add_Sat_sign_16b(Psi_quant[C_N_del],var_16);     /* F13.3                  */
+#else	/* matching TCS211 */
+          if (var_16>C_max_step)
+            Psi_quant[C_N_del] += C_max_step;
+          else if (var_16<C_min_step)
+            Psi_quant[C_N_del] += C_min_step;
+          else Psi_quant[C_N_del] += var_16;     /* F13.3                  */
+#endif
+
+                 /* F0.32 * F13.3 = F5.35    */
+         Psi=Mult_40b(l1_config.params.psi_st_32,Psi_quant[C_N_del], &guardout);
+         /*  (F13.3<<16 )+(F5.35>>16) = F13.19 */
+         Psi=((WORD32)guardout<<16)+((UWORD32)Psi>>16);
+
+       }/*end if AFC_OPEN_LOOP*/
+       else
+       {
+
+         /* delay line for Psi_quant values */
+         for (i=1;i<=C_N_del;i++)
+           Psi_quant[i-1]=Psi_quant[i];
+
+                /************************************/
+                /*         Estimation               */
+                /************************************/
+                if ( (l1_config.params.rgap_algo != 0) &&
+                    ((l1_mode==CON_EST_MODE2)||(l1_mode==DEDIC_MODE)
+                    #if L1_GPRS
+                    || l1_mode==PACKET_TRANSFER_MODE
+                    #endif
+                    ))
+                {
+
+                    M_Count += *frame_count;
+                    if (snr >= l1_config.params.afc_snr_thr) {
+                        // Accumulate average over N TDMA frames
+                        psi_avg[0] += psi_past[C_N_del];
+                        // Count number of good snr's within window_avg_size chunks
+                        good_snr++;
+                    }
+
+                    // M_Count >= M ?
+                    if (M_Count >= l1_config.params.afc_win_avg_size_M) {
+                        // M_Count counts how far we have reached in the window_avg_size blocks
+
+                        // Scale estimate relative to good snr - Don't divide by zero in case of bad measurements
+                        if (good_snr > 0)
+                            psi_avg[0] /= good_snr;
+
+                        // We now have an estimation over window_avg_size TDMA frames in psi_avg[0]
+                        if (first_avg == 1) {
+                            first_avg = 0;
+                            // Use first estimation as best guess for the other avg values
+                            // This is used both at initialisation and when returning from reception gap
+                            for (i = 1; i <= C_PSI_AVG_SIZE_D ; i++)
+                                psi_avg[i] = psi_avg[0];
+                        }
+
+                        // Estimation 1st order
+                        // Use biggest window to reduce noise effects signal in psi values
+                        // NOTE: Due to performance issues division by MSIZE is in predictor
+                        if (l1_config.params.rgap_algo >= 1) {
+                            quant_avg = (WORD16) (psi_avg[0] - psi_avg[C_PSI_AVG_SIZE_D]);
+            }
+
+                        for (i = C_PSI_AVG_SIZE_D - 1; i >= 0 ; i--)
+                            psi_avg[i+1] = psi_avg[i];
+                        psi_avg[0] = 0;
+                        M_Count = 0;
+                        good_snr = 0;
+        }
+
+                } else {
+                        // No estmation when in Idle mode (DEEP or BIG SLEEP) => Reset!
+                        first_avg  = 1;
+                        M_Count  = 0;
+                        good_snr   = 0;
+                        psi_avg[0] = 0;
+                }
+
+         /********************/
+         /* Filter algorithm */
+         /********************/
+
+         /* Covariance error is increased of C_Q */
+         P=P+(*frame_count)*C_Q;
+
+         /* Clipping of P */
+         if (P>C_thr_P) P=C_thr_P;
+
+         if (snr>=C_thr_snr)
+         {
+           /* Clipping of error angle */
+           if (angle>C_thr_phi)
+            angle=C_thr_phi;
+           if (angle<-C_thr_phi)
+            angle=-C_thr_phi;
+
+           /* Kalman gain                             */
+           /*K=P*(1/(P+C_a0_kalman+(C_g_kalman*RNS))) */
+           /*C_a0_kalman=0.01                         */
+           /*C_g_kalman =0.05                         */
+           num=(C_g_kalman/snr)+P+C_a0_kalman;
+                         /* (F2.30 / F6.10) = F 12.20 */
+
+           /* denom = P << 19 = F 1.39                                */
+           /* extension of denom=P to a 40 bits variable              */
+           /* denom (F12.20) << 16 = F 4.36                           */
+           guard1=(WORD16)((WORD32)P>>16);
+           /* denom = P<<16 = (F4.36) << 3 = F 1.39                   */
+           denomH=(UWORD16)P;
+           /* Low part of denom is equal to 0, because P has been 16  */
+           /* bits left shifted previously.                           */
+           denomH_3msb=(denomH>>13)&0x0007;
+           guard1=(guard1<<3)|denomH_3msb;
+           denomH<<=3;
+           denom=denomH<<16;   //(UWORD32) removed typecast omaps00090550
+           /* num + guard1 are a 40 bits representation of P          */
+           /* In order to compute P(F1.39)/num, we sample P in guard1 */
+           /* (scaled to a 32 bits number) and num (32 bits number)   */
+           /* K = ((guard1<<24)/num)<<8 + (denom/num)                 */
+           var1=(WORD32)guard1<<24;
+           var1=var1/num;
+           var1=(WORD32)var1<<8;
+           /* var2 is an unsigned variable, var1 contains signed guard*/
+           /* bits.                                                   */
+           #if 0	/* fixed LoCosto code */
+             var2=  ((WORD32)(denom)/(num));  //omaps00090550
+           #else	/* matching TCS211 */
+             var2=  denom / num;
+           #endif
+           K = (var1+var2)<<1;             /* F1.39 / F12.20 = F13.19 */
+                                           /* F13.19 << 1 = F12.20    */
+
+           /* Clipping of the Kalman gain  */
+           if (K>=C_thr_K)
+             K=C_thr_K;
+
+           /*******************************************************/
+           /* P=(1-K)*P = 0.8 * 0.5 at maximum                    */
+           /*******************************************************/
+           /* Perform a positive variable F12.20 multiplication by*/
+           /* positive variable F12.20                            */
+           var_16=(WORD16)(1048576L-K);   /* acclow(1-K) = F12.20  */
+           guard1=0;                     /* positive variable     */
+           var1=UMult_40b(P,var_16,&guard1);
+           var_16=(WORD16)((1048576L-K)>>16);
+                                         /* acchigh(1-K) = F12.20 */
+           var2=P*var_16;                /* var2 = 0x80000 * 0xc  */
+                                         /* at maximum, so result */
+                                         /* is 32 bits WORD32 and   */
+                                         /* equal 0x600000        */
+           /* extension of var2 to a 40 bits variable : var2<<16  */
+           guard2=(WORD16)((WORD32)var2>>16);
+           guard1guard2=((WORD32)guard1<<16) |((WORD32) guard2&0x0000FFFFL);
+           var2=var2<<16;
+           var_32=Add_40b(guard1guard2,var1,var2,&guardout);
+           /* var_32 (F8.40) >> 16 = F8.24  */
+           LGuard=(WORD32)guardout<<16;
+           var1=(UWORD32)var_32>>16;
+           /* var_32 >> 4 = F12.20          */
+           P=(var1+LGuard)>>4;
+
+           Phi_32=Mult_40b(l1_config.params.psi_st_32,Psi_quant[0],&guardout);
+                                       /* F0.32 * F13.3 = F5.35    */
+           LGuard=(WORD32)guardout<<16;  /* var_32 (F5.35) >> 16     */
+                                       /* F13.19                   */
+           var1=(UWORD32)Phi_32>>16;
+           Phi_32=Psi-(LGuard+var1);   /* F13.19                   */
+
+           /*Phi=angle-Phi_32*/
+           Phi_32=((WORD32)angle<<4)-Phi_32;
+                                        /* F1.15 * 4 = F13.19       */
+           Phi=(WORD16)(Phi_32>>4);      /* F17.15                   */
+           /*var1=K*Phi                    F12.20 * F1.15 = 13.35   */
+           guard1=0;
+           var1=Mult_40b(K,Phi,&guard1);
+                                        /* var1 (F13.35) >> 16      */
+                                        /* F13.19                   */
+           LGuard=(WORD32)guard1<<16;
+           var1=(UWORD32)var1>>16;
+           Psi+=var1+LGuard;
+           } else {
+                /************************************/
+                /*         Prediction               */
+                /************************************/
+
+                // Only predict in dedicated mode
+                // NO prediction in idle mode
+                //   l1a_l1s_com.dedic_set.SignalCode = NULL
+                if ( (l1_config.params.rgap_algo != 0) &&
+                    ((l1_mode==CON_EST_MODE2)||(l1_mode==DEDIC_MODE)
+                    #if L1_GPRS
+                    || l1_mode==PACKET_TRANSFER_MODE
+                    #endif
+                    ))
+                {
+
+                  /* Prediction of psi during reception gaps */
+                  B_Count+= *frame_count;
+
+                    /* Predict psi ONLY when we have sufficient measurements available                   */
+                    /* If we don't have enough measurements we don't do anything (= 0th order estimation)*/
+
+                    // Was the consecutive bad SNRs threshold value exceeded?
+                    if (B_Count>= l1_config.params.rgap_bad_snr_count_B) {
+
+                        // Predict with 0th order estimation is the default
+
+                        // Predict with 1st order estimation
+                        if (l1_config.params.rgap_algo >= 1)
+                            Psi += ((quant_avg * (l1_config.params.rgap_bad_snr_count_B))/(C_MSIZE));
+
+                        B_Count= B_Count - l1_config.params.rgap_bad_snr_count_B;
+
+                        // Indicate by raising first_avg flag that a reception gap has occurred
+                        // I.e. the psi_avg table must be reinitialised after leaving reception gap
+                        first_avg = 1;
+
+                        // Counters in estimation part must also be reset
+                        M_Count  = 0;
+                        good_snr   = 0;
+                        psi_avg[0] = 0;
+                    }
+                }
+           }
+
+           /* Quantize psi value */
+
+           var_32=Mult_40b(Psi,l1_config.params.psi_st_inv,&guardout);
+                                        /* F13.19 * C      = F13.19 */
+
+#if(RF_FAM == 61)
+           /* In order to implement the NINT function for a F13.3, we check */
+           /* if var_32 + 0.5*2**18 is a multiple of 2**18                  */
+           quotient=(WORD16)((WORD32)(((WORD32)(var_32+(1<<17)))/(1<<18)));
+           var_16=quotient*4;
+#else
+           /* In order to implement the NINT function for a F13.3, we check */
+           /* if var_32 + 0.5*2**19 is a multiple of 2**19                  */
+           quotient=(WORD16)((WORD32)(((WORD32)(var_32+(1<<18)))/(1<<19)));
+           var_16=quotient*8;
+#endif
+           if (var_16>C_max_step)
+             Psi_quant[C_N_del]=C_max_step;
+           else
+             if(var_16<C_min_step)
+               Psi_quant[C_N_del]=C_min_step;
+             else Psi_quant[C_N_del]=var_16; /* F13.3                 */
+
+
+       }/*end AFC_CLOSE_LOOP*/
+    } /* end else AFC_INIT*/
+
+       *frame_count = 0;
+       return(Psi_quant[C_N_del]>>3); /* F16.0 */
+    } /* end case algo 3 */
+#endif
+
+#if (VCXO_ALGO == 1)
+    default:
+      return 0;
+//omaps00090550      break;
+  } // end of Switch
+  #endif
+
+} /* end l1ctl_afc */
+
+
+/************************************/
+/* Automatic timing control (TOA)   */
+/************************************/
+
+#if (TOA_ALGO == 2)
+
+#define TOA_DEBUG_ENABLE 0
+
+
+#if (TOA_DEBUG_ENABLE == 1)
+
+  #define TOA_MAKE_ZERO    0
+
+  #define  TOA_LOG_BUFFER_LENGTH  4096
+
+  typedef struct
+  {
+    UWORD16 SNR_val;
+    UWORD16 TOA_val;
+    UWORD16 l1_mode;
+    UWORD16 toa_frames_counter;
+    UWORD16 fn_mod42432;
+  }T_TOA_log_debug;
+
+
+  T_TOA_log_debug  toa_log_debug[TOA_LOG_BUFFER_LENGTH];
+  UWORD32          toa_log_index;
+
+  UWORD32          toa_make_zero_f;
+
+#endif
+
+/*-------------------------------------------------------*/
+/* l1ctl_toa()                                           */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+
+WORD16 l1ctl_toa (UWORD8 phase, UWORD32 l1_mode, UWORD16 SNR_val, UWORD16 TOA_val)
+{
+  WORD16     TOA_period_len = TOA_PERIOD_LEN [l1_mode];
+  WORD16     TOA_SHIFT=ISH_INVALID;
+  UWORD16    cumul_abs;
+  WORD16     cumul_sign;
+  WORD32     prod_tmp, div_tmp,prod_sign;
+  WORD32     toa_update_flag=0;
+  WORD16     cumul;
+  UWORD16    cumul_counter;
+#if (NEW_TOA_ALGO == 1)
+UWORD16	 Trans_active;
+  static WORD16            cumul_noTrans =0;
+  static UWORD16           period_counter_noTrans =0;
+
+  if ((l1_mode==CON_EST_MODE2)||(l1_mode==DEDIC_MODE)
+#if L1_GPRS
+    || l1_mode==PACKET_TRANSFER_MODE
+#endif
+    )
+    Trans_active=TRUE;
+  else Trans_active=FALSE;
+#endif
+  if (phase==TOA_INIT)
+  {
+#if (NEW_TOA_ALGO == 1)
+ cumul_noTrans =0;
+ period_counter_noTrans =0;
+#endif
+
+     l1s.toa_var.toa_frames_counter=0;
+     l1s.toa_var.toa_accumul_counter=0;
+     l1s.toa_var.toa_accumul_value=0;
+     #if (TOA_DEBUG_ENABLE == 1)
+       toa_log_index = 0;
+       #if (TOA_MAKE_ZERO == 1)
+          toa_make_zero_f = 1;
+       #else
+          toa_make_zero_f = 0;
+       #endif
+     #endif
+
+     return (TOA_SHIFT);
+  }
+
+   cumul         = l1s.toa_var.toa_accumul_value;
+   cumul_counter = l1s.toa_var.toa_accumul_counter;
+
+   #if (TOA_DEBUG_ENABLE == 1)
+     toa_log_debug[toa_log_index].SNR_val = SNR_val;
+     toa_log_debug[toa_log_index].TOA_val = TOA_val;
+     toa_log_debug[toa_log_index].l1_mode = l1_mode;
+     toa_log_debug[toa_log_index].toa_frames_counter = l1s.toa_var.toa_frames_counter;
+     toa_log_debug[toa_log_index].fn_mod42432 = l1s.actual_time.fn_mod42432;
+
+     toa_log_index++;
+     if(toa_log_index == TOA_LOG_BUFFER_LENGTH)
+     {
+       toa_log_index = 0;
+     }
+   #endif /* #if (TOA_DEBUG_ENABLE == 1) */
+
+   #if (TRACE_TYPE == 5)
+     trace_toa_sim_ctrl(SNR_val, TOA_val, l1_mode, l1s.toa_var.toa_frames_counter,
+                        l1s.toa_var.toa_accumul_counter, l1s.toa_var.toa_accumul_value);
+   #endif
+
+   l1s.toa_var.toa_frames_counter++;
+
+ {
+    /* Fix for TOA */
+      #define DSP_CALC_NO_TABS_HO  0x3CA4
+
+    UWORD16 *toa_ho_fix;
+    toa_ho_fix=(UWORD16 *)API_address_dsp2mcu(DSP_CALC_NO_TABS_HO);
+
+    if ((TOA_val >= 22) || (TOA_val <= 6)) {
+      *toa_ho_fix = 1;
+     }
+
+    if (*toa_ho_fix == 1) {
+ 	 if((TOA_val <= 18) && (TOA_val >= 10)) {
+ 	   *toa_ho_fix = 0;
+	  }
+	 } else {
+	  *toa_ho_fix = 0;
+	 }
+ }
+
+
+#if (NEW_TOA_ALGO == 1)
+ if (Trans_active)
+{
+#endif
+   if (SNR_val>= L1_TOA_SNR_THRESHOLD)
+   {
+     cumul_counter++;
+
+     prod_tmp = L1_TOA_LAMBDA * cumul;
+     prod_tmp = prod_tmp + ((0x00004000)); // basically for rounding
+     div_tmp = ((prod_tmp >> 15) & (0x0000FFFF));
+     cumul = div_tmp;
+
+     //  implemented below is
+     //  cumul = cumul + (L1_TOA_ONE_MINUS_LAMBDA * signum(TOA_Val - L1_TOA_EXPECTED_TOA))
+     if(TOA_val > L1_TOA_EXPECTED_TOA) {
+       cumul = cumul + L1_TOA_ONE_MINUS_LAMBDA;
+     }
+     else if (TOA_val < L1_TOA_EXPECTED_TOA) {
+       cumul = cumul - L1_TOA_ONE_MINUS_LAMBDA;
+     }
+   } // End if SNR_val
+
+   if(l1s.toa_var.toa_update_flag == TRUE)
+   {
+     toa_update_flag = 1;
+   }
+
+   if (toa_update_flag)
+   {
+     cumul_sign = (cumul>0)? 1: -1;
+     cumul_abs = cumul_sign*cumul;
+     if(cumul_counter <= 5)
+     {
+       TOA_SHIFT = (cumul_abs<=L1_TOA_THRESHOLD_15)? 0: cumul_sign;
+     }
+     else if(cumul_counter == 6)
+     {
+       TOA_SHIFT = (cumul_abs<=L1_TOA_THRESHOLD_20)? 0: cumul_sign;
+     }
+     else if(cumul_counter == 7)
+     {
+       TOA_SHIFT = (cumul_abs<=L1_TOA_THRESHOLD_25)? 0: cumul_sign;
+     }
+     else if(cumul_counter >= 8)
+     {
+       TOA_SHIFT = (cumul_abs<=L1_TOA_THRESHOLD_30)? 0: cumul_sign;
+     }
+     #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+       trace_info.toa_trace_var.toa_accumul_value     = cumul;
+       trace_info.toa_trace_var.toa_accumul_counter   = cumul_counter;
+       trace_info.toa_trace_var.toa_frames_counter    = l1s.toa_var.toa_frames_counter;
+     #endif
+
+     cumul = 0;
+     cumul_counter = 0;
+     l1s.toa_var.toa_frames_counter = 0;
+     l1s.toa_var.toa_update_flag    = FALSE;
+
+     #if (TOA_DEBUG_ENABLE == 1)
+       #if (TOA_MAKE_ZERO == 1)
+         if (toa_make_zero_f == 1)
+         {
+           TOA_SHIFT=0;
+         }
+       #endif /*#if (TOA_DEBUG_ENABLE == 1)*/
+     #endif /*#if (TOA_MAKE_ZERO == 1)*/
+
+   } // end of if toa_update_flag
+ #if (NEW_TOA_ALGO == 1)
+
+}
+
+else
+{
+	period_counter_noTrans++;
+
+	if (SNR_val>= L1_TOA_SNR_THRESHOLD)
+   {
+     cumul_noTrans = cumul_noTrans + TOA_val - L1_TOA_EXPECTED_TOA;
+
+   } // End if SNR_val
+
+   if (l1s.toa_var.toa_update_flag == TRUE)
+   {
+      switch (period_counter_noTrans)
+      {
+        case 2:
+          if (cumul_noTrans>=0)
+            TOA_SHIFT = (cumul_noTrans+1) >>1 ;
+          else
+            TOA_SHIFT = (cumul_noTrans) >>1 ;
+          break;
+        case 3: /* Not fully accurate rounding*/
+          if (cumul_noTrans>=0)
+            TOA_SHIFT = (cumul_noTrans+2)/3 ;
+          else
+            TOA_SHIFT = (cumul_noTrans-2)/3 ;
+          break;
+       case 4:
+          if (cumul_noTrans>=0)
+            TOA_SHIFT = (cumul_noTrans+2) >>2 ;
+          else
+            TOA_SHIFT = (cumul_noTrans+1) >>2 ;
+          break;
+       default:
+          TOA_SHIFT = cumul_noTrans;
+          break;
+    } /* end switch*/
+
+		if (TOA_SHIFT>8)
+				TOA_SHIFT =8;
+		if (TOA_SHIFT<-8)
+				TOA_SHIFT =-8;
+
+	#if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+       trace_info.toa_trace_var.toa_accumul_value     = cumul_noTrans;
+       trace_info.toa_trace_var.toa_accumul_counter   = period_counter_noTrans;
+       trace_info.toa_trace_var.toa_frames_counter    = period_counter_noTrans;
+  #endif
+
+     cumul_noTrans = 0;
+     period_counter_noTrans = 0;
+     l1s.toa_var.toa_update_flag = FALSE;
+     #if (TOA_DEBUG_ENABLE == 1)
+       #if (TOA_MAKE_ZERO == 1)
+         if (toa_make_zero_f == 1)
+         {
+           TOA_SHIFT=0;
+         }
+       #endif /*#if (TOA_DEBUG_ENABLE == 1)*/
+     #endif /*#if (TOA_MAKE_ZERO == 1)*/
+
+   } // end if update_flag
+}
+#endif
+   // error a TOA is waiting to be updated in the TPU and will be erased
+   #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+   if (l1s.toa_var.toa_shift != ISH_INVALID)
+   {
+     l1_trace_toa_not_updated (); // should not occur!!
+   }
+  #endif
+
+  if (TOA_SHIFT != ISH_INVALID) // new TOA => set the mask frames
+  {
+    // Set mask counter to 2 (2 frames masked).
+    l1s.toa_var.toa_snr_mask = 2;
+  }
+
+  l1s.toa_var.toa_accumul_value     = cumul;
+  l1s.toa_var.toa_accumul_counter   = cumul_counter;
+
+  return(TOA_SHIFT);
+
+} // l1ctl_toa
+
+
+#else
+/*-------------------------------------------------------*/
+/* l1ctl_toa_update()                                    */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+WORD16 l1ctl_toa_update(UWORD32 *TOASP, UWORD32 l1_mode)
+{
+  static UWORD16  Old_TOA_estimated=12; //unit is Qbit
+  UWORD32  TOAMAX;
+  WORD16   IZW,ISH,i;
+  UWORD32  TOA_estimated=0;      //unit is Qbit
+  UWORD16  Trans_active;
+
+  if ((l1_mode==CON_EST_MODE2)||(l1_mode==DEDIC_MODE)
+#if L1_GPRS
+    || l1_mode==PACKET_TRANSFER_MODE
+#endif
+    )
+    Trans_active=TRUE;
+  else Trans_active=FALSE;
+
+  /* TOA offset computation and clock adjustement */
+  TOAMAX=0;
+  for (i=1;i<TOA_HISTO_LEN;i++)
+  {
+    if (TOASP[i]>TOAMAX)
+      TOAMAX=TOASP[i];
+  }
+  TOAMAX >>= C_RED;
+  i=1;IZW=0;
+  while (i<TOA_HISTO_LEN && IZW==0)
+  {
+    if (TOASP[i]>=TOAMAX)
+      IZW=i;
+    i++;
+  }
+
+  /* Estimated TOA calculation */
+  if (TOASP[IZW-1]<(2*TOAMAX/3))
+  {
+    TOA_estimated=IZW;
+    TOA_estimated *= 4; // unit in QBit
+  }
+  else
+  {
+#if 0	/* fix added in LoCosto, not present in TCS211 */
+    UWORD32 TOA_divisor;
+#endif
+    TOA_estimated=(TOASP[IZW]*IZW)+(TOASP[IZW-1]*(IZW-1)>>C_GEW);
+    TOA_estimated *= 8; //F13.3 in order to have qBit precision
+#if 0
+    TOA_divisor = TOASP[IZW]+(TOASP[IZW-1] >> C_GEW);
+    if (TOA_divisor!=0)
+#endif
+    {
+      TOA_estimated /= TOASP[IZW]+(TOASP[IZW-1] >> C_GEW);
+      TOA_estimated /= 2; // unit in QBit ("/8" then "*4" = "/2")
+    }
+#if 0
+    else
+    {
+      TOA_estimated = 0;
+    }
+#endif
+  }
+
+  if (Trans_active)
+    TOA_estimated=(TOA_estimated+(Old_TOA_estimated+4)) / 2;
+
+  /* Offset calculation*/
+  if (TOA_estimated>=17 || TOA_estimated<=15)
+    ISH=TOA_estimated - 16;
+  else
+    ISH=0;
+
+  if (Trans_active)
+  {
+    if (ISH>1) ISH=1;
+    if (ISH<-1) ISH=-1;
+  }
+  else
+  {
+    if (ISH>8) ISH=8;
+    if (ISH<-8) ISH=-8;
+  }
+
+  Old_TOA_estimated = TOA_estimated - ISH  - 4;
+
+
+  return (ISH);
+}
+
+/*-------------------------------------------------------*/
+/* l1ctl_toa()                                           */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality : generate an histogram of TOA weighted */
+/*                 with SNR                              */
+/*-------------------------------------------------------*/
+WORD16 l1ctl_toa(UWORD8 phase, UWORD32 l1_mode, UWORD16 SNR_val, UWORD16 TOA_val, BOOL *toa_update, UWORD16 *toa_period_count
+#if (FF_L1_FAST_DECODING == 1)
+    , UWORD8 skipped_values
+#endif
+    )
+{
+//         xSignalHeaderRec *msg;
+         UWORD16           i;
+         WORD16            TOA_period_len = TOA_PERIOD_LEN[l1_mode];
+  static UWORD32           histo[TOA_HISTO_LEN];
+  static WORD16            period_counter=0;
+         UWORD32           SNR_ZW;
+         WORD16            ISH=ISH_INVALID;
+
+  UWORD8 histo_center;
+
+#if 0
+  if ((l1_mode==CON_EST_MODE2)||(l1_mode==DEDIC_MODE))
+    histo_center=4;
+  else
+    histo_center=5;
+#else
+  histo_center=4;
+#endif
+
+
+  if (phase==TOA_INIT)
+  {
+     period_counter=0;
+
+     for (i=0;i<TOA_HISTO_LEN;i++)
+       histo[i]=0;
+     histo[histo_center]=128;  //F6.10
+
+     return(ISH);
+  }
+#if (FF_L1_FAST_DECODING == 1)
+  /* Manage any missing bursts due to fast decoding */
+  period_counter += skipped_values;
+#endif
+
+  period_counter++;
+  /* Filter update */
+  if (SNR_val>=C_SNRGR)
+  {
+     if (SNR_val>C_SNR_THR)
+      SNR_ZW=C_SNR_THR;
+     else
+      SNR_ZW=SNR_val;
+     histo[TOA_val+1]+=SNR_ZW; /* if TOA=0 histo[1]++                  */
+                               /* if TOA=1 histo[2]++                  */
+                               /* ...                                  */
+                               /* if TOA=9 histo[10]++                 */
+                               /* histo[0] is reserved for computation */
+  }
+
+  #if L1_GPRS
+    if (l1_mode==PACKET_TRANSFER_MODE)
+    {
+      if (*toa_update)
+      {
+        // Get ISH.
+        ISH = l1ctl_toa_update(histo, l1_mode);
+
+        //reset TOA period length counter
+        period_counter=0;
+
+        //reset histogram
+        for (i=0;i<TOA_HISTO_LEN;i++)
+          histo[i]=0;
+        histo[histo_center]=128;  //F6.10
+
+        *toa_update       = FALSE;  // reset TOA update flag
+        *toa_period_count = 0;      // reset TOA period counter
+      }
+    }
+    else
+  #endif
+  if (period_counter>=TOA_period_len)
+  // It is time to compute a new ISH and to reset the histogram.
+  // Rem: ">=" is very important since a "l1 mode" change can give
+  //      a "TOA_period_len" smaller than the previous one an
+  //      therefore a "period_counter" may be already higher than
+  //      the new "TOA_period_len".
+  {
+     // Get ISH.
+     ISH = l1ctl_toa_update(histo, l1_mode);
+
+     //reset TOA period length counter
+     period_counter=0;
+
+     //reset histogram
+     for (i=0;i<TOA_HISTO_LEN;i++)
+         histo[i]=0;
+     histo[histo_center]=128;  //F6.10
+  }
+
+  // error a TOA is waiting to be updated in the TPU and will be erased
+  #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+    if (l1s.toa_shift != ISH_INVALID)
+    {
+      l1_trace_toa_not_updated(); // should not occur !!
+    }
+  #endif
+
+  if (ISH != ISH_INVALID) // new TOA => set the mask frames
+  {
+     // Set mask counter to 2 (2 frames masked).
+      l1s.toa_snr_mask = 2;
+  }
+
+  return(ISH);
+}
+#endif
+
+/*-------------------------------------------------------*/
+/* l1ctl_txpwr()                                         */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+UWORD8 l1ctl_txpwr(UWORD8 target_txpwr, UWORD8 current_txpwr)
+{
+  if(target_txpwr > current_txpwr)
+  {
+    current_txpwr ++;   // Increase TX power by 2 dB.
+  }
+  else
+  if(target_txpwr < current_txpwr)
+  {
+    current_txpwr --;   // Decrease TX power by 2 dB.
+  }
+
+  return(current_txpwr);
+}
+
+
+/************************************/
+/* Automatic Gain Control           */
+/************************************/
+/*-------------------------------------------------------*/
+/* l1ctl_encode_delta1()                                 */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+#if(L1_FF_MULTIBAND == 0)
+WORD8 l1ctl_encode_delta1(UWORD16 radio_freq)
+{
+  WORD8 freq_band;
+
+  switch(l1_config.std.id)
+  {
+    case GSM:
+    case GSM_E:
+    case DCS1800:
+    case PCS1900:
+    case GSM850:
+      freq_band = l1_config.std.cal_freq1_band1;
+      break;
+    case DUAL:
+    case DUALEXT:
+    case DUAL_US:
+      if(radio_freq >= l1_config.std.first_radio_freq_band2)
+        freq_band = l1_config.std.cal_freq1_band2;
+      else
+        freq_band = l1_config.std.cal_freq1_band1;
+      break;
+  }
+  return(freq_band);
+}
+#endif
+/*-------------------------------------------------------*/
+/* l1ctl_encode_lna()                                    */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+#if (L1_FF_MULTIBAND == 0)
+void l1ctl_encode_lna( UWORD8   input_level,
+                       UWORD8  *lna_state,
+                       UWORD16  radio_freq)
+{
+
+  /*** LNA Hysteresis is implemented as following :
+
+            |
+          On|---<>----+-------+
+            |         |       |
+   LNA      |         |       |
+            |         ^       v
+            |         |       |
+            |         |       |
+         Off|         +-------+----<>-----
+            +--------------------------------
+              50      40      30      20   input_level /-dBm
+                   THR_HIGH THR_LOW                          ***/
+
+
+
+
+
+  if(((l1_config.std.id == DUAL) || (l1_config.std.id == DUALEXT) ||(l1_config.std.id == DUAL_US)) &&
+     (radio_freq >= l1_config.std.first_radio_freq_band2))
+  {
+    if      ( input_level > l1_config.std.lna_switch_thr_high_band2  )  // < -40dBm ?
+    {
+       *lna_state =  LNA_ON;  // lna_off = FALSE
+    }
+    else if ( input_level < l1_config.std.lna_switch_thr_low_band2   )   // > -30dBm ?
+    {
+       *lna_state =  LNA_OFF; // lna off = TRUE
+    }
+  }
+  else
+  {
+    if      ( input_level > l1_config.std.lna_switch_thr_high_band1  )  // < -40dBm ?
+    {
+       *lna_state =  LNA_ON;  // lna_off = FALSE
+    }
+    else if ( input_level < l1_config.std.lna_switch_thr_low_band1   )   // > -30dBm ?
+    {
+       *lna_state =  LNA_OFF; // lna off = TRUE
+    }
+  }
+    
+}
+
+#endif
+
+/*-------------------------------------------------------*/
+/* l1ctl_csgc()                                          */
+/*-------------------------------------------------------*/
+/* Description:                                          */
+/* ============                                          */
+/* If we are running the first pass of a measurement     */
+/* session, we use the HIGH_AGC default agc setting to   */
+/* compute the input level from the measured power from  */
+/* the DSP. If this input level is saturated we set a    */
+/* saturation flag, otherwise we validate the measure and*/
+/* store, for the considered carrier, the input level.   */
+/* When all the carriers have been scanned and some have */
+/* been flagged "saturated", we measure them with the    */
+/* LOW_AGC agc setting, then store, for the considered   */
+/* carrier, the input level.                             */
+/*-------------------------------------------------------*/
+UWORD8 l1ctl_csgc(UWORD8 pm, UWORD16 radio_freq)
+{
+   WORD16   current_IL, current_calibrated_IL;
+   WORD8    delta1_freq, delta2_freq;
+   WORD16   delta_drp_gain=0;
+   UWORD32  index;
+   UWORD16  g_magic;
+   #if (RF_FAM == 61) && (L1_FF_MULTIBAND == 0)
+     UWORD16  arfcn;
+   #endif 
+   UWORD16 dco_algo_ctl_pw_temp = 0;
+   UWORD8 if_ctl = 0;
+   #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+     UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+   #endif
+
+#if (L1_FF_MULTIBAND == 0)
+
+   // initialize index
+   index = radio_freq - l1_config.std.radio_freq_index_offset;
+
+#else
+
+   index = 
+    l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
+
+#endif /*if(L1_FF_MULTIBAND == 0)*/
+
+   delta1_freq = l1ctl_encode_delta1(radio_freq);
+   delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+   g_magic = l1ctl_get_g_magic(radio_freq);
+
+#if (RF_FAM == 61) && (L1_FF_MULTIBAND == 0)
+   arfcn = Convert_l1_radio_freq(radio_freq);
+#endif 
+
+   if (l1a_l1s_com.full_list.meas_1st_pass_read)
+   {
+     // We validate or not power measure (pm) for the considered carrier
+     // with measurement achieved with HIGH_AGC setting. We are working
+     // with non calibrated IL to avoid saturation
+#if(RF_FAM == 61)
+   #if (CODE_VERSION != SIMULATION)
+
+     #if (PWMEAS_IF_MODE_FORCE == 0)
+       cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_INVALID ,
+           0,
+           radio_freq,if_threshold);
+     #else
+       if_ctl = IF_120KHZ_DSP;
+       dco_algo_ctl_pw_temp = DCO_IF_0KHZ;
+     #endif
+
+     #if (L1_FF_MULTIBAND == 0)
+       delta_drp_gain = drp_gain_correction(arfcn, LNA_ON, (l1_config.params.high_agc << 1));    // F7.1 format
+     #else
+       delta_drp_gain = drp_gain_correction(radio_freq, LNA_ON, (l1_config.params.high_agc << 1));    // F7.1 format
+     #endif // MULTIBAND == 0 else
+
+     if(if_ctl == IF_100KHZ_DSP){
+       delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
+     }
+     else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
+       delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
+     }
+
+   #endif
+#endif
+     if (0==pm)  // Check and filter illegal pm value by using last valid IL
+       current_IL = (WORD16)(l1a_l1s_com.last_input_level[index].input_level);
+     else
+     {
+#if TESTMODE
+       if (!l1_config.agc_enable)
+         current_IL = (WORD16)(-(pm - ( (l1_config.tmode.rx_params.agc << 1) - delta_drp_gain )  - g_magic));
+       else
+#endif
+         current_IL = (WORD16)(-(pm - ( (l1_config.params.high_agc <<1) - delta_drp_gain) - g_magic));
+                 // for array index purpose, we work with positive IL
+
+     }
+
+     // NOTE: lna_value do not appear in this formula because lna is ALWAYS ON for
+     // ----  this algorithm, so lna_value=lna_off*l1_config.params.lna_att_gsm=0
+
+     if ((current_IL<l1_config.params.high_agc_sat_thr)  // Warning : we are working with positive IL
+                                                         // for IL_2_AGC_xx index purpose.
+     #if TESTMODE
+         && (l1_config.agc_enable)
+     #endif
+        )
+     {
+       // pm is saturated so measure is not valid
+       l1a_l1s_com.full_list.nbr_sat_carrier_ctrl++;
+       l1a_l1s_com.full_list.nbr_sat_carrier_read++;
+       l1a_l1s_com.full_list.sat_flag[l1a_l1s_com.full_list.next_to_read] = 1;
+     }
+     else
+     {
+       current_calibrated_IL = current_IL - delta1_freq - delta2_freq;
+
+       #if TESTMODE
+         // When running with fixed AGC setting saturated carriers may occur:
+         // protect against negative IL;
+         if ((!l1_config.agc_enable) && (current_calibrated_IL < 0))
+         {
+           current_calibrated_IL=0;
+           current_IL=0;
+         }
+       #endif
+
+       // Protect IL stores against overflow
+       if (current_calibrated_IL>INDEX_MAX)
+         current_calibrated_IL=INDEX_MAX;
+       if (current_IL>INDEX_MAX)
+         current_IL=INDEX_MAX;
+
+       // we validate the measure and save input_level and lna_off fields.
+       l1ctl_encode_lna((UWORD8)(current_calibrated_IL>>1),
+                        &(l1a_l1s_com.last_input_level[index].lna_off),
+                        radio_freq);
+
+       l1a_l1s_com.last_input_level[index].input_level = (UWORD8)current_IL +
+	 l1ctl_get_lna_att(radio_freq) *
+	   l1a_l1s_com.last_input_level[index].lna_off;
+
+       l1a_l1s_com.full_list.sat_flag[l1a_l1s_com.full_list.next_to_read] = 0;
+     }
+   }
+   else // 2nd pass if any.
+   {
+     // we validate the measure and save input_level and lna_off(always 0)
+     // fields.
+     #if(RF_FAM == 61)
+       #if (CODE_VERSION != SIMULATION)
+        cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_INVALID,
+            0,radio_freq,if_threshold);
+        #if (L1_FF_MULTIBAND == 0)       
+          delta_drp_gain = drp_gain_correction(arfcn, LNA_ON, (l1_config.params.low_agc << 1));    // F7.1 format
+        #else
+          delta_drp_gain = drp_gain_correction(radio_freq, LNA_ON, (l1_config.params.low_agc << 1));    // F7.1 format
+        #endif 
+        if(if_ctl == IF_100KHZ_DSP){
+          delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
+        }
+        else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
+          delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
+        }
+       #endif
+     #endif
+
+
+     if (0==pm)  // Check and filter illegal pm value by using last valid IL
+       current_IL = (WORD16)(l1a_l1s_com.last_input_level[index].input_level);
+     else
+       current_IL = (WORD16)(-(pm - ( (l1_config.params.low_agc << 1) - delta_drp_gain ) - g_magic));
+
+     current_calibrated_IL = current_IL - delta1_freq - delta2_freq;
+
+     // Protect IL stores against overflow
+     if (current_calibrated_IL>INDEX_MAX)
+       current_calibrated_IL=INDEX_MAX;
+     if (current_IL>INDEX_MAX)
+       current_IL=INDEX_MAX;
+
+     l1ctl_encode_lna((UWORD8)(current_calibrated_IL>>1),
+                      &(l1a_l1s_com.last_input_level[index].lna_off),
+                      radio_freq);
+
+     l1a_l1s_com.last_input_level[index].input_level = (UWORD8)current_IL +
+	l1ctl_get_lna_att(radio_freq) *
+	  l1a_l1s_com.last_input_level[index].lna_off;
+
+     l1a_l1s_com.full_list.sat_flag[l1a_l1s_com.full_list.next_to_read] = 0;
+   }
+
+   return((UWORD8)current_calibrated_IL);
+}
+
+/*-------------------------------------------------------*/
+/* l1ctl_pgc()                                           */
+/*-------------------------------------------------------*/
+/* Description : For a given radio_freq, last_known_agc is    */
+/* ============  based on a prior knowledge (the last    */
+/*               stored input_level for the considered   */
+/*               carrier). From the power measurement on */
+/*               this carrier (pm), we update the        */
+/*               input_level for this carrier, for the   */
+/*               next task to control.                   */
+/*-------------------------------------------------------*/
+UWORD8 l1ctl_pgc(UWORD8 pm, UWORD8 last_known_il,
+                 UWORD8 lna_off, UWORD16 radio_freq)
+{
+   WORD32  last_known_agc;
+   WORD32  current_IL, current_calibrated_IL;
+   WORD8   delta1_freq, delta2_freq;
+   WORD16  delta_drp_gain=0;
+   WORD32  index, lna_value;
+   #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+     UWORD16 arfcn;
+   #endif
+   UWORD16 dco_algo_ctl_pw_temp = 0;
+   UWORD8 if_ctl = 0;
+   #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+     UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+   #endif
+
+#if (L1_FF_MULTIBAND == 0)
+
+   // initialize index
+   index = radio_freq - l1_config.std.radio_freq_index_offset;
+
+#else
+
+   index = l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
+
+#endif // #if (L1_FF_MULTIBAND == 0) else
+
+   delta1_freq = l1ctl_encode_delta1(radio_freq);
+   delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+   lna_value = lna_off * l1ctl_get_lna_att(radio_freq);
+
+   last_known_agc = (Cust_get_agc_from_IL(radio_freq, last_known_il >> 1, PWR_ID)) << 1;
+   // F7.1 in order to be compatible with
+   // pm and IL formats [-20,+140 in F7.1]
+   // contain the input_level value we use
+   // in the associated CTL task to build
+   // the agc used in this CTL.
+
+#if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+#if (L1_FF_MULTIBAND == 0)
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn = radio_freq;
+#endif
+#endif
+
+#if(RF_FAM == 61)
+   #if (CODE_VERSION != SIMULATION)
+
+     #if (PWMEAS_IF_MODE_FORCE == 0)
+    cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
+                                         last_known_il,
+                                         radio_freq,if_threshold);
+     #else
+       if_ctl = IF_120KHZ_DSP;
+       dco_algo_ctl_pw_temp = DCO_IF_0KHZ;
+     #endif
+
+     delta_drp_gain = drp_gain_correction(arfcn, lna_off, last_known_agc);     // F7.1 format
+     if(if_ctl == IF_100KHZ_DSP){
+       delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
+     }
+     else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
+       delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
+     }
+
+   #endif
+#endif
+
+   if (0==pm)  // Check and filter illegal pm value by using last valid IL
+     current_IL = l1a_l1s_com.last_input_level[index].input_level - lna_value;
+   else
+     current_IL = -(pm - (last_known_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
+
+   current_calibrated_IL = current_IL - delta1_freq - delta2_freq;
+
+   // Protect IL stores against overflow
+   if (current_calibrated_IL>INDEX_MAX)
+     current_calibrated_IL=INDEX_MAX;
+   if (current_IL>INDEX_MAX)
+     current_IL=INDEX_MAX;
+
+   // we validate the measure and save input_level and lna_off fields
+   l1ctl_encode_lna((UWORD8)(current_calibrated_IL>>1),
+                    &(l1a_l1s_com.last_input_level[index].lna_off),
+                    radio_freq);
+
+   l1a_l1s_com.last_input_level[index].input_level = (UWORD8)current_IL +
+      l1ctl_get_lna_att(radio_freq) *
+	l1a_l1s_com.last_input_level[index].lna_off;
+
+   return((UWORD8)current_calibrated_IL);
+}
+
+
+/*-------------------------------------------------------*/
+/* l1ctl_pgc2()                                          */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* =============                                         */
+/* from power measurement pm_high_agc,                   */
+/* achieve with an HIGH_AGC setting, and pm_low_agc      */
+/* achieve with a LOW_AGC seeting, we deduce the new     */
+/* AGC to apply in the next CTL task.                    */
+/*-------------------------------------------------------*/
+void l1ctl_pgc2(UWORD8 pm_high_agc, UWORD8 pm_low_agc, UWORD16 radio_freq)
+{
+   UWORD8   pm;
+   WORD32   IL_high_agc, IL_low_agc, new_IL, current_calibrated_IL;
+   WORD8    delta1_freq, delta2_freq;
+   WORD16   delta_high_drp_gain=0;
+   WORD16   delta_low_drp_gain=0;
+   WORD32   index;
+   UWORD16  g_magic;
+   #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+     UWORD16  arfcn;
+   #endif
+   UWORD16 dco_algo_ctl_pw_temp = 0;
+   UWORD8 if_ctl = 0;
+   #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+     UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+   #endif
+
+#if (L1_FF_MULTIBAND == 0)
+
+   // initialize index
+   index = radio_freq - l1_config.std.radio_freq_index_offset;
+
+#else
+
+   index = 
+    l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
+
+#endif // #if (L1_FF_MULTIBAND == 0) else
+
+   delta1_freq = l1ctl_encode_delta1(radio_freq);
+   delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+   g_magic = l1ctl_get_g_magic(radio_freq);
+
+   // lna_off was set to 0 during CTRL, so lna_value = 0 do not appear in the following
+   // formula.
+
+#if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+#if (L1_FF_MULTIBAND == 0)
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn = radio_freq;
+#endif
+#endif
+
+   if ((0==pm_high_agc) || (0==pm_low_agc))  // Check and filter illegal pm value(s) by using last valid IL
+     new_IL      = l1a_l1s_com.last_input_level[index].input_level;
+   else
+   {
+
+#if(RF_FAM == 61)
+   #if (CODE_VERSION != SIMULATION)
+
+#if (PWMEAS_IF_MODE_FORCE == 0)
+       cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_INVALID ,
+           0,
+           radio_freq,if_threshold);
+     #else
+       if_ctl = IF_120KHZ_DSP;
+       dco_algo_ctl_pw_temp = DCO_IF_0KHZ;
+     #endif
+
+
+	 delta_high_drp_gain = drp_gain_correction(arfcn, LNA_ON, (l1_config.params.high_agc << 1));    // F7.1 format
+     delta_low_drp_gain  = drp_gain_correction(arfcn, LNA_ON, (l1_config.params.low_agc << 1));     // F7.1 format
+     if(if_ctl == IF_100KHZ_DSP){
+       delta_high_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
+       delta_low_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
+     }
+     else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
+       delta_high_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
+       delta_low_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
+     }
+   #endif
+#endif
+
+     IL_high_agc =  -(pm_high_agc - ((l1_config.params.high_agc << 1) - delta_high_drp_gain) - g_magic);
+     IL_low_agc  =  -(pm_low_agc  - ((l1_config.params.low_agc << 1) - delta_low_drp_gain) - g_magic);
+
+     // HIGH_AGC and LOW_AGC are formatted to F7.1 in order to be compatible with
+     // pm and IL formats
+
+     if (IL_low_agc>=l1_config.params.low_agc_noise_thr)
+     // pm_low_agc was on the noise floor, so not valid
+     {
+       // whatever the value of pm_high_agc, we consider it
+       // as the right setting
+       new_IL = IL_high_agc;
+       pm     = pm_high_agc;
+     }
+     else
+     {
+       // pm_low_agc is valid.
+       if (IL_high_agc<=l1_config.params.high_agc_sat_thr)
+       {
+         // pm_high_agc is not valid, it's saturated.
+         new_IL = IL_low_agc;
+         pm     = pm_low_agc;
+       }
+       else
+       {
+         // both pm_low_agc and pm_high_agc are valid, so we test the one that
+         // gives the maximum input level and consider it as the right setting.
+        if (IL_high_agc<=IL_low_agc)
+         {
+           new_IL = IL_high_agc;
+           pm     = pm_high_agc;
+         }
+         else
+         {
+           new_IL  = IL_low_agc;
+           pm      = pm_low_agc;
+         }
+       }
+     }
+   }
+
+   #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+     RTTL1_FILL_MON_MEAS(pm_high_agc, IL_high_agc - delta1_freq - delta2_freq, MS_AGC_ID, radio_freq)
+     RTTL1_FILL_MON_MEAS(pm_low_agc,  IL_low_agc  - delta1_freq - delta2_freq, MS_AGC_ID, radio_freq)
+   #endif
+
+   current_calibrated_IL = new_IL - delta1_freq - delta2_freq;
+
+   // Protect IL stores against overflow
+   if (current_calibrated_IL>INDEX_MAX)
+     current_calibrated_IL=INDEX_MAX;
+   if (new_IL>INDEX_MAX)
+     new_IL=INDEX_MAX;
+
+   // Updating of input_level and lna_off fields in order to correctly
+   // setting the AGC for the next task.
+   l1ctl_encode_lna((UWORD8)(current_calibrated_IL>>1),
+                    &(l1a_l1s_com.last_input_level[index].lna_off),
+                    radio_freq);
+
+   l1a_l1s_com.last_input_level[index].input_level = (UWORD8)new_IL +
+      l1ctl_get_lna_att(radio_freq) *
+	l1a_l1s_com.last_input_level[index].lna_off;
+}
+
+
+/*-------------------------------------------------------*/
+/* l1ctl_find_max()                                      */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+UWORD8 l1ctl_find_max(UWORD8 *buff, UWORD8 buffer_len)
+{
+
+  // WARNING: for array index purpose we work with POSITIVE input level
+  //          so maximum search for negative numbers is equivalent to
+  //          minimum search for positive numbers!!!!!!
+  //          (-30 > -120 but 30 < 120)
+
+  UWORD8  maximum = 240;
+  UWORD8  i;
+
+  for (i=0; i<buffer_len; i++)
+  {
+    if (buff[i]<maximum)
+      maximum=buff[i];
+  }
+
+  return(maximum);
+}
+
+/*-------------------------------------------------------*/
+/* l1ctl_pagc()                                          */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* ===========                                           */
+/* We deduce the last_known_agc from the last stored     */
+/* input_level for the considered carrier. We use this   */
+/* agc value to "build" the input level linked to the pm */
+/* we have just read.                                    */
+/* This input level is used to feed a fifo of 4 elements */
+/* and then compute an input_level maximum. This value is*/
+/* used to update the input_level for this carrier. This */
+/* input_level will be used for the next task to control.*/
+/*-------------------------------------------------------*/
+UWORD8 l1ctl_pagc(UWORD8 pm, UWORD16 radio_freq, T_INPUT_LEVEL *IL_info_ptr)
+{
+   WORD8   delta1_freq, delta2_freq;
+   WORD16  delta_drp_gain=0;
+   WORD32  last_known_agc;
+   UWORD8  IL_max;
+   WORD32  current_IL, current_calibrated_IL;
+   UWORD8  i;
+   WORD32  lna_value;
+   #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+     UWORD16 arfcn;
+   #endif
+   UWORD8  lna_off;
+   UWORD16 dco_algo_ctl_pw_temp = 0;
+   UWORD8 if_ctl = 0;
+   #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+     UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+   #endif
+
+   delta1_freq = l1ctl_encode_delta1(radio_freq);
+   delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+   // Update fifo
+   for (i=3;i>0;i--)
+     l1a_l1s_com.Scell_info.buff_beacon[i]=l1a_l1s_com.Scell_info.buff_beacon[i-1];
+
+   // from the lna state (ON/OFF) we compute the attenuation
+   // that was applied to signal when performing the power
+   // measure.
+   lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
+
+   // Compute applied agc for this pm
+   last_known_agc = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
+                                  // F7.1 in order to be compatible
+                                  // with pm and IL formats
+                                  // contain the input_level value we use
+                                  // in the associated CTL task to build
+                                  // the agc used in this CTL.
+
+#if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+#if (L1_FF_MULTIBAND == 0)
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn = radio_freq;
+#endif
+#endif
+
+#if(RF_FAM == 61)
+   #if (CODE_VERSION != SIMULATION)
+
+    cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
+                                          l1a_l1s_com.Scell_used_IL_dd.input_level,
+                                         radio_freq,if_threshold);
+     lna_off = l1a_l1s_com.Scell_used_IL_dd.lna_off;
+     delta_drp_gain = drp_gain_correction(arfcn, lna_off, last_known_agc);     // F7.1 format
+     if(if_ctl == IF_100KHZ_DSP){
+       delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
+     }
+     else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
+       delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
+     }
+
+   #endif
+#endif
+
+   if (0==pm)  // Check and filter illegal pm value by using last valid IL
+     current_IL = IL_info_ptr->input_level - lna_value;
+   else
+     current_IL = -(pm - (last_known_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
+
+   current_calibrated_IL = current_IL - delta1_freq - delta2_freq;
+
+   // Protect IL stores against overflow
+   if (current_calibrated_IL>INDEX_MAX)
+     current_calibrated_IL=INDEX_MAX;
+   if (current_IL>INDEX_MAX)
+     current_IL=INDEX_MAX;
+
+   l1a_l1s_com.Scell_info.buff_beacon[0]  = (UWORD8)current_IL;
+
+   IL_max = l1ctl_find_max(&(l1a_l1s_com.Scell_info.buff_beacon[0]),4);
+
+   //input levels are always stored with lna_on
+   l1ctl_encode_lna( (UWORD8)(current_calibrated_IL>>1),
+                     &(IL_info_ptr->lna_off),
+                     radio_freq );
+
+   IL_info_ptr->input_level = IL_max + l1ctl_get_lna_att(radio_freq) *
+					IL_info_ptr->lna_off;
+
+   #if L2_L3_SIMUL
+     #if (DEBUG_TRACE==BUFFER_TRACE_PAGC)
+       buffer_trace(4,IL_info_ptr->input_level,last_known_agc,
+                      l1a_l1s_com.Scell_used_IL_dd.input_level,Cust_get_agc_from_IL(radio_freq, IL_max >> 1, MAX_ID));
+     #endif
+   #endif
+
+   return((UWORD8)current_calibrated_IL);
+}
+
+/*-------------------------------------------------------*/
+/* l1ctl_dpagc()                                         */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* ===========                                           */
+/* Based on the same principle as the one used for PAGC  */
+/* algorithm except that we feed 3 different fifo:       */
+/* 1) one is dedicated to BCCH carrier                   */
+/* 2) another one is dedicated to all the other type of  */
+/*    bursts                                             */
+/* 3) the last one is dedicated to non DTX influenced    */
+/*    bursts                                             */
+/*-------------------------------------------------------*/
+UWORD8 l1ctl_dpagc(BOOL dtx_on, BOOL beacon, UWORD8 pm, UWORD16 radio_freq, T_INPUT_LEVEL *IL_info_ptr)
+{
+  UWORD8       av_G_all, av_G_DTX;
+  UWORD8       max_G_all, max_G_DTX;
+  WORD32       last_known_agc, new_IL, current_calibrated_IL;
+  WORD8        delta1_freq, delta2_freq;
+  WORD16       delta_drp_gain=0;
+  UWORD8       i;
+  UWORD8      *tab_ptr;
+  T_DEDIC_SET *aset;
+  WORD32       lna_value;
+  #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+    UWORD16      arfcn;
+  #endif
+  UWORD8       lna_off;
+  UWORD16 dco_algo_ctl_pw_temp = 0;
+  UWORD8 if_ctl = 0;
+  #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+    UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+  #endif
+
+  delta1_freq = l1ctl_encode_delta1(radio_freq);
+  delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+  aset = l1a_l1s_com.dedic_set.aset;
+
+  if (beacon)
+    tab_ptr = l1a_l1s_com.Scell_info.buff_beacon;
+  else
+    tab_ptr = aset->G_all;
+
+  // Update fifo
+  for (i=DPAGC_FIFO_LEN-1;i>0;i--)
+    tab_ptr[i]=tab_ptr[i-1];
+
+  #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
+      last_known_agc = (l1_config.tmode.rx_params.agc) << 1;
+      lna_value = (l1_config.tmode.rx_params.lna_off) * l1ctl_get_lna_att(radio_freq);
+    }
+    else
+  #endif
+    {
+      #if DPAGC_MAX_FLAG
+        last_known_agc  = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
+        // F7.1 in order to be compatible with pm and IL formats
+      #else
+        last_known_agc  = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, AV_ID)) << 1;
+        // F7.1 in order to be compatible with pm and IL formats
+      #endif
+      // input_level_dd : contain the input_level value we use
+      // in the associated CTL task to build the agc used in this CTL.
+
+      lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
+    }
+
+#if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+#if (L1_FF_MULTIBAND == 0)
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn = radio_freq;
+#endif
+#endif
+
+#if(RF_FAM == 61)
+   #if (CODE_VERSION != SIMULATION)
+
+    cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
+                                          l1a_l1s_com.Scell_used_IL_dd.input_level,
+                                         radio_freq,if_threshold);
+     lna_off = l1a_l1s_com.Scell_used_IL_dd.lna_off;
+     delta_drp_gain = drp_gain_correction(arfcn, lna_off, last_known_agc);     // F7.1 format
+     if(if_ctl == IF_100KHZ_DSP){
+       delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
+     }
+     else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
+       delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
+     }
+
+   #endif
+#endif
+
+  if (0==pm)  // Check and filter illegal pm value by using last valid IL
+    new_IL    = IL_info_ptr->input_level - lna_value;
+  else
+    new_IL    = -(pm - (last_known_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
+
+  current_calibrated_IL = new_IL - delta1_freq - delta2_freq;
+
+  // Protect IL stores against overflow
+  if (current_calibrated_IL>INDEX_MAX)
+    current_calibrated_IL=INDEX_MAX;
+
+  #if TESTMODE
+    if (l1tm.tmode_state.dedicated_active)  // Implies l1_config.TestMode = 1
+    {
+      // Update l1tm.tmode_stats.rssi_fifo (delay line from index 3 to 0)
+      for (i=(sizeof(l1tm.tmode_stats.rssi_fifo)/sizeof(l1tm.tmode_stats.rssi_fifo[0]))-1; i>0; i--)
+      {
+        l1tm.tmode_stats.rssi_fifo[i] = l1tm.tmode_stats.rssi_fifo[i-1];
+      }
+      l1tm.tmode_stats.rssi_fifo[0] = current_calibrated_IL; // rssi value is F7.1
+      l1tm.tmode_stats.rssi_recent  = current_calibrated_IL; // rssi value is F7.1
+    }
+  #endif
+
+  if (new_IL>INDEX_MAX)
+    new_IL=INDEX_MAX;
+
+  tab_ptr[0] = (UWORD8)new_IL;
+
+  if (dtx_on && !beacon)
+  {
+   // Update DTX fifo
+   for (i=DPAGC_FIFO_LEN-1;i>0;i--)
+     aset->G_DTX[i]=aset->G_DTX[i-1];
+
+   aset->G_DTX[0]=tab_ptr[0];
+  }
+
+  /* Computation of MAX{G_all[i],G_DTX[j]} i,j=0..3 */
+  #if DPAGC_MAX_FLAG
+    max_G_all   = l1ctl_find_max(&(tab_ptr[0]),DPAGC_FIFO_LEN);
+
+    if (!beacon)
+    {
+      max_G_DTX = l1ctl_find_max(&(aset->G_DTX[0]),DPAGC_FIFO_LEN);
+
+      // WARNING: for array index purpose we work with POSITIVE input level
+      //          so maximum search for negative numbers is equivalent to
+      //          minimum search for positive numbers!!!!!!
+      //          (-30 > -120 but 30 < 120)
+      if (max_G_all <= max_G_DTX)
+        new_IL = max_G_all;
+      else
+        new_IL = max_G_DTX;
+    }
+    else
+      new_IL = max_G_all;
+  #else
+    av_G_all=av_G_DTX=0;
+
+    for (i=0;i<DPAGC_FIFO_LEN;i++)
+     av_G_all += tab_ptr[i];
+
+    av_G_all /= DPAGC_FIFO_LEN;
+
+    if (!beacon)
+    {
+      for (i=0;i<DPAGC_FIFO_LEN;i++)
+       av_G_DTX += aset->G_DTX[i];
+
+      av_G_DTX /= DPAGC_FIFO_LEN;
+
+      if (av_G_all >= av_G_DTX)
+        new_IL = av_G_all;
+      else
+        new_IL = av_G_DTX;
+    }
+    else
+      new_IL = av_G_all;
+  #endif
+
+  // Updating of input_level and lna_off fields in order to correctly
+  // setting the AGC for the next task.
+  // input_level is always store with lna_on
+  l1ctl_encode_lna( (UWORD8)(current_calibrated_IL>>1),
+                    &(IL_info_ptr->lna_off),
+                    radio_freq );
+
+  IL_info_ptr->input_level = (UWORD8)new_IL + l1ctl_get_lna_att(radio_freq) *
+					IL_info_ptr->lna_off;
+
+  #if L2_L3_SIMUL
+    #if (DEBUG_TRACE==BUFFER_TRACE_DPAGC)
+      buffer_trace(4,IL_info_ptr->input_level,last_known_agc,
+                     l1a_l1s_com.Scell_used_IL_dd.input_level,Cust_get_agc_from_IL(radio_freq, new_IL >> 1, MAX_ID));
+    #endif
+  #endif
+
+  return((UWORD8)current_calibrated_IL);
+}
+
+#if (AMR == 1)
+  /*-------------------------------------------------------*/
+  /* l1ctl_dpagc_amr()                                     */
+  /*-------------------------------------------------------*/
+  /* Description :                                         */
+  /* ===========                                           */
+  /* Based on the same principle as the one used for DPAGC */
+  /* algorithm except that the way to feed the G_dtx is    */
+  /* different                                             */
+  /*-------------------------------------------------------*/
+  UWORD8 l1ctl_dpagc_amr(BOOL dtx_on, BOOL beacon, UWORD8 pm, UWORD16 radio_freq, T_INPUT_LEVEL *IL_info_ptr)
+  {
+    UWORD8       av_G_all, av_G_DTX;
+    UWORD8       max_G_all, max_G_DTX, max_il;
+    WORD32       last_known_agc, new_IL, current_calibrated_IL;
+    WORD8        delta1_freq, delta2_freq;
+    WORD16       delta_drp_gain=0;
+    UWORD8       i;
+    UWORD8       *tab_ptr, *tab_amr_ptr;
+    T_DEDIC_SET *aset;
+    WORD32       lna_value;
+    #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+	UWORD16  arfcn;
+    #endif
+    UWORD8       lna_off;
+    UWORD16 dco_algo_ctl_pw_temp = 0;
+    UWORD8 if_ctl = 0;
+    #if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+	UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+    #endif
+
+    delta1_freq = l1ctl_encode_delta1(radio_freq);
+    delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+    aset = l1a_l1s_com.dedic_set.aset;
+
+    if (beacon)
+    tab_ptr = l1a_l1s_com.Scell_info.buff_beacon;
+    else
+    tab_ptr = aset->G_all;
+
+    // Update fifo
+    for (i=DPAGC_FIFO_LEN-1;i>0;i--)
+      tab_ptr[i]=tab_ptr[i-1];
+
+    tab_amr_ptr = aset->G_amr;
+    for (i=DPAGC_AMR_FIFO_LEN-1;i>0;i--)
+      tab_amr_ptr[i]=tab_amr_ptr[i-1];
+
+    #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
+        last_known_agc = (l1_config.tmode.rx_params.agc) << 1;
+        lna_value = (l1_config.tmode.rx_params.lna_off) * l1ctl_get_lna_att(radio_freq);
+      }
+      else
+    #endif
+      {
+        #if DPAGC_MAX_FLAG
+          last_known_agc  = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
+          // F7.1 in order to be compatible with pm and IL formats
+        #else
+          last_known_agc  = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, AV_ID)) << 1;
+          // F7.1 in order to be compatible with pm and IL formats
+        #endif
+        // input_level_dd : contain the input_level value we use
+        // in the associated CTL task to build the agc used in this CTL.
+
+        lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
+      }
+
+#if (RF_FAM == 61) && (CODE_VERSION != SIMULATION)
+#if (L1_FF_MULTIBAND == 0)
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn = radio_freq;
+#endif
+#endif
+
+#if(RF_FAM == 61)
+   #if (CODE_VERSION != SIMULATION)
+    cust_get_if_dco_ctl_algo(&dco_algo_ctl_pw_temp, &if_ctl, (UWORD8) L1_IL_VALID ,
+                                          l1a_l1s_com.Scell_used_IL_dd.input_level,
+                                         radio_freq,if_threshold);
+     lna_off = l1a_l1s_com.Scell_used_IL_dd.lna_off;
+     delta_drp_gain = drp_gain_correction(arfcn, lna_off, last_known_agc);     // F7.1 format
+     if(if_ctl == IF_100KHZ_DSP){
+       delta_drp_gain += SCF_ATTENUATION_LIF_100KHZ;
+     }
+     else{ /* i.e. if_ctl = IF_120KHZ_DSP*/
+       delta_drp_gain += SCF_ATTENUATION_LIF_120KHZ;
+     }
+   #endif
+#endif
+
+    if (0==pm)  // Check and filter illegal pm value by using last valid IL
+      new_IL    = IL_info_ptr->input_level - lna_value;
+    else
+      new_IL    = -(pm - (last_known_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
+
+    current_calibrated_IL = new_IL - delta1_freq - delta2_freq;
+
+    // Protect IL stores against overflow
+    if (current_calibrated_IL>INDEX_MAX)
+      current_calibrated_IL=INDEX_MAX;
+
+    #if TESTMODE
+      if (l1tm.tmode_state.dedicated_active)  // Implies l1_config.TestMode = 1
+      {
+        // Update l1tm.tmode_stats.rssi_fifo (delay line from index 3 to 0)
+        for (i=(sizeof(l1tm.tmode_stats.rssi_fifo)/sizeof(l1tm.tmode_stats.rssi_fifo[0]))-1; i>0; i--)
+       {
+          l1tm.tmode_stats.rssi_fifo[i] = l1tm.tmode_stats.rssi_fifo[i-1];
+        }
+        l1tm.tmode_stats.rssi_fifo[0] = current_calibrated_IL; // rssi value is F7.1
+        l1tm.tmode_stats.rssi_recent  = current_calibrated_IL; // rssi value is F7.1
+      }
+    #endif
+
+    if (new_IL>INDEX_MAX)
+      new_IL=INDEX_MAX;
+
+     tab_ptr[0] = (UWORD8)new_IL;
+     tab_amr_ptr[0] = (UWORD8)new_IL;
+
+    if (dtx_on && !beacon)
+    {
+      // a new AMR block is received, feed the G_dtx with the max_il of the block
+      for (i=DPAGC_FIFO_LEN-1;i>0;i--)
+        aset->G_DTX[i]=aset->G_DTX[i-1];
+
+      if (l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_AHS_MODE)
+      {
+        // Keep the max_il between the last 2 bursts
+        if (aset->G_amr[0] > aset->G_amr[1])
+          max_il = aset->G_amr[0];
+        else
+          max_il = aset->G_amr[1];
+      }
+      else
+      {
+        // Keep the max_il between the last 4 bursts
+        max_il = l1ctl_find_max(&aset->G_amr[0], DPAGC_AMR_FIFO_LEN);
+      }
+
+      aset->G_DTX[0]= max_il;
+    }
+
+    /* Computation of MAX{G_all[i],G_DTX[j]} i,j=0..3 */
+    #if DPAGC_MAX_FLAG
+      max_G_all   = l1ctl_find_max(&(tab_ptr[0]),DPAGC_FIFO_LEN);
+
+      if (!beacon)
+      {
+        max_G_DTX = l1ctl_find_max(&(aset->G_DTX[0]),DPAGC_FIFO_LEN);
+
+        // WARNING: for array index purpose we work with POSITIVE input level
+        //          so maximum search for negative numbers is equivalent to
+        //          minimum search for positive numbers!!!!!!
+        //          (-30 > -120 but 30 < 120)
+        if (max_G_all <= max_G_DTX)
+          new_IL = max_G_all;
+        else
+          new_IL = max_G_DTX;
+      }
+      else
+        new_IL = max_G_all;
+    #else
+      av_G_all=av_G_DTX=0;
+
+      for (i=0;i<DPAGC_FIFO_LEN;i++)
+     av_G_all += tab_ptr[i];
+
+      av_G_all /= DPAGC_FIFO_LEN;
+
+      if (!beacon)
+      {
+        for (i=0;i<DPAGC_FIFO_LEN;i++)
+         av_G_DTX += aset->G_DTX[i];
+
+        av_G_DTX /= DPAGC_FIFO_LEN;
+
+        if (av_G_all >= av_G_DTX)
+          new_IL = av_G_all;
+        else
+          new_IL = av_G_DTX;
+      }
+      else
+        new_IL = av_G_all;
+    #endif
+
+    // Updating of input_level and lna_off fields in order to correctly
+    // setting the AGC for the next task.
+    // input_level is always store with lna_on
+
+    l1ctl_encode_lna( (UWORD8)(current_calibrated_IL>>1),
+                      &(IL_info_ptr->lna_off),
+                      radio_freq );
+    IL_info_ptr->input_level = (UWORD8)new_IL + l1ctl_get_lna_att(radio_freq) *
+						IL_info_ptr->lna_off;
+
+    #if L2_L3_SIMUL
+      #if (DEBUG_TRACE==BUFFER_TRACE_DPAGC)
+        buffer_trace(4,IL_info_ptr->input_level,last_known_agc,
+                       l1a_l1s_com.Scell_used_IL_dd.input_level,Cust_get_agc_from_IL(radio_freq, new_IL >> 1, MAX_ID));
+      #endif
+    #endif
+
+    return((UWORD8)current_calibrated_IL);
+  }
+#endif  // AMR == 1
+
+/*-------------------------------------------------------*/
+/* l1ctl_get_g_magic()                                   */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+#if (L1_FF_MULTIBAND == 0)
+UWORD16 l1ctl_get_g_magic(UWORD16 radio_freq)
+{
+
+
+  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)
+      return(l1_config.std.g_magic_band2);
+    else
+      return(l1_config.std.g_magic_band1);
+  }
+  else
+    return(l1_config.std.g_magic_band1);
+  
+
+}
+#endif
+
+/*-------------------------------------------------------*/
+/* l1ctl_get_lna_att()                                   */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+#if (L1_FF_MULTIBAND == 0)
+UWORD16 l1ctl_get_lna_att(UWORD16 radio_freq)
+{
+
+
+  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)
+      return(l1_config.std.lna_att_band2);
+    else
+      return(l1_config.std.lna_att_band1);
+  }
+  else
+    return(l1_config.std.lna_att_band1);
+  
+  
+}
+#endif 
+/*-------------------------------------------------------*/
+/* l1ctl_update_TPU_with_toa()                           */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+void l1ctl_update_TPU_with_toa(void)
+{
+  #if (TOA_ALGO != 0)
+    WORD16 toa_shift;
+
+    #if (TOA_ALGO == 2)
+      toa_shift = l1s.toa_var.toa_shift;
+    #else
+      toa_shift = l1s.toa_shift;
+    #endif
+
+    if (toa_shift != ISH_INVALID)
+    // New ISH (TOA shift) has been stored in "l1s.toa_shift".
+    {
+      // NEW !!! For EOTD measurements in IDLE mode, cut AFC updates...
+      #if (L1_EOTD==1)
+        #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
+          {
+            // In dedicated or transfer modes we need to track an TOA
+            // updates to post correct th results, else E-OTD implementation
+            // has qb errors...
+
+            if( (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
+                && (l1a_l1s_com.nsync.eotd_toa_phase == 1) )
+            {
+              l1a_l1s_com.nsync.eotd_toa_tracking += toa_shift;
+            }
+      #endif
+            // Update tpu offset.
+            l1s.tpu_offset = (l1s.tpu_offset + TPU_CLOCK_RANGE + toa_shift) % TPU_CLOCK_RANGE;
+
+            #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+              #if (GSM_IDLE_RAM == 0)
+                l1_trace_new_toa();
+              #else
+                l1_trace_new_toa_intram();
+              #endif
+            #endif
+
+      #if (L1_EOTD==1)
+          }
+      #endif
+
+      #if (TRACE_TYPE == 5)
+        #if (TOA_ALGO == 2)
+          trace_toa_sim_update (toa_shift,l1s.tpu_offset);
+        #endif
+      #endif
+
+      // Reset ISH.
+      #if (TOA_ALGO == 2)
+        l1s.toa_var.toa_shift = ISH_INVALID;   // Reset the ISH.
+      #else
+        l1s.toa_shift = ISH_INVALID;   // Reset the ISH.
+      #endif
+    }
+  #endif
+}
+
+
+/*-------------------------------------------------------*/
+/* l1ctl_saic()                                          */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+
+#if (L1_SAIC != 0)
+#define SWH_CHANTAP_INIT 0xFFD068CE
+#if (NEW_SNR_THRESHOLD == 1)
+UWORD8 l1ctl_saic (UWORD8 IL_for_rxlev, UWORD32 l1_mode, UWORD8 task, UWORD8 * saic_flag)
+#else
+UWORD8 l1ctl_saic (UWORD8 IL_for_rxlev, UWORD32 l1_mode)
+#endif   /* NEW_SNR_THRESHOLD */
+{
+  UWORD16 SWH_flag = 0;
+  UWORD8  CSF_Filter_choice = L1_SAIC_HARDWARE_FILTER;
+#if (NEW_SNR_THRESHOLD == 0)
+  volatile UWORD16 *ptr;
+  UWORD8 saic_flag;
+#endif /* NEW_SNR_THRESHOLD */
+#if (NEW_SNR_THRESHOLD == 0)
+  ptr = (volatile UWORD16 * ) (SWH_CHANTAP_INIT);
+  *ptr = 0;
+  saic_flag=1;
+#else
+  *saic_flag=0;
+#endif
+
+  switch (l1_mode)
+  {
+    case DEDIC_MODE:  // GSM DEDICATED MODE
+    {
+#if (NEW_SNR_THRESHOLD == 1)
+      *saic_flag=1;
+#endif
+      if(IL_for_rxlev < L1_SAIC_GENIE_GSM_DEDIC_THRESHOLD)
+      {
+        SWH_flag=1;
+      }
+
+      break;
+    }
+    #if L1_GPRS
+      case PACKET_TRANSFER_MODE: // PACKET TRANSFER MODE
+      {
+#if (NEW_SNR_THRESHOLD == 0)
+        #if (L1_SAIC == 1)
+          if(IL_for_rxlev < L1_SAIC_GENIE_GPRS_PCKT_TRAN_THRESHOLD)
+          {
+             *ptr = 4;
+          }
+        #endif /*#if (L1_SAIC == 3)*/
+#endif
+
+        #if (L1_SAIC == 3)
+          if(IL_for_rxlev < L1_SAIC_GENIE_GPRS_PCKT_TRAN_THRESHOLD)
+          {
+            SWH_flag = 1;
+          }
+        #endif /*#if (L1_SAIC == 3)*/
+        break;
+      }
+   #endif /*#if L1_GPRS*/
+   default: /* GSM OR GPRS IDLE MODES */
+   {
+     #if ((L1_SAIC == 2)||(L1_SAIC == 3))
+       if(IL_for_rxlev < L1_SAIC_GENIE_GSM_GPRS_IDLE_THRESHOLD)
+       {
+         SWH_flag=1;
+       }
+     #endif
+     break;
+   }
+  }
+
+  l1ddsp_load_swh_flag (SWH_flag ,
+#if (NEW_SNR_THRESHOLD == 0)
+		  saic_flag
+#else
+		  *saic_flag
+#endif
+		  );
+
+  if(SWH_flag == 1)
+  {
+    CSF_Filter_choice = L1_SAIC_PROGRAMMABLE_FILTER;
+  }
+
+
+  #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+    l1_trace_saic(SWH_flag,
+#if (NEW_SNR_THRESHOLD == 0)
+		  saic_flag
+#else
+		    *saic_flag
+#endif
+		    );
+  #endif
+  #if (TRACE_TYPE == 5)
+    trace_saic_sim(IL_for_rxlev, l1_mode, SWH_flag);
+  #endif
+
+  return(CSF_Filter_choice);
+}
+#endif
+
+#if (FF_L1_FAST_DECODING == 1)
+/*-----------------------------------------------------------------*/
+/* l1ctl_pagc_missing_bursts                                       */
+/*-----------------------------------------------------------------*/
+/*                                                                 */
+/* Description:                                                    */
+/* ------------                                                    */
+/* When fast decoding is active, fewer bursts are decoded. As a    */
+/* result, fewer gain values are available. The PAGC algo must     */
+/* be updated with the missed values.                              */
+/*                                                                 */
+/* Input parameters:                                               */
+/* -----------------                                               */
+/* UWORD8 skipped_values: the number of skipped bursts due to fast */
+/*                        decoding.                                */
+/*                                                                 */
+/* Input parameters from globals:                                  */
+/* ------------------------------                                  */
+/* l1a_l1s_com.Scell_info.buff_beacon: Input Level (IL) FIFO       */
+/* l1_config.params.il_min: minimum level                          */
+/*                                                                 */
+/* Output parameters:                                              */
+/* ------------------                                              */
+/* none                                                            */
+/*                                                                 */
+/* Modified parameters from globals:                               */
+/* ---------------------------------                               */
+/* l1a_l1s_com.Scell_info.buff_beacon: Input Level (IL) FIFO       */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+
+void l1ctl_pagc_missing_bursts (UWORD8 skipped_values)
+{
+  UWORD8 i = 0;
+
+  /* skipped_values cannot be greater than 3, otherwise this is an error
+   * and the PAGC algorithm mustn't be updated. */
+  if (skipped_values > 3)
+  {
+    return;
+  }
+
+  /* Update fifo by removing skipped_values of samples */
+  for (i = 3; i > (skipped_values - 1); i--)
+  {
+    l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-skipped_values];
+  }
+
+  /* Insert minimum IL level as many times a burst has been skipped */
+  for (i = 0; i < skipped_values; i++)
+  {
+    l1a_l1s_com.Scell_info.buff_beacon[i] = l1_config.params.il_min;
+  }
+}
+#endif /* #if (FF_L1_FAST_DECODING == 1)  */