Commit 26c0b0e1 authored by Parminder Singh's avatar Parminder Singh Committed by Marwan Hammouda

AGC: RX Gain calculation, UE command line argument: --agc to enable feature.

            Option --agc
                    - enables Automatic gain control
                    - rx gain values adjusted automatically irrespective of the rxgain provided
parent f88a7906
...@@ -135,7 +135,7 @@ ...@@ -135,7 +135,7 @@
#define CONFIG_HLP_TP_Scaling "set scaling P for TO" #define CONFIG_HLP_TP_Scaling "set scaling P for TO"
#define CONFIG_HLP_TI_Scaling "set scaling I for TO" #define CONFIG_HLP_TI_Scaling "set scaling I for TO"
#define CONFIG_HLP_TO_Iinit "Init the I part of the PI controller for timing offset compensation" #define CONFIG_HLP_TO_Iinit "Init the I part of the PI controller for timing offset compensation"
#define CONFIG_HLP_AGC "Enable Receive Automatic Gain control"
/*--------------------------------------------------------------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for LOG utility */ /* command line parameters for LOG utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */ /* optname helpstr paramflags XXXptr defXXXval type numelt */
......
...@@ -640,6 +640,19 @@ nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) ...@@ -640,6 +640,19 @@ nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc)
} }
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500); LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
/* AGC RX GAIN */
/* USRP API Call for changing RX gain in a thread in mixed slot */
if ((UE->measurements.rx_gain_update == 1) &&
(proc->rx_slot_type == NR_MIXED_SLOT) &&
(proc->frame_rx % UPDATE_RX_GAIN == 0) &&
(proc->nr_slot_rx < 9)) {
/* reset averaging */
UE->init_averaging = 1;
/* Reset the rx gain update flag */
UE->measurements.rx_gain_update = 0;
/* Call the USRP API ina separate thread */
UE->rfdevice.trx_set_gains_func(&UE->rfdevice,&UE->rfdevice.openair0_cfg[0],1);
}
} }
ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx); ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
......
...@@ -293,10 +293,12 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ ...@@ -293,10 +293,12 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->chest_time = nrUE_params.chest_time; UE->chest_time = nrUE_params.chest_time;
UE->no_timing_correction = nrUE_params.no_timing_correction; UE->no_timing_correction = nrUE_params.no_timing_correction;
UE->timing_advance = nrUE_params.timing_advance; UE->timing_advance = nrUE_params.timing_advance;
UE->enable_agc = nrUE_params.enable_agc;
LOG_I(PHY,"Set UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d, chest-time %d\n", LOG_I(PHY,"Set UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d, chest-time %d\n",
UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq, UE->chest_time); UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq, UE->chest_time);
LOG_I(PHY,"dl AGC setting %d\n", UE->enable_agc);
// Set FP variables // Set FP variables
if (tddflag){ if (tddflag){
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
{"TOP" , CONFIG_HLP_TP_Scaling, 0, .dblptr=&TO_PScaling, .defdblval=1.0, TYPE_DOUBLE, 0}, \ {"TOP" , CONFIG_HLP_TP_Scaling, 0, .dblptr=&TO_PScaling, .defdblval=1.0, TYPE_DOUBLE, 0}, \
{"TOI" , CONFIG_HLP_TI_Scaling, 0, .dblptr=&TO_IScaling, .defdblval=0.1, TYPE_DOUBLE, 0}, \ {"TOI" , CONFIG_HLP_TI_Scaling, 0, .dblptr=&TO_IScaling, .defdblval=0.1, TYPE_DOUBLE, 0}, \
{"TOII", CONFIG_HLP_TO_Iinit, 0, .iptr=&TO_IScalingInit, .defintval=0, TYPE_INT, 0}, \ {"TOII", CONFIG_HLP_TO_Iinit, 0, .iptr=&TO_IScalingInit, .defintval=0, TYPE_INT, 0}, \
} {"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.enable_agc), .defintval=0, TYPE_INT, 0}}
// clang-format on // clang-format on
typedef struct { typedef struct {
...@@ -100,6 +100,7 @@ typedef struct { ...@@ -100,6 +100,7 @@ typedef struct {
int threequarter_fs; int threequarter_fs;
int N_RB_DL; int N_RB_DL;
int ssb_start_subcarrier; int ssb_start_subcarrier;
int enable_agc;
} nrUE_params_t; } nrUE_params_t;
extern uint64_t get_nrUE_optmask(void); extern uint64_t get_nrUE_optmask(void);
extern uint64_t set_nrUE_optmask(uint64_t bitmask); extern uint64_t set_nrUE_optmask(uint64_t bitmask);
......
...@@ -22,55 +22,36 @@ ...@@ -22,55 +22,36 @@
#include "PHY/types.h" #include "PHY/types.h"
#include "PHY/defs_nr_UE.h" #include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern_nr_ue.h" #include "PHY/phy_extern_nr_ue.h"
/* Adjust the RX Gain based upon NF based upon SS block measurements */
void void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue) {
phy_adjust_gain_nr (PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id) /* Average received noise power */
{ const int n0_dB = 10 * log10(ue->measurements.n0_power_avg);
/* Taget noise power to be achieved */
LOG_D(PHY,"Gain control: rssi %d (%d,%d)\n", const int n0_dB_target = 20;
rx_power_fil_dB, /* Margin to be used for decision is 3 dB */
ue->measurements.rssi, const int margin = 3;
ue->measurements.rx_power_avg_dB[eNB_id] /* If noise power is higher than target reduce the gain */
); if (n0_dB > (n0_dB_target + margin)) {
ue->measurements.rx_gain_update = 1;
// Gain control with hysterisis ue->rfdevice.openair0_cfg[0].rx_gain[0] = ue->rfdevice.app_rx_gain[0] - 3;
// Adjust gain in ue->rx_vars[0].rx_total_gain_dB } else if (n0_dB < (n0_dB_target - margin)) {
/* If noise power is lower than the target increase the gain */
if (rx_power_fil_dB < TARGET_RX_POWER - 5) //&& (ue->rx_total_gain_dB < MAX_RF_GAIN) ) ue->measurements.rx_gain_update = 1;
ue->rx_total_gain_dB+=5; ue->rfdevice.openair0_cfg[0].rx_gain[0] = ue->rfdevice.app_rx_gain[0] + 3;
else if (rx_power_fil_dB > TARGET_RX_POWER + 5) //&& (ue->rx_total_gain_dB > MIN_RF_GAIN) ) }
ue->rx_total_gain_dB-=5; /* Upper-limit for the Rx gain, below 10 dB from max possible USRP Gain */
if (ue->rfdevice.openair0_cfg[0].rx_gain[0] > (ue->rfdevice.max_rx_gain[0] - 10)) {
if (ue->rx_total_gain_dB>MAX_RF_GAIN) { ue->rfdevice.openair0_cfg[0].rx_gain[0] = (ue->rfdevice.max_rx_gain[0] - 10);
/* ue->measurements.rx_gain_update = 1;
if ((openair_daq_vars.rx_rf_mode==0) && (openair_daq_vars.mode == openair_NOT_SYNCHED)) { }
openair_daq_vars.rx_rf_mode=1; /* lower limit for Rx gain is set to 20 dB with 20 dB attenuator inbetween Tx/Rx */
ue->rx_total_gain_dB = max(MIN_RF_GAIN,MAX_RF_GAIN-25); if (ue->rfdevice.openair0_cfg[0].rx_gain[0] < 20) {
} ue->rfdevice.openair0_cfg[0].rx_gain[0] = 20;
else { ue->measurements.rx_gain_update = 1;
*/
ue->rx_total_gain_dB = MAX_RF_GAIN;
} else if (ue->rx_total_gain_dB<MIN_RF_GAIN) {
/*
if ((openair_daq_vars.rx_rf_mode==1) && (openair_daq_vars.mode == openair_NOT_SYNCHED)) {
openair_daq_vars.rx_rf_mode=0;
ue->rx_total_gain_dB = min(MAX_RF_GAIN,MIN_RF_GAIN+25);
}
else {
*/
ue->rx_total_gain_dB = MIN_RF_GAIN;
} }
LOG_D(PHY,"Gain control: rx_total_gain_dB = %d TARGET_RX_POWER %d (max %d,rxpf %d)\n",ue->rx_total_gain_dB,TARGET_RX_POWER,MAX_RF_GAIN,rx_power_fil_dB); LOG_D(PHY,
"Gain Control: Flag %d, n0_dB : %3d (dB) Old Rx Gain: %3.2f (dB) New Rx Gain %3.2f\n",
#ifdef DEBUG_PHY ue->measurements.rx_gain_update, n0_dB,
/* if ((ue->frame%100==0) || (ue->frame < 10)) ue->rfdevice.app_rx_gain[0], ue->rfdevice.openair0_cfg[0].rx_gain[0]);
msg("[PHY][ADJUST_GAIN] frame %d, rx_power = %d, rx_power_fil = %d, rx_power_fil_dB = %d, coef=%d, ncoef=%d, rx_total_gain_dB = %d (%d,%d,%d)\n",
ue->frame,rx_power,rx_power_fil,rx_power_fil_dB,coef,ncoef,ue->rx_total_gain_dB,
TARGET_RX_POWER,MAX_RF_GAIN,MIN_RF_GAIN);
*/
#endif //DEBUG_PHY
} }
...@@ -122,9 +122,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, ...@@ -122,9 +122,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc, UE_nr_rxtx_proc_t *proc,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue);
uint32_t rx_power_fil_dB,
uint8_t gNB_id);
void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
int nbRx, int nbRx,
......
...@@ -162,15 +162,17 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, ...@@ -162,15 +162,17 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.wideband_cqi_tot[gNB_id] = ue->measurements.rx_power_tot_dB[gNB_id] - ue->measurements.n0_power_tot_dB; ue->measurements.wideband_cqi_tot[gNB_id] = ue->measurements.rx_power_tot_dB[gNB_id] - ue->measurements.n0_power_tot_dB;
ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - dB_fixed(ue->measurements.n0_power_avg); ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - dB_fixed(ue->measurements.n0_power_avg);
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - 10*log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size); ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - 10*log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
ue->measurements.rx_rssi_fixed_point_dB[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0])- dB_fixed(ue->frame_parms.ofdm_symbol_size);
LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dB (%d dBm/RE), WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", LOG_D(PHY,
gNB_id, "[gNB %d] Slot %d, RSSI %d dB (%d dBm/RE), WBandCQI %d dB, rxPwrAvg "
slot, "%d, n0PwrAvg %d, Instant CQI %d (dB), RSSI Fixed Point (dB) %d\n",
ue->measurements.rx_power_avg_dB[gNB_id], gNB_id, slot, ue->measurements.rx_power_avg_dB[gNB_id],
ue->measurements.rx_rssi_dBm[gNB_id], ue->measurements.rx_rssi_dBm[gNB_id],
ue->measurements.wideband_cqi_avg[gNB_id], ue->measurements.wideband_cqi_avg[gNB_id],
ue->measurements.rx_power_avg[gNB_id], ue->measurements.rx_power_avg[gNB_id],
ue->measurements.n0_power_tot); ue->measurements.n0_power_tot,
ue->measurements.wideband_cqi_tot[gNB_id],
ue->measurements.rx_rssi_fixed_point_dB[gNB_id]);
} }
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
...@@ -517,19 +519,28 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, ...@@ -517,19 +519,28 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
} }
ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot); ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot);
LOG_A(PHY, "aarx: %d\n", aarx);
#ifdef DEBUG_MEAS_RRC /* dBm/Hz*/
const int psd_awgn = -174; const int psd_awgn = -174;
const int scs = 15000 * (1 << ue->frame_parms.numerology_index); const int scs = 15000 * (1 << ue->frame_parms.numerology_index);
const int nf_usrp = ue->measurements.n0_power_tot_dB + 3 + 30 - ((int)rx_gain - (int)rx_gain_offset) - 10 * log10(pow(2, 30)) - (psd_awgn + dB_fixed(scs) + dB_fixed(ue->frame_parms.ofdm_symbol_size)); ue->measurements.noise_figure_dB = ue->measurements.n0_power_tot_dB + 30 -
LOG_D(PHY, "In [%s][slot:%d] NF USRP %d dB\n", __FUNCTION__, slot, nf_usrp); ((int)rx_gain - (int)rx_gain_offset) -
#endif 10 * log10(pow(2, 30)) -
(psd_awgn + dB_fixed(scs) +
LOG_D(PHY, "In [%s][slot:%d] Noise Level %d (digital level %d dB, noise power spectral density %f dBm/RE)\n", dB_fixed(ue->frame_parms.ofdm_symbol_size));
__FUNCTION__, /* Noise Floor calculations per dB/RE in fixed point */
slot, ue->measurements.noise_floor_fixed = ue->measurements.n0_power_tot_dB -
ue->measurements.n0_power_tot, ((int)rx_gain - (int)rx_gain_offset) -
ue->measurements.n0_power_tot_dB, dB_fixed(ue->frame_parms.ofdm_symbol_size);
ue->measurements.n0_power_tot_dB + 30 - 10*log10(pow(2, 30)) - dB_fixed(ue->frame_parms.ofdm_symbol_size) - ((int)rx_gain - (int)rx_gain_offset)); /* Noise Power spectral density calculations in dBm/RE */
ue->measurements.noise_psd = ue->measurements.n0_power_tot_dB + 30 -
10 * log10(pow(2, 30)) -
dB_fixed(ue->frame_parms.ofdm_symbol_size) -
((int)rx_gain - (int)rx_gain_offset);
LOG_D(PHY,
"In [%s][slot:%d] Noise Level %d Noise Level %d (dB), Noise PSD %d (dBm/RE), NF USRP %d (dB) Noise Floor %d (dB/RE) \n",
__FUNCTION__, slot, ue->measurements.n0_power_tot,
ue->measurements.n0_power_tot_dB, ue->measurements.noise_psd,
ue->measurements.noise_figure_dB, ue->measurements.noise_floor_fixed);
} }
...@@ -173,7 +173,12 @@ typedef struct { ...@@ -173,7 +173,12 @@ typedef struct {
unsigned short n0_power_avg_dB; unsigned short n0_power_avg_dB;
//! total estimated noise power (dBm) //! total estimated noise power (dBm)
short n0_power_tot_dBm; short n0_power_tot_dBm;
//! noise_floor in dB
unsigned int noise_figure_dB;
//! noise floor fixpoint in dB/RE
int noise_floor_fixed;
//! noise power spectral density
int noise_psd;
// UE measurements // UE measurements
//! estimated received spatial signal power (linear) //! estimated received spatial signal power (linear)
fourDimArray_t *rx_spatial_power; fourDimArray_t *rx_spatial_power;
...@@ -202,6 +207,8 @@ typedef struct { ...@@ -202,6 +207,8 @@ typedef struct {
//! estimated rssi (dBm) //! estimated rssi (dBm)
short rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX]; short rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX];
//! estimated rssi (dB) fixed point
short rx_rssi_fixed_point_dB[NUMBER_OF_CONNECTED_gNB_MAX];
//! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
int rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS];// int rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS];//
//! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
...@@ -238,6 +245,8 @@ typedef struct { ...@@ -238,6 +245,8 @@ typedef struct {
UE_nr_rxtx_proc_t *meas_proc; UE_nr_rxtx_proc_t *meas_proc;
pthread_t meas_thread; pthread_t meas_thread;
bool meas_running; bool meas_running;
// update the flag to update rx gain value
short rx_gain_update;
} PHY_NR_MEASUREMENTS; } PHY_NR_MEASUREMENTS;
typedef struct { typedef struct {
...@@ -685,6 +694,9 @@ typedef struct { ...@@ -685,6 +694,9 @@ typedef struct {
notifiedFIFO_t phy_config_ind; notifiedFIFO_t phy_config_ind;
notifiedFIFO_t *tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME]; notifiedFIFO_t *tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME];
int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME]; int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME];
// Enables Automatic gain control. controlled by --agc flag
int enable_agc;
} PHY_VARS_NR_UE; } PHY_VARS_NR_UE;
typedef struct nr_phy_data_tx_s { typedef struct nr_phy_data_tx_s {
......
...@@ -185,6 +185,8 @@ ...@@ -185,6 +185,8 @@
//#define MIN_RF_GAIN 96 //#define MIN_RF_GAIN 96
#define MAX_RF_GAIN 200 #define MAX_RF_GAIN 200
#define MIN_RF_GAIN 80 #define MIN_RF_GAIN 80
// update rx after 20 frames for usrp
#define UPDATE_RX_GAIN 20
#define PHY_SYNCH_OFFSET ((OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)-1) // OFFSET of BEACON SYNCH #define PHY_SYNCH_OFFSET ((OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)-1) // OFFSET of BEACON SYNCH
#define PHY_SYNCH_MIN_POWER 1000 #define PHY_SYNCH_MIN_POWER 1000
......
...@@ -312,7 +312,7 @@ void nr_ue_measurement_procedures(uint16_t l, ...@@ -312,7 +312,7 @@ void nr_ue_measurement_procedures(uint16_t l,
uint32_t pdsch_est_size, uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size]) { int32_t dl_ch_estimates[][pdsch_est_size]) {
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; int frame_rx = proc->frame_rx;
int nr_slot_rx = proc->nr_slot_rx; int nr_slot_rx = proc->nr_slot_rx;
int gNB_id = proc->gNB_id; int gNB_id = proc->gNB_id;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
...@@ -339,25 +339,16 @@ void nr_ue_measurement_procedures(uint16_t l, ...@@ -339,25 +339,16 @@ void nr_ue_measurement_procedures(uint16_t l,
T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)), T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
T_INT((int)ue->measurements.rx_power_avg_dB[0]), T_INT((int)ue->measurements.rx_power_avg_dB[0]),
T_INT((int)ue->measurements.n0_power_avg_dB), T_INT((int)ue->measurements.n0_power_avg_dB),
T_INT((int)ue->measurements.wideband_cqi_avg[0])); T_INT((int)ue->measurements.wideband_cqi_avg[0]),
T_INT((int)ue->common_vars.freq_offset));
#endif #endif
}
// accumulate and filter timing offset estimation every subframe (instead of every frame)
if (( nr_slot_rx == 2) && (l==(2-frame_parms->Ncp))) {
// AGC
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
//printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[gNB_id]);
phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[gNB_id],gNB_id);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
}
if ((frame_rx % UPDATE_RX_GAIN == 0) && (ue->enable_agc)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN);
phy_adjust_gain_nr(ue);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
} }
......
...@@ -392,6 +392,14 @@ struct openair0_device_t { ...@@ -392,6 +392,14 @@ struct openair0_device_t {
/* !brief Indicates if device already initialized */ /* !brief Indicates if device already initialized */
int is_init; int is_init;
/* !brief Store the value of max gain limit for the RX 4*4 MIMO */
double max_rx_gain[4];
/* !brief Store the value of applied gain for the RX 4*4 MIMO */
double app_rx_gain[4];
/* !brief Store the value of max gain limit for the TX 4*4 MIMO */
double max_tx_gain[4];
/* !brief Store the value of applied gain for the TX 4*4 MIMO */
double app_tx_gain[4];
/*!brief Can be used by driver to hold internal structure*/ /*!brief Can be used by driver to hold internal structure*/
void *priv; void *priv;
...@@ -422,7 +430,7 @@ struct openair0_device_t { ...@@ -422,7 +430,7 @@ struct openair0_device_t {
int (*trx_start_func)(openair0_device *device); int (*trx_start_func)(openair0_device *device);
/*! \brief Called to configure the device /*! \brief Called to configure the device
@param device pointer to the device structure specific to the RF hardware target @param device pointer to the device structure specific to the RF hardware target
*/ */
...@@ -525,7 +533,7 @@ struct openair0_device_t { ...@@ -525,7 +533,7 @@ struct openair0_device_t {
* \param openair0_cfg RF frontend parameters set by application * \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success * \returns 0 in success
*/ */
int (*trx_set_gains_func)(openair0_device *device, openair0_config_t *openair0_cfg); int (*trx_set_gains_func)(openair0_device *device, openair0_config_t *openair0_cfg, int dont_block);
/*! \brief RRU Configuration callback /*! \brief RRU Configuration callback
* \param idx RU index * \param idx RU index
......
...@@ -258,7 +258,7 @@ int trx_eth_set_freq(openair0_device* device, openair0_config_t *openair0_cfg) ...@@ -258,7 +258,7 @@ int trx_eth_set_freq(openair0_device* device, openair0_config_t *openair0_cfg)
} }
int trx_eth_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) int trx_eth_set_gains(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block)
{ {
return(0); return(0);
} }
......
...@@ -882,6 +882,26 @@ int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *open ...@@ -882,6 +882,26 @@ int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *open
s->usrp->set_rx_freq(rx_tune_req); s->usrp->set_rx_freq(rx_tune_req);
return(0); return(0);
} }
/*! \brief Set Tx Gains thread
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
static void *set_tx_gain_thread(void *arg) {
openair0_device *device=(openair0_device *)arg;
usrp_state_t *s = (usrp_state_t *)device->priv;
s->usrp->set_tx_gain(device->app_tx_gain[0]);
return NULL;
}
/*! \brief Set Gains (TX/RX) in thread
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
*/
static void *set_rx_gain_thread(void *arg) {
openair0_device *device=(openair0_device *)arg;
usrp_state_t *s = (usrp_state_t *)device->priv;
s->usrp->set_rx_gain(device->app_rx_gain[0]);
return NULL;
}
/*! \brief Set Gains (TX/RX) /*! \brief Set Gains (TX/RX)
* \param device the hardware to use * \param device the hardware to use
...@@ -889,23 +909,44 @@ int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *open ...@@ -889,23 +909,44 @@ int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *open
* \returns 0 in success * \returns 0 in success
*/ */
int trx_usrp_set_gains(openair0_device *device, int trx_usrp_set_gains(openair0_device *device,
openair0_config_t *openair0_cfg) { openair0_config_t *openair0_cfg, int dont_block) {
usrp_state_t *s = (usrp_state_t *)device->priv; usrp_state_t *s = (usrp_state_t *)device->priv;
::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(0); double gain = 0;
s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[0]); pthread_t thread_1, thread_2;
::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); // calculate tx gain
gain = device->max_tx_gain[0] - openair0_cfg[0].tx_gain[0];
// limit to maximum gain if(gain != device->app_tx_gain[0]) {
if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { // updated applied tx gain for UL processing
LOG_E(HW,"RX Gain 0 too high, reduce by %f dB\n", device->app_tx_gain[0] = gain;
openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); if (dont_block == 1) {
exit(-1); pthread_create(&thread_1, NULL, set_tx_gain_thread, (void *)device);
} else {
//API call to USRP
s->usrp->set_tx_gain(gain);
}
LOG_D(HW, "USRP TX gain is %3.2f Max Tx Gain: %3.2f)\n",
gain, device->max_tx_gain[0]);
}
// Rx gain
gain = openair0_cfg[0].rx_gain[0] - openair0_cfg[0].rx_gain_offset[0];
if(gain != device->app_rx_gain[0]) {
// limit to maximum RX gain
if (gain > device->max_rx_gain[0]) {
LOG_E(HW,"RX Gain 0 too high, reduce by %3.2f dB\n",
gain - device->max_rx_gain[0]);
exit(-1);
}
device->app_rx_gain[0] = gain;
if (dont_block == 1) {
pthread_create(&thread_2, NULL, set_rx_gain_thread, (void *)device);
} else {
//API call to USRP
s->usrp->set_rx_gain(gain);
}
LOG_D(HW, "USRP RX gain is %3.2f, Max Rx Gain: %3.2f)\n",
gain, device->max_rx_gain[0]);
} }
s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]);
LOG_I(HW,"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n",
openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0],
openair0_cfg[0].rx_gain[0],gain_range.stop());
return(0); return(0);
} }
...@@ -1487,6 +1528,11 @@ extern "C" { ...@@ -1487,6 +1528,11 @@ extern "C" {
gain=gain_range.stop(); gain=gain_range.stop();
} }
// store the max limit for RX gain
device->max_rx_gain[i] = gain_range.stop();
// store the actual applied RX gain
device->app_rx_gain[i] = gain;
s->usrp->set_rx_gain(gain,i+choffset); s->usrp->set_rx_gain(gain,i+choffset);
LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i, LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i,
openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i],
...@@ -1499,6 +1545,10 @@ extern "C" { ...@@ -1499,6 +1545,10 @@ extern "C" {
for(int i=0; i<((int) s->usrp->get_tx_num_channels()); i++) { for(int i=0; i<((int) s->usrp->get_tx_num_channels()); i++) {
::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i); ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(i);
// store the max limit for TX gain
device->max_tx_gain[i] = gain_range_tx.stop();
// store the actual applied TX gain
device->app_tx_gain[i] = gain_range_tx.stop() - openair0_cfg[0].tx_gain[i];
if (i<openair0_cfg[0].tx_num_channels) { if (i<openair0_cfg[0].tx_num_channels) {
s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i+choffset); s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i+choffset);
......
...@@ -1068,7 +1068,7 @@ static int rfsimulator_stop(openair0_device *device) { ...@@ -1068,7 +1068,7 @@ static int rfsimulator_stop(openair0_device *device) {
static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg) { static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg) {
return 0; return 0;
} }
static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg, int dont_block) {
return 0; return 0;
} }
static int rfsimulator_write_init(openair0_device *device) { static int rfsimulator_write_init(openair0_device *device) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment