diff --git a/srslte/include/srslte/ch_estimation/chest_ul.h b/srslte/include/srslte/ch_estimation/chest_ul.h index 90a706cc7..8f21cb6b3 100644 --- a/srslte/include/srslte/ch_estimation/chest_ul.h +++ b/srslte/include/srslte/ch_estimation/chest_ul.h @@ -56,6 +56,7 @@ typedef struct { bool dmrs_signal_configured; cf_t *pilot_estimates; + cf_t *pilot_estimates_tmp[4]; cf_t *pilot_recv_signal; cf_t *pilot_known_signal; cf_t *tmp_noise; @@ -105,7 +106,8 @@ SRSLTE_API int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t *q, cf_t *ce, srslte_pucch_format_t format, uint32_t n_pucch, - uint32_t sf_idx); + uint32_t sf_idx, + uint8_t *pucch2_ack_bits); SRSLTE_API float srslte_chest_ul_get_noise_estimate(srslte_chest_ul_t *q); diff --git a/srslte/lib/ch_estimation/chest_ul.c b/srslte/lib/ch_estimation/chest_ul.c index 7e558c2d0..9f86b69ee 100644 --- a/srslte/lib/ch_estimation/chest_ul.c +++ b/srslte/lib/ch_estimation/chest_ul.c @@ -78,6 +78,13 @@ int srslte_chest_ul_init(srslte_chest_ul_t *q, srslte_cell_t cell) perror("malloc"); goto clean_exit; } + for (int i=0;i<4;i++) { + q->pilot_estimates_tmp[i] = srslte_vec_malloc(sizeof(cf_t) * NOF_REFS_SF); + if (!q->pilot_estimates_tmp[i]) { + perror("malloc"); + goto clean_exit; + } + } q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * (NOF_REFS_SF+1)); if (!q->pilot_recv_signal) { perror("malloc"); @@ -125,6 +132,11 @@ void srslte_chest_ul_free(srslte_chest_ul_t *q) if (q->pilot_estimates) { free(q->pilot_estimates); } + for (int i=0;i<4;i++) { + if (q->pilot_estimates_tmp[i]) { + free(q->pilot_estimates_tmp[i]); + } + } if (q->pilot_recv_signal) { free(q->pilot_recv_signal); } @@ -266,7 +278,8 @@ int srslte_chest_ul_estimate(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, } int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, - srslte_pucch_format_t format, uint32_t n_pucch, uint32_t sf_idx) + srslte_pucch_format_t format, uint32_t n_pucch, uint32_t sf_idx, + uint8_t *pucch2_ack_bits) { if (!q->dmrs_signal_configured) { fprintf(stderr, "Error must call srslte_chest_ul_set_cfg() before using the UL estimator\n"); @@ -285,11 +298,37 @@ int srslte_chest_ul_estimate_pucch(srslte_chest_ul_t *q, cf_t *input, cf_t *ce, /* Generate known pilots */ uint8_t pucch2_bits[2] = {0, 0}; - srslte_refsignal_dmrs_pucch_gen(&q->dmrs_signal, format, n_pucch, sf_idx, pucch2_bits, q->pilot_known_signal), + if (format == SRSLTE_PUCCH_FORMAT_2A || format == SRSLTE_PUCCH_FORMAT_2B) { + float max = -1e9; + int i_max = 0; + + int m = 0; + if (format == SRSLTE_PUCCH_FORMAT_2A) { + m = 2; + } else { + m = 4; + } + + for (int i=0;idmrs_signal, format, n_pucch, sf_idx, pucch2_bits, q->pilot_known_signal); + srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->pilot_known_signal, q->pilot_estimates_tmp[i], nrefs_sf); + float x = cabsf(srslte_vec_acc_cc(q->pilot_estimates_tmp[i], nrefs_sf)); + if (x >= max) { + max = x; + i_max = i; + } + } + memcpy(q->pilot_estimates, q->pilot_estimates_tmp[i_max], nrefs_sf*sizeof(cf_t)); + pucch2_ack_bits[0] = i_max%2; + pucch2_ack_bits[1] = i_max/2; + } else { + srslte_refsignal_dmrs_pucch_gen(&q->dmrs_signal, format, n_pucch, sf_idx, pucch2_bits, q->pilot_known_signal); + /* Use the known DMRS signal to compute Least-squares estimates */ + srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->pilot_known_signal, q->pilot_estimates, nrefs_sf); + } - /* Use the known DMRS signal to compute Least-squares estimates */ - srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->pilot_known_signal, q->pilot_estimates, nrefs_sf); - if (ce != NULL) { /* FIXME: Currently averaging entire slot, performance good enough? */ for (int ns=0;ns<2;ns++) { diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index 2ef5ebe5b..f536e33f8 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -230,12 +230,11 @@ int get_pucch(srslte_enb_ul_t *q, uint16_t rnti, uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data->scheduling_request, &q->users[rnti]->pucch_sched); - if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, sf_rx)) { + if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, sf_rx, &bits[20])) { fprintf(stderr,"Error estimating PUCCH DMRS\n"); return SRSLTE_ERROR; } - int ret_val = srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, rnti, q->sf_symbols, q->ce, noise_power, bits); if (ret_val < 0) { fprintf(stderr,"Error decoding PUCCH\n"); @@ -271,9 +270,15 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint16_t rnti, uci_data->uci_ack = pucch_bits[0]; } - // Decode CQI bits + // PUCCH2 CQI bits are decoded inside srslte_pucch_decode() if (uci_data->uci_cqi_len) { memcpy(uci_data->uci_cqi, pucch_bits, uci_data->uci_cqi_len*sizeof(uint8_t)); + if (uci_data->uci_ack_len >= 1) { + uci_data->uci_ack = pucch_bits[20]; + } + if (uci_data->uci_ack_len == 2) { + uci_data->uci_ack_2 = pucch_bits[21]; + } } return SRSLTE_SUCCESS; diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index 487f4c04a..443dd57bd 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -794,6 +794,8 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, bits[0] = b_max; break; case SRSLTE_PUCCH_FORMAT_2: + case SRSLTE_PUCCH_FORMAT_2A: + case SRSLTE_PUCCH_FORMAT_2B: if (q->users[rnti]) { pucch_encode_(q, format, n_pucch, sf_idx, rnti, NULL, ref, true); srslte_vec_prod_conj_ccc(q->z, ref, q->z_tmp, SRSLTE_PUCCH_MAX_SYMBOLS);