From a3a1d268b7ac81446c364a5466a5220b41881fec Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 29 Nov 2017 18:30:21 +0100 Subject: [PATCH] Improved CFO estimation/correction by filtering central 6 PRB. Cleaned ue_sync/sync/pss objects. Used const attr in vector and other objects --- lib/examples/cell_measurement.c | 3 - lib/examples/pdsch_ue.c | 9 +- lib/include/srslte/phy/dft/dft.h | 14 +- lib/include/srslte/phy/sync/cfo.h | 2 +- lib/include/srslte/phy/sync/cp.h | 2 +- lib/include/srslte/phy/sync/pss.h | 12 +- lib/include/srslte/phy/sync/sss.h | 10 +- lib/include/srslte/phy/sync/sync.h | 84 ++-- lib/include/srslte/phy/ue/ue_sync.h | 37 +- lib/include/srslte/phy/utils/convolution.h | 16 +- lib/include/srslte/phy/utils/simd.h | 22 +- lib/include/srslte/phy/utils/vector.h | 98 ++-- lib/include/srslte/phy/utils/vector_simd.h | 65 +-- lib/src/phy/dft/dft_fftw.c | 10 +- lib/src/phy/modem/demod_soft.c | 4 +- .../phy/resampling/test/resample_arb_bench.c | 2 +- lib/src/phy/rf/rf_blade_imp.c | 4 +- lib/src/phy/rf/rf_utils.c | 7 +- lib/src/phy/sync/cfo.c | 2 +- lib/src/phy/sync/cp.c | 4 +- lib/src/phy/sync/find_sss.c | 8 +- lib/src/phy/sync/pss.c | 115 +++-- lib/src/phy/sync/sync.c | 439 ++++++++++-------- lib/src/phy/sync/test/pss_usrp.c | 18 +- lib/src/phy/sync/test/sync_test.c | 3 +- lib/src/phy/ue/ue_cell_search.c | 4 +- lib/src/phy/ue/ue_sync.c | 242 +++++----- lib/src/phy/utils/convolution.c | 6 +- lib/src/phy/utils/test/vector_test.c | 2 +- lib/src/phy/utils/vector.c | 107 ++--- lib/src/phy/utils/vector_simd.c | 67 +-- srsue/src/phy/phch_recv.cc | 6 +- 32 files changed, 753 insertions(+), 671 deletions(-) diff --git a/lib/examples/cell_measurement.c b/lib/examples/cell_measurement.c index 6415257f0..573cab255 100644 --- a/lib/examples/cell_measurement.c +++ b/lib/examples/cell_measurement.c @@ -299,9 +299,6 @@ int main(int argc, char **argv) { float rx_gain_offset = 0; - // Set initial CFO for ue_sync - srslte_ue_sync_set_cfo(&ue_sync, cfo); - /* Main loop */ while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) { diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index e8d4b1d00..e15aa473f 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -579,11 +579,8 @@ int main(int argc, char **argv) { srslte_ra_dl_dci_t old_dl_dci; bzero(&old_dl_dci, sizeof(srslte_ra_dl_dci_t)); #endif - - ue_sync.correct_cfo = !prog_args.disable_cfo; - - // Set initial CFO for ue_sync - srslte_ue_sync_set_cfo(&ue_sync, cfo); + + ue_sync.cfo_correct_enable = !prog_args.disable_cfo; srslte_pbch_decode_reset(&ue_mib.pbch); @@ -776,7 +773,7 @@ int main(int argc, char **argv) { /* Print basic Parameters */ PRINT_LINE(" nof layers: %d", ue_dl.pdsch_cfg.nof_layers); PRINT_LINE("nof codewords: %d", SRSLTE_RA_DL_GRANT_NOF_TB(&ue_dl.pdsch_cfg.grant)); - PRINT_LINE(" CFO: %+5.2f kHz", srslte_ue_sync_get_cfo(&ue_sync) / 1000); + PRINT_LINE(" CFO: %+7.2f kHz", srslte_ue_sync_get_cfo(&ue_sync)); PRINT_LINE(" SNR: %+5.1f dB | %+5.1f dB", 10 * log10(rsrp0 / noise), 10 * log10(rsrp1 / noise)); PRINT_LINE(" Rb: %6.2f / %6.2f / %6.2f Mbps (net/maximum/processing)", uerate, enodebrate, procrate); PRINT_LINE(" PDCCH-Miss: %5.2f%%", 100 * (1 - (float) ue_dl.nof_detected / nof_trials)); diff --git a/lib/include/srslte/phy/dft/dft.h b/lib/include/srslte/phy/dft/dft.h index b3dd4378b..afe8024d2 100644 --- a/lib/include/srslte/phy/dft/dft.h +++ b/lib/include/srslte/phy/dft/dft.h @@ -139,22 +139,22 @@ SRSLTE_API void srslte_dft_plan_set_dc(srslte_dft_plan_t *plan, /* Compute DFT */ -SRSLTE_API void srslte_dft_run(srslte_dft_plan_t *plan, - void *in, +SRSLTE_API void srslte_dft_run(srslte_dft_plan_t *plan, + const void *in, void *out); -SRSLTE_API void srslte_dft_run_c_zerocopy(srslte_dft_plan_t *plan, - cf_t *in, +SRSLTE_API void srslte_dft_run_c_zerocopy(srslte_dft_plan_t *plan, + const cf_t *in, cf_t *out); -SRSLTE_API void srslte_dft_run_c(srslte_dft_plan_t *plan, - cf_t *in, +SRSLTE_API void srslte_dft_run_c(srslte_dft_plan_t *plan, + const cf_t *in, cf_t *out); SRSLTE_API void srslte_dft_run_guru_c(srslte_dft_plan_t *plan); SRSLTE_API void srslte_dft_run_r(srslte_dft_plan_t *plan, - float *in, + const float *in, float *out); #endif // DFT_H_ diff --git a/lib/include/srslte/phy/sync/cfo.h b/lib/include/srslte/phy/sync/cfo.h index fd2ab4d83..5b9b3c0dd 100644 --- a/lib/include/srslte/phy/sync/cfo.h +++ b/lib/include/srslte/phy/sync/cfo.h @@ -66,7 +66,7 @@ SRSLTE_API void srslte_cfo_set_tol(srslte_cfo_t *h, float tol); SRSLTE_API void srslte_cfo_correct(srslte_cfo_t *h, - cf_t *input, + const cf_t *input, cf_t *output, float freq); diff --git a/lib/include/srslte/phy/sync/cp.h b/lib/include/srslte/phy/sync/cp.h index 9daf7d4f6..d9da03722 100644 --- a/lib/include/srslte/phy/sync/cp.h +++ b/lib/include/srslte/phy/sync/cp.h @@ -47,7 +47,7 @@ SRSLTE_API int srslte_cp_synch_resize(srslte_cp_synch_t *q, uint32_t symbol_sz); SRSLTE_API uint32_t srslte_cp_synch(srslte_cp_synch_t *q, - cf_t *input, + const cf_t *input, uint32_t max_offset, uint32_t nof_symbols, uint32_t cp_len); diff --git a/lib/include/srslte/phy/sync/pss.h b/lib/include/srslte/phy/sync/pss.h index f94b2deba..aba84f5cd 100644 --- a/lib/include/srslte/phy/sync/pss.h +++ b/lib/include/srslte/phy/sync/pss.h @@ -63,8 +63,6 @@ #define SRSLTE_PSS_ACCUMULATE_ABS // If enabled, accumulates the correlation absolute value on consecutive calls to srslte_pss_synch_find_pss -#define SRSLTE_PSS_ABS_SQUARE // If enabled, compute abs square, otherwise computes absolute value only - #define SRSLTE_PSS_RETURN_PSR // If enabled returns peak to side-lobe ratio, otherwise returns absolute peak value @@ -137,7 +135,7 @@ SRSLTE_API void srslte_pss_synch_filter_enable(srslte_pss_synch_t *q, bool enable); SRSLTE_API void srslte_pss_synch_filter(srslte_pss_synch_t *q, - cf_t *input, + const cf_t *input, cf_t *output); SRSLTE_API int srslte_pss_generate(cf_t *signal, @@ -160,14 +158,14 @@ SRSLTE_API int srslte_pss_synch_set_N_id_2(srslte_pss_synch_t *q, uint32_t N_id_2); SRSLTE_API int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, - cf_t *input, + const cf_t *input, float *corr_peak_value); SRSLTE_API int srslte_pss_synch_chest(srslte_pss_synch_t *q, - cf_t *input, + const cf_t *input, cf_t ce[SRSLTE_PSS_LEN]); -SRSLTE_API float srslte_pss_synch_cfo_compute(srslte_pss_synch_t* q, - cf_t *pss_recv); +SRSLTE_API float srslte_pss_synch_cfo_compute(srslte_pss_synch_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 35eedac8f..4a0942d61 100644 --- a/lib/include/srslte/phy/sync/sss.h +++ b/lib/include/srslte/phy/sync/sss.h @@ -107,8 +107,8 @@ SRSLTE_API void srslte_sss_put_slot(float *sss, SRSLTE_API int srslte_sss_synch_set_N_id_2(srslte_sss_synch_t *q, uint32_t N_id_2); -SRSLTE_API int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q, - cf_t *input, +SRSLTE_API 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, @@ -117,15 +117,15 @@ SRSLTE_API int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q, float *m1_value); SRSLTE_API int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, - cf_t *input, + const cf_t *input, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, uint32_t *m1, float *m1_value); -SRSLTE_API int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, - cf_t *input, +SRSLTE_API int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, + const cf_t *input, uint32_t *m0, float *m0_value, uint32_t *m1, diff --git a/lib/include/srslte/phy/sync/sync.h b/lib/include/srslte/phy/sync/sync.h index 1c70b2449..151c530b1 100644 --- a/lib/include/srslte/phy/sync/sync.h +++ b/lib/include/srslte/phy/sync/sync.h @@ -74,19 +74,8 @@ typedef struct SRSLTE_API { uint32_t fft_size; uint32_t frame_size; uint32_t max_offset; - bool enable_cfo_corr; - bool mean_cfo2_isunset; - bool mean_cfo_isunset; - float mean_cfo; - float mean_cfo2; - int cfo_i; - bool find_cfo_i; - bool find_cfo_i_initiated; - float cfo_ema_alpha; uint32_t nof_symbols; uint32_t cp_len; - srslte_cfo_t cfocorr; - srslte_cfo_t cfocorr2; float current_cfo_tol; sss_alg_t sss_alg; bool detect_cp; @@ -102,6 +91,30 @@ typedef struct SRSLTE_API { uint32_t max_frame_size; + + // variables for various CFO estimation methods + bool cfo_cp_enable; + bool cfo_pss_enable; + bool cfo_i_enable; + + bool cfo_cp_is_set; + bool cfo_pss_is_set; + bool cfo_i_initiated; + + float cfo_cp_mean; + float cfo_pss_mean; + int cfo_i_value; + + float cfo_ema_alpha; + + srslte_cfo_t cfo_corr_frame; + srslte_cfo_t cfo_corr_symbol; + + bool sss_filtering_enabled; + bool pss_filtering_enabled; + cf_t sss_filt[SRSLTE_SYMBOL_SZ_MAX]; + cf_t pss_filt[SRSLTE_SYMBOL_SZ_MAX]; + }srslte_sync_t; typedef enum { @@ -135,29 +148,23 @@ SRSLTE_API void srslte_sync_reset(srslte_sync_t *q); /* Finds a correlation peak in the input signal around position find_offset */ SRSLTE_API srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, - cf_t *input, + const cf_t *input, uint32_t find_offset, uint32_t *peak_position); /* Estimates the CP length */ SRSLTE_API srslte_cp_t srslte_sync_detect_cp(srslte_sync_t *q, - cf_t *input, + const cf_t *input, uint32_t peak_pos); /* Sets the threshold for peak comparison */ SRSLTE_API void srslte_sync_set_threshold(srslte_sync_t *q, float threshold); -SRSLTE_API void srslte_sync_set_cfo_tol(srslte_sync_t *q, - float tol); - /* Gets the subframe idx (0 or 5) */ SRSLTE_API uint32_t srslte_sync_get_sf_idx(srslte_sync_t *q); -/* Gets the last peak value */ -SRSLTE_API float srslte_sync_get_last_peak_value(srslte_sync_t *q); - -/* Gets the mean peak value */ +/* Gets the peak value */ SRSLTE_API float srslte_sync_get_peak_value(srslte_sync_t *q); /* Choose SSS detection algorithm */ @@ -175,23 +182,40 @@ SRSLTE_API int srslte_sync_set_N_id_2(srslte_sync_t *q, /* Gets the Physical CellId from the last call to synch_run() */ SRSLTE_API int srslte_sync_get_cell_id(srslte_sync_t *q); +/* Enables/disables filtering of the central PRBs before PSS CFO estimation or SSS correlation*/ +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); + /* Gets the CFO estimation from the last call to synch_run() */ SRSLTE_API float srslte_sync_get_cfo(srslte_sync_t *q); -/* Sets known CFO to avoid long transients due to average */ -SRSLTE_API void srslte_sync_set_cfo(srslte_sync_t *q, float cfo); +/* Resets internal CFO state */ +SRSLTE_API void srslte_sync_cfo_reset(srslte_sync_t *q); -/* Set integer CFO */ -SRSLTE_API void srslte_sync_set_cfo_i(srslte_sync_t *q, - int cfo_i); +/* Copies CFO internal state from another object to avoid long transients */ +SRSLTE_API void srslte_sync_copy_cfo(srslte_sync_t *q, + srslte_sync_t *src_obj); -SRSLTE_API void srslte_sync_set_cfo_enable(srslte_sync_t *q, - bool enable); +/* Enable different CFO estimation stages */ +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); +SRSLTE_API void srslte_sync_set_cfo_pss_enable(srslte_sync_t *q, + bool enable); + +/* Sets CFO correctors tolerance (in Hz) */ +SRSLTE_API void srslte_sync_set_cfo_tol(srslte_sync_t *q, + float tol); /* Sets the exponential moving average coefficient for CFO averaging */ SRSLTE_API void srslte_sync_set_cfo_ema_alpha(srslte_sync_t *q, float alpha); + /* Gets the CP length estimation from the last call to synch_run() */ SRSLTE_API srslte_cp_t srslte_sync_get_cp(srslte_sync_t *q); @@ -199,10 +223,6 @@ SRSLTE_API srslte_cp_t srslte_sync_get_cp(srslte_sync_t *q); SRSLTE_API void srslte_sync_set_cp(srslte_sync_t *q, srslte_cp_t cp); -/* Enable integer CFO detection */ -SRSLTE_API void srslte_sync_cfo_i_detec_en(srslte_sync_t *q, - bool enabled); - /* Enables/Disables SSS detection */ SRSLTE_API void srslte_sync_sss_en(srslte_sync_t *q, bool enabled); @@ -211,8 +231,6 @@ SRSLTE_API srslte_pss_synch_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q); SRSLTE_API bool srslte_sync_sss_detected(srslte_sync_t *q); -SRSLTE_API bool srslte_sync_sss_is_en(srslte_sync_t *q); - /* Enables/Disables CP detection */ SRSLTE_API void srslte_sync_cp_en(srslte_sync_t *q, bool enabled); diff --git a/lib/include/srslte/phy/ue/ue_sync.h b/lib/include/srslte/phy/ue/ue_sync.h index e5877dd23..11d7893c8 100644 --- a/lib/include/srslte/phy/ue/ue_sync.h +++ b/lib/include/srslte/phy/ue/ue_sync.h @@ -110,8 +110,12 @@ typedef struct SRSLTE_API { uint32_t sf_idx; bool decode_sss_on_track; - bool correct_cfo; - + + bool cfo_correct_enable; + float cfo_current_value; + float cfo_loop_bw; + float cfo_pss_tol; + uint32_t peak_idx; int next_rf_sample_offset; int last_sample_offset; @@ -165,6 +169,10 @@ SRSLTE_API void srslte_ue_sync_free(srslte_ue_sync_t *q); SRSLTE_API int srslte_ue_sync_set_cell(srslte_ue_sync_t *q, srslte_cell_t cell); +SRSLTE_API void srslte_ue_sync_cfo_reset(srslte_ue_sync_t *q); + +SRSLTE_API void srslte_ue_sync_reset(srslte_ue_sync_t *q); + SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(void*, double), float init_gain_value); @@ -175,34 +183,34 @@ SRSLTE_API void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q, uint32_t period); /* CAUTION: input_buffer MUST have space for 2 subframes */ -SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, +SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer); -SRSLTE_API int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, +SRSLTE_API int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS]); SRSLTE_API void srslte_ue_sync_set_cfo_tol(srslte_ue_sync_t *q, float tol); -SRSLTE_API void srslte_ue_sync_set_cfo(srslte_ue_sync_t *q, - float cfo); +SRSLTE_API void srslte_ue_sync_copy_cfo(srslte_ue_sync_t *q, + srslte_ue_sync_t *src_obj); + +SRSLTE_API void srslte_ue_sync_set_cfo_loop_bw(srslte_ue_sync_t *q, + float bw, + float pss_tol); SRSLTE_API void srslte_ue_sync_set_cfo_ema(srslte_ue_sync_t *q, float ema); -SRSLTE_API void srslte_ue_sync_cfo_i_detec_en(srslte_ue_sync_t *q, - bool enable); +SRSLTE_API void srslte_ue_sync_set_cfo_i_enable(srslte_ue_sync_t *q, + bool enable); -SRSLTE_API void srslte_ue_sync_reset(srslte_ue_sync_t *q); - -SRSLTE_API void srslte_ue_sync_set_N_id_2(srslte_ue_sync_t *q, +SRSLTE_API void srslte_ue_sync_set_N_id_2(srslte_ue_sync_t *q, uint32_t N_id_2); SRSLTE_API void srslte_ue_sync_decode_sss_on_track(srslte_ue_sync_t *q, bool enabled); -SRSLTE_API srslte_ue_sync_state_t srslte_ue_sync_get_state(srslte_ue_sync_t *q); - SRSLTE_API uint32_t srslte_ue_sync_get_sfidx(srslte_ue_sync_t *q); SRSLTE_API float srslte_ue_sync_get_cfo(srslte_ue_sync_t *q); @@ -218,8 +226,5 @@ SRSLTE_API void srslte_ue_sync_get_last_timestamp(srslte_ue_sync_t *q, srslte_timestamp_t *timestamp); - - - #endif // SYNC_FRAME_ diff --git a/lib/include/srslte/phy/utils/convolution.h b/lib/include/srslte/phy/utils/convolution.h index fcb321ce5..a93dfb955 100644 --- a/lib/include/srslte/phy/utils/convolution.h +++ b/lib/include/srslte/phy/utils/convolution.h @@ -66,18 +66,18 @@ SRSLTE_API int srslte_conv_fft_cc_replan(srslte_conv_fft_cc_t *q, SRSLTE_API void srslte_conv_fft_cc_free(srslte_conv_fft_cc_t *q); -SRSLTE_API uint32_t srslte_conv_fft_cc_run(srslte_conv_fft_cc_t *q, - cf_t *input, - cf_t *filter, +SRSLTE_API uint32_t srslte_conv_fft_cc_run(srslte_conv_fft_cc_t *q, + const cf_t *input, + const cf_t *filter, cf_t *output); -SRSLTE_API uint32_t srslte_conv_fft_cc_run_opt(srslte_conv_fft_cc_t *q, - cf_t *input, - cf_t *filter_freq, +SRSLTE_API uint32_t srslte_conv_fft_cc_run_opt(srslte_conv_fft_cc_t *q, + const cf_t *input, + const cf_t *filter_freq, cf_t *output); -SRSLTE_API uint32_t srslte_conv_cc(cf_t *input, - cf_t *filter, +SRSLTE_API uint32_t srslte_conv_cc(const cf_t *input, + const cf_t *filter, cf_t *output, uint32_t input_len, uint32_t filter_len); diff --git a/lib/include/srslte/phy/utils/simd.h b/lib/include/srslte/phy/utils/simd.h index cec003886..226e2ecae 100644 --- a/lib/include/srslte/phy/utils/simd.h +++ b/lib/include/srslte/phy/utils/simd.h @@ -172,7 +172,7 @@ typedef float32x4_t simd_f_t; #endif /* LV_HAVE_AVX512 */ /* Single precision Floating point functions */ -static inline simd_f_t srslte_simd_f_load(float *ptr) { +static inline simd_f_t srslte_simd_f_load(const float *ptr) { #ifdef LV_HAVE_AVX512 return _mm512_load_ps(ptr); #else /* LV_HAVE_AVX512 */ @@ -190,7 +190,7 @@ static inline simd_f_t srslte_simd_f_load(float *ptr) { #endif /* LV_HAVE_AVX512 */ } -static inline simd_f_t srslte_simd_f_loadu(float *ptr) { +static inline simd_f_t srslte_simd_f_loadu(const float *ptr) { #ifdef LV_HAVE_AVX512 return _mm512_loadu_ps(ptr); #else /* LV_HAVE_AVX512 */ @@ -477,7 +477,7 @@ typedef struct { #endif /* Complex Single precission Floating point functions */ -static inline simd_cf_t srslte_simd_cfi_load(cf_t *ptr) { +static inline simd_cf_t srslte_simd_cfi_load(const cf_t *ptr) { simd_cf_t ret; #ifdef LV_HAVE_AVX512 __m512 in1 = _mm512_load_ps((float*)(ptr)); @@ -513,7 +513,7 @@ static inline simd_cf_t srslte_simd_cfi_load(cf_t *ptr) { } /* Complex Single precission Floating point functions */ -static inline simd_cf_t srslte_simd_cfi_loadu(cf_t *ptr) { +static inline simd_cf_t srslte_simd_cfi_loadu(const cf_t *ptr) { simd_cf_t ret; #ifdef LV_HAVE_AVX512 __m512 in1 = _mm512_loadu_ps((float*)(ptr)); @@ -548,7 +548,7 @@ static inline simd_cf_t srslte_simd_cfi_loadu(cf_t *ptr) { return ret; } -static inline simd_cf_t srslte_simd_cf_load(float *re, float *im) { +static inline simd_cf_t srslte_simd_cf_load(const float *re, const float *im) { simd_cf_t ret; #ifdef LV_HAVE_AVX512 ret.re = _mm512_load_ps(re); @@ -572,7 +572,7 @@ static inline simd_cf_t srslte_simd_cf_load(float *re, float *im) { return ret; } -static inline simd_cf_t srslte_simd_cf_loadu(float *re, float *im) { +static inline simd_cf_t srslte_simd_cf_loadu(const float *re, const float *im) { simd_cf_t ret; #ifdef LV_HAVE_AVX512 ret.re = _mm512_loadu_ps(re); @@ -1074,7 +1074,7 @@ typedef int16x8_t simd_s_t; #endif /* LV_HAVE_AVX2 */ #endif /* LV_HAVE_AVX512 */ -static inline simd_s_t srslte_simd_s_load(int16_t *ptr) { +static inline simd_s_t srslte_simd_s_load(const int16_t *ptr) { #ifdef LV_HAVE_AVX512 return _mm512_load_si512(ptr); #else /* LV_HAVE_AVX512 */ @@ -1092,7 +1092,7 @@ static inline simd_s_t srslte_simd_s_load(int16_t *ptr) { #endif /* LV_HAVE_AVX512 */ } -static inline simd_s_t srslte_simd_s_loadu(int16_t *ptr) { +static inline simd_s_t srslte_simd_s_loadu(const int16_t *ptr) { #ifdef LV_HAVE_AVX512 return _mm512_loadu_si512(ptr); #else /* LV_HAVE_AVX512 */ @@ -1267,7 +1267,7 @@ typedef } simd_c16_t; /* Fixed point precision (16-bit) functions */ -static inline simd_c16_t srslte_simd_c16i_load(c16_t *ptr) { +static inline simd_c16_t srslte_simd_c16i_load(const c16_t *ptr) { simd_c16_t ret; #ifdef LV_HAVE_AVX512 __m512i in1 = _mm512_load_si512((__m512i*)(ptr)); @@ -1296,7 +1296,7 @@ static inline simd_c16_t srslte_simd_c16i_load(c16_t *ptr) { return ret; } -static inline simd_c16_t srslte_simd_c16_load(int16_t *re, int16_t *im) { +static inline simd_c16_t srslte_simd_c16_load(const int16_t *re, const int16_t *im) { simd_c16_t ret; #ifdef LV_HAVE_AVX2 ret.re.m256 = _mm256_load_si256((__m256i*)(re)); @@ -1315,7 +1315,7 @@ static inline simd_c16_t srslte_simd_c16_load(int16_t *re, int16_t *im) { return ret; } -static inline simd_c16_t srslte_simd_c16_loadu(int16_t *re, int16_t *im) { +static inline simd_c16_t srslte_simd_c16_loadu(const int16_t *re, const int16_t *im) { simd_c16_t ret; #ifdef LV_HAVE_AVX2 ret.re.m256 = _mm256_loadu_si256((__m256i*)(re)); diff --git a/lib/include/srslte/phy/utils/vector.h b/lib/include/srslte/phy/utils/vector.h index 7dad585a0..a4028e495 100644 --- a/lib/include/srslte/phy/utils/vector.h +++ b/lib/include/srslte/phy/utils/vector.h @@ -55,100 +55,100 @@ extern "C" { /*logical operations */ -SRSLTE_API void srslte_vec_xor_bbb(int8_t *x,int8_t *y,int8_t *z, uint32_t len); +SRSLTE_API void srslte_vec_xor_bbb(int8_t *x,int8_t *y,int8_t *z, const uint32_t len); /** Return the sum of all the elements */ -SRSLTE_API float srslte_vec_acc_ff(float *x, uint32_t len); -SRSLTE_API cf_t srslte_vec_acc_cc(cf_t *x, uint32_t len); +SRSLTE_API float srslte_vec_acc_ff(const float *x, const uint32_t len); +SRSLTE_API cf_t srslte_vec_acc_cc(const cf_t *x, const uint32_t len); SRSLTE_API void *srslte_vec_malloc(uint32_t size); SRSLTE_API void *srslte_vec_realloc(void *ptr, uint32_t old_size, uint32_t new_size); /* print vectors */ -SRSLTE_API void srslte_vec_fprint_c(FILE *stream, cf_t *x, uint32_t len); -SRSLTE_API void srslte_vec_fprint_f(FILE *stream, float *x, uint32_t len); -SRSLTE_API void srslte_vec_fprint_b(FILE *stream, uint8_t *x, uint32_t len); -SRSLTE_API void srslte_vec_fprint_byte(FILE *stream, uint8_t *x, uint32_t len); -SRSLTE_API void srslte_vec_fprint_i(FILE *stream, int *x, uint32_t len); -SRSLTE_API void srslte_vec_fprint_s(FILE *stream, short *x, uint32_t len); -SRSLTE_API void srslte_vec_fprint_hex(FILE *stream, uint8_t *x, uint32_t len); -SRSLTE_API void srslte_vec_sprint_hex(char *str, uint8_t *x, uint32_t len); +SRSLTE_API void srslte_vec_fprint_c(FILE *stream, cf_t *x, const uint32_t len); +SRSLTE_API void srslte_vec_fprint_f(FILE *stream, float *x, const uint32_t len); +SRSLTE_API void srslte_vec_fprint_b(FILE *stream, uint8_t *x, const uint32_t len); +SRSLTE_API void srslte_vec_fprint_byte(FILE *stream, uint8_t *x, const uint32_t len); +SRSLTE_API void srslte_vec_fprint_i(FILE *stream, int *x, const uint32_t len); +SRSLTE_API void srslte_vec_fprint_s(FILE *stream, short *x, const uint32_t len); +SRSLTE_API void srslte_vec_fprint_hex(FILE *stream, uint8_t *x, const uint32_t len); +SRSLTE_API void srslte_vec_sprint_hex(char *str, uint8_t *x, const uint32_t len); /* Saves/loads a vector to a file */ -SRSLTE_API void srslte_vec_save_file(char *filename, void *buffer, uint32_t len); -SRSLTE_API void srslte_vec_load_file(char *filename, void *buffer, uint32_t len); +SRSLTE_API void srslte_vec_save_file(char *filename, const void *buffer, const uint32_t len); +SRSLTE_API void srslte_vec_load_file(char *filename, void *buffer, const uint32_t len); /* sum two vectors */ -SRSLTE_API void srslte_vec_sum_fff(float *x, float *y, float *z, uint32_t len); -SRSLTE_API void srslte_vec_sum_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len); -SRSLTE_API void srslte_vec_sub_sss(int16_t *x, int16_t *y, int16_t *z, uint32_t len); -SRSLTE_API void srslte_vec_sum_sss(int16_t *x, int16_t *y, int16_t *z, uint32_t len); +SRSLTE_API void srslte_vec_sum_fff(const float *x, const float *y, float *z, const uint32_t len); +SRSLTE_API void srslte_vec_sum_ccc(const cf_t *x, const cf_t *y, cf_t *z, const uint32_t len); +SRSLTE_API void srslte_vec_sub_sss(const int16_t *x, const int16_t *y, int16_t *z, const uint32_t len); +SRSLTE_API void srslte_vec_sum_sss(const int16_t *x, const int16_t *y, int16_t *z, const uint32_t len); /* substract two vectors z=x-y */ -SRSLTE_API void srslte_vec_sub_fff(float *x, float *y, float *z, uint32_t len); -SRSLTE_API void srslte_vec_sub_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len); +SRSLTE_API void srslte_vec_sub_fff(const float *x, const float *y, float *z, const uint32_t len); +SRSLTE_API void srslte_vec_sub_ccc(const cf_t *x, const cf_t *y, cf_t *z, const uint32_t len); /* scalar product */ -SRSLTE_API void srslte_vec_sc_prod_cfc(cf_t *x, float h, cf_t *z, uint32_t len); -SRSLTE_API void srslte_vec_sc_prod_ccc(cf_t *x, cf_t h, cf_t *z, uint32_t len); -SRSLTE_API void srslte_vec_sc_prod_fff(float *x, float h, float *z, uint32_t len); +SRSLTE_API void srslte_vec_sc_prod_cfc(const cf_t *x, const float h, cf_t *z, const uint32_t len); +SRSLTE_API void srslte_vec_sc_prod_ccc(const cf_t *x, const cf_t h, cf_t *z, const uint32_t len); +SRSLTE_API void srslte_vec_sc_prod_fff(const float *x, const float h, float *z, const uint32_t len); -SRSLTE_API void srslte_vec_convert_fi(float *x, int16_t *z, float scale, uint32_t len); -SRSLTE_API void srslte_vec_convert_if(int16_t *x, float *z, float scale, uint32_t len); +SRSLTE_API void srslte_vec_convert_fi(const float *x, const float scale, int16_t *z, const uint32_t len); +SRSLTE_API void srslte_vec_convert_if(const int16_t *x, const float scale, float *z, const uint32_t len); -SRSLTE_API void srslte_vec_lut_sss(short *x, unsigned short *lut, short *y, uint32_t len); +SRSLTE_API void srslte_vec_lut_sss(const short *x, const unsigned short *lut, short *y, const uint32_t len); /* vector product (element-wise) */ -SRSLTE_API void srslte_vec_prod_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len); -SRSLTE_API void srslte_vec_prod_ccc_split(float *x_re, float *x_im, float *y_re, float *y_im, float *z_re, float *z_im, uint32_t len); +SRSLTE_API void srslte_vec_prod_ccc(const cf_t *x, const cf_t *y, cf_t *z, const uint32_t len); +SRSLTE_API void srslte_vec_prod_ccc_split(const float *x_re, const float *x_im, const float *y_re, const float *y_im, float *z_re, float *z_im, const uint32_t len); /* vector product (element-wise) */ -SRSLTE_API void srslte_vec_prod_cfc(cf_t *x, float *y, cf_t *z, uint32_t len); +SRSLTE_API void srslte_vec_prod_cfc(const cf_t *x, const float *y, cf_t *z, const uint32_t len); /* conjugate vector product (element-wise) */ -SRSLTE_API void srslte_vec_prod_conj_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len); +SRSLTE_API void srslte_vec_prod_conj_ccc(const cf_t *x, const cf_t *y, cf_t *z, const uint32_t len); /* real vector product (element-wise) */ -SRSLTE_API void srslte_vec_prod_fff(float *x, float *y, float *z, uint32_t len); -SRSLTE_API void srslte_vec_prod_sss(int16_t *x, int16_t *y, int16_t *z, uint32_t len); +SRSLTE_API void srslte_vec_prod_fff(const float *x, const float *y, float *z, const uint32_t len); +SRSLTE_API void srslte_vec_prod_sss(const int16_t *x, const int16_t *y, int16_t *z, const uint32_t len); /* Dot-product */ -SRSLTE_API cf_t srslte_vec_dot_prod_cfc(cf_t *x, float *y, uint32_t len); -SRSLTE_API cf_t srslte_vec_dot_prod_ccc(cf_t *x, cf_t *y, uint32_t len); -SRSLTE_API cf_t srslte_vec_dot_prod_conj_ccc(cf_t *x, cf_t *y, uint32_t len); -SRSLTE_API float srslte_vec_dot_prod_fff(float *x, float *y, uint32_t len); -SRSLTE_API int32_t srslte_vec_dot_prod_sss(int16_t *x, int16_t *y, uint32_t len); +SRSLTE_API cf_t srslte_vec_dot_prod_cfc(const cf_t *x, const float *y, const uint32_t len); +SRSLTE_API cf_t srslte_vec_dot_prod_ccc(const cf_t *x, const cf_t *y, const uint32_t len); +SRSLTE_API cf_t srslte_vec_dot_prod_conj_ccc(const cf_t *x, const cf_t *y, const uint32_t len); +SRSLTE_API float srslte_vec_dot_prod_fff(const float *x, const float *y, const uint32_t len); +SRSLTE_API int32_t srslte_vec_dot_prod_sss(const int16_t *x, const int16_t *y, const uint32_t len); /* z=x/y vector division (element-wise) */ -SRSLTE_API void srslte_vec_div_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len); -SRSLTE_API void srslte_vec_div_cfc(cf_t *x, float *y, cf_t *z, uint32_t len); -SRSLTE_API void srslte_vec_div_fff(float *x, float *y, float *z, uint32_t len); +SRSLTE_API void srslte_vec_div_ccc(const cf_t *x, const cf_t *y, cf_t *z, const uint32_t len); +SRSLTE_API void srslte_vec_div_cfc(const cf_t *x, const float *y, cf_t *z, const uint32_t len); +SRSLTE_API void srslte_vec_div_fff(const float *x, const float *y, float *z, const uint32_t len); /* conjugate */ -SRSLTE_API void srslte_vec_conj_cc(cf_t *x, cf_t *y, uint32_t len); +SRSLTE_API void srslte_vec_conj_cc(const cf_t *x, cf_t *y, const uint32_t len); /* average vector power */ -SRSLTE_API float srslte_vec_avg_power_cf(cf_t *x, uint32_t len); +SRSLTE_API float srslte_vec_avg_power_cf(const cf_t *x, const uint32_t len); /* Correlation between complex vectors x and y */ -SRSLTE_API float srslte_vec_corr_ccc(cf_t *x, cf_t *y, uint32_t len); +SRSLTE_API float srslte_vec_corr_ccc(const cf_t *x, cf_t *y, const uint32_t len); /* return the index of the maximum value in the vector */ -SRSLTE_API uint32_t srslte_vec_max_fi(float *x, uint32_t len); -SRSLTE_API uint32_t srslte_vec_max_abs_ci(cf_t *x, uint32_t len); +SRSLTE_API uint32_t srslte_vec_max_fi(const float *x, const uint32_t len); +SRSLTE_API uint32_t srslte_vec_max_abs_ci(const cf_t *x, const uint32_t len); /* quantify vector of floats or int16 and convert to uint8_t */ -SRSLTE_API void srslte_vec_quant_fuc(float *in, uint8_t *out, float gain, float offset, float clip, uint32_t len); -SRSLTE_API void srslte_vec_quant_suc(int16_t *in, uint8_t *out, float gain, int16_t offset, int16_t clip, uint32_t len); +SRSLTE_API void srslte_vec_quant_fuc(const float *in, uint8_t *out, const float gain, const float offset, const float clip, const uint32_t len); +SRSLTE_API void srslte_vec_quant_suc(const int16_t *in, uint8_t *out, const float gain, const int16_t offset, const int16_t clip, const uint32_t len); /* magnitude of each vector element */ -SRSLTE_API void srslte_vec_abs_cf(cf_t *x, float *abs, uint32_t len); -SRSLTE_API void srslte_vec_abs_square_cf(cf_t *x, float *abs_square, uint32_t len); +SRSLTE_API void srslte_vec_abs_cf(const cf_t *x, float *abs, const uint32_t len); +SRSLTE_API void srslte_vec_abs_square_cf(const cf_t *x, float *abs_square, const uint32_t len); /* Copy 256 bit aligned vector */ -SRSLTE_API void srs_vec_cf_cpy(cf_t *src, cf_t *dst, int len); +SRSLTE_API void srs_vec_cf_cpy(const cf_t *src, cf_t *dst, const int len); #ifdef __cplusplus } diff --git a/lib/include/srslte/phy/utils/vector_simd.h b/lib/include/srslte/phy/utils/vector_simd.h index 468c5e11a..54ac55f98 100644 --- a/lib/include/srslte/phy/utils/vector_simd.h +++ b/lib/include/srslte/phy/utils/vector_simd.h @@ -55,77 +55,78 @@ extern "C" { /*SIMD Logical operations*/ -SRSLTE_API void srslte_vec_xor_bbb_simd(int8_t *x, int8_t *y, int8_t *z, int len); +SRSLTE_API void srslte_vec_xor_bbb_simd(const int8_t *x, const int8_t *y, int8_t *z, int len); /* SIMD Basic vector math */ -SRSLTE_API void srslte_vec_sum_sss_simd(int16_t *x, int16_t *y, int16_t *z, int len); +SRSLTE_API void srslte_vec_sum_sss_simd(const int16_t *x, const int16_t *y, int16_t *z, int len); -SRSLTE_API void srslte_vec_sub_sss_simd(int16_t *x, int16_t *y, int16_t *z, int len); +SRSLTE_API void srslte_vec_sub_sss_simd(const int16_t *x, const int16_t *y, int16_t *z, int len); -SRSLTE_API float srslte_vec_acc_ff_simd(float *x, int len); +SRSLTE_API float srslte_vec_acc_ff_simd(const float *x, int len); -SRSLTE_API cf_t srslte_vec_acc_cc_simd(cf_t *x, int len); +SRSLTE_API cf_t srslte_vec_acc_cc_simd(const cf_t *x, int len); -SRSLTE_API void srslte_vec_add_fff_simd(float *x, float *y, float *z, int len); +SRSLTE_API void srslte_vec_add_fff_simd(const float *x, const float *y, float *z, int len); -SRSLTE_API void srslte_vec_sub_fff_simd(float *x, float *y, float *z, int len); +SRSLTE_API void srslte_vec_sub_fff_simd(const float *x, const float *y, float *z, int len); /* SIMD Vector Scalar Product */ -SRSLTE_API void srslte_vec_sc_prod_cfc_simd(const cf_t *x,const float h,cf_t *y,const int len); +SRSLTE_API void srslte_vec_sc_prod_cfc_simd(const cf_t *x, const float h,cf_t *y, const int len); -SRSLTE_API void srslte_vec_sc_prod_fff_simd(float *x, float h, float *z, int len); +SRSLTE_API void srslte_vec_sc_prod_fff_simd(const float *x, const float h, float *z, const int len); -SRSLTE_API void srslte_vec_sc_prod_ccc_simd(cf_t *x, cf_t h, cf_t *z, int len); +SRSLTE_API void srslte_vec_sc_prod_ccc_simd(const cf_t *x, const cf_t h, cf_t *z, const int len); /* SIMD Vector Product */ -SRSLTE_API void srslte_vec_prod_ccc_split_simd(float *a_re, float *a_im, float *b_re, float *b_im, float *r_re, float *r_im, int len); +SRSLTE_API void srslte_vec_prod_ccc_split_simd(const float *a_re, const float *a_im, const float *b_re, const float *b_im, + float *r_re, float *r_im, const int len); -SRSLTE_API void srslte_vec_prod_ccc_c16_simd(int16_t *a_re, int16_t *a_im, int16_t *b_re, int16_t *b_im, int16_t *r_re, - int16_t *r_im, int len); +SRSLTE_API void srslte_vec_prod_ccc_c16_simd(const int16_t *a_re, const int16_t *a_im, const int16_t *b_re, const int16_t *b_im, + int16_t *r_re, int16_t *r_im, const int len); -SRSLTE_API void srslte_vec_prod_sss_simd(int16_t *x, int16_t *y, int16_t *z, int len); +SRSLTE_API void srslte_vec_prod_sss_simd(const int16_t *x, const int16_t *y, int16_t *z, const int len); -SRSLTE_API void srslte_vec_prod_cfc_simd(cf_t *x, float *y, cf_t *z, int len); +SRSLTE_API void srslte_vec_prod_cfc_simd(const cf_t *x, const float *y, cf_t *z, const int len); -SRSLTE_API void srslte_vec_prod_fff_simd(float *x, float *y, float *z, int len); +SRSLTE_API void srslte_vec_prod_fff_simd(const float *x, const float *y, float *z, const int len); -SRSLTE_API void srslte_vec_prod_ccc_simd(cf_t *x,cf_t *y, cf_t *z, int len); +SRSLTE_API void srslte_vec_prod_ccc_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len); -SRSLTE_API void srslte_vec_prod_conj_ccc_simd(cf_t *x,cf_t *y, cf_t *z, int len); +SRSLTE_API void srslte_vec_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len); /* SIMD Division */ -SRSLTE_API void srslte_vec_div_ccc_simd(cf_t *x,cf_t *y, cf_t *z, int len); +SRSLTE_API void srslte_vec_div_ccc_simd(const cf_t *x, const cf_t *y, cf_t *z, const int len); -SRSLTE_API void srslte_vec_div_cfc_simd(cf_t *x, float *y, cf_t *z, int len); +SRSLTE_API void srslte_vec_div_cfc_simd(const cf_t *x, const float *y, cf_t *z, const int len); -SRSLTE_API void srslte_vec_div_fff_simd(float *x, float *y, float *z, int len); +SRSLTE_API void srslte_vec_div_fff_simd(const float *x, const float *y, float *z, const int len); /* SIMD Dot product */ -SRSLTE_API cf_t srslte_vec_dot_prod_conj_ccc_simd(cf_t *x, cf_t *y, int len); +SRSLTE_API cf_t srslte_vec_dot_prod_conj_ccc_simd(const cf_t *x, const cf_t *y, const int len); -SRSLTE_API cf_t srslte_vec_dot_prod_ccc_simd(cf_t *x, cf_t *y, int len); +SRSLTE_API cf_t srslte_vec_dot_prod_ccc_simd(const cf_t *x, const cf_t *y, const int len); -SRSLTE_API c16_t srslte_vec_dot_prod_ccc_c16i_simd(c16_t *x, c16_t *y, int len); +SRSLTE_API c16_t srslte_vec_dot_prod_ccc_c16i_simd(const c16_t *x, const c16_t *y, const int len); -SRSLTE_API int srslte_vec_dot_prod_sss_simd(int16_t *x, int16_t *y, int len); +SRSLTE_API int srslte_vec_dot_prod_sss_simd(const int16_t *x, const int16_t *y, const int len); /* SIMD Modulus functions */ -SRSLTE_API void srslte_vec_abs_cf_simd(cf_t *x, float *z, int len); +SRSLTE_API void srslte_vec_abs_cf_simd(const cf_t *x, float *z, const int len); -SRSLTE_API void srslte_vec_abs_square_cf_simd(cf_t *x, float *z, int len); +SRSLTE_API void srslte_vec_abs_square_cf_simd(const cf_t *x, float *z, const int len); /* Other Functions */ -SRSLTE_API void srslte_vec_lut_sss_simd(short *x, unsigned short *lut, short *y, int len); +SRSLTE_API void srslte_vec_lut_sss_simd(const short *x, const unsigned short *lut, short *y, const int len); -SRSLTE_API void srslte_vec_convert_fi_simd(float *x, int16_t *z, float scale, int len); +SRSLTE_API void srslte_vec_convert_fi_simd(const float *x, int16_t *z, const float scale, const int len); -SRSLTE_API void srslte_vec_cp_simd(cf_t *src, cf_t *dst, int len); +SRSLTE_API void srslte_vec_cp_simd(const cf_t *src, cf_t *dst, int len); /* SIMD Find Max functions */ -SRSLTE_API uint32_t srslte_vec_max_fi_simd(float *x, int len); +SRSLTE_API uint32_t srslte_vec_max_fi_simd(const float *x, const int len); -SRSLTE_API uint32_t srslte_vec_max_ci_simd(cf_t *x, int len); +SRSLTE_API uint32_t srslte_vec_max_ci_simd(const cf_t *x, const int len); #ifdef __cplusplus } diff --git a/lib/src/phy/dft/dft_fftw.c b/lib/src/phy/dft/dft_fftw.c index 9d6898117..e6eb70ecf 100644 --- a/lib/src/phy/dft/dft_fftw.c +++ b/lib/src/phy/dft/dft_fftw.c @@ -245,7 +245,7 @@ static void copy_post(uint8_t *dst, uint8_t *src, int size_d, int len, } } -void srslte_dft_run(srslte_dft_plan_t *plan, void *in, void *out) { +void srslte_dft_run(srslte_dft_plan_t *plan, const void *in, void *out) { if(plan->mode == SRSLTE_DFT_COMPLEX) { srslte_dft_run_c(plan,in,out); } else { @@ -253,11 +253,11 @@ void srslte_dft_run(srslte_dft_plan_t *plan, void *in, void *out) { } } -void srslte_dft_run_c_zerocopy(srslte_dft_plan_t *plan, cf_t *in, cf_t *out) { - fftwf_execute_dft(plan->p, in, out); +void srslte_dft_run_c_zerocopy(srslte_dft_plan_t *plan, const cf_t *in, cf_t *out) { + fftwf_execute_dft(plan->p, (cf_t*) in, out); } -void srslte_dft_run_c(srslte_dft_plan_t *plan, cf_t *in, cf_t *out) { +void srslte_dft_run_c(srslte_dft_plan_t *plan, const cf_t *in, cf_t *out) { float norm; int i; fftwf_complex *f_out = plan->out; @@ -286,7 +286,7 @@ void srslte_dft_run_guru_c(srslte_dft_plan_t *plan) { } } -void srslte_dft_run_r(srslte_dft_plan_t *plan, float *in, float *out) { +void srslte_dft_run_r(srslte_dft_plan_t *plan, const float *in, float *out) { float norm; int i; int len = plan->size; diff --git a/lib/src/phy/modem/demod_soft.c b/lib/src/phy/modem/demod_soft.c index 259a12271..0ea3ce938 100644 --- a/lib/src/phy/modem/demod_soft.c +++ b/lib/src/phy/modem/demod_soft.c @@ -57,11 +57,11 @@ void demod_bpsk_lte(const cf_t *symbols, float *llr, int nsymbols) { } void demod_qpsk_lte_s(const cf_t *symbols, short *llr, int nsymbols) { - srslte_vec_convert_fi((float*) symbols, llr, -SCALE_SHORT_CONV_QPSK*sqrt(2), nsymbols*2); + srslte_vec_convert_fi((const float*) symbols, -SCALE_SHORT_CONV_QPSK*sqrt(2), llr, nsymbols*2); } void demod_qpsk_lte(const cf_t *symbols, float *llr, int nsymbols) { - srslte_vec_sc_prod_fff((float*) symbols, -sqrt(2), llr, nsymbols*2); + srslte_vec_sc_prod_fff((const float*) symbols, -sqrt(2), llr, nsymbols*2); } void demod_16qam_lte(const cf_t *symbols, float *llr, int nsymbols) { diff --git a/lib/src/phy/resampling/test/resample_arb_bench.c b/lib/src/phy/resampling/test/resample_arb_bench.c index 773291913..e9ef3c442 100644 --- a/lib/src/phy/resampling/test/resample_arb_bench.c +++ b/lib/src/phy/resampling/test/resample_arb_bench.c @@ -50,7 +50,7 @@ int main(int argc, char **argv) { clock_t start = clock(), diff; for(int xx = 0; xxrx_rate, meta.timestamp, secs, frac_secs); - srslte_vec_convert_if(handler->rx_buffer, data, 2048, 2*nsamples); + srslte_vec_convert_if(handler->rx_buffer, 2048, data, 2*nsamples); return nsamples; } @@ -506,7 +506,7 @@ int rf_blade_send_timed(void *h, return -1; } - srslte_vec_convert_fi(data, handler->tx_buffer, 2048, 2*nsamples); + srslte_vec_convert_fi(data, 2048, handler->tx_buffer, 2*nsamples); memset(&meta, 0, sizeof(meta)); if (is_start_of_burst) { diff --git a/lib/src/phy/rf/rf_utils.c b/lib/src/phy/rf/rf_utils.c index ce288b5c5..f97784305 100644 --- a/lib/src/phy/rf/rf_utils.c +++ b/lib/src/phy/rf/rf_utils.c @@ -123,12 +123,7 @@ 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); - - // Set CFO if available - if (cfo) { - srslte_ue_sync_set_cfo(&ue_mib.ue_sync, *cfo); - } - + /* Find and decody MIB */ ret = srslte_ue_mib_sync_decode(&ue_mib, config->max_frames_pbch, bch_payload, &cell->nof_ports, NULL); if (ret < 0) { diff --git a/lib/src/phy/sync/cfo.c b/lib/src/phy/sync/cfo.c index 34498ce58..44c795c19 100644 --- a/lib/src/phy/sync/cfo.c +++ b/lib/src/phy/sync/cfo.c @@ -83,7 +83,7 @@ int srslte_cfo_resize(srslte_cfo_t *h, uint32_t samples) { return SRSLTE_SUCCESS; } -void srslte_cfo_correct(srslte_cfo_t *h, cf_t *input, cf_t *output, float freq) { +void srslte_cfo_correct(srslte_cfo_t *h, const cf_t *input, cf_t *output, float freq) { if (fabs(h->last_freq - freq) > h->tol) { h->last_freq = freq; srslte_cexptab_gen(&h->tab, h->cur_cexp, h->last_freq, h->nsamples); diff --git a/lib/src/phy/sync/cp.c b/lib/src/phy/sync/cp.c index a282f6dfd..80d0a2179 100644 --- a/lib/src/phy/sync/cp.c +++ b/lib/src/phy/sync/cp.c @@ -63,14 +63,14 @@ int srslte_cp_synch_resize(srslte_cp_synch_t *q, uint32_t symbol_sz) } -uint32_t srslte_cp_synch(srslte_cp_synch_t *q, cf_t *input, uint32_t max_offset, uint32_t nof_symbols, uint32_t cp_len) +uint32_t srslte_cp_synch(srslte_cp_synch_t *q, const cf_t *input, uint32_t max_offset, uint32_t nof_symbols, uint32_t cp_len) { if (max_offset > q->symbol_sz) { max_offset = q->symbol_sz; } for (int i=0;icorr[i] = 0; - cf_t *inputPtr = input; + const cf_t *inputPtr = input; for (int n=0;ncorr[i] += srslte_vec_dot_prod_conj_ccc(&inputPtr[i], &inputPtr[i+q->symbol_sz], cplen)/nof_symbols; diff --git a/lib/src/phy/sync/find_sss.c b/lib/src/phy/sync/find_sss.c index 082aee52a..70b300bd3 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, cf_t *input, cf_t *ce, cf_t y[2][SRSLTE_SSS_N]) { +static void extract_pair_sss(srslte_sss_synch_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,7 +88,7 @@ static void extract_pair_sss(srslte_sss_synch_t *q, cf_t *input, cf_t *ce, cf_t } -int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, cf_t *input, uint32_t *m0, float *m0_value, +int srslte_sss_synch_m0m1_diff(srslte_sss_synch_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); @@ -102,7 +102,7 @@ int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, cf_t *input, uint32_t *m0, * */ -int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, cf_t *input, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, +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, uint32_t *m1, float *m1_value) { @@ -145,7 +145,7 @@ int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, cf_t *input, cf_t ce[2 * Jung-In Kim, Jung-Su Han, Hee-Jin Roh and Hyung-Jin Choi */ -int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q, cf_t *input, uint32_t M, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, +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, uint32_t *m1, float *m1_value) { diff --git a/lib/src/phy/sync/pss.c b/lib/src/phy/sync/pss.c index 411579d7c..d93fe0896 100644 --- a/lib/src/phy/sync/pss.c +++ b/lib/src/phy/sync/pss.c @@ -119,7 +119,7 @@ int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q, buffer_size = fft_size + frame_size + 1; - q->filter_pss_enable = true; + q->filter_pss_enable = false; if(q->decimate > 1) { int filter_order = 3; @@ -417,6 +417,37 @@ void srslte_pss_synch_set_ema_alpha(srslte_pss_synch_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) +{ + // Find end of peak lobe to the right + int pl_ub = corr_peak_pos+1; + while(q->conv_output_avg[pl_ub+1] <= q->conv_output_avg[pl_ub] && pl_ub < conv_output_len) { + pl_ub ++; + } + // Find end of peak lobe to the left + int pl_lb; + if (corr_peak_pos > 2) { + pl_lb = corr_peak_pos-1; + while(q->conv_output_avg[pl_lb-1] <= q->conv_output_avg[pl_lb] && pl_lb > 1) { + pl_lb --; + } + } else { + pl_lb = 0; + } + + int sl_distance_right = conv_output_len-1-pl_ub; + if (sl_distance_right < 0) { + sl_distance_right = 0; + } + int sl_distance_left = pl_lb; + + int sl_right = pl_ub+srslte_vec_max_fi(&q->conv_output_avg[pl_ub], sl_distance_right); + int sl_left = srslte_vec_max_fi(q->conv_output_avg, sl_distance_left); + float side_lobe_value = SRSLTE_MAX(q->conv_output_avg[sl_right], q->conv_output_avg[sl_left]); + + return q->conv_output_avg[corr_peak_pos]/side_lobe_value; +} + /** Performs time-domain PSS correlation. * Returns the index of the PSS correlation peak in a subframe. * The frame starts at corr_peak_pos-subframe_size/2. @@ -424,7 +455,7 @@ void srslte_pss_synch_set_ema_alpha(srslte_pss_synch_t *q, float alpha) { * * Input buffer must be subframe_size long. */ -int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, cf_t *input, float *corr_peak_value) +int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, const cf_t *input, float *corr_peak_value) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -448,16 +479,13 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, cf_t *input, float *corr_pe */ if (q->frame_size >= q->fft_size) { #ifdef CONVOLUTION_FFT - memcpy(q->tmp_input, input, (q->frame_size * q->decimate) * sizeof(cf_t)); - if(q->decimate > 1) - { - srslte_filt_decim_cc_execute(&(q->filter), q->tmp_input, q->filter.downsampled_input, q->filter.filter_output , (q->frame_size * q->decimate)); - conv_output_len = srslte_conv_fft_cc_run_opt(&q->conv_fft, q->filter.filter_output,q->pss_signal_freq_full[q->N_id_2], q->conv_output); - } - else - { - conv_output_len = srslte_conv_fft_cc_run_opt(&q->conv_fft, q->tmp_input, q->pss_signal_freq_full[q->N_id_2], q->conv_output); - } + memcpy(q->tmp_input, input, (q->frame_size * q->decimate) * sizeof(cf_t)); + if(q->decimate > 1) { + srslte_filt_decim_cc_execute(&(q->filter), q->tmp_input, q->filter.downsampled_input, q->filter.filter_output , (q->frame_size * q->decimate)); + conv_output_len = srslte_conv_fft_cc_run_opt(&q->conv_fft, q->filter.filter_output,q->pss_signal_freq_full[q->N_id_2], q->conv_output); + } else { + conv_output_len = srslte_conv_fft_cc_run_opt(&q->conv_fft, q->tmp_input, q->pss_signal_freq_full[q->N_id_2], q->conv_output); + } #else conv_output_len = srslte_conv_cc(input, q->pss_signal_time[q->N_id_2], q->conv_output, q->frame_size, q->fft_size); @@ -469,13 +497,10 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, cf_t *input, float *corr_pe conv_output_len = q->frame_size; } + // Compute modulus square + srslte_vec_abs_square_cf(q->conv_output, q->conv_output_abs, conv_output_len-1); - #ifdef SRSLTE_PSS_ABS_SQUARE - srslte_vec_abs_square_cf(q->conv_output, q->conv_output_abs, conv_output_len-1); - #else - srslte_vec_abs_cf(q->conv_output, q->conv_output_abs, conv_output_len-1); - #endif - + // If enabled, average the absolute value from previous calls if (q->ema_alpha < 1.0 && q->ema_alpha > 0.0) { srslte_vec_sc_prod_fff(q->conv_output_abs, q->ema_alpha, q->conv_output_abs, conv_output_len-1); srslte_vec_sc_prod_fff(q->conv_output_avg, 1-q->ema_alpha, q->conv_output_avg, conv_output_len-1); @@ -484,6 +509,7 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, cf_t *input, float *corr_pe } else { memcpy(q->conv_output_avg, q->conv_output_abs, sizeof(float)*(conv_output_len-1)); } + /* Find maximum of the absolute value of the correlation */ corr_peak_pos = srslte_vec_max_fi(q->conv_output_avg, conv_output_len-1); @@ -491,39 +517,8 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, cf_t *input, float *corr_pe q->peak_value = q->conv_output_avg[corr_peak_pos]; #ifdef SRSLTE_PSS_RETURN_PSR - // Find second side lobe - - // Find end of peak lobe to the right - int pl_ub = corr_peak_pos+1; - while(q->conv_output_avg[pl_ub+1] <= q->conv_output_avg[pl_ub] && pl_ub < conv_output_len) { - pl_ub ++; - } - // Find end of peak lobe to the left - int pl_lb; - if (corr_peak_pos > 2) { - pl_lb = corr_peak_pos-1; - while(q->conv_output_avg[pl_lb-1] <= q->conv_output_avg[pl_lb] && pl_lb > 1) { - pl_lb --; - } - } else { - pl_lb = 0; - } - - int sl_distance_right = conv_output_len-1-pl_ub; - if (sl_distance_right < 0) { - sl_distance_right = 0; - } - int sl_distance_left = pl_lb; - - int sl_right = pl_ub+srslte_vec_max_fi(&q->conv_output_avg[pl_ub], sl_distance_right); - int sl_left = srslte_vec_max_fi(q->conv_output_avg, sl_distance_left); - float side_lobe_value = SRSLTE_MAX(q->conv_output_avg[sl_right], q->conv_output_avg[sl_left]); if (corr_peak_value) { - *corr_peak_value = q->conv_output_avg[corr_peak_pos]/side_lobe_value; - - if (*corr_peak_value < 10) - DEBUG("peak_pos=%2d, pl_ub=%2d, pl_lb=%2d, sl_right: %2d, sl_left: %2d, PSR: %.2f/%.2f=%.2f\n", corr_peak_pos, pl_ub, pl_lb, - sl_right,sl_left, q->conv_output_avg[corr_peak_pos], side_lobe_value,*corr_peak_value); + *corr_peak_value = compute_peak_sidelobe(q, corr_peak_pos, conv_output_len); } #else if (corr_peak_value) { @@ -531,14 +526,12 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, cf_t *input, float *corr_pe } #endif - if(q->decimate >1) - { - int decimation_correction = (q->filter.num_taps - 2); - corr_peak_pos = corr_peak_pos - decimation_correction; - corr_peak_pos = corr_peak_pos*q->decimate; + if(q->decimate >1) { + int decimation_correction = (q->filter.num_taps - 2); + corr_peak_pos = corr_peak_pos - decimation_correction; + corr_peak_pos = corr_peak_pos*q->decimate; } - if (q->frame_size >= q->fft_size) { ret = (int) corr_peak_pos; } else { @@ -552,7 +545,7 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, cf_t *input, float *corr_pe * 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, cf_t *input, cf_t ce[SRSLTE_PSS_LEN]) { +int srslte_pss_synch_chest(srslte_pss_synch_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]; @@ -577,7 +570,7 @@ int srslte_pss_synch_chest(srslte_pss_synch_t *q, cf_t *input, cf_t ce[SRSLTE_PS } // Frequency-domain filtering of the central 64 sub-carriers -void srslte_pss_synch_filter(srslte_pss_synch_t *q, cf_t *input, cf_t *output) +void srslte_pss_synch_filter(srslte_pss_synch_t *q, const cf_t *input, cf_t *output) { srslte_dft_run_c(&q->dftp_input, input, q->tmp_fft); @@ -593,14 +586,14 @@ void srslte_pss_synch_filter(srslte_pss_synch_t *q, cf_t *input, cf_t *output) * 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, cf_t *pss_recv) { +float srslte_pss_synch_cfo_compute(srslte_pss_synch_t* q, const cf_t *pss_recv) { cf_t y0, y1; - cf_t *pss_ptr = pss_recv; + const cf_t *pss_ptr = pss_recv; if (q->filter_pss_enable) { srslte_pss_synch_filter(q, pss_recv, q->tmp_fft); - pss_ptr = q->tmp_fft; + pss_ptr = (const cf_t*) q->tmp_fft; } y0 = srslte_vec_dot_prod_ccc(q->pss_signal_time[q->N_id_2], pss_ptr, q->fft_size/2); diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index d1a477046..d14419965 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -37,11 +37,10 @@ #include "srslte/phy/utils/vector.h" #include "srslte/phy/sync/cfo.h" -#define MEANPEAK_EMA_ALPHA 0.1 -#define CFO_EMA_ALPHA 0.1 -#define CP_EMA_ALPHA 0.1 +#define CFO_EMA_ALPHA 0.1 +#define CP_EMA_ALPHA 0.1 -#define DEFAULT_CFO_TOL 50.0 // Hz +#define DEFAULT_CFO_TOL 50.0 // Hz static bool fft_size_isvalid(uint32_t fft_size) { if (fft_size >= SRSLTE_SYNC_FFT_SZ_MIN && fft_size <= SRSLTE_SYNC_FFT_SZ_MAX && (fft_size%64) == 0) { @@ -51,13 +50,12 @@ static bool fft_size_isvalid(uint32_t fft_size) { } } - - int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, uint32_t fft_size) { return srslte_sync_init_decim(q, frame_size, max_offset, fft_size, 1); } -int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, uint32_t fft_size, int decimate) { +int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, uint32_t fft_size, int decimate) +{ int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -67,31 +65,34 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_sync_t)); - q->detect_cp = true; - q->sss_en = true; - q->mean_cfo = 0; - q->mean_cfo2 = 0; - q->N_id_2 = 1000; + + q->N_id_2 = 1000; q->N_id_1 = 1000; - q->cfo_i = 0; - q->find_cfo_i = false; - q->find_cfo_i_initiated = false; + q->cfo_ema_alpha = CFO_EMA_ALPHA; + q->sss_alg = SSS_FULL; + + q->detect_cp = true; + q->sss_en = true; + q->cfo_pss_enable = false; + 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; q->max_offset = max_offset; - q->sss_alg = SSS_FULL; q->max_frame_size = frame_size; - q->mean_cfo_isunset = true; - q->mean_cfo2_isunset = true; - q->enable_cfo_corr = true; - if (srslte_cfo_init(&q->cfocorr, q->frame_size)) { + srslte_sync_cfo_reset(q); + + if (srslte_cfo_init(&q->cfo_corr_frame, q->frame_size)) { fprintf(stderr, "Error initiating CFO\n"); goto clean_exit; } - if (srslte_cfo_init(&q->cfocorr2, q->frame_size)) { + if (srslte_cfo_init(&q->cfo_corr_symbol, q->fft_size)) { fprintf(stderr, "Error initiating CFO\n"); goto clean_exit; } @@ -147,18 +148,23 @@ clean_exit: return ret; } -void srslte_sync_free(srslte_sync_t *q) { +void srslte_sync_free(srslte_sync_t *q) +{ if (q) { + srslte_pss_synch_free(&q->pss); srslte_sss_synch_free(&q->sss); - srslte_cfo_free(&q->cfocorr); - srslte_cfo_free(&q->cfocorr2); + srslte_cfo_free(&q->cfo_corr_frame); + srslte_cfo_free(&q->cfo_corr_symbol); srslte_cp_synch_free(&q->cp_synch); - for (int i=0;i<2;i++) { - if (q->cfo_i_corr[i]) { - free(q->cfo_i_corr[i]); + + if (q->cfo_i_initiated) { + for (int i=0;i<2;i++) { + if (q->cfo_i_corr[i]) { + free(q->cfo_i_corr[i]); + } + srslte_pss_synch_free(&q->pss_i[i]); } - srslte_pss_synch_free(&q->pss_i[i]); } if (q->temp) { free(q->temp); @@ -174,53 +180,51 @@ int srslte_sync_resize(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offse frame_size <= 307200 && fft_size_isvalid(fft_size)) { - ret = SRSLTE_ERROR; - if (frame_size > q->max_frame_size) { fprintf(stderr, "Error in sync_resize(): frame_size must be lower than initialized\n"); return SRSLTE_ERROR; } - q->detect_cp = true; - q->sss_en = true; - q->mean_cfo = 0; - q->mean_cfo2 = 0; - q->N_id_2 = 1000; - q->N_id_1 = 1000; - q->cfo_i = 0; - q->find_cfo_i = false; - q->find_cfo_i_initiated = false; - q->cfo_ema_alpha = CFO_EMA_ALPHA; - q->fft_size = fft_size; + + q->fft_size = fft_size; q->frame_size = frame_size; q->max_offset = max_offset; - q->sss_alg = SSS_FULL; - q->enable_cfo_corr = true; - - if (srslte_pss_synch_resize(&q->pss, max_offset, fft_size, 0)) { + if (srslte_pss_synch_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, fft_size)) { + if (srslte_sss_synch_resize(&q->sss, q->fft_size)) { fprintf(stderr, "Error resizing SSS object\n"); return SRSLTE_ERROR; } - if (srslte_cp_synch_resize(&q->cp_synch, fft_size)) { + if (srslte_cp_synch_resize(&q->cp_synch, q->fft_size)) { fprintf(stderr, "Error resizing CFO\n"); return SRSLTE_ERROR; } - if (srslte_cfo_resize(&q->cfocorr, q->frame_size)) { + if (srslte_cfo_resize(&q->cfo_corr_frame, q->frame_size)) { fprintf(stderr, "Error resizing CFO\n"); return SRSLTE_ERROR; } - if (srslte_cfo_resize(&q->cfocorr2, q->frame_size)) { + if (srslte_cfo_resize(&q->cfo_corr_symbol, q->fft_size)) { fprintf(stderr, "Error resizing CFO\n"); return SRSLTE_ERROR; } + 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)) { + fprintf(stderr, "Error initializing PSS object\n"); + } + for (int t=0;tframe_size;t++) { + q->cfo_i_corr[i][t] = cexpf(-2*_Complex_I*M_PI*offset*(float) t/q->fft_size); + } + } + } + // Update CFO tolerance srslte_sync_set_cfo_tol(q, q->current_cfo_tol); @@ -236,30 +240,14 @@ int srslte_sync_resize(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offse void srslte_sync_set_cfo_tol(srslte_sync_t *q, float tol) { q->current_cfo_tol = tol; - srslte_cfo_set_tol(&q->cfocorr, tol/(15000.0*q->fft_size)); - srslte_cfo_set_tol(&q->cfocorr2, tol/(15000.0*q->fft_size)); + srslte_cfo_set_tol(&q->cfo_corr_frame, tol/(15000.0*q->fft_size)); + srslte_cfo_set_tol(&q->cfo_corr_symbol, tol/(15000.0*q->fft_size)); } void srslte_sync_set_threshold(srslte_sync_t *q, float threshold) { q->threshold = threshold; } -void srslte_sync_cfo_i_detec_en(srslte_sync_t *q, bool enabled) { - q->find_cfo_i = enabled; - if (enabled && !q->find_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)) { - fprintf(stderr, "Error initializing PSS object\n"); - } - for (int t=0;tframe_size;t++) { - q->cfo_i_corr[i][t] = cexpf(-2*_Complex_I*M_PI*offset*(float) t/q->fft_size); - } - } - q->find_cfo_i_initiated = true; - } -} - void srslte_sync_sss_en(srslte_sync_t *q, bool enabled) { q->sss_en = enabled; } @@ -291,32 +279,61 @@ uint32_t srslte_sync_get_sf_idx(srslte_sync_t *q) { } float srslte_sync_get_cfo(srslte_sync_t *q) { - return q->mean_cfo2 + q->cfo_i; + return q->cfo_cp_mean + q->cfo_pss_mean + q->cfo_i_value; } -void srslte_sync_set_cfo(srslte_sync_t *q, float cfo) { - q->mean_cfo = cfo; - q->mean_cfo2 = cfo; - q->mean_cfo2_isunset = false; - q->mean_cfo_isunset = false; +void srslte_sync_cfo_reset(srslte_sync_t *q) +{ + q->cfo_cp_mean = 0; + q->cfo_cp_is_set = false; + q->cfo_pss_mean = 0; + q->cfo_pss_is_set = false; } -void srslte_sync_set_cfo_i(srslte_sync_t *q, int cfo_i) { - q->cfo_i = cfo_i; +void srslte_sync_copy_cfo(srslte_sync_t *q, srslte_sync_t *src_obj) { + q->cfo_cp_mean = src_obj->cfo_cp_mean; + q->cfo_pss_mean = src_obj->cfo_pss_mean; + q->cfo_i_value = src_obj->cfo_i_value; + q->cfo_cp_is_set = false; + q->cfo_pss_is_set = false; } -void srslte_sync_set_cfo_enable(srslte_sync_t *q, bool enable) { - q->enable_cfo_corr = enable; +void srslte_sync_set_cfo_i_enable(srslte_sync_t *q, bool enable) { + q->cfo_i_enable = 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)) { + fprintf(stderr, "Error initializing PSS object\n"); + } + for (int t=0;tframe_size;t++) { + q->cfo_i_corr[i][t] = cexpf(-2*_Complex_I*M_PI*offset*(float) t/q->fft_size); + } + } + q->cfo_i_initiated = true; + } +} + +void srslte_sync_set_sss_filt_enable(srslte_sync_t *q, bool enable) { + q->sss_filtering_enabled = enable; +} + +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_pss_enable(srslte_sync_t *q, bool enable) { + q->cfo_pss_enable = enable; } void srslte_sync_set_cfo_ema_alpha(srslte_sync_t *q, float alpha) { q->cfo_ema_alpha = alpha; } -float srslte_sync_get_last_peak_value(srslte_sync_t *q) { - return q->peak_value; -} - float srslte_sync_get_peak_value(srslte_sync_t *q) { return q->peak_value; } @@ -325,18 +342,17 @@ void srslte_sync_cp_en(srslte_sync_t *q, bool enabled) { q->detect_cp = enabled; } -bool srslte_sync_sss_is_en(srslte_sync_t *q) { - return q->sss_en; -} - -void srslte_sync_set_em_alpha(srslte_sync_t *q, float alpha) { +void srslte_sync_set_em_alpha(srslte_sync_t *q, float alpha) +{ srslte_pss_synch_set_ema_alpha(&q->pss, alpha); } -srslte_cp_t srslte_sync_get_cp(srslte_sync_t *q) { +srslte_cp_t srslte_sync_get_cp(srslte_sync_t *q) +{ return q->cp; } -void srslte_sync_set_cp(srslte_sync_t *q, srslte_cp_t cp) { +void srslte_sync_set_cp(srslte_sync_t *q, srslte_cp_t cp) +{ q->cp = cp; q->cp_len = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(1,q->fft_size):SRSLTE_CP_LEN_EXT(q->fft_size); if (q->frame_size < q->fft_size) { @@ -346,7 +362,8 @@ void srslte_sync_set_cp(srslte_sync_t *q, srslte_cp_t cp) { } } -void srslte_sync_set_sss_algorithm(srslte_sync_t *q, sss_alg_t alg) { +void srslte_sync_set_sss_algorithm(srslte_sync_t *q, sss_alg_t alg) +{ q->sss_alg = alg; } @@ -354,7 +371,7 @@ void srslte_sync_set_sss_algorithm(srslte_sync_t *q, sss_alg_t alg) { * "SSS Detection Method for Initial Cell Search in 3GPP LTE FDD/TDD Dual Mode Receiver" * by Jung-In Kim et al. */ -srslte_cp_t srslte_sync_detect_cp(srslte_sync_t *q, cf_t *input, uint32_t peak_pos) +srslte_cp_t srslte_sync_detect_cp(srslte_sync_t *q, const cf_t *input, uint32_t peak_pos) { float R_norm=0, R_ext=0, C_norm=0, C_ext=0; float M_norm=0, M_ext=0; @@ -370,8 +387,8 @@ srslte_cp_t srslte_sync_detect_cp(srslte_sync_t *q, cf_t *input, uint32_t peak_p if (nof_symbols > 0) { - cf_t *input_cp_norm = &input[peak_pos-nof_symbols*(q->fft_size+cp_norm_len)]; - cf_t *input_cp_ext = &input[peak_pos-nof_symbols*(q->fft_size+cp_ext_len)]; + const cf_t *input_cp_norm = &input[peak_pos-nof_symbols*(q->fft_size+cp_norm_len)]; + const cf_t *input_cp_ext = &input[peak_pos-nof_symbols*(q->fft_size+cp_ext_len)]; for (int i=0;ifft_size], input_cp_norm, cp_norm_len)); @@ -414,28 +431,21 @@ srslte_cp_t srslte_sync_detect_cp(srslte_sync_t *q, cf_t *input, uint32_t peak_p /* Returns 1 if the SSS is found, 0 if not and -1 if there is not enough space * to correlate */ -int sync_sss(srslte_sync_t *q, cf_t *input, uint32_t peak_pos, srslte_cp_t cp) { - int sss_idx, ret; +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); - /* Make sure we have enough room to find SSS sequence */ - sss_idx = (int) peak_pos-2*q->fft_size-SRSLTE_CP_LEN(q->fft_size, (SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM_LEN:SRSLTE_CP_EXT_LEN)); - if (sss_idx < 0) { - DEBUG("Not enough room to decode SSS (sss_idx=%d, peak_pos=%d)\n", sss_idx, peak_pos); - return SRSLTE_ERROR; - } - DEBUG("Searching SSS around sss_idx: %d, peak_pos: %d\n", sss_idx, peak_pos); - switch(q->sss_alg) { case SSS_DIFF: - srslte_sss_synch_m0m1_diff(&q->sss, &input[sss_idx], &q->m0, &q->m0_value, &q->m1, &q->m1_value); + srslte_sss_synch_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[sss_idx], 3, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); + srslte_sss_synch_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[sss_idx], 1, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); + srslte_sss_synch_m0m1_partial(&q->sss, input, 1, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); break; } @@ -452,20 +462,23 @@ int sync_sss(srslte_sync_t *q, cf_t *input, uint32_t peak_pos, srslte_cp_t cp) { } } -srslte_pss_synch_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q) { +srslte_pss_synch_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]}; - return pss_obj[q->cfo_i+1]; + return pss_obj[q->cfo_i_value+1]; } -static float cfo_estimate(srslte_sync_t *q, cf_t *input) { +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, 2, SRSLTE_CP_LEN_NORM(1,q->fft_size)); + cp_offset = srslte_cp_synch(&q->cp_synch, input, q->max_offset, 7, 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; } -static int cfo_i_estimate(srslte_sync_t *q, cf_t *input, int find_offset, int *peak_pos) { +static int cfo_i_estimate(srslte_sync_t *q, const cf_t *input, int find_offset, int *peak_pos, int *cfo_i) +{ float peak_value; float max_peak_value = -99; int max_cfo_i = 0; @@ -473,6 +486,9 @@ static int cfo_i_estimate(srslte_sync_t *q, cf_t *input, int find_offset, int *p 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); + if (p < 0) { + return -1; + } if (peak_value > max_peak_value) { max_peak_value = peak_value; if (peak_pos) { @@ -481,125 +497,172 @@ static int cfo_i_estimate(srslte_sync_t *q, cf_t *input, int find_offset, int *p q->peak_value = peak_value; max_cfo_i = cfo_i-1; } - } - return max_cfo_i; -} - -float srslte_sync_cfo_estimate(srslte_sync_t *q, cf_t *input, int find_offset) { - float cfo_f = cfo_estimate(q, input); - - int cfo_i = 0; - if (q->find_cfo_i) { - cfo_i = cfo_i_estimate(q, input, find_offset, NULL); } - return (float) cfo_i + cfo_f; + if (cfo_i) { + *cfo_i = max_cfo_i; + } + return 0; } /** Finds the PSS sequence previously defined by a call to srslte_sync_set_N_id_2() - * around the position find_offset in the buffer input. + * around the position find_offset in the buffer input. + * * Returns 1 if the correlation peak exceeds the threshold set by srslte_sync_set_threshold() * or 0 otherwise. Returns a negative number on error (if N_id_2 has not been set) - * + * + * The input signal is not modified. Any CFO correction is done in internal buffers + * * The maximum of the correlation peak is always stored in *peak_position */ -srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32_t *peak_position) +srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, const cf_t *input, uint32_t find_offset, uint32_t *peak_position) { - - srslte_sync_find_ret_t ret = SRSLTE_SYNC_ERROR; - + srslte_sync_find_ret_t ret = SRSLTE_SYNC_ERROR; + int peak_pos = 0; + if (!q) { return SRSLTE_ERROR_INVALID_INPUTS; } - if (input != NULL && + if (input != NULL && srslte_N_id_2_isvalid(q->N_id_2) && fft_size_isvalid(q->fft_size)) { - int peak_pos = 0; - - ret = SRSLTE_SUCCESS; - + if (peak_position) { *peak_position = 0; } - cf_t *input_cfo = input; + const cf_t *input_ptr = input; - if (q->enable_cfo_corr) { - float cfo = cfo_estimate(q, input); + /* First CFO estimation stage is integer. + * Finds max PSS correlation for shifted +1/0/-1 integer versions. + * This should only used once N_id_2 is set + */ + if (q->cfo_i_enable) { + if (cfo_i_estimate(q, input_ptr, find_offset, &peak_pos, &q->cfo_i_value) < 0) { + fprintf(stderr, "Error calling finding PSS sequence at : %d \n", peak_pos); + return SRSLTE_ERROR; + } + // Correct it using precomputed signal and store in buffer (don't modify input signal) + if (q->cfo_i_value != 0) { + srslte_vec_prod_ccc((cf_t*) input_ptr, q->cfo_i_corr[q->cfo_i_value<0?0:1], q->temp, q->frame_size); + INFO("Compensating cfo_i=%d\n", q->cfo_i_value); + input_ptr = q->temp; + } + } - if (q->mean_cfo_isunset) { - q->mean_cfo = cfo; - q->mean_cfo_isunset = false; + /* Second stage is coarse fractional CFO estimation using CP. + * In case of multi-cell, this can lead to incorrect estimations if CFO from different cells is different + */ + if (q->cfo_cp_enable) { + float cfo_cp = cfo_cp_estimate(q, input_ptr); + + if (!q->cfo_cp_is_set) { + q->cfo_cp_mean = cfo_cp; + q->cfo_cp_is_set = true; } else { /* compute exponential moving average CFO */ - q->mean_cfo = SRSLTE_VEC_EMA(cfo, q->mean_cfo, q->cfo_ema_alpha); + q->cfo_cp_mean = SRSLTE_VEC_EMA(cfo_cp, q->cfo_cp_mean, q->cfo_ema_alpha); } + INFO("CP-CFO: estimated=%f, mean=%f\n", cfo_cp, q->cfo_cp_mean); + /* Correct CFO with the averaged CFO estimation */ - srslte_cfo_correct(&q->cfocorr2, input, q->temp, -q->mean_cfo / q->fft_size); - - input_cfo = q->temp; + srslte_cfo_correct(&q->cfo_corr_frame, input_ptr, q->temp, -q->cfo_cp_mean / q->fft_size); + input_ptr = q->temp; } - - /* If integer CFO is enabled, find max PSS correlation for shifted +1/0/-1 integer versions */ - if (q->find_cfo_i && q->enable_cfo_corr) { - q->cfo_i = cfo_i_estimate(q, input_cfo, find_offset, &peak_pos); - if (q->cfo_i != 0) { - srslte_vec_prod_ccc(input_cfo, q->cfo_i_corr[q->cfo_i<0?0:1], input_cfo, q->frame_size); - INFO("Compensating cfo_i=%d\n", q->cfo_i); + + /* 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); + if (peak_pos < 0) { + fprintf(stderr, "Error calling finding PSS sequence at : %d \n", peak_pos); + return SRSLTE_ERROR; } } - srslte_pss_synch_set_N_id_2(&q->pss, q->N_id_2); - peak_pos = srslte_pss_synch_find_pss(&q->pss, &input_cfo[find_offset], &q->peak_value); - - // this compensates for the constant time shift caused by the low pass filter - if(q->decimate && peak_pos < 0) - { - peak_pos = 0 ;//peak_pos + q->decimate*(2);// replace 2 with q->filter_size -2; - } - if (peak_pos < 0) { - fprintf(stderr, "Error calling finding PSS sequence at : %d \n", peak_pos); - return SRSLTE_ERROR; - } + INFO("PSS: id=%d, peak_pos=%d, peak_value=%f\n", q->N_id_2, peak_pos, q->peak_value); + // Save peak position if (peak_position) { *peak_position = (uint32_t) peak_pos; } - - // Try to detect SSS - if (q->sss_en) { - // Set an invalid N_id_1 indicating SSS is yet to be detected - q->N_id_1 = 1000; - - if (sync_sss(q, input_cfo, find_offset + peak_pos, q->cp) < 0) { - DEBUG("No space for SSS processing. Frame starts at %d\n", peak_pos); - } - } - - /* If peak is over threshold, compute CFO and SSS */ - if (q->peak_value >= q->threshold) { - if (q->detect_cp) { - if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) { - srslte_sync_set_cp(q, srslte_sync_detect_cp(q, input_cfo, peak_pos + find_offset)); + // In case of decimation, this compensates for the constant time shift caused by the low pass filter + if(q->decimate && peak_pos < 0) { + peak_pos = 0 ;//peak_pos + q->decimate*(2);// replace 2 with q->filter_size -2; + } + + /* If peak is over threshold, compute CFO and SSS */ + if (q->peak_value >= q->threshold || q->threshold == 0) { + + if (q->cfo_pss_enable && peak_pos >= q->fft_size) { + + // 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); + pss_ptr = q->pss_filt; + } + + // PSS-based CFO estimation + float cfo_pss = srslte_pss_synch_cfo_compute(&q->pss, pss_ptr); + if (!q->cfo_pss_is_set) { + q->cfo_pss_mean = cfo_pss; + q->cfo_pss_is_set = true; + } else { + q->cfo_pss_mean = SRSLTE_VEC_EMA(cfo_pss, q->cfo_pss_mean, q->cfo_ema_alpha); + } + + INFO("PSS-CFO: filter=%s, estimated=%f, mean=%f\n", + q->pss_filtering_enabled?"yes":"no", cfo_pss, q->cfo_pss_mean); + + } + + // If there is enough space for CP and PSS-based CFO estimation + if (peak_pos + find_offset >= 2 * (q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) { + + // If SSS search is enabled, correlate SSS sequence + if (q->sss_en) { + + // Set an invalid N_id_1 indicating SSS is yet to be detected + q->N_id_1 = 1000; + + int sss_idx = find_offset + peak_pos - 2 * q->fft_size - + SRSLTE_CP_LEN(q->fft_size, (SRSLTE_CP_ISNORM(q->cp) ? SRSLTE_CP_NORM_LEN : SRSLTE_CP_EXT_LEN)); + + const cf_t *sss_ptr = &input_ptr[sss_idx]; + + // 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); + sss_ptr = q->sss_filt; + } + + if (sync_sss_symbol(q, sss_ptr) < 0) { + fprintf(stderr, "Error correlating SSS\n"); + return -1; + } + } + + // Detect CP length + if (q->detect_cp) { + srslte_sync_set_cp(q, srslte_sync_detect_cp(q, input_ptr, peak_pos + find_offset)); } else { DEBUG("Not enough room to detect CP length. Peak position: %d\n", peak_pos); } - } - if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) { - float cfo2 = srslte_pss_synch_cfo_compute(&q->pss, &input[find_offset + peak_pos - q->fft_size]); - if (q->mean_cfo2_isunset) { - q->mean_cfo2 = cfo2; - q->mean_cfo2_isunset = true; - } else { - q->mean_cfo2 = SRSLTE_VEC_EMA(cfo2, q->mean_cfo2, q->cfo_ema_alpha); - } ret = SRSLTE_SYNC_FOUND; } else { - ret = SRSLTE_SYNC_FOUND_NOSPACE; + ret = SRSLTE_SYNC_FOUND_NOSPACE; } } else { ret = SRSLTE_SYNC_NOFOUND; @@ -607,7 +670,7 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t DEBUG("SYNC ret=%d N_id_2=%d find_offset=%d frame_len=%d, pos=%d peak=%.2f threshold=%.2f sf_idx=%d, CFO=%.3f kHz\n", ret, q->N_id_2, find_offset, q->frame_size, peak_pos, q->peak_value, - q->threshold, q->sf_idx, 15*(q->cfo_i+q->mean_cfo)); + q->threshold, q->sf_idx, 15*(srslte_sync_get_cfo(q))); } else if (srslte_N_id_2_isvalid(q->N_id_2)) { fprintf(stderr, "Must call srslte_sync_set_N_id_2() first!\n"); diff --git a/lib/src/phy/sync/test/pss_usrp.c b/lib/src/phy/sync/test/pss_usrp.c index 8e8377b83..7c22652f7 100644 --- a/lib/src/phy/sync/test/pss_usrp.c +++ b/lib/src/phy/sync/test/pss_usrp.c @@ -221,7 +221,9 @@ int main(int argc, char **argv) { uint32_t max_peak = 0; uint32_t max_peak_ = 0; uint32_t min_peak = fft_size; - uint32_t min_peak_ = fft_size; + uint32_t min_peak_ = fft_size; + + pss.filter_pss_enable = true; while(frame_cnt < nof_frames || nof_frames == -1) { n = srslte_rf_recv(&rf, buffer, flen - peak_offset, 1); @@ -243,7 +245,7 @@ int main(int argc, char **argv) { if (peak_idx >= fft_size) { - // Estimate CFO + // Estimate CFO cfo = srslte_pss_synch_cfo_compute(&pss, &buffer[peak_idx-fft_size]); mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt); @@ -255,10 +257,14 @@ int main(int argc, char **argv) { fprintf(stderr, "Error computing channel estimation\n"); exit(-1); } - - // Find SSS + + // 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) { + + // Filter SSS + srslte_pss_synch_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) { @@ -301,12 +307,12 @@ int main(int argc, char **argv) { } printf("[%5d]: Pos: %5d (%d-%d), PSR: %4.1f (~%4.1f) Pdet: %4.2f, " - "FA: %4.2f, CFO: %+4.1f kHz, SFO: %+.2f Hz SSSmiss: %4.2f/%4.2f/%4.2f CPNorm: %.0f%%\r", + "FA: %4.2f, CFO: %+7.1f Hz, SFO: %+.2f Hz SSSmiss: %4.2f/%4.2f/%4.2f CPNorm: %.0f%%\r", frame_cnt, peak_idx, min_peak_, max_peak_, peak_value, mean_peak, (float) nof_det/frame_cnt, - (float) nof_nopeakdet/frame_cnt, mean_cfo*15, sfo, + (float) nof_nopeakdet/frame_cnt, mean_cfo*15000, sfo, (float) sss_error1/nof_det,(float) sss_error2/nof_det,(float) sss_error3/nof_det, (float) cp_is_norm/nof_det * 100); diff --git a/lib/src/phy/sync/test/sync_test.c b/lib/src/phy/sync/test/sync_test.c index 1e3951884..9016c1baa 100644 --- a/lib/src/phy/sync/test/sync_test.c +++ b/lib/src/phy/sync/test/sync_test.c @@ -124,8 +124,7 @@ int main(int argc, char **argv) { /* Set a very high threshold to make sure the correlation is ok */ srslte_sync_set_threshold(&syncobj, 5.0); srslte_sync_set_sss_algorithm(&syncobj, SSS_PARTIAL_3); - srslte_sync_set_cfo_enable(&syncobj, false); - + if (cell_id == -1) { cid = 0; max_cid = 49; diff --git a/lib/src/phy/ue/ue_cell_search.c b/lib/src/phy/ue/ue_cell_search.c index dc35fb48c..133aad144 100644 --- a/lib/src/phy/ue/ue_cell_search.c +++ b/lib/src/phy/ue/ue_cell_search.c @@ -116,7 +116,7 @@ int srslte_ue_cellsearch_init_multi(srslte_ue_cellsearch_t * q, uint32_t max_fra goto clean_exit; } if (srslte_ue_sync_set_cell(&q->ue_sync, cell)) { - fprintf(stderr, "Error initiating ue_sync\n"); + fprintf(stderr, "Error setting cell in ue_sync\n"); goto clean_exit; } @@ -292,6 +292,8 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, srslte_ue_sync_set_N_id_2(&q->ue_sync, N_id_2); srslte_ue_sync_reset(&q->ue_sync); + srslte_ue_sync_cfo_reset(&q->ue_sync); + do { ret = srslte_ue_sync_zerocopy_multi(&q->ue_sync, q->sf_buffer); diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index 960d1de66..b6e0bd589 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -47,6 +47,9 @@ #define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 0 #define DEFAULT_SFO_EMA_COEFF 0.1 +#define DEFAULT_CFO_BW 0.2 +#define DEFAULT_CFO_PSS_TOL 100 // typical accuracy of PSS estimation + cf_t dummy_buffer0[15*2048/2]; cf_t dummy_buffer1[15*2048/2]; @@ -70,9 +73,10 @@ int srslte_ue_sync_init_file_multi(srslte_ue_sync_t *q, uint32_t nof_prb, char * q->file_mode = true; q->sf_len = SRSLTE_SF_LEN(srslte_symbol_sz(nof_prb)); q->file_cfo = -offset_freq; - q->correct_cfo = true; q->fft_size = srslte_symbol_sz(nof_prb); q->nof_rx_antennas = nof_rx_ant; + + q->cfo_correct_enable = true; if (srslte_cfo_init(&q->file_cfo_correct, 2*q->sf_len)) { fprintf(stderr, "Error initiating CFO\n"); @@ -96,6 +100,7 @@ int srslte_ue_sync_init_file_multi(srslte_ue_sync_t *q, uint32_t nof_prb, char * free(file_offset_buffer); } + srslte_ue_sync_cfo_reset(q); srslte_ue_sync_reset(q); ret = SRSLTE_SUCCESS; @@ -107,6 +112,31 @@ clean_exit: return ret; } +void srslte_ue_sync_cfo_reset(srslte_ue_sync_t *q) +{ + q->cfo_current_value = 0; + srslte_sync_cfo_reset(&q->strack); + srslte_sync_cfo_reset(&q->sfind); +} + +void srslte_ue_sync_reset(srslte_ue_sync_t *q) { + + if (!q->file_mode) { + srslte_sync_reset(&q->sfind); + srslte_sync_reset(&q->strack); + } else { + q->sf_idx = 9; + } + q->state = SF_FIND; + q->frame_ok_cnt = 0; + q->frame_no_cnt = 0; + q->frame_total_cnt = 0; + q->mean_sample_offset = 0.0; + q->next_rf_sample_offset = 0; + q->frame_find_cnt = 0; +} + + int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(void*, double), float init_gain_value) { uint32_t nframes; if (q->nof_recv_sf == 1) { @@ -179,13 +209,16 @@ int srslte_ue_sync_init_multi_decim(srslte_ue_sync_t *q, q->fft_size = srslte_symbol_sz(max_prb); q->sf_len = SRSLTE_SF_LEN(q->fft_size); q->file_mode = false; - q->correct_cfo = true; - q->agc_period = 0; + q->agc_period = 0; q->sample_offset_correct_period = DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD; q->sfo_ema = DEFAULT_SFO_EMA_COEFF; q->max_prb = max_prb; + q->cfo_pss_tol = DEFAULT_CFO_PSS_TOL; + q->cfo_loop_bw = DEFAULT_CFO_BW; + q->cfo_correct_enable = true; + if (search_cell) { /* If the cell is unkown, we search PSS/SSS in 5 ms */ @@ -220,6 +253,29 @@ 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_filt_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, true); + + // FIXME: CP detection not working very well. Not supporting Extended CP right now + 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; } @@ -255,8 +311,6 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t *q, srslte_cell_t cell) if (q != NULL && srslte_nofprb_isvalid(cell.nof_prb)) { - ret = SRSLTE_ERROR; - if (cell.nof_prb > q->max_prb) { fprintf(stderr, "Error in ue_sync_set_cell(): cell.nof_prb must be lower than initialized\n"); return SRSLTE_ERROR; @@ -271,15 +325,10 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t *q, srslte_cell_t cell) /* If the cell is unkown, we search PSS/SSS in 5 ms */ q->nof_recv_sf = 5; - - q->decode_sss_on_track = true; - } else { /* If the cell is known, we work on a 1ms basis */ q->nof_recv_sf = 1; - - q->decode_sss_on_track = true; } q->frame_len = q->nof_recv_sf*q->sf_len; @@ -289,59 +338,51 @@ int srslte_ue_sync_set_cell(srslte_ue_sync_t *q, srslte_cell_t cell) } if(srslte_sync_resize(&q->sfind, q->frame_len, q->frame_len, q->fft_size)) { - fprintf(stderr, "Error initiating sync find\n"); + fprintf(stderr, "Error setting cell sync find\n"); return SRSLTE_ERROR; } if (cell.id == 1000) { if(srslte_sync_resize(&q->strack, q->frame_len, TRACK_FRAME_SIZE, q->fft_size)) { - fprintf(stderr, "Error initiating sync track\n"); + fprintf(stderr, "Error setting cell sync track\n"); return SRSLTE_ERROR; } } else { if(srslte_sync_resize(&q->strack, q->frame_len, SRSLTE_CP_LEN_NORM(1,q->fft_size), q->fft_size)) { - fprintf(stderr, "Error initiating sync track\n"); + fprintf(stderr, "Error setting cell sync track\n"); return SRSLTE_ERROR; } } if (cell.id == 1000) { - /* If the cell id is unknown, enable CP detection on find */ - // FIXME: CP detection not working very well. Not supporting Extended CP right now - srslte_sync_cp_en(&q->sfind, false); - srslte_sync_cp_en(&q->strack, false); + q->nof_avg_find_frames = FIND_NOF_AVG_FRAMES; - srslte_sync_set_cfo_ema_alpha(&q->sfind, 0.8); + srslte_sync_set_cfo_ema_alpha(&q->sfind, 0.8); srslte_sync_set_cfo_ema_alpha(&q->strack, 0.1); - srslte_sync_cfo_i_detec_en(&q->sfind, false); + srslte_sync_set_em_alpha(&q->sfind, 1); - q->nof_avg_find_frames = FIND_NOF_AVG_FRAMES; - srslte_sync_set_threshold(&q->sfind, 2.0); + srslte_sync_set_threshold(&q->sfind, 2.0); srslte_sync_set_threshold(&q->strack, 1.2); } else { - srslte_sync_set_N_id_2(&q->sfind, cell.id%3); - srslte_sync_set_N_id_2(&q->strack, cell.id%3); - q->sfind.cp = cell.cp; + q->sfind.cp = cell.cp; q->strack.cp = cell.cp; - srslte_sync_cp_en(&q->sfind, false); - srslte_sync_cp_en(&q->strack, false); - srslte_sync_cfo_i_detec_en(&q->sfind, false); + srslte_sync_set_N_id_2(&q->sfind, cell.id%3); + srslte_sync_set_N_id_2(&q->strack, cell.id%3); - srslte_sync_set_cfo_ema_alpha(&q->sfind, 0.1); + srslte_sync_set_cfo_ema_alpha(&q->sfind, 0.1); srslte_sync_set_cfo_ema_alpha(&q->strack, 0.1); /* In find phase and if the cell is known, do not average pss correlation * because we only capture 1 subframe and do not know where the peak is. */ q->nof_avg_find_frames = 1; - srslte_sync_set_em_alpha(&q->sfind, 1); - srslte_sync_set_threshold(&q->sfind, 3.0); + 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.2); srslte_sync_set_threshold(&q->strack, 1.2); - } srslte_ue_sync_reset(q); @@ -357,34 +398,35 @@ void srslte_ue_sync_get_last_timestamp(srslte_ue_sync_t *q, srslte_timestamp_t * memcpy(timestamp, &q->last_timestamp, sizeof(srslte_timestamp_t)); } -uint32_t srslte_ue_sync_peak_idx(srslte_ue_sync_t *q) { - return q->peak_idx; +void srslte_ue_sync_set_cfo_loop_bw(srslte_ue_sync_t *q, float bw, float pss_tol) { + q->cfo_loop_bw = bw; + q->cfo_pss_tol = pss_tol; } void srslte_ue_sync_set_cfo_ema(srslte_ue_sync_t *q, float ema) { - srslte_sync_set_cfo_ema_alpha(&q->sfind, ema); + srslte_sync_set_cfo_ema_alpha(&q->sfind, ema); srslte_sync_set_cfo_ema_alpha(&q->strack, ema); } -srslte_ue_sync_state_t srslte_ue_sync_get_state(srslte_ue_sync_t *q) { - return q->state; -} uint32_t srslte_ue_sync_get_sfidx(srslte_ue_sync_t *q) { return q->sf_idx; } -void srslte_ue_sync_cfo_i_detec_en(srslte_ue_sync_t *q, bool enable) { - srslte_sync_cfo_i_detec_en(&q->strack, enable); - srslte_sync_cfo_i_detec_en(&q->sfind, enable); +void srslte_ue_sync_set_cfo_i_enable(srslte_ue_sync_t *q, bool enable) { + printf("Warning: Setting integer CFO detection/correction. This is experimental!\n"); + srslte_sync_set_cfo_i_enable(&q->strack, enable); + srslte_sync_set_cfo_i_enable(&q->sfind, enable); } float srslte_ue_sync_get_cfo(srslte_ue_sync_t *q) { - return 15000 * srslte_sync_get_cfo(&q->strack); + return 15000 * q->cfo_current_value; } -void srslte_ue_sync_set_cfo(srslte_ue_sync_t *q, float cfo) { - srslte_sync_set_cfo(&q->sfind, cfo/15000); - srslte_sync_set_cfo(&q->strack, cfo/15000); +void srslte_ue_sync_copy_cfo(srslte_ue_sync_t *q, srslte_ue_sync_t *src_obj) { + // Copy find object internal CFO averages + srslte_sync_copy_cfo(&q->sfind, &src_obj->sfind); + // Current CFO is tracking-phase CFO of previous object + q->cfo_current_value = srslte_ue_sync_get_cfo(src_obj); } void srslte_ue_sync_set_cfo_tol(srslte_ue_sync_t *q, float cfo_tol) {} @@ -406,7 +448,8 @@ void srslte_ue_sync_set_sfo_ema(srslte_ue_sync_t *q, float ema_coefficient) { } void srslte_ue_sync_decode_sss_on_track(srslte_ue_sync_t *q, bool enabled) { - q->decode_sss_on_track = enabled; + q->decode_sss_on_track = enabled; + srslte_sync_sss_en(&q->strack, q->decode_sss_on_track); } void srslte_ue_sync_set_N_id_2(srslte_ue_sync_t *q, uint32_t N_id_2) { @@ -434,7 +477,7 @@ static int find_peak_ok(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS q->frame_find_cnt++; DEBUG("Found peak %d at %d, value %.3f, Cell_id: %d CP: %s\n", q->frame_find_cnt, q->peak_idx, - srslte_sync_get_last_peak_value(&q->sfind), q->cell.id, srslte_cp_string(q->cell.cp)); + srslte_sync_get_peak_value(&q->sfind), q->cell.id, srslte_cp_string(q->cell.cp)); if (q->frame_find_cnt >= q->nof_avg_find_frames || q->peak_idx < 2*q->fft_size) { INFO("Realigning frame, reading %d samples\n", q->peak_idx+q->sf_len/2); @@ -453,9 +496,9 @@ static int find_peak_ok(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS /* Goto Tracking state */ q->state = SF_TRACK; - /* Initialize track state CFO */ - q->strack.mean_cfo = q->sfind.mean_cfo; - q->strack.cfo_i = q->sfind.cfo_i; + /* Set CFO values. Since we correct before track, the initial track state is CFO=0 Hz */ + q->cfo_current_value = srslte_sync_get_cfo(&q->sfind); + srslte_sync_cfo_reset(&q->strack); } return 0; @@ -491,6 +534,14 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { q->mean_sample_offset = q->last_sample_offset; } + /* Adjust current CFO estimation with PSS + * Since sync track has enabled only PSS-based correlation, get_cfo() returns that value only, already filtered. + */ + INFO("TRACK: cfo_current: %f, cfo_strack=%f\n", 15000*q->cfo_current_value, 15000*srslte_sync_get_cfo(&q->strack)); + if (abs(srslte_sync_get_cfo(&q->strack)*q->cfo_loop_bw) > q->cfo_pss_tol) { + q->cfo_current_value += srslte_sync_get_cfo(&q->strack)*q->cfo_loop_bw; + } + // Compute cumulative moving average time offset */ if (!frame_idx) { // Adjust RF sampling time based on the mean sampling offset @@ -543,13 +594,7 @@ static int track_peak_no(srslte_ue_sync_t *q) { return 0; } else { INFO("Tracking peak not found. Peak %.3f, %d lost\n", - srslte_sync_get_last_peak_value(&q->strack), (int) q->frame_no_cnt); - /* - printf("Saving files: pss_corr (%d), input (%d)\n", q->strack.pss.frame_size, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); - srslte_vec_save_file("pss_corr", q->strack.pss.conv_output_avg, q->strack.pss.frame_size*sizeof(float)); - srslte_vec_save_file("input", q->input_buffer, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)*sizeof(cf_t)); - exit(-1); - */ + srslte_sync_get_peak_value(&q->strack), (int) q->frame_no_cnt); return 1; } @@ -578,12 +623,10 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PO return SRSLTE_SUCCESS; } -bool first_track = true; - int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { - cf_t *_input_buffer[SRSLTE_MAX_PORTS]; - _input_buffer[0] = input_buffer; - return srslte_ue_sync_zerocopy_multi(q, _input_buffer); + cf_t *_input_buffer[SRSLTE_MAX_PORTS]; + _input_buffer[0] = input_buffer; + return srslte_ue_sync_zerocopy_multi(q, _input_buffer); } /* Returns 1 if the subframe is synchronized in time, 0 otherwise */ @@ -610,7 +653,7 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE return SRSLTE_ERROR; } } - if (q->correct_cfo) { + if (q->cfo_correct_enable) { for (int i = 0; i < q->nof_rx_antennas; i++) { srslte_cfo_correct(&q->file_cfo_correct, input_buffer[i], @@ -625,13 +668,14 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE INFO("Reading %d samples. sf_idx = %d\n", q->sf_len, q->sf_idx); ret = 1; } else { + if (receive_samples(q, input_buffer)) { fprintf(stderr, "Error receiving samples\n"); return SRSLTE_ERROR; } switch (q->state) { - case SF_FIND: + case SF_FIND: switch(srslte_sync_find(&q->sfind, input_buffer[0], 0, &q->peak_idx)) { case SRSLTE_SYNC_ERROR: ret = SRSLTE_ERROR; @@ -659,37 +703,39 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE case SF_TRACK: ret = 1; - - srslte_sync_sss_en(&q->strack, q->decode_sss_on_track); - + + // Increase subframe counter q->sf_idx = (q->sf_idx + q->nof_recv_sf) % 10; - /* Every SF idx 0 and 5, find peak around known position q->peak_idx */ - if (q->sf_idx == 0 || q->sf_idx == 5) { + // Correct CFO before PSS/SSS tracking using the sync object corrector (initialized for 1 ms) + if (q->cfo_correct_enable) { + 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); + } + } + /* Every SF idx 0 and 5, find peak around known position q->peak_idx */ + if (q->sf_idx == 0 || q->sf_idx == 5) + { + // Process AGC every period if (q->do_agc && (q->agc_period == 0 || (q->agc_period && (q->frame_total_cnt%q->agc_period) == 0))) { srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); } - #ifdef MEASURE_EXEC_TIME - struct timeval t[3]; - gettimeofday(&t[1], NULL); - #endif - - track_idx = 0; - - /* Track PSS/SSS around the expected PSS position + /* 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; switch(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)) { case SRSLTE_SYNC_ERROR: - ret = SRSLTE_ERROR; fprintf(stderr, "Error tracking correlation peak\n"); return SRSLTE_ERROR; case SRSLTE_SYNC_FOUND: @@ -699,19 +745,13 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE // It's very very unlikely that we fall here because this event should happen at FIND phase only ret = 0; q->state = SF_FIND; - printf("Warning: No space for SSS/CP while in tracking phase\n"); + INFO("Warning: No space for SSS/CP while in tracking phase\n"); break; case SRSLTE_SYNC_NOFOUND: ret = track_peak_no(q); break; } - #ifdef MEASURE_EXEC_TIME - gettimeofday(&t[2], NULL); - get_time_interval(t); - q->mean_exec_time = (float) SRSLTE_VEC_CMA((float) t[0].tv_usec, q->mean_exec_time, q->frame_total_cnt); - #endif - if (ret == SRSLTE_ERROR) { fprintf(stderr, "Error processing tracking peak\n"); q->state = SF_FIND; @@ -719,40 +759,12 @@ int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE } q->frame_total_cnt++; - } - if (q->correct_cfo) { - for (int i=0;inof_rx_antennas;i++) { - srslte_cfo_correct(&q->strack.cfocorr, - input_buffer[i], - input_buffer[i], - -srslte_sync_get_cfo(&q->strack) / q->fft_size); - } - } + } break; } - } } return ret; } -void srslte_ue_sync_reset(srslte_ue_sync_t *q) { - - if (!q->file_mode) { - srslte_sync_reset(&q->sfind); - srslte_sync_reset(&q->strack); - } else { - q->sf_idx = 9; - } - q->state = SF_FIND; - q->frame_ok_cnt = 0; - q->frame_no_cnt = 0; - q->frame_total_cnt = 0; - q->mean_sample_offset = 0.0; - q->next_rf_sample_offset = 0; - q->frame_find_cnt = 0; - #ifdef MEASURE_EXEC_TIME - q->mean_exec_time = 0; - #endif -} diff --git a/lib/src/phy/utils/convolution.c b/lib/src/phy/utils/convolution.c index f96bdd4a2..59807ad5b 100644 --- a/lib/src/phy/utils/convolution.c +++ b/lib/src/phy/utils/convolution.c @@ -115,7 +115,7 @@ void srslte_conv_fft_cc_free(srslte_conv_fft_cc_t *q) { } -uint32_t srslte_conv_fft_cc_run_opt(srslte_conv_fft_cc_t *q, cf_t *input, cf_t *filter_freq, cf_t *output) +uint32_t srslte_conv_fft_cc_run_opt(srslte_conv_fft_cc_t *q, const cf_t *input, const cf_t *filter_freq, cf_t *output) { srslte_dft_run_c(&q->input_plan, input, q->input_fft); srslte_vec_prod_ccc(q->input_fft, filter_freq, q->output_fft, q->output_len); @@ -125,7 +125,7 @@ uint32_t srslte_conv_fft_cc_run_opt(srslte_conv_fft_cc_t *q, cf_t *input, cf_t * } -uint32_t srslte_conv_fft_cc_run(srslte_conv_fft_cc_t *q, cf_t *input, cf_t *filter, cf_t *output) { +uint32_t srslte_conv_fft_cc_run(srslte_conv_fft_cc_t *q, const cf_t *input, const cf_t *filter, cf_t *output) { srslte_dft_run_c(&q->filter_plan, filter, q->filter_fft); @@ -133,7 +133,7 @@ uint32_t srslte_conv_fft_cc_run(srslte_conv_fft_cc_t *q, cf_t *input, cf_t *filt } -uint32_t srslte_conv_cc(cf_t *input, cf_t *filter, cf_t *output, uint32_t input_len, uint32_t filter_len) { +uint32_t srslte_conv_cc(const cf_t *input, const cf_t *filter, cf_t *output, uint32_t input_len, uint32_t filter_len) { uint32_t i; uint32_t M = filter_len; uint32_t N = input_len; diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index a717a7537..cb7eff480 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -441,7 +441,7 @@ TEST(srslte_vec_convert_fi, x[i] = (float) RANDOM_F(); } - TEST_CALL(srslte_vec_convert_fi(x, z, scale, block_size)) + TEST_CALL(srslte_vec_convert_fi(x, scale, z, block_size)) for (int i = 0; i < block_size; i++) { gold = (short) ((x[i] * scale)); diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index 5d5b6747a..35457fcb5 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -37,79 +37,73 @@ -void srslte_vec_xor_bbb(int8_t *x,int8_t *y,int8_t *z, uint32_t len) { +void srslte_vec_xor_bbb(int8_t *x,int8_t *y,int8_t *z, const uint32_t len) { srslte_vec_xor_bbb_simd(x, y, z, len); } // Used in PRACH detector, AGC and chest_dl for noise averaging -float srslte_vec_acc_ff(float *x, uint32_t len) { +float srslte_vec_acc_ff(const float *x, const uint32_t len) { return srslte_vec_acc_ff_simd(x, len); } -void srslte_vec_ema_filter(cf_t *new_data, cf_t *average, cf_t *output, float coeff, uint32_t len) { - srslte_vec_sc_prod_cfc(new_data, coeff, new_data, len); - srslte_vec_sc_prod_cfc(average, 1-coeff, output, len); - srslte_vec_sum_ccc(output, new_data, output, len); -} - -cf_t srslte_vec_acc_cc(cf_t *x, uint32_t len) { +cf_t srslte_vec_acc_cc(const cf_t *x, const uint32_t len) { return srslte_vec_acc_cc_simd(x, len); } -void srslte_vec_sub_fff(float *x, float *y, float *z, uint32_t len) { +void srslte_vec_sub_fff(const float *x, const float *y, float *z, const uint32_t len) { srslte_vec_sub_fff_simd(x, y, z, len); } -void srslte_vec_sub_sss(int16_t *x, int16_t *y, int16_t *z, uint32_t len) { +void srslte_vec_sub_sss(const int16_t *x, const int16_t *y, int16_t *z, const uint32_t len) { srslte_vec_sub_sss_simd(x, y, z, len); } // Noise estimation in chest_dl, interpolation -void srslte_vec_sub_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len) { - return srslte_vec_sub_fff((float*) x,(float*) y,(float*) z, 2*len); +void srslte_vec_sub_ccc(const cf_t *x, const cf_t *y, cf_t *z, const uint32_t len) { + return srslte_vec_sub_fff((const float*) x,(const float*) y,(float*) z, 2*len); } // Used in PSS/SSS and sum_ccc -void srslte_vec_sum_fff(float *x, float *y, float *z, uint32_t len) { +void srslte_vec_sum_fff(const float *x, const float *y, float *z, const uint32_t len) { srslte_vec_add_fff_simd(x, y, z, len); } -void srslte_vec_sum_sss(int16_t *x, int16_t *y, int16_t *z, uint32_t len) { +void srslte_vec_sum_sss(const int16_t *x, const int16_t *y, int16_t *z, const uint32_t len) { srslte_vec_sum_sss_simd(x, y, z, len); } -void srslte_vec_sum_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len) { +void srslte_vec_sum_ccc(const cf_t *x, const cf_t *y, cf_t *z, const uint32_t len) { srslte_vec_sum_fff((float*) x,(float*) y,(float*) z,2*len); } // PSS, PBCH, DEMOD, FFTW, etc. -void srslte_vec_sc_prod_fff(float *x, float h, float *z, uint32_t len) { +void srslte_vec_sc_prod_fff(const float *x, const float h, float *z, const uint32_t len) { srslte_vec_sc_prod_fff_simd(x, h, z, len); } // Used throughout -void srslte_vec_sc_prod_cfc(cf_t *x, float h, cf_t *z, uint32_t len) { +void srslte_vec_sc_prod_cfc(const const cf_t *x, const float h, cf_t *z, const uint32_t len) { srslte_vec_sc_prod_cfc_simd(x,h,z,len); } // Chest UL -void srslte_vec_sc_prod_ccc(cf_t *x, cf_t h, cf_t *z, uint32_t len) { +void srslte_vec_sc_prod_ccc(const cf_t *x, const cf_t h, cf_t *z, const uint32_t len) { srslte_vec_sc_prod_ccc_simd(x,h,z,len); } // Used in turbo decoder -void srslte_vec_convert_if(int16_t *x, float *z, float scale, uint32_t len) { +void srslte_vec_convert_if(const int16_t *x, const float scale, float *z, const uint32_t len) { int i; for (i=0;iargs->cfo_integer_enabled) { - srslte_ue_sync_cfo_i_detec_en(q, true); + srslte_ue_sync_set_cfo_i_enable(q, true); } srslte_ue_sync_set_cfo_ema(q, worker_com->args->cfo_ema); @@ -328,7 +328,7 @@ int phch_recv::cell_search(int force_N_id_2) { } srslte_ue_sync_reset(&ue_mib_sync.ue_sync); - srslte_ue_sync_set_cfo(&ue_mib_sync.ue_sync, cellsearch_cfo); + srslte_ue_sync_copy_cfo(&ue_mib_sync.ue_sync, &cs.ue_sync); /* Find and decode MIB */ int sfn_offset; @@ -340,7 +340,7 @@ int phch_recv::cell_search(int force_N_id_2) { cellsearch_cfo = srslte_ue_sync_get_cfo(&ue_mib_sync.ue_sync); srslte_ue_sync_reset(&ue_sync); - srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo); + srslte_ue_sync_copy_cfo(&ue_sync, &ue_mib_sync.ue_sync); if (ret == 1) { srslte_pbch_mib_unpack(bch_payload, &cell, NULL);