From 6711387ad7e141ca9ed9c390577f85aeafd72920 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 17 Dec 2017 23:05:28 +0100 Subject: [PATCH] Disabled AGC for initial cell search. Copy CFO from search and disable CP based CFO after search to reduce overhead --- lib/examples/pdsch_ue.c | 13 +++++++-- lib/include/srslte/phy/sync/sync.h | 6 +++- lib/include/srslte/phy/ue/ue_sync.h | 3 +- lib/src/phy/rf/rf_utils.c | 33 ++++++++------------- lib/src/phy/sync/sync.c | 8 +++-- lib/src/phy/ue/ue_sync.c | 45 +++++++++++++++-------------- srsue/hdr/phy/phch_recv.h | 2 +- srsue/src/phy/phch_recv.cc | 24 ++++++++------- 8 files changed, 72 insertions(+), 62 deletions(-) diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index ef8b643e4..032ef5c47 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -417,8 +417,8 @@ int main(int argc, char **argv) { fprintf(stderr, "Error opening rf\n"); exit(-1); } - srslte_rf_set_rx_gain(&rf, 50); - cell_detect_config.init_agc = 50; + srslte_rf_set_rx_gain(&rf, srslte_rf_get_rx_gain(&rf)); + cell_detect_config.init_agc = srslte_rf_get_rx_gain(&rf); } sigset_t sigset; @@ -546,6 +546,13 @@ int main(int argc, char **argv) { exit(-1); } + // Disable CP based CFO estimation during find + ue_sync.cfo_current_value = cfo/15000; + ue_sync.cfo_is_copied = true; + ue_sync.cfo_correct_enable_find = true; + srslte_sync_set_cfo_cp_enable(&ue_sync.sfind, false, 0); + + srslte_chest_dl_cfo_estimate_enable(&ue_dl.chest, prog_args.enable_cfo_ref, 1023); srslte_chest_dl_average_subframe(&ue_dl.chest, prog_args.average_subframe); @@ -595,7 +602,7 @@ int main(int argc, char **argv) { bzero(&old_dl_dci, sizeof(srslte_ra_dl_dci_t)); #endif - ue_sync.cfo_correct_enable = !prog_args.disable_cfo; + ue_sync.cfo_correct_enable_track = !prog_args.disable_cfo; srslte_pbch_decode_reset(&ue_mib.pbch); diff --git a/lib/include/srslte/phy/sync/sync.h b/lib/include/srslte/phy/sync/sync.h index 791ef641b..232bc5fc4 100644 --- a/lib/include/srslte/phy/sync/sync.h +++ b/lib/include/srslte/phy/sync/sync.h @@ -108,6 +108,8 @@ typedef struct SRSLTE_API { float cfo_ema_alpha; + uint32_t cfo_cp_nsymbols; + srslte_cfo_t cfo_corr_frame; srslte_cfo_t cfo_corr_symbol; @@ -204,7 +206,9 @@ SRSLTE_API void srslte_sync_copy_cfo(srslte_sync_t *q, SRSLTE_API void srslte_sync_set_cfo_i_enable(srslte_sync_t *q, bool enable); SRSLTE_API void srslte_sync_set_cfo_cp_enable(srslte_sync_t *q, - bool enable); + bool enable, + uint32_t nof_symbols); + SRSLTE_API void srslte_sync_set_cfo_pss_enable(srslte_sync_t *q, bool enable); diff --git a/lib/include/srslte/phy/ue/ue_sync.h b/lib/include/srslte/phy/ue/ue_sync.h index 83f64bab6..ff863c3f9 100644 --- a/lib/include/srslte/phy/ue/ue_sync.h +++ b/lib/include/srslte/phy/ue/ue_sync.h @@ -122,7 +122,8 @@ typedef struct SRSLTE_API { bool decode_sss_on_track; bool cfo_is_copied; - bool cfo_correct_enable; + bool cfo_correct_enable_track; + bool cfo_correct_enable_find; float cfo_current_value; float cfo_loop_bw_pss; float cfo_loop_bw_ref; diff --git a/lib/src/phy/rf/rf_utils.c b/lib/src/phy/rf/rf_utils.c index 892ad817e..ea016c721 100644 --- a/lib/src/phy/rf/rf_utils.c +++ b/lib/src/phy/rf/rf_utils.c @@ -113,10 +113,6 @@ int rf_mib_decoder(srslte_rf_t *rf, uint32_t nof_rx_antennas,cell_search_cfg_t * goto clean_exit; } - if (config->init_agc > 0) { - srslte_ue_sync_start_agc(&ue_mib.ue_sync, srslte_rf_set_rx_gain_th_wrapper, config->init_agc); - } - int srate = srslte_sampling_freq_hz(SRSLTE_UE_MIB_NOF_PRB); INFO("Setting sampling frequency %.2f MHz for PSS search\n", (float) srate/1000000); srslte_rf_set_rx_srate(rf, (float) srate); @@ -124,7 +120,15 @@ int rf_mib_decoder(srslte_rf_t *rf, uint32_t nof_rx_antennas,cell_search_cfg_t * INFO("Starting receiver...\n", 0); srslte_rf_start_rx_stream(rf, false); - /* Find and decody MIB */ + // Copy CFO estimate if provided and disable CP estimation during find + if (cfo) { + ue_mib.ue_sync.cfo_current_value = *cfo/15000; + ue_mib.ue_sync.cfo_is_copied = true; + ue_mib.ue_sync.cfo_correct_enable_find = true; + srslte_sync_set_cfo_cp_enable(&ue_mib.ue_sync.sfind, false, 0); + } + + /* Find and decode MIB */ ret = srslte_ue_mib_sync_decode(&ue_mib, config->max_frames_pbch, bch_payload, &cell->nof_ports, NULL); if (ret < 0) { fprintf(stderr, "Error decoding MIB\n"); @@ -133,12 +137,7 @@ int rf_mib_decoder(srslte_rf_t *rf, uint32_t nof_rx_antennas,cell_search_cfg_t * if (ret == 1) { srslte_pbch_mib_unpack(bch_payload, cell, NULL); } - - // Save AGC value - if (config->init_agc > 0) { - config->init_agc = srslte_agc_get_gain(&ue_mib.ue_sync.agc); - } - + // Save CFO if (cfo) { *cfo = srslte_ue_sync_get_cfo(&ue_mib.ue_sync); @@ -171,10 +170,7 @@ int rf_cell_search(srslte_rf_t *rf, uint32_t nof_rx_antennas, if (config->nof_valid_pss_frames) { srslte_ue_cellsearch_set_nof_valid_frames(&cs, config->nof_valid_pss_frames); } - if (config->init_agc > 0) { - srslte_ue_sync_start_agc(&cs.ue_sync, srslte_rf_set_rx_gain_th_wrapper, config->init_agc); - } - + INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000); srslte_rf_set_rx_srate(rf, SRSLTE_CS_SAMP_FREQ); @@ -217,12 +213,7 @@ int rf_cell_search(srslte_rf_t *rf, uint32_t nof_rx_antennas, // Save CFO if (cfo) { - *cfo = found_cells[max_peak_cell].cfo; - } - - // Save AGC value for MIB decoding - if (config->init_agc > 0) { - config->init_agc = srslte_agc_get_gain(&cs.ue_sync.agc); + *cfo = found_cells[max_peak_cell].cfo; } srslte_rf_stop_rx_stream(rf); diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index 1508f4afb..bf86eef4d 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -80,6 +80,7 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o q->cfo_i_initiated = false; q->pss_filtering_enabled = false; + q->cfo_cp_nsymbols = 3; q->fft_size = fft_size; q->frame_size = frame_size; q->max_offset = max_offset; @@ -326,8 +327,9 @@ void srslte_sync_set_pss_filt_enable(srslte_sync_t *q, bool enable) { q->pss_filtering_enabled = enable; } -void srslte_sync_set_cfo_cp_enable(srslte_sync_t *q, bool enable) { - q->cfo_cp_enable = enable; +void srslte_sync_set_cfo_cp_enable(srslte_sync_t *q, bool enable, uint32_t nof_symbols) { + q->cfo_cp_enable = enable; + q->cfo_cp_nsymbols = nof_symbols; } void srslte_sync_set_cfo_pss_enable(srslte_sync_t *q, bool enable) { @@ -475,7 +477,7 @@ srslte_pss_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q) static float cfo_cp_estimate(srslte_sync_t *q, const cf_t *input) { uint32_t cp_offset = 0; - cp_offset = srslte_cp_synch(&q->cp_synch, input, q->max_offset, 1, SRSLTE_CP_LEN_NORM(1,q->fft_size)); + cp_offset = srslte_cp_synch(&q->cp_synch, input, q->max_offset, q->cfo_cp_nsymbols, SRSLTE_CP_LEN_NORM(1,q->fft_size)); cf_t cp_corr_max = srslte_cp_synch_corr_output(&q->cp_synch, cp_offset); float cfo = -carg(cp_corr_max) / M_PI / 2; return cfo; diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index 0a6c1c9ff..f3360dda7 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -74,8 +74,9 @@ int srslte_ue_sync_init_file_multi(srslte_ue_sync_t *q, uint32_t nof_prb, char * q->fft_size = srslte_symbol_sz(nof_prb); q->nof_rx_antennas = nof_rx_ant; - q->cfo_correct_enable = true; - + q->cfo_correct_enable_find = false; + q->cfo_correct_enable_track = true; + if (srslte_cfo_init(&q->file_cfo_correct, 2*q->sf_len)) { fprintf(stderr, "Error initiating CFO\n"); goto clean_exit; @@ -220,7 +221,9 @@ int srslte_ue_sync_init_multi_decim(srslte_ue_sync_t *q, q->cfo_pss_min = DEFAULT_CFO_PSS_MIN; q->cfo_loop_bw_pss = DEFAULT_CFO_BW_PSS; q->cfo_loop_bw_ref = DEFAULT_CFO_BW_REF; - q->cfo_correct_enable = true; + + q->cfo_correct_enable_find = false; + q->cfo_correct_enable_track = true; q->pss_stable_cnt = 0; q->pss_stable_timeout = DEFAULT_PSS_STABLE_TIMEOUT; @@ -261,14 +264,12 @@ int srslte_ue_sync_init_multi_decim(srslte_ue_sync_t *q, // Configure FIND and TRACK sync objects behaviour (this configuration is always the same) srslte_sync_set_cfo_i_enable(&q->sfind, false); - srslte_sync_set_cfo_cp_enable(&q->sfind, true); srslte_sync_set_cfo_pss_enable(&q->sfind, true); srslte_sync_set_pss_filt_enable(&q->sfind, true); srslte_sync_set_sss_eq_enable(&q->sfind, false); // During track, we do CFO correction outside the sync object srslte_sync_set_cfo_i_enable(&q->strack, false); - srslte_sync_set_cfo_cp_enable(&q->strack, false); srslte_sync_set_cfo_pss_enable(&q->strack, true); srslte_sync_set_pss_filt_enable(&q->strack, true); srslte_sync_set_sss_eq_enable(&q->strack, false); @@ -277,11 +278,9 @@ int srslte_ue_sync_init_multi_decim(srslte_ue_sync_t *q, srslte_sync_cp_en(&q->strack, false); srslte_sync_cp_en(&q->sfind, false); - srslte_sync_sss_en(&q->strack, true); q->decode_sss_on_track = true; - ret = SRSLTE_SUCCESS; } @@ -392,8 +391,13 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t *q, srslte_cell_t cell) srslte_sync_set_em_alpha(&q->strack, 0.2); srslte_sync_set_threshold(&q->strack, 1.2); + } + // When cell is unknown, do CP CFO correction + srslte_sync_set_cfo_cp_enable(&q->sfind, true, q->frame_len<10000?14:3); + q->cfo_correct_enable_find = false; + srslte_ue_sync_reset(q); ret = SRSLTE_SUCCESS; @@ -671,8 +675,6 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { return srslte_ue_sync_zerocopy_multi(q, _input_buffer); } -int track_time, find_time; - /* Returns 1 if the subframe is synchronized in time, 0 otherwise */ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS]) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -697,7 +699,7 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE return SRSLTE_ERROR; } } - if (q->cfo_correct_enable) { + if (q->cfo_correct_enable_track) { for (int i = 0; i < q->nof_rx_antennas; i++) { srslte_cfo_correct(&q->file_cfo_correct, input_buffer[i], @@ -718,14 +720,18 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE return SRSLTE_ERROR; } int n; - struct timeval t[3]; switch (q->state) { case SF_FIND: - gettimeofday(&t[1], NULL); + // Correct CFO before PSS/SSS find using the sync object corrector (initialized for 1 ms) + if (q->cfo_correct_enable_find) { + for (int i=0;inof_rx_antennas;i++) { + srslte_cfo_correct(&q->strack.cfo_corr_frame, + input_buffer[i], + input_buffer[i], + -q->cfo_current_value/q->fft_size); + } + } n = srslte_sync_find(&q->sfind, input_buffer[0], 0, &q->peak_idx); - gettimeofday(&t[2], NULL); - get_time_interval(t); - find_time = t[0].tv_usec; switch(n) { case SRSLTE_SYNC_ERROR: ret = SRSLTE_ERROR; @@ -758,7 +764,7 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE q->sf_idx = (q->sf_idx + q->nof_recv_sf) % 10; // Correct CFO before PSS/SSS tracking using the sync object corrector (initialized for 1 ms) - if (q->cfo_correct_enable) { + if (q->cfo_correct_enable_track) { for (int i=0;inof_rx_antennas;i++) { srslte_cfo_correct(&q->strack.cfo_corr_frame, input_buffer[i], @@ -780,14 +786,9 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE /* Track PSS/SSS around the expected PSS position * In tracking phase, the subframe carrying the PSS is always the last one of the frame */ - track_idx = 0; - gettimeofday(&t[1], NULL); - int n = srslte_sync_find(&q->strack, input_buffer[0], + n = srslte_sync_find(&q->strack, input_buffer[0], q->frame_len - q->sf_len/2 - q->fft_size - q->strack.max_offset/2, &track_idx); - gettimeofday(&t[2], NULL); - get_time_interval(t); - track_time = t[0].tv_usec; switch(n) { case SRSLTE_SYNC_ERROR: diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 6c7ff7717..2d6dd93b7 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -95,7 +95,7 @@ private: void reset(); void radio_error(); bool wait_radio_reset(); - void set_ue_sync_opts(srslte_ue_sync_t *q); + void set_ue_sync_opts(srslte_ue_sync_t *q, float cfo); void run_thread(); void set_sampling_rate(); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 4f70999dd..75f6ae36c 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -182,7 +182,7 @@ void phch_recv::set_time_adv_sec(float _time_adv_sec) } } -void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q) +void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q, float cfo) { if (worker_com->args->cfo_integer_enabled) { srslte_ue_sync_set_cfo_i_enable(q, true); @@ -198,6 +198,14 @@ void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q) q->strack.pss.chest_on_filter = worker_com->args->sic_pss_enabled; + // Disable CP based CFO estimation during find + if (cfo != 0) { + q->cfo_current_value = cfo/15000; + q->cfo_is_copied = true; + q->cfo_correct_enable_find = true; + srslte_sync_set_cfo_cp_enable(&q->sfind, false, 0); + } + int time_correct_period = worker_com->args->time_correct_period; if (time_correct_period > 0) { srslte_ue_sync_set_sample_offset_correct_period(q, time_correct_period); @@ -238,7 +246,7 @@ bool phch_recv::set_cell() { } // Set options defined in expert section - set_ue_sync_opts(&ue_sync); + set_ue_sync_opts(&ue_sync, search_p.get_last_cfo()); // Reset ue_sync and set CFO/gain from search procedure srslte_ue_sync_reset(&ue_sync); @@ -774,11 +782,7 @@ void phch_recv::search::init(cf_t *buffer[SRSLTE_MAX_PORTS], srslte::log *log_h, srslte_ue_cellsearch_set_nof_valid_frames(&cs, 2); // Set options defined in expert section - p->set_ue_sync_opts(&cs.ue_sync); - - if (p->do_agc) { - srslte_ue_sync_start_agc(&cs.ue_sync, callback_set_rx_gain, 40); - } + p->set_ue_sync_opts(&cs.ue_sync, 0); force_N_id_2 = -1; } @@ -859,10 +863,11 @@ phch_recv::search::ret_code phch_recv::search::run(srslte_cell_t *cell) } // Set options defined in expert section - p->set_ue_sync_opts(&ue_mib_sync.ue_sync); + p->set_ue_sync_opts(&ue_mib_sync.ue_sync, cfo); + // Start AGC after initial cell search if (p->do_agc) { - srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, srslte_agc_get_gain(&cs.ue_sync.agc)); + srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, p->radio_h->get_rx_gain()); } srslte_ue_sync_reset(&ue_mib_sync.ue_sync); @@ -1211,7 +1216,6 @@ void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled) // Configure FIND object behaviour (this configuration is always the same) srslte_sync_set_cfo_ema_alpha(&sync_find, 1.0); srslte_sync_set_cfo_i_enable(&sync_find, false); - srslte_sync_set_cfo_cp_enable(&sync_find, false); srslte_sync_set_cfo_pss_enable(&sync_find, true); srslte_sync_set_pss_filt_enable(&sync_find, true); srslte_sync_set_sss_eq_enable(&sync_find, true);