From 1f6e63ae4fdf96ce153eedc61b5d37199aac8e08 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 4 Oct 2016 19:11:04 +0200 Subject: [PATCH] cfo: srslte_sync_get_cfo() returns PSS-based CFO estimation. Gives better results than CP-based --- srslte/examples/pdsch_ue.c | 6 ------ srslte/include/srslte/sync/sync.h | 2 ++ srslte/lib/rf/rf_blade_imp.c | 7 +++++++ srslte/lib/sync/sync.c | 35 +++++++++++++++++++++++-------- srslte/lib/ue/ue_dl.c | 7 +++++++ srslte/lib/ue/ue_sync.c | 10 ++++----- 6 files changed, 46 insertions(+), 21 deletions(-) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index 15254697d..a9f48b941 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -511,12 +511,6 @@ int main(int argc, char **argv) { if (n < 0) { // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); } else if (n > 0) { - - /* - printf("Saving signal...\n"); - srslte_ue_dl_save_signal(&ue_dl, &ue_dl.softbuffer, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), rv, prog_args.rnti); - exit(-1); - */ /* Send data if socket active */ if (prog_args.net_port > 0) { diff --git a/srslte/include/srslte/sync/sync.h b/srslte/include/srslte/sync/sync.h index de13244df..b5eccbb88 100644 --- a/srslte/include/srslte/sync/sync.h +++ b/srslte/include/srslte/sync/sync.h @@ -76,6 +76,7 @@ typedef struct SRSLTE_API { uint32_t max_offset; bool enable_cfo_corr; float mean_cfo; + float mean_cfo2; int cfo_i; bool find_cfo_i; bool find_cfo_i_initiated; @@ -93,6 +94,7 @@ typedef struct SRSLTE_API { float m1_value; float M_norm_avg; float M_ext_avg; + cf_t *temp; }srslte_sync_t; diff --git a/srslte/lib/rf/rf_blade_imp.c b/srslte/lib/rf/rf_blade_imp.c index 031ef6fe9..fbe9b3fc6 100644 --- a/srslte/lib/rf/rf_blade_imp.c +++ b/srslte/lib/rf/rf_blade_imp.c @@ -341,6 +341,10 @@ double rf_blade_set_rx_freq(void *h, double freq) (uint32_t) freq, bladerf_strerror(status)); return -1; } + f_int=0; + bladerf_get_frequency(handler->dev, BLADERF_MODULE_RX, &f_int); + printf("set RX frequency to %u\n", f_int); + return freq; } @@ -355,6 +359,9 @@ double rf_blade_set_tx_freq(void *h, double freq) return -1; } + f_int=0; + bladerf_get_frequency(handler->dev, BLADERF_MODULE_TX, &f_int); + printf("set TX frequency to %u\n", f_int); return freq; } diff --git a/srslte/lib/sync/sync.c b/srslte/lib/sync/sync.c index df44ed77b..12bde29f1 100644 --- a/srslte/lib/sync/sync.c +++ b/srslte/lib/sync/sync.c @@ -61,6 +61,7 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, q->detect_cp = true; q->sss_en = true; q->mean_cfo = 0; + q->mean_cfo2 = 0; q->N_id_2 = 1000; q->N_id_1 = 1000; q->cfo_i = 0; @@ -78,8 +79,8 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, goto clean_exit; } - // Set a CFO tolerance of approx 100 Hz - srslte_cfo_set_tol(&q->cfocorr, 100.0/(15000.0*q->fft_size)); + // Set a CFO tolerance of approx 50 Hz + srslte_cfo_set_tol(&q->cfocorr, 50.0/(15000.0*q->fft_size)); for (int i=0;i<2;i++) { q->cfo_i_corr[i] = srslte_vec_malloc(sizeof(cf_t)*q->frame_size); @@ -89,6 +90,12 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, } } + q->temp = srslte_vec_malloc(sizeof(cf_t)*2*q->frame_size); + if (!q->temp) { + perror("malloc"); + goto clean_exit; + } + srslte_sync_set_cp(q, SRSLTE_CP_NORM); if (srslte_pss_synch_init_fft(&q->pss, max_offset, fft_size)) { @@ -131,6 +138,9 @@ void srslte_sync_free(srslte_sync_t *q) { } srslte_pss_synch_free(&q->pss_i[i]); } + if (q->temp) { + free(q->temp); + } } } @@ -185,7 +195,7 @@ uint32_t srslte_sync_get_sf_idx(srslte_sync_t *q) { } float srslte_sync_get_cfo(srslte_sync_t *q) { - return q->mean_cfo + q->cfo_i; + return q->mean_cfo2 + q->cfo_i; } void srslte_sync_set_cfo(srslte_sync_t *q, float cfo) { @@ -413,6 +423,8 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t if (peak_position) { *peak_position = 0; } + + cf_t *input_cfo = input; if (q->enable_cfo_corr) { float cfo = cfo_estimate(q, input); @@ -421,19 +433,21 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t q->mean_cfo = SRSLTE_VEC_EMA(cfo, q->mean_cfo, q->cfo_ema_alpha); /* Correct CFO with the averaged CFO estimation */ - srslte_cfo_correct(&q->cfocorr, input, input, -q->mean_cfo / q->fft_size); + srslte_cfo_correct(&q->cfocorr, input, q->temp, -q->mean_cfo / q->fft_size); + + input_cfo = q->temp; } /* If integer CFO is enabled, find max PSS correlation for shifted +1/0/-1 integer versions */ if (q->find_cfo_i && q->enable_cfo_corr) { - q->cfo_i = cfo_i_estimate(q, input, find_offset, &peak_pos); + q->cfo_i = cfo_i_estimate(q, input_cfo, find_offset, &peak_pos); if (q->cfo_i != 0) { - srslte_vec_prod_ccc(input, q->cfo_i_corr[q->cfo_i<0?0:1], input, q->frame_size); + srslte_vec_prod_ccc(input_cfo, q->cfo_i_corr[q->cfo_i<0?0:1], input_cfo, q->frame_size); INFO("Compensating cfo_i=%d\n", q->cfo_i); } } else { srslte_pss_synch_set_N_id_2(&q->pss, q->N_id_2); - peak_pos = srslte_pss_synch_find_pss(&q->pss, &input[find_offset], &q->peak_value); + peak_pos = srslte_pss_synch_find_pss(&q->pss, &input_cfo[find_offset], &q->peak_value); if (peak_pos < 0) { fprintf(stderr, "Error calling finding PSS sequence\n"); return SRSLTE_ERROR; @@ -449,7 +463,7 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t // Set an invalid N_id_1 indicating SSS is yet to be detected q->N_id_1 = 1000; - if (sync_sss(q, input, find_offset + peak_pos, q->cp) < 0) { + if (sync_sss(q, input_cfo, find_offset + peak_pos, q->cp) < 0) { DEBUG("No space for SSS processing. Frame starts at %d\n", peak_pos); } } @@ -459,13 +473,16 @@ srslte_sync_find_ret_t srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t if (q->detect_cp) { if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) { - srslte_sync_set_cp(q, srslte_sync_detect_cp(q, input, peak_pos + find_offset)); + srslte_sync_set_cp(q, srslte_sync_detect_cp(q, input_cfo, peak_pos + find_offset)); } else { DEBUG("Not enough room to detect CP length. Peak position: %d\n", peak_pos); } } if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) { + float cfo2 = srslte_pss_synch_cfo_compute(&q->pss, &input[find_offset + peak_pos - q->fft_size]); + q->mean_cfo2 = SRSLTE_VEC_EMA(cfo2, q->mean_cfo2, q->cfo_ema_alpha); + ret = SRSLTE_SYNC_FOUND; } else { ret = SRSLTE_SYNC_FOUND_NOSPACE; diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index a26242da9..11014b963 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -302,6 +302,13 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint fprintf(stderr, "Error calling srslte_pdsch_decode()\n"); } } + + printf("Saving signal...\n"); + srslte_vec_save_file("input", input, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); + srslte_ue_dl_save_signal(q, &q->softbuffer, sf_idx, rvidx, rnti, cfi); + //exit(-1); + + } q->pkts_total++; diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index aef15e342..603eb9e15 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -605,14 +605,12 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { } q->frame_total_cnt++; - } else { - if (q->correct_cfo) { - srslte_cfo_correct(&q->sfind.cfocorr, + } + if (q->correct_cfo) { + srslte_cfo_correct(&q->sfind.cfocorr, input_buffer, input_buffer, - -srslte_sync_get_cfo(&q->strack) / q->fft_size); - - } + -srslte_sync_get_cfo(&q->strack) / q->fft_size); } break; }