band_helper: add helper to derive DL/UL freq from abs_freq_point

calculate DL and UL freq in carrier struct based on given values
This commit is contained in:
Andre Puschmann 2021-09-09 18:17:29 +02:00
parent 377eb52b86
commit d26a7e0350
2 changed files with 84 additions and 4 deletions

View File

@ -31,6 +31,9 @@ public:
// Return frequency of given NR-ARFCN in Hz
double nr_arfcn_to_freq(uint32_t nr_arfcn);
// Frequency in Hz to NR-ARFCN
uint32_t freq_to_nr_arfcn(double freq);
// Possible values of delta f_raster in Table 5.4.2.3-1 and Table 5.4.2.3-2
enum delta_f_raster_t {
DEFAULT = 0, // for bands with 2 possible values for delta_f_raster (e.g. 15 and 30 kHz), the lower is chosen
@ -70,6 +73,16 @@ public:
*/
uint32_t get_ul_arfcn_from_dl_arfcn(uint32_t dl_arfcn) const;
/**
* @brief Compute the DL and UL center frequency for a NR carrier
*
* Results are stored inside the carrier struct.
*
* @param carrier Reference to a carrier struct including PRB, abs. frequency point A and carrier offset.
* @return int SRSRAN_SUCESS The center frequency
*/
int get_center_freq_from_abs_freq_point_a(srsran_carrier_nr_t& carrier);
/**
* @brief Selects the SSB pattern case according to the band number and subcarrier spacing
* @remark Described by TS 38.101-1 Table 5.4.3.3-1: Applicable SS raster entries per operating band
@ -165,25 +178,36 @@ private:
}};
struct nr_raster_params {
double freq_range_start;
double freq_range_end;
double delta_F_global_kHz;
double F_REF_Offs_MHz;
uint32_t N_REF_Offs;
uint32_t N_REF_min;
uint32_t N_REF_max;
bool operator==(const nr_raster_params& rhs) const
{
return freq_range_start == rhs.freq_range_start && freq_range_end == rhs.freq_range_end &&
delta_F_global_kHz == rhs.delta_F_global_kHz && F_REF_Offs_MHz == rhs.F_REF_Offs_MHz &&
N_REF_Offs == rhs.N_REF_Offs && N_REF_min == rhs.N_REF_min && N_REF_max == rhs.N_REF_max;
}
};
// Helper to calculate F_REF according to Table 5.4.2.1-1
nr_raster_params get_raster_params(uint32_t nr_arfcn);
nr_raster_params get_raster_params(double freq);
bool is_valid_raster_param(const nr_raster_params& raster);
static const uint32_t max_nr_arfcn = 3279165;
static constexpr std::array<nr_raster_params, 3> nr_fr_params = {{
// clang-format off
// Frequency range 0 - 3000 MHz
{5, 0.0, 0, 0, 599999},
{0, 3000, 5, 0.0, 0, 0, 599999},
// Frequency range 3000 - 24250 MHz
{15, 3000.0, 600000, 600000, 2016666},
{3000, 24250, 15, 3000.0, 600000, 600000, 2016666},
// Frequency range 24250 - 100000 MHz
{60, 24250.08, 2016667, 2016667, max_nr_arfcn}
{24250, 100000, 60, 24250.08, 2016667, 2016667, max_nr_arfcn}
// clang-format on
}};

View File

@ -29,9 +29,21 @@ constexpr std::array<srsran_band_helper::nr_band_ss_raster, srsran_band_helper::
double srsran_band_helper::nr_arfcn_to_freq(uint32_t nr_arfcn)
{
nr_raster_params params = get_raster_params(nr_arfcn);
if (not is_valid_raster_param(params)) {
return 0.0;
}
return (params.F_REF_Offs_MHz * 1e6 + params.delta_F_global_kHz * (nr_arfcn - params.N_REF_Offs) * 1e3);
}
uint32_t srsran_band_helper::freq_to_nr_arfcn(double freq)
{
nr_raster_params params = get_raster_params(freq);
if (not is_valid_raster_param(params)) {
return 0;
}
return (((freq + params.F_REF_Offs_MHz * 1e6) / 1e3 / params.delta_F_global_kHz) + params.N_REF_Offs);
}
// Implements 5.4.2.1 in TS 38.104
std::vector<uint32_t> srsran_band_helper::get_bands_nr(uint32_t nr_arfcn,
srsran_band_helper::delta_f_raster_t delta_f_raster)
@ -94,7 +106,31 @@ uint32_t srsran_band_helper::get_ul_arfcn_from_dl_arfcn(uint32_t dl_arfcn) const
}
}
return UINT16_MAX;
return 0;
}
int srsran_band_helper::get_center_freq_from_abs_freq_point_a(srsran_carrier_nr_t& carrier)
{
// for FR1 unit of resources blocks for freq calc is always 180kHz regardless for actual SCS of carrier
// TODO: add offset_to_carrier
double abs_freq_point_a_freq = nr_arfcn_to_freq(carrier.absolute_frequency_point_a);
carrier.dl_center_freq =
abs_freq_point_a_freq +
(carrier.nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) *
SRSRAN_NRE);
// UL depends on duplex
if (get_duplex_mode(get_band_from_dl_arfcn(carrier.absolute_frequency_point_a)) == SRSRAN_DUPLEX_MODE_TDD) {
// TDD case
carrier.ul_center_freq = carrier.dl_center_freq;
} else {
// FDD case
uint32_t dl_arfcn = freq_to_nr_arfcn(carrier.dl_center_freq);
uint32_t ul_arfcn = get_ul_arfcn_from_dl_arfcn(dl_arfcn);
carrier.ul_center_freq = nr_arfcn_to_freq(ul_arfcn);
}
return SRSRAN_SUCCESS;
}
srsran_ssb_patern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const
@ -198,4 +234,24 @@ srsran_band_helper::nr_raster_params srsran_band_helper::get_raster_params(uint3
return {}; // return empty params
}
srsran_band_helper::nr_raster_params srsran_band_helper::get_raster_params(double freq)
{
for (auto& fr : nr_fr_params) {
if (freq >= fr.freq_range_start * 1e6 && freq <= fr.freq_range_end * 1e6) {
return fr;
}
}
return {}; // return empty params
}
bool srsran_band_helper::is_valid_raster_param(const srsran_band_helper::nr_raster_params& raster)
{
for (auto& fr : nr_fr_params) {
if (fr == raster) {
return true;
}
}
return false;
}
} // namespace srsran