diff --git a/lib/examples/npdsch_enodeb.c b/lib/examples/npdsch_enodeb.c index e19fbb8d4..ceba9ba31 100644 --- a/lib/examples/npdsch_enodeb.c +++ b/lib/examples/npdsch_enodeb.c @@ -511,7 +511,8 @@ int main(int argc, char** argv) fprintf(stderr, "Invalid number of PRB %d\n", cell.base.nof_prb); exit(-1); } - printf("Set TX gain: %.1f dB\n", srslte_rf_set_tx_gain(&radio, rf_gain)); + srslte_rf_set_tx_gain(&radio, rf_gain); + printf("Set TX gain: %.1f dB\n", srslte_rf_get_tx_gain(&radio)); printf("Set TX freq: %.2f MHz\n", srslte_rf_set_tx_freq(&radio, 0, rf_freq) / 1000000); } #endif diff --git a/lib/examples/npdsch_ue.c b/lib/examples/npdsch_ue.c index 52bd7a274..6588258be 100644 --- a/lib/examples/npdsch_ue.c +++ b/lib/examples/npdsch_ue.c @@ -363,7 +363,8 @@ int main(int argc, char** argv) } /* Set receiver gain */ if (prog_args.rf_gain > 0) { - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, prog_args.rf_gain)); + srslte_rf_set_rx_gain(&rf, prog_args.rf_gain); + printf("Set RX gain: %.1f dB\n", prog_args.rf_gain); } else { printf("Starting AGC thread...\n"); if (srslte_rf_start_gain_thread(&rf, false)) { diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index e95369ebd..6146c4438 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -778,7 +778,8 @@ int main(int argc, char** argv) ERROR("Invalid number of PRB %d\n", cell.nof_prb); exit(-1); } - printf("Set TX gain: %.1f dB\n", srslte_rf_set_tx_gain(&radio, rf_gain)); + srslte_rf_set_tx_gain(&radio, rf_gain); + printf("Set TX gain: %.1f dB\n", srslte_rf_get_tx_gain(&radio)); printf("Set TX freq: %.2f MHz\n", srslte_rf_set_tx_freq(&radio, cell.nof_ports, rf_freq) / 1000000); } #endif diff --git a/lib/examples/pssch_ue.c b/lib/examples/pssch_ue.c index 01d028f16..9b420af90 100644 --- a/lib/examples/pssch_ue.c +++ b/lib/examples/pssch_ue.c @@ -258,9 +258,11 @@ int main(int argc, char** argv) exit(-1); } + srslte_rf_set_rx_gain(&radio, prog_args.rf_gain); + printf("Set RX freq: %.6f MHz\n", srslte_rf_set_rx_freq(&radio, prog_args.nof_rx_antennas, prog_args.rf_freq) / 1e6); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&radio, prog_args.rf_gain)); + printf("Set RX gain: %.1f dB\n", prog_args.rf_gain); int srate = srslte_sampling_freq_hz(cell_sl.nof_prb); if (srate != -1) { diff --git a/lib/examples/usrp_capture.c b/lib/examples/usrp_capture.c index b010ccf2b..428eb7058 100644 --- a/lib/examples/usrp_capture.c +++ b/lib/examples/usrp_capture.c @@ -133,8 +133,10 @@ int main(int argc, char** argv) sigaddset(&sigset, SIGINT); sigprocmask(SIG_UNBLOCK, &sigset, NULL); - printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, nof_rx_antennas, rf_freq) / 1000000); - printf("Set RX gain: %.2f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + srslte_rf_set_rx_gain(&rf, rf_gain); + srslte_rf_set_rx_freq(&rf, nof_rx_antennas, rf_freq); + printf("Set RX freq: %.2f MHz\n", rf_freq / 1000000); + printf("Set RX gain: %.2f dB\n", rf_gain); float srate = srslte_rf_set_rx_srate(&rf, rf_rate); if (srate != rf_rate) { srate = srslte_rf_set_rx_srate(&rf, rf_rate); diff --git a/lib/examples/usrp_capture_sync.c b/lib/examples/usrp_capture_sync.c index ed98b1f7a..aad2b85a7 100644 --- a/lib/examples/usrp_capture_sync.c +++ b/lib/examples/usrp_capture_sync.c @@ -161,8 +161,9 @@ int main(int argc, char** argv) sigaddset(&sigset, SIGINT); sigprocmask(SIG_UNBLOCK, &sigset, NULL); + srslte_rf_set_rx_gain(&rf, rf_gain); printf("Set RX freq: %.6f MHz\n", srslte_rf_set_rx_freq(&rf, nof_rx_antennas, rf_freq) / 1000000); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + printf("Set RX gain: %.1f dB\n", srslte_rf_get_rx_gain(&rf)); int srate = srslte_sampling_freq_hz(nof_prb); if (srate != -1) { printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); diff --git a/lib/examples/usrp_capture_sync_nbiot.c b/lib/examples/usrp_capture_sync_nbiot.c index e5906095a..59f9b616d 100644 --- a/lib/examples/usrp_capture_sync_nbiot.c +++ b/lib/examples/usrp_capture_sync_nbiot.c @@ -117,8 +117,9 @@ int main(int argc, char** argv) sigaddset(&sigset, SIGINT); sigprocmask(SIG_UNBLOCK, &sigset, NULL); + srslte_rf_set_rx_gain(&rf, rf_gain); printf("Set RX freq: %.6f MHz\n", srslte_rf_set_rx_freq(&rf, 0, rf_freq) / 1000000); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + printf("Set RX gain: %.1f dB\n", srslte_rf_get_rx_gain(&rf)); int srate = srslte_sampling_freq_hz(nof_prb); if (srate != -1) { printf("Setting sampling rate %.2f MHz\n", (float)srate / 1e6); diff --git a/lib/examples/usrp_txrx.c b/lib/examples/usrp_txrx.c index 4ac49f6a1..1626c06ef 100644 --- a/lib/examples/usrp_txrx.c +++ b/lib/examples/usrp_txrx.c @@ -145,12 +145,16 @@ int main(int argc, char** argv) srslte_rf_set_rx_srate(&rf, (double)srate); srslte_rf_set_tx_srate(&rf, (double)srate); + srslte_rf_set_rx_gain(&rf, rf_rx_gain); + srslte_rf_set_tx_gain(&rf, srslte_rf_tx_gain); + srslte_rf_set_rx_freq(&rf, 0, rf_freq); + printf("Subframe len: %d samples\n", flen); printf("Time advance: %f us\n", time_adv_sec * 1e6); printf("Set TX/RX rate: %.2f MHz\n", (float)srate / 1000000); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_rx_gain)); - printf("Set TX gain: %.1f dB\n", srslte_rf_set_tx_gain(&rf, srslte_rf_tx_gain)); - printf("Set TX/RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, 0, rf_freq) / 1000000); + printf("Set RX gain: %.1f dB\n", rf_rx_gain); + printf("Set TX gain: %.1f dB\n", srslte_rf_tx_gain); + printf("Set TX/RX freq: %.2f MHz\n", rf_freq / 1000000); srslte_rf_set_tx_freq(&rf, 0, rf_freq); sleep(1); diff --git a/lib/examples/zmq_remote_rx.c b/lib/examples/zmq_remote_rx.c index 9b1ec9624..46e0ad574 100644 --- a/lib/examples/zmq_remote_rx.c +++ b/lib/examples/zmq_remote_rx.c @@ -169,9 +169,11 @@ static int init_radio(uint32_t* buffer_len) ERROR("Error opening rf\n"); return -1; } + srslte_rf_set_rx_gain(&radio, rf_gain); + srslte_rf_set_rx_freq(&radio, nof_rx_antennas, rf_freq); - printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&radio, nof_rx_antennas, rf_freq) / 1000000); - printf("Set RX gain: %.2f dB\n", srslte_rf_set_rx_gain(&radio, rf_gain)); + printf("Set RX freq: %.2f MHz\n", rf_freq / 1000000); + printf("Set RX gain: %.2f dB\n", rf_gain); float srate = srslte_rf_set_rx_srate(&radio, rf_rate); if (srate != rf_rate) { ERROR("Error setting samplign frequency %.2f MHz\n", rf_rate * 1e-6); diff --git a/lib/include/srslte/common/interfaces_common.h b/lib/include/srslte/common/interfaces_common.h index ba8eb2e51..fbd4e970e 100644 --- a/lib/include/srslte/common/interfaces_common.h +++ b/lib/include/srslte/common/interfaces_common.h @@ -49,6 +49,7 @@ typedef struct { float freq_offset; float rx_gain; float tx_gain; + float tx_gain_ch[SRSLTE_MAX_CARRIERS]; float tx_max_power; float tx_gain_offset; float rx_gain_offset; diff --git a/lib/include/srslte/phy/rf/rf.h b/lib/include/srslte/phy/rf/rf.h index 9aa7acaa3..b08f7847c 100644 --- a/lib/include/srslte/phy/rf/rf.h +++ b/lib/include/srslte/phy/rf/rf.h @@ -95,11 +95,13 @@ SRSLTE_API float srslte_rf_get_rssi(srslte_rf_t* h); SRSLTE_API double srslte_rf_set_rx_srate(srslte_rf_t* h, double freq); -SRSLTE_API double srslte_rf_set_rx_gain(srslte_rf_t* h, double gain); +SRSLTE_API int srslte_rf_set_rx_gain(srslte_rf_t* h, double gain); + +SRSLTE_API int srslte_rf_set_rx_gain_ch(srslte_rf_t* h, uint32_t ch, double gain); SRSLTE_API void srslte_rf_set_tx_rx_gain_offset(srslte_rf_t* h, double offset); -SRSLTE_API double srslte_rf_set_rx_gain_th(srslte_rf_t* h, double gain); +SRSLTE_API int srslte_rf_set_rx_gain_th(srslte_rf_t* h, double gain); SRSLTE_API double srslte_rf_get_rx_gain(srslte_rf_t* h); @@ -127,7 +129,9 @@ SRSLTE_API int srslte_rf_recv_with_time_multi(srslte_rf_t* h, SRSLTE_API double srslte_rf_set_tx_srate(srslte_rf_t* h, double freq); -SRSLTE_API double srslte_rf_set_tx_gain(srslte_rf_t* h, double gain); +SRSLTE_API int srslte_rf_set_tx_gain(srslte_rf_t* h, double gain); + +SRSLTE_API int srslte_rf_set_tx_gain_ch(srslte_rf_t* h, uint32_t ch, double gain); SRSLTE_API double srslte_rf_set_tx_freq(srslte_rf_t* h, uint32_t ch, double freq); diff --git a/lib/src/phy/rf/rf_blade_imp.c b/lib/src/phy/rf/rf_blade_imp.c index 2e122f2ed..c365b108b 100644 --- a/lib/src/phy/rf/rf_blade_imp.c +++ b/lib/src/phy/rf/rf_blade_imp.c @@ -282,28 +282,38 @@ double rf_blade_set_tx_srate(void* h, double freq) return (double)handler->tx_rate; } -double rf_blade_set_rx_gain(void* h, double gain) +int rf_blade_set_rx_gain(void* h, double gain) { int status; rf_blade_handler_t* handler = (rf_blade_handler_t*)h; status = bladerf_set_gain(handler->dev, BLADERF_RX_X1, (bladerf_gain)gain); if (status != 0) { ERROR("Failed to set RX gain: %s\n", bladerf_strerror(status)); - return -1; + return SRSLTE_ERROR; } - return rf_blade_get_rx_gain(h); + return SRSLTE_SUCCESS; +} + +int rf_blade_set_rx_gain_ch(void* h, uint32_t ch, double gain) +{ + return rf_blade_set_rx_gain(h, gain); } -double rf_blade_set_tx_gain(void* h, double gain) +int rf_blade_set_tx_gain(void* h, double gain) { int status; rf_blade_handler_t* handler = (rf_blade_handler_t*)h; status = bladerf_set_gain(handler->dev, BLADERF_TX_X1, (bladerf_gain)gain); if (status != 0) { ERROR("Failed to set TX gain: %s\n", bladerf_strerror(status)); - return -1; + return SRSLTE_ERROR; } - return rf_blade_get_tx_gain(h); + return SRSLTE_SUCCESS; +} + +int rf_blade_set_tx_gain_ch(void* h, uint32_t ch, double gain) +{ + return rf_blade_set_tx_gain(h, gain); } double rf_blade_get_rx_gain(void* h) diff --git a/lib/src/phy/rf/rf_blade_imp.h b/lib/src/phy/rf/rf_blade_imp.h index 5fcc06efc..c93a54574 100644 --- a/lib/src/phy/rf/rf_blade_imp.h +++ b/lib/src/phy/rf/rf_blade_imp.h @@ -46,7 +46,9 @@ SRSLTE_API float rf_blade_get_rssi(void* h); SRSLTE_API double rf_blade_set_rx_srate(void* h, double freq); -SRSLTE_API double rf_blade_set_rx_gain(void* h, double gain); +SRSLTE_API int rf_blade_set_rx_gain(void* h, double gain); + +SRSLTE_API int rf_blade_set_rx_gain_ch(void* h, uint32_t ch, double gain); SRSLTE_API float rf_blade_get_rx_gain_offset(void* h); @@ -70,7 +72,9 @@ rf_blade_recv_with_time(void* h, void* data, uint32_t nsamples, bool blocking, t SRSLTE_API double rf_blade_set_tx_srate(void* h, double freq); -SRSLTE_API double rf_blade_set_tx_gain(void* h, double gain); +SRSLTE_API int rf_blade_set_tx_gain(void* h, double gain); + +SRSLTE_API int rf_blade_set_tx_gain_ch(void* h, uint32_t ch, double gain); SRSLTE_API double rf_blade_set_tx_freq(void* h, uint32_t ch, double freq); diff --git a/lib/src/phy/rf/rf_dev.h b/lib/src/phy/rf/rf_dev.h index 0525d4b9e..d42abe7a9 100644 --- a/lib/src/phy/rf/rf_dev.h +++ b/lib/src/phy/rf/rf_dev.h @@ -37,8 +37,10 @@ typedef struct { int (*srslte_rf_open_multi)(char* args, void** h, uint32_t nof_channels); int (*srslte_rf_close)(void* h); double (*srslte_rf_set_rx_srate)(void* h, double freq); - double (*srslte_rf_set_rx_gain)(void* h, double gain); - double (*srslte_rf_set_tx_gain)(void* h, double gain); + int (*srslte_rf_set_rx_gain)(void* h, double gain); + int (*srslte_rf_set_rx_gain_ch)(void* h, uint32_t ch, double gain); + int (*srslte_rf_set_tx_gain)(void* h, double gain); + int (*srslte_rf_set_tx_gain_ch)(void* h, uint32_t ch, double gain); double (*srslte_rf_get_rx_gain)(void* h); double (*srslte_rf_get_tx_gain)(void* h); srslte_rf_info_t* (*srslte_rf_get_info)(void* h); @@ -98,7 +100,9 @@ static rf_dev_t dev_uhd = {"UHD", rf_uhd_close, rf_uhd_set_rx_srate, rf_uhd_set_rx_gain, + rf_uhd_set_rx_gain_ch, rf_uhd_set_tx_gain, + rf_uhd_set_tx_gain_ch, rf_uhd_get_rx_gain, rf_uhd_get_tx_gain, rf_uhd_get_info, @@ -132,7 +136,9 @@ static rf_dev_t dev_blade = {"bladeRF", rf_blade_close, rf_blade_set_rx_srate, rf_blade_set_rx_gain, + rf_blade_set_rx_gain_ch, rf_blade_set_tx_gain, + rf_blade_set_tx_gain_ch, rf_blade_get_rx_gain, rf_blade_get_tx_gain, rf_blade_get_info, @@ -165,7 +171,9 @@ static rf_dev_t dev_soapy = {"soapy", rf_soapy_close, rf_soapy_set_rx_srate, rf_soapy_set_rx_gain, + rf_soapy_set_rx_gain_ch, rf_soapy_set_tx_gain, + rf_soapy_set_tx_gain_ch, rf_soapy_get_rx_gain, rf_soapy_get_tx_gain, rf_soapy_get_info, @@ -200,7 +208,9 @@ static rf_dev_t dev_zmq = {"zmq", rf_zmq_close, rf_zmq_set_rx_srate, rf_zmq_set_rx_gain, + rf_zmq_set_rx_gain_ch, rf_zmq_set_tx_gain, + rf_zmq_set_tx_gain_ch, rf_zmq_get_rx_gain, rf_zmq_get_tx_gain, rf_zmq_get_info, @@ -225,10 +235,10 @@ int dummy_rcv() } void dummy_fnc() {} -static rf_dev_t dev_dummy = {"dummy", dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, - dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, - dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, - dummy_fnc, dummy_fnc, dummy_rcv, dummy_fnc, dummy_fnc, dummy_fnc}; +static rf_dev_t dev_dummy = {"dummy", dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, + dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, + dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_rcv, + dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc}; #endif static rf_dev_t* available_devices[] = { diff --git a/lib/src/phy/rf/rf_imp.c b/lib/src/phy/rf/rf_imp.c index ac0d14b0e..ff398e962 100644 --- a/lib/src/phy/rf/rf_imp.c +++ b/lib/src/phy/rf/rf_imp.c @@ -35,7 +35,7 @@ int rf_get_available_devices(char** devnames, int max_strlen) return i; } -double srslte_rf_set_rx_gain_th(srslte_rf_t* rf, double gain) +int srslte_rf_set_rx_gain_th(srslte_rf_t* rf, double gain) { if (gain > rf->cur_rx_gain + 2 || gain < rf->cur_rx_gain - 2) { pthread_mutex_lock(&rf->mutex); @@ -43,7 +43,7 @@ double srslte_rf_set_rx_gain_th(srslte_rf_t* rf, double gain) pthread_cond_signal(&rf->cond); pthread_mutex_unlock(&rf->mutex); } - return rf->cur_rx_gain; + return SRSLTE_SUCCESS; } void srslte_rf_set_tx_rx_gain_offset(srslte_rf_t* rf, double offset) @@ -67,7 +67,6 @@ static void* thread_gain_fcn(void* h) rf->new_rx_gain = rf->cur_rx_gain; } if (rf->tx_gain_same_rx) { - printf("setting also tx\n"); srslte_rf_set_tx_gain(h, rf->cur_rx_gain + rf->tx_rx_gain_offset); } pthread_mutex_unlock(&rf->mutex); @@ -197,11 +196,16 @@ double srslte_rf_set_rx_srate(srslte_rf_t* rf, double freq) return ((rf_dev_t*)rf->dev)->srslte_rf_set_rx_srate(rf->handler, freq); } -double srslte_rf_set_rx_gain(srslte_rf_t* rf, double gain) +int srslte_rf_set_rx_gain(srslte_rf_t* rf, double gain) { return ((rf_dev_t*)rf->dev)->srslte_rf_set_rx_gain(rf->handler, gain); } +int srslte_rf_set_rx_gain_ch(srslte_rf_t* rf, uint32_t ch, double gain) +{ + return ((rf_dev_t*)rf->dev)->srslte_rf_set_rx_gain_ch(rf->handler, ch, gain); +} + double srslte_rf_get_rx_gain(srslte_rf_t* rf) { return ((rf_dev_t*)rf->dev)->srslte_rf_get_rx_gain(rf->handler); @@ -256,11 +260,16 @@ int srslte_rf_recv_with_time_multi(srslte_rf_t* rf, return ((rf_dev_t*)rf->dev)->srslte_rf_recv_with_time_multi(rf->handler, data, nsamples, blocking, secs, frac_secs); } -double srslte_rf_set_tx_gain(srslte_rf_t* rf, double gain) +int srslte_rf_set_tx_gain(srslte_rf_t* rf, double gain) { return ((rf_dev_t*)rf->dev)->srslte_rf_set_tx_gain(rf->handler, gain); } +int srslte_rf_set_tx_gain_ch(srslte_rf_t* rf, uint32_t ch, double gain) +{ + return ((rf_dev_t*)rf->dev)->srslte_rf_set_tx_gain_ch(rf->handler, ch, gain); +} + double srslte_rf_set_tx_srate(srslte_rf_t* rf, double freq) { return ((rf_dev_t*)rf->dev)->srslte_rf_set_tx_srate(rf->handler, freq); diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 445e533cd..0a8e52264 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -694,29 +694,46 @@ double rf_soapy_set_tx_srate(void* h, double rate) return handler->tx_rate; } -double rf_soapy_set_rx_gain(void* h, double gain) +int rf_soapy_set_rx_gain(void* h, double gain) { rf_soapy_handler_t* handler = (rf_soapy_handler_t*)h; - for (uint32_t i = 0; i < handler->num_rx_channels; i++) { - if (SoapySDRDevice_setGain(handler->device, SOAPY_SDR_RX, i, gain) != 0) { - printf("setGain fail: %s\n", SoapySDRDevice_lastError()); + if (rf_soapy_set_rx_gain_ch(h, i, gain) < 0) { return SRSLTE_ERROR; } } - return rf_soapy_get_rx_gain(h); + return SRSLTE_SUCCESS; +} + +int rf_soapy_set_rx_gain_ch(void* h, uint32_t ch, double gain) +{ + rf_soapy_handler_t* handler = (rf_soapy_handler_t*)h; + if (SoapySDRDevice_setGain(handler->device, SOAPY_SDR_RX, ch, gain) != 0) { + printf("setGain fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + return SRSLTE_SUCCESS; } -double rf_soapy_set_tx_gain(void* h, double gain) +int rf_soapy_set_tx_gain(void* h, double gain) { rf_soapy_handler_t* handler = (rf_soapy_handler_t*)h; for (uint32_t i = 0; i < handler->num_tx_channels; i++) { - if (SoapySDRDevice_setGain(handler->device, SOAPY_SDR_TX, i, gain) != 0) { - printf("setGain fail: %s\n", SoapySDRDevice_lastError()); + if (rf_soapy_set_tx_gain_ch(h, i, gain) < 0) { return SRSLTE_ERROR; } } - return rf_soapy_get_tx_gain(h); + return SRSLTE_SUCCESS; +} + +int rf_soapy_set_tx_gain_ch(void* h, uint32_t ch, double gain) +{ + rf_soapy_handler_t* handler = (rf_soapy_handler_t*)h; + if (SoapySDRDevice_setGain(handler->device, SOAPY_SDR_TX, ch, gain) != 0) { + printf("setGain fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + return SRSLTE_SUCCESS; } // Return gain of first channel diff --git a/lib/src/phy/rf/rf_soapy_imp.h b/lib/src/phy/rf/rf_soapy_imp.h index 58907560d..383c83ef4 100644 --- a/lib/src/phy/rf/rf_soapy_imp.h +++ b/lib/src/phy/rf/rf_soapy_imp.h @@ -54,11 +54,15 @@ SRSLTE_API void rf_soapy_set_master_clock_rate(void* h, double rate); SRSLTE_API double rf_soapy_set_rx_srate(void* h, double freq); -SRSLTE_API double rf_soapy_set_rx_gain(void* h, double gain); +SRSLTE_API int rf_soapy_set_rx_gain(void* h, double gain); + +SRSLTE_API int rf_soapy_set_rx_gain_ch(void* h, uint32_t ch, double gain); SRSLTE_API double rf_soapy_get_rx_gain(void* h); -SRSLTE_API double rf_soapy_set_tx_gain(void* h, double gain); +SRSLTE_API int rf_soapy_set_tx_gain(void* h, double gain); + +SRSLTE_API int rf_soapy_set_tx_gain_ch(void* h, uint32_t ch, double gain); SRSLTE_API double rf_soapy_get_tx_gain(void* h); diff --git a/lib/src/phy/rf/rf_uhd_imp.cc b/lib/src/phy/rf/rf_uhd_imp.cc index 6df6ff8eb..c0c28fd2f 100644 --- a/lib/src/phy/rf/rf_uhd_imp.cc +++ b/lib/src/phy/rf/rf_uhd_imp.cc @@ -984,28 +984,48 @@ double rf_uhd_set_tx_srate(void* h, double freq) return freq; } -double rf_uhd_set_rx_gain(void* h, double gain) +int rf_uhd_set_rx_gain(void* h, double gain) { rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; for (size_t i = 0; i < handler->nof_rx_channels; i++) { - if (handler->uhd.set_rx_gain(i, gain) != UHD_ERROR_NONE) { + if (rf_uhd_set_rx_gain_ch(h, i, gain)) { print_usrp_error(handler); return SRSLTE_ERROR; } } - return gain; + return SRSLTE_SUCCESS; +} + +int rf_uhd_set_rx_gain_ch(void* h, uint32_t ch, double gain) +{ + rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; + if (handler->uhd.set_rx_gain(ch, gain) != UHD_ERROR_NONE) { + print_usrp_error(handler); + return SRSLTE_ERROR; + } + return SRSLTE_SUCCESS; } -double rf_uhd_set_tx_gain(void* h, double gain) +int rf_uhd_set_tx_gain(void* h, double gain) { rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; for (size_t i = 0; i < handler->nof_tx_channels; i++) { - if (handler->uhd.set_tx_gain(i, gain) != UHD_ERROR_NONE) { + if (rf_uhd_set_tx_gain_ch(h, i, gain)) { print_usrp_error(handler); return SRSLTE_ERROR; } } - return gain; + return SRSLTE_SUCCESS; +} + +int rf_uhd_set_tx_gain_ch(void* h, uint32_t ch, double gain) +{ + rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; + if (handler->uhd.set_tx_gain(ch, gain) != UHD_ERROR_NONE) { + print_usrp_error(handler); + return SRSLTE_ERROR; + } + return SRSLTE_SUCCESS; } double rf_uhd_get_rx_gain(void* h) diff --git a/lib/src/phy/rf/rf_uhd_imp.h b/lib/src/phy/rf/rf_uhd_imp.h index 8f6bd84de..f2f61e934 100644 --- a/lib/src/phy/rf/rf_uhd_imp.h +++ b/lib/src/phy/rf/rf_uhd_imp.h @@ -58,7 +58,9 @@ SRSLTE_API float rf_uhd_get_rssi(void* h); SRSLTE_API double rf_uhd_set_rx_srate(void* h, double freq); -SRSLTE_API double rf_uhd_set_rx_gain(void* h, double gain); +SRSLTE_API int rf_uhd_set_rx_gain(void* h, double gain); + +SRSLTE_API int rf_uhd_set_rx_gain_ch(void* h, uint32_t ch, double gain); SRSLTE_API double rf_uhd_get_rx_gain(void* h); @@ -80,7 +82,9 @@ rf_uhd_recv_with_time_multi(void* h, void** data, uint32_t nsamples, bool blocki SRSLTE_API double rf_uhd_set_tx_srate(void* h, double freq); -SRSLTE_API double rf_uhd_set_tx_gain(void* h, double gain); +SRSLTE_API int rf_uhd_set_tx_gain(void* h, double gain); + +SRSLTE_API int rf_uhd_set_tx_gain_ch(void* h, uint32_t ch, double gain); SRSLTE_API double rf_uhd_set_tx_freq(void* h, uint32_t ch, double freq); diff --git a/lib/src/phy/rf/rf_zmq_imp.c b/lib/src/phy/rf/rf_zmq_imp.c index 0b7cb7d21..93819ae7d 100644 --- a/lib/src/phy/rf/rf_zmq_imp.c +++ b/lib/src/phy/rf/rf_zmq_imp.c @@ -452,20 +452,28 @@ double rf_zmq_set_tx_srate(void* h, double srate) return ret; } -double rf_zmq_set_rx_gain(void* h, double gain) +int rf_zmq_set_rx_gain(void* h, double gain) { - double ret = 0.0; if (h) { rf_zmq_handler_t* handler = (rf_zmq_handler_t*)h; handler->rx_gain = gain; - ret = gain; } - return ret; + return SRSLTE_SUCCESS; } -double rf_zmq_set_tx_gain(void* h, double gain) +int rf_zmq_set_rx_gain_ch(void* h, uint32_t ch, double gain) { - return 0.0; + return rf_zmq_set_rx_gain(h, gain); +} + +int rf_zmq_set_tx_gain(void* h, double gain) +{ + return SRSLTE_SUCCESS; +} + +int rf_zmq_set_tx_gain_ch(void* h, uint32_t ch, double gain) +{ + return rf_zmq_set_tx_gain(h, gain); } double rf_zmq_get_rx_gain(void* h) diff --git a/lib/src/phy/rf/rf_zmq_imp.h b/lib/src/phy/rf/rf_zmq_imp.h index afd96c515..136394c10 100644 --- a/lib/src/phy/rf/rf_zmq_imp.h +++ b/lib/src/phy/rf/rf_zmq_imp.h @@ -52,7 +52,9 @@ SRSLTE_API float rf_zmq_get_rssi(void* h); SRSLTE_API double rf_zmq_set_rx_srate(void* h, double freq); -SRSLTE_API double rf_zmq_set_rx_gain(void* h, double gain); +SRSLTE_API int rf_zmq_set_rx_gain(void* h, double gain); + +SRSLTE_API int rf_zmq_set_rx_gain_ch(void* h, uint32_t ch, double gain); SRSLTE_API double rf_zmq_get_rx_gain(void* h); @@ -74,7 +76,9 @@ rf_zmq_recv_with_time_multi(void* h, void** data, uint32_t nsamples, bool blocki SRSLTE_API double rf_zmq_set_tx_srate(void* h, double freq); -SRSLTE_API double rf_zmq_set_tx_gain(void* h, double gain); +SRSLTE_API int rf_zmq_set_tx_gain(void* h, double gain); + +SRSLTE_API int rf_zmq_set_tx_gain_ch(void* h, uint32_t ch, double gain); SRSLTE_API double rf_zmq_set_tx_freq(void* h, uint32_t ch, double freq); diff --git a/lib/src/phy/sync/test/npss_usrp.c b/lib/src/phy/sync/test/npss_usrp.c index 2add58fe6..1fe9c256a 100644 --- a/lib/src/phy/sync/test/npss_usrp.c +++ b/lib/src/phy/sync/test/npss_usrp.c @@ -177,8 +177,9 @@ int main(int argc, char** argv) exit(-1); } + srslte_rf_set_rx_gain(&rf, rf_gain); printf("Set RX rate: %.2f MHz\n", srslte_rf_set_rx_srate(&rf, srate) / 1000000); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + printf("Set RX gain: %.1f dB\n", srslte_rf_get_rx_gain(&rf)); printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, 0, rf_freq) / 1000000); buffer = srslte_vec_cf_malloc(flen * 2); diff --git a/lib/src/phy/sync/test/nsss_usrp.c b/lib/src/phy/sync/test/nsss_usrp.c index 0f8e9942f..e0da9bae9 100644 --- a/lib/src/phy/sync/test/nsss_usrp.c +++ b/lib/src/phy/sync/test/nsss_usrp.c @@ -136,9 +136,9 @@ int main(int argc, char** argv) fprintf(stderr, "Error opening rf\n"); exit(-1); } - + srslte_rf_set_rx_gain(&rf, rf_gain); printf("Set RX rate: %.2f MHz\n", srslte_rf_set_rx_srate(&rf, srate) / 1000000); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + printf("Set RX gain: %.1f dB\n", srslte_rf_get_rx_gain(&rf)); printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, 0, rf_freq) / 1000000); buffer = srslte_vec_cf_malloc(input_len * 2); diff --git a/lib/src/phy/sync/test/pss_usrp.c b/lib/src/phy/sync/test/pss_usrp.c index 7286045df..b3bc0f192 100644 --- a/lib/src/phy/sync/test/pss_usrp.c +++ b/lib/src/phy/sync/test/pss_usrp.c @@ -159,9 +159,9 @@ int main(int argc, char** argv) ERROR("Error opening rf\n"); exit(-1); } - + srslte_rf_set_rx_gain(&rf, rf_gain); printf("Set RX rate: %.2f MHz\n", srslte_rf_set_rx_srate(&rf, srate) / 1000000); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + printf("Set RX gain: %.1f dB\n", srslte_rf_get_rx_gain(&rf)); printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, 0, rf_freq) / 1000000); buffer = srslte_vec_cf_malloc(flen * 2); diff --git a/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c b/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c index e1b0022ac..664b83491 100644 --- a/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c +++ b/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c @@ -139,8 +139,9 @@ int main(int argc, char** argv) exit(-1); } + srslte_rf_set_rx_gain(&rf_device, rf_gain); printf("Set RX rate: %.2f MHz\n", srslte_rf_set_rx_srate(&rf_device, srate) / 1000000); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf_device, rf_gain)); + printf("Set RX gain: %.1f dB\n", srslte_rf_get_rx_gain(&rf_device)); printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf_device, 0, rf_freq) / 1000000); srslte_ue_mib_sync_nbiot_t mib_sync; diff --git a/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c b/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c index f1cd9d585..fdd1fec71 100644 --- a/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c +++ b/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c @@ -161,8 +161,9 @@ int main(int argc, char** argv) exit(-1); } + srslte_rf_set_rx_gain(&rf, rf_gain); printf("Set RX rate: %.2f MHz\n", srslte_rf_set_rx_srate(&rf, srate) / 1000000); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + printf("Set RX gain: %.1f dB\n", srslte_rf_get_rx_gain(&rf)); printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, 0, rf_freq) / 1000000); // Allocate memory for rx'ing samples (1 full frame) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 37a3ef99d..b35a97fdb 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -139,6 +139,7 @@ int radio::init(const rf_args_t& args, phy_interface_radio* phy_) } else { set_rx_gain(args.rx_gain); } + // Set gain for all channels if (args.tx_gain > 0) { set_tx_gain(args.tx_gain); } else { @@ -147,6 +148,26 @@ int radio::init(const rf_args_t& args, phy_interface_radio* phy_) log_h->console("\nWarning: TX gain was not set. Using open-loop power control (not working properly)\n\n"); } + // Set individual gains + for (uint32_t i = 0; i < args.nof_carriers; i++) { + if (args.tx_gain_ch[i] > 0) { + for (uint32_t j = 0; j < nof_antennas; i++) { + uint32_t phys_antenna_idx = i * nof_antennas + j; + + // From channel number deduce RF device index and channel + uint32_t rf_device_idx = phys_antenna_idx / nof_channels_x_dev; + uint32_t rf_channel_idx = phys_antenna_idx % nof_channels_x_dev; + + log_h->info( + "Setting individual tx_gain=%.1f on dev=%d ch=%d\n", args.tx_gain_ch[i], rf_device_idx, rf_channel_idx); + if (srslte_rf_set_tx_gain_ch(&rf_devices[rf_device_idx], rf_channel_idx, args.tx_gain_ch[i]) < 0) { + log_h->error( + "Setting channel tx_gain=%.1f on dev=%d ch=%d\n", args.tx_gain_ch[i], rf_device_idx, rf_channel_idx); + } + } + } + } + // Frequency offset freq_offset = args.freq_offset; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 806fa70e9..9c1cf82de 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -78,7 +78,12 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) ("rf.dl_freq", bpo::value(&args->phy.dl_freq)->default_value(-1), "Downlink Frequency (if positive overrides EARFCN)") ("rf.ul_freq", bpo::value(&args->phy.ul_freq)->default_value(-1), "Uplink Frequency (if positive overrides EARFCN)") ("rf.rx_gain", bpo::value(&args->rf.rx_gain)->default_value(-1), "Front-end receiver gain") - ("rf.tx_gain", bpo::value(&args->rf.tx_gain)->default_value(-1), "Front-end transmitter gain") + ("rf.tx_gain", bpo::value(&args->rf.tx_gain)->default_value(-1), "Front-end transmitter gain (all channels)") + ("rf.tx_gain[0]", bpo::value(&args->rf.tx_gain_ch[0])->default_value(-1), "Front-end transmitter gain CH0") + ("rf.tx_gain[1]", bpo::value(&args->rf.tx_gain_ch[1])->default_value(-1), "Front-end transmitter gain CH1") + ("rf.tx_gain[2]", bpo::value(&args->rf.tx_gain_ch[2])->default_value(-1), "Front-end transmitter gain CH2") + ("rf.tx_gain[3]", bpo::value(&args->rf.tx_gain_ch[3])->default_value(-1), "Front-end transmitter gain CH3") + ("rf.tx_gain[4]", bpo::value(&args->rf.tx_gain_ch[4])->default_value(-1), "Front-end transmitter gain CH4") ("rf.nof_carriers", bpo::value(&args->rf.nof_carriers)->default_value(1), "Number of carriers") ("rf.nof_antennas", bpo::value(&args->rf.nof_antennas)->default_value(1), "Number of antennas per carrier")