Fixed SIC for PSS using channel estimates, added option to disable it (not usable on synchronous same-site cells). Use PSS CE in SSS decoding

master
Ismael Gomez 7 years ago
parent 3607ac6154
commit 48dfc08fa3

@ -998,7 +998,7 @@ void *plot_thread_run(void *arg) {
if (!prog_args.input_file_name) { if (!prog_args.input_file_name) {
if (plot_track) { if (plot_track) {
srslte_pss_synch_t *pss_obj = srslte_sync_get_cur_pss_obj(&ue_sync.strack); srslte_pss_t *pss_obj = srslte_sync_get_cur_pss_obj(&ue_sync.strack);
int max = srslte_vec_max_fi(pss_obj->conv_output_avg, pss_obj->frame_size+pss_obj->fft_size-1); int max = srslte_vec_max_fi(pss_obj->conv_output_avg, pss_obj->frame_size+pss_obj->fft_size-1);
srslte_vec_sc_prod_fff(pss_obj->conv_output_avg, srslte_vec_sc_prod_fff(pss_obj->conv_output_avg,
1/pss_obj->conv_output_avg[max], 1/pss_obj->conv_output_avg[max],

@ -102,8 +102,8 @@ void parse_args(int argc, char **argv) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
srslte_filesource_t fsrc; srslte_filesource_t fsrc;
srslte_filesink_t fsink; srslte_filesink_t fsink;
srslte_pss_synch_t pss[3]; // One for each N_id_2 srslte_pss_t pss[3]; // One for each N_id_2
srslte_sss_synch_t sss[3]; // One for each N_id_2 srslte_sss_t sss[3]; // One for each N_id_2
srslte_cfo_t cfocorr; srslte_cfo_t cfocorr;
int peak_pos[3]; int peak_pos[3];
float *cfo; float *cfo;
@ -163,19 +163,19 @@ int main(int argc, char **argv) {
* a) requries more memory but has less latency and is paralellizable. * a) requries more memory but has less latency and is paralellizable.
*/ */
for (N_id_2=0;N_id_2<3;N_id_2++) { for (N_id_2=0;N_id_2<3;N_id_2++) {
if (srslte_pss_synch_init(&pss[N_id_2], frame_length)) { if (srslte_pss_init(&pss[N_id_2], frame_length)) {
fprintf(stderr, "Error initializing PSS object\n"); fprintf(stderr, "Error initializing PSS object\n");
exit(-1); exit(-1);
} }
if (srslte_pss_synch_set_N_id_2(&pss[N_id_2], N_id_2)) { if (srslte_pss_set_N_id_2(&pss[N_id_2], N_id_2)) {
fprintf(stderr, "Error initializing N_id_2\n"); fprintf(stderr, "Error initializing N_id_2\n");
exit(-1); exit(-1);
} }
if (srslte_sss_synch_init(&sss[N_id_2], 128)) { if (srslte_sss_init(&sss[N_id_2], 128)) {
fprintf(stderr, "Error initializing SSS object\n"); fprintf(stderr, "Error initializing SSS object\n");
exit(-1); exit(-1);
} }
if (srslte_sss_synch_set_N_id_2(&sss[N_id_2], N_id_2)) { if (srslte_sss_set_N_id_2(&sss[N_id_2], N_id_2)) {
fprintf(stderr, "Error initializing N_id_2\n"); fprintf(stderr, "Error initializing N_id_2\n");
exit(-1); exit(-1);
} }
@ -199,10 +199,10 @@ int main(int argc, char **argv) {
if (force_N_id_2 != -1) { if (force_N_id_2 != -1) {
N_id_2 = force_N_id_2; N_id_2 = force_N_id_2;
peak_pos[N_id_2] = srslte_pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]); peak_pos[N_id_2] = srslte_pss_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]);
} else { } else {
for (N_id_2=0;N_id_2<3;N_id_2++) { for (N_id_2=0;N_id_2<3;N_id_2++) {
peak_pos[N_id_2] = srslte_pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]); peak_pos[N_id_2] = srslte_pss_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]);
} }
float max_value=-99999; float max_value=-99999;
N_id_2=-1; N_id_2=-1;
@ -220,13 +220,13 @@ int main(int argc, char **argv) {
sss_idx = peak_pos[N_id_2]-2*(symbol_sz+SRSLTE_CP_LEN(symbol_sz,SRSLTE_CP_NORM_LEN)); sss_idx = peak_pos[N_id_2]-2*(symbol_sz+SRSLTE_CP_LEN(symbol_sz,SRSLTE_CP_NORM_LEN));
if (sss_idx >= 0) { if (sss_idx >= 0) {
srslte_sss_synch_m0m1_diff(&sss[N_id_2], &input[sss_idx], srslte_sss_m0m1_diff(&sss[N_id_2], &input[sss_idx],
&m0, &m0_value, &m1, &m1_value); &m0, &m0_value, &m1, &m1_value);
cfo[frame_cnt] = srslte_pss_synch_cfo_compute(&pss[N_id_2], &input[peak_pos[N_id_2]-128]); cfo[frame_cnt] = srslte_pss_cfo_compute(&pss[N_id_2], &input[peak_pos[N_id_2]-128]);
printf("\t%d\t%d\t%d\t%d\t%.3f\t\t%3d\t%d\t%d\t%.3f\n", printf("\t%d\t%d\t%d\t%d\t%.3f\t\t%3d\t%d\t%d\t%.3f\n",
frame_cnt,N_id_2, srslte_sss_synch_N_id_1(&sss[N_id_2], m0, m1), frame_cnt,N_id_2, srslte_sss_N_id_1(&sss[N_id_2], m0, m1),
srslte_sss_synch_subframe(m0, m1), peak_value[N_id_2], srslte_sss_subframe(m0, m1), peak_value[N_id_2],
peak_pos[N_id_2], m0, m1, peak_pos[N_id_2], m0, m1,
cfo[frame_cnt]); cfo[frame_cnt]);
} }
@ -254,8 +254,8 @@ int main(int argc, char **argv) {
printf("Average CFO: %.3f\n", cfo_mean); printf("Average CFO: %.3f\n", cfo_mean);
for (N_id_2=0;N_id_2<3;N_id_2++) { for (N_id_2=0;N_id_2<3;N_id_2++) {
srslte_pss_synch_free(&pss[N_id_2]); srslte_pss_free(&pss[N_id_2]);
srslte_sss_synch_free(&sss[N_id_2]); srslte_sss_free(&sss[N_id_2]);
} }
srslte_filesource_free(&fsrc); srslte_filesource_free(&fsrc);

@ -488,6 +488,7 @@ typedef struct {
std::string sss_algorithm; std::string sss_algorithm;
float estimator_fil_w; float estimator_fil_w;
bool rssi_sensor_enabled; bool rssi_sensor_enabled;
bool sic_pss_enabled;
} phy_args_t; } phy_args_t;

@ -29,9 +29,9 @@
* *
* Description: Primary synchronization signal (PSS) generation and detection. * Description: Primary synchronization signal (PSS) generation and detection.
* *
* The srslte_pss_synch_t object provides functions for fast * The srslte_pss_t object provides functions for fast
* computation of the crosscorrelation between the PSS and received * computation of the crosscorrelation between the PSS and received
* signal and CFO estimation. Also, the function srslte_pss_synch_tperiodic() * signal and CFO estimation. Also, the function srslte_pss_tperiodic()
* is designed to be called periodically every subframe, taking * is designed to be called periodically every subframe, taking
* care of the correct data alignment with respect to the PSS sequence. * care of the correct data alignment with respect to the PSS sequence.
* *
@ -61,7 +61,7 @@
/* PSS processing options */ /* PSS processing options */
#define SRSLTE_PSS_ACCUMULATE_ABS // If enabled, accumulates the correlation absolute value on consecutive calls to srslte_pss_synch_find_pss #define SRSLTE_PSS_ACCUMULATE_ABS // If enabled, accumulates the correlation absolute value on consecutive calls to srslte_pss_find_pss
#define SRSLTE_PSS_RETURN_PSR // If enabled returns peak to side-lobe ratio, otherwise returns absolute peak value #define SRSLTE_PSS_RETURN_PSR // If enabled returns peak to side-lobe ratio, otherwise returns absolute peak value
@ -85,6 +85,7 @@ typedef struct SRSLTE_API {
cf_t *pss_signal_freq_full[3]; cf_t *pss_signal_freq_full[3];
cf_t *pss_signal_time[3]; cf_t *pss_signal_time[3];
cf_t *pss_signal_time_scale[3];
cf_t pss_signal_freq[3][SRSLTE_PSS_LEN]; // One sequence for each N_id_2 cf_t pss_signal_freq[3][SRSLTE_PSS_LEN]; // One sequence for each N_id_2
cf_t *tmp_input; cf_t *tmp_input;
@ -100,41 +101,48 @@ typedef struct SRSLTE_API {
cf_t tmp_fft[SRSLTE_SYMBOL_SZ_MAX]; cf_t tmp_fft[SRSLTE_SYMBOL_SZ_MAX];
cf_t tmp_fft2[SRSLTE_SYMBOL_SZ_MAX]; cf_t tmp_fft2[SRSLTE_SYMBOL_SZ_MAX];
}srslte_pss_synch_t; cf_t tmp_ce[SRSLTE_PSS_LEN];
bool chest_on_filter;
}srslte_pss_t;
typedef enum { PSS_TX, PSS_RX } pss_direction_t; typedef enum { PSS_TX, PSS_RX } pss_direction_t;
/* Basic functionality */ /* Basic functionality */
SRSLTE_API int srslte_pss_synch_init_fft(srslte_pss_synch_t *q, SRSLTE_API int srslte_pss_init_fft(srslte_pss_t *q,
uint32_t frame_size, uint32_t frame_size,
uint32_t fft_size); uint32_t fft_size);
SRSLTE_API int srslte_pss_synch_init_fft_offset(srslte_pss_synch_t *q, SRSLTE_API int srslte_pss_init_fft_offset(srslte_pss_t *q,
uint32_t frame_size, uint32_t frame_size,
uint32_t fft_size, uint32_t fft_size,
int cfo_i); int cfo_i);
SRSLTE_API int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q, SRSLTE_API int srslte_pss_init_fft_offset_decim(srslte_pss_t *q,
uint32_t frame_size, uint32_t frame_size,
uint32_t fft_size, uint32_t fft_size,
int cfo_i, int cfo_i,
int decimate); int decimate);
SRSLTE_API int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, SRSLTE_API int srslte_pss_resize(srslte_pss_t *q, uint32_t frame_size,
uint32_t fft_size, uint32_t fft_size,
int offset); int offset);
SRSLTE_API int srslte_pss_synch_init(srslte_pss_synch_t *q, SRSLTE_API int srslte_pss_init(srslte_pss_t *q,
uint32_t frame_size); uint32_t frame_size);
SRSLTE_API void srslte_pss_synch_free(srslte_pss_synch_t *q); SRSLTE_API void srslte_pss_free(srslte_pss_t *q);
SRSLTE_API void srslte_pss_synch_reset(srslte_pss_synch_t *q); SRSLTE_API void srslte_pss_reset(srslte_pss_t *q);
SRSLTE_API void srslte_pss_synch_filter_enable(srslte_pss_synch_t *q, SRSLTE_API void srslte_pss_filter_enable(srslte_pss_t *q,
bool enable); bool enable);
SRSLTE_API void srslte_pss_synch_filter(srslte_pss_synch_t *q, SRSLTE_API void srslte_pss_sic(srslte_pss_t *q,
cf_t *input);
SRSLTE_API void srslte_pss_filter(srslte_pss_t *q,
const cf_t *input, const cf_t *input,
cf_t *output); cf_t *output);
@ -151,21 +159,21 @@ SRSLTE_API void srslte_pss_put_slot(cf_t *pss_signal,
uint32_t nof_prb, uint32_t nof_prb,
srslte_cp_t cp); srslte_cp_t cp);
SRSLTE_API void srslte_pss_synch_set_ema_alpha(srslte_pss_synch_t *q, SRSLTE_API void srslte_pss_set_ema_alpha(srslte_pss_t *q,
float alpha); float alpha);
SRSLTE_API int srslte_pss_synch_set_N_id_2(srslte_pss_synch_t *q, SRSLTE_API int srslte_pss_set_N_id_2(srslte_pss_t *q,
uint32_t N_id_2); uint32_t N_id_2);
SRSLTE_API int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, SRSLTE_API int srslte_pss_find_pss(srslte_pss_t *q,
const cf_t *input, const cf_t *input,
float *corr_peak_value); float *corr_peak_value);
SRSLTE_API int srslte_pss_synch_chest(srslte_pss_synch_t *q, SRSLTE_API int srslte_pss_chest(srslte_pss_t *q,
const cf_t *input, const cf_t *input,
cf_t ce[SRSLTE_PSS_LEN]); cf_t ce[SRSLTE_PSS_LEN]);
SRSLTE_API float srslte_pss_synch_cfo_compute(srslte_pss_synch_t* q, SRSLTE_API float srslte_pss_cfo_compute(srslte_pss_t* q,
const cf_t *pss_recv); const cf_t *pss_recv);
#endif // PSS_ #endif // PSS_

@ -83,17 +83,17 @@ typedef struct SRSLTE_API {
float corr_output_m0[SRSLTE_SSS_N]; float corr_output_m0[SRSLTE_SSS_N];
float corr_output_m1[SRSLTE_SSS_N]; float corr_output_m1[SRSLTE_SSS_N];
}srslte_sss_synch_t; }srslte_sss_t;
/* Basic functionality */ /* Basic functionality */
SRSLTE_API int srslte_sss_synch_init(srslte_sss_synch_t *q, SRSLTE_API int srslte_sss_init(srslte_sss_t *q,
uint32_t fft_size); uint32_t fft_size);
SRSLTE_API int srslte_sss_synch_resize(srslte_sss_synch_t *q, SRSLTE_API int srslte_sss_resize(srslte_sss_t *q,
uint32_t fft_size); uint32_t fft_size);
SRSLTE_API void srslte_sss_synch_free(srslte_sss_synch_t *q); SRSLTE_API void srslte_sss_free(srslte_sss_t *q);
SRSLTE_API void srslte_sss_generate(float *signal0, SRSLTE_API void srslte_sss_generate(float *signal0,
float *signal5, float *signal5,
@ -104,10 +104,10 @@ SRSLTE_API void srslte_sss_put_slot(float *sss,
uint32_t nof_prb, uint32_t nof_prb,
srslte_cp_t cp); srslte_cp_t cp);
SRSLTE_API int srslte_sss_synch_set_N_id_2(srslte_sss_synch_t *q, SRSLTE_API int srslte_sss_set_N_id_2(srslte_sss_t *q,
uint32_t N_id_2); uint32_t N_id_2);
SRSLTE_API int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q, SRSLTE_API int srslte_sss_m0m1_partial(srslte_sss_t *q,
const cf_t *input, const cf_t *input,
uint32_t M, uint32_t M,
cf_t ce[2*SRSLTE_SSS_N], cf_t ce[2*SRSLTE_SSS_N],
@ -116,7 +116,7 @@ SRSLTE_API int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q,
uint32_t *m1, uint32_t *m1,
float *m1_value); float *m1_value);
SRSLTE_API int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, SRSLTE_API int srslte_sss_m0m1_diff_coh(srslte_sss_t *q,
const cf_t *input, const cf_t *input,
cf_t ce[2*SRSLTE_SSS_N], cf_t ce[2*SRSLTE_SSS_N],
uint32_t *m0, uint32_t *m0,
@ -124,7 +124,7 @@ SRSLTE_API int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q,
uint32_t *m1, uint32_t *m1,
float *m1_value); float *m1_value);
SRSLTE_API int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, SRSLTE_API int srslte_sss_m0m1_diff(srslte_sss_t *q,
const cf_t *input, const cf_t *input,
uint32_t *m0, uint32_t *m0,
float *m0_value, float *m0_value,
@ -132,25 +132,25 @@ SRSLTE_API int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q,
float *m1_value); float *m1_value);
SRSLTE_API uint32_t srslte_sss_synch_subframe(uint32_t m0, SRSLTE_API uint32_t srslte_sss_subframe(uint32_t m0,
uint32_t m1); uint32_t m1);
SRSLTE_API int srslte_sss_synch_N_id_1(srslte_sss_synch_t *q, SRSLTE_API int srslte_sss_N_id_1(srslte_sss_t *q,
uint32_t m0, uint32_t m0,
uint32_t m1); uint32_t m1);
SRSLTE_API int srslte_sss_synch_frame(srslte_sss_synch_t *q, SRSLTE_API int srslte_sss_frame(srslte_sss_t *q,
cf_t *input, cf_t *input,
uint32_t *subframe_idx, uint32_t *subframe_idx,
uint32_t *N_id_1); uint32_t *N_id_1);
SRSLTE_API void srslte_sss_synch_set_threshold(srslte_sss_synch_t *q, SRSLTE_API void srslte_sss_set_threshold(srslte_sss_t *q,
float threshold); float threshold);
SRSLTE_API void srslte_sss_synch_set_symbol_sz(srslte_sss_synch_t *q, SRSLTE_API void srslte_sss_set_symbol_sz(srslte_sss_t *q,
uint32_t symbol_sz); uint32_t symbol_sz);
SRSLTE_API void srslte_sss_synch_set_subframe_sz(srslte_sss_synch_t *q, SRSLTE_API void srslte_sss_set_subframe_sz(srslte_sss_t *q,
uint32_t subframe_sz); uint32_t subframe_sz);
#endif // SSS_ #endif // SSS_

@ -60,9 +60,9 @@
typedef enum {SSS_DIFF=0, SSS_PARTIAL_3=2, SSS_FULL=1} sss_alg_t; typedef enum {SSS_DIFF=0, SSS_PARTIAL_3=2, SSS_FULL=1} sss_alg_t;
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
srslte_pss_synch_t pss; srslte_pss_t pss;
srslte_pss_synch_t pss_i[2]; srslte_pss_t pss_i[2];
srslte_sss_synch_t sss; srslte_sss_t sss;
srslte_cp_synch_t cp_synch; srslte_cp_synch_t cp_synch;
cf_t *cfo_i_corr[2]; cf_t *cfo_i_corr[2];
int decimate; int decimate;
@ -110,7 +110,7 @@ typedef struct SRSLTE_API {
srslte_cfo_t cfo_corr_frame; srslte_cfo_t cfo_corr_frame;
srslte_cfo_t cfo_corr_symbol; srslte_cfo_t cfo_corr_symbol;
bool sss_filtering_enabled; bool sss_channel_equalize;
bool pss_filtering_enabled; bool pss_filtering_enabled;
cf_t sss_filt[SRSLTE_SYMBOL_SZ_MAX]; cf_t sss_filt[SRSLTE_SYMBOL_SZ_MAX];
cf_t pss_filt[SRSLTE_SYMBOL_SZ_MAX]; cf_t pss_filt[SRSLTE_SYMBOL_SZ_MAX];
@ -186,7 +186,7 @@ SRSLTE_API int srslte_sync_get_cell_id(srslte_sync_t *q);
SRSLTE_API void srslte_sync_set_pss_filt_enable(srslte_sync_t *q, SRSLTE_API void srslte_sync_set_pss_filt_enable(srslte_sync_t *q,
bool enable); bool enable);
SRSLTE_API void srslte_sync_set_sss_filt_enable(srslte_sync_t *q, SRSLTE_API void srslte_sync_set_sss_eq_enable(srslte_sync_t *q,
bool enable); bool enable);
/* Gets the CFO estimation from the last call to synch_run() */ /* Gets the CFO estimation from the last call to synch_run() */
@ -227,7 +227,7 @@ SRSLTE_API void srslte_sync_set_cp(srslte_sync_t *q,
SRSLTE_API void srslte_sync_sss_en(srslte_sync_t *q, SRSLTE_API void srslte_sync_sss_en(srslte_sync_t *q,
bool enabled); bool enabled);
SRSLTE_API srslte_pss_synch_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q); SRSLTE_API srslte_pss_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q);
SRSLTE_API bool srslte_sync_sss_detected(srslte_sync_t *q); SRSLTE_API bool srslte_sync_sss_detected(srslte_sync_t *q);

@ -68,7 +68,7 @@ static void corr_all_sz_partial(cf_t z[SRSLTE_SSS_N], float s[SRSLTE_SSS_N][SRSL
} }
} }
static void extract_pair_sss(srslte_sss_synch_t *q, const cf_t *input, cf_t *ce, cf_t y[2][SRSLTE_SSS_N]) { static void extract_pair_sss(srslte_sss_t *q, const cf_t *input, cf_t *ce, cf_t y[2][SRSLTE_SSS_N]) {
cf_t input_fft[SRSLTE_SYMBOL_SZ_MAX]; cf_t input_fft[SRSLTE_SYMBOL_SZ_MAX];
srslte_dft_run_c(&q->dftp_input, input, input_fft); srslte_dft_run_c(&q->dftp_input, input, input_fft);
@ -88,10 +88,10 @@ static void extract_pair_sss(srslte_sss_synch_t *q, const cf_t *input, cf_t *ce,
} }
int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, const cf_t *input, uint32_t *m0, float *m0_value, int srslte_sss_m0m1_diff(srslte_sss_t *q, const cf_t *input, uint32_t *m0, float *m0_value,
uint32_t *m1, float *m1_value) uint32_t *m1, float *m1_value)
{ {
return srslte_sss_synch_m0m1_diff_coh(q, input, NULL, m0, m0_value, m1, m1_value); return srslte_sss_m0m1_diff_coh(q, input, NULL, m0, m0_value, m1, m1_value);
} }
/* Differential SSS estimation. /* Differential SSS estimation.
@ -102,7 +102,7 @@ int srslte_sss_synch_m0m1_diff(srslte_sss_synch_t *q, const cf_t *input, uint32_
* *
*/ */
int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, const cf_t *input, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, int srslte_sss_m0m1_diff_coh(srslte_sss_t *q, const cf_t *input, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value,
uint32_t *m1, float *m1_value) uint32_t *m1, float *m1_value)
{ {
@ -145,7 +145,7 @@ int srslte_sss_synch_m0m1_diff_coh(srslte_sss_synch_t *q, const cf_t *input, cf_
* Jung-In Kim, Jung-Su Han, Hee-Jin Roh and Hyung-Jin Choi * Jung-In Kim, Jung-Su Han, Hee-Jin Roh and Hyung-Jin Choi
*/ */
int srslte_sss_synch_m0m1_partial(srslte_sss_synch_t *q, const cf_t *input, uint32_t M, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value, int srslte_sss_m0m1_partial(srslte_sss_t *q, const cf_t *input, uint32_t M, cf_t ce[2*SRSLTE_SSS_N], uint32_t *m0, float *m0_value,
uint32_t *m1, float *m1_value) uint32_t *m1, float *m1_value)
{ {

@ -35,7 +35,7 @@
#include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/debug.h"
int srslte_pss_synch_init_N_id_2(cf_t *pss_signal_freq, cf_t *pss_signal_time, int srslte_pss_init_N_id_2(cf_t *pss_signal_freq, cf_t *pss_signal_time,
uint32_t N_id_2, uint32_t fft_size, int cfo_i) { uint32_t N_id_2, uint32_t fft_size, int cfo_i) {
srslte_dft_plan_t plan; srslte_dft_plan_t plan;
cf_t pss_signal_pad[2048]; cf_t pss_signal_pad[2048];
@ -73,16 +73,16 @@ int srslte_pss_synch_init_N_id_2(cf_t *pss_signal_freq, cf_t *pss_signal_time,
/* Initializes the PSS synchronization object with fft_size=128 /* Initializes the PSS synchronization object with fft_size=128
*/ */
int srslte_pss_synch_init(srslte_pss_synch_t *q, uint32_t frame_size) { int srslte_pss_init(srslte_pss_t *q, uint32_t frame_size) {
return srslte_pss_synch_init_fft(q, frame_size, 128); return srslte_pss_init_fft(q, frame_size, 128);
} }
int srslte_pss_synch_init_fft(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t fft_size) { int srslte_pss_init_fft(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size) {
return srslte_pss_synch_init_fft_offset(q, frame_size, fft_size, 0); return srslte_pss_init_fft_offset(q, frame_size, fft_size, 0);
} }
int srslte_pss_synch_init_fft_offset(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t fft_size, int offset) { int srslte_pss_init_fft_offset(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size, int offset) {
return srslte_pss_synch_init_fft_offset_decim(q, frame_size, fft_size, offset, 1); return srslte_pss_init_fft_offset_decim(q, frame_size, fft_size, offset, 1);
} }
/* Initializes the PSS synchronization object. /* Initializes the PSS synchronization object.
@ -90,7 +90,7 @@ int srslte_pss_synch_init_fft_offset(srslte_pss_synch_t *q, uint32_t frame_size,
* It correlates a signal of frame_size samples with the PSS sequence in the frequency * It correlates a signal of frame_size samples with the PSS sequence in the frequency
* domain. The PSS sequence is transformed using fft_size samples. * domain. The PSS sequence is transformed using fft_size samples.
*/ */
int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q, int srslte_pss_init_fft_offset_decim(srslte_pss_t *q,
uint32_t max_frame_size, uint32_t max_fft_size, uint32_t max_frame_size, uint32_t max_fft_size,
int offset, int decimate) int offset, int decimate)
{ {
@ -102,7 +102,7 @@ int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q,
uint32_t N_id_2; uint32_t N_id_2;
uint32_t buffer_size; uint32_t buffer_size;
bzero(q, sizeof(srslte_pss_synch_t)); bzero(q, sizeof(srslte_pss_t));
q->N_id_2 = 10; q->N_id_2 = 10;
q->ema_alpha = 0.2; q->ema_alpha = 0.2;
@ -143,7 +143,7 @@ int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q,
} }
srslte_dft_plan_set_mirror(&q->idftp_input, true); srslte_dft_plan_set_mirror(&q->idftp_input, true);
srslte_dft_plan_set_dc(&q->idftp_input, true); srslte_dft_plan_set_dc(&q->idftp_input, true);
srslte_dft_plan_set_norm(&q->idftp_input, true); srslte_dft_plan_set_norm(&q->idftp_input, false);
bzero(q->tmp_fft2, sizeof(cf_t)*SRSLTE_SYMBOL_SZ_MAX); bzero(q->tmp_fft2, sizeof(cf_t)*SRSLTE_SYMBOL_SZ_MAX);
@ -183,7 +183,7 @@ int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q,
goto clean_and_exit; goto clean_and_exit;
} }
/* The PSS is translated into the time domain for each N_id_2 */ /* The PSS is translated into the time domain for each N_id_2 */
if (srslte_pss_synch_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { if (srslte_pss_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) {
fprintf(stderr, "Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); fprintf(stderr, "Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size);
goto clean_and_exit; goto clean_and_exit;
} }
@ -192,27 +192,25 @@ int srslte_pss_synch_init_fft_offset_decim(srslte_pss_synch_t *q,
#ifdef CONVOLUTION_FFT #ifdef CONVOLUTION_FFT
for(N_id_2=0; N_id_2<3; N_id_2++)
q->pss_signal_freq_full[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t));
if (srslte_conv_fft_cc_init(&q->conv_fft, frame_size, fft_size)) { if (srslte_conv_fft_cc_init(&q->conv_fft, frame_size, fft_size)) {
fprintf(stderr, "Error initiating convolution FFT\n"); fprintf(stderr, "Error initiating convolution FFT\n");
goto clean_and_exit; goto clean_and_exit;
} }
for(int i=0; i<3; i++) { for(N_id_2=0; N_id_2<3; N_id_2++) {
srslte_dft_run_c(&q->conv_fft.filter_plan, q->pss_signal_time[i], q->pss_signal_freq_full[i]); q->pss_signal_freq_full[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t));
srslte_dft_run_c(&q->conv_fft.filter_plan, q->pss_signal_time[N_id_2], q->pss_signal_freq_full[N_id_2]);
} }
#endif #endif
srslte_pss_synch_reset(q); srslte_pss_reset(q);
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} }
clean_and_exit: clean_and_exit:
if (ret == SRSLTE_ERROR) { if (ret == SRSLTE_ERROR) {
srslte_pss_synch_free(q); srslte_pss_free(q);
} }
return ret; return ret;
@ -224,7 +222,7 @@ clean_and_exit:
* It correlates a signal of frame_size samples with the PSS sequence in the frequency * It correlates a signal of frame_size samples with the PSS sequence in the frequency
* domain. The PSS sequence is transformed using fft_size samples. * domain. The PSS sequence is transformed using fft_size samples.
*/ */
int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t fft_size, int offset) { int srslte_pss_resize(srslte_pss_t *q, uint32_t frame_size, uint32_t fft_size, int offset) {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
@ -233,7 +231,7 @@ int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t
ret = SRSLTE_ERROR; ret = SRSLTE_ERROR;
if (fft_size > q->max_fft_size || frame_size > q->max_frame_size) { if (fft_size > q->max_fft_size || frame_size > q->max_frame_size) {
fprintf(stderr, "Error in pss_synch_config(): fft_size and frame_size must be lower than initialized\n"); fprintf(stderr, "Error in pss_config(): fft_size and frame_size must be lower than initialized\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -273,7 +271,7 @@ int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t
// Generate PSS sequences for this FFT size // Generate PSS sequences for this FFT size
for (N_id_2=0;N_id_2<3;N_id_2++) { for (N_id_2=0;N_id_2<3;N_id_2++) {
if (srslte_pss_synch_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { if (srslte_pss_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) {
fprintf(stderr, "Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); fprintf(stderr, "Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -291,7 +289,7 @@ int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t
#endif #endif
srslte_pss_synch_reset(q); srslte_pss_reset(q);
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} }
@ -299,7 +297,7 @@ int srslte_pss_synch_resize(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t
} }
void srslte_pss_synch_free(srslte_pss_synch_t *q) { void srslte_pss_free(srslte_pss_t *q) {
uint32_t i; uint32_t i;
if (q) { if (q) {
@ -339,11 +337,11 @@ void srslte_pss_synch_free(srslte_pss_synch_t *q) {
} }
bzero(q, sizeof(srslte_pss_synch_t)); bzero(q, sizeof(srslte_pss_t));
} }
} }
void srslte_pss_synch_reset(srslte_pss_synch_t *q) { void srslte_pss_reset(srslte_pss_t *q) {
uint32_t buffer_size = q->fft_size + q->frame_size + 1; uint32_t buffer_size = q->fft_size + q->frame_size + 1;
bzero(q->conv_output_avg, sizeof(float) * buffer_size); bzero(q->conv_output_avg, sizeof(float) * buffer_size);
} }
@ -401,7 +399,7 @@ void srslte_pss_get_slot(cf_t *slot, cf_t *pss_signal, uint32_t nof_prb, srslte_
/** Sets the current N_id_2 value. Returns -1 on error, 0 otherwise /** Sets the current N_id_2 value. Returns -1 on error, 0 otherwise
*/ */
int srslte_pss_synch_set_N_id_2(srslte_pss_synch_t *q, uint32_t N_id_2) { int srslte_pss_set_N_id_2(srslte_pss_t *q, uint32_t N_id_2) {
if (!srslte_N_id_2_isvalid((N_id_2))) { if (!srslte_N_id_2_isvalid((N_id_2))) {
fprintf(stderr, "Invalid N_id_2 %d\n", N_id_2); fprintf(stderr, "Invalid N_id_2 %d\n", N_id_2);
return -1; return -1;
@ -413,11 +411,11 @@ int srslte_pss_synch_set_N_id_2(srslte_pss_synch_t *q, uint32_t N_id_2) {
/* Sets the weight factor alpha for the exponential moving average of the PSS correlation output /* Sets the weight factor alpha for the exponential moving average of the PSS correlation output
*/ */
void srslte_pss_synch_set_ema_alpha(srslte_pss_synch_t *q, float alpha) { void srslte_pss_set_ema_alpha(srslte_pss_t *q, float alpha) {
q->ema_alpha = alpha; q->ema_alpha = alpha;
} }
float compute_peak_sidelobe(srslte_pss_synch_t *q, uint32_t corr_peak_pos, uint32_t conv_output_len) float compute_peak_sidelobe(srslte_pss_t *q, uint32_t corr_peak_pos, uint32_t conv_output_len)
{ {
// Find end of peak lobe to the right // Find end of peak lobe to the right
int pl_ub = corr_peak_pos+1; int pl_ub = corr_peak_pos+1;
@ -455,7 +453,7 @@ float compute_peak_sidelobe(srslte_pss_synch_t *q, uint32_t corr_peak_pos, uint3
* *
* Input buffer must be subframe_size long. * Input buffer must be subframe_size long.
*/ */
int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, const cf_t *input, float *corr_peak_value) int srslte_pss_find_pss(srslte_pss_t *q, const cf_t *input, float *corr_peak_value)
{ {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
@ -474,7 +472,7 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, const cf_t *input, float *c
/* Correlate input with PSS sequence /* Correlate input with PSS sequence
* *
* We do not reverse time-domain PSS signal because it's conjugate is symmetric. * We do not reverse time-domain PSS signal because it's conjugate is symmetric.
* The conjugate operation on pss_signal_time has been done in srslte_pss_synch_init_N_id_2 * The conjugate operation on pss_signal_time has been done in srslte_pss_init_N_id_2
* This is why we can use FFT-based convolution * This is why we can use FFT-based convolution
*/ */
if (q->frame_size >= q->fft_size) { if (q->frame_size >= q->fft_size) {
@ -545,9 +543,8 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, const cf_t *input, float *c
* input signal is in the time-domain. * input signal is in the time-domain.
* ce is the returned frequency-domain channel estimates. * ce is the returned frequency-domain channel estimates.
*/ */
int srslte_pss_synch_chest(srslte_pss_synch_t *q, const cf_t *input, cf_t ce[SRSLTE_PSS_LEN]) { int srslte_pss_chest(srslte_pss_t *q, const cf_t *input, cf_t ce[SRSLTE_PSS_LEN]) {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
cf_t input_fft[SRSLTE_SYMBOL_SZ_MAX];
if (q != NULL && if (q != NULL &&
input != NULL) input != NULL)
@ -559,18 +556,41 @@ int srslte_pss_synch_chest(srslte_pss_synch_t *q, const cf_t *input, cf_t ce[SRS
} }
/* Transform to frequency-domain */ /* Transform to frequency-domain */
srslte_dft_run_c(&q->dftp_input, input, input_fft); srslte_dft_run_c(&q->dftp_input, input, q->tmp_fft);
/* Compute channel estimate taking the PSS sequence as reference */ /* Compute channel estimate taking the PSS sequence as reference */
srslte_vec_prod_conj_ccc(&input_fft[(q->fft_size-SRSLTE_PSS_LEN)/2], q->pss_signal_freq[q->N_id_2], ce, SRSLTE_PSS_LEN); srslte_vec_prod_conj_ccc(&q->tmp_fft[(q->fft_size-SRSLTE_PSS_LEN)/2], q->pss_signal_freq[q->N_id_2], ce, SRSLTE_PSS_LEN);
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} }
return ret; return ret;
} }
/* input points to beginning of last OFDM symbol of slot 0 of subframe 0 or 5
* It must be called after calling srslte_pss_cfo_compute() with filter enabled
*/
void srslte_pss_sic(srslte_pss_t *q, cf_t *input) {
if (q->chest_on_filter) {
bzero(q->tmp_fft, sizeof(cf_t)*q->fft_size);
// Pass transmitted PSS sequence through the channel
srslte_vec_prod_ccc(q->pss_signal_freq[q->N_id_2], q->tmp_ce, &q->tmp_fft[(q->fft_size-SRSLTE_PSS_LEN)/2], SRSLTE_PSS_LEN);
// Get time-domain version of the received PSS
srslte_dft_run_c(&q->idftp_input, q->tmp_fft, q->tmp_fft2);
// Substract received PSS from this N_id_2 from the input signal
srslte_vec_sc_prod_cfc(q->tmp_fft2, 1.0/q->fft_size, q->tmp_fft2, q->fft_size);
srslte_vec_sub_ccc(input, q->tmp_fft2, input, q->fft_size);
} else {
fprintf(stderr, "Error calling srslte_pss_sic(): need to enable channel estimation on filtering\n");
}
}
// Frequency-domain filtering of the central 64 sub-carriers // Frequency-domain filtering of the central 64 sub-carriers
void srslte_pss_synch_filter(srslte_pss_synch_t *q, const cf_t *input, cf_t *output) void srslte_pss_filter(srslte_pss_t *q, const cf_t *input, cf_t *output)
{ {
srslte_dft_run_c(&q->dftp_input, input, q->tmp_fft); srslte_dft_run_c(&q->dftp_input, input, q->tmp_fft);
@ -578,6 +598,10 @@ void srslte_pss_synch_filter(srslte_pss_synch_t *q, const cf_t *input, cf_t *out
&q->tmp_fft[q->fft_size/2-SRSLTE_PSS_LEN/2], &q->tmp_fft[q->fft_size/2-SRSLTE_PSS_LEN/2],
sizeof(cf_t)*SRSLTE_PSS_LEN); sizeof(cf_t)*SRSLTE_PSS_LEN);
if (q->chest_on_filter) {
srslte_vec_prod_conj_ccc(&q->tmp_fft[(q->fft_size-SRSLTE_PSS_LEN)/2], q->pss_signal_freq[q->N_id_2], q->tmp_ce, SRSLTE_PSS_LEN);
}
srslte_dft_run_c(&q->idftp_input, q->tmp_fft2, output); srslte_dft_run_c(&q->idftp_input, q->tmp_fft2, output);
} }
@ -586,13 +610,13 @@ void srslte_pss_synch_filter(srslte_pss_synch_t *q, const cf_t *input, cf_t *out
* Source: An Efcient CFO Estimation Algorithm for the Downlink of 3GPP-LTE * Source: An Efcient CFO Estimation Algorithm for the Downlink of 3GPP-LTE
* Feng Wang and Yu Zhu * Feng Wang and Yu Zhu
*/ */
float srslte_pss_synch_cfo_compute(srslte_pss_synch_t* q, const cf_t *pss_recv) { float srslte_pss_cfo_compute(srslte_pss_t* q, const cf_t *pss_recv) {
cf_t y0, y1; cf_t y0, y1;
const cf_t *pss_ptr = pss_recv; const cf_t *pss_ptr = pss_recv;
if (q->filter_pss_enable) { if (q->filter_pss_enable) {
srslte_pss_synch_filter(q, pss_recv, q->tmp_fft); srslte_pss_filter(q, pss_recv, q->tmp_fft);
pss_ptr = (const cf_t*) q->tmp_fft; pss_ptr = (const cf_t*) q->tmp_fft;
} }

@ -40,7 +40,7 @@ void generate_sss_all_tables(srslte_sss_tables_t *tables, uint32_t N_id_2);
void convert_tables(srslte_sss_fc_tables_t *fc_tables, srslte_sss_tables_t *in); void convert_tables(srslte_sss_fc_tables_t *fc_tables, srslte_sss_tables_t *in);
void generate_N_id_1_table(uint32_t table[30][30]); void generate_N_id_1_table(uint32_t table[30][30]);
int srslte_sss_synch_init(srslte_sss_synch_t *q, uint32_t fft_size) { int srslte_sss_init(srslte_sss_t *q, uint32_t fft_size) {
if (q != NULL && if (q != NULL &&
fft_size <= 2048) fft_size <= 2048)
@ -48,10 +48,10 @@ int srslte_sss_synch_init(srslte_sss_synch_t *q, uint32_t fft_size) {
uint32_t N_id_2; uint32_t N_id_2;
srslte_sss_tables_t sss_tables; srslte_sss_tables_t sss_tables;
bzero(q, sizeof(srslte_sss_synch_t)); bzero(q, sizeof(srslte_sss_t));
if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) {
srslte_sss_synch_free(q); srslte_sss_free(q);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
srslte_dft_plan_set_mirror(&q->dftp_input, true); srslte_dft_plan_set_mirror(&q->dftp_input, true);
@ -72,7 +72,7 @@ int srslte_sss_synch_init(srslte_sss_synch_t *q, uint32_t fft_size) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
int srslte_sss_synch_resize(srslte_sss_synch_t *q, uint32_t fft_size) { int srslte_sss_resize(srslte_sss_t *q, uint32_t fft_size) {
if (q != NULL && if (q != NULL &&
fft_size <= 2048) fft_size <= 2048)
{ {
@ -81,7 +81,7 @@ int srslte_sss_synch_resize(srslte_sss_synch_t *q, uint32_t fft_size) {
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (srslte_dft_replan(&q->dftp_input, fft_size)) { if (srslte_dft_replan(&q->dftp_input, fft_size)) {
srslte_sss_synch_free(q); srslte_sss_free(q);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
q->fft_size = fft_size; q->fft_size = fft_size;
@ -90,13 +90,13 @@ int srslte_sss_synch_resize(srslte_sss_synch_t *q, uint32_t fft_size) {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
void srslte_sss_synch_free(srslte_sss_synch_t *q) { void srslte_sss_free(srslte_sss_t *q) {
srslte_dft_plan_free(&q->dftp_input); srslte_dft_plan_free(&q->dftp_input);
bzero(q, sizeof(srslte_sss_synch_t)); bzero(q, sizeof(srslte_sss_t));
} }
/** Sets the N_id_2 to search for */ /** Sets the N_id_2 to search for */
int srslte_sss_synch_set_N_id_2(srslte_sss_synch_t *q, uint32_t N_id_2) { int srslte_sss_set_N_id_2(srslte_sss_t *q, uint32_t N_id_2) {
if (!srslte_N_id_2_isvalid(N_id_2)) { if (!srslte_N_id_2_isvalid(N_id_2)) {
fprintf(stderr, "Invalid N_id_2 %d\n", N_id_2); fprintf(stderr, "Invalid N_id_2 %d\n", N_id_2);
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -124,12 +124,12 @@ void srslte_sss_put_slot(float *sss, cf_t *slot, uint32_t nof_prb, srslte_cp_t c
} }
/** Sets the SSS correlation peak detection threshold */ /** Sets the SSS correlation peak detection threshold */
void srslte_sss_synch_set_threshold(srslte_sss_synch_t *q, float threshold) { void srslte_sss_set_threshold(srslte_sss_t *q, float threshold) {
q->corr_peak_threshold = threshold; q->corr_peak_threshold = threshold;
} }
/** Returns the subframe index based on the m0 and m1 values */ /** Returns the subframe index based on the m0 and m1 values */
uint32_t srslte_sss_synch_subframe(uint32_t m0, uint32_t m1) { uint32_t srslte_sss_subframe(uint32_t m0, uint32_t m1) {
if (m1 > m0) { if (m1 > m0) {
return 0; return 0;
} else { } else {
@ -138,7 +138,7 @@ uint32_t srslte_sss_synch_subframe(uint32_t m0, uint32_t m1) {
} }
/** Returns the N_id_1 value based on the m0 and m1 values */ /** Returns the N_id_1 value based on the m0 and m1 values */
int srslte_sss_synch_N_id_1(srslte_sss_synch_t *q, uint32_t m0, uint32_t m1) { int srslte_sss_N_id_1(srslte_sss_t *q, uint32_t m0, uint32_t m1) {
int N_id_1 = -1; int N_id_1 = -1;
if (m1 > m0) { if (m1 > m0) {
if (m0 < 30 && m1 - 1 < 30) { if (m0 < 30 && m1 - 1 < 30) {

@ -77,7 +77,6 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o
q->cfo_cp_enable = false; q->cfo_cp_enable = false;
q->cfo_i_initiated = false; q->cfo_i_initiated = false;
q->pss_filtering_enabled = false; q->pss_filtering_enabled = false;
q->sss_filtering_enabled = false;
q->fft_size = fft_size; q->fft_size = fft_size;
q->frame_size = frame_size; q->frame_size = frame_size;
@ -119,11 +118,11 @@ int srslte_sync_init_decim(srslte_sync_t *q, uint32_t frame_size, uint32_t max_o
decimate = 1; decimate = 1;
} }
if (srslte_pss_synch_init_fft_offset_decim(&q->pss, max_offset, fft_size, 0, decimate)) { if (srslte_pss_init_fft_offset_decim(&q->pss, max_offset, fft_size, 0, decimate)) {
fprintf(stderr, "Error initializing PSS object\n"); fprintf(stderr, "Error initializing PSS object\n");
goto clean_exit; goto clean_exit;
} }
if (srslte_sss_synch_init(&q->sss, fft_size)) { if (srslte_sss_init(&q->sss, fft_size)) {
fprintf(stderr, "Error initializing SSS object\n"); fprintf(stderr, "Error initializing SSS object\n");
goto clean_exit; goto clean_exit;
} }
@ -151,8 +150,8 @@ void srslte_sync_free(srslte_sync_t *q)
{ {
if (q) { if (q) {
srslte_pss_synch_free(&q->pss); srslte_pss_free(&q->pss);
srslte_sss_synch_free(&q->sss); srslte_sss_free(&q->sss);
srslte_cfo_free(&q->cfo_corr_frame); srslte_cfo_free(&q->cfo_corr_frame);
srslte_cfo_free(&q->cfo_corr_symbol); srslte_cfo_free(&q->cfo_corr_symbol);
srslte_cp_synch_free(&q->cp_synch); srslte_cp_synch_free(&q->cp_synch);
@ -162,7 +161,7 @@ void srslte_sync_free(srslte_sync_t *q)
if (q->cfo_i_corr[i]) { if (q->cfo_i_corr[i]) {
free(q->cfo_i_corr[i]); free(q->cfo_i_corr[i]);
} }
srslte_pss_synch_free(&q->pss_i[i]); srslte_pss_free(&q->pss_i[i]);
} }
} }
if (q->temp) { if (q->temp) {
@ -188,11 +187,11 @@ int srslte_sync_resize(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offse
q->frame_size = frame_size; q->frame_size = frame_size;
q->max_offset = max_offset; q->max_offset = max_offset;
if (srslte_pss_synch_resize(&q->pss, q->max_offset, q->fft_size, 0)) { if (srslte_pss_resize(&q->pss, q->max_offset, q->fft_size, 0)) {
fprintf(stderr, "Error resizing PSS object\n"); fprintf(stderr, "Error resizing PSS object\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (srslte_sss_synch_resize(&q->sss, q->fft_size)) { if (srslte_sss_resize(&q->sss, q->fft_size)) {
fprintf(stderr, "Error resizing SSS object\n"); fprintf(stderr, "Error resizing SSS object\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -215,7 +214,7 @@ int srslte_sync_resize(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offse
if (q->cfo_i_initiated) { if (q->cfo_i_initiated) {
for (int i=0;i<2;i++) { for (int i=0;i<2;i++) {
int offset=(i==0)?-1:1; int offset=(i==0)?-1:1;
if (srslte_pss_synch_resize(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { if (srslte_pss_resize(&q->pss_i[i], q->max_offset, q->fft_size, offset)) {
fprintf(stderr, "Error initializing PSS object\n"); fprintf(stderr, "Error initializing PSS object\n");
} }
for (int t=0;t<q->frame_size;t++) { for (int t=0;t<q->frame_size;t++) {
@ -302,7 +301,7 @@ void srslte_sync_set_cfo_i_enable(srslte_sync_t *q, bool enable) {
if (q->cfo_i_enable && !q->cfo_i_initiated) { if (q->cfo_i_enable && !q->cfo_i_initiated) {
for (int i=0;i<2;i++) { for (int i=0;i<2;i++) {
int offset=(i==0)?-1:1; int offset=(i==0)?-1:1;
if (srslte_pss_synch_init_fft_offset(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { if (srslte_pss_init_fft_offset(&q->pss_i[i], q->max_offset, q->fft_size, offset)) {
fprintf(stderr, "Error initializing PSS object\n"); fprintf(stderr, "Error initializing PSS object\n");
} }
for (int t=0;t<q->frame_size;t++) { for (int t=0;t<q->frame_size;t++) {
@ -313,8 +312,12 @@ void srslte_sync_set_cfo_i_enable(srslte_sync_t *q, bool enable) {
} }
} }
void srslte_sync_set_sss_filt_enable(srslte_sync_t *q, bool enable) { void srslte_sync_set_sss_eq_enable(srslte_sync_t *q, bool enable) {
q->sss_filtering_enabled = enable; q->sss_channel_equalize = enable;
if (enable) {
q->pss_filtering_enabled = true;
q->pss.chest_on_filter = true;
}
} }
void srslte_sync_set_pss_filt_enable(srslte_sync_t *q, bool enable) { void srslte_sync_set_pss_filt_enable(srslte_sync_t *q, bool enable) {
@ -343,7 +346,7 @@ void srslte_sync_cp_en(srslte_sync_t *q, bool enabled) {
void srslte_sync_set_em_alpha(srslte_sync_t *q, float alpha) void srslte_sync_set_em_alpha(srslte_sync_t *q, float alpha)
{ {
srslte_pss_synch_set_ema_alpha(&q->pss, alpha); srslte_pss_set_ema_alpha(&q->pss, alpha);
} }
srslte_cp_t srslte_sync_get_cp(srslte_sync_t *q) srslte_cp_t srslte_sync_get_cp(srslte_sync_t *q)
@ -434,22 +437,22 @@ int sync_sss_symbol(srslte_sync_t *q, const cf_t *input)
{ {
int ret; int ret;
srslte_sss_synch_set_N_id_2(&q->sss, q->N_id_2); srslte_sss_set_N_id_2(&q->sss, q->N_id_2);
switch(q->sss_alg) { switch(q->sss_alg) {
case SSS_DIFF: case SSS_DIFF:
srslte_sss_synch_m0m1_diff(&q->sss, input, &q->m0, &q->m0_value, &q->m1, &q->m1_value); srslte_sss_m0m1_diff(&q->sss, input, &q->m0, &q->m0_value, &q->m1, &q->m1_value);
break; break;
case SSS_PARTIAL_3: case SSS_PARTIAL_3:
srslte_sss_synch_m0m1_partial(&q->sss, input, 3, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); srslte_sss_m0m1_partial(&q->sss, input, 3, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value);
break; break;
case SSS_FULL: case SSS_FULL:
srslte_sss_synch_m0m1_partial(&q->sss, input, 1, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); srslte_sss_m0m1_partial(&q->sss, input, 1, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value);
break; break;
} }
q->sf_idx = srslte_sss_synch_subframe(q->m0, q->m1); q->sf_idx = srslte_sss_subframe(q->m0, q->m1);
ret = srslte_sss_synch_N_id_1(&q->sss, q->m0, q->m1); ret = srslte_sss_N_id_1(&q->sss, q->m0, q->m1);
if (ret >= 0) { if (ret >= 0) {
q->N_id_1 = (uint32_t) ret; q->N_id_1 = (uint32_t) ret;
DEBUG("SSS detected N_id_1=%d, sf_idx=%d, %s CP\n", DEBUG("SSS detected N_id_1=%d, sf_idx=%d, %s CP\n",
@ -461,9 +464,9 @@ int sync_sss_symbol(srslte_sync_t *q, const cf_t *input)
} }
} }
srslte_pss_synch_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q) srslte_pss_t* srslte_sync_get_cur_pss_obj(srslte_sync_t *q)
{ {
srslte_pss_synch_t *pss_obj[3] = {&q->pss_i[0], &q->pss, &q->pss_i[1]}; srslte_pss_t *pss_obj[3] = {&q->pss_i[0], &q->pss, &q->pss_i[1]};
return pss_obj[q->cfo_i_value+1]; return pss_obj[q->cfo_i_value+1];
} }
@ -481,10 +484,10 @@ static int cfo_i_estimate(srslte_sync_t *q, const cf_t *input, int find_offset,
float peak_value; float peak_value;
float max_peak_value = -99; float max_peak_value = -99;
int max_cfo_i = 0; int max_cfo_i = 0;
srslte_pss_synch_t *pss_obj[3] = {&q->pss_i[0], &q->pss, &q->pss_i[1]}; srslte_pss_t *pss_obj[3] = {&q->pss_i[0], &q->pss, &q->pss_i[1]};
for (int cfo_i=0;cfo_i<3;cfo_i++) { 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); srslte_pss_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); int p = srslte_pss_find_pss(pss_obj[cfo_i], &input[find_offset], &peak_value);
if (p < 0) { if (p < 0) {
return -1; return -1;
} }
@ -574,8 +577,8 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, const cf_t *input, uin
/* Find maximum of PSS correlation. If Integer CFO is enabled, correlation is already done /* Find maximum of PSS correlation. If Integer CFO is enabled, correlation is already done
*/ */
if (!q->cfo_i_enable) { if (!q->cfo_i_enable) {
srslte_pss_synch_set_N_id_2(&q->pss, q->N_id_2); srslte_pss_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); peak_pos = srslte_pss_find_pss(&q->pss, &input_ptr[find_offset], q->threshold>0?&q->peak_value:NULL);
if (peak_pos < 0) { if (peak_pos < 0) {
fprintf(stderr, "Error calling finding PSS sequence at : %d \n", peak_pos); fprintf(stderr, "Error calling finding PSS sequence at : %d \n", peak_pos);
return SRSLTE_ERROR; return SRSLTE_ERROR;
@ -602,12 +605,12 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, const cf_t *input, uin
// Filter central bands before PSS-based CFO estimation // Filter central bands before PSS-based CFO estimation
const cf_t *pss_ptr = &input_ptr[find_offset + peak_pos - q->fft_size]; const cf_t *pss_ptr = &input_ptr[find_offset + peak_pos - q->fft_size];
if (q->pss_filtering_enabled) { if (q->pss_filtering_enabled) {
srslte_pss_synch_filter(&q->pss, pss_ptr, q->pss_filt); srslte_pss_filter(&q->pss, pss_ptr, q->pss_filt);
pss_ptr = q->pss_filt; pss_ptr = q->pss_filt;
} }
// PSS-based CFO estimation // PSS-based CFO estimation
float cfo_pss = srslte_pss_synch_cfo_compute(&q->pss, pss_ptr); float cfo_pss = srslte_pss_cfo_compute(&q->pss, pss_ptr);
if (!q->cfo_pss_is_set) { if (!q->cfo_pss_is_set) {
q->cfo_pss_mean = cfo_pss; q->cfo_pss_mean = cfo_pss;
q->cfo_pss_is_set = true; q->cfo_pss_is_set = true;
@ -637,12 +640,11 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, const cf_t *input, uin
// Correct CFO if detected in PSS // Correct CFO if detected in PSS
if (q->cfo_pss_enable) { if (q->cfo_pss_enable) {
srslte_cfo_correct(&q->cfo_corr_symbol, sss_ptr, q->sss_filt, -q->cfo_pss_mean / q->fft_size); srslte_cfo_correct(&q->cfo_corr_symbol, sss_ptr, q->sss_filt, -q->cfo_pss_mean / q->fft_size);
sss_ptr = q->sss_filt; // Equalize channel if estimated in PSS
if (q->sss_channel_equalize && q->pss.chest_on_filter && q->pss_filtering_enabled) {
srslte_vec_prod_ccc(&q->sss_filt[q->fft_size/2-SRSLTE_PSS_LEN/2], q->pss.tmp_ce,
&q->sss_filt[q->fft_size/2-SRSLTE_PSS_LEN/2], SRSLTE_PSS_LEN);
} }
// 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; sss_ptr = q->sss_filt;
} }
@ -681,5 +683,5 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, const cf_t *input, uin
void srslte_sync_reset(srslte_sync_t *q) { void srslte_sync_reset(srslte_sync_t *q) {
q->M_ext_avg = 0; q->M_ext_avg = 0;
q->M_norm_avg = 0; q->M_norm_avg = 0;
srslte_pss_synch_reset(&q->pss); srslte_pss_reset(&q->pss);
} }

@ -121,9 +121,9 @@ int main(int argc, char **argv) {
srslte_filesource_t fsrc; srslte_filesource_t fsrc;
cf_t *buffer; cf_t *buffer;
int frame_cnt, n; int frame_cnt, n;
srslte_pss_synch_t pss; srslte_pss_t pss;
srslte_cfo_t cfocorr, cfocorr64; srslte_cfo_t cfocorr, cfocorr64;
srslte_sss_synch_t sss; srslte_sss_t sss;
int32_t flen; int32_t flen;
int peak_idx, last_peak; int peak_idx, last_peak;
float peak_value; float peak_value;
@ -152,12 +152,12 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (srslte_pss_synch_init_fft(&pss, flen, fft_size)) { if (srslte_pss_init_fft(&pss, flen, fft_size)) {
fprintf(stderr, "Error initiating PSS\n"); fprintf(stderr, "Error initiating PSS\n");
exit(-1); exit(-1);
} }
if (srslte_pss_synch_set_N_id_2(&pss, N_id_2_sync)) { if (srslte_pss_set_N_id_2(&pss, N_id_2_sync)) {
fprintf(stderr, "Error setting N_id_2=%d\n",N_id_2_sync); fprintf(stderr, "Error setting N_id_2=%d\n",N_id_2_sync);
exit(-1); exit(-1);
} }
@ -165,12 +165,12 @@ int main(int argc, char **argv) {
srslte_cfo_init(&cfocorr, flen); srslte_cfo_init(&cfocorr, flen);
srslte_cfo_init(&cfocorr64, flen); srslte_cfo_init(&cfocorr64, flen);
if (srslte_sss_synch_init(&sss, fft_size)) { if (srslte_sss_init(&sss, fft_size)) {
fprintf(stderr, "Error initializing SSS object\n"); fprintf(stderr, "Error initializing SSS object\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
srslte_sss_synch_set_N_id_2(&sss, N_id_2); srslte_sss_set_N_id_2(&sss, N_id_2);
printf("Opening file...\n"); printf("Opening file...\n");
if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { if (srslte_filesource_init(&fsrc, input_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) {
@ -210,7 +210,7 @@ int main(int argc, char **argv) {
break; break;
} }
peak_idx = srslte_pss_synch_find_pss(&pss, buffer, &peak_value); peak_idx = srslte_pss_find_pss(&pss, buffer, &peak_value);
if (peak_idx < 0) { if (peak_idx < 0) {
fprintf(stderr, "Error finding PSS peak\n"); fprintf(stderr, "Error finding PSS peak\n");
exit(-1); exit(-1);
@ -224,14 +224,14 @@ int main(int argc, char **argv) {
if (peak_idx >= fft_size) { if (peak_idx >= fft_size) {
// Estimate CFO // Estimate CFO
cfo = srslte_pss_synch_cfo_compute(&pss, &buffer[peak_idx-fft_size]); cfo = srslte_pss_cfo_compute(&pss, &buffer[peak_idx-fft_size]);
mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt); mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt);
// Correct CFO // Correct CFO
srslte_cfo_correct(&cfocorr, buffer, buffer, -mean_cfo / fft_size); srslte_cfo_correct(&cfocorr, buffer, buffer, -mean_cfo / fft_size);
// Estimate channel // Estimate channel
if (srslte_pss_synch_chest(&pss, &buffer[peak_idx-fft_size], ce)) { if (srslte_pss_chest(&pss, &buffer[peak_idx-fft_size], ce)) {
fprintf(stderr, "Error computing channel estimation\n"); fprintf(stderr, "Error computing channel estimation\n");
exit(-1); exit(-1);
} }
@ -239,22 +239,22 @@ int main(int argc, char **argv) {
// 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)); 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) { if (sss_idx >= 0 && sss_idx < flen-fft_size) {
srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value); srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value);
if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) {
sss_error2++; sss_error2++;
} }
INFO("sf_idx = %d\n", srslte_sss_synch_subframe(m0, m1)); INFO("sf_idx = %d\n", srslte_sss_subframe(m0, m1));
INFO("Partial N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); INFO("Partial N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1));
srslte_sss_synch_m0m1_diff(&sss, &buffer[sss_idx], &m0, &m0_value, &m1, &m1_value); srslte_sss_m0m1_diff(&sss, &buffer[sss_idx], &m0, &m0_value, &m1, &m1_value);
if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) {
sss_error3++; sss_error3++;
} }
INFO("Diff N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); INFO("Diff N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1));
srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value);
if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) {
sss_error1++; sss_error1++;
} }
INFO("Full N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); INFO("Full N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1));
} }
// Estimate CP // Estimate CP
@ -269,7 +269,7 @@ int main(int argc, char **argv) {
INFO("No space for CFO computation. Frame starts at \n",peak_idx); INFO("No space for CFO computation. Frame starts at \n",peak_idx);
} }
if(srslte_sss_synch_subframe(m0,m1) == 0) if(srslte_sss_subframe(m0,m1) == 0)
{ {
#ifndef DISABLE_GRAPHICS #ifndef DISABLE_GRAPHICS
if (!disable_plots) if (!disable_plots)
@ -317,7 +317,7 @@ int main(int argc, char **argv) {
} }
srslte_pss_synch_free(&pss); srslte_pss_free(&pss);
free(buffer); free(buffer);
srslte_filesource_free(&fsrc); srslte_filesource_free(&fsrc);
#ifndef DISABLE_GRAPHICS #ifndef DISABLE_GRAPHICS

@ -47,7 +47,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{ {
srslte_cell_t cell; srslte_cell_t cell;
srslte_pss_synch_t pss; srslte_pss_t pss;
cf_t *input_symbols; cf_t *input_symbols;
int frame_len; int frame_len;
@ -74,17 +74,17 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
frame_len = (int) mxGetScalar(prhs[NOF_INPUTS]); frame_len = (int) mxGetScalar(prhs[NOF_INPUTS]);
} }
if (srslte_pss_synch_init_fft(&pss, frame_len, srslte_symbol_sz(cell.nof_prb))) { if (srslte_pss_init_fft(&pss, frame_len, srslte_symbol_sz(cell.nof_prb))) {
fprintf(stderr, "Error initiating PSS\n"); fprintf(stderr, "Error initiating PSS\n");
exit(-1); exit(-1);
} }
if (srslte_pss_synch_set_N_id_2(&pss, cell.id%3)) { if (srslte_pss_set_N_id_2(&pss, cell.id%3)) {
fprintf(stderr, "Error setting N_id_2=%d\n",cell.id%3); fprintf(stderr, "Error setting N_id_2=%d\n",cell.id%3);
exit(-1); exit(-1);
} }
srslte_pss_synch_set_ema_alpha(&pss, 1.0); srslte_pss_set_ema_alpha(&pss, 1.0);
int peak_idx = srslte_pss_synch_find_pss(&pss, input_symbols, NULL); int peak_idx = srslte_pss_find_pss(&pss, input_symbols, NULL);
if (nlhs >= 1) { if (nlhs >= 1) {
plhs[0] = mxCreateDoubleScalar(peak_idx); plhs[0] = mxCreateDoubleScalar(peak_idx);
@ -93,7 +93,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mexutils_write_cf(pss.conv_output, &plhs[1], frame_len, 1); mexutils_write_cf(pss.conv_output, &plhs[1], frame_len, 1);
} }
srslte_pss_synch_free(&pss); srslte_pss_free(&pss);
free(input_symbols); free(input_symbols);
return; return;

@ -125,9 +125,9 @@ int main(int argc, char **argv) {
cf_t *buffer; cf_t *buffer;
int frame_cnt, n; int frame_cnt, n;
srslte_rf_t rf; srslte_rf_t rf;
srslte_pss_synch_t pss; srslte_pss_t pss;
srslte_cfo_t cfocorr, cfocorr64; srslte_cfo_t cfocorr, cfocorr64;
srslte_sss_synch_t sss; srslte_sss_t sss;
int32_t flen; int32_t flen;
int peak_idx, last_peak; int peak_idx, last_peak;
float peak_value; float peak_value;
@ -176,12 +176,12 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (srslte_pss_synch_init_fft(&pss, flen, fft_size)) { if (srslte_pss_init_fft(&pss, flen, fft_size)) {
fprintf(stderr, "Error initiating PSS\n"); fprintf(stderr, "Error initiating PSS\n");
exit(-1); exit(-1);
} }
if (srslte_pss_synch_set_N_id_2(&pss, N_id_2_sync)) { if (srslte_pss_set_N_id_2(&pss, N_id_2_sync)) {
fprintf(stderr, "Error setting N_id_2=%d\n",N_id_2_sync); fprintf(stderr, "Error setting N_id_2=%d\n",N_id_2_sync);
exit(-1); exit(-1);
} }
@ -189,12 +189,12 @@ int main(int argc, char **argv) {
srslte_cfo_init(&cfocorr, flen); srslte_cfo_init(&cfocorr, flen);
srslte_cfo_init(&cfocorr64, flen); srslte_cfo_init(&cfocorr64, flen);
if (srslte_sss_synch_init(&sss, fft_size)) { if (srslte_sss_init(&sss, fft_size)) {
fprintf(stderr, "Error initializing SSS object\n"); fprintf(stderr, "Error initializing SSS object\n");
exit(-1); exit(-1);
} }
srslte_sss_synch_set_N_id_2(&sss, N_id_2); srslte_sss_set_N_id_2(&sss, N_id_2);
printf("N_id_2: %d\n", N_id_2); printf("N_id_2: %d\n", N_id_2);
@ -232,7 +232,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
peak_idx = srslte_pss_synch_find_pss(&pss, buffer, &peak_value); peak_idx = srslte_pss_find_pss(&pss, buffer, &peak_value);
if (peak_idx < 0) { if (peak_idx < 0) {
fprintf(stderr, "Error finding PSS peak\n"); fprintf(stderr, "Error finding PSS peak\n");
exit(-1); exit(-1);
@ -246,14 +246,14 @@ int main(int argc, char **argv) {
if (peak_idx >= fft_size) { if (peak_idx >= fft_size) {
// Estimate CFO // Estimate CFO
cfo = srslte_pss_synch_cfo_compute(&pss, &buffer[peak_idx-fft_size]); cfo = srslte_pss_cfo_compute(&pss, &buffer[peak_idx-fft_size]);
mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt); mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt);
// Correct CFO // Correct CFO
srslte_cfo_correct(&cfocorr, buffer, buffer, -mean_cfo / fft_size); srslte_cfo_correct(&cfocorr, buffer, buffer, -mean_cfo / fft_size);
// Estimate channel // Estimate channel
if (srslte_pss_synch_chest(&pss, &buffer[peak_idx-fft_size], ce)) { if (srslte_pss_chest(&pss, &buffer[peak_idx-fft_size], ce)) {
fprintf(stderr, "Error computing channel estimation\n"); fprintf(stderr, "Error computing channel estimation\n");
exit(-1); exit(-1);
} }
@ -263,22 +263,22 @@ int main(int argc, char **argv) {
if (sss_idx >= 0 && sss_idx < flen-fft_size) { if (sss_idx >= 0 && sss_idx < flen-fft_size) {
// Filter SSS // Filter SSS
srslte_pss_synch_filter(&pss, &buffer[sss_idx], &buffer[sss_idx]); srslte_pss_filter(&pss, &buffer[sss_idx], &buffer[sss_idx]);
INFO("Full N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); INFO("Full N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1));
srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 1, ce, &m0, &m0_value, &m1, &m1_value); srslte_sss_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) { if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) {
sss_error2++; sss_error2++;
} }
INFO("Partial N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); INFO("Partial N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1));
srslte_sss_synch_m0m1_diff_coh(&sss, &buffer[sss_idx], ce, &m0, &m0_value, &m1, &m1_value); srslte_sss_m0m1_diff_coh(&sss, &buffer[sss_idx], ce, &m0, &m0_value, &m1, &m1_value);
if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) {
sss_error3++; sss_error3++;
} }
INFO("Diff N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); INFO("Diff N_id_1: %d\n", srslte_sss_N_id_1(&sss, m0, m1));
} }
srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); srslte_sss_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value);
if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { if (srslte_sss_N_id_1(&sss, m0, m1) != N_id_1) {
sss_error1++; sss_error1++;
} }
@ -294,7 +294,7 @@ int main(int argc, char **argv) {
INFO("No space for CFO computation. Frame starts at \n",peak_idx); INFO("No space for CFO computation. Frame starts at \n",peak_idx);
} }
if(srslte_sss_synch_subframe(m0,m1) == 0) if(srslte_sss_subframe(m0,m1) == 0)
{ {
#ifndef DISABLE_GRAPHICS #ifndef DISABLE_GRAPHICS
if (!disable_plots) if (!disable_plots)
@ -358,8 +358,8 @@ int main(int argc, char **argv) {
} }
srslte_sss_synch_free(&sss); srslte_sss_free(&sss);
srslte_pss_synch_free(&pss); srslte_pss_free(&pss);
free(buffer); free(buffer);
srslte_rf_close(&rf); srslte_rf_close(&rf);

@ -50,7 +50,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{ {
srslte_cell_t cell; srslte_cell_t cell;
srslte_sss_synch_t sss; srslte_sss_t sss;
cf_t *input_symbols; cf_t *input_symbols;
int frame_len; int frame_len;
uint32_t m0, m1; uint32_t m0, m1;
@ -80,12 +80,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (srslte_sss_synch_init(&sss, srslte_symbol_sz(cell.nof_prb))) { if (srslte_sss_init(&sss, srslte_symbol_sz(cell.nof_prb))) {
mexErrMsgTxt("Error initializing SSS object\n"); mexErrMsgTxt("Error initializing SSS object\n");
return; return;
} }
srslte_sss_synch_set_N_id_2(&sss, cell.id%3); srslte_sss_set_N_id_2(&sss, cell.id%3);
// Find SSS // Find SSS
uint32_t sss_idx = SRSLTE_SLOT_IDX_CPNORM(5,srslte_symbol_sz(cell.nof_prb)); uint32_t sss_idx = SRSLTE_SLOT_IDX_CPNORM(5,srslte_symbol_sz(cell.nof_prb));
@ -95,23 +95,23 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
//mexPrintf("SSS begins at %d/%d. Running algorithm %s\n", sss_idx, frame_len, alg); //mexPrintf("SSS begins at %d/%d. Running algorithm %s\n", sss_idx, frame_len, alg);
if (!strcmp(alg, "partial")) { if (!strcmp(alg, "partial")) {
srslte_sss_synch_m0m1_partial(&sss, &input_symbols[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value); srslte_sss_m0m1_partial(&sss, &input_symbols[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value);
} else if (!strcmp(alg, "diff")) { } else if (!strcmp(alg, "diff")) {
srslte_sss_synch_m0m1_diff(&sss, &input_symbols[sss_idx], &m0, &m0_value, &m1, &m1_value); srslte_sss_m0m1_diff(&sss, &input_symbols[sss_idx], &m0, &m0_value, &m1, &m1_value);
} else if (!strcmp(alg, "full")) { } else if (!strcmp(alg, "full")) {
srslte_sss_synch_m0m1_partial(&sss, &input_symbols[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); srslte_sss_m0m1_partial(&sss, &input_symbols[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value);
} else { } else {
mexErrMsgTxt("Unsupported algorithm type\n"); mexErrMsgTxt("Unsupported algorithm type\n");
return; return;
} }
//mexPrintf("m0: %d, m1: %d, N_id_1: %d\n", m0, m1, srslte_sss_synch_N_id_1(&sss, m0, m1)); //mexPrintf("m0: %d, m1: %d, N_id_1: %d\n", m0, m1, srslte_sss_N_id_1(&sss, m0, m1));
if (nlhs >= 1) { if (nlhs >= 1) {
plhs[0] = mxCreateDoubleScalar(srslte_sss_synch_N_id_1(&sss, m0, m1)); plhs[0] = mxCreateDoubleScalar(srslte_sss_N_id_1(&sss, m0, m1));
} }
if (nlhs >= 2) { if (nlhs >= 2) {
plhs[1] = mxCreateDoubleScalar(srslte_sss_synch_subframe(m0, m1)); plhs[1] = mxCreateDoubleScalar(srslte_sss_subframe(m0, m1));
} }
if (nlhs >= 3) { if (nlhs >= 3) {
mexutils_write_f(sss.corr_output_m0, &plhs[2], SRSLTE_SSS_N, 1); mexutils_write_f(sss.corr_output_m0, &plhs[2], SRSLTE_SSS_N, 1);
@ -119,7 +119,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
if (nlhs >= 4) { if (nlhs >= 4) {
mexutils_write_f(sss.corr_output_m1, &plhs[3], SRSLTE_SSS_N, 1); mexutils_write_f(sss.corr_output_m1, &plhs[3], SRSLTE_SSS_N, 1);
} }
srslte_sss_synch_free(&sss); srslte_sss_free(&sss);
free(input_symbols); free(input_symbols);
return; return;

@ -272,14 +272,14 @@ int srslte_ue_sync_init_multi_decim(srslte_ue_sync_t *q,
srslte_sync_set_cfo_cp_enable(&q->sfind, true); srslte_sync_set_cfo_cp_enable(&q->sfind, true);
srslte_sync_set_cfo_pss_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_pss_filt_enable(&q->sfind, true);
srslte_sync_set_sss_filt_enable(&q->sfind, true); srslte_sync_set_sss_eq_enable(&q->sfind, true);
// During track, we do CFO correction outside the sync object // During track, we do CFO correction outside the sync object
srslte_sync_set_cfo_i_enable(&q->strack, false); srslte_sync_set_cfo_i_enable(&q->strack, false);
srslte_sync_set_cfo_cp_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_cfo_pss_enable(&q->strack, true);
srslte_sync_set_pss_filt_enable(&q->strack, true); srslte_sync_set_pss_filt_enable(&q->strack, true);
srslte_sync_set_sss_filt_enable(&q->strack, false); srslte_sync_set_sss_eq_enable(&q->strack, false);
// FIXME: CP detection not working very well. Not supporting Extended CP right now // 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->strack, false);

@ -102,8 +102,6 @@ private:
bool set_frequency(); bool set_frequency();
bool set_cell(); bool set_cell();
static void substract_sync(cf_t *buffer, uint32_t nof_prb, srslte_sync_t *sync_obj);
void cell_search_inc(); void cell_search_inc();
void resync_sfn(bool is_connected = false, bool rx_now = false); void resync_sfn(bool is_connected = false, bool rx_now = false);
bool stop_sync(); bool stop_sync();
@ -202,7 +200,7 @@ private:
float rsrq; float rsrq;
uint32_t offset; uint32_t offset;
} cell_info_t; } cell_info_t;
void init(srslte::log *log_h); void init(srslte::log *log_h, bool sic_pss_enabled);
void reset(); void reset();
int find_cells(cf_t *input_buffer, float rx_gain_offset, srslte_cell_t current_cell, uint32_t nof_sf, cell_info_t found_cells[MAX_CELLS]); int find_cells(cf_t *input_buffer, float rx_gain_offset, srslte_cell_t current_cell, uint32_t nof_sf, cell_info_t found_cells[MAX_CELLS]);
private: private:
@ -214,6 +212,7 @@ private:
srslte::log *log_h; srslte::log *log_h;
srslte_sync_t sync_find; srslte_sync_t sync_find;
bool sic_pss_enabled;
uint32_t current_fft_sz; uint32_t current_fft_sz;
measure measure_p; measure measure_p;
}; };

@ -394,16 +394,14 @@ void ra_proc::step_response_reception() {
void ra_proc::step_response_error() void ra_proc::step_response_error()
{ {
if (ra_is_ho) {
state = RA_PROBLEM;
rrc->ho_ra_completed(false);
return;
}
preambleTransmissionCounter++; preambleTransmissionCounter++;
if (preambleTransmissionCounter >= preambleTransMax + 1) { if (preambleTransmissionCounter >= preambleTransMax + 1) {
rError("Maximum number of transmissions reached (%d)\n", preambleTransMax); rError("Maximum number of transmissions reached (%d)\n", preambleTransMax);
rrc->ra_problem(); rrc->ra_problem();
state = RA_PROBLEM; state = RA_PROBLEM;
if (ra_is_ho) {
rrc->ho_ra_completed(false);
}
} else { } else {
backoff_interval_start = phy_h->get_current_tti(); backoff_interval_start = phy_h->get_current_tti();
if (backoff_param_ms) { if (backoff_param_ms) {

@ -233,11 +233,14 @@ void parse_args(all_args_t *args, int argc, char *argv[]) {
bpo::value<float>(&args->expert.phy.cfo_loop_ref_min)->default_value(0), bpo::value<float>(&args->expert.phy.cfo_loop_ref_min)->default_value(0),
"Tolerance (in Hz) of the RS estimation method. Below this value, RS estimation does not feeds back the loop") "Tolerance (in Hz) of the RS estimation method. Below this value, RS estimation does not feeds back the loop")
("expert.cfo_loop_pss_conv", ("expert.cfo_loop_pss_conv",
bpo::value<uint32_t>(&args->expert.phy.cfo_loop_pss_conv)->default_value(20), bpo::value<uint32_t>(&args->expert.phy.cfo_loop_pss_conv)->default_value(20),
"After the PSS estimation is below cfo_loop_pss_tol for cfo_loop_pss_timeout times consecutively, RS adjustments are allowed.") "After the PSS estimation is below cfo_loop_pss_tol for cfo_loop_pss_timeout times consecutively, RS adjustments are allowed.")
("expert.sic_pss_enabled",
bpo::value<bool>(&args->expert.phy.sic_pss_enabled)->default_value(true),
"Applies Successive Interference Cancellation to PSS signals when searching for neighbour cells. Must be disabled if cells have identical channel and timing.")
("expert.average_subframe_enabled", ("expert.average_subframe_enabled",
bpo::value<bool>(&args->expert.phy.average_subframe_enabled)->default_value(false), bpo::value<bool>(&args->expert.phy.average_subframe_enabled)->default_value(false),
"Averages in the time domain the channel estimates within 1 subframe. Needs accurate CFO correction.") "Averages in the time domain the channel estimates within 1 subframe. Needs accurate CFO correction.")

@ -197,6 +197,8 @@ void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q)
worker_com->args->cfo_loop_pss_tol, worker_com->args->cfo_loop_pss_tol,
worker_com->args->cfo_loop_pss_conv); worker_com->args->cfo_loop_pss_conv);
q->strack.pss.chest_on_filter = true;
int time_correct_period = worker_com->args->time_correct_period; int time_correct_period = worker_com->args->time_correct_period;
if (time_correct_period > 0) { if (time_correct_period > 0) {
srslte_ue_sync_set_sample_offset_correct_period(q, time_correct_period); srslte_ue_sync_set_sample_offset_correct_period(q, time_correct_period);
@ -629,7 +631,7 @@ void phch_recv::run_thread()
worker = (phch_worker *) workers_pool->wait_worker(tti); worker = (phch_worker *) workers_pool->wait_worker(tti);
if (worker) { if (worker) {
for (uint32_t i = 0; i < nof_rx_antennas; i++) { for (uint32_t i = 0; i < SRSLTE_MAX_PORTS; i++) {
buffer[i] = worker->get_buffer(i); buffer[i] = worker->get_buffer(i);
} }
@ -669,12 +671,12 @@ void phch_recv::run_thread()
worker_com->p0_preamble = prach_buffer->get_p0_preamble(); worker_com->p0_preamble = prach_buffer->get_p0_preamble();
worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble); worker_com->cur_radio_power = SRSLTE_MIN(SRSLTE_PC_MAX, worker_com->pathloss+worker_com->p0_preamble);
} }
workers_pool->start_worker(worker); workers_pool->start_worker(worker);
// Substract PSS/SSS from current cell before computing intra-frequency if ((tti%5) == 0 && worker_com->args->sic_pss_enabled) {
/*if ((tti%5) == 0) { srslte_pss_sic(&ue_sync.strack.pss, &buffer[0][SRSLTE_SF_LEN_PRB(cell.nof_prb)/2-ue_sync.strack.fft_size]);
substract_sync(buffer[0], cell.nof_prb, &ue_sync.strack); }
}*/
intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb)); intra_freq_meas.write(tti, buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb));
out_of_sync_cnt = 0; out_of_sync_cnt = 0;
break; break;
@ -726,24 +728,6 @@ void phch_recv::out_of_sync() {
} }
} }
void phch_recv::substract_sync(cf_t *buffer, uint32_t nof_prb, srslte_sync_t *sync_obj)
{
uint32_t hf_len = SRSLTE_SF_LEN_PRB(nof_prb)/2;
uint32_t fft_sz = srslte_symbol_sz(nof_prb);
srslte_vec_sc_prod_cfc(sync_obj->pss_filt, 1.0/sqrtf(fft_sz), sync_obj->pss_filt, fft_sz);
srslte_vec_sc_prod_cfc(sync_obj->sss_filt, 1.0/sqrtf(fft_sz), sync_obj->sss_filt, fft_sz);
srslte_vec_sub_ccc(&buffer[hf_len-fft_sz],
sync_obj->pss_filt,
&buffer[hf_len-fft_sz],
fft_sz);
srslte_vec_sub_ccc(&buffer[hf_len-2*fft_sz-SRSLTE_CP_LEN(fft_sz, SRSLTE_CP_NORM_LEN)],
sync_obj->sss_filt,
&buffer[hf_len-2*fft_sz-SRSLTE_CP_LEN(fft_sz, SRSLTE_CP_NORM_LEN)],
fft_sz);
}
@ -1194,9 +1178,10 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx)
* Secondary cell receiver * Secondary cell receiver
*/ */
void phch_recv::scell_recv::init(srslte::log *log_h) void phch_recv::scell_recv::init(srslte::log *log_h, bool sic_pss_enabled)
{ {
this->log_h = log_h; this->log_h = log_h;
this->sic_pss_enabled = sic_pss_enabled;
// and a separate ue_sync instance // and a separate ue_sync instance
@ -1213,16 +1198,18 @@ void phch_recv::scell_recv::init(srslte::log *log_h)
return; return;
} }
srslte_sync_cp_en(&sync_find, false); srslte_sync_cp_en(&sync_find, false);
srslte_sync_set_threshold(&sync_find, 1.3); srslte_sync_set_threshold(&sync_find, 1.2);
srslte_sync_set_em_alpha(&sync_find, 0.0); srslte_sync_set_em_alpha(&sync_find, 0.0);
// Configure FIND object behaviour (this configuration is always the same) // Configure FIND object behaviour (this configuration is always the same)
srslte_sync_set_cfo_ema_alpha(&sync_find, 0.5); srslte_sync_set_cfo_ema_alpha(&sync_find, 1.0);
srslte_sync_set_cfo_i_enable(&sync_find, false); srslte_sync_set_cfo_i_enable(&sync_find, false);
srslte_sync_set_cfo_cp_enable(&sync_find, false); srslte_sync_set_cfo_cp_enable(&sync_find, false);
srslte_sync_set_cfo_pss_enable(&sync_find, true); srslte_sync_set_cfo_pss_enable(&sync_find, true);
srslte_sync_set_pss_filt_enable(&sync_find, true); srslte_sync_set_pss_filt_enable(&sync_find, true);
srslte_sync_set_sss_filt_enable(&sync_find, true); srslte_sync_set_sss_eq_enable(&sync_find, true);
sync_find.pss.chest_on_filter = true;
reset(); reset();
} }
@ -1259,11 +1246,12 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
for (uint32_t n_id_2=0;n_id_2<3;n_id_2++) { for (uint32_t n_id_2=0;n_id_2<3;n_id_2++) {
if (n_id_2 != (cell.id%3) || sic_pss_enabled) {
srslte_sync_set_N_id_2(&sync_find, n_id_2); srslte_sync_set_N_id_2(&sync_find, n_id_2);
srslte_sync_find_ret_t sync_res; srslte_sync_find_ret_t sync_res;
//do {
do {
srslte_sync_reset(&sync_find); srslte_sync_reset(&sync_find);
srslte_sync_cfo_reset(&sync_find); srslte_sync_cfo_reset(&sync_find);
@ -1289,26 +1277,27 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
measure_p.set_cell(found_cell); measure_p.set_cell(found_cell);
// Correct CFO // Correct CFO
/*
srslte_cfo_correct(&sync_find.cfo_corr_frame, srslte_cfo_correct(&sync_find.cfo_corr_frame,
input_buffer, input_buffer,
input_cfo_corrected, input_cfo_corrected,
-srslte_sync_get_cfo(&sync_find)/sync_find.fft_size); -srslte_sync_get_cfo(&sync_find)/sync_find.fft_size);
*/
switch(measure_p.run_multiple_subframes(input_buffer, peak_idx, sf_idx, nof_sf)) {
switch(measure_p.run_multiple_subframes(input_cfo_corrected, peak_idx, sf_idx, nof_sf)) {
case measure::MEASURE_OK: case measure::MEASURE_OK:
cells[nof_cells].pci = found_cell.id; cells[nof_cells].pci = found_cell.id;
cells[nof_cells].rsrp = measure_p.rsrp(); cells[nof_cells].rsrp = measure_p.rsrp();
cells[nof_cells].rsrq = measure_p.rsrq(); cells[nof_cells].rsrq = measure_p.rsrq();
cells[nof_cells].offset = measure_p.frame_st_idx(); cells[nof_cells].offset = measure_p.frame_st_idx();
nof_cells++;
// Substract interference from input buffer (for the next cell) Info("INTRA: Found neighbour cell %d: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f n_id_2=%d, CFO=%6.1f Hz\n",
//substract_sync(&input_buffer[measure_p.frame_st_idx()], cell.nof_prb, &sync_find); nof_cells, cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, n_id_2, 15000*srslte_sync_get_cfo(&sync_find));
Info("INTRA: Found neighbour cell: PCI=%03d, RSRP=%5.1f dBm, peak_idx=%5d, peak_value=%3.2f n_id_2=%d, CFO=%6.1f Hz\n", nof_cells++;
cell_id, measure_p.rsrp(), measure_p.frame_st_idx(), sync_find.peak_value, n_id_2, 15000*srslte_sync_get_cfo(&sync_find));
if (sic_pss_enabled) {
srslte_pss_sic(&sync_find.pss, &input_buffer[sf_len/2-fft_sz]);
}
break; break;
case measure::ERROR: case measure::ERROR:
@ -1328,7 +1317,8 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset,
default: default:
break; break;
} }
//} while(sync_res == SRSLTE_SYNC_FOUND); } while (sync_res == SRSLTE_SYNC_FOUND && sic_pss_enabled);
}
} }
return nof_cells; return nof_cells;
} }
@ -1380,7 +1370,7 @@ void phch_recv::intra_measure::init(phch_common *common, rrc_interface_phy *rrc,
receive_enabled = false; receive_enabled = false;
// Start scell // Start scell
scell.init(log_h); scell.init(log_h, common->args->sic_pss_enabled);
search_buffer = (cf_t*) srslte_vec_malloc(CAPTURE_LEN_SF*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB)*sizeof(cf_t)); search_buffer = (cf_t*) srslte_vec_malloc(CAPTURE_LEN_SF*SRSLTE_SF_LEN_PRB(SRSLTE_MAX_PRB)*sizeof(cf_t));

@ -1087,7 +1087,9 @@ void rrc::ho_ra_completed(bool ra_successful) {
rrc_log->console("HO %ssuccessful\n", ra_successful?"":"un"); rrc_log->console("HO %ssuccessful\n", ra_successful?"":"un");
pending_mob_reconf = false; pending_mob_reconf = false;
if (ra_successful) {
state = RRC_STATE_CONNECTED; state = RRC_STATE_CONNECTED;
}
} else { } else {
rrc_log->error("Received HO random access completed but no pending mobility reconfiguration info\n"); rrc_log->error("Received HO random access completed but no pending mobility reconfiguration info\n");
} }

@ -154,6 +154,10 @@ enable = false
# average_subframe_enabled: Averages in the time domain the channel estimates within 1 subframe. # average_subframe_enabled: Averages in the time domain the channel estimates within 1 subframe.
# Needs accurate CFO correction. # Needs accurate CFO correction.
# #
# sic_pss_enabled: Applies Successive Interference Cancellation to PSS signals when searching for neighbour cells.
# Must be disabled if cells have identical channel and timing, for instance if generated from
# the same source.
#
# metrics_csv_enable: Write UE metrics to CSV file. # metrics_csv_enable: Write UE metrics to CSV file.
# #
# metrics_csv_filename: File path to use for CSV metrics. # metrics_csv_filename: File path to use for CSV metrics.
@ -191,6 +195,7 @@ enable = false
#sss_algorithm = full #sss_algorithm = full
#estimator_fil_w = 0.1 #estimator_fil_w = 0.1
#average_subframe_enabled = false #average_subframe_enabled = false
#sic_pss_enabled = true
#pregenerate_signals = false #pregenerate_signals = false
#metrics_csv_enable = false #metrics_csv_enable = false
#metrics_csv_filename = /tmp/ue_metrics.csv #metrics_csv_filename = /tmp/ue_metrics.csv

Loading…
Cancel
Save