diff --git a/lib/include/srsran/phy/phch/ra_ul_nr.h b/lib/include/srsran/phy/phch/ra_ul_nr.h index 958579257..b069b0734 100644 --- a/lib/include/srsran/phy/phch/ra_ul_nr.h +++ b/lib/include/srsran/phy/phch/ra_ul_nr.h @@ -119,11 +119,13 @@ SRSRAN_API int srsran_ra_ul_nr_freq(const srsran_carrier_nr_t* carrier, * @brief Selects a valid PUCCH resource for transmission * @param pucch_cfg PUCCH configuration from upper layers * @param uci_cfg Uplink Control information configuration (and PDCCH context) + * @param N_bwp_sz Uplink BWP size in nof_prb * @param[out] resource Selected resource for transmitting PUCCH * @return SRSRAN_SUCCESS if provided configuration is valid, SRSRAN_ERROR code otherwise */ SRSRAN_API int srsran_ra_ul_nr_pucch_resource(const srsran_pucch_nr_hl_cfg_t* pucch_cfg, const srsran_uci_cfg_nr_t* uci_cfg, + uint32_t N_bwp_sz, srsran_pucch_nr_resource_t* resource); /** diff --git a/lib/src/common/phy_cfg_nr.cc b/lib/src/common/phy_cfg_nr.cc index 98433d21f..fac74521d 100644 --- a/lib/src/common/phy_cfg_nr.cc +++ b/lib/src/common/phy_cfg_nr.cc @@ -321,7 +321,7 @@ bool phy_cfg_nr_t::get_pucch_uci_cfg(const srsran_slot_cfg_t& slot_cfg, srsran_pucch_nr_resource_t& resource) const { // Select PUCCH resource - if (srsran_ra_ul_nr_pucch_resource(&pucch, &uci_cfg, &resource) < SRSRAN_SUCCESS) { + if (srsran_ra_ul_nr_pucch_resource(&pucch, &uci_cfg, carrier.nof_prb, &resource) < SRSRAN_SUCCESS) { ERROR("Selecting PUCCH resource"); return false; } diff --git a/lib/src/phy/phch/ra_ul_nr.c b/lib/src/phy/phch/ra_ul_nr.c index 66567301e..2aaeb660a 100644 --- a/lib/src/phy/phch/ra_ul_nr.c +++ b/lib/src/phy/phch/ra_ul_nr.c @@ -470,31 +470,89 @@ int srsran_ra_ul_nr_freq(const srsran_carrier_nr_t* carrier, return SRSRAN_ERROR; } +typedef struct { + srsran_pucch_nr_format_t format; + uint32_t start_symbol; + uint32_t rb_offset; + uint32_t N_cs; +} pucch_res_common_cfg_t; + +// Table 9.2.1-1 +#define PUCCH_RES_COMMON_CFG_IDX_MAX 15 +static pucch_res_common_cfg_t pucch_res_common_cfg[PUCCH_RES_COMMON_CFG_IDX_MAX + 1] = { + {SRSRAN_PUCCH_NR_FORMAT_0, 12, 0, 2}, + {SRSRAN_PUCCH_NR_FORMAT_0, 12, 0, 3}, + {SRSRAN_PUCCH_NR_FORMAT_0, 12, 3, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 10, 0, 2}, + {SRSRAN_PUCCH_NR_FORMAT_1, 10, 0, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 10, 2, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 10, 4, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 4, 0, 2}, + {SRSRAN_PUCCH_NR_FORMAT_1, 4, 0, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 4, 2, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 4, 4, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 0, 2}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 0, 4}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 2, 4}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 4, 4}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 0, 4}}; + // Implements TS 38.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration -static int ra_ul_nr_pucch_resource_default(uint32_t r_pucch, srsran_pucch_nr_resource_t* resource) +static int ra_ul_nr_pucch_resource_default(uint32_t pucch_res_common_idx, + uint32_t N_size_bwp, + uint32_t r_pucch, + srsran_pucch_nr_resource_t* resource) { - // From BWP config - uint32_t N_size_bwp = 52; + if (pucch_res_common_idx > PUCCH_RES_COMMON_CFG_IDX_MAX) { + ERROR("Invalid pucch_res_common_idx value (%d)\n", pucch_res_common_idx); + return SRSRAN_ERROR; + } - // From row of index 11 - uint32_t rb_offset_bwp = 0; - uint32_t N_cs = 2; - uint32_t cs_v[2] = {0, 6}; + uint32_t cs_v_2[2] = {0, 6}; + uint32_t cs_v_3[3] = {0, 4, 8}; + uint32_t cs_v_4[4] = {0, 3, 6, 9}; - resource->start_symbol_idx = 0; - resource->nof_symbols = 14; + // Table 9.2.1-1 + resource->format = pucch_res_common_cfg[pucch_res_common_idx].format; + resource->start_symbol_idx = pucch_res_common_cfg[pucch_res_common_idx].start_symbol; + resource->nof_symbols = 14 - resource->start_symbol_idx; + uint32_t rb_offset_bwp = pucch_res_common_cfg[pucch_res_common_idx].rb_offset; + uint32_t N_cs = pucch_res_common_cfg[pucch_res_common_idx].N_cs; + + // Special case for cs_v_2 value + if (pucch_res_common_idx == 0) { + cs_v_2[1] = 3; + } + + // Special case for rb_offset + if (pucch_res_common_idx == 15) { + rb_offset_bwp = N_size_bwp / 4; + } + uint32_t csv_idx = 0; if (r_pucch / 8 == 0) { - resource->starting_prb = rb_offset_bwp + SRSRAN_FLOOR(r_pucch, N_cs); - resource->second_hop_prb = N_size_bwp - 1 - resource->starting_prb; - resource->initial_cyclic_shift = cs_v[r_pucch % N_cs]; + resource->starting_prb = rb_offset_bwp + SRSRAN_FLOOR(r_pucch, N_cs); + resource->second_hop_prb = N_size_bwp - 1 - resource->starting_prb; + csv_idx = r_pucch % N_cs; } else { - resource->second_hop_prb = rb_offset_bwp + SRSRAN_FLOOR(r_pucch - 8, N_cs); - resource->starting_prb = N_size_bwp - 1 - resource->second_hop_prb; - resource->initial_cyclic_shift = cs_v[(r_pucch - 8) % N_cs]; + resource->second_hop_prb = rb_offset_bwp + SRSRAN_FLOOR(r_pucch - 8, N_cs); + resource->starting_prb = N_size_bwp - 1 - resource->second_hop_prb; + csv_idx = (r_pucch - 8) % N_cs; } - return SRSRAN_ERROR; + switch (N_cs) { + case 2: + resource->initial_cyclic_shift = cs_v_2[csv_idx]; + break; + case 3: + resource->initial_cyclic_shift = cs_v_3[csv_idx]; + break; + case 4: + resource->initial_cyclic_shift = cs_v_4[csv_idx]; + break; + } + + return SRSRAN_SUCCESS; } static int ra_ul_nr_pucch_resource_hl(const srsran_pucch_nr_hl_cfg_t* cfg, @@ -542,6 +600,7 @@ static int ra_ul_nr_pucch_resource_hl(const srsran_pucch_nr_hl_cfg_t* cfg, int srsran_ra_ul_nr_pucch_resource(const srsran_pucch_nr_hl_cfg_t* pucch_cfg, const srsran_uci_cfg_nr_t* uci_cfg, + uint32_t N_bwp_sz, srsran_pucch_nr_resource_t* resource) { if (pucch_cfg == NULL || uci_cfg == NULL || resource == NULL) { @@ -643,9 +702,9 @@ int srsran_ra_ul_nr_pucch_resource(const srsran_pucch_nr_hl_cfg_t* pucch_cfg, // a PUCCH resource set is provided by pucch-ResourceCommon through an index to a row of Table 9.2.1-1 for size // transmission of HARQ-ACK information on PUCCH in an initial UL BWP of N BWP PRBs. if (!pucch_cfg->enabled) { - uint32_t N_cce = SRSRAN_FLOOR(52, 6); + uint32_t N_cce = SRSRAN_FLOOR(N_bwp_sz, 6); uint32_t r_pucch = ((2 * uci_cfg->pucch.n_cce_0) / N_cce) + 2 * uci_cfg->pucch.resource_id; - return ra_ul_nr_pucch_resource_default(r_pucch, resource); + return ra_ul_nr_pucch_resource_default(pucch_cfg->common.resource_common, N_bwp_sz, r_pucch, resource); } return ra_ul_nr_pucch_resource_hl(pucch_cfg, uci_cfg, uci_cfg->pucch.resource_id, resource); } diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index c8b3f68e9..99ee6f95b 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -669,24 +669,9 @@ bool cc_worker::work_ul() phy.set_ul_metrics(ul_m); } else if (srsran_uci_nr_total_bits(&uci_data.cfg) > 0) { - // Currently, default PUCCH is not supported, in this case log it and pretend no UCI was available - if (not cfg.pucch.enabled) { - if (logger.info.enabled()) { - std::array str; - srsran_uci_nr_info(&uci_data, str.data(), str.size()); - logger.info( - "PUCCH: No PUCCH resource to transmit UCI cc=%d, %s, tti_tx=%d", cc_idx, str.data(), ul_slot_cfg.idx); - } - - // No NR signal shall be transmitted - srsran_vec_cf_zero(tx_buffer[0], ue_ul.ifft.sf_sz); - - return true; - } - // Get PUCCH resource srsran_pucch_nr_resource_t resource = {}; - if (srsran_ra_ul_nr_pucch_resource(&cfg.pucch, &uci_data.cfg, &resource) < SRSRAN_SUCCESS) { + if (srsran_ra_ul_nr_pucch_resource(&cfg.pucch, &uci_data.cfg, cfg.carrier.nof_prb, &resource) < SRSRAN_SUCCESS) { ERROR("Selecting PUCCH resource"); return false; }