From fb6eb4f9d11f4a12629f3cefb984f1d4efb380b8 Mon Sep 17 00:00:00 2001 From: ismagom Date: Tue, 14 Oct 2014 13:56:18 +0100 Subject: [PATCH] Merged with #51 --- lte/examples/CMakeLists.txt | 3 + lte/examples/cell_search.c | 45 ++-- lte/phy/examples/cell_measurement.c | 218 +++++++++++++++ .../include/liblte/phy/common/phy_common.h | 2 +- lte/phy/include/liblte/phy/sync/sync.h | 7 +- lte/phy/include/liblte/phy/ue/ue_mib.h | 5 +- lte/phy/include/liblte/phy/utils/vector.h | 8 +- lte/phy/lib/ch_estimation/test/CMakeLists.txt | 17 -- .../lib/ch_estimation/test/chest_test_dl.c | 253 ------------------ .../lib/ch_estimation/test/chest_test_ul.c | 249 ----------------- lte/phy/lib/phch/src/pdsch.c | 7 +- lte/phy/lib/sync/src/pss.c | 46 +--- lte/phy/lib/sync/src/sync.c | 104 +++---- lte/phy/lib/sync/test/pss_usrp.c | 4 +- lte/phy/lib/ue/src/ue_dl.c | 7 +- lte/phy/lib/ue/src/ue_mib.c | 168 +++++++----- lte/phy/lib/ue/src/ue_sync.c | 50 ++-- lte/rrc/include/liblte/rrc/rrc.h | 29 +- 18 files changed, 441 insertions(+), 781 deletions(-) create mode 100644 lte/phy/examples/cell_measurement.c delete mode 100644 lte/phy/lib/ch_estimation/test/chest_test_dl.c delete mode 100644 lte/phy/lib/ch_estimation/test/chest_test_ul.c diff --git a/lte/examples/CMakeLists.txt b/lte/examples/CMakeLists.txt index 74febba3b..3a799c37a 100644 --- a/lte/examples/CMakeLists.txt +++ b/lte/examples/CMakeLists.txt @@ -86,6 +86,9 @@ IF(${CUHD_FIND} GREATER -1) add_executable(cell_measurement cell_measurement.c cuhd_utils.c) target_link_libraries(cell_measurement cuhd lte_rrc lte_phy) + add_executable(cell_measurement cell_measurement.c cell_search_utils.c) + target_link_libraries(cell_measurement cuhd lte_phy) + MESSAGE(STATUS " UHD examples will be installed.") ELSE(${CUHD_FIND} GREATER -1) diff --git a/lte/examples/cell_search.c b/lte/examples/cell_search.c index 6f1072ac8..1bda450ca 100644 --- a/lte/examples/cell_search.c +++ b/lte/examples/cell_search.c @@ -119,8 +119,8 @@ int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples) { int main(int argc, char **argv) { int n; void *uhd; - ue_cell_search_t cs; - ue_cell_search_result_t found_cells[3]; + ue_celldetect_t s; + ue_celldetect_result_t found_cells[3]; int nof_freqs; lte_earfcn_t channels[MAX_EARFCN]; uint32_t freq; @@ -140,7 +140,22 @@ int main(int argc, char **argv) { exit(-1); } - for (freq=0;freq 0) { + ue_celldetect_set_threshold(&s, threshold); + } + + if (nof_frames_total > 0) { + ue_celldetect_set_nof_frames_total(&s, nof_frames_total); + } + if (nof_frames_detected > 0) { + ue_celldetect_set_nof_frames_detected(&s, nof_frames_detected); + } + + for (freq=0;freq config.threshold/2) { - lte_cell_t cell; - cell.id = found_cells[i].cell_id; - cell.cp = found_cells[i].cp; - int ret = cuhd_mib_decoder(uhd, 100, &cell); - if (ret < 0) { - fprintf(stderr, "Error decoding MIB\n"); + if (found_cells[i].peak > threshold/2) { + if (decode_pbch(uhd, &found_cells[i], nof_frames_total, &mib)) { + fprintf(stderr, "Error decoding PBCH\n"); exit(-1); } if (ret == MIB_FOUND) { diff --git a/lte/phy/examples/cell_measurement.c b/lte/phy/examples/cell_measurement.c new file mode 100644 index 000000000..1e2baf724 --- /dev/null +++ b/lte/phy/examples/cell_measurement.c @@ -0,0 +1,218 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2014 The libLTE Developers. See the + * COPYRIGHT file at the top-level directory of this distribution. + * + * \section LICENSE + * + * This file is part of the libLTE library. + * + * libLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * libLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * A copy of the GNU Lesser General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "liblte/phy/phy.h" +#include "liblte/cuhd/cuhd.h" +#include "cell_search_utils.h" + +/********************************************************************** + * Program arguments processing + ***********************************************************************/ +typedef struct { + int nof_subframes; + bool disable_plots; + int force_N_id_2; + char *uhd_args; + float uhd_freq; + float uhd_gain; +}prog_args_t; + +void args_default(prog_args_t *args) { + args->nof_subframes = -1; + args->force_N_id_2 = -1; // Pick the best + args->uhd_args = ""; + args->uhd_freq = -1.0; + args->uhd_gain = 60.0; +} + +void usage(prog_args_t *args, char *prog) { + printf("Usage: %s [aglnv] -f rx_frequency (in Hz)\n", prog); + printf("\t-a UHD args [Default %s]\n", args->uhd_args); + printf("\t-g UHD RX gain [Default %.2f dB]\n", args->uhd_gain); + printf("\t-l Force N_id_2 [Default best]\n"); + printf("\t-n nof_subframes [Default %d]\n", args->nof_subframes); + printf("\t-v [set verbose to debug, default none]\n"); +} + +void parse_args(prog_args_t *args, int argc, char **argv) { + int opt; + args_default(args); + while ((opt = getopt(argc, argv, "aglnvf")) != -1) { + switch (opt) { + case 'a': + args->uhd_args = argv[optind]; + break; + case 'g': + args->uhd_gain = atof(argv[optind]); + break; + case 'f': + args->uhd_freq = atof(argv[optind]); + break; + case 'n': + args->nof_subframes = atoi(argv[optind]); + break; + case 'l': + args->force_N_id_2 = atoi(argv[optind]); + break; + case 'v': + verbose++; + break; + default: + usage(args, argv[0]); + exit(-1); + } + } + if (args->uhd_freq < 0) { + usage(args, argv[0]); + exit(-1); + } +} +/**********************************************************************/ + +/* TODO: Do something with the output data */ +char data[10000]; + +int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples) { + DEBUG(" ---- Receive %d samples ---- \n", nsamples); + return cuhd_recv(h, data, nsamples, 1); +} + + +int main(int argc, char **argv) { + int ret; + cf_t *sf_buffer; + prog_args_t prog_args; + lte_cell_t cell; + int64_t sf_cnt; + pbch_mib_t mib; + ue_sync_t ue_sync; + void *uhd; + + parse_args(&prog_args, argc, argv); + + printf("Opening UHD device...\n"); + if (cuhd_open(prog_args.uhd_args, &uhd)) { + fprintf(stderr, "Error opening uhd\n"); + exit(-1); + } + /* Set receiver gain */ + cuhd_set_rx_gain(uhd, prog_args.uhd_gain); + + /* set receiver frequency */ + cuhd_set_rx_freq(uhd, (double) prog_args.uhd_freq); + cuhd_rx_wait_lo_locked(uhd); + printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000); + + if (cell_search(uhd, prog_args.force_N_id_2, &cell, &mib)) { + fprintf(stderr, "Cell not found\n"); + exit(-1); + } + + cuhd_start_rx_stream(uhd); + + if (ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper, uhd)) { + fprintf(stderr, "Error initiating ue_sync\n"); + exit(-1); + } + + /* Initialize subframe counter */ + sf_cnt = 0; + + lte_fft_t fft; + chest_t chest; + + if (lte_fft_init(&fft, cell.cp, cell.nof_prb)) { + fprintf(stderr, "Error initiating FFT\n"); + return -1; + } + if (chest_init_LTEDL(&chest, cell)) { + fprintf(stderr, "Error initiating channel estimator\n"); + return -1; + } + + int sf_re = SF_LEN_RE(cell.nof_prb, cell.cp); + cf_t *sf_symbols = vec_malloc(sf_re * sizeof(cf_t)); + unsigned int nframes=0; + + /* Main loop */ + while (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) { + + ret = ue_sync_get_buffer(&ue_sync, &sf_buffer); + if (ret < 0) { + fprintf(stderr, "Error calling ue_sync_work()\n"); + } + + float rssi=0, rsrp=0, rsrq=0; + + /* iodev_receive returns 1 if successfully read 1 aligned subframe */ + if (ret == 1) { + + /* Run FFT for all subframe data */ + lte_fft_run_sf(&fft, sf_buffer, sf_symbols); + + chest_measure_sf(&chest, sf_symbols, ue_sync_get_sfidx(&ue_sync)); + rssi = VEC_CMA(chest_rssi_sf(&chest, sf_symbols),rssi,nframes); + rsrq = VEC_CMA(chest_rsrq_sf(&chest, sf_symbols, ue_sync_get_sfidx(&ue_sync)),rsrq,nframes); + rsrp = VEC_CMA(chest_rsrp_sf(&chest, ue_sync_get_sfidx(&ue_sync)),rsrp,nframes); + nframes++; + + // Plot and Printf + if ((nframes%10) == 0) { + printf("CFO: %+6.4f KHz, SFO: %+6.4f Khz, RSSI: %+5.2f dBm, RSRP: %+4.2f dBm, RSRQ: %4.2f dB\r", + ue_sync_get_cfo(&ue_sync)/1000, ue_sync_get_sfo(&ue_sync)/1000, + 10*log10(rssi*1000/4/cell.nof_prb/12/2)-prog_args.uhd_gain, + 10*log10(rsrp*1000)-prog_args.uhd_gain, + 10*log10(rsrq)); + } + + } else if (ret == 0) { + printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r", + sync_get_peak_value(&ue_sync.sfind), + ue_sync.frame_total_cnt, ue_sync.state); + } + sf_cnt++; + } // Main loop + + ue_sync_free(&ue_sync); + cuhd_close(uhd); + printf("\nBye\n"); + exit(0); +} + + + diff --git a/lte/phy/include/liblte/phy/common/phy_common.h b/lte/phy/include/liblte/phy/common/phy_common.h index a04e35f6a..3103b2b37 100644 --- a/lte/phy/include/liblte/phy/common/phy_common.h +++ b/lte/phy/include/liblte/phy/common/phy_common.h @@ -101,7 +101,7 @@ typedef enum {CPNORM, CPEXT} lte_cp_t; (symbol_idx-1)*(symbol_sz+CP(symbol_sz, CPNORM_LEN)))) #define SLOT_IDX_CPEXT(idx, symbol_sz) (idx*(symbol_sz+CP(symbol_sz, CPEXT_LEN))) -#define RE_IDX(nof_prb, symbol_idx, sample_idx) ((symbol_idx)*(nof_prb)*(RE_X_RB) + sample_idx) +#define SAMPLE_IDX(nof_prb, symbol_idx, sample_idx) ((symbol_idx)*(nof_prb)*(RE_X_RB) + sample_idx) #define RS_VSHIFT(cell_id) (cell_id%6) diff --git a/lte/phy/include/liblte/phy/sync/sync.h b/lte/phy/include/liblte/phy/sync/sync.h index 52f91920b..4d5c89f43 100644 --- a/lte/phy/include/liblte/phy/sync/sync.h +++ b/lte/phy/include/liblte/phy/sync/sync.h @@ -76,9 +76,6 @@ typedef struct LIBLTE_API { uint32_t m1; float m0_value; float m1_value; - float M_norm_avg; - float M_ext_avg; - }sync_t; @@ -138,6 +135,10 @@ LIBLTE_API lte_cp_t sync_get_cp(sync_t *q); /* Sets the CP length estimation (must do it if disabled) */ LIBLTE_API void sync_set_cp(sync_t *q, lte_cp_t cp); +/* Enables/Disables energy normalization every frame. If disabled, uses the mean */ +LIBLTE_API void sync_normalize_en(sync_t *q, + bool enable); + /* Enables/Disables SSS detection */ LIBLTE_API void sync_sss_en(sync_t *q, bool enabled); diff --git a/lte/phy/include/liblte/phy/ue/ue_mib.h b/lte/phy/include/liblte/phy/ue/ue_mib.h index 836f014c8..fdd01ef66 100644 --- a/lte/phy/include/liblte/phy/ue/ue_mib.h +++ b/lte/phy/include/liblte/phy/ue/ue_mib.h @@ -56,9 +56,10 @@ #include "liblte/phy/common/fft.h" -#define MIB_MAX_PORTS 4 -#define MIB_NOF_PRB 6 +#define MIB_NOF_PORTS 2 +#define MIB_FRAME_SIZE 9600 +#define MIB_FRAME_UNALIGNED -3 #define MIB_FOUND 1 #define MIB_NOTFOUND 0 diff --git a/lte/phy/include/liblte/phy/utils/vector.h b/lte/phy/include/liblte/phy/utils/vector.h index 00671534b..0d24dc4e5 100644 --- a/lte/phy/include/liblte/phy/utils/vector.h +++ b/lte/phy/include/liblte/phy/utils/vector.h @@ -35,15 +35,11 @@ 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)) +#define VEC_CMA(data, average, n) ((data) + ((data) - (average)) / ((n)+1)) // Exponential moving average -#define VEC_EMA(data, average, alpha) ((alpha)*(data)+(1-alpha)*(average)) +#define VEC_EMA(data, average, alpha) ((factor)*(data)+(1-alpha)*(average)) /** Return the sum of all the elements */ LIBLTE_API int vec_acc_ii(int *x, uint32_t len); diff --git a/lte/phy/lib/ch_estimation/test/CMakeLists.txt b/lte/phy/lib/ch_estimation/test/CMakeLists.txt index 296997bc0..e0990fe53 100644 --- a/lte/phy/lib/ch_estimation/test/CMakeLists.txt +++ b/lte/phy/lib/ch_estimation/test/CMakeLists.txt @@ -30,17 +30,6 @@ ADD_TEST(chest_test_dl_cellid0 chest_test_dl -c 0) ADD_TEST(chest_test_dl_cellid1 chest_test_dl -c 1) ADD_TEST(chest_test_dl_cellid2 chest_test_dl -c 2) -ADD_TEST(chest_test_dl_cellid0 chest_test_dl -c 0 -r 50) -ADD_TEST(chest_test_dl_cellid1 chest_test_dl -c 1 -r 50) -ADD_TEST(chest_test_dl_cellid2 chest_test_dl -c 2 -r 50) - -######################################################################## -# Downlink MEX libs -######################################################################## - -BuildMex(MEXNAME chest SOURCES chest_test_dl_mex.c LIBRARIES lte_phy) - - ######################################################################## # Uplink Channel Estimation TEST ######################################################################## @@ -54,9 +43,3 @@ BuildMex(MEXNAME chest SOURCES chest_test_dl_mex.c LIBRARIES lte_phy) - - - - - - diff --git a/lte/phy/lib/ch_estimation/test/chest_test_dl.c b/lte/phy/lib/ch_estimation/test/chest_test_dl.c deleted file mode 100644 index 8b60a23c0..000000000 --- a/lte/phy/lib/ch_estimation/test/chest_test_dl.c +++ /dev/null @@ -1,253 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2014 The libLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the libLTE library. - * - * libLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * libLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * A copy of the GNU Lesser General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include -#include -#include - -#include "liblte/phy/phy.h" - -lte_cell_t cell = { - 6, // nof_prb - 1, // nof_ports - 1000, // cell_id - CPNORM // cyclic prefix -}; - -char *output_matlab = NULL; - -void usage(char *prog) { - printf("Usage: %s [recov]\n", prog); - - printf("\t-r nof_prb [Default %d]\n", cell.nof_prb); - printf("\t-e extended cyclic prefix [Default normal]\n"); - - printf("\t-c cell_id (1000 tests all). [Default %d]\n", cell.id); - - printf("\t-o output matlab file [Default %s]\n",output_matlab?output_matlab:"None"); - printf("\t-v increase verbosity\n"); -} - -void parse_args(int argc, char **argv) { - int opt; - while ((opt = getopt(argc, argv, "recov")) != -1) { - switch(opt) { - case 'r': - cell.nof_prb = atoi(argv[optind]); - break; - case 'e': - cell.cp = CPEXT; - break; - case 'c': - cell.id = atoi(argv[optind]); - break; - case 'o': - output_matlab = argv[optind]; - break; - case 'v': - verbose++; - break; - default: - usage(argv[0]); - exit(-1); - } - } -} - - -int main(int argc, char **argv) { - chest_dl_t est; - precoding_t cheq; - cf_t *input = NULL, *ce = NULL, *h = NULL, *output = NULL; - int i, j, n_port, sf_idx, cid, num_re; - int ret = -1; - int max_cid; - FILE *fmatlab = NULL; - - parse_args(argc,argv); - - if (output_matlab) { - fmatlab=fopen(output_matlab, "w"); - if (!fmatlab) { - perror("fopen"); - goto do_exit; - } - } - - num_re = 2 * cell.nof_prb * RE_X_RB * CP_NSYMB(cell.cp); - - input = malloc(num_re * sizeof(cf_t)); - if (!input) { - perror("malloc"); - goto do_exit; - } - output = malloc(num_re * sizeof(cf_t)); - if (!output) { - perror("malloc"); - goto do_exit; - } - h = malloc(num_re * sizeof(cf_t)); - if (!h) { - perror("malloc"); - goto do_exit; - } - ce = malloc(num_re * sizeof(cf_t)); - if (!ce) { - perror("malloc"); - goto do_exit; - } - - if (cell.id == 1000) { - cid = 0; - max_cid = 504; - } else { - cid = cell.id; - max_cid = cell.id; - } - - precoding_init(&cheq, num_re); - - while(cid <= max_cid) { - cell.id = cid; - if (chest_dl_init(&est, cell)) { - fprintf(stderr, "Error initializing equalizer\n"); - goto do_exit; - } - - for (sf_idx=0;sf_idx<1;sf_idx++) { - for (n_port=0;n_port 1.7) { - goto do_exit; - } - - if (fmatlab) { - fprintf(fmatlab, "input="); - vec_fprint_c(fmatlab, input, num_re); - fprintf(fmatlab, ";\n"); - fprintf(fmatlab, "h="); - vec_fprint_c(fmatlab, h, num_re); - fprintf(fmatlab, ";\n"); - fprintf(fmatlab, "ce="); - vec_fprint_c(fmatlab, ce, num_re); - fprintf(fmatlab, ";\n"); - } - } - } - chest_dl_free(&est); - cid+=10; - INFO("cid=%d\n", cid); - } - - - ret = 0; - -do_exit: - - precoding_free(&cheq); - - if (output) { - free(output); - } - if (ce) { - free(ce); - } - if (input) { - free(input); - } - if (h) { - free(h); - } - - if (!ret) { - printf("OK\n"); - } else { - printf("Error at cid=%d, slot=%d, port=%d\n",cid, sf_idx, n_port); - } - - exit(ret); -} diff --git a/lte/phy/lib/ch_estimation/test/chest_test_ul.c b/lte/phy/lib/ch_estimation/test/chest_test_ul.c deleted file mode 100644 index 60a2327fe..000000000 --- a/lte/phy/lib/ch_estimation/test/chest_test_ul.c +++ /dev/null @@ -1,249 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2014 The libLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the libLTE library. - * - * libLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * libLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * A copy of the GNU Lesser General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include -#include -#include - -#include "liblte/phy/phy.h" - -lte_cell_t cell = { - 6, // nof_prb - MAX_PORTS, // nof_ports - 1000, // cell_id - CPNORM // cyclic prefix -}; - -uint8_t *output_matlab = NULL; - -void usage(char *prog) { - printf("Usage: %s [recov]\n", prog); - - printf("\t-r nof_prb [Default %d]\n", cell.nof_prb); - printf("\t-e extended cyclic prefix [Default normal]\n"); - - printf("\t-c cell_id (1000 tests all). [Default %d]\n", cell.id); - - printf("\t-o output matlab file [Default %s]\n",output_matlab?output_matlab:"None"); - printf("\t-v increase verbosity\n"); -} - -void parse_args(int argc, char **argv) { - int opt; - while ((opt = getopt(argc, argv, "recov")) != -1) { - switch(opt) { - case 'r': - cell.nof_prb = atoi(argv[optind]); - break; - case 'e': - cell.cp = CPEXT; - break; - case 'c': - cell.id = atoi(argv[optind]); - break; - case 'o': - output_matlab = argv[optind]; - break; - case 'v': - verbose++; - break; - default: - usage(argv[0]); - exit(-1); - } - } -} - -int check_mse(float mod, float arg, int n_port) { - INFO("mod=%.4f, arg=%.4f, n_port=%d\n", mod, arg, n_port); - switch(n_port) { - case 0: - if (mod > 0.029) { - return -1; - } - if (arg > 0.029) { - return -1; - } - break; - case 1: - if (mod > 0.012) { - return -1; - } - if (arg > 0.012) { - return -1; - } - break; - case 2: - case 3: - if (mod > 3.33) { - return -1; - } - if (arg > 0.63) { - return -1; - } - break; - default: - return -1; - } - return 0; -} - -int main(int argc, char **argv) { - chest_t eq; - cf_t *input = NULL, *ce = NULL, *h = NULL; - refsignal_t refs; - int i, j, n_port, n_slot, cid, num_re; - int ret = -1; - int max_cid; - FILE *fmatlab = NULL; - float mse_mag, mse_phase; - - parse_args(argc,argv); - - if (output_matlab) { - fmatlab=fopen(output_matlab, "w"); - if (!fmatlab) { - perror("fopen"); - goto do_exit; - } - } - - num_re = cell.nof_prb * RE_X_RB * CP_NSYMB(cell.cp); - - input = malloc(num_re * sizeof(cf_t)); - if (!input) { - perror("malloc"); - goto do_exit; - } - h = malloc(num_re * sizeof(cf_t)); - if (!h) { - perror("malloc"); - goto do_exit; - } - ce = malloc(num_re * sizeof(cf_t)); - if (!ce) { - perror("malloc"); - goto do_exit; - } - - if (cell.id == 1000) { - cid = 0; - max_cid = 504; - } else { - cid = cell.id; - max_cid = cell.id; - } - - while(cid <= max_cid) { - cell.id = cid; - if (chest_init_LTEUL(&eq, cell)) { - fprintf(stderr, "Error initializing equalizer\n"); - goto do_exit; - } - - for (n_slot=0;n_slotnof_iterations < TDEC_MAX_ITERATIONS && !early_stop); - q->average_nof_iterations = VEC_EMA((float) q->nof_iterations, q->average_nof_iterations, 0.2); - + + q->average_nof_iterations = VEC_CMA((float) q->nof_iterations, + q->average_nof_iterations, + q->average_nof_iterations_n); + q->average_nof_iterations_n++; /* Copy data to another buffer, removing the Codeblock CRC */ if (i < harq_process->cb_segm.C - 1) { diff --git a/lte/phy/lib/sync/src/pss.c b/lte/phy/lib/sync/src/pss.c index 7eab9ab3b..6e67d3798 100644 --- a/lte/phy/lib/sync/src/pss.c +++ b/lte/phy/lib/sync/src/pss.c @@ -321,51 +321,7 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value) vec_sum_fff(q->conv_output_abs, q->conv_output_avg, q->conv_output_avg, conv_output_len-1); /* Find maximum of the absolute value of the correlation */ - corr_peak_pos = vec_max_fi(q->conv_output_avg, conv_output_len-1); - - // save absolute value - q->peak_value = q->conv_output_avg[corr_peak_pos]; - -#ifdef PSS_RETURN_PSR - // Find second side lobe - - // Find end of peak lobe to the right - int pl_ub = corr_peak_pos+1; - while(q->conv_output_avg[pl_ub+1] <= q->conv_output_avg[pl_ub] && pl_ub < conv_output_len) { - pl_ub ++; - } - // Find end of peak lobe to the left - int pl_lb; - if (corr_peak_pos > 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], 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) { - DEBUG("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 + corr_peak_pos = vec_max_abs_ci(q->conv_output, conv_output_len-1); if (corr_peak_value) { *corr_peak_value = q->conv_output_avg[corr_peak_pos]; } diff --git a/lte/phy/lib/sync/src/sync.c b/lte/phy/lib/sync/src/sync.c index 6a6dfae4c..d74006c40 100644 --- a/lte/phy/lib/sync/src/sync.c +++ b/lte/phy/lib/sync/src/sync.c @@ -59,8 +59,8 @@ int sync_init(sync_t *q, uint32_t frame_size, uint32_t fft_size) { bzero(q, sizeof(sync_t)); q->detect_cp = true; - q->cp = CPNORM; - q->mean_peak_value = 0.0; + q->normalize_en = true; + q->mean_energy = 1.0; q->sss_en = true; q->correct_cfo = true; q->mean_cfo = 0; @@ -175,10 +175,6 @@ void sync_set_cp(sync_t *q, lte_cp_t cp) { q->cp = cp; } -void sync_set_sss_algorithm(sync_t *q, sss_alg_t alg) { - q->sss_alg = alg; -} - /* CP detection algorithm taken from: * "SSS Detection Method for Initial Cell Search in 3GPP LTE FDD/TDD Dual Mode Receiver" * by Jung-In Kim et al. @@ -227,33 +223,20 @@ lte_cp_t sync_detect_cp(sync_t *q, cf_t *input, uint32_t peak_pos) } } -/* Returns 1 if the SSS is found, 0 if not and -1 if there is not enough space - * to correlate - */ -int sync_sss(sync_t *q, cf_t *input, uint32_t peak_pos, lte_cp_t cp) { +int sync_sss(sync_t *q, cf_t *input, uint32_t peak_pos) { int sss_idx, ret; sss_synch_set_N_id_2(&q->sss, q->N_id_2); /* Make sure we have enough room to find SSS sequence */ - sss_idx = (int) peak_pos-2*q->fft_size-CP(q->fft_size, (CP_ISNORM(q->cp)?CPNORM_LEN:CPEXT_LEN)); + sss_idx = (int) peak_pos - 2*(q->fft_size + CP(q->fft_size, q->cp)); if (sss_idx < 0) { INFO("Not enough room to decode CP SSS (sss_idx=%d, peak_pos=%d)\n", sss_idx, peak_pos); return LIBLTE_ERROR; } DEBUG("Searching SSS around sss_idx: %d, peak_pos: %d\n", sss_idx, peak_pos); - switch(q->sss_alg) { - case SSS_DIFF: - sss_synch_m0m1_diff(&q->sss, &input[sss_idx], &q->m0, &q->m0_value, &q->m1, &q->m1_value); - break; - case SSS_PARTIAL_3: - sss_synch_m0m1_partial(&q->sss, &input[sss_idx], 3, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); - break; - case SSS_FULL: - sss_synch_m0m1_partial(&q->sss, &input[sss_idx], 1, NULL, &q->m0, &q->m0_value, &q->m1, &q->m1_value); - break; - } + sss_synch_m0m1(&q->sss, &input[sss_idx], &q->m0, &q->m0_value, &q->m1, &q->m1_value); q->sf_idx = sss_synch_subframe(q->m0, q->m1); ret = sss_synch_N_id_1(&q->sss, q->m0, q->m1); @@ -281,6 +264,8 @@ int sync_find(sync_t *q, cf_t *input, uint32_t find_offset, uint32_t *peak_posit int ret = LIBLTE_ERROR_INVALID_INPUTS; + float peak_unnormalized=0, energy=1; + if (q != NULL && input != NULL && lte_N_id_2_isvalid(q->N_id_2) && @@ -288,68 +273,63 @@ int sync_find(sync_t *q, cf_t *input, uint32_t find_offset, uint32_t *peak_posit { int peak_pos; - ret = LIBLTE_SUCCESS; - if (peak_position) { *peak_position = 0; } pss_synch_set_N_id_2(&q->pss, q->N_id_2); - peak_pos = pss_synch_find_pss(&q->pss, &input[find_offset], &q->peak_value); + peak_pos = pss_synch_find_pss(&q->pss, &input[find_offset], &peak_unnormalized); if (peak_pos < 0) { fprintf(stderr, "Error calling finding PSS sequence\n"); return LIBLTE_ERROR; } + if (q->normalize_en && + peak_pos + find_offset >= q->fft_size) + { + /* Compute the energy of the received PSS sequence to normalize */ + cf_t *pss_ptr = &input[find_offset+peak_pos-q->fft_size]; + energy = sqrtf(crealf(vec_dot_prod_conj_ccc(pss_ptr, pss_ptr, q->fft_size)) / (q->fft_size)); + q->mean_energy = VEC_CMA(energy, q->mean_energy, q->frame_cnt); + } else { + if (q->mean_energy == 0.0) { + q->mean_energy = 1.0; + } + energy = q->mean_energy; + } q->mean_peak_value = VEC_EMA(q->peak_value, q->mean_peak_value, MEANPEAK_EMA_ALPHA); - if (peak_position) { - *peak_position = (uint32_t) peak_pos; - } + /* Normalize and compute mean peak value */ + q->peak_value = peak_unnormalized/energy; + q->mean_peak_value = VEC_CMA(q->peak_value, q->mean_peak_value, q->frame_cnt); + q->frame_cnt++; /* If peak is over threshold, compute CFO and SSS */ - if (q->peak_value >= q->threshold) { - - // Make sure we have enough space to estimate CFO - if (peak_pos + find_offset >= q->fft_size) { - float cfo = pss_synch_cfo_compute(&q->pss, &input[find_offset+peak_pos-q->fft_size]); - - /* compute cumulative moving average CFO */ - q->mean_cfo = VEC_EMA(cfo, q->mean_cfo, CFO_EMA_ALPHA); - } else { - INFO("No space for CFO computation. Frame starts at \n",peak_pos); - } - - if (q->detect_cp) { - if (peak_pos + find_offset >= 2*(q->fft_size + CP_EXT(q->fft_size))) { - q->cp = sync_detect_cp(q, input, peak_pos + find_offset); + if (q->peak_value >= q->threshold) { + if (find_offset + peak_pos >= q->fft_size) { + q->cfo = pss_synch_cfo_compute(&q->pss, &input[find_offset+peak_pos-q->fft_size]); + if (q->sss_en) { + ret = sync_sss(q, input, find_offset + peak_pos); + if (ret < 0) { + fprintf(stderr, "Error synchronizing with SSS\n"); + return LIBLTE_ERROR; + } } else { - INFO("Not enough room to detect CP length. Peak position: %d\n", peak_pos); + ret = 1; } + } else { + INFO("No space for CFO computation. Frame starts at \n",peak_pos); } - - // Try to detect SSS - if (q->sss_en) { - /* Correct CFO with the averaged CFO estimation */ - if (q->mean_cfo && q->correct_cfo) { - cfo_correct(&q->cfocorr, input, input, -q->mean_cfo / q->fft_size); - } - - // 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) { - INFO("No space for SSS processing. Frame starts at %d\n", peak_pos); - } + + if (peak_position) { + *peak_position = (uint32_t) peak_pos; } - // Return 1 (peak detected) even if we couldn't estimate CFO and SSS - ret = 1; } else { ret = 0; } - INFO("SYNC ret=%d N_id_2=%d find_offset=%d pos=%d peak=%.2f threshold=%.2f sf_idx=%d, CFO=%.3f KHz\n", - ret, q->N_id_2, find_offset, peak_pos, q->peak_value, q->threshold, q->sf_idx, 15*q->mean_cfo); + INFO("SYNC ret=%d N_id_2=%d pos=%d peak=%.2f/%.2f=%.2f threshold=%.2f sf_idx=%d offset=%d\n", + ret, q->N_id_2, peak_pos, peak_unnormalized,energy,q->peak_value, q->threshold, q->sf_idx, find_offset); } else if (lte_N_id_2_isvalid(q->N_id_2)) { fprintf(stderr, "Must call sync_set_N_id_2() first!\n"); diff --git a/lte/phy/lib/sync/test/pss_usrp.c b/lte/phy/lib/sync/test/pss_usrp.c index fac32e19e..95749c79a 100644 --- a/lte/phy/lib/sync/test/pss_usrp.c +++ b/lte/phy/lib/sync/test/pss_usrp.c @@ -220,7 +220,9 @@ int main(int argc, char **argv) { mean_peak = VEC_CMA(peak_value, mean_peak, frame_cnt); - if (peak_value >= threshold) { + mean_peak = VEC_CMA(x, mean_peak, frame_cnt); + + if (x >= threshold) { nof_det++; if (peak_idx >= fft_size) { diff --git a/lte/phy/lib/ue/src/ue_dl.c b/lte/phy/lib/ue/src/ue_dl.c index c0f48a10b..346c6564c 100644 --- a/lte/phy/lib/ue/src/ue_dl.c +++ b/lte/phy/lib/ue/src/ue_dl.c @@ -192,7 +192,12 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui gettimeofday(&t[1], NULL); /* Get channel estimates for each port */ - chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, sf_idx); + chest_ce_sf(&q->chest, q->sf_symbols, q->ce, sf_idx); + + gettimeofday(&t[2], NULL); + get_time_interval(t); + mean_exec_time = (float) VEC_CMA((float) t[0].tv_usec, mean_exec_time, frame_cnt); + frame_cnt++; /* First decode PCFICH and obtain CFI */ if (pcfich_decode(&q->pcfich, q->sf_symbols, q->ce, diff --git a/lte/phy/lib/ue/src/ue_mib.c b/lte/phy/lib/ue/src/ue_mib.c index e8f6c7096..09c224f13 100644 --- a/lte/phy/lib/ue/src/ue_mib.c +++ b/lte/phy/lib/ue/src/ue_mib.c @@ -36,8 +36,14 @@ #include "liblte/phy/utils/debug.h" #include "liblte/phy/utils/vector.h" +#define FIND_FFTSIZE 128 +#define FIND_SFLEN 5*SF_LEN(FIND_FFTSIZE) + +#define MIB_FIND_THRESHOLD 0.0 + int ue_mib_init(ue_mib_t * q, - lte_cell_t cell) + uint32_t cell_id, + lte_cp_t cp) { int ret = LIBLTE_ERROR_INVALID_INPUTS; @@ -62,7 +68,17 @@ int ue_mib_init(ue_mib_t * q, } } - if (lte_fft_init(&q->fft, cell.cp, cell.nof_prb)) { + if (sync_init(&q->sfind, FIND_SFLEN, FIND_FFTSIZE)) { + goto clean_exit; + } + + sync_set_threshold(&q->sfind, MIB_FIND_THRESHOLD); + sync_sss_en(&q->sfind, true); + sync_set_N_id_2(&q->sfind, cell_id % 3); + sync_cp_en(&q->sfind, false); + sync_set_cp(&q->sfind, cp); + + if (lte_fft_init(&q->fft, cp, cell.nof_prb)) { fprintf(stderr, "Error initializing FFT\n"); goto clean_exit; } @@ -114,45 +130,48 @@ void ue_mib_reset(ue_mib_t * q) int ue_mib_decode(ue_mib_t * q, cf_t *input, uint8_t bch_payload[BCH_PAYLOAD_LEN], uint32_t *nof_tx_ports, uint32_t *sfn_offset) +{ + sync_set_threshold(&q->sfind, threshold); +} + +static int mib_decoder_run(ue_mib_t * q, cf_t *input, pbch_mib_t *mib) { int ret = LIBLTE_SUCCESS; - cf_t *ce_slot1[MAX_PORTS]; /* Run FFT for the slot symbols */ lte_fft_run_sf(&q->fft, input, q->sf_symbols); /* Get channel estimates of slot #1 for each port */ - ret = chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, 0); + ret = chest_ce_slot(&q->chest, q->slot1_symbols, q->ce, 1); if (ret < 0) { return LIBLTE_ERROR; } + /* Reset decoder if we missed a frame */ - if (q->frame_cnt > 8) { - INFO("Resetting PBCH decoder after %d frames\n", q->frame_cnt); + if ((q->last_frame_trial && (abs(q->frame_cnt - q->last_frame_trial) > 2)) || + q->frame_cnt > 16) + { + INFO("Resetting PBCH decoder: last trial %u, now is %u\n", + q->last_frame_trial, q->frame_cnt); ue_mib_reset(q); } - for (int i=0;ice[i][SLOT_LEN_RE(q->chest.cell.nof_prb, q->chest.cell.cp)]; - } - /* Decode PBCH */ - ret = pbch_decode(&q->pbch, &q->sf_symbols[SLOT_LEN_RE(q->chest.cell.nof_prb, q->chest.cell.cp)], - ce_slot1, chest_dl_get_noise_estimate(&q->chest), - bch_payload, nof_tx_ports, sfn_offset); + ret = pbch_decode(&q->pbch, q->slot1_symbols, q->ce, mib); if (ret < 0) { - fprintf(stderr, "Error decoding PBCH (%d)\n", ret); + fprintf(stderr, "Error decoding PBCH\n"); } else if (ret == 1) { - INFO("MIB decoded: %u\n", q->frame_cnt); + INFO("MIB decoded: %u\n", q->frame_cnt/2); ue_mib_reset(q); ret = MIB_FOUND; } else { - INFO("MIB not decoded: %u\n", q->frame_cnt); - q->frame_cnt++; - ret = MIB_NOTFOUND; + INFO("MIB not decoded: %u\n", q->frame_cnt / 2); + q->last_frame_trial = q->frame_cnt; + ret = LIBLTE_SUCCESS; } return ret; } +int counter1=0,counter2=0,counter3=0,counter4=0; @@ -162,73 +181,74 @@ int ue_mib_sync_init(ue_mib_sync_t *q, int (recv_callback)(void*, void*, uint32_t), void *stream_handler) { - lte_cell_t cell; - cell.nof_ports = MIB_MAX_PORTS; - cell.id = cell_id; - cell.cp = cp; - cell.nof_prb = MIB_NOF_PRB; - - if (ue_mib_init(&q->ue_mib, cell)) { - fprintf(stderr, "Error initiating ue_mib\n"); - return LIBLTE_ERROR; - } - if (ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { - fprintf(stderr, "Error initiating ue_sync\n"); - ue_mib_free(&q->ue_mib); - return LIBLTE_ERROR; - } - ue_sync_decode_sss_on_track(&q->ue_sync, true); - return LIBLTE_SUCCESS; -} + int ret = LIBLTE_ERROR_INVALID_INPUTS; + uint32_t peak_idx=0; + uint32_t nof_input_frames; void ue_mib_sync_free(ue_mib_sync_t *q) { ue_mib_free(&q->ue_mib); ue_sync_free(&q->ue_sync); } -void ue_mib_sync_reset(ue_mib_sync_t * q) { - ue_mib_reset(&q->ue_mib); - ue_sync_reset(&q->ue_sync); -} - -int ue_mib_sync_decode(ue_mib_sync_t * q, - uint32_t max_frames_timeout, - uint8_t bch_payload[BCH_PAYLOAD_LEN], - uint32_t *nof_tx_ports, - uint32_t *sfn_offset) -{ - - int ret = LIBLTE_ERROR_INVALID_INPUTS; - cf_t *sf_buffer = NULL; - uint32_t nof_frames = 0; - int mib_ret = MIB_NOTFOUND; - - if (q != NULL) + if (q != NULL && + signal != NULL) { - ret = LIBLTE_SUCCESS; - do { - mib_ret = MIB_NOTFOUND; - ret = ue_sync_get_buffer(&q->ue_sync, &sf_buffer); + if (nsamples < MIB_FRAME_SIZE) { + fprintf(stderr, "Error: nsamples must be greater than %d\n", MIB_FRAME_SIZE); + return LIBLTE_ERROR; + } + + ret = LIBLTE_SUCCESS; + + if (nsamples % MIB_FRAME_SIZE) { + printf("Warning: nsamples must be a multiple of %d. Some samples will be ignored\n", MIB_FRAME_SIZE); + nsamples = (nsamples/MIB_FRAME_SIZE) * MIB_FRAME_SIZE; + } + nof_input_frames = nsamples/MIB_FRAME_SIZE; + + for (uint32_t nf=0;nfsfind, signal, nf*MIB_FRAME_SIZE, &peak_idx); if (ret < 0) { - fprintf(stderr, "Error calling ue_sync_work()\n"); - break; - } else if (ue_sync_get_sfidx(&q->ue_sync) == 0) { - if (ret == 1) { - ue_mib_reset(&q->ue_mib); - mib_ret = ue_mib_decode(&q->ue_mib, sf_buffer, bch_payload, nof_tx_ports, sfn_offset); - - } else { - INFO("Resetting PBCH decoder after %d frames\n", q->ue_mib.frame_cnt); - ue_mib_reset(&q->ue_mib); - } - nof_frames++; + fprintf(stderr, "Error finding correlation peak (%d)\n", ret); + return -1; } - } while (mib_ret == MIB_NOTFOUND && ret >= 0 && nof_frames < max_frames_timeout); - if (mib_ret < 0) { - ret = mib_ret; - } + + if (ret == 0) { + counter2++; + } else if (ret == 1) { + counter4++; + } + + /* Check if we have space for reading the MIB and we are in Subframe #0 */ + if (ret == 1 && + nf*MIB_FRAME_SIZE + peak_idx + 960 <= nsamples && + sync_sss_detected(&q->sfind) && + sync_get_sf_idx(&q->sfind) == 0) + { + INFO("Trying to decode MIB\n",0); + ret = mib_decoder_run(q, &signal[nf*MIB_FRAME_SIZE+peak_idx], mib); + counter3++; + } else if ((ret == LIBLTE_SUCCESS && peak_idx != 0) || + (ret == 1 && nf*MIB_FRAME_SIZE + peak_idx + 960 > nsamples)) + { + printf("Not enough space for PBCH\n",0); + ret = MIB_FRAME_UNALIGNED; + } else { + INFO("SSS not detected\n",0); + ret = 0; + } + + counter1++; + INFO("Total: %3d - Sync0: %3d - Sync1: %3d - Tried: %3d - Peak: %4d - Ret: %d\n",counter1,counter2,counter4, counter3, peak_idx, ret); + + q->frame_cnt++; + } } return mib_ret; } + + diff --git a/lte/phy/lib/ue/src/ue_sync.c b/lte/phy/lib/ue/src/ue_sync.c index e5944f9cb..359a32318 100644 --- a/lte/phy/lib/ue/src/ue_sync.c +++ b/lte/phy/lib/ue/src/ue_sync.c @@ -46,17 +46,8 @@ cf_t dummy[MAX_TIME_OFFSET]; #define TRACK_FRAME_SIZE 32 #define FIND_NOF_AVG_FRAMES 2 -int ue_sync_init_file(ue_sync_t *q, uint32_t nof_prb, char *file_name) { - int ret = LIBLTE_ERROR_INVALID_INPUTS; - - if (q != NULL && - file_name != NULL && - lte_nofprb_isvalid(nof_prb)) - { - ret = LIBLTE_ERROR; - bzero(q, sizeof(ue_sync_t)); - q->file_mode = true; - q->sf_len = SF_LEN(lte_symbol_sz(nof_prb)); +#define FIND_THRESHOLD 1.2 +#define TRACK_THRESHOLD 0.2 if (filesource_init(&q->file_source, file_name, COMPLEX_FLOAT_BIN)) { fprintf(stderr, "Error opening file %s\n", file_name); @@ -217,7 +208,7 @@ float ue_sync_get_cfo(ue_sync_t *q) { } float ue_sync_get_sfo(ue_sync_t *q) { - return 5000*q->mean_time_offset; + return 1000*q->mean_time_offset; } void ue_sync_decode_sss_on_track(ue_sync_t *q, bool enabled) { @@ -276,12 +267,11 @@ static int track_peak_ok(ue_sync_t *q, uint32_t track_idx) { /* Make sure subframe idx is what we expect */ if ((q->sf_idx != sync_get_sf_idx(&q->strack)) && q->decode_sss_on_track) { - if (sync_get_cell_id(&q->strack) == q->cell.id) { - INFO("Warning: Expected SF idx %d but got %d (%d,%g - %d,%g)!\n", - q->sf_idx, sync_get_sf_idx(&q->strack), - q->strack.m0, q->strack.m0_value, q->strack.m1, q->strack.m1_value); - q->sf_idx = sync_get_sf_idx(&q->strack); - } + INFO("Warning: Expected SF idx %d but got %d (%d,%g - %d,%g)!\n", + q->sf_idx, sync_get_sf_idx(&q->strack), q->strack.m0, q->strack.m1, q->strack.m0_value, q->strack.m1_value); + /* FIXME: What should we do in this case? */ + q->sf_idx = sync_get_sf_idx(&q->strack); + q->state = SF_TRACK; } else { // Adjust time offset q->time_offset = ((int) track_idx - (int) q->strack.frame_size/2 - (int) q->strack.fft_size); @@ -304,7 +294,12 @@ static int track_peak_ok(ue_sync_t *q, uint32_t track_idx) { q->time_offset = 0; } - q->peak_idx = q->sf_len/2 + q->time_offset; + /* compute cumulative moving average CFO */ + q->cur_cfo = VEC_CMA(sync_get_cfo(&q->strack), q->cur_cfo, q->frame_ok_cnt); + /* compute cumulative moving average time offset */ + q->mean_time_offset = (float) VEC_CMA((float) q->time_offset, q->mean_time_offset, q->frame_ok_cnt); + + q->peak_idx = CURRENT_SFLEN/2 + q->time_offset; q->frame_ok_cnt++; q->frame_no_cnt = 0; } @@ -444,13 +439,16 @@ int ue_sync_get_buffer(ue_sync_t *q, cf_t **sf_symbols) { q->frame_total_cnt++; } - /* Do CFO Correction if not done in track and deliver the frame */ - if (!q->strack.correct_cfo) { - cfo_correct(&q->sfind.cfocorr, - q->input_buffer, - q->input_buffer, - -sync_get_cfo(&q->strack) / q->fft_size); - + #ifdef MEASURE_EXEC_TIME + gettimeofday(&t[2], NULL); + get_time_interval(t); + q->mean_exec_time = (float) VEC_CMA((float) t[0].tv_usec, q->mean_exec_time, q->frame_total_cnt); + #endif + + if (ret == 1) { + ret = track_peak_ok(q, track_idx); + } else { + ret = track_peak_no(q); } *sf_symbols = q->input_buffer; diff --git a/lte/rrc/include/liblte/rrc/rrc.h b/lte/rrc/include/liblte/rrc/rrc.h index 513c0c4ed..af03a5b41 100644 --- a/lte/rrc/include/liblte/rrc/rrc.h +++ b/lte/rrc/include/liblte/rrc/rrc.h @@ -29,22 +29,19 @@ #include #include -#ifndef _LTE_RRC_ -#define _LTE_RRC_ +int decode_pbch(void *uhd, + ue_celldetect_result_t *found_cell, + uint32_t nof_frames_total, + pbch_mib_t *mib); -#ifdef __cplusplus - extern "C" { -#endif +int find_all_cells(void *uhd, + ue_celldetect_result_t found_cell[3]); -#include "liblte/config.h" +int find_cell(void *uhd, + ue_celldetect_result_t *found_cell, + uint32_t N_id_2); -#include "liblte/rrc/messages/bcch.h" -#include "liblte/rrc/messages/sib1.h" -#include "liblte/rrc/messages/sib4.h" -#include "liblte/rrc/common/rrc_common.h" - -#ifdef __cplusplus -} -#endif - -#endif +int cell_search(void *uhd, + int force_N_id_2, + lte_cell_t *cell, + pbch_mib_t *mib); \ No newline at end of file