diff src/cs/layer1/cmacs/macs.c @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cs/layer1/cmacs/macs.c	Fri Oct 16 06:23:26 2020 +0000
@@ -0,0 +1,3164 @@
+/************* Revision Control System Header *************
+ *                  GSM Layer 1 software
+ * MACS.C
+ *
+ *        Filename macs.c
+ *  Copyright 2003 (C) Texas Instruments
+ *
+ ************* Revision Control System Header *************/
+
+
+//---Configuration flags---------------------------------------------------
+
+#define TFI_FILTERING   1   // TFI FILTERING activated if set to 1
+//-------------------------------------------------------------------------
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "l1_macro.h"
+#include "l1_confg.h"
+
+#if L1_GPRS
+
+#include "l1_types.h"
+#include "l1_const.h"
+
+#if TESTMODE
+  #include "l1tm_defty.h"
+  #include "l1tm_varex.h"
+#endif
+#if (AUDIO_TASK == 1)
+  #include "l1audio_const.h"
+  #include "l1audio_cust.h"
+  #include "l1audio_defty.h"
+#endif
+#if (L1_GTT == 1)
+  #include "l1gtt_const.h"
+  #include "l1gtt_defty.h"
+#endif
+#if (L1_MP3 == 1)
+  #include "l1mp3_defty.h"
+#endif
+#if (L1_MIDI == 1)
+  #include "l1midi_defty.h"
+#endif
+#include "l1_defty.h"
+#include "l1_varex.h"
+#include "l1_signa.h"
+
+#include "l1p_cons.h"
+#include "l1p_msgt.h"
+#include "l1p_deft.h"
+#include "l1p_vare.h"
+#include "l1p_sign.h"
+
+#include "macs_def.h"
+#include "macs_cst.h"
+#include "macs_var.h"
+
+#if FF_TBF
+  #include "l1_trace.h"
+  #if (CODE_VERSION == SIMULATION)
+    #include "sim_cons.h"
+    #include "sim_def.h"
+    #include "sim_var.h"
+  #endif
+#endif
+/**********************************************************/
+/* MACS-S Prototypes                                      */
+/**********************************************************/
+
+void l1ps_macs_meas            (void);                // Measurement gap processing
+void l1ps_macs_header_decoding (UWORD8 rx_no,
+                                UWORD8 *tfi_result,
+                                UWORD8 *pr);          // MAC header decoding
+void l1ps_macs_read            (UWORD8 pr_table[8]);  // MAC-S control tasks processing
+void l1ps_macs_ctrl            (void);                // MAC-S read tasks processing
+void l1ps_macs_init            (void);                // MAC-S initialization
+
+#if FF_TBF
+void l1ps_macs_rlc_uplink_info (void);
+#endif
+
+/**********************************************************/
+/* EXTERNAL Prototypes                                    */
+/**********************************************************/
+
+void l1pddsp_transfer_mslot_ctrl(UWORD8  burst_nb,
+                                 UWORD8  dl_bitmap,
+                                 UWORD8  ul_bitmap,
+                                 UWORD8  *usf_table,
+                                 UWORD8  mac_mode,
+                                 UWORD8  *ul_buffer_index,
+                                 UWORD8  tsc,
+                                 UWORD16 radio_freq,
+                                 UWORD8  synchro_timeslot,
+                               #if FF_L1_IT_DSP_USF
+                                 UWORD8  dsp_usf_interrupt
+                               #else
+                                 UWORD8  usf_vote_enable
+                               #endif
+                               );
+
+/* RLC interface for uplink RLC/MAC blocks */
+/*-----------------------------------------*/
+
+void rlc_uplink(
+                 UWORD8   assignment_id,
+                 UWORD8   tx_data_no,            // Number of timeslot that can be used
+                                                 //   for uplink data block transfer
+                 UWORD32  fn,                    // Next frame number
+                 UWORD8   timing_advance_value,  // Timing advance (255 if unknown)
+                 API      *ul_poll_response,     // Pointer on a_pu_gprs (NDB): poll response blocks
+                 API      *ul_data,              // Pointer on a_du_gprs (NDB): uplink data blocks
+                 BOOL     allocation_exhausted   // Set to 1 if fixed allocation exhausted
+               );
+
+#if TESTMODE
+void l1tm_rlc_uplink(UWORD8 tx, API *ul_data);
+#endif
+
+/* RLC interface for downlink RLC/MAC blocks */
+/*-------------------------------------------*/
+#if FF_TBF
+
+void rlc_downlink_data(
+                        UWORD8   assignment_id,
+                        UWORD32  fn,             // Actual frame number
+                        API      *dl             // Pointer on a_dd_gprs (NDB): downlink blocks
+                      );
+void rlc_uplink_info(
+                     UWORD8   assignment_id,
+                     UWORD32  fn,
+                     UWORD8   rlc_blocks_sent,    // Number of uplink blocks that was transmitted
+                                                  // during the last block period
+                     UWORD8   last_poll_response  // Status of the poll responses of
+                    );                            // the last block period
+
+UWORD8 rlc_downlink_copy_buffer(UWORD8 isr);
+
+
+#else
+
+void rlc_downlink(
+                   UWORD8   assignment_id,
+                   UWORD32  fn,                  // Actual frame number
+                   API      *dl,                 // Pointer on a_dd_gprs (NDB): downlink blocks
+                   UWORD8   rlc_blocks_sent,     // Number of uplink blocks that was transmitted
+                                                 //   during the last block period
+                   UWORD8   last_poll_response   // Status of the poll responses of
+                                                 //   the last block period
+                 );
+
+#endif
+
+#if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+  #include "l1_trace.h"
+#endif
+
+
+#if FF_TBF
+  #include <stddef.h>
+
+  #if (CODE_VERSION == SIMULATION)
+    API* const A_DD_XGPRS[1][4] =
+    {
+      {&buf.ndb_gprs.a_dd_gprs[0][0], &buf.ndb_gprs.a_dd_gprs[1][0], &buf.ndb_gprs.a_dd_gprs[2][0], &buf.ndb_gprs.a_dd_gprs[3][0]},
+    };
+
+    API* const A_DU_XGPRS[1][4] =
+    {
+      {&buf.ndb_gprs.a_du_gprs[0][0], &buf.ndb_gprs.a_du_gprs[1][0], &buf.ndb_gprs.a_du_gprs[2][0], &buf.ndb_gprs.a_du_gprs[3][0]}
+    };
+
+  #else
+    API* const A_DD_XGPRS[1][4] =
+    {
+      {
+        (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS, a_dd_gprs[0][0])),
+        (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS, a_dd_gprs[1][0])),
+        (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS, a_dd_gprs[2][0])),
+        (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS, a_dd_gprs[3][0]))
+      }
+    };
+
+    API* const  A_DU_XGPRS[1][4] =
+    {
+      {
+        (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS,a_du_gprs[0][0])),
+        (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS,a_du_gprs[1][0])),
+        (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS,a_du_gprs[2][0])),
+        (API*)(NDB_ADR_GPRS + offsetof(T_NDB_MCU_DSP_GPRS,a_du_gprs[3][0]))
+      }
+    };
+  #endif
+
+#endif
+/*-----------------------------------------------------------*/
+/* l1ps_macs_init()                                          */
+/*-----------------------------------------------------------*/
+/* Parameters:                                               */
+/*                                                           */
+/* Return:                                                   */
+/*                                                           */
+/* Description: This function initializes MAC-S variables    */
+/*              and must be called before the first call     */
+/*              of MAC-S                                     */
+/*-----------------------------------------------------------*/
+void l1ps_macs_init(void)
+{
+  UWORD8 i;
+
+  #if FF_TBF
+    macs.dl_buffer_index            = INVALID;
+    for (i=0;i<NBR_SHARED_BUFFER_RLC;i++)
+      macs.rlc_dbl_buffer[i].d_rlcmac_rx_no_gprs = 0xff;
+  #endif
+  /* General TBF parameters processed by MAC-S */
+  /*********************************************/
+
+  macs.sti_block_id           = 0;
+
+  /* Ressources allocated by MAC-S             */
+  /*********************************************/
+
+  macs.rx_allocation          = 0;
+  macs.tx_allocation          = 0;
+  macs.tx_prach_allocation    = 0;
+  macs.tx_data                = 0;
+  macs.pwr_allocation         = 0xff;
+  macs.last_rx_alloc          = 0;
+
+  #if FF_L1_IT_DSP_USF
+    macs.dsp_usf_interrupt    = 0;
+  #endif
+
+  macs.rx_blk_period          = NO_DL_BLK;
+  macs.rlc_blocks_sent        = 0;
+  macs.rx_no                  = 0;
+  macs.last_poll_response     = 0;
+
+  macs.usf_good               = 0;
+  macs.usf_vote_enable        = 0;
+  macs.tra_gap                = 8;
+  macs.fix_alloc_exhaust      = FALSE;
+  macs.next_usf_mon_block[0]  = macs.next_usf_mon_block[1] = 0;
+
+  for (i = 0; i < TS_NUMBER; i ++)
+  {
+    macs.ul_buffer_index[i] = INVALID;
+  }
+  #if L1_EDA
+    for (i = 0; i < 4; i++)
+    {
+      macs.monitored_ts[i] = INVALID;
+    }
+    macs.rx_monitored      = 0;
+    macs.last_rx_monitored = 0;
+    macs.lowest_poll_ts    = INVALID;
+  #endif
+
+  #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+    // Reset PDTCH trace structure
+    for(i=0; i<8; i++)
+    {
+      trace_info.pdtch_trace.dl_status[i] = 0;
+      trace_info.pdtch_trace.ul_status[i] = 0;
+      trace_info.pdtch_trace.blk_status   = 0;
+    }
+  #endif
+
+} /* End of l1ps_macs_init */
+
+/*-----------------------------------------------------------*/
+/* l1ps_macs_ctrl()                                          */
+/*-----------------------------------------------------------*/
+/* Parameters:global l1ps_macs_com           changed         */
+/*            global l1s                     unchanged       */
+/*            global l1a_l1s_com             unchanged       */
+/*            global l1ps_dsp_com            changed         */
+/*                                                           */
+/* Return:                                                   */
+/*                                                           */
+/* Description: MAC_S manages the timeslot allocation for    */
+/*              downlink and uplink transfer and assign a    */
+/*              measurement gap according to the MS class,   */
+/*              the frame number when it's called and the    */
+/*              allocation information given by Layer 1.     */
+/*              It also program the corresponding tasks on   */
+/*              the DSP and asks the RLC layer for uplink    */
+/*              blocks                                       */
+/*-----------------------------------------------------------*/
+void l1ps_macs_ctrl(void)
+{
+  #define NDB_PTR  l1ps_dsp_com.pdsp_ndb_ptr
+  #define SET_PTR  l1pa_l1ps_com.transfer.aset
+
+  #if MACS_STATUS
+    // No error
+    l1ps_macs_com.macs_status.nb = 0;
+  #endif
+
+  /***********************************************************/
+  /* USF values updating in dynamic mode (first frames of    */
+  /* block periods)                                          */
+  /***********************************************************/
+
+  if  ((SET_PTR->allocated_tbf == UL_TBF) || (SET_PTR->allocated_tbf == BOTH_TBF))
+  {
+  #if L1_EDA
+    if ((SET_PTR->mac_mode == DYN_ALLOC) || (SET_PTR->mac_mode == EXT_DYN_ALLOC))
+  #else
+    if (SET_PTR->mac_mode == DYN_ALLOC)
+  #endif
+    {
+      // Test if the USF must be read in the current frame
+      // Concern the first frames of each block period (useful when
+      // some USF values weren't valid the frame before)
+      //                                                            FN 13
+      //    0   1   2   3    4   5   6   7    8   9   10  11   12
+      // ----------------------------------------------------------
+      // ||       B0      ||       B1      ||       B2      || I ||
+      // ||   |   |   |   ||   | X |   |   ||   | X |   |   ||   ||
+      // ----------------------------------------------------------
+      //                                                            X:USF Reading
+
+    #if FF_L1_IT_DSP_USF
+      if (l1ps_macs_com.usf_status == USF_IT_DSP)
+    #else
+      if (   (l1s.next_time.fn_mod13 == 5)
+          || (l1s.next_time.fn_mod13 == 9))
+    #endif
+      {
+        // USF values are read
+        // Uplink timeslots whose USF was INVALID the frame before are de-allocated
+        // if their USF value is now BAD
+
+        UWORD8 tn;
+
+        // Reading of the d_usf_updated_gprs value
+        API    usf_updated = NDB_PTR->d_usf_updated_gprs;
+
+        #if !L1_EDA
+        // For each timeslot that can be allocated in uplink...
+        for (tn = macs.first_monitored_ts; tn <= macs.last_monitored_ts; tn ++)
+        {
+          // If USF vote was enabled on this timeslot
+          if(macs.usf_vote_enable & (MASK_SLOT0 >> tn))
+          {
+            // Clear the USF vote flag
+            macs.usf_vote_enable &= ~(MASK_SLOT0 >> tn);
+
+            // Read USF value
+            if (((usf_updated >> ((MAX_TS_NB - tn) * 2)) & MASK_2SLOTS) == USF_GOOD)
+            {
+              // This timeslot is valid and good
+              macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (tn + 3));
+              macs.next_usf_mon_block[tn - macs.first_monitored_ts] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
+            }
+            else
+            {
+              // This timeslot is bad or invalid
+              // If the slot was allocated for data
+              if (macs.tx_data & (MASK_SLOT0 >> (tn + RXTX_DELAY)))
+              {
+                // rlc_blocks_sent decremented
+                macs.rlc_blocks_sent --;
+
+              #if FF_L1_IT_DSP_USF
+                    // If next timeslot is also a data block:
+                    // Shift data block to next TX opportunity. For MS class 12
+                    // with dynamic allocation, 2 TX data max and they are
+                    // contiguous (optimization).
+                    if (macs.tx_data & (MASK_SLOT0 >> (tn + 1 + RXTX_DELAY)))
+                    {
+                      macs.ul_buffer_index[tn + 1 + RXTX_DELAY] = macs.ul_buffer_index[tn + RXTX_DELAY];
+
+                    }
+
+                    // Cancel burst
+                    macs.ul_buffer_index[tn + RXTX_DELAY] = INVALID;
+
+              #endif // FF_L1_IT_DSP_USF
+
+                #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+                  if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+                    trace_info.pdtch_trace.ul_status[tn + RXTX_DELAY] = 0;
+                #endif
+
+                #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+                  RTTL1_FILL_MACS_STATUS(TX_CANCELLED_USF, tn)
+                #endif
+              }
+            }
+          } // End if "USF vote enabled on this timeslot"
+        } // End for
+
+        /* Uplink resources de-allocated by the DSP are de-allocated by MAC-S */
+        macs.tx_allocation &= (UWORD8)  (macs.usf_good | ~macs.tx_data);
+        macs.tx_data       &= (UWORD8)  (macs.usf_good | ~macs.tx_data);
+        #else //#if !L1_EDA
+          UWORD8  i = 0;
+
+          //for all timeslots that need to be monitored
+          while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
+          {
+            // If USF vote was enabled on this timeslot
+            if(macs.usf_vote_enable & (MASK_SLOT0 >> macs.monitored_ts[i]))
+            {
+              // Clear the USF vote flag
+              macs.usf_vote_enable &= ~(MASK_SLOT0 >> macs.monitored_ts[i]);
+
+              // Read USF value
+              if ((((usf_updated >> ((MAX_TS_NB - macs.monitored_ts[i]) * 2)) & MASK_2SLOTS) == USF_GOOD)
+                  && (macs.last_rx_monitored & (MASK_SLOT0 >> macs.monitored_ts[i])))
+              {
+                if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
+                {
+                  //RX timeslots to monitor have to be updated upon USF status receipt (only first ts with
+                  //good USF has to be considered)
+                  if ((macs.monitored_ts[i] <= macs.lowest_poll_ts) ||
+                      ((MASK_SLOT0 >> macs.monitored_ts[i]) & macs.rx_allocation))
+                    macs.rx_monitored |= (UWORD8) (MASK_SLOT0 >> macs.monitored_ts[i]);
+
+                  // Clear the USF vote flag
+                  macs.usf_vote_enable = 0;
+
+                  //if the USF value is GOOD all remaining timelots that needed to be monitored
+                  //have to be considered as having GOOD USFs
+                  while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
+                  {
+                    // Update good USFs bitmap
+                    macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
+                    i++;
+                  }
+                  macs.next_usf_mon_block[0] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
+                  break;
+                }
+                else
+                {
+                  // This timeslot is valid and good
+                  macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
+                  macs.next_usf_mon_block[macs.monitored_ts[i] - macs.first_monitored_ts] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
+                }
+              }
+              else //USF is BAD or INVALID
+              {
+                //The TDMA before USF status was not known so USF was supposed to be GOOD but
+                // now it turns out to be BAD or INVALID so block is deallocated.
+                if (macs.tx_data & (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY)))
+                {
+                  UWORD8 j;
+
+                  // rlc_blocks_sent decremented
+                  macs.rlc_blocks_sent --;
+
+                  tn = macs.monitored_ts[i];
+
+                  #if FF_L1_IT_DSP_USF
+                    //For all monitored ts (beginning with last one), if the timeslot is a data block then
+                    //data block is shifted to next monitored ts.
+                    j=3;
+                    while (macs.monitored_ts[j] != tn)
+                    {
+                      if ((macs.monitored_ts[j] != INVALID) &&
+                          (macs.tx_data & (MASK_SLOT0 >> (macs.monitored_ts[j] + RXTX_DELAY))))
+                      {
+                        macs.ul_buffer_index[macs.monitored_ts[j] + RXTX_DELAY] = macs.ul_buffer_index[macs.monitored_ts[j-1] + RXTX_DELAY];
+                        #if L1_EGPRS
+                          macs.tx_modulation &= ~(MASK_SLOT0 >> (macs.monitored_ts[j] + RXTX_DELAY));
+                          macs.tx_modulation |= ((macs.tx_modulation &
+                                                (MASK_SLOT0 >> (macs.monitored_ts[j-1] + RXTX_DELAY)))
+                                               >> (macs.monitored_ts[j]-macs.monitored_ts[j-1]));
+                        #endif // L1_EGPRS
+                      }
+                      j--;
+                    }
+
+                    // Cancel burst
+                    macs.ul_buffer_index[tn + RXTX_DELAY] = INVALID;
+                    #if L1_EGPRS
+                      macs.tx_modulation &= ~(MASK_SLOT0 >> (tn + RXTX_DELAY));
+                    #endif // L1_EGPRS
+                  #endif // FF_L1_IT_DSP_USF
+                }//if (macs.tx_data & (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY)))
+                if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
+                {
+                  //USF for current timeslot is BAD so it has to be monitored for next USF
+                  //period
+                  if ((macs.monitored_ts[i] <= macs.lowest_poll_ts) ||
+                      ((MASK_SLOT0 >> macs.monitored_ts[i]) & macs.rx_allocation))
+                    macs.rx_monitored |= (UWORD8) (MASK_SLOT0 >> macs.monitored_ts[i]);
+                }
+              }
+            }//if(macs.usf_vote_enable & (MASK_SLOT0 >> macs.monitored_ts[i]))
+            i++;
+          }//while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
+
+          if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
+          {
+            // Downlink monitoring is updated depending on USF status
+            macs.rx_allocation |= macs.rx_monitored;
+          }
+
+          // Uplink resources de-allocated by the DSP are de-allocated by MAC-S
+          macs.tx_allocation &= (UWORD8)  (macs.usf_good | ~macs.tx_data);
+          macs.tx_data       &= (UWORD8)  (macs.usf_good | ~macs.tx_data);
+        #endif //#if !L1_EDA
+
+        // Measurement gap processing
+        l1ps_macs_meas();
+
+      } // End if FN13 = 4 OR 8
+    } // End if dynamic allocation mode
+  } // End if uplink TBF
+
+
+  #if FF_L1_IT_DSP_USF
+    if (l1ps_macs_com.usf_status != USF_IT_DSP)
+    {
+  #endif
+
+  /************************************************************/
+  /*****  RESSOURCE ALLOCATION FOR THE NEXT BLOCK PERIOD  *****/
+  /************************************************************/
+
+  // If the next frame is the first of a block period
+  //                                                           FN 13
+  //    0   1   2   3    4   5   6   7    8   9   10  11   12
+  // ----------------------------------------------------------
+  // ||       B0      ||       B1      ||       B2      || I ||
+  // || X |   |   |   || X |   |   |   || X |   |   |   ||   ||
+  // ----------------------------------------------------------
+
+  if (   (l1s.next_time.fn_mod13 == 4)
+      || (l1s.next_time.fn_mod13 == 8)
+      || (l1s.next_time.fn_mod13 == 0))
+  {
+    UWORD8   tx                  = 0;      // MS class Tx parameter checked
+    UWORD8   rx                  = 0;      // MS class Rx parameter checked
+    UWORD8   tx_no;                        // Number of allocated uplink timeslots
+    UWORD8   highest_ul_ts;                // Highest numbered allocated uplink resource
+    UWORD8   lowest_ul_ts;                 // Lowest numbered allocated uplink resource
+    UWORD8   highest_dl_ts;                // Highest numbered allocated uplink resource
+    UWORD8   lowest_dl_ts;                 // Lowest numbered allocated uplink resource
+    UWORD8   tra_before_frame;             // Number of free Tx slots at the end of the
+                                           // previous frame
+
+
+    /***********************************************************/
+    /* New allocated ressources                                */
+    /***********************************************************/
+
+    /*---------------------------------------------------------*/
+    /* New assignment or synchronization change                */
+    /*---------------------------------------------------------*/
+
+    if (   (l1ps_macs_com.new_set != FALSE)
+        || (l1a_l1s_com.dl_tn != macs.old_synchro_ts))
+    {
+      UWORD8  tn;
+      UWORD8  fn_mod13;
+      UWORD32 fn_div13;
+
+      /* Fixed allocation mode initialization */
+      /*--------------------------------------*/
+
+      if (SET_PTR->mac_mode == FIX_ALLOC_NO_HALF)
+      {
+        if (((SET_PTR->assignment_command == UL_TBF) || (SET_PTR->assignment_command == BOTH_TBF)) &&
+            (l1ps_macs_com.new_set))
+        {
+          // Starting time block ID processing
+          fn_div13 = (UWORD32) (SET_PTR->tbf_sti.absolute_fn / 13);             // FN / 13
+          fn_mod13 = (UWORD8) (SET_PTR->tbf_sti.absolute_fn - (fn_div13 * 13)); // FN mod 13
+          macs.sti_block_id = (UWORD32) (  (3 * (UWORD32) fn_div13)             // Block ID
+                                       + (fn_mod13 / 4));
+
+          // Starting time not aligned on a block period
+          if ((fn_mod13 != 0) && (fn_mod13 != 4) && (fn_mod13 != 8) && (fn_mod13 != 12))
+            macs.sti_block_id ++;
+
+          // Reset the fixed allocation bitmap exhaustion flag only in case of a new assignment
+          macs.fix_alloc_exhaust      = FALSE;
+        }
+
+      } // End of fixed mode initialization
+      else
+
+        #if L1_EDA
+          /*  Extended Dynamic/Dynamic allocation mode initialization  */
+          /*------------------------------------------*/
+
+          if ((SET_PTR->mac_mode == DYN_ALLOC) || (SET_PTR->mac_mode == EXT_DYN_ALLOC))
+        #else
+      /*  Dynamic allocation mode initialization  */
+      /*------------------------------------------*/
+
+      if (SET_PTR->mac_mode == DYN_ALLOC)
+        #endif
+      {
+        if ((SET_PTR->assignment_command == UL_TBF) || (SET_PTR->assignment_command == BOTH_TBF) ||
+            (l1a_l1s_com.dl_tn != macs.old_synchro_ts))
+        {
+          // USF value aren't kept
+          macs.usf_good           = 0;
+          macs.usf_vote_enable    = 0;         // No USF vote
+          macs.rx_blk_period      = NO_DL_BLK;
+
+          if (l1ps_macs_com.new_set)
+          // USF monitoring block set to current block to immediately enable
+          // the USF monitoring in case of new UL TBF
+            macs.next_usf_mon_block[0] = macs.next_usf_mon_block[1] = l1s.next_time.block_id;
+
+          // First and last allocated Tx number updating
+          macs.first_monitored_ts = INVALID;
+          macs.last_monitored_ts  = INVALID;
+
+          tn = 0;
+          // Search of the lowest timeslot allocated in uplink
+          while (   !(SET_PTR->ul_tbf_alloc->timeslot_alloc & (MASK_SLOT0 >> tn))
+                 && (tn < TS_NUMBER))
+            tn ++;
+
+          if (tn != TS_NUMBER)
+          {
+            macs.first_monitored_ts = tn - l1a_l1s_com.dl_tn;
+            tn = MAX_TS_NB;
+
+            // Search of the highest timeslot allocated in uplink
+            while (!(SET_PTR->ul_tbf_alloc->timeslot_alloc & (MASK_SLOT0 >> tn)))
+              tn --;
+            macs.last_monitored_ts = tn - l1a_l1s_com.dl_tn;
+                #if L1_EDA
+                  //Extended Dynamic or Dynamic Allocation has been set
+                  {
+                    UWORD8  i=0;
+                    macs.rx_monitored   = 0;
+                    //Search among the timeslots allocated in uplink, the timeslots that are really
+                    //allocated (macs.first_monitored_ts and macs.last_monitored_ts are for sure
+                    //allocated but the allocation can have holes inbetween)
+                    for (i = 0; i < 4; i++)
+                    {
+                      macs.monitored_ts[i] = INVALID;
+                    }
+                    i = 0;
+                    for (tn = macs.first_monitored_ts; tn <= macs.last_monitored_ts; tn++)
+                    {
+                      //Find the ts that are allocated and need therefore to be monitored
+                      if (((SET_PTR->ul_tbf_alloc->timeslot_alloc & (MASK_SLOT0 >> (tn + l1a_l1s_com.dl_tn))) && (SET_PTR->mac_mode == EXT_DYN_ALLOC))
+                         || (SET_PTR->mac_mode == DYN_ALLOC))
+                      {
+                        macs.monitored_ts[i]= tn;
+                        i++;
+                      }
+                    }
+                  }
+                #endif //#if L1_EDA
+              }
+            }
+            #if L1_EDA
+              if((SET_PTR->mac_mode == EXT_DYN_ALLOC))
+                l1ps_macs_com.fb_sb_task_detect = TRUE;
+              else
+                l1ps_macs_com.fb_sb_task_detect = FALSE;
+            #endif
+      } // End of dynamic mode initialization
+
+      /* Reset of new_set */
+      /*------------------*/
+
+      l1ps_macs_com.new_set = FALSE;
+
+    } // End of new allocation
+
+    /*---------------------------------------------------------*/
+    /* Resource initialization                                 */
+    /*---------------------------------------------------------*/
+
+    macs.pwr_allocation      = 0;  // Power measurements
+    macs.rx_allocation       = 0;  // Rx allocation
+    macs.tx_allocation       = 0;  // Tx allocation
+    macs.tx_data             = 0;  // Tx data allocation
+    macs.tx_prach_allocation = 0;  // Tx PRACH allocation
+    #if FF_L1_IT_DSP_USF
+     macs.dsp_usf_interrupt = 0;  // DSP interrupt for USF decoding needed
+    #endif
+
+    /***********************************************************/
+    /* Downlink TBF processing                                 */
+    /***********************************************************/
+
+    if ((SET_PTR->allocated_tbf == DL_TBF) || (SET_PTR->allocated_tbf == BOTH_TBF))
+    {
+      /* Downlink resources are allocated */
+      macs.rx_allocation = (UWORD8) (   SET_PTR->dl_tbf_alloc.timeslot_alloc
+                                     << l1a_l1s_com.dl_tn);
+    } /* End if downlink TBF processing  */
+
+    /***********************************************************/
+    /* Uplink TBF processing                                   */
+    /***********************************************************/
+
+    if ((SET_PTR->allocated_tbf == UL_TBF) || (SET_PTR->allocated_tbf == BOTH_TBF))
+    {
+
+      /*---------------------------------------------------------*/
+      /* Dynamic allocation mode                                 */
+      /*---------------------------------------------------------*/
+
+        #if L1_EDA
+          if ((SET_PTR->mac_mode == DYN_ALLOC) || (SET_PTR->mac_mode == EXT_DYN_ALLOC))
+        #else
+          if (SET_PTR->mac_mode == DYN_ALLOC)
+        #endif
+      {
+        UWORD8 i;
+        UWORD8 tn;
+        API    usf_updated;
+
+            #if !L1_EDA
+        /* Downlink resource monitoring */
+        /*------------------------------*/
+
+        macs.rx_allocation |= (UWORD8)  (   SET_PTR->ul_tbf_alloc->timeslot_alloc
+                                        << l1a_l1s_com.dl_tn);
+
+        /* USF values reading */
+        /*--------------------*/
+
+        // An uplink timeslot is allocated by MAC-S if it's allocated by the network and
+        //    - USF is updated and good
+        // OR - USF isn't updated
+
+        // Reading of the d_usf_updated_gprs value
+        usf_updated = NDB_PTR->d_usf_updated_gprs;
+
+        // For each timeslot that can be allocated in uplink...
+        for (tn = macs.first_monitored_ts; tn <= macs.last_monitored_ts; tn ++)
+        {
+          UWORD8 tn_usf;
+          WORD32 delta;
+
+          // Remaining blocks before a new USF reading
+          delta = (WORD8) (macs.next_usf_mon_block[tn - macs.first_monitored_ts] - l1s.next_time.block_id);
+
+          // MAX_FN modulo
+          if (delta <= 0) delta += MAX_BLOCK_ID;
+
+          if (delta >= USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity])
+          {
+            // USF no more usable
+            // Clear USF in good USFs bitmap
+            macs.usf_good &= (UWORD8) ~(MASK_SLOT0 >> (tn + 3));
+
+            // Clear USF vote
+            macs.usf_vote_enable &= (UWORD8) ~(MASK_SLOT0 >> tn);
+
+            // If downlink blocks were entirely received during the last block period
+            if (macs.rx_blk_period == l1s.next_time.block_id)
+            {
+              // Read USF
+              tn_usf = (UWORD8) ((usf_updated >> ((MAX_TS_NB - tn) << 1)) & MASK_2SLOTS);
+
+              if (tn_usf == USF_GOOD)
+              {
+                // Update good USFs bitmap
+                macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (tn + 3));
+                macs.next_usf_mon_block[tn - macs.first_monitored_ts] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
+              }
+              else
+              if ((tn_usf == USF_INVALID) && (l1s.next_time.fn_mod13 != 0))
+              {
+                // Unknown USF:
+                //    - TPU is programmed to tranmit a block on timeslot tn
+                //    - DSP will set the TX PWR to 0 for this timeslot is USF is bad
+                //      (USF vote mechanism)
+
+                macs.tx_allocation   |= (MASK_SLOT0 >> (tn + 3));
+                macs.usf_vote_enable |= (MASK_SLOT0 >> tn);
+              }
+            } // End if "downlink block entirely received"
+          } // End if "USF no more usable"
+        } // End for
+
+            #else  //#if !L1_EDA
+              {
+                UWORD8 tn_usf;
+                WORD32 delta;
+                UWORD8 i=0;
+
+                if (SET_PTR->mac_mode == DYN_ALLOC)
+                {
+                  /* Downlink resource monitoring */
+                  /*------------------------------*/
+
+                  macs.rx_allocation |= (UWORD8)  (   SET_PTR->ul_tbf_alloc->timeslot_alloc
+                                                << l1a_l1s_com.dl_tn);
+
+                  macs.last_rx_monitored = macs.rx_allocation;
+                }
+                else
+                {
+                  // Remaining blocks before a new USF reading
+                  delta = (WORD8) (macs.next_usf_mon_block[0] - l1s.next_time.block_id);
+
+                  // MAX_FN modulo
+                  if (delta <= 0) delta += MAX_BLOCK_ID;
+
+                  //Save last rx_monitored timeslots
+                  macs.last_rx_monitored = macs.rx_monitored;
+
+                  //for all timeslots to monitor (timeslots allocated in UL)
+                  for (tn = macs.first_monitored_ts; tn <= macs.last_monitored_ts; tn++)
+                  {
+                    //All possible timeslots to monitor have to be monitored
+                    // (USF validity period exhausted)
+                    if (macs.monitored_ts[i] != INVALID)
+                      macs.rx_monitored |= (MASK_SLOT0 >> macs.monitored_ts[i]);
+                    i++;
+                  }
+
+                  //USF validity period is exhausted
+                  if (delta >= USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity])
+                  {
+                    //USF need to be evaluated for next block period
+                    macs.usf_good = 0;
+                  }
+                  else
+                  {
+                    //Set monitored ts again if poll occured on one ts during a block granularity period = 4
+                    //note: macs.usf_good is always different from 0
+                    i=0;
+                    while (!(macs.usf_good & (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY))))
+                      i++;
+                    macs.rx_monitored &= (UWORD8) ~(MASK_ALL_SLOTS >> macs.monitored_ts[i+1]);
+                  }
+                }
+
+                // Reading of the d_usf_updated_gprs value
+                usf_updated = NDB_PTR->d_usf_updated_gprs;
+
+                i=0;
+                //for all possible timeslots to monitor
+                while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
+                {
+                  if (SET_PTR->mac_mode == DYN_ALLOC)
+                  {
+                    // Remaining blocks before a new USF reading
+                    delta = (WORD8) (macs.next_usf_mon_block[macs.monitored_ts[i] - macs.first_monitored_ts] - l1s.next_time.block_id);
+
+                    // MAX_FN modulo
+                    if (delta <= 0) delta += MAX_BLOCK_ID;
+                  }
+
+                  //USF validity period is exhausted
+                  if (delta >= USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity])
+                  {
+                    if (SET_PTR->mac_mode == DYN_ALLOC)
+                    {
+                      // USF no more usable
+                      // Clear USF in good USFs bitmap
+                      macs.usf_good &= (UWORD8) ~(MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
+
+                      // Clear USF vote
+                      macs.usf_vote_enable &= (UWORD8) ~(MASK_SLOT0 >> macs.monitored_ts[i]);
+                    }
+
+                    if ((macs.rx_blk_period == l1s.next_time.block_id) && (macs.last_rx_monitored & (MASK_SLOT0 >> macs.monitored_ts[i])))
+                    {
+
+                      #if L1_EGPRS
+                        // EGPRS switched radio loopback sub mode on: dynamic allocation
+                        // but USF are always deemed to be good
+                        if (l1ps_macs_com.loop_param.sub_mode == TRUE)
+                          tn_usf = USF_GOOD;
+                        else
+                      #endif
+                          // Read USF
+                         tn_usf = (UWORD8) ((usf_updated >> ((MAX_TS_NB - macs.monitored_ts[i]) << 1)) & MASK_2SLOTS);
+
+                      if (tn_usf == USF_GOOD)
+                      {
+                        if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
+                        {
+                          //Deallocate monitored ts
+                          macs.rx_monitored &= (UWORD8) ~(MASK_ALL_SLOTS >> macs.monitored_ts[i+1]);
+
+                          //As USF is good for current monitored ts, all subsequent monitored ts have
+                          //to be deallocated and the associated USF set to USF_GOOD
+                          while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
+                          {
+                            //Update good USFs bitmap
+                            macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
+                            i++;
+                          }
+                          macs.next_usf_mon_block[0] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
+                          break;
+                        }
+                        else
+                        {
+                          // Update good USFs bitmap
+                          macs.usf_good |= (UWORD8) (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
+                          macs.next_usf_mon_block[macs.monitored_ts[i] - macs.first_monitored_ts] = l1s.next_time.block_id + USF_BLOCK_GRANULARITY[SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_granularity];
+                        }
+                      }
+                      else
+                      if ((tn_usf == USF_INVALID) && (l1s.next_time.fn_mod13 != 0))
+                      {
+                        if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
+                        {
+                          //Deallocate monitored ts
+                          macs.rx_monitored &= (UWORD8) ~(MASK_ALL_SLOTS >> macs.monitored_ts[i+1]);
+
+                          //As USF is invalid (status of USF not yet known) for current monitored ts, the USF is
+                          //supposed to be good and therefore Tx is allocated and all subsequent monitored ts
+                          //have to be deallocated. Vote mechanism is also enabled for these latter timeslots.
+                          while ((macs.monitored_ts[i] != INVALID) && (i <= 3))
+                          {
+                            macs.tx_allocation |= (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
+                            macs.usf_vote_enable |= (MASK_SLOT0 >> macs.monitored_ts[i]);
+                            i++;
+                          }
+                          break;
+                        }
+                        else
+                        {
+                          // Unknown USF:
+                          //    - TPU is programmed to tranmit a block on timeslot tn
+                          //    - DSP will set the TX PWR to 0 for this timeslot is USF is bad
+                          //      (USF vote mechanism)
+
+                          macs.tx_allocation   |= (MASK_SLOT0 >> (macs.monitored_ts[i] + RXTX_DELAY));
+                          macs.usf_vote_enable |= (MASK_SLOT0 >> macs.monitored_ts[i]);
+                        }
+                      }
+                    }//if ((macs.rx_blk_period == l1s.next_time.block_id) && (macs.last_rx_monitored & (MASK_SLOT0 >> macs.monitored_ts[i])))
+                  }
+                  i++;
+                }//while ((tn != INVALID) && (i <= 3))
+              }//if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
+
+              /* Downlink resource monitoring */
+              /*------------------------------*/
+              macs.rx_allocation |= macs.rx_monitored;
+            #endif //#if !L1_EDA
+        /* Uplink resources allocation according to USF values */
+        /*-----------------------------------------------------*/
+
+        i = l1a_l1s_com.dl_tn - RXTX_DELAY;
+        if (i < TS_NUMBER)
+        {
+          macs.tx_allocation |= (UWORD8) (  macs.usf_good
+                                          & (SET_PTR->ul_tbf_alloc->timeslot_alloc << i));
+        }
+        else
+        {
+          macs.tx_allocation |= (UWORD8) (  macs.usf_good
+                                          & (SET_PTR->ul_tbf_alloc->timeslot_alloc >> (-i)));
+        }
+
+            #if L1_EDA
+              //if FB/SB activity detected in comming idle frame, some TX burst have to be deallocated
+              //to allow opening of FB/SB window (no TX activity should be scheduled in slots 6 and 7)
+              if (l1ps_macs_com.fb_sb_task_enabled && l1ps_macs_com.fb_sb_task_detect)
+              {
+                macs.tx_allocation &= ~(MASK_SLOT0 >> 6);
+              }
+            #endif
+
+       #if FF_L1_IT_DSP_USF
+              // UL or BOTH TBF with dynamic allocation in use. DSP has to generate
+              // an interrupt for USF validity for the block to be received if it
+              // is either RBN (radio block number) % 3 = 0 or 1.
+
+              if (   (l1s.next_time.fn_mod13 == 0)
+                  || (l1s.next_time.fn_mod13 == 4))
+
+                macs.dsp_usf_interrupt = 1;
+       #endif
+
+      } /* end if dynamic allocation mode */
+
+      /*---------------------------------------------------------*/
+      /* Fixed allocation mode                                   */
+      /*---------------------------------------------------------*/
+
+      if (SET_PTR->mac_mode == FIX_ALLOC_NO_HALF)
+      {
+        UWORD8   i;
+        UWORD32  blk_id = l1s.next_time.block_id;
+
+        /* Allocation bitmap isn't exhausted */
+        /*-----------------------------------*/
+
+        if(macs.fix_alloc_exhaust == FALSE)
+        {
+
+          // Allocation exhaustion detection
+          //---------------------------------
+
+          //
+          // 0  current_fn  End of allocation                      STI  FN_MAX
+          // |-----|---------|--------------------------------------|----||
+          // |.....|.........|                                      |....||
+          // |-----|---------|--------------------------------------|----||
+          //
+          // In this case, the Starting time is elapsed but current_fn < STI
+          // ---> We must have (current block_ID - STI_block_ID) > 0
+          //
+          if (blk_id < macs.sti_block_id)
+          {
+            blk_id += MAX_BLOCK_ID;  // MAX_BLOCK_ID is the block ID obtained when fn = FN_MAX
+
+          } // End of FN MAX modulo management
+
+          #if TESTMODE
+            // Never let exhaust the UL allocation in test mode packet transfer operation
+            if (l1_config.TestMode)
+              blk_id = macs.sti_block_id;
+          #endif
+
+          /* Allocation bitmap isn't exhausted */
+          if (blk_id < (macs.sti_block_id + SET_PTR->ul_tbf_alloc->fixed_alloc.bitmap_length))
+          {
+
+            // Uplink allocation
+            //------------------
+
+            // Resources are allocated according to the allocation bitmap or ts_override
+            macs.tx_allocation = (UWORD8)
+                       (  SET_PTR->ul_tbf_alloc->timeslot_alloc
+                        & (  SET_PTR->ul_tbf_alloc->fixed_alloc.bitmap[blk_id - macs.sti_block_id]
+                           | SET_PTR->ts_override));
+            // Delay
+            i = l1a_l1s_com.dl_tn - RXTX_DELAY;
+            if (i > MAX_TS_NB)
+              macs.tx_allocation >>= (-i);
+            else
+              macs.tx_allocation <<= i;
+
+            // Monitoring
+            //-----------
+
+            if ((l1s.next_time.fn_mod13 == 0) || (macs.rx_blk_period != l1s.next_time.block_id))
+            {
+              // Last frame was an idle frame or was used for another task --> considered as a free frame
+              tra_before_frame = 8;
+            }
+            else
+            {
+              tra_before_frame = macs.tra_gap;  // Tra gap of last TDMA frame is saved
+            }
+
+            // DOWNLINK CONTROL TIMESLOT ALLOCATION
+
+            if (  SET_PTR->ul_tbf_alloc->timeslot_alloc
+                & (MASK_SLOT0 >> SET_PTR->ul_tbf_alloc->fixed_alloc.ctrl_timeslot))
+            {
+              // Tra and Ttb met --> allocates the downlink control timeslot
+              macs.rx_allocation |= (UWORD8)
+                               (MASK_SLOT0 >> (  SET_PTR->ul_tbf_alloc->fixed_alloc.ctrl_timeslot
+                                               - l1a_l1s_com.dl_tn));
+            }
+
+            // UPLINK PDCH MONITORING
+            else
+            {
+              // The control timeslot has been released
+
+              // Allocates uplink TBF timeslots for monitoring
+              macs.rx_allocation |= (UWORD8) (   SET_PTR->ul_tbf_alloc->timeslot_alloc
+                                              << l1a_l1s_com.dl_tn);
+            }
+
+            // If Ttb or Tra not respected, the problem comes from uplink TBF
+            // monitored timeslots
+            // If Ttb not respected, downlink resources are removed
+            for(i = 0; i <= MS_CLASS[SET_PTR->multislot_class].ttb; i++)
+              macs.rx_allocation &=  (~((UWORD8)(macs.tx_allocation << i)));
+
+            // Tra respect according to the current allocation
+            for(i = 0; i <= MS_CLASS[SET_PTR->multislot_class].tra; i++)
+              macs.rx_allocation &= (~((UWORD8)(macs.tx_allocation << (8-i))));
+
+            // Tra respect according to the last allocation
+            if (tra_before_frame < MS_CLASS[SET_PTR->multislot_class].tra)
+            {
+              macs.rx_allocation &= MASK_ALL_SLOTS >> (MS_CLASS[SET_PTR->multislot_class].tra - tra_before_frame);
+            }
+
+            #if MACS_STATUS
+              if (macs.rx_allocation == 0)
+              {
+                l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = NO_RX_MONITORED;
+                l1ps_macs_com.macs_status.nb ++;
+              }
+            #endif
+
+            // Last block of the allocation bitmap... next block will use new settings
+            // for timeslot monitoring
+            if ((blk_id + 1) == (macs.sti_block_id + SET_PTR->ul_tbf_alloc->fixed_alloc.bitmap_length))
+            {
+              macs.fix_alloc_exhaust               = TRUE;
+              // Informs L1S
+              l1ps_macs_com.fix_alloc_exhaust_flag = TRUE;
+            }
+
+
+          } // End if "allocation bitmap isn't exhausted"
+          else
+
+          // Allocation bitmap has exhausted
+          {
+            macs.fix_alloc_exhaust               = TRUE;
+            // Informs L1S
+            l1ps_macs_com.fix_alloc_exhaust_flag = TRUE;
+
+            // Allocates uplink TBF timeslots for monitoring
+            macs.rx_allocation |= (UWORD8) (   SET_PTR->ul_tbf_alloc->timeslot_alloc
+                                            << l1a_l1s_com.dl_tn);
+
+          }
+
+        } // End if "allocation bitmap not exhausted"
+
+        /* Allocation bitmap is exhausted */
+        /*--------------------------------*/
+        else
+        {
+          // Allocates uplink TBF timeslots for monitoring
+          macs.rx_allocation |= (UWORD8) (   SET_PTR->ul_tbf_alloc->timeslot_alloc
+                                          << l1a_l1s_com.dl_tn);
+
+        } // End if fixed allocation exhausted
+
+      } // End of fixed allocation processing
+
+    } // End of uplink TBF processing
+
+    /***********************************************************/
+    /* Allocation parameters checking and updating             */
+    /***********************************************************/
+    {
+      UWORD8 ts;
+      BOOL   rx_ts;
+      BOOL   tx_ts;
+
+ #if MACS_STATUS
+      UWORD8 time   = INVALID;  /* Timeslot counter */
+ #endif
+
+      tx_no         = 0;
+      highest_ul_ts = INVALID;
+      lowest_ul_ts  = INVALID;
+      highest_dl_ts = INVALID;
+      lowest_dl_ts  = INVALID;
+
+      /*---------------------------------------------------------*/
+      /* Trb, Ttb parameters verification and Rx, Tx number, Sum */
+      /* and highest_ul_ts parameters processing                 */
+      /*---------------------------------------------------------*/
+
+      /* We verifies all allocated uplink and downlink timeslots */
+      for (ts = 0; ts < TS_NUMBER; ts ++)
+      {
+        rx_ts = (UWORD8) (macs.rx_allocation & (MASK_SLOT0 >> ts));
+        tx_ts = (UWORD8) (macs.tx_allocation & (MASK_SLOT0 >> ts));
+
+      #if MACS_STATUS
+
+        /* If Rx(ts) = 0 and Tx(ts) = 0 */
+        /*------------------------------*/
+
+        if ((!rx_ts) && (!tx_ts))
+        {
+          /* time is incremented */
+          /* If time was invalid, it becomes active */
+          if (time < TS_NUMBER)
+            time ++;
+          if ((time == RX_SLOT)||(time == TX_SLOT))
+            time = 1;
+        } /* End if Rx = 0 and Tx = 0 */
+
+        /* If Rx(ts) = 1 and Tx(ts) = 1 */
+        /*------------------------------*/
+
+        if ((rx_ts) && (tx_ts))
+        {
+          /* error (only type 1 mobiles are supported) */
+          l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_TIME_ERROR;
+          l1ps_macs_com.macs_status.nb ++;
+        } /* End if Rx = 1 and Tx = 1 */
+      #endif
+
+        /* If Rx(ts) = 1 */
+        /*---------------*/
+
+        if (rx_ts)
+        {
+          highest_dl_ts = ts;
+        #if MACS_STATUS
+          /* If time is valid (invalid=0xFF) and time<Trb --> error */
+          if ((time < MS_CLASS[SET_PTR->multislot_class].trb) || (time == TX_SLOT))
+          {
+            l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_TIME_ERROR;
+            l1ps_macs_com.macs_status.nb ++;
+          }
+          time = RX_SLOT;
+        #endif
+          /* First Rx updating */
+          if (lowest_dl_ts == INVALID)
+            lowest_dl_ts = ts;
+
+        } /* End if Rx = 1 */
+
+        /* If Tx(ts) = 1 */
+        /*---------------*/
+
+        if (tx_ts)
+        {
+          /* Number of Tx is incremented and highest_ul_ts is updated */
+          tx_no ++;
+          highest_ul_ts = ts;
+        #if MACS_STATUS
+          /* If time is valid (invalid=0xFF) and time<Ttb --> error */
+          if (   (time < MS_CLASS[SET_PTR->multislot_class].ttb)
+              || (time == RX_SLOT))
+          {
+            l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_TIME_ERROR;
+            l1ps_macs_com.macs_status.nb ++;
+          }
+          time = TX_SLOT;
+        #endif
+          /* First Tx updating */
+          if (lowest_ul_ts == INVALID)
+            lowest_ul_ts = ts;
+
+          #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+            if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+              trace_info.pdtch_trace.ul_status[ts] |= 0x4;
+          #endif
+        } /* End if Tx = 1 */
+
+      } /* End for */
+
+      /* Rx and Tx MS class parameters are updated */
+      if (lowest_dl_ts != INVALID)
+        rx = (UWORD8) (highest_dl_ts - lowest_dl_ts + 1);
+
+      if (lowest_ul_ts != INVALID)
+        tx = (UWORD8) (highest_ul_ts - lowest_ul_ts + 1);
+
+    #if MACS_STATUS
+      // If the Trb parameter isn't respected at the end of
+      // the TDMA frame --> MS Class isn't suported
+      // Note: we considered that the first slot of the next TDMA is always a RX
+      if (time < MS_CLASS[SET_PTR->multislot_class].trb)
+      {
+        l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_TIME_ERROR;
+        l1ps_macs_com.macs_status.nb ++;
+      }
+
+      /*---------------------------------------------------------*/
+      /* Sum, Rx and Tx parameters verification                  */
+      /*---------------------------------------------------------*/
+
+      if (  ((rx + tx) > MS_CLASS[SET_PTR->multislot_class].sum)
+          ||(rx > MS_CLASS[SET_PTR->multislot_class].rx)
+          ||(tx > MS_CLASS[SET_PTR->multislot_class].tx))
+      {
+        l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_SUM_ERROR;
+        l1ps_macs_com.macs_status.nb ++;
+      }
+
+      // If all downlink timeslots are before the first uplink timeslot or after
+      // the last uplink timeslot, Rx and Tx parameters are met
+      if (   (   (highest_dl_ts > lowest_ul_ts)
+              || (lowest_dl_ts > lowest_ul_ts))
+          && (   (highest_dl_ts < highest_ul_ts)
+              || (lowest_dl_ts < highest_ul_ts)))
+      {
+        l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = MS_CLASS_SUM_ERROR;
+        l1ps_macs_com.macs_status.nb ++;
+      }
+
+    #endif
+
+    } /* End of allocation parameters checking and updating */
+
+
+    /***********************************************************/
+    /* Uplink RLC/MAC blocks management (RLC - DSP interfaces) */
+    /* PACCH/U placement (Poll response processing)            */
+    /***********************************************************/
+
+    {
+      BOOL   poll;              // TRUE if the poll response is processed
+      UWORD8 highest_ul_data;   // Highest uplink timeslot assigned for data transfer
+      UWORD8 tx_allocation_s;   // Used for saving of macs.tx_allocation
+      UWORD8 rx_allocation_s;   // Used for saving of macs.rx_allocation
+      UWORD8 tx_data_s;         // Used for saving of macs.tx_data
+      UWORD8 highest_ul_ts_s;   // Used for saving of highest_ul_ts
+      UWORD8 lowest_ul_ts_s;    // Used for saving of lowest_ul_ts
+      UWORD8 poll_resp_ts;      // Timeslot on which the MS must transmit a poll response
+      UWORD8 ts;
+      UWORD8 i;
+          #if L1_EDA
+            UWORD8 rx_monitored_s; // Used for saving of rx_monitored
+          #endif
+
+      /*---------------------------------------------------------*/
+      /* Uplink buffer indexes initialization                    */
+      /*---------------------------------------------------------*/
+
+      macs.ul_buffer_index[0] = macs.ul_buffer_index[1] = macs.ul_buffer_index[2] =
+        macs.ul_buffer_index[3] = macs.ul_buffer_index[4] = macs.ul_buffer_index[5] =
+        macs.ul_buffer_index[6] = macs.ul_buffer_index[7] = INVALID;
+
+      // Reset all uplink blocks CS-TYPE in order to disable the validity of blocks not sent
+      for(i=0; i<4; i++)
+      {
+        NDB_PTR->a_du_gprs[i][0] = CS_NONE_TYPE;
+        NDB_PTR->a_pu_gprs[i][0] = CS_NONE_TYPE;
+      }
+
+      /*---------------------------------------------------------*/
+      /* Uplink RLC/MAC blocks request to RLC (RLC_UPLINK)       */
+      /*---------------------------------------------------------*/
+
+      /* All allocated uplink resources are used for data */
+      macs.tx_data = macs.tx_allocation;
+      highest_ul_data = highest_ul_ts;
+
+      /* RLC UPLINK CALL */
+      /*-----------------*/
+
+      #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+        if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_UL_NO_TA)
+          if ((SET_PTR->packet_ta.ta == 255) && (macs.tx_allocation != 0))
+            Trace_uplink_no_TA();
+      #endif
+
+      #if TESTMODE
+        if (l1_config.TestMode)
+        {
+          l1tm_rlc_uplink (tx_no, (API*) NDB_PTR->a_du_gprs);
+        }
+        else
+      #endif
+      {
+        rlc_uplink(SET_PTR->assignment_id,         // Assignment ID
+                   tx_no,                          // Number of timeslot that can be used
+                                                   //   for uplink data block transfer
+                   l1s.next_time.fn,               // Next frame number
+                   SET_PTR->packet_ta.ta,          // Timing advance value
+                   (API*) NDB_PTR->a_pu_gprs,      // Pointer on poll response struct
+                   (API*) NDB_PTR->a_du_gprs,      // Pointer on uplink block struct
+                   macs.fix_alloc_exhaust          // Set to 1 if fixed allocation exhausted
+        );
+      }
+
+          #if FF_TBF
+            #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+              if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_RLC_PARAM)
+              {
+                UWORD32 cs_type = 0;
+                //Get the cs_type from the UL buffer API header
+                //The cs_type format: byte0 (LSByte) -indicates the CS type of TS0
+                //byte1- CS type of TS1
+                //byt2 - CS type of TS2
+                //byte3(MSBye) - CS type of TS3
+                for (i=0;i<tx_no;i++)
+                {
+                                        cs_type |= ((((UWORD8) NDB_PTR->a_du_gprs[i][0]) & CS_GPRS_MASK) << (8*i));
+
+                }
+                Trace_rlc_ul_param(SET_PTR->assignment_id,         // Assignment ID
+                                   l1s.next_time.fn,               // Next frame number
+                                   tx_no,                          // Number of UL timeslot that can be used
+                                   SET_PTR->packet_ta.ta,          // Timing advance value
+                                   macs.fix_alloc_exhaust,
+                                   cs_type );
+              }
+            #endif
+          #else
+      #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+        if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_RLC_PARAM)
+        {
+          Trace_rlc_ul_param(SET_PTR->assignment_id,         // Assignment ID
+                             tx_no,                          // Number of timeslot that can be used
+                                                             //   for uplink data block transfer
+                             l1s.next_time.fn,               // Next frame number
+                             SET_PTR->packet_ta.ta,          // Timing advance value
+                             (UWORD32) NDB_PTR->a_pu_gprs,      // Pointer on poll response struct
+                             (UWORD32) NDB_PTR->a_du_gprs,      // Pointer on uplink block struct
+                             macs.fix_alloc_exhaust);
+        }
+      #endif
+          #endif
+
+      i = 0;
+
+      /*---------------------------------------------------------*/
+      /* Poll responses processing                               */
+      /*---------------------------------------------------------*/
+          #if L1_EDA
+            macs.lowest_poll_ts = INVALID;
+          #endif
+
+      /* While a poll response is requested */
+      while (  (   ((((UWORD8) NDB_PTR->a_pu_gprs[i][0]) & 0xF) == CS1_TYPE_POLL)
+                || ((((UWORD8) NDB_PTR->a_pu_gprs[i][0]) & 0xF) == CS_PAB8_TYPE)
+                || ((((UWORD8) NDB_PTR->a_pu_gprs[i][0]) & 0xF) == CS_PAB11_TYPE))
+             && (i < 4))
+      {
+        poll = TRUE;
+
+        // The number of the timeslot on which the poll response is requested is converted to
+        // become relative to L1 synchronization
+        poll_resp_ts =   (UWORD8) NDB_PTR->a_pu_gprs[i][1]
+                      -  l1a_l1s_com.dl_tn
+                      +  RXTX_DELAY;
+
+        // All timeslots on which a poll is requested are set in last_poll_response.
+        // last_poll_response will be updated in FN13 = 2, 6 and 10, when the 4th control
+        // task will be processed for the current block period --> we'll be sure the poll
+        // responses are entirely transmitted (no BCCH monitoring)
+        macs.last_poll_response |= (UWORD8) (MASK_SLOT0 >> poll_resp_ts);
+
+        // Allocations are saved: it's useful to restore uplink slots that were removed
+        // for mapping a poll response that is finally not processed
+        tx_allocation_s = macs.tx_allocation;
+        rx_allocation_s = macs.rx_allocation;
+        tx_data_s       = macs.tx_data;
+        lowest_ul_ts_s  = lowest_ul_ts;
+        highest_ul_ts_s = highest_ul_ts;
+            #if L1_EDA
+              rx_monitored_s  = macs.rx_monitored;
+            #endif
+          #if L1_EDA
+            //In the case of concurrent TBFs in extended dynamic mode, poll response can be canceled
+            //if response is not done on concurrent timeslots
+            if (((SET_PTR->allocated_tbf == BOTH_TBF) && (SET_PTR->mac_mode == EXT_DYN_ALLOC)) &&
+                (!((SET_PTR->dl_tbf_alloc.timeslot_alloc) & (SET_PTR->ul_tbf_alloc->timeslot_alloc)
+                & (MASK_SLOT0 >> NDB_PTR->a_pu_gprs[i][1]))))
+            {
+              // Poll response not done
+              poll = FALSE;
+            }
+            else
+          #endif
+        /* If the requested timeslot is allocated for data transfer */
+        /*----------------------------------------------------------*/
+
+        if (macs.tx_data & (MASK_SLOT0 >> poll_resp_ts))
+        {
+          /* The slot is removed in tx_data */
+          /* No allocation modification */
+          macs.tx_data &= (UWORD8) (~(MASK_SLOT0 >> poll_resp_ts));
+
+          #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+            RTTL1_FILL_MACS_STATUS(TX_CANCELLED_POLL, poll_resp_ts)
+          #endif
+
+        } /* End if slot allocated for data */
+
+        /* If the poll response is requested on an invalid timeslot    */
+        /* i.e:                                                        */
+        /*    - Timeslot > 7 or < 0                                    */
+        /*    - Timeslot that avoid the RX on the first timeslot       */
+        /*      according to Ttb                                       */
+        /*-------------------------------------------------------------*/
+
+        else
+        if ((poll_resp_ts > 7) || (poll_resp_ts <= MS_CLASS[SET_PTR->multislot_class].ttb))
+        {
+          // Poll response not done
+          poll = FALSE;
+        }
+
+        /* If the Tra parameter isn't respected */
+        /*--------------------------------------*/
+
+          #if L1_EDA
+            //Tra does not always apply with EDA.
+            else
+            if ((  (MASK_SLOT0 >> poll_resp_ts)
+                & (   macs.rx_allocation
+                   >> (TS_NUMBER - MS_CLASS[SET_PTR->multislot_class].tra)) && (SET_PTR->mac_mode != EXT_DYN_ALLOC))
+                || ((poll_resp_ts == 6) && (l1ps_macs_com.fb_sb_task_enabled)))
+          #else
+        else
+        if (  (MASK_SLOT0 >> poll_resp_ts)
+            & (   macs.rx_allocation
+               >> (TS_NUMBER - MS_CLASS[SET_PTR->multislot_class].tra)))
+
+          #endif
+        {
+          // Poll response not done
+          poll = FALSE;
+        }
+
+        /* Ttb and Tra respected                                         */
+        /* Poll on a slot not already allocated for uplink data transfer */
+        /*---------------------------------------------------------------*/
+
+        else
+        {
+          /* If Ttb parameter isn't respected  */
+          /*-----------------------------------*/
+
+          // If one or several downlink timeslots are allocated between:
+          //    - Ttb timeslots before the timeslot to use for poll response
+          //    - AND the last slot of the frame (optimization)
+          //          --> Ttb parameter isn't respected if the poll response is transmitted
+          //              so the RX resources are removed
+
+          macs.rx_allocation &= ~((UWORD8) (  macs.rx_allocation
+                                            & (   MASK_ALL_SLOTS
+                                               >> (  poll_resp_ts
+                                                   - MS_CLASS[SET_PTR->multislot_class].ttb))));
+
+              #if L1_EDA
+                if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
+                {
+                  UWORD8 only_monitored_ts;
+
+                  only_monitored_ts = ~((UWORD8)(SET_PTR->dl_tbf_alloc.timeslot_alloc << l1a_l1s_com.dl_tn)) & macs.rx_monitored;
+                  macs.rx_allocation &= ~(only_monitored_ts & (MASK_ALL_SLOTS >> (poll_resp_ts + 1 - RXTX_DELAY)));
+                  macs.rx_monitored &= macs.rx_allocation;
+                }
+              #endif
+          /* The requested slot is allocated */
+          macs.tx_allocation |= (UWORD8)  (MASK_SLOT0 >> poll_resp_ts);
+
+          /* Lowest, highest numbered uplink timeslot and Tx parameter are updated */
+
+          if (poll_resp_ts < lowest_ul_ts)
+            lowest_ul_ts = poll_resp_ts;
+
+          if ((poll_resp_ts > highest_ul_ts) || (highest_ul_ts == INVALID))
+            highest_ul_ts = poll_resp_ts;
+
+          tx = (UWORD8) (highest_ul_ts - lowest_ul_ts + 1);
+
+          /* Tx and Sum parameters checking */
+          /*--------------------------------*/
+
+          /* While Tx or Sum parameter isn't respected and the poll response hasn't */
+          /* already been removed */
+          while (   (   (tx > MS_CLASS[SET_PTR->multislot_class].tx)
+                     || ((rx + tx) > MS_CLASS[SET_PTR->multislot_class].sum))
+                 && (poll == TRUE))
+          {
+            /* If no uplink timeslot is used for data */
+            if (macs.tx_data == 0)
+            {
+              /* The poll response isn't processed */
+              poll = FALSE;
+            }
+            else
+            {
+              /* Highest uplink PDTCH is removed */
+              macs.tx_allocation &= (UWORD8) (~(MASK_SLOT0 >> highest_ul_data));
+              macs.tx_data       &= (UWORD8) (~(MASK_SLOT0 >> highest_ul_data));
+
+              #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+                RTTL1_FILL_MACS_STATUS(TX_CANCELLED_POLL, highest_ul_data)
+              #endif
+
+              /* Lowest, highest numbered uplink timeslot and Tx parameter are updated */
+
+              lowest_ul_ts    = INVALID;
+              highest_ul_ts   = INVALID;
+              highest_ul_data = INVALID;
+
+              for (ts = 0; ts < TS_NUMBER; ts ++)
+              {
+                if (macs.tx_allocation & (MASK_SLOT0 >> ts))
+                {
+                  if (lowest_ul_ts == INVALID)
+                    lowest_ul_ts = ts;
+                  highest_ul_ts = ts;
+                  if (macs.tx_data & (MASK_SLOT0 >> ts))
+                    highest_ul_data = ts;
+                }
+              }
+
+              tx = (UWORD8) (highest_ul_ts - lowest_ul_ts + 1);
+
+            }
+          } /* End while Tx or Sum parameter not met */
+        } /* End of case "poll on a timeslot not already allocated for uplink data transfer"
+                         " Tra and Ttb respected " */
+
+        /* If the poll response is done */
+        /*------------------------------*/
+        if (poll == TRUE)
+        {
+          // Note: Power measurement always found because Tra met
+
+          UWORD8   cs_type;
+          UWORD16  prach_info;
+              #if L1_EDA
+                UWORD8 only_monitored_ts;
+              #endif
+
+          cs_type    = (UWORD8)  ((NDB_PTR->a_pu_gprs[i][0]) & 0xF);
+          prach_info = (UWORD16) l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][2];
+
+          if(cs_type == CS_PAB8_TYPE)
+          {
+            l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][2] = ((API)(l1a_l1s_com.Scell_info.bsic << 2)) |
+                                                         ((API)(prach_info) << 8);
+            l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][3] = 0;
+
+            // macs.tx_prach_allocation is updated
+            macs.tx_prach_allocation |= (UWORD8) (MASK_SLOT0 >> poll_resp_ts);
+          }
+          else
+          if(cs_type == CS_PAB11_TYPE)
+          {
+            l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][2] = ((API)(prach_info) << 5);
+            l1ps_dsp_com.pdsp_ndb_ptr->a_pu_gprs[i][3] = ((API)(l1a_l1s_com.Scell_info.bsic << 10));
+
+            // macs.tx_prach_allocation is updated
+            macs.tx_prach_allocation |= (UWORD8) (MASK_SLOT0 >> poll_resp_ts);
+          }
+
+              #if L1_EDA
+                only_monitored_ts = ~((UWORD8)(SET_PTR->dl_tbf_alloc.timeslot_alloc << l1a_l1s_com.dl_tn)) & (SET_PTR->ul_tbf_alloc->timeslot_alloc<< l1a_l1s_com.dl_tn);
+                //lowest_poll_ts variable is used to remove only monitored ts above a ts
+                //used for a poll.
+                if (SET_PTR->mac_mode == EXT_DYN_ALLOC)
+                {
+                  if ((poll_resp_ts - RXTX_DELAY) < macs.lowest_poll_ts)
+                    macs.lowest_poll_ts = (poll_resp_ts - RXTX_DELAY);
+                }
+              #endif
+          #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+            RTTL1_FILL_UL_PDTCH(cs_type, tx_allocation_s & (0x80 >> poll_resp_ts), poll_resp_ts + l1a_l1s_com.dl_tn)
+          #endif
+
+          // a_ul_buffer_gprs updating
+          macs.ul_buffer_index[poll_resp_ts] = i + 8;
+
+          #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+            if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+            {
+              trace_info.pdtch_trace.ul_status[poll_resp_ts] |= cs_type << 4;
+              trace_info.pdtch_trace.ul_status[poll_resp_ts] |= 1;
+            }
+          #endif
+        } // End if the poll response is processed
+
+        /* If the poll response isn't processed */
+        /*--------------------------------------*/
+        else
+        {
+          // All allocation parameters that may have been modified to map
+          // this poll response are restored
+          macs.tx_allocation = tx_allocation_s;
+          macs.rx_allocation = rx_allocation_s;
+          macs.tx_data       = tx_data_s;
+          highest_ul_ts      = highest_ul_ts_s;
+          lowest_ul_ts       = lowest_ul_ts_s;
+
+        #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+          if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+            trace_info.pdtch_trace.blk_status |= 0x01;
+        #endif
+
+        #if MACS_STATUS
+          l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb]= POLL_ERROR_MS_CLASS;
+          l1ps_macs_com.macs_status.nb ++;
+        #endif
+
+        #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+          RTTL1_FILL_MACS_STATUS(POLL_REJECT, poll_resp_ts)
+        #endif
+        } // End if the poll response isn't processed
+            //The trace for poll response
+            #if FF_TBF
+              #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+                if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_POLL_PARAM)
+                {
+                   Trace_rlc_poll_param ( poll, //Indicate whether L1 is going to transmit poll resp or not: 0-no, 1-yes
+                                                     l1s.next_time.fn, //next frm on whih poll resp will be sent
+                                                     poll_resp_ts, //Timseslot for poll response
+                                                     macs.tx_allocation,
+                                                     (UWORD32)macs.tx_data,
+                                                     macs.rx_allocation,
+                                                     (UWORD32)macs.last_poll_response,
+                                                     ((NDB_PTR->a_pu_gprs[i][0]) & CS_GPRS_MASK));
+
+                }
+              #endif
+            #endif
+        i ++;
+
+      } /* End while a poll response is requested and can be mapped */
+
+      /*---------------------------------------------------------*/
+      /* Uplink RLC/MAC data blocks processing                   */
+      /*---------------------------------------------------------*/
+
+      i                          = 0;
+      ts                         = 0;
+      macs.rlc_blocks_sent       = 0;
+
+      // tx_data_s represents here the remaining timeslots that must be associated
+      // with a RLC/MAC data block
+      tx_data_s                  = macs.tx_data;
+
+      /* While a timeslot is available to transmit an uplink RLC/MAC data block */
+      while (tx_data_s != 0)
+      {
+        /* If slot is allocated for data transfer */
+        if (macs.tx_data & (MASK_SLOT0 >> ts))
+        {
+          UWORD8 cs_type = (((UWORD8) NDB_PTR->a_du_gprs[i][0]) & 0xF);
+
+          /* If no RLC/MAC block is sent by RLC */
+          /*------------------------------------*/
+
+          if (cs_type == CS_NONE_TYPE)
+          {
+            // All uplink timeslots used for data and situated after this timeslot
+            // (inluding this timeslot) are removed
+            macs.tx_allocation &= (UWORD8) (~(  macs.tx_data  & (MASK_ALL_SLOTS >> ts)));
+            macs.tx_data &= (UWORD8) (~(MASK_ALL_SLOTS >> ts));
+            tx_data_s = 0;
+
+            #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+              RTTL1_FILL_MACS_STATUS(TX_ALLOWED_NO_BLK, ts)
+                  #if FF_TBF
+                    //Update the ul_status fileds for cond PDTCH trace
+                    //Since this blcok doesn't have any valid CS scheme, cs_type=0 and payload=11
+                    if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+                    {
+                      //Bits7,6,5,4 (cs_type)of ul_status should all be zeros
+                      trace_info.pdtch_trace.ul_status[ts] &= 0x0f;
+                      //Make the payload as NA
+                      trace_info.pdtch_trace.ul_status[ts] |= 0x03;
+                    }
+                  #endif
+            #endif
+          }
+
+          /* Else: uplink RLC/MAC data block transfer processing */
+          /*-----------------------------------------------------*/
+          else
+          {
+            #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+              if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+              {
+                trace_info.pdtch_trace.ul_status[ts] |= ((UWORD8) cs_type) << 4;
+                trace_info.pdtch_trace.ul_status[ts] |= 2;
+              }
+            #endif
+
+            /* A data block is assigned to timeslot ts */
+            tx_data_s &= (UWORD8) (~(MASK_SLOT0 >> ts));
+            /* rlc_blocks_sent value processed */
+            macs.rlc_blocks_sent ++;
+            /* Uplink buffer index stored in ul_buffer_index */
+            macs.ul_buffer_index[ts] = i;
+
+            /* Next data block */
+            i ++;
+          }
+
+        } /* End if slot allocated for data transfer */
+
+        /* Next timeslot */
+        ts ++;
+      } /* End while */
+
+    } /* End of poll responses / uplink blocks processing */
+
+    /***********************************************************/
+    /* Measurement gap allocation                              */
+    /***********************************************************/
+
+    l1ps_macs_meas();
+
+  #if MACS_STATUS
+    if (macs.pwr_allocation == 0)
+    {
+      l1ps_macs_com.macs_status.id[l1ps_macs_com.macs_status.nb] = NO_MEAS_MAPPED;
+      l1ps_macs_com.macs_status.nb ++;
+    }
+  #endif
+
+    // Initialize the reception block period
+    macs.rx_blk_period   = NO_DL_BLK;
+
+  } /* End if next frame is the first of a block period */
+
+  /***********************************************************/
+  /* RLC_DOWNLINK call enabling for uplink PDCH status       */
+  /***********************************************************/
+
+  //                                                           FN 13
+  //    0   1   2   3    4   5   6   7    8   9   10  11   12
+  // ----------------------------------------------------------
+  // ||       B0      ||       B1      ||       B2      || I ||
+  // ||   |   |   |   || X |   |   |   || X |   |   |   || X ||
+  // ----------------------------------------------------------
+
+  if (   (l1s.actual_time.fn_mod13 == 4)
+      || (l1s.actual_time.fn_mod13 == 8)
+      || (l1s.actual_time.fn_mod13 == 12))
+  {
+        #if (FF_TBF)
+          l1ps_macs_rlc_uplink_info();
+        #else
+    l1ps_macs_com.rlc_downlink_call = TRUE;
+        #endif
+
+    // RTT: trace UL PDTCH blocks
+    #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+      if (SELECTED_BITMAP(RTTL1_ENABLE_UL_PDTCH))
+      {
+        UWORD8 i,j = 0;
+
+        for(i=2; i < 8; i++)
+        {
+          if (macs.tx_data & (0x80 >> i))
+          {
+            RTTL1_FILL_UL_PDTCH((((UWORD8) NDB_PTR->a_du_gprs[j][0]) & 0xF), 1, i)
+            j++;
+          }
+        }
+      }
+    #endif
+  }
+
+  #if FF_L1_IT_DSP_USF
+    } // if (l1ps_macs_com.usf_status != USF_IT_DSP)
+  #endif // FF_L1_IT_DSP_USF
+
+
+  /***********************************************************/
+  /* MAC-S control result for LAYER 1                        */
+  /***********************************************************/
+
+  /* We update allocation structures in Layer 1 - MAC-S interface */
+  l1ps_macs_com.rx_allocation       = macs.rx_allocation;
+  l1ps_macs_com.tx_nb_allocation    = macs.tx_allocation & (~macs.tx_prach_allocation);
+  l1ps_macs_com.tx_prach_allocation = macs.tx_prach_allocation;
+  l1ps_macs_com.pwr_allocation      = macs.pwr_allocation;
+
+
+  #if FF_L1_IT_DSP_USF
+    // When dynamic allocation is in use for uplink TBF, notifies L1S about
+    // USF uncertainty for FN%13=3 and 7
+    if (l1ps_macs_com.usf_status != USF_IT_DSP)
+    {
+      if (macs.usf_vote_enable)
+        l1ps_macs_com.usf_status = USF_AWAITED;
+      else
+        l1ps_macs_com.usf_status = USF_AVAILABLE;
+    }
+  #endif // FF_L1_IT_DSP_USF
+
+  /***********************************************************/
+  /* DSP programming                                         */
+  /***********************************************************/
+
+  // Write uplink blocks - timeslots correspondance in a_ul_buffer_gprs
+  // MAC mode in d_sched_mode_gprs and the USF table in a_usf_gprs (Each frame)
+
+  #if FF_L1_IT_DSP_USF
+    if (l1ps_macs_com.usf_status != USF_AWAITED)
+  #endif // FF_L1_IT_DSP_USF
+
+  l1pddsp_transfer_mslot_ctrl
+      (l1s.next_time.fn_mod13_mod4,                   // Burst number (0 to 3)
+       macs.rx_allocation,                            // DL Bitmap
+       macs.tx_allocation,                            // UL Bitmap
+       SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_table, // USF table
+       SET_PTR->mac_mode,                             // MAC mode
+       macs.ul_buffer_index,                          // UL buffer index
+       SET_PTR->tsc,                                  // Training sequence code
+       l1a_l1s_com.dedic_set.radio_freq,              // Radio Freq. used for I/Q swap.
+       l1a_l1s_com.dl_tn,                             // DL Transfer Sync. TN.
+         #if FF_L1_IT_DSP_USF
+           macs.dsp_usf_interrupt                         // USF interrupt activation
+         #else
+           macs.usf_vote_enable                           // USF vote activation
+         #endif
+       );
+
+
+  /*****************************************************************/
+  /* TBF parameters saving and updating                            */
+  /* last_rx_allocation, TFI, rlc_blocks_sent and last_poll_error  */
+  /*****************************************************************/
+
+  //                                                           FN 13
+  //    0   1   2   3    4   5   6   7    8   9   10  11   12
+  // ----------------------------------------------------------
+  // ||       B0      ||       B1      ||       B2      || I ||
+  // ||   |   |   | X ||   |   |   | X ||   |   |   | X ||   ||
+  // ----------------------------------------------------------
+
+  if (   (l1s.next_time.fn_mod13 == 3)
+      || (l1s.next_time.fn_mod13 == 7)
+      || (l1s.next_time.fn_mod13 == 11))
+  {
+    // Downlink blocks to report to RLC
+    macs.last_rx_alloc  = macs.rx_allocation;
+    macs.rx_blk_period  = l1s.next_time.block_id + 1;
+    if (macs.rx_blk_period > MAX_BLOCK_ID)
+      macs.rx_blk_period -= (UWORD32) (MAX_BLOCK_ID + 1);
+
+    // Synchronization memorization for synchro. change detection
+    macs.old_synchro_ts = l1a_l1s_com.dl_tn;
+
+    macs.tx_allocation       = 0;
+    macs.tx_prach_allocation = 0;
+  } /* End if FN13 = 2, 6 OR 10 */
+
+} /* END OF L1PS_MACS_CTRL() */
+
+/*-----------------------------------------------------------*/
+/* l1ps_macs_read()                                          */
+/*-----------------------------------------------------------*/
+/* Parameters: global l1ps_macs_com           unchanged      */
+/*             global l1s                     unchanged      */
+/*             global l1a_l1s_com             unchanged      */
+/*             global l1ps_dsp_com            changed        */
+/*                                                           */
+/* Return:                                                   */
+/*                                                           */
+/* Description: l1ps_macs_read checks the last received      */
+/*              downlink blocks. It checks if the TFI field  */
+/*              is present and good in the block header and  */
+/*              write in the NDB the number of received      */
+/*              received blocks and on which timeslot was    */
+/*              received each data block and how much block. */
+/*              Then the RLC layer is called (rlc_downlink)  */
+/*-----------------------------------------------------------*/
+void l1ps_macs_read(UWORD8 pr_table[8])
+{
+  #define NDB_PTR  l1ps_dsp_com.pdsp_ndb_ptr
+
+  /***********************************************************/
+  /* Downlink RLC/MAC block management                       */
+  /***********************************************************/
+
+  // If we are in the first frame after a block period */
+  //                                                           FN 13
+  //    0   1   2   3    4   5   6   7    8   9   10  11   12
+  // ----------------------------------------------------------
+  // ||       B0      ||       B1      ||       B2      || I ||
+  // ||   |   |   |   || X |   |   |   || X |   |   |   || X ||
+  // ----------------------------------------------------------
+  //                                         X: Received downlink RLC/MAC block management
+  if (  (l1s.actual_time.fn_mod13 == 4)
+      ||(l1s.actual_time.fn_mod13 == 8)
+      ||(l1s.actual_time.fn_mod13 == 12))
+  {
+    UWORD8            ts;            // Timeslot pointer
+    BOOL              tfi_result;    // Set to 1 if the TFI field is present and good
+    #if FF_TBF
+      UWORD8         cs_type;
+      BOOL           crc_error = 0;
+    #endif
+
+    /* For each radio block allocated for downlink transfer in the last block period */
+    for (ts = 0; ts < TS_NUMBER; ts ++)
+    {
+      if (macs.last_rx_alloc & (MASK_SLOT0 >> ts))
+      {
+        l1ps_macs_header_decoding(macs.rx_no, &tfi_result, &(pr_table[ts]));
+
+        #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+          if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+          {
+            trace_info.pdtch_trace.dl_status[macs.rx_no] |= tfi_result << 4;
+            #if FF_TBF
+                  crc_error = NDB_PTR->a_dd_gprs[macs.rx_no][0] & (1<<B_CRC_BLOCK_ERROR);
+                  //In the case of GPRS b_cs_type is 4bit info.
+                  cs_type = NDB_PTR->a_dd_gprs[macs.rx_no][0] & CS_GPRS_MASK;
+              #if L1_EGPRS
+                }
+              #endif
+              //If the blcok received is in CRC error, update the bit0 of dl_status as 1
+              if (crc_error == (1<<B_CRC_BLOCK_ERROR))
+              {
+                trace_info.pdtch_trace.dl_status[macs.rx_no] |= 0x01;
+              }
+              else
+              {
+                // No CRC error. Good Block
+                //dl_cs_type used only for BINARY TRACE. We put the following limitation so that
+                //in the case of EGPRS with MCS we don't enter here.
+                if ((cs_type > CS1_TYPE_DATA) && (cs_type <= CS4_TYPE))
+                {
+                  trace_info.pdtch_trace.dl_cs_type |= ((cs_type - 3) & 3) << (macs.rx_no * 2);
+                }
+              }
+            #else
+            if (l1ps_dsp_com.pdsp_ndb_ptr->a_dd_gprs[macs.rx_no][0] & 0x0100) // CRC error
+              trace_info.pdtch_trace.dl_status[macs.rx_no] = 1;
+            else
+            {
+              // CS type
+              UWORD8 cs_type = NDB_PTR->a_dd_gprs[macs.rx_no][0] & 0xf;
+
+              if (cs_type != CS1_TYPE_DATA)
+                trace_info.pdtch_trace.dl_cs_type |= ((cs_type - 3) & 3) << macs.rx_no;
+            }
+            #endif
+          }
+        #endif
+
+        // TFI filtering result stored in the downlink block buffer header
+        NDB_PTR->a_dd_gprs[macs.rx_no][0] &= (API) (TFI_BIT_MASK);
+        NDB_PTR->a_dd_gprs[macs.rx_no][0] |= (API) (tfi_result << TFI_BIT_SHIFT);
+
+        /*---------------------------------------------------------*/
+        /* Timeslot and Rx_no values updating                      */
+        /*---------------------------------------------------------*/
+
+        // Timeslot number (relative to the network) on which the block was received is
+        // stored in the downlink block buffer header
+
+        NDB_PTR->a_dd_gprs[macs.rx_no][1] = ts + l1a_l1s_com.dl_tn;
+
+        #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
+          RTTL1_FILL_DL_PDTCH((UWORD8) (NDB_PTR->a_dd_gprs[macs.rx_no][4]),    \
+                              tfi_result,                                      \
+                              NDB_PTR->a_dd_gprs[macs.rx_no][0] & 0x0100 >> 8, \
+                              NDB_PTR->a_dd_gprs[macs.rx_no][0] & 0x000f,      \
+                              ts + l1a_l1s_com.dl_tn)
+        #endif
+
+        macs.rx_no ++;
+
+      } /* End if timeslot was allocated in downlink for the last block period */
+    } /* Next timeslot (FOR statement) */
+
+    #if FF_TBF
+      //The "rlc_downlink_bufferize_param" structure is used to memorize parameters
+      //over a block period in order to cope with spreading issue.
+      //
+      // C|W R    |
+      //  |C W R  |
+      //  |  C W R|       TBF 1
+      //  |    C W|R <------------
+      //----------------------
+      //  |      C|W R <--------------
+      //  |       |C W R
+      //  |       |  C W R       TBF 2
+      //  |       |    C W R
+      //                   ^
+      //                   |
+      //                   worst case where the rlc_downlink() function can be called
+      //                   when spreading occurs
+
+      //the case above depicts a new TBF assignment without change of the synchronization:
+      //as the call to the rlc_downlink() function (that needs among other the assignment id parameter)
+      //can be delayed due to spreading, the assignment id of TBF 1 should be memorized
+      //until the call of the rlc_downlink() function that handles the last block of TBF 1
+
+      l1ps_macs_com.rlc_downlink_bufferize_param.allocated_tbf = l1ps.read_param.allocated_tbf;
+      l1ps_macs_com.rlc_downlink_bufferize_param.assignment_id = l1ps.read_param.assignment_id;
+      #if L1_EGPRS
+        l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode      = l1ps.read_param.tbf_mode;
+      #endif
+
+      // New buffer to be allocated
+      macs.dl_buffer_index = INVALID;
+      // Initialize spreading counter
+      macs.tdma_delay = 0;
+
+      // rlc_uplink_info() invokation in case of block skipped due to resynchro
+      // See L1_MCU-CHG-17924
+      if (l1s.task_status[PDTCH].current_status != RE_ENTERED)
+        l1ps_macs_rlc_uplink_info();
+    #endif
+    /***********************************************************/
+    /* RLC_DOWNLINK call enabling for downlink PDCH status     */
+    /***********************************************************/
+    l1ps_macs_com.rlc_downlink_call = TRUE;
+
+    #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+    #if L1_BINARY_TRACE == 0
+      if (trace_info.current_config->l1_dyn_trace & (1<<L1_DYN_TRACE_DL_PDTCH_CRC))
+      {
+        BOOL    crc_error=0;
+        UWORD8  i;
+
+        for(i=0;i<macs.rx_no;i++)
+          crc_error |= ((NDB_PTR->a_dd_gprs[i][0] & 0x0100) >> (1+i));
+
+        Trace_Packet_Transfer(crc_error); // Previous RX blocks CRC_ERROR summary
+      }
+    #endif
+    #endif
+
+  } /* End if first frame after a block period */
+
+} /* END OF L1PS_MACS_READ */
+
+/*-----------------------------------------------------------*/
+/* l1ps_macs_meas()                                          */
+/*-----------------------------------------------------------*/
+/* Parameters: global l1ps_macs_com           unchanged      */
+/*             global l1a_l1s_com             unchanged      */
+/*             static macs.rx_allocation      unchanged      */
+/*             static macs.tx_allocation      unchanged      */
+/*             static macs.pwr_allocation     changed        */
+/* Return:                                                   */
+/*                                                           */
+/* Description: This function processes the power measurement*/
+/*              gap according to the MS class and timeslots  */
+/*              allocated in macs.tx_allocation and          */
+/*              macs.rx_allocation fields.                   */
+/*-----------------------------------------------------------*/
+void l1ps_macs_meas()
+{
+  #define SET_PTR l1pa_l1ps_com.transfer.aset
+
+  WORD8  ts                = 7;       // Timeslot pointer
+  UWORD8 gap               = 0;       // Gap size counter
+  UWORD8 meas              = 0;       // Temporary gap processing
+  UWORD8 bitmap_rx, bitmap_tx;
+
+  macs.pwr_allocation = 0;
+  bitmap_rx = macs.rx_allocation;
+  bitmap_tx = macs.tx_allocation;
+
+  // Searching of the last allocated timeslot
+  // Note: Layer 1 always synchronize on a RX event, so the Tra gap will always
+  //       be found after the last allocated timeslot of a frame
+
+  while (   (ts >= 0)
+         && ((bitmap_rx & 0x01) == 0)
+         && ((bitmap_tx & 0x01) == 0))
+  {
+    // Memorization of the timeslot
+    meas |= (UWORD8) (MASK_SLOT0 >> ts);
+    // Gap is incremented
+    gap ++;
+
+    bitmap_rx >>= 1;
+    bitmap_tx >>= 1;
+    ts --;
+  }
+
+  // Last allocated timeslot: ts
+  // Power gap size: gap
+
+  // Save the "tra gap" at the end of the frame
+  macs.tra_gap = gap;
+
+  // If Tra respected before the first Rx of the frame after
+  // Here we consider that L1 is ALWAYS synchronized on a RX timeslot
+  if (gap >= MS_CLASS[SET_PTR->multislot_class].tra)
+  {
+    // The gap is allocated
+    macs.pwr_allocation |= meas;
+  }
+  else
+  // If the first slot of the next frame is free and permit to respect the Tra parameter
+  // in fixed mode
+  // Notes:
+  // - if Tra not respected and the current slot 0 isn't allocated --> the slot 0 of
+  //   the next frame will not be allocated (only possible in Fixed mode)
+  // - in all cases, only one timeslot need to be removed
+  if (   (gap + 1 >= MS_CLASS[SET_PTR->multislot_class].tra)
+      && (!(macs.rx_allocation & MASK_SLOT0)))
+  {
+    // The gap is allocated
+    macs.pwr_allocation |= meas;
+  }
+
+#if L1_EDA
+  //if in extended dynamic allocation and if no power measurement is set in Tra gap (Tra not fulfilled)
+  //then power measurement is set in Tta gap if MS class supports it.
+  if ((SET_PTR->mac_mode == EXT_DYN_ALLOC) && (!macs.pwr_allocation))
+  {
+    UWORD8  i = MAX_TS_NB;
+
+    //compute tta
+    while (!(macs.rx_allocation & (MASK_SLOT0 >> i)))
+     i--;
+
+    i++;
+    gap = 0;
+    meas = 0;
+    while (!(macs.tx_allocation & (MASK_SLOT0 >> i)))
+    {
+     gap++;
+     meas |= (UWORD8) (MASK_SLOT0 >> i);
+     i++;
+    }
+
+    if (gap <= MS_CLASS[SET_PTR->multislot_class].tta)
+      macs.pwr_allocation |= meas;
+  }
+#endif //#if L1_EDA
+} /* End of l1ps_macs_meas */
+
+/*-----------------------------------------------------------*/
+/* l1ps_macs_header_decoding()                               */
+/*-----------------------------------------------------------*/
+/* Parameters:                                               */
+/*                                                           */
+/* Return:                                                   */
+/*                                                           */
+/* Description: This function process the TFI filtering and  */
+/*              decode the PR value in the MAC header of the */
+/*              block stored in buffer rx_no.                */
+/*-----------------------------------------------------------*/
+void l1ps_macs_header_decoding(UWORD8 rx_no, UWORD8 *tfi_result, UWORD8 *pr)
+{
+  UWORD8            payload;       // Payload type value in the RLC/MAC header
+  UWORD8            tfi;           // TFI value
+  UWORD16           mac_header[2]; // Downlink block MAC header
+
+  *pr = 0;
+
+  // DSP Driver
+  // Downlink block MAC header reading
+
+  mac_header[0] = NDB_PTR->a_dd_gprs[rx_no][4];
+  mac_header[1] = NDB_PTR->a_dd_gprs[rx_no][5];
+
+  *tfi_result = TFI_NOT_FILTERED;
+
+#if TFI_FILTERING
+
+  /*---------------------------------------------------------*/
+  /* TFI Filtering                                           */
+  /*---------------------------------------------------------*/
+
+  *tfi_result = TFI_BAD;
+
+  /* Payload reading in the block header */
+  /*-------------------------------------*/
+
+  payload = (UWORD8) (((mac_header[0]) >> PAYLOAD_SHIFT) & PAYLOAD_MASK);
+
+  #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+    if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+    {
+      trace_info.pdtch_trace.dl_status[rx_no] |= payload << 6;
+      // RRBP + S/P trace
+      trace_info.pdtch_trace.dl_status[rx_no] |= (mac_header[0] & (0x38)) >> 2;
+    }
+  #endif
+
+  /* If the payload time isn't "RESERVED" */
+  if (payload != RESERVED)
+  {
+    /* Data block case, processed if a downlink TBF is assigned */
+    /*----------------------------------------------------------*/
+
+    if (payload == DATA_BLOCK)
+    {
+      *pr = (UWORD8) ((mac_header[0] >> DATA_PR_SHIFT) & PR_MASK);
+
+      if ((l1ps.read_param.allocated_tbf == DL_TBF) || (l1ps.read_param.allocated_tbf == BOTH_TBF))
+      {
+        // TFI value reading
+        tfi = (UWORD8) ((mac_header[0] & DATA_TFI_MASK) >> DATA_TFI_SHIFT);
+
+        // Downlink TFI control
+        if (tfi == l1ps.read_param.dl_tfi)
+        {
+          *tfi_result    = TFI_GOOD;
+        }
+      } // End if "downlink TBF enabled"
+
+    } /* End of data block case */
+
+    /* Control block case */
+    /*--------------------*/
+
+    else
+    {
+      /* Optionnal field is no present */
+      if (payload == CTRL_NO_OPTIONAL)
+        *tfi_result = TFI_NOT_PRESENT;
+
+      /* Optionnal field is present */
+      if (payload == CTRL_OPTIONAL)
+      {
+        *pr = (UWORD8) ((mac_header[1] >> CTRL_PR_SHIFT) & PR_MASK);
+
+        /* AC = 1 : TFI is present */
+        if (mac_header[0] & AC_MASK)
+        {
+          // TFI value reading
+          tfi = (UWORD8) ((mac_header[1] & CTRL_TFI_MASK) >> CTRL_TFI_SHIFT);
+
+          /* If direction is downlink TBF (D = 1) and a downlink TBF is in progress */
+          if ( mac_header[1] & MASK_D)
+          {
+            if (   (l1ps.read_param.allocated_tbf == DL_TBF)
+                || (l1ps.read_param.allocated_tbf == BOTH_TBF))
+            {
+              // Downlink TFI value is checked
+              if (tfi == l1ps.read_param.dl_tfi)
+              {
+                *tfi_result = TFI_GOOD;
+              }
+            }
+          } /* End if direction is downlink */
+
+          /* If direction is uplink TBF (D = 0) and an uplink TBF is in progress */
+          else if (   (l1ps.read_param.allocated_tbf == UL_TBF)
+                   || (l1ps.read_param.allocated_tbf == BOTH_TBF))
+          {
+            // Uplink TFI value is checked
+            if (tfi == l1ps.read_param.ul_tfi)
+            {
+              *tfi_result = TFI_GOOD;
+            }
+
+          } /* End if direction is uplink */
+
+        } /* End if AC = 1 */
+
+        /* AC = 0 : TFI is no present */
+        else
+          *tfi_result = TFI_NOT_PRESENT;
+
+      } // End if control block with optionnal field
+
+    } // End of control block case
+
+  } // End if PAYLOAD != "RESERVED"
+
+#endif
+
+  /*---------------------------------------------------------*/
+  /* pr_table updating                                       */
+  /*---------------------------------------------------------*/
+
+  if(l1ps.read_param.dl_pwr_ctl.p0 == 255)
+    *pr = 0; // PR unused in "No power control" mode
+  else
+    *pr = PR_CONVERSION[l1ps.read_param.dl_pwr_ctl.bts_pwr_ctl_mode][*pr];
+
+  // If TFI isn't good
+  if (*tfi_result != TFI_GOOD)
+  {
+    // Set bit 7 to 1
+    *pr |= 0x80;
+  }
+
+}
+
+/*-----------------------------------------------------------*/
+/* l1ps_macs_rlc_downlink_call()                             */
+/*-----------------------------------------------------------*/
+/* Parameters:                                               */
+/*                                                           */
+/* Return:                                                   */
+/*                                                           */
+/* Description: This function is called at the end of L1S    */
+/*              execution if RLC_DOWNLINK must be called.    */
+/*                                                           */
+/*-----------------------------------------------------------*/
+void l1ps_macs_rlc_downlink_call(void)
+{
+  UWORD8 i;
+  #if FF_TBF
+    UWORD32         fn;
+    BOOL            rlc_dl_call = FALSE;
+    API*            rlc_buffer;
+    API*            dummy_rlc_buffer = NULL;
+
+    //correct reporting of FN to L3 should be TDMA 4, 8 or 12 of MF13
+    fn=l1s.actual_time.fn-l1s.actual_time.fn_mod13_mod4;
+
+    //when fn is in first block of the MF13 (which value is not a correct value
+    //to report to upper layer) then fn should be decremented so that fn%13 = 12
+    if(l1s.actual_time.fn_mod13 <= 3)
+      fn--;
+
+    //to cope with border case
+//    if (fn < 0)  //OMAPS00090550
+//      fn += MAX_FN - 1; //OMAPS00090550
+
+    // Retrieve decoded blocks from API. All payload decoded check.
+    if (!rlc_downlink_copy_buffer(FALSE))
+    {
+      // Flag RLC call
+      rlc_dl_call = TRUE;
+
+      // RLC buffer exhaustion check
+      if ((macs.dl_buffer_index == INVALID) || (l1a_l1s_com.recovery_flag))
+      {
+        if (macs.tdma_delay >= 3)
+        {
+          // No block reported ever by DSP
+      //    #if (TRACE_TYPE==1) || (TRACE_TYPE==4)
+      //      l1_trace_egprs(NO_BLOCKS_PASSED_TO_L3);
+       //   #endif
+
+          #if (TRACE_TYPE==5)
+            trace_fct_simu("MACS ERROR: No RLC blocks passed to L3 on current frame", 0);
+            sprintf(errormsg,"MACS ERROR: No RLC blocks passed to L3 on current frame");
+            log_sim_error(ERR);
+          #endif
+        }
+        else
+        {
+          // No RLC buffer available
+
+          #if (TRACE_TYPE==5)
+            trace_fct_simu("MACS ERROR: No free buffer to copy RLC blocks on current frame", 0);
+            //sprintf(errormsg,"MACS ERROR: No free buffer to copy RLC blocks on current frame");
+            //log_sim_error(ERR);
+          #endif
+        }
+
+        // Dummy buffer to be reported
+        rlc_buffer = (API*) dummy_rlc_buffer;
+      }
+      // RLC buffer has been succesfully allocated
+      else
+      {
+        // RLC buffer to be reported
+        rlc_buffer = (API*) &(macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs);
+
+        #if (TRACE_TYPE == 1)||(TRACE_TYPE == 4)
+          #if L1_BINARY_TRACE == 0
+            if (trace_info.current_config->l1_dyn_trace & (1<<L1_DYN_TRACE_DL_PDTCH_CRC))
+            {
+              BOOL    crc_error=0;
+              UWORD8  i;
+              #if L1_EGPRS
+                if (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS)
+                {
+                  for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
+                    crc_error |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> (1+i));
+                }
+                else
+              #endif
+                {
+                  for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
+                    crc_error |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_gprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> (1+i));
+                }
+              Trace_Packet_Transfer(crc_error); // Previous RX blocks CRC_ERROR summary
+            }
+          #endif
+        #endif
+        #if L1_EGPRS
+          // IR testing specific trace
+          #if (TRACE_TYPE == 1)||(TRACE_TYPE == 4)
+            if ((trace_info.current_config->l1_dyn_trace & (1<<L1_DYN_TRACE_IR))
+                && (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS))
+            {
+              UWORD8 j ;
+              // Clear ir trace variables
+              trace_info.ir_trace.crc    = 0;
+              trace_info.ir_trace.mcs    = 0;
+		          trace_info.ir_trace.status_ir_tfi = 0;
+              trace_info.ir_trace.puncturing = 0;
+
+              for(j=0;j<MS_CLASS[MAX_CLASS].rx;j++)
+              {
+                trace_info.ir_trace.bsn[j] = 0;
+                trace_info.ir_trace.cv_bep_egprs[j]= 0;
+		            trace_info.ir_trace.mean_bep_egprs[j] = 0;
+              }
+
+              // Retrieve IR info from every PDCH
+              for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
+              {
+                UWORD16 crc;
+                UWORD16 bsn1, bsn2;
+                UWORD8  mcs;
+                UWORD8  cps;
+                UWORD8  k;
+
+                // retrieve coding scheme
+                mcs = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & CS_EGPRS_MASK);
+
+                j = k = 0 ;
+
+                // retrieve BSN
+                switch (mcs)
+                {
+                  case CS1_TYPE_POLL:
+                  case CS1_TYPE_DATA:
+                  case CS2_TYPE:
+                  case CS3_TYPE:
+                  case CS4_TYPE:
+                    // GPRS data block
+                    if ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) || (mcs == CS1_TYPE_POLL))
+                      bsn1 = 0xffff;
+                    else
+                      bsn1 = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1] >> 1) & 0x7f);
+                    bsn2 = 0;
+
+                    crc = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & ((1 << B_CRC_HEADER_ERROR) + (1 << B_CRC_PAYLOAD1_ERROR) + (1 << B_CRC_BLOCK_ERROR)));
+                    crc = (crc >> B_CRC_HEADER_ERROR);
+                    break;
+
+                  case MCS1_TYPE:
+                  case MCS2_TYPE:
+                  case MCS3_TYPE:
+                  case MCS4_TYPE:
+                    // rlc mac header type 3
+                    cps = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1]) >> 9) & 0x0F ;
+                    j = 255 ; // cps is set
+                  case MCS5_TYPE:
+                  case MCS6_TYPE:
+                      // rlc mac header type 2
+                    if (j != 255)
+                    {
+                      cps = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1]) >> 9) & 0x07 ;
+                    }
+                    do
+                    {
+                      if (cps == CPS_value1_6[k][mcs-MCS1_TYPE])
+                      { // set puncturing scheme for payload 1 and 2: 0x01 PS1 0x10 PS2 0x11 PS3 related to time slot i
+                        trace_info.ir_trace.puncturing |= (((k+1) << 2) << (4*(3-i))) ;
+                        break ;
+                      }
+                      k++;
+                    } while (k < 3) ;
+
+                    // EGPRS data block, Header Type 2 and 3
+                    if (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_HEADER_ERROR))
+                      bsn1 = 0xffff;
+                    else
+                    {
+                      bsn1 = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 0] >> 14) & 0x03);
+                      bsn1 |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1] & 0x1ff) << 2);
+                    }
+                    bsn2 = 0;
+
+                    crc = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & ((1 << B_CRC_HEADER_ERROR) + (1 << B_CRC_PAYLOAD1_ERROR) + (1 << B_CRC_BLOCK_ERROR)));
+                    crc = (crc >> B_CRC_HEADER_ERROR);
+                    break;
+
+                  case MCS7_TYPE:
+                  case MCS8_TYPE:
+                  case MCS9_TYPE:
+                    // rlc mac header type 1
+                    cps = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 2]) >> 3) & 0x1F ;
+                    do
+                    {
+                      if (cps == CPS_value7_9[j][k][mcs-MCS7_TYPE])
+                      {  // set puncturing scheme for payload 1 and 2: 0x01 PS1 0x10 PS2 0x11 PS3 related to time slot i
+                        trace_info.ir_trace.puncturing |= ((((j+1) << 2) | (k+1)) << (4*(3-i))) ;
+                        break ;
+                      }
+                      k++;
+                      if (k == 3)
+                      {
+                        k = 0;
+                        j++ ;
+                      }
+                    } while (j < 3) ;
+
+                    // EGPRS data block, Header Type 1
+                    if (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_HEADER_ERROR))
+                    {
+                      bsn1 = 0xffff;
+                      bsn2 = 0xffff;
+                    }
+                    else
+                    {
+                      bsn1 =  ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 0] >> 14) & 0x03);
+                      bsn1 |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1] & 0x1ff) << 2);
+
+                      bsn2 =  ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 1] >> 9) & 0x7f);
+                      bsn2 |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][SIZE_DSP_HEADER_EGPRS + 2] & 0x07) << 7);
+                      bsn2 += bsn1;
+                      if (bsn2 >= 2048)
+                        bsn2 -= 2048;
+                    }
+
+                    crc = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & ((1 << B_CRC_HEADER_ERROR) + (1 << B_CRC_PAYLOAD1_ERROR) + (1 << B_CRC_PAYLOAD2_ERROR) + (1 << B_CRC_BLOCK_ERROR)));
+                    crc = (crc >> B_CRC_HEADER_ERROR);
+                    break;
+
+                  default:
+                    bsn1 = 0xffff;
+                    bsn2 = 0xffff;
+                    crc = ((1 << B_CRC_HEADER_ERROR) + (1 << B_CRC_PAYLOAD1_ERROR) + (1 << B_CRC_PAYLOAD2_ERROR) + (1 << B_CRC_BLOCK_ERROR));
+                    crc = (crc >> B_CRC_HEADER_ERROR);
+                    break;
+                }
+
+                // Update IR info from current PDCH
+                trace_info.ir_trace.crc    |= (crc << ((3-i)*8));
+                trace_info.ir_trace.bsn[i] =  ((bsn1 << 16) | bsn2);
+                trace_info.ir_trace.mcs    |= ((mcs << ((3-i)*8)));
+
+                /* we take only the msb of cv_bep and mean_bep */
+                trace_info.ir_trace.cv_bep_egprs[i] = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][2]) >> 8) ;
+                trace_info.ir_trace.mean_bep_egprs[i] = (macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][3]) ;
+                if (((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & TFI_BIT_MASK) >> TFI_BIT_SHIFT) == TFI_BAD)
+                  trace_info.ir_trace.status_ir_tfi |= (0x1 << (3-i)) ; /* set tfi flag to 1 if block is not for MS */
+              }
+
+              trace_info.ir_trace.fn = l1s.actual_time.fn ;
+              trace_info.ir_trace.status_ir_tfi |= ((macs.rlc_dbl_buffer[macs.dl_buffer_index].dl_status & (1 << IR_OUT_OF_MEMORY))<<(7-IR_OUT_OF_MEMORY)) ;
+
+             // Output trace
+              Trace_IR (&trace_info.ir_trace) ;
+            }
+          #endif //(TRACE_TYPE == 1)||(TRACE_TYPE == 4)
+        #endif //L1_EGPRS
+        #if TESTMODE
+          if (l1_config.TestMode)
+          {
+            BOOL    crc_error_bler; //Local var used for accumulating BLER
+            UWORD8  i;
+
+            l1tm.tmode_stats.bler_total_blocks++;
+            #if L1_EGPRS
+              if (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS)
+              {
+                for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
+                {
+                  //bler_total_blocks gives the total number of blocks for computing BLER
+                  //The block error is assigned to crc_error_bler.
+                  //If the block is in error bler_crc is incremented.
+                  crc_error_bler = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> B_CRC_BLOCK_ERROR);
+                  if (crc_error_bler == TRUE)
+                    l1tm.tmode_stats.bler_crc[i]++;
+                }
+              }
+              else
+            #endif
+              {
+                for(i=0;i<macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs;i++)
+                {
+                  //bler_total_blocks gives the total number of blocks for computing BLER
+                  //The block error is assigned to crc_error_bler.
+                  //If the block is in error bler_crc is incremented.
+                  crc_error_bler = ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_gprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> B_CRC_BLOCK_ERROR);
+                  if (crc_error_bler == TRUE)
+                    l1tm.tmode_stats.bler_crc[i]++;
+                }
+              }
+          }
+        #endif
+      }
+    }
+    // Payload still awaited
+    else // (!rlc_downlink_copy_buffer(FALSE)
+    {
+      // Check spreading limit not exceeded
+      if ((macs.tdma_delay >= 3) || (l1a_l1s_com.recovery_flag))
+      {
+        // Free RLC buffer
+        macs.rlc_dbl_buffer[macs.dl_buffer_index].d_rlcmac_rx_no_gprs = RLC_BLOCK_ACK;
+
+        // Flag RLC call
+        rlc_dl_call = TRUE;
+
+        // Dummy buffer to be reported
+        rlc_buffer = (API*) dummy_rlc_buffer;
+
+        // No block reported ever by DSP
+
+        #if (TRACE_TYPE==5)
+          trace_fct_simu("MACS ERROR: No RLC blocks passed to L3 on current frame", 0);
+          sprintf(errormsg,"MACS ERROR: No RLC blocks passed to L3 on current frame");
+          log_sim_error(ERR);
+        #endif
+      }
+      else
+        // Increment spreading counter
+        macs.tdma_delay++;
+    } // (!rlc_downlink_copy_buffer(FALSE)
+
+    // Function RLC_DOWNLINK_DATA() to be invoked
+    if (rlc_dl_call)
+    {
+
+      rlc_downlink_data( l1ps_macs_com.rlc_downlink_bufferize_param.assignment_id, // Assignment ID
+                         fn,                                                       // Frame number
+                         rlc_buffer                                                // Pointer on the DL structure
+                       );
+
+      // Add the RLC_D traces in the case of EGPRS also
+
+      #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+        if ((trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_RLC_PARAM)
+           && (rlc_buffer != NULL))
+        {
+          UWORD8 i;
+          UWORD16 dl_blk_status[4] = {0,0,0,0};
+          for (i=0;i<macs.rx_no;i++)
+          {
+            #if (L1_EGPRS)
+              if (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS)
+              {
+                dl_blk_status[i] = A_DD_XGPRS[TBF_MODE_EGPRS][i][0];
+              }
+              else
+              {
+            #endif
+                dl_blk_status[i] = (((UWORD8) NDB_PTR->a_dd_gprs[i][0]) & 0x070F);
+            #if (L1_EGPRS)
+              }
+            #endif
+          }
+          Trace_rlc_dl_param(l1ps_macs_com.rlc_downlink_bufferize_param.assignment_id,
+                       l1s.actual_time.fn,
+                       macs.rx_no,
+                       macs.rlc_blocks_sent,
+                       macs.last_poll_response,
+                       (dl_blk_status[1]<<16) |dl_blk_status[0], //dl_blk_status for TS1 and TS0
+                       (dl_blk_status[3]<<16) |dl_blk_status[2]);//dl_blk_status for TS3 and TS2
+        }
+      #endif
+      macs.rx_no                      = 0;
+      l1ps_macs_com.rlc_downlink_call = FALSE;
+    }
+
+  #else
+
+  #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+    if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+    {
+      // If some RX have been received or some TX have been programmed
+      if ((macs.last_rx_alloc != 0) || (macs.tx_allocation != 0))
+      {
+        // Send trace
+        Trace_condensed_pdtch(macs.last_rx_alloc, macs.tx_allocation);
+      }
+
+      // Reset PDTCH trace structure
+      for(i=0; i<8; i++)
+      {
+        trace_info.pdtch_trace.dl_status[i] = 0;
+        trace_info.pdtch_trace.ul_status[i] = 0;
+      }
+      trace_info.pdtch_trace.dl_cs_type   = 0;
+      trace_info.pdtch_trace.blk_status   = 0;
+    }
+  #endif
+
+
+  // Last_poll_error processing
+  //---------------------------
+
+  // All slots allocated for poll response transmission (allocated in tx_allocation
+  // but not in tx_data) are set to 0 (no error) in last_poll_response
+  macs.last_poll_response &= (UWORD8) (~(macs.tx_allocation) | macs.tx_data);
+
+  /* last_poll_response correspondance with network timeslot numbers */
+  i = macs.old_synchro_ts - RXTX_DELAY;
+
+  if (i > MAX_TS_NB)
+  {
+    macs.last_poll_response <<= (-i);
+  }
+  else
+  {
+    macs.last_poll_response >>= i;
+  }
+
+  // Store number of RX within NDB for RLC
+  //--------------------------------------
+
+  NDB_PTR->d_rlcmac_rx_no_gprs = macs.rx_no;
+
+  #if L1_RECOVERY
+    // blocks get a CRC error in case of COM error
+    if (l1a_l1s_com.recovery_flag == TRUE)
+    {
+     // force bad CRC for 4 RX slots
+      NDB_PTR->a_dd_gprs[0][0] |= 0x0100;
+      NDB_PTR->a_dd_gprs[1][0] |= 0x0100;
+      NDB_PTR->a_dd_gprs[2][0] |= 0x0100;
+      NDB_PTR->a_dd_gprs[3][0] |= 0x0100;
+    }
+  #endif
+  /******************/
+
+  // Call RLC_DOWNLINK
+  //------------------
+
+  rlc_downlink( l1ps.read_param.assignment_id,            // Assignment ID
+                l1s.actual_time.fn,                       // Frame number
+                (API*) &(NDB_PTR->d_rlcmac_rx_no_gprs),   // Pointer on the DL structure
+                 macs.rlc_blocks_sent,                    // ID of the last transmitted uplink
+                                                          //   data block
+                 macs.last_poll_response                  // Status of the poll responses of
+              );                                          //   the last block period
+
+  #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+    if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_RLC_PARAM)
+    {
+      Trace_rlc_dl_param(l1ps.read_param.assignment_id,
+                         l1s.actual_time.fn,
+                         (UWORD32) &(NDB_PTR->d_rlcmac_rx_no_gprs),
+                         (UWORD8)  NDB_PTR->d_rlcmac_rx_no_gprs,
+                         macs.rlc_blocks_sent,
+                         macs.last_poll_response);
+    }
+  #endif
+
+      /* FreeCalypso TCS211 reconstruction */
+      #if 0 //TESTMODE
+          if (l1_config.TestMode)
+          {
+            BOOL    crc_error_bler; //Local var used for accumulating BLER
+            UWORD8  i;
+
+            l1tm.tmode_stats.bler_total_blocks++;
+
+            for(i=0; i < macs.rx_no; i++)
+             {
+                //bler_total_blocks gives the total number of blocks for computing BLER
+                //The block error is assigned to crc_error_bler.
+                //If the block is in error bler_crc is incremented.
+               crc_error_bler = ( (NDB_PTR->a_dd_gprs[i][0] & (1 << B_CRC_BLOCK_ERROR)) >> B_CRC_BLOCK_ERROR);
+               if (crc_error_bler == TRUE)
+                 l1tm.tmode_stats.bler_crc[i]++;
+              }
+          }
+        #endif
+
+  // Clear parameters
+  //-----------------
+
+  /* All downlink blocks were processed */
+  macs.last_rx_alloc              = 0;
+  macs.rx_no                      = 0;
+  macs.rlc_blocks_sent            = 0;
+  macs.last_poll_response         = 0;
+
+  l1ps_macs_com.rlc_downlink_call = FALSE;
+
+  // Reset CS type.
+  //---------------
+  #if (DSP == 33)  || (DSP == 34) || (DSP == 35) || (DSP == 36) || (DSP == 37) || (DSP == 38) || (DSP == 39)
+    NDB_PTR->a_dd_gprs[0][0] = NDB_PTR->a_dd_gprs[1][0] = NDB_PTR->a_dd_gprs[2][0] =
+    NDB_PTR->a_dd_gprs[3][0] = NDB_PTR->a_dd_gprs[4][0] = NDB_PTR->a_dd_gprs[5][0] =
+    NDB_PTR->a_dd_gprs[6][0] = NDB_PTR->a_dd_gprs[7][0] = CS_NONE_TYPE;
+  #else
+    NDB_PTR->a_dd_gprs[0][0] = NDB_PTR->a_dd_gprs[1][0] = NDB_PTR->a_dd_gprs[2][0] =
+    NDB_PTR->a_dd_gprs[3][0] = CS_NONE_TYPE;
+  #endif
+#endif
+}//void l1ps_macs_rlc_downlink_call(void)
+#if FF_TBF
+/*-----------------------------------------------------------*/
+/* l1ps_macs_rlc_uplink_info()                             */
+/*-----------------------------------------------------------*/
+/* Parameters:                                               */
+/*                                                           */
+/* Return:                                                   */
+/*                                                           */
+/* Description: This function is called in the               */
+/*              l1ps_macs_ctrl() function on TDMA 4, 8 or 12 */
+/*              of MF13                                      */
+/*                                                           */
+/*-----------------------------------------------------------*/
+void l1ps_macs_rlc_uplink_info(void)
+{
+  UWORD8 i;
+
+  #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4))
+    if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_CONDENSED_PDTCH)
+    {
+      // If some RX have been received or some TX have been programmed
+      if ((macs.last_rx_alloc != 0) || (macs.tx_allocation != 0))
+      {
+        // Send trace
+        Trace_condensed_pdtch(macs.last_rx_alloc, macs.tx_allocation);
+      }
+
+      // Reset PDTCH trace structure
+      for(i=0; i<8; i++)
+      {
+        trace_info.pdtch_trace.dl_status[i] = 0;
+        trace_info.pdtch_trace.ul_status[i] = 0;
+      }
+      trace_info.pdtch_trace.dl_cs_type   = 0;
+      trace_info.pdtch_trace.blk_status   = 0;
+    }
+  #endif
+
+  // Last_poll_error processing
+  //---------------------------
+
+  /* All slots allocated for poll response transmission (allocated in tx_allocation
+     but not in tx_data) are set to 0 (no error) in last_poll_response */
+  macs.last_poll_response &= (UWORD8) (~(macs.tx_allocation) | macs.tx_data);
+
+  /* last_poll_response correspondance with network timeslot numbers */
+  i = macs.old_synchro_ts - RXTX_DELAY;
+
+  if (i > MAX_TS_NB)
+  {
+    macs.last_poll_response <<= (-i);
+  }
+  else
+  {
+    macs.last_poll_response >>= i;
+  }
+
+  #if L1_EGPRS
+    //sub_mode is ON
+    if (l1ps_macs_com.loop_param.sub_mode == TRUE)
+    {
+      macs.rlc_blocks_sent    = 0;
+      macs.last_poll_response = 0;
+    }
+  #endif
+
+  rlc_uplink_info(l1ps.read_param.assignment_id,
+                  l1s.actual_time.fn,
+                  macs.rlc_blocks_sent,
+                  macs.last_poll_response);
+
+  //While the initialization of these variables is performed in the
+  //l1ps_macs_rlc_downlink_call() for GPRS, for EGPRS the initialization
+  //is done here below. Note that it is still performed on frame index 0
+  //of MF13 in the l1s_end_manager() function whether in EGPRS or GPRS mode.
+  //The variable below is set in the l1ps_macs_ctrl() function on frame index 2 of MF13
+  //and stores the rx allocation. This allocation is used later in the l1ps_macs_read()
+  //function to pass the blocks that were received in the previous block period.
+  macs.last_rx_alloc              = 0;
+  macs.rlc_blocks_sent            = 0;
+  macs.last_poll_response         = 0;
+}
+
+/*-----------------------------------------------------------*/
+/* rlc_downlink_copy_buffer()                                */
+/*-----------------------------------------------------------*/
+/* Parameters:  isr: flag that indicates whether the call    */
+/*                   of this function is performed at the    */
+/*                   beginning of the hisr() function        */
+/*                   (hisr = TRUE) or not.                   */
+/*                                                           */
+/* Return:      missing_payload: flag that indicates if still*/
+/*                               payloads are missing after  */
+/*                               the copy                    */
+/*                                                           */
+/* Description: This function is called in the hisr()        */
+/*              function with hisr = TRUE and in the         */
+/*              l1ps_macs_rlc_downlink_call() function       */
+/*              with hisr = FALSE                            */
+/*-----------------------------------------------------------*/
+  UWORD8 rlc_downlink_copy_buffer(UWORD8 isr)
+  {
+    BOOL missing_payload   = FALSE;
+    BOOL allocation_needed = FALSE;
+
+    UWORD32 i,j;
+
+    // Downlink blocks expected
+    if (l1ps_macs_com.rlc_downlink_call)
+    {
+      // Not in TDMA3 unless we are in ISR so we may have blocks to copy
+      if ( ((macs.tdma_delay < 3) && (!isr)) // No logical XOR in C
+           || ((macs.tdma_delay >= 3) && (isr))
+         )
+
+      {
+        // Test buffer allocation requirement if not already allocated
+        if (macs.dl_buffer_index == INVALID)
+        {
+            allocation_needed = TRUE;
+        }
+
+        // Look for an available buffer and initialize it
+        if (allocation_needed)
+        {
+          for (i = 0; i < NBR_SHARED_BUFFER_RLC; i++)
+          {
+            //as soon as one free block is found
+            if (macs.rlc_dbl_buffer[i].d_rlcmac_rx_no_gprs == RLC_BLOCK_ACK)
+            {
+              // Store buffer index
+              macs.dl_buffer_index = i;
+              // Store number of blocks in buffer passed to RLC
+              macs.rlc_dbl_buffer[i].d_rlcmac_rx_no_gprs = macs.rx_no;
+              break;
+            }
+          }
+        }
+
+        // Copy available blocks if buffer allocated
+        if (macs.dl_buffer_index != INVALID)
+        {
+          // GPRS mode, no spreading
+        #if L1_EGPRS
+          if (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_GPRS)
+        #endif
+          {
+            // Copy whole bunch of blocks (4 downlink, worst case)
+            for (i=0;i<NBR_BUFFER_GPRS;i++)
+            {
+              memcpy((char*) &macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_gprs[i][0],
+                     (char*) A_DD_XGPRS[TBF_MODE_GPRS][i],
+                     SIZE_GPRS_DL_BUFF * sizeof(API));
+            }
+          }
+          // EGPRS mode
+        #if L1_EGPRS
+          else
+          {
+            // Parse every expected block
+            for (i = 0; i < macs.rx_no; i++)
+            {
+              // If not already copied
+              if ((macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0] & CS_EGPRS_MASK) == CS_NONE_TYPE)
+              {
+                // New block available in API
+                if (A_DD_XGPRS[TBF_MODE_EGPRS][i][0] & (1 << B_BLK_READY))
+                {
+                  // Copy block from API to SRAM
+                  memcpy((char*) &macs.rlc_dbl_buffer[macs.dl_buffer_index].buffer.a_dd_egprs[i][0],
+                         (char*) A_DD_XGPRS[TBF_MODE_EGPRS][i],
+                         SIZE_EGPRS_DL_BUFF * sizeof(API));
+
+                  // Acknowledge DSP
+                  A_DD_XGPRS[TBF_MODE_EGPRS][i][0] &= ~(1 << B_BLK_READY);
+                }
+                else
+                  missing_payload = TRUE;
+              }
+            }
+          } // TBF mode
+        #endif
+
+          // Store "missing payload" flag used for TDMA3 limit case.
+          macs.dl_missing_payload = missing_payload;
+
+        } // Buffer is allocated
+        else
+        {
+          // No buffer allocated yet
+          if (allocation_needed)
+            // RLC Buffer exhaustion - abort
+            missing_payload = FALSE;
+          else
+           // No buffer allocated yet as no block present
+           missing_payload = TRUE;
+
+          // Still some buffer expected
+          macs.dl_missing_payload = TRUE;
+        }
+      } // Not in ISR TDMA 0,1,2, or ISR from TDMA 3
+      else if ((macs.tdma_delay >= 3) && (!isr))
+      {
+        // End of L1S in TDMA3, we need to report the status from ISR call.
+        missing_payload = macs.dl_missing_payload;
+      }
+
+      // IR status reporting (relevant for EGPRS only)
+      //----------------------------------------------
+
+      // RLC buffer allocated, all blocks received
+      if ((macs.dl_buffer_index != INVALID) && (!missing_payload))
+      {
+      #if L1_EGPRS
+        if ( (l1ps_macs_com.rlc_downlink_bufferize_param.tbf_mode == TBF_MODE_EGPRS)
+             && (l1ps_dsp_com.edsp_ndb_ptr->d_modem_status_egprs & (1 << B_IR_OUT_OF_MEM)) )
+        {
+          // EGPRS TBF mode, IR out of memory status flag is set
+          macs.rlc_dbl_buffer[macs.dl_buffer_index].dl_status |= (1 << IR_OUT_OF_MEMORY);
+        }
+        else
+      #endif
+        {
+          // GPRS TBF mode or EGPRS but IR out of memory not detected
+          macs.rlc_dbl_buffer[macs.dl_buffer_index].dl_status &= (~(1 << IR_OUT_OF_MEMORY));
+        }
+      }
+    } // if (l1ps_macs_com.rlc_downlink_call)
+
+    // Return blocks receipt completion status
+    return missing_payload;
+}
+
+#endif //FF_TBF
+
+#if TESTMODE
+  //===========================================================================
+  // Function called instead of l1ps_macs_ctrl if CMU200 loop mode is selected
+  //===========================================================================
+
+  void l1ps_tmode_macs_ctrl(void)
+  {
+    #define NDB_PTR  l1ps_dsp_com.pdsp_ndb_ptr
+    #define SET_PTR  l1pa_l1ps_com.transfer.aset
+
+    NDB_PTR->a_du_gprs[0][0]     = l1_config.tmode.tx_params.coding_scheme;
+
+    /* Enable loop */
+    NDB_PTR->d_sched_mode_gprs |= (1<<6);
+
+    // Force single slot allocation for CMU loop: 1RX, 1TX
+    macs.rx_allocation = 0x80;
+    macs.tx_allocation = 0x10;
+    macs.tx_prach_allocation = 0;
+    macs.pwr_allocation = 0;
+
+    macs.ul_buffer_index[0] = 0xFF;                          // UL buffer index
+    macs.ul_buffer_index[1] = 0xFF;
+    macs.ul_buffer_index[2] = 0xFF;
+    macs.ul_buffer_index[3] = 0;
+    macs.ul_buffer_index[4] = 0xFF;
+    macs.ul_buffer_index[5] = 0xFF;
+    macs.ul_buffer_index[6] = 0xFF;
+    macs.ul_buffer_index[7] = 0xFF;
+
+    /* Disable USF management in the DSP */
+    macs.usf_vote_enable = 0;
+
+    /***********************************************************/
+    /* MAC-S control result for LAYER 1                        */
+    /***********************************************************/
+
+    /* We update allocation structures in Layer 1 - MAC-S interface */
+    l1ps_macs_com.rx_allocation       = macs.rx_allocation;
+    l1ps_macs_com.tx_nb_allocation    = macs.tx_allocation & (~macs.tx_prach_allocation);
+    l1ps_macs_com.tx_prach_allocation = macs.tx_prach_allocation;
+    l1ps_macs_com.pwr_allocation      = macs.pwr_allocation;
+
+    /***********************************************************/
+    /* DSP programming                                         */
+    /***********************************************************/
+
+    // Write uplink blocks - timeslots correspondance in a_ul_buffer_gprs
+    // MAC mode in d_sched_mode_gprs and the USF table in a_usf_gprs (Each frame)
+
+    l1pddsp_transfer_mslot_ctrl
+        (l1s.next_time.fn_mod13_mod4,                   // Burst number (0 to 3)
+         macs.rx_allocation,                            // DL Bitmap
+         macs.tx_allocation,                            // UL Bitmap
+         SET_PTR->ul_tbf_alloc->dynamic_alloc.usf_table, // USF table
+         SET_PTR->mac_mode,                             // MAC mode
+         macs.ul_buffer_index,                          // UL buffer index
+         SET_PTR->tsc,                                  // Training sequence code
+         l1a_l1s_com.dedic_set.radio_freq,              // Radio Freq. used for I/Q swap.
+         l1a_l1s_com.dl_tn,                             // DL Transfer Sync. TN.
+       #if FF_L1_IT_DSP_USF
+         macs.dsp_usf_interrupt                         // USF interrupt activation
+       #else
+         macs.usf_vote_enable                           // USF vote activation
+       #endif
+     );
+
+   //NDB_PTR->a_ctrl_ched_gprs[0] = CS1_TYPE_DATA;
+   NDB_PTR->a_ctrl_ched_gprs[0] = NDB_PTR->a_du_gprs[0][0];
+
+  }
+#endif
+#endif // L1_GPRS