diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index fb56322e54..a2ee62fbde 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -67,6 +67,49 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) return max_pos - sync_pos; } +int nr_est_timing_advance_srs(NR_DL_FRAME_PARMS *frame_parms, + int32_t **srs_estimated_channel_time) { + int timing_advance = 0; + int max_val = 0; + + for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { + int temp = 0; + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + int Re = ((int16_t*)srs_estimated_channel_time[aa])[(i<<1)]; + int Im = ((int16_t*)srs_estimated_channel_time[aa])[1+(i<<1)]; + temp += (Re*Re/2) + (Im*Im/2); + } + if (temp > max_val) { + timing_advance = i; + max_val = temp; + } + } + + if (timing_advance > frame_parms->ofdm_symbol_size/2) { + timing_advance = timing_advance - frame_parms->ofdm_symbol_size; + } + + // Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size + uint16_t bw_scaling = frame_parms->ofdm_symbol_size >> 11; + + // do some integer rounding to improve TA accuracy + int sync_pos_rounded; + if (timing_advance > 0) { + sync_pos_rounded = timing_advance + (bw_scaling >> 1) - 1; + } else { + sync_pos_rounded = timing_advance - (bw_scaling >> 1) + 1; + } + + int timing_advance_update = sync_pos_rounded / bw_scaling; + + // put timing advance command in 0..63 range + timing_advance_update += 31; + + if (timing_advance_update < 0) timing_advance_update = 0; + if (timing_advance_update > 63) timing_advance_update = 63; + + return timing_advance_update; +} void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) { diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index 38b6556948..914b0d7385 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -55,6 +55,9 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id); +int nr_est_timing_advance_srs(NR_DL_FRAME_PARMS *frame_parms, + int32_t **srs_estimated_channel_time); + void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *frame_parms, nfapi_nr_pusch_pdu_t *rel15_ul, diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index b8aa108f10..4e75090d4b 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -877,7 +877,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->UL_INFO.srs_ind.slot = slot_rx; gNB->srs_pdu_list[num_srs].handle = srs_pdu->handle; gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti; - //gNB->srs_pdu_list[num_srs].timing_advance; + gNB->srs_pdu_list[num_srs].timing_advance = nr_est_timing_advance_srs(&gNB->frame_parms, gNB->nr_srs_info[i]->srs_estimated_channel_time); gNB->srs_pdu_list[num_srs].num_symbols = 1<num_symbols; gNB->srs_pdu_list[num_srs].wide_band_snr = (*gNB->nr_srs_info[i]->snr + 64)<<1; gNB->srs_pdu_list[num_srs].num_reported_symbols = 1<num_symbols; @@ -895,6 +895,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn); LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot); LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].rnti = 0x%04x\n", num_srs, gNB->srs_pdu_list[num_srs].rnti); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance); LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_symbols); LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].wide_band_snr = %i\n", num_srs, gNB->srs_pdu_list[num_srs].wide_band_snr); LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_reported_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_reported_symbols);