From 942037beb3fe5055b250e0560b83943fd2348456 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 26 Apr 2021 14:45:56 +0200 Subject: [PATCH] 5G NR: move CIR peak to 0 The rotation compensating the shifted OFDM position _before_ the channel estimation makes the CIR peak move back to 0. We have to take this into account on gNB side when calculating the timing advance command, and on UE side in the time adjustment. --- .../PHY/NR_ESTIMATION/nr_measurements_gNB.c | 17 ++- .../PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c | 116 +++++++++--------- 2 files changed, 65 insertions(+), 68 deletions(-) diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index 36e1c3fee9..ca5108ef45 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -39,20 +39,20 @@ extern openair0_config_t openair0_cfg[MAX_CARDS]; int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) { - int i, aa, max_pos = 0, max_val = 0; - + int max_pos = 0, max_val = 0; + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id]; int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time; - - int sync_pos = frame_parms->nb_prefix_samples / frame_parms->ofdm_offset_divisor; - for (i = 0; i < frame_parms->ofdm_symbol_size; i++) { + const int sync_pos = 0; + + for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { int temp = 0; - for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; - short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + int Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)]; + int Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -65,7 +65,6 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) if (max_pos > frame_parms->ofdm_symbol_size/2) max_pos = max_pos - frame_parms->ofdm_symbol_size; - return max_pos - sync_pos; } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index f411e8d5b2..4cebeab712 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -45,25 +45,23 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, static int max_pos_fil = 0; static int count_max_pos_ok = 0; static int first_time = 1; - int temp = 0, i, aa, max_val = 0, max_pos = 0; - int diff; - short Re,Im,ncoef; + int max_val = 0, max_pos = 0; + const int sync_pos = 0; uint8_t sync_offset = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN); - ncoef = 32767 - coef; + short ncoef = 32767 - coef; LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset); - // we only use channel estimates from tx antenna 0 here - for (i = 0; i < frame_parms->nb_prefix_samples; i++) { - temp = 0; + for (int i = 0; i < frame_parms->nb_prefix_samples; i++) { + int temp = 0; - for (aa=0; aanb_antennas_rx; aa++) { - Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + int Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; + int Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -73,6 +71,9 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, } } + if (max_pos > frame_parms->ofdm_symbol_size/2) + max_pos = max_pos - frame_parms->ofdm_symbol_size; + // filter position to reduce jitter if (clear == 1) max_pos_fil = max_pos; @@ -82,61 +83,58 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, // do not filter to have proactive timing adjustment //max_pos_fil = max_pos; - diff = max_pos_fil - (frame_parms->nb_prefix_samples / frame_parms->ofdm_offset_divisor); + int diff = max_pos_fil - sync_pos; - if (frame_parms->freq_range==nr_FR2) - sync_offset = 2; - else - sync_offset = 0; - - if ( abs(diff) < (SYNCH_HYST+sync_offset) ) - ue->rx_offset = 0; - else - ue->rx_offset = diff; + if (frame_parms->freq_range==nr_FR2) + sync_offset = 2; + else + sync_offset = 0; - if(abs(diff)<5) - count_max_pos_ok ++; - else - count_max_pos_ok = 0; - - //printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok); + if ( abs(diff) < (SYNCH_HYST+sync_offset) ) + ue->rx_offset = 0; + else + ue->rx_offset = diff; - if(count_max_pos_ok > 10 && first_time == 1) - { - first_time = 0; - ue->time_sync_cell = 1; - if (get_softmodem_params()->do_ra) { - LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); - //mac_resynch(); - //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id); - ue->UE_mode[0] = PRACH; - ue->prach_resources[gNB_id]->sync_frame = frame; - ue->prach_resources[gNB_id]->init_msg1 = 0; - } else { - ue->UE_mode[0] = PUSCH; - } - } + if(abs(diff)<5) + count_max_pos_ok ++; + else + count_max_pos_ok = 0; + + //printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok); - if (ue->rx_offset < 0) - ue->rx_offset += frame_parms->samples_per_frame; + if(count_max_pos_ok > 10 && first_time == 1) + { + first_time = 0; + ue->time_sync_cell = 1; + if (get_softmodem_params()->do_ra) { + LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); + //mac_resynch(); + //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id); + ue->UE_mode[0] = PRACH; + ue->prach_resources[gNB_id]->sync_frame = frame; + ue->prach_resources[gNB_id]->init_msg1 = 0; + } else { + ue->UE_mode[0] = PUSCH; + } + } - if (ue->rx_offset >= frame_parms->samples_per_frame) - ue->rx_offset -= frame_parms->samples_per_frame; + if (ue->rx_offset < 0) + ue->rx_offset += frame_parms->samples_per_frame; + if (ue->rx_offset >= frame_parms->samples_per_frame) + ue->rx_offset -= frame_parms->samples_per_frame; +#ifdef DEBUG_PHY + LOG_D(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n", + subframe, + diff, + ue->rx_offset, + clear, + max_pos, + max_pos_fil, + max_val, + sync_pos); +#endif //DEBUG_PHY - #ifdef DEBUG_PHY - LOG_D(PHY,"AbsSubframe %d: diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", - subframe, - diff, - ue->rx_offset, - clear, - max_pos, - max_pos_fil, - temp,max_val, - (frame_parms->nb_prefix_samples>>3)); - #endif //DEBUG_PHY - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); }