Refactor carrier frequency from PHY and fix OFDM phase compensation

master
Xavier Arteaga 3 years ago committed by Andre Puschmann
parent fda35bf6a1
commit 8f90ee847a

@ -90,20 +90,13 @@ public:
srsran_duplex_mode_t get_duplex_mode(uint16_t band) const; srsran_duplex_mode_t get_duplex_mode(uint16_t band) const;
/** /**
* @brief Compute the DL center frequency for a NR carrier * @brief Compute the center frequency for a NR carrier from its bandwidth and the absolute pointA
* *
* @param carrier Const Reference to a carrier struct including PRB, abs. frequency point A and carrier offset. * @param nof_prb Carrier bandwidth in number of RB
* @param freq_point_a_arfcn Absolute Point A frequency ARFCN
* @return double Frequency in Hz * @return double Frequency in Hz
*/ */
double get_dl_center_freq(const srsran_carrier_nr_t& carrier); double get_center_freq_from_abs_freq_point_a(uint32_t nof_prb, uint32_t freq_point_a_arfcn);
/**
* @brief Compute the UL center frequency for a NR carrier
*
* @param carrier Const Reference to a carrier struct including PRB, abs. frequency point A and carrier offset.
* @return double Frequency in Hz
*/
double get_ul_center_freq(const srsran_carrier_nr_t& carrier);
/** /**
* @brief Compute the absolute frequency point A for a arfcn * @brief Compute the absolute frequency point A for a arfcn
@ -146,8 +139,6 @@ public:
private: private:
// internal helper // internal helper
double get_center_freq_from_abs_freq_point_a(uint32_t nof_prb, uint32_t freq_point_a_arfcn);
double get_abs_freq_point_a_from_center_freq(uint32_t nof_prb, double center_freq); 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 // Elements of TS 38.101-1 Table 5.2-1: NR operating bands in FR1

@ -33,6 +33,7 @@ struct phy_cfg_nr_t {
uint32_t periodicity_ms = 0; uint32_t periodicity_ms = 0;
std::array<bool, SRSRAN_SSB_NOF_CANDIDATES> position_in_burst = {}; std::array<bool, SRSRAN_SSB_NOF_CANDIDATES> position_in_burst = {};
srsran_subcarrier_spacing_t scs = srsran_subcarrier_spacing_30kHz; srsran_subcarrier_spacing_t scs = srsran_subcarrier_spacing_30kHz;
srsran_ssb_patern_t pattern = SRSRAN_SSB_PATTERN_A;
}; };
srsran_duplex_config_nr_t duplex = {}; srsran_duplex_config_nr_t duplex = {};

@ -370,9 +370,9 @@ typedef enum {
*/ */
typedef struct SRSRAN_API { typedef struct SRSRAN_API {
uint32_t pci; uint32_t pci;
uint32_t absolute_frequency_ssb; double dl_center_frequency_hz; ///< Absolute baseband center frequency in Hz for DL grid
uint32_t dl_absolute_frequency_point_a; double ul_center_frequency_hz; ///< Absolute baseband center frequency in Hz for UL grid
uint32_t ul_absolute_frequency_point_a; double ssb_center_freq_hz; ///< SS/PBCH Block center frequency in Hz. Set to 0 if not present
uint32_t offset_to_carrier; ///< Offset between point A and the lowest subcarrier of the lowest RB uint32_t offset_to_carrier; ///< Offset between point A and the lowest subcarrier of the lowest RB
srsran_subcarrier_spacing_t scs; srsran_subcarrier_spacing_t scs;
uint32_t nof_prb; ///< @brief See TS 38.101-1 Table 5.3.2-1 for more details uint32_t nof_prb; ///< @brief See TS 38.101-1 Table 5.3.2-1 for more details
@ -383,6 +383,12 @@ typedef struct SRSRAN_API {
///< TS 38.212 [17], clause 5.4.2.1) ///< TS 38.212 [17], clause 5.4.2.1)
} srsran_carrier_nr_t; } srsran_carrier_nr_t;
#define SRSRAN_DEFAULT_CARRIER_NR \
{ \
.pci = 500, .dl_center_frequency_hz = 3.5e9, .ul_center_frequency_hz = 3.5e9, .ssb_center_freq_hz = 3.5e9, \
.offset_to_carrier = 0, .scs = srsran_subcarrier_spacing_15kHz, .nof_prb = 52, .start = 0, .max_mimo_layers = 1 \
}
/** /**
* @brief NR Slot parameters. It contains parameters that change in a slot basis. * @brief NR Slot parameters. It contains parameters that change in a slot basis.
*/ */

@ -12,6 +12,7 @@
#include "srsran/asn1/rrc_nr_utils.h" #include "srsran/asn1/rrc_nr_utils.h"
#include "srsran/asn1/rrc_nr.h" #include "srsran/asn1/rrc_nr.h"
#include "srsran/common/band_helper.h"
#include "srsran/config.h" #include "srsran/config.h"
#include "srsran/interfaces/pdcp_interface_types.h" #include "srsran/interfaces/pdcp_interface_types.h"
#include "srsran/interfaces/rlc_interface_types.h" #include "srsran/interfaces/rlc_interface_types.h"
@ -1368,10 +1369,11 @@ bool make_phy_carrier_cfg(const freq_info_dl_s& asn1_freq_info_dl, srsran_carrie
} }
// As the carrier structure requires parameters from different objects, set fields separately // As the carrier structure requires parameters from different objects, set fields separately
out_carrier_nr->absolute_frequency_ssb = absolute_frequency_ssb; srsran::srsran_band_helper bands;
out_carrier_nr->dl_absolute_frequency_point_a = asn1_freq_info_dl.absolute_freq_point_a; out_carrier_nr->ssb_center_freq_hz = srsran::srsran_band_helper().nr_arfcn_to_freq(absolute_frequency_ssb);
out_carrier_nr->ul_absolute_frequency_point_a = out_carrier_nr->dl_center_frequency_hz = bands.get_center_freq_from_abs_freq_point_a(
out_carrier_nr->dl_absolute_frequency_point_a; // needs to be updated for FDD asn1_freq_info_dl.scs_specific_carrier_list[0].carrier_bw, asn1_freq_info_dl.absolute_freq_point_a);
out_carrier_nr->ul_center_frequency_hz = out_carrier_nr->dl_center_frequency_hz; // needs to be updated for FDD
out_carrier_nr->offset_to_carrier = asn1_freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier; out_carrier_nr->offset_to_carrier = asn1_freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier;
out_carrier_nr->nof_prb = asn1_freq_info_dl.scs_specific_carrier_list[0].carrier_bw; out_carrier_nr->nof_prb = asn1_freq_info_dl.scs_specific_carrier_list[0].carrier_bw;
out_carrier_nr->scs = scs; out_carrier_nr->scs = scs;
@ -1394,6 +1396,20 @@ static inline void make_ssb_positions_in_burst(const bitstring_t&
bool make_phy_ssb_cfg(const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell_cfg, phy_cfg_nr_t::ssb_cfg_t* out_ssb) bool make_phy_ssb_cfg(const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell_cfg, phy_cfg_nr_t::ssb_cfg_t* out_ssb)
{ {
phy_cfg_nr_t::ssb_cfg_t ssb = {}; phy_cfg_nr_t::ssb_cfg_t ssb = {};
if (serv_cell_cfg.ssb_subcarrier_spacing_present) {
switch (serv_cell_cfg.ssb_subcarrier_spacing) {
case subcarrier_spacing_e::khz15:
ssb.scs = srsran_subcarrier_spacing_15kHz;
break;
case subcarrier_spacing_e::khz30:
ssb.scs = srsran_subcarrier_spacing_30kHz;
break;
default:
asn1::log_error("SSB SCS not supported");
return false;
}
}
if (serv_cell_cfg.ssb_positions_in_burst_present) { if (serv_cell_cfg.ssb_positions_in_burst_present) {
switch (serv_cell_cfg.ssb_positions_in_burst.type()) { switch (serv_cell_cfg.ssb_positions_in_burst.type()) {
case serving_cell_cfg_common_s::ssb_positions_in_burst_c_::types_opts::short_bitmap: case serving_cell_cfg_common_s::ssb_positions_in_burst_c_::types_opts::short_bitmap:

@ -109,16 +109,6 @@ uint32_t srsran_band_helper::get_ul_arfcn_from_dl_arfcn(uint32_t dl_arfcn) const
return 0; return 0;
} }
double srsran_band_helper::get_dl_center_freq(const srsran_carrier_nr_t& carrier)
{
return get_center_freq_from_abs_freq_point_a(carrier.nof_prb, carrier.dl_absolute_frequency_point_a);
}
double srsran_band_helper::get_ul_center_freq(const srsran_carrier_nr_t& carrier)
{
return get_center_freq_from_abs_freq_point_a(carrier.nof_prb, carrier.ul_absolute_frequency_point_a);
}
double srsran_band_helper::get_center_freq_from_abs_freq_point_a(uint32_t nof_prb, uint32_t freq_point_a_arfcn) double srsran_band_helper::get_center_freq_from_abs_freq_point_a(uint32_t nof_prb, uint32_t freq_point_a_arfcn)
{ {
// for FR1 unit of resources blocks for freq calc is always 180kHz regardless for actual SCS of carrier // for FR1 unit of resources blocks for freq calc is always 180kHz regardless for actual SCS of carrier

@ -69,8 +69,8 @@ void phy_cfg_nr_default_t::make_carrier_custom_10MHz(srsran_carrier_nr_t& carrie
carrier.nof_prb = 52; carrier.nof_prb = 52;
carrier.max_mimo_layers = 1; carrier.max_mimo_layers = 1;
carrier.pci = 500; carrier.pci = 500;
carrier.dl_absolute_frequency_point_a = 633928; carrier.dl_center_frequency_hz = 2.6e9;
carrier.absolute_frequency_ssb = 634176; carrier.ssb_center_freq_hz = carrier.dl_center_frequency_hz;
carrier.offset_to_carrier = 0; carrier.offset_to_carrier = 0;
carrier.scs = srsran_subcarrier_spacing_15kHz; carrier.scs = srsran_subcarrier_spacing_15kHz;
} }
@ -80,8 +80,8 @@ void phy_cfg_nr_default_t::make_carrier_custom_20MHz(srsran_carrier_nr_t& carrie
carrier.nof_prb = 106; carrier.nof_prb = 106;
carrier.max_mimo_layers = 1; carrier.max_mimo_layers = 1;
carrier.pci = 500; carrier.pci = 500;
carrier.dl_absolute_frequency_point_a = 633928; carrier.dl_center_frequency_hz = 2.6e9;
carrier.absolute_frequency_ssb = 634176; carrier.ssb_center_freq_hz = carrier.dl_center_frequency_hz;
carrier.offset_to_carrier = 0; carrier.offset_to_carrier = 0;
carrier.scs = srsran_subcarrier_spacing_15kHz; carrier.scs = srsran_subcarrier_spacing_15kHz;
} }

@ -41,12 +41,8 @@ int bands_test_nr()
TESTASSERT(bands.nr_arfcn_to_freq(167300) == 836.5e6); TESTASSERT(bands.nr_arfcn_to_freq(167300) == 836.5e6);
// check actual freqs for FDD carrier (example values are for 52 PRB) // check actual freqs for FDD carrier (example values are for 52 PRB)
srsran_carrier_nr_t carrier = {}; TESTASSERT(bands.get_center_freq_from_abs_freq_point_a(52, 175364) == 881.5e6);
carrier.dl_absolute_frequency_point_a = 175364; TESTASSERT(bands.get_center_freq_from_abs_freq_point_a(52, 166364) == 836.5e6);
carrier.ul_absolute_frequency_point_a = 166364;
carrier.nof_prb = 52;
TESTASSERT(bands.get_dl_center_freq(carrier) == 881.5e6);
TESTASSERT(bands.get_ul_center_freq(carrier) == 836.5e6);
// b3 // b3
TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6); TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6);

@ -17,17 +17,7 @@
#include <srsran/srsran.h> #include <srsran/srsran.h>
#include <stdlib.h> #include <stdlib.h>
static srsran_carrier_nr_t carrier = { static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR;
1, // pci
0, // absolute_frequency_ssb
0, // dl_absolute_frequency_point_a
0, // ul_absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
50, // nof_prb
0, // start
1 // max_mimo_layers
};
static float snr_dB = 20.0; static float snr_dB = 20.0;
static float power_control_offset = NAN; static float power_control_offset = NAN;

@ -20,17 +20,7 @@
#include <strings.h> #include <strings.h>
#include <unistd.h> #include <unistd.h>
static srsran_carrier_nr_t carrier = { static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR;
1, // pci
0, // absolute_frequency_ssb
0, // dl_absolute_frequency_point_a
0, // ul_absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
50, // nof_prb
0, // start
1 // max_mimo_layers
};
typedef struct { typedef struct {
srsran_sch_mapping_type_t mapping_type; srsran_sch_mapping_type_t mapping_type;

@ -249,24 +249,14 @@ float srsran_symbol_offset_s(uint32_t l, srsran_subcarrier_spacing_t scs)
// Compute at what symbol there is a longer CP // Compute at what symbol there is a longer CP
uint32_t cp_boundary = SRSRAN_EXT_CP_SYMBOL(scs); uint32_t cp_boundary = SRSRAN_EXT_CP_SYMBOL(scs);
// First symbol CP // Number of samples (DFT + short CP) in between the first and l symbols
uint32_t N = 0; uint32_t N = ((2048 + 144) * l) >> (uint32_t)scs;
// Symbols in between the first and l
N += (2048 + 144) * l;
// Add extended CP samples from first OFDM symbol // Add extended CP samples from first OFDM symbol
if (l > 0) { N += 16 * SRSRAN_CEIL(l, cp_boundary);
N += 16;
}
// Add extra samples at the longer CP boundary
if (l >= cp_boundary) {
N += 16;
}
// Compute time using reference sampling rate // Compute time using reference sampling rate
float TS = SRSRAN_LTE_TS / (float)(1U << (uint32_t)scs); float TS = SRSRAN_LTE_TS;
// Return symbol offset in seconds // Return symbol offset in seconds
return (float)N * TS; return (float)N * TS;

@ -349,8 +349,8 @@ int srsran_ofdm_set_phase_compensation(srsran_ofdm_t* q, double center_freq_hz)
// Extract modulation required parameters // Extract modulation required parameters
uint32_t symbol_sz = q->cfg.symbol_sz; uint32_t symbol_sz = q->cfg.symbol_sz;
float scs = 15e3f; //< Assume 15kHz subcarrier spacing double scs = 15e3; //< Assume 15kHz subcarrier spacing
float srate_hz = symbol_sz * scs; double srate_hz = symbol_sz * scs;
// Assert parameters // Assert parameters
if (!isnormal(srate_hz)) { if (!isnormal(srate_hz)) {
@ -360,16 +360,20 @@ int srsran_ofdm_set_phase_compensation(srsran_ofdm_t* q, double center_freq_hz)
// Otherwise calculate the phase // Otherwise calculate the phase
uint32_t count = 0; uint32_t count = 0;
for (uint32_t l = 0; l < q->nof_symbols * SRSRAN_NOF_SLOTS_PER_SF; l++) { for (uint32_t l = 0; l < q->nof_symbols * SRSRAN_NOF_SLOTS_PER_SF; l++) {
uint32_t cp_len = SRSRAN_CP_ISNORM(q->cfg.cp) ? SRSRAN_CP_LEN_NORM(l, symbol_sz) : SRSRAN_CP_LEN_EXT(symbol_sz); uint32_t cp_len =
SRSRAN_CP_ISNORM(q->cfg.cp) ? SRSRAN_CP_LEN_NORM(l % q->nof_symbols, symbol_sz) : SRSRAN_CP_LEN_EXT(symbol_sz);
// Advance CP // Advance CP
count += cp_len; count += cp_len;
// Calculate symbol start time // Calculate symbol start time
double t_start = (float)count / srate_hz; double t_start = (double)count / srate_hz;
// Calculate phase
double phase_rad = -2.0 * M_PI * center_freq_hz * t_start;
// Calculate compensation phase in double precision and then convert to single // Calculate compensation phase in double precision and then convert to single
q->phase_compensation[l] = (cf_t)cexp(-I * 2.0 * M_PI * center_freq_hz * t_start); q->phase_compensation[l] = (cf_t)cexp(I * phase_rad);
// Advance symbol // Advance symbol
count += symbol_sz; count += symbol_sz;

@ -128,6 +128,7 @@ int srsran_gnb_dl_set_carrier(srsran_gnb_dl_t* q, const srsran_carrier_nr_t* car
fft_cfg.nof_prb = carrier->nof_prb; fft_cfg.nof_prb = carrier->nof_prb;
fft_cfg.symbol_sz = srsran_min_symbol_sz_rb(carrier->nof_prb); fft_cfg.symbol_sz = srsran_min_symbol_sz_rb(carrier->nof_prb);
fft_cfg.keep_dc = true; fft_cfg.keep_dc = true;
fft_cfg.phase_compensation_hz = carrier->dl_center_frequency_hz;
for (uint32_t i = 0; i < q->nof_tx_antennas; i++) { for (uint32_t i = 0; i < q->nof_tx_antennas; i++) {
fft_cfg.in_buffer = q->sf_symbols[i]; fft_cfg.in_buffer = q->sf_symbols[i];

@ -135,6 +135,7 @@ int srsran_gnb_ul_set_carrier(srsran_gnb_ul_t* q, const srsran_carrier_nr_t* car
ofdm_cfg.rx_window_offset = GNB_UL_NR_FFT_WINDOW_OFFSET; ofdm_cfg.rx_window_offset = GNB_UL_NR_FFT_WINDOW_OFFSET;
ofdm_cfg.symbol_sz = srsran_min_symbol_sz_rb(carrier->nof_prb); ofdm_cfg.symbol_sz = srsran_min_symbol_sz_rb(carrier->nof_prb);
ofdm_cfg.keep_dc = true; ofdm_cfg.keep_dc = true;
ofdm_cfg.phase_compensation_hz = carrier->dl_center_frequency_hz;
if (srsran_ofdm_rx_init_cfg(&q->fft, &ofdm_cfg) < SRSRAN_SUCCESS) { if (srsran_ofdm_rx_init_cfg(&q->fft, &ofdm_cfg) < SRSRAN_SUCCESS) {
return SRSRAN_ERROR; return SRSRAN_ERROR;

@ -15,17 +15,7 @@
#include "srsran/phy/utils/random.h" #include "srsran/phy/utils/random.h"
#include <getopt.h> #include <getopt.h>
static srsran_carrier_nr_t carrier = { static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR;
1, // pci
0, // absolute_frequency_ssb
0, // dl_absolute_frequency_point_a
0, // ul_absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
50, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint16_t rnti = 0x1234; static uint16_t rnti = 0x1234;
static bool fast_sweep = true; static bool fast_sweep = true;

@ -20,17 +20,7 @@
#include <getopt.h> #include <getopt.h>
#include <math.h> #include <math.h>
static srsran_carrier_nr_t carrier = { static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR;
1, // pci
0, // absolute_frequency_ssb
0, // dl_absolute_frequency_point_a
0, // ul_absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
SRSRAN_MAX_PRB_NR, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint32_t n_prb = 0; // Set to 0 for steering static uint32_t n_prb = 0; // Set to 0 for steering
static uint32_t mcs = 30; // Set to 30 for steering static uint32_t mcs = 30; // Set to 30 for steering

@ -22,17 +22,7 @@
#include <strings.h> #include <strings.h>
#include <unistd.h> #include <unistd.h>
static srsran_carrier_nr_t carrier = { static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR;
1, // pci
0, // absolute_frequency_ssb
0, // dl_absolute_frequency_point_a
0, // ul_absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
6, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint32_t starting_prb_stride = 4; static uint32_t starting_prb_stride = 4;
static uint32_t starting_symbol_stride = 4; static uint32_t starting_symbol_stride = 4;
@ -261,6 +251,9 @@ static void usage(char* prog)
static void parse_args(int argc, char** argv) static void parse_args(int argc, char** argv)
{ {
// Limit default number of RB
carrier.nof_prb = 6;
int opt; int opt;
while ((opt = getopt(argc, argv, "cnfsv")) != -1) { while ((opt = getopt(argc, argv, "cnfsv")) != -1) {
switch (opt) { switch (opt) {

@ -19,18 +19,7 @@
#include <complex.h> #include <complex.h>
#include <getopt.h> #include <getopt.h>
static srsran_carrier_nr_t carrier = { static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR;
1, // pci
0, // absolute_frequency_ssb
0, // dl_absolute_frequency_point_a
0, // ul_absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
SRSRAN_MAX_PRB_NR, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint32_t n_prb = 0; // Set to 0 for steering static uint32_t n_prb = 0; // Set to 0 for steering
static uint32_t mcs = 30; // Set to 30 for steering static uint32_t mcs = 30; // Set to 30 for steering
static srsran_sch_cfg_nr_t pusch_cfg = {}; static srsran_sch_cfg_nr_t pusch_cfg = {};

@ -18,17 +18,7 @@
#include <getopt.h> #include <getopt.h>
#include <srsran/phy/utils/random.h> #include <srsran/phy/utils/random.h>
static srsran_carrier_nr_t carrier = { static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR;
1, // pci
0, // absolute_frequency_ssb
0, // dl_absolute_frequency_point_a
0, // ul_absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
SRSRAN_MAX_PRB_NR, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint32_t n_prb = 0; // Set to 0 for steering static uint32_t n_prb = 0; // Set to 0 for steering
static uint32_t mcs = 30; // Set to 30 for steering static uint32_t mcs = 30; // Set to 30 for steering

@ -592,6 +592,11 @@ int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* m
// Map SSB in resource grid and perform IFFT // Map SSB in resource grid and perform IFFT
ssb_modulate_symbol(q, ssb_grid, l); ssb_modulate_symbol(q, ssb_grid, l);
// Phase compensation
cf_t phase_compensation = (cf_t)cexp(-I * 2.0 * M_PI * q->cfg.center_freq_hz * (double)t_offset / q->cfg.srate_hz);
srsran_vec_sc_prod_ccc(q->tmp_time, phase_compensation, q->tmp_time, q->symbol_sz);
t_offset += (int)(q->symbol_sz + q->cp_sz);
// Add cyclic prefix to input; // Add cyclic prefix to input;
srsran_vec_sum_ccc(in_ptr, &q->tmp_time[q->symbol_sz - q->cp_sz], out_ptr, q->cp_sz); srsran_vec_sum_ccc(in_ptr, &q->tmp_time[q->symbol_sz - q->cp_sz], out_ptr, q->cp_sz);
in_ptr += q->cp_sz; in_ptr += q->cp_sz;
@ -617,6 +622,10 @@ static int ssb_demodulate(srsran_ssb_t* q, const cf_t* in, uint32_t t_offset, cf
srsran_vec_cf_copy(q->tmp_time, in_ptr, q->symbol_sz); srsran_vec_cf_copy(q->tmp_time, in_ptr, q->symbol_sz);
in_ptr += q->symbol_sz + SRSRAN_CEIL(q->cp_sz, 2); in_ptr += q->symbol_sz + SRSRAN_CEIL(q->cp_sz, 2);
// Phase compensation
cf_t phase_compensation = (cf_t)cexp(-I * 2.0 * M_PI * q->cfg.center_freq_hz * (double)t_offset / q->cfg.srate_hz);
t_offset += q->symbol_sz + q->cp_sz;
// Convert to frequency domain // Convert to frequency domain
srsran_dft_run_guru_c(&q->fft); srsran_dft_run_guru_c(&q->fft);
@ -642,7 +651,7 @@ static int ssb_demodulate(srsran_ssb_t* q, const cf_t* in, uint32_t t_offset, cf
// Normalize // Normalize
float norm = sqrtf((float)q->symbol_sz); float norm = sqrtf((float)q->symbol_sz);
if (isnormal(norm)) { if (isnormal(norm)) {
srsran_vec_sc_prod_cfc(ptr, 1.0f / norm, ptr, SRSRAN_SSB_BW_SUBC); srsran_vec_sc_prod_ccc(ptr, conjf(phase_compensation) / norm, ptr, SRSRAN_SSB_BW_SUBC);
} }
} }

@ -16,17 +16,7 @@
#include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/debug.h"
#include <getopt.h> #include <getopt.h>
static srsran_carrier_nr_t carrier = { static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR;
501, // pci
0, // absolute_frequency_ssb
0, // dl_absolute_frequency_point_a
0, // ul_absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
52, // nof_prb
0, // start
1 // max_mimo_layers
};
static char* filename = NULL; static char* filename = NULL;
static srsran_pdcch_cfg_nr_t pdcch_cfg = {}; static srsran_pdcch_cfg_nr_t pdcch_cfg = {};

@ -165,6 +165,8 @@ int srsran_ue_dl_nr_set_carrier(srsran_ue_dl_nr_t* q, const srsran_carrier_nr_t*
cfg.cp = SRSRAN_CP_NORM; cfg.cp = SRSRAN_CP_NORM;
cfg.keep_dc = true; cfg.keep_dc = true;
cfg.rx_window_offset = UE_DL_NR_FFT_WINDOW_OFFSET; cfg.rx_window_offset = UE_DL_NR_FFT_WINDOW_OFFSET;
cfg.phase_compensation_hz = carrier->dl_center_frequency_hz;
srsran_ofdm_rx_init_cfg(&q->fft[i], &cfg); srsran_ofdm_rx_init_cfg(&q->fft[i], &cfg);
} }
} }

@ -72,6 +72,7 @@ int srsran_ue_ul_nr_set_carrier(srsran_ue_ul_nr_t* q, const srsran_carrier_nr_t*
fft_cfg.nof_prb = carrier->nof_prb; fft_cfg.nof_prb = carrier->nof_prb;
fft_cfg.symbol_sz = srsran_min_symbol_sz_rb(carrier->nof_prb); fft_cfg.symbol_sz = srsran_min_symbol_sz_rb(carrier->nof_prb);
fft_cfg.keep_dc = true; fft_cfg.keep_dc = true;
fft_cfg.phase_compensation_hz = carrier->dl_center_frequency_hz;
if (srsran_ofdm_tx_init_cfg(&q->ifft, &fft_cfg) < SRSRAN_SUCCESS) { if (srsran_ofdm_tx_init_cfg(&q->ifft, &fft_cfg) < SRSRAN_SUCCESS) {
ERROR("Initiating OFDM"); ERROR("Initiating OFDM");
return SRSRAN_ERROR; return SRSRAN_ERROR;

@ -19,18 +19,7 @@
#include "srsran/phy/utils/vector.h" #include "srsran/phy/utils/vector.h"
#include <getopt.h> #include <getopt.h>
static srsran_carrier_nr_t carrier = { static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR;
501, // pci
0, // absolute_frequency_ssb
0, // dl_absolute_frequency_point_a
0, // ul_absolute_frequency_point_a
0, // offset_to_carrier
srsran_subcarrier_spacing_15kHz, // scs
52, // nof_prb
0, // start
1 // max_mimo_layers
};
static uint32_t n_prb = 0; // Set to 0 for steering static uint32_t n_prb = 0; // Set to 0 for steering
static uint32_t mcs = 30; // Set to 30 for steering static uint32_t mcs = 30; // Set to 30 for steering
static srsran_sch_cfg_nr_t pdsch_cfg = {}; static srsran_sch_cfg_nr_t pdsch_cfg = {};
@ -406,7 +395,7 @@ int main(int argc, char** argv)
if (data_tx[tb] == NULL) { if (data_tx[tb] == NULL) {
continue; continue;
} }
srsran_random_byte_vector(rand_gen, data_tx[tb], pdsch_cfg.grant.tb[tb].tbs/8); srsran_random_byte_vector(rand_gen, data_tx[tb], pdsch_cfg.grant.tb[tb].tbs / 8);
pdsch_cfg.grant.tb[tb].softbuffer.tx = &softbuffer_tx; pdsch_cfg.grant.tb[tb].softbuffer.tx = &softbuffer_tx;
} }

@ -85,21 +85,13 @@ bool cc_worker::update_cfg()
return false; return false;
} }
double abs_freq_point_a_freq =
srsran::srsran_band_helper().nr_arfcn_to_freq(phy.cfg.carrier.dl_absolute_frequency_point_a);
double abs_freq_ssb_freq = srsran::srsran_band_helper().nr_arfcn_to_freq(phy.cfg.carrier.absolute_frequency_ssb);
double carrier_center_freq =
abs_freq_point_a_freq + (phy.cfg.carrier.nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs) * SRSRAN_NRE);
uint16_t band = srsran::srsran_band_helper().get_band_from_dl_freq_Hz(carrier_center_freq);
srsran_ssb_cfg_t ssb_cfg = {}; srsran_ssb_cfg_t ssb_cfg = {};
ssb_cfg.srate_hz = srsran_min_symbol_sz_rb(phy.cfg.carrier.nof_prb) * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs); ssb_cfg.srate_hz = srsran_min_symbol_sz_rb(phy.cfg.carrier.nof_prb) * SRSRAN_SUBC_SPACING_NR(phy.cfg.carrier.scs);
ssb_cfg.center_freq_hz = carrier_center_freq; ssb_cfg.center_freq_hz = phy.cfg.carrier.dl_center_frequency_hz;
ssb_cfg.ssb_freq_hz = abs_freq_ssb_freq; ssb_cfg.ssb_freq_hz = phy.cfg.carrier.ssb_center_freq_hz;
ssb_cfg.scs = phy.cfg.ssb.scs; ssb_cfg.scs = phy.cfg.ssb.scs;
ssb_cfg.pattern = srsran::srsran_band_helper().get_ssb_pattern(band, phy.cfg.ssb.scs); ssb_cfg.pattern = phy.cfg.ssb.pattern;
ssb_cfg.duplex_mode = srsran::srsran_band_helper().get_duplex_mode(band); ssb_cfg.duplex_mode = phy.cfg.duplex.mode;
ssb_cfg.periodicity_ms = phy.cfg.ssb.periodicity_ms; ssb_cfg.periodicity_ms = phy.cfg.ssb.periodicity_ms;
if (srsran_ssb_set_cfg(&ssb, &ssb_cfg) < SRSRAN_SUCCESS) { if (srsran_ssb_set_cfg(&ssb, &ssb_cfg) < SRSRAN_SUCCESS) {

@ -10,6 +10,7 @@
* *
*/ */
#include "srsue/hdr/phy/nr/worker_pool.h" #include "srsue/hdr/phy/nr/worker_pool.h"
#include "srsran/common/band_helper.h"
namespace srsue { namespace srsue {
namespace nr { namespace nr {
@ -138,15 +139,15 @@ int worker_pool::set_ul_grant(uint32_t rar
} }
bool worker_pool::set_config(const srsran::phy_cfg_nr_t& cfg) bool worker_pool::set_config(const srsran::phy_cfg_nr_t& cfg)
{ {
uint32_t dl_arfcn = srsran::srsran_band_helper().freq_to_nr_arfcn(cfg.carrier.dl_center_frequency_hz);
phy_state.cfg = cfg; phy_state.cfg = cfg;
logger.info( logger.info("Setting new PHY configuration ARFCN=%d, PCI=%d", dl_arfcn, cfg.carrier.pci);
"Setting new PHY configuration ARFCN=%d, PCI=%d", cfg.carrier.dl_absolute_frequency_point_a, cfg.carrier.pci);
// Set carrier information // Set carrier information
info_metrics_t info = {}; info_metrics_t info = {};
info.pci = cfg.carrier.pci; info.pci = cfg.carrier.pci;
info.dl_earfcn = cfg.carrier.absolute_frequency_ssb; info.dl_earfcn = dl_arfcn;
phy_state.set_info_metrics(info); phy_state.set_info_metrics(info);
// Best effort to convert NR carrier into LTE cell // Best effort to convert NR carrier into LTE cell

@ -659,15 +659,13 @@ void phy::set_earfcn(std::vector<uint32_t> earfcns)
bool phy::set_config(const srsran::phy_cfg_nr_t& cfg) bool phy::set_config(const srsran::phy_cfg_nr_t& cfg)
{ {
srsran::srsran_band_helper band_helper; srsran::srsran_band_helper band_helper;
double dl_freq_hz = band_helper.get_dl_center_freq(cfg.carrier);
double ul_freq_hz = band_helper.get_ul_center_freq(cfg.carrier);
// tune radio // tune radio
for (uint32_t i = 0; i < common.args->nof_nr_carriers; i++) { for (uint32_t i = 0; i < common.args->nof_nr_carriers; i++) {
logger_phy.info("Tuning Rx channel %d to %.2f MHz", i + common.args->nof_lte_carriers, dl_freq_hz / 1e6); logger_phy.info("Tuning Rx channel %d to %.2f MHz", i + common.args->nof_lte_carriers, cfg.carrier.dl_center_frequency_hz / 1e6);
radio->set_rx_freq(i + common.args->nof_lte_carriers, dl_freq_hz); radio->set_rx_freq(i + common.args->nof_lte_carriers, cfg.carrier.dl_center_frequency_hz);
logger_phy.info("Tuning Tx channel %d to %.2f MHz", i + common.args->nof_lte_carriers, ul_freq_hz / 1e6); logger_phy.info("Tuning Tx channel %d to %.2f MHz", i + common.args->nof_lte_carriers, cfg.carrier.ul_center_frequency_hz / 1e6);
radio->set_tx_freq(i + common.args->nof_lte_carriers, ul_freq_hz); radio->set_tx_freq(i + common.args->nof_lte_carriers, cfg.carrier.ul_center_frequency_hz);
} }
return nr_workers.set_config(cfg); return nr_workers.set_config(cfg);

@ -31,9 +31,7 @@ namespace srsue {
const char* rrc_nr::rrc_nr_state_text[] = {"IDLE", "CONNECTED", "CONNECTED-INACTIVE"}; const char* rrc_nr::rrc_nr_state_text[] = {"IDLE", "CONNECTED", "CONNECTED-INACTIVE"};
rrc_nr::rrc_nr(srsran::task_sched_handle task_sched_) : rrc_nr::rrc_nr(srsran::task_sched_handle task_sched_) :
logger(srslog::fetch_basic_logger("RRC-NR")), logger(srslog::fetch_basic_logger("RRC-NR")), task_sched(task_sched_), conn_recfg_proc(this)
task_sched(task_sched_),
conn_recfg_proc(this)
{} {}
rrc_nr::~rrc_nr() = default; rrc_nr::~rrc_nr() = default;
@ -778,20 +776,18 @@ bool rrc_nr::apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_com
// Load CORESET Zero // Load CORESET Zero
if (pdcch_cfg_common.ctrl_res_set_zero_present) { if (pdcch_cfg_common.ctrl_res_set_zero_present) {
// Get band number srsran::srsran_band_helper bands;
srsran::srsran_band_helper band_helper;
uint16_t band = band_helper.get_band_from_dl_arfcn(phy_cfg.carrier.dl_absolute_frequency_point_a);
// Get pointA and SSB absolute frequencies // Get pointA and SSB absolute frequencies
double pointA_abs_freq_Hz = band_helper.nr_arfcn_to_freq(phy_cfg.carrier.dl_absolute_frequency_point_a); double pointA_abs_freq_Hz =
double ssb_abs_freq_Hz = band_helper.nr_arfcn_to_freq(phy_cfg.carrier.absolute_frequency_ssb); phy_cfg.carrier.dl_center_frequency_hz -
phy_cfg.carrier.nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(phy_cfg.carrier.scs) / 2;
double ssb_abs_freq_Hz = phy_cfg.carrier.ssb_center_freq_hz;
// Calculate integer SSB to pointA frequency offset in Hz // Calculate integer SSB to pointA frequency offset in Hz
uint32_t ssb_pointA_freq_offset_Hz = uint32_t ssb_pointA_freq_offset_Hz =
(ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0; (ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0;
srsran_subcarrier_spacing_t ssb_scs = phy_cfg.ssb.scs;
// TODO: Select subcarrier spacing from SSB (depending on band)
srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz;
// Select PDCCH subcarrrier spacing from PDCCH BWP // Select PDCCH subcarrrier spacing from PDCCH BWP
srsran_subcarrier_spacing_t pdcch_scs = phy_cfg.carrier.scs; srsran_subcarrier_spacing_t pdcch_scs = phy_cfg.carrier.scs;
@ -903,7 +899,8 @@ bool rrc_nr::apply_ul_common_cfg(const asn1::rrc_nr::ul_cfg_common_s& ul_cfg_com
{ {
if (ul_cfg_common.freq_info_ul_present && ul_cfg_common.freq_info_ul.absolute_freq_point_a_present) { if (ul_cfg_common.freq_info_ul_present && ul_cfg_common.freq_info_ul.absolute_freq_point_a_present) {
// Update UL frequency point if provided // Update UL frequency point if provided
phy_cfg.carrier.ul_absolute_frequency_point_a = ul_cfg_common.freq_info_ul.absolute_freq_point_a; phy_cfg.carrier.ul_center_frequency_hz = srsran::srsran_band_helper().get_center_freq_from_abs_freq_point_a(
phy_cfg.carrier.nof_prb, ul_cfg_common.freq_info_ul.absolute_freq_point_a);
} }
if (ul_cfg_common.init_ul_bwp_present) { if (ul_cfg_common.init_ul_bwp_present) {
if (ul_cfg_common.init_ul_bwp.rach_cfg_common_present) { if (ul_cfg_common.init_ul_bwp.rach_cfg_common_present) {
@ -1165,6 +1162,13 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
logger.warning("Secondary primary cell ul cfg common not present"); logger.warning("Secondary primary cell ul cfg common not present");
return false; return false;
} }
phy_cfg_nr_t::ssb_cfg_t ssb_cfg = {};
if (make_phy_ssb_cfg(recfg_with_sync.sp_cell_cfg_common, &ssb_cfg) == true) {
phy_cfg.ssb = ssb_cfg;
} else {
logger.warning("Warning while building SSB config structure");
return false;
}
if (recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present) { if (recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present) {
if (apply_dl_common_cfg(recfg_with_sync.sp_cell_cfg_common.dl_cfg_common) == false) { if (apply_dl_common_cfg(recfg_with_sync.sp_cell_cfg_common.dl_cfg_common) == false) {
return false; return false;
@ -1173,14 +1177,6 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg)
logger.warning("DL cfg common not present"); logger.warning("DL cfg common not present");
return false; return false;
} }
phy_cfg_nr_t::ssb_cfg_t ssb_cfg = {};
if (make_phy_ssb_cfg(recfg_with_sync.sp_cell_cfg_common, &ssb_cfg) == true) {
phy_cfg.ssb = ssb_cfg;
} else {
logger.warning("Warning while building SSB config structure");
return false;
}
if (recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common_present) { if (recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common_present) {
logger.info("TDD UL DL config present, using TDD"); logger.info("TDD UL DL config present, using TDD");
srsran_duplex_config_nr_t duplex; srsran_duplex_config_nr_t duplex;

Loading…
Cancel
Save