diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
index f107b5b9736c6418d12a896f8628fd4c24d8c909..7fb42e566aa5c1812ef62394ff5c458c753a444b 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
@@ -46,7 +46,9 @@
 #define FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH 0x03
 #define FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH 0x04
 #define FAPI_NR_DL_CONFIG_TYPE_P_DLSCH 0x05
-#define FAPI_NR_DL_CONFIG_TYPES 0x05
+#define FAPI_NR_DL_CONFIG_TYPE_CSI_RS 0x06
+#define FAPI_NR_DL_CONFIG_TYPE_CSI_IM 0x07
+#define FAPI_NR_DL_CONFIG_TYPES 0x07
 
 #define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
 #define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index dac75bd6ec542d5b654fb59a46adae660ae59721..284ef22fc4c8fe9f72007c82aee0e3a63d49930e 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -473,11 +473,53 @@ typedef struct {
   fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config_rel15;
 } fapi_nr_dl_config_dlsch_pdu;
 
+
+typedef struct {
+  uint16_t bwp_size;//
+  uint16_t bwp_start;//
+  uint8_t  subcarrier_spacing;//
+  uint8_t  cyclic_prefix;//
+  uint16_t start_rb;
+  uint16_t nr_of_rbs;
+  uint8_t  csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP
+  uint8_t  row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18
+  uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter
+  uint8_t  symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13
+  uint8_t  symb_l1;//
+  uint8_t  cdm_type;
+  uint8_t  freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three
+  uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023
+} fapi_nr_dl_config_csirs_pdu_rel15_t;
+
+
+typedef struct {
+  uint16_t bwp_size;
+  uint16_t bwp_start;
+  uint8_t  subcarrier_spacing;
+  uint16_t start_rb;
+  uint16_t nr_of_rbs;
+  uint8_t k_csiim[4];
+  uint8_t l_csiim[4];
+} fapi_nr_dl_config_csiim_pdu_rel15_t;
+
+
+typedef struct {
+  fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_rel15;
+} fapi_nr_dl_config_csirs_pdu;
+
+
+typedef struct {
+  fapi_nr_dl_config_csiim_pdu_rel15_t csiim_config_rel15;
+} fapi_nr_dl_config_csiim_pdu;
+
+
 typedef struct {
   uint8_t pdu_type;
   union {
     fapi_nr_dl_config_dci_pdu dci_config_pdu;
     fapi_nr_dl_config_dlsch_pdu dlsch_config_pdu;
+    fapi_nr_dl_config_csirs_pdu csirs_config_pdu;
+    fapi_nr_dl_config_csiim_pdu csiim_config_pdu;
   };
 } fapi_nr_dl_config_request_pdu_t;
 
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index 30eae2d30f511255e56bef6783b2f116c2e626a9..7281f8e29074f2fb7c1b038c41ab0e9856ac9ef6 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -642,6 +642,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 unsigned short p,
                                 unsigned char symbol,
                                 unsigned short BWPStart,
+                                uint8_t config_type,
                                 unsigned short bwp_start_subcarrier,
                                 unsigned short nb_rb_pdsch)
 {
@@ -653,10 +654,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int16_t *fl=NULL,*fm=NULL,*fr=NULL,*fml=NULL,*fmr=NULL,*fmm=NULL,*fdcl=NULL,*fdcr=NULL,*fdclh=NULL,*fdcrh=NULL, *frl=NULL, *frr=NULL;
   int ch_offset,symbol_offset;
 
-  NR_UE_DLSCH_t  **dlsch = ue->dlsch[proc->thread_id][gNB_id];
-  const unsigned char harq_pid = dlsch[0]->current_harq_pid;
-  NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-
   uint8_t nushift;
   int **dl_ch_estimates  =ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates;
   int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
@@ -678,7 +675,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   if (is_SI) {
     rb_offset -= BWPStart;
   }
-  uint8_t config_type = dlsch0_harq->dmrsConfigType;
   int8_t delta = get_delta(p, config_type);
 
   // checking if re-initialization of scrambling IDs is needed
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index c5330ce2f2e7e2a98f3d77591046f4ea8bb6cc84..4dec92143a10799ac41aa946c3a199dd6fe2b947 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -72,6 +72,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 unsigned short p,
                                 unsigned char symbol,
                                 unsigned short BWPStart,
+                                uint8_t config_type,
                                 unsigned short bwp_start_subcarrier,
                                 unsigned short nb_rb_pdsch);
 
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 9aa84b6704f41b3b68c861e9a84c49715765f018..8af91b1f386508b33d6b41cfaa17c8bf36a0c074 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -214,6 +214,59 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
   return 0;
 }
 
+
+void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
+                     fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
+                     module_id_t module_id,
+                     int rnti) {
+
+  const uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
+  dlsch0->current_harq_pid = current_harq_pid;
+  dlsch0->active = 1;
+  dlsch0->rnti = rnti;
+
+  LOG_D(PHY,"current_harq_pid = %d\n", current_harq_pid);
+
+  NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
+  AssertFatal(dlsch0_harq, "no harq_process for HARQ PID %d\n", current_harq_pid);
+
+  dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
+  dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
+  dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
+  dlsch0_harq->start_rb = dlsch_config_pdu->start_rb;
+  dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols;
+  dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
+  dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
+  dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
+  dlsch0_harq->n_dmrs_cdm_groups = dlsch_config_pdu->n_dmrs_cdm_groups;
+  dlsch0_harq->dmrs_ports = dlsch_config_pdu->dmrs_ports;
+  dlsch0_harq->mcs = dlsch_config_pdu->mcs;
+  dlsch0_harq->rvidx = dlsch_config_pdu->rv;
+  dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
+  //get nrOfLayers from DCI info
+  uint8_t Nl = 0;
+  for (int i = 0; i < 12; i++) { // max 12 ports
+    if ((dlsch_config_pdu->dmrs_ports>>i)&0x01) Nl += 1;
+  }
+  dlsch0_harq->Nl = Nl;
+  dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
+  downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch_config_pdu->rv, dlsch0->rnti_type);
+  if (dlsch0_harq->status != ACTIVE) {
+    // dlsch0_harq->status not ACTIVE due to false retransmission
+    // Reset the following flag to skip PDSCH procedures in that case and retrasmit harq status
+    dlsch0->active = 0;
+    update_harq_status(module_id,dlsch0->current_harq_pid,dlsch0_harq->ack);
+  }
+  /* PTRS */
+  dlsch0_harq->PTRSFreqDensity = dlsch_config_pdu->PTRSFreqDensity;
+  dlsch0_harq->PTRSTimeDensity = dlsch_config_pdu->PTRSTimeDensity;
+  dlsch0_harq->PTRSPortIndex = dlsch_config_pdu->PTRSPortIndex;
+  dlsch0_harq->nEpreRatioOfPDSCHToPTRS = dlsch_config_pdu->nEpreRatioOfPDSCHToPTRS;
+  dlsch0_harq->PTRSReOffset = dlsch_config_pdu->PTRSReOffset;
+  dlsch0_harq->pduBitmap = dlsch_config_pdu->pduBitmap;
+  LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs);
+}
+
 int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
   bool found = false;
@@ -221,7 +274,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
     module_id_t module_id = scheduled_response->module_id;
     uint8_t cc_id = scheduled_response->CC_id, thread_id;
-    uint32_t i;
     int slot = scheduled_response->slot;
 
     // Note: we have to handle the thread IDs for this. To be revisited completely.
@@ -233,89 +285,53 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
 
     if(scheduled_response->dl_config != NULL){
       fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
-
+      fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu;
+      fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config;
       pdcch_vars->nb_search_space = 0;
 
-      for (i = 0; i < dl_config->number_pdus; ++i){
+      for (int i = 0; i < dl_config->number_pdus; ++i){
         AssertFatal(dl_config->number_pdus < FAPI_NR_DL_CONFIG_LIST_NUM,"dl_config->number_pdus %d out of bounds\n",dl_config->number_pdus);
         AssertFatal(dl_config->dl_config_list[i].pdu_type<=FAPI_NR_DL_CONFIG_TYPES,"pdu_type %d > 2\n",dl_config->dl_config_list[i].pdu_type);
         LOG_D(PHY, "In %s: frame %d slot %d received 1 DL %s PDU of %d total DL PDUs:\n",
               __FUNCTION__, scheduled_response->frame, slot, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus);
 
-        if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) {
-
-          fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
-          memcpy((void*)&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config));
-          pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1;
-          pdcch_vars->sfn = scheduled_response->frame;
-          pdcch_vars->slot = slot;
-          LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space);
-
-        } else {
-
-          fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
-          uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
-
-          if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DLSCH){
-            dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
-          }
-          else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){
+        switch(dl_config->dl_config_list[i].pdu_type) {
+          case FAPI_NR_DL_CONFIG_TYPE_DCI:
+            pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15;
+            memcpy(&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],pdcch_config,sizeof(*pdcch_config));
+            pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1;
+            pdcch_vars->sfn = scheduled_response->frame;
+            pdcch_vars->slot = slot;
+            LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space);
+            break;
+          case FAPI_NR_DL_CONFIG_TYPE_CSI_IM:
+            LOG_I(PHY,"Received CSI-IM PDU at FAPI\n");
+            break;
+          case FAPI_NR_DL_CONFIG_TYPE_CSI_RS:
+            LOG_I(PHY,"Received CSI-RS PDU at FAPI\n");
+            break;
+          case FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH:
+            dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
             dlsch0->rnti_type = _RA_RNTI_;
-            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
-          }
-          else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){
+            dlsch0->harq_processes[dlsch_config_pdu->harq_process_nbr]->status = ACTIVE;
+            configure_dlsch(dlsch0, dlsch_config_pdu, module_id,
+                            dl_config->dl_config_list[i].dlsch_config_pdu.rnti);
+            break;
+          case FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH:
+            dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
             dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0];
             dlsch0->rnti_type = _SI_RNTI_;
-            dlsch0->harq_processes[current_harq_pid]->status = ACTIVE;
-          }
-
-          dlsch0->current_harq_pid = current_harq_pid;
-          dlsch0->active = 1;
-          dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
-
-          LOG_D(PHY,"slot %d current_harq_pid = %d\n",slot, current_harq_pid);
-
-          NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
-          if (dlsch0_harq){
-
-            dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
-            dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
-            dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
-            dlsch0_harq->start_rb = dlsch_config_pdu->start_rb;
-            dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols;
-            dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
-            dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
-            dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
-            dlsch0_harq->n_dmrs_cdm_groups = dlsch_config_pdu->n_dmrs_cdm_groups;
-            dlsch0_harq->dmrs_ports = dlsch_config_pdu->dmrs_ports;
-            dlsch0_harq->mcs = dlsch_config_pdu->mcs;
-            dlsch0_harq->rvidx = dlsch_config_pdu->rv;
-            dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
-            //get nrOfLayers from DCI info
-            uint8_t Nl = 0;
-            for (i = 0; i < 12; i++) { // max 12 ports
-              if ((dlsch_config_pdu->dmrs_ports>>i)&0x01) Nl += 1;
-            }
-            dlsch0_harq->Nl = Nl;
-            dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
-            downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch_config_pdu->rv, dlsch0->rnti_type);
-            if (dlsch0_harq->status != ACTIVE) {
-              // dlsch0_harq->status not ACTIVE due to false retransmission
-              // Reset the following flag to skip PDSCH procedures in that case and retrasmit harq status
-              dlsch0->active = 0;
-              update_harq_status(module_id,dlsch0->current_harq_pid,dlsch0_harq->ack);
-            }
-            /* PTRS */
-            dlsch0_harq->PTRSFreqDensity = dlsch_config_pdu->PTRSFreqDensity;
-            dlsch0_harq->PTRSTimeDensity = dlsch_config_pdu->PTRSTimeDensity;
-            dlsch0_harq->PTRSPortIndex = dlsch_config_pdu->PTRSPortIndex;
-            dlsch0_harq->nEpreRatioOfPDSCHToPTRS = dlsch_config_pdu->nEpreRatioOfPDSCHToPTRS;
-            dlsch0_harq->PTRSReOffset = dlsch_config_pdu->PTRSReOffset;
-            dlsch0_harq->pduBitmap = dlsch_config_pdu->pduBitmap;
-            LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n",
-                  dlsch0->g_pucch, dlsch0_harq->mcs);
-          }
+            dlsch0->harq_processes[dlsch_config_pdu->harq_process_nbr]->status = ACTIVE;
+            configure_dlsch(dlsch0, dlsch_config_pdu, module_id,
+                            dl_config->dl_config_list[i].dlsch_config_pdu.rnti);
+            break;
+          case FAPI_NR_DL_CONFIG_TYPE_DLSCH:
+            dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
+            dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
+            configure_dlsch(dlsch0, dlsch_config_pdu, module_id,
+                            dl_config->dl_config_list[i].dlsch_config_pdu.rnti);
+            break;
         }
       }
       dl_config->number_pdus = 0;
@@ -326,9 +342,9 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
       fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config;
       int pdu_done = 0;
       pthread_mutex_lock(&ul_config->mutex_ul_config);
-      LOG_D(PHY, "%d.%d ul S ul_config %p pdu_done %d number_pdus %d\n", scheduled_response->frame, slot, ul_config, pdu_done, ul_config->number_pdus);
 
-      for (i = 0; i < ul_config->number_pdus; ++i){
+      LOG_D(PHY, "%d.%d ul S ul_config %p pdu_done %d number_pdus %d\n", scheduled_response->frame, slot, ul_config, pdu_done, ul_config->number_pdus);
+      for (int i = 0; i < ul_config->number_pdus; ++i){
 
         AssertFatal(ul_config->ul_config_list[i].pdu_type <= FAPI_NR_UL_CONFIG_TYPES,"pdu_type %d out of bounds\n",ul_config->ul_config_list[i].pdu_type);
         LOG_D(PHY, "In %s: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config);
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index a058ffaa2a2562c1d6bd0d2a9e252b004de4bce4..0d284de71c4541df679fa05b376e207cd1616138 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -576,6 +576,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
                                       get_dmrs_port(aatx,dlsch0_harq->dmrs_ports),
                                       m,
                                       BWPStart,
+                                      dlsch0_harq->dmrsConfigType,
                                       ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12,
                                       pdsch_nb_rb);
 #if 0
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 144ef56d4ca0a63845106bb1a9949f7cf0f7426f..94b7ab18bfda7e0f9b0a08240bc09204814151e6 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -3337,65 +3337,65 @@ uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i
 
 
 void csi_period_offset(NR_CSI_ReportConfig_t *csirep,
-                       NR_NZP_CSI_RS_Resource_t *nzpcsi,
+                       struct NR_CSI_ResourcePeriodicityAndOffset *periodicityAndOffset,
                        int *period, int *offset) {
 
-  if(nzpcsi != NULL) {
+  if(periodicityAndOffset != NULL) {
 
-    NR_CSI_ResourcePeriodicityAndOffset_PR p_and_o = nzpcsi->periodicityAndOffset->present;
+    NR_CSI_ResourcePeriodicityAndOffset_PR p_and_o = periodicityAndOffset->present;
 
     switch(p_and_o){
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots4:
         *period = 4;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots4;
+        *offset = periodicityAndOffset->choice.slots4;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots5:
         *period = 5;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots5;
+        *offset = periodicityAndOffset->choice.slots5;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots8:
         *period = 8;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots8;
+        *offset = periodicityAndOffset->choice.slots8;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots10:
         *period = 10;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots10;
+        *offset = periodicityAndOffset->choice.slots10;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots16:
         *period = 16;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots16;
+        *offset = periodicityAndOffset->choice.slots16;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots20:
         *period = 20;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots20;
+        *offset = periodicityAndOffset->choice.slots20;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots32:
         *period = 32;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots32;
+        *offset = periodicityAndOffset->choice.slots32;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots40:
         *period = 40;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots40;
+        *offset = periodicityAndOffset->choice.slots40;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots64:
         *period = 64;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots64;
+        *offset = periodicityAndOffset->choice.slots64;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots80:
         *period = 80;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots80;
+        *offset = periodicityAndOffset->choice.slots80;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots160:
         *period = 160;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots160;
+        *offset = periodicityAndOffset->choice.slots160;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots320:
         *period = 320;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots320;
+        *offset = periodicityAndOffset->choice.slots320;
         break;
       case NR_CSI_ResourcePeriodicityAndOffset_PR_slots640:
         *period = 640;
-        *offset = nzpcsi->periodicityAndOffset->choice.slots640;
+        *offset = periodicityAndOffset->choice.slots640;
         break;
     default:
       AssertFatal(1==0,"No periodicity and offset found in CSI resource");
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 29ac20b29724e842972f399a753e1ce3e797b52a..c150c4f134aecb73181bb89c789b8b94e941c7b1 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -161,7 +161,7 @@ int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
 void find_period_offest_SR (NR_SchedulingRequestResourceConfig_t *SchedulingReqRec, int *period, int *offset);
 
 void csi_period_offset(NR_CSI_ReportConfig_t *csirep,
-                       NR_NZP_CSI_RS_Resource_t *nzpcsi,
+                       struct NR_CSI_ResourcePeriodicityAndOffset *periodicityAndOffset,
                        int *period, int *offset);
 
 void reverse_n_bits(uint8_t *value, uint16_t bitlen);
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index c814ed16b907313d84314cd07360c5873ccea148..3e4d53b985be0ae4270287fed9ef0e5d7ec2e4e4 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -214,6 +214,7 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
 
 uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
                            PUCCH_sched_t *pucch,
+                           int csi_report_id,
                            NR_CSI_MeasConfig_t *csi_MeasConfig);
 
 uint8_t get_rsrp_index(int rsrp);
@@ -351,6 +352,8 @@ and fills the PRACH PDU per each FD occasion.
 */
 void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, int thread_id);
 void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, int thread_id);
+void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot);
+void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot);
 
 /* \brief This function schedules the Msg3 transmission
 @param
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index bd8b2816ac1bc55b881f672e5aa307c833a2ddb2..c57736990c79425db127df3bad2ea5df72d5069b 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -2403,7 +2403,7 @@ uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac,
                       "CSI resource not found among PUCCH resources\n");
 
           pucch->resource_indicator = found;
-          csi_bits = nr_get_csi_payload(mac, pucch, csi_measconfig);
+          csi_bits += nr_get_csi_payload(mac, pucch, csi_report_id, csi_measconfig);
         }
       }
       else
@@ -2417,31 +2417,30 @@ uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac,
 
 uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
                            PUCCH_sched_t *pucch,
+                           int csi_report_id,
                            NR_CSI_MeasConfig_t *csi_MeasConfig) {
 
   int n_csi_bits = 0;
 
   AssertFatal(csi_MeasConfig->csi_ReportConfigToAddModList->list.count>0,"No CSI Report configuration available\n");
 
-  for (int csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
-    struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
-    NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
-    switch(csi_reportconfig->reportQuantity.present) {
-      case NR_CSI_ReportConfig__reportQuantity_PR_none:
-        break;
-      case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
-        n_csi_bits += get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
-        break;
-      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
-      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
-      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
-      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
-      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
-      case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
-        AssertFatal(1==0,"Measurement report based on CSI-RS not availalble\n");
-      default:
-        AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
-    }
+  struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
+  NR_CSI_ResourceConfigId_t csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
+  switch(csi_reportconfig->reportQuantity.present) {
+    case NR_CSI_ReportConfig__reportQuantity_PR_none:
+      break;
+    case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
+      n_csi_bits = get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig);
+      break;
+    case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
+    case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI:
+    case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1:
+    case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
+    case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
+    case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
+      AssertFatal(1==0,"Measurement report based on CSI-RS not availalble\n");
+    default:
+      AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
   }
   return (n_csi_bits);
 }
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index 7e469c675adc1152d81163e07e9175312ddb6f79..e1058e1173fe901cf0cd9ad86866ad22ea3e0bca 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -1046,6 +1046,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
     nr_dcireq_t dcireq;
 
     if(mac->cg != NULL){ // we have a cg
+
+      nr_schedule_csirs_reception(mac, rx_frame, rx_slot);
+      nr_schedule_csi_for_im(mac, rx_frame, rx_slot);
+
       dcireq.module_id = mod_id;
       dcireq.gNB_index = gNB_index;
       dcireq.cc_id     = cc_id;
@@ -2307,7 +2311,6 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
     return;
 
   if (N_UCI > 0) {
-
     LOG_D(NR_MAC,"%d.%d configure pucch, O_SR %d, O_ACK %d, O_CSI %d\n",frameP,slotP,O_SR,O_ACK,O_CSI);
     pucch->resource_set_id = find_pucch_resource_set(mac, O_ACK + O_CSI);
     select_pucch_resource(mac, pucch);
@@ -2331,9 +2334,206 @@ void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, in
     if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
       mac->if_module->scheduled_response(&scheduled_response);
   }
+}
+
+
+void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) {
+
+  if (mac->ra.ra_state != RA_SUCCEEDED && get_softmodem_params()->phy_test == 0)
+    return;
 
+  NR_CellGroupConfig_t *CellGroup = mac->cg;
+
+  if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated ||
+      !CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig)
+    return;
+
+  NR_CSI_MeasConfig_t *csi_measconfig = CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
+
+  if (csi_measconfig->csi_IM_ResourceToAddModList == NULL)
+    return;
+
+  fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
+  NR_CSI_IM_Resource_t *imcsi;
+  int period, offset;
+  NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id;
+  int mu = mac->DLbwp[dl_bwp_id-1] ?
+    mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing :
+    mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing;
+
+  for (int id = 0; id < csi_measconfig->csi_IM_ResourceToAddModList->list.count; id++){
+    imcsi = csi_measconfig->csi_IM_ResourceToAddModList->list.array[id];
+    csi_period_offset(NULL,imcsi->periodicityAndOffset,&period,&offset);
+    if((frame*nr_slots_per_frame[mu]+slot-offset)%period != 0)
+      continue;
+    fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csiim_config_pdu.csiim_config_rel15;
+    const NR_BWP_Downlink_t *dlbwp = mac->DLbwp[dl_bwp_id-1];
+    const int locationAndBandwidth = dlbwp != NULL ? dlbwp->bwp_Common->genericParameters.locationAndBandwidth:
+                                     mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth;
+    csiim_config_pdu->bwp_size = NRRIV2BW(locationAndBandwidth, MAX_BWP_SIZE);
+    csiim_config_pdu->bwp_start = NRRIV2PRBOFFSET(locationAndBandwidth, MAX_BWP_SIZE);
+    csiim_config_pdu->subcarrier_spacing = mu;
+    csiim_config_pdu->start_rb = imcsi->freqBand->startingRB;
+    csiim_config_pdu->nr_of_rbs = imcsi->freqBand->nrofRBs;
+    // As specified in 5.2.2.4 of 38.214
+    switch (imcsi->csi_IM_ResourceElementPattern->present) {
+      case NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern0:
+        for (int i = 0; i<4; i++) {
+          csiim_config_pdu->k_csiim[i] = (imcsi->csi_IM_ResourceElementPattern->choice.pattern0->subcarrierLocation_p0<<1) + (i>>1);
+          csiim_config_pdu->l_csiim[i] = imcsi->csi_IM_ResourceElementPattern->choice.pattern0->symbolLocation_p0 + (i%2);
+        }
+        break;
+      case NR_CSI_IM_Resource__csi_IM_ResourceElementPattern_PR_pattern1:
+        for (int i = 0; i<4; i++) {
+          csiim_config_pdu->k_csiim[i] = (imcsi->csi_IM_ResourceElementPattern->choice.pattern1->subcarrierLocation_p1<<2) + i;
+          csiim_config_pdu->l_csiim[i] = imcsi->csi_IM_ResourceElementPattern->choice.pattern1->symbolLocation_p1;
+        }
+        break;
+      default:
+        AssertFatal(1==0, "Invalid CSI-IM pattern\n");
+    }
+    dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_IM;
+    dl_config->number_pdus = dl_config->number_pdus + 1;
+  }
 }
 
+void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) {
+
+  if (mac->ra.ra_state != RA_SUCCEEDED && get_softmodem_params()->phy_test == 0)
+    return;
+
+  NR_CellGroupConfig_t *CellGroup = mac->cg;
+
+  if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated ||
+      !CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig)
+    return;
+
+  NR_CSI_MeasConfig_t *csi_measconfig = CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
+
+  if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList == NULL)
+    return;
+
+  fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
+  NR_NZP_CSI_RS_Resource_t *nzpcsi;
+  int period, offset;
+  NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id;
+  int mu = mac->DLbwp[dl_bwp_id-1] ?
+    mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing :
+    mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing;
+
+  for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){
+    nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id];
+    csi_period_offset(NULL,nzpcsi->periodicityAndOffset,&period,&offset);
+    if((frame*nr_slots_per_frame[mu]+slot-offset)%period != 0)
+      continue;
+    LOG_D(MAC,"Scheduling reception of CSI-RS in frame %d slot %d\n",frame,slot);
+    fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csirs_config_pdu.csirs_config_rel15;
+
+    NR_CSI_RS_ResourceMapping_t  resourceMapping = nzpcsi->resourceMapping;
+
+    const NR_BWP_Downlink_t *dlbwp = mac->DLbwp[dl_bwp_id-1];
+    const int locationAndBandwidth = dlbwp != NULL ? dlbwp->bwp_Common->genericParameters.locationAndBandwidth:
+                                     mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth;
+    csirs_config_pdu->bwp_size = NRRIV2BW(locationAndBandwidth, MAX_BWP_SIZE);
+    csirs_config_pdu->bwp_start = NRRIV2PRBOFFSET(locationAndBandwidth, MAX_BWP_SIZE);
+    csirs_config_pdu->subcarrier_spacing = mu;
+    csirs_config_pdu->start_rb = resourceMapping.freqBand.startingRB;
+    csirs_config_pdu->nr_of_rbs = resourceMapping.freqBand.nrofRBs;
+    csirs_config_pdu->csi_type = 1; // NZP-CSI-RS
+    csirs_config_pdu->symb_l0 = resourceMapping.firstOFDMSymbolInTimeDomain;
+    if (resourceMapping.firstOFDMSymbolInTimeDomain2)
+      csirs_config_pdu->symb_l1 = *resourceMapping.firstOFDMSymbolInTimeDomain2;
+    csirs_config_pdu->cdm_type = resourceMapping.cdm_Type;
+    csirs_config_pdu->freq_density = resourceMapping.density.present;
+    if ((resourceMapping.density.present == NR_CSI_RS_ResourceMapping__density_PR_dot5)
+        && (resourceMapping.density.choice.dot5 == NR_CSI_RS_ResourceMapping__density__dot5_evenPRBs))
+      csirs_config_pdu->freq_density--;
+    csirs_config_pdu->scramb_id = nzpcsi->scramblingID;
+    switch(resourceMapping.frequencyDomainAllocation.present){
+      case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1:
+        csirs_config_pdu->row = 1;
+        csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f;
+        break;
+      case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
+        csirs_config_pdu->row = 2;
+        csirs_config_pdu->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) |
+                                        ((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<4)&0xff0));
+        break;
+      case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4:
+        csirs_config_pdu->row = 4;
+        csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07;
+        break;
+      case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other:
+        csirs_config_pdu->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f;
+        // determining the row of table 7.4.1.5.3-1 in 38.211
+        switch(resourceMapping.nrofPorts){
+          case NR_CSI_RS_ResourceMapping__nrofPorts_p1:
+            AssertFatal(1==0,"Resource with 1 CSI port shouldn't be within other rows\n");
+            break;
+          case NR_CSI_RS_ResourceMapping__nrofPorts_p2:
+            csirs_config_pdu->row = 3;
+            break;
+          case NR_CSI_RS_ResourceMapping__nrofPorts_p4:
+            csirs_config_pdu->row = 5;
+            break;
+          case NR_CSI_RS_ResourceMapping__nrofPorts_p8:
+            if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2)
+              csirs_config_pdu->row = 8;
+            else{
+              int num_k = 0;
+              for (int k=0; k<6; k++)
+                num_k+=(((csirs_config_pdu->freq_domain)>>k)&0x01);
+              if(num_k==4)
+                csirs_config_pdu->row = 6;
+              else
+                csirs_config_pdu->row = 7;
+            }
+            break;
+          case NR_CSI_RS_ResourceMapping__nrofPorts_p12:
+            if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2)
+              csirs_config_pdu->row = 10;
+            else
+              csirs_config_pdu->row = 9;
+            break;
+          case NR_CSI_RS_ResourceMapping__nrofPorts_p16:
+            if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2)
+              csirs_config_pdu->row = 12;
+            else
+              csirs_config_pdu->row = 11;
+            break;
+          case NR_CSI_RS_ResourceMapping__nrofPorts_p24:
+            if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2)
+              csirs_config_pdu->row = 14;
+            else{
+              if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4)
+                csirs_config_pdu->row = 15;
+              else
+                csirs_config_pdu->row = 13;
+            }
+            break;
+          case NR_CSI_RS_ResourceMapping__nrofPorts_p32:
+            if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2)
+              csirs_config_pdu->row = 17;
+            else{
+              if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4)
+                csirs_config_pdu->row = 18;
+              else
+                csirs_config_pdu->row = 16;
+            }
+            break;
+        default:
+          AssertFatal(1==0,"Invalid number of ports in CSI-RS resource\n");
+        }
+        break;
+      default:
+        AssertFatal(1==0,"Invalid freqency domain allocation in CSI-RS resource\n");
+    }
+    dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_RS;
+    dl_config->number_pdus = dl_config->number_pdus + 1;
+  }
+}
+
+
 // This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x
 // PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3.
 // - todo:
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 938b9f2584c0096f084a7138876e0e187ec217c5..dbfaf7ac76ef4daf692140631fae398f67997926 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -2491,11 +2491,11 @@ void nr_csirs_scheduling(int Mod_idP,
       for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){
         nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id];
         NR_CSI_RS_ResourceMapping_t  resourceMapping = nzpcsi->resourceMapping;
-        csi_period_offset(NULL,nzpcsi,&period,&offset);
+        csi_period_offset(NULL,nzpcsi->periodicityAndOffset,&period,&offset);
 
         if((frame*n_slots_frame+slot-offset)%period == 0) {
 
-          LOG_I(MAC,"Scheduling CSI-RS in frame %d slot %d\n",frame,slot);
+          LOG_D(MAC,"Scheduling CSI-RS in frame %d slot %d\n",frame,slot);
 
           nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
           memset((void*)dl_tti_csirs_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -2539,7 +2539,7 @@ void nr_csirs_scheduling(int Mod_idP,
             case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
               csirs_pdu_rel15->row = 2;
               csirs_pdu_rel15->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) |
-                                             ((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<8)&0xff0));
+                                             ((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<4)&0xff0));
               for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
                 vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
               break;
@@ -2554,6 +2554,7 @@ void nr_csirs_scheduling(int Mod_idP,
               // determining the row of table 7.4.1.5.3-1 in 38.211
               switch(resourceMapping.nrofPorts){
                 case NR_CSI_RS_ResourceMapping__nrofPorts_p1:
+                  AssertFatal(1==0,"Resource with 1 CSI port shouldn't be within other rows\n");
                   break;
                 case NR_CSI_RS_ResourceMapping__nrofPorts_p2:
                   csirs_pdu_rel15->row = 3;
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index b4938404bd5b51853f3777907d33d51d85173d66..6130cd256d77ae1da10b8e616c1e97cf447a86b0 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -1335,17 +1335,17 @@ void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
        resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
        resourceMapping.frequencyDomainAllocation.choice.row2.size = 2;
        resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 4;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]=0;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]=16;
+       resourceMapping.frequencyDomainAllocation.choice.row2.buf[0] = 0;
+       resourceMapping.frequencyDomainAllocation.choice.row2.buf[1] = 16;
        resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p1;
        resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_noCDM;
        break;
      case 2:
        resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf = calloc(2, sizeof(uint8_t));
-       resourceMapping.frequencyDomainAllocation.choice.row2.size = 1;
-       resourceMapping.frequencyDomainAllocation.choice.row2.bits_unused = 2;
-       resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]=4;
+       resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(2, sizeof(uint8_t));
+       resourceMapping.frequencyDomainAllocation.choice.other.size = 1;
+       resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2;
+       resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 4;
        resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p2;
        resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2;
        break;