From ec321f971d8e8350521a06f3a32f90c4f7ff9b29 Mon Sep 17 00:00:00 2001 From: ismagom Date: Sun, 6 Jul 2014 21:08:11 +0200 Subject: [PATCH] Fixed error in PDSCH mapping. Further API simplification --- lte/phy/examples/pdsch_enodeb.c | 4 +- lte/phy/examples/pdsch_ue.c | 28 +- lte/phy/include/liblte/phy/common/fft.h | 14 +- lte/phy/include/liblte/phy/phch/dci.h | 2 + lte/phy/include/liblte/phy/phch/pdcch.h | 23 +- lte/phy/include/liblte/phy/phch/regs.h | 12 + lte/phy/lib/ch_estimation/src/refsignal.c | 12 +- lte/phy/lib/common/src/fft.c | 44 +-- lte/phy/lib/fec/src/convcoder.c | 35 ++- lte/phy/lib/phch/src/dci.c | 12 +- lte/phy/lib/phch/src/pdcch.c | 309 ++++++++++------------ lte/phy/lib/phch/src/regs.c | 103 +++++--- lte/phy/lib/phch/test/pdcch_file_test.c | 24 +- lte/phy/lib/phch/test/pdcch_test.c | 31 ++- lte/phy/lib/phch/test/pdsch_file_test.c | 24 +- lte/phy/lib/sync/src/sync_frame.c | 5 +- 16 files changed, 357 insertions(+), 325 deletions(-) diff --git a/lte/phy/examples/pdsch_enodeb.c b/lte/phy/examples/pdsch_enodeb.c index 34947396e..511a0c3a0 100644 --- a/lte/phy/examples/pdsch_enodeb.c +++ b/lte/phy/examples/pdsch_enodeb.c @@ -334,13 +334,11 @@ int main(int argc, char **argv) { data[i] = rand()%2; } - if (pdcch_encode_msg(&pdcch, &dci_msg, locations[sf_idx][0], 1234)) { + if (pdcch_encode(&pdcch, &dci_msg, locations[sf_idx][0], 1234, sf_symbols, sf_idx, cfi)) { fprintf(stderr, "Error encoding DCI message\n"); exit(-1); } - pdcch_gen_symbols(&pdcch, sf_symbols, sf_idx, cfi); - pdsch_encode(&pdsch, data, sf_symbols, sf_idx, ra_dl.mcs, &prb_alloc); /* Transform to OFDM symbols */ diff --git a/lte/phy/examples/pdsch_ue.c b/lte/phy/examples/pdsch_ue.c index 85aed0250..2d6c0af73 100644 --- a/lte/phy/examples/pdsch_ue.c +++ b/lte/phy/examples/pdsch_ue.c @@ -393,8 +393,7 @@ int cell_id_init(int nof_prb, int cell_id) { char data[10000]; int rx_run(cf_t *input, int sf_idx) { - uint32_t cfi, cfi_distance; - int i, nof_dcis; + uint32_t cfi, cfi_distance, i; cf_t *input_decim; ra_pdsch_t ra_dl; ra_prb_t prb_alloc; @@ -430,18 +429,19 @@ int rx_run(cf_t *input, int sf_idx) { /* Search only UE-specific locations */ nof_locations = pdcch_ue_locations(&pdcch, locations, 10, sf_idx, cfi, 1234); - pdcch_extract_llr(&pdcch, fft_buffer, ce, nof_frames, cfi); - - - nof_dcis = pdcch_decode_msg(&pdcch, &dci_msg, locations, nof_locations, Format1, 1234); - if (nof_dcis < 0) { - fprintf(stderr, "Error decoding DCI messages\n"); - return -1; + uint16_t crc_rem = 0; + for (i=0;i 0) { + if (!disable_plots && crc_rem == 1234) { int n_re = 2 * RE_X_RB * CPNORM_NSYMB * cell.nof_prb; for (i = 0; i < n_re; i++) { tmp_plot[i] = 10 * log10f(cabsf(fft_buffer[i])); diff --git a/lte/phy/include/liblte/phy/common/fft.h b/lte/phy/include/liblte/phy/common/fft.h index 048bd37dc..3e20c475f 100644 --- a/lte/phy/include/liblte/phy/common/fft.h +++ b/lte/phy/include/liblte/phy/common/fft.h @@ -42,18 +42,18 @@ typedef _Complex float cf_t; /* this is only a shortcut */ /* This is common for both directions */ typedef struct LIBLTE_API{ dft_plan_t fft_plan; - int nof_symbols; - int symbol_sz; - int nof_guards; - int nof_re; - int slot_sz; + uint32_t nof_symbols; + uint32_t symbol_sz; + uint32_t nof_guards; + uint32_t nof_re; + uint32_t slot_sz; lte_cp_t cp; cf_t *tmp; // for removing zero padding }lte_fft_t; LIBLTE_API int lte_fft_init(lte_fft_t *q, lte_cp_t cp_type, - int nof_prb); + uint32_t nof_prb); LIBLTE_API void lte_fft_free(lte_fft_t *q); @@ -67,7 +67,7 @@ LIBLTE_API void lte_fft_run_sf(lte_fft_t *q, LIBLTE_API int lte_ifft_init(lte_fft_t *q, lte_cp_t cp_type, - int nof_prb); + uint32_t nof_prb); LIBLTE_API void lte_ifft_free(lte_fft_t *q); diff --git a/lte/phy/include/liblte/phy/phch/dci.h b/lte/phy/include/liblte/phy/phch/dci.h index 79f37e1b5..a5ee5e658 100644 --- a/lte/phy/include/liblte/phy/phch/dci.h +++ b/lte/phy/include/liblte/phy/phch/dci.h @@ -78,6 +78,8 @@ LIBLTE_API int dci_location_set(dci_location_t *c, uint32_t L, uint32_t nCCE); +LIBLTE_API bool dci_location_isvalid(dci_location_t *c); + LIBLTE_API int dci_msg_get_type(dci_msg_t *msg, dci_msg_type_t *type, uint32_t nof_prb, diff --git a/lte/phy/include/liblte/phy/phch/pdcch.h b/lte/phy/include/liblte/phy/phch/pdcch.h index c48e84808..87aa91eb8 100644 --- a/lte/phy/include/liblte/phy/phch/pdcch.h +++ b/lte/phy/include/liblte/phy/phch/pdcch.h @@ -59,8 +59,7 @@ typedef enum LIBLTE_API { /* PDCCH object */ typedef struct LIBLTE_API { lte_cell_t cell; - uint32_t nof_bits; - uint32_t nof_symbols; + uint32_t e_bits; uint32_t nof_regs; uint32_t nof_cce; uint32_t max_bits; @@ -91,33 +90,27 @@ LIBLTE_API void pdcch_free(pdcch_t *q); /* Encoding function */ -LIBLTE_API void pdcch_reset(pdcch_t *q); - -LIBLTE_API int pdcch_encode_msg(pdcch_t *q, +LIBLTE_API int pdcch_encode(pdcch_t *q, dci_msg_t *msg, dci_location_t location, - uint16_t rnti); - -LIBLTE_API int pdcch_gen_symbols(pdcch_t *q, - cf_t *sf_symbols[MAX_PORTS], - uint32_t nsubframe, - uint32_t cfi); - + uint16_t rnti, + cf_t *sf_symbols[MAX_PORTS], + uint32_t nsubframe, + uint32_t cfi); /* Decoding functions: Extract the LLRs and save them in the pdcch_t object */ LIBLTE_API int pdcch_extract_llr(pdcch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], + dci_location_t location, uint32_t nsubframe, uint32_t cfi); /* Decoding functions: Try to decode a DCI message after calling pdcch_extract_llr */ LIBLTE_API int pdcch_decode_msg(pdcch_t *q, dci_msg_t *msg, - dci_location_t *locations, - uint32_t nof_locations, dci_format_t format, - uint16_t rnti); + uint16_t *crc_rem); /* Function for generation of UE-specific search space DCI locations */ LIBLTE_API uint32_t pdcch_ue_locations(pdcch_t *q, diff --git a/lte/phy/include/liblte/phy/phch/regs.h b/lte/phy/include/liblte/phy/phch/regs.h index 38f3515a9..1b2f470d6 100644 --- a/lte/phy/include/liblte/phy/phch/regs.h +++ b/lte/phy/include/liblte/phy/phch/regs.h @@ -114,10 +114,22 @@ LIBLTE_API int regs_pdcch_put(regs_t *h, cf_t *pdcch_symbols, cf_t *slot_symbols); +LIBLTE_API int regs_pdcch_put_offset(regs_t *h, + cf_t *pdcch_symbols, + cf_t *slot_symbols, + uint32_t start_reg, + uint32_t nof_regs); + LIBLTE_API int regs_pdcch_get(regs_t *h, cf_t *slot_symbols, cf_t *pdcch_symbols); +LIBLTE_API int regs_pdcch_get_offset(regs_t *h, + cf_t *slot_symbols, + cf_t *pdcch_symbols, + uint32_t start_reg, + uint32_t nof_regs); + #endif // REGS_H_ diff --git a/lte/phy/lib/ch_estimation/src/refsignal.c b/lte/phy/lib/ch_estimation/src/refsignal.c index eb476f0ca..0ecdb59c1 100644 --- a/lte/phy/lib/ch_estimation/src/refsignal.c +++ b/lte/phy/lib/ch_estimation/src/refsignal.c @@ -67,12 +67,12 @@ int refsignal_v(uint32_t port_id, uint32_t ns, uint32_t symbol_id) { return v; } -int refsignal_k(int m, int v, uint32_t cell_id) { +uint32_t refsignal_k(uint32_t m, uint32_t v, uint32_t cell_id) { return 6*m+((v+(cell_id%6))%6); } int refsignal_put(refsignal_t *q, cf_t *slot_symbols) { - int i; + uint32_t i; uint32_t fidx, tidx; if (q != NULL && slot_symbols != NULL) @@ -96,12 +96,12 @@ int refsignal_init_LTEDL(refsignal_t *q, uint32_t port_id, uint32_t nslot, uint32_t c_init; uint32_t ns, l, lp[2]; - int N_cp; - int i; + uint32_t N_cp; + uint32_t i; int ret = LIBLTE_ERROR_INVALID_INPUTS; sequence_t seq; int v; - int mp; + uint32_t mp; uint32_t nof_refs_x_symbol, nof_ref_symbols; if (q != NULL && @@ -171,7 +171,7 @@ int refsignal_init_LTEDL(refsignal_t *q, uint32_t port_id, uint32_t nslot, __imag__ q->refs[idx(l,i)].simbol = (1 - 2 * (float) seq.c[2 * mp + 1]) / sqrt(2); /* mapping to resource elements */ - q->refs[idx(l,i)].freq_idx = refsignal_k(i, v, cell.id); + q->refs[idx(l,i)].freq_idx = refsignal_k(i, (uint32_t) v, cell.id); q->refs[idx(l,i)].time_idx = lp[l]; } } diff --git a/lte/phy/lib/common/src/fft.c b/lte/phy/lib/common/src/fft.c index dfe083b16..a21aa2c15 100644 --- a/lte/phy/lib/common/src/fft.c +++ b/lte/phy/lib/common/src/fft.c @@ -35,10 +35,10 @@ #include "liblte/phy/utils/debug.h" #include "liblte/phy/utils/vector.h" -int lte_fft_init_(lte_fft_t *q, lte_cp_t cp, int nof_prb, dft_dir_t dir) { +int lte_fft_init_(lte_fft_t *q, lte_cp_t cp, uint32_t nof_prb, dft_dir_t dir) { int symbol_sz = lte_symbol_sz(nof_prb); - if (symbol_sz == -1) { + if (symbol_sz < 0) { fprintf(stderr, "Error: Invalid nof_prb=%d\n", nof_prb); return -1; } @@ -46,7 +46,7 @@ int lte_fft_init_(lte_fft_t *q, lte_cp_t cp, int nof_prb, dft_dir_t dir) { fprintf(stderr, "Error: Creating DFT plan\n"); return -1; } - q->tmp = malloc(symbol_sz * sizeof(cf_t)); + q->tmp = malloc((uint32_t) symbol_sz * sizeof(cf_t)); if (!q->tmp) { perror("malloc"); return -1; @@ -56,7 +56,7 @@ int lte_fft_init_(lte_fft_t *q, lte_cp_t cp, int nof_prb, dft_dir_t dir) { dft_plan_set_norm(&q->fft_plan, true); dft_plan_set_dc(&q->fft_plan, true); - q->symbol_sz = symbol_sz; + q->symbol_sz = (uint32_t) symbol_sz; q->nof_symbols = CP_NSYMB(cp); q->cp = cp; q->nof_re = nof_prb * RE_X_RB; @@ -66,7 +66,8 @@ int lte_fft_init_(lte_fft_t *q, lte_cp_t cp, int nof_prb, dft_dir_t dir) { DEBUG("Init %s symbol_sz=%d, nof_symbols=%d, cp=%s, nof_re=%d, nof_guards=%d\n", dir==FORWARD?"FFT":"iFFT", q->symbol_sz, q->nof_symbols, q->cp==CPNORM?"Normal":"Extended", q->nof_re, q->nof_guards); - return 0; + + return LIBLTE_SUCCESS; } void lte_fft_free_(lte_fft_t *q) { @@ -77,7 +78,7 @@ void lte_fft_free_(lte_fft_t *q) { bzero(q, sizeof(lte_fft_t)); } -int lte_fft_init(lte_fft_t *q, lte_cp_t cp, int nof_prb) { +int lte_fft_init(lte_fft_t *q, lte_cp_t cp, uint32_t nof_prb) { return lte_fft_init_(q, cp, nof_prb, FORWARD); } @@ -85,17 +86,20 @@ void lte_fft_free(lte_fft_t *q) { lte_fft_free_(q); } -int lte_ifft_init(lte_fft_t *q, lte_cp_t cp, int nof_prb) { - int i; - if (lte_fft_init_(q, cp, nof_prb, BACKWARD)) { - return -1; - } - /* set now zeros at CP */ - for (i=0;inof_symbols;i++) { - bzero(q->tmp, q->nof_guards * sizeof(cf_t)); - bzero(&q->tmp[q->nof_re + q->nof_guards], q->nof_guards * sizeof(cf_t)); +int lte_ifft_init(lte_fft_t *q, lte_cp_t cp, uint32_t nof_prb) { + uint32_t i; + int ret; + + ret = lte_fft_init_(q, cp, nof_prb, BACKWARD); + + if (ret == LIBLTE_SUCCESS) { + /* set now zeros at CP */ + for (i=0;inof_symbols;i++) { + bzero(q->tmp, q->nof_guards * sizeof(cf_t)); + bzero(&q->tmp[q->nof_re + q->nof_guards], q->nof_guards * sizeof(cf_t)); + } } - return 0; + return ret; } void lte_ifft_free(lte_fft_t *q) { @@ -106,7 +110,7 @@ void lte_ifft_free(lte_fft_t *q) { * Performs FFT on a each symbol and removes CP. */ void lte_fft_run_slot(lte_fft_t *q, cf_t *input, cf_t *output) { - int i; + uint32_t i; for (i=0;inof_symbols;i++) { input += CP_ISNORM(q->cp)?CP_NORM(i, q->symbol_sz):CP_EXT(q->symbol_sz); dft_run_c(&q->fft_plan, input, q->tmp); @@ -117,7 +121,7 @@ void lte_fft_run_slot(lte_fft_t *q, cf_t *input, cf_t *output) { } void lte_fft_run_sf(lte_fft_t *q, cf_t *input, cf_t *output) { - int n; + uint32_t n; for (n=0;n<2;n++) { lte_fft_run_slot(q, &input[n*q->slot_sz], &output[n*q->nof_re*q->nof_symbols]); } @@ -127,7 +131,7 @@ void lte_fft_run_sf(lte_fft_t *q, cf_t *input, cf_t *output) { * Performs FFT on a each symbol and adds CP. */ void lte_ifft_run_slot(lte_fft_t *q, cf_t *input, cf_t *output) { - int i, cp_len; + uint32_t i, cp_len; for (i=0;inof_symbols;i++) { cp_len = CP_ISNORM(q->cp)?CP_NORM(i, q->symbol_sz):CP_EXT(q->symbol_sz); memcpy(&q->tmp[q->nof_guards], input, q->nof_re * sizeof(cf_t)); @@ -140,7 +144,7 @@ void lte_ifft_run_slot(lte_fft_t *q, cf_t *input, cf_t *output) { } void lte_ifft_run_sf(lte_fft_t *q, cf_t *input, cf_t *output) { - int n; + uint32_t n; for (n=0;n<2;n++) { lte_ifft_run_slot(q, &input[n*q->nof_re*q->nof_symbols], &output[n*q->slot_sz]); } diff --git a/lte/phy/lib/fec/src/convcoder.c b/lte/phy/lib/fec/src/convcoder.c index 65b8236be..2153327ac 100644 --- a/lte/phy/lib/fec/src/convcoder.c +++ b/lte/phy/lib/fec/src/convcoder.c @@ -39,23 +39,30 @@ int convcoder_encode(convcoder_t *q, char *input, char *output, uint32_t frame_l uint32_t i,j; uint32_t len = q->tail_biting ? frame_length : (frame_length + q->K - 1); - if (q->tail_biting) { - sr = 0; - for (i=frame_length - q->K + 1; i q->K + 1) + { + if (q->tail_biting) { + sr = 0; + for (i=frame_length - q->K + 1; iR;j++) { - output[q->R * i + j] = parity(sr & q->poly[j]); + for (i = 0; i < len; i++) { + char bit = (i < frame_length) ? (input[i] & 1) : 0; + sr = (sr << 1) | bit; + for (j=0;jR;j++) { + output[q->R * i + j] = parity(sr & q->poly[j]); + } } + return q->R*len; + } else { + return LIBLTE_ERROR_INVALID_INPUTS; } - - return q->R*len; } diff --git a/lte/phy/lib/phch/src/dci.c b/lte/phy/lib/phch/src/dci.c index 05e0fc35b..ed8ff16fc 100644 --- a/lte/phy/lib/phch/src/dci.c +++ b/lte/phy/lib/phch/src/dci.c @@ -57,6 +57,14 @@ int dci_location_set(dci_location_t *c, uint32_t L, uint32_t nCCE) { return LIBLTE_SUCCESS; } +bool dci_location_isvalid(dci_location_t *c) { + if (c->L <= 3 && c->ncce <= 87) { + return true; + } else { + return false; + } +} + uint32_t riv_nbits(uint32_t nof_prb) { return (uint32_t) ceilf(log2f((float) nof_prb * ((float) nof_prb + 1) / 2)); } @@ -785,7 +793,9 @@ void dci_msg_type_fprint(FILE *f, dci_msg_type_t type) { } int dci_msg_get_type(dci_msg_t *msg, dci_msg_type_t *type, uint32_t nof_prb, - uint16_t msg_rnti, uint16_t crnti) { + uint16_t msg_rnti, uint16_t crnti) +{ + DEBUG("Get message type: nof_bits=%d, msg_rnti=0x%x, crnti=0x%x\n", msg->nof_bits, msg_rnti, crnti); if (msg->nof_bits == dci_format_sizeof(Format0, nof_prb) && !msg->data[0]) { type->type = PUSCH_SCHED; diff --git a/lte/phy/lib/phch/src/pdcch.c b/lte/phy/lib/phch/src/pdcch.c index 0c719671b..d46c63d96 100644 --- a/lte/phy/lib/phch/src/pdcch.c +++ b/lte/phy/lib/phch/src/pdcch.c @@ -54,8 +54,6 @@ static void set_cfi(pdcch_t *q, uint32_t cfi) { if (cfi > 0 && cfi < 4) { q->nof_regs = (regs_pdcch_nregs(q->regs, cfi) / 9) * 9; q->nof_cce = q->nof_regs / 9; - q->nof_symbols = 4 * q->nof_regs; - q->nof_bits = 2 * q->nof_symbols; } } @@ -63,7 +61,7 @@ static void set_cfi(pdcch_t *q, uint32_t cfi) { /** Initializes the PDCCH transmitter and receiver */ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) { int ret = LIBLTE_ERROR_INVALID_INPUTS; - int i; + uint32_t i; if (q != NULL && regs != NULL && @@ -74,13 +72,10 @@ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) { q->cell = cell; q->regs = regs; - /* Now allocate memory for the maximum number of REGs (CFI=3) - */ - set_cfi(q, 3); - q->max_bits = q->nof_bits; + /* Allocate memory for the largest aggregation level L=3 */ + q->max_bits = PDCCH_FORMAT_NOF_BITS(3); - INFO("Init PDCCH: %d CCEs (%d REGs), %d bits, %d symbols, %d ports\n", - q->nof_cce, q->nof_regs, q->nof_bits, q->nof_symbols, q->cell.nof_ports); + INFO("Init PDCCH: %d bits, %d symbols, %d ports\n", q->max_bits, q->max_bits/2, q->cell.nof_ports); if (modem_table_std(&q->mod, LTE_QPSK, true)) { goto clean; @@ -94,7 +89,7 @@ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) { demod_soft_alg_set(&q->demod, APPROX); for (i = 0; i < NSUBFRAMES_X_FRAME; i++) { - if (sequence_pdcch(&q->seq_pdcch[i], 2 * i, q->cell.id, q->nof_bits)) { + if (sequence_pdcch(&q->seq_pdcch[i], 2 * i, q->cell.id, q->max_bits)) { goto clean; } } @@ -104,31 +99,31 @@ int pdcch_init(pdcch_t *q, regs_t *regs, lte_cell_t cell) { goto clean; } - q->pdcch_e = malloc(sizeof(char) * q->nof_bits); + q->pdcch_e = malloc(sizeof(char) * q->max_bits); if (!q->pdcch_e) { goto clean; } - q->pdcch_llr = malloc(sizeof(float) * q->nof_bits); + q->pdcch_llr = malloc(sizeof(float) * q->max_bits); if (!q->pdcch_llr) { goto clean; } - q->pdcch_d = malloc(sizeof(cf_t) * q->nof_symbols); + q->pdcch_d = malloc(sizeof(cf_t) * q->max_bits / 2); if (!q->pdcch_d) { goto clean; } for (i = 0; i < MAX_PORTS; i++) { - q->ce[i] = malloc(sizeof(cf_t) * q->nof_symbols); + q->ce[i] = malloc(sizeof(cf_t) * q->max_bits / 2); if (!q->ce[i]) { goto clean; } - q->pdcch_x[i] = malloc(sizeof(cf_t) * q->nof_symbols); + q->pdcch_x[i] = malloc(sizeof(cf_t) * q->max_bits / 2); if (!q->pdcch_x[i]) { goto clean; } - q->pdcch_symbols[i] = malloc(sizeof(cf_t) * q->nof_symbols); + q->pdcch_symbols[i] = malloc(sizeof(cf_t) * q->max_bits / 2); if (!q->pdcch_symbols[i]) { goto clean; } @@ -277,10 +272,6 @@ static int dci_decode(pdcch_t *q, float *e, char *data, uint32_t E, uint32_t nof nof_bits < DCI_MAX_BITS) { - if (VERBOSE_ISDEBUG()) { - vec_fprint_f(stdout, e, E); - } - /* unrate matching */ rm_conv_rx(e, E, tmp, 3 * (nof_bits + 16)); @@ -299,7 +290,7 @@ static int dci_decode(pdcch_t *q, float *e, char *data, uint32_t E, uint32_t nof x = &data[nof_bits]; p_bits = (uint16_t) bit_unpack(&x, 16); crc_res = ((uint16_t) crc_checksum(&q->crc, data, nof_bits) & 0xffff); - DEBUG("p_bits: 0x%x, crc_res: 0x%x, tot: 0x%x\n", p_bits, crc_res, + DEBUG("p_bits: 0x%x, crc_checksum: 0x%x, crc_rem: 0x%x\n", p_bits, crc_res, p_bits ^ crc_res); if (crc) { @@ -313,123 +304,113 @@ static int dci_decode(pdcch_t *q, float *e, char *data, uint32_t E, uint32_t nof /** Tries to decode a DCI message from the LLRs stored in the pdcch_t structure by the function * pdcch_extract_llr(). This function can be called multiple times. - * The decoded message is stored in msg. Up to nof_locations are tried from the array of dci_locations_t - * pointed by locations. The CRC is checked agains the RNTI parameter. + * The decoded message is stored in msg and the CRC remainder in crc_rem pointer * - * Returns 1 if the message is correctly decoded, 0 if not and -1 on error. */ -int pdcch_decode_msg(pdcch_t *q, dci_msg_t *msg, - dci_location_t *locations, uint32_t nof_locations, - dci_format_t format, uint16_t rnti) +int pdcch_decode_msg(pdcch_t *q, dci_msg_t *msg, dci_format_t format, uint16_t *crc_rem) { + int ret = LIBLTE_ERROR_INVALID_INPUTS; if (q != NULL && msg != NULL && - locations != NULL && - nof_locations > 0) + crc_rem != NULL) { - uint16_t crc_res; uint32_t nof_bits = dci_format_sizeof(format, q->cell.nof_prb); - uint32_t i; - i = 0; - do { - INFO("Trying Candidate: Nbits: %d, E: %3d, nCCE: %d, L: %d, RNTI: 0x%x\n", - nof_bits, PDCCH_FORMAT_NOF_BITS(locations[i].L), locations[i].ncce, locations[i].L, rnti); - - if (dci_decode(q, &q->pdcch_llr[72 * locations[i].ncce], msg->data, - PDCCH_FORMAT_NOF_BITS(locations[i].L), nof_bits, &crc_res) != LIBLTE_SUCCESS) { - return LIBLTE_ERROR; - } - if (crc_res != rnti) { - i++; - } - } while(i < nof_locations && crc_res != rnti); - - if (rnti == crc_res) { + ret = dci_decode(q, q->pdcch_llr, msg->data, q->e_bits, nof_bits, crc_rem); + if (ret == LIBLTE_SUCCESS) { msg->nof_bits = nof_bits; - INFO("FOUND Candidate: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", - nof_bits, PDCCH_FORMAT_NOF_BITS(locations[i].L), locations[i].ncce, locations[i].L, rnti); - return 1; - } else { - return LIBLTE_SUCCESS; - } + } } - return LIBLTE_ERROR_INVALID_INPUTS; + return ret; } -/** Extracts the LLRs from the subframe symbols (demodulation) and stores them in the pdcch_t structure. - * DCI messages can be extracted calling the function pdcch_decode_msg(). - * Every time this function is called, the last demodulated symbols are overwritten. +/** Extracts the LLRs from dci_location_t location of the subframe and stores them in the pdcch_t structure. + * DCI messages can be extracted from this location calling the function pdcch_decode_msg(). + * Every time this function is called (with a different location), the last demodulated symbols are overwritten and + * new messages from other locations can be decoded */ -int pdcch_extract_llr(pdcch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], uint32_t nsubframe, uint32_t cfi) { +int pdcch_extract_llr(pdcch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], + dci_location_t location, uint32_t nsubframe, uint32_t cfi) { + int ret = LIBLTE_ERROR_INVALID_INPUTS; + /* Set pointers for layermapping & precoding */ - uint32_t i; + uint32_t i, nof_symbols; cf_t *x[MAX_LAYERS]; if (q != NULL && nsubframe < 10 && cfi > 0 && - cfi < 4) + cfi < 4 && + dci_location_isvalid(&location)) { set_cfi(q, cfi); - /* number of layers equals number of ports */ - for (i = 0; i < q->cell.nof_ports; i++) { - x[i] = q->pdcch_x[i]; - } - memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); - - /* extract symbols */ - int n = regs_pdcch_get(q->regs, sf_symbols, q->pdcch_symbols[0]); - if (q->nof_symbols != n) { - fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", - q->nof_symbols, n); - return LIBLTE_ERROR; - } + q->e_bits = PDCCH_FORMAT_NOF_BITS(location.L); + nof_symbols = q->e_bits/2; + ret = LIBLTE_ERROR; + + if (location.ncce + PDCCH_FORMAT_NOF_CCE(location.L) <= q->nof_cce) { + + INFO("Extracting LLRs: E: %d, nCCE: %d, L: %d\n", + q->e_bits, location.ncce, location.L); - /* extract channel estimates */ - for (i = 0; i < q->cell.nof_ports; i++) { - n = regs_pdcch_get(q->regs, ce[i], q->ce[i]); - if (q->nof_symbols != n) { - fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", - q->nof_symbols, n); - return LIBLTE_ERROR; + /* number of layers equals number of ports */ + for (i = 0; i < q->cell.nof_ports; i++) { + x[i] = q->pdcch_x[i]; + } + memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); + + /* extract symbols */ + int n = regs_pdcch_get_offset(q->regs, sf_symbols, q->pdcch_symbols[0], + location.ncce * 9, PDCCH_FORMAT_NOF_REGS(location.L)); + if (nof_symbols != n) { + fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n); + return ret; } - } - /* in control channels, only diversity is supported */ - if (q->cell.nof_ports == 1) { - /* no need for layer demapping */ - predecoding_single_zf(q->pdcch_symbols[0], q->ce[0], q->pdcch_d, - q->nof_symbols); - } else { - predecoding_diversity_zf(q->pdcch_symbols[0], q->ce, x, q->cell.nof_ports, - q->nof_symbols); - layerdemap_diversity(x, q->pdcch_d, q->cell.nof_ports, - q->nof_symbols / q->cell.nof_ports); - } + /* extract channel estimates */ + for (i = 0; i < q->cell.nof_ports; i++) { + n = regs_pdcch_get_offset(q->regs, ce[i], q->ce[i], + location.ncce * 9, PDCCH_FORMAT_NOF_REGS(location.L)); + if (nof_symbols != n) { + fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n); + return ret; + } + } - DEBUG("pdcch d symbols: ", 0); - if (VERBOSE_ISDEBUG()) { - vec_fprint_c(stdout, q->pdcch_d, q->nof_symbols); - } + /* in control channels, only diversity is supported */ + if (q->cell.nof_ports == 1) { + /* no need for layer demapping */ + predecoding_single_zf(q->pdcch_symbols[0], q->ce[0], q->pdcch_d, nof_symbols); + } else { + predecoding_diversity_zf(q->pdcch_symbols[0], q->ce, x, q->cell.nof_ports, nof_symbols); + layerdemap_diversity(x, q->pdcch_d, q->cell.nof_ports, nof_symbols / q->cell.nof_ports); + } - /* demodulate symbols */ - demod_soft_sigma_set(&q->demod, 1.0); - demod_soft_demodulate(&q->demod, q->pdcch_d, q->pdcch_llr, q->nof_symbols); + DEBUG("pdcch d symbols: ", 0); + if (VERBOSE_ISDEBUG()) { + vec_fprint_c(stdout, q->pdcch_d, nof_symbols); + } - DEBUG("llr: ", 0); - if (VERBOSE_ISDEBUG()) { - vec_fprint_f(stdout, q->pdcch_llr, q->nof_bits); - } + /* demodulate symbols */ + demod_soft_sigma_set(&q->demod, 1.0); + demod_soft_demodulate(&q->demod, q->pdcch_d, q->pdcch_llr, nof_symbols); - /* descramble */ - scrambling_f_offset(&q->seq_pdcch[nsubframe], q->pdcch_llr, 0, q->nof_bits); + DEBUG("llr: ", 0); + if (VERBOSE_ISDEBUG()) { + vec_fprint_f(stdout, q->pdcch_llr, q->e_bits); + } - return LIBLTE_SUCCESS; + /* descramble */ + scrambling_f_offset(&q->seq_pdcch[nsubframe], q->pdcch_llr, 72 * location.ncce, q->e_bits); + + ret = LIBLTE_SUCCESS; + } else { + fprintf(stderr, "Illegal DCI message nCCE: %d, L: %d, nof_cce: %d\n", location.ncce, location.L, q->nof_cce); + } } - return LIBLTE_ERROR_INVALID_INPUTS; + return ret; } @@ -487,91 +468,79 @@ static int dci_encode(pdcch_t *q, char *data, char *e, uint32_t nof_bits, uint32 } } -void pdcch_reset(pdcch_t *q) { - /* should add elements? Or maybe random bits to facilitate power estimation */ - bzero(q->pdcch_e, q->nof_bits); -} - /** Encodes ONE DCI message and allocates the encoded bits to the dci_location_t indicated by * the parameter location. The CRC is scrambled with the RNTI parameter. - * This function can be called multiple times and encoded DCI messages will be stored in the - * pdcch_t structure. A final call to the function pdcch_gen_symbols() will generate and map the - * symbols to the subframe for transmission. + * This function can be called multiple times and encoded DCI messages will be allocated to the + * sf_symbols buffer ready for transmission. * If the same location is provided in multiple messages, the encoded bits will be overwritten. * * @TODO: Use a bitmask and CFI to ensure message locations are valid and old messages are not overwritten. */ -int pdcch_encode_msg(pdcch_t *q, dci_msg_t *msg, dci_location_t location, uint16_t rnti) { +int pdcch_encode(pdcch_t *q, dci_msg_t *msg, dci_location_t location, uint16_t rnti, + cf_t *sf_symbols[MAX_PORTS], uint32_t nsubframe, uint32_t cfi) { int ret = LIBLTE_ERROR_INVALID_INPUTS; + uint32_t i; + cf_t *x[MAX_LAYERS]; + uint32_t nof_symbols; - if (q != NULL) { + if (q != NULL && + sf_symbols != NULL && + nsubframe < 10 && + cfi > 0 && + cfi < 4 && + dci_location_isvalid(&location)) + { + + set_cfi(q, cfi); + + q->e_bits = PDCCH_FORMAT_NOF_BITS(location.L); + nof_symbols = q->e_bits/2; ret = LIBLTE_ERROR; - if (location.L < 4 && + if (location.ncce + PDCCH_FORMAT_NOF_CCE(location.L) <= q->nof_cce && msg->nof_bits < DCI_MAX_BITS) { INFO("Encoding DCI: Nbits: %d, E: %d, nCCE: %d, L: %d, RNTI: 0x%x\n", - msg->nof_bits, - PDCCH_FORMAT_NOF_BITS(location.L), - location.ncce, location.L, rnti); + msg->nof_bits, q->e_bits, location.ncce, location.L, rnti); - dci_encode(q, msg->data, &q->pdcch_e[72 * location.ncce], msg->nof_bits, - PDCCH_FORMAT_NOF_BITS(location.L), rnti); + dci_encode(q, msg->data, q->pdcch_e, msg->nof_bits, q->e_bits, rnti); + /* number of layers equals number of ports */ + for (i = 0; i < q->cell.nof_ports; i++) { + x[i] = q->pdcch_x[i]; + } + memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); + + scrambling_b_offset(&q->seq_pdcch[nsubframe], q->pdcch_e, 72 * location.ncce, q->e_bits); + + DEBUG("Scrambling output: ", 0); + if (VERBOSE_ISDEBUG()) { + vec_fprint_b(stdout, q->pdcch_e, q->e_bits); + } + + mod_modulate(&q->mod, q->pdcch_e, q->pdcch_d, q->e_bits); + + /* layer mapping & precoding */ + if (q->cell.nof_ports > 1) { + layermap_diversity(q->pdcch_d, x, q->cell.nof_ports, nof_symbols); + precoding_diversity(x, q->pdcch_symbols, q->cell.nof_ports, nof_symbols / q->cell.nof_ports); + } else { + memcpy(q->pdcch_symbols[0], q->pdcch_d, nof_symbols * sizeof(cf_t)); + } + + /* mapping to resource elements */ + for (i = 0; i < q->cell.nof_ports; i++) { + regs_pdcch_put_offset(q->regs, q->pdcch_symbols[i], sf_symbols[i], + location.ncce * 9, PDCCH_FORMAT_NOF_REGS(location.L)); + } + ret = LIBLTE_SUCCESS; } else { - fprintf(stderr, "Illegal DCI message nCCE: %d, L: %d, nof_cce: %d\n", - location.ncce, location.L, q->nof_cce); + fprintf(stderr, "Illegal DCI message nCCE: %d, L: %d, nof_cce: %d\n", location.ncce, location.L, q->nof_cce); } } return ret; } -/** Converts the set of DCI messages encoded using the function pdcch_encode_msg() - * to symbols mapped to the subframe ready for transmission - */ -int pdcch_gen_symbols(pdcch_t *q, cf_t *slot_symbols[MAX_PORTS], uint32_t nsubframe, uint32_t cfi) { - int i; - /* Set pointers for layermapping & precoding */ - cf_t *x[MAX_LAYERS]; - - if (q != NULL && - slot_symbols != NULL && - nsubframe < 10 && - cfi > 0 && - cfi < 4) - { - set_cfi(q, cfi); - - /* number of layers equals number of ports */ - for (i = 0; i < q->cell.nof_ports; i++) { - x[i] = q->pdcch_x[i]; - } - memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); - - scrambling_b_offset(&q->seq_pdcch[nsubframe], q->pdcch_e, 0, q->nof_bits); - - mod_modulate(&q->mod, q->pdcch_e, q->pdcch_d, q->nof_bits); - - /* layer mapping & precoding */ - if (q->cell.nof_ports > 1) { - layermap_diversity(q->pdcch_d, x, q->cell.nof_ports, q->nof_symbols); - precoding_diversity(x, q->pdcch_symbols, q->cell.nof_ports, - q->nof_symbols / q->cell.nof_ports); - } else { - memcpy(q->pdcch_symbols[0], q->pdcch_d, q->nof_symbols * sizeof(cf_t)); - } - - /* mapping to resource elements */ - for (i = 0; i < q->cell.nof_ports; i++) { - regs_pdcch_put(q->regs, q->pdcch_symbols[i], slot_symbols[i]); - } - return LIBLTE_SUCCESS; - } else { - return LIBLTE_ERROR_INVALID_INPUTS; - } -} - - diff --git a/lte/phy/lib/phch/src/regs.c b/lte/phy/lib/phch/src/regs.c index 12f512e7a..0c0bf5405 100644 --- a/lte/phy/lib/phch/src/regs.c +++ b/lte/phy/lib/phch/src/regs.c @@ -34,6 +34,9 @@ #include "liblte/phy/phch/regs.h" #include "liblte/phy/utils/debug.h" +#define REG_IDX(r, i, n) r->k[i]+r->l*n*RE_X_RB + + regs_reg_t *regs_find_reg(regs_t *h, uint32_t k, uint32_t l); int regs_put_reg(regs_reg_t *reg, cf_t *reg_data, @@ -79,7 +82,8 @@ const unsigned char PDCCH_PERM[PDCCH_NCOLS] = int regs_pdcch_init(regs_t *h) { int i, m, cfi, nof_ctrl_symbols; int ret = LIBLTE_ERROR; - int nrows, ndummy, j, k, kp; + int nrows, ndummy, j; + uint32_t k, kp; regs_reg_t **tmp = NULL; bzero(&h->pdcch, sizeof(regs_ch_t)); @@ -126,9 +130,10 @@ int regs_pdcch_init(regs_t *h) { for (i = 0; i < nrows; i++) { if (i*PDCCH_NCOLS + PDCCH_PERM[j] >= ndummy) { m = i*PDCCH_NCOLS + PDCCH_PERM[j]-ndummy; - kp = (k-h->cell.id)%h->pdcch[cfi].nof_regs; - if (kp < 0) { - kp += h->pdcch[cfi].nof_regs; + if (k < h->cell.id) { + kp = (h->pdcch[cfi].nof_regs + k-h->cell.id)%h->pdcch[cfi].nof_regs; + } else { + kp = (k-h->cell.id)%h->pdcch[cfi].nof_regs; } h->pdcch[cfi].regs[m] = tmp[kp]; k++; @@ -163,28 +168,54 @@ int regs_pdcch_nregs(regs_t *h, uint32_t cfi) { /** Copy quadruplets to REGs and cyclic shift them, according to the * second part of 6.8.5 in 36.211 */ -int regs_pdcch_put(regs_t *h, cf_t *pdcch_symbols, cf_t *slot_symbols) { - if (!h->cfi_initiated) { + +int regs_pdcch_put_offset(regs_t *h, cf_t *pdcch_symbols, cf_t *slot_symbols, uint32_t start_reg, uint32_t nof_regs) { + if (h->cfi_initiated) { + if (start_reg + nof_regs <= h->pdcch[h->cfi].nof_regs) { + uint32_t i, k; + k = 0; + for (i=start_reg;ipdcch[h->cfi].regs[i], &pdcch_symbols[k], slot_symbols, h->cell.nof_prb); + k += 4; + } + return k; + } else { + fprintf(stderr, "Out of range: start_reg + nof_reg must be lower than %d\n", h->pdcch[h->cfi].nof_regs); + return LIBLTE_ERROR; + } + } else { fprintf(stderr, "Must call regs_set_cfi() first\n"); return LIBLTE_ERROR; } - int i; - for (i=0;ipdcch[h->cfi].nof_regs;i++) { - regs_put_reg(h->pdcch[h->cfi].regs[i], &pdcch_symbols[i*4], slot_symbols, h->cell.nof_prb); - } - return h->pdcch[h->cfi].nof_regs*4; } -int regs_pdcch_get(regs_t *h, cf_t *slot_symbols, cf_t *pdcch_symbols) { - if (!h->cfi_initiated) { +int regs_pdcch_put(regs_t *h, cf_t *pdcch_symbols, cf_t *slot_symbols) { + return regs_pdcch_put_offset(h, pdcch_symbols, slot_symbols, 0, h->pdcch[h->cfi].nof_regs); +} + +int regs_pdcch_get_offset(regs_t *h, cf_t *slot_symbols, cf_t *pdcch_symbols, uint32_t start_reg, uint32_t nof_regs) { + if (h->cfi_initiated) { + if (start_reg + nof_regs <= h->pdcch[h->cfi].nof_regs) { + uint32_t i, k; + k = 0; + for (i=start_reg;ipdcch[h->cfi].regs[i], slot_symbols, &pdcch_symbols[k], h->cell.nof_prb); + k += 4; + } + return k; + } else { + fprintf(stderr, "Out of range: start_reg + nof_reg must be lower than %d\n", h->pdcch[h->cfi].nof_regs); + return LIBLTE_ERROR; + } + } else { fprintf(stderr, "Must call regs_set_cfi() first\n"); return LIBLTE_ERROR; } - int i; - for (i=0;ipdcch[h->cfi].nof_regs;i++) { - regs_get_reg(h->pdcch[h->cfi].regs[i], slot_symbols, &pdcch_symbols[i*4], h->cell.nof_prb); - } - return h->pdcch[h->cfi].nof_regs*4; +} + + +int regs_pdcch_get(regs_t *h, cf_t *slot_symbols, cf_t *pdcch_symbols) { + return regs_pdcch_get_offset(h, slot_symbols, pdcch_symbols, 0, h->pdcch[h->cfi].nof_regs); } @@ -201,7 +232,7 @@ int regs_pdcch_get(regs_t *h, cf_t *slot_symbols, cf_t *pdcch_symbols) { */ int regs_phich_init(regs_t *h) { float ng; - int i,ni,li,n[3],nreg,mi; + uint32_t i, ni, li, n[3], nreg, mi; regs_reg_t **regs_phich[3]; int ret = LIBLTE_ERROR; @@ -306,7 +337,7 @@ clean_and_exit: } void regs_phich_free(regs_t *h) { - int i; + uint32_t i; if (h->phich) { if (CP_ISEXT(h->cell.cp)) { h->ngroups_phich /= 2; @@ -321,7 +352,7 @@ void regs_phich_free(regs_t *h) { } uint32_t regs_phich_nregs(regs_t *h) { - int i; + uint32_t i; uint32_t n; n=0; for (i=0;ingroups_phich;i++) { @@ -343,7 +374,7 @@ uint32_t regs_phich_ngroups(regs_t *h) { * Returns the number of written symbols, or -1 on error */ int regs_phich_add(regs_t *h, cf_t phich_symbols[REGS_PHICH_NSYM], uint32_t ngroup, cf_t *slot_symbols) { - int i; + uint32_t i; if (ngroup >= h->ngroups_phich) { fprintf(stderr, "Error invalid ngroup %d\n", ngroup); return LIBLTE_ERROR_INVALID_INPUTS; @@ -364,7 +395,7 @@ int regs_phich_add(regs_t *h, cf_t phich_symbols[REGS_PHICH_NSYM], uint32_t ngro * Returns the number of written symbols, or -1 on error */ int regs_phich_reset(regs_t *h, cf_t *slot_symbols) { - int i; + uint32_t i; uint32_t ngroup, ng; for (ngroup = 0;ngroup < h->ngroups_phich;CP_ISEXT(h->cell.cp)?ngroup+=2:ngroup++) { if (CP_ISEXT(h->cell.cp)) { @@ -386,7 +417,7 @@ int regs_phich_reset(regs_t *h, cf_t *slot_symbols) { * Returns the number of written symbols, or -1 on error */ int regs_phich_get(regs_t *h, cf_t *slot_symbols, cf_t phich_symbols[REGS_PHICH_NSYM], uint32_t ngroup) { - int i; + uint32_t i; if (ngroup >= h->ngroups_phich) { fprintf(stderr, "Error invalid ngroup %d\n", ngroup); return LIBLTE_ERROR_INVALID_INPUTS; @@ -421,7 +452,7 @@ int regs_phich_get(regs_t *h, cf_t *slot_symbols, cf_t phich_symbols[REGS_PHICH_ * 36.211 10.3 section 6.7.4 */ int regs_pcfich_init(regs_t *h) { - int i; + uint32_t i; uint32_t k_hat, k; regs_ch_t *ch = &h->pcfich; @@ -475,7 +506,7 @@ uint32_t regs_pcfich_nregs(regs_t *h) { int regs_pcfich_put(regs_t *h, cf_t pcfich_symbols[REGS_PCFICH_NSYM], cf_t *slot_symbols) { regs_ch_t *rch = &h->pcfich; - int i; + uint32_t i; for (i = 0; i < rch->nof_regs && i*REGS_RE_X_REG < REGS_PCFICH_NSYM; i++) { regs_put_reg(rch->regs[i], &pcfich_symbols[i*REGS_RE_X_REG], slot_symbols, h->cell.nof_prb); } @@ -489,7 +520,7 @@ int regs_pcfich_put(regs_t *h, cf_t pcfich_symbols[REGS_PCFICH_NSYM], cf_t *slot */ int regs_pcfich_get(regs_t *h, cf_t *slot_symbols, cf_t ch_data[REGS_PCFICH_NSYM]) { regs_ch_t *rch = &h->pcfich; - int i; + uint32_t i; for (i = 0; i < rch->nof_regs && i*REGS_RE_X_REG < REGS_PCFICH_NSYM; i++) { regs_get_reg(rch->regs[i], slot_symbols, &ch_data[i*REGS_RE_X_REG], h->cell.nof_prb); } @@ -516,7 +547,7 @@ int regs_pcfich_get(regs_t *h, cf_t *slot_symbols, cf_t ch_data[REGS_PCFICH_NSYM ***************************************************************/ regs_reg_t *regs_find_reg(regs_t *h, uint32_t k, uint32_t l) { - int i; + uint32_t i; for (i=0;inof_regs;i++) { if (h->regs[i].l == l && h->regs[i].k0 == k) { return &h->regs[i]; @@ -563,7 +594,7 @@ int regs_num_x_symbol(uint32_t symbol, uint32_t nof_port, lte_cp_t cp) { * 36.211 Section 6.2.4 */ int regs_reg_init(regs_reg_t *reg, uint32_t symbol, uint32_t nreg, uint32_t k0, uint32_t maxreg, uint32_t vo) { - int i, j, z; + uint32_t i, j, z; reg->l = symbol; reg->assigned = false; @@ -643,10 +674,10 @@ int regs_set_cfi(regs_t *h, uint32_t cfi) { */ int regs_init(regs_t *h, phich_resources_t phich_res, phich_length_t phich_len, lte_cell_t cell) { int ret = LIBLTE_ERROR_INVALID_INPUTS; - int i, k; + uint32_t i, k; uint32_t j[4], jmax, prb; uint32_t n[4], vo; - int max_ctrl_symbols; + uint32_t max_ctrl_symbols; if (h != NULL && lte_cell_isvalid(&cell)) @@ -727,13 +758,11 @@ clean_and_exit: return ret; } -#define REG_IDX(r, i, n) r->k[i]+r->l*n*RE_X_RB - /** * Puts one REG data (4 symbols) in the slot symbols array */ int regs_put_reg(regs_reg_t *reg, cf_t *reg_data, cf_t *slot_symbols, uint32_t nof_prb) { - int i; + uint32_t i; for (i = 0; i < REGS_RE_X_REG; i++) { slot_symbols[REG_IDX(reg, i, nof_prb)] = reg_data[i]; } @@ -745,7 +774,7 @@ int regs_put_reg(regs_reg_t *reg, cf_t *reg_data, cf_t *slot_symbols, uint32_t n * Used by PHICH */ int regs_add_reg(regs_reg_t *reg, cf_t *reg_data, cf_t *slot_symbols, uint32_t nof_prb) { - int i; + uint32_t i; for (i = 0; i < REGS_RE_X_REG; i++) { slot_symbols[REG_IDX(reg, i, nof_prb)] += reg_data[i]; } @@ -757,7 +786,7 @@ int regs_add_reg(regs_reg_t *reg, cf_t *reg_data, cf_t *slot_symbols, uint32_t n * Reset REG data (4 symbols) in the slot symbols array */ int regs_reset_reg(regs_reg_t *reg, cf_t *slot_symbols, uint32_t nof_prb) { - int i; + uint32_t i; for (i = 0; i < REGS_RE_X_REG; i++) { slot_symbols[REG_IDX(reg, i, nof_prb)] = 0; } @@ -768,7 +797,7 @@ int regs_reset_reg(regs_reg_t *reg, cf_t *slot_symbols, uint32_t nof_prb) { * Gets one REG data (4 symbols) from the slot symbols array */ int regs_get_reg(regs_reg_t *reg, cf_t *slot_symbols, cf_t *reg_data, uint32_t nof_prb) { - int i; + uint32_t i; for (i = 0; i < REGS_RE_X_REG; i++) { reg_data[i] = slot_symbols[REG_IDX(reg, i, nof_prb)]; } diff --git a/lte/phy/lib/phch/test/pdcch_file_test.c b/lte/phy/lib/phch/test/pdcch_file_test.c index f583a26b9..98ee55743 100644 --- a/lte/phy/lib/phch/test/pdcch_file_test.c +++ b/lte/phy/lib/phch/test/pdcch_file_test.c @@ -208,7 +208,6 @@ void base_free() { int main(int argc, char **argv) { ra_pdsch_t ra_dl; int i; - int nof_dcis; int nof_frames; int ret; dci_location_t locations[10]; @@ -264,20 +263,19 @@ int main(int argc, char **argv) { } } - if (pdcch_extract_llr(&pdcch, fft_buffer, ce, nof_frames, cfi)) { - fprintf(stderr, "Error extracting LLRs\n"); - return -1; + uint16_t crc_rem = 0; + for (i=0;i= 1234 && crc_rem < 1234 + nof_dcis) { + crc_rem -= 1234; + memcpy(&dci_rx[crc_rem], &dci_tmp, sizeof(dci_msg_t)); + } else { + printf("Received invalid DCI CRC 0x%x\n", crc_rem); goto quit; } } diff --git a/lte/phy/lib/phch/test/pdsch_file_test.c b/lte/phy/lib/phch/test/pdsch_file_test.c index def1c9e43..e436a83a1 100644 --- a/lte/phy/lib/phch/test/pdsch_file_test.c +++ b/lte/phy/lib/phch/test/pdsch_file_test.c @@ -218,7 +218,6 @@ int main(int argc, char **argv) { ra_pdsch_t ra_dl; ra_prb_t prb_alloc; int i; - int nof_dcis; int nof_frames; int ret; char *data; @@ -280,17 +279,20 @@ int main(int argc, char **argv) { } } - pdcch_extract_llr(&pdcch, fft_buffer, ce, nof_frames, cfi); - - nof_dcis = pdcch_decode_msg(&pdcch, &dci_msg, locations, nof_locations, Format1A, rnti); - if (nof_dcis < 0) { - fprintf(stderr, "Error decoding DCI messages\n"); - return -1; + + uint16_t crc_rem = 0; + for (i=0;i #include #include +#include #include "liblte/phy/resampling/decim.h" #include "liblte/phy/resampling/resample_arb.h" @@ -120,6 +121,8 @@ void sync_frame_run(sync_frame_t *q, cf_t *input) { break; } + assert(q->peak_idx < TRACK_LEN); + track_idx = sync_track(&q->s, &input[q->peak_idx - TRACK_LEN]); INFO("TRACK %3d: SF=%d. Previous idx is %d New Offset is %d\n", @@ -140,7 +143,7 @@ void sync_frame_run(sync_frame_t *q, cf_t *input) { q->cur_cfo = (sync_get_cfo(&q->s) + q->frame_cnt * q->cur_cfo) / (q->frame_cnt + 1); /* compute cumulative moving average time offset */ - q->timeoffset = (float) (track_idx - TRACK_LEN + q->timeoffset * q->frame_cnt) + q->timeoffset = (float) ((float) track_idx - TRACK_LEN + q->timeoffset * q->frame_cnt) / (q->frame_cnt + 1); q->last_found = q->frame_cnt;