nr,gnb,rrc: fix ssb frequency derivation when coreset0 is active

master
Francisco 3 years ago committed by Andre Puschmann
parent 92c4e6e2d0
commit 0b8a6970f0

@ -704,6 +704,16 @@ SRSRAN_API int srsran_coreset_zero(uint32_t n_cell_id,
uint32_t idx,
srsran_coreset_t* coreset);
/**
* @brief Obtain offset in RBs between CoresetZero and SSB. See TS 38.213, Tables 13-{1,...,10}
* @param idx Index of 13-{1,...10} table
* @param ssb_scs SS/PBCH block subcarrier spacing
* @param pdcch_scs PDCCH subcarrier spacing
* @return offset in RBs, or -1 in case of invalid inputs
*/
SRSRAN_API int
srsran_coreset0_ssb_offset(uint32_t idx, srsran_subcarrier_spacing_t ssb_scs, srsran_subcarrier_spacing_t pdcch_scs);
/**
* @brief Convert SSB pattern to string
* @param pattern

@ -163,7 +163,7 @@ uint32_t srsran_band_helper::get_abs_freq_ssb_arfcn(uint16_t
double freq_point_a_hz = nr_arfcn_to_freq(freq_point_a_arfcn);
double ssb_bw_hz = SRSRAN_SSB_BW_SUBC * SRSRAN_SUBC_SPACING_NR(scs);
double coreset0_offset_hz = coreset0_offset_rb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(scs);
return find_lower_bound_abs_freq_ssb(band, scs, freq_point_a_hz + coreset0_offset_hz / 2 + ssb_bw_hz / 2);
return find_lower_bound_abs_freq_ssb(band, scs, freq_point_a_hz + coreset0_offset_hz + ssb_bw_hz / 2);
}
srsran_ssb_patern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const

@ -51,7 +51,7 @@ int bands_test_nr()
TESTASSERT(bands.nr_arfcn_to_freq(376000) == 1880.0e6);
TESTASSERT(bands.get_abs_freq_point_a_arfcn(52, 368500) == 367564);
TESTASSERT(bands.get_abs_freq_ssb_arfcn(3, srsran_subcarrier_spacing_15kHz, 367564) > 367924);
TESTASSERT_EQ(368410, bands.get_abs_freq_ssb_arfcn(3, srsran_subcarrier_spacing_15kHz, 367564, 16));
TESTASSERT_EQ(368410, bands.get_abs_freq_ssb_arfcn(3, srsran_subcarrier_spacing_15kHz, 367564, 12));
// n5
TESTASSERT(bands.get_duplex_mode(5) == SRSRAN_DUPLEX_MODE_FDD);
TESTASSERT(bands.nr_arfcn_to_freq(176300) == 881.5e6);

@ -682,6 +682,48 @@ int srsran_coreset_zero(uint32_t n_cell_id,
return SRSRAN_SUCCESS;
}
int srsran_coreset0_ssb_offset(uint32_t idx, srsran_subcarrier_spacing_t ssb_scs, srsran_subcarrier_spacing_t pdcch_scs)
{
// Verify inputs
if (idx >= 16) {
ERROR("Invalid CORESET Zero input. idx=%d", idx);
return SRSRAN_ERROR_INVALID_INPUTS;
}
// Default entry to NULL
const coreset_zero_entry_t* entry = NULL;
// Table 13-1: Set of resource blocks and slot symbols of CORESET for Type0-PDCCH search space set
// when {SS/PBCH block, PDCCH} SCS is {15, 15} kHz for frequency bands with minimum channel
// bandwidth 5 MHz or 10 MHz
if (ssb_scs == srsran_subcarrier_spacing_15kHz && pdcch_scs == srsran_subcarrier_spacing_15kHz) {
entry = &coreset_zero_15_15[idx];
}
// Table 13-2: Set of resource blocks and slot symbols of CORESET for Type0-PDCCH search space set
// when {SS/PBCH block, PDCCH} SCS is {15, 30} kHz for frequency bands with minimum channel
// bandwidth 5 MHz or 10 MHz
if (ssb_scs == srsran_subcarrier_spacing_15kHz && pdcch_scs == srsran_subcarrier_spacing_30kHz) {
entry = &coreset_zero_15_30[idx];
}
// Table 13-3: Set of resource blocks and slot symbols of CORESET for Type0-PDCCH search space set
// when {SS/PBCH block, PDCCH} SCS is {30, 15} kHz for frequency bands with minimum channel
// bandwidth 5 MHz or 10 MHz
if (ssb_scs == srsran_subcarrier_spacing_30kHz && pdcch_scs == srsran_subcarrier_spacing_15kHz) {
entry = &coreset_zero_30_15[idx];
}
// Check a valid entry has been selected
if (entry == NULL) {
ERROR("Unhandled case ssb_scs=%s, pdcch_scs=%s",
srsran_subcarrier_spacing_to_str(ssb_scs),
srsran_subcarrier_spacing_to_str(pdcch_scs));
return SRSRAN_ERROR;
}
return entry->offset_rb;
}
const char* srsran_ssb_pattern_to_str(srsran_ssb_patern_t pattern)
{
switch (pattern) {

@ -1643,23 +1643,20 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t*
}
// fill remaining SSB fields
uint32_t coreset0_rb_offset = 0;
int coreset0_rb_offset = 0;
if (rrc_nr_cfg_->is_standalone) {
// Taken from TS 38.213, Table 13-1
if (cfg.phy_cell.carrier.nof_prb > 96) {
coreset0_rb_offset = 96;
} else if (cfg.phy_cell.carrier.nof_prb > 48) {
coreset0_rb_offset = 16;
} else {
coreset0_rb_offset = 4;
}
const uint32_t coreset0_idx = 6; // See TS 38.331 - controlResourceSetZero / Table 13-1 index
cfg.phy_cell.pdcch.coreset_present[0] = true;
// Get offset in RBs between CORESET#0 and SSB
coreset0_rb_offset = srsran_coreset0_ssb_offset(coreset0_idx, cfg.ssb_cfg.scs, cfg.phy_cell.carrier.scs);
srsran_assert(coreset0_rb_offset >= 0, "Failed to compute RB offset between CORESET#0 and SSB");
}
cfg.ssb_absolute_freq_point =
band_helper.get_abs_freq_ssb_arfcn(cfg.band, cfg.ssb_cfg.scs, cfg.dl_absolute_freq_point_a, coreset0_rb_offset);
if (cfg.ssb_absolute_freq_point == 0) {
ERROR("Can't derive SSB freq point for dl_arfcn %d and band %d", cfg.dl_arfcn, cfg.band);
return SRSRAN_ERROR;
}
srsran_assert(cfg.ssb_absolute_freq_point > 0,
"Can't derive SSB freq point for dl_arfcn %d and band %d",
cfg.dl_arfcn,
cfg.band);
// Convert to frequency for PHY
cfg.phy_cell.carrier.ssb_center_freq_hz = band_helper.nr_arfcn_to_freq(cfg.ssb_absolute_freq_point);

@ -51,7 +51,7 @@ int rrc_nr::init(const rrc_nr_cfg_t& cfg_,
cfg = cfg_;
if (cfg.is_standalone) {
// Generate parameters of Coreset#0 and SS#0
const uint32_t coreset0_idx = 6;
const uint32_t coreset0_idx = 6; // See TS 38.331 - controlResourceSetZero
cfg.cell_list[0].phy_cell.pdcch.coreset_present[0] = true;
// Get pointA and SSB absolute frequencies
double pointA_abs_freq_Hz = cfg.cell_list[0].phy_cell.carrier.dl_center_frequency_hz -

Loading…
Cancel
Save