From 48dfc08fa3d84e7d58cc2242511b31fdaeea6dc8 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sun, 3 Dec 2017 22:13:07 -0600 Subject: [PATCH] Fixed SIC for PSS using channel estimates, added option to disable it (not usable on synchronous same-site cells). Use PSS CE in SSS decoding --- lib/examples/pdsch_ue.c | 2 +- lib/examples/synch_file.c | 28 +-- lib/include/srslte/interfaces/ue_interfaces.h | 1 + lib/include/srslte/phy/sync/pss.h | 44 +++-- lib/include/srslte/phy/sync/sss.h | 28 +-- lib/include/srslte/phy/sync/sync.h | 14 +- lib/src/phy/sync/find_sss.c | 10 +- lib/src/phy/sync/pss.c | 98 ++++++---- lib/src/phy/sync/sss.c | 22 +-- lib/src/phy/sync/sync.c | 72 +++---- lib/src/phy/sync/test/pss_file.c | 42 ++-- lib/src/phy/sync/test/pss_mex.c | 12 +- lib/src/phy/sync/test/pss_usrp.c | 44 ++--- lib/src/phy/sync/test/sss_mex.c | 20 +- lib/src/phy/ue/ue_sync.c | 4 +- srsue/hdr/phy/phch_recv.h | 5 +- srsue/src/mac/proc_ra.cc | 8 +- srsue/src/main.cc | 5 +- srsue/src/phy/phch_recv.cc | 182 +++++++++--------- srsue/src/upper/rrc.cc | 4 +- srsue/ue.conf.example | 5 + 21 files changed, 341 insertions(+), 309 deletions(-) diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index ae43a5260..6293d0e70 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -998,7 +998,7 @@ void *plot_thread_run(void *arg) { if (!prog_args.input_file_name) { if (plot_track) { - srslte_pss_synch_t *pss_obj = srslte_sync_get_cur_pss_obj(&ue_sync.strack); + srslte_pss_t *pss_obj = srslte_sync_get_cur_pss_obj(&ue_sync.strack); int max = srslte_vec_max_fi(pss_obj->conv_output_avg, pss_obj->frame_size+pss_obj->fft_size-1); srslte_vec_sc_prod_fff(pss_obj->conv_output_avg, 1/pss_obj->conv_output_avg[max], diff --git a/lib/examples/synch_file.c b/lib/examples/synch_file.c index 178e56e99..4d553bd38 100644 --- a/lib/examples/synch_file.c +++ b/lib/examples/synch_file.c @@ -102,8 +102,8 @@ void parse_args(int argc, char **argv) { int main(int argc, char **argv) { srslte_filesource_t fsrc; srslte_filesink_t fsink; - srslte_pss_synch_t pss[3]; // One for each N_id_2 - srslte_sss_synch_t sss[3]; // One for each N_id_2 + srslte_pss_t pss[3]; // One for each N_id_2 + srslte_sss_t sss[3]; // One for each N_id_2 srslte_cfo_t cfocorr; int peak_pos[3]; float *cfo; @@ -163,19 +163,19 @@ int main(int argc, char **argv) { * a) requries more memory but has less latency and is paralellizable. */ for (N_id_2=0;N_id_2<3;N_id_2++) { - if (srslte_pss_synch_init(&pss[N_id_2], frame_length)) { + if (srslte_pss_init(&pss[N_id_2], frame_length)) { fprintf(stderr, "Error initializing PSS object\n"); exit(-1); } - if (srslte_pss_synch_set_N_id_2(&pss[N_id_2], N_id_2)) { + if (srslte_pss_set_N_id_2(&pss[N_id_2], N_id_2)) { fprintf(stderr, "Error initializing N_id_2\n"); exit(-1); } - if (srslte_sss_synch_init(&sss[N_id_2], 128)) { + if (srslte_sss_init(&sss[N_id_2], 128)) { fprintf(stderr, "Error initializing SSS object\n"); exit(-1); } - if (srslte_sss_synch_set_N_id_2(&sss[N_id_2], N_id_2)) { + if (srslte_sss_set_N_id_2(&sss[N_id_2], N_id_2)) { fprintf(stderr, "Error initializing N_id_2\n"); exit(-1); } @@ -199,10 +199,10 @@ int main(int argc, char **argv) { if (force_N_id_2 != -1) { N_id_2 = force_N_id_2; - peak_pos[N_id_2] = srslte_pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]); + peak_pos[N_id_2] = srslte_pss_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]); } else { for (N_id_2=0;N_id_2<3;N_id_2++) { - peak_pos[N_id_2] = srslte_pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]); + peak_pos[N_id_2] = srslte_pss_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]); } float max_value=-99999; N_id_2=-1; @@ -220,13 +220,13 @@ int main(int argc, char **argv) { sss_idx = peak_pos[N_id_2]-2*(symbol_sz+SRSLTE_CP_LEN(symbol_sz,SRSLTE_CP_NORM_LEN)); if (sss_idx >= 0) { - srslte_sss_synch_m0m1_diff(&sss[N_id_2], &input[sss_idx], + srslte_sss_m0m1_diff(&sss[N_id_2], &input[sss_idx], &m0, &m0_value, &m1, &m1_value); - cfo[frame_cnt] = srslte_pss_synch_cfo_compute(&pss[N_id_2], &input[peak_pos[N_id_2]-128]); + cfo[frame_cnt] = srslte_pss_cfo_compute(&pss[N_id_2], &input[peak_pos[N_id_2]-128]); printf("\t%d\t%d\t%d\t%d\t%.3f\t\t%3d\t%d\t%d\t%.3f\n", - frame_cnt,N_id_2, srslte_sss_synch_N_id_1(&sss[N_id_2], m0, m1), - srslte_sss_synch_subframe(m0, m1), peak_value[N_id_2], + frame_cnt,N_id_2, srslte_sss_N_id_1(&sss[N_id_2], m0, m1), + srslte_sss_subframe(m0, m1), peak_value[N_id_2], peak_pos[N_id_2], m0, m1, cfo[frame_cnt]); } @@ -254,8 +254,8 @@ int main(int argc, char **argv) { printf("Average CFO: %.3f\n", cfo_mean); for (N_id_2=0;N_id_2<3;N_id_2++) { - srslte_pss_synch_free(&pss[N_id_2]); - srslte_sss_synch_free(&sss[N_id_2]); + srslte_pss_free(&pss[N_id_2]); + srslte_sss_free(&sss[N_id_2]); } srslte_filesource_free(&fsrc); diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 540ccb715..e8a33c207 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -488,6 +488,7 @@ typedef struct { std::string sss_algorithm; float estimator_fil_w; bool rssi_sensor_enabled; + bool sic_pss_enabled; } phy_args_t; diff --git a/lib/include/srslte/phy/sync/pss.h b/lib/include/srslte/phy/sync/pss.h index aba84f5cd..922bc0286 100644 --- a/lib/include/srslte/phy/sync/pss.h +++ b/lib/include/srslte/phy/sync/pss.h @@ -29,9 +29,9 @@ * * Description: Primary synchronization signal (PSS) generation and detection. * - * The srslte_pss_synch_t object provides functions for fast + * The srslte_pss_t object provides functions for fast * computation of the crosscorrelation between the PSS and received - * signal and CFO estimation. Also, the function srslte_pss_synch_tperiodic() + * signal and CFO estimation. Also, the function srslte_pss_tperiodic() * is designed to be called periodically every subframe, taking * care of the correct data alignment with respect to the PSS sequence. * @@ -61,7 +61,7 @@ /* PSS processing options */ -#define SRSLTE_PSS_ACCUMULATE_ABS // If enabled, accumulates the correlation absolute value on consecutive calls to srslte_pss_synch_find_pss +#define SRSLTE_PSS_ACCUMULATE_ABS // If enabled, accumulates the correlation absolute value on consecutive calls to srslte_pss_find_pss #define SRSLTE_PSS_RETURN_PSR // If enabled returns peak to side-lobe ratio, otherwise returns absolute peak value @@ -85,6 +85,7 @@ typedef struct SRSLTE_API { cf_t *pss_signal_freq_full[3]; cf_t *pss_signal_time[3]; + cf_t *pss_signal_time_scale[3]; cf_t pss_signal_freq[3][SRSLTE_PSS_LEN]; // One sequence for each N_id_2 cf_t *tmp_input; @@ -100,41 +101,48 @@ typedef struct SRSLTE_API { cf_t tmp_fft[SRSLTE_SYMBOL_SZ_MAX]; cf_t tmp_fft2[SRSLTE_SYMBOL_SZ_MAX]; -}srslte_pss_synch_t; + cf_t tmp_ce[SRSLTE_PSS_LEN]; + + bool chest_on_filter; + +}srslte_pss_t; typedef enum { PSS_TX, PSS_RX } pss_direction_t; /* Basic functionality */ -SRSLTE_API int srslte_pss_synch_init_fft(srslte_pss_synch_t *q, +SRSLTE_API int srslte_pss_init_fft(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size); -SRSLTE_API int srslte_pss_synch_init_fft_offset(srslte_pss_synch_t *q, +SRSLTE_API int srslte_pss_init_fft_offset(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size, int cfo_i); -SRSLTE_API int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q, +SRSLTE_API int srslte_pss_init_fft_offset_decim(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size, int cfo_i, int decimate); -SRSLTE_API int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, +SRSLTE_API int srslte_pss_resize(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size, int offset); -SRSLTE_API int srslte_pss_synch_init(srslte_pss_synch_t *q, +SRSLTE_API int srslte_pss_init(srslte_pss_t *q, uint32_t frame_size); -SRSLTE_API void srslte_pss_synch_free(srslte_pss_synch_t *q); +SRSLTE_API void srslte_pss_free(srslte_pss_t *q); -SRSLTE_API void srslte_pss_synch_reset(srslte_pss_synch_t *q); +SRSLTE_API void srslte_pss_reset(srslte_pss_t *q); -SRSLTE_API void srslte_pss_synch_filter_enable(srslte_pss_synch_t *q, +SRSLTE_API void srslte_pss_filter_enable(srslte_pss_t *q, bool enable); -SRSLTE_API void srslte_pss_synch_filter(srslte_pss_synch_t *q, +SRSLTE_API void srslte_pss_sic(srslte_pss_t *q, + cf_t *input); + +SRSLTE_API void srslte_pss_filter(srslte_pss_t *q, const cf_t *input, cf_t *output); @@ -151,21 +159,21 @@ SRSLTE_API void srslte_pss_put_slot(cf_t *pss_signal, uint32_t nof_prb, srslte_cp_t cp); -SRSLTE_API void srslte_pss_synch_set_ema_alpha(srslte_pss_synch_t *q, +SRSLTE_API void srslte_pss_set_ema_alpha(srslte_pss_t *q, float alpha); -SRSLTE_API int srslte_pss_synch_set_N_id_2(srslte_pss_synch_t *q, +SRSLTE_API int srslte_pss_set_N_id_2(srslte_pss_t *q, uint32_t N_id_2); -SRSLTE_API int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, +SRSLTE_API int srslte_pss_find_pss(srslte_pss_t *q, const cf_t *input, float *corr_peak_value); -SRSLTE_API int srslte_pss_synch_chest(srslte_pss_synch_t *q, +SRSLTE_API int srslte_pss_chest(srslte_pss_t *q, const cf_t *input, cf_t ce[SRSLTE_PSS_LEN]); -SRSLTE_API float srslte_pss_synch_cfo_compute(srslte_pss_synch_t* q, +SRSLTE_API float srslte_pss_cfo_compute(srslte_pss_t* q, const cf_t *pss_recv); #endif // PSS_ diff --git a/lib/include/srslte/phy/sync/sss.h b/lib/include/srslte/phy/sync/sss.h index 4a0942d61..9f77d1ce6 100644 --- a/lib/include/srslte/phy/sync/sss.h +++ b/lib/include/srslte/phy/sync/sss.h @@ -83,17 +83,17 @@ typedef struct SRSLTE_API { float corr_output_m0[SRSLTE_SSS_N]; float corr_output_m1[SRSLTE_SSS_N]; -}srslte_sss_synch_t; +}srslte_sss_t; /* Basic functionality */ -SRSLTE_API int srslte_sss_synch_init(srslte_sss_synch_t *q, +SRSLTE_API int srslte_sss_init(srslte_sss_t *q, uint32_t fft_size); -SRSLTE_API int srslte_sss_synch_resize(srslte_sss_synch_t *q, +SRSLTE_API int srslte_sss_resize(srslte_sss_t *q, uint32_t fft_size); -SRSLTE_API void srslte_sss_synch_free(srslte_sss_synch_t *q); +SRSLTE_API void srslte_sss_free(srslte_sss_t *q); SRSLTE_API void srslte_sss_generate(float *signal0, float *signal5, @@ -104,10 +104,10 @@ SRSLTE_API void srslte_sss_put_slot(float *sss, uint32_t nof_prb, srslte_cp_t cp); -SRSLTE_API int srslte_sss_synch_set_N_id_2(srslte_sss_synch_t *q, +SRSLTE_API int srslte_sss_set_N_id_2(srslte_sss_t *q, uint32_t N_id_2); -SRSLTE_API int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q, +SRSLTE_API int srslte_sss_m0m1_partial(srslte_sss_t *q, const cf_t *input, uint32_t M, cf_t ce[2*SRSLTE_SSS_N], @@ -116,7 +116,7 @@ SRSLTE_API int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q, uint32_t *m1, float *m1_value); -SRSLTE_API int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, +SRSLTE_API int srslte_sss_m0m1_diff_coh(srslte_sss_t *q, const cf_t *input, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, @@ -124,7 +124,7 @@ SRSLTE_API int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, uint32_t *m1, float *m1_value); -SRSLTE_API int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, +SRSLTE_API int srslte_sss_m0m1_diff(srslte_sss_t *q, const cf_t *input, uint32_t *m0, float *m0_value, @@ -132,25 +132,25 @@ SRSLTE_API int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, float *m1_value); -SRSLTE_API uint32_t srslte_sss_synch_subframe(uint32_t m0, +SRSLTE_API uint32_t srslte_sss_subframe(uint32_t m0, uint32_t m1); -SRSLTE_API int srslte_sss_synch_N_id_1(srslte_sss_synch_t *q, +SRSLTE_API int srslte_sss_N_id_1(srslte_sss_t *q, uint32_t m0, uint32_t m1); -SRSLTE_API int srslte_sss_synch_frame(srslte_sss_synch_t *q, +SRSLTE_API int srslte_sss_frame(srslte_sss_t *q, cf_t *input, uint32_t *subframe_idx, uint32_t *N_id_1); -SRSLTE_API void srslte_sss_synch_set_threshold(srslte_sss_synch_t *q, +SRSLTE_API void srslte_sss_set_threshold(srslte_sss_t *q, float threshold); -SRSLTE_API void srslte_sss_synch_set_symbol_sz(srslte_sss_synch_t *q, +SRSLTE_API void srslte_sss_set_symbol_sz(srslte_sss_t *q, uint32_t symbol_sz); -SRSLTE_API void srslte_sss_synch_set_subframe_sz(srslte_sss_synch_t *q, +SRSLTE_API void srslte_sss_set_subframe_sz(srslte_sss_t *q, uint32_t subframe_sz); #endif // SSS_ diff --git a/lib/include/srslte/phy/sync/sync.h b/lib/include/srslte/phy/sync/sync.h index 151c530b1..3146761ce 100644 --- a/lib/include/srslte/phy/sync/sync.h +++ b/lib/include/srslte/phy/sync/sync.h @@ -60,9 +60,9 @@ typedef enum {SSS_DIFF=0, SSS_PARTIAL_3=2, SSS_FULL=1} sss_alg_t; typedef struct SRSLTE_API { - srslte_pss_synch_t pss; - srslte_pss_synch_t pss_i[2]; - srslte_sss_synch_t sss; + srslte_pss_t pss; + srslte_pss_t pss_i[2]; + srslte_sss_t sss; srslte_cp_synch_t cp_synch; cf_t *cfo_i_corr[2]; int decimate; @@ -110,7 +110,7 @@ typedef struct SRSLTE_API { srslte_cfo_t cfo_corr_frame; srslte_cfo_t cfo_corr_symbol; - bool sss_filtering_enabled; + bool sss_channel_equalize; bool pss_filtering_enabled; cf_t sss_filt[SRSLTE_SYMBOL_SZ_MAX]; cf_t pss_filt[SRSLTE_SYMBOL_SZ_MAX]; @@ -186,8 +186,8 @@ SRSLTE_API int srslte_sync_get_cell_id(srslte_sync_t *q); SRSLTE_API void srslte_sync_set_pss_filt_enable(srslte_sync_t *q, bool enable); -SRSLTE_API void srslte_sync_set_sss_filt_enable(srslte_sync_t *q, - bool enable); +SRSLTE_API void srslte_sync_set_sss_eq_enable(srslte_sync_t *q, + bool enable); /* Gets the CFO estimation from the last call to synch_run() */ SRSLTE_API float srslte_sync_get_cfo(srslte_sync_t *q); @@ -227,7 +227,7 @@ SRSLTE_API void srslte_sync_set_cp(srslte_sync_t *q, SRSLTE_API void srslte_sync_sss_en(srslte_sync_t *q, bool enabled); -SRSLTE_API srslte_pss_synch_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q); +SRSLTE_API srslte_pss_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q); SRSLTE_API bool srslte_sync_sss_detected(srslte_sync_t *q); diff --git a/lib/src/phy/sync/find_sss.c b/lib/src/phy/sync/find_sss.c index 70b300bd3..6695d70c2 100644 --- a/lib/src/phy/sync/find_sss.c +++ b/lib/src/phy/sync/find_sss.c @@ -68,7 +68,7 @@ static void corr_all_sz_partial(cf_t z[SRSLTE_SSS_N], float s[SRSLTE_SSS_N][SRSL } } -static void extract_pair_sss(srslte_sss_synch_t *q, const cf_t *input, cf_t *ce, cf_t y[2][SRSLTE_SSS_N]) { +static void extract_pair_sss(srslte_sss_t *q, const cf_t *input, cf_t *ce, cf_t y[2][SRSLTE_SSS_N]) { cf_t input_fft[SRSLTE_SYMBOL_SZ_MAX]; srslte_dft_run_c(&q->dftp_input, input, input_fft); @@ -88,10 +88,10 @@ static void extract_pair_sss(srslte_sss_synch_t *q, const cf_t *input, cf_t *ce, } -int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, const cf_t *input, uint32_t *m0, float *m0_value, +int srslte_sss_m0m1_diff(srslte_sss_t *q, const cf_t *input, uint32_t *m0, float *m0_value, uint32_t *m1, float *m1_value) { - return srslte_sss_synch_m0m1_diff_coh(q, input, NULL, m0, m0_value, m1, m1_value); + return srslte_sss_m0m1_diff_coh(q, input, NULL, m0, m0_value, m1, m1_value); } /* Differential SSS estimation. @@ -102,7 +102,7 @@ int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, const cf_t *input, uint32_ * */ -int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, const cf_t *input, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, +int srslte_sss_m0m1_diff_coh(srslte_sss_t *q, const cf_t *input, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, uint32_t *m1, float *m1_value) { @@ -145,7 +145,7 @@ int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, const cf_t *input, cf_ * Jung-In Kim, Jung-Su Han, Hee-Jin Roh and Hyung-Jin Choi */ -int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q, const cf_t *input, uint32_t M, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, +int srslte_sss_m0m1_partial(srslte_sss_t *q, const cf_t *input, uint32_t M, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, uint32_t *m1, float *m1_value) { diff --git a/lib/src/phy/sync/pss.c b/lib/src/phy/sync/pss.c index d93fe0896..1f56dfda9 100644 --- a/lib/src/phy/sync/pss.c +++ b/lib/src/phy/sync/pss.c @@ -35,7 +35,7 @@ #include "srslte/phy/utils/debug.h" -int srslte_pss_synch_init_N_id_2(cf_t *pss_signal_freq, cf_t *pss_signal_time, +int srslte_pss_init_N_id_2(cf_t *pss_signal_freq, cf_t *pss_signal_time, uint32_t N_id_2, uint32_t fft_size, int cfo_i) { srslte_dft_plan_t plan; cf_t pss_signal_pad[2048]; @@ -73,16 +73,16 @@ int srslte_pss_synch_init_N_id_2(cf_t *pss_signal_freq, cf_t *pss_signal_time, /* Initializes the PSS synchronization object with fft_size=128 */ -int srslte_pss_synch_init(srslte_pss_synch_t *q, uint32_t frame_size) { - return srslte_pss_synch_init_fft(q, frame_size, 128); +int srslte_pss_init(srslte_pss_t *q, uint32_t frame_size) { + return srslte_pss_init_fft(q, frame_size, 128); } -int srslte_pss_synch_init_fft(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t fft_size) { - return srslte_pss_synch_init_fft_offset(q, frame_size, fft_size, 0); +int srslte_pss_init_fft(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size) { + return srslte_pss_init_fft_offset(q, frame_size, fft_size, 0); } -int srslte_pss_synch_init_fft_offset(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t fft_size, int offset) { - return srslte_pss_synch_init_fft_offset_decim(q, frame_size, fft_size, offset, 1); +int srslte_pss_init_fft_offset(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size, int offset) { + return srslte_pss_init_fft_offset_decim(q, frame_size, fft_size, offset, 1); } /* Initializes the PSS synchronization object. @@ -90,7 +90,7 @@ int srslte_pss_synch_init_fft_offset(srslte_pss_synch_t *q, uint32_t frame_size, * It correlates a signal of frame_size samples with the PSS sequence in the frequency * domain. The PSS sequence is transformed using fft_size samples. */ -int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q, +int srslte_pss_init_fft_offset_decim(srslte_pss_t *q, uint32_t max_frame_size, uint32_t max_fft_size, int offset, int decimate) { @@ -102,7 +102,7 @@ int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q, uint32_t N_id_2; uint32_t buffer_size; - bzero(q, sizeof(srslte_pss_synch_t)); + bzero(q, sizeof(srslte_pss_t)); q->N_id_2 = 10; q->ema_alpha = 0.2; @@ -143,7 +143,7 @@ int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q, } srslte_dft_plan_set_mirror(&q->idftp_input, true); srslte_dft_plan_set_dc(&q->idftp_input, true); - srslte_dft_plan_set_norm(&q->idftp_input, true); + srslte_dft_plan_set_norm(&q->idftp_input, false); bzero(q->tmp_fft2, sizeof(cf_t)*SRSLTE_SYMBOL_SZ_MAX); @@ -183,7 +183,7 @@ int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q, goto clean_and_exit; } /* The PSS is translated into the time domain for each N_id_2 */ - if (srslte_pss_synch_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { + if (srslte_pss_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { fprintf(stderr, "Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); goto clean_and_exit; } @@ -192,27 +192,25 @@ int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q, #ifdef CONVOLUTION_FFT - for(N_id_2=0; N_id_2<3; N_id_2++) - q->pss_signal_freq_full[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t)); - if (srslte_conv_fft_cc_init(&q->conv_fft, frame_size, fft_size)) { fprintf(stderr, "Error initiating convolution FFT\n"); goto clean_and_exit; } - for(int i=0; i<3; i++) { - srslte_dft_run_c(&q->conv_fft.filter_plan, q->pss_signal_time[i], q->pss_signal_freq_full[i]); + for(N_id_2=0; N_id_2<3; N_id_2++) { + q->pss_signal_freq_full[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t)); + srslte_dft_run_c(&q->conv_fft.filter_plan, q->pss_signal_time[N_id_2], q->pss_signal_freq_full[N_id_2]); } #endif - srslte_pss_synch_reset(q); + srslte_pss_reset(q); ret = SRSLTE_SUCCESS; } clean_and_exit: if (ret == SRSLTE_ERROR) { - srslte_pss_synch_free(q); + srslte_pss_free(q); } return ret; @@ -224,7 +222,7 @@ clean_and_exit: * It correlates a signal of frame_size samples with the PSS sequence in the frequency * domain. The PSS sequence is transformed using fft_size samples. */ -int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t fft_size, int offset) { +int srslte_pss_resize(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size, int offset) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -233,7 +231,7 @@ int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t ret = SRSLTE_ERROR; if (fft_size > q->max_fft_size || frame_size > q->max_frame_size) { - fprintf(stderr, "Error in pss_synch_config(): fft_size and frame_size must be lower than initialized\n"); + fprintf(stderr, "Error in pss_config(): fft_size and frame_size must be lower than initialized\n"); return SRSLTE_ERROR; } @@ -273,7 +271,7 @@ int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t // Generate PSS sequences for this FFT size for (N_id_2=0;N_id_2<3;N_id_2++) { - if (srslte_pss_synch_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { + if (srslte_pss_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { fprintf(stderr, "Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); return SRSLTE_ERROR; } @@ -291,7 +289,7 @@ int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t #endif - srslte_pss_synch_reset(q); + srslte_pss_reset(q); ret = SRSLTE_SUCCESS; } @@ -299,7 +297,7 @@ int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t } -void srslte_pss_synch_free(srslte_pss_synch_t *q) { +void srslte_pss_free(srslte_pss_t *q) { uint32_t i; if (q) { @@ -339,11 +337,11 @@ void srslte_pss_synch_free(srslte_pss_synch_t *q) { } - bzero(q, sizeof(srslte_pss_synch_t)); + bzero(q, sizeof(srslte_pss_t)); } } -void srslte_pss_synch_reset(srslte_pss_synch_t *q) { +void srslte_pss_reset(srslte_pss_t *q) { uint32_t buffer_size = q->fft_size + q->frame_size + 1; bzero(q->conv_output_avg, sizeof(float) * buffer_size); } @@ -401,7 +399,7 @@ void srslte_pss_get_slot(cf_t *slot, cf_t *pss_signal, uint32_t nof_prb, srslte_ /** Sets the current N_id_2 value. Returns -1 on error, 0 otherwise */ -int srslte_pss_synch_set_N_id_2(srslte_pss_synch_t *q, uint32_t N_id_2) { +int srslte_pss_set_N_id_2(srslte_pss_t *q, uint32_t N_id_2) { if (!srslte_N_id_2_isvalid((N_id_2))) { fprintf(stderr, "Invalid N_id_2 %d\n", N_id_2); return -1; @@ -413,11 +411,11 @@ int srslte_pss_synch_set_N_id_2(srslte_pss_synch_t *q, uint32_t N_id_2) { /* Sets the weight factor alpha for the exponential moving average of the PSS correlation output */ -void srslte_pss_synch_set_ema_alpha(srslte_pss_synch_t *q, float alpha) { +void srslte_pss_set_ema_alpha(srslte_pss_t *q, float alpha) { q->ema_alpha = alpha; } -float compute_peak_sidelobe(srslte_pss_synch_t *q, uint32_t corr_peak_pos, uint32_t conv_output_len) +float compute_peak_sidelobe(srslte_pss_t *q, uint32_t corr_peak_pos, uint32_t conv_output_len) { // Find end of peak lobe to the right int pl_ub = corr_peak_pos+1; @@ -455,7 +453,7 @@ float compute_peak_sidelobe(srslte_pss_synch_t *q, uint32_t corr_peak_pos, uint3 * * Input buffer must be subframe_size long. */ -int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, const cf_t *input, float *corr_peak_value) +int srslte_pss_find_pss(srslte_pss_t *q, const cf_t *input, float *corr_peak_value) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -474,7 +472,7 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, const cf_t *input, float *c /* Correlate input with PSS sequence * * We do not reverse time-domain PSS signal because it's conjugate is symmetric. - * The conjugate operation on pss_signal_time has been done in srslte_pss_synch_init_N_id_2 + * The conjugate operation on pss_signal_time has been done in srslte_pss_init_N_id_2 * This is why we can use FFT-based convolution */ if (q->frame_size >= q->fft_size) { @@ -545,9 +543,8 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, const cf_t *input, float *c * input signal is in the time-domain. * ce is the returned frequency-domain channel estimates. */ -int srslte_pss_synch_chest(srslte_pss_synch_t *q, const cf_t *input, cf_t ce[SRSLTE_PSS_LEN]) { +int srslte_pss_chest(srslte_pss_t *q, const cf_t *input, cf_t ce[SRSLTE_PSS_LEN]) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - cf_t input_fft[SRSLTE_SYMBOL_SZ_MAX]; if (q != NULL && input != NULL) @@ -559,18 +556,41 @@ int srslte_pss_synch_chest(srslte_pss_synch_t *q, const cf_t *input, cf_t ce[SRS } /* Transform to frequency-domain */ - srslte_dft_run_c(&q->dftp_input, input, input_fft); + srslte_dft_run_c(&q->dftp_input, input, q->tmp_fft); /* Compute channel estimate taking the PSS sequence as reference */ - srslte_vec_prod_conj_ccc(&input_fft[(q->fft_size-SRSLTE_PSS_LEN)/2], q->pss_signal_freq[q->N_id_2], ce, SRSLTE_PSS_LEN); + srslte_vec_prod_conj_ccc(&q->tmp_fft[(q->fft_size-SRSLTE_PSS_LEN)/2], q->pss_signal_freq[q->N_id_2], ce, SRSLTE_PSS_LEN); ret = SRSLTE_SUCCESS; } return ret; } +/* input points to beginning of last OFDM symbol of slot 0 of subframe 0 or 5 + * It must be called after calling srslte_pss_cfo_compute() with filter enabled + */ +void srslte_pss_sic(srslte_pss_t *q, cf_t *input) { + if (q->chest_on_filter) { + + bzero(q->tmp_fft, sizeof(cf_t)*q->fft_size); + + // Pass transmitted PSS sequence through the channel + srslte_vec_prod_ccc(q->pss_signal_freq[q->N_id_2], q->tmp_ce, &q->tmp_fft[(q->fft_size-SRSLTE_PSS_LEN)/2], SRSLTE_PSS_LEN); + + // Get time-domain version of the received PSS + srslte_dft_run_c(&q->idftp_input, q->tmp_fft, q->tmp_fft2); + + // Substract received PSS from this N_id_2 from the input signal + srslte_vec_sc_prod_cfc(q->tmp_fft2, 1.0/q->fft_size, q->tmp_fft2, q->fft_size); + srslte_vec_sub_ccc(input, q->tmp_fft2, input, q->fft_size); + + } else { + fprintf(stderr, "Error calling srslte_pss_sic(): need to enable channel estimation on filtering\n"); + } +} + // Frequency-domain filtering of the central 64 sub-carriers -void srslte_pss_synch_filter(srslte_pss_synch_t *q, const cf_t *input, cf_t *output) +void srslte_pss_filter(srslte_pss_t *q, const cf_t *input, cf_t *output) { srslte_dft_run_c(&q->dftp_input, input, q->tmp_fft); @@ -578,6 +598,10 @@ void srslte_pss_synch_filter(srslte_pss_synch_t *q, const cf_t *input, cf_t *out &q->tmp_fft[q->fft_size/2-SRSLTE_PSS_LEN/2], sizeof(cf_t)*SRSLTE_PSS_LEN); + if (q->chest_on_filter) { + srslte_vec_prod_conj_ccc(&q->tmp_fft[(q->fft_size-SRSLTE_PSS_LEN)/2], q->pss_signal_freq[q->N_id_2], q->tmp_ce, SRSLTE_PSS_LEN); + } + srslte_dft_run_c(&q->idftp_input, q->tmp_fft2, output); } @@ -586,13 +610,13 @@ void srslte_pss_synch_filter(srslte_pss_synch_t *q, const cf_t *input, cf_t *out * Source: An Efficient CFO Estimation Algorithm for the Downlink of 3GPP-LTE * Feng Wang and Yu Zhu */ -float srslte_pss_synch_cfo_compute(srslte_pss_synch_t* q, const cf_t *pss_recv) { +float srslte_pss_cfo_compute(srslte_pss_t* q, const cf_t *pss_recv) { cf_t y0, y1; const cf_t *pss_ptr = pss_recv; if (q->filter_pss_enable) { - srslte_pss_synch_filter(q, pss_recv, q->tmp_fft); + srslte_pss_filter(q, pss_recv, q->tmp_fft); pss_ptr = (const cf_t*) q->tmp_fft; } diff --git a/lib/src/phy/sync/sss.c b/lib/src/phy/sync/sss.c index 4ed7b1d6c..31091bdb3 100644 --- a/lib/src/phy/sync/sss.c +++ b/lib/src/phy/sync/sss.c @@ -40,7 +40,7 @@ void generate_sss_all_tables(srslte_sss_tables_t *tables, uint32_t N_id_2); void convert_tables(srslte_sss_fc_tables_t *fc_tables, srslte_sss_tables_t *in); void generate_N_id_1_table(uint32_t table[30][30]); -int srslte_sss_synch_init(srslte_sss_synch_t *q, uint32_t fft_size) { +int srslte_sss_init(srslte_sss_t *q, uint32_t fft_size) { if (q != NULL && fft_size <= 2048) @@ -48,10 +48,10 @@ int srslte_sss_synch_init(srslte_sss_synch_t *q, uint32_t fft_size) { uint32_t N_id_2; srslte_sss_tables_t sss_tables; - bzero(q, sizeof(srslte_sss_synch_t)); + bzero(q, sizeof(srslte_sss_t)); if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { - srslte_sss_synch_free(q); + srslte_sss_free(q); return SRSLTE_ERROR; } srslte_dft_plan_set_mirror(&q->dftp_input, true); @@ -72,7 +72,7 @@ int srslte_sss_synch_init(srslte_sss_synch_t *q, uint32_t fft_size) { return SRSLTE_ERROR_INVALID_INPUTS; } -int srslte_sss_synch_resize(srslte_sss_synch_t *q, uint32_t fft_size) { +int srslte_sss_resize(srslte_sss_t *q, uint32_t fft_size) { if (q != NULL && fft_size <= 2048) { @@ -81,7 +81,7 @@ int srslte_sss_synch_resize(srslte_sss_synch_t *q, uint32_t fft_size) { return SRSLTE_ERROR; } if (srslte_dft_replan(&q->dftp_input, fft_size)) { - srslte_sss_synch_free(q); + srslte_sss_free(q); return SRSLTE_ERROR; } q->fft_size = fft_size; @@ -90,13 +90,13 @@ int srslte_sss_synch_resize(srslte_sss_synch_t *q, uint32_t fft_size) { return SRSLTE_ERROR_INVALID_INPUTS; } -void srslte_sss_synch_free(srslte_sss_synch_t *q) { +void srslte_sss_free(srslte_sss_t *q) { srslte_dft_plan_free(&q->dftp_input); - bzero(q, sizeof(srslte_sss_synch_t)); + bzero(q, sizeof(srslte_sss_t)); } /** Sets the N_id_2 to search for */ -int srslte_sss_synch_set_N_id_2(srslte_sss_synch_t *q, uint32_t N_id_2) { +int srslte_sss_set_N_id_2(srslte_sss_t *q, uint32_t N_id_2) { if (!srslte_N_id_2_isvalid(N_id_2)) { fprintf(stderr, "Invalid N_id_2 %d\n", N_id_2); return SRSLTE_ERROR; @@ -124,12 +124,12 @@ void srslte_sss_put_slot(float *sss, cf_t *slot, uint32_t nof_prb, srslte_cp_t c } /** Sets the SSS correlation peak detection threshold */ -void srslte_sss_synch_set_threshold(srslte_sss_synch_t *q, float threshold) { +void srslte_sss_set_threshold(srslte_sss_t *q, float threshold) { q->corr_peak_threshold = threshold; } /** Returns the subframe index based on the m0 and m1 values */ -uint32_t srslte_sss_synch_subframe(uint32_t m0, uint32_t m1) { +uint32_t srslte_sss_subframe(uint32_t m0, uint32_t m1) { if (m1 > m0) { return 0; } else { @@ -138,7 +138,7 @@ uint32_t srslte_sss_synch_subframe(uint32_t m0, uint32_t m1) { } /** Returns the N_id_1 value based on the m0 and m1 values */ -int srslte_sss_synch_N_id_1(srslte_sss_synch_t *q, uint32_t m0, uint32_t m1) { +int srslte_sss_N_id_1(srslte_sss_t *q, uint32_t m0, uint32_t m1) { int N_id_1 = -1; if (m1 > m0) { if (m0 < 30 && m1 - 1 < 30) { diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index a74be30d6..13a5f7e69 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -77,7 +77,6 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o q->cfo_cp_enable = false; q->cfo_i_initiated = false; q->pss_filtering_enabled = false; - q->sss_filtering_enabled = false; q->fft_size = fft_size; q->frame_size = frame_size; @@ -119,11 +118,11 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o decimate = 1; } - if (srslte_pss_synch_init_fft_offset_decim(&q->pss, max_offset, fft_size, 0, decimate)) { + if (srslte_pss_init_fft_offset_decim(&q->pss, max_offset, fft_size, 0, decimate)) { fprintf(stderr, "Error initializing PSS object\n"); goto clean_exit; } - if (srslte_sss_synch_init(&q->sss, fft_size)) { + if (srslte_sss_init(&q->sss, fft_size)) { fprintf(stderr, "Error initializing SSS object\n"); goto clean_exit; } @@ -151,8 +150,8 @@ void srslte_sync_free(srslte_sync_t *q) { if (q) { - srslte_pss_synch_free(&q->pss); - srslte_sss_synch_free(&q->sss); + srslte_pss_free(&q->pss); + srslte_sss_free(&q->sss); srslte_cfo_free(&q->cfo_corr_frame); srslte_cfo_free(&q->cfo_corr_symbol); srslte_cp_synch_free(&q->cp_synch); @@ -162,7 +161,7 @@ void srslte_sync_free(srslte_sync_t *q) if (q->cfo_i_corr[i]) { free(q->cfo_i_corr[i]); } - srslte_pss_synch_free(&q->pss_i[i]); + srslte_pss_free(&q->pss_i[i]); } } if (q->temp) { @@ -188,11 +187,11 @@ int srslte_sync_resize(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offse q->frame_size = frame_size; q->max_offset = max_offset; - if (srslte_pss_synch_resize(&q->pss, q->max_offset, q->fft_size, 0)) { + if (srslte_pss_resize(&q->pss, q->max_offset, q->fft_size, 0)) { fprintf(stderr, "Error resizing PSS object\n"); return SRSLTE_ERROR; } - if (srslte_sss_synch_resize(&q->sss, q->fft_size)) { + if (srslte_sss_resize(&q->sss, q->fft_size)) { fprintf(stderr, "Error resizing SSS object\n"); return SRSLTE_ERROR; } @@ -215,7 +214,7 @@ int srslte_sync_resize(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offse if (q->cfo_i_initiated) { for (int i=0;i<2;i++) { int offset=(i==0)?-1:1; - if (srslte_pss_synch_resize(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { + if (srslte_pss_resize(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { fprintf(stderr, "Error initializing PSS object\n"); } for (int t=0;tframe_size;t++) { @@ -302,7 +301,7 @@ void srslte_sync_set_cfo_i_enable(srslte_sync_t *q, bool enable) { if (q->cfo_i_enable && !q->cfo_i_initiated) { for (int i=0;i<2;i++) { int offset=(i==0)?-1:1; - if (srslte_pss_synch_init_fft_offset(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { + if (srslte_pss_init_fft_offset(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { fprintf(stderr, "Error initializing PSS object\n"); } for (int t=0;tframe_size;t++) { @@ -313,8 +312,12 @@ void srslte_sync_set_cfo_i_enable(srslte_sync_t *q, bool enable) { } } -void srslte_sync_set_sss_filt_enable(srslte_sync_t *q, bool enable) { - q->sss_filtering_enabled = enable; +void srslte_sync_set_sss_eq_enable(srslte_sync_t *q, bool enable) { + q->sss_channel_equalize = enable; + if (enable) { + q->pss_filtering_enabled = true; + q->pss.chest_on_filter = true; + } } void srslte_sync_set_pss_filt_enable(srslte_sync_t *q, bool enable) { @@ -343,7 +346,7 @@ void srslte_sync_cp_en(srslte_sync_t *q, bool enabled) { void srslte_sync_set_em_alpha(srslte_sync_t *q, float alpha) { - srslte_pss_synch_set_ema_alpha(&q->pss, alpha); + srslte_pss_set_ema_alpha(&q->pss, alpha); } srslte_cp_t srslte_sync_get_cp(srslte_sync_t *q) @@ -434,22 +437,22 @@ int sync_sss_symbol(srslte_sync_t *q, const cf_t *input) { int ret; - srslte_sss_synch_set_N_id_2(&q->sss, q->N_id_2); + srslte_sss_set_N_id_2(&q->sss, q->N_id_2); switch(q->sss_alg) { case SSS_DIFF: - srslte_sss_synch_m0m1_diff(&q->sss, input, &q->m0, &q->m0_value, &q->m1, &q->m1_value); + srslte_sss_m0m1_diff(&q->sss, input, &q->m0, &q->m0_value, &q->m1, &q->m1_value); break; case SSS_PARTIAL_3: - srslte_sss_synch_m0m1_partial(&q->sss, input, 3, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); + srslte_sss_m0m1_partial(&q->sss, input, 3, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); break; case SSS_FULL: - srslte_sss_synch_m0m1_partial(&q->sss, input, 1, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); + srslte_sss_m0m1_partial(&q->sss, input, 1, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); break; } - q->sf_idx = srslte_sss_synch_subframe(q->m0, q->m1); - ret = srslte_sss_synch_N_id_1(&q->sss, q->m0, q->m1); + q->sf_idx = srslte_sss_subframe(q->m0, q->m1); + ret = srslte_sss_N_id_1(&q->sss, q->m0, q->m1); if (ret >= 0) { q->N_id_1 = (uint32_t) ret; DEBUG("SSS detected N_id_1=%d, sf_idx=%d, %s CP\n", @@ -461,9 +464,9 @@ int sync_sss_symbol(srslte_sync_t *q, const cf_t *input) } } -srslte_pss_synch_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q) +srslte_pss_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q) { - srslte_pss_synch_t *pss_obj[3] = {&q->pss_i[0], &q->pss, &q->pss_i[1]}; + srslte_pss_t *pss_obj[3] = {&q->pss_i[0], &q->pss, &q->pss_i[1]}; return pss_obj[q->cfo_i_value+1]; } @@ -481,10 +484,10 @@ static int cfo_i_estimate(srslte_sync_t *q, const cf_t *input, int find_offset, float peak_value; float max_peak_value = -99; int max_cfo_i = 0; - srslte_pss_synch_t *pss_obj[3] = {&q->pss_i[0], &q->pss, &q->pss_i[1]}; + srslte_pss_t *pss_obj[3] = {&q->pss_i[0], &q->pss, &q->pss_i[1]}; for (int cfo_i=0;cfo_i<3;cfo_i++) { - srslte_pss_synch_set_N_id_2(pss_obj[cfo_i], q->N_id_2); - int p = srslte_pss_synch_find_pss(pss_obj[cfo_i], &input[find_offset], &peak_value); + srslte_pss_set_N_id_2(pss_obj[cfo_i], q->N_id_2); + int p = srslte_pss_find_pss(pss_obj[cfo_i], &input[find_offset], &peak_value); if (p < 0) { return -1; } @@ -574,8 +577,8 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, const cf_t *input, uin /* Find maximum of PSS correlation. If Integer CFO is enabled, correlation is already done */ if (!q->cfo_i_enable) { - srslte_pss_synch_set_N_id_2(&q->pss, q->N_id_2); - peak_pos = srslte_pss_synch_find_pss(&q->pss, &input_ptr[find_offset], q->threshold>0?&q->peak_value:NULL); + srslte_pss_set_N_id_2(&q->pss, q->N_id_2); + peak_pos = srslte_pss_find_pss(&q->pss, &input_ptr[find_offset], q->threshold>0?&q->peak_value:NULL); if (peak_pos < 0) { fprintf(stderr, "Error calling finding PSS sequence at : %d \n", peak_pos); return SRSLTE_ERROR; @@ -602,12 +605,12 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, const cf_t *input, uin // Filter central bands before PSS-based CFO estimation const cf_t *pss_ptr = &input_ptr[find_offset + peak_pos - q->fft_size]; if (q->pss_filtering_enabled) { - srslte_pss_synch_filter(&q->pss, pss_ptr, q->pss_filt); + srslte_pss_filter(&q->pss, pss_ptr, q->pss_filt); pss_ptr = q->pss_filt; } // PSS-based CFO estimation - float cfo_pss = srslte_pss_synch_cfo_compute(&q->pss, pss_ptr); + float cfo_pss = srslte_pss_cfo_compute(&q->pss, pss_ptr); if (!q->cfo_pss_is_set) { q->cfo_pss_mean = cfo_pss; q->cfo_pss_is_set = true; @@ -637,12 +640,11 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, const cf_t *input, uin // Correct CFO if detected in PSS if (q->cfo_pss_enable) { srslte_cfo_correct(&q->cfo_corr_symbol, sss_ptr, q->sss_filt, -q->cfo_pss_mean / q->fft_size); - sss_ptr = q->sss_filt; - } - - // Filter central bands before SSS estimation - if (q->sss_filtering_enabled) { - srslte_pss_synch_filter(&q->pss, sss_ptr, q->sss_filt); + // Equalize channel if estimated in PSS + if (q->sss_channel_equalize && q->pss.chest_on_filter && q->pss_filtering_enabled) { + srslte_vec_prod_ccc(&q->sss_filt[q->fft_size/2-SRSLTE_PSS_LEN/2], q->pss.tmp_ce, + &q->sss_filt[q->fft_size/2-SRSLTE_PSS_LEN/2], SRSLTE_PSS_LEN); + } sss_ptr = q->sss_filt; } @@ -681,5 +683,5 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, const cf_t *input, uin void srslte_sync_reset(srslte_sync_t *q) { q->M_ext_avg = 0; q->M_norm_avg = 0; - srslte_pss_synch_reset(&q->pss); + srslte_pss_reset(&q->pss); } diff --git a/lib/src/phy/sync/test/pss_file.c b/lib/src/phy/sync/test/pss_file.c index 7f70ad8ff..4087366ec 100644 --- a/lib/src/phy/sync/test/pss_file.c +++ b/lib/src/phy/sync/test/pss_file.c @@ -121,9 +121,9 @@ int main(int argc, char **argv) { srslte_filesource_t fsrc; cf_t *buffer; int frame_cnt, n; - srslte_pss_synch_t pss; + srslte_pss_t pss; srslte_cfo_t cfocorr, cfocorr64; - srslte_sss_synch_t sss; + srslte_sss_t sss; int32_t flen; int peak_idx, last_peak; float peak_value; @@ -152,12 +152,12 @@ int main(int argc, char **argv) { exit(-1); } - if (srslte_pss_synch_init_fft(&pss, flen, fft_size)) { + if (srslte_pss_init_fft(&pss, flen, fft_size)) { fprintf(stderr, "Error initiating PSS\n"); exit(-1); } - if (srslte_pss_synch_set_N_id_2(&pss, N_id_2_sync)) { + if (srslte_pss_set_N_id_2(&pss, N_id_2_sync)) { fprintf(stderr, "Error setting N_id_2=%d\n",N_id_2_sync); exit(-1); } @@ -165,12 +165,12 @@ int main(int argc, char **argv) { srslte_cfo_init(&cfocorr, flen); srslte_cfo_init(&cfocorr64, flen); - if (srslte_sss_synch_init(&sss, fft_size)) { + if (srslte_sss_init(&sss, fft_size)) { fprintf(stderr, "Error initializing SSS object\n"); return SRSLTE_ERROR; } - srslte_sss_synch_set_N_id_2(&sss, N_id_2); + srslte_sss_set_N_id_2(&sss, N_id_2); printf("Opening file...\n"); if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { @@ -210,7 +210,7 @@ int main(int argc, char **argv) { break; } - peak_idx = srslte_pss_synch_find_pss(&pss, buffer, &peak_value); + peak_idx = srslte_pss_find_pss(&pss, buffer, &peak_value); if (peak_idx < 0) { fprintf(stderr, "Error finding PSS peak\n"); exit(-1); @@ -224,14 +224,14 @@ int main(int argc, char **argv) { if (peak_idx >= fft_size) { // Estimate CFO - cfo = srslte_pss_synch_cfo_compute(&pss, &buffer[peak_idx-fft_size]); + cfo = srslte_pss_cfo_compute(&pss, &buffer[peak_idx-fft_size]); mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt); // Correct CFO srslte_cfo_correct(&cfocorr, buffer, buffer, -mean_cfo / fft_size); // Estimate channel - if (srslte_pss_synch_chest(&pss, &buffer[peak_idx-fft_size], ce)) { + if (srslte_pss_chest(&pss, &buffer[peak_idx-fft_size], ce)) { fprintf(stderr, "Error computing channel estimation\n"); exit(-1); } @@ -239,22 +239,22 @@ int main(int argc, char **argv) { // Find SSS int sss_idx = peak_idx-2*fft_size-(SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_LEN(fft_size, SRSLTE_CP_NORM_LEN):SRSLTE_CP_LEN(fft_size, SRSLTE_CP_EXT_LEN)); if (sss_idx >= 0 && sss_idx < flen-fft_size) { - srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value); - if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { + srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value); + if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) { sss_error2++; } - INFO("sf_idx = %d\n", srslte_sss_synch_subframe(m0, m1)); - INFO("Partial N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); - srslte_sss_synch_m0m1_diff(&sss, &buffer[sss_idx], &m0, &m0_value, &m1, &m1_value); - if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { + INFO("sf_idx = %d\n", srslte_sss_subframe(m0, m1)); + INFO("Partial N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1)); + srslte_sss_m0m1_diff(&sss, &buffer[sss_idx], &m0, &m0_value, &m1, &m1_value); + if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) { sss_error3++; } - INFO("Diff N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); - srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); - if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { + INFO("Diff N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1)); + srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); + if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) { sss_error1++; } - INFO("Full N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); + INFO("Full N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1)); } // Estimate CP @@ -269,7 +269,7 @@ int main(int argc, char **argv) { INFO("No space for CFO computation. Frame starts at \n",peak_idx); } - if(srslte_sss_synch_subframe(m0,m1) == 0) + if(srslte_sss_subframe(m0,m1) == 0) { #ifndef DISABLE_GRAPHICS if (!disable_plots) @@ -317,7 +317,7 @@ int main(int argc, char **argv) { } - srslte_pss_synch_free(&pss); + srslte_pss_free(&pss); free(buffer); srslte_filesource_free(&fsrc); #ifndef DISABLE_GRAPHICS diff --git a/lib/src/phy/sync/test/pss_mex.c b/lib/src/phy/sync/test/pss_mex.c index 77922a020..59cc0a897 100644 --- a/lib/src/phy/sync/test/pss_mex.c +++ b/lib/src/phy/sync/test/pss_mex.c @@ -47,7 +47,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { srslte_cell_t cell; - srslte_pss_synch_t pss; + srslte_pss_t pss; cf_t *input_symbols; int frame_len; @@ -74,17 +74,17 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) frame_len = (int) mxGetScalar(prhs[NOF_INPUTS]); } - if (srslte_pss_synch_init_fft(&pss, frame_len, srslte_symbol_sz(cell.nof_prb))) { + if (srslte_pss_init_fft(&pss, frame_len, srslte_symbol_sz(cell.nof_prb))) { fprintf(stderr, "Error initiating PSS\n"); exit(-1); } - if (srslte_pss_synch_set_N_id_2(&pss, cell.id%3)) { + if (srslte_pss_set_N_id_2(&pss, cell.id%3)) { fprintf(stderr, "Error setting N_id_2=%d\n",cell.id%3); exit(-1); } - srslte_pss_synch_set_ema_alpha(&pss, 1.0); + srslte_pss_set_ema_alpha(&pss, 1.0); - int peak_idx = srslte_pss_synch_find_pss(&pss, input_symbols, NULL); + int peak_idx = srslte_pss_find_pss(&pss, input_symbols, NULL); if (nlhs >= 1) { plhs[0] = mxCreateDoubleScalar(peak_idx); @@ -93,7 +93,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexutils_write_cf(pss.conv_output, &plhs[1], frame_len, 1); } - srslte_pss_synch_free(&pss); + srslte_pss_free(&pss); free(input_symbols); return; diff --git a/lib/src/phy/sync/test/pss_usrp.c b/lib/src/phy/sync/test/pss_usrp.c index 704340b2f..70881f15b 100644 --- a/lib/src/phy/sync/test/pss_usrp.c +++ b/lib/src/phy/sync/test/pss_usrp.c @@ -125,9 +125,9 @@ int main(int argc, char **argv) { cf_t *buffer; int frame_cnt, n; srslte_rf_t rf; - srslte_pss_synch_t pss; + srslte_pss_t pss; srslte_cfo_t cfocorr, cfocorr64; - srslte_sss_synch_t sss; + srslte_sss_t sss; int32_t flen; int peak_idx, last_peak; float peak_value; @@ -176,12 +176,12 @@ int main(int argc, char **argv) { exit(-1); } - if (srslte_pss_synch_init_fft(&pss, flen, fft_size)) { + if (srslte_pss_init_fft(&pss, flen, fft_size)) { fprintf(stderr, "Error initiating PSS\n"); exit(-1); } - if (srslte_pss_synch_set_N_id_2(&pss, N_id_2_sync)) { + if (srslte_pss_set_N_id_2(&pss, N_id_2_sync)) { fprintf(stderr, "Error setting N_id_2=%d\n",N_id_2_sync); exit(-1); } @@ -189,12 +189,12 @@ int main(int argc, char **argv) { srslte_cfo_init(&cfocorr, flen); srslte_cfo_init(&cfocorr64, flen); - if (srslte_sss_synch_init(&sss, fft_size)) { + if (srslte_sss_init(&sss, fft_size)) { fprintf(stderr, "Error initializing SSS object\n"); exit(-1); } - srslte_sss_synch_set_N_id_2(&sss, N_id_2); + srslte_sss_set_N_id_2(&sss, N_id_2); printf("N_id_2: %d\n", N_id_2); @@ -232,7 +232,7 @@ int main(int argc, char **argv) { exit(-1); } - peak_idx = srslte_pss_synch_find_pss(&pss, buffer, &peak_value); + peak_idx = srslte_pss_find_pss(&pss, buffer, &peak_value); if (peak_idx < 0) { fprintf(stderr, "Error finding PSS peak\n"); exit(-1); @@ -246,14 +246,14 @@ int main(int argc, char **argv) { if (peak_idx >= fft_size) { // Estimate CFO - cfo = srslte_pss_synch_cfo_compute(&pss, &buffer[peak_idx-fft_size]); + cfo = srslte_pss_cfo_compute(&pss, &buffer[peak_idx-fft_size]); mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt); // Correct CFO srslte_cfo_correct(&cfocorr, buffer, buffer, -mean_cfo / fft_size); // Estimate channel - if (srslte_pss_synch_chest(&pss, &buffer[peak_idx-fft_size], ce)) { + if (srslte_pss_chest(&pss, &buffer[peak_idx-fft_size], ce)) { fprintf(stderr, "Error computing channel estimation\n"); exit(-1); } @@ -263,22 +263,22 @@ int main(int argc, char **argv) { if (sss_idx >= 0 && sss_idx < flen-fft_size) { // Filter SSS - srslte_pss_synch_filter(&pss, &buffer[sss_idx], &buffer[sss_idx]); + srslte_pss_filter(&pss, &buffer[sss_idx], &buffer[sss_idx]); - INFO("Full N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); - srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 1, ce, &m0, &m0_value, &m1, &m1_value); - if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { + INFO("Full N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1)); + srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 1, ce, &m0, &m0_value, &m1, &m1_value); + if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) { sss_error2++; } - INFO("Partial N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); - srslte_sss_synch_m0m1_diff_coh(&sss, &buffer[sss_idx], ce, &m0, &m0_value, &m1, &m1_value); - if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { + INFO("Partial N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1)); + srslte_sss_m0m1_diff_coh(&sss, &buffer[sss_idx], ce, &m0, &m0_value, &m1, &m1_value); + if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) { sss_error3++; } - INFO("Diff N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); + INFO("Diff N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1)); } - srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); - if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { + srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); + if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) { sss_error1++; } @@ -294,7 +294,7 @@ int main(int argc, char **argv) { INFO("No space for CFO computation. Frame starts at \n",peak_idx); } - if(srslte_sss_synch_subframe(m0,m1) == 0) + if(srslte_sss_subframe(m0,m1) == 0) { #ifndef DISABLE_GRAPHICS if (!disable_plots) @@ -358,8 +358,8 @@ int main(int argc, char **argv) { } - srslte_sss_synch_free(&sss); - srslte_pss_synch_free(&pss); + srslte_sss_free(&sss); + srslte_pss_free(&pss); free(buffer); srslte_rf_close(&rf); diff --git a/lib/src/phy/sync/test/sss_mex.c b/lib/src/phy/sync/test/sss_mex.c index 4c92d81ec..56165fe3d 100644 --- a/lib/src/phy/sync/test/sss_mex.c +++ b/lib/src/phy/sync/test/sss_mex.c @@ -50,7 +50,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { srslte_cell_t cell; - srslte_sss_synch_t sss; + srslte_sss_t sss; cf_t *input_symbols; int frame_len; uint32_t m0, m1; @@ -80,12 +80,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } - if (srslte_sss_synch_init(&sss, srslte_symbol_sz(cell.nof_prb))) { + if (srslte_sss_init(&sss, srslte_symbol_sz(cell.nof_prb))) { mexErrMsgTxt("Error initializing SSS object\n"); return; } - srslte_sss_synch_set_N_id_2(&sss, cell.id%3); + srslte_sss_set_N_id_2(&sss, cell.id%3); // Find SSS uint32_t sss_idx = SRSLTE_SLOT_IDX_CPNORM(5,srslte_symbol_sz(cell.nof_prb)); @@ -95,23 +95,23 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } //mexPrintf("SSS begins at %d/%d. Running algorithm %s\n", sss_idx, frame_len, alg); if (!strcmp(alg, "partial")) { - srslte_sss_synch_m0m1_partial(&sss, &input_symbols[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value); + srslte_sss_m0m1_partial(&sss, &input_symbols[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value); } else if (!strcmp(alg, "diff")) { - srslte_sss_synch_m0m1_diff(&sss, &input_symbols[sss_idx], &m0, &m0_value, &m1, &m1_value); + srslte_sss_m0m1_diff(&sss, &input_symbols[sss_idx], &m0, &m0_value, &m1, &m1_value); } else if (!strcmp(alg, "full")) { - srslte_sss_synch_m0m1_partial(&sss, &input_symbols[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); + srslte_sss_m0m1_partial(&sss, &input_symbols[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); } else { mexErrMsgTxt("Unsupported algorithm type\n"); return; } - //mexPrintf("m0: %d, m1: %d, N_id_1: %d\n", m0, m1, srslte_sss_synch_N_id_1(&sss, m0, m1)); + //mexPrintf("m0: %d, m1: %d, N_id_1: %d\n", m0, m1, srslte_sss_N_id_1(&sss, m0, m1)); if (nlhs >= 1) { - plhs[0] = mxCreateDoubleScalar(srslte_sss_synch_N_id_1(&sss, m0, m1)); + plhs[0] = mxCreateDoubleScalar(srslte_sss_N_id_1(&sss, m0, m1)); } if (nlhs >= 2) { - plhs[1] = mxCreateDoubleScalar(srslte_sss_synch_subframe(m0, m1)); + plhs[1] = mxCreateDoubleScalar(srslte_sss_subframe(m0, m1)); } if (nlhs >= 3) { mexutils_write_f(sss.corr_output_m0, &plhs[2], SRSLTE_SSS_N, 1); @@ -119,7 +119,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) if (nlhs >= 4) { mexutils_write_f(sss.corr_output_m1, &plhs[3], SRSLTE_SSS_N, 1); } - srslte_sss_synch_free(&sss); + srslte_sss_free(&sss); free(input_symbols); return; diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index b5d89743f..7eb877b3b 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -272,14 +272,14 @@ int srslte_ue_sync_init_multi_decim(srslte_ue_sync_t *q, 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_filt_enable(&q->sfind, true); + srslte_sync_set_sss_eq_enable(&q->sfind, true); // 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_filt_enable(&q->strack, false); + srslte_sync_set_sss_eq_enable(&q->strack, false); // FIXME: CP detection not working very well. Not supporting Extended CP right now srslte_sync_cp_en(&q->strack, false); diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 667f0a93c..6c7ff7717 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -102,8 +102,6 @@ private: bool set_frequency(); bool set_cell(); - static void substract_sync(cf_t *buffer, uint32_t nof_prb, srslte_sync_t *sync_obj); - void cell_search_inc(); void resync_sfn(bool is_connected = false, bool rx_now = false); bool stop_sync(); @@ -202,7 +200,7 @@ private: float rsrq; uint32_t offset; } cell_info_t; - void init(srslte::log *log_h); + void init(srslte::log *log_h, bool sic_pss_enabled); void reset(); int find_cells(cf_t *input_buffer, float rx_gain_offset, srslte_cell_t current_cell, uint32_t nof_sf, cell_info_t found_cells[MAX_CELLS]); private: @@ -214,6 +212,7 @@ private: srslte::log *log_h; srslte_sync_t sync_find; + bool sic_pss_enabled; uint32_t current_fft_sz; measure measure_p; }; diff --git a/srsue/src/mac/proc_ra.cc b/srsue/src/mac/proc_ra.cc index 18548be23..0a1855c80 100644 --- a/srsue/src/mac/proc_ra.cc +++ b/srsue/src/mac/proc_ra.cc @@ -394,16 +394,14 @@ void ra_proc::step_response_reception() { void ra_proc::step_response_error() { - if (ra_is_ho) { - state = RA_PROBLEM; - rrc->ho_ra_completed(false); - return; - } preambleTransmissionCounter++; if (preambleTransmissionCounter >= preambleTransMax + 1) { rError("Maximum number of transmissions reached (%d)\n", preambleTransMax); rrc->ra_problem(); state = RA_PROBLEM; + if (ra_is_ho) { + rrc->ho_ra_completed(false); + } } else { backoff_interval_start = phy_h->get_current_tti(); if (backoff_param_ms) { diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 8a25801f2..09a382246 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -233,11 +233,14 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { bpo::value(&args->expert.phy.cfo_loop_ref_min)->default_value(0), "Tolerance (in Hz) of the RS estimation method. Below this value, RS estimation does not feeds back the loop") - ("expert.cfo_loop_pss_conv", bpo::value(&args->expert.phy.cfo_loop_pss_conv)->default_value(20), "After the PSS estimation is below cfo_loop_pss_tol for cfo_loop_pss_timeout times consecutively, RS adjustments are allowed.") + ("expert.sic_pss_enabled", + bpo::value(&args->expert.phy.sic_pss_enabled)->default_value(true), + "Applies Successive Interference Cancellation to PSS signals when searching for neighbour cells. Must be disabled if cells have identical channel and timing.") + ("expert.average_subframe_enabled", bpo::value(&args->expert.phy.average_subframe_enabled)->default_value(false), "Averages in the time domain the channel estimates within 1 subframe. Needs accurate CFO correction.") diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 7a78fc11c..9225c6f73 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -197,6 +197,8 @@ void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q) worker_com->args->cfo_loop_pss_tol, worker_com->args->cfo_loop_pss_conv); + q->strack.pss.chest_on_filter = true; + 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); @@ -629,7 +631,7 @@ void phch_recv::run_thread() worker = (phch_worker *) workers_pool->wait_worker(tti); if (worker) { - for (uint32_t i = 0; i < nof_rx_antennas; i++) { + for (uint32_t i = 0; i < SRSLTE_MAX_PORTS; i++) { buffer[i] = worker->get_buffer(i); } @@ -669,12 +671,12 @@ void phch_recv::run_thread() 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); } + workers_pool->start_worker(worker); - // Substract PSS/SSS from current cell before computing intra-frequency - /*if ((tti%5) == 0) { - substract_sync(buffer[0], cell.nof_prb, &ue_sync.strack); - }*/ + if ((tti%5) == 0 && worker_com->args->sic_pss_enabled) { + srslte_pss_sic(&ue_sync.strack.pss, &buffer[0][SRSLTE_SF_LEN_PRB(cell.nof_prb)/2-ue_sync.strack.fft_size]); + } intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb)); out_of_sync_cnt = 0; break; @@ -726,24 +728,6 @@ void phch_recv::out_of_sync() { } } -void phch_recv::substract_sync(cf_t *buffer, uint32_t nof_prb, srslte_sync_t *sync_obj) -{ - uint32_t hf_len = SRSLTE_SF_LEN_PRB(nof_prb)/2; - uint32_t fft_sz = srslte_symbol_sz(nof_prb); - - srslte_vec_sc_prod_cfc(sync_obj->pss_filt, 1.0/sqrtf(fft_sz), sync_obj->pss_filt, fft_sz); - srslte_vec_sc_prod_cfc(sync_obj->sss_filt, 1.0/sqrtf(fft_sz), sync_obj->sss_filt, fft_sz); - - srslte_vec_sub_ccc(&buffer[hf_len-fft_sz], - sync_obj->pss_filt, - &buffer[hf_len-fft_sz], - fft_sz); - - srslte_vec_sub_ccc(&buffer[hf_len-2*fft_sz-SRSLTE_CP_LEN(fft_sz, SRSLTE_CP_NORM_LEN)], - sync_obj->sss_filt, - &buffer[hf_len-2*fft_sz-SRSLTE_CP_LEN(fft_sz, SRSLTE_CP_NORM_LEN)], - fft_sz); -} @@ -1194,9 +1178,10 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) * Secondary cell receiver */ -void phch_recv::scell_recv::init(srslte::log *log_h) +void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled) { this->log_h = log_h; + this->sic_pss_enabled = sic_pss_enabled; // and a separate ue_sync instance @@ -1213,16 +1198,18 @@ void phch_recv::scell_recv::init(srslte::log *log_h) return; } srslte_sync_cp_en(&sync_find, false); - srslte_sync_set_threshold(&sync_find, 1.3); + srslte_sync_set_threshold(&sync_find, 1.2); srslte_sync_set_em_alpha(&sync_find, 0.0); // Configure FIND object behaviour (this configuration is always the same) - srslte_sync_set_cfo_ema_alpha(&sync_find, 0.5); + 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_filt_enable(&sync_find, true); + srslte_sync_set_sss_eq_enable(&sync_find, true); + + sync_find.pss.chest_on_filter = true; reset(); } @@ -1259,76 +1246,79 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, for (uint32_t n_id_2=0;n_id_2<3;n_id_2++) { - srslte_sync_set_N_id_2(&sync_find, n_id_2); - - srslte_sync_find_ret_t sync_res; - //do { - - srslte_sync_reset(&sync_find); - srslte_sync_cfo_reset(&sync_find); - - sync_res = srslte_sync_find(&sync_find, input_buffer, 0, &peak_idx); - - switch(sync_res) { - case SRSLTE_SYNC_ERROR: - return SRSLTE_ERROR; - fprintf(stderr, "Error finding correlation peak\n"); - return SRSLTE_ERROR; - case SRSLTE_SYNC_FOUND: - sf_idx = srslte_sync_get_sf_idx(&sync_find); - cell_id = srslte_sync_get_cell_id(&sync_find); - - if (cell_id >= 0) { - // We found the same cell as before, look another N_id_2 - if ((uint32_t) cell_id == found_cell.id || (uint32_t) cell_id == cell.id) { - sync_res = SRSLTE_SYNC_NOFOUND; - } else { - // We found a new cell ID - found_cell.id = cell_id; - found_cell.nof_ports = 1; // Use port 0 only for measurement - measure_p.set_cell(found_cell); - - // Correct CFO - /* - srslte_cfo_correct(&sync_find.cfo_corr_frame, - input_buffer, - input_cfo_corrected, - -srslte_sync_get_cfo(&sync_find)/sync_find.fft_size); - */ - - switch(measure_p.run_multiple_subframes(input_buffer, peak_idx, sf_idx, nof_sf)) { - case measure::MEASURE_OK: - cells[nof_cells].pci = found_cell.id; - cells[nof_cells].rsrp = measure_p.rsrp(); - cells[nof_cells].rsrq = measure_p.rsrq(); - cells[nof_cells].offset = measure_p.frame_st_idx(); - nof_cells++; - - // Substract interference from input buffer (for the next cell) - //substract_sync(&input_buffer[measure_p.frame_st_idx()], cell.nof_prb, &sync_find); - - Info("INTRA: Found neighbour cell: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f n_id_2=%d, CFO=%6.1f Hz\n", - cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, n_id_2, 15000*srslte_sync_get_cfo(&sync_find)); - - break; - case measure::ERROR: - Error("Measuring neighbour cell\n"); - return SRSLTE_ERROR; - default: - break; + if (n_id_2 != (cell.id%3) || sic_pss_enabled) { + srslte_sync_set_N_id_2(&sync_find, n_id_2); + + srslte_sync_find_ret_t sync_res; + + do { + srslte_sync_reset(&sync_find); + srslte_sync_cfo_reset(&sync_find); + + sync_res = srslte_sync_find(&sync_find, input_buffer, 0, &peak_idx); + + switch(sync_res) { + case SRSLTE_SYNC_ERROR: + return SRSLTE_ERROR; + fprintf(stderr, "Error finding correlation peak\n"); + return SRSLTE_ERROR; + case SRSLTE_SYNC_FOUND: + sf_idx = srslte_sync_get_sf_idx(&sync_find); + cell_id = srslte_sync_get_cell_id(&sync_find); + + if (cell_id >= 0) { + // We found the same cell as before, look another N_id_2 + if ((uint32_t) cell_id == found_cell.id || (uint32_t) cell_id == cell.id) { + sync_res = SRSLTE_SYNC_NOFOUND; + } else { + // We found a new cell ID + found_cell.id = cell_id; + found_cell.nof_ports = 1; // Use port 0 only for measurement + measure_p.set_cell(found_cell); + + // Correct CFO + srslte_cfo_correct(&sync_find.cfo_corr_frame, + input_buffer, + input_cfo_corrected, + -srslte_sync_get_cfo(&sync_find)/sync_find.fft_size); + + + switch(measure_p.run_multiple_subframes(input_cfo_corrected, peak_idx, sf_idx, nof_sf)) { + case measure::MEASURE_OK: + cells[nof_cells].pci = found_cell.id; + cells[nof_cells].rsrp = measure_p.rsrp(); + cells[nof_cells].rsrq = measure_p.rsrq(); + cells[nof_cells].offset = measure_p.frame_st_idx(); + + Info("INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f n_id_2=%d, CFO=%6.1f Hz\n", + nof_cells, cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, n_id_2, 15000*srslte_sync_get_cfo(&sync_find)); + + nof_cells++; + + if (sic_pss_enabled) { + srslte_pss_sic(&sync_find.pss, &input_buffer[sf_len/2-fft_sz]); + } + + break; + case measure::ERROR: + Error("Measuring neighbour cell\n"); + return SRSLTE_ERROR; + default: + break; + } } + } else { + sync_res = SRSLTE_SYNC_NOFOUND; } - } else { - sync_res = SRSLTE_SYNC_NOFOUND; - } - break; - case SRSLTE_SYNC_FOUND_NOSPACE: - /* If a peak was found but there is not enough space for SSS/CP detection, discard a few samples */ - break; - default: - break; - } - //} while(sync_res == SRSLTE_SYNC_FOUND); + break; + case SRSLTE_SYNC_FOUND_NOSPACE: + /* If a peak was found but there is not enough space for SSS/CP detection, discard a few samples */ + break; + default: + break; + } + } while (sync_res == SRSLTE_SYNC_FOUND && sic_pss_enabled); + } } return nof_cells; } @@ -1380,7 +1370,7 @@ void phch_recv::intra_measure::init(phch_common *common, rrc_interface_phy *rrc, receive_enabled = false; // Start scell - scell.init(log_h); + scell.init(log_h, common->args->sic_pss_enabled); search_buffer = (cf_t*) srslte_vec_malloc(CAPTURE_LEN_SF*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB)*sizeof(cf_t)); diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 461a4f9ee..55c39cfe0 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1087,7 +1087,9 @@ void rrc::ho_ra_completed(bool ra_successful) { rrc_log->console("HO %ssuccessful\n", ra_successful?"":"un"); pending_mob_reconf = false; - state = RRC_STATE_CONNECTED; + if (ra_successful) { + state = RRC_STATE_CONNECTED; + } } else { rrc_log->error("Received HO random access completed but no pending mobility reconfiguration info\n"); } diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 54b07f8ef..444f9e156 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -154,6 +154,10 @@ enable = false # average_subframe_enabled: Averages in the time domain the channel estimates within 1 subframe. # Needs accurate CFO correction. # +# sic_pss_enabled: Applies Successive Interference Cancellation to PSS signals when searching for neighbour cells. +# Must be disabled if cells have identical channel and timing, for instance if generated from +# the same source. +# # metrics_csv_enable: Write UE metrics to CSV file. # # metrics_csv_filename: File path to use for CSV metrics. @@ -191,6 +195,7 @@ enable = false #sss_algorithm = full #estimator_fil_w = 0.1 #average_subframe_enabled = false +#sic_pss_enabled = true #pregenerate_signals = false #metrics_csv_enable = false #metrics_csv_filename = /tmp/ue_metrics.csv