diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 5de1f71efd75a108aeb244c61aeeb6a30d03b152..2f74c3524bd2bac8fcd2462aa9fa7e0670b9766b 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -369,8 +369,8 @@ void fh_if4p5_south_in(RU_t *ru,
   proc->frame_rx = f;
   proc->timestamp_rx = (proc->frame_rx * fp->samples_per_subframe * 10)  + fp->get_samples_slot_timestamp(proc->tti_rx, fp, 0);
   //  proc->timestamp_tx = proc->timestamp_rx +  (4*fp->samples_per_subframe);
-  proc->tti_tx   = (sl+(fp->slots_per_subframe*ru->sf_ahead))%fp->slots_per_frame;
-  proc->frame_tx = (sl>(fp->slots_per_frame-1-(fp->slots_per_subframe*ru->sf_ahead))) ? (f+1)&1023 : f;
+  proc->tti_tx   = (sl+ru->sl_ahead)%fp->slots_per_frame;
+  proc->frame_tx = (sl>(fp->slots_per_frame-1-(ru->sl_ahead))) ? (f+1)&1023 : f;
 
   if (proc->first_rx == 0) {
     if (proc->tti_rx != *slot) {
@@ -1290,7 +1290,7 @@ void *ru_thread( void *param ) {
     }
   }
 
-  LOG_I(PHY, "Signaling main thread that RU %d is ready, sf_ahead %d\n",ru->idx,ru->sf_ahead);
+  LOG_I(PHY, "Signaling main thread that RU %d is ready, sl_ahead %d\n",ru->idx,ru->sl_ahead);
   pthread_mutex_lock(&RC.ru_mutex);
   RC.ru_mask &= ~(1<<ru->idx);
   pthread_cond_signal(&RC.ru_cond);
@@ -1376,9 +1376,12 @@ void *ru_thread( void *param ) {
       opp_enabled = opp_enabled0;
     }
     if (initial_wait == 0 && ru->rx_fhaul.trials > 1000) reset_meas(&ru->rx_fhaul);
-    proc->timestamp_tx = proc->timestamp_rx + (ru->sf_ahead*fp->samples_per_subframe);
-    proc->frame_tx     = (proc->tti_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*ru->sf_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
-    proc->tti_tx      = (proc->tti_rx + (fp->slots_per_subframe*ru->sf_ahead))%fp->slots_per_frame;
+    proc->timestamp_tx = proc->timestamp_rx;
+    int sl=proc->tti_tx;
+    for (int slidx=0;slidx<ru->sl_ahead;slidx++)
+       proc->timestamp_tx += fp->get_samples_per_slot((sl+slidx)%fp->slots_per_frame,fp);
+    proc->frame_tx     = (proc->tti_rx > (fp->slots_per_frame-1-(ru->sl_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
+    proc->tti_tx      = (proc->tti_rx + ru->sl_ahead)%fp->slots_per_frame;
     LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n",
           frame,slot,
           proc->frame_rx,proc->tti_rx,
@@ -2122,7 +2125,7 @@ static void NRRCconfig_RU(void) {
       RC.ru[j]->if_frequency                      = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr);
       RC.ru[j]->if_freq_offset                    = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr);
       RC.ru[j]->do_precoding                      = *(RUParamList.paramarray[j][RU_DO_PRECODING].iptr);
-      RC.ru[j]->sf_ahead                          = *(RUParamList.paramarray[j][RU_SF_AHEAD].iptr);
+      RC.ru[j]->sl_ahead                          = *(RUParamList.paramarray[j][RU_SL_AHEAD].iptr);
       RC.ru[j]->num_bands                         = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
       for (i=0; i<RC.ru[j]->num_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
       RC.ru[j]->openair0_cfg.nr_flag              = *(RUParamList.paramarray[j][RU_NR_FLAG].iptr);
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 6d59137f80d5130c957b580aa372b4144fae7b27..dc7b8bf8e337c4b9fbe6c8b8f5ada6a4ef6b9813 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -772,8 +772,8 @@ int main( int argc, char **argv ) {
     for (ru_id=0; ru_id<RC.nb_RU; ru_id++) {
       RC.ru[ru_id]->rf_map.card=0;
       RC.ru[ru_id]->rf_map.chain=CC_id+chain_offset;
-      if (ru_id==0) sl_ahead = RC.ru[ru_id]->sf_ahead * RC.gNB[0]->frame_parms.slots_per_subframe;	
-      else AssertFatal(RC.ru[ru_id]->sf_ahead != RC.ru[0]->sf_ahead,"RU %d has different sf_ahead %d than RU 0 %d\n",RC.ru[ru_id]->sf_ahead,RC.ru[0]->sf_ahead);
+      if (ru_id==0) sl_ahead = RC.ru[ru_id]->sl_ahead;	
+      else AssertFatal(RC.ru[ru_id]->sl_ahead != RC.ru[0]->sl_ahead,"RU %d has different sl_ahead %d than RU 0 %d\n",RC.ru[ru_id]->sl_ahead,RC.ru[0]->sl_ahead);
     }
     
   }
diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h
index 5dfb0722db3f5e1e90efdc3c10789598b64bf2c4..e70bb811b72ebc774ecdd1a9191a7eda5e043811 100644
--- a/openair1/PHY/defs_RU.h
+++ b/openair1/PHY/defs_RU.h
@@ -506,8 +506,10 @@ typedef struct RU_t_s {
   int att_tx;
   /// flag to indicate precoding operation in RU
   int do_precoding;
-  /// TX processing advance in subframes
+  /// TX processing advance in subframes (for LTE)
   int sf_ahead;
+  /// TX processing advance in slots (for NR)
+  int sl_ahead;
   /// FAPI confiuration
   nfapi_nr_config_request_scf_t  config;
   /// Frame parameters
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index 840e1a8ab2966067366bca074d29ef3a53a1524c..a533b8cb23a6b18258bbe6997eb70d5bdcd8543e 100644
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -100,6 +100,7 @@ typedef enum {
 #define CONFIG_STRING_RU_IF_FREQ_OFFSET           "if_offset"
 #define CONFIG_STRING_RU_DO_PRECODING             "do_precoding"
 #define CONFIG_STRING_RU_SF_AHEAD                 "sf_ahead"
+#define CONFIG_STRING_RU_SL_AHEAD                 "sl_ahead"
 #define CONFIG_STRING_RU_NR_FLAG                  "nr_flag"
 #define CONFIG_STRING_RU_NR_SCS_FOR_RASTER        "nr_scs_for_raster"
 
@@ -133,8 +134,9 @@ typedef enum {
 #define RU_IF_FREQ_OFFSET             27
 #define RU_DO_PRECODING               28
 #define RU_SF_AHEAD                   29
-#define RU_NR_FLAG                    30 
-#define RU_NR_SCS_FOR_RASTER          31
+#define RU_SL_AHEAD                   30 
+#define RU_NR_FLAG                    31 
+#define RU_NR_SCS_FOR_RASTER          32
 /*-----------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            RU configuration parameters                                                                  */
 /*   optname                                   helpstr   paramflags    XXXptr          defXXXval                   type      numelt        */
@@ -170,6 +172,7 @@ typedef enum {
     {CONFIG_STRING_RU_IF_FREQ_OFFSET,              NULL,       0,       iptr:NULL,       defintval:0,             TYPE_INT,         0}, \
     {CONFIG_STRING_RU_DO_PRECODING,                NULL,       0,       iptr:NULL,       defintval:0,             TYPE_INT,         0}, \
     {CONFIG_STRING_RU_SF_AHEAD,                    NULL,       0,       iptr:NULL,       defintval:4,             TYPE_INT,         0}, \
+    {CONFIG_STRING_RU_SL_AHEAD,                    NULL,       0,       iptr:NULL,       defintval:4,             TYPE_INT,         0}, \
     {CONFIG_STRING_RU_NR_FLAG,                     NULL,       0,       iptr:NULL,       defintval:0,             TYPE_INT,         0}, \
     {CONFIG_STRING_RU_NR_SCS_FOR_RASTER,           NULL,       0,       iptr:NULL,       defintval:1,             TYPE_INT,         0}, \
   }
diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h
index 436271fc0b8cffe1781b846631d64f2106c4c0ca..e634f077e269c030b2ab53da28f8f2ff7e216e1e 100644
--- a/openair2/GNB_APP/MACRLC_nr_paramdef.h
+++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h
@@ -65,6 +65,8 @@
 #define CONFIG_STRING_MACRLC_DL_RD2_BLER_THRESHOLD         "dl_rd2_bler_threshold"
 #define CONFIG_STRING_MACRLC_DL_MAX_MCS                    "dl_max_mcs"
 #define CONFIG_STRING_MACRLC_HARQ_ROUND_MAX                "harq_round_max"
+#define CONFIG_STRING_MACRLC_MIN_GRANT_PRB                 "min_grant_prb"
+#define CONFIG_STRING_MACRLC_MIN_GRANT_MCS                 "min_grant_mcs"
 
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            MacRLC  configuration parameters                                                                           */
@@ -97,7 +99,9 @@
 {CONFIG_STRING_MACRLC_DL_BLER_TARGET_LOWER,   "Lower threshold of BLER to increase DL MCS",   0, dblptr:NULL,  defdblval:0.05,  TYPE_DOUBLE,  0},        \
 {CONFIG_STRING_MACRLC_DL_RD2_BLER_THRESHOLD,  "Threshold of RD2/RETX2 BLER to decrease DL MCS", 0, dblptr:NULL,  defdblval:0.01,  TYPE_DOUBLE,  0},      \
 {CONFIG_STRING_MACRLC_DL_MAX_MCS,             "Maximum DL MCS that should be used", 0, u8ptr:NULL,  defintval:28,  TYPE_UINT8,  0},      \
-{CONFIG_STRING_MACRLC_HARQ_ROUND_MAX,         "Maximum number of HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0} \
+{CONFIG_STRING_MACRLC_HARQ_ROUND_MAX,         "Maximum number of HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \
+{CONFIG_STRING_MACRLC_MIN_GRANT_PRB,         "Minimal Periodic ULSCH Grant PRBs", 0, u8ptr:NULL, defintval:5, TYPE_UINT8, 0}, \
+{CONFIG_STRING_MACRLC_MIN_GRANT_MCS,         "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0} \
 }
 #define MACRLC_CC_IDX                                          0
 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX                      1
@@ -126,5 +130,7 @@
 #define MACRLC_DL_RD2_BLER_THRESHOLD_IDX                       24
 #define MACRLC_DL_MAX_MCS_IDX                                  25
 #define MACRLC_HARQ_ROUND_MAX_IDX                              26
+#define MACRLC_MIN_GRANT_PRB_IDX                               27
+#define MACRLC_MIN_GRANT_MCS_IDX                               28
 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #endif
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 72237bf6c9588a29d3acb80b4f1d6f7a63859e68..b088cf7ed16fe2425a0533794628aa600b0bcf71 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -811,6 +811,8 @@ void RCconfig_nr_macrlc() {
       RC.nrmac[j]->dl_rd2_bler_threshold = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_RD2_BLER_THRESHOLD_IDX].dblptr);
       RC.nrmac[j]->dl_max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr);
       RC.nrmac[j]->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_HARQ_ROUND_MAX_IDX].u8ptr);
+      RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr);
+      RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr);
       RC.nrmac[j]->num_ulprbbl = num_prbbl;
       memcpy(RC.nrmac[j]->ulprbbl,prbbl,275*sizeof(prbbl[0]));
     }//  for (j=0;j<RC.nb_nr_macrlc_inst;j++)
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 92db25178ad4e7445549545f13893f6301fa4b1c..362338cfc3080e2694ad05315b9459156fc1c2a4 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -496,9 +496,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
     const int nr_ulstart_slot = tdd->nrofDownlinkSlots + (tdd->nrofUplinkSymbols == 0);
 
     for (int slot = 0; slot < n; ++slot) {
-      /* FIXME: it seems there is a problem with slot 0/10/slots right after UL:
-       * we just get retransmissions. Thus, do not schedule such slots in DL */
-      if (slot % nr_slots_period != 0)
+      if (slot != 0)
         RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64);
       RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
       LOG_D(NR_MAC, "slot %d DL %d UL %d\n",
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 4ddffc5184e746f80f37d8409c5ec70f6ca29d21..c5ec5e04e8c291761883ab4c0c0e5aace002c807 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -916,16 +916,23 @@ void nr_get_Msg3alloc(module_id_t module_id,
     int nb_slots_per_period = ((1<<mu)*10)/nb_periods_per_frame;
     for (int i=0; i<pusch_TimeDomainAllocationList->list.count; i++) {
       k2 = *pusch_TimeDomainAllocationList->list.array[i]->k2;
-      // we want to transmit in the uplink symbols of mixed slot
+      int start_symbol_index,nr_of_symbols;
+      SLIV2SL(pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength, &start_symbol_index, &nr_of_symbols);
+      LOG_I(NR_MAC,"Checking Msg3 TDA %d : k2 %d, sliv %d,S %d L %d\n",i,(int)k2,(int)pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength,start_symbol_index,nr_of_symbols);
+      // we want to transmit in the uplink symbols of mixed slot AND assuming Msg2 was in the mixed slot
       if ((k2 + DELTA[mu])%nb_slots_per_period == 0) {
         temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
         ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
-        if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot)) {
+
+        if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot) &&
+            nr_of_symbols<=scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols&&
+            start_symbol_index>=(14-scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols)) {
           ra->Msg3_tda_id = i;
           break;
         }
       }
     }
+    AssertFatal(ra->Msg3_tda_id < 16, "Couldn't find an appropriate TD allocation for Msg3\n");
   }
   else {
     ra->Msg3_tda_id = 0;
@@ -953,7 +960,7 @@ void nr_get_Msg3alloc(module_id_t module_id,
       tdd_beam_association[num_tdd_period] = ra->beam_id;
   }
 
-  LOG_D(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id);
+  LOG_I(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id);
   uint16_t *vrb_map_UL =
       &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
 
@@ -1021,7 +1028,7 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
   pusch_pdu->data_scrambling_id = *scc->physCellId;
   pusch_pdu->nrOfLayers = 1;
   pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position);
-  LOG_D(MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d , ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos);
+  LOG_I(MAC, "MSG3 mcs %d, nb_rb %d, first_rb %d, start_sym:%d NR Symb:%d mappingtype:%d , ul_dmrs_symb_pos:%x\n", pusch_pdu->mcs_index,msg3_nb_rb,msg3_first_rb, start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos);
   pusch_pdu->dmrs_config_type = 0;
   pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
   pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
@@ -1115,7 +1122,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
     fh = ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping ? 1 : 0;
   }
 
-  LOG_D(NR_MAC, "Frame %d, Slot %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
+  LOG_I(NR_MAC, "Frame %d, Slot %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
     frameP,
     slotP,
     ra->Msg3_frame,
@@ -1404,8 +1411,9 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]);
 
     if(ra->cfra) {
-      LOG_I(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
+      LOG_I(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CFRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
     }
+    else LOG_I(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception (CBRA) for SFN.Slot %d.%d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
 
     T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->RA_rnti), T_INT(frameP),
       T_INT(slotP), T_INT(0), T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 689f621b86eca7976dfe61c106ed91737707790b..a48a59b67b6771e957d0bf482d80f4ef3d49628c 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -979,7 +979,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
   gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
   if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
     return;
-
   /* PREPROCESSOR */
   gNB_mac->pre_processor_dl(module_id, frame, slot);
 
@@ -1351,6 +1350,21 @@ void nr_schedule_ue_spec(module_id_t module_id,
                 size);
           if (len == 0)
             break;
+          struct timespec time_request;
+          clock_gettime(CLOCK_REALTIME, &time_request);
+          if (lcid>=4)           
+                LOG_D(NR_MAC,
+                "%4d.%2d [UE %04x]: Time %lu.%lu:  %d bytes %s %d -> DLSCH (ndata %lu, remaining size %lu)\n",
+                frame,
+                slot,
+                rnti,
+                time_request.tv_sec,
+                time_request.tv_nsec,
+                len,
+                lcid < 4 ? "DCCH" : "DTCH",
+                lcid,
+                (unsigned long)ndata,
+                (unsigned long)size);
 
           header->R = 0;
           header->F = 1;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index e54e1f203abe7232926758deb1ac2e7f99363f4e..eb51f1ca2678985cd6f09ec6ec6a488895fc3062 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -463,12 +463,14 @@ int nr_process_mac_pdu(module_id_t module_idP,
             mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
             mac_subheader_len = 2;
           }
-
-          LOG_D(NR_MAC, "In %s: [UE %d] %d.%d : ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
-                __func__,
-                module_idP,
+          struct timespec time_request;
+          clock_gettime(CLOCK_REALTIME, &time_request);
+          LOG_D(NR_MAC, "[UE %x] %d.%d : Time %lu.%lu ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
+                UE_info->rnti[UE_id],
                 frameP,
                 slot,
+                time_request.tv_sec,
+                time_request.tv_nsec,
                 rx_lcid<4?"DCCH":"DTCH",
                 rx_lcid,
                 module_idP,
@@ -711,8 +713,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
         UE_info->mac_stats[UE_id].ulsch_DTX++;
       }
       if (UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt >= pusch_failure_thres) {
-         LOG_W(NR_MAC,"Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n",
-               UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt);
+         LOG_W(NR_MAC,"%d.%d Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n",
+               frameP,slotP,UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt);
          UE_info->UE_sched_ctrl[UE_id].ul_failure = 1;
          nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP);
       }
@@ -909,17 +911,22 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
 
   const struct gNB_MAC_INST_s *nrmac = RC.nrmac[mod_id];
   const NR_UE_sched_ctrl_t *sched_ctrl = &nrmac->UE_info.UE_sched_ctrl[UE_id];
-  const int last_ul_sched = sched_ctrl->last_ul_frame * n + sched_ctrl->last_ul_slot;
 
   const NR_TDD_UL_DL_Pattern_t *tdd =
       scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
   int num_slots_per_period;
+  int last_ul_slot,last_ul_sched;
   int tdd_period_len[8] = {500,625,1000,1250,2000,2500,5000,10000};
-  if (tdd)
+  if (tdd) { // Force the default transmission in a full slot as early as possible in the UL portion of TDD period (last_ul_slot)
     num_slots_per_period = n*tdd_period_len[tdd->dl_UL_TransmissionPeriodicity]/10000;
-  else
+    last_ul_slot=1+tdd->nrofDownlinkSlots;
+  }
+  else {
     num_slots_per_period = n;
+    last_ul_slot = sched_ctrl->last_ul_slot; 
+  }
 
+  last_ul_sched = sched_ctrl->last_ul_frame * n + last_ul_slot;
   const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
   /* UE is to be scheduled if
    * (1) we think the UE has more bytes awaiting than what we scheduled
@@ -1111,7 +1118,7 @@ void pf_ul(module_id_t module_id,
   gNB_MAC_INST *nrmac = RC.nrmac[module_id];
   NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
   NR_UE_info_t *UE_info = &nrmac->UE_info;
-  const int min_rb = 5;
+  const int min_rb = nrmac->min_grant_prb;
   float coeff_ue[MAX_MOBILES_PER_GNB];
   // UEs that could be scheduled
   int ue_array[MAX_MOBILES_PER_GNB];
@@ -1226,7 +1233,7 @@ void pf_ul(module_id_t module_id,
           || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
         nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
       NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
-      sched_pusch->mcs = 9;
+      sched_pusch->mcs = nrmac->min_grant_mcs;
       update_ul_ue_R_Qm(sched_pusch, ps);
       sched_pusch->rbStart = rbStart;
       sched_pusch->rbSize = min_rb;
@@ -1252,7 +1259,7 @@ void pf_ul(module_id_t module_id,
     add_tail_nr_list(&UE_sched, UE_id);
 
     /* Calculate coefficient*/
-    sched_pusch->mcs = 9;
+    sched_pusch->mcs = nrmac->min_grant_mcs;
     const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs];
     coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id];
     LOG_D(NR_MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
@@ -1401,7 +1408,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
   if (tda < 0)
     return false;
   int K2 = get_K2(scc, sched_ctrl->active_ubwp, tda, mu);
-  const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
+  const int sched_frame = (frame + (slot + K2 >= nr_slots_per_frame[mu]))&1023;
   const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
 
   if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 417318f8a3a2208f0b2503a1eeab7fc2a617696c..d78fe4e154dce85f359a9c709a5953b21b6cb2c3 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -806,6 +806,8 @@ typedef struct gNB_MAC_INST_s {
   double dl_rd2_bler_threshold;
   uint8_t dl_max_mcs;
   uint8_t harq_round_max;
+  uint8_t min_grant_prb;
+  uint8_t min_grant_mcs;
 } gNB_MAC_INST;
 
 #endif /*__LAYER2_NR_MAC_GNB_H__ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index 5129d46ddc3a48f53b80d62b3b987690941a17e4..1442a9af7271fe2b44687d9a5387024cbf641920 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -655,6 +655,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
       if (entity->has_sdap == 1 && entity->has_sdapULheader == 1)
 	offset = 1; // this is the offset of the SDAP header in bytes
 
+
       message_p = itti_alloc_new_message_sized(TASK_PDCP_ENB, 0,
 					       GTPV1U_GNB_TUNNEL_DATA_REQ,
 					       sizeof(gtpv1u_gnb_tunnel_data_req_t) + size
@@ -673,7 +674,10 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
         LOG_I(PDCP, "%s() (drb %d) SDAP header %2x\n",__func__, rb_id, buf[0]);
         sdap_gnb_ul_header_handler(buf[0]); // Handler for the UL gNB SDAP Header
       }
-      LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size-offset);
+      struct timespec time_request;
+      clock_gettime(CLOCK_REALTIME, &time_request);
+      LOG_D(PDCP, "%s() (drb %d) Time %lu.%lu sending message to gtp size %d\n", __func__, rb_id, time_request.tv_sec,time_request.tv_nsec,
+                                                                                         size-offset);
       itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p);
    }
   }
@@ -725,7 +729,7 @@ rb_found:
     req->offset        = GTPU_HEADER_OVERHEAD_MAX;
     req->rnti          = ue->rnti;
     req->pdusession_id = rb_id;
-    LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n",
+    LOG_I(PDCP, "%s() (drb %d) sending message to gtp size %d\n",
 	  __func__, rb_id, size);
     extern instance_t CUuniqInstance;
     itti_send_msg_to_task(TASK_VARIABLE, CUuniqInstance, message_p);
@@ -733,8 +737,9 @@ rb_found:
     
     memblock = get_free_mem_block(size, __FUNCTION__);
     memcpy(memblock->data, buf, size);
-    
-    LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, rb_id, size);
+    struct timespec time_request;
+    clock_gettime(CLOCK_REALTIME, &time_request); 
+    LOG_D(PDCP, "%s(): (rb %d) calling enqueue_rlc_data_req size %d at time %lu.%lu\n", __func__, rb_id, size,time_request.tv_sec,time_request.tv_nsec);
     //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]);
     //printf("\n");
     enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock);
@@ -1342,7 +1347,9 @@ static boolean_t pdcp_data_req_drb(
   const sdu_size_t sdu_buffer_size,
   unsigned char *const sdu_buffer)
 {
-  LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size);
+  struct timespec time_request;
+  clock_gettime(CLOCK_REALTIME, &time_request);
+  LOG_D(PDCP, "%s() called at time %lu.%lu, size %d\n", __func__, time_request.tv_sec,time_request.tv_nsec,sdu_buffer_size);
   nr_pdcp_ue_t *ue;
   nr_pdcp_entity_t *rb;
   int rnti = ctxt_pP->rnti;
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 78e06d37e2914fde662a0ffe26471f59e108f122..b9d617d2eb679e1fbdce7a1f84d05877bb5aa207 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -462,9 +462,14 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size)
   exit(1);
 
 rb_found:
-  LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d\n",
-        __FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size);
+  if (is_srb==0) {
+     struct timespec time_request;
+     clock_gettime(CLOCK_REALTIME, &time_request);
 
+     LOG_D(RLC, "%s:%d:%s: delivering SDU Time %lu.%lu (rnti %d is_srb %d rb_id %d) size %d\n",
+           __FILE__, __LINE__, __FUNCTION__, time_request.tv_sec,time_request.tv_nsec,
+           ue->rnti, is_srb, rb_id, size);
+  }
   /* unused fields? */
   ctx.instance = 0;
   ctx.frame = 0;
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index 65f835d3fd6e343a32fc29e9f75941d9c0566b98..4eb5b065859ca388e583ded0e0fe65b233af6609 100755
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -1051,7 +1051,7 @@ void fill_initial_SpCellConfig(rnti_t rnti,
   NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0));
   pucchres0->pucch_ResourceId=0;
   //pucchres0->startingPRB=0;
-  pucchres0->startingPRB=(8+rnti) % curr_bwp;
+  pucchres0->startingPRB=(8+rnti) % (curr_bwp/2);
   LOG_D(NR_RRC, "pucchres0->startPRB %ld rnti %d curr_bwp %d\n", pucchres0->startingPRB, rnti, curr_bwp);
   pucchres0->intraSlotFrequencyHopping=NULL;
   pucchres0->secondHopPRB=NULL;
@@ -1260,14 +1260,8 @@ void fill_initial_SpCellConfig(rnti_t rnti,
   schedulingRequestResourceConfig->schedulingRequestID= 0;
   schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset));
   schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40;
-  // note: make sure that there is no issue here. Later choose the RNTI accordingly.
-  //       Here we would be limited to 3 UEs on this resource (1 1/2 Frames 30 kHz SCS, 5 ms TDD periodicity => slots 7,8,9).
-  //       This should be a temporary resource until the first RRCReconfiguration gives new pucch resources.
-  // Check for above configuration and exit for now if it is not the case
   AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30,
               "SCS != 30kHz\n");
-  AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5,
-              "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
 
   schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8;
   schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c
index 6b7f9a21b93cfc13f1f95d8c07c070014928b524..af1fb9224789a92ae62bfa29fdd7bbe4461e5baf 100644
--- a/openair2/RRC/NR/nr_rrc_config.c
+++ b/openair2/RRC/NR/nr_rrc_config.c
@@ -62,12 +62,30 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
 
   //TODO change to accomodate for SRS
 
-  int temp_min_delay = 6; // k2 = 2 or 3 won'r work as well as higher values
+  lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
+  int temp_min_delay; 
+  if(frame_type==TDD && scc->tdd_UL_DL_ConfigurationCommon) {
+  
+    switch (scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity) {
+      default:
+        temp_min_delay = 6;
+        break;
+      case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms2p5:  // 30kHz SCS
+      case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms2:    // 60kHz SCS
+      case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms1p25: // 60kHz SCS
+      case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms1:    // 120kHz SCS
+      case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms0p625:    // 120kHz SCS
+      case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms0p5:    // 120kHz SCS
+        temp_min_delay = 2; 
+        break;
+    }
+  }
+
+
   int k2 = (min_fb_delay<temp_min_delay)?temp_min_delay:min_fb_delay;
 
   uint8_t DELTA[4]= {2,3,4,6}; // Delta parameter for Msg3
   int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
-  lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
 
   struct NR_PUSCH_TimeDomainResourceAllocation *pusch_timedomainresourceallocation = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation));
   pusch_timedomainresourceallocation->k2  = CALLOC(1,sizeof(long));
@@ -77,6 +95,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
   ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation); 
 
   if(frame_type==TDD) {
+      
     // TDD
     if(scc->tdd_UL_DL_ConfigurationCommon) {
       int ul_symb = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;