diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 0c2ff806e..1966c6f45 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -497,6 +497,8 @@ typedef struct { float cfo_loop_bw_ref; float cfo_loop_ref_min; float cfo_loop_pss_tol; + float sfo_ema; + uint32_t sfo_correct_period; uint32_t cfo_loop_pss_conv; uint32_t cfo_ref_mask; bool average_subframe_enabled; diff --git a/lib/include/srslte/phy/ue/ue_sync.h b/lib/include/srslte/phy/ue/ue_sync.h index 3d9807aea..8eb18f636 100644 --- a/lib/include/srslte/phy/ue/ue_sync.h +++ b/lib/include/srslte/phy/ue/ue_sync.h @@ -61,6 +61,8 @@ #include "srslte/phy/common/timestamp.h" #include "srslte/phy/io/filesource.h" +#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 10 +#define DEFAULT_SFO_EMA_COEFF 0.1 #define DEFAULT_CFO_BW_PSS 0.05 #define DEFAULT_CFO_PSS_MIN 400 // typical bias of PSS estimation. @@ -140,8 +142,7 @@ typedef struct SRSLTE_API { int next_rf_sample_offset; int last_sample_offset; float mean_sample_offset; - float mean_sfo; - uint32_t sample_offset_correct_period; + uint32_t sample_offset_correct_period; float sfo_ema; @@ -248,8 +249,11 @@ SRSLTE_API float srslte_ue_sync_get_sfo(srslte_ue_sync_t *q); SRSLTE_API int srslte_ue_sync_get_last_sample_offset(srslte_ue_sync_t *q); -SRSLTE_API void srslte_ue_sync_set_sample_offset_correct_period(srslte_ue_sync_t *q, - uint32_t nof_subframes); +SRSLTE_API void srslte_ue_sync_set_sfo_correct_period(srslte_ue_sync_t *q, + uint32_t nof_subframes); + +SRSLTE_API void srslte_ue_sync_set_sfo_ema(srslte_ue_sync_t *q, + float ema_coefficient); SRSLTE_API void srslte_ue_sync_get_last_timestamp(srslte_ue_sync_t *q, srslte_timestamp_t *timestamp); diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index 38355af92..a0ae46990 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -41,11 +41,9 @@ #define MAX_TIME_OFFSET 128 -#define TRACK_MAX_LOST 100 +#define TRACK_MAX_LOST 10 #define TRACK_FRAME_SIZE 32 #define FIND_NOF_AVG_FRAMES 4 -#define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 0 -#define DEFAULT_SFO_EMA_COEFF 0.1 cf_t dummy_buffer0[15*2048/2]; @@ -386,7 +384,7 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t *q, srslte_cell_t cell) srslte_sync_set_em_alpha(&q->sfind, 1); srslte_sync_set_threshold(&q->sfind, 3.0); - srslte_sync_set_em_alpha(&q->strack, 0.2); + srslte_sync_set_em_alpha(&q->strack, 0.0); srslte_sync_set_threshold(&q->strack, 1.2); } @@ -464,14 +462,14 @@ void srslte_ue_sync_set_cfo_tol(srslte_ue_sync_t *q, float cfo_tol) { } float srslte_ue_sync_get_sfo(srslte_ue_sync_t *q) { - return q->mean_sfo/5e-3; + return q->mean_sample_offset/5e-3; } int srslte_ue_sync_get_last_sample_offset(srslte_ue_sync_t *q) { return q->last_sample_offset; } -void srslte_ue_sync_set_sample_offset_correct_period(srslte_ue_sync_t *q, uint32_t nof_subframes) { +void srslte_ue_sync_set_sfo_correct_period(srslte_ue_sync_t *q, uint32_t nof_subframes) { q->sample_offset_correct_period = nof_subframes; } @@ -563,7 +561,7 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { uint32_t frame_idx = 0; if (q->sample_offset_correct_period) { frame_idx = q->frame_ok_cnt%q->sample_offset_correct_period; - q->mean_sample_offset += (float) q->last_sample_offset/q->sample_offset_correct_period; + q->mean_sample_offset = SRSLTE_VEC_EMA((float) q->last_sample_offset, q->mean_sample_offset, q->sfo_ema); } else { q->mean_sample_offset = q->last_sample_offset; } @@ -589,23 +587,12 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { if (!frame_idx) { // Adjust RF sampling time based on the mean sampling offset q->next_rf_sample_offset = (int) round(q->mean_sample_offset); - - // Reset PSS averaging if correcting every a period longer than 1 - if (q->sample_offset_correct_period > 1) { - srslte_sync_reset(&q->strack); - } - - // Compute SFO based on mean sample offset - if (q->sample_offset_correct_period) { - q->mean_sample_offset /= q->sample_offset_correct_period; - } - q->mean_sfo = SRSLTE_VEC_EMA(q->mean_sample_offset, q->mean_sfo, q->sfo_ema); if (q->next_rf_sample_offset) { - INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, %.5f samples/5-sf, ema=%f, length=%d\n", + INFO("Time offset adjustment: %d samples (%.2f), mean SFO: %.2f Hz, ema=%f, length=%d\n", q->next_rf_sample_offset, q->mean_sample_offset, srslte_ue_sync_get_sfo(q), - q->mean_sfo, q->sfo_ema, q->sample_offset_correct_period); + q->sfo_ema, q->sample_offset_correct_period); } q->mean_sample_offset = 0; } diff --git a/srsue/hdr/phy/phch_common.h b/srsue/hdr/phy/phch_common.h index 11f974791..6fce44c1c 100644 --- a/srsue/hdr/phy/phch_common.h +++ b/srsue/hdr/phy/phch_common.h @@ -65,7 +65,6 @@ public: float cur_radio_power; float cur_pusch_power; float avg_rsrp; - float avg_rsrp_cqi; float avg_rsrp_dbm; float avg_rsrq_db; float avg_rssi_dbm; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 10759321e..1825fc721 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -187,6 +187,14 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.cqi_fixed)->default_value(-1), "Fixes the reported CQI to a constant value. Default disabled.") + ("expert.sfo_correct_period", + bpo::value(&args->expert.phy.sfo_correct_period)->default_value(DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD), + "Period in ms to correct sample time") + + ("expert.sfo_emma", + bpo::value(&args->expert.phy.sfo_ema)->default_value(DEFAULT_SFO_EMA_COEFF), + "EMA coefficient to average sample offsets used to compute SFO") + ("expert.snr_ema_coeff", bpo::value(&args->expert.phy.snr_ema_coeff)->default_value(0.1), "Sets the SNR exponential moving average coefficient (Default 0.1)") diff --git a/srsue/src/phy/phch_common.cc b/srsue/src/phy/phch_common.cc index afd131958..647d0e0c7 100644 --- a/srsue/src/phy/phch_common.cc +++ b/srsue/src/phy/phch_common.cc @@ -344,7 +344,6 @@ void phch_common::reset() { cur_pusch_power = 0; avg_snr_db_cqi = 0; avg_rsrp = 0; - avg_rsrp_cqi = 0; avg_rsrp_dbm = 0; avg_rsrq_db = 0; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index f2ef205c9..499309d1e 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -683,6 +683,10 @@ void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q, float cfo) srslte_sync_set_cfo_cp_enable(&q->sfind, false, 0); } + // Set SFO ema and correct period + srslte_ue_sync_set_sfo_correct_period(q, worker_com->args->sfo_correct_period); + srslte_ue_sync_set_sfo_ema(q, worker_com->args->sfo_ema); + sss_alg_t sss_alg = SSS_FULL; if (!worker_com->args->sss_algorithm.compare("diff")) { sss_alg = SSS_DIFF; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 1aedde814..746a7e430 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -407,7 +407,7 @@ void phch_worker::work_imp() update_measurements(); if (chest_ok) { - if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db_cqi > 0.0) { + if (phy->avg_rsrp_dbm > -130.0 && phy->avg_snr_db_cqi > -6.0) { log_h->debug("SNR=%.1f dB, RSRP=%.1f dBm sync=in-sync from channel estimator\n", phy->avg_snr_db_cqi, phy->avg_rsrp_dbm); chest_loop->in_sync(); @@ -1433,7 +1433,7 @@ void phch_worker::update_measurements() } // Average RSRP taken from CRS - float rsrp_lin = srslte_chest_dl_get_rsrp_neighbour(&ue_dl.chest); + float rsrp_lin = srslte_chest_dl_get_rsrp(&ue_dl.chest); if (isnormal(rsrp_lin)) { if (!phy->avg_rsrp) { phy->avg_rsrp = SRSLTE_VEC_EMA(rsrp_lin, phy->avg_rsrp, snr_ema_coeff); @@ -1473,17 +1473,7 @@ void phch_worker::update_measurements() } } - // To compute CQI use RSRP measurements from resource elements in RS since is more robust to time offset - float rsrp_lin_cqi = srslte_chest_dl_get_rsrp(&ue_dl.chest); - if (isnormal(rsrp_lin_cqi)) { - if (!phy->avg_rsrp_cqi) { - phy->avg_rsrp_cqi = SRSLTE_VEC_EMA(rsrp_lin_cqi, phy->avg_rsrp_cqi, snr_ema_coeff); - } else { - phy->avg_rsrp_cqi = rsrp_lin_cqi; - } - } - - phy->avg_snr_db_cqi = 10*log10(phy->avg_rsrp_cqi/phy->avg_noise); + phy->avg_snr_db_cqi = 10*log10(phy->avg_rsrp/phy->avg_noise); // Store metrics dl_metrics.n = phy->avg_noise; diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 11fbdc0e6..43b5e1e7d 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -153,7 +153,9 @@ enable = false # good for long channels. For best performance at highest SNR reduce it to 1. # sfo_correct_disable: Disables phase correction before channel estimation to compensate for # sampling frequency offset. Default is enabled. -# sss_algorithm: Selects the SSS estimation algorithm. Can choose between +# sfo_ema: EMA coefficient to average sample offsets used to compute SFO +# sfo_correct_period: Period in ms to correct sample time to adjust for SFO +# sss_algorithm: Selects the SSS estimation algorithm. Can choose between # {full, partial, diff}. # estimator_fil_auto: The channel estimator smooths the channel estimate with an adaptative filter. # estimator_fil_stddev: Sets the channel estimator smooth gaussian filter standard deviation. @@ -210,6 +212,8 @@ enable = false #equalizer_mode = mmse #time_correct_period = 5 #sfo_correct_disable = false +#sfo_ema = 0.1 +#sfo_correct_period = 10 #sss_algorithm = full #estimator_fil_auto = false #estimator_fil_stddev = 1.0