diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 9a7a68a34..e69419983 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -474,7 +474,8 @@ typedef struct { int cqi_max; int cqi_fixed; float snr_ema_coeff; - std::string snr_estim_alg; + std::string snr_estim_alg; + bool cfo_is_doppler; bool cfo_integer_enabled; float cfo_correct_tol_hz; float cfo_pss_ema; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index d71bcb1d5..f955b30ce 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -104,6 +104,8 @@ private: void cell_search_inc(); void cell_reselect(); + float get_cfo(); + uint32_t new_earfcn; srslte_cell_t new_cell; diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index 6f72285b2..e87603e5d 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -73,7 +73,6 @@ public: float get_rsrp(); float get_noise(); float get_cfo(); - float get_ul_cfo(); private: /* Inherited from thread_pool::worker. Function called every subframe to run the DL/UL processing */ diff --git a/srsue/src/main.cc b/srsue/src/main.cc index d2d029c63..00fd23cf8 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -203,6 +203,11 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.equalizer_mode)->default_value("mmse"), "Equalizer mode") + ("expert.cfo_is_doppler", + bpo::value(&args->expert.phy.cfo_is_doppler)->default_value(false), + "Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed" + "to be caused by the local oscillator and the UL correction is in the opposite direction. Default assumes oscillator.") + ("expert.cfo_integer_enabled", bpo::value(&args->expert.phy.cfo_integer_enabled)->default_value(false), "Enables integer CFO estimation and correction.") @@ -215,12 +220,6 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.cfo_pss_ema)->default_value(DEFAULT_CFO_EMA_TRACK), "CFO Exponential Moving Average coefficient for PSS estimation during TRACK.") - /* REF EMA is currently not used - ("expert.cfo_ref_ema", - bpo::value(&args->expert.phy.cfo_ref_ema)->default_value(0.01), - "CFO Exponential Moving Average coefficient for RS estimation after PSS acquisition") - */ - ("expert.cfo_ref_mask", bpo::value(&args->expert.phy.cfo_ref_mask)->default_value(1023), "Bitmask for subframes on which to run RS estimation (set to 0 to disable, default all sf)") diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 456f14ea0..38dd5b561 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -428,6 +428,25 @@ bool phch_recv::set_frequency() } } +float phch_recv::get_cfo() +{ + float cfo = srslte_ue_sync_get_cfo(&ue_sync); + + float ret = cfo*ul_dl_factor; + + if (worker_com->args->cfo_is_doppler) { + ret *= -1; + } + + if (radio_h->get_freq_offset() != 0.0f) { + /* Compensates the radio frequency offset applied equally to DL and UL */ + const float offset_hz = (float) radio_h->get_freq_offset() * (1.0f - ul_dl_factor); + ret = cfo - offset_hz; + } + + return ret/15000; +} + void phch_recv::set_sampling_rate() { current_srate = (float) srslte_sampling_freq_hz(cell.nof_prb); @@ -633,7 +652,7 @@ void phch_recv::run_thread() metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync); metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync); - worker->set_cfo(ul_dl_factor * metrics.cfo / 15000); + worker->set_cfo(get_cfo()); worker_com->set_sync_metrics(metrics); /* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */ @@ -659,7 +678,7 @@ void phch_recv::run_thread() if (prach_buffer->is_ready_to_send(tti)) { srslte_timestamp_copy(&tx_time_prach, &rx_time); srslte_timestamp_add(&tx_time_prach, 0, prach::tx_advance_sf * 1e-3); - prach_buffer->send(radio_h, ul_dl_factor * metrics.cfo / 15000, worker_com->pathloss, tx_time_prach); + prach_buffer->send(radio_h, get_cfo(), worker_com->pathloss, tx_time_prach); radio_h->tx_end(); worker_com->p0_preamble = prach_buffer->get_p0_preamble(); worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index b3a33ea6c..e613719cb 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -223,20 +223,6 @@ float phch_worker::get_cfo() return cfo; } -float phch_worker::get_ul_cfo() { - srslte::radio *radio = phy->get_radio(); - - if (radio->get_freq_offset() != 0.0f) { - /* Compensates the radio frequency offset applied equally to DL and UL */ - const float ul_dl_ratio = (float) radio->get_tx_freq() / (float) radio->get_rx_freq(); - const float offset_hz = (float) radio->get_freq_offset() * (1.0f - ul_dl_ratio); - return cfo - offset_hz / (15000); - } else { - return cfo; - } - -} - void phch_worker::work_imp() { if (!cell_initiated) { @@ -360,7 +346,7 @@ void phch_worker::work_imp() } /* Set UL CFO before transmission */ - srslte_ue_ul_set_cfo(&ue_ul, get_ul_cfo()); + srslte_ue_ul_set_cfo(&ue_ul, cfo); /* Transmit PUSCH, PUCCH or SRS */ bool signal_ready = false; diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 52442e4af..a3de1a678 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -172,6 +172,8 @@ enable = false # cfo_correct_tol_hz: Tolerance (in Hz) for digial CFO compensation. Lower tolerance means that # a new table will be generated more often. # +# cfo_is_doppler: Assume detected CFO is doppler and correct the UL in the same direction. If disabled, the CFO is assumed +# to be caused by the local oscillator and the UL correction is in the opposite direction. Default assumes oscillator. # cfo_pss_ema: CFO Exponential Moving Average coefficient for PSS estimation during TRACK. # cfo_ref_ema: CFO Exponential Moving Average coefficient for RS estimation after PSS acquisition # cfo_ref_mask: Bitmask for subframes on which to run RS estimation (set to 0 to disable, default sf=[1, 5]) @@ -211,6 +213,7 @@ enable = false #pdsch_csi_enabled = true # Caution! Only TM1 supported! # CFO related values +#cfo_is_doppler = false #cfo_integer_enabled = false #cfo_correct_tol_hz = 1.0 #cfo_pss_ema = 0.05