From f58f74b1024852c718fabc98614e47487bc4ac2e Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 18 Sep 2017 16:45:12 +0200 Subject: [PATCH 1/3] Solved PHICH Segmentation fault for MIMO --- lib/include/srslte/phy/phch/phich.h | 14 ++------------ lib/src/phy/phch/phich.c | 23 +++-------------------- lib/src/phy/phch/test/phich_file_test.c | 2 +- lib/src/phy/phch/test/phich_test.c | 24 ++++++++++++++---------- lib/src/phy/ue/ue_dl.c | 8 +------- 5 files changed, 21 insertions(+), 50 deletions(-) diff --git a/lib/include/srslte/phy/phch/phich.h b/lib/include/srslte/phy/phch/phich.h index f560fdc80..0645e22b1 100644 --- a/lib/include/srslte/phy/phch/phich.h +++ b/lib/include/srslte/phy/phch/phich.h @@ -101,8 +101,8 @@ SRSLTE_API void srslte_phich_calc(srslte_phich_t *q, uint32_t *nseq); SRSLTE_API int srslte_phich_decode(srslte_phich_t *q, - cf_t *slot_symbols, - cf_t *ce[SRSLTE_MAX_PORTS], + cf_t *slot_symbols[SRSLTE_MAX_PORTS], + cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate, uint32_t ngroup, uint32_t nseq, @@ -110,16 +110,6 @@ SRSLTE_API int srslte_phich_decode(srslte_phich_t *q, uint8_t *ack, float *distance); -SRSLTE_API int srslte_phich_decode_multi(srslte_phich_t *q, - cf_t *slot_symbols[SRSLTE_MAX_PORTS], - cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], - float noise_estimate, - uint32_t ngroup, - uint32_t nseq, - uint32_t nsubframe, - uint8_t *ack, - float *distance); - SRSLTE_API int srslte_phich_encode(srslte_phich_t *q, uint8_t ack, uint32_t ngroup, diff --git a/lib/src/phy/phch/phich.c b/lib/src/phy/phch/phich.c index a7cb282fd..14a0d5426 100644 --- a/lib/src/phy/phch/phich.c +++ b/lib/src/phy/phch/phich.c @@ -173,26 +173,9 @@ void srslte_phich_ack_encode(uint8_t ack, uint8_t bits[SRSLTE_PHICH_NBITS]) { memset(bits, ack, 3 * sizeof(uint8_t)); } -int srslte_phich_decode(srslte_phich_t *q, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, - uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) -{ - cf_t *_sf_symbols[SRSLTE_MAX_PORTS]; - cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; - - _sf_symbols[0] = sf_symbols; - for (int i=0;icell.nof_ports;i++) { - _ce[i][0] = ce[i]; - } - - return srslte_phich_decode_multi(q, _sf_symbols, _ce, noise_estimate, ngroup, nseq, subframe, ack, distance); -} -/* Decodes the phich channel and saves the CFI in the cfi pointer. - * - * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error - */ -int srslte_phich_decode_multi(srslte_phich_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate, - uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) -{ +int srslte_phich_decode(srslte_phich_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS], + cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate, + uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) { /* Set pointers for layermapping & precoding */ int i, j; diff --git a/lib/src/phy/phch/test/phich_file_test.c b/lib/src/phy/phch/test/phich_file_test.c index 0250c6f0b..968aa5cbc 100644 --- a/lib/src/phy/phch/test/phich_file_test.c +++ b/lib/src/phy/phch/test/phich_file_test.c @@ -263,7 +263,7 @@ int main(int argc, char **argv) { for (ngroup=0;ngroupphich), srslte_phich_nsf(&q->phich)); - cf_t *ce0[SRSLTE_MAX_PORTS]; - for (int i=0;ice_m[i][0]; - } - - - if (!srslte_phich_decode(&q->phich, q->sf_symbols_m[0], ce0, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { + if (!srslte_phich_decode(&q->phich, q->sf_symbols_m, q->ce_m, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { INFO("Decoded PHICH %d with distance %f\n", ack_bit, distance); } else { fprintf(stderr, "Error decoding PHICH\n"); From 336a6b621796575171366a005bb744121d00bc8f Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 19 Sep 2017 10:32:29 +0200 Subject: [PATCH 2/3] Increased compatibility for TM3 and TM4 with one Rx antenna --- lib/src/phy/mimo/precoding.c | 4 +-- lib/src/phy/phch/pdsch.c | 19 +++++++++--- lib/src/phy/ue/ue_dl.c | 60 +++++++++++++++++------------------- srsue/src/phy/phch_worker.cc | 33 +++++++++++++++----- 4 files changed, 71 insertions(+), 45 deletions(-) diff --git a/lib/src/phy/mimo/precoding.c b/lib/src/phy/mimo/precoding.c index bf9047977..6f3e43889 100644 --- a/lib/src/phy/mimo/precoding.c +++ b/lib/src/phy/mimo/precoding.c @@ -1367,7 +1367,7 @@ int srslte_predecoding_multiplex(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_P int nof_rxant, int nof_ports, int nof_layers, int codebook_idx, int nof_symbols, float noise_estimate) { - if (nof_ports == 2 && nof_rxant == 2) { + if (nof_ports == 2 && nof_rxant <= 2) { if (nof_layers == 2) { switch (mimo_decoder) { case SRSLTE_MIMO_DECODER_ZF: @@ -1407,7 +1407,7 @@ int srslte_predecoding_multiplex(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_P } else if (nof_ports == 4) { ERROR("Error predecoding multiplex: not implemented for %d Tx ports", nof_ports); } else { - ERROR("Error predecoding multiplex: Invalid combination of ports %d and rx antennax %d\n", nof_ports, nof_rxant); + ERROR("Error predecoding multiplex: Invalid combination of ports %d and rx antennas %d\n", nof_ports, nof_rxant); } return SRSLTE_ERROR; } diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 16f72a37e..de553630e 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -246,7 +246,7 @@ static int pdsch_init(srslte_pdsch_t *q, uint32_t max_prb, bool is_ue, uint32_t goto clean; } if (q->is_ue) { - for (int j=0;jnof_rx_antennas;j++) { + for (int j = 0; j < SRSLTE_MAX_PORTS; j++) { q->ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->ce[i][j]) { goto clean; @@ -309,7 +309,7 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { free(q->symbols[i]); } if (q->is_ue) { - for (int j=0;jnof_rx_antennas;j++) { + for (int j = 0; j < SRSLTE_MAX_PORTS; j++) { if (q->ce[i][j]) { free(q->ce[i][j]); } @@ -713,8 +713,9 @@ int srslte_pdsch_pmi_select(srslte_pdsch_t *q, cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate, uint32_t nof_ce, uint32_t pmi[SRSLTE_MAX_LAYERS], float sinr[SRSLTE_MAX_LAYERS][SRSLTE_MAX_CODEBOOKS]) { - if (q->cell.nof_ports == 2 && q->nof_rx_antennas == 2) { - for (int nof_layers = 1; nof_layers <= 2; nof_layers++ ) { + if (q->cell.nof_ports == 2 && q->nof_rx_antennas <= 2) { + int nof_layers = 1; + for (; nof_layers <= q->nof_rx_antennas; nof_layers++ ) { if (sinr[nof_layers - 1] && pmi) { if (srslte_precoding_pmi_select(ce, nof_ce, noise_estimate, nof_layers, &pmi[nof_layers - 1], sinr[nof_layers - 1]) < 0) { @@ -723,6 +724,16 @@ int srslte_pdsch_pmi_select(srslte_pdsch_t *q, } } } + + /* FIXME: Set other layers to 0 */ + for (; nof_layers <= SRSLTE_MAX_LAYERS; nof_layers++ ) { + if (sinr[nof_layers - 1] && pmi) { + for (int cb = 0; cb < SRSLTE_MAX_CODEBOOKS; cb++) { + sinr[nof_layers - 1][cb] = -INFINITY; + } + pmi[nof_layers - 1] = 0; + } + } } else { ERROR("Not implemented configuration"); return SRSLTE_ERROR_INVALID_INPUTS; diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index cbeb6ce87..fd04a4c85 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -115,7 +115,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, } srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft.symbol_sz); - for (int j=0;jsf_symbols_m[j] = srslte_vec_malloc(MAX_SFLEN_RE * sizeof(cf_t)); if (!q->sf_symbols_m[j]) { perror("malloc"); @@ -127,6 +127,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, perror("malloc"); goto clean_exit; } + bzero(q->ce_m[i][j], MAX_SFLEN_RE * sizeof(cf_t)); } } @@ -163,7 +164,7 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) { free(q->softbuffers[i]); } } - for (int j=0;jnof_rx_antennas;j++) { + for (int j = 0; j < SRSLTE_MAX_PORTS; j++) { if (q->sf_symbols_m[j]) { free(q->sf_symbols_m[j]); } @@ -516,10 +517,10 @@ int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q, uint8_t *ri, uint8_t *pmi, flo float best_sinr = -INFINITY; uint8_t best_pmi = 0, best_ri = 0; - if (q->cell.nof_ports < 2 || q->nof_rx_antennas < 2) { + if (q->cell.nof_ports < 2) { /* Do nothing */ return SRSLTE_SUCCESS; - } else if (q->cell.nof_ports == 2 && q->nof_rx_antennas == 2) { + } else { if (srslte_pdsch_pmi_select(&q->pdsch, &q->pdsch_cfg, q->ce_m, noise_estimate, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp), q->pmi, q->sinr)) { ERROR("SINR calculation error"); @@ -527,7 +528,7 @@ int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q, uint8_t *ri, uint8_t *pmi, flo } /* Select the best Rank indicator (RI) and Precoding Matrix Indicator (PMI) */ - for (uint32_t nof_layers = 1; nof_layers <= 2; nof_layers++) { + for (uint32_t nof_layers = 1; nof_layers <= SRSLTE_MAX_LAYERS; nof_layers++) { float _sinr = q->sinr[nof_layers - 1][q->pmi[nof_layers - 1]] * nof_layers * nof_layers; if (_sinr > best_sinr + 0.1) { best_sinr = _sinr; @@ -535,37 +536,34 @@ int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q, uint8_t *ri, uint8_t *pmi, flo best_ri = (uint8_t) (nof_layers - 1); } } + } - /* Set RI */ - if (ri != NULL) { - *ri = best_ri; - } + /* Print Trace */ + if (ri != NULL && pmi != NULL && current_sinr != NULL) { + INFO("PDSCH Select RI=%d; PMI=%d; Current SINR=%.1fdB (nof_layers=%d, codebook_idx=%d)\n", *ri, *pmi, + 10*log10(*current_sinr), q->pdsch_cfg.nof_layers, q->pdsch_cfg.codebook_idx); + } - /* Set PMI */ - if (pmi != NULL) { - *pmi = best_pmi; - } + /* Set RI */ + if (ri != NULL) { + *ri = best_ri; + } - /* Set current SINR */ - if (current_sinr != NULL && q->pdsch_cfg.mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) { - if (q->pdsch_cfg.nof_layers == 1) { - *current_sinr = q->sinr[0][q->pdsch_cfg.codebook_idx]; - } else if (q->pdsch_cfg.nof_layers == 2) { - *current_sinr = q->sinr[1][q->pdsch_cfg.codebook_idx - 1]; - } else { - ERROR("Not implemented number of layers (%d)", q->pdsch_cfg.nof_layers); - return SRSLTE_ERROR; - } - } + /* Set PMI */ + if (pmi != NULL) { + *pmi = best_pmi; + } - /* Print Trace */ - if (ri != NULL && pmi != NULL && current_sinr != NULL) { - INFO("PDSCH Select RI=%d; PMI=%d; Current SINR=%.1fdB (nof_layers=%d, codebook_idx=%d)\n", *ri, *pmi, - 10*log10(*current_sinr), q->pdsch_cfg.nof_layers, q->pdsch_cfg.codebook_idx); + /* Set current SINR */ + if (current_sinr != NULL && q->pdsch_cfg.mimo_type == SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX) { + if (q->pdsch_cfg.nof_layers == 1) { + *current_sinr = q->sinr[0][q->pdsch_cfg.codebook_idx]; + } else if (q->pdsch_cfg.nof_layers == 2) { + *current_sinr = q->sinr[1][q->pdsch_cfg.codebook_idx - 1]; + } else { + ERROR("Not implemented number of layers (%d)", q->pdsch_cfg.nof_layers); + return SRSLTE_ERROR; } - } else { - ERROR("Not implemented configuration"); - return SRSLTE_ERROR_INVALID_INPUTS; } return SRSLTE_SUCCESS; diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 2f99c2699..f1dff5f8d 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -255,9 +255,17 @@ void phch_worker::work_imp() /* Select Rank Indicator by computing Condition Number */ if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_3) { - float cn = 0.0f; - srslte_ue_dl_ri_select(&ue_dl, &uci_data.uci_ri, &cn); - uci_data.uci_ri_len = 1; + if (ue_dl.nof_rx_antennas > 1) { + /* If 2 ort more receiving antennas, select RI */ + float cn = 0.0f; + srslte_ue_dl_ri_select(&ue_dl, &uci_data.uci_ri, &cn); + uci_data.uci_ri_len = 1; + } else { + /* If only one receiving antenna, force RI for 1 layer */ + uci_data.uci_ri = 0; + uci_data.uci_ri_len = 1; + Warning("Only one receiving antenna with TM3. Forcing RI=1 layer.\n"); + } } else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4){ float sinr = 0.0f; uint8 packed_pmi = 0; @@ -271,6 +279,11 @@ void phch_worker::work_imp() uci_data.uci_pmi_len = 1; uci_data.uci_dif_cqi_len = 3; } + + /* If only one antenna in TM4 print limitation warning */ + if (ue_dl.nof_rx_antennas < 2) { + Warning("Only one receiving antenna with TM4. Forcing RI=1 layer (PMI=%d).\n", packed_pmi); + } } } } @@ -508,20 +521,22 @@ int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSL case LIBLTE_RRC_TRANSMISSION_MODE_3: if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 1) { mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; - } else if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) { + } else if (ue_dl.nof_rx_antennas > 1 && SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) { mimo_type = SRSLTE_MIMO_TYPE_CDD; } else { - Error("Wrong number of transport blocks (%d) for TM3\n", SRSLTE_RA_DL_GRANT_NOF_TB(grant)); + Error("Wrong combination of antennas (%d) or transport blocks (%d) for TM3\n", ue_dl.nof_rx_antennas, + SRSLTE_RA_DL_GRANT_NOF_TB(grant)); valid_config = false; } break; case LIBLTE_RRC_TRANSMISSION_MODE_4: if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 1) { mimo_type = (grant->pinfo == 0) ? SRSLTE_MIMO_TYPE_TX_DIVERSITY : SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX; - } else if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) { + } else if (ue_dl.nof_rx_antennas > 1 && SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) { mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX; } else { - Error("Wrong number of transport blocks (%d) for TM4\n", SRSLTE_RA_DL_GRANT_NOF_TB(grant)); + Error("Wrong combination of antennas (%d) or transport blocks (%d) for TM3\n", ue_dl.nof_rx_antennas, + SRSLTE_RA_DL_GRANT_NOF_TB(grant)); valid_config = false; } break; @@ -923,12 +938,14 @@ void phch_worker::encode_pucch() float tx_power = srslte_ue_ul_pucch_power(&ue_ul, phy->pathloss, ue_ul.last_pucch_format, uci_data.uci_cqi_len, uci_data.uci_ack_len); float gain = set_power(tx_power); - Info("PUCCH: power=%.2f dBm, tti_tx=%d, n_cce=%3d, n_pucch=%d, n_prb=%d, ack=%s%s, ri=%s, sr=%s, cfo=%.1f Hz%s\n", + Info("PUCCH: power=%.2f dBm, tti_tx=%d, n_cce=%3d, n_pucch=%d, n_prb=%d, ack=%s%s, ri=%s, pmi=%s%s, sr=%s, cfo=%.1f Hz%s\n", tx_power, (tti+4)%10240, last_dl_pdcch_ncce, ue_ul.pucch.last_n_pucch, ue_ul.pucch.last_n_prb, uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no", uci_data.uci_ack_len>1?(uci_data.uci_ack_2?"1":"0"):"", uci_data.uci_ri_len>0?(uci_data.uci_ri?"1":"0"):"no", + uci_data.uci_pmi_len>0?(uci_data.uci_pmi[1]?"1":"0"):"no", + uci_data.uci_pmi_len>0?(uci_data.uci_pmi[0]?"1":"0"):"", uci_data.scheduling_request?"yes":"no", cfo*15000, timestr); } From 55446fc2a214a68ce4ed6e35ff0d6c474b4fd72b Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 21 Sep 2017 10:03:02 +0200 Subject: [PATCH 3/3] Over the wire format can be selected through RF args --- lib/src/phy/rf/rf_uhd_imp.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index ad69c0642..d392d828c 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -386,7 +386,17 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) uhd_usrp_set_clock_source(handler->usrp, "gpsdo", 0); } - + // Set over the wire format + char *otw_format = "sc16"; + if (strstr(args, "otw_format=sc12")) { + otw_format = "sc12"; + } else if (strstr(args, "otw_format=sc16")) { + /* Do nothing */ + } else if (strstr(args, "otw_format=")) { + fprintf(stderr, "Wrong over the wire format. Valid formats: sc12, sc16\n", error); + return -1; + } + handler->has_rssi = get_has_rssi(handler); if (handler->has_rssi) { uhd_sensor_value_make_from_realnum(&handler->rssi_value, "rssi", 0, "dBm", "%f"); @@ -395,7 +405,7 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) size_t channel[4] = {0, 1, 2, 3}; uhd_stream_args_t stream_args = { .cpu_format = "fc32", - .otw_format = (nof_channels > 1) ? "sc12" : "sc16", + .otw_format = otw_format, .args = "", .channel_list = channel, .n_channels = nof_channels, @@ -632,7 +642,8 @@ int rf_uhd_recv_with_time_multi(void *h, return -1; } else if (error_code != UHD_RX_METADATA_ERROR_CODE_NONE ) { fprintf(stderr, "Error code 0x%x was returned during streaming. Aborting.\n", error_code); - return -1; + // FIXME: Keep going if an error not mentioned above occurs + // return -1; } } while (n < nsamples && trials < 100);