srsLTE: AGC only uses boundaries for requesting gain to Radio

master
Xavier Arteaga 5 years ago committed by Andre Puschmann
parent 097f492430
commit c92dce71b7

@ -130,9 +130,9 @@ void sig_int_handler(int signo)
} }
} }
float srslte_rf_set_rx_gain_wrapper(void* h, float f) static SRSLTE_AGC_CALLBACK(srslte_rf_set_rx_gain_wrapper)
{ {
return srslte_rf_set_rx_gain((srslte_rf_t*)h, f); srslte_rf_set_rx_gain((srslte_rf_t*)h, gain_db);
} }
int main(int argc, char** argv) int main(int argc, char** argv)

@ -139,9 +139,9 @@ void sig_int_handler(int signo)
} }
} }
float srslte_rf_set_rx_gain_wrapper(void* h, float f) static SRSLTE_AGC_CALLBACK(srslte_rf_set_rx_gain_wrapper)
{ {
return srslte_rf_set_rx_gain((srslte_rf_t*)h, f); srslte_rf_set_rx_gain((srslte_rf_t*)h, gain_db);
} }
int main(int argc, char** argv) int main(int argc, char** argv)

@ -349,9 +349,9 @@ int srslte_rf_recv_wrapper(void* h, cf_t* data_[SRSLTE_MAX_PORTS], uint32_t nsam
return srslte_rf_recv_with_time_multi(h, ptr, nsamples, true, NULL, NULL); return srslte_rf_recv_with_time_multi(h, ptr, nsamples, true, NULL, NULL);
} }
float srslte_rf_set_rx_gain_th_wrapper_(void* h, float f) static SRSLTE_AGC_CALLBACK(srslte_rf_set_rx_gain_th_wrapper_)
{ {
return srslte_rf_set_rx_gain_th((srslte_rf_t*)h, f); srslte_rf_set_rx_gain_th((srslte_rf_t*)h, gain_db);
} }
#endif #endif

@ -51,10 +51,10 @@ public:
virtual void set_tx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) = 0; virtual void set_tx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) = 0;
virtual void set_rx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) = 0; virtual void set_rx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) = 0;
virtual float set_rx_gain_th(const float& gain) = 0; virtual void set_rx_gain_th(const float& gain) = 0;
virtual void set_rx_gain(const uint32_t& radio_idx, const float& gain) = 0; virtual void set_rx_gain(const uint32_t& radio_idx, const float& gain) = 0;
virtual void set_tx_srate(const uint32_t& radio_idx, const double& srate) = 0; virtual void set_tx_srate(const uint32_t& radio_idx, const double& srate) = 0;
virtual void set_rx_srate(const uint32_t& radio_idx, const double& srate) = 0; virtual void set_rx_srate(const uint32_t& radio_idx, const double& srate) = 0;
// getter // getter
virtual float get_rx_gain(const uint32_t& radio_idx) = 0; virtual float get_rx_gain(const uint32_t& radio_idx) = 0;

@ -37,6 +37,7 @@
#include "srslte/config.h" #include "srslte/config.h"
#define SRSLTE_AGC_CALLBACK(NAME) void(NAME)(void* h, float gain_db)
#define SRSLTE_AGC_DEFAULT_TARGET 0.3 #define SRSLTE_AGC_DEFAULT_TARGET 0.3
#define SRSLTE_AGC_DEFAULT_BW 0.7 #define SRSLTE_AGC_DEFAULT_BW 0.7
@ -47,11 +48,12 @@ typedef struct SRSLTE_API {
float gain; float gain;
float min_gain_db; float min_gain_db;
float max_gain_db; float max_gain_db;
float default_gain_db;
float y_out; float y_out;
bool lock; bool lock;
bool isfirst; bool isfirst;
void* uhd_handler; void* uhd_handler;
float (*set_gain_callback)(void*, float); SRSLTE_AGC_CALLBACK(*set_gain_callback);
srslte_agc_mode_t mode; srslte_agc_mode_t mode;
float target; float target;
uint32_t nof_frames; uint32_t nof_frames;
@ -66,7 +68,7 @@ SRSLTE_API int srslte_agc_init_acc(srslte_agc_t* q, srslte_agc_mode_t mode, uint
SRSLTE_API int srslte_agc_init_uhd(srslte_agc_t* q, SRSLTE_API int srslte_agc_init_uhd(srslte_agc_t* q,
srslte_agc_mode_t mode, srslte_agc_mode_t mode,
uint32_t nof_frames, uint32_t nof_frames,
float(set_gain_callback)(void*, float), SRSLTE_AGC_CALLBACK(set_gain_callback),
void* uhd_handler); void* uhd_handler);
SRSLTE_API void srslte_agc_free(srslte_agc_t* q); SRSLTE_API void srslte_agc_free(srslte_agc_t* q);

@ -200,7 +200,7 @@ SRSLTE_API void srslte_ue_sync_set_nof_find_frames(srslte_ue_sync_t* q, uint32_t
SRSLTE_API srslte_frame_type_t srslte_ue_sync_get_frame_type(srslte_ue_sync_t* q); SRSLTE_API srslte_frame_type_t srslte_ue_sync_get_frame_type(srslte_ue_sync_t* q);
SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t* q, SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t* q,
float(set_gain_callback)(void*, float), SRSLTE_AGC_CALLBACK(set_gain_callback),
float min_gain, float min_gain,
float max_gain, float max_gain,
float init_gain_value); float init_gain_value);

@ -123,7 +123,7 @@ SRSLTE_API void srslte_ue_sync_nbiot_free(srslte_nbiot_ue_sync_t* q);
SRSLTE_API int srslte_ue_sync_nbiot_set_cell(srslte_nbiot_ue_sync_t* q, srslte_nbiot_cell_t cell); SRSLTE_API int srslte_ue_sync_nbiot_set_cell(srslte_nbiot_ue_sync_t* q, srslte_nbiot_cell_t cell);
SRSLTE_API int srslte_ue_sync_nbiot_start_agc(srslte_nbiot_ue_sync_t* q, SRSLTE_API int srslte_ue_sync_nbiot_start_agc(srslte_nbiot_ue_sync_t* q,
float(set_gain_callback)(void*, float), SRSLTE_AGC_CALLBACK(set_gain_callback),
float init_gain_value); float init_gain_value);
SRSLTE_API uint32_t srslte_ue_sync_nbiot_sf_len(srslte_nbiot_ue_sync_t* q); SRSLTE_API uint32_t srslte_ue_sync_nbiot_sf_len(srslte_nbiot_ue_sync_t* q);

@ -96,10 +96,10 @@ public:
bool rx_now(cf_t* buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t* rxd_time); bool rx_now(cf_t* buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t* rxd_time);
bool rx_at(cf_t* buffer, uint32_t nof_samples, srslte_timestamp_t rx_time); bool rx_at(cf_t* buffer, uint32_t nof_samples, srslte_timestamp_t rx_time);
void set_tx_gain(float gain); void set_tx_gain(float gain);
void set_rx_gain(float gain); void set_rx_gain(float gain);
void set_tx_rx_gain_offset(float offset); void set_tx_rx_gain_offset(float offset);
float set_rx_gain_th(float gain); void set_rx_gain_th(float gain);
void set_freq_offset(double freq); void set_freq_offset(double freq);
void set_tx_freq(uint32_t chan, double freq); void set_tx_freq(uint32_t chan, double freq);

@ -102,7 +102,7 @@ public:
return radios.at(radio_idx)->rx_now(buffer, nof_samples, rxd_time); return radios.at(radio_idx)->rx_now(buffer, nof_samples, rxd_time);
} }
void set_rx_gain(const uint32_t& radio_idx, const float& gain) override { radios.at(radio_idx)->set_rx_gain(gain); } void set_rx_gain(const uint32_t& radio_idx, const float& gain) override { radios.at(radio_idx)->set_rx_gain(gain); }
float set_rx_gain_th(const float& gain) override { return radios.at(0)->set_rx_gain_th(gain); } void set_rx_gain_th(const float& gain) override { radios.at(0)->set_rx_gain_th(gain); }
float get_rx_gain(const uint32_t& radio_idx) override { return radios.at(radio_idx)->get_rx_gain(); } float get_rx_gain(const uint32_t& radio_idx) override { return radios.at(radio_idx)->get_rx_gain(); }
void set_tx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) override void set_tx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) override
{ {

@ -59,7 +59,7 @@ int srslte_agc_init_acc(srslte_agc_t* q, srslte_agc_mode_t mode, uint32_t nof_fr
int srslte_agc_init_uhd(srslte_agc_t* q, int srslte_agc_init_uhd(srslte_agc_t* q,
srslte_agc_mode_t mode, srslte_agc_mode_t mode,
uint32_t nof_frames, uint32_t nof_frames,
float(set_gain_callback)(void*, float), SRSLTE_AGC_CALLBACK(set_gain_callback),
void* uhd_handler) void* uhd_handler)
{ {
if (!srslte_agc_init_acc(q, mode, nof_frames)) { if (!srslte_agc_init_acc(q, mode, nof_frames)) {
@ -83,11 +83,11 @@ void srslte_agc_reset(srslte_agc_t* q)
{ {
q->bandwidth = SRSLTE_AGC_DEFAULT_BW; q->bandwidth = SRSLTE_AGC_DEFAULT_BW;
q->lock = false; q->lock = false;
q->gain = srslte_convert_dB_to_power(50.0f); q->gain = srslte_convert_dB_to_power(q->default_gain_db);
q->y_out = 1.0; q->y_out = 1.0;
q->isfirst = true; q->isfirst = true;
if (q->set_gain_callback && q->uhd_handler) { if (q->set_gain_callback && q->uhd_handler) {
q->set_gain_callback(q->uhd_handler, srslte_convert_power_to_dB(q->gain)); q->set_gain_callback(q->uhd_handler, q->default_gain_db);
} }
} }
@ -96,6 +96,7 @@ void srslte_agc_set_gain_range(srslte_agc_t* q, float min_gain_db, float max_gai
if (q) { if (q) {
q->min_gain_db = min_gain_db; q->min_gain_db = min_gain_db;
q->max_gain_db = max_gain_db; q->max_gain_db = max_gain_db;
q->default_gain_db = (max_gain_db + min_gain_db) / 2.0f;
} }
} }
@ -138,7 +139,6 @@ void srslte_agc_process(srslte_agc_t* q, cf_t* signal, uint32_t len)
{ {
if (!q->lock) { if (!q->lock) {
float gain_db = srslte_convert_power_to_dB(q->gain); float gain_db = srslte_convert_power_to_dB(q->gain);
float gain_uhd_db = 50.0f;
float y = 0; float y = 0;
// Apply current gain to input signal // Apply current gain to input signal
@ -152,13 +152,13 @@ void srslte_agc_process(srslte_agc_t* q, cf_t* signal, uint32_t len)
gain_db = q->max_gain_db; gain_db = q->max_gain_db;
INFO("Warning: Rx signal strength is too weak. Forcing maximum Rx gain %.2fdB\n", gain_db); INFO("Warning: Rx signal strength is too weak. Forcing maximum Rx gain %.2fdB\n", gain_db);
} else if (isinf(gain_db) || isnan(gain_db)) { } else if (isinf(gain_db) || isnan(gain_db)) {
gain_db = (q->min_gain_db + q->max_gain_db) / 2.0; gain_db = q->default_gain_db;
INFO("Warning: AGC went to an unknown state. Setting Rx gain to %.2fdB\n", gain_db); INFO("Warning: AGC went to an unknown state. Setting Rx gain to %.2fdB\n", gain_db);
} }
// Set gain // Set gain
gain_uhd_db = q->set_gain_callback(q->uhd_handler, gain_db); q->set_gain_callback(q->uhd_handler, gain_db);
q->gain = srslte_convert_dB_to_power(gain_uhd_db); q->gain = srslte_convert_dB_to_power(gain_db);
} }
float* t; float* t;
switch (q->mode) { switch (q->mode) {
@ -201,7 +201,7 @@ void srslte_agc_process(srslte_agc_t* q, cf_t* signal, uint32_t len)
if (!q->lock) { if (!q->lock) {
q->gain *= q->target / q->y_out; q->gain *= q->target / q->y_out;
} }
INFO("AGC gain: %.2f (%.2f) y_out=%.3f, y=%.3f target=%.1f\n", gain_db, gain_uhd_db, q->y_out, y, q->target); INFO("AGC gain: %.2f y_out=%.3f, y=%.3f target=%.1f\n", gain_db, q->y_out, y, q->target);
} }
} }
} }

@ -141,7 +141,7 @@ void srslte_ue_sync_reset(srslte_ue_sync_t* q)
} }
int srslte_ue_sync_start_agc(srslte_ue_sync_t* q, int srslte_ue_sync_start_agc(srslte_ue_sync_t* q,
float(set_gain_callback)(void*, float), SRSLTE_AGC_CALLBACK(set_gain_callback),
float min_gain_db, float min_gain_db,
float max_gain_db, float max_gain_db,
float init_gain_value_db) float init_gain_value_db)

@ -127,7 +127,7 @@ clean_exit:
} }
int srslte_ue_sync_nbiot_start_agc(srslte_nbiot_ue_sync_t* q, int srslte_ue_sync_nbiot_start_agc(srslte_nbiot_ue_sync_t* q,
float(set_gain_callback)(void*, float), SRSLTE_AGC_CALLBACK(set_gain_callback),
float init_gain_value) float init_gain_value)
{ {
uint32_t nframes; uint32_t nframes;

@ -280,9 +280,9 @@ void radio::set_rx_gain(float gain)
srslte_rf_set_rx_gain(&rf_device, gain); srslte_rf_set_rx_gain(&rf_device, gain);
} }
float radio::set_rx_gain_th(float gain) void radio::set_rx_gain_th(float gain)
{ {
return srslte_rf_set_rx_gain_th(&rf_device, gain); srslte_rf_set_rx_gain_th(&rf_device, gain);
} }
void radio::set_rx_srate(double srate) void radio::set_rx_srate(double srate)

@ -151,10 +151,10 @@ void parse_args(int argc, char** argv)
} }
} }
static float set_gain_callback(void* h, float gain) static SRSLTE_AGC_CALLBACK(set_gain_callback)
{ {
auto r = (radio*)h; auto r = (radio*)h;
return r->set_rx_gain_th(gain); r->set_rx_gain_th(gain_db);
} }
#ifdef ENABLE_GUI #ifdef ENABLE_GUI

@ -54,31 +54,22 @@ public:
const srslte_cell_t* get_cell() { return &cell; }; const srslte_cell_t* get_cell() { return &cell; };
// Other functions // Other functions
const static int MUTEX_X_WORKER = 4; void set_rx_gain(float gain);
double set_rx_gain(double gain); int radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time);
int radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time); bool tti_align(uint32_t tti);
bool tti_align(uint32_t tti); void read_sf(cf_t** dst, srslte_timestamp_t* timestamp, int* next_offset);
void read_sf(cf_t** dst, srslte_timestamp_t* timestamp, int* next_offset);
private: private:
class phch_scell_recv_buffer class phch_scell_recv_buffer
{ {
private: private:
uint32_t tti; uint32_t tti = 0;
srslte_timestamp_t timestamp; srslte_timestamp_t timestamp = {};
int next_offset; int next_offset = 0;
cf_t* buffer[SRSLTE_MAX_PORTS]; cf_t* buffer[SRSLTE_MAX_PORTS] = {};
public: public:
phch_scell_recv_buffer() phch_scell_recv_buffer() = default;
{
tti = 0;
next_offset = 0;
bzero(&timestamp, sizeof(timestamp));
for (cf_t*& b : buffer) {
b = nullptr;
}
}
~phch_scell_recv_buffer() ~phch_scell_recv_buffer()
{ {

@ -89,8 +89,8 @@ public:
void force_freq(float dl_freq, float ul_freq); void force_freq(float dl_freq, float ul_freq);
// Other functions // Other functions
double set_rx_gain(double gain); void set_rx_gain(float gain);
int radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time); int radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time);
private: private:
// Class to run cell search // Class to run cell search

@ -79,9 +79,9 @@ static int radio_recv_callback(void* obj, cf_t* data[SRSLTE_MAX_PORTS], uint32_t
return ((async_scell_recv*)obj)->radio_recv_fnc(data, nsamples, rx_time); return ((async_scell_recv*)obj)->radio_recv_fnc(data, nsamples, rx_time);
} }
static float callback_set_rx_gain(void* h, float gain) static SRSLTE_AGC_CALLBACK(callback_set_rx_gain)
{ {
return (float)((async_scell_recv*)h)->set_rx_gain(gain); ((async_scell_recv*)h)->set_rx_gain(gain_db);
} }
void async_scell_recv::init(srslte::radio_interface_phy* _radio_handler, phy_common* _worker_com, srslte::log* _log_h) void async_scell_recv::init(srslte::radio_interface_phy* _radio_handler, phy_common* _worker_com, srslte::log* _log_h)
@ -198,9 +198,9 @@ void async_scell_recv::set_agc_enable(bool enable)
} }
} }
double async_scell_recv::set_rx_gain(double gain) void async_scell_recv::set_rx_gain(float gain)
{ {
return radio_h->set_rx_gain_th((float)gain); radio_h->set_rx_gain_th(gain);
} }
int async_scell_recv::radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time) int async_scell_recv::radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time)

@ -47,9 +47,9 @@ static int radio_recv_callback(void* obj, cf_t* data[SRSLTE_MAX_PORTS], uint32_t
return ((sync*)obj)->radio_recv_fnc(data, nsamples, rx_time); return ((sync*)obj)->radio_recv_fnc(data, nsamples, rx_time);
} }
float callback_set_rx_gain(void* h, float gain) static SRSLTE_AGC_CALLBACK(callback_set_rx_gain)
{ {
return ((sync*)h)->set_rx_gain(gain); ((sync*)h)->set_rx_gain(gain_db);
} }
void sync::init(srslte::radio_interface_phy* _radio, void sync::init(srslte::radio_interface_phy* _radio,
@ -963,9 +963,9 @@ int sync::radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte
} }
} }
double sync::set_rx_gain(double gain) void sync::set_rx_gain(float gain)
{ {
return radio_h->set_rx_gain_th(gain); radio_h->set_rx_gain_th(gain);
} }
/********* /*********

@ -275,12 +275,11 @@ private:
rx_freq = (float)freq; rx_freq = (float)freq;
log_h.info("Set Rx freq to %+.0f MHz.\n", freq * 1.0e-6); log_h.info("Set Rx freq to %+.0f MHz.\n", freq * 1.0e-6);
} }
float set_rx_gain_th(const float& gain) override void set_rx_gain_th(const float& gain) override
{ {
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
rx_gain = srslte_convert_dB_to_amplitude(gain); rx_gain = srslte_convert_dB_to_amplitude(gain);
log_h.info("Set Rx gain-th to %+.1f dB (%.6f).\n", gain, rx_gain); log_h.info("Set Rx gain-th to %+.1f dB (%.6f).\n", gain, rx_gain);
return srslte_convert_amplitude_to_dB(rx_gain);
} }
void set_rx_gain(const uint32_t& radio_idx, const float& gain) override void set_rx_gain(const uint32_t& radio_idx, const float& gain) override
{ {

Loading…
Cancel
Save