diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 077302b207..ac2b7e21f6 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -381,6 +381,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) } } + ue->nr_csi_im_info = (nr_csi_im_info_t *)malloc16_clear(sizeof(nr_csi_im_info_t)); + ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); ue->nr_srs_info->sc_list = (uint16_t *) malloc16_clear(6*fp->N_RB_UL*sizeof(uint16_t)); ue->nr_srs_info->srs_generated_signal = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); @@ -530,6 +532,8 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq); free_and_zero(ue->nr_csi_rs_info); + free_and_zero(ue->nr_csi_im_info); + for (int i = 0; i < fp->nb_antennas_rx; i++) { free_and_zero(ue->nr_srs_info->srs_received_signal[i]); free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel[i]); diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index 719d8e11b4..e9baf7e722 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -600,6 +600,80 @@ int nr_csi_rs_cqi_estimation(uint32_t precoded_sinr, return 0; } +int nr_csi_im_power_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu, + uint32_t *interference_plus_noise_power) { + + int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; + NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + + uint16_t end_rb = csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs > csiim_config_pdu->bwp_size ? + csiim_config_pdu->bwp_size : csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs; + + int32_t count = 0; + int32_t sum_re = 0; + int32_t sum_im = 0; + int32_t sum2_re = 0; + int32_t sum2_im = 0; + + int l_csiim[4] = {-1, -1, -1, -1}; + + for(int symb_idx = 0; symb_idx < 4; symb_idx++) { + + uint8_t symb = csiim_config_pdu->l_csiim[symb_idx]; + bool done = false; + for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) { + if (l_csiim[symb_idx2] == symb) { + done = true; + } + } + + if (done) { + continue; + } + + l_csiim[symb_idx] = symb; + uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; + + for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { + + c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset]; + + for (int rb = csiim_config_pdu->start_rb; rb < end_rb; rb++) { + + uint16_t sc0_offset = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; + + for (int sc_idx = 0; sc_idx<4; sc_idx++) { + + uint16_t sc = sc0_offset + csiim_config_pdu->k_csiim[sc_idx]; + +#ifdef NR_CSIIM_DEBUG + LOG_I(NR_PHY, "(ant_rx %i, sc %i) real %i, imag %i\n", ant_rx, rb, rx_signal[sc].r, rx_signal[sc].i); +#endif + + sum_re += rx_signal[sc].r; + sum_im += rx_signal[sc].i; + sum2_re += rx_signal[sc].r*rx_signal[sc].r; + sum2_im += rx_signal[sc].i*rx_signal[sc].i; + count++; + } + } + } + } + + int32_t power_re = sum2_re/count - (sum_re/count)*(sum_re/count); + int32_t power_im = sum2_im/count - (sum_im/count)*(sum_im/count); + + *interference_plus_noise_power = power_re + power_im; + +#ifdef NR_CSIIM_DEBUG + LOG_I(NR_PHY, "interference_plus_noise_power based on CSI-IM = %i\n", *interference_plus_noise_power); +#endif + + return 0; +} + int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { if(!ue->csiim_vars[gNB_id]->active) { @@ -618,6 +692,8 @@ int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t LOG_I(NR_PHY, "csiim_config_pdu->l_csiim = %i.%i.%i.%i\n", csiim_config_pdu->l_csiim[0], csiim_config_pdu->l_csiim[1], csiim_config_pdu->l_csiim[2], csiim_config_pdu->l_csiim[3]); #endif + nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_im_info->interference_plus_noise_power); + return 0; } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index bd6808c54d..0c8dcc195c 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -881,6 +881,9 @@ typedef struct { /// CSI-RS variables nr_csi_rs_info_t *nr_csi_rs_info; + /// CSI-IM variables + nr_csi_im_info_t *nr_csi_im_info; + //#if defined(UPGRADE_RAT_NR) #if 1 SystemInformationBlockType1_nr_t systemInformationBlockType1_nr; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index a94bb30787..1d23e48a3b 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -284,6 +284,10 @@ typedef struct { uint8_t *cqi; } nr_csi_rs_info_t; +typedef struct { + uint32_t interference_plus_noise_power; +} nr_csi_im_info_t; + typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; typedef uint32_t (*get_samples_per_slot_t)(int slot, NR_DL_FRAME_PARMS* fp);