diff src/cs/layer1/cfile/l1_cmplx.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 edcb8364d45b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cs/layer1/cfile/l1_cmplx.c	Fri Oct 16 06:23:26 2020 +0000
@@ -0,0 +1,12071 @@
+/************* Revision Controle System Header *************
+ *                  GSM Layer 1 software
+ * L1_CMPLX.C
+ *
+ *        Filename l1_cmplx.c
+ *  Copyright 2003 (C) Texas Instruments
+ *
+ ************* Revision Controle System Header *************/
+
+#define  L1_CMPLX_C
+
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+#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"
+  #include <l1_trace.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 "l2_l3.h"
+    #include "hw_debug.h"
+  #endif
+
+  #if L1_GPRS
+    #include "l1p_cons.h"
+    #include "l1p_msgt.h"
+    #include "l1p_deft.h"
+    #include "l1p_vare.h"
+    #include "l1p_sign.h"
+  #endif
+
+  #include "sim_cons.h"
+  #include "sim_def.h"
+  extern T_hw FAR hw;
+
+#else
+  #include "abb.h"
+  #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"
+    #if (RF_FAM == 60)
+      #include "pld.h"
+    #endif
+  #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"
+  #include "l1_trace.h"
+  #include "l1_ctl.h"
+  #if L2_L3_SIMUL
+    #include "l2_l3.h"
+    #include "hw_debug.h"
+    #include "l2_simul.h"
+  #endif
+
+  #if L1_GPRS
+    #include "l1p_cons.h"
+    #include "l1p_msgt.h"
+    #include "l1p_deft.h"
+    #include "l1p_vare.h"
+    #include "l1p_sign.h"
+  #endif
+#endif
+
+#if(RF_FAM == 61)
+  #include "l1_rf61.h"
+  #include "tpudrv61.h"
+#endif
+#include "l1_ctl.h"
+
+#if W_A_DSP1
+extern UWORD8 old_sacch_DSP_bug;
+#endif
+
+#if TESTMODE
+  #include "l1tm_msgty.h"
+  #include "l1tm_signa.h"
+  #include "l1tm_varex.h"
+  void l1tm_fill_burst (UWORD16 pattern, UWORD16 *TM_ul_data);
+  #if (ANLG_FAM != 11)
+  void ABB_Write_Uplink_Data(SYS_UWORD16 *TM_ul_data);
+  #else
+  // TODO
+  #endif
+#endif
+
+#if ((TRACE_TYPE==2) || (TRACE_TYPE==3))
+  extern void L1_trace_string(char *s);
+  extern void L1_trace_char  (char s);
+#endif
+
+#if (GSM_IDLE_RAM != 0)
+#if (OP_L1_STANDALONE == 1)
+#include "csmi_simul.h"
+#else
+#include "csmi/sleep.h"
+#endif
+#endif
+
+#if (RF_FAM == 61)
+  #include "l1_rf61.h"
+#if (DRP_FW_EXT==1)
+  #include "l1_drp_inc.h"
+#else
+  #include "drp_drive.h"
+#endif
+#endif
+
+/*-------------------------------------------------------*/
+/* Prototypes of external functions used in this file.   */
+/*-------------------------------------------------------*/
+void l1dmacro_synchro        (UWORD32 when, UWORD32 value);
+
+void l1dmacro_offset         (UWORD32 offset_value, WORD32 relative_time);
+void l1dmacro_rx_synth       (UWORD16 arfcn);
+void l1dmacro_agc            (UWORD16 arfcn,WORD8 gain, UWORD8 lna
+	                                   #if (RF_FAM == 61)
+                                            ,UWORD8 if_ctl
+						#endif
+							   );
+void l1dmacro_rx_nb          (UWORD16 arfcn);
+void l1dmacro_afc            (UWORD16 afc_value, UWORD8 win_id);
+void l1dmacro_adc_read_rx    (void);
+#if (CODE_VERSION != SIMULATION)
+#if (L1_MADC_ON ==1)
+void l1dmacro_adc_read_rx_cs_mode0(void);
+#endif
+#endif
+
+#if (RF_FAM != 61)
+void l1dtpu_serv_rx_nb       (UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off,
+                              UWORD32 synchro_serv,UWORD32 new_offset,BOOL change_offset, UWORD8 adc_active);
+#endif
+
+#if (RF_FAM == 61)
+void l1dtpu_serv_rx_nb       (UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off,
+                              UWORD32 synchro_serv,UWORD32 new_offset,BOOL change_offset,
+                              UWORD8 adc_active, UWORD8 csf_filter_choice, UWORD8 if_ctl
+#if (NEW_SNR_THRESHOLD == 1)
+                                  ,UWORD8 saic_flag
+#endif /* NEW_SNR_THRESHOLD*/
+                              );
+#endif /* RF_FAM == 61*/
+
+void l1ddsp_meas_read        (UWORD8 nbmeas, UWORD8 *pm);
+
+#if L1_GPRS
+void l1pddsp_synchro         (UWORD8 switch_mode, UWORD8  camp_timeslot);
+void l1pddsp_load_bcchn_task (UWORD8 tsq,UWORD16 radio_freq);
+void l1pddsp_meas_ctrl       (UWORD8 nbmeas, UWORD8 pm_pos);
+void l1pddsp_meas_read       (UWORD8 nbmeas, UWORD8 *a_pm);
+#if FF_L1_IT_DSP_USF
+void l1pddsp_idle_rx_nb      (UWORD8 burst_nb, UWORD8 tsq, UWORD16 radio_freq,
+                              UWORD8 timeslot_no, BOOL ptcch_dl, BOOL usf_interrupt);
+#else
+void l1pddsp_idle_rx_nb      (UWORD8 burst_nb, UWORD8 tsq, UWORD16 radio_freq,
+                              UWORD8 timeslot_no, BOOL ptcch_dl);
+#endif
+#endif
+
+#if (RF_FAM == 61)
+void   cust_get_if_dco_ctl_algo (UWORD16* dco_algo_ctl, UWORD8* if_ctl,
+  UWORD8 input_level_flag, UWORD8 input_level, UWORD16 radio_freq, UWORD8 if_threshold);
+#endif
+
+
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+
+extern UWORD16 toa_tab[4];
+
+
+#if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0))  // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START         // KEEP IN EXTERNAL MEM otherwise
+  UWORD16 toa_tab[4];
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+#endif
+
+
+#if TESTMODE
+  UWORD16 TM_ul_data[16]; //Uplink data to be stored into Omega Uplink buffer
+#endif
+#if ((REL99 == 1) && (FF_BHO == 1))
+  void l1dtpu_neig_fbsb(UWORD16 radio_freq, WORD8 agc, UWORD8 lna_off); // Blind handover
+#endif
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_hwtest()                                     */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* task HWTEST. This function check the checksum of the  */
+/* DSP.                                                  */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP        */
+/*   interface. This is used mainly to swap then the     */
+/*   com. page at the end of a control frame.            */
+/*   -> set CTRL_TEST bit in the register.               */
+/*-------------------------------------------------------*/
+void l1s_ctrl_hwtest(UWORD8 task, UWORD8 param2)
+{
+  // Flag DSP programmation.
+  // ************************
+  l1ddsp_load_monit_task(DSP_TASK_CODE[task],0);
+
+  // Set "CTRL_TEST" flag in the controle flag register.
+  l1s.dsp_ctrl_reg |= CTRL_TEST;
+}
+
+/*-------------------------------------------------------*/
+/* l1s_read_hwtest()                                     */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* task HWTEST. This function read the checksum of the   */
+/* DSP.                                                  */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1a_l1s_com.l1s_en_task"                             */
+/*   L1S task enable bit register.                       */
+/*   -> disable HWTEST task.                             */
+/*                                                       */
+/* "l1s.task_status[HWTEST].current_status"              */
+/*   current task status for HWTEST task.                */
+/*   -> disactivate HWTEST task.                         */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_read_hwtest(UWORD8 task, UWORD8 param2)
+{
+  #if (TRACE_TYPE==2) || (TRACE_TYPE==3)//OMAPS00090550
+  UWORD32 flash_type = 0;
+  #endif
+  xSignalHeaderRec *msg;
+
+  #if (CODE_VERSION != SIMULATION)
+    #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
+      l1s.version.dsp_code_version  = l1s_dsp_com.dsp_ndb_ptr->d_version_number1;
+      l1s.version.dsp_checksum      = (UWORD16) (l1s_dsp_com.dsp_db_r_ptr->a_pm[1] & 0xffff);
+      l1s.version.dsp_patch_version = l1s_dsp_com.dsp_ndb_ptr->d_version_number2;
+    #else
+      l1s.version.dsp_code_version  = (UWORD16) (l1s_dsp_com.dsp_db_r_ptr->a_pm[0] & 0xffff);
+      l1s.version.dsp_checksum      = (UWORD16) (l1s_dsp_com.dsp_db_r_ptr->a_pm[1] & 0xffff);
+    //l1s.version.dsp_patch_version = (UWORD16) (l1s_dsp_com.dsp_db_r_ptr->a_pm[2] & 0xffff);
+      l1s.version.dsp_patch_version = (UWORD32) *((API *) SC_CHKSUM_VER);
+      //NOTE: dsp_patch_version is duplicated in d_version_number
+    #endif
+  #endif // NOT_SIMULATION
+
+  // send L1_INIT_HW_CON to L1A...
+  msg = os_alloc_sig(sizeof(T_TST_TEST_HW_CON));
+  DEBUGMSG(status,NU_ALLOC_ERR)
+  msg->SignalCode = L1_TEST_HW_INFO;
+
+  // added for the new naming convention
+  ((T_TST_TEST_HW_CON*)(msg->SigP))->dsp_code_version  = l1s.version.dsp_code_version;
+  ((T_TST_TEST_HW_CON*)(msg->SigP))->dsp_checksum      = l1s.version.dsp_checksum;
+  ((T_TST_TEST_HW_CON*)(msg->SigP))->dsp_patch_version = l1s.version.dsp_patch_version;
+  ((T_TST_TEST_HW_CON*)(msg->SigP))->mcu_tcs_program_release = l1s.version.mcu_tcs_program_release;
+  ((T_TST_TEST_HW_CON*)(msg->SigP))->mcu_tcs_official        = l1s.version.mcu_tcs_official;
+  ((T_TST_TEST_HW_CON*)(msg->SigP))->mcu_tcs_internal        = l1s.version.mcu_tcs_internal;
+
+  os_send_sig(msg, L1C1_QUEUE);
+
+  DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+
+  #if (TRACE_TYPE==2) || (TRACE_TYPE==3)
+    uart_trace_checksum(flash_type);
+  #endif
+
+  // HWTEST task is completed, make it INACTIVE.
+  // It is a 1 shot task, it must be also disabled in L1S.
+  l1s.task_status[task].current_status = INACTIVE;
+  l1a_l1s_com.l1s_en_task[HWTEST] = TASK_DISABLED;
+
+  // Flag the use of the MCU/DSP dual page read interface.
+  // ******************************************************
+
+  // Set flag used to change the read page at the end of "l1_synch" only.
+  l1s_dsp_com.dsp_r_page_used = TRUE;
+}
+
+/*-------------------------------------------------------*/
+/* l1s_new_synchro()                                     */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* task SYNCHRO. This function mainly adapts the L1/TPU  */
+/* timebase to a new setting. This new setting can come  */
+/* from a timeslot change or a full change of serving    */
+/* cell. This change is a big discontinuity, it requires */
+/* some global variable reset. Here is a summary of the  */
+/* execution:                                            */
+/*                                                       */
+/*  - Traces for debug.                                  */
+/*  - Disables the L1S task SYNCHRO (SYNCHRO is 1 shot)  */
+/*    and make it inactive (current status set to        */
+/*    INACTIVE).                                         */
+/*  - Compute timeshift.                                 */
+/*  - Program serving cell fine timeshift for TPU.       */
+/*  - Execute serving cell frame number timeshift.       */
+/*  - Flag TPU programmation.                            */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1a_l1s_com.tn_difference"                           */
+/*   timeslot difference between new and old setting.    */
+/*   This is used when timeshift is due to a change of   */
+/*   timeslot but on the same serving cell.              */
+/*   -> reset to 0.                                      */
+/*                                                       */
+/* "l1a_l1s_com.Scell_inf.time_alignmt"                  */
+/*   fine time difference between current setting and    */
+/*   new setting to achieve.                             */
+/*   -> reset to 0.                                      */
+/*                                                       */
+/* "l1a_l1s_com.Scell_inf.fn_offset"                     */
+/*   frame number offset between current setting and new */
+/*   setting to achieve.                                 */
+/*   -> reset to 0.                                      */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for SYNCHRO and OFFSET register in the TPU    */
+/*   for current serving cell setting.                   */
+/*   -> set to the new setting.                          */
+/*                                                       */
+/* "l1a_l1s_com.l1s_en_task"                             */
+/*   L1S task enable bit register.                       */
+/*   -> disable SYNCHRO task.                            */
+/*                                                       */
+/* "l1s.task_status[SYNCHRO].current_status"             */
+/*   current task status for SYNCHRO task.               */
+/*   -> disactivate SYNCHRO task.                        */
+/*                                                       */
+/* "l1s.actual_time, l1s.next_time"                      */
+/*   frame number and derived numbers for current frame  */
+/*   and next frame.                                     */
+/*   -> update to new setting.                           */
+/*                                                       */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU        */
+/*   interface. This is used mainly to swap then the     */
+/*   com. page at the end of a control frame.            */
+/*   -> set CTRL_SYNC bit in the register.               */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_new_synchro(UWORD8 param1, UWORD8 param2)
+{
+  WORD32       offset;
+  UWORD32      tpu_offset_shift;
+  T_CELL_INFO *sptr = &(l1a_l1s_com.Scell_info);
+
+  // Traces for debug mainly used during L1 simulation.
+  // ***************************************************
+
+  #if (TRACE_TYPE!=0)
+    trace_fct(CST_L1S_NEW_SYNCHRO, l1a_l1s_com.Scell_info.radio_freq);
+  #endif
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_tpu(dltsk_trace[SYNCHRO].name);
+  #endif
+
+  // Disable SYNCHRO task.
+  // **********************
+
+  // SYNCHRO task is a one shot task enabled by L1A and
+  // disables after its execution in L1S. Here is the disabling.
+  l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_DISABLED;
+  l1s.task_status[SYNCHRO].current_status = INACTIVE;
+
+  #if 0	/* FreeCalypso TCS211 reconstruction */
+  #if L1_GPRS
+  //Change of mode when synchro is executed when switching from idle to transfer
+  //In this case, PDTCH task has been enabled in transfer mode manager, but the mode is still not PACKET_TRANSFER_MODE
+  if((l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED) && (l1a_l1s_com.mode != PACKET_TRANSFER_MODE))
+    l1a_l1s_com.mode = PACKET_TRANSFER_MODE;
+  #endif
+  #endif
+
+  // Compute timeshift.
+  // *******************
+
+  if(l1a_l1s_com.tn_difference < 0)
+  // "tn_difference" field is not 0 only when the new serving cell is the same
+  // as the old one. Therefore, we are just changing the timeslot.
+  // If the new timeslot if lower than the old one then the serving FN must
+  // be incremented by 1. To do so, we use the "fn_offset" field which is
+  // loaded with "1".
+  {
+    sptr->fn_offset += 1;
+    l1a_l1s_com.tn_difference += 8;
+  }
+
+  // update the TPU with the new TOA if necessary
+  l1ctl_update_TPU_with_toa();
+
+  // Manage shifting value for TPU offset register...
+  // if staying on the same serving cell but changing the RX timeslot (CCCH_GROUP or timeslot),
+  // then the "timeslot difference" between old and new configuration is given in "tn_difference",
+  // else "tn_difference" must contain 0.
+  tpu_offset_shift = (sptr->time_alignmt) + (l1a_l1s_com.tn_difference * BP_DURATION);
+
+  // Clear "timeslot difference" parameter.
+  l1a_l1s_com.tn_difference = 0;
+
+  // Get FN difference between actual synchro and the one we are going to switch to.
+  // The switch (slide of OFFSET and REG_COM_INT) is performed at the time "OFFSET - epsilon".
+  // If "tpu_offset_shift" is greater than "OFFSET - epsilon (called SWITCH_TIME)" then
+  // the next interrupt is going to occur very soon after the switch, and new FN comes directly
+  // from current FN + the "fn_offset" (minus 1 since FN has just been incremented). Else 1 frame
+  // is missed and new FN comes from "fn_offset + 1" (minus 1 since FN has just been incremented).
+  offset = sptr->fn_offset - 1;
+  if(tpu_offset_shift <= SWITCH_TIME) offset++;
+  #if L1_FF_WA_OMAPS00099442
+    if(l1a_l1s_com.change_tpu_offset_flag == TRUE){
+      l1s.tpu_offset = (l1s.tpu_offset + (TPU_CLOCK_RANGE >> 1) ) % TPU_CLOCK_RANGE;
+      l1a_l1s_com.change_tpu_offset_flag = FALSE;
+    }
+  #endif
+
+  // Shift "tpu_offset" accordingly to the computed "tpu_offset_shift" value.
+  // Rem: "%" is required since the result value can be greater than 2*TPU_CLOCK_RANGE.
+  l1s.tpu_offset = (l1s.tpu_offset + tpu_offset_shift) % TPU_CLOCK_RANGE;
+
+  // Program serving cell fine timeshift for TPU.
+  // *********************************************
+
+  // Store the fine time shifting program in the MCU/TPU com.
+  l1dmacro_synchro(SWITCH_TIME, l1s.tpu_offset);
+
+  // Execute serving cell frame number timeshift.
+  // *********************************************
+
+  // Slide frame numbers and derived numbers to jump on new setting.
+  l1s_increment_time(&(l1s.actual_time), offset); // Update actual_time.
+
+  l1s.next_time      = l1s.actual_time;
+  l1s_increment_time(&(l1s.next_time), 1);        // Next time is actual_time + 1
+
+  #if L1_GPRS
+    l1s.next_plus_time = l1s.next_time;
+    l1s_increment_time(&(l1s.next_plus_time), 1); // Next_plus time is next_time + 1
+  #endif
+
+  #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+    trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1));//OMAPS00090550
+  #endif
+
+  #if (TOA_ALGO == 2)
+    // Fix in case of handovers and Test Mode
+    l1s.toa_var.toa_update_fn = l1s.toa_var.toa_update_fn + offset;
+    if(l1s.toa_var.toa_update_fn >= MAX_FN)
+    {
+      l1s.toa_var.toa_update_fn-= MAX_FN;
+    }
+  #endif
+
+
+
+  // the FN was changed: it could have an impact on the gauging algorithm
+        //Nina modify to save power, not forbid deep sleep, only force gauging in next paging
+	/* FreeCalypso Frankenstein: see l1_async.c regarding Nina's change */
+#define	NINA_ADDED	0
+#if NINA_ADDED
+if(l1s.force_gauging_next_paging_due_to_CCHR != 1)
+#endif
+{
+l1s.pw_mgr.enough_gaug = FALSE;  // forbid Deep sleep until next gauging
+}
+
+
+  // Clear Serving offset and bob.
+  sptr->fn_offset    = 0;
+  sptr->time_alignmt = 0;
+
+  // Flag TPU programmation.
+  // ************************
+
+  // Set "CTRL_SYNC" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_SYNC;
+
+  #if (CODE_VERSION == SIMULATION)
+    si_scheduling(MPHC_SCELL_NBCCH_REQ, NULL, TRUE);
+    si_scheduling(MPHC_SCELL_EBCCH_REQ, NULL, TRUE);
+  #endif
+
+  #if TESTMODE
+    // Continuous mode: if we are in continuous mode: return to the no continuous mode.
+    if ((l1_config.TestMode) && (l1_config.tmode.rf_params.tmode_continuous == TM_CONTINUOUS))
+      l1_config.tmode.rf_params.tmode_continuous = TM_NO_CONTINUOUS;
+  #endif
+
+  #if L1_GPRS
+    // Signals the GSM->GPRS or GPRS->GSM switch to the DSP.
+    // ******************************************************
+    l1pddsp_synchro(l1a_l1s_com.dsp_scheduler_mode, l1a_l1s_com.dl_tn);
+
+    // Flag DSP programmation.
+    // Set "CTRL_SYNC" flag in the controle flag register.
+    l1s.dsp_ctrl_reg |= CTRL_SYNC;
+  #endif
+
+  #if (CODE_VERSION == SIMULATION)
+    si_scheduling(MPHC_SCELL_NBCCH_REQ, NULL, TRUE);
+    si_scheduling(MPHC_SCELL_EBCCH_REQ, NULL, TRUE);
+  #endif
+}
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_ADC()                                        */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* task ADC. This function program the L1/TPU in order   */
+/* to perform an ADC measurement in CS_MODE0             */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_ADC(UWORD8 param1, UWORD8 param2)
+{
+  // Traces and debug.
+  // ******************
+
+  #if (TRACE_TYPE!=0)
+    trace_fct(CST_L1S_CTRL_ADC, (UWORD32)(-1));//OMAPS00090550
+  #endif
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+  #endif
+
+  //  In CS_MODE0, MPHC_RXLEV_REQ is not received periodically. In case network is not found,
+  //the period between 2 MPHC_RXLEV_REQ increases and can be as high as 360 seconds (Max Value)
+  // To enable MADC periodically, the function l1dmacro_adc_read_rx_cs_mode0; is called
+  #if (CODE_VERSION != SIMULATION)
+     #if (L1_MADC_ON ==1)
+            if (l1a_l1s_com.mode == CS_MODE0)
+                    l1dmacro_adc_read_rx_cs_mode0();
+          else
+                 l1dmacro_adc_read_rx(); // ADC performed into a rx scenario to have BULON and BULENA signals off so maintaining
+                         // low power consumption on ABB
+     #else
+           l1dmacro_adc_read_rx(); // ADC performed into a rx scenario to have BULON and BULENA signals off so maintaining
+                         // low power consumption on ABB
+      #endif  // End of L1_MADC_ON == 1
+  #else
+            l1dmacro_adc_read_rx(); // ADC performed into a rx scenario to have BULON and BULENA signals off so maintaining
+                         // low power consumption on ABB
+  #endif
+
+
+  l1s.task_status[ADC_CSMODE0].current_status = INACTIVE;
+
+  if (l1a_l1s_com.adc_mode & ADC_NEXT_CS_MODE0)  // performe ADC only one time
+  {
+     l1a_l1s_com.adc_mode &= ADC_MASK_RESET_IDLE; // reset in order to have only one ADC measurement in CS_MODE0
+     l1a_l1s_com.l1s_en_task[ADC_CSMODE0] = TASK_DISABLED; // disable the ADC task in case of one shot
+  }
+
+  // Set "CTRL_MS" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_ADC;
+}
+
+#if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0))  // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START         // KEEP IN EXTERNAL MEM otherwise
+
+/*-------------------------------------------------------*/
+/* l1s_abort()                                           */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* task ABORT. When the L1S merge manager routine,       */
+/* "l1s_merge_manager()", finds a conflict between a     */
+/* running task and a pending task, it can come to       */
+/* aborting the running one to start executing the       */
+/* pending. Here is the routine which resets the comm.   */
+/* between the MCU and the DSP and TPU. The DSP is also  */
+/* signaled to abort any ongoing task. Here is a summary */
+/* of the execution:                                     */
+/*                                                       */
+/*  - Traces for debug.                                  */
+/*  - Reset MCU/DSP and MCU/TPU communications.          */
+/*  - Signals the ABORT process to the DSP.              */
+/*  - Flag DSP programmation.                            */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1s.tpu_offset"                                      */
+/*   OFFSET/SYNCHRO registers value for current serving  */
+/*   cell setting.                                       */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP        */
+/*   interface. This is used mainly to swap then the     */
+/*   com. page at the end of a control frame.            */
+/*   -> set CTRL_ABORT bit in the register.              */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_abort(UWORD8 param1, UWORD8 param2)
+{
+  // Traces for debug.
+  // ******************
+
+  #if (TRACE_TYPE==5)
+    trace_fct(CST_L1S_ABORT, l1a_l1s_com.Scell_info.radio_freq);
+  #endif
+
+  #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+    trace_fct(CST_L1S_ABORT_W0_R0, (UWORD32)(-1));//OMAPS00090550
+  #endif
+
+  #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+    if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_L1S_DEBUG)
+      Trace_L1s_Abort(trace_info.abort_task);
+  #endif
+
+  // Reset MCU/DSP and MCU/TPU communications.
+  // ******************************************
+
+  // Reset Hardware...
+  // Set "tpu_reset_bit" to 1.
+  // Reset DSP write/read page.
+  // Reset communication pointers.
+  // Immediate Reload offset with Serving one.
+  l1d_reset_hw(l1s.tpu_offset);
+
+  l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+  // Signals the ABORT process to the DSP.
+  // **************************************
+
+  // Set "b_abort" to TRUE, dsp will reset current and pending tasks.
+  l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= (1 << B_TASK_ABORT);
+
+
+  // Tasks are aborted on DSP side => forbid measurements during ABORT
+  l1s.forbid_meas = 1;
+
+  // Flag DSP programmation.
+  // ************************
+
+  // Set "CTRL_ABORT" flag in the controle flag register.
+  l1s.dsp_ctrl_reg |= CTRL_ABORT;
+#if (FF_L1_FAST_DECODING == 1)
+  /* Reset fast decoding */
+  l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_NONE;
+  l1a_apihisr_com.fast_decoding.contiguous_decoding = FALSE;
+#endif /* #if (FF_L1_FAST_DECODING == 1) */
+}
+
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+#endif
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_msagc()                                      */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: BCCHN,FBNEW,SB1,SB2,SBCONF. This function is   */
+/* the control function for making a power measurement   */
+/* for refreshing the AGC for those tasks. It programs   */
+/* the DSP and the TPU for making 1 measurement in the   */
+/* next frame. Here is a summary of the execution:       */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*    - Get the cell information structure.              */
+/*    - Traces and debug.                                */
+/*    - Programs DSP for measurement task.               */
+/*    - Programs TPU for measurement task.               */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   BCCHN, BCCH Neighbor reading task.                  */
+/*   FBNEW, Frequency Burst detection task in Idle mode. */
+/*   SB1, Synchro Burst reading task in Idle mode.       */
+/*   SB2, Synchro Burst detection task in Idle mode.     */
+/*   SBCONF, Synchro Burst confirmation task in Idle     */
+/*   mode.                                               */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1s.afc"                                             */
+/*   current AFC value to be applied for FBNEW and SB2   */
+/*   tasks in Cell Selection only.                       */
+/*                                                       */
+/* "l1a_l1s_com.task_param"                              */
+/*   task semaphore bit register. Used to skip this      */
+/*   control if L1A has changed or is changing some of   */
+/*   the task parameters.                                */
+/*                                                       */
+/* "l1a_l1s_com.Ncell_info.bcch"                         */
+/* "l1a_l1s_com.Ncell_info.acquis"                       */
+/* "l1a_l1s_com.Ncell_info.acquis"                       */
+/* "l1a_l1s_com.Ncell_info.conf"                         */
+/*   cell information structure used for BCCHN,FBNEW,    */
+/*   SB1/SB2,SBCONF respectively.                        */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_win"                                         */
+/*   each frame is composed with a maximum of 3          */
+/*   working/TPU windows (typically RX/TX/PW). This is   */
+/*   a counter used to count the number of windows       */
+/*   used.                                               */
+/*   -> incremented.                                     */
+/*                                                       */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU        */
+/*   interface. This is used mainly to swap then the     */
+/*   com. page at the end of a control frame.            */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP        */
+/*   interface. This is used mainly to swap then the     */
+/*   com. page at the end of a control frame.            */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_msagc(UWORD8 task, UWORD8 param2)
+{
+  #if (RF_FAM == 61)
+      UWORD16 dco_algo_ctl_pw = 0;
+      UWORD8 if_ctl = 0;
+//OMAPS00090550	  UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+  #endif
+
+  if(!(l1a_l1s_com.task_param[task]))
+  // Check the task semaphore. The control body is executed only
+  // when the task semaphore is 0. This semaphore can be set to
+  // 1 whenever L1A makes some changes to the task parameters.
+  {
+    T_NCELL_SINGLE *cell_info_ptr = NULL;
+#if (L1_GPRS)
+    T_NCELL_SINGLE pbcchn_cell_info;
+#endif
+#if ((REL99 == 1) && (FF_BHO == 1))
+    T_NCELL_SINGLE bho_cell_info;
+#endif
+
+    // Get the cell information structure.
+    // ************************************
+
+    switch(task)
+    {
+      case BCCHN:    cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm];break;
+      case BCCHN_TOP:cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top];break;
+      case FBNEW:    cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id];    break;
+      case SB2:      cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];    break;
+      case SBCONF:   cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id];break;
+
+#if ((REL99 == 1) && (FF_BHO == 1))
+      case FBSB:
+      {
+        cell_info_ptr = &bho_cell_info;
+        bho_cell_info.radio_freq = l1a_l1s_com.nsync_fbsb.radio_freq;
+        bho_cell_info.fn_offset  = l1a_l1s_com.nsync_fbsb.fn_offset;
+      }
+      break;
+#endif
+
+      #if (L1_GPRS)
+        case PBCCHN_IDLE:
+        {
+          cell_info_ptr               = &pbcchn_cell_info;
+          pbcchn_cell_info.radio_freq = l1pa_l1ps_com.pbcchn.bcch_carrier;
+          pbcchn_cell_info.fn_offset  = l1pa_l1ps_com.pbcchn.fn_offset;
+        }
+        break;
+      #endif
+      default: return;
+    }
+
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE!=0)
+      trace_fct(CST_L1S_CTRL_MSAGC, cell_info_ptr->radio_freq);
+    #endif
+
+    l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+
+    // Programs DSP for measurement task.
+    // ***********************************
+
+    // Dsp pgm... (2 measurement).
+    #if L1_GPRS
+      switch (l1a_l1s_com.dsp_scheduler_mode)
+      {
+        case GPRS_SCHEDULER:
+        {
+          l1pddsp_meas_ctrl(2,0);
+        } break;
+
+        case GSM_SCHEDULER:
+        {
+          l1ddsp_load_monit_task(2, 0);
+        } break;
+      }
+    #else
+      l1ddsp_load_monit_task(2, 0);
+    #endif
+
+  #if (RF_FAM == 61)
+   #if (PWMEAS_IF_MODE_FORCE == 0)
+      cust_get_if_dco_ctl_algo (&dco_algo_ctl_pw, &if_ctl,
+          (UWORD8) L1_IL_INVALID, 0,
+          cell_info_ptr->radio_freq,C_IF_ZERO_LOW_THRESHOLD_GSM);//OMAPS00090550
+    #else
+      if_ctl = IF_120KHZ_DSP;
+      dco_algo_ctl_pw = DCO_IF_0KHZ;
+    #endif
+
+    // Duplicate the outcome of DCO control as there are 2 PM
+    dco_algo_ctl_pw = (((dco_algo_ctl_pw<<2) & 0x0C) | (dco_algo_ctl_pw & 0x03)); // 0000ZLZL
+    l1ddsp_load_dco_ctl_algo_pw(dco_algo_ctl_pw);
+  #endif
+
+    // Programs TPU for measurement task.
+    // ***********************************
+         // tpu pgm: measurement only.
+     if (task == FBNEW)
+     {
+         l1dtpu_meas(cell_info_ptr->radio_freq,
+                     l1_config.params.high_agc,
+                     0,                                 // 0 is set for lna_off = 0
+                     l1s.tpu_win,
+                     l1s.tpu_offset, INACTIVE
+     #if(RF_FAM == 61)
+                    ,L1_AFC_NONE
+                    ,if_ctl
+     #endif
+     	                      );
+     }
+     else
+     {
+    	     l1dtpu_meas(cell_info_ptr->radio_freq,
+                     l1_config.params.high_agc,
+                     0,                                 // 0 is set for lna_off = 0
+                     l1s.tpu_win,
+                     l1s.tpu_offset, INACTIVE
+     #if(RF_FAM == 61)
+                    ,L1_AFC_SCRIPT_MODE
+                    ,if_ctl
+     #endif
+     	                      );
+     }
+
+    #if L2_L3_SIMUL
+      #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+        buffer_trace(4, l1s.actual_time.fn, cell_info_ptr->radio_freq,
+                        cell_info_ptr->fn_offset, l1s.tpu_win);
+      #endif
+    #endif
+
+if (task == FBNEW)
+{
+    // Increment tpu window identifier.
+    l1s.tpu_win += (l1_config.params.rx_synth_load_split + PWR_LOAD);
+
+    // tpu pgm: measurement only.
+    l1dtpu_meas(cell_info_ptr->radio_freq,
+                l1_config.params.low_agc,
+                0,                          // 0 is set for lna_off = 0
+                l1s.tpu_win,
+                l1s.tpu_offset,
+                INACTIVE
+#if(RF_FAM == 61)
+                ,L1_AFC_SCRIPT_MODE
+                ,if_ctl
+#endif
+	);
+}
+else
+{
+    // Increment tpu window identifier.
+    l1s.tpu_win += (l1_config.params.rx_synth_load_split + PWR_LOAD);
+
+    // tpu pgm: measurement only.
+    l1dtpu_meas(cell_info_ptr->radio_freq,
+                l1_config.params.low_agc,
+                0,                          // 0 is set for lna_off = 0
+                l1s.tpu_win,
+                l1s.tpu_offset,
+                INACTIVE
+#if(RF_FAM == 61)
+                ,L1_AFC_SCRIPT_MODE
+                ,if_ctl
+#endif
+	);
+}
+    // Increment tpu window identifier.
+    l1s.tpu_win += (l1_config.params.rx_synth_load_split + PWR_LOAD);
+  }
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_MS" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_MS;
+  l1s.dsp_ctrl_reg |= CTRL_MS;
+
+  // This task is not compatible with Neigh. Measurement. Store task length
+  // in "forbid_meas" to indicate when the task will last.
+  l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+}
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_fb()                                         */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: FBNEW,FB51. This function is the control       */
+/* function for making a frequency burst acquisition on  */
+/* a neighbor cell. It programs the DSP and the TPU for  */
+/* making 1 attempt in reading the frequency burst.Here  */
+/* is a summary of the execution:                        */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*    - Traces and debug.                                */
+/*    - Programs DSP for FB acquisition task.            */
+/*    - Programs TPU for FB acquisition task.            */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   FBNEW, Frequency Burst detection task in Idle mode. */
+/*   FB51, Frequency Burst detection task in Dedicated   */
+/*   mode.                                               */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.task_param"                              */
+/*   task semaphore bit register. Used to skip this      */
+/*   control if L1A has changed or is changing some of   */
+/*   the task parameters.                                */
+/*                                                       */
+/* "l1a_l1s_com.Ncell_info.acquis"                       */
+/*   cell information structure used for FBNEW and FB51  */
+/*   tasks.                                              */
+/*                                                       */
+/* "l1a_l1s_com.fb_mode"                                 */
+/*   the frequency burst detection algorithm implemented */
+/*   in the DSP uses 2 different modes. The mode to use  */
+/*   is indicated by this global variable and is passed  */
+/*   to the DSP.                                         */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU        */
+/*   interface. This is used mainly to swap then the     */
+/*   com. page at the end of a control frame.            */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP        */
+/*   interface. This is used mainly to swap then the     */
+/*   com. page at the end of a control frame.            */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_fb(UWORD8 task, UWORD8 param2)
+{
+  WORD8    agc;
+  UWORD8   lna_off;
+  BOOL     en_task;
+  BOOL     task_param;
+  UWORD32  dsp_task;
+#if (L1_FF_MULTIBAND == 1)
+  UWORD16  operative_radio_freq;
+#endif
+
+
+  // Get "enable" task flag and "synchro semaphore" for current task.
+  en_task    = l1a_l1s_com.l1s_en_task[task];
+  task_param = l1a_l1s_com.task_param[task];
+
+  if((en_task) && !(task_param))
+  // Check the task semaphore and enable flag. The control body is executed only
+  // when the task semaphore is 0 and enable flag is 1. The semaphore can be set to
+  // 1 whenever L1A makes some changes to the task parameters. The enable can be
+  // reset to 0 when the task is no more enabled.
+  {
+    T_NCELL_SINGLE  *cell_info_ptr = NULL;
+
+    // Get the cell information structure.
+    // ************************************
+    cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id];
+
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE!=0)
+      trace_fct(CST_L1S_CTRL_FB, cell_info_ptr->radio_freq);
+    #endif
+
+    #if (TRACE_TYPE==5) && FLOWCHART
+      trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+    #endif
+
+    l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 13) ;
+
+    // Programs DSP for required task.
+    // ********************************
+
+    // dsp pgm...
+
+    dsp_task = l1s_swap_iq_dl(cell_info_ptr->radio_freq,task);
+
+    l1ddsp_load_monit_task(dsp_task, l1a_l1s_com.fb_mode);
+
+    // Programs TPU for required task.
+    // ********************************
+#if (L1_FF_MULTIBAND == 0)
+
+    // Get AGC to be applied.
+    agc = Cust_get_agc_from_IL(cell_info_ptr->radio_freq,l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, AV_ID);
+    // lna_off flag is updated ONLY in case of l1ctl_pgc2 control algo
+    lna_off = l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+#else // L1_FF_MULTIBAND = 1 below
+
+    operative_radio_freq = l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq );
+    // lna_off flag is updated ONLY in case of l1ctl_pgc2 control algo
+    lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+    // Get AGC to be applied.
+    agc = Cust_get_agc_from_IL(cell_info_ptr->radio_freq,l1a_l1s_com.last_input_level[operative_radio_freq].input_level >> 1, AV_ID);
+    
+#endif // #if (L1_FF_MULTIBAND == 0) else
+
+
+    // tpu pgm...
+    l1dtpu_neig_fb(cell_info_ptr->radio_freq, agc, lna_off);
+  }
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+
+  // This task is not compatible with Neigh. Measurement. Store task length
+  // in "forbid_meas" to indicate when the task will last.
+  // Rem: Only FB51 task starts from this ctrl function.
+  if(task==FB51) l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+}
+
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_fbsb()                                      */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: FBSB. This function is the control             */
+/* function for making a frequency + synchro burst       */
+/* on a neighbor cell in case of blind handover          */
+/* It programs the DSP and the TPU for                   */
+/* making 1 attempt in reading the frequency & synchro   */
+/* burst                                                 */
+/* Here is a summary of the execution:                   */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*    - Traces and debug.                                */
+/*    - Programs DSP for FB+SB acquisition task.         */
+/*    - Programs TPU for FB+SB acquisition task.         */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   FBSB, Frequency + Synchro burst detection task in   */
+/*        blind handover                                 */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.task_param"                              */
+/*   task semaphore bit register. Used to skip this      */
+/*   control if L1A has changed or is changing some of   */
+/*   the task parameters.                                */
+/*                                                       */
+/* "l1a_l1s_com.nsync_fbsb"                              */
+/*   cell information structure used for FBSB tasks.     */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU        */
+/*   interface. This is used mainly to swap then the     */
+/*   com. page at the end of a control frame.            */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP        */
+/*   interface. This is used mainly to swap then the     */
+/*   com. page at the end of a control frame.            */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+#if ((REL99 == 1) && (FF_BHO == 1))
+void l1s_ctrl_fbsb(UWORD8 task, UWORD8 param2)
+{
+
+  WORD8    agc;
+  UWORD8   lna_off;
+  UWORD32  dsp_task;
+  //added by sajal for DCXO
+  UWORD8 input_level;
+  #if (RF_FAM == 61)
+  UWORD16 dco_algo_ctl_sb = 0;
+  UWORD8 if_ctl = 0;
+  UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+  #endif
+#if (L1_FF_MULTIBAND == 1)
+  UWORD16 operative_radio_freq;
+#endif
+  
+
+
+  // Traces and debug.
+  // ******************
+
+#if (TRACE_TYPE!=0)
+  //  trace_fct(CST_L1S_CTRL_FBSB, l1a_l1s_com.nsync_fbsb.radio_freq);
+#endif
+
+#if (TRACE_TYPE==5) && FLOWCHART
+  trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+#endif
+
+  l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 13) ;
+
+  // Programs DSP for required task.
+  // ********************************
+
+  // dsp pgm...
+
+  dsp_task = l1s_swap_iq_dl(l1a_l1s_com.nsync_fbsb.radio_freq, task);
+
+  l1ddsp_load_monit_task(dsp_task, 1);
+#if (L1_FF_MULTIBAND == 0)
+  input_level = l1a_l1s_com.last_input_level[l1a_l1s_com.nsync_fbsb.radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+#else
+	operative_radio_freq = 
+	  l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.nsync_fbsb.radio_freq);
+	input_level = 
+	  l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+#endif
+
+   #if (RF_FAM == 61)   // Locosto DCO
+        cust_get_if_dco_ctl_algo(&dco_algo_ctl_sb, &if_ctl, (UWORD8) L1_IL_VALID ,
+                                           input_level,
+                                             l1a_l1s_com.nsync_fbsb.radio_freq,if_threshold);
+
+	l1ddsp_load_dco_ctl_algo_sb(dco_algo_ctl_sb);
+   #endif
+
+  // Programs TPU for required task.
+  // ********************************
+#if (L1_FF_MULTIBAND == 0)
+  
+  // lna_off flag is updated ONLY in case of l1ctl_pgc2 control algo
+  lna_off = l1a_l1s_com.last_input_level[l1a_l1s_com.nsync_fbsb.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+  // Get AGC to be applied.
+  agc = Cust_get_agc_from_IL(l1a_l1s_com.nsync_fbsb.radio_freq, l1a_l1s_com.last_input_level[l1a_l1s_com.nsync_fbsb.radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, AV_ID);
+
+#else // L1_FF_MULTIBAND = 1 below
+
+  /*operative_radio_freq = 
+    l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.nsync_fbsb.radio_freq);*/
+
+  // lna_off flag is updated ONLY in case of l1ctl_pgc2 control algo
+  lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+
+  // Get AGC to be applied.
+  agc = 
+    Cust_get_agc_from_IL(l1a_l1s_com.nsync_fbsb.radio_freq, l1a_l1s_com.last_input_level[operative_radio_freq].input_level >> 1, AV_ID);
+
+#endif // #if (L1_FF_MULTIBAND == 0) else 
+
+  // tpu pgm...
+
+  l1dtpu_neig_fbsb(l1a_l1s_com.nsync_fbsb.radio_freq, agc, lna_off);
+
+  // Disable Task
+// FTH  l1a_l1s_com.l1s_en_task[FBSB] = TASK_DISABLED;
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+}
+#endif //#if ((REL99 == 1) && (FF_BHO == 1))
+
+
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_sbgen()                                      */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: SB1,SB2,SB51,SBCONF,SBCNF51. This function is  */
+/* the control function for making a synchro burst       */
+/* reading on a neighbor cell in Cell Selection, Idle    */
+/* mode and dedicated mode SDCCH. It programs the DSP    */
+/* and the TPU for making 1 attempt in reading the       */
+/* synchro burst. Here is a summary of the execution:    */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*    - Get the cell information structure.              */
+/*    - Traces and debug.                                */
+/*    - Programs DSP for SB reading task.                */
+/*    - Programs TPU for SB reading task.                */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   SB1, Synchro Burst reading task in Idle mode.       */
+/*   SB2, Synchro Burst detection task in Idle mode.     */
+/*   SBCONF, Synchro Burst confirmation task in Idle     */
+/*   mode.                                               */
+/*   SB51, Synchro Burst reading task in Dedicated mode. */
+/*   SBCNF51, Synchro Burst confirmation task in         */
+/*   Dedicated mode.                                     */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.task_param"                              */
+/*   task semaphore bit register. Used to skip this      */
+/*   control if L1A has changed or is changing some of   */
+/*   the task parameters.                                */
+/*                                                       */
+/* "l1a_l1s_com.Ncell_info.acquis"                       */
+/*   cell information structure used for SB1, SB2 and    */
+/*   SB51 tasks.                                         */
+/*                                                       */
+/* "l1a_l1s_com.Ncell_info.conf"                         */
+/*   cell information structure used for SBCONF and      */
+/*   SBCNF51 tasks.                                      */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for SYNCHRO and OFFSET register in the TPU    */
+/*   for current serving cell setting. It is used here   */
+/*   by the synchro burst reading TPU driver since this  */
+/*   driver changes the OFFSET register. At the end of   */
+/*   the task it restores the serving cell offset value. */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_sbgen(UWORD8 task, UWORD8 attempt)
+{
+  UWORD8   reload_serv_offset = TRUE;   // Default: offset serving reloaded.
+  WORD8    agc;
+  UWORD8   lna_off;
+  BOOL     en_task;
+  BOOL     task_param;
+  UWORD32  dsp_task;
+  UWORD8 input_level;
+  #if (RF_FAM == 61)
+      UWORD16 dco_algo_ctl_sb = 0;
+      UWORD8 if_ctl = 0;
+	  UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+  #endif
+#if (L1_FF_MULTIBAND == 1)
+  UWORD16 operative_radio_freq;
+#endif
+
+
+  // Get "enable" task flag and "synchro semaphore" for current task.
+  en_task    = l1a_l1s_com.l1s_en_task[task];
+  task_param = l1a_l1s_com.task_param[task];
+
+  if((en_task) && !(task_param))
+  // Check the task semaphore and enable flag. The control body is executed only
+  // when the task semaphore is 0 and enable flag is 1. The semaphore can be set to
+  // 1 whenever L1A makes some changes to the task parameters. The enable can be
+  // reset to 0 when the task is no more enabled.
+  {
+    T_NCELL_SINGLE *cell_info_ptr = NULL;
+
+    switch(task)
+    {
+      case SB2:
+      {
+        // Get the cell information structure.
+        // ************************************
+        cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];
+
+        if(attempt == 1) reload_serv_offset = FALSE; // Offset serving not reloaded on 1st CTRL.
+
+        #if (TRACE_TYPE!=0)
+          trace_fct(CST_L1S_CTRL_SB2, cell_info_ptr->radio_freq);
+        #endif
+      }
+      break;
+
+      case SB51:
+      {
+        // Get the cell information structure.
+        // ************************************
+        cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];
+
+        #if (TRACE_TYPE!=0)
+          trace_fct(CST_L1S_CTRL_SB51, cell_info_ptr->radio_freq);
+        #endif
+      }
+      break;
+
+      case SBCONF:
+      case SBCNF51:
+      {
+        // Get the cell information structure.
+        // ************************************
+        cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id];
+
+        #if (TRACE_TYPE!=0)
+          if(task == SBCONF)
+            trace_fct(CST_L1S_CTRL_SBCONF, cell_info_ptr->radio_freq);
+          else
+            trace_fct(CST_L1S_CTRL_SBCNF51, cell_info_ptr->radio_freq);
+        #endif
+#if (L1_EOTD==1)
+        // We need to trigger the TOA tracking / adjustment period
+        // which logs all TOA updates after E-OTD has started...
+
+        if(l1a_l1s_com.nsync.eotd_meas_session == TRUE)
+        {
+          if(    (l1a_l1s_com.nsync.eotd_toa_phase == 0)
+              && (l1a_l1s_com.nsync.active_sbconf_id == 12) )
+          {
+            l1a_l1s_com.nsync.eotd_toa_tracking = 0;
+            l1a_l1s_com.nsync.eotd_toa_phase = 1;
+          }
+
+          l1a_l1s_com.nsync.eotd_cache_toa_tracking = l1a_l1s_com.nsync.eotd_toa_tracking;
+        }
+#endif
+
+
+      }
+      break;
+
+      default: return;
+    }
+
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE==5) && FLOWCHART
+      trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+    #endif
+
+    l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 3) ;
+
+    // Programs DSP for required task.
+    // ********************************
+
+    // dsp pgm...
+    dsp_task = l1s_swap_iq_dl(cell_info_ptr->radio_freq,task);
+    l1ddsp_load_monit_task(dsp_task, 0);
+
+#if (L1_FF_MULTIBAND == 0)
+    input_level = l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+#else // L1_FF_MULTIBAND = 1 below
+    operative_radio_freq = 
+      l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq); 
+    input_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+#endif //#if (L1_FF_MULTIBAND == 0) else
+
+   #if (RF_FAM == 61)   // Locosto DCO
+        cust_get_if_dco_ctl_algo(&dco_algo_ctl_sb, &if_ctl, (UWORD8) L1_IL_VALID ,
+                                           input_level,
+                                             cell_info_ptr->radio_freq,if_threshold);
+
+     // This is a work-around for a DSP problem (OMAPS00117845)
+     // The problem happens during neighbor FB/SB, when there is an
+     // IDLE frame between neighbor FB and SB. 
+     // Neighbor cell SB(SB2) is different from other kind of SB decode.
+     // For SB2 we open the RF window for 2 frames (2 C W W R)
+     // For both Control, l1s_dsp_com.dsp_db_common_w_ptr->d_dco_algo_ctrl_sb is updated.
+     // However DSP copies DB value to NDB and this value is copied only once.
+     // At the end of the first SB, DSP right shifts the NDB variable.
+     // The fix below replicates the DCO control information 4 times
+     // so that DSP has correct information even after right shifting during first SB.
+   
+        if(task == SB2)
+	 {
+	   dco_algo_ctl_sb *= 0x55;
+	 }
+    
+
+
+
+	l1ddsp_load_dco_ctl_algo_sb(dco_algo_ctl_sb);
+   #endif
+
+    // Programs TPU for required task.
+    // ********************************
+#if (L1_FF_MULTIBAND == 0)
+    
+    // Get AGC to be applied.
+    agc = Cust_get_agc_from_IL(cell_info_ptr->radio_freq, input_level >> 1, AV_ID);
+    // lna_off flag is ONLY updated in case of l1ctl_pgc2 control algorithm
+    lna_off = l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+#else // L1_FF_MULTIBAND = 0 below
+
+    operative_radio_freq = 
+      l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq); 
+    // lna_off flag is ONLY updated in case of l1ctl_pgc2 control algorithm
+    lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+    // Get AGC to be applied.
+    agc = 
+      Cust_get_agc_from_IL(cell_info_ptr->radio_freq, input_level >> 1, AV_ID);
+
+#endif // #if (L1_FF_MULTIBAND == 0) else
+
+    // tpu pgm...
+    l1dtpu_neig_sb(cell_info_ptr->radio_freq,
+                   agc,
+                   lna_off,
+                   cell_info_ptr->time_alignmt,
+                   l1s.tpu_offset,
+                   reload_serv_offset,
+                   attempt
+                #if (RF_FAM == 61)
+                   ,if_ctl
+                #endif
+	                         );
+
+    #if L2_L3_SIMUL
+      #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+        buffer_trace(4, l1s.actual_time.fn, cell_info_ptr->radio_freq,
+                        cell_info_ptr->time_alignmt,l1s.tpu_offset);
+      #endif
+    #endif
+  }
+  else
+  // The task has been disabled or some parameters have changed, the serving tpu offset
+  // must be restored.
+  {
+    if(attempt==2)
+    {
+      l1dmacro_offset(l1s.tpu_offset,IMM);
+    }
+  }
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+
+  // This task is not compatible with Neigh. Measurement. Store task length
+  // in "forbid_meas" to indicate when the task will last.
+  // Rem: Only SB51/SBCNF51 tasks start from this ctrl function.
+  if((task==SB51)||(task==SBCNF51)) l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+}
+
+#if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_fb26()                                       */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: FB26. This function is the control function    */
+/* for making a frequency burst acquisition attempt on   */
+/* a neighbor cell in dedicated mode TCH. It programs    */
+/* the DSP and the TPU for making 1 attempt in reading   */
+/* the frequency burst.Here is a summary of the          */
+/* execution:                                            */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*    - Traces and debug.                                */
+/*    - Programs DSP for FB acquisition task.            */
+/*    - Programs TPU for FB acquisition task.            */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.Ncell_info.acquis"                       */
+/*   cell information structure used for FB26 task.      */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for SYNCHRO and OFFSET register in the TPU    */
+/*   for current serving cell setting. It is used here   */
+/*   by the frequency burst reading TPU driver since     */
+/*   this driver changes the OFFSET register. At the end */
+/*   of the task it restores the serving cell offset     */
+/*   value.                                              */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_fb26(UWORD8 param1, UWORD8 param2)
+{
+  WORD8    agc;
+  BOOL     lna_off;
+  UWORD32  dsp_task;
+  UWORD16  radio_freq = 0;
+#if (L1_FF_MULTIBAND == 1)
+  UWORD16 operative_radio_freq;
+#endif
+  
+#if (L1_12NEIGH ==1)
+  BOOL     en_task;
+  BOOL     task_param;
+
+  // Get "enable" task flag and "synchro semaphore" for current task.
+  en_task    = l1a_l1s_com.l1s_en_task[param1];
+  task_param = l1a_l1s_com.task_param[param1];
+
+  if((en_task) && !(task_param))
+  // Check the task semaphore and enable flag. The control body is executed only
+  // when the task semaphore is 0 and enable flag is 1. The semaphore can be set to
+  // 1 whenever L1A makes some changes to the task parameters. The enable can be
+  // reset to 0 when the task is no more enabled.
+#else
+  if(!(l1a_l1s_com.task_param[FB26] == SEMAPHORE_SET))
+#endif
+  // Check the task semaphore. The control body is executed only
+  // when the task semaphore is 0. This semaphore can be set to
+  // 1 whenever L1A makes some changes to the task parameters.
+  {
+#if (L1_12NEIGH ==1)
+    T_NCELL_SINGLE *cell_info_ptr = NULL;
+
+    cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id];
+    radio_freq = cell_info_ptr->radio_freq;
+#else
+    radio_freq = l1a_l1s_com.nsync.list[0].radio_freq;
+#endif
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE!=0)
+      trace_fct(CST_L1S_CTRL_FB26, radio_freq);
+    #endif
+
+    #if (TRACE_TYPE==5) && FLOWCHART
+      trace_flowchart_dsp_tpu(dltsk_trace[FB26].name);
+    #endif
+
+    // Programs DSP for FB26 task.
+    // ****************************
+
+    // dsp pgm...
+
+    dsp_task = l1s_swap_iq_dl(radio_freq,FB26);
+
+    l1ddsp_load_monit_task(dsp_task, 1);
+
+    // Programs TPU for FB26 task.
+    // ****************************
+#if (L1_FF_MULTIBAND == 0)
+    
+    // agc is just computed from last stored IL
+    agc     = Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, AV_ID);
+    lna_off = l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+#else // L1_FF_MULTIBAND = 1 below
+
+    operative_radio_freq = 
+      l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
+    lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+    // agc is just computed from last stored IL
+    agc     = 
+    Cust_get_agc_from_IL(radio_freq, l1a_l1s_com.last_input_level[operative_radio_freq].input_level >> 1, AV_ID);
+
+#endif // #if (L1_FF_MULTIBAND == 1) else
+
+
+    // tpu pgm...
+    l1dtpu_neig_fb26(radio_freq,
+                     agc,
+                     lna_off,
+                     l1s.tpu_offset);
+  }
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+
+  // This task is not compatible with Neigh. Measurement. Store task length
+  // in "forbid_meas" to indicate when the task will last.
+  // Special case: we set forbid_meas to skip the measurements in the frames
+  // FN%26=24 or 25.
+  l1s.forbid_meas = 3;
+}
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+#endif // MOVE_IN_INTERNAL_RAM
+
+#if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_sb26()                                       */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: SB1,SB2,SB51,SBCONF,SBCNF51. This function is  */
+/* the control function for making a synchro burst       */
+/* reading on a neighbor cell in Cell Selection, Idle    */
+/* mode and dedicated mode SDCCH. It programs the DSP    */
+/* and the TPU for making 1 attempt in reading the       */
+/* synchro burst. Here is a summary of the execution:    */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*    - Get the cell information structure.              */
+/*    - Traces and debug.                                */
+/*    - Programs DSP for SB reading task.                */
+/*    - Programs TPU for SB reading task.                */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   SB26, Synchro Burst reading task in Dedicated mode, */
+/*   TCH.                                                */
+/*   SBCNF26, Synchro Burst confirmation task in Dedic.  */
+/*   mode TCH.                                           */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.Ncell_info.acquis"                       */
+/*   cell information structure used for SB26 task.      */
+/*                                                       */
+/* "l1a_l1s_com.Ncell_info.conf"                         */
+/*   cell information structure used for SBCNF26 task.   */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for SYNCHRO and OFFSET register in the TPU    */
+/*   for current serving cell setting. It is used here   */
+/*   by the synchro burst reading TPU driver since this  */
+/*   driver changes the OFFSET register. At the end of   */
+/*   the task it restores the serving cell offset value. */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_sb26(UWORD8 task, UWORD8 param2)
+{
+  UWORD32  nb_nop = 0;
+  WORD8    agc;
+  BOOL     lna_off;
+  UWORD32  dsp_task;
+  UWORD8 input_level;
+  UWORD32 temp;
+#if (L1_FF_MULTIBAND == 1)
+  UWORD16 operative_radio_freq;
+#endif
+
+#if (L1_12NEIGH ==1)
+  BOOL     en_task;
+  BOOL     task_param;
+#if (RF_FAM == 61)
+      UWORD16 dco_algo_ctl_sb = 0;
+      UWORD8   if_ctl = 0 ;
+	  UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+#endif
+
+   // Get "enable" task flag and "synchro semaphore" for current task.
+  en_task    = l1a_l1s_com.l1s_en_task[task];
+  task_param = l1a_l1s_com.task_param[task];
+
+ if((en_task) && !(task_param))
+#else
+  if(!(l1a_l1s_com.task_param[task]))
+#endif
+  // Check the task semaphore. The control body is executed only
+  // when the task semaphore is 0. This semaphore can be set to
+  // 1 whenever L1A makes some changes to the task parameters.
+  {
+    UWORD16  radio_freq = 0;
+    UWORD32  time_alignmt = 0;
+#if (L1_12NEIGH ==1)
+    T_NCELL_SINGLE *cell_info_ptr;
+
+    if (task == SB26)
+       cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];
+    if (task == SBCNF26)
+    {
+
+#if (L1_EOTD==1)
+       // We need to trigger the TOA tracking / adjustment period
+       // which logs all TOA updates after E-OTD has started...
+
+       if(l1a_l1s_com.nsync.eotd_meas_session == TRUE)
+       {
+         if(    (l1a_l1s_com.nsync.eotd_toa_phase == 0)
+             && (l1a_l1s_com.nsync.active_sbconf_id == 12) )
+         {
+           l1a_l1s_com.nsync.eotd_toa_tracking = 0;
+           l1a_l1s_com.nsync.eotd_toa_phase = 1;
+         }
+
+         l1a_l1s_com.nsync.eotd_cache_toa_tracking = l1a_l1s_com.nsync.eotd_toa_tracking;
+       }
+#endif
+
+       cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id];
+
+    }
+    radio_freq   = cell_info_ptr->radio_freq;
+    time_alignmt = cell_info_ptr->time_alignmt;
+
+#else
+    // Get the cell information.
+    // **************************
+    radio_freq   = l1a_l1s_com.nsync.list[0].radio_freq;
+    time_alignmt = l1a_l1s_com.nsync.list[0].time_alignmt;
+#endif
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE!=0)
+      switch(task)
+      {
+        case SB26:    trace_fct(CST_L1S_CTRL_SB26, radio_freq);    break;
+        case SBCNF26: trace_fct(CST_L1S_CTRL_SBCNF26, radio_freq); break;
+      }
+    #endif
+
+    #if (TRACE_TYPE==5) && FLOWCHART
+      trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+    #endif
+
+    // Programs DSP for required task.
+    // ********************************
+    // dsp pgm...
+
+    dsp_task = l1s_swap_iq_dl(radio_freq,task);
+    l1ddsp_load_monit_task(dsp_task, 0);
+
+    // Programs TPU for required task.
+    // ********************************
+  temp = (UWORD32)(l1_config.params.fb26_anchoring_time - EPSILON_SYNC);
+  #if (L1_12NEIGH ==1)
+      if((cell_info_ptr->sb26_offset == 1) &&
+         (time_alignmt >= temp)) //omaps00090550
+  #else
+      if((l1a_l1s_com.nsync.list[0].sb26_offset == 1) &&
+         (time_alignmt >= temp)) //omaps00090550
+  #endif
+    // SB is in the 2nd frame of the search slot...
+    // ...and SB is at the very end of the slot.
+    // We insert a nop in the tpu scenario to
+    // be able to jump the 1st frame.
+    {
+      nb_nop = 1;
+    }
+
+#if (L1_FF_MULTIBAND == 0)
+
+    // agc is just computed from last stored IL
+    input_level = l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+    agc     = Cust_get_agc_from_IL(radio_freq, input_level >> 1, AV_ID);
+    lna_off = l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+#else // L1_FF_MULTIBAND = 1 below
+
+    operative_radio_freq = 
+      l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq); 
+    // agc is just computed from last stored IL
+    input_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+    lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;    
+    agc     = Cust_get_agc_from_IL(radio_freq, input_level >> 1, AV_ID);    
+
+#endif // #if (L1_FF_MULTIBAND == 0) else
+
+    #if (RF_FAM == 61)   // Locosto DCO
+       cust_get_if_dco_ctl_algo(&dco_algo_ctl_sb, &if_ctl, (UWORD8) L1_IL_VALID,
+                                          input_level,
+                                           radio_freq,if_threshold);
+      	l1ddsp_load_dco_ctl_algo_sb(dco_algo_ctl_sb);
+    #endif
+
+    // tpu pgm...
+    l1dtpu_neig_sb26(radio_freq,
+                     agc,
+                     lna_off,
+                     time_alignmt,
+                     nb_nop,
+                     l1s.tpu_offset
+                    #if (RF_FAM == 61)
+                    ,if_ctl
+                    #endif
+                               	);
+  }
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+
+  // This task is not compatible with Neigh. Measurement. Store task length
+  // in "forbid_meas" to indicate when the task will last.
+  // Special case: we set forbid_meas to skip the measurements in the frames
+  // FN%26=24 or 25.
+  l1s.forbid_meas = 3;
+}
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+#endif // MOVE_IN_INTERNAL_RAM
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_smscb()                                      */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: SMSCB. This function is the control function   */
+/* for reading a CBCH burst on the serving cell. It      */
+/* shifts the OFFSET register to match the normal burst  */
+/* receive task with the CBCH timeslot number (0,1,2 or  */
+/* 3), programs a normal burst reading and restores the  */
+/* OFFSET to the serving cell timeslot 0. On the last    */
+/* control (4th burst), the SYNCHRO/OFFSET registers are */
+/* shifted back to the normal idle mode PCH reading      */
+/* setting. Here is a summary of the execution:          */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*    - Traces and debug.                                */
+/*    - Programs DSP for SMSCB task, reading 1 burst.    */
+/*    - Programs TPU for SMSCB task, reading 1 burst.    */
+/*    - Shift TPU SYNCHRO/OFFSET registers back to the   */
+/*      PAGING TASK timeslot.                            */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   SMSCB, Short Message Service Cell Broadcast.        */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.cbch_desc"                               */
+/*   Cell Broadcast CHannel description structure.       */
+/*                                                       */
+/* "l1a_l1s_com.Scell_info.bsic"                         */
+/*   BSIC of the serving cell. It is used here to pass   */
+/*   the training sequence number (part of BSIC) to the  */
+/*   DSP.                                                */
+/*                                                       */
+/* "l1s.afc"                                             */
+/*   current AFC value to be applied for SMSCB reading   */
+/*   task.                                               */
+/*                                                       */
+/* "l1a_l1s_com.offset_tn0"                              */
+/*   value to load in the OFFSET register to shift then  */
+/*   any receive task to the timeslot 0 of the serving   */
+/*   cell. This is the default setting to restore after  */
+/*   any CBCH burst reading.                             */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for the TPU SYNCHRO and OFFSET registers      */
+/*   for current serving cell setting. It is used here   */
+/*   at the end of the CBCH task controls to restore the */
+/*   SYNCHRO/OFFSET registers to the normal setting in   */
+/*   idle mode.                                          */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.actual_time, l1s.next_time"                      */
+/*   frame number and derived numbers for current frame  */
+/*   and next frame.                                     */
+/*   -> update to cope with side effect due to synchro.  */
+/*      changes/restores.                                */
+/*                                                       */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_smscb(UWORD8 task, UWORD8 burst_id)
+{
+  UWORD16  rx_radio_freq;
+  UWORD32  offset_smscb;
+  WORD8    agc;
+  UWORD8   lna_off;
+  UWORD32  dsp_task;
+  static   WORD32 new_tpu_offset;
+  static   BOOL   change_synchro;
+#if 0	/* FreeCalypso TCS211 reconstruction */
+  UWORD8 input_level;
+#endif
+#if (L1_FF_MULTIBAND == 1)
+  UWORD16 operative_radio_freq;
+#endif
+
+#if (NEW_SNR_THRESHOLD == 1)
+  UWORD8 saic_flag=0;
+#endif /* NEW_SNR_THRESHOLD */
+#if (RF_FAM == 61)
+  UWORD16 dco_algo_ctl_nb = 0;
+  UWORD8 if_ctl = 0;
+  UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+  // By default we choose the hardware filter
+  UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+#endif
+
+  // Needed for simulated DSP GRPS scheduler
+  #if (CODE_VERSION == SIMULATION)
+    UWORD32 tpu_w_page;
+
+    if (hw.tpu_r_page==0)
+     tpu_w_page=1;
+    else
+     tpu_w_page=0;
+
+    hw.rx_id[tpu_w_page][0]=0;
+    hw.num_rx[tpu_w_page][0]=1;
+    hw.rx_group_id[tpu_w_page]=1;
+  #endif
+
+
+  if((l1a_l1s_com.l1s_en_task[task] == TASK_ENABLED) &&
+    !(l1a_l1s_com.task_param[task] == SEMAPHORE_SET))
+  // Check the task semaphore. The control body is executed only
+  // when the task semaphore is 0. This semaphore can be set to
+  // 1 whenever L1A makes some changes to the task parameters.
+  {
+    // Get ARFCN to be used for current control. Output of the hopping algorithm.
+    rx_radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE==5) && FLOWCHART
+      trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+    #endif
+
+    #if (TRACE_TYPE!=0)
+      trace_fct(CST_L1S_CTRL_SMSCB, rx_radio_freq);
+    #endif
+
+    l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+    // Programs DSP for SMSCB task according to the DSP scheduler used
+    // ****************************************************************
+
+  #if L1_GPRS
+    switch(l1a_l1s_com.dsp_scheduler_mode)
+    {
+      // dsp pgm is made using GSM scheduler...
+      case GSM_SCHEDULER:
+      {
+        dsp_task = l1s_swap_iq_dl(rx_radio_freq, task);
+
+        // dsp pgm...
+        l1ddsp_load_rx_task(dsp_task,burst_id,l1a_l1s_com.cbch_desc.tsc);
+      }
+      break;
+
+      // dsp pgm is made using GPRS scheduler...
+      case GPRS_SCHEDULER:
+      {
+      #if FF_L1_IT_DSP_USF
+        l1pddsp_idle_rx_nb(burst_id,l1a_l1s_com.cbch_desc.tsc,rx_radio_freq,0,FALSE,FALSE);
+      #else
+        l1pddsp_idle_rx_nb(burst_id,l1a_l1s_com.cbch_desc.tsc,rx_radio_freq,0,FALSE);
+      #endif
+      }
+      break;
+    }
+  #else
+    dsp_task = l1s_swap_iq_dl(rx_radio_freq, task);
+
+    // dsp pgm...
+    l1ddsp_load_rx_task(dsp_task,burst_id,l1a_l1s_com.cbch_desc.tsc);
+ #endif
+
+    // Check if "Synchro" change is needed.
+    // *************************************
+
+    // If so the synchro is changed by 4 timeslots.
+    if(burst_id == BURST_1)
+    {
+      // This task is not compatible with Neigh. Measurement. Store task length
+      // in "forbid_meas" to indicate when the task will last.
+      l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+
+      change_synchro = l1a_l1s_com.change_synchro_cbch;
+
+      if(change_synchro)
+      {
+        // compute TPU offset for "current timeslot + 4 timeslot"
+        new_tpu_offset = l1s.tpu_offset + (4 * TN_WIDTH);
+
+        if(new_tpu_offset >= TPU_CLOCK_RANGE)
+          new_tpu_offset -= TPU_CLOCK_RANGE;
+
+        // Slide synchro to match current timeslot + 4 timeslot.
+        l1dmacro_synchro(l1_config.params.rx_change_synchro_time, new_tpu_offset);
+      }
+      else
+      {
+        new_tpu_offset = l1s.tpu_offset;
+      }
+    }
+
+    // Programs TPU for SMSCB task, reading 1 burst.
+    // **********************************************
+
+    offset_smscb = new_tpu_offset + l1a_l1s_com.tn_smscb * TN_WIDTH;
+    if (offset_smscb >= TPU_CLOCK_RANGE)
+      offset_smscb -= TPU_CLOCK_RANGE;
+
+#if 1	/* FreeCalypso match TCS211 */
+
+    // agc is set with the input_level computed from PAGC algo
+    agc     = Cust_get_agc_from_IL(l1a_l1s_com.Scell_info.radio_freq, l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, MAX_ID);
+    lna_off = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+#elif (L1_FF_MULTIBAND == 0)
+
+    // agc is set with the input_level computed from PAGC algo
+    input_level =  l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+    agc     = Cust_get_agc_from_IL(l1a_l1s_com.Scell_info.radio_freq,input_level >> 1, MAX_ID);
+    lna_off = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+#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); 
+    input_level =  l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+    lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+    agc     = Cust_get_agc_from_IL(l1a_l1s_com.Scell_info.radio_freq,input_level >> 1, MAX_ID);
+
+
+#endif // #if (L1_FF_MULTIBAND == 0) else
+
+    #if(RF_FAM == 61)   // Locosto DCO
+       cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID,
+                                                 input_level,
+                                                 l1a_l1s_com.Scell_info.radio_freq,if_threshold);
+
+        l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+    #endif
+
+    // Store IL used for current CTRL in order to be able to buil IL from pm
+    // in READ phase.
+#if 1	/* FreeCalypso match TCS211 */
+
+    l1a_l1s_com.Scell_used_IL.input_level = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+    l1a_l1s_com.Scell_used_IL.lna_off     = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+#elif (L1_FF_MULTIBAND == 0)
+
+    l1a_l1s_com.Scell_used_IL.input_level = input_level;
+    l1a_l1s_com.Scell_used_IL.lna_off     = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+#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);
+    l1a_l1s_com.Scell_used_IL.input_level = input_level;
+    l1a_l1s_com.Scell_used_IL.lna_off     = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+
+#endif // #if (L1_FF_MULTIBAND == 1) else    
+
+    #if (L1_SAIC != 0)
+      // If SAIC is enabled, call the low level SAIC control function
+      csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+    #if (NEW_SNR_THRESHOLD == 1)
+          ,task
+          ,&saic_flag
+    #endif
+          );
+    #endif
+
+    // tpu pgm...
+    l1dtpu_serv_rx_nb(rx_radio_freq,
+                      agc,
+                      lna_off,
+                      new_tpu_offset,
+                      offset_smscb,
+                      TRUE,
+                      FALSE
+                    #if (RF_FAM == 61)
+                      ,csf_filter_choice
+                      ,if_ctl
+                    #endif
+                    #if (NEW_SNR_THRESHOLD == 1)
+                      ,saic_flag
+                    #endif   /* NEW_SNR_THRESHOLD */
+      	                            );
+
+  } // End if(task enabled and semaphore false)
+
+  // Remark:
+  //--------
+  // When the task is aborted, we must continue to make dummy
+  // DSP programming to avoid communication mismatch due
+  // to C/W/R pipelining.
+
+  // We must also ensure the Synchro back since synchro change has surely be done
+  // in the 1st CTRL phase.
+
+  // Shift TPU SYNCHRO/OFFSET registers back to the default timeslot (normally (P)CCCH one).
+  // ****************************************************************************************
+  // When the CBCH reading control is completed (4 burst controled),
+  // the SYNCHRO/OFFSET registers are shifted back to the normal idle
+  // setting used for (P)CCCH reading on the serving cell.
+
+  // Check if "Synchro" change was needed.
+  // If so the synchro is changed to recover normal synchro.
+  if(burst_id == BURST_4)
+  {
+    if(change_synchro)
+    {
+      // Slide synchro back to mach current serving timeslot.
+      l1dmacro_synchro(SWITCH_TIME, l1s.tpu_offset);
+
+      // Increment frame number.
+      #if L1_GPRS
+        l1s.actual_time    = l1s.next_time;
+        l1s.next_time      = l1s.next_plus_time;
+        l1s_increment_time(&(l1s.next_plus_time), 1);  // Increment "next_plus time".
+      #else
+        l1s.actual_time = l1s.next_time;
+        l1s_increment_time(&(l1s.next_time), 1);  // Increment "next time".
+      #endif
+
+      #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+        trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1));//OMAPS00090550
+      #endif
+
+      l1s.tpu_ctrl_reg |= CTRL_SYCB;
+      l1s.dsp_ctrl_reg |= CTRL_SYNC;
+    }
+  }
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+}
+
+#if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0))  // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START         // KEEP IN EXTERNAL MEM otherwise
+
+#if 0	/* FreeCalypso TCS211 reconstruction */
+UWORD32 qual_acc_idle1[2];
+#endif
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_snb_dl()                                     */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* serving cell normal burst reading tasks: NP, EP,      */
+/* BCCHS, ALLC, DDL and ADL. This function is the control*/
+/* function for reading a normal burst on the serving    */
+/* cell. It programs the DSP and the TPU for reading a   */
+/* normal burst without change on the TPU OFFSET         */
+/* register and flags the reading of the normal paging   */
+/* burst. This flag is used by the measurement manager   */
+/* "l1s_meas_manager()" at the end of L1S. Here is a     */
+/* summary of the execution:                             */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*      - Catch ARFCN and set CIPHERING reduced frame    */
+/*        number.                                        */
+/*      - Traces and debug.                              */
+/*      - Programs DSP for required task.                */
+/*      - Programs TPU for required task.                */
+/*      - Flag the reading of a Normal Paging burst.     */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   NP, Normal paging reading task.                     */
+/*   EP, Extended paging reading task.                   */
+/*   BCCHS, BCCH Serving reading task.                   */
+/*   ALLC, All serving cell CCCH reading task.           */
+/*                                                       */
+/*   DDL, SDCCH DOWNLINK reading task.                   */
+/*   ADL, SACCH DOWNLINK (associated with SDCCH)reading  */
+/*   task.                                               */
+/*                                                       */
+/* "burst_id"                                            */
+/*   BURST_1, 1st burst of the task.                     */
+/*   BURST_2, 2nd burst of the task.                     */
+/*   BURST_3, 3rd burst of the task.                     */
+/*   BURST_4, 4th burst of the task.                     */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.dedic_set"                               */
+/*   Dedicated channel parameter structure. It is used   */
+/*   to get the ARFCN to use for SDCCH (DDL, ADL). This  */
+/*   ARFCN comes from the HOPPING algorithm called just  */
+/*   before calling this function.                       */
+/*                                                       */
+/* "l1a_l1s_com.Scell_info"                              */
+/*  Serving cell information structure.                  */
+/*    .radio_freq, serving cell beacon frequency.             */
+/*    .bsic, BSIC of the serving cell. It is used here   */
+/*           to pass the training sequence number (part  */
+/*           of BSIC) to the DSP.                        */
+/*                                                       */
+/* "l1s.afc"                                             */
+/*   current AFC value to be applied for the given task. */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for the TPU SYNCHRO and OFFSET registers      */
+/*   for current serving cell setting. It is used here   */
+/*   to refresh the TPU SYNCHRO and OFFSET registers     */
+/*   with a corrected (time tracking of the serving)     */
+/*   value prior to reading a serving cell normal burst. */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.np_ctrl"                                         */
+/*   Flag set when a normal paging burst reading is      */
+/*   controled. This flag is used by the measurement     */
+/*   manager "l1s_meas_manager()", at the end of L1S, to */
+/*   scheduling the neighbor cell measurements.          */
+/*   -> set to 1.                                        */
+/*                                                       */
+/* "l1s.tpu_win"                                         */
+/*   each frame is composed with a maximum of 3          */
+/*   working/TPU windows (typically RX/TX/PW). This is   */
+/*   a counter used to count the number of windows       */
+/*   used.                                               */
+/*   -> incremented.                                     */
+/*                                                       */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_snb_dl(UWORD8 task, UWORD8 burst_id)
+{
+  UWORD8          lna_off;
+  WORD8           agc;
+  UWORD16         rx_radio_freq;
+  UWORD8          tsc;
+  T_INPUT_LEVEL  *IL_info_ptr;
+  UWORD32         dsp_task;
+  static  BOOL    change_synchro;
+  UWORD8          adc_active = INACTIVE;
+#if (L1_FF_MULTIBAND == 1)
+  UWORD16 operative_radio_freq;
+#endif /*L1_FF_MULTIBAND*/
+  
+#if L1_GPRS
+  static  BOOL    algo_change_synchro_active = FALSE;
+  static  BOOL    BCCHS_in_transfert = FALSE;
+#endif
+#if 0	/* FreeCalypso match TCS211 */
+  UWORD8 input_level = 0; //omaps00090550
+#endif
+#if (RF_FAM == 61)
+  UWORD16 dco_algo_ctl_nb = 0;
+  UWORD8 if_ctl = 0;
+  UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+  // By default we choose the hardware filter
+  UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+#endif
+#if (NEW_SNR_THRESHOLD == 1)
+  UWORD8 saic_flag=0;
+#endif /* NEW_SNR_THRESHOLD */
+
+#if (FF_L1_FAST_DECODING == 1)
+  BOOL fast_decoding_authorized = FALSE;
+
+  if ( (burst_id == BURST_1) && (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_FORBIDDEN) )
+  {
+    l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_NONE;
+  }
+
+  fast_decoding_authorized = l1s_check_fast_decoding_authorized(task);
+
+  if ( fast_decoding_authorized && l1s_check_deferred_control(task,burst_id) )
+  {
+    /* Control is deferred until the upcoming fast decoding IT */
+    return;
+  } /* if (fast_decoding_authorized)*/
+
+  /* In all other cases, control must be performed now. */
+#endif /* FF_L1_FAST_DECODING == 1 */
+
+  if(!(l1a_l1s_com.task_param[task] == SEMAPHORE_SET))
+    // Check the task semaphore. The control body is executed only
+    // when the task semaphore is 0. This semaphore can be set to
+    // 1 whenever L1A makes some changes to the task parameters.
+  {
+    // Catch ARFCN and set CIPHERING reduced frame number.
+    // Catch Training sequence.
+    // ****************************************************
+
+    if((task == DDL) || (task == ADL))
+      // Dedicated mode SDCCH downlink.
+    {
+      // Get ARFCN to be used for current control.
+      rx_radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+
+      if (rx_radio_freq==l1a_l1s_com.Scell_info.radio_freq) // we are working on a beacon freq.
+        IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+      else
+        IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;// we are working on a daughter freq
+
+      // Catch training sequence code from the channel description.
+      tsc = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->tsc;
+
+      // Set CIPHERING reduced frame number.
+#if (AMR == 1)
+  #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+        SIG_ONLY_MODE,
+        l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+        #if !FF_L1_IT_DSP_DTX
+          0, 0, 0, 0, 0, 0);
+        #else
+          0, 0, 0, 0, 0, 0, 0);
+        #endif
+  #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+        SIG_ONLY_MODE,
+        l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+        #if !FF_L1_IT_DSP_DTX
+          0, 0, 0, 0);
+        #else
+          0, 0, 0, 0, 0);
+        #endif
+  #endif
+#else
+  #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+        SIG_ONLY_MODE,
+        l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+        #if !FF_L1_IT_DSP_DTX
+          0, 0, 0, 0, 0);
+        #else
+          0, 0, 0, 0, 0, 0);
+        #endif
+  #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+        SIG_ONLY_MODE,
+        l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+        #if !FF_L1_IT_DSP_DTX
+          0, 0, 0);
+        #else
+          0, 0, 0, 0);
+        #endif
+  #endif
+#endif
+      // for SDCCH we use DPAGC algorithm.
+#if DPAGC_MAX_FLAG
+      agc = Cust_get_agc_from_IL(rx_radio_freq, IL_info_ptr->input_level >> 1, MAX_ID);
+#else
+      agc = Cust_get_agc_from_IL(rx_radio_freq, IL_info_ptr->input_level >> 1, AV_ID);
+#endif
+      lna_off = IL_info_ptr->lna_off;
+
+
+
+      // Store input_level and lna_off field  used for current CTRL in order to be able to build IL
+      // from pm in READ phase.
+      l1a_l1s_com.Scell_used_IL = *IL_info_ptr;
+    } // end if (task == DDL) || (task == ADL)
+    else
+    {
+      rx_radio_freq = l1a_l1s_com.Scell_info.radio_freq;
+
+      // Catch training sequence code from serving cell BCC (part of BSIC).
+      tsc = l1a_l1s_com.Scell_info.bsic & 0x0007;
+
+      // for PCH/E_PCH/Serving BCCH and All CCCH we use
+      // PAGC algorithm.
+#if 1	/* FreeCalypso match TCS211 */
+
+      agc     = Cust_get_agc_from_IL(rx_radio_freq, l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, MAX_ID);
+      lna_off = l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+      // Store input_level and lna_off fields used for current CTRL in order to be able
+      // to build IL from pm in READ phase.
+      l1a_l1s_com.Scell_used_IL = l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset];
+
+#elif (L1_FF_MULTIBAND == 0)
+
+      input_level = l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset].input_level ;
+      lna_off = l1a_l1s_com.last_input_level[rx_radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+      agc     = Cust_get_agc_from_IL(rx_radio_freq, input_level >> 1, MAX_ID);
+
+
+      // Store input_level and lna_off fields used for current CTRL in order to be able
+      // to build IL from pm in READ phase.
+      l1a_l1s_com.Scell_used_IL = l1a_l1s_com.last_input_level[rx_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(rx_radio_freq);
+
+      input_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level ;
+      lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+      agc     = Cust_get_agc_from_IL(rx_radio_freq, input_level >> 1, MAX_ID);
+
+
+      // Store input_level and lna_off fields used for current CTRL in order to be able
+      // to build IL from pm in READ phase.
+      l1a_l1s_com.Scell_used_IL = l1a_l1s_com.last_input_level[operative_radio_freq];
+
+
+#endif // #if (L1_FF_MULTIBAND == 0) else
+
+      
+    }
+
+   #if(RF_FAM == 61)   // Locosto DCO
+          cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID ,
+                                                    input_level,
+                                                    rx_radio_freq,if_threshold);
+          l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+   #endif //RF_FAM =61
+
+    #if (L1_SAIC != 0)
+      // If SAIC is enabled, call the low level SAIC control function
+      csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+      #if (NEW_SNR_THRESHOLD == 1)
+          ,task
+          ,&saic_flag
+      #endif
+          );
+   #endif  //L1_SAIC != 0
+
+    // ADC measurement
+    // ***************
+    // check if during the 1st burst of the bloc an ADC measurement must be performed
+    if ((burst_id == BURST_1) && (task == NP))
+    {
+#if L1_GPRS
+      //In case of network mode of operation II or III, CCCH reading is possible
+      //in packet idle mode and in packet transfer mode.
+      //ADC measurements are already managed by comlex function of Packet idle tasks
+      if (!((l1a_l1s_com.l1s_en_task[PNP]    == TASK_ENABLED) ||
+        (l1a_l1s_com.l1s_en_task[PEP]    == TASK_ENABLED) ||
+        (l1a_l1s_com.l1s_en_task[PALLC]  == TASK_ENABLED) ||
+        (l1a_l1s_com.l1s_en_task[PDTCH]  == TASK_ENABLED) ||
+        (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)))
+#endif
+      {
+        adc_active = l1s_ADC_decision_on_NP();
+      }
+    } // end if (burst_id == BURST_1) && (task == NP)
+
+    if (task == ADL)
+    {
+      // ADC measurement for SACCH DL
+      // ****************************
+
+      // check if during the SACCH burst an ADC measurement must be performed
+      if (l1a_l1s_com.adc_mode & ADC_NEXT_TRAFFIC_DL)  // perform ADC only one time
+      {
+        adc_active = ACTIVE;
+        l1a_l1s_com.adc_mode &= ADC_MASK_RESET_TRAFFIC; // reset in order to have only one ADC measurement in Traffic
+      }
+      else
+      if (l1a_l1s_com.adc_mode & ADC_EACH_TRAFFIC_DL) // perform ADC on each period bloc
+      {
+        if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_traffic_period) // wait for the period
+        {
+          adc_active = ACTIVE;
+          l1a_l1s_com.adc_cpt = 0;
+        }
+      }
+    }
+
+    // Traces and debug.
+    // ******************
+
+#if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+#endif
+
+#if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+    trace_fct(CST_L1S_CTRL_SNB_DL_BURST0 + burst_id, (UWORD32)(-1));//OMAPS00090550
+#endif
+
+#if (TRACE_TYPE==5)
+    trace_fct(CST_L1S_CTRL_SNB_DL, rx_radio_freq);
+#endif
+
+    l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+    // the l1a_l1s_com.mode variable could change during the block: So test this variable only on the 1st block
+    // See BUG2237 (mode change from Idle to Transfert during BCCHS task)
+#if (L1_GPRS)
+    if (burst_id == BURST_1)
+      BCCHS_in_transfert = ((l1a_l1s_com.mode == PACKET_TRANSFER_MODE) && ((task == EBCCHS) || (task == NBCCHS)));
+#endif
+
+    // Programs DSP according to the DSP scheduler used
+    // *************************************************
+
+
+#if (L1_GPRS)
+    switch(l1a_l1s_com.dsp_scheduler_mode)
+    {
+      // dsp pgm is made using GSM scheduler...
+    case GSM_SCHEDULER:
+#if (FF_L1_FAST_DECODING == 1)
+      l1ddsp_load_fast_dec_task(task,burst_id);
+#endif
+      dsp_task = l1s_swap_iq_dl(rx_radio_freq,task);
+      l1ddsp_load_rx_task(dsp_task, burst_id, tsc);
+      break;
+
+      // dsp pgm is made using GPRS scheduler...
+    case GPRS_SCHEDULER:
+#if (FF_L1_FAST_DECODING == 1)
+          l1ddsp_load_fast_dec_task(task,burst_id);
+#endif
+        #if FF_L1_IT_DSP_USF
+          l1pddsp_idle_rx_nb(burst_id,tsc,rx_radio_freq,0,FALSE,FALSE);
+        #else
+          l1pddsp_idle_rx_nb(burst_id,tsc,rx_radio_freq,0,FALSE);
+        #endif
+      break;
+    }
+#else
+#if (FF_L1_FAST_DECODING == 1)
+    l1ddsp_load_fast_dec_task(task,burst_id);
+#endif
+    dsp_task = l1s_swap_iq_dl(rx_radio_freq,task);
+    l1ddsp_load_rx_task(dsp_task, burst_id, tsc);
+#endif
+
+    // update the TPU with the new TOA if necessary
+    l1ctl_update_TPU_with_toa();
+
+    // Programs TPU for required task.
+    // ********************************
+#if (L1_GPRS)
+
+    //In case of network mode of operation II or III, CCCH reading is possible
+    //in packet idle mode and in packet transfer mode.
+    // if (TS(CCCH) - TS(current task))%8 >= 4    synchro change is required
+    // if not, OFFSET change is required
+    //
+    if (((task == EP) || (task == NP)) &&
+      ((l1a_l1s_com.l1s_en_task[PNP]    == TASK_ENABLED) ||
+      (l1a_l1s_com.l1s_en_task[PEP]    == TASK_ENABLED) ||
+      (l1a_l1s_com.l1s_en_task[PALLC]  == TASK_ENABLED) ||
+      (l1a_l1s_com.l1s_en_task[PDTCH]  == TASK_ENABLED) ||
+      (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)))
+    {
+      UWORD32  new_offset;
+      WORD32   new_synchro;
+      UWORD32  ts_ccch;
+
+      ts_ccch =  (l1a_l1s_com.ccch_group * 2);                //timeslot CCCH burts
+      new_offset = (ts_ccch  - l1a_l1s_com.dl_tn + 8) % 8;    //dl_tn is the current time slot from previous task
+
+      if (burst_id == BURST_1)
+        l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+
+      if (new_offset >= 4)
+        algo_change_synchro_active = TRUE;
+
+      if (algo_change_synchro_active)
+      {
+        // compute TPU offset for "current timeslot + 4 timeslot"
+        new_synchro = l1s.tpu_offset + (4 * TN_WIDTH);
+
+        if(new_synchro >= TPU_CLOCK_RANGE)
+          new_synchro -= TPU_CLOCK_RANGE;
+
+        //compute new offset
+        new_offset = (((ts_ccch + 4 - l1a_l1s_com.dl_tn)%8) * TN_WIDTH) + new_synchro;
+      }
+      //no synchro change required, but new offset is computed
+      else
+      {
+        new_synchro = l1s.tpu_offset;
+        new_offset = (new_offset * TN_WIDTH) + new_synchro;
+      }
+
+      if (new_offset >= TPU_CLOCK_RANGE)
+        new_offset -= TPU_CLOCK_RANGE;
+
+      // tpu pgm...
+      l1dtpu_serv_rx_nb(rx_radio_freq,
+        agc,
+        lna_off,
+        new_synchro,
+        new_offset,
+        TRUE,
+        adc_active
+        #if (RF_FAM == 61)
+	   ,csf_filter_choice
+	   ,if_ctl
+	#endif
+    #if (NEW_SNR_THRESHOLD == 1)
+     ,saic_flag
+    #endif /*NEW_SNR_THRESHOLD */
+        );
+    } // end if (task == EP) || (task == NP) in packet Idle
+
+    // in case of EBCCHS and NBCCHS in packet transfer a change synchro is performed
+    else if (BCCHS_in_transfert)
+    {
+      UWORD32  new_offset;
+      WORD32   new_synchro;
+
+      change_synchro = ((l1a_l1s_com.dl_tn > 0) && (l1a_l1s_com.dl_tn < 5 ));
+
+      // if change synchro is needed
+      if(change_synchro) // TS= [1,2,3,4]
+      {
+        // the synchro is changed by 4 timeslots.
+        new_synchro = l1s.tpu_offset + (4 * TN_WIDTH);
+        if(new_synchro >= TPU_CLOCK_RANGE)
+          new_synchro -= TPU_CLOCK_RANGE;
+
+        // the TPU offset is changed according to the PDTCH time slot
+        // because of the new synchro above with a shift of 4TS,
+        // 4TS are substract to the offset
+        new_offset  = (8 - 4 - l1a_l1s_com.dl_tn) * TN_WIDTH;
+      }
+      else
+      {
+        // the synchro is unchanged
+        new_synchro = l1s.tpu_offset;
+
+        // the TPU offset is changed according to the PDTCH time slot
+        new_offset  = (8 - l1a_l1s_com.dl_tn) * TN_WIDTH;
+      }
+
+      new_offset += new_synchro;
+      if (new_offset >= TPU_CLOCK_RANGE)
+        new_offset -= TPU_CLOCK_RANGE;
+
+      // tpu pgm...
+      #if (RF_FAM == 61)
+        l1dtpu_serv_rx_nb(rx_radio_freq,
+          agc,
+          lna_off,
+          new_synchro,
+          new_offset,
+          TRUE,
+          adc_active,
+          csf_filter_choice,
+          if_ctl
+          #if (NEW_SNR_THRESHOLD == 1)
+          ,saic_flag
+          #endif /*NEW_SNR_THRESHOLD */
+          );
+	#endif
+
+	#if(RF_FAM != 61)
+         l1dtpu_serv_rx_nb(rx_radio_freq,
+           agc,
+           lna_off,
+           new_synchro,
+           new_offset,
+           TRUE,
+           adc_active);
+	#endif
+
+    } // end if (task == EBCCHS) || (task == NBCCHS) in packet Idle
+    else
+#endif
+    {
+      // tpu pgm...
+      #if (RF_FAM == 61)
+        l1dtpu_serv_rx_nb(rx_radio_freq,
+          agc,
+          lna_off,
+          l1s.tpu_offset,
+          l1s.tpu_offset,
+          FALSE,
+          adc_active,
+          csf_filter_choice,
+          if_ctl
+          #if (NEW_SNR_THRESHOLD == 1)
+          ,saic_flag
+          #endif /*NEW_SNR_THRESHOLD */
+          );
+	#endif
+       #if (RF_FAM != 61)
+         l1dtpu_serv_rx_nb(rx_radio_freq,
+           agc,
+           lna_off,
+           l1s.tpu_offset,
+           l1s.tpu_offset,
+           FALSE,
+           adc_active);
+	#endif
+    }
+
+    // Increment tpu window identifier.
+    l1s.tpu_win += (l1_config.params.rx_synth_load_split + RX_LOAD);
+
+    // GSM DSP scheduler is not able to handle PWR too close to RX normal burst.
+    // We have to oblige a min of 1 burst period between RX and PWR
+    if(l1_config.params.rx_synth_load_split < BP_SPLIT)
+      l1s.tpu_win += BP_SPLIT - l1_config.params.rx_synth_load_split;
+
+   #if L2_L3_SIMUL
+   #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+       buffer_trace(4, l1s.actual_time.fn, rx_radio_freq,
+         l1s.tpu_win,l1s.tpu_offset);
+   #endif
+   #endif
+  }
+
+    #if (L1_GPRS)
+
+    //In case of network mode of operation II or III, CCCH reading is possible
+    //in packet idle mode and in packet transfer mode.
+
+    if (((task == EP) || (task == NP)) &&
+        ((l1a_l1s_com.l1s_en_task[PNP]    == TASK_ENABLED) ||
+         (l1a_l1s_com.l1s_en_task[PEP]    == TASK_ENABLED) ||
+         (l1a_l1s_com.l1s_en_task[PALLC]  == TASK_ENABLED) ||
+         (l1a_l1s_com.l1s_en_task[PDTCH]  == TASK_ENABLED) ||
+         (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)))
+    {
+        if((burst_id == BURST_4) && algo_change_synchro_active)
+        {
+
+            // Slide synchro back to mach current serving timeslot.
+            l1dmacro_synchro(SWITCH_TIME, l1s.tpu_offset);
+
+
+            // Increment frame number.
+            l1s.actual_time    = l1s.next_time;
+            l1s.next_time      = l1s.next_plus_time;
+            l1s_increment_time (&(l1s.next_plus_time), 1);  // Increment "next_plus time".
+
+            l1s.tpu_ctrl_reg |= CTRL_SYCB;
+            l1s.dsp_ctrl_reg |= CTRL_SYNC;
+            l1s.ctrl_synch_before = FALSE;
+            algo_change_synchro_active = FALSE;
+
+            #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+              trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1));//OMAPS00090550
+            #endif
+        }
+    }
+
+    // in case of EBCCHS and NBCCHS in packet transfer a change synchro is performed
+    else if (BCCHS_in_transfert)
+    {
+      // Shift TPU SYNCHRO/OFFSET registers back to the default timeslot .
+      // ****************************************************************
+      // When the E/NBCCHS reading control is completed ,
+      // the SYNCHRO/OFFSET registers are shifted back to the normal
+      // setting used for PCCH reading on the serving cell.
+      // Check if "Synchro" change was needed.
+      // If so the synchro is changed to recover normal synchro.
+      if(burst_id == BURST_4)
+      {
+        if(change_synchro) // TS= [1,2,3,4]
+        {
+          // Slide synchro back to mach current serving timeslot.
+          l1dmacro_synchro(SWITCH_TIME, l1s.tpu_offset);
+
+          // Increment frame number.
+          l1s.actual_time    = l1s.next_time;
+          l1s.next_time      = l1s.next_plus_time;
+          l1s_increment_time(&(l1s.next_plus_time), 1);  // Increment "next_plus time".
+
+          #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+            trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1));//OMAPS00090550
+          #endif
+
+          l1s.tpu_ctrl_reg |= CTRL_SYCB;
+          l1s.dsp_ctrl_reg |= CTRL_SYNC;
+        }
+      }
+
+      // This task is not compatible with Neigh. Measurement. Store task length
+      // in "forbid_meas" to indicate when the task will last.
+      if(burst_id == BURST_1)
+        l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+    }
+  #endif
+
+  // Flag the reading of a Normal Paging burst.
+  // *******************************************
+
+  // Set flag "NP contoled !!". Used in "l1_synch()" to generate meas. controles.
+  if(task == NP)
+     l1a_l1s_com.ba_list.np_ctrl = burst_id+1;
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+}
+
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+#endif
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_snb_ul()                                     */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* serving cell normal burst sending tasks: DUL, AUL.    */
+/* This function is the control function for sending a   */
+/* burst on a SDCCH channel. It programs the DSP and the */
+/* TPU for sending a normal burst taking into account    */
+/* the timing adavance. Here is a summary of the         */
+/* execution:                                            */
+/*                                                       */
+/*  - Catch ARFCN.                                       */
+/*  - Traces and debug.                                  */
+/*  - Programs DSP for required task.                    */
+/*  - Catch UL data block from DLL and gives it to DSP.  */
+/*  - Programs TPU for required task.                    */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   DUL, SDCCH UPLINK sending task.                     */
+/*   AUL, SACCH UPLINK (associated with SDCCH)sending    */
+/*   task.                                               */
+/*                                                       */
+/* "burst_id"                                            */
+/*   BURST_1, 1st burst of the task.                     */
+/*   BURST_2, 2nd burst of the task.                     */
+/*   BURST_3, 3rd burst of the task.                     */
+/*   BURST_4, 4th burst of the task.                     */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.dedic_set"                               */
+/*   Dedicated channel parameter structure. It is used   */
+/*   to get the ARFCN to use for SDCCH (DUL, AUL). This  */
+/*   ARFCN comes from the HOPPING algorithm called just  */
+/*   before calling this function.                       */
+/*                                                       */
+/* "l1a_l1s_com.Scell_info"                              */
+/*  Serving cell information structure.                  */
+/*    .bsic, BSIC of the serving cell. It is used here   */
+/*           to pass the training sequence number (part  */
+/*           of BSIC) to the DSP.                        */
+/*                                                       */
+/* "l1s.afc"                                             */
+/*   current AFC value to be applied for the given task. */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for the TPU SYNCHRO and OFFSET registers      */
+/*   for current serving cell setting. It is used here   */
+/*   to restore this value in the OFFSET register after  */
+/*   the TX burst programming.                           */
+/*                                                       */
+/* "l1s.applied_txpwr"                                   */
+/*   Applied transmit power.                             */
+/*                                                       */
+/* "l1s.reported_txpwr"                                  */
+/*   Transmit power to report in the L1 header of the    */
+/*   SACCH data block.                                   */
+/*                                                       */
+/* "l1a_l1s_com.dedic_set.aset"                          */
+/*   Active dedicated mode parameter set.                */
+/*    .timing_advance, Timing advance to apply to the UL */
+/*                     burst transmission.               */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_win"                                         */
+/*   each frame is composed with a maximum of 3          */
+/*   working/TPU windows (typically RX/TX/PW). This is   */
+/*   a counter used to count the number of windows       */
+/*   used.                                               */
+/*   -> set to TDMA_WIN3.                                */
+/*                                                       */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_snb_ul(UWORD8 task, UWORD8 burst_id)
+{
+  T_RADIO_FRAME  *tx_data = NULL;
+  UWORD16         tx_radio_freq;
+  UWORD32         dsp_task;
+  UWORD8          adc_active_ul = INACTIVE;
+
+  // Catch ARFCN.
+  // *************
+
+  // Get ARFCN to be used for current control.
+  tx_radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+
+  // Traces and debug.
+  // ******************
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+    if(burst_id == BURST_1) trace_flowchart_dsptx(dltsk_trace[task].name);
+  #endif
+
+  #if (TRACE_TYPE!=0)
+    trace_fct(CST_L1S_CTRL_SNB_UL, tx_radio_freq);
+  #endif
+
+  l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+  // Programs DSP for required task.
+  // ********************************
+
+  // Set CIPHERING reduced frame number.
+  #if (AMR == 1)
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            SIG_ONLY_MODE,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+                          #if !FF_L1_IT_DSP_DTX
+                            0, 0, 0, 0, 0, 0);
+    #else
+                            0, 0, 0, 0, 0, 0, 0);
+                          #endif
+    #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            SIG_ONLY_MODE,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+                          #if !FF_L1_IT_DSP_DTX
+                            0, 0, 0, 0);
+                          #else
+                            0, 0, 0, 0, 0);
+                          #endif
+    #endif
+  #else
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            SIG_ONLY_MODE,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+                          #if !FF_L1_IT_DSP_DTX
+                            0, 0, 0, 0, 0);
+                          #else
+                            0, 0, 0, 0, 0, 0);
+                          #endif
+    #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            SIG_ONLY_MODE,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type,
+                          #if !FF_L1_IT_DSP_DTX
+                            0, 0, 0);
+                          #else
+                            0, 0, 0, 0);
+                          #endif
+    #endif
+  #endif
+
+  if(task == DUL)
+  // SDCCH/UL task.
+  {
+    if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+    // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+    // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+    // Handover command is received from L3 through L1A.
+    {
+      // TX burst is a RACH.
+      // ********************
+      // dsp and tpu pgm...
+      l1s_ctrl_rach(RAHO,NO_PAR);
+
+      // Decrement number of HO ACCESS burst still to be sent.
+      // Rem: (-1) is used for Async. HO.
+      if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != -1)
+        l1a_l1s_com.dedic_set.aset->ho_acc_to_send --;
+
+      if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send == 0)
+      // Handover access procedure is completed.
+      // -> send L1C_HANDOVER_FINISHED message with "cause = COMPLETED" to L1A.
+      {
+        l1s_send_ho_finished(HO_COMPLETE);
+      }
+    }
+
+    else
+    {
+      // TX burst is a Normal Burst.
+      // ****************************
+      // dsp pgm...
+
+      #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+        RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+      #endif
+
+      dsp_task = l1s_swap_iq_ul(tx_radio_freq,task);
+
+      l1ddsp_load_tx_task(dsp_task,
+                          burst_id,
+                          l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->tsc);
+
+      // tpu pgm...
+      l1dtpu_serv_tx_nb(tx_radio_freq,
+                        l1a_l1s_com.dedic_set.aset->timing_advance,
+                        l1s.tpu_offset,
+                        l1s.applied_txpwr,INACTIVE);
+
+      // Catch UL data block from DLL and gives it to DSP.
+      // **************************************************
+      // SDCCH info.
+      if(burst_id == BURST_1)
+      // perform "PH_DATA_REQ" from L2...
+      {
+        // Get SDCCH/UL data block from L2.
+        tx_data = dll_read_dcch(SIG_ONLY_MODE);
+
+        // Store the UL data block in MCU/DSP interface.
+        if(tx_data != NULL)  // NULL should never occur !!!
+        {
+          #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+            RTTL1_FILL_UL_DCCH
+            trace_info.facch_ul_count ++;
+          #endif
+
+          l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, &(tx_data->A[0]));
+        }
+      }
+    }
+
+    // In any case set TXPWR.
+    l1ddsp_load_txpwr(l1s.applied_txpwr, tx_radio_freq);
+
+  }  // End if(task == DUL)
+
+  else
+  // SACCH/UL task.
+  {
+
+    if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+    // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+    // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+    // Handover command is received from L3 through L1A.
+    // Rem: it is not allowed to send HO ACCESS burst on SACCH/UL. We must
+    // then avoid any normal burst transmission by setting txpwr=NO_TXPWR. The DSP
+    // and TPU are controled normally.
+    {
+      // Set TXPWR.
+      l1ddsp_load_txpwr(NO_TXPWR, tx_radio_freq);
+
+      #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+        RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, NO_TXPWR)
+      #endif
+    }
+
+    else
+    {
+      // Set TXPWR.
+      l1ddsp_load_txpwr(l1s.applied_txpwr, tx_radio_freq);
+
+      #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+        RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+      #endif
+    }
+
+    //ADC Measurements
+    //
+
+    // Check if during the SACCH burst an ADC measurement shall be performed
+
+    if (l1a_l1s_com.adc_mode & ADC_NEXT_TRAFFIC_UL)  // perform ADC only one time
+    {
+       adc_active_ul = ACTIVE;
+       l1a_l1s_com.adc_mode &= ADC_MASK_RESET_TRAFFIC; // reset in order to have only one ADC measurement in Traffic
+    }
+    else
+    {
+      if (l1a_l1s_com.adc_mode & ADC_EACH_TRAFFIC_UL) // perform ADC on each period bloc
+      {
+        if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_traffic_period) // wait for the period
+        {
+          adc_active_ul = ACTIVE;
+          l1a_l1s_com.adc_cpt = 0;
+        }
+      }
+    }
+
+
+    // In any case TX burst is a Normal Burst.
+    // ****************************************
+    // dsp pgm...
+
+    dsp_task = l1s_swap_iq_ul(tx_radio_freq,task);
+
+    l1ddsp_load_tx_task(dsp_task,
+                        burst_id,
+                        l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->tsc);
+
+    // tpu pgm...
+    l1dtpu_serv_tx_nb(tx_radio_freq,
+                      l1a_l1s_com.dedic_set.aset->timing_advance,
+                      l1s.tpu_offset,
+                      l1s.applied_txpwr,adc_active_ul);
+
+
+    // Catch UL data block from DLL and gives it to DSP.
+    // **************************************************
+    // SACCH info.
+    if(burst_id == BURST_1)
+    // perform "PH_DATA_REQ" from L2...
+    {
+
+      #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+      BOOL tx_data_flag = FALSE; //omaps00090550
+      #endif
+
+          #if (FF_REPEATED_SACCH == 1)
+	  	    #if TESTMODE
+	  	        if(l1_config.repeat_sacch_enable != REPEATED_SACCH_ENABLE) /* disable the repeated sacch mode  */
+	  	         {
+	  	             l1s.repeated_sacch.sro = 0; /* set no repetition order */
+	  	             l1s.repeated_sacch.buffer_empty = TRUE; /* set no buffer */
+	  	         }
+	  	    #endif /* TESTMODE */
+	  #endif /* (FF_REPEATED_SACCH == 1) */
+    #if (FF_REPEATED_SACCH == 1)
+      /* Get data from PS if only no repetition order is required (1st condition)
+         or no repetition candidate exists (2nd condition) */
+      if(    (l1s.repeated_sacch.sro == 0) || (l1s.repeated_sacch.buffer_empty == TRUE)    )
+{
+    #endif  /* (FF_REPEATED_SACCH == 1) */
+      tx_data = dll_read_sacch(SIG_ONLY_MODE);
+
+      if(tx_data != NULL)  // NULL should never occur !!!
+      {
+#if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+        tx_data_flag =TRUE;  //omaps00090550
+#endif
+        // Set L1 Header...
+        tx_data->A[0] = l1s.reported_txpwr;
+    #if (FF_REPEATED_SACCH == 1)
+		/* Include the SACCH Repetition Request (SRR) in the L1 Header */
+		tx_data->A[0] |= (l1s.repeated_sacch.srr <<6);
+
+   #endif  /* FF_REPEATED_SACCH */
+        tx_data->A[1] = l1a_l1s_com.dedic_set.aset->timing_advance;
+
+        // Store the UL data block in MCU/DSP interface.
+        l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, &(tx_data->A[0]));
+           #if (FF_REPEATED_SACCH == 1 )
+		        /* Store the block data in case of a retransmission order */
+		        /* Retransmission is done in case of a SAPI0 and not 3    */
+		          if(((tx_data->A[2]&0x1C) >> 2) == SAPI_0)
+		          {
+		              l1s_store_sacch_buffer( &(l1s.repeated_sacch), &(tx_data->A[0]));
+		           }
+		          else // FIXME FIXME NOT sure whether this needs to be done
+		          {
+		            /* the SACCH repetition block occurrence will always come as a consecutive pair */
+		            /* To handle DL UL | DL  UL  | DL UL                                             */
+		            /*            -               0 | SRO  3  | -   new data should be asked from PS old 0 cannot be repeated */
+		                 l1s.repeated_sacch.buffer_empty=TRUE;
+		          }
+		  #endif /* FF_REPEATED_SACCH */
+
+       }/*  end of   if(tx_data != NULL) */
+#if (FF_REPEATED_SACCH == 1)
+     }
+
+      else if ((l1s.repeated_sacch.sro == 1) && (l1s.repeated_sacch.buffer_empty == FALSE))
+      {
+         /*  Put data block in MCU/DSP com.  */
+         l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, l1s.repeated_sacch.buffer );
+         l1s.repeated_sacch.buffer_empty = TRUE;   /* Set that the buffer is now empty (only one repetition) */
+      }
+#endif /* FF_REPEATED_SACCH */
+
+      #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+          RTTL1_FILL_UL_SACCH(tx_data_flag,l1a_l1s_com.dedic_set.aset->timing_advance, l1s.reported_txpwr)   //omaps00090550
+      #endif
+
+    }
+  }
+
+  // Set tpu window identifier for Power meas after TX.
+  l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_nb_load_split + l1_config.params.rx_synth_load_split;
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_TX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_TX;
+  l1s.dsp_ctrl_reg |= CTRL_TX;
+}
+
+#if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_nnb()                                        */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* neigbor cell normal burst reading tasks: BCCHN.       */
+/* This function is the control function for reading 4   */
+/* normal bursts on a neighbor cell. It programs the DSP */
+/* and the TPU for reading the 4 bursts taking into      */
+/* account the time difference between the serving and   */
+/* the neighbor cells. To this avail, it shifts the TPU  */
+/* OFFSET register according to this time difference and */
+/* restores the serving offset value when the 4 burst    */
+/* reading are completed. Here is a summary of the       */
+/* execution:                                            */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*      - Traces and debug.                              */
+/*      - Programs DSP for required task.                */
+/*      - Programs TPU for required task.                */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   BCCHN, BCCH Neighbor reading task.                  */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.Ncell_info.bcch"                         */
+/*   cell information structure used for BCCHN task.     */
+/*                                                       */
+/* "l1a_l1s_com.l1s_en_task"                             */
+/*   L1S task enable bit register. Used here to check if */
+/*   the Full BCCH Reading task is enabled and then to   */
+/*   take the decision to reloading the serving value    */
+/*   in the TPU OFFSET register.                         */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for SYNCHRO and OFFSET register in the TPU    */
+/*   for current serving cell setting. At the end of     */
+/*   the task this value is restored in the OFFSET       */
+/*   register.                                           */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_nnb(UWORD8 task, UWORD8 param2)
+{
+  UWORD8           lna_off;
+  WORD8            agc;
+  T_NCELL_SINGLE  *cell_info_ptr = NULL;
+  BOOL             en_task;
+  BOOL             task_param;
+  UWORD32          dsp_task;
+#if(L1_FF_MULTIBAND == 1)
+ UWORD16 operative_radio_freq;
+ UWORD8  input_level;
+#endif
+  
+#if (RF_FAM == 61)
+       UWORD16 dco_algo_ctl_nb = 0;
+       UWORD8 if_ctl = 0;
+	   UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+#endif
+
+  // Get "enable" task flag and "synchro semaphore" for current task.
+  en_task    = l1a_l1s_com.l1s_en_task[task];
+  task_param = l1a_l1s_com.task_param[task];
+
+
+
+  if((en_task) && !(task_param))
+  // Check the task semaphore and enable flag. The control body is executed only
+  // when the task semaphore is 0 and enable flag is 1. The semaphore can be set to
+  // 1 whenever L1A makes some changes to the task parameters. The enable can be
+  // reset to 0 when the task is no more enabled.
+  {
+    // Get the cell information structure.
+    // ************************************
+    if (task == BCCHN)
+      cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm];
+    else // BCCHN_TOP and BCCHN_TRAN tasks
+      cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top];
+
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE!=0)
+      trace_fct(CST_L1S_CTRL_NNB, cell_info_ptr->radio_freq);
+    #endif
+
+    #if (TRACE_TYPE==5) && FLOWCHART
+      trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+    #endif
+
+    l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 6) ;
+
+    // Programs DSP for required task.
+    // ********************************
+
+    #if L1_GPRS
+      switch(l1a_l1s_com.dsp_scheduler_mode)
+      {
+        // dsp pgm is made using GSM scheduler...
+        case GSM_SCHEDULER:
+          dsp_task = l1s_swap_iq_dl(cell_info_ptr->radio_freq,task);
+          l1ddsp_load_rx_task(dsp_task,
+                              0,
+                              cell_info_ptr->tsc);
+        break;
+
+        // dsp pgm is made using GPRS scheduler...
+        case GPRS_SCHEDULER:
+          l1pddsp_load_bcchn_task(cell_info_ptr->tsc, cell_info_ptr->radio_freq);
+        break;
+      }
+    #else
+      // dsp pgm...
+      dsp_task = l1s_swap_iq_dl(cell_info_ptr->radio_freq,task);
+      l1ddsp_load_rx_task(dsp_task,
+                          0,
+                          cell_info_ptr->tsc);
+    #endif
+
+    // Programs TPU for required task.
+    // ********************************
+
+    // We program 4 burst reading. The OFFSET register is used to
+    // cope with the time difference between the serving and the
+    // neighbor cells. The serving cell offset value (l1s.tpu_offset)
+    // is restored at the end of the 4 burst reading.
+#if (L1_FF_MULTIBAND == 0)
+
+    // agc is computed from PGC2 algo result.
+    agc     = Cust_get_agc_from_IL(cell_info_ptr->radio_freq, l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level >> 1, AV_ID);
+    lna_off = l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].lna_off;
+
+#else // L1_FF_MULTIBAND = 1 below
+
+    operative_radio_freq = 
+      l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq);
+    lna_off = l1a_l1s_com.last_input_level[operative_radio_freq].lna_off;
+    input_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level;
+    // agc is computed from PGC2 algo result.
+    agc     = Cust_get_agc_from_IL(cell_info_ptr->radio_freq, l1a_l1s_com.last_input_level[operative_radio_freq].input_level >> 1, AV_ID);
+
+#endif // #if (L1_FF_MULTIBAND == 0) else
+
+
+
+    #if(RF_FAM == 61)  // Locosto DCO
+        cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID,
+#if (L1_FF_MULTIBAND == 0)        
+                                       l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level,
+#else
+                                       input_level,
+#endif                                        
+                                        cell_info_ptr->radio_freq,if_threshold);
+
+        //dco_algo_ctl has 0000 00ZL
+         dco_algo_ctl_nb *= 0x55;   // replicate 0000 00zL as ZLZL ZLZL
+
+        l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+    #endif
+
+    #if L2_L3_SIMUL
+      #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+        buffer_trace(4, l1s.actual_time.fn, cell_info_ptr->radio_freq,
+                        cell_info_ptr->time_alignmt, cell_info_ptr->fn_offset);
+      #endif
+    #endif
+
+  #if (RF_FAM == 61)
+      if ( cell_info_ptr->time_alignmt >= TPU_CLOCK_RANGE - EPSILON_SYNC)
+      {
+        // Insert 1 NOP to correct the EPSILON_SYNC side effect
+        l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                          agc,
+                          lna_off,
+                          cell_info_ptr->time_alignmt,
+                          l1s.tpu_offset,
+                          FALSE, 1,
+   			     if_ctl
+            #if (NEW_SNR_THRESHOLD == 1)
+             ,SAIC_OFF
+            #endif /* NEW_SNR_THRESHOLD == 1*/
+             );
+      }
+      else
+      {
+        l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                          agc,
+                          lna_off,
+                          cell_info_ptr->time_alignmt,
+                          l1s.tpu_offset,
+                          FALSE, 0,
+   			     if_ctl
+             #if (NEW_SNR_THRESHOLD == 1)
+             ,SAIC_OFF
+            #endif /* NEW_SNR_THRESHOLD == 1*/
+             );
+      }
+
+      l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                        agc,
+                        lna_off,
+                        cell_info_ptr->time_alignmt,
+                        l1s.tpu_offset,
+                        FALSE, 0,
+   			     if_ctl
+             #if (NEW_SNR_THRESHOLD == 1)
+             ,SAIC_OFF
+            #endif /* NEW_SNR_THRESHOLD == 1*/
+             );
+      l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                        agc,
+                        lna_off,
+                        cell_info_ptr->time_alignmt,
+                        l1s.tpu_offset,
+                        FALSE, 0,
+   			     if_ctl
+            #if (NEW_SNR_THRESHOLD == 1)
+             ,SAIC_OFF
+            #endif /* NEW_SNR_THRESHOLD == 1*/
+             );
+      l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                        agc,
+                        lna_off,
+                        cell_info_ptr->time_alignmt,
+                        l1s.tpu_offset,
+                        TRUE, 0,
+   			     if_ctl
+            #if (NEW_SNR_THRESHOLD == 1)
+             ,SAIC_OFF
+            #endif /* NEW_SNR_THRESHOLD == 1*/
+             );
+  #endif // RF_FAM == 61
+
+  #if (RF_FAM != 61)
+      if ( cell_info_ptr->time_alignmt >= TPU_CLOCK_RANGE - EPSILON_SYNC)
+      {
+        // Insert 1 NOP to correct the EPSILON_SYNC side effect
+        l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                          agc,
+                          lna_off,
+                          cell_info_ptr->time_alignmt,
+                          l1s.tpu_offset,
+                          FALSE, 1);
+      }
+      else
+      {
+        l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                          agc,
+                          lna_off,
+                          cell_info_ptr->time_alignmt,
+                          l1s.tpu_offset,
+                          FALSE, 0);
+      }
+
+      l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                        agc,
+                        lna_off,
+                        cell_info_ptr->time_alignmt,
+                        l1s.tpu_offset,
+                        FALSE, 0);
+      l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                        agc,
+                        lna_off,
+                        cell_info_ptr->time_alignmt,
+                        l1s.tpu_offset,
+                        FALSE, 0);
+      l1dtpu_neig_rx_nb(cell_info_ptr->radio_freq,
+                        agc,
+                        lna_off,
+                        cell_info_ptr->time_alignmt,
+                        l1s.tpu_offset,
+                        TRUE, 0);
+  #endif // RF_FAM != 61
+  }
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+
+  #if L1_GPRS
+  // This task is not compatible with Neigh. Measurement. Store task length
+  // in "forbid_meas" to indicate when the task will last.
+  if(task == BCCHN_TRAN)
+  {
+    // In IDLE mode, l1s.forbid_meas is setted by the AGC ctrl
+    l1s.forbid_meas = TASK_ROM_MFTAB[task].size;
+  }
+  #endif
+}
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+#endif // MOVE_IN_INTERNAL_RAM
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_rach()                                       */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* serving cell Random Access burst sending tasks: RAAC, */
+/* RAHO. This function is the control function for       */
+/* sending a random access burst to the serving cell.    */
+/* This sending is either a Channel Request (connection  */
+/* establishment) or a Handover Access burst (dedicated  */
+/* mode). It programs the DSP and the TPU for sending a  */
+/* random access burst with a null timing advance.       */
+/* Here is a summary of the execution:                   */
+/*                                                       */
+/*  - Traces and debug.                                  */
+/*  - Programs DSP for required task.                    */
+/*  - Build RACH data block and store in MCU/DSP com.    */
+/*  - Programs TPU for required task.                    */
+/*  - Send confirmation msg to L1A.                      */
+/*  - Flag DSP and TPU programmation.                    */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   RAAC, RACH sending task for Channel Request.        */
+/*   RAHO, RACH sending task for Handover Access.        */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.Scell_info"                              */
+/*  Serving cell information structure.                  */
+/*    .bsic, BSIC of the serving cell. It is used here   */
+/*           to pass the training sequence number (part  */
+/*           of BSIC) to the DSP.                        */
+/*    .radio_freq, serving cell beacon frequency.             */
+/*                                                       */
+/* "l1s.afc"                                             */
+/*   current AFC value to be applied for the given task. */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for the TPU SYNCHRO and OFFSET registers      */
+/*   for current serving cell setting. It is used here   */
+/*   to restore this value in the OFFSET register after  */
+/*   the TX burst programming.                           */
+/*                                                       */
+/* "l1s.applied_txpwr"                                   */
+/*   Applied transmit power.                             */
+/*                                                       */
+/* "l1a_l1s_com.ra_info"                                 */
+/*   random access task parameters.                      */
+/*   .channel_request, random number sent in the case    */
+/*      of Channel Request (RAAC).                       */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_win"                                         */
+/*   each frame is composed with a maximum of 3          */
+/*   working/TPU windows (typically RX/TX/PW). This is   */
+/*   a counter used to count the number of windows       */
+/*   used.                                               */
+/*   -> set to TDMA_WIN3.                                */
+/*                                                       */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_rach(UWORD8 task, UWORD8 param2)
+{
+  UWORD8   tx_data[2];
+  UWORD16  radio_freq=0;
+  UWORD32  dsp_task;
+  UWORD8   adc_active=INACTIVE;
+
+  // Get ARFCN to be used for current control.
+  // *******************************************
+
+  if(task == RAHO)
+  // Handover Access...
+  {
+    // The ARFCN comes from the HOPPING algorithm called
+    // prior to calling any CTRL function in the current frame.
+    radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+  }
+  else
+  // Network Access...
+  {
+    #if TESTMODE
+      if (l1_config.TestMode)
+      {
+        // A TX_TCH task has been enabled in TestMode with burst_type=access burst.
+        // Thus set radio_freq to tch_arfcn .
+        radio_freq = l1_config.tmode.rf_params.tch_arfcn;
+      }
+      else
+    #endif
+    {
+      // The ARFCN is the BEACON frequency.
+      radio_freq = l1a_l1s_com.Scell_info.radio_freq;
+    }
+  }
+
+
+  // ADC measurement
+  // ***************
+
+  // check if during the RACH an ADC measurement must be performed
+  if (task == RAACC)
+   if (l1a_l1s_com.adc_mode & ADC_EACH_RACH)  // perform ADC on each burst
+       adc_active = ACTIVE;
+
+
+  // Traces and debug.
+  // ******************
+
+  #if (TRACE_TYPE!=0)
+    trace_fct(CST_L1S_CTRL_RACH, radio_freq);
+  #endif
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dsp_tpu(dltsk_trace[task].name);
+  #endif
+
+  l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+  #if (CODE_VERSION!=SIMULATION)
+    #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+      L1_trace_string("RA");
+    #endif
+  #endif
+
+  // Programs DSP for required task.
+  // ********************************
+
+  // dsp pgm...
+
+  dsp_task = l1s_swap_iq_ul(radio_freq,task);
+
+  l1ddsp_load_ra_task(dsp_task);
+
+  // Set TXPWR.
+  l1ddsp_load_txpwr(l1s.applied_txpwr, radio_freq);
+
+  // Build RACH data block and store in MCU/DSP com.
+  // ************************************************
+
+  // RACH info.
+  if(task == RAACC)
+  // RACH data is only the "channel_request". (BYTE format data).
+  {
+    tx_data[0] = (l1a_l1s_com.Scell_info.bsic << 2);
+    tx_data[1] = l1a_l1s_com.ra_info.channel_request;
+
+  }
+  else
+  // RACH data is only the "handover access" (BYTE format data).
+  {
+    tx_data[0] = (l1a_l1s_com.Scell_info.bsic << 2);
+    tx_data[1] = l1a_l1s_com.dedic_set.aset->ho_acc;
+  }
+
+  // Store data block in MCU/DSP com.
+  l1ddsp_load_info(DSP_TASK_CODE[task], &(l1s_dsp_com.dsp_ndb_ptr->d_rach), &(tx_data[0]));
+
+  // Programs TPU for required task.
+  // ********************************
+
+  // tpu pgm...
+  l1dtpu_serv_tx_ra(radio_freq, l1s.tpu_offset, l1s.applied_txpwr, adc_active);
+
+  // Set tpu window identifier for Power meas if any.
+  l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_ra_load_split + l1_config.params.rx_synth_load_split;
+
+  #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+    RTTL1_FILL_UL_AB(task, l1s.applied_txpwr)
+  #endif
+
+  // Flag DSP and TPU programmation.
+  // ********************************
+
+  // Set "CTRL_TX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_TX;
+  l1s.dsp_ctrl_reg |= CTRL_TX;
+}
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_tchtd()                                      */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description: This function controls the non transmitting slot in case of Half Rate TCH  */
+/* ------------                                          */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_tchtd(UWORD8 task, UWORD8 param2)
+{
+  T_CHANNEL_DESCRIPTION  *desc_ptr;
+  #if FF_L1_IT_DSP_DTX
+    BOOL dtx_dsp_interrupt = FALSE;
+  #endif
+
+  // Traces and debug.
+  // ******************
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dsp_tpu(dltsk_trace[TCHD].name);
+  #endif
+
+  l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+  // Catch channel description.
+  // ***************************
+
+  // Catch the active channel description used along the routine.
+  // It contains:
+  //    "channel_type", {TCH_F, TCH_H, SDCCH_4, SDCCH_8}.
+  //    "subchannel", {0, 1}. 0 is the default value for TCH_F.
+  desc_ptr = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr;
+
+  /**************************************************************************/
+  /* TCH/Dummy Receive...                                                   */
+  /**************************************************************************/
+  #if (TRACE_TYPE!=0)
+    trace_fct(CST_L1S_CTRL_TCHT_DUMMY__DL, l1a_l1s_com.dedic_set.radio_freq);
+  #endif
+
+  #if FF_L1_IT_DSP_DTX
+    // Fast DTX active only in TCH AHS
+    if ((l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_AHS_MODE)
+        && (l1a_l1s_com.dedic_set.aset->dtx_allowed == TRUE))
+    {
+      // AHS0
+      if (desc_ptr->subchannel == 0)
+      {
+        // DTX interrupt request for B1 and B2 (no DTX uncertainty on B0 thanks to idle frame)
+        if (l1s.next_time.fn_mod13 <= 7)
+          dtx_dsp_interrupt = TRUE;
+      }
+
+      // AHS1
+      else
+      {
+        // DTX interrupt requested for ALL blocks (idle frame does not help)
+        dtx_dsp_interrupt = TRUE;
+      }
+    }
+  #endif
+
+  /*--------------------------------------------*/
+  /* Program DSP...                             */
+  /*--------------------------------------------*/
+  // dsp pgm.
+  l1ddsp_load_rx_task(DSP_TASK_CODE[task], 0, desc_ptr->tsc);
+
+  /*--------------------------------------------*/
+  /* Flag DSP and TPU programmation...          */
+  /*--------------------------------------------*/
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+
+
+  /*----------------------------------------------*/
+  /* Common for Dedicated mode: DSP parameters... */
+  /*----------------------------------------------*/
+  #if (AMR == 1)
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            0,
+                            l1a_l1s_com.dedic_set.reset_sacch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.vocoder_on);
+    #else
+                            l1a_l1s_com.dedic_set.vocoder_on,
+                            dtx_dsp_interrupt);
+                          #endif
+    #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                          #if !FF_L1_IT_DSP_DTX
+                            0);
+  #else
+                            0,
+                            dtx_dsp_interrupt);
+                          #endif
+    #endif
+  #else
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            l1a_l1s_com.dedic_set.reset_sacch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.vocoder_on);
+                          #else
+                            l1a_l1s_com.dedic_set.vocoder_on,
+                            dtx_dsp_interrupt);
+                          #endif
+    #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.sync_tch);
+                          #else
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            dtx_dsp_interrupt);
+                          #endif
+    #endif
+  #endif
+
+  // Clear "sync_tch" and "reset_sacch" flag to maintain normal TCH process.
+  l1a_l1s_com.dedic_set.sync_tch = FALSE;
+#if (FF_L1_TCH_VOCODER_CONTROL == 1)
+  l1a_l1s_com.dedic_set.reset_sacch = FALSE;
+#endif
+
+  // Set tpu window identifier for Power meas in case of dummy burst in Half-rate
+  l1s.tpu_win = 0;
+}
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_tchth()                                      */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* dedicated mode TCH task: TCHTH. This function is the  */
+/* control function for reading the DL burst and sending */
+/* the UL burst. The UL burst can be a Normal Burst in   */
+/* normal case or an Access Burst when starting a        */
+/* Handover procedure. Both Half rate and Full rate TCH  */
+/* channel are handled. The DSP and the TPU are          */
+/* programmed for both the DL and UL bursts. The timing  */
+/* advance is taken into account for positionning the UL */
+/* burst.                                                */
+/*                                                       */
+/* This function accesses the L1/DLL and L1/DATA         */
+/* interface ("dll_read_dcch()", "tx_tch_data()"         */
+/* functions respectively) and passes then the returned  */
+/* data blocks to the DSP.                               */
+/*                                                       */
+/* Here is a summary of the execution:                   */
+/*                                                       */
+/*  - Traces and debug.                                  */
+/*  - Catch channel description and ARFCN.               */
+/*  - TCH/T Receive...                                   */
+/*      - Program DSP for RX.                            */
+/*      - Program TPU for RX.                            */
+/*      - Flag DSP and TPU programmation.                */
+/*  - TCH/T Transmit...                                  */
+/*      - If Any Handover Access burst to send           */
+/*          - Call "l1s_ctrl_rach()".                    */
+/*      - Else                                           */
+/*          - Get DATA block if required for TCH.        */
+/*          - Program DSP for TX.                        */
+/*          - Program TPU for TX.                        */
+/*          - Flag DSP and TPU programmation.            */
+/*  - Common for DL/UL: DSP parameters.                  */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   TCHTH, Traffic Channel TCH Half rate.               */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.dedic_set"                               */
+/*   Dedicated channel parameter structure.              */
+/*     .radio_freq, ARFCN value set by the Hopping algo.      */
+/*     .aset, active dedicated parameter set.            */
+/*                                                       */
+/* "l1a_l1s_com.Scell_info"                              */
+/*  Serving cell information structure.                  */
+/*    .bsic, BSIC of the serving cell. It is used here   */
+/*           to pass the training sequence number (part  */
+/*           of BSIC) to the DSP.                        */
+/*                                                       */
+/* "l1s.afc"                                             */
+/*   current AFC value to be applied for the given task. */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for the TPU SYNCHRO and OFFSET registers      */
+/*   for current serving cell setting.                   */
+/*                                                       */
+/* "l1s.applied_txpwr"                                   */
+/*   Applied transmit power.                             */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_win"                                         */
+/*   each frame is composed with a maximum of 3          */
+/*   working/TPU windows (typically RX/TX/PW). This is   */
+/*   a counter used to count the number of windows       */
+/*   used.                                               */
+/*   -> set to TDMA_WIN3.                                */
+/*                                                       */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_tchth(UWORD8 task, UWORD8 param2)
+{
+  UWORD16                 radio_freq=0;
+  T_CHANNEL_DESCRIPTION  *desc_ptr;
+  UWORD8                  lna_off;
+  WORD8                   agc;
+  T_INPUT_LEVEL          *IL_info_ptr;
+  UWORD32                 dsp_task;
+  UWORD32                 fn_mod_52;
+  UWORD8 input_level;
+#if (RF_FAM == 61)
+  UWORD16 dco_algo_ctl_nb = 0;
+  UWORD8 if_ctl = 0;
+  UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+  // By default we choose the hardware filter
+  UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+#endif
+#if FF_L1_IT_DSP_DTX
+  BOOL                    dtx_dsp_interrupt=FALSE; //omaps00090550
+#endif
+#if (NEW_SNR_THRESHOLD == 1)
+  UWORD8 saic_flag=0;
+#endif /* NEW_SNR_THRESHOLD */
+  // Traces and debug.
+  // ******************
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dsp_tpu(dltsk_trace[TCHTH].name);
+  #endif
+
+  l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+  // Catch channel description and ARFCN.
+  // *************************************
+
+  // Catch the active channel description used along the routine.
+  // It contains:
+  //    "channel_type", {TCH_F, TCH_H, SDCCH_4, SDCCH_8}.
+  //    "subchannel", {0, 1}. 0 is the default value for TCH_F.
+  desc_ptr = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr;
+
+  // Get ARFCN to be used for current control. This  ARFCN comes from
+  // the HOPPING algorithm called just before calling this function.
+  radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+
+  if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+    IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+                       // we are working on a beacon freq.
+  else
+    IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;
+                       // we are working on a daughter freq.
+
+#if FF_L1_IT_DSP_DTX
+  // Skip RX DSP/RF programming part during DTX HISR
+  if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+  {
+#endif
+
+  /**************************************************************************/
+  /* TCH/T Receive...                                                       */
+  /**************************************************************************/
+  #if (TRACE_TYPE!=0)
+    trace_fct(CST_L1S_CTRL_TCHTH__DL, radio_freq);
+  #endif
+
+  /*--------------------------------------------*/
+  /* Program DSP...                             */
+  /*--------------------------------------------*/
+
+  dsp_task = l1s_swap_iq_dl(radio_freq,task);
+
+  // dsp pgm.
+  l1ddsp_load_rx_task(dsp_task, 0, desc_ptr->tsc);
+
+  // Set TXPWR.
+  l1ddsp_load_txpwr(l1s.applied_txpwr, radio_freq);
+
+ input_level =  IL_info_ptr->input_level ;
+
+  #if(RF_FAM == 61)   // Locosto DCO
+    cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID,
+                                              input_level ,
+                                              radio_freq,if_threshold);
+    l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+  #endif
+
+  /*--------------------------------------------*/
+  /* Program TPU...                             */
+  /*--------------------------------------------*/
+  // for TCHTH we use DPAGC algorithm.
+  #if DPAGC_MAX_FLAG
+    agc = Cust_get_agc_from_IL(radio_freq, input_level >> 1, MAX_ID);
+  #else
+    agc = Cust_get_agc_from_IL(radio_freq, input_level >> 1, AV_ID);
+  #endif
+  lna_off = IL_info_ptr->lna_off;
+
+
+  // Store input_level and lna_off fields used for current CTRL in order to be able
+  // to build IL from pm in READ phase.
+  l1a_l1s_com.Scell_used_IL = *IL_info_ptr;
+
+  #if (L1_SAIC != 0)
+    // If SAIC is enabled, call the low level SAIC control function
+    csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+    #if (NEW_SNR_THRESHOLD == 1)
+        ,task
+        ,&saic_flag
+    #endif
+    );
+  #endif
+
+  // update the TPU with the new TOA if necessary
+  l1ctl_update_TPU_with_toa();
+
+  // Program a serving cell normal burst reading in TPU.
+  #if (RF_FAM == 61)
+    l1dtpu_serv_rx_nb(radio_freq,
+                    agc,
+                    lna_off,
+                    l1s.tpu_offset,
+                    l1s.tpu_offset,
+                    FALSE,INACTIVE, csf_filter_choice, if_ctl
+                    #if (NEW_SNR_THRESHOLD == 1)
+                    ,saic_flag
+                    #endif /*NEW_SNR_THRESHOLD */
+                    );
+  #endif
+  #if (RF_FAM != 61)
+    l1dtpu_serv_rx_nb(radio_freq,
+                      agc,
+                      lna_off,
+                      l1s.tpu_offset,
+                      l1s.tpu_offset,
+                      FALSE,INACTIVE);
+  #endif
+
+  // Increment tpu window identifier.
+  l1s.tpu_win += (l1_config.params.rx_synth_load_split + RX_LOAD);
+
+  /*--------------------------------------------*/
+  /* Flag DSP and TPU programmation...          */
+  /*--------------------------------------------*/
+
+  // Set "CTRL_RX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+#if FF_L1_IT_DSP_DTX
+  } // if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+#endif
+
+  /**************************************************************************/
+  /* TCH/T Transmit...                                                      */
+  /**************************************************************************/
+
+  // Any Handover Access burst to send ?
+  // ************************************
+
+  if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+  // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+  // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+  // Handover command is received from L3 through L1A.
+  // We must then replace the TCH UL normal burst by a RACH and decrement
+  // this counter.
+  {
+    if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != -1)
+      l1a_l1s_com.dedic_set.aset->ho_acc_to_send --;
+    l1s_ctrl_rach(RAHO,NO_PAR);
+
+    if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send == 0)
+    // Handover access procedure is completed.
+    // -> send L1C_HANDOVER_FINISHED message with "cause = COMPLETED" to L1A.
+    {
+      l1s_send_ho_finished(HO_COMPLETE);
+    }
+  }
+  else
+  // TCH/UL is a normal burst.
+  {
+    UWORD8 channel_mode = l1a_l1s_com.dedic_set.aset->achan_ptr->mode;
+    //omaps00090550 UWORD8 channel_type = desc_ptr->channel_type;
+    UWORD8  subchannel = desc_ptr->subchannel;
+
+    #if (TRACE_TYPE!=0)
+      trace_fct(CST_L1S_CTRL_TCHTH__UL, radio_freq);
+    #endif
+
+#if FF_L1_IT_DSP_DTX
+  // FACCH and IDS handled during L1S, have to be skipped during DTX HISR
+  if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+  {
+    #endif
+
+    /*--------------------------------------------*/
+    /* Get DATA block if required for TCH.        */
+    /*--------------------------------------------*/
+    // Half rate traffic channel...
+    {
+      // Rem: time to get data block is
+      //      Subchannel 0: FN%26 in {0, 8, 17}.
+      //      Subchannel 1: FN%26 in {1, 9, 18}.
+      //   => normalised time: FN_normalised = FN%26 - subchannel, in {0, 8, 17}.
+      // so CTL: must occur 2 TDMAs before, on
+      //      Subchannel 0: FN%26 in {23, 6, 15}.
+      //      Subchannel 1: FN%26 in {24, 7, 16}.
+      UWORD8  normalised_fn = l1s.next_time.t2 - subchannel;  // FN%26 - subchannel
+
+      if((normalised_fn == 23) || (normalised_fn == 6) || (normalised_fn == 15))
+      // It is time to check if a FACCH/UL data block is available from DLL or
+      // if a data block is available from the DATA interface.
+      {
+        T_RADIO_FRAME  *tx_data = NULL;
+
+        // Check if any FACCH to transmit.
+        // Rem: when mode is "SIGNALLING ONLY" the "dll_read_dcch()" function
+        // always give back a block of FACCH (true block or dummy one).
+        tx_data = dll_read_dcch(channel_mode);
+        if(tx_data != NULL)
+        {
+          // In DTX mode in HS, all 6 FACCH 1/2 bursts must always be transmitted.
+          // Note: FACCH presence is checked 1 "control" before "control" of 1st burst of FACCH due to a DSP constraint
+          // i.e. 3 bursts before FACCH interleaving boundary
+          // So we must wait 1 control before controlling the transmission of 6 FACCH 1/2 bursts
+          l1s.facch_bursts = 7;
+
+          #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+            RTTL1_FILL_UL_DCCH
+            trace_info.facch_ul_count ++;
+          #endif
+
+          l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_fu, &(tx_data->A[0]));
+          #if (TRACE_TYPE==5) && FLOWCHART
+            trace_flowchart_dsptx(dltsk_trace[TCHTH].name);
+          #endif
+        }
+
+        #if (AMR == 1)
+          // Check if any DATA traffic info frame available.
+          // This check is used for all full rate channels except when
+          // this channel is in SIGNALLING ONLY mode or in Half Rate
+          // Speech mode or in adaptative Half Rate mode.
+          if((channel_mode != TCH_HS_MODE)  &&
+             (channel_mode != TCH_AHS_MODE) &&
+             (channel_mode != SIG_ONLY_MODE))
+        #else
+          // Check if any DATA traffic info frame available.
+          // This check is used for all full rate channels except when
+          // this channel is in SIGNALLING ONLY mode or in Half Rate
+          // Speech mode.
+          if((channel_mode != TCH_HS_MODE) && (channel_mode != SIG_ONLY_MODE))
+        #endif
+        {
+          UWORD8  *tx_data = NULL;
+
+          tx_data = tx_tch_data();
+          if(tx_data != NULL)
+          {
+            // Store the DATA/UL data block in the MCU/DSP com. according
+            // to the "subchannel".
+            if(subchannel == 0) l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_0, tx_data);
+            else                l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_1, tx_data);
+            #if (TRACE_TYPE==5) && FLOWCHART
+              trace_flowchart_dsptx(dltsk_trace[TCHTH].name);
+            #endif
+          }
+        }
+      }
+    }
+
+#if FF_L1_IT_DSP_DTX
+    // Fast DTX active only in TCH AHS
+    if ((l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_AHS_MODE)
+        && (l1a_l1s_com.dedic_set.aset->dtx_allowed == TRUE))
+    {
+      // AHS0
+      if (desc_ptr->subchannel == 0)
+      {
+        // DTX interrupt request for B1 and B2 (no DTX uncertainty on B0 thanks to idle frame)
+        if (l1s.next_time.fn_mod13 <= 7)
+          dtx_dsp_interrupt = TRUE;
+
+        // DTX uncertainty check
+        if  ((l1a_apihisr_com.dtx.fast_dtx_ready == TRUE) &&                   // Fast DTX can be used
+             ((l1s.next_time.fn_mod13 == 4) || (l1s.next_time.fn_mod13 == 8))) // new block boundary
+          l1a_apihisr_com.dtx.dtx_status = DTX_AWAITED;
+      }
+
+      // AHS1
+      else
+      {
+        // DTX interrupt requested for ALL blocks (idle frame does not help)
+        dtx_dsp_interrupt = TRUE;
+
+        // DTX uncertainty check
+        if  ((l1a_apihisr_com.dtx.fast_dtx_ready == TRUE) &&                   // Fast DTX can be used
+             ((l1s.next_time.fn_mod13 == 1) || (l1s.next_time.fn_mod13 == 5)|| (l1s.next_time.fn_mod13 == 9))) // new block boundary
+          l1a_apihisr_com.dtx.dtx_status = DTX_AWAITED;
+      }
+    }
+    else
+      l1a_apihisr_com.dtx.dtx_status = DTX_AVAILABLE;
+  } // if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+
+  // Postpone TPU/DSP programming when DTX status not available from DSP
+  if (l1a_apihisr_com.dtx.dtx_status != DTX_AWAITED)
+  {
+    BOOL tx_active =FALSE; //omaps00090550
+#endif
+    /*--------------------------------------------*/
+    /* Program DSP...                             */
+    /*--------------------------------------------*/
+
+    dsp_task = l1s_swap_iq_ul(radio_freq,task);
+
+    l1ddsp_load_tx_task(dsp_task, 0, desc_ptr->tsc);
+
+    /*--------------------------------------------*/
+    /* Program TPU...                             */
+    /*--------------------------------------------*/
+
+    fn_mod_52   = l1s.actual_time.fn % 52;
+
+    l1s.facch_bursts--;
+    if (l1s.facch_bursts < 0)
+      l1s.facch_bursts = -1;
+  #if FF_L1_IT_DSP_DTX
+    // Condition for TX TPU programming channel mode dependant
+    switch (channel_mode)
+    {
+      case SIG_ONLY_MODE:
+      case TCH_24H_MODE:
+      case TCH_48H_MODE:
+        // DTX not supported
+        tx_active = TRUE;
+        break;
+
+      case TCH_HS_MODE:
+        if ((l1s.dtx_ul_on == FALSE) ||                                // No DTX
+            ((l1s.facch_bursts >= 0) && (l1s.facch_bursts <= 5)) || // FACCH in progress
+            ((subchannel == 0) && ((fn_mod_52 == 51) || (/*(fn_mod_52 >= 0) && omaps00090550*/(fn_mod_52 <= 5)))) || // SID HS0
+            ((subchannel == 1) && (fn_mod_52 >= 13) && (fn_mod_52 <= 19)) // SID HS1
+           )
+          tx_active = TRUE;
+        else
+          tx_active = FALSE;
+        break;
+
+      case TCH_AHS_MODE:
+        if (l1a_apihisr_com.dtx.tx_active) // DSP (Fast) DTX status
+		tx_active = TRUE;
+        else
+          tx_active = FALSE;
+        break;
+    }
+
+    // TPU TX burst programming
+    if (tx_active)
+  #else
+
+    // In DTX mode, UL bursts should not be transmitted when no voice activity is detected
+    // we must not call TPU scenario if dtx_on == TRUE in HS (See Technical Memo)
+    // However, in DTX mode, several bursts must always be transmitted (See ETSI 05.08, 8.3)
+    if ( (channel_mode != TCH_HS_MODE) ||
+         (l1s.dtx_ul_on == FALSE) ||
+         ( (l1s.facch_bursts >= 0) && (l1s.facch_bursts <= 5) ) ||
+         ( (subchannel == 0) && ((fn_mod_52 == 51) || ((fn_mod_52 >= 0) && (fn_mod_52 <= 5))) ) ||
+         ( (subchannel == 1) && (fn_mod_52 >= 13) && (fn_mod_52 <= 19) ))
+  #endif
+    {
+        l1dtpu_serv_tx_nb(radio_freq, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.tpu_offset, l1s.applied_txpwr,INACTIVE);
+    }
+
+    #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+      RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+    #endif
+
+  #if FF_L1_IT_DSP_DTX
+    } // if (l1a_apihisr_com.dtx.dtx_status != DTX_AWAITED)
+  #endif
+  } // TCH/UL is a normal burst.
+
+
+#if FF_L1_IT_DSP_DTX
+  // Postpone TPU/DSP programming when DTX status not available from DSP
+  if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+  {
+#endif
+
+  /*----------------------------------------------*/
+  /* Common for Dedicated mode: DSP parameters... */
+  /*----------------------------------------------*/
+  #if (AMR == 1)
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            l1a_l1s_com.dedic_set.sync_amr,
+                            l1a_l1s_com.dedic_set.reset_sacch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.vocoder_on);
+    #else
+                            l1a_l1s_com.dedic_set.vocoder_on,
+                            dtx_dsp_interrupt);
+                          #endif
+    #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.sync_amr);
+                          #else
+                            l1a_l1s_com.dedic_set.sync_amr,
+                            dtx_dsp_interrupt);
+                          #endif
+    #endif
+
+    // Clear "sync_amr" flag to maintain normal TCH process.
+    l1a_l1s_com.dedic_set.sync_amr = FALSE;
+  #else
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            l1a_l1s_com.dedic_set.reset_sacch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.vocoder_on);
+    #else
+                            l1a_l1s_com.dedic_set.vocoder_on,
+                            dtx_dsp_interrupt);
+                          #endif
+    #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.sync_tch);
+                          #else
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            dtx_dsp_interrupt);
+                          #endif
+    #endif
+  #endif
+
+  // reset the FACCH header of the API buffer on the control following an ABORT to avoid decoding unwanted FACCH
+  if (l1a_l1s_com.dedic_set.reset_facch == TRUE)
+  {
+    // Reset A_FD header.
+    // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+    l1s_dsp_com.dsp_ndb_ptr->a_fd[0] = (1<<B_FIRE1);
+    l1s_dsp_com.dsp_ndb_ptr->a_fd[2] = 0xffff;
+  }
+
+  // Clear "sync_tch" and "reset_sacch" flag to maintain normal TCH process.
+  l1a_l1s_com.dedic_set.sync_tch = FALSE;
+  l1a_l1s_com.dedic_set.reset_facch = FALSE;
+#if (FF_L1_TCH_VOCODER_CONTROL == 1)
+  l1a_l1s_com.dedic_set.reset_sacch = FALSE;
+#endif
+
+  // Set tpu window identifier for Power meas.
+  l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_nb_load_split + l1_config.params.rx_synth_load_split;
+
+  /*--------------------------------------------*/
+  /* Flag DSP and TPU programmation...          */
+  /*--------------------------------------------*/
+
+  // Set "CTRL_TX" flag in the controle flag register.
+  l1s.tpu_ctrl_reg |= CTRL_TX;
+  l1s.dsp_ctrl_reg |= CTRL_TX;
+#if FF_L1_IT_DSP_DTX
+  } //if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+#endif
+}
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_tchtf()                                      */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* dedicated mode TCH task: TCHTF. This function is the  */
+/* control function for reading the DL burst and sending */
+/* the UL burst. The UL burst can be a Normal Burst in   */
+/* normal case or an Access Burst when starting a        */
+/* Handover procedure. Both Half rate and Full rate TCH  */
+/* channel are handled. The DSP and the TPU are          */
+/* programmed for both the DL and UL bursts. The timing  */
+/* advance is taken into account for positionning the UL */
+/* burst.                                                */
+/*                                                       */
+/* This function accesses the L1/DLL and L1/DATA         */
+/* interface ("dll_read_dcch()", "tx_tch_data()"         */
+/* functions respectively) and passes then the returned  */
+/* data blocks to the DSP.                               */
+/*                                                       */
+/* Here is a summary of the execution:                   */
+/*                                                       */
+/*  - Traces and debug.                                  */
+/*  - Catch channel description and ARFCN.               */
+/*  - TCH/T Receive...                                   */
+/*      - Program DSP for RX.                            */
+/*      - Program TPU for RX.                            */
+/*      - Flag DSP and TPU programmation.                */
+/*  - TCH/T Transmit...                                  */
+/*      - If Any Handover Access burst to send           */
+/*          - Call "l1s_ctrl_rach()".                    */
+/*      - Else                                           */
+/*          - Get DATA block if required for TCH.        */
+/*          - Program DSP for TX.                        */
+/*          - Program TPU for TX.                        */
+/*          - Flag DSP and TPU programmation.            */
+/*  - Common for DL/UL: DSP parameters.                  */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   TCHTF, Traffic Channel TCH Full rate.               */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.dedic_set"                               */
+/*   Dedicated channel parameter structure.              */
+/*     .radio_freq, ARFCN value set by the Hopping algo.      */
+/*     .aset, active dedicated parameter set.            */
+/*                                                       */
+/* "l1a_l1s_com.Scell_info"                              */
+/*  Serving cell information structure.                  */
+/*    .bsic, BSIC of the serving cell. It is used here   */
+/*           to pass the training sequence number (part  */
+/*           of BSIC) to the DSP.                        */
+/*                                                       */
+/* "l1s.afc"                                             */
+/*   current AFC value to be applied for the given task. */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for the TPU SYNCHRO and OFFSET registers      */
+/*   for current serving cell setting.                   */
+/*                                                       */
+/* "l1s.applied_txpwr"                                   */
+/*   Applied transmit power.                             */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_win"                                         */
+/*   each frame is composed with a maximum of 3          */
+/*   working/TPU windows (typically RX/TX/PW). This is   */
+/*   a counter used to count the number of windows       */
+/*   used.                                               */
+/*   -> set to TDMA_WIN3.                                */
+/*                                                       */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_tchtf(UWORD8 task, UWORD8 param2)
+{
+  UWORD16                 radio_freq=0;
+  T_CHANNEL_DESCRIPTION  *desc_ptr;
+  UWORD8                  lna_off;
+  WORD8                   agc;
+  T_INPUT_LEVEL          *IL_info_ptr;
+  UWORD32                 dsp_task;
+  UWORD32                 fn_mod_104;
+#if (RF_FAM == 61)
+  UWORD16 dco_algo_ctl_nb;
+  UWORD8 if_ctl =0 ; //omaps00090550
+  UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+  // By default we choose the hardware filter
+  UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+#endif
+#if FF_L1_IT_DSP_DTX
+  BOOL                    dtx_dsp_interrupt = FALSE;
+#endif
+#if (NEW_SNR_THRESHOLD == 1)
+  UWORD8 saic_flag;
+#endif
+  // Traces and debug.
+  // ******************
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dsp_tpu(dltsk_trace[TCHTF].name);
+  #endif
+
+  l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+  // Catch channel description and ARFCN.
+  // *************************************
+
+  // Catch the active channel description used along the routine.
+  // It contains:
+  //    "channel_type", {TCH_F, TCH_H, SDCCH_4, SDCCH_8}.
+  //    "subchannel", {0, 1}. 0 is the default value for TCH_F.
+  desc_ptr = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr;
+
+  // Get ARFCN to be used for current control. This  ARFCN comes from
+  // the HOPPING algorithm called just before calling this function.
+  radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+
+  if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+    IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+                       // we are working on a beacon freq.
+  else
+    IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;
+                       // we are working on a daughter freq.
+
+#if FF_L1_IT_DSP_DTX
+  // Skip RX DSP/RF programming part during DTX HISR
+  if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+  {
+#endif
+
+  /**************************************************************************/
+  /* TCH/T Receive...                                                       */
+  /**************************************************************************/
+  #if (TRACE_TYPE!=0)
+    trace_fct(CST_L1S_CTRL_TCHTF__DL, radio_freq);
+  #endif
+
+  /*--------------------------------------------*/
+  /* Program DSP...                             */
+  /*--------------------------------------------*/
+  // dsp pgm.
+
+  dsp_task = l1s_swap_iq_dl(radio_freq,task);
+
+  l1ddsp_load_rx_task(dsp_task, 0, desc_ptr->tsc);
+
+  #if(RF_FAM == 61)  // Locosto DCO
+      cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID,
+                                         IL_info_ptr->input_level ,
+                                          radio_freq,if_threshold);
+      l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+  #endif
+
+  #if TESTMODE
+    // if Normal Mode or
+    // if TestMode DL+UL
+    // NOTE: UL only true if DL is true in TCHTF!
+    if ( !l1_config.TestMode ||
+        (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK)))
+  #endif
+    {
+      // Set TXPWR.
+      l1ddsp_load_txpwr(l1s.applied_txpwr, radio_freq);
+    }
+
+  /*--------------------------------------------*/
+  /* Program TPU...                             */
+  /*--------------------------------------------*/
+
+  // for TCHTF we use DPAGC algorithm.
+  #if DPAGC_MAX_FLAG
+    agc = Cust_get_agc_from_IL(radio_freq, IL_info_ptr->input_level >> 1, MAX_ID);
+  #else
+    agc = Cust_get_agc_from_IL(radio_freq, IL_info_ptr->input_level >> 1, AV_ID);
+  #endif
+  lna_off = IL_info_ptr->lna_off;
+
+
+  // Store input_level and lna_off fields used for current CTRL in order to be able
+  // to build IL from pm in READ phase.
+  l1a_l1s_com.Scell_used_IL = *IL_info_ptr;
+
+  #if (L1_SAIC != 0)
+    // If SAIC is enabled, call the low level SAIC control function
+    csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+  #if (NEW_SNR_THRESHOLD == 1)
+        ,task
+        ,&saic_flag
+  #endif
+   );
+  #endif
+
+  #if TESTMODE
+    // Continuous mode: Rx TPU programmation only in NO_CONTINUOUS or START_RX_CONTINUOUS mode.
+    if ((!l1_config.TestMode)                                             ||
+        (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS)        ||
+        (l1_config.tmode.rf_params.tmode_continuous == TM_START_RX_CONTINUOUS))
+  #endif
+    {
+      // update the TPU with the new TOA if necessary
+      l1ctl_update_TPU_with_toa();
+
+      // Program a serving cell normal burst reading in TPU.
+      l1dtpu_serv_rx_nb(radio_freq,
+                        agc,
+                        lna_off,
+                        l1s.tpu_offset,
+                        l1s.tpu_offset,
+                        FALSE,INACTIVE
+                      #if (RF_FAM == 61)
+			    ,csf_filter_choice
+			    ,if_ctl
+                      #endif
+          #if (NEW_SNR_THRESHOLD == 1)
+          ,saic_flag
+          #endif /*NEW_SNR_THRESHOLD*/
+			                 );
+    }
+
+  // Increment tpu window identifier.
+  l1s.tpu_win += (l1_config.params.rx_synth_load_split + RX_LOAD);
+
+  /*--------------------------------------------*/
+  /* Flag DSP and TPU programmation...          */
+  /*--------------------------------------------*/
+
+  // Set "CTRL_RX" flag in the controle flag register.
+
+  #if TESTMODE
+    // Continuous mode: swap TPU page for Rx only in NO_CONTINUOUS or START_RX_CONTINUOUS mode.
+    if ((!l1_config.TestMode)                                            ||
+        (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS)       ||
+        (l1_config.tmode.rf_params.tmode_continuous == TM_START_RX_CONTINUOUS))
+  #endif
+    {
+  l1s.tpu_ctrl_reg |= CTRL_RX;
+    }
+  l1s.dsp_ctrl_reg |= CTRL_RX;
+#if FF_L1_IT_DSP_DTX
+  } // if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+#endif
+
+  /**************************************************************************/
+  /* TCH/T Transmit...                                                      */
+  /**************************************************************************/
+
+  // Any Handover Access burst to send ?
+  // ************************************
+
+  if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+  // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+  // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+  // Handover command is received from L3 through L1A.
+  // We must then replace the TCH UL normal burst by a RACH and decrement
+  // this counter.
+  {
+    if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != -1)
+      l1a_l1s_com.dedic_set.aset->ho_acc_to_send --;
+    l1s_ctrl_rach(RAHO,NO_PAR);
+
+    if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send == 0)
+    // Handover access procedure is completed.
+    // -> send L1C_HANDOVER_FINISHED message with "cause = COMPLETED" to L1A.
+    {
+      l1s_send_ho_finished(HO_COMPLETE);
+    }
+  }
+  else
+  // TCH/UL is a normal burst.
+  {
+    UWORD8 channel_mode = l1a_l1s_com.dedic_set.aset->achan_ptr->mode;
+   //OMAPS00090550 UWORD8 channel_type = desc_ptr->channel_type;
+
+    #if (TRACE_TYPE!=0)
+      trace_fct(CST_L1S_CTRL_TCHTF__UL, radio_freq);
+    #endif
+
+#if FF_L1_IT_DSP_DTX
+  // FACCH and IDS handled during L1S, have to be skipped during DTX HISR
+  if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+  {
+#endif
+    /*--------------------------------------------*/
+    /* Get DATA block if required for TCH.        */
+    /*--------------------------------------------*/
+    // Full rate traffic channel...
+    {
+      UWORD8 fn_report_mod13_mod4 = (l1s.next_time.fn_in_report % 13) % 4;
+
+      if(fn_report_mod13_mod4 == 3)
+      // It is time to check if a FACCH/UL data block is available from DLL or
+      // if a data block is available from the DATA interface.
+      {
+        T_RADIO_FRAME  *tx_data = NULL;
+
+        // Check if any FACCH to transmit.
+        // Rem: when mode is "SIGNALLING ONLY" the "dll_read_dcch()" function
+        // always gives back a block of FACCH (true block or dummy one).
+        // In ETM test mode, the protocol stack is not active and hence we do not require any FACCH data from L23
+        // But this change is applicable only when ETM scripts are run with PS-builds. In case of L1-SA,
+        // dll_read_dcch() is called which is just a stub function (It just returns a NULL ptr for L1 SA)
+	/* FreeCalypso: this logic is not present in TCS211 */
+	#if 0
+        #if TESTMODE
+        #if (OP_L1_STANDALONE == 0)
+         if(!l1_config.TestMode)
+        #endif // (OP_L1_STANDALONE == 0)
+        #endif // TESTMODE
+	#endif
+         {
+        tx_data = dll_read_dcch(channel_mode);
+         }
+
+        if(tx_data != NULL)
+        {
+          // In DTX mode in FR and EFR, all 8 FACCH 1/2 bursts must always be transmitted.
+          // Note: FACCH presence is checked 1 "control" before "control" of 1st burst of FACCH due to a DSP constraint
+          // i.e. 2 bursts before FACCH interleaving boundary
+          //So we must wait 1 burst before controlling the transmission of 8 FACCH 1/2 bursts
+          l1s.facch_bursts = 9;
+
+          #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+            RTTL1_FILL_UL_DCCH
+            trace_info.facch_ul_count ++;
+          #endif
+
+          // Store the FACCH/UL data block in the MCU/DSP com.
+          #if TRACE_TYPE==3
+            if (l1_stats.type == PLAY_UL)
+            {
+              // load A_DU_1 in PLAY Uplink mode.
+              l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_1, &(tx_data->A[0]));
+
+
+              if (channel_mode == TCH_EFR_MODE)
+              {
+                WORD32 bit5word14, bit2word14, bit12word15, bit15word15;
+
+                 // clear CRC bits and repetition bits
+                l1s_dsp_com.dsp_ndb_ptr->a_du_1[7]  &= 0x807f;
+                l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] &= 0xfc24;
+                l1s_dsp_com.dsp_ndb_ptr->a_du_1[15] &= 0x93ff;
+                l1s_dsp_com.dsp_ndb_ptr->a_du_1[19] &= 0xff00;
+
+                // read repetition bits
+                bit5word14  = (l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] >> 5)& 0x1;
+                bit2word14  = (l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] >> 2)& 0x1;
+                bit12word15  = (l1s_dsp_com.dsp_ndb_ptr->a_du_1[15] >> 12) & 0x1;
+                bit15word15 = (l1s_dsp_com.dsp_ndb_ptr->a_du_1[15] >> 15)& 0x1;
+
+                // copy repetition bits
+                l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] |=
+                         (bit5word14 << 4 | bit5word14 << 3 |
+                          bit2word14 | bit2word14 << 1);
+
+                l1s_dsp_com.dsp_ndb_ptr->a_du_1[15] |=
+                         (bit15word15 << 13 | bit12word15 << 14 |
+                          bit12word15 << 10 | bit15word15 << 11);
+              }
+              else
+              {
+                l1s_dsp_com.dsp_ndb_ptr->a_du_1[14] &= 0xfc3f;
+                l1s_dsp_com.dsp_ndb_ptr->a_du_1[19] &= 0xff00;
+              }
+
+              // set PLAY Uplink bit .......
+              l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= (1 << B_PLAY_UL);
+            }
+            else
+              l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_fu, &(tx_data->A[0]));
+          #else
+            l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_fu, &(tx_data->A[0]));
+          #endif
+          #if (TRACE_TYPE==5) && FLOWCHART
+            trace_flowchart_dsptx(dltsk_trace[TCHTF].name);
+          #endif
+        }
+
+        #if (AMR == 1)
+          // Check if any DATA traffic info frame available.
+          // This check is used for all full rate channels except when
+          // this channel is in SIGNALLING ONLY mode or in Full Rate
+          // Speech mode or adaptative full rate mode.
+          if((channel_mode != TCH_FS_MODE)   &&
+             (channel_mode != SIG_ONLY_MODE) &&
+             (channel_mode != TCH_EFR_MODE)  &&
+             (channel_mode != TCH_AFS_MODE))
+        #else
+          // Check if any DATA traffic info frame available.
+          // This check is used for all full rate channels except when
+          // this channel is in SIGNALLING ONLY mode or in Full Rate
+          // Speech mode.
+          if((channel_mode != TCH_FS_MODE)   &&
+             (channel_mode != SIG_ONLY_MODE) &&
+             (channel_mode != TCH_EFR_MODE))
+        #endif
+        {
+          #if IDS
+          {
+            UWORD8  fn_report_mod26;
+            API *data_ul;
+
+            data_ul = l1s_dsp_com.dsp_ndb_ptr->a_du_0;
+            fn_report_mod26 = l1s.next_time.fn_in_report%26;
+
+            // Set flag for UL/DL block information: for TCH/F48 mode only
+            if((channel_mode == TCH_48F_MODE) && ((fn_report_mod26 == 7) || (fn_report_mod26 == 16)
+                || (fn_report_mod26 == 24)))
+              l1s_dsp_com.dsp_ndb_ptr->d_ra_act |= (3 << B_F48BLK);
+            else
+              l1s_dsp_com.dsp_ndb_ptr->d_ra_act &= ~(3 << B_F48BLK);
+            dll_data_ul(l1s_dsp_com.dsp_ndb_ptr->a_data_buf_ul, &l1s_dsp_com.dsp_ndb_ptr->d_ra_conf,
+                        &l1s_dsp_com.dsp_ndb_ptr->d_ra_act, &l1s_dsp_com.dsp_ndb_ptr->d_ra_test,
+                        &l1s_dsp_com.dsp_ndb_ptr->d_ra_statu, &l1s_dsp_com.dsp_ndb_ptr->d_fax);
+
+            // Fill a_du_0 data block Header.
+      // Note: a_du_0 header is fill when dummy block is filled as well when data block
+            //       is filled (buffer a_data_buf_ul
+            data_ul[0] = (1 << B_BLUD);     // 1st word: Set B_BLU bit.
+            data_ul[1] = 0;                 // 2nd word: cleared.
+            data_ul[2] = 0;                 // 3rd word: cleared.
+
+          }
+          #else
+          {
+            UWORD8  *tx_data = NULL;
+
+            tx_data = tx_tch_data();
+            if(tx_data != NULL)
+            {
+              // Store the DATA/UL data block in the MCU/DSP com.
+              #if TRACE_TYPE==3
+                if (l1_stats.type == PLAY_UL)
+                {
+                  // load A_DU_1 in PLAY Uplink mode.
+                  l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_1, tx_data);
+                  if (channel_mode == TCH_48F_MODE)
+                    l1s_dsp_com.dsp_ndb_ptr->a_du_1[10] &= 0x00ff;
+                  if (channel_mode == TCH_24F_MODE)
+                    l1s_dsp_com.dsp_ndb_ptr->a_du_1[7]  &= 0x00ff;
+                  // set PLAY Uplink bit .......
+                  l1s_dsp_com.dsp_ndb_ptr->d_tch_mode |= (1 << B_PLAY_UL);
+                }
+                else
+                  l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_0, tx_data);
+              #else
+                l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_du_0, tx_data);
+              #endif
+            }
+
+            #if (TRACE_TYPE==5) && FLOWCHART
+              trace_flowchart_dsptx(dltsk_trace[TCHTF].name);
+            #endif
+          }
+          #endif
+        }
+      }
+    }
+
+#if FF_L1_IT_DSP_DTX
+    // Fast DTX active only in TCH AFS, for TDMA3 from speech block = 0, 1 [MOD 3]
+    if ((l1a_l1s_com.dedic_set.aset->achan_ptr->mode == TCH_AFS_MODE)
+        && (l1a_l1s_com.dedic_set.aset->dtx_allowed == TRUE))
+    {
+      // DTX interrupt request for B1 and B2 (no DTX uncertainty on B0 thanks to idle frame)
+      if (l1s.next_time.fn_mod13 <= 7)
+        dtx_dsp_interrupt = TRUE;
+
+      // DTX uncertainty check
+      if  ((l1a_apihisr_com.dtx.fast_dtx_ready == TRUE) &&                   // Fast DTX can be used
+           ((l1s.next_time.fn_mod13 == 4) || (l1s.next_time.fn_mod13 == 8))) // new block boundary
+        l1a_apihisr_com.dtx.dtx_status = DTX_AWAITED;
+    }
+    else
+      l1a_apihisr_com.dtx.dtx_status = DTX_AVAILABLE;
+  } // if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+
+  // Postpone TPU/DSP programming when DTX status not available from DSP
+  if (l1a_apihisr_com.dtx.dtx_status != DTX_AWAITED)
+  {
+    BOOL tx_active =FALSE; //omaps00090550
+#endif
+    #if TESTMODE
+      // if Normal Mode or
+      // if TestMode and UL+DL
+      // NOTE: UL only true if DL is true in TCHTF!
+      if ( !l1_config.TestMode ||
+          (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK)))
+    #endif
+      {
+        /*--------------------------------------------*/
+        /* Program DSP...                             */
+        /*--------------------------------------------*/
+
+        dsp_task = l1s_swap_iq_ul(radio_freq,task);
+
+        l1ddsp_load_tx_task(dsp_task, 0, desc_ptr->tsc);
+
+        /*--------------------------------------------*/
+        /* Program TPU...                             */
+        /*--------------------------------------------*/
+
+        fn_mod_104   = l1s.actual_time.fn % 104;
+
+        #if TESTMODE
+          if ((!l1_config.TestMode)                                      ||
+              (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) ||
+              (l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS))
+        #endif
+          {
+            l1s.facch_bursts--;
+	    if (l1s.facch_bursts < 0)
+	      l1s.facch_bursts = -1;
+
+      #if FF_L1_IT_DSP_DTX
+        // Condition for TX TPU programming channel mode dependant
+        switch (channel_mode)
+        {
+          case SIG_ONLY_MODE:
+          case TCH_24F_MODE:
+          case TCH_48F_MODE:
+          case TCH_96_MODE:
+          case TCH_144_MODE:
+            // DTX not supported
+            tx_active = TRUE;
+            break;
+
+          case TCH_FS_MODE:
+          case TCH_EFR_MODE:
+            if ((l1s.dtx_ul_on == FALSE) ||                                // No DTX
+                ((l1s.facch_bursts >= 0) && (l1s.facch_bursts <= 7)) || // FACCH in progress
+                ((fn_mod_104 >= 51) && (fn_mod_104 <= 58))              // SID
+               )
+              tx_active = TRUE;
+            else
+              tx_active = FALSE;
+            break;
+
+          case TCH_AFS_MODE:
+            if (l1a_apihisr_com.dtx.tx_active) // DSP (Fast) DTX status
+	    tx_active = TRUE;
+            else
+	    tx_active = FALSE;
+            break;
+        }
+
+        // TPU TX burst programming
+        if (tx_active)
+      #else
+            // In DTX mode, UL bursts should not be transmitted when no voice activity is detected
+	    // we must not call TPU scenario if dtx_on == TRUE in EFR and FR (See Technical Memo)
+	    // However, in DTX mode, bursts 52 to 59 (modulo 104) must always be transmitted
+	    // FACCH must also be transmitted but we must wait 1 bursts before transmitting 8 1/2 bursts
+	    if ( ((channel_mode != TCH_FS_MODE) && (channel_mode != TCH_EFR_MODE)) ||
+                 (l1s.dtx_ul_on == FALSE) ||
+                 ( (l1s.facch_bursts >= 0) && (l1s.facch_bursts <= 7) ) ||
+		 ((fn_mod_104 >= 51) && (fn_mod_104 <= 58)) )
+      #endif
+            {
+             l1dtpu_serv_tx_nb(radio_freq, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.tpu_offset, l1s.applied_txpwr,INACTIVE);
+            }
+          }
+
+        #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+          RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+        #endif
+
+    }
+  #if FF_L1_IT_DSP_DTX
+    } // if (l1a_apihisr_com.dtx.dtx_status != DTX_AWAITED)
+  #endif
+  } // TCH/UL is a normal burst.
+#if FF_L1_IT_DSP_DTX
+  // Postpone TPU/DSP programming when DTX status not available from DSP
+  if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+  {
+#endif
+
+  /*----------------------------------------------*/
+  /* Common for Dedicated mode: DSP parameters... */
+  /*----------------------------------------------*/
+  #if (AMR == 1)
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            0,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            l1a_l1s_com.dedic_set.sync_amr,
+                            l1a_l1s_com.dedic_set.reset_sacch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.vocoder_on);
+    #else
+                            l1a_l1s_com.dedic_set.vocoder_on,
+                            dtx_dsp_interrupt);
+                          #endif
+    #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            0,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.sync_amr);
+                          #else
+                            l1a_l1s_com.dedic_set.sync_amr,
+                            dtx_dsp_interrupt);
+                          #endif
+    #endif
+
+    // Clear "sync_amr" flag to maintain normal TCH process.
+    l1a_l1s_com.dedic_set.sync_amr = FALSE;
+  #else
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            0,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            l1a_l1s_com.dedic_set.reset_sacch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.vocoder_on);
+    #else
+                            l1a_l1s_com.dedic_set.vocoder_on,
+                            dtx_dsp_interrupt);
+                          #endif
+    #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            0,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.sync_tch);
+                          #else
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            dtx_dsp_interrupt);
+                          #endif
+    #endif
+  #endif
+
+  // reset the FACCH header of the API buffer on the control following an ABORT to avoid decoding unwanted FACCH
+  if (l1a_l1s_com.dedic_set.reset_facch == TRUE)
+  {
+    // Reset A_FD header.
+    // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+    l1s_dsp_com.dsp_ndb_ptr->a_fd[0] = (1<<B_FIRE1);
+    l1s_dsp_com.dsp_ndb_ptr->a_fd[2] = 0xffff;
+  }
+
+  // Clear "sync_tch" and "reset_sacch" flag to maintain normal TCH process.
+  l1a_l1s_com.dedic_set.sync_tch = FALSE;
+  l1a_l1s_com.dedic_set.reset_facch = FALSE;
+#if (FF_L1_TCH_VOCODER_CONTROL == 1)
+  l1a_l1s_com.dedic_set.reset_sacch = FALSE;
+#endif
+
+  // Set tpu window identifier for Power meas or FS/SB search.
+  l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_nb_load_split + l1_config.params.rx_synth_load_split;
+
+  /*--------------------------------------------*/
+  /* Flag DSP and TPU programmation...          */
+  /*--------------------------------------------*/
+
+  #if TESTMODE
+    // if Normal Mode or
+    // if TestMode and UL+DL
+    // NOTE: UL only true if DL is true in TCHTF!
+    if ( !l1_config.TestMode ||
+       (  l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK)))
+  #endif
+    {
+      #if TESTMODE
+        // Continuous mode: swap TPU page for Tx in NO_CONTINUOUS or START_TX_CONTINUOUS mode.
+        if ((!l1_config.TestMode)                                      ||
+            (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS) ||
+            (l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS))
+      #endif
+        {
+          l1s.tpu_ctrl_reg |= CTRL_TX;
+        }
+      l1s.dsp_ctrl_reg |= CTRL_TX;
+    }
+
+  #if TESTMODE
+    // Continuous mode: if end of control of START_RX/TX: go to CONTINUOUS state
+    if (l1_config.TestMode && (l1_config.tmode.rf_params.tmode_continuous != TM_NO_CONTINUOUS))
+      l1_config.tmode.rf_params.tmode_continuous = TM_CONTINUOUS;
+  #endif
+#if FF_L1_IT_DSP_DTX
+  } //if (l1a_apihisr_com.dtx.dtx_status != DTX_IT_DSP)
+  #endif
+}
+
+/*-------------------------------------------------------*/
+/* l1s_ctrl_tcha()                                       */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* dedicated mode TCH task: TCHA. This function is the   */
+/* control function for reading the DL burst and sending */
+/* the UL burst on the Slow Associated Channel (SACCH)   */
+/* associated with the traffic channel. The UL burst can */
+/* be a Normal Burst in normal case or an Access Burst   */
+/* when starting a Handover procedure. Both Half rate    */
+/* and Full rate TCH channel are handled. The DSP and    */
+/* the TPU are programmed for both the DL and UL bursts. */
+/* The timing advance is taken into account for          */
+/* positionning the UL burst.                            */
+/*                                                       */
+/* This function accesses the L1/DLL interface           */
+/* ("dll_read_sacch()" function) and passes then the     */
+/* returned data blocks to the DSP after having set the  */
+/* L1 header part of the block.                          */
+/*                                                       */
+/* Here is a summary of the execution:                   */
+/*                                                       */
+/*  - Traces and debug.                                  */
+/*  - Catch channel description and ARFCN.               */
+/*  - TCH/SACCH Receive...                               */
+/*      - Program DSP for RX.                            */
+/*      - Program TPU for RX.                            */
+/*      - Flag DSP and TPU programmation.                */
+/*  - TCH/SACCH Transmit...                              */
+/*      - If Any Handover Access burst to send           */
+/*          - Call "l1s_ctrl_rach()".                    */
+/*      - Else                                           */
+/*          - Get DATA block from DLL if required.       */
+/*          - Program DSP for TX.                        */
+/*          - Program TPU for TX.                        */
+/*          - Flag DSP and TPU programmation.            */
+/*  - Common for DL/UL: DSP parameters.                  */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   TCHA, Associated channel task when dedicated/TCH.   */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.dedic_set"                               */
+/*   Dedicated channel parameter structure.              */
+/*     .radio_freq, ARFCN value set by the Hopping algo.      */
+/*     .aset, active dedicated parameter set.            */
+/*                                                       */
+/* "l1a_l1s_com.Scell_info"                              */
+/*  Serving cell information structure.                  */
+/*    .bsic, BSIC of the serving cell. It is used here   */
+/*           to pass the training sequence number (part  */
+/*           of BSIC) to the DSP.                        */
+/*                                                       */
+/* "l1s.afc"                                             */
+/*   current AFC value to be applied for the given task. */
+/*                                                       */
+/* "l1s.tpu_offset"                                      */
+/*   value for the TPU SYNCHRO and OFFSET registers      */
+/*   for current serving cell setting.                   */
+/*                                                       */
+/* "l1s.applied_txpwr"                                   */
+/*   Applied transmit power.                             */
+/*                                                       */
+/* "l1s.reported_txpwr"                                  */
+/*   Transmit power to report in the L1 header of the    */
+/*   SACCH data block.                                   */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.tpu_win"                                         */
+/*   each frame is composed with a maximum of 3          */
+/*   working/TPU windows (typically RX/TX/PW). This is   */
+/*   a counter used to count the number of windows       */
+/*   used.                                               */
+/*   -> set to TDMA_WIN3.                                */
+/*                                                       */
+/* "l1s.tpu_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/TPU com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/* "l1s.dsp_ctrl_reg"                                    */
+/*   bit register used to know at the end of L1S if      */
+/*   something has been programmed on the MCU/DSP com.   */
+/*   This is used mainly to swap then the com. page at   */
+/*   the end of a control frame.                         */
+/*   -> set CTRL_RX bit in the register.                 */
+/*   -> set CTRL_TX bit in the register.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_ctrl_tcha(UWORD8 task, UWORD8 param2)
+{
+  UWORD16                radio_freq=0;
+  T_CHANNEL_DESCRIPTION *desc_ptr;
+  UWORD8                 lna_off =0;//omaps00090550
+  WORD8                  agc =0; //omaps00090550
+  T_INPUT_LEVEL         *IL_info_ptr;
+  UWORD32                dsp_task;
+  UWORD8                 adc_active_ul = INACTIVE;
+  UWORD8                 adc_active_dl = INACTIVE;
+#if (RF_FAM == 61)
+  UWORD16 dco_algo_ctl_nb = 0;
+  UWORD8 if_ctl = 0;
+  UWORD8 if_threshold = C_IF_ZERO_LOW_THRESHOLD_GSM;
+  // By default we choose the hardware filter
+  UWORD8 csf_filter_choice = L1_SAIC_HARDWARE_FILTER;
+#endif
+#if (NEW_SNR_THRESHOLD == 1)
+  UWORD8 saic_flag=0;
+#endif /*NEW_SNR_THRESHOLD */
+  // Traces and debug.
+  // ******************
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dsp_tpu(dltsk_trace[TCHA].name);
+  #endif
+
+  l1s_dsp_com.dsp_db_w_ptr->d_debug = (l1s.debug_time + 2) ;
+
+  // Catch channel description and ARFCN.
+  // *************************************
+
+  // Catch the active channel description used along the routine.
+  // It contains:
+  //    "channel_type", {TCH_F, TCH_H, SDCCH_4, SDCCH_8}.
+  //    "subchannel", {0, 1}. 0 is the default value for TCH_F.
+  desc_ptr = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr;
+
+  // Get ARFCN to be used for current control.
+  radio_freq = l1a_l1s_com.dedic_set.radio_freq;
+
+  if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+    IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+                          // we are working on a beacon freq.
+  else
+    IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;
+                          // we are working on a daughter freq.
+
+  /**************************************************************************/
+  /* SACCH Receive...                                                       */
+  /**************************************************************************/
+
+  // ADC measurement
+  // ***************
+
+  // check if during the SACCH burst an ADC measurement must be performed
+   if (l1a_l1s_com.adc_mode & ADC_NEXT_TRAFFIC_DL)  // perform ADC only one time
+   {
+      adc_active_dl = ACTIVE;
+      l1a_l1s_com.adc_mode &= ADC_MASK_RESET_TRAFFIC; // reset in order to have only one ADC measurement in Traffic
+   }
+   else
+     if (l1a_l1s_com.adc_mode & ADC_EACH_TRAFFIC_DL) // perform ADC on each period bloc
+       if (l1s.next_time.fn_in_report == 12) //periodic with each 1st SACCH burst
+         if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_traffic_period) // wait for the period
+         {
+           adc_active_dl = ACTIVE;
+           l1a_l1s_com.adc_cpt = 0;
+         }
+
+  #if TESTMODE
+    // if Normal Mode or
+    // if TestMode and DL-only or DL+UL
+    if ( !l1_config.TestMode ||
+         (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_DOWNLINK)))
+  #endif
+    {
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_CTRL_TCHA___DL, radio_freq);
+      #endif
+
+      /*--------------------------------------------*/
+      /* Program DSP...                             */
+      /*--------------------------------------------*/
+      // dsp pgm.
+
+      dsp_task = l1s_swap_iq_dl(radio_freq,task);
+      l1ddsp_load_rx_task(dsp_task, 0, desc_ptr->tsc);
+
+      #if(RF_FAM == 61)    // Locosto DCO
+         cust_get_if_dco_ctl_algo(&dco_algo_ctl_nb, &if_ctl, (UWORD8) L1_IL_VALID ,
+                                         IL_info_ptr->input_level ,
+                                          radio_freq,if_threshold);
+   	l1ddsp_load_dco_ctl_algo_nb(dco_algo_ctl_nb);
+      #endif
+
+      /*--------------------------------------------*/
+      /* Program TPU...                             */
+      /*--------------------------------------------*/
+      // for TCHA we use DPAGC algorithm.
+      #if DPAGC_MAX_FLAG
+        agc = Cust_get_agc_from_IL(radio_freq, IL_info_ptr->input_level >> 1, MAX_ID);
+      #else
+        agc = Cust_get_agc_from_IL(radio_freq, IL_info_ptr->input_level >> 1, AV_ID);
+      #endif
+      lna_off = IL_info_ptr->lna_off;
+
+
+
+      // Store input_level and lna_off fields used for current CTRL in order to be able
+      // to build IL from pm in READ phase.
+      l1a_l1s_com.Scell_used_IL = *IL_info_ptr;
+
+      #if (L1_SAIC != 0)
+        // If SAIC is enabled, call the low level SAIC control function
+        csf_filter_choice = l1ctl_saic(l1a_l1s_com.Scell_used_IL.input_level,l1a_l1s_com.mode
+        #if (NEW_SNR_THRESHOLD == 1)
+            ,task
+            ,&saic_flag
+        #endif
+        );
+      #endif
+
+      #if TESTMODE
+        // Continuous mode: Rx TPU programmation only in NO_CONTINUOUS or START_RX_CONTINUOUS mode.
+        if ((!l1_config.TestMode)                                           ||
+            (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS)      ||
+            (l1_config.tmode.rf_params.tmode_continuous == TM_START_RX_CONTINUOUS))
+      #endif
+        {
+          // update the TPU with the new TOA if necessary
+          l1ctl_update_TPU_with_toa();
+
+          // Program a serving cell normal burst reading in TPU.
+          l1dtpu_serv_rx_nb(radio_freq,
+                            agc,
+                            lna_off,
+                            l1s.tpu_offset,
+                            l1s.tpu_offset,
+                            FALSE,adc_active_dl
+                          #if (RF_FAM == 61)
+				,csf_filter_choice
+				,if_ctl
+			  #endif
+                          #if (NEW_SNR_THRESHOLD == 1)
+                            ,saic_flag
+                          #endif /* NEW_SNR_THRESHOLD */
+					 );
+        }
+
+  // Increment tpu window identifier.
+  l1s.tpu_win += (l1_config.params.rx_synth_load_split + RX_LOAD);
+
+  // Set "CTRL_RX" flag in the control flag register.
+  #if TESTMODE
+    // Continuous mode: swap TPU page for Rx only in NO_CONTINUOUS or START_RX_CONTINUOUS mode.
+    if ((!l1_config.TestMode)                                           ||
+        (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS)      ||
+        (l1_config.tmode.rf_params.tmode_continuous == TM_START_RX_CONTINUOUS))
+  #endif
+    {
+      l1s.tpu_ctrl_reg |= CTRL_RX;
+    }
+    l1s.dsp_ctrl_reg |= CTRL_RX;
+
+  }
+
+  /**************************************************************************/
+  /* TCH/T Transmit...                                                      */
+  /**************************************************************************/
+
+  // Any Handover Access burst to send ? --> TXPWR management
+  // ************************************
+
+  if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send != 0)
+  // "ho_acc_to_send" is a counter of Handover Access burst still to send.
+  // This counter is set by "l1s_dedicated_mode_manager()" in L1S when a
+  // Handover command is received from L3 through L1A.
+  // When Handover access is in progress, nothing but RACH can be transmitted.
+  // RACH is not allowed on SACCH therefore TX is avoided by setting
+  // the txpwr to NO_TXPWR !!!
+  {
+#if 0	/* LoCosto code */
+    // NOTE: The spec says RACH bursts on SACCH UL is optional. hence it should not be counted
+    // Refer spec 04.08
+    l1s_ctrl_rach(RAHO,NO_PAR);
+#else	/* TCS211 reconstruction, code taken from TSM30 */
+    // Set TXPWR.
+    l1ddsp_load_txpwr(NO_TXPWR, radio_freq);
+ 
+    #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+      RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, NO_TXPWR)
+    #endif
+#endif
+  }
+  else
+  // TCH/UL is a normal burst.
+  // TX power must be the normal one
+  {
+    // Set TXPWR.
+    l1ddsp_load_txpwr(l1s.applied_txpwr, radio_freq);
+
+    #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+      RTTL1_FILL_UL_NB(task, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.applied_txpwr)
+    #endif
+
+    // ADC measurement
+    // ***************
+
+    // check if during the SACCH burst an ADC measurement must be performed
+    if (l1a_l1s_com.adc_mode & ADC_NEXT_TRAFFIC_UL)  // perform ADC only one time
+    {
+       adc_active_ul = ACTIVE;
+       l1a_l1s_com.adc_mode &= ADC_MASK_RESET_TRAFFIC; // reset in order to have only one ADC measurement in Traffic
+    }
+    else
+      if (l1a_l1s_com.adc_mode & ADC_EACH_TRAFFIC_UL) // perform ADC on each period bloc
+        if (l1s.next_time.fn_in_report == 12) //periodic with each 1st SACCH burst
+          if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_traffic_period) // wait for the period
+          {
+            adc_active_ul = ACTIVE;
+            l1a_l1s_com.adc_cpt = 0;
+          }
+
+#if 1	/* FreeCalypso TCS211 reconstruction */
+  } // End of "TCH/UL is a normal burst"
+#endif
+
+    // In any case (normal TX or no TX due to Handover Access process)
+    // the full TCHA task must be controled for TPU and DSP.
+    {
+      T_RADIO_FRAME   *tx_data = NULL;
+
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_CTRL_TCHA___UL, radio_freq);
+      #endif
+
+      /*--------------------------------------------*/
+      /* Get DATA block if required for SACCH.      */
+      /*--------------------------------------------*/
+      if(l1s.next_time.fn_in_report == 12)
+      // It is time to get a SACCH data block from DLL.
+      // Call "dll_read_sacch()" to perform "PH_DATA_REQ" and pass
+      // the data block to the DSP..
+      {
+	  #if ((FF_REPEATED_SACCH)     && ( TESTMODE))
+          if(l1_config.repeat_sacch_enable != REPEATED_SACCH_ENABLE)
+        {
+               l1s.repeated_sacch.sro = 0;
+               l1s.repeated_sacch.buffer_empty = TRUE;
+          }
+      #endif /* #if ((FF_REPEATED_SACCH)     && ( TESTMODE)) */
+#if FF_REPEATED_SACCH
+        /* Get data from PS if only no repetition order is required (1st condition) */
+        /* or no repetition candidate exists (2nd condition)                        */
+     if((l1s.repeated_sacch.sro == 0)  ||  (l1s.repeated_sacch.buffer_empty == TRUE))
+#endif /* FF_REPEATED_SACCH */
+     {
+        tx_data = dll_read_sacch(SIG_ONLY_MODE);
+        if(tx_data != NULL)
+        {
+          // Set L1 Header...
+          tx_data->A[0] = l1s.reported_txpwr;
+          tx_data->A[1] = l1a_l1s_com.dedic_set.aset->timing_advance;
+
+        #if FF_REPEATED_SACCH
+                /* Include the SACCH Repetition Request (SRR) in the L1 Header */
+           tx_data->A[0] |= (l1s.repeated_sacch.srr <<6);
+        #endif  /* FF_REPEATED_SACCH */
+          // Put data block in MCU/DSP com.
+          l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, &(tx_data->A[0]));
+          #if (FF_REPEATED_SACCH == 1 )
+             if(((tx_data->A[2]&0x1C) >> 2) == SAPI_0)    /* Store the block data in case of a retransmission order */
+            {
+                 l1s_store_sacch_buffer( &(l1s.repeated_sacch), &(tx_data->A[0]));
+                 /* Stores the buffer and turns of the buffer_empty flag as false */
+             }
+            else
+            {
+            /* the SACCH repetition block occurrence will always come as a consecutive pair   */
+            /* To handle DL UL | DL  UL  | DL UL                                              */
+            /*            -  0 | SRO  3  | -   new data should be asked from PS old 0 cannot be repeated */
+                l1s.repeated_sacch.buffer_empty=TRUE;
+            }
+         #endif /* FF_REPEATED_SACCH */
+         } /* if(tx_data != NULL) */
+
+          #if (TRACE_TYPE==5) && FLOWCHART
+            trace_flowchart_dsptx(dltsk_trace[TCHA].name);
+          #endif
+        }/* if((l1s.repeated_sacch.sro == 0)  ||  (l1s.repeated_sacch.buffer_empty == TRUE))*/
+      #if FF_REPEATED_SACCH
+	       else if ((l1s.repeated_sacch.sro == 1) && (l1s.repeated_sacch.buffer_empty == FALSE))
+	       {
+	            /* Put data block in MCU/DSP com. */
+	            l1ddsp_load_info(DSP_TASK_CODE[task], l1s_dsp_com.dsp_ndb_ptr->a_cu, l1s.repeated_sacch.buffer );
+	            l1s.repeated_sacch.buffer_empty = TRUE;     /* Set that the buffer is now empty (only one repetition) */
+	       } /* end else repetition */
+	  #endif /* FF_REPEATED_SACCH */
+        // check to be removed
+      }
+
+      /*--------------------------------------------*/
+      /* Program DSP...                             */
+      /*--------------------------------------------*/
+      #if TESTMODE
+        // UL-only...
+        // Use SPI to write to Omega uplink buffer, do NOT use DSP
+        if (l1_config.TestMode && l1_config.tmode.rf_params.down_up == TMODE_UPLINK)
+          {
+          #if (CODE_VERSION != SIMULATION)
+            // For Calyso+ & Before...
+            #if (RF_FAM == 12)
+            ABB_Write_Register_on_page(PAGE0, AUXAPC, Cust_get_pwr_data(l1s.applied_txpwr, radio_freq
+            																			   #if(REL99 && FF_PRF)
+            																			   ,1
+            																			   #endif
+            																			   ));
+            l1tm_fill_burst(l1_config.tmode.tx_params.burst_data, &TM_ul_data[0]);
+            ABB_Write_Uplink_Data(&TM_ul_data[0]);
+          #endif
+
+            //For  UppCosto, Tx Data Write is via PLD to DRP & Ramp is via the ABB Driver
+       #if (RF_FAM == 60)
+         ABB_Write_Register_on_page(PAGE0, AUXAPC, Cust_get_pwr_data(l1s.applied_txpwr, radio_freq
+																						#if(REL99 && FF_PRF)
+																						,1
+																						#endif
+																						));
+              l1tm_fill_burst(l1_config.tmode.tx_params.burst_data, &TM_ul_data[0]);
+              PLD_Write_Uplink_Data(&TM_ul_data[0]);
+            #endif
+
+           #if (RF_FAM == 61)
+              // For DRP we use the DSP to write the TX Power via a new variable apclev in API
+        // A new variable is required in API as DSP copies the tx_power_ctl (which is
+        // normally used to pass the APCLEV value to DSP) to APCLEV ONLY when there is a
+        // burst to be transmitted
+        l1ddsp_apc_load_apclev(Cust_get_pwr_data(l1s.applied_txpwr, radio_freq
+        															#if(REL99 && FF_PRF)
+        															,1
+        															#endif
+                                                                    ));
+              l1tm_fill_burst(l1_config.tmode.tx_params.burst_data, &TM_ul_data[0]);
+              DRP_Write_Uplink_Data(&TM_ul_data[0]);
+            #endif
+
+    #endif
+          }
+        // Use DSP...
+        // if Normal Mode or
+        // if TestMode and DL+UL
+        else if ( !l1_config.TestMode ||
+                (l1_config.TestMode && l1_config.tmode.rf_params.down_up == (TMODE_DOWNLINK|TMODE_UPLINK)))
+          {
+            dsp_task = l1s_swap_iq_ul(radio_freq,task);
+
+            l1ddsp_load_tx_task(dsp_task, 0, desc_ptr->tsc);
+          }
+      #else
+        dsp_task = l1s_swap_iq_ul(radio_freq,task);
+
+        l1ddsp_load_tx_task(dsp_task, 0, desc_ptr->tsc);
+      #endif
+
+        /*--------------------------------------------*/
+        /* Program TPU...                             */
+        /*--------------------------------------------*/
+      #if TESTMODE
+        // if Normal Mode or
+        // if TestMode and UL-only or DL+UL
+        if ( !l1_config.TestMode ||
+           (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK) &&
+           (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS           ||
+            l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS)))
+      #endif
+            {
+               l1dtpu_serv_tx_nb(radio_freq, l1a_l1s_com.dedic_set.aset->timing_advance, l1s.tpu_offset, l1s.applied_txpwr, adc_active_ul);
+            }
+    }
+
+#if 0	/* FreeCalypso TCS211 reconstruction */
+  } // End of "TCH/UL is a normal burst"
+#endif
+
+  /*----------------------------------------------*/
+  /* Common for Dedicated mode: DSP parameters... */
+  /*----------------------------------------------*/
+
+  #if (AMR == 1)
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            l1a_l1s_com.dedic_set.sync_amr,
+                            l1a_l1s_com.dedic_set.reset_sacch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.vocoder_on);
+                          #else
+                            l1a_l1s_com.dedic_set.vocoder_on,
+                            0);
+                          #endif
+    #else // FF_L1_TCH_VOCODER_CONTROL
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.sync_amr);
+                          #else
+                            l1a_l1s_com.dedic_set.sync_amr,
+                            0);
+                          #endif
+    #endif // FF_L1_TCH_VOCODER_CONTROL
+
+    l1a_l1s_com.dedic_set.sync_amr    = FALSE;
+
+  #else // AMR
+    #if (FF_L1_TCH_VOCODER_CONTROL == 1)
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            l1a_l1s_com.dedic_set.reset_sacch,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.vocoder_on);
+    #else
+                            l1a_l1s_com.dedic_set.vocoder_on,
+                            0);
+                          #endif
+    #else
+      l1ddsp_load_tch_param(&(l1s.next_time),
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->mode,
+                            desc_ptr->channel_type,
+                            desc_ptr->subchannel,
+                            l1a_l1s_com.dedic_set.aset->achan_ptr->tch_loop,
+                          #if !FF_L1_IT_DSP_DTX
+                            l1a_l1s_com.dedic_set.sync_tch);
+                          #else
+                            l1a_l1s_com.dedic_set.sync_tch,
+                            0);
+                          #endif
+    #endif
+  #endif // AMR
+
+  // Clear "sync_tch" flag to maintain normal TCH process.
+  l1a_l1s_com.dedic_set.sync_tch = FALSE;
+#if (FF_L1_TCH_VOCODER_CONTROL)
+  l1a_l1s_com.dedic_set.reset_sacch = FALSE;
+#endif
+
+#if 0	/* FreeCalypso TCS211 reconstruction */
+  if(l1a_l1s_com.dedic_set.aset->ho_acc_to_send == 0)
+  {
+#endif
+    // Set tpu window identifier for Power meas or FS/SB search.
+    l1s.tpu_win = (3 * BP_SPLIT) + l1_config.params.tx_nb_load_split + l1_config.params.rx_synth_load_split;
+
+    /*--------------------------------------------*/
+    /* Flag DSP and TPU programmation...          */
+    /*--------------------------------------------*/
+    #if TESTMODE
+      // if Normal Mode or
+      // if TestMode and UL-only or DL+UL
+      if ( !l1_config.TestMode ||
+         (l1_config.TestMode && (l1_config.tmode.rf_params.down_up & TMODE_UPLINK)))
+    #endif
+      {
+        #if TESTMODE
+          // Continuous mode: swap TPU page for Tx in NO_CONTINUOUS or START_TX_CONTINUOUS mode.
+          if ((!l1_config.TestMode)                                           ||
+              (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS)      ||
+              (l1_config.tmode.rf_params.tmode_continuous == TM_START_TX_CONTINUOUS))
+        #endif
+          {
+            l1s.tpu_ctrl_reg |= CTRL_TX;
+          }
+        l1s.dsp_ctrl_reg |= CTRL_TX;
+      }
+
+    #if TESTMODE
+      // Continuous mode: if end of control of START_RX/TX: go to CONTINUOUS state
+      if (l1_config.TestMode && (l1_config.tmode.rf_params.tmode_continuous != TM_NO_CONTINUOUS))
+        l1_config.tmode.rf_params.tmode_continuous = TM_CONTINUOUS;
+    #endif
+
+#if 0	/* FreeCalypso TCS211 reconstruction */
+  }
+#endif
+}
+
+#if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+/*-------------------------------------------------------*/
+/* l1s_hopping_algo()                                    */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* dedicated mode tasks: DDL, DUL, ADL, AUL, TCHTH/F and */
+/* TCHA. This function performs the Hopping Sequence     */
+/* generation. It computes the ARFCN to use on the next  */
+/* frame. When the channel does not hop, it returns      */
+/* the fixe ARFCN provided in the channel description.   */
+/*                                                       */
+/* If the channel is hopping and the ARFCN result is the */
+/* BEACON frequency, an indication flag is set to warn   */
+/* the DSP ("b_bcch_freq_ind").                          */
+/*                                                       */
+/* (see GSM05.02 $6.2.3)                                 */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.dedic_set.aset"                          */
+/*   Active set of Dedicated channel parameters.         */
+/*                                                       */
+/* "l1s.l1s.next_time"                                   */
+/*   frame number and derived numbers for next frame.    */
+/*                                                       */
+/* Returned parameter in globals:                        */
+/* ------------------------------                        */
+/*                                                       */
+/* "l1a_l1s_com.dedic_set.radio_freq"                    */
+/*   ARFCN to be used on the next frame.                 */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_hopping_algo(UWORD8 task, UWORD8 param2)
+{
+  UWORD8               mai;
+  T_CHN_SEL           *chan_sel;
+  T_MOBILE_ALLOCATION *alist_ptr;
+
+  UWORD16             *ma;
+  UWORD8               n;
+  UWORD8               hsn;
+  UWORD8               maio;
+  UWORD16             *radio_freq_ptr;
+  UWORD16             *beacon_channel_ptr=&l1a_l1s_com.Scell_info.radio_freq; // beacon channel of the serving cell
+  T_TIME_INFO         *time_ptr;
+  T_TIME_INFO         next_neighbor_time;
+
+
+  switch(task)
+  {
+
+#if L1_GPRS
+    case PTCCH:
+    {
+      chan_sel       = &(l1pa_l1ps_com.transfer.aset->freq_param.chan_sel);
+      alist_ptr      = &(l1pa_l1ps_com.transfer.aset->freq_param.freq_list);
+      radio_freq_ptr = &l1pa_l1ps_com.transfer.ptcch.radio_freq;
+      time_ptr       = &l1s.next_time;
+    }
+    break;
+
+    case PDTCH:
+    case SINGLE:
+    // For PDTCH, set pointers to the PACKET parameter structures.
+    {
+      chan_sel       = &(l1pa_l1ps_com.transfer.aset->freq_param.chan_sel);
+      alist_ptr      = &(l1pa_l1ps_com.transfer.aset->freq_param.freq_list);
+      radio_freq_ptr = &l1a_l1s_com.dedic_set.radio_freq;
+      time_ptr       = &l1s.next_time;
+    }
+    break;
+
+    case PALLC:
+    case PNP:
+    case PEP:
+    {
+      chan_sel       = &l1pa_l1ps_com.pccch.packet_chn_desc.chan_sel;
+      alist_ptr      = &l1pa_l1ps_com.pccch.frequency_list;
+      radio_freq_ptr = &l1pa_l1ps_com.p_idle_param.radio_freq;
+      time_ptr       = &l1s.next_time;
+    }
+    break;
+
+    case POLL:
+    {
+      // Load adequat freq. list according to the current mode:
+      // SINGLE (i.e. 2 phase access) else Packet Access or Packet Idle
+      if(l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)
+      {
+        chan_sel       = &(l1pa_l1ps_com.transfer.aset->freq_param.chan_sel);
+        alist_ptr      = &(l1pa_l1ps_com.transfer.aset->freq_param.freq_list);
+        radio_freq_ptr = &l1a_l1s_com.dedic_set.radio_freq;
+      }
+      else
+      {
+        chan_sel       = &l1pa_l1ps_com.pccch.packet_chn_desc.chan_sel;
+        alist_ptr      = &l1pa_l1ps_com.pccch.frequency_list;
+        radio_freq_ptr = &l1pa_l1ps_com.p_idle_param.radio_freq;
+      }
+      time_ptr       = &l1s.next_time;
+    }
+    break;
+
+    case PBCCHS:
+    {
+      chan_sel       = &l1pa_l1ps_com.pbcchs.packet_chn_desc.chan_sel;
+      alist_ptr      = &l1pa_l1ps_com.pbcchs.frequency_list;
+      radio_freq_ptr = &l1pa_l1ps_com.p_idle_param.radio_freq;
+
+      // If PBCCHS controlled one frame in advance --> correct Frame Number when PBCCH block is read
+      if (l1pa_l1ps_com.pbcchs.control_offset)
+        time_ptr       = &l1s.next_plus_time;
+      else
+      time_ptr       = &l1s.next_time;
+    }
+    break;
+
+    case PBCCHN_IDLE:
+    case PBCCHN_TRAN:
+    {
+      WORD32  next_neighbor_time_fn;
+
+      chan_sel           = &l1pa_l1ps_com.pbcchn.packet_chn_desc.chan_sel;
+      alist_ptr          = &l1pa_l1ps_com.pbcchn.frequency_list;
+      radio_freq_ptr     = &l1pa_l1ps_com.p_idle_param.radio_freq;
+      beacon_channel_ptr = &l1pa_l1ps_com.pbcchn.bcch_carrier;
+      time_ptr           = &next_neighbor_time;
+
+      // To review (is there any better solution?)...........
+      next_neighbor_time_fn = l1s.next_time.fn + l1pa_l1ps_com.pbcchn.fn_offset;
+
+      #if 0	/* correct code (corrected by TI for LoCosto) */
+      if (next_neighbor_time_fn > ((WORD32)MAX_FN))//OMAPS00090550
+      #else	/* wrong code to match TCS211 disassembly */
+      if (next_neighbor_time_fn > MAX_FN)
+      #endif
+        next_neighbor_time.fn = (UWORD32) (next_neighbor_time_fn - MAX_FN);
+      else if (next_neighbor_time_fn < 0)
+        next_neighbor_time.fn = (UWORD32) (next_neighbor_time_fn + MAX_FN);
+      else
+        next_neighbor_time.fn = (UWORD32) (next_neighbor_time_fn);
+
+      next_neighbor_time.t1 = next_neighbor_time.fn / (26L*51L);       // T1 = FN div 26*51
+      next_neighbor_time.t2 = next_neighbor_time.fn % 26;              // T2 = FN % 26.
+      next_neighbor_time.t3 = next_neighbor_time.fn % 51;              // T3 = FN % 51.
+    }
+    break;
+
+    case ITMEAS:
+    {
+      // Packet transfer mode
+      if (l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED)
+      {
+        // We use the active TBF frequency parameters
+        chan_sel  = &(l1pa_l1ps_com.transfer.aset->freq_param.chan_sel);
+        alist_ptr = &(l1pa_l1ps_com.transfer.aset->freq_param.freq_list);
+      }
+
+      // Packet idle mode
+      else
+      {
+        // We use the frequency parameters given in the MPHP_INT_MEAS_REQ message
+        chan_sel     = &(l1pa_l1ps_com.itmeas.packet_intm_freq_param.chan_sel);
+        alist_ptr    = &(l1pa_l1ps_com.itmeas.packet_intm_freq_param.freq_list);
+      }
+
+      radio_freq_ptr = &l1pa_l1ps_com.itmeas.radio_freq;
+      time_ptr       = &l1s.next_plus_time;
+    }
+    break;
+
+#endif
+
+    case SMSCB:
+    // For SMSCB, set pointers to the SMSCB parameter structures.
+    {
+      chan_sel       = &l1a_l1s_com.cbch_desc.chan_sel;
+      alist_ptr      = &l1a_l1s_com.cbch_freq_list;
+      radio_freq_ptr = &l1a_l1s_com.dedic_set.radio_freq;
+
+      // If SMSCB is controlled one frame in advance --> correct Frame Number when SMSCB block is read
+      if (l1a_l1s_com.pre_scheduled_cbch)
+        time_ptr       = &l1s.next_plus_time;
+      else
+      time_ptr       = &l1s.next_time;
+    }
+    break;
+
+    default:
+    // For SDCCH/TCH, set pointers to the active channel description.
+    {
+      chan_sel       = &(l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->chan_sel);
+      alist_ptr      = l1a_l1s_com.dedic_set.aset->ma.alist_ptr;
+      radio_freq_ptr = &l1a_l1s_com.dedic_set.radio_freq;
+      time_ptr       = &l1s.next_time;
+    }
+  } // End of switch(task)
+
+  // Set local variables.
+  ma   = &(alist_ptr->rf_chan_no.A[0]);
+  n    =   alist_ptr->rf_chan_cnt;
+  hsn  =   chan_sel->rf_channel.hopping_rf.hsn;
+  maio =   chan_sel->rf_channel.hopping_rf.maio;
+
+  if(chan_sel->h == FALSE)
+  // Single RF channel, NOT HOPPING.
+  {
+    *radio_freq_ptr = chan_sel->rf_channel.single_rf.radio_freq;
+  }
+
+  else
+  // Hopping channel...
+  {
+    /**************************************************/
+    /* Perform the HOPPING algorithm.                 */
+    /**************************************************/
+    if(hsn == 0)
+    // Cyclic hopping...
+    {
+      mai = (time_ptr->fn + maio) % n;
+    }
+    else
+    {
+      UWORD8  i = 0;
+      UWORD8  m;
+      UWORD8  mp;
+      UWORD8  nbin;
+      UWORD8  tp;
+      UWORD8  s;
+      UWORD8  t1r = (UWORD8)(time_ptr->t1 % 64);
+
+      while(i<=6)
+      {
+        if((n >> i) > 0) nbin = i;
+        i++;
+      }
+      nbin++;
+
+      m  = time_ptr->t2 + RNTABLE[(hsn ^ t1r) + time_ptr->t3];
+      mp = m % (1L << nbin);
+      tp = time_ptr->t3 % (1L << nbin);
+
+      if(mp < n) s = mp;
+      else       s = (mp + tp) % n;
+
+      mai = (s + maio) % n;
+    }
+
+    *radio_freq_ptr = ma[mai];
+  }
+
+  if(*radio_freq_ptr == *beacon_channel_ptr)
+  // If ARFCN is the BEACON...
+  {
+    // Set "b_bcch_freq_ind" to TRUE.
+    l1s_dsp_com.dsp_db_w_ptr->d_ctrl_system |= (1 << B_BCCH_FREQ_IND);
+
+  }
+}
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+#endif // MOVE_IN_INTERNAL_RAM
+
+//===============================================================================================//
+
+#if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0))  // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START         // KEEP IN EXTERNAL MEM otherwise
+
+/*-------------------------------------------------------*/
+/* l1s_read_dummy()                                      */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* task: ABORT. Since this task just aborts any ongoing  */
+/* DSP task, there is no result returned by the DSP to   */
+/* the MCU when this abort is completed, but the MCU/DSP */
+/* com. read page must be switched properly. This the    */
+/* only reason why we have created this function.        */
+/*                                                       */
+/* Modified parameter in globals:                        */
+/* ------------------------------                        */
+/*                                                       */
+/* "l1s_dsp_com.dsp_r_page_used"                         */
+/*   Flag used by the function which closes L1S          */
+/*   execution ("l1s_end_manager()") to know if the      */
+/*   MCU/DSP read page must be switched.                 */
+/*   -> Set to 1.                                        */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_read_dummy(UWORD8 task, UWORD8 param2)
+{
+  l1_check_com_mismatch(task);
+
+  #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+    trace_fct(CST_L1S_READ_DUMMY ,(UWORD32)(-1));//OMAPS00090550
+  #endif
+
+      // task is completed, make it INACTIVE (only in case of TCHD).
+  if(task == TCHD)
+   l1s.task_status[task].current_status = INACTIVE;
+
+  #if FF_L1_IT_DSP_DTX
+    // Fast DTX status update
+    if(task == TCHD)
+    {
+      UWORD8 subchannel = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel;
+
+      // Currently used for TCH-AHS only
+      if (((subchannel == 0) && (l1s.actual_time.fn_mod13_mod4 == 0)) || // FN%13 = 4, 8 and 12 for TCH/H0 (no Read on FN%13=0)
+          ((subchannel == 1) && (l1s.actual_time.fn_mod13_mod4 == 1)))   // FN%13 = 1, 5 and 9  for TCH/H1
+      {
+        // Latch TX activity status if DTX allowed
+        if ((l1a_l1s_com.dedic_set.aset->dtx_allowed == FALSE) ||                // No DTX allowed
+            (l1s_dsp_com.dsp_ndb_ptr->d_fast_dtx_enc_data ) || // DTX allowed but not used
+            (l1a_apihisr_com.dtx.fast_dtx_ready == FALSE))                       // Fast DTX status is invalid
+          l1a_apihisr_com.dtx.tx_active = TRUE;
+        else
+          l1a_apihisr_com.dtx.tx_active = FALSE;
+      }
+    }
+  #endif
+  // Set flag used to change the read page at the end of "l1_synch".
+  l1s_dsp_com.dsp_r_page_used = TRUE;
+}
+
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+#endif
+
+/*-------------------------------------------------------*/
+/* l1s_read_msagc()                                      */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: BCCHN,FBNEW,SB1,SB2,SBCONF. This function is   */
+/* the reading result function used for reading a power  */
+/* measurement result used then to refreshing the AGC    */
+/* for those tasks. Here is a summary of the execution:  */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low.                         */
+/*    - Get the cell information structure.              */
+/*    - Traces and debug.                                */
+/*    - Read receive level result from MCU/DSP interface.*/
+/*  - Flag the use of the MCU/DSP dual page read         */
+/*    interface.                                         */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   BCCHN, BCCH Neighbor reading task.                  */
+/*   FBNEW, Frequency Burst detection task in Idle mode. */
+/*   SB1, Synchro Burst reading task in Idle mode.       */
+/*   SB2, Synchro Burst detection task in Idle mode.     */
+/*   SBCONF, Synchro Burst confirmation task in Idle     */
+/*   mode.                                               */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.Ncell_info.bcch"                         */
+/* "l1a_l1s_com.Ncell_info.acquis"                       */
+/* "l1a_l1s_com.Ncell_info.acquis"                       */
+/* "l1a_l1s_com.Ncell_info.conf"                         */
+/*   cell information structure used for BCCHN,FBNEW,    */
+/*   SB1/SB2,SBCONF respectively.                        */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s_dsp_com.dsp_r_page_used"                         */
+/*   Flag used by the function which closes L1S          */
+/*   execution ("l1s_end_manager()") to know if the      */
+/*   MCU/DSP read page must be switched.                 */
+/*   -> Set to 1.                                        */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_read_msagc(UWORD8 task, UWORD8 param2)
+{
+  BOOL      en_task;
+  BOOL      task_param;
+  UWORD8    pm_level[2];
+#if (L1_FF_MULTIBAND == 1)
+  UWORD16  operative_radio_freq;
+#endif
+
+
+  // Get "enable" task flag and "synchro semaphore" for current task.
+  en_task    = l1a_l1s_com.l1s_en_task[task];
+  task_param = l1a_l1s_com.task_param[task];
+
+  if((en_task) && !(task_param))
+  // Check the task semaphore and the task enable bit. The reading
+  // task body is executed only when the task semaphore is 0 and the
+  // task is still enabled.
+  // The semaphore can be set to 1 whenever L1A makes some changes
+  // to the task parameters. The task can be disabled by L1A.
+  {
+    T_NCELL_SINGLE  *cell_info_ptr = NULL;
+    #if (L1_GPRS)
+      T_NCELL_SINGLE pbcchn_cell_info;
+    #endif
+#if ((REL99 == 1) && (FF_BHO == 1))
+    T_NCELL_SINGLE bho_cell_info;
+#endif
+
+    // Get the cell information structure.
+    // ************************************
+
+    switch(task)
+    {
+      case BCCHN_TOP:  cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top  ]; break;
+      case BCCHN:      cell_info_ptr = &l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm ]; break;
+      case FBNEW:  cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id];     break;
+      case SB2:    cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];     break;
+      case SBCONF: cell_info_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id]; break;
+#if ((REL99 == 1) && (FF_BHO == 1))
+      case FBSB:
+      {
+        cell_info_ptr = &bho_cell_info;
+        bho_cell_info.radio_freq = l1a_l1s_com.nsync_fbsb.radio_freq;
+        bho_cell_info.fn_offset  = l1a_l1s_com.nsync_fbsb.fn_offset;
+      }
+      break;
+#endif
+      #if (L1_GPRS)
+        case PBCCHN_IDLE:
+        {
+          cell_info_ptr = &pbcchn_cell_info;
+          pbcchn_cell_info.radio_freq = l1pa_l1ps_com.pbcchn.bcch_carrier;
+          pbcchn_cell_info.fn_offset  = l1pa_l1ps_com.pbcchn.fn_offset;
+        }
+        break;
+      #endif
+
+      default: return;
+    }
+
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE!=0)
+      trace_fct(CST_L1S_READ_MSAGC , cell_info_ptr->radio_freq);
+    #endif
+
+    #if L2_L3_SIMUL
+      #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+        buffer_trace(4, l1s.actual_time.fn, cell_info_ptr->radio_freq,
+                      cell_info_ptr->fn_offset, pm);
+      #endif
+    #endif
+
+    l1_check_com_mismatch(MS_AGC_ID);
+
+    // Read receive level result from MCU/DSP interface.
+    // **************************************************
+    // Read 2 received levels...
+    #if L1_GPRS
+      switch (l1a_l1s_com.dsp_scheduler_mode)
+      {
+        case GPRS_SCHEDULER:
+        {
+          // Call the reading driver using GPRS scheduler
+          l1pddsp_meas_read(2, pm_level);
+        } break;
+
+        case GSM_SCHEDULER:
+        {
+          // Call the reading driver using GSM scheduler
+          l1ddsp_meas_read(2, pm_level);
+        } break;
+      }
+    #else
+      l1ddsp_meas_read(2, pm_level);
+    #endif
+
+    // Power Measurement performed during last l1s_ctrl_msagc with HIGH_AGC
+    // returned in pm_level[0]
+    // Power measurement performed during last l1s_ctrl_msagc with LOW_AGC
+    // returned in pm_level[1]
+
+    l1_check_pm_error(pm_level[0], MS_AGC_ID);
+    l1_check_pm_error(pm_level[1], MS_AGC_ID);
+
+    l1ctl_pgc2(pm_level[0], pm_level[1], cell_info_ptr->radio_freq);
+
+    #if L2_L3_SIMUL
+      #if (DEBUG_TRACE == BUFFER_TRACE_LNA)
+      
+       #if (L1_FF_MULTIBAND == 0)
+            buffer_trace (4, 22, cell_info_ptr->radio_freq,
+                      l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].input_level,
+                      l1a_l1s_com.last_input_level[cell_info_ptr->radio_freq - l1_config.std.radio_freq_index_offset].lna_off);
+
+       #else // L1_FF_MULTIBAND = 1 below
+
+            operative_radio_freq = 
+              l1_multiband_radio_freq_convert_into_operative_radio_freq(cell_info_ptr->radio_freq);
+            buffer_trace (4, 22, cell_info_ptr->radio_freq,
+                     l1a_l1s_com.last_input_level[cell_info_ptr->agc_index].input_level,
+                     l1a_l1s_com.last_input_level[cell_info_ptr->agc_index].lna_off); 
+
+       #endif // #if (L1_FF_MULTIBAND == 0) else
+
+      #endif
+    #endif
+  }
+
+  // Flag the use of the MCU/DSP dual page read interface.
+  // ******************************************************
+
+  // Set flag used to change the read page at the end of "l1_synch".
+  l1s_dsp_com.dsp_r_page_used = TRUE;
+}
+
+#if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+/*-------------------------------------------------------*/
+/* l1s_read_mon_result()                                 */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: FBNEW,SB1,SB2,SBCONF,SB51,SBCNF51,SB26,SBCNF26.*/
+/* This function is the reading result function used for */
+/* reading the neighbor cell monitoring results. Here is */
+/* a summary of the execution:                           */
+/*                                                       */
+/*  - Traces and debug.                                  */
+/*  - Get task result from MCU/DSP read interface.       */
+/*                                                       */
+/*      - case: FBNEW/FB51.                              */
+/*          - If SEMAPHORE(task) is low.                 */
+/*              - Update AFC if required.                */
+/*              - Read FB detection results.             */
+/*              - Reports results to L1A.                */
+/*          - Disactivate and Disable task.              */
+/*          - Reset buffers and flags in NDB.            */
+/*                                                       */
+/*      - case: FB26.                                    */
+/*          - Read FB detection results.                 */
+/*          - Reports results to L1A.                    */
+/*          - Disactivate task.                          */
+/*                                                       */
+/*      - case: SB26/SBCNF26.                            */
+/*          - Read SB reading results.                   */
+/*          - Reports results to L1A.                    */
+/*          - Disactivate task.                          */
+/*                                                       */
+/*      - case: SB1/SB2/SB51/SBCONF/SBCNF51.             */
+/*          - If SEMAPHORE(task) is low.                 */
+/*              - Update AFC if required.                */
+/*              - Read FB detection results.             */
+/*              - Reports results to L1A.                */
+/*          - Disactivate task when required.            */
+/*                                                       */
+/*  - Flag the use of the MCU/DSP dual page read         */
+/*    interface.                                         */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   FBNEW, Frequency Burst detection task in Idle mode. */
+/*   SB1, Synchro Burst reading task in Idle mode.       */
+/*   SB2, Synchro Burst detection task in Idle mode.     */
+/*   SBCONF, Synchro Burst confirmation task in Idle     */
+/*   mode.                                               */
+/*   SB51, Synchro Burst reading task in SDCCH Dedicated */
+/*   mode.                                               */
+/*   SBCNF51, Synchro Burst confirmation task in SDCCH   */
+/*   Dedicated mode.                                     */
+/*   SB26, Synchro Burst reading task in TCH Dedicated   */
+/*   mode.                                               */
+/*   SBCNF26, Synchro Burst confirmation task in TCH     */
+/*   Dedicated mode.                                     */
+/*                                                       */
+/* "attempt_for_sb2"                                     */
+/*   Since SB2 calls twice this function, this parameter */
+/*   tells the function which call it it. Used mainly    */
+/*   to know when to DISACTIVATE the task.               */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.task_param"                              */
+/*   task semaphore bit register. Used to skip the body  */
+/*   of this function if L1A has changed or is changing  */
+/*   some of the task parameters.                        */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1a_l1s_com.l1s_en_task"                             */
+/*   L1S task enable bit register.                       */
+/*   -> disable FBNEW,FB51 task.                         */
+/*                                                       */
+/* "l1s.task_status[task].current_status"                */
+/*   current task status. It must be reset (INACTIVE)    */
+/*   when the task is completed.                         */
+/*   -> disactivate task.                                */
+/*                                                       */
+/* "l1s_dsp_com.dsp_r_page_used"                         */
+/*   Flag used by the function which closes L1S          */
+/*   execution ("l1s_end_manager()") to know if the      */
+/*   MCU/DSP read page must be switched.                 */
+/*   -> Set to 1.                                        */
+/*                                                       */
+/* Use of MCU/DSP interface:                             */
+/* -------------------------                             */
+/* "l1s_dsp_com.dsp_ndb_ptr"                             */
+/*   pointer to the non double buffered part (NDB) of    */
+/*   the MCU/DSP interface. This part is R/W for both    */
+/*   DSP and MCU.                                        */
+/*                                                       */
+/* "l1s_dsp_com.dsp_db_r_ptr"                            */
+/*   pointer to the double buffered part (DB) of the     */
+/*   MCU/DSP interface. This pointer points to the READ  */
+/*   page.                                               */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_read_mon_result(UWORD8 task, UWORD8 attempt)
+{
+  UWORD32   flag=0;
+  UWORD32   toa;
+  UWORD32   pm;
+  UWORD32   angle;
+  UWORD32   snr;
+
+  #if TESTMODE
+    UWORD32   pm_fullres;
+  #endif
+
+  API      *data;
+
+  BOOL      en_task;
+  BOOL      task_param;
+  UWORD32   fb_abort_flag=0;
+
+  /*-------------------------------------------------------------------------------*/
+  /* READ MONITORING TASK RESULTS FROM MCU/DSP INTERFACE...                        */
+  /*-------------------------------------------------------------------------------*/
+  // Get "enable" task flag and "synchro semaphore" for current task.
+  en_task    = l1a_l1s_com.l1s_en_task[task];
+  task_param = l1a_l1s_com.task_param[task];
+
+  // Traces and debug.
+  // ******************
+    #if (TRACE_TYPE!=0)&& (TRACE_TYPE !=5)
+      trace_fct(CST_L1S_READ_MON_RESULT,(UWORD32)(-1));
+    #endif
+
+  if(!(en_task) || (task_param))
+  {
+    #if (TRACE_TYPE!=0)
+      // Current task is no more alive, L1A changed the task parameters.
+      // -> Trace "ABORT" on log file and screen.
+      trace_fct(CST_TASK_KILLED, (UWORD32)(-1));
+    #endif
+  }
+  else
+  // Current task is still alive, check task identifier and debug number...
+  {
+    #if (TRACE_TYPE!=0)
+      if((task != FB26) && (task != SB26) && (task != SBCNF26)) // DB cannot be used for FB26/SB26/SBCNF26 result.
+        if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_md & 0xffff) !=
+           (UWORD32)DSP_TASK_CODE[task])
+          // Task id. different than the one expected...
+          trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND,(UWORD32)(-1));
+    #endif
+
+    if((task != FB26) && (task != SB26)
+       && (task != SBCNF26) && (attempt==12)
+       #if ((REL99 == 1) && (FF_BHO == 1))
+         && (task != FBSB)
+       #endif
+      ) // DB cannot be used for FB26/SB26/SBCNF26 result.
+    {
+        l1_check_com_mismatch(task);
+    }
+  }
+
+  // Get task result from MCU/DSP read interface.
+  // *********************************************
+
+  switch(task)
+  {
+    case FBNEW :
+    case FB51 :
+    /*---------------------------------------------------*/
+    /* Frequency burst detection result...               */
+    /*---------------------------------------------------*/
+    {
+      if((en_task) && !(task_param))
+      // Check the task semaphore and the task enable bit. The reading
+      // task body is executed only when the task semaphore is 0 and the
+      // task is still enabled.
+      // The semaphore can be set to 1 whenever L1A makes some changes
+      // to the task parameters. The task can be disabled by L1A.
+      {
+        flag  = l1s_dsp_com.dsp_ndb_ptr->d_fb_det              & 0xffff; //  1 means FOUND.
+        toa   = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA]   & 0xffff; //  Unit is BIT.
+        pm    = (l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM]   & 0xffff) >> 5;
+                                                                         //  WARNING... to be used!!!
+        #if TESTMODE
+          pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff;  // F26.6
+        #endif
+        angle = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_ANGLE] & 0xffff; //  WARNING... to be used!!!
+        snr   = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_SNR]   & 0xffff; //  WARNING... to be used!!!
+
+
+        // Check FB detection flag and attempt:
+        // If no detection and attempt < 12 than continue FB search
+        // Attempt=11: special case: wait for next (last) read, as
+        // other task may already be programmed in MFTAB (do not flush !!!)
+        if(((!flag) && (attempt < 11)) || (attempt==11))
+          break;
+
+        // If FB detection occurs before 11th attempt, abort FB search
+        if((flag == TRUE) && (attempt < 11))
+          fb_abort_flag=TRUE;
+
+
+        if (fb_abort_flag == TRUE)
+        {
+          if ((l1s_dsp_com.dsp_db_r_ptr->d_debug & 0xffff) != ((l1s.debug_time + (12 - attempt)) % 65536))
+            l1_check_com_mismatch(task);
+        }
+
+//       l1_check_pm_error(pm, task);
+
+        #if TRACE_TYPE==3
+          stats_samples_fb(flag,toa,pm,angle,snr);
+        #endif
+
+        #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+          uart_trace(FB51);
+        #endif
+
+        // Update AFC: Call AFC control function (KALMAN filter).
+        #if AFC_ALGO
+          #if TESTMODE
+            if (l1_config.afc_enable)
+          #endif
+            {
+              WORD16 old_afc=l1s.afc;
+
+           if((flag == TRUE) && (l1a_l1s_com.mode == CS_MODE))
+           {
+            #if (VCXO_ALGO == 0)
+              l1s.afc = l1ctl_afc(AFC_OPEN_LOOP,
+                                  &l1s.afc_frame_count,
+                                  (WORD16)angle,
+                                  0,
+                                  l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq);
+            #else
+              l1s.afc = l1ctl_afc(AFC_OPEN_LOOP,
+                                  &l1s.afc_frame_count,
+                                  (WORD16)angle,
+                                  0,
+                                  l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq,l1a_l1s_com.mode);
+            #endif
+            #if L2_L3_SIMUL
+              #if (DEBUG_TRACE == BUFFER_TRACE_AFC_OPEN)
+                buffer_trace (4,(WORD16)angle,old_afc,l1s.afc,0);
+              #endif
+            #endif
+              }
+            }
+        #endif
+
+        // Call FB report function (send report msg to L1A).
+        #if TESTMODE
+          if (l1_config.TestMode)
+            l1s_read_fb(task, flag, toa, attempt, pm_fullres, angle, snr);
+          else
+            l1s_read_fb(task, flag, toa, attempt, pm, angle, snr);
+        #else
+          l1s_read_fb(task, flag, toa, attempt, pm, angle, snr);
+        #endif
+
+        // The Frequency Burst detection task in Idle (FBNEW) and
+        // Dedicated/SDCCH (FB51) are 1 shot tasks, they must be
+        // disabled in L1S when they are completed. Disable it.
+        l1a_l1s_com.l1s_en_task[task] = TASK_DISABLED;
+
+        // the status is not used in D51 and D26 modes
+        if (task != FB51 )
+        {
+          l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].status = NSYNC_COMPLETED;
+        }
+      }
+
+      if ((fb_abort_flag == TRUE) || (attempt==12))
+      {
+        // FB task is completed, make it INACTIVE.
+        l1s.task_status[task].current_status = INACTIVE;
+
+        // Reset buffers and flags in NDB ...
+        l1s_dsp_com.dsp_ndb_ptr->d_fb_det            = FALSE;
+        l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA] = 0;
+
+        // This task is not compatible with Neigh. Measurement.
+        // Clear "forbid_meas" to indicate when the task is complete.
+        l1s.forbid_meas = 0;
+      }
+
+      // FB search finished before 11th attempt:
+      // -reset DSP R/W pages, DSP tasks and TPU
+      // -flush MFTAB and reset frame count
+      // -adjust debug time
+      if(fb_abort_flag)
+      {
+        l1d_reset_hw(l1s.tpu_offset);
+        l1s.tpu_ctrl_reg |= CTRL_FB_ABORT; // set CTRL bit -> tpu_end_scenario
+        l1s_clear_mftab(l1s.mftab.frmlst);
+        l1s.frame_count = 0;
+
+#if 0	/* FreeCalypso TCS211 reconstruction */
+        // This task is not compatible with Neigh. Measurement.
+        // Clear "forbid_meas" to indicate when the task is complete.
+        l1s.forbid_meas = 0;
+#endif
+      }
+    }
+    break;
+
+    case FB26 :
+    /*---------------------------------------------------*/
+    /* Frequency burst detection result...               */
+    /*---------------------------------------------------*/
+    {
+      UWORD8 neigh_id;
+
+      // read cell identifier.
+      neigh_id = l1a_l1s_com.nsync.active_fb_id;
+
+      if((en_task) && !(task_param))
+      // Check the task semaphore and the task enable bit. The reading
+      // task body is executed only when the task semaphore is 0 and the
+      // task is still enabled.
+      // The semaphore can be set to 1 whenever L1A makes some changes
+      // to the task parameters. The task can be disabled by L1A.
+      {
+        flag  = l1s_dsp_com.dsp_ndb_ptr->d_fb_det              & 0xffff; //  1 means FOUND.
+        toa   = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA]   & 0xffff; //  Unit is BIT.
+        pm    = (l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM]   & 0xffff) >> 5;
+                                                                         //  WARNING... to be used!!!
+        #if TESTMODE
+          pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff;  // F10.6
+        #endif
+
+        // CQ 19836: do not check PM on FB26
+        //l1_check_pm_error(pm, task);
+
+        angle = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_ANGLE] & 0xffff; //  WARNING... to be used!!!
+        snr   = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_SNR]   & 0xffff; //  WARNING... to be used!!!
+
+        // Call FB report function (send report msg to L1A).
+        #if TESTMODE
+          if (l1_config.TestMode)
+            l1s_read_fb(task, flag, toa, NO_PAR, pm_fullres, angle, snr);
+          else
+            l1s_read_fb(task, flag, toa, NO_PAR, pm, angle, snr);
+        #else
+          l1s_read_fb(task, flag, toa, NO_PAR, pm, angle, snr);
+        #endif
+      }
+
+      #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+        uart_trace(FB26);
+      #endif
+
+
+      // The Frequency Burst detection task in Dedicated/TCH
+      // is composed with several attempts managed in L1A.
+      //    -> task is completed: set INACTIVE.
+      l1s.task_status[task].current_status = INACTIVE;
+
+      // Reset buffers and flags in NDB ...
+      l1s_dsp_com.dsp_ndb_ptr->d_fb_det            = FALSE;
+      l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA] = 0;
+    }
+    break;
+
+    case SB26 :
+    case SBCNF26 :
+    /*---------------------------------------------------*/
+    /* Synchro. burst detection result...                */
+    /*---------------------------------------------------*/
+    {
+      if((en_task) && !(task_param))
+      // Check the task semaphore and the task enable bit. The reading
+      // task body is executed only when the task semaphore is 0 and the
+
+      // task is still enabled.
+      // The semaphore can be set to 1 whenever L1A makes some changes
+      // to the task parameters. The task can be disabled by L1A.
+      {
+        flag  = !(((l1s_dsp_com.dsp_ndb_ptr->a_sch26[0] & 0xffff) & (1<<B_SCH_CRC)) >> B_SCH_CRC); //  1 means ERROR.
+        toa   = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA]   & 0xffff;  //  Unit is BIT.
+        pm    = (l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM]   & 0xffff) >> 5;
+                                                                          //  WARNING... to be used!!!
+        #if TESTMODE
+          pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff;  // F26.6
+        #endif
+
+        angle = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_ANGLE] & 0xffff;
+        snr   = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_SNR]   & 0xffff;
+        data  = &(l1s_dsp_com.dsp_ndb_ptr->a_sch26[3]);                   // Set data block pointer (skip header).
+
+        l1_check_pm_error(pm, task);
+
+        // Call SB report function (send report msg to L1A).
+        #if TESTMODE
+          if (l1_config.TestMode)
+            l1s_read_sb(task, flag, data, toa, attempt, pm_fullres, angle, snr);
+          else
+            l1s_read_sb(task, flag, data, toa, attempt, pm, angle, snr);
+        #else
+          l1s_read_sb(task, flag, data, toa, attempt, pm, angle, snr);
+        #endif
+      }
+      #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+        uart_trace(SB26);
+      #endif
+
+
+      // The Synchro Burst detection (SB26) and confirmation (SBCNF26)
+      // tasks in Dedicated/TCH are enabling/disabling are fully
+      // managed by L1A.
+      //    -> task is completed: set INACTIVE.
+      l1s.task_status[task].current_status = INACTIVE;
+
+      // Reset buffers and flags in NDB ...
+      l1s_dsp_com.dsp_ndb_ptr->a_sch26[0]    =  (1<<B_SCH_CRC);
+    }
+    break;
+
+    case SB2 :
+    case SBCONF :
+    case SB51 :
+    case SBCNF51 :
+    /*---------------------------------------------------*/
+    /* Synchro. burst detection result...                */
+    /*---------------------------------------------------*/
+    {
+      if((en_task) && !(task_param))
+      // Check the task semaphore and the task enable bit. The reading
+      // task body is executed only when the task semaphore is 0 and the
+      // task is still enabled.
+      // The semaphore can be set to 1 whenever L1A makes some changes
+      // to the task parameters. The task can be disabled by L1A.
+      {
+        UWORD8  neigh_id;
+
+        if((task == SB2) || (task == SB51))
+          neigh_id = l1a_l1s_com.nsync.active_sb_id;
+        else
+          neigh_id = l1a_l1s_com.nsync.active_sbconf_id;
+
+        flag  = !(((l1s_dsp_com.dsp_db_r_ptr->a_sch[0] & 0xffff) & (1<<B_SCH_CRC)) >> B_SCH_CRC); //  1 means ERROR.
+        toa   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA]   & 0xffff;  //  Unit is BIT.
+        pm    = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]   & 0xffff) >> 5;
+                                                                           //  WARNING... to be used!!!
+        #if TESTMODE
+          pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff;  // F26.6
+        #endif
+
+        angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+        snr   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR]   & 0xffff;
+        data  = &(l1s_dsp_com.dsp_db_r_ptr->a_sch[3]);                     // Set data block pointer (skip header).
+
+        #if (L1_DEBUG_IQ_DUMP == 1)
+          l1ddsp_read_iq_dump(task);
+        #endif
+
+        l1_check_pm_error(pm, task);
+
+        // CQ30474. In case SNR is too low, the SB shall be considered as failed.
+        // This is valuable for code running on target with DSP 3606.
+
+	/*
+	 * FreeCalypso: despite the above comment,
+	 * this code is NOT present in TCS211.
+	 */
+#if 0
+#if (CODE_VERSION == NOT_SIMULATION)
+       if ( snr < MIN_ACCEPTABLE_SNR_FOR_SB )
+         flag = FALSE;
+#endif
+#endif
+
+        #if L2_L3_SIMUL
+          #if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+            buffer_trace(4, l1s.actual_time.fn, toa,pm, l1s_dsp_com.dsp_db_r_ptr->a_sch[0] & 0xffff);
+          #endif
+        #endif
+
+        #if TRACE_TYPE==3
+          stats_samples_sb(flag,toa,pm,angle,snr);
+        #endif
+        #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+          if (task == SBCONF) uart_trace(SBCONF);
+          else uart_trace(SB2);        // display result code...
+        #endif
+
+        // Update AFC: Call AFC control function (KALMAN filter).
+        #if AFC_ALGO
+          #if TESTMODE
+            if (l1_config.afc_enable)
+          #endif
+            {
+              WORD16 old_afc=l1s.afc;
+
+           if((flag == TRUE) && (l1a_l1s_com.mode == CS_MODE))
+           {
+            #if (VCXO_ALGO == 0)
+              l1s.afc = l1ctl_afc(AFC_OPEN_LOOP,
+                                  &l1s.afc_frame_count,
+                                  (WORD16)angle,
+                                  0,
+                                  l1a_l1s_com.nsync.list[neigh_id].radio_freq);
+            #else
+              l1s.afc = l1ctl_afc(AFC_OPEN_LOOP,
+                                  &l1s.afc_frame_count,
+                                  (WORD16)angle,
+                                  0,
+                                  l1a_l1s_com.nsync.list[neigh_id].radio_freq,l1a_l1s_com.mode);
+            #endif
+
+                #if L2_L3_SIMUL
+                  #if (DEBUG_TRACE == BUFFER_TRACE_AFC_OPEN)
+                    buffer_trace (4,(WORD16)angle,old_afc,l1s.afc,1);
+                  #endif
+                #endif
+              }
+            }
+        #endif
+
+        // Call SB report function (send report msg to L1A).
+        #if TESTMODE
+          if (l1_config.TestMode)
+            l1s_read_sb(task, flag, data, toa, attempt, pm_fullres, angle, snr);
+          else
+            l1s_read_sb(task, flag, data, toa, attempt, pm, angle, snr);
+        #else
+          l1s_read_sb(task, flag, data, toa, attempt, pm, angle, snr);
+        #endif
+
+        // the status is not used in D51 and D26 modes
+        if ((task != SBCNF51 ) && (task != SB51))
+        {
+          // SB2 activity completed for this neighbour cell.
+          if((task != SB2) || ((task == SB2) && (attempt == 2)))
+            l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_COMPLETED;
+        }
+      }
+
+      // All tasks are completed by this function except SB2 which
+      // calls it twice. SB2 is then completed only when making the
+      // second execution of this function.
+      //    -> task is completed: set INACTIVE.
+      if((task != SB2) || (task == SB2) && (attempt == 2))
+      {
+        l1s.task_status[task].current_status = INACTIVE;
+        l1a_l1s_com.l1s_en_task[task] = TASK_DISABLED;
+      }
+    }
+    break;
+#if ((REL99 == 1) && (FF_BHO == 1))
+    case FBSB :
+
+    /*---------------------------------------------------*/
+    /* Frequency + Synchro burst detection result...     */
+    /*---------------------------------------------------*/
+    {
+      BOOL abort_flag = FALSE;
+
+      if (l1a_l1s_com.nsync_fbsb.fb_found_attempt == 0)
+      // Looking for FB
+      {
+        flag  = l1s_dsp_com.dsp_ndb_ptr->d_fb_det & 0xffff; //  flag = TRUE means FOUND.
+        toa   = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_TOA]   & 0xffff; //  Unit is BIT.
+        pm    = (l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM]   & 0xffff) >> 5;
+#if TESTMODE
+        pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff;  // F26.6
+#endif
+        angle = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_ANGLE] & 0xffff;
+        snr   = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_SNR]   & 0xffff;
+
+        if (flag) // FB detected
+        {
+          // Store toa and attempt for future use
+          l1a_l1s_com.nsync_fbsb.fb_toa = toa;
+          l1a_l1s_com.nsync_fbsb.fb_found_attempt = attempt;
+
+#if (TRACE_TYPE == 3)
+          stats_samples_fb(flag, toa, pm, angle, snr);
+#endif
+
+#if (TRACE_TYPE == 2 ) || (TRACE_TYPE == 3)
+          // uart_trace(FBSB);
+#endif
+        }
+        else
+        {
+          if (attempt < 12)
+          {
+            // FB not found, some attempts remaining
+            break;
+          }
+          else
+          {
+            // FB not found, no attempt remaining
+            // Call FBSB report function (send report msg to L1A).
+#if TESTMODE
+            if (l1_config.TestMode)
+              l1s_read_fbsb(task, attempt, FALSE, FALSE, (API *)NULL, toa, pm, angle, snr);
+            else
+#endif
+              l1s_read_fbsb(task, attempt, FALSE, FALSE, (API *)NULL, toa, pm, angle, snr);
+
+            abort_flag = TRUE;
+          }
+        }
+      }
+      else // if (l1a_l1s_com.nsync_fbsb.fb_found_attempt == 0)
+      // Looking for SB
+      {
+        flag  = !(((l1s_dsp_com.dsp_db_r_ptr->a_sch[0] & 0xffff) & (1<<B_SCH_CRC)) >> B_SCH_CRC); //  //  flag = TRUE means FOUND.
+        toa   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA]   & 0xffff;  //  Unit is BIT.
+        pm    = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]   & 0xffff) >> 5;
+#if TESTMODE
+        pm_fullres = l1s_dsp_com.dsp_ndb_ptr->a_sync_demod[D_PM] & 0xffff;  // F26.6
+#endif
+        angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+        snr   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR]   & 0xffff;
+        data  = &(l1s_dsp_com.dsp_db_r_ptr->a_sch[3]);  		   // Set data block pointer (skip header).
+
+        if (flag) // SB detected
+        {
+          // SB found report SUCCESS
+
+#if L2_L3_SIMUL
+#if (DEBUG_TRACE == BUFFER_TRACE_OFFSET_NEIGH)
+          buffer_trace(4, l1s.actual_time.fn, toa,pm, l1s_dsp_com.dsp_db_r_ptr->a_sch[0] & 0xffff);
+#endif
+#endif
+
+#if (TRACE_TYPE == 3)
+          stats_samples_sb(flag, toa, pm, angle, snr);
+#endif
+
+#if (TRACE_TYPE == 2 ) || (TRACE_TYPE == 3)
+          // uart_trace(FBSB);        // display result code...
+#endif
+
+          // Call FBSB report function (send report msg to L1A).
+#if TESTMODE
+  	      if (l1_config.TestMode)
+  	        l1s_read_fbsb(task, attempt, TRUE, TRUE, data, toa, pm, angle, snr);
+  	      else
+#endif
+  	        l1s_read_fbsb(task, attempt, TRUE, TRUE, data, toa, pm, angle, snr);
+
+  	      abort_flag = TRUE;
+  	    }
+  	    else // if (flag)
+  	    {
+  	      if (attempt < (l1a_l1s_com.nsync_fbsb.fb_found_attempt + 2))
+  	      {
+  	        // SB not found, one attempt remaining
+  	        break;
+  	      }
+  	      else
+  	      {
+  	        // SB not found, no attempt remaining
+  	        // Call FBSB report function (send report msg to L1A).
+#if TESTMODE
+ 	        if (l1_config.TestMode)
+ 	          l1s_read_fbsb(task, attempt, TRUE, FALSE, (API *)NULL, toa, pm, angle, snr);
+ 	        else
+#endif
+  	          l1s_read_fbsb(task, attempt, TRUE, FALSE, (API *)NULL, toa, pm, angle, snr);
+
+  	        abort_flag = TRUE;
+  	      }
+  	    }
+      } // if(l1a_l1s_com.nsync_fbsb.fb_found_attempt == 0)
+
+
+      if(abort_flag == TRUE)
+      {
+        //    -> task is completed: set INACTIVE.
+        l1s.task_status[task].current_status = INACTIVE;
+        l1a_l1s_com.l1s_en_task[task] = TASK_DISABLED;
+
+        if (attempt < 14)
+        {
+          // FBSB search finished before last attempt:
+          // -reset DSP R/W pages, DSP tasks and TPU
+          // -flush MFTAB and reset frame count
+          // -adjust debug time
+          l1d_reset_hw(l1s.tpu_offset);
+          l1s.tpu_ctrl_reg |= CTRL_FBSB_ABORT; // set CTRL bit -> tpu_end_scenario
+          l1s_clear_mftab(l1s.mftab.frmlst);
+          l1s.frame_count = 0;
+        }
+      }
+    }
+#endif // #if ((REL99 == 1) && (FF_BHO == 1))
+  }
+
+  // Flag the use of the MCU/DSP dual page read interface.
+  // ******************************************************
+
+  // Set flag used to change the read page at the end of "l1_synch" only if not
+  // in dedicated/TCH mode (FB26,SB26,SBCNF26). Those task are not following the
+  // common principle. They use only the NDB part of the MCU/DSP interface, no
+  // page swapping is then needed.
+#if ((REL99 == 1) && (FF_BHO == 1))
+  if(((task != FB26) && (task != SB26) && (task != SBCNF26) && (task != FBNEW) && (task != FB51) && (task != FBSB)) ||
+#else
+  if(((task != FB26) && (task != SB26) && (task != SBCNF26) && (task != FBNEW) && (task != FB51)) ||
+#endif // #if ((REL99 == 1) && (FF_BHO == 1))
+     ((!fb_abort_flag) && (attempt==12)))
+    l1s_dsp_com.dsp_r_page_used = TRUE;
+}
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+#endif // MOVE_IN_INTERNAL_RAM
+
+#if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0))  // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START         // KEEP IN EXTERNAL MEM otherwise
+
+/*-------------------------------------------------------*/
+/* l1s_read_snb_dl()                                     */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: BCCHS,NP,EP,ALLC,SMSCB.                        */
+/* This function is the reading result function used for */
+/* reading a serving cell burst acquisition result in    */
+/* any mode except dedicated mode. Here is a summary of  */
+/* the execution:                                        */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low and task still enabled.  */
+/*      - Traces and debug.                              */
+/*      - Read control results and feed control algo.    */
+/*      - Read DL DATA block from MCU/DSP interface.     */
+/*  - Disactivate task.                                  */
+/*  - Flag the use of the MCU/DSP dual page read         */
+/*    interface.                                         */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   NP, Normal paging reading task.                     */
+/*   EP, Extended paging reading task.                   */
+/*   BCCHS, BCCH Serving reading task.                   */
+/*   ALLC, All serving cell CCCH reading task.           */
+/*   SMSCB, Short Message Service Cell Broadcast task.   */
+/*                                                       */
+/* "burst_id"                                            */
+/*   BURST_1, 1st burst of the task.                     */
+/*   BURST_2, 2nd burst of the task.                     */
+/*   BURST_3, 3rd burst of the task.                     */
+/*   BURST_4, 4th burst of the task.                     */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.task_param"                              */
+/*   task semaphore bit register. Used to skip the body  */
+/*   of this function if L1A has changed or is changing  */
+/*   some of the task parameters.                        */
+/*                                                       */
+/* "l1a_l1s_com.l1s_en_task"                             */
+/*   L1S task enable bit register.                       */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.task_status[task].current_status"                */
+/*   current task status. It must be reset (INACTIVE)    */
+/*   when the task is completed.                         */
+/*   -> disactivate task.                                */
+/*                                                       */
+/* "l1s_dsp_com.dsp_r_page_used"                         */
+/*   Flag used by the function which closes L1S          */
+/*   execution ("l1s_end_manager()") to know if the      */
+/*   MCU/DSP read page must be switched.                 */
+/*   -> Set to 1.                                        */
+/*                                                       */
+/* Use of MCU/DSP interface:                             */
+/* -------------------------                             */
+/* "l1s_dsp_com.dsp_ndb_ptr"                             */
+/*   pointer to the non double buffered part (NDB) of    */
+/*   the MCU/DSP interface. This part is R/W for both    */
+/*   DSP and MCU.                                        */
+/*                                                       */
+/* "l1s_dsp_com.dsp_db_r_ptr"                            */
+/*   pointer to the double buffered part (DB) of the     */
+/*   MCU/DSP interface. This pointer points to the READ  */
+/*   page.                                               */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_read_snb_dl(UWORD8 task, UWORD8 burst_id)
+{
+  UWORD32   toa;
+  UWORD32   pm;
+  UWORD32   angle;
+  UWORD32   snr;
+  BOOL      en_task;
+  BOOL      task_param;
+  UWORD16   radio_freq=0;
+  static UWORD16 pwr_level;
+#if L1_FF_MULTIBAND == 1
+  UWORD16  operative_radio_freq;
+#endif
+  
+#if (FF_L1_FAST_DECODING == 1)
+  UWORD8 skipped_bursts = 0;
+  BOOL fast_decoding_authorized = l1s_check_fast_decoding_authorized(task);
+  BOOL fast_decoded = (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_COMPLETE);
+  if (fast_decoded)
+  {
+    skipped_bursts = BURST_4 - burst_id;
+  }
+#endif /* if (FF_L1_FAST_DECODING == 1) */
+
+  /*--------------------------------------------------------*/
+  /* READ SERVING CELL RECEIVE TASK RESULTS...              */
+  /*--------------------------------------------------------*/
+  /* Rem: only a partial result is present in the mcu<-dsp  */
+  /* communication buffer. The DATA BLOCK content itself is */
+  /* in the last comm. (BURST_4)                               */
+  /*--------------------------------------------------------*/
+  // Get "enable" task flag and "synchro semaphore" for current task.
+  en_task    = l1a_l1s_com.l1s_en_task[task];
+  task_param = l1a_l1s_com.task_param[task];
+
+  if((en_task) && !(task_param))
+  // Check the task semaphore and the task enable bit. The reading
+  // task body is executed only when the task semaphore is 0 and the
+  // task is still enabled.
+  // The semaphore can be set to 1 whenever L1A makes some changes
+  // to the task parameters. The task can be disabled by L1A.
+  {
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+      trace_fct(CST_L1S_READ_SNB_DL , (UWORD32)(-1));//OMAPS00090550
+    #endif
+
+    #if (TRACE_TYPE!=0)
+      #if L1_GPRS
+         if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+         {
+            // Check task identifier...
+            if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+              trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));//OMAPS00090550
+
+            // Check burst identifier...
+            if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_burst_d & 0xffff) != burst_id)
+              trace_fct(CST_DL_BURST_DOES_NOT_CORRESPOND, (UWORD32)(-1));//OMAPS00090550
+         }
+         else // GPRS scheduler
+         {
+            // Check burst identifier...
+            if(l1ps_dsp_com.pdsp_db_r_ptr->d_burst_nb_gprs != burst_id)
+              trace_fct(CST_DL_BURST_DOES_NOT_CORRESPOND, (UWORD32)(-1));
+         }
+      #else
+        // Check task identifier...
+        if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+          trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+
+        // Check burst identifier...
+        if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_burst_d & 0xffff) != burst_id)
+          trace_fct(CST_DL_BURST_DOES_NOT_CORRESPOND,(UWORD32)( -1));
+      #endif
+    #endif
+
+    l1_check_com_mismatch(task);
+
+    // Read control results and feed control algorithms.
+    // **************************************************
+
+    // Read control information.
+    #if L1_GPRS
+      if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+      {
+        toa   =  l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA]   & 0xffff;
+        pm    = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]    & 0xffff) >> 5;
+        angle =  l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+        snr   =  l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR]   & 0xffff;
+      }
+      else
+      {
+        toa   =  l1ps_dsp_com.pdsp_db_r_ptr->a_burst_toa_gprs[0]   & 0xffff;
+        pm    = (l1ps_dsp_com.pdsp_db_r_ptr->a_burst_pm_gprs[0]    & 0xffff) >> 5;
+        angle =  l1ps_dsp_com.pdsp_db_r_ptr->a_burst_angle_gprs[0] & 0xffff;
+        snr   =  l1ps_dsp_com.pdsp_db_r_ptr->a_burst_snr_gprs[0]   & 0xffff;
+      }
+    #else
+        toa   =  l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA]   & 0xffff;
+        pm    = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]    & 0xffff) >> 5;
+        angle =  l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+        snr   =  l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR]   & 0xffff;
+    #endif
+
+    l1_check_pm_error(pm, task);
+
+    // Update AGC: Call PAGC algorithm
+    radio_freq = l1a_l1s_com.Scell_info.radio_freq;
+
+#if (L1_FF_MULTIBAND == 0)
+
+    l1a_l1s_com.Scell_IL_for_rxlev = l1ctl_pagc((UWORD8)pm, radio_freq,
+                                                &l1a_l1s_com.last_input_level[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(radio_freq);
+  l1a_l1s_com.Scell_IL_for_rxlev = l1ctl_pagc((UWORD8)pm, radio_freq,
+                                                &l1a_l1s_com.last_input_level[operative_radio_freq]);  
+
+#endif // #if (L1_FF_MULTIBAND == 0) else
+
+
+#if (FF_L1_FAST_DECODING == 1)
+    if (skipped_bursts>0)
+    {
+      l1ctl_pagc_missing_bursts(skipped_bursts);
+    }
+#endif /* if (FF_L1_FAST_DECODING == 1) */
+
+    #if L2_L3_SIMUL
+      #if (DEBUG_TRACE == BUFFER_TRACE_LNA)
+      
+        #if (L1_FF_MULTIBAND == 0)
+            buffer_trace (4, 33, radio_freq,
+                      l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].input_level,
+                      l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset].lna_off);
+        
+        #else // L1_FF_MULTIBAND = 1 below
+        
+            buffer_trace (4, 33, radio_freq,
+                      l1a_l1s_com.last_input_level[operative_radio_freq].input_level,
+                      l1a_l1s_com.last_input_level[operative_radio_freq].lna_off);
+        
+        #endif // #if (L1_FF_MULTIBAND == 0) else 
+        
+      #endif
+    #endif
+
+    #if TRACE_TYPE==3
+      stats_samples_nb(toa,pm,angle,snr,burst_id,task);
+    #endif
+
+    // Update AFC: Call AFC control function (KALMAN filter).
+    #if AFC_ALGO
+      #if TESTMODE
+        if (l1_config.afc_enable)
+      #endif
+        {
+		  #if L2_L3_SIMUL
+          #if (DEBUG_TRACE == BUFFER_TRACE_AFC_OPEN)//omaps00090550
+          WORD16 old_afc  = l1s.afc;
+          WORD16 old_count= l1s.afc_frame_count;
+          #endif
+          #endif
+
+
+
+          #if (VCXO_ALGO == 0)
+            l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+          #else
+            l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+          #endif
+
+          #if L2_L3_SIMUL
+            #if (DEBUG_TRACE == BUFFER_TRACE_AFC_OPEN)
+              buffer_trace (4,(WORD16)angle,old_count,old_afc,l1s.afc);
+            #endif
+            #if (DEBUG_TRACE == BUFFER_TRACE_TOA)
+             if (task == NP || task == EP)
+               buffer_trace(5,
+                           l1s.debug_time,
+                           0xf1,
+                           i,
+                           l1s.afc,
+                           angle );
+            #endif
+          #endif
+        }
+    #endif
+
+    //Feed TOA histogram.
+    #if (TOA_ALGO != 0)
+    if (task != SMSCB)
+   {
+      #if (TOA_ALGO == 2)
+        if(l1s.toa_var.toa_snr_mask == 0)
+      #else
+        if(l1s.toa_snr_mask == 0)
+      #endif
+      #if (RF_FAM == 2) // RF 2
+        #if (TOA_ALGO == 2)
+			if(l1a_l1s_com.Scell_IL_for_rxlev < IL_FOR_RXLEV_SNR)
+			{
+           l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa);
+			}
+			else
+			{
+				l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa);
+			}
+        #else
+			if(l1a_l1s_com.Scell_IL_for_rxlev <IL_FOR_RXLEV_SNR)
+            {
+           l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count
+#if (FF_L1_FAST_DECODING == 1)
+               , skipped_bursts
+#endif
+               );
+			}
+			else
+			{
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count
+#if (FF_L1_FAST_DECODING == 1)
+                    , skipped_bursts
+#endif
+                    );
+			}
+        #endif
+
+        #if L2_L3_SIMUL
+          #if (DEBUG_TRACE == BUFFER_TRACE_TOA )
+           if (task == NP || task == EP)
+             buffer_trace(5,
+                     l1s.debug_time,
+                     0xf0,
+                     toa,
+                     snr,
+                     l1s.tpu_offset );
+          #endif
+        #endif
+      #else // RF 2
+        #if (TOA_ALGO == 2)
+			if(l1a_l1s_com.Scell_IL_for_rxlev < IL_FOR_RXLEV_SNR)
+			{
+           l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa);
+			}
+			else
+			{
+				l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa);
+			}
+        #else
+			if(l1a_l1s_com.Scell_IL_for_rxlev <IL_FOR_RXLEV_SNR)
+            {
+           l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count
+#if (FF_L1_FAST_DECODING == 1)
+               , skipped_bursts
+#endif
+               );
+			}
+			else
+			{
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count
+#if (FF_L1_FAST_DECODING ==1)
+                    , skipped_bursts
+#endif
+                    );
+			}
+        #endif
+      #endif // RF 2
+   }
+  #else  // TOA_ALGO
+    #if L2_L3_SIMUL
+      #if (DEBUG_TRACE == BUFFER_TRACE_TOA)
+        if (task == NP || task == EP)
+             buffer_trace(5,
+                     l1s.debug_time,
+                     0xf0,
+                     toa,
+                     snr,
+                     l1s.tpu_offset );
+      #endif
+    #endif
+  #endif // TOA_ALGO
+
+    #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+      RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, l1a_l1s_com.Scell_IL_for_rxlev)
+    #endif
+    #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+      l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, l1a_l1s_com.Scell_IL_for_rxlev);
+    #endif
+    #if (BURST_PARAM_LOG_ENABLE == 1)
+      l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, l1a_l1s_com.Scell_IL_for_rxlev);
+    #endif
+
+    // compute the Data bloc Power.
+    // ******************************
+    if(burst_id == BURST_1)
+      pwr_level = 0;
+
+    // add the burst power
+    pwr_level += l1a_l1s_com.Scell_IL_for_rxlev;
+
+
+    // Read downlink DATA block from MCU/DSP interface.
+
+    if (task == NP)
+    {
+          toa_tab[burst_id] = toa;
+  }
+
+#if 0	/* FreeCalypso TCS211 reconstruction */
+// added Enhanced RSSI
+   if(l1s_dsp_com.dsp_ndb_ptr->a_cd[2] != 0xffff)
+   {
+        qual_acc_idle1[0]  += l1s_dsp_com.dsp_ndb_ptr->a_cd[2];
+        //RX Qual value reporting- total number of decoded bits
+         qual_acc_idle1[1] += 1;
+   }
+#endif
+
+#if (FF_L1_FAST_DECODING == 1)
+    /* Perform the reporting if
+        - Burst is the 4th one (whether CRC is ok or not)
+        - Fast decoding enabled and CRC already ok
+    */
+    if ( (burst_id == BURST_4) || fast_decoded )
+#else /* #if (FF_L1_FAST_DECODING == 1) */
+    if(burst_id == BURST_4)
+#endif /* FF_L1_FAST_DECODING */
+    {
+      UWORD8 i;
+
+      #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+        uart_trace(task);
+      #endif
+
+      // the data power bloc = pwr_level/4.
+#if (FF_L1_FAST_DECODING == 1)
+      /* Data power block = pwr_level / (nb of bursts)*/
+      pwr_level = pwr_level / (burst_id + 1);
+#else /* #if (FF_L1_FAST_DECODING == 1) */
+      // the data power bloc = pwr_level/4.
+      pwr_level = pwr_level >> 2;
+#endif /* #if (FF_L1_FAST_DECODING == 1) #else*/
+
+#if (FF_L1_FAST_DECODING == 1)
+      if(!fast_decoding_authorized)
+      {
+        /* When fast decoding wasn't used, burst_id is undefined (for the trace) */
+        l1a_l1s_com.last_fast_decoding = 0;
+      }
+      else
+      {
+        l1a_l1s_com.last_fast_decoding = burst_id + 1;
+      }
+#endif /* #if (FF_L1_FAST_DECODING == 1) */
+
+      // Read L3 frame block and send msg to L1A.
+      #if L1_GPRS
+        if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+          l1s_read_l3frm(pwr_level,&(l1s_dsp_com.dsp_ndb_ptr->a_cd[0]), task);
+        else
+          l1s_read_l3frm(pwr_level,&(l1ps_dsp_com.pdsp_ndb_ptr->a_dd_gprs[0][0]), task);
+      #else
+          l1s_read_l3frm(pwr_level,&(l1s_dsp_com.dsp_ndb_ptr->a_cd[0]), task);
+      #endif
+
+      #if L1_GPRS
+        if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+      #endif
+      {
+        // reset buffers and flags in NDB ...
+        // reset nerr....
+        // reset A_CD contents.......
+        l1s_dsp_com.dsp_ndb_ptr->a_cd[2]     =  0xffff;
+        for (i=0;i<12;i++)
+          l1s_dsp_com.dsp_ndb_ptr->a_cd[3+i] =  0x0000;
+      }
+
+    } // End if...
+  } // End if...
+
+  // The NP/EP task was enabled and could cancel a PTCCH burst
+  // This incomplete PTCCH decoding block cause DSP troubles and so COM/PM errors
+  // and then a recovery  => in this case restart the PTCCH from the burst 0
+#if L1_GPRS
+  if((task == NP)||(task == EP))
+    if(l1a_l1s_com.l1s_en_task[PTCCH] == TASK_ENABLED)
+      if(l1pa_l1ps_com.transfer.ptcch.activity & PTCCH_DL) // a PTCCH DL task is running
+        if((l1s.actual_time.t2 >= 13) && (l1s.actual_time.t2 <= 17))  // only if the NP/EP remove a PTCCH activity
+        {
+          // Restart PTCCH DL task from the begining (i.e BURST 0).
+          l1pa_l1ps_com.transfer.ptcch.activity ^= PTCCH_DL;  // disable PTCCH_DL activity running
+          l1pa_l1ps_com.transfer.ptcch.request_dl = TRUE;     // restart PTCCH DL from the Burst0
+        }
+#endif
+
+  // Deactivate task.
+  // ******************
+
+  // End of task -> task must become INACTIVE.
+  // Rem: some TASKS (ALLC) can be pipelined and therefore must stay active if
+  // they have already reentered the flow.
+#if (FF_L1_FAST_DECODING == 1)
+  if ( (burst_id == BURST_4) || fast_decoded )
+#else /* #if (FF_L1_FAST_DECODING == 1) */
+  if(burst_id == BURST_4)
+#endif /* #if (FF_L1_FAST_DECODING == 1) #else*/
+
+  {
+#if (FF_L1_FAST_DECODING == 1)
+    if((task == NP) || (task == NBCCHS))
+    {
+      if (l1a_apihisr_com.fast_decoding.contiguous_decoding == TRUE)
+      {
+        /* A new block has started, a new fast API IT is expected */
+        l1a_apihisr_com.fast_decoding.contiguous_decoding = FALSE;
+        l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_AWAITED;
+      }
+      else if(task == l1a_apihisr_com.fast_decoding.task)
+      {
+        /* Reset decoding status */
+        l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_NONE;
+      }
+    }  /* end if tsk == NP */
+#endif /* #if (FF_L1_FAST_DECODING == 1) */    
+    if(l1s.task_status[task].current_status == RE_ENTERED)
+      l1s.task_status[task].current_status = ACTIVE;
+    else
+      l1s.task_status[task].current_status = INACTIVE;
+#if (FF_L1_FAST_DECODING == 1)
+    if (burst_id != BURST_4)
+    {
+      /* Successful decode before the 4th burst, no other control/read activities are needed */
+      l1s_clean_mftab(task, burst_id + 3);
+      if(l1s.frame_count == (4 -burst_id))
+      {
+          l1s.frame_count = 1;
+      }
+    }
+#endif /* #if (FF_L1_FAST_DECODING == 1) */
+  }
+
+  #if (L1_DEBUG_IQ_DUMP == 1)
+    l1ddsp_read_iq_dump(task);
+  #endif
+
+  // Flag the use of the MCU/DSP dual page read interface.
+  // ******************************************************
+
+  // Set flag used to change the read page at the end of "l1_synch".
+  l1s_dsp_com.dsp_r_page_used = TRUE;
+}
+
+
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+#endif
+
+/*-------------------------------------------------------*/
+/* l1s_read_nnb()                                        */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: BCCHN.                                         */
+/* This function is the reading result function used for */
+/* reading a neighbor cell block acquisition result in   */
+/* idle mode. Here is a summary of the execution:        */
+/*                                                       */
+/*  - If SEMAPHORE(task) is low and task still enabled.  */
+/*      - Traces and debug.                              */
+/*      - Read DL DATA block from MCU/DSP interface.     */
+/*  - Disactivate task.                                  */
+/*  - Flag the use of the MCU/DSP dual page read         */
+/*    interface.                                         */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   BCCHN, BCCH Neighbor reading task.                  */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.task_param"                              */
+/*   task semaphore bit register. Used to skip the body  */
+/*   of this function if L1A has changed or is changing  */
+/*   some of the task parameters.                        */
+/*                                                       */
+/* "l1a_l1s_com.l1s_en_task"                             */
+/*   L1S task enable bit register.                       */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.task_status[task].current_status"                */
+/*   current task status. It must be reset (INACTIVE)    */
+/*   when the task is completed.                         */
+/*   -> disactivate task.                                */
+/*                                                       */
+/* "l1s_dsp_com.dsp_r_page_used"                         */
+/*   Flag used by the function which closes L1S          */
+/*   execution ("l1s_end_manager()") to know if the      */
+/*   MCU/DSP read page must be switched.                 */
+/*   -> Set to 1.                                        */
+/*                                                       */
+/* Use of MCU/DSP interface:                             */
+/* -------------------------                             */
+/* "l1s_dsp_com.dsp_ndb_ptr"                             */
+/*   pointer to the non double buffered part (NDB) of    */
+/*   the MCU/DSP interface. This part is R/W for both    */
+/*   DSP and MCU.                                        */
+/*                                                       */
+/* "l1s_dsp_com.dsp_db_r_ptr"                            */
+/*   pointer to the double buffered part (DB) of the     */
+/*   MCU/DSP interface. This pointer points to the READ  */
+/*   page.                                               */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1s_read_nnb(UWORD8 task, UWORD8 param)
+{
+  BOOL     en_task;
+  BOOL     task_param;
+  UWORD16  neigh_radio_freq;
+  UWORD16  pwr_level;
+  UWORD8   active_neigh_id;
+#if (L1_FF_MULTIBAND == 1)
+ UWORD16 operative_radio_freq;
+#endif
+
+
+  /*--------------------------------------------------------*/
+  /* READ NEIGBOR CELL RECEIVE TASK RESULTS...              */
+  /*--------------------------------------------------------*/
+  /* Rem: the full result is present in the mcu<-dsp        */
+  /* communication buffer.                                  */
+  /*--------------------------------------------------------*/
+  // Get "enable" task flag and "synchro semaphore" for current task.
+  en_task    = l1a_l1s_com.l1s_en_task[task];
+  task_param = l1a_l1s_com.task_param[task];
+
+  if((en_task) && !(task_param))
+  // Check the task semaphore and the task enable bit. The reading
+  // task body is executed only when the task semaphore is 0 and the
+  // task is still enabled.
+  // The semaphore can be set to 1 whenever L1A makes some changes
+  // to the task parameters. The task can be disabled by L1A.
+  {
+    // Traces and debug.
+    // ******************
+
+    #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+      trace_fct(CST_L1S_READ_NNB ,(UWORD32)(-1));
+    #endif
+
+
+    #if (TRACE_TYPE!=0)
+      // Check task identifier...
+      #if L1_GPRS
+        switch(l1a_l1s_com.dsp_scheduler_mode)
+        {
+          case GSM_SCHEDULER:
+          {
+            if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+              trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+          } break;
+          case GPRS_SCHEDULER:
+          {
+            if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_md & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+              trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+          } break;
+        }
+      #else
+        if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+          trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+      #endif
+    #endif
+
+    l1_check_com_mismatch(task);
+
+    #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+      uart_trace(task);
+    #endif
+
+    if(task == BCCHN)
+      active_neigh_id = l1a_l1s_com.bcchn.active_neigh_id_norm;
+    else // BCCHN_TRAN and BCCHN_TOP tasks
+      active_neigh_id = l1a_l1s_com.bcchn.active_neigh_id_top;
+
+    // the mean power level is impossible for the neighbor bloc, so the las input level is used.
+    neigh_radio_freq = l1a_l1s_com.bcchn.list[active_neigh_id].radio_freq;
+#if 1	/* FreeCalypso TCS211 reconstruction */
+    pwr_level = l1a_l1s_com.last_input_level[neigh_radio_freq].input_level;
+#elif (L1_FF_MULTIBAND == 0)
+    pwr_level = l1a_l1s_com.last_input_level[neigh_radio_freq - l1_config.std.radio_freq_index_offset].input_level;
+#else
+    operative_radio_freq = l1_multiband_radio_freq_convert_into_operative_radio_freq(neigh_radio_freq);
+    pwr_level = l1a_l1s_com.last_input_level[operative_radio_freq].input_level; 
+#endif
+
+
+
+    // Read downlink DATA block from MCU/DSP interface.
+    // *************************************************
+
+    // Read L3 frame block and send msg to L1A.
+    #if L1_GPRS
+      if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+        l1s_read_l3frm(pwr_level,&(l1s_dsp_com.dsp_ndb_ptr->a_cd[0]), task);
+      else
+        l1s_read_l3frm(pwr_level,&(l1ps_dsp_com.pdsp_ndb_ptr->a_dd_gprs[0][0]), task);
+    #else
+        l1s_read_l3frm(pwr_level,&(l1s_dsp_com.dsp_ndb_ptr->a_cd[0]), task);
+    #endif
+    // Disable the served TC from the TC bitmap.
+    if(task == BCCHN)
+      l1a_l1s_com.bcchn.list[active_neigh_id].bcch_blks_req ^=
+        ((UWORD16)(1L << l1a_l1s_com.bcchn.active_neigh_tc_norm));
+    else // BCCHN_TRAN and BCCHN_TOP tasks
+      l1a_l1s_com.bcchn.list[active_neigh_id].bcch_blks_req ^=
+        ((UWORD16)(1L << l1a_l1s_com.bcchn.active_neigh_tc_top));
+  }
+
+  // The BCCHN task was enabled and could cancel a PTCCH burst
+  // This incomplete PTCCH decoding block cause DSP troubles and so COM/PM errors
+  // and then a recovery (seen with ULYSS) => in this case restart the PTCCH from the burst 0
+  #if L1_GPRS
+    if (task == BCCHN_TRAN)
+    if(l1a_l1s_com.l1s_en_task[PTCCH] == TASK_ENABLED)
+    if(l1pa_l1ps_com.transfer.ptcch.activity & PTCCH_DL) // a PTCCH DL task is running
+    if ((l1s.actual_time.t2 >= 13) && (l1s.actual_time.t2 <= 18))  // only if the BCCHN remove a PTCCH activity
+    {
+      // Restart PTCCH DL task from the begining (i.e BURST 0).
+      l1pa_l1ps_com.transfer.ptcch.activity ^= PTCCH_DL;  // disable PTCCH_DL activity running
+      l1pa_l1ps_com.transfer.ptcch.request_dl = TRUE;     // restart PTCCH DL from the Burst0
+     }
+  #endif
+
+  // Disactivate task.
+  // ******************
+
+  // End of task -> task must become INACTIVE.
+  l1s.task_status[task].current_status = INACTIVE;
+
+  #if (L1_DEBUG_IQ_DUMP == 1)
+    l1ddsp_read_iq_dump(task);
+  #endif
+
+  // Flag the use of the MCU/DSP dual page read interface.
+  // ******************************************************
+
+  // Set flag used to change the read page at the end of "l1_synch".
+  l1s_dsp_com.dsp_r_page_used = TRUE;
+}
+
+/*-------------------------------------------------------*/
+/* l1s_read_dedic_dl()                                   */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* This function is a "COMPLEX" function used by the L1S */
+/* tasks: DDL,ADL,TCHTH,TCHTF,TCHA.                      */
+/* This function is the reading result function used for */
+/* dedicated mode. Here is a summary of the execution:   */
+/*                                                       */
+/*  - Traces and debug.                                  */
+/*  - Read control results and feed control algo.        */
+/*  - Read DL DATA block from MCU/DSP interface.         */
+/*  - Flag the use of the MCU/DSP dual page read         */
+/*    interface.                                         */
+/*                                                       */
+/* Input parameters:                                     */
+/* -----------------                                     */
+/* "task"                                                */
+/*   DDL, SDCCH DOWNLINK reading task.                   */
+/*   ADL, SACCH DOWNLINK (associated with SDCCH)reading  */
+/*   task.                                               */
+/*   TCHTH, TCH channel task when dedicated/TCH Half rate*/
+/*   TCHTF, TCH channel task when dedicated/TCH Full rate*/
+/*   TCHA, Associated channel task when dedicated/TCH.   */
+/*                                                       */
+/* "burst_id" (used only by DDL/ADL tasks).              */
+/*   BURST_1, 1st burst of the task.                     */
+/*   BURST_2, 2nd burst of the task.                     */
+/*   BURST_3, 3rd burst of the task.                     */
+/*   BURST_4, 4th burst of the task.                     */
+/*                                                       */
+/* Input parameters from globals:                        */
+/* ------------------------------                        */
+/* "l1a_l1s_com.task_param"                              */
+/*   task semaphore bit register. Used to skip the body  */
+/*   of this function if L1A has changed or is changing  */
+/*   some of the task parameters.                        */
+/*                                                       */
+/* "l1a_l1s_com.l1s_en_task"                             */
+/*   L1S task enable bit register.                       */
+/*                                                       */
+/* Modified parameters from globals:                     */
+/* ---------------------------------                     */
+/* "l1s.task_status[task].current_status"                */
+/*   current task status. It must be reset (INACTIVE)    */
+/*   when the task is completed.                         */
+/*   -> disactivate task.                                */
+/*                                                       */
+/* "l1s_dsp_com.dsp_r_page_used"                         */
+/*   Flag used by the function which closes L1S          */
+/*   execution ("l1s_end_manager()") to know if the      */
+/*   MCU/DSP read page must be switched.                 */
+/*   -> Set to 1.                                        */
+/*                                                       */
+/* Use of MCU/DSP interface:                             */
+/* -------------------------                             */
+/* "l1s_dsp_com.dsp_ndb_ptr"                             */
+/*   pointer to the non double buffered part (NDB) of    */
+/*   the MCU/DSP interface. This part is R/W for both    */
+/*   DSP and MCU.                                        */
+/*                                                       */
+/* "l1s_dsp_com.dsp_db_r_ptr"                            */
+/*   pointer to the double buffered part (DB) of the     */
+/*   MCU/DSP interface. This pointer points to the READ  */
+/*   page.                                               */
+/*                                                       */
+/* RXQUAL :                                              */
+/* 1) SDCCH : for RXQUAL_FULL and RXQUAL_SUB we accumu-  */
+/*            -late number of estimated errors (a_cd[2]) */
+/*            for ALL SACCH and SDCCH TDMA frames.       */
+/* 2) TCH   : for RXQUAL_FULL in TCH_FS_MODE and         */
+/*            TCH_24F_MODE, we accumulate number of      */
+/*            estimated errors for ALL FACCH (a_fd[2])   */
+/*            TDMA frames and ALL speech (a_dd_0[2])     */
+/*            TDMA frames.                               */
+/*            for RXQUAL_FULL in all data modes (except  */
+/*            TCH_24F_MODE, see above) we accumulate     */
+/*            number of errors for ALL FACCH (a_fd[2])   */
+/*            TDMA frames and ALL data (a_dd_0[2])       */
+/*            TDMA frames.                               */
+/*            for RXQUAL_SUB in TCH_FS_MODE and          */
+/*            TCH_24F_MODE, we only accumulate number of */
+/*            estimated errors for FACCH (a_fd[2]) TDMA  */
+/*            frames and speech (a_dd_0[2]) TDMA frames  */
+/*            at SID block boundary position.            */
+/*            for RXQUAL_SUB in all data modes (except   */
+/*            TCH_24F_MODE, see above) we only accumulate*/
+/*            number of estimated errors for FACCH       */
+/*            (a_fd[2]) TDMA frames at SID block boundary*/
+/*            position. The GSM specification 5.08 $8.4  */
+/*            is not clear about data block at SID block */
+/*            boundary position. Do we need to accumulate*/
+/*            if L2/fill frame at this SID block boundary*/
+/*            position.                                  */
+/* Note: before accumulating FACCH TDMA frame we only    */
+/*       check b_blud value, we don't mind about b_fire. */
+/*-------------------------------------------------------*/
+void l1s_read_dedic_dl(UWORD8 task, UWORD8 burst_id)
+{
+  UWORD32         toa;
+  UWORD32         pm;
+  UWORD32         angle;
+  UWORD32         snr;
+  BOOL            beacon;
+  T_INPUT_LEVEL  *IL_info_ptr;
+  UWORD16         radio_freq=0;
+
+  #if TESTMODE
+    UWORD32 pm_fullres =0;//omaps00090550
+  #endif
+
+
+  #if REL99
+  #if FF_EMR
+    T_EMR_PARAMS emr_params;    // strucutre to store pre-calculated parameter
+
+    /*--------------------------------------------------------*/
+    /* INITIALIZATION OF EMR params..                         */
+    /*--------------------------------------------------------*/
+
+    emr_params.task             = task;
+    emr_params.burst_id         = burst_id;
+    emr_params.facch_present    = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+    emr_params.facch_fire1      = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+    emr_params.a_dd_0_blud      = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+    emr_params.a_dd_0_bfi       = ((l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0])&(1<<B_BFI)) >> B_BFI; // 3rd bit tells the BAD frame
+    emr_params.a_dd_1_blud      = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+    emr_params.a_dd_1_bfi       = ((l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0])&(1<<B_BFI)) >> B_BFI; // 3rd bit tells the BAD frame
+    emr_params.b_m1             = ((l1s_dsp_com.dsp_ndb_ptr->a_data_buf_dl[1]) &(1<<B_M1)) >> B_M1; // = 1 if second half frame for data 14.4
+    emr_params.b_f48blk_dl      = ((l1s_dsp_com.dsp_ndb_ptr->d_ra_act) &(1<<B_F48BLK_DL)) >> B_F48BLK_DL; // = 1 if second half frame for data 4.8
+    emr_params.b_ce             = (((l1s_dsp_com.dsp_ndb_ptr->d_ra_conf) & (1<<B_CE)) >> B_CE);
+    emr_params.a_ntd            = (((l1s_dsp_com.dsp_ndb_ptr->a_data_buf_dl[1]) & (1<<B_FCS_OK)) >> B_FCS_OK);
+    emr_params.a_cd_fire1       = (l1s_dsp_com.dsp_ndb_ptr->a_cd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+    emr_params.sid_present_sub0 = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_SID1)) >> B_SID1; // find out whether sid1 is 0/1
+    emr_params.sid_present_sub1 = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_SID1)) >> B_SID1; // find out whether sid1 is 0/1
+    #if (AMR == 1)
+      emr_params.amr_facch_present= (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+      emr_params.amr_facch_fire1  = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+      emr_params.b_ratscch_blud   = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+      emr_params.ratscch_rxtype   = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+      emr_params.amr_rx_type_sub0 = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+      emr_params.amr_rx_type_sub1 = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+    #endif //(AMR == 1)
+  #endif //FF_EMR
+  #endif //REL99
+
+
+
+  /*--------------------------------------------------------*/
+  /* READ DEDICATED CHANNEL DL RESULTS...                   */
+  /*--------------------------------------------------------*/
+
+  // Traces and debug.
+  // ******************
+  #if (TRACE_TYPE!=0) && (TRACE_TYPE !=5)
+      trace_fct(CST_L1S_READ_DEDIC_DL, -1);
+  #endif
+
+  #if (TRACE_TYPE!=0)
+    // Check task identifier...
+    if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_d & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+      trace_fct(CST_DL_TASKS_DO_NOT_CORRESPOND, (UWORD32)(-1));
+  #endif
+
+    #if (TESTMODE)
+      // WARNING!
+      // Don't trace MCU-DSP mismatches during UL-only in TestMode. The DSP is not working
+      // in that case so it is normal. However, if tracing happens the CPU overloads
+      if (l1_config.TestMode && l1_config.tmode.rf_params.down_up & TMODE_DOWNLINK)
+    #endif
+      {
+          l1_check_com_mismatch(task);
+      }
+
+  radio_freq = l1a_l1s_com.dedic_set.radio_freq_dd;
+
+  if (radio_freq == l1a_l1s_com.Scell_info.radio_freq)
+  {
+    beacon=1;
+    IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas_beacon;
+  }
+  else
+  {
+    beacon=0;
+    IL_info_ptr = &l1a_l1s_com.Scell_info.traffic_meas;
+  }
+
+  #if (AMR == 1)
+  {
+    // RATSCCH detection
+    UWORD16 ratscch_dl_header=l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0];
+    UWORD16 b_ratscch_dl_blud = (ratscch_dl_header & (1<<B_BLUD)) >> B_BLUD;
+
+    if(b_ratscch_dl_blud==TRUE)
+    {
+      UWORD8 rx_type = (ratscch_dl_header & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+
+      if(rx_type==C_RATSCCH_GOOD)
+      {
+        // RATSCCH block detected
+        l1s_amr_update_from_ratscch(&l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0]);
+      }
+    }
+  }
+  #endif    // AMR
+
+  switch(task)
+  {
+    case DDL :
+    case ADL :
+    /*---------------------------------------------------*/
+    /* Dedicated mode: SDCCH receive task.               */
+    /* Rem: only a partial result is present in the      */
+    /* mcu<-dsp communication buffer. The BLOCK content  */
+    /* itself is in the last comm. (BURST_4)             */
+    /*---------------------------------------------------*/
+    {
+      UWORD8    i, IL_for_rxlev;
+
+      #if (TRACE_TYPE!=0)
+        // Check burst identifier...
+        if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_burst_d & 0xffff) != burst_id)
+          trace_fct(CST_DL_BURST_DOES_NOT_CORRESPOND, (UWORD32)(-1));
+      #endif
+
+      // Read control results and feed control algorithms.
+      // **************************************************
+
+      // Read control information.
+      toa   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA]   & 0xffff;
+      pm    = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]   & 0xffff) >> 5;
+      angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+      snr   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR]   & 0xffff;
+
+      l1_check_pm_error(pm, task);
+
+      // Update AGC: Call DPAGC algorithm
+      IL_for_rxlev = l1ctl_dpagc(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr); // dtx_on = 0
+
+      // Dedicated mode serving cell measurement reading.
+      #if REL99
+      #if FF_EMR
+        // only task,burst_id is valid in structure pointed by *emr_params
+        l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+      #endif
+      #else
+        l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+      #endif
+
+      #if TRACE_TYPE==3
+        stats_samples_nb(toa,pm,angle,snr,burst_id,task);
+      #endif
+
+      // Update AFC: Call AFC control function (KALMAN filter).
+      #if AFC_ALGO
+        #if TESTMODE
+          if (l1_config.afc_enable)
+        #endif
+          {
+            #if (VCXO_ALGO == 0)
+              l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+            #else
+              l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+            #endif
+          }
+      #endif
+
+      //Feed TOA histogram.
+      #if (TOA_ALGO != 0)
+          #if (TOA_ALGO == 2)
+            if(l1s.toa_var.toa_snr_mask == 0)
+          #else
+            if(l1s.toa_snr_mask == 0)
+          #endif
+          {
+            #if 1	/* FreeCalypso TCS211 reconstruction */
+              if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+              else
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+            #else
+              UWORD32 snr_temp;
+              snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+              #if (TOA_ALGO == 2)
+                l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+              #else
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+                #if (FF_L1_FAST_DECODING ==1)
+                    ,0
+                #endif
+                    );
+              #endif
+            #endif
+          }
+      #endif
+
+       #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+         RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev)
+       #endif
+       #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+         l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+       #endif
+       #if (BURST_PARAM_LOG_ENABLE == 1)
+         l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+       #endif
+      // Read downlink DATA block from MCU/DSP interface.
+      // *************************************************
+
+      if(burst_id == BURST_4)
+      {
+        #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+          uart_trace(task);
+        #endif
+
+        if(task == DDL)
+        {
+          // Read DCCH DL data block from DSP, pass it to L2.
+          l1s_read_dcch_dl(l1s_dsp_com.dsp_ndb_ptr->a_cd, task);
+        }
+        else
+        {
+          // Read L2 frame block and send msg to L1A.
+          l1s_read_sacch_dl(l1s_dsp_com.dsp_ndb_ptr->a_cd, task);
+        }
+
+        // RXQUAL_FULL/RXQUAL_SUB : number of estimated errors, this value is contained
+        // in a_cd[2] field, for every SACCH and SDDCH blocks
+        l1a_l1s_com.Smeas_dedic.qual_acc_full      += l1s_dsp_com.dsp_ndb_ptr->a_cd[2]&0xffff;
+        l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += A_D_BLEN;
+        l1a_l1s_com.Smeas_dedic.qual_acc_sub       += l1s_dsp_com.dsp_ndb_ptr->a_cd[2]&0xffff;
+        l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub  += A_D_BLEN;
+
+        // TEMPORARY : reset buffers and flags in NDB ...
+        //             reset nerr....
+        //             reset A_CD contents.......
+        l1s_dsp_com.dsp_ndb_ptr->a_cd[0]   =  (1<<B_FIRE1); // B_FIRE1=1,B_FIRE0=0,BLUD=0.
+        l1s_dsp_com.dsp_ndb_ptr->a_cd[2]   =  0xffff;
+        for (i=0; i<12  ;i++)
+          l1s_dsp_com.dsp_ndb_ptr->a_cd[3+i] =  0x0000;
+
+        // task is completed, make it INACTIVE.
+        l1s.task_status[task].current_status = INACTIVE;
+      }
+    }
+    break;
+
+    case TCHTH:
+    /*---------------------------------------------------*/
+    /* Dedicated mode: TCHTH receive task.               */
+    /*                 HALF RATE                         */
+    /*---------------------------------------------------*/
+    {
+      UWORD32   b_blud;
+      UWORD8    channel_mode;
+      //OMAPS00090550 UWORD8    channel_type;
+      UWORD8    subchannel;
+      UWORD32   l1_mode;
+      UWORD32   fn_mod_104;
+      UWORD32   fn_mod_52;
+      //OMAPS00090550 UWORD32   fn_report_mod13_mod4;
+      UWORD32   normalised_fn_report_mod13_mod4;
+      UWORD32   normalised_fn_report_mod26;
+      UWORD8    IL_for_rxlev = 0; //omaps00090550
+      #if (AMR == 1)
+        UWORD8    rx_type;
+        UWORD8    b_ratscch_blud,b_facch_blud;
+        UWORD8    voco_type;
+        BOOL      facch_present = FALSE;
+        #if REL99
+        #if FF_EMR
+          emr_params.amr_facch_present = FALSE;
+          emr_params.amr_facch_fire1   = FALSE;
+        #endif
+		#endif
+      #endif
+
+      // Read control results and feed control algorithms.
+      // **************************************************
+
+      // Read control information.
+      toa   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA]   & 0xffff;
+      pm    = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]   & 0xffff) >> 5;
+      angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+      snr   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR]   & 0xffff;
+
+      l1_check_pm_error(pm, task);
+
+      #if TRACE_TYPE==3
+        stats_samples_tch(toa,pm,angle,snr);
+      #endif
+      #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+        uart_trace(TCHTH);
+      #endif
+
+      // Update AFC: Call AFC control function (KALMAN filter).
+
+      #if AFC_ALGO
+        #if TESTMODE
+          if (l1_config.afc_enable)
+        #endif
+          {
+            #if (VCXO_ALGO == 0)
+              l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+            #else
+              l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+            #endif
+          }
+      #endif
+
+      // Increment number of burst not sent due to DTX.
+      if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_u & 0xffff) == TCH_DTX_UL)
+      {
+        l1a_l1s_com.Smeas_dedic.dtx_used++;
+        l1s.dtx_ul_on = TRUE;
+      }
+      else
+      {
+        l1s.dtx_ul_on = FALSE;
+      }
+
+      // Check SID frame subset...
+      channel_mode = l1a_l1s_com.dedic_set.aset->achan_ptr->mode;
+//OMAPS00090550      channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;
+      subchannel   = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->subchannel;
+      fn_mod_104   = l1s.actual_time.fn % 104;
+      fn_mod_52    = l1s.actual_time.fn % 52;
+
+    #if REL99
+    #if FF_EMR
+      // Compute FN in reporting period % 13 % 4 = (((FN-subchannel)+ 13) %13) %4
+      normalised_fn_report_mod13_mod4 = ((l1s.actual_time.fn - subchannel + 13)  % 13) % 4;
+
+      // Compute FN in reporting period % 26 independently of the considered subchannel.
+      normalised_fn_report_mod26 = (l1s.actual_time.fn - subchannel + 26)  % 26;
+
+      emr_params.channel_mode                    = channel_mode;
+      emr_params.subchannel                      = subchannel;
+      emr_params.normalised_fn_mod13_mod4 = normalised_fn_report_mod13_mod4;
+    #endif //FF_EMR
+    #endif //REL99
+
+
+    #if (AMR == 1)
+      // Check if we're in AMR DTX mode
+      if(channel_mode==TCH_AHS_MODE &&
+         ( (((l1s.actual_time.fn_mod13 % 4)==3) && (subchannel==0)) ||    // AHS0: block is decoded on DSP side at fn%13%4=2
+           (((l1s.actual_time.fn_mod13 % 4)==0) && (subchannel==1)) ))    // AHS1: block is decoded on DSP side at fn%13%4=3
+      {
+        if(subchannel==0)
+        {
+          b_blud  = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+          rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+        }
+        else
+        {
+          b_blud  = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+          rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+        }
+        b_ratscch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+        b_facch_blud   = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+
+        // Check if AMR DTX mode is on
+        if((((rx_type==SID_FIRST) || (rx_type==SID_UPDATE) || (rx_type==SID_BAD)) && b_blud==TRUE) ||
+           (rx_type==AMR_NO_DATA && b_blud==FALSE))
+		{
+          l1s.dtx_amr_dl_on=TRUE;
+		}
+        else if(b_ratscch_blud==FALSE && b_facch_blud==FALSE)
+		{
+          l1s.dtx_amr_dl_on=FALSE;
+		}
+      }
+    #endif
+
+    #if (AMR == 1)
+      if (channel_mode != TCH_AHS_MODE)
+      {
+      // This AGC and TOA update isn't applied to the adaptative half rate mode.
+      if(((channel_mode == TCH_HS_MODE) && (subchannel == 0) &&
+          (fn_mod_52 > 0)  && (fn_mod_52 <= 7))  ||
+         ((channel_mode == TCH_HS_MODE) && (subchannel == 1) &&
+          (fn_mod_52 > 14)  && (fn_mod_52 <= 21))  ||
+         ((channel_mode != TCH_HS_MODE)  &&
+         (subchannel == 0) && (fn_mod_104 > 56) && (fn_mod_104 <= 76)) ||
+         ((channel_mode != TCH_HS_MODE)  &&
+         (subchannel == 1) && (fn_mod_104 > 66) && (fn_mod_104 <= 86)))
+    #else
+      if(((channel_mode == TCH_HS_MODE) && (subchannel == 0) &&
+          (fn_mod_52 > 0)  && (fn_mod_52 <= 7))  ||
+         ((channel_mode == TCH_HS_MODE) && (subchannel == 1) &&
+          (fn_mod_52 > 14)  && (fn_mod_52 <= 21))  ||
+         ((channel_mode != TCH_HS_MODE) && (subchannel == 0) &&
+          (fn_mod_104 > 56) && (fn_mod_104 <= 76)) ||
+         ((channel_mode != TCH_HS_MODE) && (subchannel == 1) &&
+          (fn_mod_104 > 66) && (fn_mod_104 <= 86)))
+    #endif
+      // Current results are from the TDMA frame subset always received (GSM05.08, $8.3).
+      // -> pwr meas. must be used for SUB set result.
+      // -> TOA filtering can be fed with SNR/TOA.
+      // WARNING: TCH/H in signalling only is here processed like TCH/H data. GSM spec is
+      // ======== unclear !!!!!!!!!!!!!!!1
+      {
+        // Update AGC: Call DPAGC algorithm
+        IL_for_rxlev = l1ctl_dpagc(1,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+
+        // Dedicated mode serving cell measurement reading, indicate "SUB".
+        #if REL99
+        #if FF_EMR
+          l1s_read_dedic_scell_meas(IL_for_rxlev, 1,&emr_params);
+        #endif
+        #else
+          l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+        #endif
+
+        //Feed TOA histogram.
+        #if (TOA_ALGO != 0)
+          // When in 1/2 rate data, we are working on 14 SID frames (instead
+          // of 12 otherwise), so we need to increment length of the histogram
+          // filling period from 36 to 42.
+          if (channel_mode != TCH_HS_MODE)
+            l1_mode=DEDIC_MODE_HALF_DATA;
+          else
+            l1_mode=l1a_l1s_com.mode;
+
+          #if (TOA_ALGO == 2)
+            if(l1s.toa_var.toa_snr_mask == 0)
+          #else
+            if(l1s.toa_snr_mask == 0)
+          #endif
+          {
+            #if 1	/* FreeCalypso TCS211 reconstruction */
+              if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1_mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+              else
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1_mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+            #else
+              UWORD32 snr_temp;
+              snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+              #if (TOA_ALGO == 2)
+                l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1_mode, snr_temp, toa);
+              #else
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1_mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+                #if (FF_L1_FAST_DECODING == 1)
+                    ,0
+                #endif
+                    );
+              #endif
+            #endif
+          }
+        #endif
+      } // if(((channel_mode == TCH_HS_MODE) && (subchannel == 0) &&
+      else
+      {
+        // Update AGC: Call DPAGC algorithm
+        IL_for_rxlev = l1ctl_dpagc(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr);
+
+        // Dedicated mode serving cell measurement reading, full set only.
+        #if REL99
+        #if FF_EMR
+          l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+        #endif
+        #else
+          l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+        #endif
+      }
+
+    #if (AMR == 1)
+      } // if (channel_mode != TCH_AHS_MODE)
+    #endif
+
+      #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+        RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev)
+      #endif
+      #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+        l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+      #endif
+      #if (BURST_PARAM_LOG_ENABLE == 1)
+        l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+      #endif
+
+      // Read downlink DATA block from MCU/DSP interface.
+      // *************************************************
+
+      // Compute FN % 13 % 4
+      //OMAPS00090550 fn_report_mod13_mod4 = (l1s.actual_time.fn_mod13) % 4;
+      // Compute normalised FN % 13 %4 = (((FN-subchannel)+ 13) %13) %4
+      normalised_fn_report_mod13_mod4 = ((l1s.actual_time.fn - subchannel + 13)  % 13) % 4;
+      // Compute normalised FN %26 = ((FN - subchannel)+ 26) %26
+      normalised_fn_report_mod26 = (l1s.actual_time.fn - subchannel + 26)  % 26;
+
+      if((normalised_fn_report_mod26 == 16)||
+         (normalised_fn_report_mod26 == 24)||
+         (normalised_fn_report_mod26 == 7))
+        // It is time to get FACCH/H data block.
+      {
+        // FACCH: Check A_FD information block.
+        //-------------------------------------
+
+      UWORD8  temp;
+        b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+        #if ((REL99) && (AMR == 1))
+        #if FF_EMR
+          emr_params.amr_facch_fire1 = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+        #endif
+        #endif
+
+        if(b_blud == TRUE)
+        {
+          // Read FACCH DL data block from DSP, pass it to L2.
+      #if ( FF_REPEATED_DL_FACCH == 1 )
+               #if (TRACE_TYPE == 1 || TRACE_TYPE == 4)
+                trace_info.facch_dl_count_all++;
+               #endif
+                  // if the current block is a repetition reports NULL to L2 otherwise reports the current block
+                  l1s_read_dcch_dl((API*)l1s_repeated_facch_check(l1s_dsp_com.dsp_ndb_ptr->a_fd), task);
+       #else
+                  l1s_read_dcch_dl(l1s_dsp_com.dsp_ndb_ptr->a_fd, task);
+       #endif
+
+        #if (AMR == 1)
+          if (channel_mode != TCH_AHS_MODE)
+          {
+        #endif
+
+          // RXQUAL_SUB : In case of data taffic channels, accumulate number of
+          // estimated errors, this value is contained in a_fd[2] field, only
+          // for SID TDMA frames received as FACCH frames. (GSM 5.08 $8.4)
+          if (((fn_mod_104==59) &&  (channel_mode==TCH_HS_MODE)     && (subchannel==0))    ||
+              ((fn_mod_104==73) &&  (channel_mode==TCH_HS_MODE)     && (subchannel==1))    ||
+              ((fn_mod_104==76) && ((channel_mode==TCH_48H_MODE)||
+                                    (channel_mode==TCH_24H_MODE))   && (subchannel==0))    ||
+              ((fn_mod_104==86) && ((channel_mode==TCH_48H_MODE)||
+                                    (channel_mode==TCH_24H_MODE))   && (subchannel==1)))
+          // last SID TDMA frame received as FACCH frames.
+          {
+             l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_fd[2] & 0xffff;
+             l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_F_D_BLEN;
+          }
+
+        #if (AMR == 1)
+          } // if (channel_mode != TCH_AHS_MODE)
+          else
+          {
+            // Indicate to AMR specific processing that burst was a FACCH
+            facch_present = TRUE;
+            #if ((REL99) && (AMR == 1))
+            #if FF_EMR
+              emr_params.amr_facch_present = facch_present;
+            #endif
+            #endif
+
+
+            // Update AGC: Call DPAGC algorithm
+            IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+
+            // Dedicated mode serving cell measurement reading, indicate "FULL".
+            #if REL99
+            #if FF_EMR
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+            #endif
+            #else
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+            #endif
+          }
+        #endif
+
+          // RXQUAL_FULL : accumulate number of estimated errors, this value is
+          // contained in a_fd[2] field, for each TCHT block.
+          // The same for AMR
+	#if (AMR == 1)
+          // in AMR, l1s.dtx_amr_dl_on is FALSE if DTX mode is off
+          // in non AMR TCH, l1s.dtx_amr_dl_on is always FALSE
+          // In AMR DTX, DSP patch sometimes reports FACCH blocks which ARE NOT FACCH blocks
+          // therefore they shouldn't be taken into account in the RXQUALL_FULL computation
+          if(l1s.dtx_amr_dl_on==FALSE)
+	#endif
+		  {
+          l1a_l1s_com.Smeas_dedic.qual_acc_full      += l1s_dsp_com.dsp_ndb_ptr->a_fd[2] & 0xffff;
+          l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_F_D_BLEN;
+		  }
+
+          // Reset A_FD header.
+          // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+          l1s_dsp_com.dsp_ndb_ptr->a_fd[0] = (1<<B_FIRE1);
+          l1s_dsp_com.dsp_ndb_ptr->a_fd[2] = 0xffff;
+
+          // Rem: when FACCH is received, we must reset A_DD_0 header also.
+          // Reset A_DD_0 header in NDB.
+#if (AMR == 1)
+          if ((channel_mode==TCH_AHS_MODE) && (subchannel==0))
+          {
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] &= (API)(RX_TYPE_MASK);
+          }
+          else
+#endif
+          {
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+          }
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+
+          // Rem: when FACCH is received, we must reset A_DD_1 header also.
+          // Reset A_DD_0 header in NDB.
+#if (AMR == 1)
+          if ((channel_mode==TCH_AHS_MODE) && (subchannel==1))
+          {
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] &= (API)(RX_TYPE_MASK);
+          }
+          else
+#endif
+          {
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] = 0;
+          }
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+
+        } // if(b_blud == TRUE)
+
+        else
+        // No FACCH received at FACCH boundary frame. Nevertheless, need to read dummy
+        // FACCH DL data block.
+        {
+          // Dummy: Read FACCH DL data block from DSP, pass it to L2.
+          // Rem: this is an upper layer requirement to call this
+          // function at every FACCH DL boundary.
+          l1s_read_dcch_dl(NULL, task);
+        }
+      } // if((normalised_fn_report_mod26 == 16)|| ...
+
+      // else we are not at FACCH boundary frame
+      // We must check for the presence of a TCH/H block (even if it does fall on a FACCH boundary)
+      // We use the b_blud bit to confirm presence of TCH/H (or FACCH)
+      if((normalised_fn_report_mod13_mod4 == 3) && (channel_mode==TCH_HS_MODE))
+      // It is time to get TCH/HS data block.
+      {
+        #if TRACE_TYPE==3
+          if (l1_stats.type == PLAY_UL       &&
+             (channel_mode  == TCH_HS_MODE))
+            play_trace();
+        #endif
+
+        // Check A_DD_0 information block only if no FACCH.
+        if (subchannel==0)
+           b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+        else
+           b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+
+        if(b_blud == TRUE)
+        {
+          if (subchannel==0)
+          {
+            // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+            // estimated errors, this value is contained in a_dd_0[2] field, only
+            // for SID TDMA frames. (GSM 5.08 $8.4)
+            if (fn_mod_104==59)
+            {
+               l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+               l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_HS_BLEN;
+            }
+            // RXQUAL_FULL : accumulate number of estimated errors, this value is
+            // contained in a_dd_0[2] field, for each TCHT block.
+            l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+            // Reset A_DD_0 header in NDB.
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+          } // if (subchannel==0)
+          else
+          {
+            // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+            // estimated errors, this value is contained in a_dd_1[2] field, only
+            // for SID TDMA frames. (GSM 5.08 $8.4)
+            if (fn_mod_104==73)
+            {
+               l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+               l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_HS_BLEN;
+            }
+            l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+            // Reset A_DD_1 header in NDB.
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] = 0;
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+          }
+          l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_HS_BLEN;
+        } // if(b_blud == TRUE)
+      } // if((normalised_fn_report_mod13_mod4 == 3) && (channel_mode==TCH_HS_MODE))
+
+    #if (AMR == 1)
+      if(((normalised_fn_report_mod26 == 20)  ||
+          (normalised_fn_report_mod26 == 3)   ||
+          (normalised_fn_report_mod26 == 11)) &&
+         ((channel_mode == TCH_48H_MODE)      ||
+          (channel_mode == TCH_24H_MODE)))
+    #else
+      if(((normalised_fn_report_mod26 == 20)  ||
+          (normalised_fn_report_mod26 == 3)   ||
+        (normalised_fn_report_mod26 == 11)) && (channel_mode!=TCH_HS_MODE))
+    #endif
+      // It is time to get TCH/H4.8 or TCH/H2.4 data block.
+      {
+        // Check A_DD_0 information block only if no FACCH.
+        if (subchannel==0)
+           b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+        else
+           b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+
+        if(b_blud == TRUE)
+        {
+          if (subchannel==0)
+          {
+            // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+            // estimated errors, this value is contained in a_dd_0[2] field, only
+            // for SID TDMA frames. (GSM 5.08 $8.4)
+            if (fn_mod_104==76)
+            {
+               l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+               l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_F_D_BLEN;
+            }
+            // RXQUAL_FULL : accumulate number of estimated errors, this value is
+            // contained in a_dd_0[2] field, for each TCHT block.
+            l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+
+            // Reset A_DD_0 header in NDB.
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+          }
+          else
+          {
+            // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+            // estimated errors, this value is contained in a_dd_1[2] field, only
+            // for SID TDMA frames. (GSM 5.08 $8.4)
+            if (fn_mod_104==86)
+            {
+               l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+               l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_F_D_BLEN;
+            }
+            l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+            // Reset A_DD_1 header in NDB.
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] = 0;
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+          }
+          // RXQUAL_FULL : accumulate number of estimated errors, this value is
+          // contained in a_dd_1[2] field, for each TCHT block.
+          l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_F_D_BLEN;
+
+          // WARNING: sequence number is not implemented in DATA half rate
+          // TO BE DEFINED......
+        } // if(b_blud == TRUE)
+      } // if(((normalised_fn_report_mod26 == 20)  || ...
+    #if (AMR == 1)
+      if ((channel_mode == TCH_AHS_MODE) && (facch_present == FALSE))
+      {
+        // the channel is a TCH/AHS and it's time to receive a new block
+        if (subchannel == 0)
+        {
+          // Load the bit to check if the block is valid
+          b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+        }
+        else // subchannel 1
+        {
+          // Load the bit to check if the block is valid
+          b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & (1<<B_BLUD)) >> B_BLUD;
+        }
+
+        b_ratscch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+
+        // All frames except NO_DATA (b_blud = FALSE) and FACCH, i.e AMR speech/SID block or a RATSCCH block
+        if(b_ratscch_blud==TRUE)
+        {
+          // RXQUAL_FULL : accumulate number of estimated errors, this value is
+          // contained in a_ratscch_dl[2] field, for each TCHT block.
+          l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[2] & 0xffff;
+
+          // Reset the A_RATSCCH_DL header in NDB.
+          l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] = 0;
+          l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[2] = 0xffff;
+
+          // RXQUAL_FULL : the number of bits examined for errors on serving cell depends on
+          // the block received.
+          l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += RATSCCH_BLEN;
+
+          IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+            #if REL99
+            #if FF_EMR
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+            #endif
+            #else
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+            #endif
+        }
+        else if(b_blud==TRUE)
+        {
+          if (subchannel == 0)
+          {
+            // Load the type of the block received
+            rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+
+            // Load the type of vocoder currently used
+            voco_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & VOCODER_TYPE_MASK) >> VOCODER_TYPE_SHIFT;
+
+          #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+            Trace_dedic_tch_block_stat(rx_type, l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2], voco_type);
+          #endif
+
+            // RXQUAL_SUB : In case of adaptative traffic channel, accumulate number of estimated errors
+            // is contained in the a_dd_0[2] value but the accumulation is made with SID_UPDATE frame only.
+           if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+
+            {
+              l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+              l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += SID_UPDATE_BLEN;
+            }
+
+            // RXQUAL_FULL : accumulate number of estimated errors, this value is
+            // contained in a_dd_0[2] field, for each TCHT block.
+              l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+
+
+
+
+
+
+
+
+
+            // Reset A_DD_0 header in NDB.
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] &= (API)(RX_TYPE_MASK);
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+          }
+          else // subchannel ==1
+          {
+            // Load the type of the block received
+            rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+
+            // Load the type of vocoder currently used
+            voco_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] & VOCODER_TYPE_MASK) >> VOCODER_TYPE_SHIFT;
+
+          #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+            Trace_dedic_tch_block_stat(rx_type, l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2], voco_type);
+          #endif
+
+            // RXQUAL_SUB : In case of adaptative traffic channel, accumulate number of estimated errors
+            // is contained in the a_dd_1[2]  value but the accumulation is made with SID_UPDATE block only.
+			if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+
+            {
+              l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+              l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += SID_UPDATE_BLEN;
+            }
+
+            // RXQUAL_FULL : accumulate number of estimated errors, this value is
+            // contained in a_dd_1[2] field, for each TCHT block.
+              l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+
+            // Reset A_DD_1 header in NDB.
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] &= (API)(RX_TYPE_MASK);
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+          } // subchannel == 1
+
+
+
+
+
+          // RXQUAL_FULL : the number of bits examined for errors on serving cell depends on
+          // the block received.
+if((rx_type==SPEECH_GOOD) || (rx_type==SPEECH_DEGRADED) || (rx_type==SPEECH_BAD))
+          {
+            // The block length depens on the vocoder type
+            switch (voco_type)
+            {
+              case AMR_CHANNEL_7_95:
+              {
+                // TCH-AHS 7.95
+                l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_7_95_BLEN;
+              }
+              break;
+              case AMR_CHANNEL_7_4:
+              {
+                // TCH-AHS 7.4
+                l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_7_4_BLEN;
+              }
+              break;
+              case AMR_CHANNEL_6_7:
+              {
+                // TCH-AHS 6.7
+                l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_6_7_BLEN;
+              }
+              break;
+              case AMR_CHANNEL_5_9:
+              {
+                // TCH-AHS 5.9
+                l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_5_9_BLEN;
+              }
+              break;
+              case AMR_CHANNEL_5_15:
+              {
+                // TCH-AHS 5.15
+                l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_5_15_BLEN;
+              }
+              break;
+              case AMR_CHANNEL_4_75:
+              {
+                // TCH-AHS 4.75
+               l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_4_75_BLEN;
+              }
+              break;
+            } // switch
+          } // if ( (rx_type == SPEECH_GOOD) || ...
+          else
+			if((rx_type == SID_UPDATE) || (rx_type == SID_BAD))
+
+          {
+            // the block is a SID UPDATE
+            l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += SID_UPDATE_BLEN;
+          }
+
+
+
+
+
+
+
+          // AGC, TOA update for AMR... SUB FIFO only for SID_UPDATE frame
+          if((rx_type == SID_UPDATE) || (rx_type == SID_BAD))
+
+          {
+            IL_for_rxlev = l1ctl_dpagc_amr(1,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+            #if REL99
+            #if FF_EMR
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+            #endif
+            #else
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+            #endif
+
+          #if (TOA_ALGO != 0)
+            #if (TOA_ALGO == 2)
+              if(l1s.toa_var.toa_snr_mask == 0)
+            #else
+              if(l1s.toa_snr_mask == 0)
+            #endif
+            {
+              #if 1	/* FreeCalypso TCS211 reconstruction */
+                if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+                  l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+                else
+                  l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+              #else
+                UWORD32 snr_temp;
+                snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+                #if (TOA_ALGO == 2)
+                  l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+                #else
+                  l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+                  #if (FF_L1_FAST_DECODING == 1)
+                      ,0
+                  #endif
+                      );
+                #endif
+              #endif
+            }
+          #endif
+          }
+          else
+          {
+            IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+            #if REL99
+            #if FF_EMR
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+            #endif
+            #else
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+            #endif
+          }
+        } // if (b_blud == TRUE)
+        // simple burst or NO_DATA frame
+        else
+        {
+          // NO_DATA is considered a bad frame
+          if (normalised_fn_report_mod13_mod4 == 3)
+          {
+            l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AHS_4_75_BLEN;
+            if (subchannel == 0)
+            {
+              l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+
+            #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+              Trace_dedic_tch_block_stat(AMR_NO_DATA, l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2], 0);
+            #endif
+
+              // Reset A_DD_0 header in NDB.
+              l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] &= (API)(RX_TYPE_MASK);
+              l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+            }
+            else
+            {
+              l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] & 0xffff;
+
+            #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+              Trace_dedic_tch_block_stat(AMR_NO_DATA, l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2], 0);
+            #endif
+
+              // Reset A_DD_0 header in NDB.
+              l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] &= (API)(RX_TYPE_MASK);
+              l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+            }
+          }
+          // Update AGC: Call DPAGC AMR algorithm in order to fill the G_all buffer
+          IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr);
+
+          // Dedicated mode serving cell measurement reading, full set only.
+          #if REL99
+          #if FF_EMR
+            l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+          #endif
+          #else
+            l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+          #endif
+        }
+      } // if ((channel_mode == TCH_AHS_MODE) && (facch_present == FALSE))
+    #endif
+
+      // task is completed, make it INACTIVE.
+      l1s.task_status[task].current_status = INACTIVE;
+    }
+    break;
+
+    case TCHTF:
+    /*---------------------------------------------------*/
+    /* Dedicated mode: TCHTF receive task.               */
+    /*                 FULL RATE                         */
+    /*---------------------------------------------------*/
+    {
+      UWORD8   IL_for_rxlev = 0; //omaps00090550
+      UWORD32  b_blud;
+
+      UWORD8   channel_mode;
+      //OMAPS00090550 UWORD8   channel_type;
+      UWORD32  fn_mod_104;
+      //OMAPS00090550 UWORD32  fn_mod_52;
+      UWORD32  fn_report_mod13_mod4;
+      #if (AMR == 1)
+        UWORD8   rx_type;
+        UWORD8   b_ratscch_blud,b_facch_blud;
+        BOOL     facch_present = FALSE;
+      #endif
+
+      #if TESTMODE
+        xSignalHeaderRec *msg;
+      #endif
+
+      // Read control results and feed control algorithms.
+      // **************************************************
+
+      // Read control information.
+      toa   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA]   & 0xffff;
+      pm    = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]   & 0xffff) >> 5;
+      angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+      snr   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR]   & 0xffff;
+
+      l1_check_pm_error(pm, task);
+
+      #if TRACE_TYPE==3
+        stats_samples_tch(toa,pm,angle,snr);
+      #endif
+
+      #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+        uart_trace(TCHTF);
+      #endif
+
+      // Update AFC: Call AFC control function (KALMAN filter).
+      #if AFC_ALGO
+        #if TESTMODE
+          if (l1_config.afc_enable)
+        #endif
+          {
+            #if (VCXO_ALGO == 0)
+              l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+            #else
+              l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+            #endif
+          }
+      #endif
+
+      // Check SID frame subset...
+      channel_mode = l1a_l1s_com.dedic_set.aset->achan_ptr->mode;
+      //OMAPS00090550 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;
+      fn_mod_104   = l1s.actual_time.fn % 104;
+      //OMAPS00090550 fn_mod_52    = l1s.actual_time.fn % 52;
+
+	  #if (AMR == 1)
+      // Check if we're in AMR DTX mode
+      if(channel_mode==TCH_AFS_MODE && (l1s.actual_time.fn_mod13 % 4)==0)    // AFS: block is decoded on DSP side at fn%13%4=3
+      {
+        b_blud         = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+        rx_type        = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+        b_ratscch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+        b_facch_blud   = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+
+        // Check if AMR DTX mode is on
+        if((((rx_type==SID_FIRST) || (rx_type==SID_UPDATE) || (rx_type==SID_BAD)) && b_blud==TRUE) ||
+           (rx_type==AMR_NO_DATA && b_blud==FALSE))
+		{
+          l1s.dtx_amr_dl_on=TRUE;
+		}
+        else if(b_ratscch_blud==FALSE && b_facch_blud==FALSE)
+		{
+          l1s.dtx_amr_dl_on=FALSE;
+		}
+      }
+	 #endif
+
+      #if REL99
+      #if FF_EMR
+        emr_params.channel_mode = channel_mode;
+//        emr_params.fn_mod13_mod4 = l1s.actual_time.fn_mod13_mod4;
+        #if (AMR == 1)
+          emr_params.amr_facch_present = FALSE;
+          emr_params.amr_facch_fire1 = FALSE;
+        #endif
+       #endif
+      #endif
+
+      // Increment number of burst not sent due to DTX.
+      if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_u & 0xffff) == TCH_DTX_UL)
+      {
+        l1a_l1s_com.Smeas_dedic.dtx_used++;
+        l1s.dtx_ul_on = TRUE;
+      }
+      else
+      {
+        // Some bursts are always sent in DTX mode. d_task_u does not give DTX_UL
+        // so we must keep previous value of dtx_on
+        if (! ((fn_mod_104 > 52) && (fn_mod_104 <= 60)) )
+          l1s.dtx_ul_on = FALSE;
+      }
+
+    #if FF_L1_IT_DSP_DTX
+      // Currently used for TCH-AFS only
+      if (l1s.actual_time.fn_mod13_mod4 == 0) // FN%13 = 4, 8 and 12 (no TCH/F Read on FN%13=0)
+      {
+        // Latch TX activity status if DTX allowed
+        if ((l1a_l1s_com.dedic_set.aset->dtx_allowed == FALSE) ||                // No DTX allowed
+            (l1s_dsp_com.dsp_ndb_ptr->d_fast_dtx_enc_data) ||                    // DTX allowed but not used
+            (l1a_apihisr_com.dtx.fast_dtx_ready == FALSE))                       // Fast DTX status is invalid
+          l1a_apihisr_com.dtx.tx_active = TRUE;
+        else
+          l1a_apihisr_com.dtx.tx_active = FALSE;
+      }
+    #endif
+
+    #if (AMR == 1)
+      if (channel_mode != TCH_AFS_MODE)
+      {
+      // This AGC and TOA update isn't applied to the adaptative full rate mode
+    #endif
+
+      if((fn_mod_104 > 52) && (fn_mod_104 <= 60))
+      // Current results are from the TDMA frame subset always received (GSM05.08, $8.3).
+      // -> pwr meas. must be used for SUB set result.
+      // -> TOA filtering can be fed with SNR/TOA.
+      // This DTX is only applied to the mode EFR, FR and data.
+      {
+        // Update AGC: Call DPAGC algorithm
+        IL_for_rxlev = l1ctl_dpagc(1,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+
+        // Dedicated mode serving cell measurement reading, indicate "SUB".
+        #if REL99
+        #if FF_EMR
+          l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+        #endif
+        #else
+          l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+        #endif
+
+        //Feed TOA histogram.
+        #if (TOA_ALGO != 0)
+          #if (TOA_ALGO == 2)
+            if(l1s.toa_var.toa_snr_mask == 0)
+          #else
+            if(l1s.toa_snr_mask == 0)
+          #endif
+          {
+            #if 1	/* FreeCalypso TCS211 reconstruction */
+              if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+              else
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+            #else
+              UWORD32 snr_temp;
+              snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+              #if (TOA_ALGO == 2)
+                l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+              #else
+                l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+                #if (FF_L1_FAST_DECODING == 1)
+                    ,0
+                #endif
+                    );
+              #endif
+            #endif
+          }
+        #endif
+      }
+      else
+      {
+        // Update AGC: Call DPAGC algorithm
+        IL_for_rxlev = l1ctl_dpagc(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr);
+
+        // Dedicated mode serving cell measurement reading, full set only.
+        #if REL99
+        #if FF_EMR
+          l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+        #endif
+        #else
+          l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+        #endif
+      }
+    #if (AMR == 1)
+      } // if (channel_mode != TCH_AFS_MODE)
+    #endif
+
+      #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+        RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev)
+      #endif
+      #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+        l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+      #endif
+      #if (BURST_PARAM_LOG_ENABLE == 1)
+        l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+      #endif
+
+      // Read downlink DATA block from MCU/DSP interface.
+      // *************************************************
+
+      // Compute FN in reporting period % 13 % 4.
+      fn_report_mod13_mod4 = (l1s.actual_time.fn_mod13) % 4;
+
+      if(fn_report_mod13_mod4 == 0)
+      // It is time to get FACCH/F or TCH/F2.4 or TCH/(E)FS data block.
+      {
+        UWORD8 temp;
+        #if TRACE_TYPE==3
+          if (l1_stats.type == PLAY_UL &&
+             (channel_mode == TCH_FS_MODE || channel_mode == TCH_24F_MODE
+              || channel_mode == TCH_EFR_MODE))
+            play_trace();
+        #endif
+
+        // FACCH: Check A_FD information block.
+        //-------------------------------------
+
+        b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_BLUD)) >> B_BLUD;
+        #if ((REL99) && (AMR == 1))
+        #if FF_EMR
+          emr_params.amr_facch_fire1 = (l1s_dsp_com.dsp_ndb_ptr->a_fd[0] & (1<<B_FIRE1)) >> B_FIRE1;
+        #endif
+		#endif
+
+        if(b_blud == TRUE)
+        {
+          // Read FACCH DL data block from DSP, pass it to L2.
+        #if ( FF_REPEATED_DL_FACCH == 1 )
+        #if (TRACE_TYPE == 1 || TRACE_TYPE == 4)
+             trace_info.facch_dl_count_all++;
+         #endif
+          /* if the current block is a repetition reports NULL to L2 otherwise reports the current block */
+       l1s_read_dcch_dl((API*)l1s_repeated_facch_check(l1s_dsp_com.dsp_ndb_ptr->a_fd), task);
+       #else
+       /* UWORD8 error_flag =*/ l1s_read_dcch_dl(l1s_dsp_com.dsp_ndb_ptr->a_fd, task);
+      #endif /* ( FF_REPEATED_DL_FACCH == 1 ) */
+
+        #if (AMR == 1)
+          // Non AMR FACCH handling
+          if (channel_mode != TCH_AFS_MODE)
+          {
+        #endif
+
+          // RXQUAL_SUB : In case of data taffic channels, accumulate number of
+          // estimated errors, this value is contained in a_fd[2] field, only
+          // for SID TDMA frames received as FACCH frames. (GSM 5.08 $8.4)
+          if (fn_mod_104==60)
+          {
+            l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_fd[2] & 0xffff;
+            l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_F_D_BLEN;
+          }
+
+        #if (AMR == 1)
+          }
+          else
+          {
+            // AGC, RXLEV_FULL
+
+            // Indicate to AMR specific processing that burst was a FACCH
+            facch_present = TRUE;
+            #if ((REL99) && (AMR == 1))
+            #if FF_EMR
+              emr_params.amr_facch_present = facch_present;
+            #endif
+            #endif
+
+            // Update AGC: Call DPAGC algorithm
+            IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+
+            // Dedicated mode serving cell measurement reading, indicate "FULL".
+            #if REL99
+            #if FF_EMR
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+            #endif
+            #else
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+            #endif
+          }
+        #endif
+
+          // RXQUAL_FULL : accumulate number of estimated errors, this value is
+          // contained in a_fd[2] field, for each TCHT block.
+	#if (AMR == 1)
+          // in AMR, l1s.dtx_amr_dl_on is FALSE if DTX mode is off
+          // in non AMR TCH, l1s.dtx_amr_dl_on is always FALSE
+          // In AMR DTX, DSP patch sometimes reports FACCH blocks which ARE NOT FACCH blocks
+          // therefore they shouldn't be taken into account in the RXQUALL_FULL computation
+          if(l1s.dtx_amr_dl_on==FALSE)
+	#endif
+          {
+          l1a_l1s_com.Smeas_dedic.qual_acc_full      += l1s_dsp_com.dsp_ndb_ptr->a_fd[2] & 0xffff;
+          l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_F_D_BLEN;
+		  }
+
+
+
+
+
+
+
+
+
+          // Reset A_FD header.
+          // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+          l1s_dsp_com.dsp_ndb_ptr->a_fd[0] = (1<<B_FIRE1);
+          l1s_dsp_com.dsp_ndb_ptr->a_fd[2] = 0xffff;
+
+          // Rem: when FACCH is received, we must reset A_DD_0 header also.
+          // Reset A_DD_0 header in NDB.
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+
+          // Rem: when FACCH is received, we must reset A_DD_1 header also.
+          // Reset A_DD_0 header in NDB.
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_1[0] = 0;
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_1[2] = 0xffff;
+
+          #if TESTMODE
+            if (l1_config.TestMode)
+            {
+              pm_fullres = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]   & 0xffff); // F26.6
+
+              // Allocate result message.
+              msg = os_alloc_sig(sizeof(T_TMODE_TCH_INFO));
+              DEBUGMSG(status,NU_ALLOC_ERR)
+              msg->SignalCode = TMODE_TCH_INFO;
+
+              ((T_TMODE_TCH_INFO *)(msg->SigP))->pm_fullres         = pm_fullres; // F26.6
+              ((T_TMODE_TCH_INFO *)(msg->SigP))->snr                = snr;
+              ((T_TMODE_TCH_INFO *)(msg->SigP))->toa                = toa;
+              ((T_TMODE_TCH_INFO *)(msg->SigP))->angle              = (WORD16) angle; // signed
+              ((T_TMODE_TCH_INFO *)(msg->SigP))->qual_full          = l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+              ((T_TMODE_TCH_INFO *)(msg->SigP))->qual_nbr_meas_full = TCH_FS_BLEN;
+
+              // send TMODE_TCH_INFO message...
+              os_send_sig(msg, L1C1_QUEUE);
+              DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+            }
+          #endif
+        } // if (b_blud == TRUE)
+
+        else // (if (b_blud == TRUE) FACCH
+        {
+          // No FACCH received.
+
+          // Dummy: Read FACCH DL data block from DSP, pass it to L2.
+          // Rem: this is an upper layer requirement to call this
+          // function at every FACCH DL boundary.
+          l1s_read_dcch_dl(NULL, task);
+
+        #if (AMR == 1)
+          if (channel_mode != TCH_AFS_MODE)
+          {
+        #endif
+
+          // Check A_DD_0 information block for TCH/F2.4 or TCH/FS.
+          // TCH/F2.4 or TCH/FS: Check A_DD_0 information block.
+          //----------------------------------------------------
+
+          b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+          if(b_blud == TRUE)
+          {
+            // RXQUAL_SUB : In case of speech traffic channels, accumulate number of
+            // estimated errors, this value is contained in a_dd_0[2] field, only
+            // for SID TDMA frames. (GSM 5.08 $8.4)
+            if (fn_mod_104==60)
+            {
+               l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+               l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += TCH_FS_BLEN;
+            }
+
+            // RXQUAL_FULL : accumulate number of estimated errors, this value is
+            // contained in a_dd_0[2] field, for each TCHT block.
+            l1a_l1s_com.Smeas_dedic.qual_acc_full      += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+            l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_FS_BLEN;
+
+            #if TESTMODE
+              if (l1_config.TestMode)
+              {
+                pm_fullres = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]   & 0xffff); // F26.6
+
+                // Allocate result message.
+                msg = os_alloc_sig(sizeof(T_TMODE_TCH_INFO));
+                DEBUGMSG(status,NU_ALLOC_ERR)
+                msg->SignalCode = TMODE_TCH_INFO;
+
+                ((T_TMODE_TCH_INFO *)(msg->SigP))->pm_fullres         = pm_fullres; // F26.6
+                ((T_TMODE_TCH_INFO *)(msg->SigP))->snr                = snr;
+                ((T_TMODE_TCH_INFO *)(msg->SigP))->toa                = toa;
+                ((T_TMODE_TCH_INFO *)(msg->SigP))->angle              = (WORD16) angle; // signed
+                ((T_TMODE_TCH_INFO *)(msg->SigP))->qual_full          = l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+                ((T_TMODE_TCH_INFO *)(msg->SigP))->qual_nbr_meas_full = TCH_FS_BLEN;
+
+                // send TMODE_TCH_INFO message...
+                os_send_sig(msg, L1C1_QUEUE);
+                DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+              }
+            #endif
+
+            if(channel_mode == TCH_24F_MODE)
+            {
+              #if IDS
+              // Integrated Data Services implementation
+              {
+                dll_data_dl(l1s_dsp_com.dsp_ndb_ptr->a_data_buf_dl,
+                            &l1s_dsp_com.dsp_ndb_ptr->d_ra_act,
+                             &l1s_dsp_com.dsp_ndb_ptr->d_ra_statd);
+              }
+              #else
+              {
+                // DATA traffic.
+                // Pass data block to DATA ADAPTOR.
+                // REM: Data packet is always given to the DATA ADAPTOR.
+                // There is no RX quality check !!
+                {
+                  rx_tch_data(&l1s_dsp_com.dsp_ndb_ptr->a_dd_0[3], channel_mode, 0);
+                }
+              }
+              #endif
+            }
+
+            // Reset A_DD_0 header in NDB.
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+          } // if(b_blud == TRUE)
+        #if (AMR == 1)
+          } // if (channel_mode != TCH_AFS_MODE)
+        #endif
+        } // if (b_blud == TRUE) FACCH (else)
+     #if (FF_REPEATED_DL_FACCH == 1)
+#if 1
+      temp=l1s.repeated_facch.counter_candidate;
+      l1s.repeated_facch.counter_candidate=l1s.repeated_facch.counter;
+      l1s.repeated_facch.counter=temp;
+#else
+if (l1s.repeated_facch.counter_candidate == 1)
+	l1s.repeated_facch.counter_candidate = 0 ;
+else if (l1s.repeated_facch.counter_candidate == 0 )
+	l1s.repeated_facch.counter_candidate = 0 ;
+
+   l1s.repeated_facch.counter++ ;
+if (l1s.repeated_facch.counter == 4)
+{
+l1s.repeated_facch.counter = 0;
+l1s.repeated_facch.pipeline[0].buffer_empty=l1s.repeated_facch.pipeline[1].buffer_empty=TRUE;
+}
+#endif
+    #endif/*(FF_REPEATED_DL_FACCH == 1)*/
+/* FACCH Full rate */
+      } // if(fn_report_mod13_mod4 == 0)
+
+      else // if(fn_report_mod13_mod4 == 0)
+    #if (AMR == 1)
+      if ((fn_report_mod13_mod4 == 2) && (channel_mode != TCH_AFS_MODE))
+    #else
+      if(fn_report_mod13_mod4 == 2)
+    #endif
+      // It is time to get TCH/F4.8 or TCH/F9.6 data block.
+      {
+        #if TRACE_TYPE==3
+          if (l1_stats.type == PLAY_UL &&
+             (channel_mode == TCH_48F_MODE || channel_mode == TCH_96_MODE || channel_mode == TCH_144_MODE))
+            play_trace();
+        #endif
+
+        // Check A_DD_0 information block only if no FACCH.
+        b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+        if(b_blud == TRUE)
+        {
+          // RXQUAL_FULL : accumulate number of estimated errors, this value is
+          // contained in a_dd_0[2] field, for each TCHT block.
+          l1a_l1s_com.Smeas_dedic.qual_acc_full      += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+          l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_F_D_BLEN;
+
+          if((channel_mode == TCH_48F_MODE) || (channel_mode == TCH_96_MODE) || (channel_mode == TCH_144_MODE))
+          {
+            #if IDS
+            // Integrated Data Services implementation
+            {
+              dll_data_dl(l1s_dsp_com.dsp_ndb_ptr->a_data_buf_dl,
+                          &l1s_dsp_com.dsp_ndb_ptr->d_ra_act,
+                           &l1s_dsp_com.dsp_ndb_ptr->d_ra_statd);
+            }
+            #else
+            {
+              // DATA traffic.
+              // Pass data block to DATA ADAPTOR.
+              // REM: Data packet is always given to the DATA ADAPTOR.
+              // There is no RX quality check !!
+              {
+                UWORD8 sequence_number;
+                UWORD8 fn_report_mod26 = l1s.actual_time.fn_in_report % 26;
+
+                // Catch sequence number. This is used in TCH/F4.8 to distinguish
+                // data blocks (see GSM 5.02) received on B0,B2,B4 (sequence number 0)
+                // and data blocks received on B1,B2,B3 (sequence number 1).
+                if((fn_report_mod26 == 23) || (fn_report_mod26 == 6) || (fn_report_mod26 == 15))
+                  sequence_number = 0;
+                else
+                  sequence_number = 1;
+                rx_tch_data(&l1s_dsp_com.dsp_ndb_ptr->a_dd_0[3], channel_mode, sequence_number);
+              }
+            }
+          #endif
+          }
+          // Reset A_DD_0 header in NDB.
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+        } // if(b_blud == TRUE)
+      } // if(fn_report_mod13_mod4 == 2)
+
+    #if (AMR == 1)
+      if ((channel_mode == TCH_AFS_MODE) && (facch_present == FALSE))
+      {
+        // Load the bit to check if the block is valid
+        b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & (1<<B_BLUD)) >> B_BLUD;
+
+        // Load the bit to check if the block is a RATSCCH in case of rx_type = NO_DATA
+        b_ratscch_blud = (l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] & (1<<B_BLUD)) >> B_BLUD;
+
+        // All detected AMR frames except NO_DATA (b_blud = 0) and FACCH are handled here, i.e. speech/SID/RATSCCH
+        if(b_ratscch_blud==TRUE)
+        {
+          // RXQUAL_FULL : accumulate number of estimated errors, this value is
+          // contained in a_ratscch_dl[2] field, for each TCHT block.
+          l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[2] & 0xffff;
+
+          // Reset the A_RATSCCH_DL header in NDB.
+          l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[0] = 0;
+          l1s_dsp_com.dsp_ndb_ptr->a_ratscch_dl[2] = 0xffff;
+
+          // RXQUAL_FULL : the number of bits examined for errors on serving cell depends on
+          // the block received.
+          l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += RATSCCH_BLEN;
+
+          IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+            #if REL99
+            #if FF_EMR
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+            #endif
+            #else
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+            #endif
+        }
+        else if(b_blud==TRUE)
+        {
+          // Load the type of the block received
+          rx_type = (l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] & RX_TYPE_MASK) >> RX_TYPE_SHIFT;
+
+        #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+          Trace_dedic_tch_block_stat(rx_type, l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2], 0);
+        #endif
+
+          // RXQUAL_SUB : In case of adaptative traffic channel, accumulate number of estimated errors
+          // is contained in the a_dd_0[2] value but the accumulation is made with SID_UPDATE frame only.
+          // Note: SID_UPDATE frame corresponds to rx_type SID_UPDATE (b_ratscch_blud = FALSE) or SID_BAD (See Memo)
+          if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+
+          {
+            l1a_l1s_com.Smeas_dedic.qual_acc_sub      += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+            l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub += SID_UPDATE_BLEN;
+          }
+
+          // RXQUAL_FULL : accumulate number of estimated errors, this value is
+          // contained in a_dd_0[2] field, for each TCHT block.
+
+
+
+
+          // Frames, which have no class1 bit (so no quality meas is possible), have d_nerr = 0
+          // so we can add them
+            l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+
+          // Reset A_DD_0 header in NDB.
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+          l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+
+
+
+
+
+          // RXQUAL_FULL : the number of bits examined for errors on serving cell depends on
+          // the block received.
+          if((rx_type==SPEECH_GOOD) || (rx_type==SPEECH_DEGRADED) || (rx_type==SPEECH_BAD))
+          {
+            // It's a speech block
+            // Note: in AFS, the d_nerr value doesn't depend on the vocoder currently use
+            l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AFS_BLEN;
+          }
+          else if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+
+
+          {
+            // the block is a SID UPDATE frame
+            l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += SID_UPDATE_BLEN;
+          }
+
+
+
+
+
+
+
+          // AGC, TOA, RXLEV for AMR. SUB queues only for SID_UPDATE frames
+          if((rx_type==SID_UPDATE) || (rx_type==SID_BAD))
+
+          {
+            IL_for_rxlev = l1ctl_dpagc_amr(1,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+            #if REL99
+            #if FF_EMR
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+            #endif
+            #else
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+            #endif
+
+          #if (TOA_ALGO != 0)
+            #if (TOA_ALGO == 2)
+              if(l1s.toa_var.toa_snr_mask == 0)
+            #else
+              if(l1s.toa_snr_mask == 0)
+            #endif
+            {
+              #if 1	/* FreeCalypso TCS211 reconstruction */
+                if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+                  l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+                else
+                  l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+              #else
+                UWORD32 snr_temp;
+                snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+                #if (TOA_ALGO == 2)
+                  l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+                #else
+                  l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+                  #if (FF_L1_FAST_DECODING == 1)
+                      ,0
+                  #endif
+                      );
+                #endif
+              #endif
+            }
+          #endif
+          }
+          else
+          {
+            IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm, radio_freq, IL_info_ptr);
+            #if REL99
+            #if FF_EMR
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+            #endif
+            #else
+              l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+            #endif
+          }
+        } // if(b_blud==TRUE)
+        // NO_DATA block detected or simple burst
+        else
+        {
+          if (fn_report_mod13_mod4 == 0)
+          {
+            l1a_l1s_com.Smeas_dedic.qual_acc_full += l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] & 0xffff;
+            l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += TCH_AFS_BLEN;
+
+          #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+            Trace_dedic_tch_block_stat(AMR_NO_DATA, l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2], 0);
+          #endif
+
+            // Reset A_DD_0 header in NDB.
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[0] = 0;
+            l1s_dsp_com.dsp_ndb_ptr->a_dd_0[2] = 0xffff;
+          }
+
+          // Update AGC: Call DPAGC AMR algorithm in order to fill the G_all buffer
+          IL_for_rxlev = l1ctl_dpagc_amr(0,beacon,(UWORD8)pm,radio_freq,IL_info_ptr);
+
+          // Dedicated mode serving cell measurement reading, full set only.
+          #if REL99
+          #if FF_EMR
+            l1s_read_dedic_scell_meas(IL_for_rxlev, 0, &emr_params);
+          #endif
+          #else
+            l1s_read_dedic_scell_meas(IL_for_rxlev, 0);
+          #endif
+        }
+      } // if ((channel_mode == TCH_AFS_MODE) && (facch_present == FALSE))
+    #endif
+
+      // task is completed, make it INACTIVE.
+      l1s.task_status[task].current_status = INACTIVE;
+    }
+    break;
+
+    case TCHA:
+    /*---------------------------------------------------*/
+    /* Dedicated mode: SACCH receive task.               */
+    /*---------------------------------------------------*/
+    {
+      UWORD8   IL_for_rxlev;
+      UWORD32  b_blud;
+
+      // Read control results and feed control algorithms.
+      // **************************************************
+
+      // Read control information.
+      toa   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_TOA]   & 0xffff;
+      pm    = (l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_PM]   & 0xffff) >> 5;
+      angle = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_ANGLE] & 0xffff;
+      snr   = l1s_dsp_com.dsp_db_r_ptr->a_serv_demod[D_SNR]   & 0xffff;
+
+      #if TESTMODE
+        if (l1_config.TestMode && l1_config.tmode.rf_params.down_up == TMODE_UPLINK)
+        {
+          // For UL-only tasks, TCHA is scheduled in every frame. TCH_INFO message is only
+          // used to count loops; no stats are collected.
+
+          xSignalHeaderRec *msg;
+          // Allocate result message.
+          msg = os_alloc_sig(sizeof(T_TMODE_TCH_INFO));
+          DEBUGMSG(status,NU_ALLOC_ERR)
+          msg->SignalCode = TMODE_TCH_INFO;
+          // send TMODE_TCH_INFO message...
+          os_send_sig(msg, L1C1_QUEUE);
+          DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+        }
+        // WARNING!
+        // Don't trace PM=0 during UL-only in TestMode. The DSP is not working
+        // in that case so it is normal. However, if tracing happens the CPU overloads
+        if (l1_config.TestMode && l1_config.tmode.rf_params.down_up & TMODE_DOWNLINK)
+      #endif
+        {
+            l1_check_pm_error(pm, task);
+        }
+
+      #if TRACE_TYPE==3
+        stats_samples_tch_sacch(toa,pm,angle,snr);
+      #endif
+
+      #if (TRACE_TYPE==2 ) || (TRACE_TYPE==3)
+        uart_trace(task);
+      #endif
+
+      // Update AGC: Call DPAGC algorithm
+      IL_for_rxlev = l1ctl_dpagc(1,beacon,(UWORD8)pm,radio_freq,IL_info_ptr); // dtx_on = 1
+
+      // Dedicated mode serving cell measurement reading, indicate "SUB".
+      #if REL99
+      #if FF_EMR
+        l1s_read_dedic_scell_meas(IL_for_rxlev, 1, &emr_params);
+      #endif
+      #else
+        l1s_read_dedic_scell_meas(IL_for_rxlev, 1);
+      #endif
+
+      // Update AFC: Call AFC control function (KALMAN filter).
+      #if AFC_ALGO
+        #if TESTMODE
+          if (l1_config.afc_enable)
+        #endif
+          {
+            #if (VCXO_ALGO == 0)
+              l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq);
+            #else
+              l1s.afc = l1ctl_afc(AFC_CLOSED_LOOP, &l1s.afc_frame_count, (WORD16)angle, snr, radio_freq,l1a_l1s_com.mode);
+            #endif
+          }
+      #endif
+
+      //Feed TOA histogram.
+      #if (TOA_ALGO != 0)
+        #if (TOA_ALGO == 2)
+          if(l1s.toa_var.toa_snr_mask == 0)
+        #else
+          if(l1s.toa_snr_mask == 0)
+        #endif
+        {
+          #if 1	/* FreeCalypso TCS211 reconstruction */
+            if (IL_for_rxlev < IL_FOR_RXLEV_SNR)
+              l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr, toa, &l1s.toa_update, &l1s.toa_period_count);
+            else
+              l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, 0, toa, &l1s.toa_update, &l1s.toa_period_count);
+          #else
+            UWORD32 snr_temp;
+            snr_temp = (IL_for_rxlev < IL_FOR_RXLEV_SNR)? snr: 0;
+            #if (TOA_ALGO == 2)
+              l1s.toa_var.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa);
+            #else
+              l1s.toa_shift = l1ctl_toa(TOA_RUN, l1a_l1s_com.mode, snr_temp, toa, &l1s.toa_update, &l1s.toa_period_count
+              #if (FF_L1_FAST_DECODING == 1)
+                  ,0
+              #endif
+                  );
+            #endif
+          #endif
+        }
+      #endif
+
+       #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+         RTTL1_FILL_DL_BURST(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev)
+       #endif
+       #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4)) && HAVE_L1_TRACE_BURST_PARAM
+         l1_trace_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+       #endif
+       #if (BURST_PARAM_LOG_ENABLE == 1)
+         l1_log_burst_param(angle, snr, l1s.afc, task, pm, toa, IL_for_rxlev);
+       #endif
+
+      // Read downlink DATA block from MCU/DSP interface.
+      // *************************************************
+
+      if(l1s.actual_time.fn_in_report == 91)
+      // It's time to read a SACCH DL result from DSP.
+      {
+        // Check A_CD information block.
+        b_blud = (l1s_dsp_com.dsp_ndb_ptr->a_cd[0] & (1<<B_BLUD)) >> B_BLUD;
+        if(b_blud == TRUE)
+        {
+          #if W_A_DSP1
+      // Temporary correction to fix a known DSP problem.  SACCH deinterleaver not
+          // initialized on HO.
+      //
+            if (old_sacch_DSP_bug == TRUE)
+            {
+            // Invalidate the current sacch block - indicate it cannot be decoded
+              l1s_dsp_com.dsp_ndb_ptr->a_cd[0]   =  (1<<B_FIRE1); // B_FIRE1=1,B_FIRE0=0,BLUD=0.
+              old_sacch_DSP_bug = FALSE;
+            }
+          #endif
+
+          // Read data block and send msg to L1A.
+          l1s_read_sacch_dl(l1s_dsp_com.dsp_ndb_ptr->a_cd, task);
+
+          // RXQUAL_FULL/RXQUAL_SUB : Accumulate number of estimated errors, this value
+          // is contained in a_cd[2] field, for every SACCH block.
+          l1a_l1s_com.Smeas_dedic.qual_acc_full      += l1s_dsp_com.dsp_ndb_ptr->a_cd[2] & 0xffff;
+          l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full += A_D_BLEN;
+          l1a_l1s_com.Smeas_dedic.qual_acc_sub       += l1s_dsp_com.dsp_ndb_ptr->a_cd[2] & 0xffff;
+          l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub  += A_D_BLEN;
+
+          // TEMPORARY : reset buffers and flags in NDB ...
+          //             reset nerr....
+          //             reset A_CD contents.......
+          l1s_dsp_com.dsp_ndb_ptr->a_cd[0]   =  (1<<B_FIRE1); // B_FIRE1=1,B_FIRE0=0,BLUD=0.
+          l1s_dsp_com.dsp_ndb_ptr->a_cd[2]   =  0xffff;
+        }
+      }
+      #if W_A_DSP1
+        else if (l1s.actual_time.fn_in_report == 13)  // TF 5/8/98 - DSP fix
+        {
+          // As this is the first SACCH burst the known DSP bug cannot occur on a new channel.
+          old_sacch_DSP_bug = FALSE;
+        }
+      #endif
+
+      // task is completed, make it INACTIVE.
+      l1s.task_status[task].current_status = INACTIVE;
+    }
+    break;
+  } // End switch...
+
+  #if (L1_DEBUG_IQ_DUMP == 1)
+    l1ddsp_read_iq_dump(task);
+  #endif
+
+  // Flag the use of the MCU/DSP dual page read interface.
+  // ******************************************************
+
+  // Set flag used to change the read page at the end of "l1_synch".
+  l1s_dsp_com.dsp_r_page_used = TRUE;
+}
+
+/*-------------------------------------------------------*/
+/* l1s_read_tx_result()                                  */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+void l1s_read_tx_result(UWORD8 task, UWORD8 burst_id)
+{
+  /*--------------------------------------------------------*/
+  /* READ TRANSMIT TASK RESULTS...                          */
+  /*--------------------------------------------------------*/
+
+  #if (TRACE_TYPE!=0)
+    if(task==RAACC)
+    {
+      if((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_ra & 0xffff) != (UWORD32)DSP_TASK_CODE[task])
+        trace_fct(CST_UL_TASKS_DO_NOT_CORRESPOND, -1);
+    }
+    else
+    {
+      if(((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_u & 0xffff) != (UWORD32)DSP_TASK_CODE[task]) &&
+         ((UWORD32)(l1s_dsp_com.dsp_db_r_ptr->d_task_u & 0xffff) != TCH_DTX_UL))
+        trace_fct(CST_UL_TASKS_DO_NOT_CORRESPOND, -1);
+    }
+  #endif
+
+  l1_check_com_mismatch(task);
+
+  switch(task)
+  {
+    case RAACC:
+    /*---------------------------------------------------*/
+    /* Serving Cell: Random Access TX task.              */
+    /*---------------------------------------------------*/
+    // Rem: confirmation message is sent at "CTRL" to be able to give FN%42432.
+    {
+      // Send confirmation msg to L1A.
+      // ******************************
+
+      // For ACCESS phase, a confirmation msg is sent to L1A.
+      xSignalHeaderRec *msg;
+
+      // send L1C_RA_DONE to L1A...
+      msg = os_alloc_sig(sizeof(T_MPHC_RA_CON));
+      DEBUGMSG(status,NU_ALLOC_ERR)
+
+      if (l1s.actual_time.fn == 0)
+        ((T_MPHC_RA_CON *)(msg->SigP))->fn = MAX_FN - 1;
+      else
+        ((T_MPHC_RA_CON *)(msg->SigP))->fn = l1s.actual_time.fn - 1;
+
+      ((T_MPHC_RA_CON *)(msg->SigP))->channel_request = l1a_l1s_com.ra_info.channel_request;
+      msg->SignalCode = L1C_RA_DONE;
+
+      os_send_sig(msg, L1C1_QUEUE);
+      DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+
+      // Desactivate the RAACC task.
+      l1s.task_status[task].current_status = INACTIVE;
+
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_READ_RA, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+    }
+    break;
+
+    case DUL:
+    /*---------------------------------------------------*/
+    /* Serving Cell: SDCCH up link.                      */
+    /*---------------------------------------------------*/
+    {
+      // Desactivate UL task.
+      if(burst_id == BURST_4)
+      {
+        l1s.task_status[task].current_status = INACTIVE;
+
+        #if (TRACE_TYPE == 5) // in simulation only the 4th burst is traced
+          trace_fct(CST_L1S_READ_TX_NB__DUL, l1a_l1s_com.Scell_info.radio_freq);
+        #endif
+      }
+
+      #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+        trace_fct(CST_L1S_READ_TX_NB__DUL, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+    }
+    break;
+
+    case AUL:
+    /*---------------------------------------------------*/
+    /* Serving Cell: SACCH up link.                      */
+    /*---------------------------------------------------*/
+    {
+      // Desactivate UL task.
+      if(burst_id == BURST_4)
+      {
+        l1s.task_status[task].current_status = INACTIVE;
+
+        #if (TRACE_TYPE == 5) // in simulation only the 4th burst is traced
+          trace_fct(CST_L1S_READ_TX_NB__AUL, l1a_l1s_com.Scell_info.radio_freq);
+        #endif
+      }
+
+      #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+        trace_fct(CST_L1S_READ_TX_NB__AUL, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+    }
+    break;
+
+    case TCHA:
+    case TCHTF:
+    /*---------------------------------------------------*/
+    /* Serving Cell: TCH link.                           */
+    /*---------------------------------------------------*/
+    {
+      #if (TRACE_TYPE==5)
+        if(burst_id == BURST_4) // in simulation only the 4th burst is traced
+          trace_fct(CST_L1S_READ_TX_NB__TCHF, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+      #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+          trace_fct(CST_L1S_READ_TX_NB__TCHF, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+    }
+    break;
+
+    case TCHTH:
+    /*---------------------------------------------------*/
+    /* Serving Cell: TCH link.                           */
+    /*---------------------------------------------------*/
+    {
+      #if (TRACE_TYPE==5)
+        if(burst_id == BURST_2) // in simulation only lates burst is traced
+          trace_fct(CST_L1S_READ_TX_NB__TCHH, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+      #if (TRACE_TYPE!=0) && (TRACE_TYPE!=5)
+          trace_fct(CST_L1S_READ_TX_NB__TCHH, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+    }
+    break;
+  }
+
+  // Set flag used to change the read page at the end of "l1_synch".
+  l1s_dsp_com.dsp_r_page_used = TRUE;
+}
+
+/*-------------------------------------------------------*/
+/* l1s_read_dedic_scell_meas()                           */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                       */
+/*-------------------------------------------------------*/
+
+#if REL99
+#if FF_EMR
+void l1s_read_dedic_scell_meas(UWORD8 input_level, UWORD8 sub_flag, T_EMR_PARAMS *emr_params)
+{
+  UWORD8  task;
+  UWORD8  burst_id;
+  UWORD8  b_blud;
+  UWORD8  counter;
+  UWORD8  bfi;                  // band frame indicator
+  UWORD8  channel_mode;         // current channel type
+  //OMAPS00090550 UWORD8  fn_report_mod_26;
+  UWORD8  subchannel;           // half rate sub channel
+  UWORD8  sid_present;          // indication for sid block
+  UWORD16 rx_type;
+  UWORD32 normalised_fn_mod13_mod4;
+
+  UWORD16 mean_bep_lsb = 0;     //l1s_dsp_com.dsp_ndb_ptr->d_mean_bep_block_lsb;
+  UWORD16 mean_bep_msb = 0;     //l1s_dsp_com.dsp_ndb_ptr->d_mean_bep_block_msb;
+  UWORD32 mean_bep = 0;         //((mean_bep_msb<<WORD_SHIFT)|(mean_bep_lsb)) >> MEAN_BEP_FORMAT;
+  UWORD16 cv_bep = 0;           //(l1s_dsp_com.dsp_ndb_ptr->d_cv_bep_block) >> CV_BEP_FORMAT;
+
+  static WORD16 last_corr_decoded_burst[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+  static UWORD16 cv_bep_tch4_8f_144[2]   = {0, 0};
+  static UWORD32 mean_bep_tch4_8f_144[2] = {0, 0};
+
+  WORD16 rxlev = l1s_encode_rxlev(input_level);
+
+  if (l1s_dsp_com.dsp_r_page == 1)
+  {
+      cv_bep       = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_0[D_CV_BEP];
+      mean_bep_msb = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_0[D_MEAN_BEP_MSW];
+      mean_bep_lsb = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_0[D_MEAN_BEP_LSW];
+  }
+  else
+  {
+      cv_bep       = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_1[D_CV_BEP];
+      mean_bep_msb = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_1[D_MEAN_BEP_MSW];
+      mean_bep_lsb = l1s_dsp_com.dsp_ndb_ptr->a_mean_cv_bep_page_1[D_MEAN_BEP_LSW];
+  }
+
+  mean_bep = ((mean_bep_msb<<WORD_SHIFT)|(mean_bep_lsb)) >> MEAN_BEP_FORMAT;
+  cv_bep   = cv_bep >> CV_BEP_FORMAT;
+
+  // EMR : Copy of Legacy code begins
+  // Measurement must be rejected if channel is hopping, hopped on
+  // the beacon frequency and PWRC is TRUE (see GSM05.08, $8.1.3).
+  if(!((l1a_l1s_com.dedic_set.pwrc == TRUE) &&
+       (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->chan_sel.h == TRUE) &&
+       (l1a_l1s_com.dedic_set.radio_freq_dd == l1a_l1s_com.Scell_info.radio_freq)))
+  {
+    // Add to FULL set meas.
+    l1a_l1s_com.Scell_info.meas.nbr_meas++;
+    l1a_l1s_com.Scell_info.meas.acc += rxlev;
+
+    if(sub_flag == TRUE)
+    {
+      // Add to SUB set meas.
+      l1a_l1s_com.Smeas_dedic.nbr_meas_sub++;
+      l1a_l1s_com.Smeas_dedic.acc_sub += rxlev;
+    } // if(sub_flag == TRUE)
+    // EMR : Copy of Legacy code ends
+  } // if(!((l1a_l1s_com.dedic_set.pwrc == TRUE) && ....
+
+  // new rxlev is received. remove the oldest rxlev.
+  for(counter=0;counter<=6;counter++)
+    last_corr_decoded_burst[counter] = last_corr_decoded_burst[counter+1];
+
+  // store new rxlev.
+  last_corr_decoded_burst[7] = rxlev;
+
+  task                            = emr_params->task;
+  burst_id                        = emr_params->burst_id;
+  channel_mode                    = emr_params->channel_mode;
+  normalised_fn_mod13_mod4 = emr_params->normalised_fn_mod13_mod4;
+
+  // TCH FS and TCH EFR
+  if((task == TCHTF) &&
+     (l1s.actual_time.fn_mod13_mod4 == 0) &&
+     ((channel_mode == TCH_FS_MODE) ||
+      (channel_mode == TCH_EFR_MODE) ||
+      (channel_mode == SIG_ONLY_MODE)))
+  {
+    if(emr_params->facch_present == TRUE)
+    {
+      // FACCH
+      if(emr_params->facch_fire1 == FALSE)
+      {
+        // FACCH correctly decoded
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4; // 4 bursts are accumulated
+
+        // Accumulate BEP
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+        //accumulation of the correctly decoded block
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                       last_corr_decoded_burst[5] +
+                                                       last_corr_decoded_burst[6] +
+                                                       last_corr_decoded_burst[7];
+
+        if(channel_mode == SIG_ONLY_MODE)
+        // accumulation of correctly decoded blocks excluding SACCH  and SID frames FACCH only for sig only mode
+          l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+
+      } // if(facch_fire1 == FALSE)
+    } // if(facch_present == TRUE )
+    else
+    {
+      // NOT FACCH,
+      if (emr_params->a_dd_0_blud == TRUE)
+      {
+        if (emr_params->a_dd_0_bfi == FALSE)
+        {
+          // speech correctly decoded
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+          // Accumulate BEP
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+          //accumulation of the correctly decoded block
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                       last_corr_decoded_burst[5] +
+                                                       last_corr_decoded_burst[6] +
+                                                       last_corr_decoded_burst[7];
+
+          if (emr_params->sid_present_sub0 == FALSE)
+          {
+            // accumulation of correctly decoded blocks excluding SACCH FACCH and SID frames
+            l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+          } // if(sid_present == FALSE)
+        } // if(bfi == FALSE)
+      } // if(b_blud == TRUE)
+    } // else part of if(facch_present == TRUE )
+  } // TCH FS and TCH EFR
+
+  // TCH 2.4F
+  if((task == TCHTF) &&
+     (l1s.actual_time.fn_mod13_mod4 == 0) &&
+     (channel_mode == TCH_24F_MODE))
+  {
+    if(emr_params->facch_present == TRUE)
+    {
+      if(emr_params->facch_fire1 == FALSE)
+      {
+        // FACCH correctly decoded
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+        // Accumulate BEP
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+        //accumulation of the correctly decoded block
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                     last_corr_decoded_burst[5] +
+                                                     last_corr_decoded_burst[6] +
+                                                     last_corr_decoded_burst[7];
+      }
+    } // if(facch_present == TRUE)
+    else
+    {
+      // NOT FACCH check whether the data buffer is updated!!
+      if(emr_params->a_dd_0_blud == TRUE)
+      {
+        // Check if transparent data or not
+        if(emr_params->b_ce == TRUE)// Non Transparent
+        {
+          //check if correctly decoded or not
+          if(emr_params->a_ntd == FALSE)//good frame detected
+          {
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+            // Accumulate BEP
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+            //accumulation of the correctly decoded block
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                         last_corr_decoded_burst[5] +
+                                                         last_corr_decoded_burst[6] +
+                                                         last_corr_decoded_burst[7];
+            // accumulation of correctly decoded blocks excluding SACCH FACCH frames
+            l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+          } // if(a_ntd == FALSE)
+        } // if(b_ce == TRUE)
+        else
+        {
+          // 2.4F transperent data (always considered as correctly decoded)
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+          // Accumulate BEP
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+          //accumulation of the block
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                       last_corr_decoded_burst[5] +
+                                                       last_corr_decoded_burst[6] +
+                                                       last_corr_decoded_burst[7];
+
+          // accumulation of decoded blocks excluding SACCH FACCH and SID frames
+          l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+        } // if(b_ce == TRUE)
+      } // if(b_blud == TRUE)
+    } // else part of if(facch_present == TRUE)
+  } // TCH 2.4F
+
+  // TCH 9.6F
+  if((task == TCHTF) &&
+     (l1s.actual_time.fn_mod13_mod4 == 0) &&
+     (channel_mode == TCH_96_MODE))
+  {
+    if(emr_params->facch_present == TRUE)
+    {
+      if(emr_params->facch_fire1 == FALSE)
+      {
+        // FACCH correctly decoded
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+        // Accumulate BEP
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+        //accumulation of the correctly decoded block
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                     last_corr_decoded_burst[5] +
+                                                     last_corr_decoded_burst[6] +
+                                                     last_corr_decoded_burst[7];
+      } //if(fire1 == FALSE)
+    } //if(facch_present == TRUE)
+  } // if(fn_mod13_mod4 == 0)
+
+  if((task == TCHTF) &&
+     (l1s.actual_time.fn_mod13_mod4 == 2) &&
+     (channel_mode == TCH_96_MODE))
+  {
+    if(emr_params->a_dd_0_blud == TRUE)
+    {
+      // Check if transparent data or not
+      if(emr_params->b_ce == TRUE)// Non Transparent
+      {
+        //check if correctly decoded or not
+        if(emr_params->a_ntd == FALSE)//good frame detected
+        {
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+          // Accumulate BEP
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+          //accumulation of the correctly decoded block
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                       last_corr_decoded_burst[5] +
+                                                       last_corr_decoded_burst[6] +
+                                                       last_corr_decoded_burst[7];
+
+          // accumulation of correctly decoded blocks excluding SACCH FACCH frames
+          l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+        } // if(a_ntd == FALSE)
+      } // if(b_ce == TRUE)
+      else
+      {
+        // transparent data (always correctly decoded)
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+        // Accumulate BEP
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+        //accumulation of decoded block
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                     last_corr_decoded_burst[5] +
+                                                     last_corr_decoded_burst[6] +
+                                                     last_corr_decoded_burst[7];
+
+        // accumulation of decoded blocks excluding SACCH FACCH frames
+        l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+      } // transparent data
+    } // if(b_blud == TRUE)
+  } // TCH F9.6
+
+  // TCH 4.8F/14.4F
+  if((task == TCHTF) &&
+     (l1s.actual_time.fn_mod13_mod4 == 0) &&
+     ((channel_mode == TCH_48F_MODE) || (channel_mode == TCH_144_MODE)) )
+  {
+    if(emr_params->facch_present == TRUE)
+    {
+      if(emr_params->facch_fire1 == FALSE)
+      {
+        // FACCH correctly decoded
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;// 4 bursts are accumulated
+
+        // Accumulate BEP
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+        //accumulation of the correctly decoded block
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                     last_corr_decoded_burst[5] +
+                                                     last_corr_decoded_burst[6] +
+                                                     last_corr_decoded_burst[7];
+      } //if(fire1 == FALSE)
+    } //if(facch_present == TRUE)
+  } // if(fn_mod13_mod4 == 0)
+
+  if((task == TCHTF) &&
+     (l1s.actual_time.fn_mod13_mod4 == 2) &&
+     ((channel_mode == TCH_48F_MODE) || (channel_mode == TCH_144_MODE)) )
+  {
+    // block end add new value of mean_bep and cv_bep value to mean_bep_tch4_8f_144 and
+    // cv_bep_tch4_8f_144. remove the oldest value.
+    mean_bep_tch4_8f_144[0] = mean_bep_tch4_8f_144[1];
+    cv_bep_tch4_8f_144[0]   = cv_bep_tch4_8f_144[1];
+    mean_bep_tch4_8f_144[1] = mean_bep;
+    cv_bep_tch4_8f_144[1]   = cv_bep;
+
+    if ( ((emr_params->a_dd_0_blud == TRUE) && (emr_params->b_m1) && (channel_mode == TCH_144_MODE)) ||
+         ((emr_params->a_dd_0_blud == TRUE) && (emr_params->b_f48blk_dl) && (channel_mode == TCH_48F_MODE)) )
+    {
+      // Check if transparent data or not
+      if(emr_params->b_ce == TRUE) // Non transparent
+      {
+        //check if correctly decoded or not. Accumulate last 8 slots
+        if(emr_params->a_ntd == FALSE) //good frame detected
+        {
+          // two blocks are accumulated at a time, increment by 2.
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas+=8;   // 8 bursts are accumulated
+
+          // Accumulate BEP
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep_tch4_8f_144[0] + mean_bep_tch4_8f_144[1];
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep_tch4_8f_144[0] + cv_bep_tch4_8f_144[1];
+
+          // two blocks are accumulated at a time, increment by 2.
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num += 2;
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num+=2;
+
+          //accumulation of the correctly decoded block
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[0] +
+                                                       last_corr_decoded_burst[1] +
+                                                       last_corr_decoded_burst[2] +
+                                                       last_corr_decoded_burst[3] +
+                                                       last_corr_decoded_burst[4] +
+                                                       last_corr_decoded_burst[5] +
+                                                       last_corr_decoded_burst[6] +
+                                                       last_corr_decoded_burst[7];
+
+          // accumulation of correctly decoded blocks excluding SACCH FACCH frames
+          l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks +=2;
+        } // if(a_ntd == FALSE)
+      } // if(b_ce == TRUE)
+      else
+      {
+        // transparent data
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=8;   // 8 bursts are accumulated
+
+        // Accumulate BEP
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep_tch4_8f_144[0] + mean_bep_tch4_8f_144[1];
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep_tch4_8f_144[0] + cv_bep_tch4_8f_144[1];
+
+        // two blocks are accumulated at a time, increment by 2.
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num+=2;
+        l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num += 2;
+
+        //accumulation of the correctly decoded block
+        l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[0] +
+                                                     last_corr_decoded_burst[1] +
+                                                     last_corr_decoded_burst[2] +
+                                                     last_corr_decoded_burst[3] +
+                                                     last_corr_decoded_burst[4] +
+                                                     last_corr_decoded_burst[5] +
+                                                     last_corr_decoded_burst[6] +
+                                                     last_corr_decoded_burst[7];
+
+        // accumulation of correctly decoded blocks excluding SACCH FACCH frames
+        l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks +=2;
+      } // Transparent data
+    } // if(b_blud == TRUE)
+  } // TCH 4.8F/14.4
+
+
+  // TCH HS
+  if((task == TCHTH) &&
+     ((channel_mode == TCH_HS_MODE)||(channel_mode == SIG_ONLY_MODE))&&
+     (normalised_fn_mod13_mod4 == 3) )
+  {
+    UWORD8 norm_fn_mod26;
+
+    subchannel = emr_params->subchannel;
+    norm_fn_mod26 = ((l1s.actual_time.fn - subchannel + 26)  % 26);
+
+    if(subchannel == 0)
+    {
+      b_blud      = emr_params->a_dd_0_blud;
+      bfi         = emr_params->a_dd_0_bfi;       // 3rd bit tells the BAD frame.
+      sid_present = emr_params->sid_present_sub0; // find out whether sid1 is 0/1, 1 mean
+    }
+    else
+    {
+      b_blud      = emr_params->a_dd_1_blud;
+      bfi         = emr_params->a_dd_1_bfi;       // 3rd bit tells the BAD frame.
+      sid_present = emr_params->sid_present_sub1; // find out whether sid1 is 0/1, 1 mean
+    }
+
+    if(norm_fn_mod26 == 7 || norm_fn_mod26 == 16|| norm_fn_mod26 == 24 )
+    {
+      // FACCH: Check A_FD information block.
+      if(emr_params->facch_present == TRUE)
+      {
+        // FACCH correctly decoded
+        if(emr_params->facch_fire1 == FALSE)
+        {
+          // Accumulate BEP
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+          //accumulation of the correctly decoded block
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                       last_corr_decoded_burst[5] +
+                                                       last_corr_decoded_burst[6] +
+                                                       last_corr_decoded_burst[7];
+
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+          if((channel_mode == SIG_ONLY_MODE))
+            // accumulation of correctly decoded blocks excluding SACCH
+            // and SID frames FACCH only for sig only mode
+            l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+        }  //if(fire1 == FALSE)
+      }  //if(facch_present ==....)
+      else
+      {
+        // No Facch at this positions 7,16,24
+        if (b_blud == TRUE)
+        {
+          if(bfi == FALSE)
+          {
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+            // Accumulate BEP
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+            //accumulation of the correctly decoded block
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[7] +
+                                                         last_corr_decoded_burst[6] +
+                                                         last_corr_decoded_burst[5] +
+                                                         last_corr_decoded_burst[4] ;
+
+            //as per standard 05.08 section 8.3
+            //sid_present can become true only at (fn modulo 26) == 6
+            //sid_present will be false at all other points
+
+            if(sid_present == FALSE)
+              // accumulation of correctly decoded blocks excluding SACCH
+              // FACCH and SID frames
+              l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+          } // if(bfi == FALSE)
+        } // if (b_blud == TRUE)
+      }  // else facch_present
+    } //if(norm_fn_report_mod26 == 7 || norm_fn_report_mod26 == 16|| norm_fn_report_mod26 == 24 )
+    else
+    {
+      //norm_fn_report_mod26 == 3 || norm_fn_report_mod26 == 11|| norm_fn_report_mod26 == 20
+      if (b_blud == TRUE)
+      {
+        if(bfi == FALSE)
+        {
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+          // Accumulate BEP
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+          //accumulation of the correctly decoded block
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[7] +
+                                                       last_corr_decoded_burst[6] +
+                                                       last_corr_decoded_burst[5] +
+                                                       last_corr_decoded_burst[4] ;
+
+           //as per standard 05.08 section 8.3
+           //sid_present can become true only at (fn modulo 26) == 6
+           //sid_present will be false at all other points
+
+           if(sid_present == FALSE)
+             // accumulation of correctly decoded blocks excluding SACCH
+             // FACCH and SID frames
+             l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+        }  //if(bfi == FALSE)
+      } // if (b_blud == TRUE)
+    }  //else
+  }//task == TCHTH.....
+
+  // SACCH of TCH
+  if((task == TCHA))
+  {
+    //unconditionnal accumulation of rxlev_val
+    l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas++;
+    l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += rxlev;
+    if(l1s.actual_time.fn_in_report == 91)
+    {
+      // Set detection flag.
+      if(emr_params->a_cd_fire1 == FALSE)
+      {
+        // rec 05.08 8.2.3: BEP value need to be accumulated on correctly received blocks
+        // rec 05.08 8.4.8.2 : for SACCH of TCH, no accumulation for CV_BEP and nbr_rcvd_blocks
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+        l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+      } // if(fire1 == FALSE)
+    } // if(l1s.actual_time.fn_in_report == 91)
+  } // // SACCH of TCH
+
+  // SDCCH and SACCH of SDCCH
+  if (((task == DDL) || (task == ADL)) && (burst_id == BURST_4))
+  {
+    //unconditional accumulation of Rxlev_val
+    l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+    l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                 last_corr_decoded_burst[5] +
+                                                 last_corr_decoded_burst[6] +
+                                                 last_corr_decoded_burst[7];
+
+    // rec 05.08 8.2.3: in SDCCH, BEP value need to be accumulated on correctly received blocks
+    if(emr_params->a_cd_fire1 == FALSE)
+    {
+      l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+      l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+      l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+      l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+      l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+    }
+  } // SDCCH
+
+  //AMR FS
+  #if (AMR == 1)
+    if((task == TCHTF) &&
+       (channel_mode == TCH_AFS_MODE) &&
+       (l1s.actual_time.fn_mod13_mod4 == 0))
+    {
+      if(emr_params->amr_facch_present == TRUE)
+      {
+        // FACCH present
+        // FACCH correctly decoded ?
+        if(emr_params->amr_facch_fire1 == FALSE)
+        {
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+          // Accumulate BEP
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+          //accumulation of the correctly decoded block
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                       last_corr_decoded_burst[5] +
+                                                       last_corr_decoded_burst[6] +
+                                                       last_corr_decoded_burst[7];
+        } // if(fire1 == FALSE)
+      } // if(facch_present == TRUE)
+      else
+      {
+        // NOT FACCH
+        if ((emr_params->b_ratscch_blud == TRUE) && (emr_params->ratscch_rxtype == RATSCCH_GOOD))
+        {
+          //RATSCCH correctly decoded
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+          // Accumulate BEP
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+          //accumulation of the correctly decoded block
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                       last_corr_decoded_burst[5] +
+                                                       last_corr_decoded_burst[6] +
+                                                       last_corr_decoded_burst[7];
+        } // if(b_ratscch_blud == TRUE)
+        else if(emr_params->a_dd_0_blud == TRUE)
+        {
+          // Good speech frame.
+          if((emr_params->amr_rx_type_sub0 == SPEECH_GOOD) ||
+             (emr_params->amr_rx_type_sub0 == SPEECH_DEGRADED) ||
+             (emr_params->amr_rx_type_sub0 == SID_UPDATE))
+          {
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+            // Accumulate BEP
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc += mean_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   += cv_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+            //accumulation of the correctly decoded block
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                         last_corr_decoded_burst[5] +
+                                                         last_corr_decoded_burst[6] +
+                                                         last_corr_decoded_burst[7];
+
+            if ((emr_params->amr_rx_type_sub0 == SPEECH_GOOD) || (emr_params->amr_rx_type_sub0 == SPEECH_DEGRADED))
+              //Number of correctly decoded blocks excluding SACCH FACCH RATSCCH and SID frames.
+              l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+          } // if((rx_type == SPEECH_GOOD) || (rx_type == SID_UPDATE))
+        } // else if(b_blud == TRUE)
+      } // else of if(facch_present == TRUE)
+    } //AMR FS
+
+    //AMR HS
+    //TCH AHS
+    if((task == TCHTH) &&
+       (channel_mode == TCH_AHS_MODE)&&
+       (normalised_fn_mod13_mod4 == 3))
+    {
+      UWORD8 norm_fn_mod26;
+      subchannel = emr_params->subchannel;
+
+      if (subchannel == 0)
+      {
+        // Load the bit to check if the block is valid
+        b_blud =  emr_params->a_dd_0_blud;
+        rx_type = emr_params->amr_rx_type_sub0;
+      }
+      else // subchannel 1
+      {
+        // Load the bit to check if the block is valid
+        b_blud =  emr_params->a_dd_1_blud;
+        rx_type = emr_params->amr_rx_type_sub1;
+      }
+
+      norm_fn_mod26 = (l1s.actual_time.fn - subchannel +26)  % 26;
+
+      if(norm_fn_mod26 == 7 ||
+         norm_fn_mod26 == 16||
+         norm_fn_mod26 == 24 )
+      {
+        // FACCH: Check A_FD information block.
+        if(emr_params->amr_facch_present == TRUE)
+        {
+          // FACCH present
+          // FACCH correctly decoded ?
+          if(emr_params->amr_facch_fire1 == FALSE)
+          {
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+            // Accumulate BEP
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc +=mean_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   +=cv_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+            //accumulation of the correctly decoded block
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc += last_corr_decoded_burst[4] +
+                                                         last_corr_decoded_burst[5] +
+                                                         last_corr_decoded_burst[6] +
+                                                         last_corr_decoded_burst[7];
+          } // if(fire1 == FALSE)
+        } // if(facch_present == TRUE)
+        else
+        {
+          // NOT FACCH
+          // Load the bit to check if the block is a RATSCCH in caseof rx_type = NO_DATA
+          //In half rate, there are 2 consecutive frames called RATSCCH_MARKER and
+          //RATSCCH_DATA, MARKER doesn't contain any CRC. So we cannot make a decision
+          //whether RATSCCH_MARKER is correctly decoded. Hence ratscch_rxtype_prev
+          //is not valid. Hence the inner check has to be based only on ratscch_rxtype.
+          //ratscch_rxtype is updated based on the CRC of RATSCCH_DATA.
+          //The following are the decisions on the outer check "if (b_ratscch_blud == TRUE)....
+          //b_ratscch_blud is updated based on RATSCCH_DATA. Hence it is a valid check
+          //b_ratscch_blud_prev would have been accumulated based on RATSCCH_MARKER.
+          //The assumption here is that when RATSCCH_MARKER is detected, the b_blud bit of
+          //a_ratscch_dl will be updated.
+
+          if ( ((emr_params->b_ratscch_blud == TRUE) && (emr_params->ratscch_rxtype == RATSCCH_GOOD)) ||
+               ((b_blud==TRUE) && (rx_type == SID_UPDATE)) ||
+               ((b_blud == TRUE)&&(rx_type == SPEECH_DEGRADED)) ||
+               ((b_blud == TRUE)&&(rx_type == SPEECH_GOOD)) )
+          {
+            //RATSCCH or SID Update or Speech block correctly decoded, increment the counter
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+            // Accumulate BEP
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc +=mean_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   +=cv_bep;
+            l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+            l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+            //accumulation of the correctly decoded block
+            l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc +=last_corr_decoded_burst[4] +
+                                                        last_corr_decoded_burst[5] +
+                                                        last_corr_decoded_burst[6] +
+                                                        last_corr_decoded_burst[7];
+            if (((rx_type == SPEECH_GOOD) || (rx_type == SPEECH_DEGRADED)) && (emr_params->ratscch_rxtype != RATSCCH_GOOD))
+              l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+          }
+        } // else part of if(facch_present == TRUE)
+      }//fnmod26 == 7||16 || 24
+      else
+      {
+        //if (norm_fn_mod26 ==3 || norm_fn_mod26 == 11 ||
+        //norm_fn_mod26 == 20)
+
+        if ( ((emr_params->b_ratscch_blud == TRUE) && (emr_params->ratscch_rxtype == RATSCCH_GOOD)) ||
+             ((b_blud==TRUE) && (rx_type == SID_UPDATE)) ||
+             ((b_blud == TRUE)&&(rx_type == SPEECH_DEGRADED)) ||
+             ((b_blud == TRUE)&&(rx_type == SPEECH_GOOD)) )
+        {
+          //RATSCCH or SID Update or Speech block correctly decoded, increment the counter
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas +=4;   // 4 bursts are accumulated
+
+          // Accumulate BEP
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc +=mean_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   +=cv_bep;
+          l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num++;
+          l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num++;
+
+          //accumulation of the correctly decoded block
+          l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc +=last_corr_decoded_burst[4] +
+                                                      last_corr_decoded_burst[5] +
+                                                      last_corr_decoded_burst[6] +
+                                                      last_corr_decoded_burst[7];
+          if (((rx_type == SPEECH_GOOD) || (rx_type == SPEECH_DEGRADED)) && (emr_params->ratscch_rxtype != RATSCCH_GOOD))
+            l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks++;
+        }
+      } //else fn = 3,11,20
+    }//task == TCHTH.....
+  #endif //(AMR == 1)
+}
+#endif //FF_EMR
+#else //REL99
+
+void l1s_read_dedic_scell_meas(UWORD8 input_level, UWORD8 sub_flag)
+{
+  WORD16 rxlev = l1s_encode_rxlev(input_level);
+
+  // Measurement must be rejected if channel is hopping, hopped on
+  // the beacon frequency and PWRC is TRUE (see GSM05.08, $8.1.3).
+  if(!((l1a_l1s_com.dedic_set.pwrc == TRUE) &&
+       (l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->chan_sel.h == TRUE) &&
+       (l1a_l1s_com.dedic_set.radio_freq_dd == l1a_l1s_com.Scell_info.radio_freq)))
+  {
+    // Add to FULL set meas.
+    l1a_l1s_com.Scell_info.meas.nbr_meas++;
+    l1a_l1s_com.Scell_info.meas.acc += rxlev;
+
+    if(sub_flag == TRUE)
+    {
+      // Add to SUB set meas.
+      l1a_l1s_com.Smeas_dedic.nbr_meas_sub++;
+      l1a_l1s_com.Smeas_dedic.acc_sub += rxlev;
+    }
+  }
+}
+#endif //REL99
+/*-------------------------------------------------------*/
+/* l1s_dedic_reporting()                                 */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality :                                        */
+/*-------------------------------------------------------*/
+void l1s_dedic_reporting()
+{
+  xSignalHeaderRec  *msg;
+  UWORD8             i;
+  UWORD32            nbr_carrier = l1a_l1s_com.ba_list.nbr_carrier;
+
+  // Allocate L1C_MEAS_DONE message...
+  msg = os_alloc_sig(sizeof(T_MPHC_MEAS_REPORT));
+  DEBUGMSG(status,NU_ALLOC_ERR)
+  msg->SignalCode = L1C_MEAS_DONE;
+
+  // Fill miscelaneous parameters
+  //=============================
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->ba_id = l1a_l1s_com.ba_list.ba_id;
+
+  //timing_advance...
+  //txpwr...
+  //meas_valid...
+
+  // Fill msg for Neighbor Cells
+  //============================
+
+  for(i=0;i<nbr_carrier;i++)
+  {
+    T_MEAS_INFO  *ba_ptr = &l1a_l1s_com.ba_list.A[i];
+
+    ((T_MPHC_MEAS_REPORT*)(msg->SigP))->ncell_meas.A[i].bcch_freq      = ba_ptr->radio_freq;
+    ((T_MPHC_MEAS_REPORT*)(msg->SigP))->ncell_meas.A[i].rxlev_acc      = ba_ptr->acc;
+    ((T_MPHC_MEAS_REPORT*)(msg->SigP))->ncell_meas.A[i].rxlev_nbr_meas = ba_ptr->nbr_meas;
+
+    // Reset BA.
+    ba_ptr->acc      = 0;
+    ba_ptr->nbr_meas = 0;
+  }
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->no_of_ncell_meas = nbr_carrier;
+
+  // Fill msg for Serving Cell
+  //==========================
+
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_full_acc         = l1a_l1s_com.Scell_info.meas.acc;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_full_nbr_meas    = l1a_l1s_com.Scell_info.meas.nbr_meas;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_sub_acc          = l1a_l1s_com.Smeas_dedic.acc_sub;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_sub_nbr_meas     = l1a_l1s_com.Smeas_dedic.nbr_meas_sub;
+
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxqual_full_acc_errors = l1a_l1s_com.Smeas_dedic.qual_acc_full;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxqual_full_nbr_bits   = l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxqual_sub_acc_errors  = l1a_l1s_com.Smeas_dedic.qual_acc_sub;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxqual_sub_nbr_bits    = l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub;
+
+  #if REL99
+  #if FF_EMR
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_val_acc         = l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->rxlev_val_nbr_meas    = l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->nbr_rcvd_blocks       = l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->mean_bep_block_acc    = l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->cv_bep_block_acc      = l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->mean_bep_block_num    = l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->cv_bep_block_num      = l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num;
+  #endif
+  #endif
+
+  if(l1a_l1s_com.dedic_set.aset->dtx_allowed == TRUE)
+  // Set "dtx_used" flag according to DSP transmit report result only if
+  // DTX is allowed.
+  {
+    if(l1a_l1s_com.Smeas_dedic.dtx_used > 0)
+      ((T_MPHC_MEAS_REPORT*)(msg->SigP))->dtx_used = TRUE;
+    // Set the dtx_used flag in the case of TCHF/ no signaling
+    else if ((l1a_l1s_com.dedic_set.aset->chan1.mode == SIG_ONLY_MODE)
+            &&(l1a_l1s_com.dedic_set.aset->chan1.desc.channel_type==TCH_F))
+      ((T_MPHC_MEAS_REPORT*)(msg->SigP))->dtx_used = TRUE;
+    else
+      ((T_MPHC_MEAS_REPORT*)(msg->SigP))->dtx_used = FALSE;
+  }
+  else
+  {
+    ((T_MPHC_MEAS_REPORT*)(msg->SigP))->dtx_used = FALSE;
+  }
+
+  // Reset Serving Cell measurement variables.
+  l1s_reset_dedic_serving_meas();
+
+
+  // Give miscellaneous info to L3 (just for indication/debug).
+  //===========================================================
+
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->timing_advance = l1a_l1s_com.dedic_set.aset->timing_advance;
+  ((T_MPHC_MEAS_REPORT*)(msg->SigP))->txpwr_used     = l1s.reported_txpwr;
+
+  #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+    ((T_MPHC_MEAS_REPORT*)(msg->SigP))->facch_dl_count = trace_info.facch_dl_count;
+    ((T_MPHC_MEAS_REPORT*)(msg->SigP))->facch_ul_count = trace_info.facch_ul_count;
+  #if (FF_REPEATED_DL_FACCH == 1)
+    ((T_MPHC_MEAS_REPORT*)(msg->SigP))->facch_dl_combined_good_count = trace_info.facch_dl_combined_good_count; /* No of good blocks after combining */
+    ((T_MPHC_MEAS_REPORT*)(msg->SigP))->facch_dl_repetition_block_count = trace_info.facch_dl_repetition_block_count;
+  #endif/* (FF_REPEATED_DL_FACCH == 1) */
+    trace_info.facch_dl_fail_count_trace = trace_info.facch_dl_fail_count;
+    trace_info.facch_dl_count = 0;
+    trace_info.facch_ul_count = 0;
+    trace_info.facch_dl_fail_count = 0;
+   #if ( FF_REPEATED_DL_FACCH == 1 ) /* Reseting the values */
+    trace_info.facch_dl_combined_good_count = 0;
+    trace_info.facch_dl_repetition_block_count = 0;
+   #endif/* (FF_REPEATED_DL_FACCH == 1) */
+  #endif
+
+  // send L1C_MEAS_DONE message...
+  os_send_sig(msg, L1C1_QUEUE);
+  DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+}
+
+#if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+/*-------------------------------------------------------*/
+/* l1s_read_fb()                                         */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality : this function sends L1C_FB_INFO to L1A*/
+/*-------------------------------------------------------*/
+void l1s_read_fb(UWORD8 task, UWORD32 fb_flag, UWORD32 toa, UWORD32 attempt,
+                 UWORD32 pm, UWORD32 angle, UWORD32 snr)
+{
+  xSignalHeaderRec  *msg;
+  WORD32             modif_toa = 0;
+  WORD32             ntdma;
+  UWORD32            fn_offset;
+
+  // For detail of the here below equation cf. BUG1558
+  #define MAX_TOA_FOR_SB (D_NSUBB_DEDIC*48)+DL_ABB_DELAY/4-(SB_BURST_DURATION+DL_ABB_DELAY+SB_MARGIN)/4-2
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dspres(dltsk_trace[task].name);
+  #endif
+
+  #if (TRACE_TYPE!=0)
+    switch(task)
+    {
+      case FBNEW: trace_fct(CST_L1S_READ_FB, l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq);break;
+      case FB51:  trace_fct(CST_L1S_READ_FB51, l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq);break;
+      case FB26:  trace_fct(CST_L1S_READ_FB26, l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq);break;
+      default:    trace_fct(CST_UNKNOWN_FB, l1a_l1s_com.nsync.list[0].radio_freq);break;
+    }
+  #endif
+
+  if(fb_flag == TRUE)
+  {
+    switch (task)
+    {
+      case FBNEW:
+      case FB51:
+      // Compute NTDMA & TOA taking into account the 23 bit guard for next SB receive window.
+      {
+        modif_toa = toa - (SB_MARGIN/4);     // Rem: unit is "BIT".
+      }
+      break;
+
+      case FB26:
+      // Compute TOA taking into account the 23 bit guard for next SB receive window
+      // and the time diff. between a the fb search and a normal serving RX slot..
+      // Rem: TOA cannot be less than "SB_MARGIN/4".
+      {
+        // Saturate TOA to MAX_TOA_FOR_SB since it is the last position compatible with the
+        // SB26 tpu programming. MAX_TOA_FOR_SB + 1 would reject the TCHT/frame0 one frame later due
+        // to an overlap of TPU scenarios.
+        if(toa >= MAX_TOA_FOR_SB) toa = MAX_TOA_FOR_SB;
+
+        modif_toa = toa + ((l1_config.params.fb26_anchoring_time + PROVISION_TIME - START_RX_FB)/4) - (SB_MARGIN/4); // Rem: unit is "BIT".
+      }
+      break;
+    } // End of switch.
+
+    if(modif_toa < 0)
+    {
+      modif_toa = (modif_toa + (TPU_CLOCK_RANGE/4)) * 4; // Unit is changed from bit to qbit.
+      ntdma     = - 1;
+    }
+    else
+    {
+      ntdma     = modif_toa / (TPU_CLOCK_RANGE/4);
+      modif_toa = (modif_toa - ntdma * (TPU_CLOCK_RANGE/4)) * 4;  // Unit is changed from bit to qbit.
+    }
+
+    switch (task)
+    {
+      case FBNEW:
+      // Compute NTDMA & TOA taking into account the 23 bit guard for next SB receive window.
+      {
+        // "fn_offset" loaded with serving frame number corresponding to FB.
+        // Keep a %51 format to prepare SB scheduling.
+        fn_offset = (l1s.actual_time.fn - attempt + ntdma + MAX_FN) % 51;
+      }
+      break;
+
+      case FB51:
+      // Compute NTDMA & TOA taking into account the 23 bit guard for next SB receive window.
+      {
+        // "fn_offset" loaded with serving frame number corresponding to FB.
+        // Keep a full frame number to allow scheduling of SB, 2 MF51 later.
+        fn_offset = (l1s.actual_time.fn - attempt + ntdma + MAX_FN) % MAX_FN;
+      }
+      break;
+
+      case FB26:
+      {
+        // "fn_offset" loaded with serving frame number corresponding to CTL(SB26).
+        fn_offset = (l1s.actual_time.fn + 52 - 3) % MAX_FN;
+
+        if(ntdma == 1) // 2nd frame...
+          l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].sb26_offset = 1;
+        else
+          l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].sb26_offset = 0;
+      }
+      break;
+    } // End of switch.
+
+  } // End if.
+
+  // Store TOA and FN offset in neighbor cell structure.
+  l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].time_alignmt = modif_toa;
+  l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].fn_offset    = fn_offset;
+
+  // Create message T_L1C_FB_INFO.
+  msg = os_alloc_sig(sizeof(T_L1C_FB_INFO));
+  DEBUGMSG(status,NU_ALLOC_ERR)
+  msg->SignalCode = L1C_FB_INFO;
+
+  // Fill msg fields.
+  ((T_L1C_FB_INFO *) (msg->SigP))->fb_flag    = fb_flag;
+  ((T_L1C_FB_INFO *) (msg->SigP))->ntdma      = ntdma;
+  ((T_L1C_FB_INFO *) (msg->SigP))->neigh_id   = l1a_l1s_com.nsync.active_fb_id;
+  // Debug info or testmode
+  ((T_L1C_FB_INFO *) (msg->SigP))->pm       = pm;
+  ((T_L1C_FB_INFO*)(msg->SigP))->toa        = toa;
+  ((T_L1C_FB_INFO*)(msg->SigP))->angle      = angle;
+  ((T_L1C_FB_INFO*)(msg->SigP))->snr        = snr;
+  ((T_L1C_FB_INFO *) (msg->SigP))->radio_freq = l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq;
+
+  os_send_sig(msg, L1C1_QUEUE);
+  DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+}
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+#endif // MOVE_IN_INTERNAL_RAM
+
+#if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+/*-------------------------------------------------------*/
+/* l1s_read_sb()                                         */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality : this function sends L1C_SB_INFO to L1A*/
+/*-------------------------------------------------------*/
+void l1s_read_sb(UWORD8 task, UWORD32 flag, API *data, UWORD32 toa, UWORD8 attempt,
+                 UWORD32 pm, UWORD32 angle, UWORD32 snr)
+{
+  xSignalHeaderRec  *msg;
+  UWORD8             bsic=0;
+  UWORD32            sb;
+  WORD32             modif_toa = 0;
+  UWORD32            fn_offset    = 0;
+  WORD32             time_alignmt = 0;
+  T_NCELL_SINGLE    *cell_ptr = NULL; //omaps00090550 NULL;
+  UWORD32            SignalCode=0;
+  UWORD8             fn_delay     = 2; // SB result read with 2 frames delay.
+  UWORD8             neigh_id=0;
+  UWORD32            fn;
+
+  switch(task)
+  {
+    case SB2 :
+    case SB51 :
+    case SB26 :
+      // Get Neighbour cell ptr.
+      cell_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sb_id];
+      neigh_id = l1a_l1s_com.nsync.active_sb_id;
+
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_READ_SB, cell_ptr->radio_freq);
+      #endif
+
+      SignalCode = L1C_SB_INFO;
+      if(task == SB26) fn_delay = 3 - l1a_l1s_com.nsync.list[neigh_id].sb26_offset;
+    break;
+
+    case SBCONF :
+    case SBCNF51 :
+    case SBCNF26 :
+      // Get Neighbour cell ptr.
+      cell_ptr = &l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_sbconf_id];
+      neigh_id = l1a_l1s_com.nsync.active_sbconf_id;
+
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_READ_SBCONF, cell_ptr->radio_freq);
+      #endif
+
+      SignalCode = L1C_SBCONF_INFO;
+      if(task == SBCNF26) fn_delay = 3 - l1a_l1s_com.nsync.list[neigh_id].sb26_offset;
+    break;
+  }
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dspres(dltsk_trace[task].name);
+  #endif
+
+  // Compute NTDMA & TOA taking into account the 23 bit guard for next SB receive window.
+  modif_toa = (toa - (SB_MARGIN/4)) * 4;       // Rem: unit is "QBIT".
+
+  // Read SB content,.
+  sb = data[0] & 0xffff | ((data[1] & 0xffff) << 16);
+
+  if (flag == TRUE)
+  // SB has been found...
+  // We synchronized with a NEIGHBOUR cell.
+  {
+    UWORD32    t1, t2, t3, t3p;
+
+    // extract BSIC, T1, T2, T3. Compute FN.
+    // bsic contains NCC & BCC (GSM05.02, p9)
+    bsic   = (UWORD8) ((sb & 0x000000fc) >> 2);
+
+    t1  = ((sb & 0x00800000) >> 23 |   // t1 low
+           (sb & 0x0000ff00) >> 7  |   // t1 midle
+           (sb & 0x00000003) << 9);    // t1 high
+    t2  =  (sb & 0x007c0000) >> 18;
+    t3p = ((sb & 0x01000000) >> 24 |   // t3p low
+           (sb & 0x00030000) >> 15);   // t3p high
+    t3  =  (10*(t3p) +1);
+    fn  =  (51 * ((t3 - t2 + 26) % 26) + t3 + (26 * 51 * t1));
+
+    // Due to pipeline effect (CTRL.WORK.WORK.READ), sb content is taken into account
+    // "fn_delay" TDMA later: that's why we use "fn + fn_delay..." in the offset computation.
+    //
+    // NEIGHBOUR DOMAIN:
+    // -----------------
+    // |                    |<----- 1 TDMA ----->| SB                 |                    |
+    // |                    |                    |XXXX                |                    |
+    // |                    |                    |                    |                    |
+    // |                    |                    |  FN_neighbour(SB)  | FN_neighbour(SB)+1 | FN_neighbour(SB)+2
+    // |                    |                    |                    |                    |
+    //                                                                            offset   |
+    //                                                                              +      |
+    //                                                                             BOB     |
+    //                                                                       |<----------->|
+    // MS DOMAIN:                                                            |
+    // ----------                  |                    |                    |                    |
+    //        |        CTRL        |        WORK        |        WORK        |         READ       |
+    //        |                    |                    |                    |                    |
+    //
+    // offset = FN_neighbour(SB)+ fn_delay - FN_serving(READ).
+    // Bob: fine timing difference between the Neighbour timing and the MS internal timing.
+    //
+    fn_offset = (fn + fn_delay + MAX_FN - l1s.actual_time.fn) % MAX_FN;
+
+    // "time_alignmt" must be corrected (use "modif_toa" from the SB read).
+    // Check that "time_alignmt" do not become bigger than "TPU_CLOCK_RANGE".
+    // If so, "fn_offset" must be decremented.
+    time_alignmt   = cell_ptr->time_alignmt + modif_toa;
+    if(time_alignmt >= TPU_CLOCK_RANGE)
+    {
+      time_alignmt -= TPU_CLOCK_RANGE;  // qbp for sim. Normal value is 1250;
+      fn_offset    -= 1;                // WARNING....to be checked!!!!!!
+    }
+    else
+    if(time_alignmt < 0)
+    {
+      time_alignmt += TPU_CLOCK_RANGE;  // qbp for sim. Normal value is 1250;
+      fn_offset    += 1;                // WARNING....to be checked!!!!!!
+    }
+  }
+
+  #if L1_RECOVERY
+    if(flag)
+    {
+      // recovery flag is reseted because the system works fine
+      // this check is performed in all modes.
+      l1a_l1s_com.recovery_flag = FALSE;
+
+      // Reset error flags and counter
+      l1s.recovery.frame_count  = 0;
+    }
+  #endif
+
+  // In all mode send result message to L1 Async.
+  msg = os_alloc_sig(sizeof(T_MPHC_NCELL_SYNC_IND));
+  DEBUGMSG(status,NU_ALLOC_ERR)
+  msg->SignalCode   = SignalCode;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->sb_flag      = flag;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->radio_freq   = cell_ptr->radio_freq;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->bsic         = bsic;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->fn_offset    = fn_offset;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->time_alignmt = time_alignmt;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->neigh_id     = neigh_id;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->attempt      = attempt;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->pm           = pm;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->toa          = toa;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->angle        = angle;
+  ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->snr          = snr;
+
+
+  #if (L1_EOTD == 1)
+  // In EOTD mode read additional results
+  if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
+  {
+    UWORD8  i;
+    WORD16  d_eotd_first;
+    WORD16  d_eotd_max;
+    UWORD32 d_eotd_nrj;
+    API     *data = &(l1s_dsp_com.dsp_ndb_ptr->a_eotd_crosscor[0]);
+    UWORD32 fn_sb_neigh;
+
+    d_eotd_first   = l1s_dsp_com.dsp_ndb_ptr->d_eotd_first & 0xffff;
+
+    d_eotd_max     = l1s_dsp_com.dsp_ndb_ptr->d_eotd_max & 0xffff;
+
+    fn_sb_neigh = (l1s.actual_time.fn - fn_delay + MAX_FN) % MAX_FN;
+    ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->fn_sb_neigh  = fn_sb_neigh;
+
+    d_eotd_nrj   = (l1s_dsp_com.dsp_ndb_ptr->d_eotd_nrj_low & 0xffff) |
+                   ((l1s_dsp_com.dsp_ndb_ptr->d_eotd_nrj_high & 0x00ff) << 16);
+
+    // L1 SW :
+    //         CPS Cursor expects the accumulated signal level of the cross
+    //         correlation (d_eotd_nrj) to be 16bit format. The DSP reports
+    //         it as 24bit format (lsb aligned in a 32bit word).
+    //         We scale the DSP result by right shifting by 8, hence preserving
+    //         the MSBs
+
+    d_eotd_nrj >>= 8;
+
+    ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->eotd_data_valid = TRUE;
+    ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->d_eotd_first    = d_eotd_first;
+    ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->d_eotd_max      = d_eotd_max;
+    ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->d_eotd_nrj      = d_eotd_nrj;
+    ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->fn_in_SB        = fn;
+    for (i=0; i<18; i++)
+      ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->a_eotd_crosscor[i] = data[i] & 0xffff;;
+
+    if(task == SBCNF26)
+    {
+      ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->toa_correction =
+        l1a_l1s_com.nsync.eotd_cache_toa_tracking;
+    }
+    else
+    {
+      ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->toa_correction = 0;
+    }
+
+  }
+  else
+   ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->eotd_data_valid = FALSE;
+#endif
+
+
+
+  os_send_sig(msg, L1C1_QUEUE);
+  DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+}
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+#endif // MOVE_IN_INTERNAL_RAM
+
+#if (MOVE_IN_INTERNAL_RAM == 0) // Must be followed by the pragma used to duplicate the funtion in internal RAM
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+/*-------------------------------------------------------*/
+/* l1s_read_fbsb()                                       */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality : sends L1C_FBSB_INFO to L1A            */
+/*-------------------------------------------------------*/
+#if ((REL99 == 1) && (FF_BHO == 1))
+void l1s_read_fbsb(UWORD8 task, UWORD8 attempt, BOOL fb_flag,  BOOL sb_flag, API *data, UWORD32 toa, UWORD32 pm, UWORD32 angle, UWORD32 snr)
+{
+  xSignalHeaderRec  *msg;
+  UWORD8             bsic = 0;
+  UWORD32            fn_offset = 0;
+  UWORD32            time_alignmt = 0;
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dspres(dltsk_trace[task].name);
+  #endif
+
+  #if (TRACE_TYPE!=0)
+    // trace_fct(CST_L1S_READ_FBSB, l1a_l1s_com.nsync_fbsb.radio_freq);
+  #endif
+
+  if ((fb_flag == TRUE) && (sb_flag == TRUE))
+  {
+    UWORD32    toa_qbit, sb, fn, fn2, t1, t2, t3, t3p;
+    UWORD8     ntdma;
+
+    // Read SB content,.
+    sb = data[0] & 0xffff | ((data[1] & 0xffff) << 16);
+
+    // extract BSIC, T1, T2, T3. Compute FN.
+    // bsic contains NCC & BCC (GSM05.02, p9)
+    bsic   = (UWORD8) ((sb & 0x000000fc) >> 2);
+
+    t1  = ((sb & 0x00800000) >> 23 |   // t1 low
+           (sb & 0x0000ff00) >> 7  |   // t1 midle
+           (sb & 0x00000003) << 9);    // t1 high
+    t2  =  (sb & 0x007c0000) >> 18;
+    t3p = ((sb & 0x01000000) >> 24 |   // t3p low
+           (sb & 0x00030000) >> 15);   // t3p high
+    t3  =  (10*(t3p) +1);
+    fn  =  (51 * ((t3 - t2 + 26) % 26) + t3 + (26 * 51 * t1));
+
+    // _|-----------------------------------|___  : TPU WINDOW
+    //                    |FB|          |SB|
+    // _|---------------->|--------->|->|
+    //        toa_fb       1 frame  toa_sb
+    //
+    //  we also need to take into account the 23 bit guard for SB receive window.
+
+    toa_qbit = (l1a_l1s_com.nsync_fbsb.fb_toa + toa) * 4 + TPU_CLOCK_RANGE - SB_MARGIN;
+
+    ntdma = toa_qbit / TPU_CLOCK_RANGE;
+
+    fn_offset = (fn - l1s.actual_time.fn + attempt - ntdma + (2 * MAX_FN))% MAX_FN;
+
+    time_alignmt = toa_qbit - (ntdma * TPU_CLOCK_RANGE);
+  }
+
+  // Create message T_L1C_FBSB_INFO.
+  msg = os_alloc_sig(sizeof(T_L1C_FB_INFO));
+  DEBUGMSG(status,NU_ALLOC_ERR)
+  msg->SignalCode = L1C_FBSB_INFO;
+
+  // Fill msg fields.
+  ((T_L1C_FBSB_INFO *) (msg->SigP))->fb_flag      = fb_flag;
+  ((T_L1C_FBSB_INFO *) (msg->SigP))->sb_flag      = sb_flag;
+  ((T_L1C_FBSB_INFO *) (msg->SigP))->bsic         = bsic;
+  ((T_L1C_FBSB_INFO *) (msg->SigP))->fn_offset    = fn_offset;
+  ((T_L1C_FBSB_INFO *) (msg->SigP))->time_alignmt = time_alignmt;
+  ((T_L1C_FBSB_INFO *) (msg->SigP))->pm           = pm;
+  ((T_L1C_FBSB_INFO *) (msg->SigP))->toa          = toa;
+  ((T_L1C_FBSB_INFO *) (msg->SigP))->angle        = angle;
+  ((T_L1C_FBSB_INFO *) (msg->SigP))->snr          = snr;
+
+
+  os_send_sig(msg, L1C1_QUEUE);
+  DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+}
+#endif // #if ((REL99 == 1) && (FF_BHO == 1))
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+#endif // MOVE_IN_INTERNAL_RAM
+
+#if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0))  // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START         // KEEP IN EXTERNAL MEM otherwise
+
+/*-------------------------------------------------------*/
+/* l1s_read_l3frm()                                      */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality : reads NB data                         */
+/*                 and formate MPHC_DATA_IND message     */
+/*-------------------------------------------------------*/
+void l1s_read_l3frm(UWORD8 pwr_level, API *info_address, UWORD32 task_rx)
+{
+  xSignalHeaderRec *msg;
+  UWORD32           i,j;
+  UWORD32           word32;
+  UWORD32           rx_fail_flag;
+  //OMAPS00090550 UWORD32           b_fire0;
+  UWORD32           b_fire1;
+  UWORD8            tc = l1s.actual_time.tc; // Default: tc loaded with current serving TC.
+  UWORD16           radio_freq = l1a_l1s_com.Scell_info.radio_freq; // Default: radio_freq load with serving cell
+
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dspres(dltsk_trace[task_rx].name);
+  #endif
+
+  // Allocate result message.
+
+  #if (GSM_IDLE_RAM == 1)         // GPF not modified for GSM_IDLE_RAM -> enable Traffic Controller in L1S
+    if (!READ_TRAFFIC_CONT_STATE)
+    CSMI_TrafficControllerOn();
+  #endif
+
+  msg = os_alloc_sig(sizeof(T_MPHC_DATA_IND));
+  DEBUGMSG(status,NU_ALLOC_ERR)
+
+  switch(task_rx)
+  {
+    case NP:
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_READ_L3FRM__NP, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+      // Fill msg signal code and L2 channel.
+      msg->SignalCode = L1C_NP_INFO;
+      ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_PCH;
+    break;
+
+    case EP:
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_READ_L3FRM__EP, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+      // Fill msg signal code and L2 channel.
+      msg->SignalCode = L1C_EP_INFO;
+      ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_EPCH;
+    break;
+
+    case NBCCHS:
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_READ_L3FRM__NBCCHS, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+      // Fill msg signal code and L2 channel.
+      msg->SignalCode = L1C_BCCHS_INFO;
+      ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_NBCCH;
+    break;
+
+    case EBCCHS:
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_READ_L3FRM__EBCCHS, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+      // Fill msg signal code and L2 channel.
+      msg->SignalCode = L1C_BCCHS_INFO;
+      ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_EBCCH;
+    break;
+
+    case BCCHN:
+    #if L1_GPRS
+    case BCCHN_TRAN:
+    #endif
+    case BCCHN_TOP:
+      #if (TRACE_TYPE!=0)
+        if (task_rx == BCCHN)
+          trace_fct(CST_L1S_READ_L3FRM__BCCHN, l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm].radio_freq);
+        else // BCCHN_TRAN and BCCHN_TOP tasks
+          trace_fct(CST_L1S_READ_L3FRM__BCCHN, l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top].radio_freq);
+      #endif
+
+      // Fill msg signal code, L2 channel and get neighbour TC.
+      msg->SignalCode = L1C_BCCHN_INFO;
+
+      // Save neighbour ID.
+      // With TC and Neighbour ID, L1A can manage the remaining BCCH requests.
+      if (task_rx == BCCHN)
+      {
+        ((T_MPHC_DATA_IND *)(msg->SigP))->neigh_id = l1a_l1s_com.bcchn.active_neigh_id_norm;
+        tc = l1a_l1s_com.bcchn.active_neigh_tc_norm;
+        radio_freq = l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_norm].radio_freq;
+      }
+      else // BCCHN_TRAN and BCCHN_TOP tasks
+      {
+        ((T_MPHC_DATA_IND *)(msg->SigP))->neigh_id = l1a_l1s_com.bcchn.active_neigh_id_top;
+        tc = l1a_l1s_com.bcchn.active_neigh_tc_top;
+        radio_freq = l1a_l1s_com.bcchn.list[l1a_l1s_com.bcchn.active_neigh_id_top].radio_freq;
+      }
+
+      if(tc >= 8)
+      {
+        // Reading Extended BCCH.
+        tc -= 8;
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_EBCCH;
+      }
+      else
+      {
+        // Reading Normal BCCH.
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_NBCCH;
+      }
+
+    break;
+
+    case ALLC:
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_READ_L3FRM__ALLC, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+      // Fill msg signal code, L2 channel and get neighbour TC.
+      msg->SignalCode = L1C_ALLC_INFO;
+      ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_CCCH;
+    break;
+
+    case SMSCB:
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1S_READ_L3FRM__CB, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+      // Fill msg signal code, L2 channel and get neighbour TC.
+      msg->SignalCode = L1C_CB_INFO;
+      ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_CBCH;
+    break;
+
+    #if L1_GPRS
+
+      case PNP:
+        #if (TRACE_TYPE!=0)
+          trace_fct(CST_L1PS_READ_L3FRM__PNP, l1a_l1s_com.Scell_info.radio_freq);
+        #endif
+
+        // Fill msg signal code and L2 channel.
+        msg->SignalCode = L1P_PNP_INFO;
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PPCH;
+        tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+      break;
+
+      case PEP:
+        #if (TRACE_TYPE!=0)
+          trace_fct(CST_L1PS_READ_L3FRM__PEP, l1a_l1s_com.Scell_info.radio_freq);
+        #endif
+
+        // Fill msg signal code and L2 channel.
+        msg->SignalCode = L1P_PEP_INFO;
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PEPCH;
+        tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+      break;
+
+      case PALLC:
+        #if (TRACE_TYPE!=0)
+          trace_fct(CST_L1PS_READ_L3FRM__PALLC, l1a_l1s_com.Scell_info.radio_freq);
+        #endif
+
+        // Fill msg signal code and L2 channel.
+        msg->SignalCode = L1P_PALLC_INFO;
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PCCCH;
+        tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+      break;
+
+      case PBCCHS:
+        #if (TRACE_TYPE!=0)
+          trace_fct(CST_L1PS_READ_L3FRM__PBCCHS, l1a_l1s_com.Scell_info.radio_freq);
+        #endif
+
+        // Fill msg signal code and L2 channel.
+        msg->SignalCode = L1P_PBCCHS_INFO;
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PBCCH;
+        tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+      break;
+
+      case PBCCHN_IDLE:
+      case PBCCHN_TRAN:
+        #if (TRACE_TYPE!=0)
+          trace_fct(CST_L1PS_READ_L3FRM__PBCCHN, l1pa_l1ps_com.pbcchn.bcch_carrier);
+        #endif
+
+        // Fill msg signal code and L2 channel.
+        msg->SignalCode = L1P_PBCCHN_INFO;
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PBCCH;
+        tc = l1pa_l1ps_com.pbcchn.relative_position;
+        radio_freq = l1pa_l1ps_com.pbcchn.bcch_carrier;
+      break;
+
+      case SINGLE:
+        #if (TRACE_TYPE!=0)
+          trace_fct(CST_L1PS_READ_L3FRM__SINGLE, l1a_l1s_com.Scell_info.radio_freq);
+        #endif
+
+        // Fill L2 channel.
+        msg->SignalCode = L1P_PACCH_INFO;
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_PCHANNEL_PACCH;
+        tc = l1pa_l1ps_com.pbcchs.rel_pos_to_report;
+      break;
+
+    #endif
+
+    // WARNING !!! to be removed (for CBCH debugging).
+    default:
+      #if (TRACE_TYPE!=0)
+        trace_fct(CST_L1PS_READ_L3FRM__UNKNOWN, l1a_l1s_com.Scell_info.radio_freq);
+      #endif
+
+      // Fill msg signal code, L2 channel and get neighbour TC.
+      msg->SignalCode = L1C_CB_INFO;
+      ((T_MPHC_DATA_IND *)(msg->SigP))->l2_channel = L2_CHANNEL_CCCH;
+  }
+
+  #if L1_GPRS
+  if (l1a_l1s_com.dsp_scheduler_mode == GSM_SCHEDULER)
+  #endif
+  {
+    // Compute detection flag.
+ //OMAPS00090550   b_fire0 = ((info_address[0] & 0xffff) & (1<<B_FIRE0)) >> B_FIRE0;
+    b_fire1 = ((info_address[0] & 0xffff) & (1<<B_FIRE1)) >> B_FIRE1;
+    if(b_fire1 != 1)
+      rx_fail_flag = FALSE;  // information block received successfully.
+    else
+      rx_fail_flag = TRUE;   // information block reception failled.
+
+    // Get 23 bytes info. from DSP.
+    for (j=0, i=0; i<11; i++)
+    {
+      word32 = info_address[3 + i]; // Get info word, rem: skip info. header.
+      ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x000000ff);
+      ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x0000ff00) >> 8;
+    }
+    ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[22] = (info_address[14] & 0x000000ff);
+
+    // reset buffers and flags in NDB ...
+    // B_FIRE1 =1, B_FIRE0 =0 , BLUD =0
+    info_address[0] = (1<<B_FIRE1);
+  }
+  #if L1_GPRS
+    else // GPRS scheduler
+    {
+      // Compute detection flag.
+      rx_fail_flag = ((*info_address & 0x0100) >> 8);
+
+      // Get 24 bytes info. from DSP: CS1 meaningful block is of size 12 UWORD16 data.
+      // !!! WARNING: word32 type is for compatibility with chipset == 0.
+      // Can be word16 if only chipset == 2 is used.
+      for (j=0, i=0; i<12; i++)
+      {
+        // Data downloaded from a_dd_gprs[0][]...
+        word32 = info_address[4 + i]; // Get info word, rem: skip info. header.
+        #if 0	/* FreeCalypso TCS211 reconstruction */
+        if(j<23)
+        #endif
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x000000ff);
+        #if 0	/* FreeCalypso TCS211 reconstruction */
+        if(j<23)
+        #endif
+        ((T_MPHC_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x0000ff00) >> 8;
+      }
+
+      // reset buffers and flags in NDB ...
+      // reset CS_TYPE
+      info_address[0] = CS_NONE_TYPE;
+    }
+  #endif
+
+  // Report detection flag.
+  if((l1s_dsp_com.dsp_db_r_ptr->d_debug & 0xffff ) != (l1s.debug_time & 0xffff )) // in case of COM error the block is false
+    ((T_MPHC_DATA_IND *)(msg->SigP))->error_flag = TRUE;
+  else
+    ((T_MPHC_DATA_IND *)(msg->SigP))->error_flag = rx_fail_flag;
+
+  // be careful: radio_freq is setted at the beging of the code and may be modified inside the "case"
+  ((T_MPHC_DATA_IND *)(msg->SigP))->radio_freq = radio_freq;
+
+   // be careful: tc is setted at the beging of the code and may be modified inside the "case"
+  ((T_MPHC_DATA_IND *)(msg->SigP))->tc = tc;
+
+  // convert in ETSI format and send it back to L3
+  ((T_MPHC_DATA_IND *)(msg->SigP))->ccch_lev = l1s_encode_rxlev(pwr_level);
+
+#if (FF_L1_FAST_DECODING == 1)
+  // Update the fn according to the number of the last decoded burst (2, 3 or 4) in case of fast paging: alignment with a block boudary
+  if(l1a_l1s_com.last_fast_decoding == 0)
+    // fast decoding was not not used
+  ((T_MPHC_DATA_IND *)(msg->SigP))->fn       = l1s.actual_time.fn;
+  else
+    // fast decoding done, fn is incremented up to 2 frames (if fast decoding with 2 bursts), 0 if fast decoding with 4 bursts (normal decoding)
+    ((T_MPHC_DATA_IND *)(msg->SigP))->fn       = l1s.actual_time.fn + BURST_4 + 1 - l1a_l1s_com.last_fast_decoding;
+#else
+    ((T_MPHC_DATA_IND *)(msg->SigP))->fn       = l1s.actual_time.fn;
+#endif
+  // send message...
+
+  os_send_sig(msg, L1C1_QUEUE);
+  DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+}
+
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+#endif
+/*-------------------------------------------------------*/
+/* l1s_read_sacch_dl()                                   */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality : reads NB data                         */
+/*-------------------------------------------------------*/
+void l1s_read_sacch_dl(API *info_address, UWORD32 task_rx)
+{
+  xSignalHeaderRec *msg;
+  UWORD32           i,j;
+  UWORD32           word32;
+  UWORD32           rx_fail_flag;
+ //OMAPS00090550 UWORD32           b_fire0;
+  UWORD32           b_fire1;
+  #if  (FF_REPEATED_SACCH == 1)
+      BOOL           b_joint= 0; /* The flag to read the DSP response on combining */
+      static BOOL prevfail = 0;
+  #endif /* (FF_REPEATED_SACCH == 1) */
+
+  // Traces.
+  #if (TRACE_TYPE==5) && FLOWCHART
+    trace_flowchart_dspres(dltsk_trace[task_rx].name);
+  #endif
+
+  #if (TRACE_TYPE!=0)
+    if(task_rx == ADL)  trace_fct(CST_L1S_READ_SACCH_DL__ADL, l1a_l1s_com.dedic_set.radio_freq_dd);
+    if(task_rx == TCHA) trace_fct(CST_L1S_READ_SACCH_DL__TCHA, l1a_l1s_com.dedic_set.radio_freq_dd);
+  #endif
+
+ #if (((TRACE_TYPE==1) || (TRACE_TYPE==4)) && ((FF_REPEATED_SACCH == 1)))
+    trace_info.repeat_sacch.dl_count ++;        /* It is a SACCH downlink block */
+
+ #endif
+  // Compute detection flag.
+ //OMAPS00090550 b_fire0 = ((info_address[0] & 0xffff) & (1<<B_FIRE0)) >> B_FIRE0;
+  b_fire1 = ((info_address[0] & 0xffff) & (1<<B_FIRE1)) >> B_FIRE1;
+  if(b_fire1 != 1)
+    rx_fail_flag = FALSE;  // information block received successfully.
+  else
+    rx_fail_flag = TRUE;   // information block reception failled.
+
+#if  (FF_REPEATED_SACCH == 1)
+     b_joint = (BOOL)(((info_address[0] & 0xffff) & (1<<B_JOINT)) >> B_JOINT);
+
+#endif  /* (FF_REPEATED_SACCH == 1) */
+  // Clear 1st word of header.
+  info_address[0] = 0;
+
+    #if ((TESTMODE) && ((FF_REPEATED_SACCH == 1)) )
+	     if(l1_config.repeat_sacch_enable != REPEATED_SACCH_ENABLE)
+	     {
+	         l1s.repeated_sacch.srr = 0;
+	         #if (TRACE_TYPE == 1 || TRACE_TYPE == 4)
+	         trace_info.repeat_sacch.dl_buffer_empty = TRUE;
+	         #endif /* TRACE_TYPE*/
+	      }
+	     else
+	     {
+	#endif /* ((TESTMODE) && ((FF_REPEATED_SACCH == 1))) */
+
+
+	#if  (FF_REPEATED_SACCH == 1)
+
+	      if( (b_joint==TRUE) || (rx_fail_flag==TRUE ))
+	      {
+	          /* chase combining  occurred or the current block was unsuccessfully decoded.*/
+	          l1s.repeated_sacch.srr = 1;
+
+	      }
+	      else
+	      {
+	          l1s.repeated_sacch.srr = 0; // debug
+
+	      }
+
+
+	#endif /* (FF_REPEATED_SACCH == 1) */
+    #if ((TESTMODE) && ((FF_REPEATED_SACCH == 1)) )
+		    } /* end else l1_config.repeat_sacch_enable */
+	#endif /* ((TESTMODE) && ((FF_REPEATED_SACCH == 1))) */
+
+	#if ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH))
+	      trace_info.repeat_sacch.srr = l1s.repeated_sacch.srr;
+	      if(b_joint == TRUE && b_fire1!=1)
+	      {
+	           trace_info.repeat_sacch.dl_combined_good_count ++;
+	           if (prevfail == 1)
+	          trace_info.repeat_sacch.dl_error_count--;
+	      }
+	#endif /* ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH)) */
+
+#if ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH))
+	      trace_info.repeat_sacch.srr = l1s.repeated_sacch.srr;
+	      if( rx_fail_flag == TRUE) /* Information reception failed */
+	      {
+	           trace_info.repeat_sacch.dl_error_count ++;
+	      }
+
+#endif /* ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH)) */
+
+  #if TESTMODE
+    // Continunous mode: the SAACH data aren't valid. Therefore don't send to L1A.
+    if ((!l1_config.TestMode) || ((l1_config.TestMode) &&
+        (l1_config.tmode.rf_params.tmode_continuous == TM_NO_CONTINUOUS)))
+  #endif
+    {
+      // Allocate result message.
+      msg = os_alloc_sig(sizeof(T_PH_DATA_IND));
+      DEBUGMSG(status,NU_ALLOC_ERR)
+      msg->SignalCode = L1C_SACCH_INFO;
+      ((T_PH_DATA_IND *)(msg->SigP))->l2_channel_type = L2_CHANNEL_SACCH;
+
+      // Catch L1 Header if SACCH/DL data block successfully received.
+      if(rx_fail_flag == FALSE)
+      {
+        UWORD8  supplied_txpwr = info_address[3] & 0x0000001f;
+        UWORD8  supplied_ta    = (info_address[3] & 0x00007f00) >> 8;
+
+        #if (FF_REPEATED_SACCH == 1)
+		    //Set SRO parameter to transmit to the UL
+		    l1s.repeated_sacch.sro = (info_address[3] & 0x00000040) >> 6;
+             		 /*
+			 		       7   | 6  |  5      | 4   3   2   1    0
+			 		    Spare  | SRO| FPC EPC | Ordered MS power level
+			 		    	   |    Ordered timing advance
+
+		             */
+		#endif /* (FF_REPEATED_SACCH == 1) */
+        // Check max transmit power (min txpwr) according to powerclass.
+        supplied_txpwr =  l1a_clip_txpwr(supplied_txpwr,l1a_l1s_com.dedic_set.radio_freq);
+
+        #if TESTMODE
+          // Update txpwr and ta only during Normal Mode
+          if (!l1_config.TestMode)
+        #endif
+          {
+            l1a_l1s_com.dedic_set.aset->new_target_txpwr = supplied_txpwr;
+
+            // Check if supplied TA is valid, if not keep previous value.
+            if(supplied_ta < 64)
+              l1a_l1s_com.dedic_set.aset->new_timing_advance = supplied_ta;
+          }
+           #if ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH))
+		          l1s_check_sacch_dl_block(info_address);
+		          trace_info.repeat_sacch.sro = l1s.repeated_sacch.sro;
+		    #endif /* ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH)) */
+		  } /* end if rx_fail_flag */
+		  else
+		  {
+			  #if ((TRACE_TYPE==1 || TRACE_TYPE == 4) && (FF_REPEATED_SACCH))
+		       trace_info.repeat_sacch.dl_buffer_empty = TRUE;
+		      #endif
+       }
+
+      // Get 23 bytes info. from DSP.
+      for (j=0, i=0; i<11; i++)
+      {
+        word32 = info_address[3 + i]; // Get info word, rem: skip info. header.
+        ((T_PH_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x000000ff);
+        ((T_PH_DATA_IND *)(msg->SigP))->l2_frame.A[j++] = (word32 & 0x0000ff00) >> 8;
+      }
+      ((T_PH_DATA_IND *)(msg->SigP))->l2_frame.A[22] = (info_address[14] & 0x000000ff);
+
+      // Fill msg header...
+      ((T_PH_DATA_IND *)(msg->SigP))->rf_chan_num = l1a_l1s_com.Scell_info.radio_freq;
+      ((T_PH_DATA_IND *)(msg->SigP))->error_cause = rx_fail_flag;
+      ((T_PH_DATA_IND *)(msg->SigP))->bsic        = l1a_l1s_com.Scell_info.bsic;
+      ((T_PH_DATA_IND *)(msg->SigP))->tc          = l1s.actual_time.tc;
+
+      // send message...
+
+      os_send_sig(msg, L1C1_QUEUE);
+      DEBUGMSG(status,NU_SEND_QUEUE_ERR)
+
+    #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+      trace_info.sacch_d_nerr = info_address[2] & 0x00ff;
+    #endif
+    #if  (FF_REPEATED_SACCH == 1)
+       prevfail= rx_fail_flag ;
+    #endif /* (FF_REPEATED_SACCH == 1) */
+    }
+}
+
+/*-------------------------------------------------------*/
+/* l1s_read_dcch_dl()                                    */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality : reads FACCH DL data block.            */
+/*-------------------------------------------------------*/
+void l1s_read_dcch_dl(API *info_address, UWORD32 task_rx)
+{
+  UWORD8  rx_valid_flag = FALSE;
+  UWORD8 timing_advance = 255;
+  BOOL  b_joint ;  /* DSP indicator to Chase Combining */
+  #if (L1_SAGEM_INTERFACE == 1)
+  UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;
+  #endif
+
+  #if (FF_REPEATED_DL_FACCH == 1)
+      b_joint = (BOOL) (((info_address[0] & 0xffff) & (1<<B_JOINT)) >> B_JOINT);
+
+    #if TESTMODE
+          if(l1_config.repeat_facch_dl_enable != REPEATED_FACCHDL_ENABLE)  /*  repeated FACCH mode is disabled  */
+            b_joint = FALSE;
+    #endif /* TESTMODE */
+
+  #endif /* (FF_REPEATED_DL_FACCH == 1) */
+
+
+  if(info_address != NULL)
+  // A data block must be passed to L2.
+  {
+    UWORD32 b_fire1;
+
+    #if (TRACE_TYPE!=0)
+      if(task_rx == DDL)   trace_fct(CST_L1S_READ_DCCH_DL__DDL,   l1a_l1s_com.dedic_set.radio_freq_dd);
+      if(task_rx == TCHTF) trace_fct(CST_L1S_READ_DCCH_DL__TCHTF, l1a_l1s_com.dedic_set.radio_freq_dd);
+      if(task_rx == TCHTH) trace_fct(CST_L1S_READ_DCCH_DL__TCHTH, l1a_l1s_com.dedic_set.radio_freq_dd);
+    #endif
+
+    // Set detection flag.
+    b_fire1 = ((info_address[0] & 0xffff) & (1<<B_FIRE1)) >> B_FIRE1;
+    if(b_fire1 != 1)
+      rx_valid_flag = TRUE;  // information block received successfully.
+    else
+      rx_valid_flag = FALSE; // information block reception failled.
+
+    if((rx_valid_flag == TRUE) && (l1a_l1s_com.dedic_set.aset->t3124 != 0))
+    // T3124 running...
+    // Check for PHYSICAL INFORMATION message from FACCH.
+    {
+      UWORD32  message_type = info_address[5] & 0x00ff;
+
+      if(message_type == 0x2D)
+      // FACCH message is a PHYSICAL INFORMATION message.
+      {
+        // Catch TIMING ADVANCE information.
+        timing_advance = (UWORD8)((info_address[5] & 0xff00) >> 8);
+        l1a_l1s_com.dedic_set.aset->new_timing_advance = timing_advance;
+        l1a_l1s_com.dedic_set.aset->timing_advance     = timing_advance;
+
+        // Reset T3124.
+        l1a_l1s_com.dedic_set.aset->t3124 = 0;
+
+        // Stop sending Handover Access burst.
+        l1a_l1s_com.dedic_set.aset->ho_acc_to_send = 0;
+
+        // Handover access procedure is completed.
+        // -> send L1C_HANDOVER_FINISHED message with "cause = COMPLETED" to L1A.
+        l1s_send_ho_finished(HO_COMPLETE);
+      }
+    }
+
+    // Clear 1st word of header.
+    info_address[0] = 0;
+
+    // Shift data block pointer to skip DSP header.
+    info_address = &(info_address[3]);
+
+    if (rx_valid_flag == TRUE)
+    {
+      #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+        trace_info.facch_dl_count ++;
+      #endif
+      #if (FF_REPEATED_DL_FACCH == 1)  /*Fire code is correct and information recieved successfully */
+       l1s_store_facch_buffer(l1s.repeated_facch, info_address);
+      #endif
+
+	/* trace for FER calculation (Repeated FACCH mode):                          */
+        /*  nb of DL FACCH blocks correctly decoded which is not a repetition  */
+
+      #if ((TRACE_TYPE==1|| TRACE_TYPE==4) && (FF_REPEATED_DL_FACCH))
+        trace_info.facch_dl_good_block_reported++;
+        if(b_joint == TRUE) /*  The combined block is successfully decoded */
+            trace_info.facch_dl_combined_good_count++;
+      #endif /* ((TRACE_TYPE==1|| TRACE_TYPE==4) && (FF_REPEATED_DL_FACCH)) */
+      #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+        Trace_dedic_tch_block_stat(FACCH_GOOD, l1s_dsp_com.dsp_ndb_ptr->a_fd[2], 0);
+      #endif
+    }
+    else
+    {
+      #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+        trace_info.facch_dl_fail_count ++;
+      #endif
+      #if (DEBUG_DEDIC_TCH_BLOCK_STAT == 1)
+        Trace_dedic_tch_block_stat(FACCH_BAD, l1s_dsp_com.dsp_ndb_ptr->a_fd[2], 0);
+      #endif
+    }
+  }
+     #if (FF_REPEATED_DL_FACCH == 1)
+     if(rx_valid_flag == FALSE)
+     {
+      l1s.repeated_facch.pipeline[l1s.repeated_facch.counter_candidate].buffer_empty=TRUE;
+     }
+     #endif  /* (FF_REPEATED_DL_FACCH == 1) */
+
+  #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+    RTTL1_FILL_DL_DCCH(rx_valid_flag, timing_advance)
+  #endif
+
+  // Pass data block to L2.
+#if (SEND_FN_TO_L2_IN_DCCH==1)
+#if (L1_SAGEM_INTERFACE == 1)
+    dll_dcch_downlink(info_address, rx_valid_flag, l1s.actual_time.fn, channel_type);
+#else
+  dll_dcch_downlink(info_address, rx_valid_flag, l1s.actual_time.fn);
+#endif
+#else
+#if (L1_SAGEM_INTERFACE == 1)
+    dll_dcch_downlink(info_address, rx_valid_flag, channel_type);
+#else
+  dll_dcch_downlink(info_address, rx_valid_flag);
+#endif
+#endif
+
+}
+
+#if (CHIPSET==15)
+/*-------------------------------------------------------*/
+/* l1s_reset_tx_ptr()                                    */
+/*-------------------------------------------------------*/
+/* Parameters :                                          */
+/* Return     :                                          */
+/* Functionality : Reset the TX data pointer for DRP     */
+/*                 after ABORT                           */
+/*-------------------------------------------------------*/
+
+#define L1_DRP_TX_PTR_RESET_SET    (0x00000020)
+#define L1_DRP_TX_PTR_RESET_RESET  (~(L1_DRP_TX_PTR_RESET_SET))
+
+void l1s_reset_tx_ptr(UWORD8 param1, UWORD8 param2)
+{
+    volatile UWORD32 *ptr_drp_init32;
+    ptr_drp_init32 = (UWORD32 *) (DRP_API_BASE_ADDRESS + DRP_REG_SRM_CW_ADDR); //0xFFFF1E00;
+
+    // Set the TX_PTR_RESET bit to 1 to reset TX RD and WR pointers
+    (*ptr_drp_init32) = (*ptr_drp_init32)|(L1_DRP_TX_PTR_RESET_SET);
+
+    // Reset the bit to zero as aslong as the bit is 1, pointers are in reset state
+    (*ptr_drp_init32) = (*ptr_drp_init32)&(L1_DRP_TX_PTR_RESET_RESET);
+}
+#endif