mirror of https://github.com/PentHertz/srsLTE.git
Fixed error in PDSCH mapping. Further API simplification
This commit is contained in:
parent
0ebb0e7d00
commit
ec321f971d
|
@ -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 */
|
||||
|
|
|
@ -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<nof_locations && crc_rem != 1234;i++) {
|
||||
if (pdcch_extract_llr(&pdcch, fft_buffer, ce, locations[i], sf_idx, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return -1;
|
||||
}
|
||||
if (pdcch_decode_msg(&pdcch, &dci_msg, Format1A, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
INFO("Received %d DCI messages\n", nof_dcis);
|
||||
|
||||
if (nof_dcis == 1) {
|
||||
|
||||
if (crc_rem == 1234) {
|
||||
dci_msg_type_t type;
|
||||
if (dci_msg_get_type(&dci_msg, &type, cell.nof_prb, 1234, 1234)) {
|
||||
fprintf(stderr, "Can't get DCI message type\n");
|
||||
|
@ -482,7 +482,7 @@ int rx_run(cf_t *input, int sf_idx) {
|
|||
}
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
if (!disable_plots && nof_dcis > 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]));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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_
|
||||
|
||||
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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;i<q->nof_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));
|
||||
}
|
||||
}
|
||||
/* set now zeros at CP */
|
||||
for (i=0;i<q->nof_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;i<q->nof_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;i<q->nof_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]);
|
||||
}
|
||||
|
|
|
@ -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<frame_length; i++) {
|
||||
sr = (sr << 1) | (input[i] & 1);
|
||||
if (q != NULL &&
|
||||
input != NULL &&
|
||||
output != NULL &&
|
||||
frame_length > q->K + 1)
|
||||
{
|
||||
if (q->tail_biting) {
|
||||
sr = 0;
|
||||
for (i=frame_length - q->K + 1; i<frame_length; i++) {
|
||||
sr = (sr << 1) | (input[i] & 1);
|
||||
}
|
||||
} else {
|
||||
sr = 0;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
char bit = (i < frame_length) ? (input[i] & 1) : 0;
|
||||
sr = (sr << 1) | bit;
|
||||
for (j=0;j<q->R;j++) {
|
||||
output[q->R * i + j] = parity(sr & q->poly[j]);
|
||||
}
|
||||
}
|
||||
return q->R*len;
|
||||
} else {
|
||||
sr = 0;
|
||||
return LIBLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
int bit = (i < frame_length) ? (input[i] & 1) : 0;
|
||||
sr = (sr << 1) | bit;
|
||||
for (j=0;j<q->R;j++) {
|
||||
output[q->R * i + j] = parity(sr & q->poly[j]);
|
||||
}
|
||||
}
|
||||
|
||||
return q->R*len;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
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 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;
|
||||
}
|
||||
|
||||
/* 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));
|
||||
|
||||
/* 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);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
DEBUG("pdcch d symbols: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_c(stdout, q->pdcch_d, nof_symbols);
|
||||
}
|
||||
|
||||
/* demodulate symbols */
|
||||
demod_soft_sigma_set(&q->demod, 1.0);
|
||||
demod_soft_demodulate(&q->demod, q->pdcch_d, q->pdcch_llr, nof_symbols);
|
||||
|
||||
DEBUG("llr: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_f(stdout, q->pdcch_llr, q->e_bits);
|
||||
}
|
||||
|
||||
/* descramble */
|
||||
scrambling_f_offset(&q->seq_pdcch[nsubframe], q->pdcch_llr, 72 * location.ncce, q->e_bits);
|
||||
|
||||
ret = LIBLTE_SUCCESS;
|
||||
} 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);
|
||||
fprintf(stderr, "Illegal DCI message nCCE: %d, L: %d, nof_cce: %d\n", location.ncce, location.L, q->nof_cce);
|
||||
}
|
||||
|
||||
DEBUG("pdcch d symbols: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_c(stdout, q->pdcch_d, q->nof_symbols);
|
||||
}
|
||||
|
||||
/* 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("llr: ", 0);
|
||||
if (VERBOSE_ISDEBUG()) {
|
||||
vec_fprint_f(stdout, q->pdcch_llr, q->nof_bits);
|
||||
}
|
||||
|
||||
/* descramble */
|
||||
scrambling_f_offset(&q->seq_pdcch[nsubframe], q->pdcch_llr, 0, q->nof_bits);
|
||||
|
||||
return LIBLTE_SUCCESS;
|
||||
}
|
||||
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 <NIL> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;i<start_reg+nof_regs;i++) {
|
||||
regs_put_reg(h->pdcch[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;i<h->pdcch[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;i<start_reg + nof_regs;i++) {
|
||||
regs_get_reg(h->pdcch[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;i<h->pdcch[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;i<h->ngroups_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;i<h->nof_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)];
|
||||
}
|
||||
|
|
|
@ -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<nof_locations && crc_rem != rnti;i++) {
|
||||
if (pdcch_extract_llr(&pdcch, fft_buffer, ce, locations[i], nof_frames, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return -1;
|
||||
}
|
||||
if (pdcch_decode_msg(&pdcch, &dci_msg, Format1A, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
INFO("Received %d DCI messages\n", nof_dcis);
|
||||
|
||||
if (nof_dcis == 1) {
|
||||
if (crc_rem == rnti) {
|
||||
dci_msg_type_t type;
|
||||
if (dci_msg_get_type(&dci_msg, &type, cell.nof_prb, rnti, 1234)) {
|
||||
fprintf(stderr, "Can't get DCI message type\n");
|
||||
|
|
|
@ -105,7 +105,7 @@ int test_dci_payload_size() {
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
pdcch_t pdcch;
|
||||
dci_msg_t dci_tx[2], dci_rx[2];
|
||||
dci_msg_t dci_tx[2], dci_rx[2], dci_tmp;
|
||||
dci_location_t dci_locations[2];
|
||||
ra_pdsch_t ra_dl;
|
||||
regs_t regs;
|
||||
|
@ -173,16 +173,12 @@ int main(int argc, char **argv) {
|
|||
dci_msg_pack_pdsch(&ra_dl, &dci_tx[1], Format1, cell.nof_prb, false);
|
||||
dci_location_set(&dci_locations[1], 0, 1);
|
||||
|
||||
pdcch_reset(&pdcch);
|
||||
|
||||
for (i=0;i<nof_dcis;i++) {
|
||||
if (pdcch_encode_msg(&pdcch, &dci_tx[i], dci_locations[i], 1234+i)) {
|
||||
if (pdcch_encode(&pdcch, &dci_tx[i], dci_locations[i], 1234+i, slot_symbols, 0, cfi)) {
|
||||
fprintf(stderr, "Error encoding DCI message\n");
|
||||
goto quit;
|
||||
}
|
||||
}
|
||||
if (pdcch_gen_symbols(&pdcch, slot_symbols, 0, cfi)) {
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* combine outputs */
|
||||
for (i = 1; i < cell.nof_ports; i++) {
|
||||
|
@ -191,12 +187,21 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
if (pdcch_extract_llr(&pdcch, slot_symbols[0], ce, 0, cfi)) {
|
||||
goto quit;
|
||||
}
|
||||
|
||||
for (i=0;i<nof_dcis;i++) {
|
||||
if (pdcch_decode_msg(&pdcch, &dci_rx[i], dci_locations, 2, Format1, 1234+i) < 0) {
|
||||
for (i=0;i<2;i++) {
|
||||
if (pdcch_extract_llr(&pdcch, slot_symbols[0], ce, dci_locations[i], 0, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
goto quit;
|
||||
}
|
||||
uint16_t crc_rem;
|
||||
if (pdcch_decode_msg(&pdcch, &dci_tmp, Format1, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI message\n");
|
||||
goto quit;
|
||||
}
|
||||
if (crc_rem >= 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<nof_locations && crc_rem != rnti;i++) {
|
||||
if (pdcch_extract_llr(&pdcch, fft_buffer, ce, locations[i], nof_frames, cfi)) {
|
||||
fprintf(stderr, "Error extracting LLRs\n");
|
||||
return -1;
|
||||
}
|
||||
if (pdcch_decode_msg(&pdcch, &dci_msg, Format1A, &crc_rem)) {
|
||||
fprintf(stderr, "Error decoding DCI msg\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
INFO("Received %d DCI messages\n", nof_dcis);
|
||||
|
||||
if (nof_dcis == 1) {
|
||||
|
||||
if (crc_rem == rnti) {
|
||||
dci_msg_type_t type;
|
||||
if (dci_msg_get_type(&dci_msg, &type, cell.nof_prb, rnti, 1234)) {
|
||||
fprintf(stderr, "Can't get DCI message type\n");
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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;
|
||||
|
|
Loading…
Reference in New Issue