diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index f851c26eee..fafc1bcd47 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -1149,6 +1149,20 @@ void init_delay_table(uint16_t ofdm_symbol_size, } } +int set_default_nta_offset(frequency_range_t freq_range, uint32_t samples_per_subframe) +{ + // ta_offset_samples : ta_offset = samples_per_subframe : (Δf_max x N_f / 1000) + // As described in Section 4.3.1 in 38.211 + + // TODO There is no way for the UE to know about LTE-NR coexistence case + // as mentioned in Table 7.1.2-2 of 38.133 + // LTE-NR coexistence means the presence of an active LTE service in the same band as NR in current deployment + // We assume no coexistence + + uint64_t numer = (freq_range == FR1 ? 25600 : 13792) * (uint64_t)samples_per_subframe; + return numer / (4096 * 480); +} + void nr_timer_start(NR_timer_t *timer) { timer->active = true; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 3c04bca581..1e4fecc4f5 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -177,7 +177,7 @@ bool nr_timer_is_active(const NR_timer_t *timer); */ uint32_t nr_timer_elapsed_time(const NR_timer_t *timer); - +int set_default_nta_offset(frequency_range_t freq_range, uint32_t samples_per_subframe); extern const nr_bandentry_t nr_bandtable[]; static inline int get_num_dmrs(uint16_t dmrs_mask ) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 8a29e6ac2f..7f5d193d34 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -959,43 +959,10 @@ int setup_RU_buffers(RU_t *ru) { int mu = config->ssb_config.scs_common.value; int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; - if (config->cell_config.frame_duplex_type.value == TDD) { - int N_TA_offset = config->carrier_config.uplink_frequency.value < 6000000 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 - double factor=1; - - switch (mu) { - case 0: //15 kHz scs - AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); - factor = fp->samples_per_subframe / 30720.0; - break; - - case 1: //30 kHz sc - AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); - factor = fp->samples_per_subframe / 30720.0; - break; - - case 2: //60 kHz scs - AssertFatal(1==0, "scs_common should not be 60 kHz\n"); - break; - - case 3: //120 kHz scs - AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n"); - factor = fp->samples_per_subframe / 61440.0; - break; - - case 4: //240 kHz scs - AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n"); - factor = fp->samples_per_subframe / 61440.0; - break; - - default: - AssertFatal(1==0, "Invalid scs_common!\n"); - } - - ru->N_TA_offset = (int)(N_TA_offset * factor); - LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d, mu %d)\n",ru->idx,ru->N_TA_offset,factor, - config->carrier_config.uplink_frequency.value, N_RB, mu); - } else ru->N_TA_offset = 0; + ru->N_TA_offset = set_default_nta_offset(fp->freq_range, fp->samples_per_subframe); + LOG_I(PHY, + "RU %d Setting N_TA_offset to %d samples (UL Freq %d, N_RB %d, mu %d)\n", + ru->idx, ru->N_TA_offset, config->carrier_config.uplink_frequency.value, N_RB, mu); if (ru->openair0_cfg.mmapped_dma == 1) { // replace RX signal buffers with mmaped HW versions diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 9f040537d0..577f7a44d8 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -504,45 +504,16 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue) NR_DL_FRAME_PARMS *fp = &ue->frame_parms; // No timing offset for Sidelink, refer to 3GPP 38.211 Section 8.5 - if (fp->frame_type == FDD || ue->sl_mode == 2) { + if (ue->sl_mode == 2) ue->N_TA_offset = 0; - } else { - // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 - int N_TA_offset = fp->ul_CarrierFreq < 6e9 ? 400 : 431; + else + ue->N_TA_offset = set_default_nta_offset(fp->freq_range, fp->samples_per_subframe); + ue->ta_frame = -1; + ue->ta_slot = -1; - double factor = 1.0; - switch (fp->numerology_index) { - case 0: //15 kHz scs - AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); - factor = fp->samples_per_subframe / 30720.0; - break; - case 1: //30 kHz sc - AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); - factor = fp->samples_per_subframe / 30720.0; - break; - case 2: //60 kHz scs - AssertFatal(1==0, "scs_common should not be 60 kHz\n"); - break; - case 3: //120 kHz scs - AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n"); - factor = fp->samples_per_subframe / 61440.0; - break; - case 4: //240 kHz scs - AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n"); - factor = fp->samples_per_subframe / 61440.0; - break; - default: - AssertFatal(1==0, "Invalid scs_common!\n"); - } - - ue->N_TA_offset = (int)(N_TA_offset * factor); - ue->ta_frame = -1; - ue->ta_slot = -1; - - LOG_I(PHY, - "UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d, mu %d)\n", - ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, fp->N_RB_DL, fp->numerology_index); - } + LOG_I(PHY, + "UE %d Setting N_TA_offset to %d samples (UL Freq %lu, N_RB %d, mu %d)\n", + ue->Mod_id, ue->N_TA_offset, fp->ul_CarrierFreq, fp->N_RB_DL, fp->numerology_index); } void phy_init_nr_top(PHY_VARS_NR_UE *ue) { diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 6a2c300b72..939478f35c 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -316,7 +316,7 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS * fp->get_samples_slot_timestamp = &get_samples_slot_timestamp; fp->get_slot_from_timestamp = &get_slot_from_timestamp; fp->samples_per_frame = 10 * fp->samples_per_subframe; - fp->freq_range = (fp->dl_CarrierFreq < 6e9)? FR1 : FR2; + fp->freq_range = (fp->dl_CarrierFreq < 6e9) ? FR1 : FR2; fp->Ncp = Ncp; @@ -400,7 +400,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->get_samples_per_slot = &get_samples_per_slot; fp->get_samples_slot_timestamp = &get_samples_slot_timestamp; fp->samples_per_frame = 10 * fp->samples_per_subframe; - fp->freq_range = (fp->dl_CarrierFreq < 6e9)? FR1 : FR2; + fp->freq_range = (fp->dl_CarrierFreq < 6e9) ? FR1 : FR2; uint8_t sco = 0; if (((fp->freq_range == FR1) && (config->ssb_table.ssb_subcarrier_offset < 24)) ||