|
|
@ -120,7 +120,7 @@ static int pusch_init(srslte_pusch_t* q, uint32_t max_prb, bool is_ue)
|
|
|
|
|
|
|
|
|
|
|
|
INFO("Init PUSCH: %d PRBs\n", max_prb);
|
|
|
|
INFO("Init PUSCH: %d PRBs\n", max_prb);
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
for (i = 0; i < SRSLTE_MOD_NITEMS; i++) {
|
|
|
|
if (srslte_modem_table_lte(&q->mod[i], modulations[i])) {
|
|
|
|
if (srslte_modem_table_lte(&q->mod[i], modulations[i])) {
|
|
|
|
goto clean;
|
|
|
|
goto clean;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -162,11 +162,18 @@ static int pusch_init(srslte_pusch_t* q, uint32_t max_prb, bool is_ue)
|
|
|
|
goto clean;
|
|
|
|
goto clean;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Allocate eNb specific buffers
|
|
|
|
if (!q->is_ue) {
|
|
|
|
if (!q->is_ue) {
|
|
|
|
q->ce = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
|
|
|
|
q->ce = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
|
|
|
|
if (!q->ce) {
|
|
|
|
if (!q->ce) {
|
|
|
|
goto clean;
|
|
|
|
goto clean;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
q->evm_buffer = srslte_evm_buffer_alloc(6);
|
|
|
|
|
|
|
|
if (!q->evm_buffer) {
|
|
|
|
|
|
|
|
ERROR("Allocating EVM buffer\n");
|
|
|
|
|
|
|
|
goto clean;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
q->z = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
|
|
|
|
q->z = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
|
|
|
|
if (!q->z) {
|
|
|
|
if (!q->z) {
|
|
|
@ -211,7 +218,9 @@ void srslte_pusch_free(srslte_pusch_t* q)
|
|
|
|
if (q->z) {
|
|
|
|
if (q->z) {
|
|
|
|
free(q->z);
|
|
|
|
free(q->z);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (q->evm_buffer) {
|
|
|
|
|
|
|
|
srslte_evm_free(q->evm_buffer);
|
|
|
|
|
|
|
|
}
|
|
|
|
srslte_dft_precoding_free(&q->dft_precoding);
|
|
|
|
srslte_dft_precoding_free(&q->dft_precoding);
|
|
|
|
|
|
|
|
|
|
|
|
if (q->users) {
|
|
|
|
if (q->users) {
|
|
|
@ -227,7 +236,7 @@ void srslte_pusch_free(srslte_pusch_t* q)
|
|
|
|
|
|
|
|
|
|
|
|
srslte_sequence_free(&q->tmp_seq);
|
|
|
|
srslte_sequence_free(&q->tmp_seq);
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
for (i = 0; i < SRSLTE_MOD_NITEMS; i++) {
|
|
|
|
srslte_modem_table_free(&q->mod[i]);
|
|
|
|
srslte_modem_table_free(&q->mod[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
srslte_sch_free(&q->ul_sch);
|
|
|
|
srslte_sch_free(&q->ul_sch);
|
|
|
@ -241,6 +250,11 @@ int srslte_pusch_set_cell(srslte_pusch_t* q, srslte_cell_t cell)
|
|
|
|
|
|
|
|
|
|
|
|
if (q != NULL && srslte_cell_isvalid(&cell)) {
|
|
|
|
if (q != NULL && srslte_cell_isvalid(&cell)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Resize EVM buffer, only for eNb
|
|
|
|
|
|
|
|
if (!q->is_ue && q->evm_buffer) {
|
|
|
|
|
|
|
|
srslte_evm_buffer_resize(q->evm_buffer, cell.nof_prb);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
q->cell = cell;
|
|
|
|
q->cell = cell;
|
|
|
|
q->max_re = cell.nof_prb * MAX_PUSCH_RE(cell.cp);
|
|
|
|
q->max_re = cell.nof_prb * MAX_PUSCH_RE(cell.cp);
|
|
|
|
ret = SRSLTE_SUCCESS;
|
|
|
|
ret = SRSLTE_SUCCESS;
|
|
|
@ -498,6 +512,16 @@ int srslte_pusch_decode(srslte_pusch_t* q,
|
|
|
|
srslte_demod_soft_demodulate_s(cfg->grant.tb.mod, q->d, q->q, cfg->grant.nof_re);
|
|
|
|
srslte_demod_soft_demodulate_s(cfg->grant.tb.mod, q->d, q->q, cfg->grant.nof_re);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cfg->meas_evm_en && q->evm_buffer) {
|
|
|
|
|
|
|
|
if (q->llr_is_8bit) {
|
|
|
|
|
|
|
|
out->evm = srslte_evm_run_b(q->evm_buffer, &q->mod[cfg->grant.tb.mod], q->d, q->q, cfg->grant.tb.nof_bits);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
out->evm = srslte_evm_run_s(q->evm_buffer, &q->mod[cfg->grant.tb.mod], q->d, q->q, cfg->grant.tb.nof_bits);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
out->evm = NAN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Generate scrambling sequence if not pre-generated
|
|
|
|
// Generate scrambling sequence if not pre-generated
|
|
|
|
srslte_sequence_t* seq = get_user_sequence(q, cfg->rnti, sf->tti % 10, cfg->grant.tb.nof_bits);
|
|
|
|
srslte_sequence_t* seq = get_user_sequence(q, cfg->rnti, sf->tti % 10, cfg->grant.tb.nof_bits);
|
|
|
|
if (!seq) {
|
|
|
|
if (!seq) {
|
|
|
@ -563,7 +587,11 @@ uint32_t srslte_pusch_tx_info(srslte_pusch_cfg_t* cfg, srslte_uci_value_t* uci_d
|
|
|
|
return len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg, srslte_pusch_res_t* res, char* str, uint32_t str_len)
|
|
|
|
uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg,
|
|
|
|
|
|
|
|
srslte_pusch_res_t* res,
|
|
|
|
|
|
|
|
srslte_chest_ul_res_t* chest_res,
|
|
|
|
|
|
|
|
char* str,
|
|
|
|
|
|
|
|
uint32_t str_len)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t len = srslte_print_check(str, str_len, 0, "rnti=0x%x", cfg->rnti);
|
|
|
|
uint32_t len = srslte_print_check(str, str_len, 0, "rnti=0x%x", cfg->rnti);
|
|
|
@ -575,6 +603,18 @@ uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg, srslte_pusch_res_t* res,
|
|
|
|
|
|
|
|
|
|
|
|
len += srslte_uci_data_info(&cfg->uci_cfg, &res->uci, &str[len], str_len - len);
|
|
|
|
len += srslte_uci_data_info(&cfg->uci_cfg, &res->uci, &str[len], str_len - len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
len = srslte_print_check(str, str_len, len, ", snr=%.1f dB", chest_res->snr_db);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Append Time Aligment information if available
|
|
|
|
|
|
|
|
if (cfg->meas_ta_en) {
|
|
|
|
|
|
|
|
len = srslte_print_check(str, str_len, len, ", ta=%.1f us", chest_res->ta_us);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Append EVM measurement if available
|
|
|
|
|
|
|
|
if (cfg->meas_evm_en) {
|
|
|
|
|
|
|
|
len = srslte_print_check(str, str_len, len, ", evm=%.1f %%", res->evm * 100);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (cfg->meas_time_en) {
|
|
|
|
if (cfg->meas_time_en) {
|
|
|
|
len = srslte_print_check(str, str_len, len, ", t=%d us", cfg->meas_time_value);
|
|
|
|
len = srslte_print_check(str, str_len, len, ", t=%d us", cfg->meas_time_value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|