fix calculation of ssb frequency.

master
Fabian Eckermann 3 years ago committed by Andre Puschmann
parent 2111788740
commit cb721aa292

@ -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 {

@ -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
{

@ -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);

Loading…
Cancel
Save