view src/cs/layer1/cfile/l1_func.c @ 479:e9e72ec7b318

aci2: Openmoko's SMS memory full bogon removed
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 14 Jun 2018 07:43:01 +0000
parents 50a15a54801e
children
line wrap: on
line source

/************* Revision Controle System Header *************
 *                  GSM Layer 1 software
 * L1_FUNC.C
 *
 *        Filename l1_func.c
 *  Copyright 2003 (C) Texas Instruments
 *
 ************* Revision Controle System Header *************/

#define  L1_FUNC_C

#include "l1_macro.h"
#include "l1_confg.h"

#if (CODE_VERSION == SIMULATION)
  #include <string.h>
  #include "l1_types.h"
  #include "sys_types.h"
  #include "l1_const.h"
  #include "l1_time.h"
  #include "l1_signa.h"
  #if TESTMODE
    #include "l1tm_defty.h"
  #endif
  #if (AUDIO_TASK == 1)
    #include "l1audio_const.h"
    #include "l1audio_cust.h"
    #include "l1audio_defty.h"
  #endif
  #if (L1_GTT == 1)
    #include "l1gtt_const.h"
    #include "l1gtt_defty.h"
  #endif
  #if (L1_MP3 == 1)
    #include "l1mp3_defty.h"
  #endif
  #if (L1_MIDI == 1)
    #include "l1midi_defty.h"
  #endif
//ADDED FOR AAC
  #if (L1_AAC == 1)
    #include "l1aac_defty.h"
  #endif
  #include "l1_defty.h"
  #include "cust_os.h"
  #include "l1_msgty.h"
  #include "l1_varex.h"
  #include "l1_proto.h"
  #include "l1_mftab.h"
  #include "l1_tabs.h"
  #include "l1_ver.h"

  #if L1_GPRS
    #include "l1p_cons.h"
    #include "l1p_msgt.h"
    #include "l1p_deft.h"
    #include "l1p_vare.h"
    #include "l1p_tabs.h"
    #include "l1p_macr.h"
  #endif

  #include "l1_rf2.h"
  #include <stdio.h>
  #include "sim_cfg.h"
  #include "sim_cons.h"
  #include "sim_def.h"
  #include "sim_var.h"

#else

  #include <string.h>
  #include "l1_types.h"
  #include "sys_types.h"
  #include "l1_const.h"
  #if (RF_FAM == 12)
    #include "l1_rf12.h"
  #elif (RF_FAM == 61)
    #include "l1_rf61.h"
  #endif
  #include "l1_time.h"
  #include "l1_signa.h"

  #if TESTMODE
    #include "l1tm_defty.h"
  #endif
  #if (AUDIO_TASK == 1)
    #include "l1audio_const.h"
    #include "l1audio_cust.h"
    #include "l1audio_defty.h"
  #endif
  #if (L1_GTT == 1)
    #include "l1gtt_const.h"
    #include "l1gtt_defty.h"
  #endif
  #if (L1_MP3 == 1)
    #include "l1mp3_defty.h"
  #endif
  #if (L1_MIDI == 1)
    #include "l1midi_defty.h"
  #endif
//ADDED FOR AAC
  #if (L1_AAC == 1)
    #include "l1aac_defty.h"
  #endif
  #include "l1_defty.h"
  #include "cust_os.h"
  #include "l1_msgty.h"
  #include "l1_varex.h"
  #include "l1_proto.h"
  #include "l1_mftab.h"
  #include "l1_tabs.h"
  #include "l1_ver.h"
  #include "tpudrv.h"

  #include "mem.h"
  #include "inth.h"
  #include "clkm.h"
  #include "rhea_arm.h"
  #include "dma.h"
  #include "ulpd.h"
  #include "leadapi.h"

  #if (OP_L1_STANDALONE)
  #if (CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || \
      (CHIPSET == 11) || (CHIPSET == 12) || (CHIPSET == 15)
    #include "dynamic_clock.h"
  #endif
  #endif


  #if L1_GPRS
    #include "l1p_cons.h"
    #include "l1p_msgt.h"
    #include "l1p_deft.h"
    #include "l1p_vare.h"
    #include "l1p_tabs.h"
    #include "l1p_macr.h"
  #endif

#endif
#include "l1_trace.h"

#if ((TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE==4) || (TRACE_TYPE==7))
   extern void L1_trace_string(char *s);
#endif


#if (CODE_VERSION != SIMULATION)

  /* DSP patch */
  #if (DWNLD == NO_DWNLD)
    const UWORD8  patch_array[1];
    const UWORD8  DspCode_array[1] ;
    const UWORD8  DspData_array[1];
  #elif (DWNLD == PATCH_DWNLD)
    extern const UWORD8  patch_array[] ;
    const UWORD8  DspCode_array[1] ;
    const UWORD8  DspData_array[1];
  #elif (DWNLD == DSP_DWNLD)
    const UWORD8 patch_array[1] ;
    extern const UWORD8 DspCode_array[] ;
    extern const UWORD8 DspData_array[];
  #else
    extern const UWORD8  patch_array[] ;
    extern const UWORD8  DspCode_array[] ;
    extern const UWORD8  DspData_array[];
  #endif

  extern const UWORD8  bootCode[] ;
  /* DSP patch */

#if ( FF_REPEATED_DL_FACCH == 1 )
   UWORD32  fn_prev; // Added as a debug stage..
#endif

/*-------------------------------------------------------*/
/* Prototypes of internal functions used in this file.   */
/*-------------------------------------------------------*/
void l1s_init_voice_blocks (void);

/*-------------------------------------------------------*/
/* Prototypes of external functions used in this file.   */
/*-------------------------------------------------------*/
void l1dmacro_synchro   (UWORD32 when, UWORD32 value);
void LA_ReleaseLead(void);
#if (CODE_VERSION != SIMULATION)
  void l1s_audio_path_control (UWORD16 FIR_selection, UWORD16 audio_loop);
#endif

#if (L1_GPRS)
  // external functions from GPRS implementation
  void initialize_l1pvar(void);
  void l1pa_reset_cr_freq_list(void);
#endif
/*-------------------------------------------------------*/
/* dsp_power_on()                                        */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/* Remarq :   USART Buffer is 256 characters. While USART*/
/*            is not run during Application_Initialize   */
/*            (hisrs not served because Nucleus scheduler*/
/*             is not running yet) :                     */
/*            ==> check string size < 256 !!!!!!         */
/*-------------------------------------------------------*/
void dsp_power_on(void)
{
    UWORD16 dsp_start_address;
    UWORD16 param_size;
    #if IDS
      UWORD16 param_size2;
    #endif

    API i;
    API *pt;
    volatile WORD16 j;

    T_NDB_MCU_DSP * dsp_ndb_ptr;

    #if (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
      static API_SIGNED param_tab[] = {

          D_TRANSFER_RATE,

          // ..................Latencies
          D_LAT_MCU_BRIDGE,    D_LAT_MCU_HOM2SAM,

          D_LAT_MCU_BEF_FAST_ACCESS, D_LAT_DSP_AFTER_SAM,

          //...................p_gprs_install_adress
          D_HOLE,

          //...................d_misc_config
          D_MISC_CONFIG,


          //...................d_cn_sw_workaround
          C_DSP_SW_WORK_AROUND,

          //...................Reserved
          D_HOLE,              D_HOLE,
          D_HOLE,              D_HOLE,

          //...................Frequency burst
          D_FB_MARGIN_BEG,     D_FB_MARGIN_END,
          D_NSUBB_IDLE,        D_NSUBB_DEDIC,        D_FB_THR_DET_IACQ,
          D_FB_THR_DET_TRACK,
          //...................Demodulation
          D_DC_OFF_THRES,      D_DUMMY_THRES,        D_DEM_POND_GEWL,
          D_DEM_POND_RED,
          //...................TCH Full Speech
          D_MACCTHRESH1,       D_MLDT,               D_MACCTHRESH,
          D_GU,                D_GO,                 D_ATTMAX,
          D_SM,                D_B,

          //...................V42 bis
          D_V42B_SWITCH_HYST,  D_V42B_SWITCH_MIN,    D_V42B_SWITCH_MAX,
          D_V42B_RESET_DELAY,

          //...................TCH Half Speech
          D_LDT_HR,            D_MACCTRESH_HR,       D_MACCTRESH1_HR,
          D_GU_HR,             D_GO_HR,              D_B_HR,
          D_SM_HR,             D_ATTMAX_HR,

          //...................Added variables for EFR
          C_MLDT_EFR,          C_MACCTHRESH_EFR,     C_MACCTHRESH1_EFR,
          C_GU_EFR,            C_GO_EFR,             C_B_EFR,
          C_SM_EFR,            C_ATTMAX_EFR,

          //...................Full rate variables
          D_SD_MIN_THR_TCHFS,
          D_MA_MIN_THR_TCHFS,  D_MD_MAX_THR_TCHFS,   D_MD1_MAX_THR_TCHFS,

          //...................TCH Half Speech
          D_SD_MIN_THR_TCHHS, D_MA_MIN_THR_TCHHS, D_SD_AV_THR_TCHHS,
          D_MD_MAX_THR_TCHHS, D_MD1_MAX_THR_TCHHS,

          //...................TCH Enhanced Full Rate Speech
          D_SD_MIN_THR_TCHEFS,  D_MA_MIN_THR_TCHEFS,  D_MD_MAX_THR_TCHEFS,
          D_MD1_MAX_THR_TCHEFS, D_WED_FIL_INI,

          D_WED_FIL_TC,        D_X_MIN,              D_X_MAX,
          D_SLOPE,             D_Y_MIN,              D_Y_MAX,
          D_WED_DIFF_THRESHOLD,D_MABFI_MIN_THR_TCHHS,D_FACCH_THR,

          D_MAX_OVSPD_UL,      D_SYNC_THRES,        D_IDLE_THRES,
          D_M1_THRES,          D_MAX_OVSP_DL,       D_GSM_BGD_MGT
      };
      param_size = 79;

      #if (OP_L1_STANDALONE)
      #if (CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || \
          (CHIPSET == 11) || (CHIPSET == 12) || (CHIPSET == 15)
        /* Dynamic clock configuration */
        param_tab[0] = p_dynamic_clock_cfg->d_transfer_rate;
        param_tab[1] = p_dynamic_clock_cfg->d_lat_mcu_bridge;
        param_tab[2] = p_dynamic_clock_cfg->d_lat_mcu_hom2sam;
        param_tab[3] = p_dynamic_clock_cfg->d_lat_mcu_bef_fast_access;
        param_tab[4] = p_dynamic_clock_cfg->d_lat_dsp_after_sam;
      #endif
      #endif

    #elif (DSP == 33)
      static API_SIGNED param_tab[] = {

          D_TRANSFER_RATE,

          // ..................Latencies
          D_LAT_MCU_BRIDGE,    D_LAT_MCU_HOM2SAM,

          D_LAT_MCU_BEF_FAST_ACCESS, D_LAT_DSP_AFTER_SAM,

          //...................p_gprs_install_adress
          D_HOLE,

          //...................d_misc_config
          D_MISC_CONFIG,

          //...................d_cn_sw_workaround
          C_DSP_SW_WORK_AROUND,

          #if DCO_ALGO
            //...................d_cn_dco_param
            C_CN_DCO_PARAM,
          #else
            //.................. Reserved
            D_HOLE,
          #endif

          //...................Reserved
          D_HOLE,               D_HOLE,
          D_HOLE,

          //...................Frequency burst
          D_FB_MARGIN_BEG,     D_FB_MARGIN_END,
          D_NSUBB_IDLE,        D_NSUBB_DEDIC,        D_FB_THR_DET_IACQ,
          D_FB_THR_DET_TRACK,
          //...................Demodulation
          D_DC_OFF_THRES,      D_DUMMY_THRES,        D_DEM_POND_GEWL,
          D_DEM_POND_RED,
          //...................TCH Full Speech
          D_MACCTHRESH1,       D_MLDT,               D_MACCTHRESH,
          D_GU,                D_GO,                 D_ATTMAX,
          D_SM,                D_B,

          //...................V42 bis
          D_V42B_SWITCH_HYST,  D_V42B_SWITCH_MIN,    D_V42B_SWITCH_MAX,
          D_V42B_RESET_DELAY,

          //...................TCH Half Speech
          D_LDT_HR,            D_MACCTRESH_HR,       D_MACCTRESH1_HR,
          D_GU_HR,             D_GO_HR,              D_B_HR,
          D_SM_HR,             D_ATTMAX_HR,

          //...................Added variables for EFR
          C_MLDT_EFR,          C_MACCTHRESH_EFR,     C_MACCTHRESH1_EFR,
          C_GU_EFR,            C_GO_EFR,             C_B_EFR,
          C_SM_EFR,            C_ATTMAX_EFR,

          //...................Full rate variables
          D_SD_MIN_THR_TCHFS,
          D_MA_MIN_THR_TCHFS,  D_MD_MAX_THR_TCHFS,   D_MD1_MAX_THR_TCHFS,

          //...................TCH Half Speech
          D_SD_MIN_THR_TCHHS, D_MA_MIN_THR_TCHHS, D_SD_AV_THR_TCHHS,
          D_MD_MAX_THR_TCHHS, D_MD1_MAX_THR_TCHHS,

          //...................TCH Enhanced Full Rate Speech
          D_SD_MIN_THR_TCHEFS,  D_MA_MIN_THR_TCHEFS,  D_MD_MAX_THR_TCHEFS,
          D_MD1_MAX_THR_TCHEFS, D_WED_FIL_INI,

          D_WED_FIL_TC,        D_X_MIN,              D_X_MAX,
          D_SLOPE,             D_Y_MIN,              D_Y_MAX,
          D_WED_DIFF_THRESHOLD,D_MABFI_MIN_THR_TCHHS,D_FACCH_THR,

          D_MAX_OVSPD_UL,      D_SYNC_THRES,        D_IDLE_THRES,
          D_M1_THRES,          D_MAX_OVSP_DL,       D_GSM_BGD_MGT
      };
      param_size = 79;

      #if (OP_L1_STANDALONE)
      #if (CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || \
          (CHIPSET == 11) || (CHIPSET == 12)
        /* Dynamic clock configuration */
        param_tab[0] = p_dynamic_clock_cfg->d_transfer_rate;
        param_tab[1] = p_dynamic_clock_cfg->d_lat_mcu_bridge;
        param_tab[2] = p_dynamic_clock_cfg->d_lat_mcu_hom2sam;
        param_tab[3] = p_dynamic_clock_cfg->d_lat_mcu_bef_fast_access;
        param_tab[4] = p_dynamic_clock_cfg->d_lat_dsp_after_sam;
      #endif
      #endif

    #else

    #if (VOC == FR)
      static API_SIGNED param_tab[] = {
          //...................Frequency burst
          D_NSUBB_IDLE,        D_NSUBB_DEDIC,        D_FB_THR_DET_IACQ,
          D_FB_THR_DET_TRACK,
          //...................Demodulation
          D_DC_OFF_THRES,      D_DUMMY_THRES,        D_DEM_POND_GEWL,
          D_DEM_POND_RED,      D_HOLE,               D_HOLE,
          //...................TCH Full Speech
          D_MACCTHRESH1,       D_MLDT,               D_MACCTHRESH,
          D_GU,                D_GO,                 D_ATTMAX,
          D_SM,                D_B,                  D_SD_MIN_THR_TCHFS,
          D_MA_MIN_THR_TCHFS,  D_MD_MAX_THR_TCHFS,   D_MD1_MAX_THR_TCHFS,
          //...................TCH Half Speech
          D_SD_MIN_THR_TCHHS,  D_MA_MIN_THR_TCHHS,   D_SD_AV_THR_TCHHS,
          D_MD_MAX_THR_TCHHS,  D_MD1_MAX_THR_TCHHS,  D_WED_FIL_INI,
          D_WED_FIL_TC,        D_X_MIN,              D_X_MAX,
          D_SLOPE,             D_Y_MIN,              D_Y_MAX,
          D_WED_DIFF_THRESHOLD,D_MABFI_MIN_THR_TCHHS,D_FACCH_THR,
          D_DSP_TEST
      };
      param_size = 38;
    #endif

    #if (VOC == FR_HR)
      static API_SIGNED param_tab[] = {
          //...................Frequency burst
          D_NSUBB_IDLE,        D_NSUBB_DEDIC,        D_FB_THR_DET_IACQ,
          D_FB_THR_DET_TRACK,
          //...................Demodulation
          D_DC_OFF_THRES,      D_DUMMY_THRES,        D_DEM_POND_GEWL,
          D_DEM_POND_RED,      D_HOLE,               D_HOLE,
          //...................TCH Full Speech
          D_MACCTHRESH1,       D_MLDT,               D_MACCTHRESH,
          D_GU,                D_GO,                 D_ATTMAX,
          D_SM,                D_B,
          //...................TCH Half Speech
          D_LDT_HR,            D_MACCTRESH_HR,       D_MACCTRESH1_HR,
          D_GU_HR,             D_GO_HR,              D_B_HR,
          D_SM_HR,             D_ATTMAX_HR,
          //...................TCH Full Speech
          D_SD_MIN_THR_TCHFS,
          D_MA_MIN_THR_TCHFS,  D_MD_MAX_THR_TCHFS,   D_MD1_MAX_THR_TCHFS,
          //...................TCH Half Speech
          D_SD_MIN_THR_TCHHS,
          D_MA_MIN_THR_TCHHS,
          D_SD_AV_THR_TCHHS,
          D_MD_MAX_THR_TCHHS,
          D_MD1_MAX_THR_TCHHS,
          D_WED_FIL_INI,
          D_WED_FIL_TC,
          D_X_MIN,
          D_X_MAX,
          D_SLOPE,
          D_Y_MIN,
          D_Y_MAX,
          D_WED_DIFF_THRESHOLD,
          D_MABFI_MIN_THR_TCHHS,
          D_FACCH_THR,
          D_DSP_TEST
      };
      param_size = 46;
    #endif

    #if (VOC == FR_EFR)
      static API_SIGNED param_tab[] = {
          //...................Frequency burst
          D_NSUBB_IDLE,        D_NSUBB_DEDIC,        D_FB_THR_DET_IACQ,
          D_FB_THR_DET_TRACK,
          //...................Demodulation
          D_DC_OFF_THRES,      D_DUMMY_THRES,        D_DEM_POND_GEWL,
          D_DEM_POND_RED,      D_HOLE,               D_HOLE,

          //...................TCH Full Speech
          D_MACCTHRESH1,       D_MLDT,               D_MACCTHRESH,
          D_GU,                D_GO,                 D_ATTMAX,
          D_SM,                D_B,

          //...................Added variables for EFR
          C_MLDT_EFR,          C_MACCTHRESH_EFR,     C_MACCTHRESH1_EFR,
          C_GU_EFR,            C_GO_EFR,             C_B_EFR,
          C_SM_EFR,            C_ATTMAX_EFR,

          //...................Full rate variables
          D_SD_MIN_THR_TCHFS,
          D_MA_MIN_THR_TCHFS,  D_MD_MAX_THR_TCHFS,   D_MD1_MAX_THR_TCHFS,

          //...................TCH Enhanced Full Rate Speech
          D_SD_MIN_THR_TCHEFS,  D_MA_MIN_THR_TCHEFS,  D_MD_MAX_THR_TCHEFS,
          D_MD1_MAX_THR_TCHEFS, D_HOLE,               D_WED_FIL_INI,

          D_WED_FIL_TC,        D_X_MIN,              D_X_MAX,
          D_SLOPE,             D_Y_MIN,              D_Y_MAX,
          D_WED_DIFF_THRESHOLD,D_MABFI_MIN_THR_TCHHS,D_FACCH_THR,
          D_DSP_TEST
      };
      param_size = 46;
    #endif

    #if (VOC == FR_HR_EFR)
      static API_SIGNED param_tab[] = {
          //...................Frequency burst
          D_NSUBB_IDLE,        D_NSUBB_DEDIC,        D_FB_THR_DET_IACQ,
          D_FB_THR_DET_TRACK,
          //...................Demodulation
          D_DC_OFF_THRES,      D_DUMMY_THRES,        D_DEM_POND_GEWL,
          D_DEM_POND_RED,      D_HOLE,               D_TRANSFER_RATE,
          //...................TCH Full Speech
          D_MACCTHRESH1,       D_MLDT,               D_MACCTHRESH,
          D_GU,                D_GO,                 D_ATTMAX,
          D_SM,                D_B,

          //...................TCH Half Speech
          D_LDT_HR,            D_MACCTRESH_HR,       D_MACCTRESH1_HR,
          D_GU_HR,             D_GO_HR,              D_B_HR,
          D_SM_HR,             D_ATTMAX_HR,

          //...................Added variables for EFR
          C_MLDT_EFR,          C_MACCTHRESH_EFR,     C_MACCTHRESH1_EFR,
          C_GU_EFR,            C_GO_EFR,             C_B_EFR,
          C_SM_EFR,            C_ATTMAX_EFR,

          //...................Full rate variables
          D_SD_MIN_THR_TCHFS,
          D_MA_MIN_THR_TCHFS,  D_MD_MAX_THR_TCHFS,   D_MD1_MAX_THR_TCHFS,

          //...................TCH Half Speech
          D_SD_MIN_THR_TCHHS, D_MA_MIN_THR_TCHHS, D_SD_AV_THR_TCHHS,
          D_MD_MAX_THR_TCHHS, D_MD1_MAX_THR_TCHHS,

          //...................TCH Enhanced Full Rate Speech
          D_SD_MIN_THR_TCHEFS,  D_MA_MIN_THR_TCHEFS,  D_MD_MAX_THR_TCHEFS,
          D_MD1_MAX_THR_TCHEFS, D_HOLE,               D_WED_FIL_INI,

          D_WED_FIL_TC,        D_X_MIN,              D_X_MAX,
          D_SLOPE,             D_Y_MIN,              D_Y_MAX,
          D_WED_DIFF_THRESHOLD,D_MABFI_MIN_THR_TCHHS,D_FACCH_THR,
          D_HOLE,

          //...................Data patch provisions
          D_HOLE, D_HOLE, D_HOLE, D_HOLE, D_HOLE, D_HOLE, D_HOLE, D_HOLE,

          //...................Version Number, TI Number
          D_HOLE, D_HOLE,

          // ..................DSP page
          D_DSP_TEST

          #if IDS
            ,D_MAX_OVSPD_UL,      D_SYNC_THRES,        D_IDLE_THRES,
             D_M1_THRES,          D_MAX_OVSP_DL
          #endif

      };
      param_size = 67;
      #if IDS
      // Take care to not erased "d_version_number, d_ti_version and d_dsp_page" wrote by DSP before ARM
      // set PARAM memory
        param_size2 = 5;
      #endif
    #endif
    #endif // (end of DSP != 33 || DSP != 34 || DSP != 35 || DSP != 36) || (DSP != 37) || (DSP != 38) || (DSP != 39)

    // NDB pointer.
    dsp_ndb_ptr = (T_NDB_MCU_DSP *) NDB_ADR;


    //-------------
    // DSP STARTUP
    //-------------
    {
      #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE==7)
          #if (CHIPSET == 1)
            L1_trace_string ("\n\r\n\rGEMINI/POLESTAR test code\n\r-------------------------");
          #elif (CHIPSET == 2)
            L1_trace_string ("\n\r\n\rHERCULES test code\n\r------------------");
          #elif (CHIPSET == 3)
            L1_trace_string ("\n\r\n\rULYSSE/ULYSSE G0 test code\n\r--------------------------");
          #elif (CHIPSET == 4)
            L1_trace_string ("\n\r\n\rSAMSON test code\n\r----------------");
          #elif (CHIPSET == 5)
            L1_trace_string ("\n\r\n\rULYSSE G1 test code 13 MHz\n\r-------------------");
          #elif (CHIPSET == 6)
            L1_trace_string ("\n\r\n\rULYSSE G1 test code 26 MHz\n\r-------------------");
          #elif (CHIPSET == 7)
            L1_trace_string ("\n\r\n\rCALYPSO Rev A test code\n\r-------------------");
          #elif (CHIPSET == 8)
            L1_trace_string ("\n\r\n\rCALYPSO Rev B test code\n\r-------------------");
          #elif (CHIPSET == 9)
            L1_trace_string ("\n\r\n\rULYSSE C035 test code\n\r-------------------");
          #elif (CHIPSET == 10) || (CHIPSET == 11)
            L1_trace_string ("\n\r\n\rCALYPSO C035 test code\n\r-------------------");
          #elif (CHIPSET == 12)
            L1_trace_string ("\n\r\n\rCALYPSO PLUS test code\n\r-------------------");
          #elif (CHIPSET == 15)
            L1_trace_string ("\n\r\n\rLOCOSTO test code\n\r-------------------");
          #endif
      #endif

#if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE==7)
      /* Display Audio Configuration */
      L1_trace_string ("\n\rAUDIO: ");
      #if (KEYBEEP)
        L1_trace_string ("KB ");
      #endif
      #if (TONE)
        L1_trace_string ("TN ");
      #endif
      #if (MELODY_E1)
        L1_trace_string ("E1 ");
      #endif
      #if (MELODY_E2)
        L1_trace_string ("E2 ");
      #endif
      #if (VOICE_MEMO)
        L1_trace_string ("VM ");
      #endif
      #if (L1_VOICE_MEMO_AMR)
        L1_trace_string ("VMA ");
      #endif
      #if (SPEECH_RECO)
        L1_trace_string ("SR ");
      #endif
      #if (L1_NEW_AEC)
        L1_trace_string ("NEWAEC ");
      #elif (AEC)
        L1_trace_string ("AEC ");
      #endif
      #if (L1_GTT)
        L1_trace_string ("GTT ");
      #endif
      #if (FIR)
        L1_trace_string ("FIR ");
      #endif
      #if (AUDIO_MODE)
        L1_trace_string ("AUM ");
      #endif
      #if (L1_CPORT == 1)
        L1_trace_string ("CPO ");
      #endif
      #if (L1_STEREOPATH == 1)
        L1_trace_string ("STP ");
      #endif
      #if (L1_EXT_AUDIO_MGT == 1)
        L1_trace_string ("EAM ");
      #endif
      L1_trace_string ("\n\r");
#endif
      // Release Lead reset before DSP code/patch download to insure proper reset of DSP
      LA_ReleaseLead();

      // Init PLL : PLONOFF =1, PLMU = 0010 (k=3), PLLNDIV=1, PLLDIV=0
      LA_InitialLeadBoot(bootCode); // Load the bootCode in API
      LA_StartLead(CLKSTART);       // LEAD_PLL_CNTL register (on MCU side)
                                    // On SAMSON, only the LEAD reset is released

      // GSM 1.5
      //-----------------------------------------------------------------
      // After RESET release, DSP is in SAM Mode ! while API_CNTR (0xF900)
      // register is in reset state: HOM mode, PLL off, Bridge off. No ws
      // are applied for MCU<-->API access !!!!! So, MCU must wait for
      // end of Leadboot execution before accessing API.
      wait_ARM_cycles(convert_nanosec_to_cycles(10000));  // wait 10us


      if(l1_config.dwnld == NO_DWNLD)
      // NO DOWNLOAD...
      {
        #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE==7)
          L1_trace_string ("\n\r-> No download !!");
        #endif

        // Wait for READY status from DSP.
        while(*((volatile UWORD16 *)DOWNLOAD_STATUS) != LEAD_READY);

        // Set DSP start address.
        dsp_start_address = DSP_START;
      }
      else
      if(l1_config.dwnld == DSP_DWNLD)
      // DSP CODE DOWNLOAD...
      {
        WORD32 load_result;

        #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
          #if (VOC == FR)
            L1_trace_string ("\n\r-> Downloading FR DSP code...");
          #endif

          #if (VOC == FR_HR)
            L1_trace_string ("\n\r-> Downloading FR&HR DSP code...");
          #endif

          #if (VOC == FR_EFR)
            L1_trace_string ("\n\r-> Downloading FR&EFR DSP code...");
          #endif

          #if (VOC == FR_HR_EFR)
            #if IDS
              L1_trace_string ("\n\r-> Download FR&IDS DSP code...");
            #else
              L1_trace_string ("\n\r-> Downloading 3VOC DSP code...");
            #endif
          #endif
        #endif

        // Download DSP code into DSP via API / bootcode.
        load_result = LA_LoadPage(DspCode_array,0,0);

        #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
          if(load_result)
            L1_trace_string ("\n\r-> Download FAILED !!");
          else
            L1_trace_string ("\n\r-> ... finished !!");
        #endif

        #if (VOC == FR_HR) || (VOC == FR_EFR) || (VOC == FR_HR_EFR)
          #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
            #if (VOC == FR_HR)
              L1_trace_string ("\n\r-> Downloading FR&HR DSP data ROM...");
            #endif

            #if (VOC == FR_EFR)
              L1_trace_string ("\n\r-> Downloading FR&EFR DSP data ROM...");
            #endif

            #if (VOC == FR_HR_EFR)
              #if IDS
                L1_trace_string ("\n\r-> Download FR&IDS DSP Data ROM...");
              #else
                L1_trace_string ("\n\r-> Downloading 3VOC DSP DATA ROM...");
              #endif
            #endif
          #endif

          load_result = LA_LoadPage(DspData_array,1,0);

          #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
            if(load_result)
              L1_trace_string ("\n\r-> Download FAILED !!");
            else
              L1_trace_string ("\n\r-> ... finished !!");
          #endif
        #endif

        // Set DSP start address;
        dsp_start_address = DSP_START;
      }
      else
      if(l1_config.dwnld == PATCH_DWNLD)
      // DSP PATCH DOWNLOAD...
      {
        WORD32 load_result;

        #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
          L1_trace_string ("\n\r-> Downloading patch...");
        #endif

        // Download DSP patch into DSP via API / bootcode.
        load_result = LA_LoadPage(patch_array,0,0);

        #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
          if(load_result)
            L1_trace_string ("\n\r-> Download FAILED !!");
          else
            L1_trace_string ("\n\r-> ... finished !!");
        #endif

       // Catch start address always from patch_file#.c.
        dsp_start_address   = (WORD16)patch_array[3];
        dsp_start_address <<= 8;
        dsp_start_address  += (WORD16)patch_array[2];

        // if COFF2CP output, the file begins by a null tag
        if(dsp_start_address == 0)
        {
          dsp_start_address   = (WORD16)patch_array[13];
          dsp_start_address <<= 8;
          dsp_start_address  += (WORD16)patch_array[12];
        }
      }
      else
      if(l1_config.dwnld == PATCH_DSP_DWNLD)
      // DSP CODE DOWNLOAD + PATCH DOWNLOAD...
      {
        WORD32 load_result;

        #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
          #if (VOC == FR)
            L1_trace_string ("\n\r-> Downloading FR DSP code...");
          #endif

          #if (VOC == FR_HR)
            L1_trace_string ("\n\r-> Downloading FR&HR DSP code...");
          #endif

          #if (VOC == FR_EFR)
            L1_trace_string ("\n\r-> Downloading FR&EFR DSP code...");
          #endif

          #if (VOC == FR_HR_EFR)
            #if IDS
              L1_trace_string ("\n\r-> Download FR&IDS DSP code...");
            #else
              L1_trace_string ("\n\r-> Downloading 3VOC DSP code...");
            #endif
          #endif
        #endif

        // Download DSP code into DSP via API / bootcode.
        load_result = LA_LoadPage(DspCode_array,0,0);

        #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
          if(load_result)
            L1_trace_string ("\n\r-> Download FAILED !!");
          else
            L1_trace_string ("\n\r-> ... finished !!");
        #endif

        #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
          L1_trace_string ("\n\r-> Downloading patch...");
        #endif

        // Download DSP patch into DSP via API / bootcode.
        load_result = LA_LoadPage(patch_array,0,0);

        #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
          if(load_result)
            L1_trace_string ("\n\r-> Download FAILED !!");
          else
            L1_trace_string ("\n\r-> ... finished !!");
        #endif

        #if ((VOC == FR_HR) || (VOC == FR_EFR) || (VOC == FR_HR_EFR))
          #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
            #if (VOC == FR_HR)
              L1_trace_string ("\n\r-> Downloading FR&HR DSP data ROM...");
            #endif

            #if (VOC == FR_EFR)
              L1_trace_string ("\n\r-> Downloading FR&EFR DSP data ROM...");
            #endif

            #if (VOC == FR_HR_EFR)
              #if IDS
                L1_trace_string ("\n\r-> Download FR&IDS DSP data ROM...");
              #else
                L1_trace_string ("\n\r-> Downloading 3VOC DSP data ROM...");
              #endif
            #endif
          #endif

          load_result = LA_LoadPage(DspData_array,1,0);

          #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE == 7)
            if(load_result)
              L1_trace_string ("\n\r-> Download FAILED !!");
            else
              L1_trace_string ("\n\r-> ... finished !!");
          #endif
        #endif


        // Catch start address always from patch_file#.c.
        dsp_start_address   = (WORD16)patch_array[3];
        dsp_start_address <<= 8;
        dsp_start_address  += (WORD16)patch_array[2];

        // if COFF2CP output, the file begins by a null tag
        if(dsp_start_address == 0)
        {
          dsp_start_address   = (WORD16)patch_array[13];
          dsp_start_address <<= 8;
          dsp_start_address  += (WORD16)patch_array[12];
        }
      }

      #if (DSP == 16 || DSP == 17 || DSP == 30 || DSP == 31 || DSP == 32)
        dsp_ndb_ptr->d_pll_clkmod1 = CLKMOD1;                         // PLL variable (multiply by 3 factor)+ Power consumpt.
        dsp_ndb_ptr->d_pll_clkmod2 = CLKMOD2;                         // PLL variable (40 us lock time)
      #endif
    }

    #if (TRACE_TYPE==1) || (TRACE_TYPE==2) || (TRACE_TYPE==3) || (TRACE_TYPE==7)
      L1_trace_string ("\n\r\n\r");
    #endif

    //--------------------------------------------------------------
    // Loading of NDB parameters.......
    //--------------------------------------------------------------

    #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
      // Initialize background control variable to No background. Background tasks can be launch in GPRS
      // as in GSM.
      dsp_ndb_ptr->d_background_enable = 0;
      dsp_ndb_ptr->d_background_abort  = 0;
      dsp_ndb_ptr->d_background_state  = 0;
      dsp_ndb_ptr->d_debug_ptr         = 0x0074;
      dsp_ndb_ptr->d_debug_bk          = 0x0001;
      dsp_ndb_ptr->d_pll_config        = C_PLL_CONFIG;
      dsp_ndb_ptr->p_debug_buffer      = C_DEBUG_BUFFER_ADD;
      dsp_ndb_ptr->d_debug_buffer_size = C_DEBUG_BUFFER_SIZE;
      dsp_ndb_ptr->d_debug_trace_type  = C_DEBUG_TRACE_TYPE;


      #if (CHIPSET == 12) || (CHIPSET == 15)
        dsp_ndb_ptr->d_swh_flag_ndb  = 0; /* interpolation off for  non SAIC build*/
        dsp_ndb_ptr->d_swh_Clipping_Threshold_ndb = 0x0000;
        #if (DSP == 36) || (DSP == 37) || (DSP == 39)
          #if (L1_SAIC != 0)
            dsp_ndb_ptr->d_swh_flag_ndb  = SAIC_INITIAL_VALUE;
            dsp_ndb_ptr->d_swh_Clipping_Threshold_ndb = 0x4000;
          #endif
        #endif
      #endif

      #if (W_A_DSP_IDLE3 == 1)
        // Deep Sleep work around used on Calypso
        // This init is used to backward compatibility with old patch.
        dsp_ndb_ptr->d_dsp_state       = C_DSP_IDLE3;
      #endif

      dsp_ndb_ptr->d_audio_gain_ul     = 0;
      dsp_ndb_ptr->d_audio_gain_dl     = 0;

    // for patch >= 2100, use new AEC
    #if (!L1_NEW_AEC)
      dsp_ndb_ptr->d_es_level_api      = 0x5213;
    #endif
      dsp_ndb_ptr->d_mu_api            = 0x5000;
    #else
      #if L1_GPRS
      {
        T_NDB_MCU_DSP_GPRS *p_ndb_gprs = (T_NDB_MCU_DSP_GPRS *) NDB_ADR_GPRS;

        // Initialize background control variable to No background.
        p_ndb_gprs->d_background_enable = 0;
        p_ndb_gprs->d_background_abort  = 0;
        p_ndb_gprs->d_background_state  = 0;
      }
      #endif

      #if (AMR == 1)
        // Reset NDB pointer for AMR trace
        dsp_ndb_ptr->p_debug_amr = 0;
      #endif

    #endif

    //--------------------------------------------------------------
    // Loading of PARAM area.......
    //--------------------------------------------------------------
    // Load PARAM memory...
    pt = (API *) PARAM_ADR;

    for (i=0; i<param_size; i++) *pt++ = param_tab[i];
    #if (DSP < 33) && (IDS)
      pt += 3;
      for (i= param_size + 3; i<param_size + 3 + param_size2; i++) *pt++ = param_tab[i];
    #endif

    #if (DSP == 33) || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
    {
      T_PARAM_MCU_DSP *pt_param = (T_PARAM_MCU_DSP *) PARAM_ADR;

      // "d_gprs_install_address" has to be set only if no PATCH is download, i.e.
      //  "d_gprs_install_address" is automatically set by DSP if a PATCH is download
      if ((l1_config.dwnld == DSP_DWNLD) || (l1_config.dwnld == NO_DWNLD))
        pt_param->d_gprs_install_address    = INSTALL_ADD;
    }
    #endif

    #if L1_GPRS
      //--------------------------------------------------------------
      // Loading of GPRS PARAM area.......
      //--------------------------------------------------------------
      // Load GPRS PARAM memory...
      {
        T_PARAM_MCU_DSP_GPRS *pt_gprs = (T_PARAM_MCU_DSP_GPRS *) PARAM_ADR_GPRS;

        // WARNING: must be configured according to the ARM & DSP clock speed.
        // The following values are required with a 13MHz ARM clock and with a 65 MIPS DSP.
        pt_gprs->d_overlay_rlcmac_cfg_gprs = 0;
        pt_gprs->d_mac_threshold           = 0x4e20;
        pt_gprs->d_sd_threshold            = 0x0016;
        pt_gprs->d_nb_max_iteration        = 0x0004;

        #if (DSP != 33) && (DSP != 34) && (DSP != 35) && (DSP != 36) && (DSP != 37) && (DSP != 38) && (DSP != 39)

          #if (OP_L1_STANDALONE)
          #if (CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || \
              (CHIPSET == 11) || (CHIPSET == 12)
            pt_gprs->d_lat_mcu_bridge          = p_dynamic_clock_cfg->d_lat_mcu_bridge;
            pt_gprs->d_lat_mcu_hom2sam         = p_dynamic_clock_cfg->d_lat_mcu_hom2sam;
          #endif
          #endif

          #if (CHIPSET == 4)
            #if (!OP_L1_STANDALONE)
              // Latency for DSP at 78 MIPS
              pt_gprs->d_lat_mcu_bridge          = 0x0009;
            #endif
            pt_gprs->d_lat_pll2div             = 0x000C;
            #if (!OP_L1_STANDALONE)
              pt_gprs->d_lat_mcu_hom2sam         = 0x000C;
            #endif
          #else
            #if (!OP_L1_STANDALONE)
              pt_gprs->d_lat_mcu_bridge          = 0x0008;
            #endif
            pt_gprs->d_lat_pll2div             = 0x000A;
            #if (!OP_L1_STANDALONE)
              pt_gprs->d_lat_mcu_hom2sam         = 0x000A;
            #endif
          #endif

          // To be removed once G0 patch process will be aligned with G1 & G2
          // i.e. "d_gprs_install_address" automatically set by DSP if a Patch is present.
          #if (DSP == 31)
            if ((l1_config.dwnld == PATCH_DSP_DWNLD) ||
                (l1_config.dwnld == PATCH_DWNLD))
              pt_gprs->d_gprs_install_address    = INSTALL_ADD_WITH_PATCH;
            else
              pt_gprs->d_gprs_install_address    = INSTALL_ADD;
          #else
            if ((l1_config.dwnld == DSP_DWNLD) || (l1_config.dwnld == NO_DWNLD))
              pt_gprs->d_gprs_install_address    = INSTALL_ADD;
          #endif
        #endif // DSP != 33 && DSP != 34 && (DSP != 35) && DSP != 36 && DSP != 37 && DSP != 38
      }
    #endif // L1_GPRS

    *(volatile UWORD16 *) DOWNLOAD_SIZE   = 0;                 // Size=0 to force DSP to start from address...
    *(volatile UWORD16 *) DOWNLOAD_ADDR   = dsp_start_address; // Start address.
    *(volatile UWORD16 *) DOWNLOAD_STATUS = BLOCK_READY;       // Start DSP...

}
#endif //#if CODE_VERSION!=SIMULATION

/*-------------------------------------------------------*/
/* l1s_reset_db_mcu_to_dsp()                             */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/*-------------------------------------------------------*/
void l1s_reset_db_mcu_to_dsp(T_DB_MCU_TO_DSP *page_ptr)
{
  API i;
  API size = sizeof(T_DB_MCU_TO_DSP) / sizeof(API);
  API *ptr = (API *)page_ptr;

  // Clear all locations.
  for(i=0; i<size; i++) *ptr++ = 0;
}

#if (DSP == 38) || (DSP == 39)
  /*-------------------------------------------------------*/
  /* l1s_reset_db_common_mcu_to_dsp()                                         */
  /*-------------------------------------------------------*/
  /* Parameters :                                                                            */
  /* Return     :                                                                               */
  /* Functionality :                                                                           */
  /*-------------------------------------------------------*/
  void l1s_reset_db_common_mcu_to_dsp(T_DB_COMMON_MCU_TO_DSP *page_ptr)
  {
    API i;
    API size = sizeof(T_DB_COMMON_MCU_TO_DSP) / sizeof(API);
    API *ptr = (API *)page_ptr;

    // Clear all locations.
    for(i=0; i<size; i++) *ptr++ = 0;
  }
#endif
/*-------------------------------------------------------*/
/* l1s_reset_db_dsp_to_mcu()                             */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/*-------------------------------------------------------*/
void l1s_reset_db_dsp_to_mcu(T_DB_DSP_TO_MCU *page_ptr)
{
  API i;
  API size = sizeof(T_DB_DSP_TO_MCU) / sizeof(API);
  API *ptr = (API *)page_ptr;

  // Clear all locations.
  for(i=0; i<size; i++) *ptr++ = 0;

  // Set crc result as "SB not found".
  page_ptr->a_sch[0]  =  (1<<B_SCH_CRC);   // B_SCH_CRC =1, BLUD =0
}

/*-------------------------------------------------------*/
/* l1s_increment_time()                                  */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/*-------------------------------------------------------*/
void l1s_increment_time(T_TIME_INFO *time, UWORD32 fn_offset)
{
  // Increment FN % MAX_FN.
  //------------------------
  IncMod(time->fn, fn_offset, MAX_FN);

  if(fn_offset == 1)
  // Frame by frame increment...
  //----------------------------
  {
    IncMod(time->t2, 1, 26);                // increment T2 % 26.
    IncMod(time->t3, 1, 51);                // increment T3 % 51.
    IncMod(time->fn_mod42432, 1, 42432);    // increment FN % 42432.
    IncMod(time->fn_mod13, 1, 13);          // increment FN % 13.

    if(time->t3 == 0)
    // new FN is a multiple of 51.
    {
      // Increment TC ((FN/51) % 8).
      IncMod(time->tc, 1, 8);

      // New FN is a multiple of 26 and 51 -> increment T1 % 2048 (T1=FN div (26*51)).
      if(time->t2 == 0) IncMod(time->t1, 1, 2048);
    }

    #if (L1_GPRS)
      IncMod(time->fn_mod52, 1, 52);        // increment FN % 52.
      IncMod(time->fn_mod104, 1, 104);      // increment FN % 104.

      IncMod(time->fn_mod13_mod4, 1, 4);      // increment (FN % 13) % 4.
      if(time->fn_mod13 == 0)
        time->fn_mod13_mod4 = 0;

      if((time->fn_mod13 == 0) || (time->fn_mod13 == 4) || (time->fn_mod13 == 8))
        IncMod(time->block_id, 1, MAX_BLOCK_ID);
    #endif

  }

  else
  // Jumping on a new serving cell.
  //-------------------------------
  {
    time->t2 = time->fn % 26;              // T2 = FN % 26.
    time->t3 = time->fn % 51;              // T3 = FN % 51.
    time->t1 = time->fn / (26L*51L);       // T1 = FN div 26*51
    time->tc = (time->fn / 51) % 8;        // TC = (FN div 51) % 8
    time->fn_mod42432 = time->fn % 42432;  // FN%42432.
    time->fn_mod13    = time->fn % 13;     // FN % 13.

    #if (L1_GPRS)
      time->fn_mod104     = time->fn % 104;     // FN % 104.

      if(time->fn_mod104 >= 52)                 // FN % 52.
        time->fn_mod52    = time->fn_mod104 - 52;
      else
        time->fn_mod52    = time->fn_mod104;

      time->fn_mod13_mod4 = time->fn_mod13 % 4; // FN % 13 % 4.

      time->block_id      = ((3 * (time->fn / 13)) + (time->fn_mod13 / 4));
    #endif

  }

  // Computes reporting period frame number according to the current FN
  if(l1a_l1s_com.l1s_en_task[DEDIC] == TASK_ENABLED)
  {
    T_CHANNEL_DESCRIPTION  *desc_ptr;
    UWORD8                  timeslot_no;
    UWORD8                  subchannel;

    // Get a meaningfull channel description.
    //---------------------------------------
    // Rem1: this is to avoid a bad setting of "fn_in_report" when synchro is performed
    //       whereas L1 is waiting for starting time and no channel discribed BEFORE STI.
    // Rem2: "fn_in_report" is computed with "CHAN1" parameters since it is the channel
    //       which carries the SACCH.
    if(l1a_l1s_com.dedic_set.aset->chan1.desc_ptr->channel_type == INVALID_CHANNEL)
      desc_ptr = &l1a_l1s_com.dedic_set.aset->chan1.desc;
    else
      desc_ptr = l1a_l1s_com.dedic_set.aset->chan1.desc_ptr;

    timeslot_no = desc_ptr->timeslot_no;
    subchannel  = desc_ptr->subchannel;
    if(desc_ptr->channel_type == TCH_H) timeslot_no = (2*(timeslot_no/2) + subchannel);


    // Compute "fn_in_report" according to the channel_type.
    //------------------------------------------------------
    if(desc_ptr->channel_type == SDCCH_4)
    // FN_REPORT for SDCCH/4 is: fn%102 in [37..36].
    {
      l1s.actual_time.fn_in_report = (UWORD8)((l1s.actual_time.fn - 37 + 102) % 102);
      l1s.next_time.fn_in_report   = (UWORD8)((l1s.next_time.fn   - 37 + 102) % 102);
    }
    else
    if(desc_ptr->channel_type == SDCCH_8)
    // FN_REPORT for SDCCH/4 is: fn%102 in [12..11].
    {
      l1s.actual_time.fn_in_report = (UWORD8)((l1s.actual_time.fn - 12 + 102) % 102);
      l1s.next_time.fn_in_report   = (UWORD8)((l1s.next_time.fn   - 12 + 102) % 102);
    }
    else
    // TCH_F or TCH_H...
    {
      // 1) (timeslot_no * 13) is computed in order to substract the considered beginning for this
      // timeslot and then always be in the range 0..103
      // 2) 104 is added in order to cope with negative numbers.
      l1s.actual_time.fn_in_report = (UWORD8)((l1s.actual_time.fn - (timeslot_no * 13) + 104) % 104);
      l1s.next_time.fn_in_report   = (UWORD8)((l1s.next_time.fn   - (timeslot_no * 13) + 104) % 104);
    }
  }
}

/*-------------------------------------------------------*/
/* l1s_encode_rxlev()                                    */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/*-------------------------------------------------------*/
WORD16 l1s_encode_rxlev(UWORD8 inlevel)
{
  WORD16  rxlev;

  rxlev = (221 - inlevel) / 2; // the result is divided by 2 due to
                               // the IL format is 7.1 and rxlev format is 8.0

  return(rxlev);
}

/*-------------------------------------------------------*/
/* l1s_send_ho_finished()                                */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/*-------------------------------------------------------*/
void l1s_send_ho_finished(UWORD8  cause)
{
  xSignalHeaderRec *msg;

  msg = os_alloc_sig(sizeof(T_MPHC_HANDOVER_FINISHED));
  DEBUGMSG(status,NU_ALLOC_ERR)
  msg->SignalCode = L1C_HANDOVER_FINISHED;
  ((T_MPHC_HANDOVER_FINISHED *)(msg->SigP))->cause = cause;

  os_send_sig(msg, L1C1_QUEUE);
  DEBUGMSG(status,NU_SEND_QUEUE_ERR)
}


/*-------------------------------------------------------*/
/* l1s_get_versions()                                    */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality : return address of version structur    */
/*-------------------------------------------------------*/
T_VERSION *l1s_get_version (void)
{
  //update the fields not initialized by the sw init.

  #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_patch_version = l1s_dsp_com.dsp_ndb_ptr->d_version_number2;
    // Note: if l1s.version.dsp_checksum is not initialized (field set to 0)
    // use TST_TEST_HW_REQ message to initialize the whole structur.
  #else
    l1s.version.dsp_patch_version = l1s_dsp_com.dsp_param_ptr->d_version_number;
    // Note: if l1s.version.dsp_code_version and l1s.version.dsp_checksum
    // are not initialized (fields set to 0)
    // use TST_TEST_HW_REQ message to initialize the whole structur.
  #endif

  return (&l1s.version);
}

/*-------------------------------------------------------*/
/* l1s_reset_dedic_meas()                                */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/*-------------------------------------------------------*/
void l1s_reset_dedic_serving_meas(void)
{
  // Reset rxlev related fields
  l1a_l1s_com.Scell_info.meas.acc      = 0;
  l1a_l1s_com.Scell_info.meas.nbr_meas = 0;
  l1a_l1s_com.Smeas_dedic.acc_sub      = 0;
  l1a_l1s_com.Smeas_dedic.nbr_meas_sub = 0;

  // Reset rxqual related fields
  l1a_l1s_com.Smeas_dedic.qual_acc_full      = 0;
  l1a_l1s_com.Smeas_dedic.qual_nbr_meas_full = 0;
  l1a_l1s_com.Smeas_dedic.qual_acc_sub       = 0;
  l1a_l1s_com.Smeas_dedic.qual_nbr_meas_sub  = 0;


  #if REL99
  #if FF_EMR
    // Reset EMR variables
    l1a_l1s_com.Smeas_dedic_emr.rxlev_val_acc      = 0;
    l1a_l1s_com.Smeas_dedic_emr.rxlev_val_nbr_meas = 0;
    l1a_l1s_com.Smeas_dedic_emr.nbr_rcvd_blocks    = 0;
    l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_acc = 0;
    l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_acc   = 0;
    l1a_l1s_com.Smeas_dedic_emr.mean_bep_block_num = 0;
    l1a_l1s_com.Smeas_dedic_emr.cv_bep_block_num   = 0;
  #endif
  #endif


  // Reset dtx frame counter
  l1a_l1s_com.Smeas_dedic.dtx_used = 0;
}

/*-------------------------------------------------------*/
/* SwapIQ_dl()                                           */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/*-------------------------------------------------------*/
UWORD32 l1s_swap_iq_dl(UWORD16 radio_freq, UWORD8 task)
{
  UWORD8   swap_iq;
  UWORD32  task_tab;

#if (L1_FF_MULTIBAND == 0)  
  if(((l1_config.std.id == DUAL) || (l1_config.std.id == DUALEXT) || (l1_config.std.id == DUAL_US)) &&
     (radio_freq >= l1_config.std.first_radio_freq_band2))
  {
    swap_iq = l1_config.std.swap_iq_band2;
  }
  else
  {
    swap_iq = l1_config.std.swap_iq_band1;
  }
#else // L1_FF_MULTIBAND = 1 below

  UWORD16 physical_band_id;
  physical_band_id = 
    l1_multiband_radio_freq_convert_into_physical_band_id(radio_freq);
  swap_iq = rf_band[physical_band_id].swap_iq;
  
#endif // #if (L1_FF_MULTIBAND == 0) else  

  switch(swap_iq)
  {
    case 0:  /* No swap at all. */
    case 2:  /* DL, no swap.    */
      task_tab = (UWORD32)DSP_TASK_CODE[task];
    break;
    case 1:  /* DL I/Q swap.    */
    case 3:  /* DL I/Q swap.    */
       task_tab = (UWORD32)DSP_TASK_CODE[task];
       task_tab |= 0x8000L;
    break;
  }
  return(task_tab);
}

/*-------------------------------------------------------*/
/* l1s_swap_iq_ul()                                      */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/*-------------------------------------------------------*/
UWORD32 l1s_swap_iq_ul(UWORD16 radio_freq, UWORD8 task)
{
  UWORD8   swap_iq;
  UWORD32  task_tab;

#if (L1_FF_MULTIBAND == 0)

  if(((l1_config.std.id == DUAL) || (l1_config.std.id == DUALEXT) || (l1_config.std.id == DUAL_US)) &&
     (radio_freq >= l1_config.std.first_radio_freq_band2))
  {
    swap_iq = l1_config.std.swap_iq_band2;
  }
  else
  {
    swap_iq = l1_config.std.swap_iq_band1;
  }
#else // L1_FF_MULTIBAND = 1 below

 UWORD16 physical_band_id = 0;
  physical_band_id = 
    l1_multiband_radio_freq_convert_into_physical_band_id(radio_freq);
  swap_iq = rf_band[physical_band_id].swap_iq;
  
#endif // #if (L1_FF_MULTIBAND == 0) else  

  switch(swap_iq)
  {
    case 0: /* No swap at all. */
    case 1: /* UL, no swap.    */
      task_tab = (UWORD32)DSP_TASK_CODE[task];
    break;
    case 2: /* UL I/Q swap.    */
    case 3: /* UL I/Q swap.    */
       task_tab = (UWORD32)DSP_TASK_CODE[task];
       task_tab |= 0x8000L;
    break;
  }
  return(task_tab);
}


/*-------------------------------------------------------*/
/* l1s_ADC_decision_on_NP()                              */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :                                       */
/*-------------------------------------------------------*/
UWORD8 l1s_ADC_decision_on_NP(void)
{
  UWORD8  adc_active = INACTIVE;

  if (l1a_l1s_com.l1s_en_task[ALLC] == TASK_DISABLED) // no reorg mode
  {
     if (l1a_l1s_com.adc_mode & ADC_NEXT_NORM_PAGING)  // perform ADC only one time
     {
        adc_active = ACTIVE;
        l1a_l1s_com.adc_mode &= ADC_MASK_RESET_IDLE; // reset in order to have only one ADC measurement in Idle
     }
     else
     {
       if (l1a_l1s_com.adc_mode & ADC_EACH_NORM_PAGING) // perform ADC on each "period" x bloc
         if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_idle_period) // wait for the period
         {
           adc_active = ACTIVE;
           l1a_l1s_com.adc_cpt = 0;
         }
     }
  }
  else  // ADC measurement in reorg mode
  {
     if (l1a_l1s_com.adc_mode & ADC_NEXT_NORM_PAGING_REORG)  // perform ADC only one time
     {
        adc_active = ACTIVE;
        l1a_l1s_com.adc_mode &= ADC_MASK_RESET_IDLE; // reset in order to have only one ADC measurement in Idle
     }
     else
     {
       if (l1a_l1s_com.adc_mode & ADC_EACH_NORM_PAGING_REORG) // perform ADC on each "period" x bloc
         if ((++l1a_l1s_com.adc_cpt)>=l1a_l1s_com.adc_idle_period) // wait for the period
         {
           adc_active = ACTIVE;
           l1a_l1s_com.adc_cpt = 0;
         }
     }
  }
  return(adc_active);
}


#if (AMR == 1)
/*-------------------------------------------------------*/
/* l1s_amr_get_ratscch_type()                            */
/*-------------------------------------------------------*/
/*                                                       */
/* Description:                                          */
/* ------------                                          */
/* This function returns the type of a RATSCCH block     */
/* Decoding is done according to ETSI spec 05.09         */
/*                                                       */
/* Input parameter:                                      */
/* ---------------                                       */
/* "a_ratscch"                                           */
/*    pointer to the RATSCCH block                       */
/*                                                       */
/* Output parameter:                                     */
/* ----------------                                      */
/* Type of RATSCCH block.                                */
/*  Can be:  C_RATSCCH_UNKNOWN                           */
/*           C_RATSCCH_CMI_PHASE_REQ                     */
/*           C_RATSCCH_AMR_CONFIG_REQ_MAIN               */
/*           C_RATSCCH_AMR_CONFIG_REQ_ALT                */
/*           C_RATSCCH_AMR_CONFIG_REQ_ALT_IGNORE         */
/*           C_RATSCCH_THRES_REQ                         */
/*                                                       */
/*-------------------------------------------------------*/
UWORD8 l1s_amr_get_ratscch_type(API *a_ratscch)
{
  // Check if the RATSCCH block is a CMI_PHASE_REQ block
  // -> if and only if bits 1, 3 through 34 are cleared and bit 2 is set
  if(((UWORD16)(a_ratscch[3] & 0xFFFE) == 0x0004) &&     // bits 1, 3-15 are cleared, bit 2 is set
     ((UWORD16)(a_ratscch[4]) == 0x0000) &&              // bits 16-31 are cleared
     ((UWORD16)(a_ratscch[5] & 0x0007) == 0x0000))       // bits 32-34 are cleared
  {
    return C_RATSCCH_CMI_PHASE_REQ;
  }

  // Check if the RATSCCH block is a THRES_REQ block
  // -> if and only if bits 31 through 34 are cleared and bit 30 is set
  if(((UWORD16)(a_ratscch[4] & 0xC000) == 0x4000) &&     // bit 30 is set, bit 31 is cleared
     ((UWORD16)(a_ratscch[5] & 0x0007) == 0x0000))       // bits 32-34 are cleared
  {
    return C_RATSCCH_THRES_REQ;
  }

  // Check if the RATSCCH block is a AMR_CONFIG_REQ block
  // -> if and only if bits 33-34 are cleared and bits 30-32 are set
  if(((UWORD16)(a_ratscch[4] & 0xC000) == 0xC000) &&     // bits 30-31 are set
     ((UWORD16)(a_ratscch[5] & 0x0007) == 0x0001))       // bit 32 is set, bits 33-34 are cleared
  {
    // Check if it's a main AMR_CONFIG_REQ block or an alternative AMR_CONFIG_REQ block
    UWORD16 ratscch_acs = (a_ratscch[4] & 0x0FF0) >> 4;  // get bits 20-27
    UWORD8 nb_coders,i;

    // Count number of active coders
    for(i=0, nb_coders=0; i<8; i++)
    {
      if((ratscch_acs & 1)==1)	 nb_coders++;
      ratscch_acs >>= 1;
    }

    // If the number of coders is 1, 2 or 3, it is a main AMR_CONFIG_REQ block
    if(nb_coders<=3)
      return C_RATSCCH_AMR_CONFIG_REQ_MAIN;

    // If the number of coders is more than 4, it is an alternate AMR_CONFIG_REQ block
    // Check if it must be ignored (block THRES_REQ pending) or not
    // -> if and only if bits 0 through 19 are set
    if(((UWORD16)(a_ratscch[3]) == 0xFFFF) &&            // bits 0-15 are set
       ((UWORD16)(a_ratscch[4] & 0x000F) == 0x000F))     // bits 16-19 are set
      return C_RATSCCH_AMR_CONFIG_REQ_ALT_IGNORE;
    else
      return C_RATSCCH_AMR_CONFIG_REQ_ALT;
  }

  // Block is not recognized
  return C_RATSCCH_UNKNOWN;
}


/*--------------------------------------------------------*/
/* l1s_amr_update_from_ratscch()                          */
/*--------------------------------------------------------*/
/*                                                        */
/* Description:                                           */
/* ------------                                           */
/* This function updates the AMR parameters modified by   */
/* the RATSCCH block received. This updates is done both  */
/* in the NDB and in the L1A/L1S communication structure  */
/* (aset pointer).                                        */
/* Data manipulation is done according to ETSI spec 05.08 */
/*                                                        */
/* Input parameter:                                       */
/* ---------------                                        */
/* "a_ratscch_dl"                                         */
/*    pointer to the RATSCCH block                        */
/*                                                        */
/* Output parameter:                                      */
/* ----------------                                       */
/*  n/a                                                   */
/*                                                        */
/*--------------------------------------------------------*/
void l1s_amr_update_from_ratscch(API *a_ratscch_dl)
{
  UWORD16 acs,hysteresis1,hysteresis2,hysteresis3,threshold1,threshold2,threshold3,icm,cmip;
  UWORD16 amr_change_bitmap=0;
  UWORD8  ratscch_type;
  BOOL    ratscch_unknown=TRUE; // No AMR parameters update

  // Get the RATSCCH block's type
  ratscch_type = l1s_amr_get_ratscch_type(a_ratscch_dl);

  // Check the RATSCCH block's type
  switch(ratscch_type)
  {
    case C_RATSCCH_CMI_PHASE_REQ:
    {
      // Copy CMIP to L1 structure
      cmip = a_ratscch_dl[3] & 0x0001;                  // bit 0
      l1a_l1s_com.dedic_set.aset->cmip=(UWORD8)cmip;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_CMIP;
	  // AMR parameters update flag
      ratscch_unknown=FALSE;
    }
    break;
    case C_RATSCCH_AMR_CONFIG_REQ_MAIN:
    {
      // Copy ACS to L1 structure
      acs = (a_ratscch_dl[4] & 0x0FF0) >> 4;            // bits 20-27
      l1a_l1s_com.dedic_set.aset->amr_configuration.active_codec_set=(UWORD8)acs;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_ACS;

      // Copy ICM to L1 structure
      icm = (a_ratscch_dl[4] & 0x3000) >> 12;           // bits 28-29
      l1a_l1s_com.dedic_set.aset->amr_configuration.initial_codec_mode=(UWORD8)icm;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_ICM;

      // Copy hysteresis 1 to L1 structure
      hysteresis1 = (a_ratscch_dl[3] & 0x03C0) >> 6;    // bits 6-9
      l1a_l1s_com.dedic_set.aset->amr_configuration.hysteresis[0]=(UWORD8)hysteresis1;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_HYST1;

      // Copy threshold 1 to L1 structure
      threshold1 = a_ratscch_dl[3] & 0x003F;            // bits 0-5
      l1a_l1s_com.dedic_set.aset->amr_configuration.threshold[0]=(UWORD8)threshold1;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_THR1;

      // Copy hysteresis 2 to L1 structure
      hysteresis2 = a_ratscch_dl[4] & 0x000F;           // bits 16-19
      l1a_l1s_com.dedic_set.aset->amr_configuration.hysteresis[1]=(UWORD8)hysteresis2;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_HYST2;

      // Copy threshold 2 to L1 structure
      threshold2 = (a_ratscch_dl[3] & 0xFC00) >> 10;    // bits 10-15
      l1a_l1s_com.dedic_set.aset->amr_configuration.threshold[1]=(UWORD8)threshold2;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_THR2;
	  // AMR parameters update flag
      ratscch_unknown=FALSE;
    }
    break;
    case C_RATSCCH_AMR_CONFIG_REQ_ALT:
    {
      // Copy ACS to L1 structure
      acs = (a_ratscch_dl[4] & 0x0FF0) >> 4;            // bits 20-27
      l1a_l1s_com.dedic_set.aset->amr_configuration.active_codec_set=(UWORD8)acs;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_ACS;

      // Copy ICM to L1 structure
      icm = (a_ratscch_dl[4] & 0x3000) >> 12;         // bits 28-29
      l1a_l1s_com.dedic_set.aset->amr_configuration.initial_codec_mode=(UWORD8)icm;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_ICM;

      // Copy threshold 1 to L1 structure
      threshold1 = a_ratscch_dl[3] & 0x003F;           // bits 0-5
      l1a_l1s_com.dedic_set.aset->amr_configuration.threshold[0]=(UWORD8)threshold1;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_THR1;

      // Copy threshold 2 to L1 structure
      threshold2 = (a_ratscch_dl[3] & 0x0FC0) >> 6;    // bits 6-11
      l1a_l1s_com.dedic_set.aset->amr_configuration.threshold[1]=(UWORD8)threshold2;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_THR2;

      // Copy threshold 3 to L1 structure
      threshold3 = ((a_ratscch_dl[3] & 0xF000) >> 12) |  // bits 12-15
                   ((a_ratscch_dl[4] & 0x0003) << 4);    // bits 16-17
      l1a_l1s_com.dedic_set.aset->amr_configuration.threshold[2]=(UWORD8)threshold3;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_THR3;

      // Copy hysteresis 1, 2 and 3 (common hysteresis) to L1 structure
      hysteresis1 = (a_ratscch_dl[4] & 0x000C) >> 2;     // bits 18-19
      hysteresis2 = hysteresis3 = hysteresis1;
      l1a_l1s_com.dedic_set.aset->amr_configuration.hysteresis[0]=
        l1a_l1s_com.dedic_set.aset->amr_configuration.hysteresis[1]=
        l1a_l1s_com.dedic_set.aset->amr_configuration.hysteresis[2]=(UWORD8)hysteresis1;
      amr_change_bitmap |= (1 << C_AMR_CHANGE_HYST1) | (1 << C_AMR_CHANGE_HYST2) | (1 << C_AMR_CHANGE_HYST3);
	  // AMR parameters update flag
      ratscch_unknown=FALSE;
    }
    break;
    case C_RATSCCH_AMR_CONFIG_REQ_ALT_IGNORE:
    {
      // Copy ACS to L1 structure
      acs = (a_ratscch_dl[4] & 0x0FF0) >> 4;            // bits 20-27
      l1a_l1s_com.dedic_set.aset->amr_configuration.active_codec_set=(UWORD8)acs;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_ACS;

      // Copy ICM to L1 structure
      icm = (a_ratscch_dl[4] & 0x3000) >> 12;           // bits 28-29
      l1a_l1s_com.dedic_set.aset->amr_configuration.initial_codec_mode=(UWORD8)icm;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_ICM;
	  // AMR parameters update flag
      ratscch_unknown=FALSE;
    }
    break;
    case C_RATSCCH_THRES_REQ:
    {
      // Copy hysteresis 1 to L1 structure
      hysteresis1 = (a_ratscch_dl[3] & 0x03C0) >> 6;    // bits 6-9
      l1a_l1s_com.dedic_set.aset->amr_configuration.hysteresis[0]=(UWORD8)hysteresis1;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_HYST1;

      // Copy threshold 1 to L1 structure
      threshold1 = a_ratscch_dl[3] & 0x003F;            // bits 0-5
      l1a_l1s_com.dedic_set.aset->amr_configuration.threshold[0]=(UWORD8)threshold1;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_THR1;

      // Copy hysteresis 2 to L1 structure
      hysteresis2 = a_ratscch_dl[4] & 0x000F;           // bits 16-19
      l1a_l1s_com.dedic_set.aset->amr_configuration.hysteresis[1]=(UWORD8)hysteresis2;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_HYST2;

      // Copy threshold 2 to L1 structure
      threshold2 = (a_ratscch_dl[3] & 0xFC00) >> 10;    // bits 10-15
      l1a_l1s_com.dedic_set.aset->amr_configuration.threshold[1]=(UWORD8)threshold2;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_THR2;

      // Copy hysteresis 3 to L1 structure
      hysteresis3 = (a_ratscch_dl[4] & 0x3C00) >> 10;   // bits 26-29
      l1a_l1s_com.dedic_set.aset->amr_configuration.hysteresis[2]=(UWORD8)hysteresis3;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_HYST3;

      // Copy threshold 3 to L1 structure
      threshold3 = (a_ratscch_dl[4] & 0x03F0) >> 4;     // bits 20-25
      l1a_l1s_com.dedic_set.aset->amr_configuration.threshold[2]=(UWORD8)threshold3;
      amr_change_bitmap |= 1 << C_AMR_CHANGE_THR3;
	  // AMR parameters update flag
      ratscch_unknown=FALSE;
    }
    break;
    case C_RATSCCH_UNKNOWN:
    {
      // No AMR parameters update
      ratscch_unknown=TRUE;
    }
    break;
  }
  // AMR parameters update only if valid RATSCCH
  if(ratscch_unknown==FALSE)
  {
    // Update NDB with new AMR parameters
    l1ddsp_load_amr_param(l1a_l1s_com.dedic_set.aset->amr_configuration,l1a_l1s_com.dedic_set.aset->cmip);

#if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
    l1_trace_ratscch(l1s.actual_time.fn_mod42432,amr_change_bitmap);
#endif
  }
}

#endif    // AMR


/*
 * FreeCalypso TCS211 reconstruction: the following l1_memcpy_16bit()
 * function has been moved to l1_dyn_dwl_func.c.
 */

#if 0
/*--------------------------------------------------------*/
/* l1_memcpy_16bit()                                      */
/*--------------------------------------------------------*/
/*                                                        */
/* Description:                                           */
/* ------------                                           */
/* This function is equivalemt of memcopy. Thid function  */
/* does only 8/16 bit accessed to both source and         */
/* destination                                            */
/*                                                        */
/* Input parameter:                                       */
/* ---------------                                        */
/* "src" - input pointer                                  */
/* "len" - number of bytes to copy                        */
/*                                                        */
/* Output parameter:                                      */
/* ----------------                                       */
/*  "dst" - output pointer                                */
/*                                                        */
/*--------------------------------------------------------*/
void l1_memcpy_16bit(void *dst,void* src,unsigned int len)
{
	unsigned int i;
	unsigned int tempLen;
	unsigned char *cdst,*csrc;
	unsigned short *ssrc,*sdst;

	cdst=dst;
	csrc=src;
	sdst=dst;
	ssrc=src;

  if(((unsigned int)src&0x01) || ((unsigned int)dst&0x01)){
  // if either source or destination is not 16-bit aligned do the entire memcopy
  // in 8-bit
    for(i=0;i<len;i++){
      *cdst++=*csrc++;
    }
  }
  else{
    // if both the source and destination are 16-bit aligned do the memcopy
    // in 16-bits
    tempLen = len>>1;
    for(i=0;i<tempLen;i++){
      *sdst++ = *ssrc++;
    }
    if(len & 0x1){
      // if the caller wanted to copy odd number of bytes do a last 8-bit copy
      cdst=(unsigned char*)sdst;
      csrc=(unsigned char*)ssrc;
      *cdst++ = *csrc++;
    }
  }
  return;
}
#endif

#if (FF_L1_FAST_DECODING == 1)
/*-----------------------------------------------------------------*/
/* l1s_restore_synchro                                             */
/*-----------------------------------------------------------------*/
/* Description:                                                    */
/* ------------                                                    */
/* This function restores TPU synchro after an actiity             */
/* using synchro/synchro back scheme.                              */
/*                                                                 */
/* Input parameters:                                               */
/* -----------------                                               */
/* None                                                            */
/*                                                                 */
/* Input parameters from globals:                                  */
/* ------------------------------                                  */
/*  l1s.tpu_offset                                                 */
/*  l1s.next_time                                                  */
/*  l1s.next_plus_time                                             */
/*                                                                 */
/* Output parameters:                                              */
/* ------------------                                              */
/*  None                                                           */
/*                                                                 */
/* Modified parameters from globals:                               */
/* ---------------------------------                               */
/*  l1s.actual_time                                                */
/*  l1s.next_time                                                  */
/*  l1s.next_plus_time                                             */
/*  l1s.tpu_ctrl_reg                                               */
/*  l1s.dsp_ctrl_reg                                               */
/*-----------------------------------------------------------------*/
void l1s_restore_synchro(void)
{
  // 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

  l1s.tpu_ctrl_reg |= CTRL_SYCB;
  l1s.dsp_ctrl_reg |= CTRL_SYNC;

#if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
  trace_fct(CST_L1S_ADJUST_TIME, (UWORD32)(-1));
#endif
}

BOOL l1s_check_deferred_control(UWORD8 task, UWORD8 burst_id)
{
  /* Control activities are performed only if:
      - Fast decoding is not authorized
      - Fast decoding authorized, control running inside the fast HISR context and not first burst
      - Fast decoding authorized, control running inside L1S context and first burst */

  /* Running from fast API HISR? */
  BOOL fast_decoding_hisr = (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_PROCESSING);

  if (fast_decoding_hisr && (burst_id == BURST_1))
  {
    /* Error this case shouldn't happen */
    return TRUE;
  }
  else if (!fast_decoding_hisr && (burst_id != BURST_1))
  {
    /* Currently running from L1S, control must be performed on the upcoming fast HISR */
    l1a_apihisr_com.fast_decoding.task                 = task;
    l1a_apihisr_com.fast_decoding.burst_id             = burst_id;
    /* If a tasks semaphore get SET do not do deferred control */
    if(!(l1a_l1s_com.task_param[task] == SEMAPHORE_SET))
    {
      l1a_apihisr_com.fast_decoding.deferred_control_req = TRUE;
    return TRUE;
  }
  }
  else if (!fast_decoding_hisr && (burst_id == BURST_1))
  {
    /* Control running from L1S for the first burst => Control must be performed now. */
    /* As a result, a fast API IT will be triggered on the next frame                 */

    if (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_AWAITED)
    {
      /* A fast API IT was already awaited. It means that we are starting the fast decoding */
      /* of a new block before the previous one is finished.                                */
      /* This case is signaled through the variable below so the status can stay as awaited */
      /* for the first fast API IT of the new block.                                        */
      l1a_apihisr_com.fast_decoding.contiguous_decoding = TRUE;
    }
    else
    {
      l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_AWAITED;
    }
    l1a_apihisr_com.fast_decoding.task                 = task;
    return FALSE;
}
  /* In other cases do control now. */
  return FALSE;
} /* end function l1s_check_deferred_control */

BOOL l1s_check_fast_decoding_authorized(UWORD8 task)
{
  BOOL result = FALSE;

  /* Is a fast decoding already in progress (AWAITED or PROCESSING states)?          */
  /* Is a fast decoding complete but waiting for the read activity (COMPLETE state)? */
  /* In that case, it will continue, even if a mode change has occured.              */
  BOOL already_in_progress = (    (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_AWAITED)
                               || (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_PROCESSING)
                               || (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_COMPLETE) );

  /* One variable used later that contains the status of several tasks */
  BOOL no_serving_audio_and_neighbour_tasks = (
                                            (l1a_l1s_com.l1s_en_task[EP] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[ALLC] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[NSYNC] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[FBNEW] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[SBCONF] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[BCCHN] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[EBCCHS] == TASK_DISABLED)
                                         //&& (l1a_l1s_com.l1s_en_task[NBCCHS] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[BCCHN_TOP] == TASK_DISABLED)
#if (L1_GPRS)
                                         && (l1a_l1s_com.l1s_en_task[PBCCHS] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[PEP] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[PALLC] == TASK_DISABLED)
                                         && (l1a_l1s_com.l1s_en_task[PBCCHN_IDLE] == TASK_DISABLED)
#endif /* L1_GPRS */
                                         //&& (l1a_l1s_com.l1s_en_task[SMSCB] == TASK_DISABLED)
#if (L1_MP3 == 1)  
                                         && (l1a_apihisr_com.mp3.running == FALSE)
#endif
#if (L1_AAC == 1)      
                                         && (l1a_apihisr_com.aac.running == FALSE)
#endif
                                        );

  /* If fast decoding is already forbidden, do not enable it until the end of the block. */
  /* The forbidden status is reset at the first control of the block                     */
  if (l1a_apihisr_com.fast_decoding.status == C_FAST_DECODING_FORBIDDEN)
  {
    return FALSE;
  }

  switch(task)
  {
    case NP:
    {
      /* Enable Fast Paging (NP) except if CCCH reorg*/
      if (  ( already_in_progress == TRUE )
          ||
            (    (l1a_l1s_com.mode == I_MODE)
              && (l1a_l1s_com.l1s_en_task[NP] == TASK_ENABLED)
              && (no_serving_audio_and_neighbour_tasks == TRUE) )
         )
      {
        result = TRUE;
      }
      break;
    } /* case NP */

    case NBCCHS:
    {
      /* Enable Fast Paging (NP) except if CCCH reorg*/
      if (  ( already_in_progress == TRUE )
          ||
            (    (l1a_l1s_com.mode == I_MODE)
              && (l1a_l1s_com.l1s_en_task[NBCCHS] == TASK_ENABLED)
              && (no_serving_audio_and_neighbour_tasks == TRUE) )
         )
      {
        result = TRUE;
      }
      break;
    } /* case NBCCHS */

#if (L1_GPRS)
    case PNP:
    {
      /* Enable Fast Paging (PNP) except if PCCCH reorg*/
      if (  ( already_in_progress == TRUE )
          ||
            (    (l1a_l1s_com.mode == I_MODE)
              && (l1a_l1s_com.l1s_en_task[PNP] == TASK_ENABLED)
              && (no_serving_audio_and_neighbour_tasks == TRUE)
            )
         )
      {
        result = TRUE;
      }
      break;
    } /* case PNP */
#endif /* L1_GPRS*/

  } /* switch(task) */

#if (L1_GPRS)
  if ((result == FALSE) && ((task == NP) || (task == PNP) || (task == NBCCHS)))
#else  /* NO_GPRS*/
  if ((result == FALSE) && ((task == NP) || (task == NBCCHS)))
#endif /* L1_GPRS */
  {
    l1a_apihisr_com.fast_decoding.status = C_FAST_DECODING_FORBIDDEN;
  }

  return result;
} /* end function l1s_check_fast_decoding_authorized */

#endif /* FF_L1_FAST_DECODING */
/*-----------------------------------------------------------------*/
/* l1s_check_sacch_dl_block                                        */
/*-----------------------------------------------------------------*/
/* Description:                                                    */
/* ------------                                                    */
/* Downlink SACCH buffer comparison function for FER Traces        */
/* This is called only when there is a successfully decoded        */
/* block. The count of no of successfully decoded SACCH  blocks    */
/* is  updated.                                                    */
/*                                                                 */
/* Input parameters:                                               */
/* -----------------                                               */
/*  sacch_dl_block  "Downlink SACCH BLOCK"                         */
/*                                                                 */
/* Output parameters:                                              */
/* ------------------                                              */
/*  None                                                           */
/*                                                                 */
/*-----------------------------------------------------------------*/
#if ((FF_REPEATED_SACCH) && (TRACE_TYPE ==1 || TRACE_TYPE == 4))

void l1s_check_sacch_dl_block(API *sacch_dl_block)
{
     int i,j,repeat=1;
     if( trace_info.repeat_sacch.dl_buffer_empty == FALSE )
     {
           for(i=3,j=0;i<15;i++,j++)
           {
               if(trace_info.repeat_sacch.dl_buffer[j] != sacch_dl_block[i])
              {
                   break;
               }
           }
           if( i != 15 )
           {
                repeat=0;
           }
     }
     else /* if( trace_info.repeat_sacch.dl_buffer_empty == FALSE ) */
     {
         repeat=0;
     }   /* end else empty DL SACCH buffer*/
     if(repeat == 0)
     {
           trace_info.repeat_sacch.dl_good_norep++;
           for ( i=3 ; i<15 ; i++ )
          {
               trace_info.repeat_sacch.dl_buffer[i] = sacch_dl_block[i];// info_address[i];
          }
          trace_info.repeat_sacch.dl_buffer_empty = FALSE;
     } /* end if repeat = 0*/
     else
     {
        trace_info.repeat_sacch.dl_buffer_empty = TRUE;
     }  /* end else repeat = 1*/
} /* end function void l1s_check_sacch_dl_block */
#endif /*  ((FF_REPEATED_SACCH) && (TRACE_TYPE ==1 || TRACE_TYPE == 4)) */


/*-----------------------------------------------------------------*/
/* l1s_store_sacch_buffer                                          */
/*-----------------------------------------------------------------*/
/* Description:                                                    */
/* ------------                                                    */
/* Function to store data in case of a retransmission.             */
/*                                                                 */
/*                                                                 */
/* Input parameters:                                               */
/* -----------------                                               */
/*  sacch_ul_block  "SACCH Uplink block to be stored"              */
/*  repeat_sacch    "The buffer tocontain the stored block"        */
/*                                                                 */
/* Output parameters:                                              */
/* ------------------                                              */
/*  None                                                           */
/*                                                                 */
/*-----------------------------------------------------------------*/

#if (FF_REPEATED_SACCH == 1 )
void l1s_store_sacch_buffer(T_REPEAT_SACCH *repeat_sacch, UWORD8 *sacch_ul_block)
{
       int i=0;
       /* Store the first 11 words after header in the first 22 bytes. */
       for(i=0;i<23;i++)
       {
          repeat_sacch->buffer[i] = sacch_ul_block[i] ;
       }
       repeat_sacch->buffer_empty = FALSE;
}
#endif /* (FF_REPEATED_SACCH == 1 ) */


/*-----------------------------------------------------------------*/
/* l1s_repeated_facch_check                                                                           */
/*-----------------------------------------------------------------*/
/* Description:                                                                                               */
/* ------------                                                                                           */
/* If two successfully decoded blocks (separated by 8 or 9 frames)  are             */
/*  identical then it returns a NULL buffer otherwise a pointer to the last block      */
/*   data.                                                                                                       */
/*                                                                                                                 */
/*                                                                                                                 */
/* Input parameters:                                                                                      */
/* -----------------                                                                                  */
/*                         "FACCH  block to be stored"                                               */
/*                                                                                                                */
/* Output parameters:                                                                                  */
/* ------------------                                                                               */
/*  None                                                                                                       */
/*                                                                                                                  */
/*-----------------------------------------------------------------*/


#if ( FF_REPEATED_DL_FACCH == 1 )
API * l1s_repeated_facch_check(API *info_address)
{
      unsigned int repeat=1;
      unsigned int i,j;
      UWORD8 counter_candidate;
  
     counter_candidate=l1s.repeated_facch.counter_candidate;
     if( l1s.repeated_facch.pipeline[counter_candidate].buffer_empty == FALSE )
    {     
         for(i=3,j=0;i<15;j++,i++)
        {
            if(l1s.repeated_facch.pipeline[counter_candidate].buffer[j] != info_address[i])
           {  
               break;
            }   
         }  
         if( i != 15 ) 
        {  
            repeat=0;
         }  
    } 
    else
   {
        repeat=0;
    } /* end else buffer empty*/
#if TESTMODE
      if(l1_config.repeat_facch_dl_enable != REPEATED_FACCHDL_ENABLE)  // repeated FACCH mode is disabled
     {  
          repeat = 0;
     }   
#endif
     if(repeat == 0)
    {
         return &info_address[0];
     } 
    else
   {
    #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
         trace_info.facch_dl_repetition_block_count++; 
    #endif
    if (((l1s.actual_time.fn - fn_prev ) == 8) || ((l1s.actual_time.fn - fn_prev ) == 9 )) // added debug
    return (API)NULL;
    else
    return &info_address[0];
    }
}
#endif /*  FF_REPEATED_DL_FACCH == 1 */



#if ( FF_REPEATED_DL_FACCH == 1 )
void l1s_store_facch_buffer(T_REPEAT_FACCH *repeated_facch, API *facch_block)
{
      int i;
	UWORD8 counter_candidate; 
	fn_prev = l1s.actual_time.fn ;// added
      counter_candidate=repeated_facch->counter_candidate;
       /*  Store the first 12 words after header in the first 23 bytes. */
       for(i=0;i<13;i++)
       {
          repeated_facch->pipeline[counter_candidate].buffer[i] = facch_block[i] ;
       }
       repeated_facch->pipeline[counter_candidate].buffer_empty = FALSE;
}
#endif /* ( FF_REPEATED_DL_FACCH == 1 ) */

#if(L1_FF_MULTIBAND == 1)

#if 0

/*-------------------------------------------------------*/
/* l1_multiband_radio_freq_convert_into_effective_band_id*/
/*-------------------------------------------------------*/
/* Parameters : radio_freq the frequency to convert      */
/*                                                       */
/*                                                       */
/*                                                       */
/* Return     : the ID of the effectiev band in which    */
/* is located radio_freq                                 */
/* Functionality : compare radio_freq with the effective */
/* bands ranges, return efective_band_id                 */
/*                                                       */
/*                                                       */
/*-------------------------------------------------------*/
UWORD8  l1_multiband_radio_freq_convert_into_effective_band_id(UWORD16 radio_freq)
{
  UWORD8 effective_band_id = 0;
  while( effective_band_id < NB_MAX_EFFECTIVE_SUPPORTED_BANDS)
  {  
    if ((radio_freq >= multiband_conversion_data[effective_band_id].first_radio_freq)
       && (radio_freq < (multiband_conversion_data[effective_band_id].first_radio_freq + multiband_conversion_data[effective_band_id].nbmax_carrier)) )

    {
      return(effective_band_id);
    }
    else
    {
     effective_band_id ++;
    }
  }
  if(effective_band_id == NB_MAX_EFFECTIVE_SUPPORTED_BANDS)
  {
    l1_multiband_error_handler(radio_freq);
  }
  return(effective_band_id);

}
/*-------------------------------------------------------*/
/* l1_multiband_radio_freq_convert_into_physical_band_id */
/*-------------------------------------------------------*/
/* Parameters : radio_freq the frequency to convert      */
/*                                                       */
/*                                                       */
/*                                                       */
/* Return     : the ID of the physical_band band in which*/
/*  radio_freq is located                                */
/* Functionality : Identify effective_band_id, the ID of */
/* the effective band in whicb radio_freq is located     */
/* then derive physical_band_id from effective_band_id   */
/*-------------------------------------------------------*/

UWORD8 l1_multiband_radio_freq_convert_into_physical_band_id(UWORD16 radio_freq)
{ 
  UWORD8 effective_band_id, physical_band_id;
  effective_band_id = l1_multiband_radio_freq_convert_into_effective_band_id(radio_freq);
  physical_band_id = multiband_conversion_data[effective_band_id].physical_band_id;
  return(physical_band_id);
}

/*-------------------------------------------------------*/
/* l1_multiband_radio_freq_convert_into_operative_radio_freq*/
/*-------------------------------------------------------*/
/* Parameters : radio_freq the frequency to convert      */
/*                                                       */
/*                                                       */
/*                                                       */
/* Return     : the operative_radio_freq corresponding to radio_freq */
/* Functionality : identify effective_band_id, then      */
/* based on the relationships linking the ranges of operative_radio_freq*/
/* and radio_freq , derive operative_radio_freq           */
/*-------------------------------------------------------*/
UWORD16 l1_multiband_radio_freq_convert_into_operative_radio_freq(UWORD16 radio_freq)
{
  UWORD8 effective_band_id;
  UWORD16 operative_radio_freq;
  effective_band_id = l1_multiband_radio_freq_convert_into_effective_band_id(radio_freq);
  operative_radio_freq = radio_freq - multiband_conversion_data[effective_band_id].first_radio_freq + multiband_conversion_data[effective_band_id].first_operative_radio_freq;
  return(operative_radio_freq);
} 
/*--------------------------------------------------------*/
/* l1_multiband_map_radio_freq_into_tpu_table             */
/*--------------------------------------------------------*/
/* Parameters :                                           */
/* radio_freq the parameter to be converted               */
/*                                                        */
/* Return     : the index in table rf_band or rf_tpu_band */
/* corresponding to radio_freq                            */
/* Functionality :identify physical_band_id               */
/* then derive from physical_band_id, tpu_band_index to be*/
/* returned a physical band having the ID physical_band_id*/
/* is mapped to the table  rf_band[physical_band_id ]     */                                                    
/*--------------------------------------------------------*/
UWORD8 l1_multiband_map_radio_freq_into_tpu_table(UWORD16 radio_freq)
{
  UWORD8 tpu_table_index = 0;
  UWORD8 physical_band_id = 0;
  physical_band_id =  l1_multiband_radio_freq_convert_into_physical_band_id(radio_freq);
  /*For Neptune a band having the ID physical_band_id is mapped to multiband_rf_data[physical_band_id], rf_band[physical_band_id]*/
  /*Consequently the existence of this API for API is not necessary since it is redundant with l1_multiband_radio_freq_convert_into_physical_band_id*/
  tpu_table_index = physical_band_id;
  return(tpu_table_index);
}
/*--------------------------------------------------------*/
/* l1_multiband_error_handler                             */
/*--------------------------------------------------------*/
/* Parameters :                                           */
/* radio_freq the channel number received from the L3     */
/*                                                        */
/* Return     :                                           */
/* corresponding to radio_freq                            */
/* Functionality :handling error code of MULTIBAND        */                                                    
/*--------------------------------------------------------*/
void l1_multiband_error_handler(UWORD16 radio_freq)
{
  L1_MULTIBAND_TRACE_PARAMS(MULTIBAND_ERROR_TRACE_ID, 1);
#if (OP_L1_STANDALONE == 1)
#if(CODE_VERSION == NOT_SIMULATION)
  L1BSP_error_handler();
#endif /*if(CODE_VERSION == NOT_SIMULATION)*/
#endif
}
#endif // if 0
#endif   /*if (L1_FF_MULTIBAND == 1)*/ 

#if (OP_L1_STANDALONE == 1)

UWORD8 l1_get_pwr_mngt()
{
    return(l1_config.pwr_mngt);
}

#endif 

#if (L1_FF_MULTIBAND == 1)
void l1_multiband_error_handler(UWORD16 radio_freq)
{
    while(1);
}
#endif