mirror of https://github.com/PentHertz/srsLTE.git
srsgnb: derive SSB frequency and ssb_offset based on user provided coreset0 index configuration. Added extra configuration validators
This commit is contained in:
parent
fef61554b2
commit
a6a9274203
|
@ -142,6 +142,21 @@ public:
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
double get_ssb_freq_hz(uint32_t cc_idx)
|
||||||
|
{
|
||||||
|
double ret = 0.0;
|
||||||
|
|
||||||
|
if (cc_idx < cell_list_lte.size()) {
|
||||||
|
ret = cell_list_lte[cc_idx].dl_freq_hz;
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_idx -= cell_list_lte.size();
|
||||||
|
if (cc_idx < cell_list_nr.size()) {
|
||||||
|
ret = cell_list_nr[cc_idx].carrier.ssb_center_freq_hz;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
uint32_t get_rf_port(uint32_t cc_idx)
|
uint32_t get_rf_port(uint32_t cc_idx)
|
||||||
{
|
{
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
|
|
|
@ -1519,6 +1519,7 @@ static int parse_nr_cell_list(all_args_t* args, rrc_nr_cfg_t* rrc_cfg_nr, rrc_cf
|
||||||
parse_opt_field(cell_cfg.phy_cell.rf_port, cellroot, "rf_port");
|
parse_opt_field(cell_cfg.phy_cell.rf_port, cellroot, "rf_port");
|
||||||
HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.carrier.pci, cellroot, "pci"));
|
HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.carrier.pci, cellroot, "pci"));
|
||||||
HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.cell_id, cellroot, "cell_id"));
|
HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.cell_id, cellroot, "cell_id"));
|
||||||
|
HANDLEPARSERCODE(parse_required_field(cell_cfg.coreset0_idx, cellroot, "coreset0_idx"));
|
||||||
HANDLEPARSERCODE(parse_required_field(cell_cfg.prach_root_seq_idx, cellroot, "root_seq_idx"));
|
HANDLEPARSERCODE(parse_required_field(cell_cfg.prach_root_seq_idx, cellroot, "root_seq_idx"));
|
||||||
HANDLEPARSERCODE(parse_required_field(cell_cfg.tac, cellroot, "tac"));
|
HANDLEPARSERCODE(parse_required_field(cell_cfg.tac, cellroot, "tac"));
|
||||||
|
|
||||||
|
@ -2140,54 +2141,11 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t*
|
||||||
ERROR("Only 10 MHz bandwidth supported.");
|
ERROR("Only 10 MHz bandwidth supported.");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
if (rrc_nr_cfg_->is_standalone) {
|
|
||||||
if (is_valid_arfcn(cfg.band, cfg.dl_arfcn) == false) {
|
|
||||||
ERROR("DL-ARFCN %d in band n%d not supported with coreset0 config.", cfg.dl_arfcn, cfg.band);
|
|
||||||
ERROR("Valid ARFCNs for band n%d are: %s", cfg.band, valid_arfcns_to_string(cfg.band).c_str());
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
if (cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD) {
|
|
||||||
ERROR("Only FDD duplex supported in SA mode.");
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SRSRAN_SUCCESS;
|
return SRSRAN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// List of selected ARFCNs in band n3, n7 and n20 that match the coreset0 config
|
|
||||||
using arfcn_list_t = std::list<uint32_t>;
|
|
||||||
std::map<uint32_t, arfcn_list_t> valid_arfcn = {{3, {363500, 368500, 369500, 374500, 375000}},
|
|
||||||
{7, {525000, 526200, 531000}},
|
|
||||||
{20, {159000, 160200}}};
|
|
||||||
|
|
||||||
std::string valid_arfcns_to_string(uint32_t band)
|
|
||||||
{
|
|
||||||
std::string band_string;
|
|
||||||
if (valid_arfcn.find(band) != valid_arfcn.end()) {
|
|
||||||
for (const auto& arfcn : valid_arfcn.at(band)) {
|
|
||||||
band_string += std::to_string(arfcn);
|
|
||||||
band_string += ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return band_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_valid_arfcn(uint32_t band, uint32_t dl_arfcn)
|
|
||||||
{
|
|
||||||
if (valid_arfcn.find(band) == valid_arfcn.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto& arfcn_list = valid_arfcn.at(band);
|
|
||||||
for (const auto& arfcn : arfcn_list) {
|
|
||||||
if (arfcn == dl_arfcn) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace enb_conf_sections
|
} // namespace enb_conf_sections
|
||||||
|
|
||||||
namespace sib_sections {
|
namespace sib_sections {
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "srsenb/hdr/phy/txrx.h"
|
||||||
|
#include "srsran/common/band_helper.h"
|
||||||
#include "srsran/common/threads.h"
|
#include "srsran/common/threads.h"
|
||||||
#include "srsran/srsran.h"
|
#include "srsran/srsran.h"
|
||||||
|
|
||||||
#include "srsenb/hdr/phy/txrx.h"
|
|
||||||
|
|
||||||
#define Error(fmt, ...) \
|
#define Error(fmt, ...) \
|
||||||
if (SRSRAN_DEBUG_ENABLED) \
|
if (SRSRAN_DEBUG_ENABLED) \
|
||||||
logger.error(fmt, ##__VA_ARGS__)
|
logger.error(fmt, ##__VA_ARGS__)
|
||||||
|
@ -85,6 +85,8 @@ void txrx::run_thread()
|
||||||
|
|
||||||
float samp_rate = srsran_sampling_freq_hz(worker_com->get_nof_prb(0));
|
float samp_rate = srsran_sampling_freq_hz(worker_com->get_nof_prb(0));
|
||||||
|
|
||||||
|
srsran::srsran_band_helper band_helper;
|
||||||
|
|
||||||
// Configure radio
|
// Configure radio
|
||||||
radio_h->set_rx_srate(samp_rate);
|
radio_h->set_rx_srate(samp_rate);
|
||||||
radio_h->set_tx_srate(samp_rate);
|
radio_h->set_tx_srate(samp_rate);
|
||||||
|
@ -94,8 +96,11 @@ void txrx::run_thread()
|
||||||
double tx_freq_hz = worker_com->get_dl_freq_hz(cc_idx);
|
double tx_freq_hz = worker_com->get_dl_freq_hz(cc_idx);
|
||||||
double rx_freq_hz = worker_com->get_ul_freq_hz(cc_idx);
|
double rx_freq_hz = worker_com->get_ul_freq_hz(cc_idx);
|
||||||
uint32_t rf_port = worker_com->get_rf_port(cc_idx);
|
uint32_t rf_port = worker_com->get_rf_port(cc_idx);
|
||||||
srsran::console("Setting frequency: DL=%.1f Mhz, UL=%.1f MHz for cc_idx=%d nof_prb=%d\n",
|
srsran::console(
|
||||||
|
"Setting frequency: DL=%.1f Mhz, DL_SSB=%.2f Mhz (SSB-ARFCN=%d), UL=%.1f MHz for cc_idx=%d nof_prb=%d\n",
|
||||||
tx_freq_hz / 1e6f,
|
tx_freq_hz / 1e6f,
|
||||||
|
worker_com->get_ssb_freq_hz(cc_idx) / 1e6f,
|
||||||
|
band_helper.freq_to_nr_arfcn(worker_com->get_ssb_freq_hz(cc_idx)),
|
||||||
rx_freq_hz / 1e6f,
|
rx_freq_hz / 1e6f,
|
||||||
cc_idx,
|
cc_idx,
|
||||||
worker_com->get_nof_prb(cc_idx));
|
worker_com->get_nof_prb(cc_idx));
|
||||||
|
|
|
@ -80,6 +80,7 @@ struct sched_nr_cell_cfg_t {
|
||||||
|
|
||||||
uint32_t nof_layers;
|
uint32_t nof_layers;
|
||||||
uint32_t pci;
|
uint32_t pci;
|
||||||
|
uint32_t ssb_offset;
|
||||||
uint32_t dl_cell_nof_prb;
|
uint32_t dl_cell_nof_prb;
|
||||||
uint32_t ul_cell_nof_prb;
|
uint32_t ul_cell_nof_prb;
|
||||||
asn1::rrc_nr::dl_cfg_common_sib_s dl_cfg_common;
|
asn1::rrc_nr::dl_cfg_common_sib_s dl_cfg_common;
|
||||||
|
|
|
@ -36,6 +36,7 @@ struct rrc_cell_cfg_nr_t {
|
||||||
srsran_duplex_mode_t duplex_mode;
|
srsran_duplex_mode_t duplex_mode;
|
||||||
double ssb_freq_hz;
|
double ssb_freq_hz;
|
||||||
uint32_t ssb_absolute_freq_point; // derived from DL ARFCN (SSB arfcn)
|
uint32_t ssb_absolute_freq_point; // derived from DL ARFCN (SSB arfcn)
|
||||||
|
uint32_t ssb_offset;
|
||||||
srsran_subcarrier_spacing_t ssb_scs;
|
srsran_subcarrier_spacing_t ssb_scs;
|
||||||
srsran_ssb_pattern_t ssb_pattern;
|
srsran_ssb_pattern_t ssb_pattern;
|
||||||
asn1::rrc_nr::pdcch_cfg_common_s pdcch_cfg_common;
|
asn1::rrc_nr::pdcch_cfg_common_s pdcch_cfg_common;
|
||||||
|
|
|
@ -27,7 +27,7 @@ void make_mib_cfg(const sched_nr_cell_cfg_t& cfg, srsran_mib_nr_t* mib)
|
||||||
{
|
{
|
||||||
*mib = {};
|
*mib = {};
|
||||||
mib->scs_common = (srsran_subcarrier_spacing_t)cfg.dl_cfg_common.init_dl_bwp.generic_params.subcarrier_spacing.value;
|
mib->scs_common = (srsran_subcarrier_spacing_t)cfg.dl_cfg_common.init_dl_bwp.generic_params.subcarrier_spacing.value;
|
||||||
mib->ssb_offset = 6; // TODO
|
mib->ssb_offset = cfg.ssb_offset;
|
||||||
mib->dmrs_typeA_pos = (srsran_dmrs_sch_typeA_pos_t)cfg.dmrs_type_a_position.value;
|
mib->dmrs_typeA_pos = (srsran_dmrs_sch_typeA_pos_t)cfg.dmrs_type_a_position.value;
|
||||||
mib->coreset0_idx = cfg.pdcch_cfg_sib1.ctrl_res_set_zero;
|
mib->coreset0_idx = cfg.pdcch_cfg_sib1.ctrl_res_set_zero;
|
||||||
mib->ss0_idx = cfg.pdcch_cfg_sib1.search_space_zero;
|
mib->ss0_idx = cfg.pdcch_cfg_sib1.search_space_zero;
|
||||||
|
|
|
@ -71,7 +71,7 @@ inline sched_nr_cell_cfg_t get_default_cell_cfg(const srsran::phy_cfg_nr_t& phy_
|
||||||
// TODO: phy_cfg.ssb_positions_in_burst.group_presence_present
|
// TODO: phy_cfg.ssb_positions_in_burst.group_presence_present
|
||||||
cell_cfg.dmrs_type_a_position.value = asn1::rrc_nr::mib_s::dmrs_type_a_position_opts::pos2;
|
cell_cfg.dmrs_type_a_position.value = asn1::rrc_nr::mib_s::dmrs_type_a_position_opts::pos2;
|
||||||
cell_cfg.ssb_scs.value = (asn1::rrc_nr::subcarrier_spacing_opts::options)phy_cfg.ssb.scs;
|
cell_cfg.ssb_scs.value = (asn1::rrc_nr::subcarrier_spacing_opts::options)phy_cfg.ssb.scs;
|
||||||
cell_cfg.pdcch_cfg_sib1.ctrl_res_set_zero = 6;
|
cell_cfg.pdcch_cfg_sib1.ctrl_res_set_zero = 0;
|
||||||
cell_cfg.pdcch_cfg_sib1.search_space_zero = 0;
|
cell_cfg.pdcch_cfg_sib1.search_space_zero = 0;
|
||||||
|
|
||||||
cell_cfg.bwps.resize(1);
|
cell_cfg.bwps.resize(1);
|
||||||
|
|
|
@ -1089,7 +1089,7 @@ int fill_mib_from_enb_cfg(const rrc_cell_cfg_nr_t& cell_cfg, asn1::rrc_nr::mib_s
|
||||||
default:
|
default:
|
||||||
srsran_terminate("Invalid carrier SCS=%d Hz", SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs));
|
srsran_terminate("Invalid carrier SCS=%d Hz", SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs));
|
||||||
}
|
}
|
||||||
mib.ssb_subcarrier_offset = 6; // TODO: currently hard-coded
|
mib.ssb_subcarrier_offset = cell_cfg.ssb_offset;
|
||||||
mib.dmrs_type_a_position.value = mib_s::dmrs_type_a_position_opts::pos2;
|
mib.dmrs_type_a_position.value = mib_s::dmrs_type_a_position_opts::pos2;
|
||||||
mib.pdcch_cfg_sib1.search_space_zero = 0;
|
mib.pdcch_cfg_sib1.search_space_zero = 0;
|
||||||
mib.pdcch_cfg_sib1.ctrl_res_set_zero = cell_cfg.coreset0_idx;
|
mib.pdcch_cfg_sib1.ctrl_res_set_zero = cell_cfg.coreset0_idx;
|
||||||
|
|
|
@ -338,6 +338,7 @@ void rrc_nr::config_mac()
|
||||||
cell.ssb_positions_in_burst = du_cfg->cell(cc).serv_cell_cfg_common().ssb_positions_in_burst;
|
cell.ssb_positions_in_burst = du_cfg->cell(cc).serv_cell_cfg_common().ssb_positions_in_burst;
|
||||||
cell.ssb_periodicity_ms = du_cfg->cell(cc).serv_cell_cfg_common().ssb_periodicity_serving_cell.to_number();
|
cell.ssb_periodicity_ms = du_cfg->cell(cc).serv_cell_cfg_common().ssb_periodicity_serving_cell.to_number();
|
||||||
cell.ssb_scs.value = (subcarrier_spacing_e::options)cfg.cell_list[0].phy_cell.carrier.scs;
|
cell.ssb_scs.value = (subcarrier_spacing_e::options)cfg.cell_list[0].phy_cell.carrier.scs;
|
||||||
|
cell.ssb_offset = du_cfg->cell(cc).mib.ssb_subcarrier_offset;
|
||||||
if (not cfg.is_standalone) {
|
if (not cfg.is_standalone) {
|
||||||
const serving_cell_cfg_common_s& serv_cell =
|
const serving_cell_cfg_common_s& serv_cell =
|
||||||
cell_ctxt->master_cell_group->sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common;
|
cell_ctxt->master_cell_group->sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common;
|
||||||
|
|
|
@ -115,7 +115,7 @@ void generate_default_nr_phy_cell(phy_cell_cfg_nr_t& phy_cell)
|
||||||
void generate_default_nr_cell(rrc_cell_cfg_nr_t& cell)
|
void generate_default_nr_cell(rrc_cell_cfg_nr_t& cell)
|
||||||
{
|
{
|
||||||
cell = {};
|
cell = {};
|
||||||
cell.coreset0_idx = 6;
|
cell.coreset0_idx = 7;
|
||||||
cell.ssb_absolute_freq_point = 0; // auto derived
|
cell.ssb_absolute_freq_point = 0; // auto derived
|
||||||
cell.num_ra_preambles = 8;
|
cell.num_ra_preambles = 8;
|
||||||
generate_default_nr_phy_cell(cell.phy_cell);
|
generate_default_nr_phy_cell(cell.phy_cell);
|
||||||
|
@ -187,8 +187,42 @@ int derive_ssb_params(bool is_sa,
|
||||||
band);
|
band);
|
||||||
|
|
||||||
// Convert to frequency for PHY
|
// Convert to frequency for PHY
|
||||||
|
cell.ssb_absolute_freq_point = ssb_abs_freq_point;
|
||||||
cell.ssb_freq_hz = band_helper.nr_arfcn_to_freq(ssb_abs_freq_point);
|
cell.ssb_freq_hz = band_helper.nr_arfcn_to_freq(ssb_abs_freq_point);
|
||||||
|
|
||||||
|
double pointA_abs_freq_Hz = dl_freq_hz - nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(pdcch_scs) / 2;
|
||||||
|
uint32_t ssb_pointA_freq_offset_Hz =
|
||||||
|
(cell.ssb_freq_hz > pointA_abs_freq_Hz) ? (uint32_t)(cell.ssb_freq_hz - pointA_abs_freq_Hz) : 0;
|
||||||
|
|
||||||
|
cell.ssb_offset = (uint32_t)(ssb_pointA_freq_offset_Hz / SRSRAN_SUBC_SPACING_NR(pdcch_scs)) % SRSRAN_NRE;
|
||||||
|
|
||||||
|
// Validate Coreset0 has space
|
||||||
|
srsran_coreset_t coreset0 = {};
|
||||||
|
ERROR_IF_NOT(
|
||||||
|
srsran_coreset_zero(
|
||||||
|
cell.phy_cell.cell_id, ssb_pointA_freq_offset_Hz, cell.ssb_scs, pdcch_scs, coreset0_idx, &coreset0) == 0,
|
||||||
|
"Deriving parameters for coreset0: index=%d, ssb_pointA_offset=%d kHz\n",
|
||||||
|
coreset0_idx,
|
||||||
|
ssb_pointA_freq_offset_Hz / 1000);
|
||||||
|
|
||||||
|
ERROR_IF_NOT(srsran_coreset_start_rb(&coreset0) + srsran_coreset_get_bw(&coreset0) <= cell.phy_cell.carrier.nof_prb,
|
||||||
|
"Coreset0 index=%d is not compatible with DL ARFCN %d in band %d\n",
|
||||||
|
coreset0_idx,
|
||||||
|
cell.dl_arfcn,
|
||||||
|
cell.band);
|
||||||
|
|
||||||
|
// Validate Coreset0 has less than 3 symbols
|
||||||
|
ERROR_IF_NOT(coreset0.duration < 3,
|
||||||
|
"Coreset0 index=%d is not supported due to overlap with SSB. Select a coreset0 index from 38.213 Table "
|
||||||
|
"13-1 such that N_symb_coreset < 3\n",
|
||||||
|
coreset0_idx);
|
||||||
|
|
||||||
|
// Validate Coreset0 has more than 24 RB
|
||||||
|
ERROR_IF_NOT(srsran_coreset_get_bw(&coreset0) > 24,
|
||||||
|
"Coreset0 configuration index=%d has only %d RB. A coreset0 index >= 6 is required such as N_rb >= 48\n",
|
||||||
|
srsran_coreset_get_bw(&coreset0),
|
||||||
|
coreset0_idx);
|
||||||
|
|
||||||
return SRSRAN_SUCCESS;
|
return SRSRAN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,15 +280,16 @@ int set_derived_nr_cell_params(bool is_sa, rrc_cell_cfg_nr_t& cell)
|
||||||
derive_phy_cell_freq_params(cell.dl_arfcn, cell.ul_arfcn, cell.phy_cell);
|
derive_phy_cell_freq_params(cell.dl_arfcn, cell.ul_arfcn, cell.phy_cell);
|
||||||
|
|
||||||
// Derive SSB params
|
// Derive SSB params
|
||||||
derive_ssb_params(is_sa,
|
ERROR_IF_NOT(derive_ssb_params(is_sa,
|
||||||
cell.dl_arfcn,
|
cell.dl_arfcn,
|
||||||
cell.band,
|
cell.band,
|
||||||
cell.phy_cell.carrier.scs,
|
cell.phy_cell.carrier.scs,
|
||||||
cell.coreset0_idx,
|
cell.coreset0_idx,
|
||||||
cell.phy_cell.carrier.nof_prb,
|
cell.phy_cell.carrier.nof_prb,
|
||||||
cell);
|
cell) == 0,
|
||||||
|
"Deriving SSB parameters\n");
|
||||||
|
|
||||||
cell.phy_cell.carrier.ssb_center_freq_hz = cell.ssb_freq_hz;
|
cell.phy_cell.carrier.ssb_center_freq_hz = cell.ssb_freq_hz;
|
||||||
cell.ssb_absolute_freq_point = band_helper.freq_to_nr_arfcn(cell.ssb_freq_hz);
|
|
||||||
|
|
||||||
// Derive remaining config params
|
// Derive remaining config params
|
||||||
if (not is_sa) {
|
if (not is_sa) {
|
||||||
|
|
Loading…
Reference in New Issue