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 (plot_track) {
srslte_pss_synch_t *pss_obj = srslte_sync_get_cur_pss_obj(&ue_sync.strack);
srslte_pss_t *pss_obj = srslte_sync_get_cur_pss_obj(&ue_sync.strack);
int max = srslte_vec_max_fi(pss_obj->conv_output_avg, pss_obj->frame_size+pss_obj->fft_size-1);
srslte_vec_sc_prod_fff(pss_obj->conv_output_avg,
1/pss_obj->conv_output_avg[max],

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -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),
"Tolerance (in Hz) of the RS estimation method. Below this value, RS estimation does not feeds back the loop")
("expert.cfo_loop_pss_conv",
bpo::value<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.")
("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",
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.")

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

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

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

Loading…
Cancel
Save