From 107f20ad2912c351683ae139b62ce9e760fd5160 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 18 Oct 2021 12:01:05 +0000 Subject: [PATCH 1/4] fix rounding in TA calculation --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 63cf6f2f2d..1685e206ae 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -403,8 +403,6 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, pthread_mutex_lock(&gNB->UL_INFO_mutex); - int timing_advance_update, cqi; - int sync_pos; NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id][0]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; NR_gNB_SCH_STATS_t *stats=get_ulsch_stats(gNB,ulsch); @@ -412,19 +410,20 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu; // pdu->data = gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b; - sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC + int sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048; - int sync_pos_rounded; + // do some integer rounding to improve TA accuracy + int sync_pos_rounded; if (sync_pos > 0) sync_pos_rounded = sync_pos + (bw_scaling / 2) - 1; else - sync_pos_rounded = sync_pos - (bw_scaling / 2) - 1; + sync_pos_rounded = sync_pos - (bw_scaling / 2) + 1; if (stats) stats->sync_pos = sync_pos; - timing_advance_update = sync_pos_rounded / bw_scaling; + int timing_advance_update = sync_pos_rounded / bw_scaling; // put timing advance command in 0..63 range timing_advance_update += 31; @@ -449,6 +448,7 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, LOG_D(PHY, "Estimated SNR for PUSCH is = %f dB (ulsch_power %f, noise %f)\n", SNRtimes10/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot)/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot)/10.0); + int cqi; if (SNRtimes10 < -640) cqi=0; else if (SNRtimes10 > 635) cqi=255; else cqi=(640+SNRtimes10)/5; From 2c2ba26553c72e7d134e4e206e7e674a95424dcd Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 21 Oct 2021 20:50:04 +0200 Subject: [PATCH 2/4] NR_UE: fix bug in timing adjustment --- executables/nr-ue.c | 2 ++ openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c | 12 +++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 1d415e1230..76c4534384 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -464,12 +464,14 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) { if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2 && UE->rx_offset > 0 ) { //LOG_I(PHY,"!!!adjusting -1 samples!!!\n"); + UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame return -1 ; } if ( UE->rx_offset > UE->frame_parms.samples_per_frame/2 && UE->rx_offset < UE->frame_parms.samples_per_frame ) { //LOG_I(PHY,"!!!adjusting +1 samples!!!\n"); + UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame return 1; } 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 3908febae9..e89280058a 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -55,13 +55,14 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, 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 (int i = 0; i < frame_parms->nb_prefix_samples; i++) { + // search for maximum position within the cyclic prefix + for (int i = -frame_parms->nb_prefix_samples/2; i < frame_parms->nb_prefix_samples/2; i++) { int temp = 0; + int j = (i < 0) ? (i + frame_parms->ofdm_symbol_size) : i; 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)]; + int Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(j<<1)]; + int Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(j<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -71,9 +72,6 @@ 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; From 209d5f1131079351adb6163fdfb78f4883672ae9 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 21 Oct 2021 21:56:01 +0200 Subject: [PATCH 3/4] NR_UE: reset max_pos_fil in timing synchronization whenever we add/remove a sample --- executables/nr-ue.c | 6 ++++-- openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c | 11 +++++------ openair1/PHY/defs_nr_UE.h | 5 +++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 76c4534384..e3fb68020b 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -464,14 +464,16 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) { if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2 && UE->rx_offset > 0 ) { //LOG_I(PHY,"!!!adjusting -1 samples!!!\n"); - UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame + UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame + UE->max_pos_fil = 0; // reset IIR filter when sample shift is applied return -1 ; } if ( UE->rx_offset > UE->frame_parms.samples_per_frame/2 && UE->rx_offset < UE->frame_parms.samples_per_frame ) { //LOG_I(PHY,"!!!adjusting +1 samples!!!\n"); - UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame + UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame + UE->max_pos_fil = 0; // reset IIR filter when sample shift is applied return 1; } 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 e89280058a..19d4bf5079 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -42,7 +42,6 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, short coef) { - static int max_pos_fil = 0; static int count_max_pos_ok = 0; static int first_time = 1; int max_val = 0, max_pos = 0; @@ -74,14 +73,14 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, // filter position to reduce jitter if (clear == 1) - max_pos_fil = max_pos; + ue->max_pos_fil = max_pos; else - max_pos_fil = ((max_pos_fil * coef) + (max_pos * ncoef)) >> 15; + ue->max_pos_fil = ((ue->max_pos_fil * coef) + (max_pos * ncoef)) >> 15; // do not filter to have proactive timing adjustment - //max_pos_fil = max_pos; + //ue->max_pos_fil = max_pos; - int diff = max_pos_fil - sync_pos; + int diff = ue->max_pos_fil - sync_pos; if (frame_parms->freq_range==nr_FR2) sync_offset = 2; @@ -129,7 +128,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, ue->rx_offset, clear, max_pos, - max_pos_fil, + ue->max_pos_fil, max_val, sync_pos); #endif //DEBUG_PHY diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 8ce18aa667..2290e9ede4 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -921,9 +921,10 @@ typedef struct { uint8_t init_sync_frame; /// temporary offset during cell search prior to MIB decoding int ssb_offset; - uint16_t symbol_offset; // offset in terms of symbols for detected ssb in sync - int rx_offset; /// Timing offset + uint16_t symbol_offset; /// offset in terms of symbols for detected ssb in sync + int rx_offset; /// Timing offset int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP + int max_pos_fil; /// Timing offset IIR filter int time_sync_cell; /// Timing Advance updates variables From 94bc375f8235f645f02ecad2c8714968fdd54743 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 21 Oct 2021 21:57:11 +0200 Subject: [PATCH 4/4] NR_UE: enable timing synchronization logging --- executables/nr-ue.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index e3fb68020b..3f57f5f64c 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -463,7 +463,7 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) { // compute TO compensation that should be applied for this frame if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2 && UE->rx_offset > 0 ) { - //LOG_I(PHY,"!!!adjusting -1 samples!!!\n"); + LOG_I(PHY,"!!!adjusting -1 samples!!! rx_offset == %d\n", UE->rx_offset); UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame UE->max_pos_fil = 0; // reset IIR filter when sample shift is applied return -1 ; @@ -471,7 +471,8 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) { if ( UE->rx_offset > UE->frame_parms.samples_per_frame/2 && UE->rx_offset < UE->frame_parms.samples_per_frame ) { - //LOG_I(PHY,"!!!adjusting +1 samples!!!\n"); + int rx_offset = UE->rx_offset - UE->frame_parms.samples_per_frame; + LOG_I(PHY,"!!!adjusting +1 samples!!! rx_offset == %d\n", rx_offset); UE->rx_offset = 0; // reset so that it is not applied falsely in case of SSB being only in every second frame UE->max_pos_fil = 0; // reset IIR filter when sample shift is applied return 1;