From 6b8d019fce682623aa3bed413ae442ba02204184 Mon Sep 17 00:00:00 2001 From: ismagom Date: Fri, 13 Feb 2015 10:02:10 +0100 Subject: [PATCH] Added DFT Transform Precoding. Added PUSCH matlab test. Added UCI PUCCH coding --- lte/phy/include/liblte/phy/phch/cqi.h | 26 +++++- lte/phy/include/liblte/phy/phch/pusch.h | 20 +++-- lte/phy/include/liblte/phy/phch/sch.h | 2 +- lte/phy/include/liblte/phy/phch/uci.h | 33 ++++--- lte/phy/include/liblte/phy/phy.h | 14 +-- lte/phy/lib/phch/src/cqi.c | 24 ++++- lte/phy/lib/phch/src/pusch.c | 115 ++++++++++-------------- lte/phy/lib/phch/src/sch.c | 2 +- lte/phy/lib/phch/src/uci.c | 69 +++++++++++--- lte/phy/lib/phch/test/CMakeLists.txt | 1 + lte/phy/lib/phch/test/pusch_test.c | 77 +++++----------- 11 files changed, 215 insertions(+), 168 deletions(-) diff --git a/lte/phy/include/liblte/phy/phch/cqi.h b/lte/phy/include/liblte/phy/phch/cqi.h index 2a72c7b74..a0aaf9c16 100644 --- a/lte/phy/include/liblte/phy/phch/cqi.h +++ b/lte/phy/include/liblte/phy/phch/cqi.h @@ -58,15 +58,37 @@ typedef struct LIBLTE_API { uint32_t position_subband; // L-bit width } cqi_ue_subband_t; +/* Table 5.2.3.3.1-1: Fields for channel quality information feedback for wideband CQI reports +(transmission mode 1, transmission mode 2, transmission mode 3, transmission mode 7 and +transmission mode 8 configured without PMI/RI reporting). +This is for PUCCH Format 2 reports +*/ +typedef struct LIBLTE_API { + uint8_t wideband_cqi; // 4-bit width +} cqi_format2_wideband_t; + +typedef struct LIBLTE_API { + uint8_t subband_cqi; // 4-bit width + uint8_t subband_label; // 1- or 2-bit width +} cqi_format2_subband_t; + -LIBLTE_API void cqi_hl_subband_pack(cqi_hl_subband_t *msg, +LIBLTE_API int cqi_hl_subband_pack(cqi_hl_subband_t *msg, uint32_t N, uint8_t *buff, uint32_t buff_len); -LIBLTE_API void cqi_ue_subband_pack(cqi_ue_subband_t *msg, +LIBLTE_API int cqi_ue_subband_pack(cqi_ue_subband_t *msg, uint32_t L, uint8_t *buff, uint32_t buff_len); +LIBLTE_API int cqi_format2_wideband_pack(cqi_format2_wideband_t *msg, + uint8_t *buff, + uint32_t buff_len); + +LIBLTE_API int cqi_format2_subband_pack(cqi_format2_subband_t *msg, + uint8_t *buff, + uint32_t buff_len); + #endif // CQI_ diff --git a/lte/phy/include/liblte/phy/phch/pusch.h b/lte/phy/include/liblte/phy/phch/pusch.h index dbdd12eb6..424266ebb 100644 --- a/lte/phy/include/liblte/phy/phch/pusch.h +++ b/lte/phy/include/liblte/phy/phch/pusch.h @@ -26,7 +26,7 @@ */ -#ifndef PUCH_ +#ifndef PUSCH_ #define PUSCH_ #include "liblte/config.h" @@ -39,24 +39,28 @@ #include "liblte/phy/phch/regs.h" #include "liblte/phy/phch/sch.h" #include "liblte/phy/phch/harq.h" +#include "liblte/phy/filter/dft_precoding.h" #define TDEC_MAX_ITERATIONS 5 typedef _Complex float cf_t; -/* PDSCH object */ +/* PUSCH object */ typedef struct LIBLTE_API { lte_cell_t cell; uint32_t max_symbols; bool rnti_is_set; uint16_t rnti; + + dft_precoding_t dft_precoding; + + precoding_t equalizer; /* buffers */ // void buffers are shared for tx and rx - cf_t *ce[MAX_PORTS]; - cf_t *pusch_symbols[MAX_PORTS]; - cf_t *pusch_x[MAX_PORTS]; + cf_t *ce; + cf_t *pusch_z; cf_t *pusch_d; void *pusch_q; @@ -84,7 +88,7 @@ LIBLTE_API int pusch_set_rnti(pusch_t *q, LIBLTE_API int pusch_encode(pusch_t *q, uint8_t *data, - cf_t *sf_symbols[MAX_PORTS], + cf_t *sf_symbols, uint32_t nsubframe, harq_t *harq_process, uint32_t rv_idx); @@ -92,14 +96,14 @@ LIBLTE_API int pusch_encode(pusch_t *q, LIBLTE_API int pusch_uci_encode(pusch_t *q, uint8_t *data, uci_data_t uci_data, - cf_t *sf_symbols[MAX_PORTS], + cf_t *sf_symbols, uint32_t subframe, harq_t *harq_process, uint32_t rv_idx); LIBLTE_API int pusch_decode(pusch_t *q, cf_t *sf_symbols, - cf_t *ce[MAX_PORTS], + cf_t *ce, float noise_estimate, uint8_t *data, uint32_t nsubframe, diff --git a/lte/phy/include/liblte/phy/phch/sch.h b/lte/phy/include/liblte/phy/phch/sch.h index 632c8be23..9345a0615 100644 --- a/lte/phy/include/liblte/phy/phch/sch.h +++ b/lte/phy/include/liblte/phy/phch/sch.h @@ -65,7 +65,7 @@ typedef struct LIBLTE_API { crc_t crc_tb; crc_t crc_cb; - uci_cqi_t uci_cqi; + uci_cqi_pusch_t uci_cqi; } sch_t; diff --git a/lte/phy/include/liblte/phy/phch/uci.h b/lte/phy/include/liblte/phy/phch/uci.h index d4390903a..419a35fca 100644 --- a/lte/phy/include/liblte/phy/phch/uci.h +++ b/lte/phy/include/liblte/phy/phch/uci.h @@ -34,13 +34,16 @@ #include "liblte/phy/phch/harq.h" #include "liblte/phy/fec/crc.h" -#define MAX_CQI_LEN 512 +#define MAX_CQI_LEN_PUSCH 512 +#define MAX_CQI_LEN_PUCCH 13 +#define CQI_CODED_PUCCH_B 20 + typedef struct LIBLTE_API { crc_t crc; - uint8_t tmp_cqi[MAX_CQI_LEN]; - uint8_t encoded_cqi[3*MAX_CQI_LEN]; -} uci_cqi_t; + uint8_t tmp_cqi[MAX_CQI_LEN_PUSCH]; + uint8_t encoded_cqi[3*MAX_CQI_LEN_PUSCH]; +} uci_cqi_pusch_t; typedef struct LIBLTE_API { uint8_t *uci_cqi; @@ -54,17 +57,21 @@ typedef struct LIBLTE_API { float beta_ack; } uci_data_t; -LIBLTE_API int uci_cqi_init(uci_cqi_t *q); +LIBLTE_API int uci_cqi_init(uci_cqi_pusch_t *q); -LIBLTE_API void uci_cqi_free(uci_cqi_t *q); +LIBLTE_API void uci_cqi_free(uci_cqi_pusch_t *q); -LIBLTE_API int uci_encode_cqi(uci_cqi_t *q, - uint8_t *cqi_data, - uint32_t cqi_len, - float beta, - uint32_t Q_prime_ri, - harq_t *harq_process, - uint8_t *q_bits); +LIBLTE_API int uci_encode_cqi_pusch(uci_cqi_pusch_t *q, + uint8_t *cqi_data, + uint32_t cqi_len, + float beta, + uint32_t Q_prime_ri, + harq_t *harq_process, + uint8_t *q_bits); + +LIBLTE_API int uci_encode_cqi_pucch(uint8_t *cqi_data, + uint32_t cqi_len, + uint8_t b_bits[CQI_CODED_PUCCH_B]); LIBLTE_API int uci_encode_ack(uint8_t data, uint32_t O_cqi, diff --git a/lte/phy/include/liblte/phy/phy.h b/lte/phy/include/liblte/phy/phy.h index 6b3831681..98970437c 100644 --- a/lte/phy/include/liblte/phy/phy.h +++ b/lte/phy/include/liblte/phy/phy.h @@ -71,6 +71,7 @@ #include "liblte/phy/fec/rm_turbo.h" #include "liblte/phy/filter/filter2d.h" +#include "liblte/phy/filter/dft_precoding.h" #include "liblte/phy/io/binsource.h" #include "liblte/phy/io/filesink.h" @@ -86,17 +87,18 @@ #include "liblte/phy/mimo/precoding.h" #include "liblte/phy/mimo/layermap.h" -#include "liblte/phy/phch/regs.h" +#include "liblte/phy/phch/cqi.h" #include "liblte/phy/phch/dci.h" -#include "liblte/phy/phch/pdcch.h" -#include "liblte/phy/phch/pdsch.h" +#include "liblte/phy/phch/harq.h" #include "liblte/phy/phch/pbch.h" #include "liblte/phy/phch/pcfich.h" +#include "liblte/phy/phch/pdcch.h" +#include "liblte/phy/phch/pdsch.h" #include "liblte/phy/phch/phich.h" - -#include "liblte/phy/phch/sch.h" - #include "liblte/phy/phch/pusch.h" +#include "liblte/phy/phch/ra.h" +#include "liblte/phy/phch/regs.h" +#include "liblte/phy/phch/sch.h" #include "liblte/phy/phch/uci.h" #include "liblte/phy/ue/ue_sync.h" diff --git a/lte/phy/lib/phch/src/cqi.c b/lte/phy/lib/phch/src/cqi.c index 7db9ed271..2136ab555 100644 --- a/lte/phy/lib/phch/src/cqi.c +++ b/lte/phy/lib/phch/src/cqi.c @@ -41,17 +41,37 @@ #include "liblte/phy/utils/debug.h" -void cqi_hl_subband_pack(cqi_hl_subband_t *msg, uint32_t N, uint8_t *buff, uint32_t buff_len) +int cqi_hl_subband_pack(cqi_hl_subband_t *msg, uint32_t N, uint8_t *buff, uint32_t buff_len) { uint8_t *body_ptr = buff; bit_pack(msg->wideband_cqi, &body_ptr, 4); bit_pack(msg->subband_diff_cqi, &body_ptr, 2*N); + + return 4+2*N; } -void cqi_ue_subband_pack(cqi_ue_subband_t *msg, uint32_t L, uint8_t *buff, uint32_t buff_len) +int cqi_ue_subband_pack(cqi_ue_subband_t *msg, uint32_t L, uint8_t *buff, uint32_t buff_len) { uint8_t *body_ptr = buff; bit_pack(msg->wideband_cqi, &body_ptr, 4); bit_pack(msg->subband_diff_cqi, &body_ptr, 2); bit_pack(msg->subband_diff_cqi, &body_ptr, L); + + return 4+2+L; } + +int cqi_format2_wideband_pack(cqi_format2_wideband_t *msg, uint8_t *buff, uint32_t buff_len) +{ + uint8_t *body_ptr = buff; + bit_pack(msg->wideband_cqi, &body_ptr, 4); + return 4; +} + +int cqi_format2_subband_pack(cqi_format2_subband_t *msg, uint8_t *buff, uint32_t buff_len) +{ + uint8_t *body_ptr = buff; + bit_pack(msg->subband_cqi, &body_ptr, 4); + bit_pack(msg->subband_label, &body_ptr, 1); + return 4+1; +} + diff --git a/lte/phy/lib/phch/src/pusch.c b/lte/phy/lib/phch/src/pusch.c index 6caa342b4..f3491e413 100644 --- a/lte/phy/lib/phch/src/pusch.c +++ b/lte/phy/lib/phch/src/pusch.c @@ -41,7 +41,7 @@ #include "liblte/phy/utils/bit.h" #include "liblte/phy/utils/debug.h" #include "liblte/phy/utils/vector.h" - +#include "liblte/phy/filter/dft_precoding.h" #define MAX_PUSCH_RE(cp) (2 * CP_NSYMB(cp) * 12) @@ -118,6 +118,14 @@ int pusch_init(pusch_t *q, lte_cell_t cell) { sch_init(&q->dl_sch); + dft_precoding_init(&q->dft_precoding, cell.nof_prb); + + /* This is for equalization at receiver */ + if (precoding_init(&q->equalizer, SF_LEN_RE(cell.nof_prb, cell.cp))) { + fprintf(stderr, "Error initializing precoding\n"); + goto clean; + } + q->rnti_is_set = false; // Allocate floats for reception (LLRs). Buffer casted to uint8_t for transmission @@ -136,19 +144,13 @@ int pusch_init(pusch_t *q, lte_cell_t cell) { goto clean; } - for (i = 0; i < q->cell.nof_ports; i++) { - q->ce[i] = vec_malloc(sizeof(cf_t) * q->max_symbols); - if (!q->ce[i]) { - goto clean; - } - q->pusch_x[i] = vec_malloc(sizeof(cf_t) * q->max_symbols); - if (!q->pusch_x[i]) { - goto clean; - } - q->pusch_symbols[i] = vec_malloc(sizeof(cf_t) * q->max_symbols); - if (!q->pusch_symbols[i]) { - goto clean; - } + q->ce = vec_malloc(sizeof(cf_t) * q->max_symbols); + if (!q->ce) { + goto clean; + } + q->pusch_z = vec_malloc(sizeof(cf_t) * q->max_symbols); + if (!q->pusch_z) { + goto clean; } ret = LIBLTE_SUCCESS; @@ -172,18 +174,17 @@ void pusch_free(pusch_t *q) { if (q->pusch_g) { free(q->pusch_g); } - for (i = 0; i < q->cell.nof_ports; i++) { - if (q->ce[i]) { - free(q->ce[i]); - } - if (q->pusch_x[i]) { - free(q->pusch_x[i]); - } - if (q->pusch_symbols[i]) { - free(q->pusch_symbols[i]); - } + if (q->ce) { + free(q->ce); } + if (q->pusch_z) { + free(q->pusch_z); + } + + dft_precoding_free(&q->dft_precoding); + precoding_free(&q->equalizer); + for (i = 0; i < NSUBFRAMES_X_FRAME; i++) { sequence_free(&q->seq_pusch[i]); } @@ -215,13 +216,12 @@ int pusch_set_rnti(pusch_t *q, uint16_t rnti) { /** Decodes the PUSCH from the received symbols */ -int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_estimate, uint8_t *data, uint32_t subframe, +int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce, float noise_estimate, uint8_t *data, uint32_t subframe, harq_t *harq_process, uint32_t rv_idx) { /* Set pointers for layermapping & precoding */ - uint32_t i, n; - cf_t *x[MAX_LAYERS]; + uint32_t n; uint32_t nof_symbols, nof_bits, nof_bits_e; if (q != NULL && @@ -233,35 +233,32 @@ int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_ if (q->rnti_is_set) { nof_bits = harq_process->mcs.tbs; - nof_symbols = harq_process->prb_alloc.re_sf[subframe]; + nof_symbols = 2*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB*(CP_NSYMB(q->cell.cp)-1); nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod); - INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", subframe, lte_mod_string(harq_process->mcs.mod), nof_bits, nof_symbols, nof_bits_e, rv_idx); - /* number of layers equals number of ports */ - for (i = 0; i < q->cell.nof_ports; i++) { - x[i] = q->pusch_x[i]; - } - memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); - /* extract symbols */ - n = pusch_get(q, sf_symbols, q->pusch_symbols[0], &harq_process->prb_alloc, subframe); + n = pusch_get(q, sf_symbols, q->pusch_d, &harq_process->prb_alloc, subframe); if (n != nof_symbols) { fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n); return LIBLTE_ERROR; } /* extract channel estimates */ - for (i = 0; i < q->cell.nof_ports; i++) { - n = pusch_get(q, ce[i], q->ce[i], &harq_process->prb_alloc, subframe); - if (n != nof_symbols) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n); - return LIBLTE_ERROR; - } + n = pusch_get(q, ce, q->ce, &harq_process->prb_alloc, subframe); + if (n != nof_symbols) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n); + return LIBLTE_ERROR; } + predecoding_single(&q->equalizer, q->pusch_d, q->ce, q->pusch_z, + nof_symbols, noise_estimate); + + dft_predecoding(&q->dft_precoding, q->pusch_z, q->pusch_d, + harq_process->prb_alloc.slot[0].nof_prb, harq_process->N_symb_ul); + /* demodulate symbols * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, * thus we don't need tot set it in the LLRs normalization @@ -277,14 +274,13 @@ int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_ } else { fprintf(stderr, "Must call pusch_set_rnti() before calling pusch_decode()\n"); return LIBLTE_ERROR; - } - + } } else { return LIBLTE_ERROR_INVALID_INPUTS; } } -int pusch_qncode(pusch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_t subframe, +int pusch_encode(pusch_t *q, uint8_t *data, cf_t *sf_symbols, uint32_t subframe, harq_t *harq_process, uint32_t rv_idx) { uci_data_t uci_data; @@ -295,28 +291,19 @@ int pusch_qncode(pusch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_ /** Converts the PUSCH data bits to symbols mapped to the slot ready for transmission */ int pusch_uci_encode(pusch_t *q, uint8_t *data, uci_data_t uci_data, - cf_t *sf_symbols[MAX_PORTS], uint32_t subframe, + cf_t *sf_symbols, uint32_t subframe, harq_t *harq_process, uint32_t rv_idx) { - int i; uint32_t nof_symbols, nof_bits_ulsch, nof_bits_e; - /* Set pointers for layermapping & precoding */ - cf_t *x[MAX_LAYERS]; - int ret = LIBLTE_ERROR_INVALID_INPUTS; + int ret = LIBLTE_ERROR_INVALID_INPUTS; - if (q != NULL && + if (q != NULL && data != NULL && subframe < 10 && harq_process != NULL) { if (q->rnti_is_set) { - for (i=0;icell.nof_ports;i++) { - if (sf_symbols[i] == NULL) { - return LIBLTE_ERROR_INVALID_INPUTS; - } - } - nof_bits_ulsch = harq_process->mcs.tbs; nof_symbols = 2*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB*(CP_NSYMB(q->cell.cp)-1); nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod); @@ -339,12 +326,6 @@ int pusch_uci_encode(pusch_t *q, uint8_t *data, uci_data_t uci_data, INFO("Encoding PUSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", subframe, lte_mod_string(harq_process->mcs.mod), nof_bits_ulsch, nof_symbols, nof_bits_e, rv_idx); - - /* number of layers equals number of ports */ - for (i = 0; i < q->cell.nof_ports; i++) { - x[i] = q->pusch_x[i]; - } - memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); if (ulsch_uci_encode(&q->dl_sch, data, uci_data, q->pusch_g, harq_process, rv_idx, q->pusch_q)) { @@ -356,11 +337,11 @@ int pusch_uci_encode(pusch_t *q, uint8_t *data, uci_data_t uci_data, mod_modulate(&q->mod[harq_process->mcs.mod], (uint8_t*) q->pusch_q, q->pusch_d, nof_bits_e); - /* mapping to resource elements */ + dft_precoding(&q->dft_precoding, q->pusch_d, q->pusch_z, + harq_process->prb_alloc.slot[0].nof_prb, harq_process->N_symb_ul); - for (i = 0; i < q->cell.nof_ports; i++) { - pusch_put(q, q->pusch_symbols[i], sf_symbols[i], &harq_process->prb_alloc, subframe); - } + /* mapping to resource elements */ + pusch_put(q, q->pusch_z, sf_symbols, &harq_process->prb_alloc, subframe); ret = LIBLTE_SUCCESS; } else { diff --git a/lte/phy/lib/phch/src/sch.c b/lte/phy/lib/phch/src/sch.c index 0544d68c9..491400737 100644 --- a/lte/phy/lib/phch/src/sch.c +++ b/lte/phy/lib/phch/src/sch.c @@ -467,7 +467,7 @@ int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *g_bi // Encode CQI if (uci_data.uci_cqi_len > 0) { - ret = uci_encode_cqi(&q->uci_cqi, uci_data.uci_cqi, uci_data.uci_cqi_len, uci_data.beta_cqi, + ret = uci_encode_cqi_pusch(&q->uci_cqi, uci_data.uci_cqi, uci_data.uci_cqi_len, uci_data.beta_cqi, Q_prime_ri, harq_process, g_bits); if (ret < 0) { return ret; diff --git a/lte/phy/lib/phch/src/uci.c b/lte/phy/lib/phch/src/uci.c index f2cbe056c..00814fd03 100644 --- a/lte/phy/lib/phch/src/uci.c +++ b/lte/phy/lib/phch/src/uci.c @@ -44,7 +44,7 @@ #include "liblte/phy/utils/debug.h" /* Table 5.2.2.6.4-1: Basis sequence for (32, O) code */ -static uint8_t M_basis_seq[32][11]={ +static uint8_t M_basis_seq_pusch[32][11]={ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, {1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1 }, {1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 }, @@ -79,14 +79,38 @@ static uint8_t M_basis_seq[32][11]={ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }; -int uci_cqi_init(uci_cqi_t *q) { + +static uint8_t M_basis_seq_pucch[20][13]={ + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}, + {1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0}, + {1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1}, + {1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1}, + {1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1}, + {1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1}, + {1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1}, + {1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1}, + {1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1}, + {1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1}, + {1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1}, + {1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1}, + {1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1}, + {1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1}, + {1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1}, + {1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1}, + {1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1}, + {1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1}, + {1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, + }; + +int uci_cqi_init(uci_cqi_pusch_t *q) { if (crc_init(&q->crc, LTE_CRC8, 8)) { return LIBLTE_ERROR; } return LIBLTE_SUCCESS; } -void uci_cqi_free(uci_cqi_t *q) { +void uci_cqi_free(uci_cqi_pusch_t *q) { } @@ -112,17 +136,17 @@ static uint32_t Q_prime_cqi(uint32_t O, float beta, uint32_t Q_prime_ri, harq_t /* Encode UCI CQI/PMI for payloads equal or lower to 11 bits (Sec 5.2.2.6.4) */ -int encode_cqi_short(uci_cqi_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_bits, uint32_t Q) +int encode_cqi_short(uci_cqi_pusch_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_bits, uint32_t Q) { - if (nof_bits < MAX_CQI_LEN && - q != NULL && - data != NULL && + if (nof_bits < MAX_CQI_LEN_PUSCH && + q != NULL && + data != NULL && q_bits != NULL) { for (int i=0;i<32;i++) { q->encoded_cqi[i] = 0; for (int n=0;nencoded_cqi[i] += (data[n] * M_basis_seq[i][n]); + q->encoded_cqi[i] += (data[n] * M_basis_seq_pusch[i][n]); } } @@ -137,13 +161,13 @@ int encode_cqi_short(uci_cqi_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_ /* Encode UCI CQI/PMI for payloads greater than 11 bits (go through CRC, conv coder and rate match) */ -int encode_cqi_long(uci_cqi_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_bits, uint32_t Q) +int encode_cqi_long(uci_cqi_pusch_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_bits, uint32_t Q) { convcoder_t encoder; - if (nof_bits + 8 < MAX_CQI_LEN && - q != NULL && - data != NULL && + if (nof_bits + 8 < MAX_CQI_LEN_PUSCH && + q != NULL && + data != NULL && q_bits != NULL) { @@ -173,9 +197,27 @@ int encode_cqi_long(uci_cqi_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_b } } +/* Encode UCI CQI/PMI as described in 5.2.3.3 of 36.212 + */ +int uci_encode_cqi_pucch(uint8_t *cqi_data, uint32_t cqi_len, uint8_t b_bits[CQI_CODED_PUCCH_B]) +{ + if (cqi_len <= MAX_CQI_LEN_PUCCH) { + for (uint32_t i=0;i 0) { - if (ulsch_uci_encode(&pusch.dl_sch, data, uci_data, pusch.pusch_g, &harq_process, rv_idx, pusch.pusch_q)) - { + if (pusch_uci_encode(&pusch, data, uci_data, sf_symbols, subframe, &harq_process, rv_idx)) { fprintf(stderr, "Error encoding TB\n"); exit(-1); } - } - vec_fprint_b(stdout, pusch.pusch_q, nof_bits_e); - /* combine outputs */ - for (i=0;i 0) { - slot_symbols[0][j] += slot_symbols[i][j]; - } - ce[i][j] = 1; - } - } - gettimeofday(&t[1], NULL); //int r = pusch_decode(&pusch, slot_symbols[0], ce, 0, data, subframe, &harq_process, rv); int r = 0; @@ -255,13 +224,11 @@ quit: pusch_free(&pusch); harq_free(&harq_process); - for (i=0;i