From 17d5ebca7ede758b759fc6fb2ce531c20369dcc4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 20 Oct 2016 17:49:51 +0200 Subject: [PATCH] isolated common tx/rx pucch functions --- srslte/include/srslte/enb/enb_ul.h | 7 +-- srslte/include/srslte/phch/pucch.h | 12 +++- srslte/lib/enb/enb_ul.c | 54 ++++++------------ srslte/lib/phch/pucch.c | 66 ++++++++++++++++++++- srslte/lib/ue/ue_ul.c | 92 ++++++------------------------ 5 files changed, 113 insertions(+), 118 deletions(-) diff --git a/srslte/include/srslte/enb/enb_ul.h b/srslte/include/srslte/enb/enb_ul.h index 8c1af2eea..60eb0e50f 100644 --- a/srslte/include/srslte/enb/enb_ul.h +++ b/srslte/include/srslte/enb/enb_ul.h @@ -125,11 +125,10 @@ SRSLTE_API void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer); SRSLTE_API int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, - srslte_pucch_format_t format, - uint32_t pdcch_n_cce, uint32_t rnti_idx, - srslte_uci_data_t *uci_data, - uint32_t sf_rx); + uint32_t pdcch_n_cce, + uint32_t sf_rx, + srslte_uci_data_t *uci_data); SRSLTE_API int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, diff --git a/srslte/include/srslte/phch/pucch.h b/srslte/include/srslte/phch/pucch.h index 4c7921dea..c5f9f7ea5 100644 --- a/srslte/include/srslte/phch/pucch.h +++ b/srslte/include/srslte/phch/pucch.h @@ -40,6 +40,7 @@ #include "srslte/common/sequence.h" #include "srslte/modem/mod.h" #include "srslte/phch/cqi.h" +#include "srslte/phch/uci.h" #define SRSLTE_PUCCH_N_SEQ 12 #define SRSLTE_PUCCH_MAX_BITS SRSLTE_CQI_MAX_BITS @@ -51,7 +52,8 @@ typedef enum SRSLTE_API { SRSLTE_PUCCH_FORMAT_1B, SRSLTE_PUCCH_FORMAT_2, SRSLTE_PUCCH_FORMAT_2A, - SRSLTE_PUCCH_FORMAT_2B + SRSLTE_PUCCH_FORMAT_2B, + SRSLTE_PUCCH_FORMAT_ERROR, } srslte_pucch_format_t; typedef struct SRSLTE_API { @@ -160,6 +162,14 @@ SRSLTE_API uint32_t srslte_pucch_m(srslte_pucch_cfg_t *cfg, uint32_t n_pucch, srslte_cp_t cp); +SRSLTE_API srslte_pucch_format_t srslte_pucch_get_format(srslte_uci_data_t *uci_data, + srslte_cp_t cp); + +SRSLTE_API uint32_t srslte_pucch_get_npucch(uint32_t n_cce, + srslte_pucch_format_t format, + bool has_scheduling_request, + srslte_pucch_sched_t *pucch_sched); + SRSLTE_API uint32_t srslte_pucch_n_prb(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, uint32_t n_pucch, diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index 64679fc1b..7732b30ed 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -216,24 +216,16 @@ void srslte_enb_ul_fft(srslte_enb_ul_t *q, cf_t *signal_buffer) srslte_ofdm_rx_sf(&q->fft, signal_buffer, q->sf_symbols); } -int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, srslte_pucch_format_t format, uint32_t pdcch_n_cce, - uint32_t rnti_idx, srslte_uci_data_t *uci_data, uint32_t sf_rx) +int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint32_t rnti_idx, + uint32_t pdcch_n_cce, uint32_t sf_rx, + srslte_uci_data_t *uci_data) { if (rnti_idx < q->nof_rnti) { - uint32_t n_pucch = 0; - switch(format) { - case SRSLTE_PUCCH_FORMAT_1: - n_pucch = q->pucch_sched[rnti_idx].n_pucch_sr; - break; - case SRSLTE_PUCCH_FORMAT_1A: - case SRSLTE_PUCCH_FORMAT_1B: - n_pucch = pdcch_n_cce + q->pucch_sched[rnti_idx].N_pucch_1; - break; - default: - fprintf(stderr, "Error getting PUCCH format %d not supported\n", format); - return SRSLTE_ERROR; - } + + srslte_pucch_format_t format = srslte_pucch_get_format(uci_data, q->cell.cp); + + uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data->scheduling_request, &q->pucch_sched[rnti_idx]); if (srslte_chest_ul_estimate_pucch(&q->chest, q->sf_symbols, q->ce, format, n_pucch, sf_rx)) { fprintf(stderr,"Error estimating PUCCH DMRS\n"); @@ -243,33 +235,21 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, srslte_pucch_format_t format, ui float noise_power = srslte_chest_ul_get_noise_estimate(&q->chest); uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; - if (srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, q->sf_symbols, q->ce, noise_power, bits)) { + int ret_val = srslte_pucch_decode(&q->pucch, format, n_pucch, sf_rx, q->sf_symbols, q->ce, noise_power, bits); + if (ret_val < 0) { fprintf(stderr,"Error decoding PUCCH\n"); return SRSLTE_ERROR; } - switch(format) { - case SRSLTE_PUCCH_FORMAT_1: - if (bits[0]) { - uci_data->scheduling_request = true; - } else { - uci_data->scheduling_request = false; - } - break; - case SRSLTE_PUCCH_FORMAT_1A: - case SRSLTE_PUCCH_FORMAT_1B: - uci_data->uci_ack = bits[0]; - uci_data->uci_ack_len = 1; - if (format == SRSLTE_PUCCH_FORMAT_1B) { - uci_data->uci_ack_2 = bits[0]; - uci_data->uci_ack_len = 2; - } - break; - default: - fprintf(stderr, "Error getting PUCCH format %d not supported\n", format); - return SRSLTE_ERROR; + // update schedulign request + if (uci_data->scheduling_request) { + uci_data->scheduling_request = ret_val; + } + + // Save ACK bits + if (uci_data->uci_ack_len > 0) { + uci_data->uci_ack = bits[0]; } - return SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid rnti_idx=%d\n", rnti_idx); diff --git a/srslte/lib/phch/pucch.c b/srslte/lib/phch/pucch.c index b066f337a..86e8bbcda 100644 --- a/srslte/lib/phch/pucch.c +++ b/srslte/lib/phch/pucch.c @@ -160,6 +160,64 @@ uint32_t get_pucch_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t return 0; } +/* Choose PUCCH format based on pending transmission as described in 10.1 of 36.213 */ +srslte_pucch_format_t srslte_pucch_get_format(srslte_uci_data_t *uci_data, srslte_cp_t cp) +{ + srslte_pucch_format_t format = SRSLTE_PUCCH_FORMAT_ERROR; + // No CQI data + if (uci_data->uci_cqi_len == 0) { + // 1-bit ACK + optional SR + if (uci_data->uci_ack_len == 1) { + format = SRSLTE_PUCCH_FORMAT_1A; + } + // 2-bit ACK + optional SR + else if (uci_data->uci_ack_len == 2) { + format = SRSLTE_PUCCH_FORMAT_1B; + } + // SR only + else if (uci_data->scheduling_request) { + format = SRSLTE_PUCCH_FORMAT_1; + } + } + // CQI data + else { + // CQI and no ack + if (uci_data->uci_ack_len == 0) { + format = SRSLTE_PUCCH_FORMAT_2; + } + // CQI + 1-bit ACK + else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1) { + format = SRSLTE_PUCCH_FORMAT_2A; + } + // CQI + 2-bit ACK + else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 2) { + format = SRSLTE_PUCCH_FORMAT_2B; + } + // CQI + 2-bit ACK + cyclic prefix + else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1 && SRSLTE_CP_ISEXT(cp)) { + format = SRSLTE_PUCCH_FORMAT_2B; + } + } + return format; +} + +/** Choose PUCCH resource as desribed in 10.1 of 36.213 */ +uint32_t srslte_pucch_get_npucch(uint32_t n_cce, srslte_pucch_format_t format, bool has_scheduling_request, srslte_pucch_sched_t *pucch_sched) +{ + uint32_t n_pucch = 0; + if (has_scheduling_request) { + n_pucch = pucch_sched->n_pucch_sr; + } else if (format != SRSLTE_PUCCH_FORMAT_2) { + if (pucch_sched->sps_enabled) { + n_pucch = pucch_sched->n_pucch_1[pucch_sched->tpc_for_pucch%4]; + } else { + n_pucch = n_cce + pucch_sched->N_pucch_1; + } + } else { + n_pucch = pucch_sched->n_pucch_2; + } +} + uint32_t srslte_pucch_n_prb(srslte_pucch_cfg_t *cfg, srslte_pucch_format_t format, uint32_t n_pucch, uint32_t nof_prb, srslte_cp_t cp, uint32_t ns) { @@ -655,15 +713,15 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, pucch_encode(q, format, n_pucch, sf_idx, bits, q->z_tmp); corr = crealf(srslte_vec_dot_prod_conj_ccc(q->z, q->z_tmp, nof_re))/nof_re; if (corr >= q->threshold_format1) { - bits[0] = 1; + ret = 1; } else { - bits[0] = 0; + ret = 0; } DEBUG("format1 corr=%f, nof_re=%d, th=%f\n", corr, nof_re, q->threshold_format1); break; case SRSLTE_PUCCH_FORMAT_1A: bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); - + ret = 0; for (int b=0;b<2;b++) { bits[0] = b; pucch_encode(q, format, n_pucch, sf_idx, bits, q->z_tmp); @@ -671,6 +729,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, if (corr > corr_max && corr >= q->threshold_format1a) { corr_max = corr; b_max = b; + ret = 1; } DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1a); } @@ -678,6 +737,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format, break; default: fprintf(stderr, "Error decoding PUCCH: Format %d not supported\n", format); + ret = SRSLTE_ERROR; break; } ret = SRSLTE_SUCCESS; diff --git a/srslte/lib/ue/ue_ul.c b/srslte/lib/ue/ue_ul.c index a8e717311..d4a97aaa9 100644 --- a/srslte/lib/ue/ue_ul.c +++ b/srslte/lib/ue/ue_ul.c @@ -220,64 +220,19 @@ int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant, return srslte_pusch_cfg(&q->pusch, &q->pusch_cfg, grant, &q->uci_cfg, &q->hopping_cfg, &q->srs_cfg, tti, rvidx, current_tx_nb); } -int pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t *format, - uint8_t pucch_bits[SRSLTE_PUCCH_MAX_BITS], uint8_t pucch2_bits[2], - srslte_cp_t cp) +// Encode bits from uci_data +void pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t format, + uint8_t pucch_bits[SRSLTE_PUCCH_MAX_BITS], + uint8_t pucch2_bits[SRSLTE_PUCCH_MAX_BITS]) { - int ret = SRSLTE_SUCCESS; - - // No CQI data - if (uci_data->uci_cqi_len == 0) { - // 1-bit ACK + optional SR - if (uci_data->uci_ack_len == 1) { - *format = SRSLTE_PUCCH_FORMAT_1A; - pucch_bits[0] = uci_data->uci_ack; - } - // 2-bit ACK + optional SR - else if (uci_data->uci_ack_len == 2) { - *format = SRSLTE_PUCCH_FORMAT_1B; - pucch_bits[0] = uci_data->uci_ack; - pucch_bits[1] = uci_data->uci_ack_2; - } - // SR only - else if (uci_data->scheduling_request) { - *format = SRSLTE_PUCCH_FORMAT_1; - } else { - ret = SRSLTE_ERROR; - } - } - // CQI data - else { - srslte_uci_encode_cqi_pucch(uci_data->uci_cqi, uci_data->uci_cqi_len, pucch_bits); - // CQI and no ack - if (uci_data->uci_ack_len == 0) { - *format = SRSLTE_PUCCH_FORMAT_2; - } - // CQI + 1-bit ACK - else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1) { - *format = SRSLTE_PUCCH_FORMAT_2A; - pucch2_bits[0] = uci_data->uci_ack; - } - // CQI + 2-bit ACK - else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 2) { - *format = SRSLTE_PUCCH_FORMAT_2B; - pucch2_bits[0] = uci_data->uci_ack; - pucch2_bits[1] = uci_data->uci_ack_2; - } - // CQI + 2-bit ACK + cyclic prefix - else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1 && SRSLTE_CP_ISEXT(cp)) { - *format = SRSLTE_PUCCH_FORMAT_2B; - pucch2_bits[0] = uci_data->uci_ack; - pucch2_bits[1] = uci_data->uci_ack_2; - } else { - ret = SRSLTE_ERROR; - } + if (format == SRSLTE_PUCCH_FORMAT_1A || format == SRSLTE_PUCCH_FORMAT_1B) { + pucch_bits[0] = uci_data->uci_ack; + pucch_bits[1] = uci_data->uci_ack_2; // this will be ignored in format 1a } - if (ret) { - fprintf(stderr, "Unsupported combination of UCI parameters: ack_len=%d, cqi_len=%d\n", - uci_data->uci_ack, uci_data->uci_cqi_len); + if (format == SRSLTE_PUCCH_FORMAT_2A || format == SRSLTE_PUCCH_FORMAT_2B) { + pucch2_bits[0] = uci_data->uci_ack; + pucch2_bits[1] = uci_data->uci_ack_2; // this will be ignored in format 2a } - return ret; } /* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal @@ -303,35 +258,24 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, bzero(pucch_bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); bzero(pucch2_bits, 2*sizeof(uint8_t)); + srslte_pucch_format_t format = srslte_pucch_get_format(&uci_data, q->cell.cp); + // Encode UCI information - if (pucch_encode_bits(&uci_data, &q->last_pucch_format, pucch_bits, pucch2_bits, q->cell.cp)) { - return SRSLTE_ERROR; - } + pucch_encode_bits(&uci_data, format, pucch_bits, pucch2_bits); // Choose n_pucch - uint32_t n_pucch = 0; - if (uci_data.scheduling_request) { - n_pucch = q->pucch_sched.n_pucch_sr; - } else if (q->last_pucch_format < SRSLTE_PUCCH_FORMAT_2) { - if (q->pucch_sched.sps_enabled) { - n_pucch = q->pucch_sched.n_pucch_1[q->pucch_sched.tpc_for_pucch%4]; - } else { - n_pucch = pdcch_n_cce + q->pucch_sched.N_pucch_1; - } - } else { - n_pucch = q->pucch_sched.n_pucch_2; - } - if (srslte_pucch_encode(&q->pucch, q->last_pucch_format, n_pucch, sf_idx, pucch_bits, q->sf_symbols)) { + uint32_t n_pucch = srslte_pucch_get_npucch(pdcch_n_cce, format, uci_data.scheduling_request, &q->pucch_sched); + if (srslte_pucch_encode(&q->pucch, format, n_pucch, sf_idx, pucch_bits, q->sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); return ret; } - if (srslte_refsignal_dmrs_pucch_gen(&q->signals, q->last_pucch_format, n_pucch, sf_idx, pucch2_bits, q->refsignal)) + if (srslte_refsignal_dmrs_pucch_gen(&q->signals, format, n_pucch, sf_idx, pucch2_bits, q->refsignal)) { fprintf(stderr, "Error generating PUSCH DRMS signals\n"); return ret; } - srslte_refsignal_dmrs_pucch_put(&q->signals, q->last_pucch_format, n_pucch, q->refsignal, q->sf_symbols); + srslte_refsignal_dmrs_pucch_put(&q->signals, format, n_pucch, q->refsignal, q->sf_symbols); if (srslte_ue_ul_srs_tx_enabled(&q->signals.srs_cfg, tti) && q->pucch.shortened) { if (q->signals_pregenerated) { @@ -341,6 +285,8 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, srslte_refsignal_srs_put(&q->signals, tti, q->srs_signal, q->sf_symbols); } } + + q->last_pucch_format = format; srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal);