From cb721aa292562fb92be9e63a045f21096625d5fc Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Mon, 4 Oct 2021 19:56:34 +0200 Subject: [PATCH] fix calculation of ssb frequency. --- lib/include/srsran/common/band_helper.h | 74 +++++++++++++++++++++---- lib/src/common/band_helper.cc | 51 ++++++++++------- srsenb/src/enb_cfg_parser.cc | 6 ++ 3 files changed, 100 insertions(+), 31 deletions(-) diff --git a/lib/include/srsran/common/band_helper.h b/lib/include/srsran/common/band_helper.h index 41425b5f8..4712ff13d 100644 --- a/lib/include/srsran/common/band_helper.h +++ b/lib/include/srsran/common/band_helper.h @@ -105,9 +105,19 @@ public: */ double get_center_freq_from_abs_freq_point_a(uint32_t nof_prb, uint32_t freq_point_a_arfcn); + /** + * @brief Compute the absolute pointA for a NR carrier from its bandwidth and the center frequency + * + * @param nof_prb Carrier bandwidth in number of RB + * @param center_freq double Frequency in Hz + * @return Absolute Point A frequency in Hz + */ + double get_abs_freq_point_a_from_center_freq(uint32_t nof_prb, double center_freq); + /** * @brief Compute the absolute frequency point A for a arfcn * + * @param band nr frequency band. * @param nof_prb Number of PRBs. * @param arfcn Given ARFCN. * @return frequency point A in arfcn notation. @@ -116,10 +126,9 @@ public: /** * @brief Compute the absolute frequency of the SSB for a DL ARFCN and a band. This selects an SSB center frequency - * following the band SS/PBCH frequency raster provided by 38.104 table 5.4.3.1-1 as close as possible to PointA + * following the band SS/PBCH frequency raster provided by TS38.104 table 5.4.3.1-1 as close as possible to PointA * without letting any SS/PBCH subcarrier below PointA * - * @param band nr frequency band. * @param scs ssb subcarrier spacing. * @param freq_point_a_arfcn frequency point a in arfcn notation. * @return absolute frequency of the SSB in arfcn notation. @@ -136,36 +145,77 @@ public: class sync_raster_t { protected: - sync_raster_t(uint32_t f, uint32_t s, uint32_t l) : first(f), step(s), last(l), gscn(f) {} + sync_raster_t(uint32_t gscn_f, uint32_t gscn_s, uint32_t gscn_l) : + gscn_first(gscn_f), gscn_step(gscn_s), gscn_last(gscn_l), gscn(gscn_f) + { + // see TS38.104 Table 5.4.3.1-1 + if (gscn_last <= 7498) { + N_first = 1; + N_last = 2499; + } else if (7499 <= gscn_last and gscn_last <= 22255) { + N_last = 14756; + } else if (22256 <= gscn_last and gscn_last <= 26639) { + N_last = 4383; + } + + N = N_first; + } uint32_t gscn; + uint32_t N; + uint32_t M[3] = {1, 3, 5}; + uint32_t M_idx = 0; private: - uint32_t first; - uint32_t step; - uint32_t last; + uint32_t gscn_first; + uint32_t gscn_step; + uint32_t gscn_last; + uint32_t N_first = 0; + uint32_t N_last = 0; public: - bool valid() const { return step != 0; } + bool valid() const { return gscn_step != 0; } void next() { - if (gscn <= last) { - gscn += step; + if (gscn_last <= 7498 and M_idx < 3) { + M_idx += 1; + if (M_idx == 3 and N <= N_last) { + M_idx = 0; + N += 1; + } + } else if (N <= N_last) { + N += 1; } } - bool end() const { return (gscn > last or step == 0); } + bool end() const { return (N > N_last or gscn_step == 0); } - void reset() { gscn = first; } + void reset() + { + N = N_first; + M_idx = 0; + } + + void gscn_next() + { + if (gscn <= gscn_last) { + gscn += gscn_step; + } + } + + bool gscn_end() const { return (gscn > gscn_last or gscn_step == 0); } + + void gscn_reset() { gscn = gscn_first; } double get_frequency() const; + + uint32_t get_gscn() const; }; sync_raster_t get_sync_raster(uint16_t band, srsran_subcarrier_spacing_t scs) const; private: // internal helper - double get_abs_freq_point_a_from_center_freq(uint32_t nof_prb, double center_freq); // Elements of TS 38.101-1 Table 5.2-1: NR operating bands in FR1 struct nr_operating_band { diff --git a/lib/src/common/band_helper.cc b/lib/src/common/band_helper.cc index 3e4960d5b..e4dd86756 100644 --- a/lib/src/common/band_helper.cc +++ b/lib/src/common/band_helper.cc @@ -136,24 +136,26 @@ double srsran_band_helper::get_abs_freq_point_a_from_center_freq(uint32_t nof_pr uint32_t srsran_band_helper::get_abs_freq_ssb_arfcn(uint16_t band, srsran_subcarrier_spacing_t scs, uint32_t freq_point_a_arfcn) { - double ssb_bw_hz = SRSRAN_SSB_BW_SUBC * SRSRAN_SUBC_SPACING_NR(scs); - sync_raster_t sync_raster = get_sync_raster(band, scs); if (!sync_raster.valid()) { return 0; } - double abs_freq_ssb_hz = sync_raster.get_frequency(); + // double abs_freq_ssb_hz = sync_raster.get_frequency(); + 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); - while (abs_freq_ssb_hz < (nr_arfcn_to_freq(freq_point_a_arfcn) + ssb_bw_hz / 2)) { - sync_raster.next(); - if (sync_raster.end()) { - return 0; + while (!sync_raster.end()) { + double abs_freq_ssb_hz = sync_raster.get_frequency(); + + if ((abs_freq_ssb_hz > (freq_point_a_hz + ssb_bw_hz / 2)) and + ((uint32_t)std::round(abs_freq_ssb_hz - freq_point_a_hz) % SRSRAN_SUBC_SPACING_NR(scs) == 0)) { + return freq_to_nr_arfcn(abs_freq_ssb_hz); } - abs_freq_ssb_hz = sync_raster.get_frequency(); - } - return freq_to_nr_arfcn(abs_freq_ssb_hz); + sync_raster.next(); + } + return 0; } srsran_ssb_patern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const @@ -213,7 +215,7 @@ srsran_duplex_mode_t srsran_band_helper::get_duplex_mode(uint16_t band) const struct sync_raster_impl : public srsran_band_helper::sync_raster_t { public: - sync_raster_impl(uint32_t f, uint32_t s, uint32_t l) : sync_raster_t(f, s, l) + sync_raster_impl(uint32_t gscn_f, uint32_t gscn_s, uint32_t gscn_l) : sync_raster_t(gscn_f, gscn_s, gscn_l) { // Do nothing } @@ -221,22 +223,20 @@ public: double srsran_band_helper::sync_raster_t::get_frequency() const { + // see TS38.104 table 5.4.3.1-1 + // Row 1 - if (gscn >= 2 and gscn <= 7498) { - double N = std::ceil((gscn - 1) / 3.0); - double M = (gscn - 3 * N) / 2.0 + 3.0; - return N * 1200e3 + M * 50e3; + if (gscn_last <= 7498) { + return N * 1200e3 + M[M_idx] * 50e3; } // Row 2 - if (gscn >= 7499 and gscn <= 22255) { - double N = gscn - 7499; + if (7499 <= gscn_last and gscn_last <= 22255) { return 3000e6 + N * 1.44e6; } // Row 3 - if (gscn >= 22256 and gscn <= 26639) { - double N = gscn - 22256; + if (22256 <= gscn_last and gscn_last <= 26639) { return 2425.08e6 + N * 17.28e6; } @@ -244,6 +244,19 @@ double srsran_band_helper::sync_raster_t::get_frequency() const return NAN; } +uint32_t srsran_band_helper::sync_raster_t::get_gscn() const +{ + if (gscn_last <= 7498) { + return 3 * N + (M[M_idx] - 3) / 2; + } else if (7499 <= gscn_last and gscn_last <= 22255) { + return 7499 + N; + } else if (22256 <= gscn_last and gscn_last <= 26639) { + return 22256 + N; + } + + return 0; +} + srsran_band_helper::sync_raster_t srsran_band_helper::get_sync_raster(uint16_t band, srsran_subcarrier_spacing_t scs) const { diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 748345350..7bc0930dd 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1540,6 +1540,12 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_cfg_, phy_cfg_t* ph cfg.ssb_absolute_freq_point = band_helper.get_abs_freq_ssb_arfcn(cfg.band, srsran_subcarrier_spacing_30kHz, cfg.dl_absolute_freq_point_a); } + + 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; + } + // Convert to frequency for PHY cfg.phy_cell.carrier.ssb_center_freq_hz = band_helper.nr_arfcn_to_freq(cfg.ssb_absolute_freq_point);