diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index f48e1101eb..7541d14436 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -37,12 +37,12 @@ #define I0_SKIP_DC 1 int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, - const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) + const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size]) { int timing_advance = 0; int max_val = 0; - for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { + for (int i = 0; i < NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size; i++) { int temp = 0; for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { int Re = ((c16_t*)srs_estimated_channel_time[aa])[i].r; @@ -55,9 +55,10 @@ int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, } } - if (timing_advance > frame_parms->ofdm_symbol_size/2) { - timing_advance = timing_advance - frame_parms->ofdm_symbol_size; + if (timing_advance > (NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size) / 2) { + timing_advance = timing_advance - (NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size); } + timing_advance = timing_advance / NR_SRS_IDFT_OVERSAMP_FACTOR; LOG_I(NR_PHY, "Estimated SRS ToA %d\n", timing_advance); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 5cb60f28b3..0906321e87 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -780,8 +780,8 @@ int nr_srs_channel_estimation(int ant, c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS], c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS], c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS], - c16_t srs_estimated_channel_time[ofdm_symbol_size], - c16_t srs_estimated_channel_time_shifted[ofdm_symbol_size], + c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], uint32_t *signal_power, uint32_t *noise_power, int16_t *noise_power_per_rb) @@ -959,15 +959,27 @@ int nr_srs_channel_estimation(int ant, #endif // Convert to time domain - freq2time(ofdm_symbol_size, (int16_t *)srs_estimated_channel_freq, (int16_t *)srs_estimated_channel_time); + int16_t ofdm_symbol_size_half = ofdm_symbol_size >> 1; + int16_t ofdm_os_size = NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size; + int16_t ofdm_os_size_half = ofdm_os_size >> 1; + int16_t start_offset = ofdm_os_size - ofdm_symbol_size_half; - memcpy(srs_estimated_channel_time_shifted, - &srs_estimated_channel_time[ofdm_symbol_size >> 1], - (ofdm_symbol_size >> 1) * sizeof(c16_t)); + c16_t chF_interpol[ofdm_os_size] __attribute__((aligned(32))); + memset(chF_interpol, 0, sizeof(chF_interpol)); - memcpy(&srs_estimated_channel_time_shifted[ofdm_symbol_size >> 1], - srs_estimated_channel_time, - (ofdm_symbol_size >> 1) * sizeof(c16_t)); + // Place SRS channel estimates in FFT shifted format for oversampling + memcpy(&chF_interpol[0], &srs_estimated_channel_freq[0], ofdm_symbol_size_half * sizeof(c16_t)); + memcpy(&chF_interpol[start_offset], + &srs_estimated_channel_freq[ofdm_symbol_size_half], + ofdm_symbol_size_half * sizeof(c16_t)); + + // Convert to time domain oversampled + freq2time(ofdm_os_size, (int16_t *)chF_interpol, (int16_t *)srs_estimated_channel_time); + + // Do FFT shift + memcpy(srs_estimated_channel_time_shifted, &srs_estimated_channel_time[ofdm_os_size_half], ofdm_os_size_half * sizeof(c16_t)); + + memcpy(&srs_estimated_channel_time_shifted[ofdm_os_size_half], srs_estimated_channel_time, ofdm_os_size_half * sizeof(c16_t)); // Compute wideband SNR int tot_subcarriers = m_SRS_b * NR_NB_SC_PER_RB; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index 4df2b47a17..f04fde7b1b 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -59,8 +59,9 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]); -int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, - const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]); +int nr_est_timing_advance_srs( + const NR_DL_FRAME_PARMS *frame_parms, + const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size]); void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *frame_parms, @@ -81,8 +82,8 @@ int nr_srs_channel_estimation(int ant, c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS], c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS], c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS], - c16_t srs_estimated_channel_time[ofdm_symbol_size], - c16_t srs_estimated_channel_time_shifted[ofdm_symbol_size], + c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], + c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], uint32_t *signal_power, uint32_t *noise_power, int16_t *noise_power_per_rb); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 1a0fabf14e..b01361ec8d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -242,7 +242,7 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB, nr_srs_info_t *nr_srs_info, int *srs_est, c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS], - c16_t srs_estimated_channel_time[][N_ap][ofdm_symbol_size], + c16_t srs_estimated_channel_time[][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], int16_t *snr_per_rb); int get_nr_prach_duration(uint8_t prach_format); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index abc700f9d2..5710b24105 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -46,6 +46,7 @@ #define MAX_NUM_RU_PER_gNB 8 #define MAX_PUCCH0_NID 8 +#define NR_SRS_IDFT_OVERSAMP_FACTOR 2 typedef struct { int nb_id; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index d25d8aace6..1b04f63950 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -868,14 +868,14 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB, nr_srs_info_t *nr_srs_info, int *srs_est, c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS], - c16_t srs_estimated_channel_time[][N_ap][ofdm_symbol_size], + c16_t srs_estimated_channel_time[][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size], int16_t *snr_per_rb) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; c16_t srs_received_signal[nb_antennas_rx][ofdm_symbol_size * N_symb_SRS]; c16_t srs_received_noise[nb_antennas_rx][ofdm_symbol_size * N_symb_SRS]; - c16_t srs_estimated_channel_time_shifted[nb_antennas_rx][N_ap][ofdm_symbol_size]; + c16_t srs_estimated_channel_time_shifted[nb_antennas_rx][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size]; start_meas(&gNB->generate_srs_stats); @@ -946,7 +946,7 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB, T_INT(frame_rx), T_INT(0), T_INT(0), - T_BUFFER(srs_estimated_channel_time_shifted[0][0], ofdm_symbol_size * sizeof(int32_t))); + T_BUFFER(srs_estimated_channel_time_shifted[0][0], NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size * sizeof(int32_t))); T(T_GNB_PHY_UL_SNR_ESTIMATE, T_INT(0), @@ -1171,7 +1171,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N int srs_est; c16_t srs_estimated_channel_freq[nb_antennas_rx][N_ap][ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32))); - c16_t srs_estimated_channel_time[nb_antennas_rx][N_ap][ofdm_symbol_size] __attribute__((aligned(32))); + c16_t srs_estimated_channel_time[nb_antennas_rx][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size] + __attribute__((aligned(32))); nr_srs_rx_procedures(gNB, frame_rx,