Compare commits

...

1 Commits

Author SHA1 Message Date
Laurent THOMAS
4e8cdf71c8 partial cleaning of existing power parameters, add power in rfsimulator 2024-07-31 09:37:46 +02:00
6 changed files with 53 additions and 45 deletions

View File

@@ -878,6 +878,10 @@ static void fill_rf_config(RU_t *ru, char *rf_config_file)
cfg->num_rb_dl=N_RB;
cfg->tx_num_channels=ru->nb_tx;
cfg->rx_num_channels=ru->nb_rx;
double band_kHz = config->carrier_config.dl_bandwidth.value * 1000;
// 5G hard code 240 sub carriers for PBCH regardless numerology (TS 38.211 - 7.4.3.1)
double pbch_band = 240 * (15 << config->ssb_config.scs_common.value);
double power_antenna_at_0dBFS = config->ssb_config.ss_pbch_power.value + 10 * log(band_kHz / pbch_band) - 10 * log(ru->nb_tx);
LOG_I(PHY,"Setting RF config for N_RB %d, NB_RX %d, NB_TX %d\n",cfg->num_rb_dl,cfg->rx_num_channels,cfg->tx_num_channels);
LOG_I(PHY,"tune_offset %.0f Hz, sample_rate %.0f Hz\n",cfg->tune_offset,cfg->sample_rate);
@@ -891,9 +895,10 @@ static void fill_rf_config(RU_t *ru, char *rf_config_file)
cfg->tx_freq[i] = (double)ru->if_frequency;
}
cfg->tx_gain[i] = ru->att_tx;
cfg->tx_gain[i] = ru->att_tx; // weird !
LOG_I(PHY, "Channel %d: setting tx_gain offset %.0f, tx_freq %.0f Hz\n",
i, cfg->tx_gain[i],cfg->tx_freq[i]);
cfg->output_power_dbm[i] = power_antenna_at_0dBFS;
}
for (i=0; i<ru->nb_rx; i++) {

View File

@@ -109,13 +109,8 @@ int get_node_type() {return -1;}
RAN_CONTEXT_t RC;
int oai_exit = 0;
static int tx_max_power[MAX_NUM_CCs] = {0};
int vcdflag = 0;
double rx_gain_off = 0.0;
char *usrp_args = NULL;
char *tx_subdev = NULL;
char *rx_subdev = NULL;
@@ -128,16 +123,6 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
uint64_t sidelink_frequency[MAX_NUM_CCs][4];
#if MAX_NUM_CCs == 1
rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}};
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
#else
rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}};
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
#endif
// UE and OAI config variables
openair0_config_t openair0_cfg[MAX_CARDS];
@@ -232,15 +217,10 @@ static void get_options(configmodule_interface_t *cfg)
void set_options(int CC_id, PHY_VARS_NR_UE *UE){
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
// Init power variables
tx_max_power[CC_id] = tx_max_power[0];
rx_gain[0][CC_id] = rx_gain[0][0];
tx_gain[0][CC_id] = tx_gain[0][0];
// Set UE variables
UE->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off;
UE->tx_total_gain_dB = (int)tx_gain[CC_id][0];
UE->tx_power_max_dBm = tx_max_power[CC_id];
UE->rx_total_gain_dB = nrUE_params.rx_gain + nrUE_params.rx_gain_off;
UE->tx_total_gain_dB = nrUE_params.tx_gain;
UE->tx_power_max_dBm = nrUE_params.tx_max_power;
UE->rf_map.card = 0;
UE->rf_map.chain = CC_id + 0;
UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations;
@@ -313,14 +293,13 @@ void init_openair0()
nr_rf_card_config_freq(&openair0_cfg[card], ul_carrier, dl_carrier, freq_off);
nr_rf_card_config_gain(&openair0_cfg[card], rx_gain_off);
nr_rf_card_config_gain(&openair0_cfg[card], nrUE_params.rx_gain_off);
openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
if (usrp_args) openair0_cfg[card].sdr_addrs = usrp_args;
if (tx_subdev) openair0_cfg[card].tx_subdev = tx_subdev;
if (rx_subdev) openair0_cfg[card].rx_subdev = rx_subdev;
openair0_cfg[card].sdr_addrs = usrp_args;
openair0_cfg[card].tx_subdev = tx_subdev;
openair0_cfg[card].rx_subdev = rx_subdev;
}
}
@@ -420,8 +399,7 @@ int main(int argc, char **argv)
}
//set_softmodem_sighandler();
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS);
memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
memset(openair0_cfg, 0, sizeof(openair0_config_t) * MAX_CARDS);
// initialize logging
logInit();
// get options and fill parameters from configuration file

View File

@@ -46,14 +46,14 @@
{"reconfig-file", CONFIG_HLP_RE_CFG_FILE, 0, .strptr=&reconfig_file, .defstrval="./reconfig.raw", TYPE_STRING, 0}, \
{"rbconfig-file", CONFIG_HLP_RB_CFG_FILE, 0, .strptr=&rbconfig_file, .defstrval="./rbconfig.raw", TYPE_STRING, 0}, \
{"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&(rx_gain[0][0]), .defdblval=110, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, .dblptr=&(tx_gain[0][0]), .defdblval=0, TYPE_DOUBLE, 0}, \
{"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&nrUE_params.rx_gain, .defdblval=110, TYPE_DOUBLE, 0}, \
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&nrUE_params.rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \
{"ue-txgain", CONFIG_HLP_UETXG, 0, .dblptr=&nrUE_params.tx_gain, .defdblval=0, TYPE_DOUBLE, 0}, \
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, .iptr=&(nrUE_params.nb_antennas_rx), .defuintval=1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, .iptr=&(nrUE_params.nb_antennas_tx), .defuintval=1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, .iptr=&(nrUE_params.UE_scan_carrier), .defintval=0, TYPE_INT, 0}, \
{"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, .iptr=&(nrUE_params.UE_fo_compensation), .defintval=0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, .iptr=&(tx_max_power[0]), .defintval=90, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, .dblptr=&nrUE_params.tx_max_power, .defdblval=20, TYPE_DOUBLE, 0}, \
{"r" , CONFIG_HLP_PRB_SA, 0, .iptr=&(nrUE_params.N_RB_DL), .defintval=106, TYPE_UINT, 0}, \
{"ssb", CONFIG_HLP_SSC, 0, .iptr=&(nrUE_params.ssb_start_subcarrier), .defintval=516, TYPE_UINT16, 0}, \
{"if_freq" , CONFIG_HLP_IF_FREQ, 0, .u64ptr=&(nrUE_params.if_freq), .defuintval=0, TYPE_UINT64, 0}, \
@@ -89,6 +89,10 @@ typedef struct {
unsigned int ntn_koffset;
double ntn_ta_common;
int agc;
double rx_gain;
double tx_gain;
double tx_max_power;
double rx_gain_off;
} nrUE_params_t;
extern uint64_t get_nrUE_optmask(void);
extern uint64_t set_nrUE_optmask(uint64_t bitmask);

View File

@@ -253,7 +253,10 @@ typedef struct openair0_config {
//! index: [0..rx_num_channels]
double rx_gain_offset[8];
//! gain for TX in dB
// for legacy code, we keep tx_gain that is actually misleading name and impossible to compute in BBU
double tx_gain[8];
// Actual value for tx ouput power for 0 dBFS per antenna
double output_power_dbm[8];
//! RX bandwidth in Hz
double rx_bw;
//! TX bandwidth in Hz
@@ -628,6 +631,12 @@ typedef struct {
uint64_t timestamp; // Timestamp value of first sample
uint32_t option_value; // Option value
uint32_t option_flag; // Option flag
float power;
// in dBm for 0 dBFS and all Tx antenna sum (dBFS is dB relative to Full Scale, so a pure single carrier sinus wave)
// FS is OAI full scale, so int16_t, independant of the actual number of bits in DAC/ADC
// if we do ofdm, the power per carrier is this power/(nb_tx_antennas * nb_carriers)
// in 3GPP standard, we have EPRE (Energy Per Resource Element), that is output power/(nb_tx_antennas * nb_RB * carriers_
// per_RB), so in dBm: power -10log(nb_tx_antennas) - 10*log(n_RB*12)
} samplesBlockHeader_t;
#ifdef __cplusplus

View File

@@ -64,7 +64,7 @@ void rxAddInput( const c16_t *input_sig,
// so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...)
// UE and NB gain control to be added
// Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...)
const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0);
const double pathLossLinear = pow(10, channelDesc->path_loss_dB / 10.0);
// Energy in one sample to calibrate input noise
// the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1)
const double noise_per_sample = pow(10,channelDesc->noise_power_dB/10.0) * 256;

View File

@@ -177,6 +177,9 @@ typedef struct {
poll_telnetcmdq_func_t poll_telnetcmdq;
int wait_timeout;
double prop_delay_ms;
float tx_power[8];
double rx_gain[8];
double rx_power;
} rfsimulator_state_t;
static int allocCirBuf(rfsimulator_state_t *bridge, int sock)
@@ -612,7 +615,8 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
buffer_t *b=&t->buf[i];
if (b->conn_sock >= 0 ) {
samplesBlockHeader_t header = {nsamps, nbAnt, timestamp};
// let's assume all tx have same power for now
samplesBlockHeader_t header = {nsamps, nbAnt, timestamp, t->tx_power[0]};
fullwrite(b->conn_sock,&header, sizeof(header), t);
sample_t tmpSamples[nsamps][nbAnt];
@@ -750,7 +754,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
// check the header and start block transfer
if ( b->headerMode==true && b->remainToTransfer==0) {
b->headerMode = false;
t->rx_power = b->th.power;
// negligate the tx poxer can change in each trasnmission, we consider it as static for the size of circularBuf
if (t->nextRxTstamp == 0) { // First block in UE, resync with the gNB current TS
t->nextRxTstamp=b->th.timestamp> nsamps_for_initial ?
b->th.timestamp - nsamps_for_initial :
@@ -761,8 +766,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
LOG_D(HW, "UE got first timestamp: starting at %lu\n", t->nextRxTstamp);
b->trashingPacket=true;
} else if (b->lastReceivedTS < b->th.timestamp) {
int nbAnt= b->th.nbAnt;
int nbAnt = b->th.nbAnt;
if ( b->th.timestamp-b->lastReceivedTS < CirSize ) {
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) {
for (int a=0; a < nbAnt; a++) {
@@ -966,6 +970,11 @@ static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *open
return 0;
}
static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator_state_t *s = device->priv;
for (int i = 0; i < s->tx_num_channels; i++)
s->tx_power[i] = openair0_cfg->output_power_dbm[i];
for (int i = 0; i < s->rx_num_channels; i++)
s->rx_gain[i] = openair0_cfg->rx_gain[i];
return 0;
}
static int rfsimulator_write_init(openair0_device *device) {
@@ -980,7 +989,9 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels;
rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels;
rfsimulator->sample_rate=openair0_cfg->sample_rate;
rfsimulator->tx_bw=openair0_cfg->tx_bw;
rfsimulator->tx_bw = openair0_cfg->tx_bw;
for (int i = 0; i < rfsimulator->tx_num_channels; i++)
rfsimulator->tx_power[i] = openair0_cfg->output_power_dbm[i];
rfsimulator_readconfig(rfsimulator);
if (rfsimulator->prop_delay_ms > 0.0)
rfsimulator->chan_offset = ceil(rfsimulator->sample_rate * rfsimulator->prop_delay_ms / 1000);
@@ -1005,11 +1016,12 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
device->trx_set_freq_func = rfsimulator_set_freq;
device->trx_set_gains_func = rfsimulator_set_gains;
device->trx_write_func = rfsimulator_write;
device->trx_read_func = rfsimulator_read;
/* let's pretend to be a b2x0 */
device->trx_read_func = rfsimulator_read;
device->type = RFSIMULATOR;
openair0_cfg[0].rx_gain[0] = 0;
device->openair0_cfg=&openair0_cfg[0];
for (int i = 0; i < rfsimulator->tx_num_channels; i++)
rfsimulator->rx_gain[i] = openair0_cfg->rx_gain[i];
// OAI style, global variables pointers stored in other modules, with race cond ignored
device->openair0_cfg = openair0_cfg;
device->priv = rfsimulator;
device->trx_write_init = rfsimulator_write_init;