From 103ead62985b7caccc7ce4848f5cf7aa67dc30c6 Mon Sep 17 00:00:00 2001 From: ismagom Date: Mon, 24 Nov 2014 16:05:15 +0000 Subject: [PATCH] Fixed pdsch_enodeb, bcch decoding for 20 MHz and CFO correction --- lte/examples/pdsch_enodeb.c | 23 ++++++++++++-------- lte/examples/pdsch_ue.c | 15 ++++++++----- lte/phy/include/liblte/phy/ue/ue_mib.h | 2 ++ lte/phy/lib/ch_estimation/src/refsignal_dl.c | 2 +- lte/phy/lib/ue/src/ue_dl.c | 3 --- lte/phy/lib/ue/src/ue_mib.c | 15 +++++++++++++ lte/phy/lib/ue/src/ue_sync.c | 2 +- lte/rrc/lib/messages/src/bcch.c | 8 +++++-- 8 files changed, 49 insertions(+), 21 deletions(-) diff --git a/lte/examples/pdsch_enodeb.c b/lte/examples/pdsch_enodeb.c index ac9c4e154..7d65e5143 100644 --- a/lte/examples/pdsch_enodeb.c +++ b/lte/examples/pdsch_enodeb.c @@ -249,6 +249,7 @@ int main(int argc, char **argv) { dci_msg_t dci_msg; dci_location_t locations[NSUBFRAMES_X_FRAME][10]; uint32_t sfn; + chest_dl_t est; #ifdef DISABLE_UHD if (argc < 3) { @@ -263,6 +264,10 @@ int main(int argc, char **argv) { sf_n_re = 2 * CPNORM_NSYMB * cell.nof_prb * RE_X_RB; sf_n_samples = 2 * SLOT_LEN(lte_symbol_sz(cell.nof_prb)); + cell.phich_length = PHICH_NORM; + cell.phich_resources = R_1; + sfn = 0; + /* this *must* be called after setting slot_len_* */ base_init(); @@ -270,12 +275,14 @@ int main(int argc, char **argv) { pss_generate(pss_signal, N_id_2); sss_generate(sss_signal0, sss_signal5, cell.id); + //refsignal_cs_generate(&csr_signal, cell); + /* Generate CRS signals */ - refsignal_cs_generate(&csr_signal, cell); + if (chest_dl_init(&est, cell)) { + fprintf(stderr, "Error initializing equalizer\n"); + exit(-1); + } - cell.phich_length = PHICH_NORM; - cell.phich_resources = R_1; - sfn = 0; for (i = 0; i < MAX_PORTS; i++) { // now there's only 1 port sf_symbols[i] = sf_buffer; @@ -324,9 +331,6 @@ int main(int argc, char **argv) { fprintf(stderr, "Error configuring HARQ process\n"); exit(-1); } - - bcch_bch_pack(&cell, 0, bch_payload_packed, BCH_PAYLOAD_LEN/8); - bit_pack_vector(bch_payload_packed, bch_payload, BCH_PAYLOAD_LEN); while (nf < nof_frames || nof_frames == -1) { for (sf_idx = 0; sf_idx < NSUBFRAMES_X_FRAME && (nf < nof_frames || nof_frames == -1); sf_idx++) { @@ -337,13 +341,14 @@ int main(int argc, char **argv) { sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_buffer, cell.nof_prb, CPNORM); } + refsignal_cs_put_sf(cell, 0, est.csr_signal.pilots[0][sf_idx], sf_buffer); bcch_bch_pack(&cell, sfn, bch_payload_packed, BCH_PAYLOAD_LEN/8); + bit_pack_vector(bch_payload_packed, bch_payload, BCH_PAYLOAD_LEN); if (sf_idx == 0) { pbch_encode(&pbch, bch_payload, sf_symbols); } - refsignal_cs_put_sf(cell, 0, csr_signal.pilots[0][sf_idx], sf_buffer); pcfich_encode(&pcfich, cfi, sf_symbols, sf_idx); @@ -362,7 +367,7 @@ int main(int argc, char **argv) { fprintf(stderr, "Error encoding PDSCH\n"); exit(-1); } - + /* Transform to OFDM symbols */ lte_ifft_run_sf(&ifft, sf_buffer, output_buffer); diff --git a/lte/examples/pdsch_ue.c b/lte/examples/pdsch_ue.c index 0701e6fa9..f79c1a273 100644 --- a/lte/examples/pdsch_ue.c +++ b/lte/examples/pdsch_ue.c @@ -206,10 +206,8 @@ int main(int argc, char **argv) { fprintf(stderr, "Error initaiting UE MIB decoder\n"); exit(-1); } - - pdsch_set_rnti(&ue_dl.pdsch, prog_args.rnti); // This is the RNTI we want to look for - + pdsch_set_rnti(&ue_dl.pdsch, prog_args.rnti); /* Initialize subframe counter */ sf_cnt = 0; @@ -301,7 +299,7 @@ int main(int argc, char **argv) { #include "liblte/graphics/plot.h" plot_real_t poutfft; plot_real_t pce; -plot_scatter_t pscatrecv, pscatequal; +plot_scatter_t pscatrecv, pscatequal, pscatequal_pdcch; float tmp_plot[SLOT_LEN_RE(MAX_PRB, CPNORM)]; float tmp_plot2[SLOT_LEN_RE(MAX_PRB, CPNORM)]; @@ -324,9 +322,15 @@ void init_plots() { plot_scatter_setYAxisScale(&pscatrecv, -4, 4); plot_scatter_init(&pscatequal); - plot_scatter_setTitle(&pscatequal, "Equalized Symbols"); + plot_scatter_setTitle(&pscatequal, "PDSCH - Equalized Symbols"); plot_scatter_setXAxisScale(&pscatequal, -2, 2); plot_scatter_setYAxisScale(&pscatequal, -2, 2); + + plot_scatter_init(&pscatequal_pdcch); + plot_scatter_setTitle(&pscatequal_pdcch, "PDCCH - Equalized Symbols"); + plot_scatter_setXAxisScale(&pscatequal_pdcch, -2, 2); + plot_scatter_setYAxisScale(&pscatequal_pdcch, -2, 2); + } void do_plots(ue_dl_t *q, uint32_t sf_idx) { @@ -349,6 +353,7 @@ void do_plots(ue_dl_t *q, uint32_t sf_idx) { 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); plot_scatter_setNewData(&pscatequal, q->pdsch.pdsch_d, nof_symbols); + plot_scatter_setNewData(&pscatequal_pdcch, q->pdcch.pdcch_d, 36*q->pdcch.nof_cce); } #endif diff --git a/lte/phy/include/liblte/phy/ue/ue_mib.h b/lte/phy/include/liblte/phy/ue/ue_mib.h index 45c14e276..3473241e6 100644 --- a/lte/phy/include/liblte/phy/ue/ue_mib.h +++ b/lte/phy/include/liblte/phy/ue/ue_mib.h @@ -58,6 +58,7 @@ #define MIB_MAX_PORTS 4 #define MIB_FRAME_SIZE_SEARCH 9600 +#define MIB_FFT_SIZE 128 #define MIB_FRAME_UNALIGNED -3 #define MIB_FOUND 1 @@ -69,6 +70,7 @@ typedef struct LIBLTE_API { cf_t *sf_symbols; cf_t *ce[MIB_MAX_PORTS]; + cfo_t cfocorr; lte_fft_t fft; chest_dl_t chest; pbch_t pbch; diff --git a/lte/phy/lib/ch_estimation/src/refsignal_dl.c b/lte/phy/lib/ch_estimation/src/refsignal_dl.c index 168637c3b..ee7b3b7f0 100644 --- a/lte/phy/lib/ch_estimation/src/refsignal_dl.c +++ b/lte/phy/lib/ch_estimation/src/refsignal_dl.c @@ -210,7 +210,7 @@ int refsignal_cs_put_sf(lte_cell_t cell, uint32_t port_id, cf_t *pilots, cf_t *s fidx = ((refsignal_cs_v(port_id, l) + (cell.id % 6)) % 6); for (i = 0; i < 2*cell.nof_prb; i++) { sf_symbols[SAMPLE_IDX(cell.nof_prb, nsymbol, fidx)] = pilots[REFSIGNAL_PILOT_IDX(i,l,cell)]; - fidx += 6; // 1 reference every 6 RE + fidx += RE_X_RB/2; // 1 reference every 6 RE } } return LIBLTE_SUCCESS; diff --git a/lte/phy/lib/ue/src/ue_dl.c b/lte/phy/lib/ue/src/ue_dl.c index 5b15e3f7c..5d122b338 100644 --- a/lte/phy/lib/ue/src/ue_dl.c +++ b/lte/phy/lib/ue/src/ue_dl.c @@ -174,8 +174,6 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32 /* Get channel estimates for each port */ chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, sf_idx); - - /* 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) { @@ -240,7 +238,6 @@ int ue_dl_decode(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint32 } } if (q->harq_process[0].mcs.mod > 0) { - ret = pdsch_decode(&q->pdsch, q->sf_symbols, q->ce, chest_dl_get_noise_estimate(&q->chest), data, sf_idx, &q->harq_process[0], rvidx); if (ret == LIBLTE_ERROR) { diff --git a/lte/phy/lib/ue/src/ue_mib.c b/lte/phy/lib/ue/src/ue_mib.c index 1f9937927..69136d980 100644 --- a/lte/phy/lib/ue/src/ue_mib.c +++ b/lte/phy/lib/ue/src/ue_mib.c @@ -90,6 +90,12 @@ int ue_mib_init(ue_mib_t * q, sync_set_cp(&q->sfind, cell.cp); } + if (cfo_init(&q->cfocorr, 5*SF_LEN_PRB(cell.nof_prb))) { + fprintf(stderr, "Error initiating CFO\n"); + goto clean_exit; + } + + if (lte_fft_init(&q->fft, cell.cp, cell.nof_prb)) { fprintf(stderr, "Error initializing FFT\n"); goto clean_exit; @@ -124,6 +130,7 @@ void ue_mib_free(ue_mib_t * q) free(q->ce[i]); } } + cfo_free(&q->cfocorr); sync_free(&q->sfind); chest_dl_free(&q->chest); pbch_free(&q->pbch); @@ -161,6 +168,7 @@ int ue_mib_decode_aligned_frame(ue_mib_t * q, cf_t *input, if (ret < 0) { return LIBLTE_ERROR; } + INFO("Channel estimated for %d ports, Noise: %f\n", q->chest.cell.nof_ports, chest_dl_get_noise_estimate(&q->chest)); /* Reset decoder if we missed a frame */ @@ -253,6 +261,13 @@ int ue_mib_sync_and_decode(ue_mib_t * q, nf*MIB_FRAME_SIZE_SEARCH + peak_idx > MIB_FRAME_SIZE_SEARCH/10) { // PSS and SSS detected and we have space to decode the PBCH. + + // Apply CFO correction + INFO("Correcting CFO: %f\n", sync_get_cfo(&q->sfind)); + cfo_correct(&q->cfocorr, &signal[nf*MIB_FRAME_SIZE_SEARCH], &signal[nf*MIB_FRAME_SIZE_SEARCH], + -sync_get_cfo(&q->sfind) / MIB_FFT_SIZE); + + INFO("Trying to decode PBCH\n",0); ret = ue_mib_decode_aligned_frame(q, &signal[nf*MIB_FRAME_SIZE_SEARCH+peak_idx-MIB_FRAME_SIZE_SEARCH/10], diff --git a/lte/phy/lib/ue/src/ue_sync.c b/lte/phy/lib/ue/src/ue_sync.c index 173848669..eb6a67d15 100644 --- a/lte/phy/lib/ue/src/ue_sync.c +++ b/lte/phy/lib/ue/src/ue_sync.c @@ -338,7 +338,7 @@ int ue_sync_get_buffer(ue_sync_t *q, cf_t **sf_symbols) { } /* Do CFO Correction and deliver the frame */ - cfo_correct(&q->cfocorr, q->input_buffer, q->input_buffer, q->cur_cfo / CURRENT_FFTSIZE); + cfo_correct(&q->cfocorr, q->input_buffer, q->input_buffer, -q->cur_cfo / CURRENT_FFTSIZE); *sf_symbols = q->input_buffer; break; diff --git a/lte/rrc/lib/messages/src/bcch.c b/lte/rrc/lib/messages/src/bcch.c index 423148ae5..c57d6bb53 100644 --- a/lte/rrc/lib/messages/src/bcch.c +++ b/lte/rrc/lib/messages/src/bcch.c @@ -85,7 +85,7 @@ int bcch_bch_pack(lte_cell_t *cell, uint32_t sfn, uint8_t *buffer, uint32_t buff sfn=(sfn>>2); req.systemFrameNumber.buf = (uint8_t*) &sfn; req.systemFrameNumber.size = 1; - req.systemFrameNumber.bits_unused= 0; + req.systemFrameNumber.bits_unused = 0; int spare = 0; req.spare.buf = (uint8_t*) &spare; req.spare.size = 2; @@ -97,7 +97,6 @@ int bcch_bch_pack(lte_cell_t *cell, uint32_t sfn, uint8_t *buffer, uint32_t buff printf("Failed to encode element %s\n", n.failed_type ? n.failed_type->name : ""); return LIBLTE_ERROR; } - return LIBLTE_SUCCESS; } @@ -131,6 +130,9 @@ int bcch_bch_unpack(uint8_t *buffer, uint32_t msg_nof_bits, lte_cell_t *cell, ui case MasterInformationBlock__dl_Bandwidth_n75: cell->nof_prb = 75; break; + case MasterInformationBlock__dl_Bandwidth_n100: + cell->nof_prb = 100; + break; } if (req->phich_Config.phich_Duration == PHICH_Config__phich_Duration_normal) { cell->phich_length = PHICH_NORM; @@ -155,6 +157,8 @@ int bcch_bch_unpack(uint8_t *buffer, uint32_t msg_nof_bits, lte_cell_t *cell, ui memcpy(&sfn_i, req->systemFrameNumber.buf, req->systemFrameNumber.size); if (sfn) { *sfn=(sfn_i<<2); + } else { + asn_fprint(stdout, &asn_DEF_MasterInformationBlock, req); } return LIBLTE_SUCCESS; }