From 5e6abc71866ccd42c708d16e154dd477f0240272 Mon Sep 17 00:00:00 2001 From: ismagom Date: Thu, 18 Dec 2014 00:30:31 +0000 Subject: [PATCH] Improved PCFICH detection using soft bit correlation. --- cuhd/lib/cuhd_imp.cpp | 18 +- lte/examples/CMakeLists.txt | 2 - lte/examples/cell_scanner/CMakeLists.txt | 28 -- lte/examples/cell_scanner/cell_scanner.c | 283 ------------------ lte/examples/cell_scanner/cell_scanner.h | 64 ---- lte/examples/cell_scanner/cell_scanner_test.c | 143 --------- lte/phy/include/liblte/phy/phch/pcfich.h | 17 +- lte/phy/lib/phch/src/pbch.c | 1 + lte/phy/lib/phch/src/pcfich.c | 71 +++-- lte/phy/lib/phch/test/pcfich_file_test.c | 10 +- lte/phy/lib/phch/test/pcfich_test.c | 14 +- lte/phy/lib/phch/test/pcfich_test_mex.c | 11 +- lte/phy/lib/ue/src/ue_dl.c | 7 +- lte/phy/lib/ue/src/ue_mib.c | 2 +- lte/phy/lib/ue/src/ue_sync.c | 2 +- 15 files changed, 84 insertions(+), 589 deletions(-) delete mode 100644 lte/examples/cell_scanner/CMakeLists.txt delete mode 100644 lte/examples/cell_scanner/cell_scanner.c delete mode 100644 lte/examples/cell_scanner/cell_scanner.h delete mode 100644 lte/examples/cell_scanner/cell_scanner_test.c diff --git a/cuhd/lib/cuhd_imp.cpp b/cuhd/lib/cuhd_imp.cpp index 33b925b97..1f9e60a5b 100644 --- a/cuhd/lib/cuhd_imp.cpp +++ b/cuhd/lib/cuhd_imp.cpp @@ -68,7 +68,7 @@ bool cuhd_rx_wait_lo_locked(void *h) { double report = 0.0; - while (isLocked(h) && report < 3.0) { + while (isLocked(h) && report < 3000.0) { report += 0.1; usleep(1000); } @@ -139,7 +139,7 @@ int cuhd_open(char *args, void **h) int cuhd_close(void *h) { cuhd_stop_rx_stream(h); - /** Something else to close the USRP?? */ + /** Something else to close the USRP?? */ return 0; } @@ -147,15 +147,17 @@ int cuhd_close(void *h) double cuhd_set_rx_srate(void *h, double freq) { cuhd_handler *handler = static_cast < cuhd_handler * >(h); + printf("Changing sampling freq now to %.2f MHz\n", freq/1000000); handler->usrp->set_rx_rate(freq); - double ret = handler->usrp->get_rx_rate(); + printf("Done\n"); + /* if ((int) ret != (int) freq) { printf("Got %f!=%f. setting master clock rate to %f\n",ret, freq, freq); handler->usrp->set_master_clock_rate(freq); handler->usrp->set_rx_rate(freq); - double ret = handler->usrp->get_rx_rate(); } - return ret; + */ + return freq; } double cuhd_set_rx_gain(void *h, double gain) @@ -168,8 +170,10 @@ double cuhd_set_rx_gain(void *h, double gain) double cuhd_set_rx_freq(void *h, double freq) { cuhd_handler *handler = static_cast < cuhd_handler * >(h); + printf("Tunning receiver to %.3f MHz\n", (double ) freq/1000000); handler->usrp->set_rx_freq(freq); - return handler->usrp->get_rx_freq(); + printf("Done\n"); + return freq; } double cuhd_set_rx_freq_offset(void *h, double freq, double off) { @@ -196,7 +200,7 @@ int cuhd_recv(void *h, void *data, uint32_t nsamples, bool blocking) std::cout << "\nError code: " << md.to_pp_string() << "\n\n"; } #endif - } while (n < nsamples); + } while (n < nsamples && md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE); return nsamples; } else { return handler->rx_stream->recv(data, nsamples, md, 0.0); diff --git a/lte/examples/CMakeLists.txt b/lte/examples/CMakeLists.txt index 72bcda270..402f3b0f1 100644 --- a/lte/examples/CMakeLists.txt +++ b/lte/examples/CMakeLists.txt @@ -92,5 +92,3 @@ IF(${CUHD_FIND} GREATER -1) ELSE(${CUHD_FIND} GREATER -1) MESSAGE(STATUS " UHD examples NOT INSTALLED: CUHD library not compiled.") ENDIF(${CUHD_FIND} GREATER -1) - -add_subdirectory(cell_scanner) \ No newline at end of file diff --git a/lte/examples/cell_scanner/CMakeLists.txt b/lte/examples/cell_scanner/CMakeLists.txt deleted file mode 100644 index 502745fe1..000000000 --- a/lte/examples/cell_scanner/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright 2012-2013 The libLTE Developers. See the -# COPYRIGHT file at the top-level directory of this distribution. -# -# 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/. -# - - -################################################################# -# CELL SCANNER TEST -################################################################# - -add_executable(cell_scanner_test cell_scanner_test.c cell_scanner.c ../cuhd_utils.c) -target_link_libraries(cell_scanner_test lte_phy lte_rrc cuhd) diff --git a/lte/examples/cell_scanner/cell_scanner.c b/lte/examples/cell_scanner/cell_scanner.c deleted file mode 100644 index ff5e5ffe1..000000000 --- a/lte/examples/cell_scanner/cell_scanner.c +++ /dev/null @@ -1,283 +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 -#include -#include -#include -#include - -#include "liblte/rrc/rrc.h" -#include "liblte/phy/phy.h" -#include "liblte/cuhd/cuhd.h" -#include "../cuhd_utils.h" -#include "cell_scanner.h" - -#define B210_DEFAULT_GAIN 40.0 -#define B210_DEFAULT_GAIN_CORREC 80.0 // Gain of the Rx chain when the gain is set to 40 - -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 cell_scanner_init(cell_scanner_t *q, cell_scanner_config_t *config) -{ - bzero(q, sizeof(cell_scanner_t)); - - memcpy(&q->config, config, sizeof(cell_scanner_config_t)); - - printf("Opening UHD device...\n"); - if (cuhd_open(q->config.uhd_args, &q->uhd)) { - fprintf(stderr, "Error opening uhd\n"); - return -1; - } - /* Set receiver gain */ - cuhd_set_rx_gain(q->uhd, B210_DEFAULT_GAIN); - - return 0; -} - -void cell_scanner_close(cell_scanner_t *q) { - cuhd_close(q->uhd); -} - -int cell_scanner_all_cells(cell_scanner_t *q, float frequency, cell_scanner_result_t *result) -{ - return cell_scanner_cell(q, frequency, -1, result); -} - -#define MAX_SINFO 10 - -int cell_scanner_cell(cell_scanner_t *q, float frequency, int N_id_2, cell_scanner_result_t *result) -{ - int ret; - cf_t *sf_buffer; - lte_cell_t cell; - int64_t sf_cnt; - ue_sync_t ue_sync; - ue_mib_t ue_mib; - ue_dl_t ue_dl; - lte_fft_t fft; - chest_dl_t chest; - uint32_t nframes_measure=0; - uint32_t nof_trials = 0; - uint32_t sfn = 0; // system frame number - int n; - uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN]; - uint32_t sfn_offset; - uint8_t data[1024]; - uint8_t data_unpacked[1024]; - - bzero(result, sizeof(cell_scanner_result_t)); - - /* set receiver frequency */ - cuhd_set_rx_freq(q->uhd, (double) frequency); - cuhd_rx_wait_lo_locked(q->uhd); - printf("Tunning receiver to %.3f MHz\n", (double ) frequency/1000000); - - cell_search_cfg_t cfg; - cfg.max_frames_pss = q->config.pss_max_frames; - cfg.max_frames_pbch = q->config.pbch_max_frames; - cfg.threshold = q->config.cell_detect_early_stop_threshold; - - ret = cuhd_search_and_decode_mib(q->uhd, &cfg, N_id_2, &cell); - if (ret < 0) { - fprintf(stderr, "Error searching cell\n"); - exit(-1); - } else if (ret == 0) { - printf("Cell not found\n"); - exit(0); - } - - /* set sampling frequency */ - int srate = lte_sampling_freq_hz(cell.nof_prb); - if (srate != -1) { - cuhd_set_rx_srate(q->uhd, (double) srate); - } else { - fprintf(stderr, "Invalid number of PRB %d\n", cell.nof_prb); - return LIBLTE_ERROR; - } - - INFO("Stopping UHD and flushing buffer...\n",0); - cuhd_stop_rx_stream(q->uhd); - cuhd_flush_buffer(q->uhd); - - if (ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper, q->uhd)) { - fprintf(stderr, "Error initiating ue_sync\n"); - exit(-1); - } - if (ue_dl_init(&ue_dl, cell, 1234)) { - fprintf(stderr, "Error initiating UE downlink processing module\n"); - exit(-1); - } - if (ue_mib_init(&ue_mib, cell)) { - fprintf(stderr, "Error initaiting UE MIB decoder\n"); - exit(-1); - } - - /* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */ - ue_dl_set_rnti(&ue_dl, SIRNTI); - - /* Initialize subframe counter */ - sf_cnt = 0; - - if (lte_fft_init(&fft, cell.cp, cell.nof_prb)) { - fprintf(stderr, "Error initiating FFT\n"); - return -1; - } - if (chest_dl_init(&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)); - - cf_t *ce[MAX_PORTS]; - for (int i=0;iuhd); - - memcpy(&result->phy_cell, &cell, sizeof(lte_cell_t)); - - chest_dl_t *chest_ptr = &ue_dl.chest; - bool mib_decoded = false; - bool sib_decoded = false; - - /* Main loop */ - while (sf_cnt < q->config.measure_avg_nof_frames) { - - ret = ue_sync_get_buffer(&ue_sync, &sf_buffer); - if (ret < 0) { - fprintf(stderr, "Error calling ue_sync_work()\n"); - } - - /* ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */ - if (ret == 1) { - if (!mib_decoded) { - if (ue_sync_get_sfidx(&ue_sync) == 0) { - pbch_decode_reset(&ue_mib.pbch); - n = ue_mib_decode(&ue_mib, sf_buffer, bch_payload_unpacked, NULL, &sfn_offset); - if (n < 0) { - fprintf(stderr, "Error decoding UE MIB\n"); - exit(-1); - } else if (n == MIB_FOUND) { - bit_unpack_vector(bch_payload_unpacked, bch_payload, BCH_PAYLOAD_LEN); - bcch_bch_unpack(bch_payload, BCH_PAYLOAD_LEN, &cell, &sfn); - printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset); - sfn = (sfn + sfn_offset)%1024; - mib_decoded = true; - } - } - } - - /* We are looking for SI Blocks, search only in appropiate places */ - if (mib_decoded && !sib_decoded && - (ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) - { - n = ue_dl_decode_sib(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync), - ((int) ceilf((float)3*(((sfn)/2)%4)/2))%4); - if (n < 0) { - fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); - exit(-1); - } else if (n == 0) { - nof_trials++; - } else { - bit_unpack_vector(data, data_unpacked, n); - void *dlsch_msg = bcch_dlsch_unpack(data_unpacked, n); - if (dlsch_msg) { - printf("\n");fflush(stdout); - cell_access_info_t cell_info; - bcch_dlsch_sib1_get_cell_access_info(dlsch_msg, &cell_info); - printf("Decoded SIB1. Cell ID: 0x%x\n", cell_info.cell_id); - - result->cell_id = cell_info.cell_id; - - bcch_dlsch_fprint(dlsch_msg, stdout); - - sib_decoded = true; - } - } - } else { - chest_ptr = &chest; - /* Run FFT for all subframe data */ - lte_fft_run_sf(&fft, sf_buffer, sf_symbols); - chest_dl_estimate(&chest, sf_symbols, ce, ue_sync_get_sfidx(&ue_sync)); - } - - result->rssi = VEC_CMA(vec_avg_power_cf(sf_buffer,SF_LEN(lte_symbol_sz(cell.nof_prb))), - result->rssi,nframes_measure); - result->rsrq = VEC_EMA(chest_dl_get_rsrq(chest_ptr),result->rsrq,0.01); - result->rsrp = VEC_CMA(chest_dl_get_rsrp(chest_ptr),result->rsrp,nframes_measure); - result->snr = VEC_EMA(chest_dl_get_snr(chest_ptr),result->snr,0.01); - nframes_measure++; - - // Plot and Printf - if ((nframes_measure%10) == 0) { - printf("CFO: %+8.4f KHz, SFO: %+8.4f Khz, RSSI: %5.1f dBm, " - "RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %5.1f dB\r", - ue_sync_get_cfo(&ue_sync)/1000, ue_sync_get_sfo(&ue_sync)/1000, - 10*log10(result->rssi*1000)-B210_DEFAULT_GAIN_CORREC, - 10*log10(result->rsrp*1000)-B210_DEFAULT_GAIN_CORREC, - 10*log10(result->rsrq), 10*log10(result->snr)); - if (verbose != VERBOSE_NONE) { - printf("\n"); - } - } - if (ue_sync_get_sfidx(&ue_sync) == 9) { - sfn++; - if (sfn == 1024) { - sfn = 0; - } - } - } 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 - - // Correct RSRP and RSSI measurements - result->rssi /= pow(10, 8); - result->rsrp /= pow(10, 8); - - ue_sync_free(&ue_sync); - - return 0; -} - - - diff --git a/lte/examples/cell_scanner/cell_scanner.h b/lte/examples/cell_scanner/cell_scanner.h deleted file mode 100644 index faf5b890a..000000000 --- a/lte/examples/cell_scanner/cell_scanner.h +++ /dev/null @@ -1,64 +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 "liblte/phy/phy.h" - -typedef struct { - int pss_max_frames; - int pbch_max_frames; - float cell_detect_early_stop_threshold; - int measure_avg_nof_frames; - char *uhd_args; -} cell_scanner_config_t; - -typedef struct { - lte_cell_t phy_cell; - uint32_t cell_id; - float rsrp; - float rsrq; - float rssi; - float snr; -} cell_scanner_result_t; - -typedef struct { - cell_scanner_config_t config; - void *uhd; -} cell_scanner_t; - -int cell_scanner_init(cell_scanner_t *q, - cell_scanner_config_t *config); - -void cell_scanner_close(cell_scanner_t *q); - -int cell_scanner_all_cells(cell_scanner_t *q, - float frequency, - cell_scanner_result_t *result); - -int cell_scanner_cell(cell_scanner_t *q, - float frequency, - int N_id_2, - cell_scanner_result_t *result); diff --git a/lte/examples/cell_scanner/cell_scanner_test.c b/lte/examples/cell_scanner/cell_scanner_test.c deleted file mode 100644 index 52a40cb8d..000000000 --- a/lte/examples/cell_scanner/cell_scanner_test.c +++ /dev/null @@ -1,143 +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 -#include -#include -#include -#include - -#include "liblte/rrc/rrc.h" -#include "liblte/phy/phy.h" -#include "liblte/cuhd/cuhd.h" -#include "cell_scanner.h" - - -/********************************************************************** - * Program arguments processing - ***********************************************************************/ -typedef struct { - int nof_subframes; - int force_N_id_2; - char *uhd_args; - float uhd_freq; -}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; -} - -void usage(prog_args_t *args, char *prog) { - printf("Usage: %s [alnv] -f rx_frequency (in Hz)\n", prog); - printf("\t-a UHD args [Default %s]\n", args->uhd_args); - 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, "alnvf")) != -1) { - switch (opt) { - case 'a': - args->uhd_args = 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); - } -} -/**********************************************************************/ - -int main(int argc, char **argv) { - prog_args_t prog_args; - cell_scanner_result_t result; - cell_scanner_config_t cfg; - cell_scanner_t cs; - - parse_args(&prog_args, argc, argv); - - // Peak-to-sidelobe ratio (PSR) threshold for cell detection early stopping. - cfg.cell_detect_early_stop_threshold = 20.0; // This is a normal value. - // maximum 5 ms frames that will be scanned maximum in the case the threshold is not exceed - // ie for bad cells - cfg.pss_max_frames = 50; // this is 250 ms - - // maximum 5 ms frames that will be received to decode the PBCH - // ie for bad cells - cfg.pbch_max_frames = 500; // this is 2500 ms - - // Number of 1 ms subframes that will be used to compute rsrp, rsrq, snr, etc average - cfg.measure_avg_nof_frames = 1000; // 1 sec - - cfg.uhd_args = prog_args.uhd_args; - - // Init USRP - if (cell_scanner_init(&cs, &cfg)) { - fprintf(stderr, "Error initiating cell scanner\n"); - exit(-1); - } - - // Scan for a frequency - if (prog_args.force_N_id_2 < 0) { - // We have 2 options, either we scan for the three possible N_id_2 root sequences... - cell_scanner_all_cells(&cs, prog_args.uhd_freq, &result); - } else { - // or we scan for a single one. - cell_scanner_cell(&cs, prog_args.uhd_freq, prog_args.force_N_id_2, &result); - } - - printf("\nResult: CellID: %d, PHYID: %d, RSRP: %.1f dBm, RSRQ: %.1f dB, SNR: %.1f dB\n", - result.cell_id, result.phy_cell.id, - 10*log10(result.rsrp*1000), 10*log10(result.rsrq), 10*log10(result.snr)); -} diff --git a/lte/phy/include/liblte/phy/phch/pcfich.h b/lte/phy/include/liblte/phy/phch/pcfich.h index cd87c14f9..c151a4d1a 100644 --- a/lte/phy/include/liblte/phy/phch/pcfich.h +++ b/lte/phy/include/liblte/phy/phch/pcfich.h @@ -33,13 +33,12 @@ #include "liblte/phy/mimo/precoding.h" #include "liblte/phy/mimo/layermap.h" #include "liblte/phy/modem/mod.h" -#include "liblte/phy/modem/demod_hard.h" +#include "liblte/phy/modem/demod_soft.h" #include "liblte/phy/scrambling/scrambling.h" #include "liblte/phy/phch/regs.h" -#define PCFICH_CFI_LEN 32 -#define PCFICH_RE PCFICH_CFI_LEN/2 -#define PCFICH_MAX_DISTANCE 5 +#define PCFICH_CFI_LEN 32 +#define PCFICH_RE PCFICH_CFI_LEN/2 typedef _Complex float cf_t; @@ -56,13 +55,19 @@ typedef struct LIBLTE_API { cf_t pcfich_symbols[MAX_PORTS][PCFICH_RE]; cf_t pcfich_x[MAX_PORTS][PCFICH_RE]; cf_t pcfich_d[PCFICH_RE]; + + // cfi table in floats + float cfi_table_float[3][PCFICH_CFI_LEN]; /* bit message */ uint8_t data[PCFICH_CFI_LEN]; + /* received soft bits */ + float data_f[PCFICH_CFI_LEN]; + /* tx & rx objects */ modem_table_t mod; - demod_hard_t demod; + demod_soft_t demod; sequence_t seq_pcfich[NSUBFRAMES_X_FRAME]; precoding_t precoding; @@ -80,7 +85,7 @@ LIBLTE_API int pcfich_decode(pcfich_t *q, float noise_estimate, uint32_t subframe, uint32_t *cfi, - uint32_t *distance); + float *corr_result); LIBLTE_API int pcfich_encode(pcfich_t *q, uint32_t cfi, diff --git a/lte/phy/lib/phch/src/pbch.c b/lte/phy/lib/phch/src/pbch.c index 579aea90b..05e00a9c4 100644 --- a/lte/phy/lib/phch/src/pbch.c +++ b/lte/phy/lib/phch/src/pbch.c @@ -148,6 +148,7 @@ int pbch_init(pbch_t *q, lte_cell_t cell) { demod_soft_init(&q->demod); demod_soft_table_set(&q->demod, &q->mod); demod_soft_alg_set(&q->demod, APPROX); + if (sequence_pbch(&q->seq_pbch, q->cell.cp, q->cell.id)) { goto clean; } diff --git a/lte/phy/lib/phch/src/pcfich.c b/lte/phy/lib/phch/src/pcfich.c index 5dd68ea05..44916dc9c 100644 --- a/lte/phy/lib/phch/src/pcfich.c +++ b/lte/phy/lib/phch/src/pcfich.c @@ -42,11 +42,15 @@ #include "liblte/phy/utils/debug.h" // Table 5.3.4-1 -static uint8_t cfi_table[4][PCFICH_CFI_LEN] = { { 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, - 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, { 1, 0, 1, +static uint8_t cfi_table[4][PCFICH_CFI_LEN] = { + { 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, + 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, + { 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, - 0, 1, 1, 0 }, { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, - 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0 }, + { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, + 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // reserved }; @@ -74,18 +78,26 @@ int pcfich_init(pcfich_t *q, regs_t *regs, lte_cell_t cell) { fprintf(stderr, "Error initializing precoding\n"); } - if (modem_table_lte(&q->mod, LTE_QPSK, false)) { + if (modem_table_lte(&q->mod, LTE_QPSK, true)) { goto clean; } - demod_hard_init(&q->demod); - demod_hard_table_set(&q->demod, LTE_QPSK); + demod_soft_init(&q->demod); + demod_soft_table_set(&q->demod, &q->mod); + demod_soft_alg_set(&q->demod, APPROX); for (int nsf = 0; nsf < NSUBFRAMES_X_FRAME; nsf++) { if (sequence_pcfich(&q->seq_pcfich[nsf], 2 * nsf, q->cell.id)) { goto clean; } } + + /* convert cfi bit tables to floats for demodulation */ + for (int i=0;i<3;i++) { + for (int j=0;jcfi_table_float[i][j] = (float) 2.0*cfi_table[i][j]-1.0; + } + } q->nof_symbols = PCFICH_RE; @@ -112,26 +124,22 @@ void pcfich_free(pcfich_t *q) { /** Finds the CFI with minimum distance with the vector of received 32 bits. * Saves the CFI value in the cfi pointer and returns the distance. */ -int pcfich_cfi_decode(uint8_t bits[PCFICH_CFI_LEN], uint32_t *cfi) { - int i, j; - int distance, index = -1; - int min = 32; - +float pcfich_cfi_decode(pcfich_t *q, uint32_t *cfi) { + int i; + int index = 0; + float max_corr = 0; + for (i = 0; i < 3; i++) { - distance = 0; - for (j = 0; j < PCFICH_CFI_LEN; j++) { - distance += (bits[j] ^ cfi_table[i][j]); - } - DEBUG("CFI=%d, distance:%d\n", i, distance); - if (distance < min) { - min = distance; - index = i; + float corr = vec_dot_prod_fff(q->cfi_table_float[i], q->data_f, PCFICH_CFI_LEN); + if (corr > max_corr) { + max_corr = corr; + index = i; } } if (cfi) { *cfi = index + 1; } - return min; + return max_corr; } /** Encodes the CFI producing a vector of 32 bits. @@ -151,8 +159,8 @@ int pcfich_cfi_encode(int cfi, uint8_t bits[PCFICH_CFI_LEN]) { * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error */ int pcfich_decode(pcfich_t *q, cf_t *slot_symbols, cf_t *ce[MAX_PORTS], float noise_estimate, - uint32_t nsubframe, uint32_t *cfi, uint32_t *distance) { - int dist; + uint32_t nsubframe, uint32_t *cfi, float *corr_result) +{ /* Set pointers for layermapping & precoding */ int i; @@ -200,21 +208,18 @@ int pcfich_decode(pcfich_t *q, cf_t *slot_symbols, cf_t *ce[MAX_PORTS], float no } /* demodulate symbols */ - demod_hard_demodulate(&q->demod, q->pcfich_d, q->data, q->nof_symbols); + demod_soft_sigma_set(&q->demod, 1.0); + demod_soft_demodulate(&q->demod, q->pcfich_d, q->data_f, q->nof_symbols); /* Scramble with the sequence for slot nslot */ - scrambling_b(&q->seq_pcfich[nsubframe], q->data); + scrambling_f(&q->seq_pcfich[nsubframe], q->data_f); /* decode CFI */ - dist = pcfich_cfi_decode(q->data, cfi); - if (distance) { - *distance = dist; - } - if (dist < PCFICH_MAX_DISTANCE) { - return 1; - } else { - return 0; + float corr = pcfich_cfi_decode(q, cfi); + if (corr_result) { + *corr_result = corr; } + return 1; } else { return LIBLTE_ERROR_INVALID_INPUTS; } diff --git a/lte/phy/lib/phch/test/pcfich_file_test.c b/lte/phy/lib/phch/test/pcfich_file_test.c index e91fa150b..e6bd53359 100644 --- a/lte/phy/lib/phch/test/pcfich_file_test.c +++ b/lte/phy/lib/phch/test/pcfich_file_test.c @@ -190,7 +190,8 @@ void base_free() { } int main(int argc, char **argv) { - uint32_t cfi, distance; + uint32_t cfi; + float cfi_corr; int n; if (argc < 3) { @@ -226,8 +227,9 @@ int main(int argc, char **argv) { INFO("Decoding PCFICH\n", 0); - n = pcfich_decode(&pcfich, fft_buffer, ce, chest_dl_get_noise_estimate(&chest), 0, &cfi, &distance); - printf("cfi: %d, distance: %d\n", cfi, distance); + + n = pcfich_decode(&pcfich, fft_buffer, ce, chest_dl_get_noise_estimate(&chest), 0, &cfi, &cfi_corr); + printf("cfi: %d, distance: %f\n", cfi, cfi_corr); base_free(); @@ -238,7 +240,7 @@ int main(int argc, char **argv) { printf("Could not decode PCFICH\n"); exit(-1); } else { - if (distance < 4 && cfi == 1) { + if (cfi_corr > 4 && cfi == 1) { exit(0); } else { exit(-1); diff --git a/lte/phy/lib/phch/test/pcfich_test.c b/lte/phy/lib/phch/test/pcfich_test.c index f4f907848..ab90f1358 100644 --- a/lte/phy/lib/phch/test/pcfich_test.c +++ b/lte/phy/lib/phch/test/pcfich_test.c @@ -82,8 +82,9 @@ int main(int argc, char **argv) { cf_t *ce[MAX_PORTS]; int nof_re; cf_t *slot_symbols[MAX_PORTS]; - uint32_t cfi, cfi_rx, nsf, distance; + uint32_t cfi, cfi_rx, nsf; int cid, max_cid; + float corr_res; parse_args(argc,argv); @@ -139,16 +140,11 @@ int main(int argc, char **argv) { slot_symbols[0][j] += slot_symbols[i][j]; } } - if (pcfich_decode(&pcfich, slot_symbols[0], ce, 0, nsf, &cfi_rx, &distance)<0) { - exit(-1); - } - INFO("cfi_tx: %d, cfi_rx: %d, ns: %d, distance: %d\n", - cfi, cfi_rx, nsf, distance); - - if (distance) { - printf("Error\n"); + if (pcfich_decode(&pcfich, slot_symbols[0], ce, 0, nsf, &cfi_rx, &corr_res)<0) { exit(-1); } + INFO("cfi_tx: %d, cfi_rx: %d, ns: %d, distance: %f\n", + cfi, cfi_rx, nsf, corr_res); } } pcfich_free(&pcfich); diff --git a/lte/phy/lib/phch/test/pcfich_test_mex.c b/lte/phy/lib/phch/test/pcfich_test_mex.c index 4fff6cc7e..2535bb816 100644 --- a/lte/phy/lib/phch/test/pcfich_test_mex.c +++ b/lte/phy/lib/phch/test/pcfich_test_mex.c @@ -70,12 +70,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } if (chest_dl_init(&chest, cell)) { - fprintf(stderr, "Error initializing equalizer\n"); + mexErrMsgTxt("Error initializing equalizer\n"); return; } if (lte_fft_init(&fft, cell.cp, cell.nof_prb)) { - fprintf(stderr, "Error initializing FFT\n"); + mexErrMsgTxt("Error initializing FFT\n"); return; } @@ -85,7 +85,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } if (pcfich_init(&pcfich, ®s, cell)) { - fprintf(stderr, "Error creating PBCH object\n"); + mexErrMsgTxt("Error creating PBCH object\n"); return; } @@ -124,8 +124,9 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } - uint32_t cfi, distance; - int n = pcfich_decode(&pcfich, input_fft, ce, noise_power, sf_idx, &cfi, &distance); + uint32_t cfi; + float corr_res; + int n = pcfich_decode(&pcfich, input_fft, ce, noise_power, sf_idx, &cfi, &corr_res); if (nlhs >= 1) { if (n < 0) { diff --git a/lte/phy/lib/ue/src/ue_dl.c b/lte/phy/lib/ue/src/ue_dl.c index 1b0b57154..f19557e22 100644 --- a/lte/phy/lib/ue/src/ue_dl.c +++ b/lte/phy/lib/ue/src/ue_dl.c @@ -174,7 +174,8 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx) { int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32_t rvidx) { - uint32_t cfi, cfi_distance, i; + uint32_t cfi, i; + float cfi_corr; ra_pdsch_t ra_dl; dci_location_t locations[MAX_CANDIDATES]; dci_msg_t dci_msg; @@ -195,12 +196,12 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui /* First decode PCFICH and obtain CFI */ if (pcfich_decode(&q->pcfich, q->sf_symbols, q->ce, - chest_dl_get_noise_estimate(&q->chest), sf_idx, &cfi, &cfi_distance)<0) { + chest_dl_get_noise_estimate(&q->chest), sf_idx, &cfi, &cfi_corr)<0) { fprintf(stderr, "Error decoding PCFICH\n"); return LIBLTE_ERROR; } - INFO("Decoded CFI=%d with distance %d\n", cfi, cfi_distance); + INFO("Decoded CFI=%d with correlation %.2f\n", cfi, cfi_corr); if (regs_set_cfi(&q->regs, cfi)) { fprintf(stderr, "Error setting CFI\n"); diff --git a/lte/phy/lib/ue/src/ue_mib.c b/lte/phy/lib/ue/src/ue_mib.c index 644b4289a..e8f6c7096 100644 --- a/lte/phy/lib/ue/src/ue_mib.c +++ b/lte/phy/lib/ue/src/ue_mib.c @@ -201,7 +201,7 @@ int ue_mib_sync_decode(ue_mib_sync_t * q, int ret = LIBLTE_ERROR_INVALID_INPUTS; cf_t *sf_buffer = NULL; uint32_t nof_frames = 0; - int mib_ret; + int mib_ret = MIB_NOTFOUND; if (q != NULL) { diff --git a/lte/phy/lib/ue/src/ue_sync.c b/lte/phy/lib/ue/src/ue_sync.c index f38f5e4ce..d82e5c709 100644 --- a/lte/phy/lib/ue/src/ue_sync.c +++ b/lte/phy/lib/ue/src/ue_sync.c @@ -272,7 +272,7 @@ int track_peak_no(ue_sync_t *q) { /* if we missed too many PSS go back to FIND */ q->frame_no_cnt++; if (q->frame_no_cnt >= TRACK_MAX_LOST) { - printf("\n%d frames lost. Going back to FIND\n", (int) q->frame_no_cnt); + INFO("\n%d frames lost. Going back to FIND\n", (int) q->frame_no_cnt); q->state = SF_FIND; } else { INFO("Tracking peak not found. Peak %.3f, %d lost\n",