diff src/cs/layer1/p_cfile/l1p_ctl.c @ 302:0740b5ff15f6

reconstructed L1_GPRS source imported from tcs211-l1-reconst
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 31 Oct 2017 03:42:35 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cs/layer1/p_cfile/l1p_ctl.c	Tue Oct 31 03:42:35 2017 +0000
@@ -0,0 +1,1742 @@
+/************* Revision Controle System Header *************
+ *                  GSM Layer 1 software 
+ * L1P_CTL.C
+ *
+ *        Filename l1p_ctl.c
+ *  Copyright 2003 (C) Texas Instruments  
+ *
+ ************* Revision Controle System Header *************/
+
+#include "l1_macro.h"
+#include "l1_confg.h"
+
+#if L1_GPRS
+#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
+  #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"
+
+  #include "l1_ctl.h"
+
+  #include "l1p_cons.h"
+  #include "l1p_msgt.h"
+  #include "l1p_deft.h"
+  #include "l1p_vare.h"
+  #include "l1p_sign.h"
+#if (OP_L1_STANDALONE == 1)
+  #ifdef _INLINE
+    #define INLINE static inline // Inline functions when -v option is set 
+  #else                          // when the compiler is ivoked.
+    #define INLINE
+  #endif
+#endif  //0maps00090550
+#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
+  #include "l1_defty.h"
+  #include "cust_os.h"
+  #include "l1_msgty.h"
+  #include "l1_varex.h"
+  #include "l1_proto.h"
+
+  #include "l1_ctl.h"
+
+  #include "l1p_cons.h"
+  #include "l1p_msgt.h"
+  #include "l1p_deft.h"
+  #include "l1p_vare.h"
+  #include "l1p_sign.h"
+  #if (OP_L1_STANDALONE == 1)
+  #ifdef _INLINE
+    #define INLINE static inline // Inline functions when -v option is set 
+  #else                          // when the compiler is ivoked.
+    #define INLINE
+  #endif
+#endif //omaps00090550
+#endif
+
+#if(RF_FAM == 61)
+   #include "l1_rf61.h"
+#endif
+
+
+// Macro definition
+//-----------------
+#define min(value1,value2) \
+  value1 < value2 ? value1 : value2
+
+// External prototypes
+//--------------------
+
+WORD8 l1ctl_encode_delta1(UWORD16 radio_freq);
+
+/*********************************************************/
+/* GPRS AGC Algorithms                                   */
+/*********************************************************/
+
+/*-------------------------------------------------------*/
+/* l1pctl_pagc_ctrl()                                    */
+/*-------------------------------------------------------*/
+/* Description:                                          */
+/* ===========                                           */
+/* Based on the same principle as the one used for PAGC  */
+/* algorithm except that we also feed the beacon FIFO    */
+/* with IL measured on other carriers (Pb parameter is   */
+/* applied)                                              */
+/* This function is used in the control phase of PCCCH,  */
+/* serving PBCCH and PTCCH reading tasks to determine    */
+/* which AGC and lna_off must apply                      */
+/*                                                       */
+/* WARNING: in the layer 1 code, input levels IL(l1) use */
+/*          format 7.1:                                  */
+/*               *********************                   */
+/*               * IL(l1) = - 2 x IL *                   */
+/*               *********************                   */
+/*          -> Reversed sign, reversed test conditions   */
+/*          -> max replaced by min                       */
+/*          ex: if IL -120 dBm, IL(l1) = 240             */
+/*-------------------------------------------------------*/
+void l1pctl_pagc_ctrl(WORD8 *agc, UWORD8 *lna_off, UWORD16 radio_freq, UWORD8 serving_cell)
+{
+  UWORD8  pb;
+  WORD16  input_level, new_calibrated_IL;
+  WORD32  freq_index;
+  UWORD16 beacon_frequency;
+  UWORD8  *lna_off_ptr;
+  UWORD8  curve_id;
+
+  // We memorize the LNA state used for other serving frequencies that can be used
+  // in Packet idle mode
+  static UWORD8 lna_off_others = 0;
+
+  if (serving_cell == TRUE)
+  {
+    beacon_frequency = l1a_l1s_com.Scell_info.radio_freq;
+    pb               = l1a_l1s_com.Scell_info.pb;
+    lna_off_ptr      = &lna_off_others;
+    curve_id         = MAX_ID;
+  }
+  else
+  {
+    beacon_frequency = l1pa_l1ps_com.pbcchn.bcch_carrier;
+    pb               = l1pa_l1ps_com.pbcchn.pb;
+    lna_off_ptr      = lna_off;
+    curve_id         = AV_ID;
+  }
+
+#if(L1_FF_MULTIBAND == 0)
+  freq_index = beacon_frequency - l1_config.std.radio_freq_index_offset;
+#else
+  freq_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(beacon_frequency);
+#endif
+  
+
+  // If the downlink channel is decoded on the beacon frequency
+  if (radio_freq == beacon_frequency)
+  {
+    // Downlink task on the serving beacon: process AGC according to the "beacon IL"
+    input_level = l1a_l1s_com.last_input_level[freq_index].input_level;
+
+    // lna_off already processed in the read phase
+    *lna_off = l1a_l1s_com.last_input_level[freq_index].lna_off;
+  }
+
+  // If the downlink channel is decoded on a frequency other than the beacon
+  else
+  {
+
+    // Process AGC according to "beacon IL + Pb"
+    input_level = (WORD16) (l1a_l1s_com.last_input_level[freq_index].input_level + pb);
+
+    // IL_2_AGC_xx array size
+    if (input_level>INDEX_MAX)
+      input_level = INDEX_MAX;
+
+    // lna_off must be processed in the control phase because input_level
+    // depends on last_input_level and Pb, and last_input_level or pb can have changed
+    // at any time
+
+    // New calibrated IL to reach on radio freq other than beacon
+    new_calibrated_IL = (WORD16) (input_level - l1ctl_encode_delta1(radio_freq)
+                                              - l1ctl_encode_delta2(radio_freq));
+
+    // IL_2_AGC_xx array size
+    if (new_calibrated_IL>INDEX_MAX)
+      new_calibrated_IL = INDEX_MAX;
+
+    // lna_off computing...
+    l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1),
+                     lna_off_ptr,
+                     radio_freq);
+
+    *lna_off = *lna_off_ptr;
+  } // End if "radio_freq != beacon_frequency"
+
+  // Process AGC to apply
+  *agc     = Cust_get_agc_from_IL(radio_freq,
+                                  input_level >> 1,
+                                  curve_id);
+
+  // Store lna_off and input_level field used for current CTRL in order to be able 
+  // to build IL from pm in READ phase.
+  l1a_l1s_com.Scell_used_IL.input_level = (UWORD8)input_level;
+  l1a_l1s_com.Scell_used_IL.lna_off     = *lna_off;
+
+} // End of "l1pctl_pagc_ctrl"
+
+/*-------------------------------------------------------*/
+/* l1pctl_pagc_read()                                    */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* ===========                                           */
+/* Based on the same principle as the one used for PAGC  */
+/* algorithm except that we also feed the beacon FIFO    */
+/* with IL measured on other carriers (Pb parameter is   */
+/* applied)                                              */
+/* This function is used in the read phase of PCCCH and  */
+/* serving PBCCH reading tasks to determine the IL value */
+/* store it in the FIFO and find the next IL to use      */
+/*                                                       */
+/* WARNING: in the layer 1 code, input levels IL(l1) use */
+/*          format 7.1:                                  */
+/*               *********************                   */
+/*               * IL(l1) = - 2 x IL *                   */
+/*               *********************                   */
+/*          -> Reversed sign, reversed test conditions   */
+/*          -> max replaced by min                       */
+/*          ex: if IL -120 dBm, IL(l1) = 240             */
+/*-------------------------------------------------------*/
+UWORD8 l1pctl_pagc_read(UWORD8 pm, UWORD16 radio_freq)
+{
+  UWORD8   i, new_IL;
+  WORD8    delta1_freq, delta2_freq;
+  WORD16   delta_drp_gain=0;
+  UWORD16  lna_value;
+  WORD16   used_agc, current_IL, new_calibrated_IL, current_calibrated_IL;
+  WORD32   serving_index;
+#if (RF_FAM == 61)
+  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_GPRS;
+#endif
+
+#if (L1_FF_MULTIBAND == 0)
+  serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
+
+#else
+  serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
+#endif /*if (L1_FF_MULTIBAND == 0)*/
+  
+
+  // Calibration factors
+  delta1_freq = l1ctl_encode_delta1(radio_freq);
+  delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+  // AGC used in the control phase (format F7.1)
+  used_agc = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
+
+  // LNA attenuation
+  lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
+
+#if (RF_FAM == 61)
+  // DRP correction 
+#if (L1_FF_MULTIBAND == 0)  
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn=radio_freq;
+#endif 
+
+   #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, used_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
+
+  // current_IL processing
+
+  if (0==pm)  // Check and filter illegal pm value by using last valid IL
+  {
+    current_IL = l1a_l1s_com.last_input_level[serving_index].input_level - lna_value;
+  }
+  else 
+  { 
+    current_IL = -(pm - (used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
+
+    // IL normalization to beacon (ILnorm = IL - Pb)
+    if (radio_freq != l1a_l1s_com.Scell_info.radio_freq)
+      current_IL -= l1a_l1s_com.Scell_info.pb;
+  }
+
+  // Calibrated IL processing
+  // NOTE: calibrated_IL is normalized to beacon. This is needed for the
+  //       pccch_lev processing
+  current_calibrated_IL = (WORD16) (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;
+
+  // FIFO management
+  for (i=3;i>0;i--)
+    l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
+  l1a_l1s_com.Scell_info.buff_beacon[0] = (UWORD8)current_IL;
+
+  // Find min IL in FIFO
+  new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon, 4);
+
+  // Input levels are always stored with lna_on 
+  new_calibrated_IL = (WORD16)  (new_IL - delta1_freq - delta2_freq);
+
+  if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
+
+  l1ctl_encode_lna( (UWORD8)(new_calibrated_IL>>1),
+                    &(l1a_l1s_com.last_input_level[serving_index].lna_off),
+                    radio_freq );
+
+  l1a_l1s_com.last_input_level[serving_index].input_level = new_IL +
+    l1a_l1s_com.last_input_level[serving_index].lna_off * l1ctl_get_lna_att(radio_freq);
+
+  return((UWORD8)current_calibrated_IL);
+} // End of "l1pctl_pagc_read"
+
+/*-------------------------------------------------------*/
+/* l1pctl_transfer_agc_init()                            */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* ===========                                           */
+/* Packet transfer AGC algorithm initialization          */
+/*-------------------------------------------------------*/
+void l1pctl_transfer_agc_init()
+{
+  WORD16   calibrated_IL;
+  UWORD16  radio_freq;
+  WORD32   serving_index;
+  WORD16   input_level;
+
+#if (L1_FF_MULTIBAND ==0)
+  serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
+
+#else
+  serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
+#endif /*if L1_FF_MULTIBAND*/
+  
+
+  // Daughter frequencies input level initialization
+  //------------------------------------------------
+  if (l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.p0 == 255)
+  {
+    // No power control mode AGC algorithm
+    input_level = (WORD16) (l1a_l1s_com.last_input_level[serving_index].input_level + l1a_l1s_com.Scell_info.pb);
+
+    // Set fn_select to current_fn
+    l1ps.fn_select                                   = l1s.actual_time.fn;
+    // Initialize algorithm in "SEARCH" phase
+    l1ps.phase                                       = SEARCH;
+  }
+  else
+  {
+    // Downlink power control AGC algorithms
+    if (l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.bts_pwr_ctl_mode == 0)
+    {
+      // BTS Power control mode A
+      input_level = (WORD16) (l1a_l1s_com.last_input_level[serving_index].input_level +
+                              l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.p0 + 10);
+      
+    }
+    else
+    {
+      // BTS power control mode B
+      input_level = (WORD16) (l1a_l1s_com.last_input_level[serving_index].input_level +
+                              l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.p0);
+
+      // Initialization: PR = P0
+      l1ps.last_PR_good = l1pa_l1ps_com.transfer.aset->dl_pwr_ctl.p0;
+    }
+  }
+
+  if (input_level>INDEX_MAX) input_level = INDEX_MAX;
+  l1a_l1s_com.Scell_info.transfer_meas.input_level = (UWORD8)input_level;
+
+
+  // Daughter frequencies lna_off processing
+  //----------------------------------------
+
+  // We need to know on which frequency band we work
+  if (!l1pa_l1ps_com.transfer.aset->freq_param.chan_sel.h)
+  {
+    // Single frequency
+    radio_freq = l1pa_l1ps_com.transfer.aset->freq_param.chan_sel.rf_channel.single_rf.radio_freq;
+  }
+  else
+  {
+    // Frequency hopping: all frequencies of the frequency list are on the same band
+    // We take the first frequency of the list
+    radio_freq = l1pa_l1ps_com.transfer.aset->freq_param.freq_list.rf_chan_no.A[0];
+  }
+
+  calibrated_IL = (WORD16) (l1a_l1s_com.Scell_info.transfer_meas.input_level
+                  - l1ctl_encode_delta1(radio_freq) - l1ctl_encode_delta2(radio_freq)
+                  - l1a_l1s_com.last_input_level[serving_index].lna_off * l1ctl_get_lna_att(radio_freq));
+                  
+  if (calibrated_IL>INDEX_MAX) calibrated_IL = INDEX_MAX; 
+
+  l1ctl_encode_lna((UWORD8)(calibrated_IL>>1), &(l1a_l1s_com.Scell_info.transfer_meas.lna_off), radio_freq);
+
+}  // End of "l1pctl_transfer_agc_init"
+
+/*-------------------------------------------------------*/
+/* l1pctl_transfer_agc_ctrl()                            */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* ===========                                           */
+/* This function is used in the control phase of PDTCH/D */
+/* to determine which AGC and lna_off must apply         */
+/*-------------------------------------------------------*/
+void l1pctl_transfer_agc_ctrl(WORD8 *agc, UWORD8 *lna_off, UWORD16 radio_freq)
+{
+  T_INPUT_LEVEL *selected_IL;
+#if(L1_FF_MULTIBAND == 1)
+  UWORD16 operative_radio_freq;
+#endif
+  
+
+  // input_level selection
+  if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+  {
+    // Beacon frequency input_level used for AGC processing
+#if(L1_FF_MULTIBAND == 0)    
+    selected_IL = &l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq
+                                                - l1_config.std.radio_freq_index_offset];
+
+#else // L1_FF_MULTIBAND = 1 below
+
+    operative_radio_freq = 
+      l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
+    selected_IL = &(l1a_l1s_com.last_input_level[operative_radio_freq]);
+
+
+#endif // #if(L1_FF_MULTIBAND == 0) else
+
+  }
+  else
+  {
+    // Daughter frequency input_level used for AGC processing
+    selected_IL = &l1a_l1s_com.Scell_info.transfer_meas;
+  }
+  *agc     = Cust_get_agc_from_IL(radio_freq,selected_IL->input_level >> 1, MAX_ID);
+  *lna_off = selected_IL->lna_off;
+
+  // Store lna_off and input_level field used for current CTRL in order to be able 
+  // to build IL from pm in READ phase.
+  l1a_l1s_com.Scell_used_IL.input_level = selected_IL->input_level;
+  l1a_l1s_com.Scell_used_IL.lna_off     = *lna_off;
+
+}
+
+/*-------------------------------------------------------*/
+/* l1pctl_npc_agc_read()                                 */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* ===========                                           */
+/* AGC algorithm in packet transfer used when            */
+/* NO POWER CONTROL is done by the BTS.                  */
+/* This function is used during the read phase of PDTCH: */
+/* 1- to determine the IL value for each timeslot in each*/
+/*    TDMA                                               */
+/* 2- to find the IL value to use for the next PDCH      */
+/*    block                                              */
+/*                                                       */
+/* Algorithm                                             */
+/* ---------                                             */
+/* For each timeslot i used for PDCH                     */
+/*   IL(i) = fct(used AGC, pm)                           */
+/*   if (beacon)                                         */
+/*     ILmax_beacon = max(ILmax_beacon, IL(i))           */
+/*   else                                                */
+/*     ILmax_others(i) = max(IL(i), ILmax_others(i))     */
+/*                                                       */
+/* If (burst_nb == 3)                                    */
+/*   If (ILmax_beacon was found during the block)        */
+/*     FIFO[beacon] updated with ILmax_beacon            */
+/*     transfer_meas = max(FIFO[beacon])                 */
+/*     Reset ILmax_beacon                                */
+/*                                                       */
+/*   For each timeslot i used for PDCH                   */
+/*     if (CRC good)                                     */
+/*       ILmax_correct = max(ILmax_correct,              */
+/*                           ILmax_others(i))            */
+/*     else                                              */
+/*       ILmax_not_correct = max(ILmax_not_correct,      */
+/*                               ILmax_others(i))        */
+/*                                                       */
+/*   If (no ILmax_correct was found)                     */
+/*     ILselected = ILmax_correct                        */
+/*     FNselected = current FN                           */
+/*   else                                                */
+/*     DeltaFN = (current FN - FNselected) % MAX_FN      */
+/*                                                       */
+/*     if (DeltaFN < 78)                                 */
+/*       ILweighted = ILselected * (1 - DeltaFN/78)      */
+/*                    - 120 * DeltaFN /78                */
+/*                                                       */
+/*       if (ILweighted < -120) ILweighted = -120        */
+/*       if (ILmax_not_correct > ILweighted)             */
+/*         ILselected = ILmax_not_correct                */
+/*         FNselected = current FN                       */
+/*     else                                              */
+/*       ILselected = -120                               */
+/*       FNselected = current FN                         */
+/*                                                       */
+/*   Reset ILmax_others[8]                               */
+/*                                                       */
+/* WARNING: in the layer 1 code, input levels IL(l1) use */
+/*          format 7.1:                                  */
+/*               *********************                   */
+/*               * IL(l1) = - 2 x IL *                   */
+/*               *********************                   */
+/*          -> Reversed sign, reversed test conditions   */
+/*          -> max replaced by min                       */
+/*          ex: if IL -120 dBm, IL(l1) = 240             */
+/*                                                       */
+/* Parameters                                            */
+/* ----------                                            */
+/* "calibrated_IL[8]"                                    */
+/*   contains the IL found on timeslots                  */
+/*   used for PDCH/D. These ILs can be used to process   */
+/*   RXLEV values.                                       */
+/*                                                       */
+/* "*pdsp_db_r_ptr"                                      */
+/*   Pointer on the DSP DB Read page, used to extract    */
+/*   pm values, burst number and timeslot allocated      */
+/*   for downlink PDCH                                   */
+/*                                                       */
+/* "*pdsp_ndb_ptr"                                       */
+/*   Pointer on the DSP NDB page, used to extract the    */
+/*   CRC value for each decoded burst                    */
+/*                                                       */
+/* Global parameters                                     */
+/* -----------------                                     */
+/* "l1a_l1s_com.Scell_info.transfer_meas.input_level"    */
+/* "l1a_l1s_com.Scell_info.transfer_meas.lna_off"        */
+/*   Used to store the ILselected and the associated     */
+/*   lna_off value.                                      */
+/*                                                       */
+/* "l1a_l1s_com.Scell_info.fn_select"                    */
+/*   Used to store the FNselected value.                 */
+/*                                                       */
+/* "l1a_l1s_com.last_input_level[freq index]             */
+/*     .input_level                                      */
+/*     .lna_off"                                         */
+/*   Used to store the beacon input level and            */
+/*   the associated lna_off value.                       */
+/*                                                       */
+/* "l1ps.transfer_beacon_buf[4]"                         */
+/*   FIFO[beacon]                                        */
+/*                                                       */
+/* "l1ps.ILmin_beacon"                                   */
+/* "l1ps.ILmin_others[8]"                                */
+/*-------------------------------------------------------*/
+void l1pctl_npc_agc_read(UWORD8 calibrated_IL[8], T_DB_DSP_TO_MCU_GPRS *pdsp_db_r_ptr,
+                         T_NDB_MCU_DSP_GPRS *pdsp_ndb_ptr)
+{
+  UWORD8       ts;
+  UWORD8       rx_no                      = 0;
+  UWORD8       bit_mask                   = 0x80;
+  UWORD8       ILmin_correct              = 255;
+  UWORD8       ILmin_not_correct          = 255;
+  WORD8        delta1_freq, delta2_freq;
+  WORD16       delta_drp_gain=0;
+  UWORD16      radio_freq, lna_value;
+  WORD16       used_agc;
+  WORD32       serving_index;
+#if (RF_FAM == 61)
+  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_GPRS;
+#endif
+
+#if(L1_FF_MULTIBAND == 0)
+  serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
+
+#else
+  serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
+#endif
+  
+
+  // Control phase parameters: same AGC, radio_freq, lna_off used for all PDTCH
+  // ***************************************************************************
+
+  // Get radio_freq on which the downlink block was received
+  radio_freq = l1a_l1s_com.dedic_set.radio_freq_dd;
+
+  // Compute calibration factors
+  delta1_freq                                      = l1ctl_encode_delta1(radio_freq);
+  delta2_freq                                      = l1ctl_encode_delta2(radio_freq);
+
+  // AGC used in the control phase (format F7.1)
+  used_agc = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
+
+  // LNA attenuation
+  lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
+
+  // Burst 0: Reset ILmin_beacon and ILmin_others
+  if(pdsp_db_r_ptr->d_burst_nb_gprs == 0)
+  {
+    l1ps.ILmin_beacon = 255; // Not valid
+
+    for (ts = 0; ts < 8; ts++)
+    {
+      l1ps.ILmin_others[ts] = (UWORD8) l1_config.params.il_min;
+    }
+  } // End if "burst 0"
+
+  // IL processing for each received burst
+  // **************************************
+
+  // For each timeslot on which a burst was received
+  for(ts = 0; ts < 8; ts ++)
+  {
+    if(pdsp_db_r_ptr->d_task_d_gprs & bit_mask)
+    {
+      WORD16       current_IL, current_calibrated_IL;
+      UWORD8       pm;
+
+      // IL = fct(pm, last_known_agc, lna_value, g_magic)
+      //-------------------------------------------------
+
+      pm    = (UWORD8) ((pdsp_db_r_ptr->a_burst_pm_gprs[ts]   & 0xffff) >> 5);
+
+      // current_IL processing
+      if (0==pm)  // Check and filter illegal pm value by using last valid IL
+      {
+        if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+          current_IL = l1a_l1s_com.last_input_level[serving_index].input_level
+                       - lna_value;
+        else
+          current_IL = l1a_l1s_com.Scell_info.transfer_meas.input_level
+                       - lna_value;
+      }
+      else
+      {
+
+#if (RF_FAM == 61)
+        // DRP correction 
+#if (L1_FF_MULTIBAND == 0)  
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn=radio_freq;
+#endif 
+
+   #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, used_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
+
+        current_IL = -(pm - (used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
+      }
+
+      // Calibrated IL processing
+      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;
+         
+      calibrated_IL[ts] = (UWORD8)(current_calibrated_IL);  
+   
+      // Keep ILmax
+      if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+      {
+        // Beacon frequency
+        l1ps.ILmin_beacon = min((UWORD8) current_IL, l1ps.ILmin_beacon);
+      }
+      else
+      {
+        // Daughter frequency
+        l1ps.ILmin_others[ts] = min((UWORD8) current_IL,l1ps.ILmin_others[ts]);
+      }
+
+      // Input Level selection among ILmax found on each timeslot during the block (when burst = 3)
+      // *******************************************************************************************
+
+      if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
+      {
+        // If CRC good
+        if (!(pdsp_ndb_ptr->a_dd_gprs[rx_no][0] & 0x0100))
+        {
+          // Find the min found IL for blocks that were correctly received
+          ILmin_correct = min(l1ps.ILmin_others[ts],ILmin_correct);
+        }
+        // If CRC bad
+        else
+        {
+          // Find the min found IL for blocks that were not correctly received
+          ILmin_not_correct = min(l1ps.ILmin_others[ts],ILmin_not_correct);
+        }
+      } // End if "burst = 3"
+
+      // Next downlink block
+      rx_no ++;
+
+    } // End if "timeslot used for downlink PDCH"
+
+    // Next timeslot
+    bit_mask >>= 1;
+  } // End for "each timeslot...."
+
+
+  // IL selection for the next block if burst = 3
+  // **********************************************
+
+  if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
+  {
+    WORD16 new_calibrated_IL;
+
+    // Beacon frequency input level updating
+    //--------------------------------------
+
+    // If a PDCH has been received on the beacon
+    if (l1ps.ILmin_beacon != 255)
+    {
+      UWORD8 i, new_IL;
+
+      // FIFO management
+      for (i=3;i>0;i--)
+        l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
+      l1a_l1s_com.Scell_info.buff_beacon[0] = l1ps.ILmin_beacon;
+
+      // Find min IL in FIFO
+      new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon, 4);
+
+      // Input levels are always stored with lna_on
+
+      // lna_off processing
+      new_calibrated_IL = (WORD16) (new_IL - l1ctl_encode_delta1(l1a_l1s_com.Scell_info.radio_freq) - l1ctl_encode_delta2(l1a_l1s_com.Scell_info.radio_freq));
+
+      if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
+
+      l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1),
+                       &(l1a_l1s_com.last_input_level[serving_index].lna_off),
+                       l1a_l1s_com.Scell_info.radio_freq);
+
+      l1a_l1s_com.last_input_level[serving_index].input_level = new_IL +
+        l1a_l1s_com.last_input_level[serving_index].lna_off *
+          l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq);
+
+    } // End of "beacon frequency input level updating"
+
+    // Daughter frequencies input level updating
+    //------------------------------------------
+
+    // If at least one block was correctly received
+    // (Note: ILs truncated to 240 so 255 isn't valid)
+    if (ILmin_correct != 255)
+    {
+      // Select the min input level found on correctly received blocks
+      l1a_l1s_com.Scell_info.transfer_meas.input_level = ILmin_correct;
+      l1ps.fn_select                                   = l1s.actual_time.fn;
+
+      // Algorithm switch to "TRACK" phase if it was in "SEARCH" phase
+      l1ps.phase                                       = TRACK;
+    }
+
+    // No block was correctly received
+    else
+    {
+      UWORD8 input_level_ref = l1a_l1s_com.Scell_info.transfer_meas.input_level
+        - l1a_l1s_com.Scell_info.transfer_meas.lna_off *
+          l1ctl_get_lna_att(radio_freq);
+      // SEARCH phase
+      if (l1ps.phase == SEARCH)
+      {
+        // If measured level superior to currently tracket level, switch to TRACK mode
+        if (input_level_ref > ILmin_not_correct)
+          l1ps.phase = TRACK;
+
+        // Select the min input level found on badly received blocks
+        l1a_l1s_com.Scell_info.transfer_meas.input_level = ILmin_not_correct;
+        l1ps.fn_select                                   = l1s.actual_time.fn;
+      }
+
+      // TRACK phase
+      else
+      {
+        // If the IL found on incorrect block is lower than current wanted IL
+        if (ILmin_not_correct < input_level_ref)
+        {
+          // Select the new IL
+          l1a_l1s_com.Scell_info.transfer_meas.input_level = ILmin_not_correct;
+          l1ps.fn_select = l1s.actual_time.fn;
+        }
+
+        // If the IL found on incorrect block is higher than current wanted IL
+        else
+        {
+          UWORD32 delta_fn;
+
+          // delta_fn processing for IL selection forgetting factor
+          delta_fn = l1s.actual_time.fn - l1ps.fn_select;
+
+          // MAX_FN modulo management
+          if (l1s.actual_time.fn < l1ps.fn_select)
+            delta_fn += MAX_FN;
+
+          // If the last selected IL is more recent than 72 frames
+          // 
+          //  |....|R...............................C|....| 
+          //        ^                               ^
+          //     fn_selected                    IL reset to -120
+          //  <-------------------------------------->
+          //                    312
+          // 306 = 312 - 4 (block_size) - 1 (Read phase fn delay) - 1 (Control phase fn advance)
+          if (delta_fn > 306)
+          {
+            WORD16 input_level;
+
+            // IL initialized to "beacon level - Pb"
+            input_level = (WORD16)
+              ((l1a_l1s_com.last_input_level[serving_index].input_level +
+                l1a_l1s_com.Scell_info.pb) -
+               (l1a_l1s_com.last_input_level[serving_index].lna_off *
+                l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq)));
+
+            if (input_level>INDEX_MAX) input_level = INDEX_MAX;    
+            l1a_l1s_com.Scell_info.transfer_meas.input_level = (UWORD8)input_level;
+            
+            l1ps.fn_select                                   = l1s.actual_time.fn;
+            // Returns to "SEARCH" phase
+            l1ps.phase                                       = SEARCH;
+          }
+          else
+          {
+            WORD16 input_level;
+
+            input_level = l1a_l1s_com.Scell_info.transfer_meas.input_level -
+              l1a_l1s_com.Scell_info.transfer_meas.lna_off *
+                l1ctl_get_lna_att(l1ps.read_param.radio_freq_for_lna);
+
+            if (input_level>INDEX_MAX) input_level = INDEX_MAX;
+
+            l1a_l1s_com.Scell_info.transfer_meas.input_level = (UWORD8)input_level;
+          }
+        } // End if the IL found on incorrect block is higher than current wanted IL 
+      } // End of "track phase"
+    } // End if no block correctly received
+
+    // lna_off processing
+    new_calibrated_IL = (WORD16) (l1a_l1s_com.Scell_info.transfer_meas.input_level - l1ctl_encode_delta1(l1ps.read_param.radio_freq_for_lna));
+    if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
+
+    l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1), &(l1a_l1s_com.Scell_info.transfer_meas.lna_off), l1ps.read_param.radio_freq_for_lna);
+
+    l1a_l1s_com.Scell_info.transfer_meas.input_level +=
+      l1a_l1s_com.Scell_info.transfer_meas.lna_off *
+        l1ctl_get_lna_att(l1ps.read_param.radio_freq_for_lna);
+  } // End if "burst = 3"
+
+} // End of "l1pctl_npc_agc_read"
+
+/*-------------------------------------------------------*/
+/* l1pctl_dpcma_agc_read()                               */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* ===========                                           */
+/* AGC algorithm in packet transfer used when the BTS    */
+/* use DOWNLINK POWER CONTROL mode A.                    */
+/* This function is used during the read phase of PDTCH: */
+/* 1- to determine the IL value for each timeslot in each*/
+/*    TDMA                                               */
+/* 2- to find the IL value to use for the next PDCH      */
+/*    block                                              */
+/*                                                       */
+/* Algorithm                                             */
+/* ---------                                             */
+/* For each timeslot i used for PDCH                     */
+/*   IL(i) = fct(used AGC, pm)                           */
+/*   if (beacon)                                         */
+/*     ILmax_beacon = max(ILmax_beacon, IL(i))           */
+/*   else                                                */
+/*     ILmax_others(i) = max(IL(i), ILmax_others(i))     */
+/*                                                       */
+/* If (burst_nb == 3)                                    */
+/*                                                       */
+/*   For each timeslot i used for PDCH                   */
+/*     if (CRC good) and                                 */
+/*        ((PR_MODE A) or (PR_MODE B and TFI good))      */
+/*       ILmax = max(ILmax, ILmax_others(i) + P0 + PR(i))*/
+/*                                                       */
+/*   ILmax=max(ILmax, ILmax_beacon)                      */
+/*   FIFO[beacon] updated with ILmax                     */
+/*   last_input_level[serving beacon] = max(FIFO[beacon])*/
+/*   transfer_meas = max(FIFO[beacon]) - P0 - 5          */
+/*                                                       */
+/*   Reset ILmax_others[8] and ILmax_beacon              */
+/*                                                       */
+/* WARNING: in the layer 1 code, input levels IL(l1) use */
+/*          format 7.1:                                  */
+/*               *********************                   */
+/*               * IL(l1) = - 2 x IL *                   */
+/*               *********************                   */
+/*          -> Reversed sign, reversed test conditions   */
+/*          -> max replaced by min                       */
+/*          ex: if IL -120 dBm, IL(l1) = 240             */
+/*                                                       */
+/* Parameters                                            */
+/* ----------                                            */
+/* "calibrated_IL[8]"                                    */
+/*   contains the IL found on timeslots                  */
+/*   used for PDCH/D. These ILs can be used to process   */
+/*   RXLEV values.                                       */
+/*                                                       */
+/* "*pdsp_db_r_ptr"                                      */
+/*   Pointer on the DSP DB Read page, used to extract    */
+/*   pm values, burst number and timeslot allocated      */
+/*   for downlink PDCH                                   */
+/*                                                       */
+/* "*pdsp_ndb_ptr"                                       */
+/*   Pointer on the DSP NDB page, used to extract the    */
+/*   CRC value for each decoded burst                    */
+/*                                                       */
+/* Global parameters                                     */
+/* -----------------                                     */
+/* "l1a_l1s_com.Scell_info.transfer_meas.input_level"    */
+/* "l1a_l1s_com.Scell_info.transfer_meas.lna_off"        */
+/*   Used to store the ILselected and the associated     */
+/*   lna_off value.                                      */
+/*                                                       */
+/* "l1a_l1s_com.last_input_level[freq. index]            */
+/*     .input_level                                      */
+/*     .lna_off"                                         */
+/*   Used to store the beacon input level and            */
+/*   the associated lna_off value.                       */
+/*                                                       */
+/* "l1ps.transfer_beacon_buf[4]"                         */
+/*   FIFO[beacon]                                        */
+/*                                                       */
+/* "l1ps.ILmin_beacon"                                   */
+/* "l1ps.ILmin_others[8]"                                */
+/*-------------------------------------------------------*/
+void l1pctl_dpcma_agc_read(UWORD8 calibrated_IL[8], T_DB_DSP_TO_MCU_GPRS *pdsp_db_r_ptr,
+                           T_NDB_MCU_DSP_GPRS *pdsp_ndb_ptr, UWORD8 pr_table[8])
+{
+  UWORD8       ts                         = 0;
+  UWORD8       rx_no                      = 0;
+  UWORD8       bit_mask                   = 0x80;
+  UWORD8       IL_norm_min                = 255;
+  WORD8        delta1_freq, delta2_freq;
+  WORD16       delta_drp_gain=0;
+  UWORD16      radio_freq, lna_value;
+  WORD16       used_agc;
+  WORD32       serving_index;
+#if (RF_FAM == 61)
+  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_GPRS;
+#endif
+
+#if(L1_FF_MULTIBAND == 0)
+  serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
+
+#else
+  serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
+#endif
+
+
+  // Control phase parameters: same AGC, radio_freq, lna_off used for all PDTCH
+  // ***************************************************************************
+
+  // Get radio_freq on which the downlink block was received
+  radio_freq     = l1a_l1s_com.dedic_set.radio_freq_dd;
+
+  // Compute calibration factors
+  delta1_freq = l1ctl_encode_delta1(radio_freq);
+  delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+  // Last known AGC (format F7.1)
+  used_agc = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
+
+  // LNA attenuation
+  lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
+
+  // Burst 0: Reset ILmin_beacon and ILmin_others
+  if(pdsp_db_r_ptr->d_burst_nb_gprs == 0)
+  {
+    l1ps.ILmin_beacon = 255;  // Not valid
+
+    for (ts = 0; ts < 8; ts++)
+    {
+       l1ps.ILmin_others[ts] = 255;  // Not valid
+    }
+  }
+
+  // IL processing for each received burst
+  // **************************************
+
+#if (RF_FAM == 61)
+  // DRP correction
+#if (L1_FF_MULTIBAND == 0)  
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn=radio_freq;
+#endif 
+
+   #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, used_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
+	 
+  // For each timeslot on which a burst was received
+  for(ts = 0; ts < 8; ts ++)
+  {
+    if(pdsp_db_r_ptr->d_task_d_gprs & bit_mask)
+    {
+      WORD16       current_IL, current_calibrated_IL;
+      UWORD8       pm;
+
+      // IL = fct(pm, last_known_agc, lna_value, g_magic)
+      //-------------------------------------------------
+
+      pm    = (UWORD8) ((pdsp_db_r_ptr->a_burst_pm_gprs[ts]   & 0xffff) >> 5);
+
+      // current_IL processing
+      if (0==pm)  // Check and filter illegal pm value by using last valid IL
+      {
+          current_IL = l1a_l1s_com.last_input_level[serving_index].input_level
+                       - lna_value;
+
+          if (radio_freq != l1a_l1s_com.Scell_info.radio_freq)
+            current_IL += (l1ps.read_param.dl_pwr_ctl.p0 + 10);
+      }
+      else
+	  {		  
+        current_IL = -(pm - (used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
+	  }
+
+      // Calibrated IL processing
+      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;
+         
+      calibrated_IL[ts] = (UWORD8)(current_calibrated_IL);  
+
+      // Keep the minimum IL
+      if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+      {
+        // Beacon frequency
+        l1ps.ILmin_beacon     = min((UWORD8) current_IL,l1ps.ILmin_beacon);
+      }
+      else
+      {
+        // Daughter frequency
+        l1ps.ILmin_others[ts] = min((UWORD8) current_IL, l1ps.ILmin_others[ts]);
+      }
+
+      // Input Level selection among ILmax found on each timeslot during the block (when burst = 3)
+      //-------------------------------------------------------------------------------------------
+
+      if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
+      {
+        // If CRC good
+        if (!(pdsp_ndb_ptr->a_dd_gprs[rx_no][0] & 0x0100))
+        {
+          // If ((PR_MODE A and TFI good) or (PR_MODE B)) AND PR != 0 [Not usable])
+          if (((l1ps.read_param.dl_pwr_ctl.pr_mode != 0) || (!(pr_table[ts] & 0x80)))
+              && ((pr_table[ts] & 0x1f) != 0))
+          {
+            if (l1ps.ILmin_others[ts] != 255)
+            {
+              UWORD8 IL_norm;
+
+              // IL normalization to beacon (ILnorm = ILmax_others(ts) - P0 - PR)
+              IL_norm = l1ps.ILmin_others[ts] - l1ps.read_param.dl_pwr_ctl.p0 - ((pr_table[ts] & 0x1f) << 1);
+
+              // Update IL_min with the minimum found IL
+              IL_norm_min = min(IL_norm, IL_norm_min);
+            }
+          }
+        } // End if "CRC good"
+
+      } // End if "burst = 3"
+
+      // Next downlink block
+      rx_no ++;
+
+    } // End if "timeslot used for downlink PDCH"
+
+    // Next timeslot
+    bit_mask >>= 1;
+
+  } // End for "each timeslot...."
+
+
+  // IL selection for the next block if burst = 3
+  // **********************************************
+
+  if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
+  {
+    UWORD8  i, new_IL;
+    UWORD16 input_level;
+    WORD16  new_calibrated_IL;
+
+    // Select the minimum IL between minimum IL found on daughter frequencies (normalized to beacon)
+    // and minimum IL found on the beacon
+    IL_norm_min = min(IL_norm_min, l1ps.ILmin_beacon);
+
+    // If a valid IL has been found
+    if (IL_norm_min != 255)
+    {
+      // FIFO management
+      for (i=3;i>0;i--)
+        l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
+
+      l1a_l1s_com.Scell_info.buff_beacon[0] = IL_norm_min;
+
+      // last_input_level[serving beacon] updating
+      //------------------------------------------
+
+      // Find min IL in FIFO
+      new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon,4);
+  
+      // Input levels are always stored with lna_on
+
+      // lna_off processing
+      new_calibrated_IL = (WORD16) (new_IL - l1ctl_encode_delta1(l1a_l1s_com.Scell_info.radio_freq) - l1ctl_encode_delta2(l1a_l1s_com.Scell_info.radio_freq));
+      if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
+
+      l1ctl_encode_lna((UWORD8)(new_calibrated_IL >> 1),
+                       &(l1a_l1s_com.last_input_level[serving_index].lna_off),
+                       l1a_l1s_com.Scell_info.radio_freq);
+
+      l1a_l1s_com.last_input_level[serving_index].input_level = new_IL +
+        l1a_l1s_com.last_input_level[serving_index].lna_off *
+          l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq);
+    }
+
+    // transfer_meas updating
+    //-----------------------
+
+    // IL = (min IL in FIFO) + P0 + 10 (PR = 5 format 7.1)
+    // Input levels are always stored with lna_on
+    input_level = l1a_l1s_com.last_input_level[serving_index].input_level
+                  - l1a_l1s_com.last_input_level[serving_index].lna_off *
+                      l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq)
+                  + l1ps.read_param.dl_pwr_ctl.p0 + 10;
+  
+    // IL_2_AGC_xx array size 
+    if (input_level>INDEX_MAX) input_level = INDEX_MAX;
+
+    // lna_off processing
+    new_calibrated_IL = (WORD16) (input_level - l1ctl_encode_delta1(l1ps.read_param.radio_freq_for_lna));
+
+    if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
+
+    l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1), &(l1a_l1s_com.Scell_info.transfer_meas.lna_off), l1ps.read_param.radio_freq_for_lna);
+
+    l1a_l1s_com.Scell_info.transfer_meas.input_level = input_level +
+      l1a_l1s_com.Scell_info.transfer_meas.lna_off *
+        l1ctl_get_lna_att(l1ps.read_param.radio_freq_for_lna);
+  } // End if "burst = 3"
+
+} // End of "l1pctl_dpcma_agc_read"
+
+/*-------------------------------------------------------*/
+/* l1pctl_dpcmb_agc_read()                               */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* ===========                                           */
+/* AGC algorithm in packet transfer used when the BTS    */
+/* use DOWNLINK POWER CONTROL mode B.                    */
+/* This function is used during the read phase of PDTCH: */
+/* 1- to determine the IL value for each timeslot in each*/
+/*    TDMA                                               */
+/* 2- to find the IL value to use for the next PDCH      */
+/*    block                                              */
+/*                                                       */
+/* Algorithm                                             */
+/* ---------                                             */
+/* For each timeslot i used for PDCH                     */
+/*   IL(i) = fct(used AGC, pm)                           */
+/*   if (beacon)                                         */
+/*     ILmax_beacon = max(ILmax_beacon, IL(i))           */
+/*   else                                                */
+/*     ILmax_others(i) = max(IL(i), ILmax_others(i))     */
+/*                                                       */
+/* If (burst_nb == 3)                                    */
+/*                                                       */
+/*   For each timeslot i used for PDCH                   */
+/*     if (CRC good)                                     */
+/*       if (TFI good) last_PR_good = PR(i)              */
+/*       if ((PR_MODE A) or (PR_MODE B and TFI good))    */
+/*         ILmax = max(ILmax, ILmax_others(i)            */
+/*                 + P0 + PR(i))                         */
+/*                                                       */
+/*   ILmax=max(ILmax, ILmax_beacon)                      */
+/*   FIFO[beacon] updated with ILmax                     */
+/*   last_input_level[serving beacon] = max(FIFO[beacon])*/
+/*   transfer_meas = max(FIFO[beacon]) - last_PR_good    */
+/*                                                       */
+/*   Reset ILmax_others[8] and ILmax_beacon              */
+/*                                                       */
+/* WARNING: in the layer 1 code, input levels IL(l1) use */
+/*          format 7.1:                                  */
+/*               *********************                   */
+/*               * IL(l1) = - 2 x IL *                   */
+/*               *********************                   */
+/*          -> Reversed sign, reversed test conditions   */
+/*          -> max replaced by min                       */
+/*          ex: if IL -120 dBm, IL(l1) = 240             */
+/*                                                       */
+/* Parameters                                            */
+/* ----------                                            */
+/* "calibrated_IL[8]"                                    */
+/*   contains the IL found on timeslots                  */
+/*   used for PDCH/D. These ILs can be used to process   */
+/*   RXLEV values.                                       */
+/*                                                       */
+/* "*pdsp_db_r_ptr"                                      */
+/*   Pointer on the DSP DB Read page, used to extract    */
+/*   pm values, burst number and timeslot allocated      */
+/*   for downlink PDCH                                   */
+/*                                                       */
+/* "*pdsp_ndb_ptr"                                       */
+/*   Pointer on the DSP NDB page, used to extract the    */
+/*   CRC value for each decoded burst                    */
+/*                                                       */
+/* Global parameters                                     */
+/* -----------------                                     */
+/* "l1a_l1s_com.Scell_info.transfer_meas.input_level"    */
+/* "l1a_l1s_com.Scell_info.transfer_meas.lna_off"        */
+/*   Used to store the ILselected and the associated     */
+/*   lna_off value.                                      */
+/*                                                       */
+/* "l1a_l1s_com.last_input_level[freq. index]            */
+/*     .input_level                                      */
+/*     .lna_off"                                         */
+/*   Used to store the beacon input level and            */
+/*   the associated lna_off value.                       */
+/*                                                       */
+/* "l1ps.transfer_beacon_buf[4]"                         */
+/*   FIFO[beacon]                                        */
+/*                                                       */
+/* "l1ps.ILmin_beacon"                                   */
+/* "l1ps.ILmin_others[8]"                                */
+/*-------------------------------------------------------*/
+void l1pctl_dpcmb_agc_read(UWORD8 calibrated_IL[8], T_DB_DSP_TO_MCU_GPRS *pdsp_db_r_ptr,
+                           T_NDB_MCU_DSP_GPRS *pdsp_ndb_ptr, UWORD8 pr_table[8])
+{
+  UWORD8       ts                         = 0;
+  UWORD8       rx_no                      = 0;
+  UWORD8       bit_mask                   = 0x80;
+  UWORD8       IL_norm_min                = 255;
+  WORD8        delta1_freq, delta2_freq;
+  WORD16       delta_drp_gain=0;
+  UWORD16      radio_freq, lna_value;
+  WORD16       used_agc;
+  WORD32       serving_index;
+#if (RF_FAM == 61)
+  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_GPRS;
+#endif
+
+#if(L1_FF_MULTIBAND == 0)
+  serving_index = l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset;
+#else
+  serving_index = l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
+#endif
+
+
+  // Control phase parameters: same AGC, radio_freq, lna_off used for all PDTCH
+  // ***************************************************************************
+
+  // Get radio_freq on which the downlink block was received
+  radio_freq     = l1a_l1s_com.dedic_set.radio_freq_dd;
+
+  // Compute calibration factors
+  delta1_freq = l1ctl_encode_delta1(radio_freq);
+  delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+  // Last known AGC (format F7.1)
+  used_agc = (Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.Scell_used_IL_dd.input_level >> 1, MAX_ID)) << 1;
+
+  // LNA attenuation
+  lna_value = l1a_l1s_com.Scell_used_IL_dd.lna_off * l1ctl_get_lna_att(radio_freq);
+
+  // Burst 0: Reset ILmin_beacon and ILmin_others
+  if(pdsp_db_r_ptr->d_burst_nb_gprs == 0)
+  {
+    l1ps.ILmin_beacon = 255;  // Not valid
+
+    for (ts = 0; ts < 8; ts++)
+    {
+       l1ps.ILmin_others[ts] = 255;  // Not valid
+    }
+  }
+
+  // IL processing for each received burst
+  // **************************************
+
+  // For each timeslot on which a burst was received
+  for(ts = 0; ts < 8; ts ++)
+  {
+    if(pdsp_db_r_ptr->d_task_d_gprs & bit_mask)
+    {
+      WORD16       current_IL, current_calibrated_IL;
+      UWORD8       pm;
+
+      // IL = fct(pm, last_known_agc, lna_value, g_magic)
+      //-------------------------------------------------
+
+      pm    = (UWORD8) ((pdsp_db_r_ptr->a_burst_pm_gprs[ts]   & 0xffff) >> 5);
+
+      // current_IL processing
+      if (0==pm)  // Check and filter illegal pm value by using last valid IL
+      {
+          current_IL = l1a_l1s_com.last_input_level[serving_index].input_level
+                       - lna_value;
+
+          if (radio_freq != l1a_l1s_com.Scell_info.radio_freq)
+            current_IL += (l1ps.last_PR_good);
+      }
+      else
+      {
+
+#if (RF_FAM == 61)
+	    // DRP correction
+#if (L1_FF_MULTIBAND == 0)  
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn=radio_freq;
+#endif 
+
+   #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, used_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
+
+        current_IL = -(pm - ( used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
+      }
+
+      // Calibrated IL processing
+      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;
+         
+      calibrated_IL[ts] = (UWORD8)(current_calibrated_IL);  
+
+      // Keep the minimum IL
+      if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+      {
+        // Beacon frequency
+        l1ps.ILmin_beacon     = min((UWORD8) current_IL,l1ps.ILmin_beacon);
+      }
+      else
+      {
+        // Daughter frequency
+        l1ps.ILmin_others[ts] = min((UWORD8) current_IL, l1ps.ILmin_others[ts]);
+      }
+
+      // Input Level selection among ILmax found on each timeslot during the block (when burst = 3)
+      //-------------------------------------------------------------------------------------------
+
+      if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
+      {
+        // If CRC good
+        if (!(pdsp_ndb_ptr->a_dd_gprs[rx_no][0] & 0x0100))
+        {
+          // If ((PR_MODE A and TFI good) or (PR_MODE B))
+          if ((l1ps.read_param.dl_pwr_ctl.pr_mode != 0) || (!(pr_table[ts] & 0x80)))
+          {
+
+            // If TFI good
+            if (!(pr_table[ts] & 0x80))
+            {
+              // Memorize decoded PR
+              l1ps.last_PR_good = ((pr_table[ts] & 0x1f) << 1);
+            }            
+
+            if (l1ps.ILmin_others[ts] != 255)
+            {
+              UWORD8 IL_norm;
+
+              // IL normalization to beacon (ILnorm = ILmax_others(ts) - PR)
+              IL_norm = l1ps.ILmin_others[ts] - ((pr_table[ts] & 0x1f) << 1);
+
+              // Update IL_min with the minimum found IL
+              IL_norm_min = min(IL_norm, IL_norm_min);
+            }
+          }
+        } // End if "CRC good"
+
+      } // End if "burst = 3"
+
+      // Next downlink block
+      rx_no ++;
+
+    } // End if "timeslot used for downlink PDCH"
+
+    // Next timeslot
+    bit_mask >>= 1;
+
+  } // End for "each timeslot...."
+
+
+  // IL selection for the next block if burst = 3
+  // **********************************************
+
+  if(pdsp_db_r_ptr->d_burst_nb_gprs == 3)
+  {
+    UWORD8  i, new_IL;
+    UWORD16 input_level;
+    WORD16  new_calibrated_IL;
+
+    // Select the minimum IL between minimum IL found on daughter frequencies (normalized to beacon)
+    // and minimum IL found on the beacon
+    IL_norm_min = min(IL_norm_min, l1ps.ILmin_beacon);
+
+    // If a valid IL has been found
+    if (IL_norm_min != 255)
+    {
+      // FIFO management
+      for (i=3;i>0;i--)
+        l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
+
+      l1a_l1s_com.Scell_info.buff_beacon[0] = IL_norm_min;
+
+      // last_input_level[serving beacon] updating
+      //------------------------------------------
+
+      // Find min IL in FIFO
+      new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon,4);
+  
+      // Input levels are always stored with lna_on
+
+      // lna_off processing
+      new_calibrated_IL = (WORD16) (new_IL - l1ctl_encode_delta1(l1a_l1s_com.Scell_info.radio_freq) - l1ctl_encode_delta2(l1a_l1s_com.Scell_info.radio_freq));
+
+      if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
+
+      l1ctl_encode_lna((UWORD8)(new_calibrated_IL >> 1),
+                       &(l1a_l1s_com.last_input_level[serving_index].lna_off),
+                       l1a_l1s_com.Scell_info.radio_freq);
+
+      l1a_l1s_com.last_input_level[serving_index].input_level = new_IL +
+        l1a_l1s_com.last_input_level[serving_index].lna_off *
+          l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq);
+    }
+
+    // transfer_meas updating
+    //-----------------------
+
+    // IL = (min IL in FIFO) + PR (Middle of the range specified by the last decoded PR with CRC and TFI good)
+    // Input levels are always stored with lna_on
+    input_level = l1a_l1s_com.last_input_level[serving_index].input_level
+                  - l1a_l1s_com.last_input_level[serving_index].lna_off *
+                    l1ctl_get_lna_att(l1a_l1s_com.Scell_info.radio_freq)
+                  + l1ps.last_PR_good;
+
+    // IL_2_AGC_xx array size 
+    if (input_level>INDEX_MAX) input_level = INDEX_MAX;
+
+    // lna_off processing
+    new_calibrated_IL = (WORD16) (input_level - l1ctl_encode_delta1(l1ps.read_param.radio_freq_for_lna));
+    
+    if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
+
+    l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1), &(l1a_l1s_com.Scell_info.transfer_meas.lna_off), l1ps.read_param.radio_freq_for_lna);
+
+    l1a_l1s_com.Scell_info.transfer_meas.input_level = input_level +
+      l1a_l1s_com.Scell_info.transfer_meas.lna_off *
+        l1ctl_get_lna_att(l1ps.read_param.radio_freq_for_lna);
+
+  } // End if "burst = 3"
+
+} // End of "l1pctl_dpcmb_agc_read"
+
+/*-------------------------------------------------------*/
+/* l1pctl_pgc()                                          */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/* =============                                         */
+/*  This function is used in packet transfer mode for the*/
+/*  Read phase of power measurements. It permits to:     */
+/*  - Process the IL value in function of the Pm and AGC */
+/*    used                                               */
+/*  - Update the FIFO[beacon] used in packet transfer AGC*/
+/*    algorithms                                         */
+/*  - Update last_input_level                            */
+/*                                                       */
+/* WARNING: in the layer 1 code, input levels IL(l1) use */
+/*          format 7.1:                                  */
+/*               *********************                   */
+/*               * IL(l1) = - 2 x IL *                   */
+/*               *********************                   */
+/*          -> Reversed sign, reversed test conditions   */
+/*          -> max replaced by min                       */
+/*          ex: if IL -120 dBm, IL(l1) = 240             */
+/*-------------------------------------------------------*/
+UWORD8 l1pctl_pgc(UWORD8 pm, UWORD8 last_known_il, UWORD8 lna_off, UWORD16 radio_freq)
+{
+  UWORD8       i, new_IL;
+  WORD8        delta1_freq, delta2_freq;
+  WORD16       delta_drp_gain=0;
+  UWORD16      lna_value;
+  WORD16       used_agc, current_IL, current_calibrated_IL, new_calibrated_IL;
+  WORD32       index;
+#if (RF_FAM == 61)
+  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_GPRS;
+#endif
+
+  // Calibration factors
+  delta1_freq = l1ctl_encode_delta1(radio_freq);
+  delta2_freq = l1ctl_encode_delta2(radio_freq);
+
+  // initialize index
+#if(L1_FF_MULTIBAND == 0)
+  index = radio_freq - l1_config.std.radio_freq_index_offset;
+
+#else
+  index = l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
+#endif
+
+
+  // LNA attenuation
+  lna_value = lna_off * l1ctl_get_lna_att(radio_freq);
+
+  // Used AGC in the control phase (format F7.1)
+  used_agc = (Cust_get_agc_from_IL(radio_freq, last_known_il >> 1, PWR_ID)) << 1;
+
+
+#if (RF_FAM == 61)
+  // DRP correction
+#if (L1_FF_MULTIBAND == 0)  
+  arfcn = Convert_l1_radio_freq(radio_freq);
+#else
+  arfcn=radio_freq;
+#endif 
+
+   #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        
+    
+     lna_off = l1a_l1s_com.Scell_used_IL_dd.lna_off;
+     delta_drp_gain = drp_gain_correction(arfcn, lna_off, used_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 - (used_agc - delta_drp_gain) + lna_value - l1ctl_get_g_magic(radio_freq));
+
+  // Calibrated IL processing
+  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;
+
+  // if radio freq is the serving beacon
+  //------------------------------------
+  if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+  {
+    // FIFO management
+    for (i=3;i>0;i--)
+      l1a_l1s_com.Scell_info.buff_beacon[i] = l1a_l1s_com.Scell_info.buff_beacon[i-1];
+    l1a_l1s_com.Scell_info.buff_beacon[0] = (UWORD8) current_IL;
+
+      // Find min IL in FIFO
+    new_IL = l1ctl_find_max(l1a_l1s_com.Scell_info.buff_beacon,4);
+
+    // lna_off processing
+    new_calibrated_IL = (WORD16) (new_IL - delta1_freq - delta2_freq);
+    if (new_calibrated_IL>INDEX_MAX) new_calibrated_IL = INDEX_MAX;
+
+    l1ctl_encode_lna((UWORD8)(new_calibrated_IL>>1),
+                     &(l1a_l1s_com.last_input_level[index].lna_off),
+                     radio_freq);
+
+    l1a_l1s_com.last_input_level[index].input_level = new_IL +
+      l1a_l1s_com.last_input_level[index].lna_off *
+        l1ctl_get_lna_att(radio_freq);
+  }
+
+  // if radio freq is a neighbor beacon
+  //-----------------------------------
+  else
+  {
+    // Update last_input_level (IL with LNA ON)
+    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 = current_IL +
+      l1a_l1s_com.last_input_level[index].lna_off *
+        l1ctl_get_lna_att(radio_freq);
+  }
+
+  return((UWORD8)current_calibrated_IL);
+
+} // End of "l1pctl_pgc"
+#endif