From 5a032c4316308fcd30c3079c98afd6e620357623 Mon Sep 17 00:00:00 2001 From: ismagom Date: Thu, 11 Dec 2014 09:06:58 +0000 Subject: [PATCH] Using short correlation for peak tracking --- lte/examples/cell_measurement.c | 29 ++++++----- lte/examples/pdsch_ue.c | 43 +++++++++------- lte/phy/include/liblte/phy/sync/pss.h | 2 - lte/phy/include/liblte/phy/utils/vector.h | 1 + lte/phy/lib/ch_estimation/src/chest_dl.c | 1 + lte/phy/lib/sync/src/pss.c | 60 ++++++++++++++++------- lte/phy/lib/sync/src/sync.c | 1 - lte/phy/lib/sync/test/pss_usrp.c | 14 ++++-- lte/phy/lib/ue/src/ue_celldetect.c | 1 + lte/phy/lib/ue/src/ue_sync.c | 7 +-- lte/phy/lib/utils/src/convolution.c | 18 ++++--- 11 files changed, 113 insertions(+), 64 deletions(-) diff --git a/lte/examples/cell_measurement.c b/lte/examples/cell_measurement.c index 1e6b2e212..40f905375 100644 --- a/lte/examples/cell_measurement.c +++ b/lte/examples/cell_measurement.c @@ -48,7 +48,7 @@ float gain_offset = B210_DEFAULT_GAIN_CORREC; cell_detect_cfg_t cell_detect_config = { 100, // nof_frames_total - 3.0 // early-stops cell detection if mean PSR is above this value + 6.0 // early-stops cell detection if mean PSR is above this value }; /********************************************************************** @@ -149,16 +149,11 @@ int main(int argc, char **argv) { uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN]; uint32_t sfn_offset; float rssi_utra=0,rssi=0, rsrp=0, rsrq=0, snr=0; - cf_t *nullce[MAX_PORTS]; uint32_t si_window_length; scheduling_info_t sinfo[MAX_SINFO]; scheduling_info_t *sinfo_sib4 = NULL; uint32_t neighbour_cell_ids[MAX_NEIGHBOUR_CELLS]; - - - for (int i=0;icell.nof_prb, q->cell.cp); uint32_t nof_symbols = q->harq_process[0].prb_alloc.re_sf[sf_idx]; @@ -386,7 +392,10 @@ void do_plots(ue_dl_t *q, uint32_t sf_idx) { } plot_real_setNewData(&poutfft, tmp_plot, nof_re); plot_real_setNewData(&pce, tmp_plot2, REFSIGNAL_NUM_SF(q->cell.nof_prb,0)); - plot_scatter_setNewData(&pscatrecv, q->pdsch.pdsch_symbols[0], nof_symbols); + int max = vec_max_fi(qs->strack.pss.conv_output_avg, qs->strack.pss.frame_size+qs->strack.pss.fft_size-1); + vec_sc_prod_fff(qs->strack.pss.conv_output_avg, 1/qs->strack.pss.conv_output_avg[max], tmp_plot2, qs->strack.pss.frame_size+qs->strack.pss.fft_size-1); + plot_real_setNewData(&p_sync, tmp_plot2, qs->strack.pss.frame_size); + plot_scatter_setNewData(&pscatequal, q->pdsch.pdsch_d, nof_symbols); plot_scatter_setNewData(&pscatequal_pdcch, q->pdcch.pdcch_d, 36*q->pdcch.nof_cce); } diff --git a/lte/phy/include/liblte/phy/sync/pss.h b/lte/phy/include/liblte/phy/sync/pss.h index 1ff0fee5f..9f5b435cf 100644 --- a/lte/phy/include/liblte/phy/sync/pss.h +++ b/lte/phy/include/liblte/phy/sync/pss.h @@ -39,8 +39,6 @@ typedef _Complex float cf_t; /* this is only a shortcut */ #define CONVOLUTION_FFT -#define DEFAULT_CORRELATION_TH 10000 -#define DEFAULT_NOSYNC_TIMEOUT 5 #define PSS_LEN 62 #define PSS_RE 6*12 diff --git a/lte/phy/include/liblte/phy/utils/vector.h b/lte/phy/include/liblte/phy/utils/vector.h index 8ba871f8c..186329b4b 100644 --- a/lte/phy/include/liblte/phy/utils/vector.h +++ b/lte/phy/include/liblte/phy/utils/vector.h @@ -37,6 +37,7 @@ typedef _Complex float cf_t; #define MAX(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) // Cumulative moving average #define VEC_CMA(data, average, n) ((average) + ((data) - (average)) / ((n)+1)) diff --git a/lte/phy/lib/ch_estimation/src/chest_dl.c b/lte/phy/lib/ch_estimation/src/chest_dl.c index 8a4c5a79e..5a9c2e5b7 100644 --- a/lte/phy/lib/ch_estimation/src/chest_dl.c +++ b/lte/phy/lib/ch_estimation/src/chest_dl.c @@ -373,6 +373,7 @@ float chest_dl_get_rssi(chest_dl_t *q) { */ float chest_dl_get_rsrq(chest_dl_t *q) { return q->cell.nof_prb*q->rsrp[0] / q->rssi[0]; + } float chest_dl_get_rsrp(chest_dl_t *q) { diff --git a/lte/phy/lib/sync/src/pss.c b/lte/phy/lib/sync/src/pss.c index ff8e1d288..b183e24b2 100644 --- a/lte/phy/lib/sync/src/pss.c +++ b/lte/phy/lib/sync/src/pss.c @@ -290,20 +290,27 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value) memcpy(q->tmp_input, input, q->frame_size * sizeof(cf_t)); /* Correlate input with PSS sequence */ - #ifdef CONVOLUTION_FFT - conv_output_len = conv_fft_cc_run(&q->conv_fft, q->tmp_input, - q->pss_signal_freq[q->N_id_2], q->conv_output); - #else - conv_output_len = conv_cc(input, q->pss_signal_freq[q->N_id_2], q->conv_output, q->frame_size, q->fft_size); - #endif + if (q->frame_size >= q->fft_size) { + #ifdef CONVOLUTION_FFT + conv_output_len = conv_fft_cc_run(&q->conv_fft, q->tmp_input, + q->pss_signal_freq[q->N_id_2], q->conv_output); + #else + conv_output_len = conv_cc(input, q->pss_signal_freq[q->N_id_2], q->conv_output, q->frame_size, q->fft_size); + #endif + } else { + for (int i=0;iframe_size;i++) { + q->conv_output[i] = vec_dot_prod_ccc(q->pss_signal_freq[q->N_id_2], &input[i], q->fft_size); + } + conv_output_len = q->frame_size; + } -#ifdef PSS_ABS_SQUARE - vec_abs_square_cf(q->conv_output, q->conv_output_abs, conv_output_len-1); -#else - vec_abs_cf(q->conv_output, q->conv_output_abs, conv_output_len-1); -#endif - + #ifdef PSS_ABS_SQUARE + vec_abs_square_cf(q->conv_output, q->conv_output_abs, conv_output_len-1); + #else + vec_abs_cf(q->conv_output, q->conv_output_abs, conv_output_len-1); + #endif + vec_sc_prod_fff(q->conv_output_abs, q->ema_alpha, q->conv_output_abs, conv_output_len-1); vec_sc_prod_fff(q->conv_output_avg, 1-q->ema_alpha, q->conv_output_avg, conv_output_len-1); @@ -321,16 +328,35 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value) pl_ub ++; } // Find end of peak lobe to the left - int pl_lb = corr_peak_pos-1; - while(q->conv_output_avg[pl_lb-1] <= q->conv_output_avg[pl_lb] && pl_lb > 1) { - pl_lb --; + int pl_lb; + if (corr_peak_pos > 0) { + pl_lb = corr_peak_pos-1; + while(q->conv_output_avg[pl_lb-1] <= q->conv_output_avg[pl_lb] && pl_lb > 1) { + pl_lb --; + } + } else { + pl_lb = 0; } + + int sl_distance_right = conv_output_len-1-pl_ub; + if (sl_distance_right < 0) { + sl_distance_right = 0; + } + int sl_distance_left = pl_lb; - int sl_right = pl_ub+vec_max_fi(&q->conv_output_avg[pl_ub], conv_output_len-1 - pl_ub); - int sl_left = vec_max_fi(q->conv_output_avg, pl_lb); + int sl_right = pl_ub+vec_max_fi(&q->conv_output_avg[pl_ub], sl_distance_right); + int sl_left = vec_max_fi(q->conv_output_avg, sl_distance_left); float side_lobe_value = MAX(q->conv_output_avg[sl_right], q->conv_output_avg[sl_left]); if (corr_peak_value) { *corr_peak_value = q->conv_output_avg[corr_peak_pos]/side_lobe_value; + + if (*corr_peak_value < 2.0) { + INFO("pl_ub=%d, pl_lb=%d, sl_right: %d (%.2f), sl_left: %d (%.2f), PSR: %.2f/%.2f=%.2f\n", pl_ub, pl_lb, + sl_right, 1000000*q->conv_output_avg[sl_right], + sl_left, 1000000*q->conv_output_avg[sl_left], + 1000000*q->conv_output_avg[corr_peak_pos], 1000000*side_lobe_value,*corr_peak_value + ); + } } #else if (corr_peak_value) { diff --git a/lte/phy/lib/sync/src/sync.c b/lte/phy/lib/sync/src/sync.c index a9ea8bde1..5048c8f4f 100644 --- a/lte/phy/lib/sync/src/sync.c +++ b/lte/phy/lib/sync/src/sync.c @@ -52,7 +52,6 @@ int sync_init(sync_t *q, uint32_t frame_size, uint32_t fft_size) { int ret = LIBLTE_ERROR_INVALID_INPUTS; if (q != NULL && - frame_size >= fft_size && frame_size <= 307200 && fft_size_isvalid(fft_size)) { diff --git a/lte/phy/lib/sync/test/pss_usrp.c b/lte/phy/lib/sync/test/pss_usrp.c index a2cade849..ea87d887c 100644 --- a/lte/phy/lib/sync/test/pss_usrp.c +++ b/lte/phy/lib/sync/test/pss_usrp.c @@ -53,14 +53,16 @@ float uhd_gain=40.0, uhd_freq=-1.0; int nof_frames = -1; uint32_t fft_size=64; float threshold = 0.4; -int N_id_2_sync = -1; +int N_id_2_sync = -1; +lte_cp_t cp=CPNORM; void usage(char *prog) { - printf("Usage: %s [adgtvnp] -f rx_frequency_hz -i cell_id\n", prog); + printf("Usage: %s [aedgtvnp] -f rx_frequency_hz -i cell_id\n", prog); printf("\t-a UHD args [Default %s]\n", uhd_args); printf("\t-g UHD Gain [Default %.2f dB]\n", uhd_gain); printf("\t-n nof_frames [Default %d]\n", nof_frames); printf("\t-l N_id_2 to sync [Default use cell_id]\n"); + printf("\t-e Extended CP [Default Normal]\n", fft_size); printf("\t-s symbol_sz [Default %d]\n", fft_size); printf("\t-t threshold [Default %.2f]\n", threshold); #ifndef DISABLE_GRAPHICS @@ -73,7 +75,7 @@ void usage(char *prog) { void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "adgtvsfil")) != -1) { + while ((opt = getopt(argc, argv, "adgetvsfil")) != -1) { switch (opt) { case 'a': uhd_args = argv[optind]; @@ -87,6 +89,9 @@ void parse_args(int argc, char **argv) { case 't': threshold = atof(argv[optind]); break; + case 'e': + cp = CPEXT; + break; case 'i': cell_id = atoi(argv[optind]); break; @@ -154,6 +159,7 @@ int main(int argc, char **argv) { fprintf(stderr, "Error initiating PSS\n"); exit(-1); } + if (pss_synch_set_N_id_2(&pss, N_id_2_sync)) { fprintf(stderr, "Error setting N_id_2=%d\n",N_id_2_sync); exit(-1); @@ -233,7 +239,7 @@ int main(int argc, char **argv) { } // Find SSS - int sss_idx = peak_idx-2*fft_size-CP(fft_size, CPNORM_LEN); + int sss_idx = peak_idx-2*fft_size-(CP_ISNORM(cp)?CP(fft_size, CPNORM_LEN):CP(fft_size, CPEXT_LEN)); if (sss_idx >= 0 && sss_idx < flen-fft_size) { sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value); if (sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { diff --git a/lte/phy/lib/ue/src/ue_celldetect.c b/lte/phy/lib/ue/src/ue_celldetect.c index 4ed86d6f6..62ae106e7 100644 --- a/lte/phy/lib/ue/src/ue_celldetect.c +++ b/lte/phy/lib/ue/src/ue_celldetect.c @@ -75,6 +75,7 @@ int ue_celldetect_init_max(ue_celldetect_t * q, uint32_t max_frames_total) { sync_set_threshold(&q->sfind, 1.0); sync_sss_en(&q->sfind, true); sync_set_sss_algorithm(&q->sfind, SSS_PARTIAL_3); + sync_set_em_alpha(&q->sfind, 0.01); q->max_frames_total = max_frames_total; q->nof_frames_total = CS_DEFAULT_NOFFRAMES_TOTAL; diff --git a/lte/phy/lib/ue/src/ue_sync.c b/lte/phy/lib/ue/src/ue_sync.c index ab7e196ea..3eb62a419 100644 --- a/lte/phy/lib/ue/src/ue_sync.c +++ b/lte/phy/lib/ue/src/ue_sync.c @@ -49,6 +49,7 @@ cf_t dummy[MAX_TIME_OFFSET]; #define FIND_THRESHOLD 4.0 #define TRACK_THRESHOLD 2.0 #define TRACK_MAX_LOST 10 +#define TRACK_FRAME_SIZE 32 int ue_sync_init(ue_sync_t *q, @@ -76,7 +77,7 @@ int ue_sync_init(ue_sync_t *q, fprintf(stderr, "Error initiating sync find\n"); goto clean_exit; } - if(sync_init(&q->strack, CURRENT_FFTSIZE, CURRENT_FFTSIZE)) { + if(sync_init(&q->strack, TRACK_FRAME_SIZE, CURRENT_FFTSIZE)) { fprintf(stderr, "Error initiating sync track\n"); goto clean_exit; } @@ -190,7 +191,7 @@ int track_peak_ok(ue_sync_t *q, uint32_t track_idx) { q->sf_idx = sync_get_sf_idx(&q->strack); } } else { - q->time_offset = ((int) track_idx - (int) CURRENT_FFTSIZE); + q->time_offset = ((int) track_idx - (int) q->strack.frame_size/2); /* If the PSS peak is beyond the frame (we sample too slowly), discard the offseted samples to align next frame */ @@ -305,7 +306,7 @@ int ue_sync_get_buffer(ue_sync_t *q, cf_t **sf_symbols) { track_idx = 0; /* track pss around the middle of the subframe, where the PSS is */ - ret = sync_find(&q->strack, q->input_buffer, CURRENT_SFLEN/2-CURRENT_FFTSIZE, &track_idx); + ret = sync_find(&q->strack, q->input_buffer, CURRENT_SFLEN/2-CURRENT_FFTSIZE-q->strack.frame_size/2, &track_idx); if (ret < 0) { fprintf(stderr, "Error tracking correlation peak\n"); return LIBLTE_ERROR; diff --git a/lte/phy/lib/utils/src/convolution.c b/lte/phy/lib/utils/src/convolution.c index 2dcac6e5f..6630b7354 100644 --- a/lte/phy/lib/utils/src/convolution.c +++ b/lte/phy/lib/utils/src/convolution.c @@ -91,15 +91,17 @@ uint32_t conv_fft_cc_run(conv_fft_cc_t *q, cf_t *input, cf_t *filter, cf_t *outp } uint32_t conv_cc(cf_t *input, cf_t *filter, cf_t *output, uint32_t input_len, uint32_t filter_len) { - uint32_t i,j; - uint32_t output_len; - output_len=input_len+filter_len-1; - for (i=0;i