Merge branch 'next' of github.com:softwareradiosystems/srsLTE into next

This commit is contained in:
Ismael Gomez 2018-06-11 20:16:08 +02:00
commit a75604eb0e
27 changed files with 371 additions and 44 deletions

View File

@ -199,7 +199,12 @@ int main(int argc, char **argv) {
srslte_ue_cellsearch_set_nof_valid_frames(&cs, cell_detect_config.nof_valid_pss_frames);
}
if (cell_detect_config.init_agc) {
srslte_ue_sync_start_agc(&cs.ue_sync, srslte_rf_set_rx_gain_wrapper, cell_detect_config.init_agc);
srslte_rf_info_t *rf_info = srslte_rf_get_info(&rf);
srslte_ue_sync_start_agc(&cs.ue_sync,
srslte_rf_set_rx_gain_wrapper,
rf_info->min_rx_gain,
rf_info->max_rx_gain,
cell_detect_config.init_agc);
}
for (freq=0;freq<nof_freqs && !go_exit;freq++) {

View File

@ -600,7 +600,12 @@ int main(int argc, char **argv) {
#ifndef DISABLE_RF
if (prog_args.rf_gain < 0) {
srslte_ue_sync_start_agc(&ue_sync, srslte_rf_set_rx_gain_th_wrapper_, cell_detect_config.init_agc);
srslte_rf_info_t *rf_info = srslte_rf_get_info(&rf);
srslte_ue_sync_start_agc(&ue_sync,
srslte_rf_set_rx_gain_th_wrapper_,
rf_info->min_rx_gain,
rf_info->max_rx_gain,
cell_detect_config.init_agc);
}
#endif
#ifdef PRINT_CHANGE_SCHEDULIGN

View File

@ -53,6 +53,8 @@ typedef enum SRSLTE_API {
typedef struct SRSLTE_API{
float bandwidth;
double gain;
double min_gain;
double max_gain;
float y_out;
bool lock;
bool isfirst;
@ -79,6 +81,8 @@ SRSLTE_API void srslte_agc_free(srslte_agc_t *q);
SRSLTE_API void srslte_agc_reset(srslte_agc_t *q);
SRSLTE_API void srslte_agc_set_gain_range(srslte_agc_t *q, double min_gain, double max_gain);
SRSLTE_API void srslte_agc_set_bandwidth(srslte_agc_t *q,
float bandwidth);

View File

@ -89,6 +89,8 @@ typedef struct SRSLTE_API {
srslte_sch_t dl_sch;
void *coworker_ptr;
} srslte_pdsch_t;
@ -167,6 +169,8 @@ SRSLTE_API void srslte_pdsch_set_max_noi(srslte_pdsch_t *q,
SRSLTE_API float srslte_pdsch_last_noi(srslte_pdsch_t *q);
SRSLTE_API int srslte_pdsch_enable_coworker(srslte_pdsch_t *q);
SRSLTE_API uint32_t srslte_pdsch_last_noi_cw(srslte_pdsch_t *q,
uint32_t cw_idx);

View File

@ -55,6 +55,14 @@ typedef struct {
float iq_q;
} srslte_rf_cal_t;
typedef struct {
double min_tx_gain;
double max_tx_gain;
double min_rx_gain;
double max_rx_gain;
} srslte_rf_info_t;
typedef struct {
enum {
SRSLTE_RF_ERROR_LATE,
@ -125,6 +133,8 @@ SRSLTE_API double srslte_rf_get_rx_gain(srslte_rf_t *h);
SRSLTE_API double srslte_rf_get_tx_gain(srslte_rf_t *h);
SRSLTE_API srslte_rf_info_t *srslte_rf_get_info(srslte_rf_t *h);
SRSLTE_API void srslte_rf_suppress_stdout(srslte_rf_t *h);
SRSLTE_API void srslte_rf_register_error_handler(srslte_rf_t *h,

View File

@ -199,7 +199,9 @@ SRSLTE_API void srslte_ue_sync_reset(srslte_ue_sync_t *q);
SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t *q,
double (set_gain_callback)(void*, double),
float init_gain_value);
double min_gain,
double max_gain,
double init_gain_value);
SRSLTE_API uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q);

View File

@ -115,6 +115,7 @@ class radio {
float get_tx_gain();
float get_rx_gain();
srslte_rf_info_t *get_info();
float get_max_tx_power();
float set_tx_power(float power);

View File

@ -45,6 +45,8 @@ int srslte_agc_init_acc(srslte_agc_t *q, srslte_agc_mode_t mode, uint32_t nof_fr
bzero(q, sizeof(srslte_agc_t));
q->mode = mode;
q->nof_frames = nof_frames;
q->max_gain = 90.0;
q->min_gain = 0.0;
if (nof_frames > 0) {
q->y_tmp = srslte_vec_malloc(sizeof(float) * nof_frames);
if (!q->y_tmp) {
@ -86,6 +88,13 @@ void srslte_agc_reset(srslte_agc_t *q) {
}
}
void srslte_agc_set_gain_range(srslte_agc_t *q, double min_gain, double max_gain) {
if (q) {
q->min_gain = min_gain;
q->max_gain = max_gain;
}
}
void srslte_agc_set_bandwidth(srslte_agc_t *q, float bandwidth) {
q->bandwidth = bandwidth;
}
@ -116,19 +125,23 @@ void srslte_agc_lock(srslte_agc_t *q, bool enable) {
void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) {
if (!q->lock) {
float gain_db = 10*log10(q->gain);
float gain_uhd_db = 50.0;
//float gain_uhd = 1.0;
double gain_db = 10.0 * log10(q->gain);
double gain_uhd_db = 50.0;
float y = 0;
// Apply current gain to input signal
if (!q->uhd_handler) {
srslte_vec_sc_prod_cfc(signal, q->gain, signal, len);
} else {
if (gain_db < 0) {
gain_db = 5.0;
}
if (isinf(gain_db) || isnan(gain_db)) {
gain_db = 40.0;
if (gain_db < q->min_gain) {
gain_db = q->min_gain + 5.0;
INFO("Warning: Rx signal strength is too high. Forcing minimum Rx gain %.2fdB\n", gain_db);
} else if (gain_db > q->max_gain) {
gain_db = q->max_gain;
INFO("Warning: Rx signal strength is too weak. Forcing maximum Rx gain %.2fdB\n", gain_db);
} else if (isinf(gain_db) || isnan(gain_db)) {
gain_db = (q->min_gain + q->max_gain) / 2.0;
INFO("Warning: AGC went to an unknown state. Setting Rx gain to %.2fdB\n", gain_db);
} else {
gain_uhd_db = q->set_gain_callback(q->uhd_handler, gain_db);
q->gain = pow(10, gain_uhd_db/10);

View File

@ -282,7 +282,7 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id, srslt
input2d[i + 1] = &q->pilot_estimates[i * nref];
}
input2d[0] = &q->tmp_noise[0];
input2d[0] = &q->tmp_noise[nref];
if (nsymbols > 3) {
srslte_vec_sc_prod_cfc(input2d[2], 2.0f, input2d[0], nref);
srslte_vec_sub_ccc(input2d[0], input2d[4], input2d[0], nref);
@ -290,7 +290,7 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id, srslt
srslte_vec_sc_prod_cfc(input2d[2], 1.0f, input2d[0], nref);
}
input2d[nsymbols + 1] = &q->tmp_noise[nref];
input2d[nsymbols + 1] = &q->tmp_noise[nref * 2];
if (nsymbols > 3) {
srslte_vec_sc_prod_cfc(input2d[nsymbols - 1], 2.0f, input2d[nsymbols + 1], nref);
srslte_vec_sub_ccc(input2d[nsymbols + 1], input2d[nsymbols - 3], input2d[nsymbols + 1], nref);

View File

@ -32,6 +32,9 @@
#include <srslte/phy/phch/pdsch_cfg.h>
#include <srslte/srslte.h>
#include <pthread.h>
#include <semaphore.h>
#include "prb_dl.h"
#include "srslte/phy/phch/pdsch.h"
#include "srslte/phy/utils/debug.h"
@ -52,6 +55,39 @@ extern int indices[100000];
extern int indices_ptr;
#endif
typedef struct {
/* Thread identifier: they must set before thread creation */
pthread_t pthread;
uint32_t cw_idx;
uint32_t tb_idx;
void *pdsch_ptr;
bool *ack;
/* Configuration Encoder/Decoder: they must be set before posting start semaphore */
srslte_pdsch_cfg_t *cfg;
srslte_sch_t dl_sch;
uint16_t rnti;
/* Encoder/Decoder data pointers: they must be set before posting start semaphore */
uint8_t *data;
void *softbuffer;
/* Execution status */
int ret_status;
/* Semaphores */
sem_t start;
sem_t finish;
/* Thread flags */
bool started;
bool quit;
} srslte_pdsch_coworker_t;
static void *srslte_pdsch_decode_thread (void *arg);
int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_grant_t *grant, uint32_t lstart_grant, uint32_t nsubframe, bool put)
{
uint32_t s, n, l, lp, lstart, lend, nof_refs;
@ -283,7 +319,26 @@ int srslte_pdsch_init_enb(srslte_pdsch_t *q, uint32_t max_prb)
return pdsch_init(q, max_prb, false, 0);
}
static void srslte_pdsch_disable_coworker(srslte_pdsch_t *q) {
srslte_pdsch_coworker_t *h = (srslte_pdsch_coworker_t *) q->coworker_ptr;
if (h) {
/* Stop threads */
h->quit = true;
sem_post(&h->start);
pthread_join(h->pthread, NULL);
pthread_detach(h->pthread);
srslte_sch_free(&h->dl_sch);
free(h);
q->coworker_ptr = NULL;
}
}
void srslte_pdsch_free(srslte_pdsch_t *q) {
srslte_pdsch_disable_coworker(q);
for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
@ -612,9 +667,9 @@ static int srslte_pdsch_codeword_encode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c
return SRSLTE_SUCCESS;
}
static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg,
srslte_softbuffer_rx_t *softbuffer, uint16_t rnti, uint8_t *data,
uint32_t codeword_idx, uint32_t tb_idx, bool *ack) {
static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, srslte_sch_t *dl_sch,
srslte_softbuffer_rx_t *softbuffer, uint16_t rnti, uint8_t *data,
uint32_t codeword_idx, uint32_t tb_idx, bool *ack) {
srslte_ra_nbits_t *nbits = &cfg->nbits[tb_idx];
srslte_ra_mcs_t *mcs = &cfg->grant.mcs[tb_idx];
uint32_t rv = cfg->rv[tb_idx];
@ -673,7 +728,7 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c
}
/* Return */
ret = srslte_dlsch_decode2(&q->dl_sch, cfg, softbuffer, q->e[codeword_idx], data, tb_idx);
ret = srslte_dlsch_decode2(dl_sch, cfg, softbuffer, q->e[codeword_idx], data, tb_idx);
q->last_nof_iterations[codeword_idx] = srslte_sch_last_noi(&q->dl_sch);
@ -694,6 +749,35 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c
return ret;
}
static void *srslte_pdsch_decode_thread(void *arg) {
srslte_pdsch_coworker_t *q = (srslte_pdsch_coworker_t *) arg;
INFO("[PDSCH Coworker] waiting for data\n");
sem_wait(&q->start);
while (!q->quit) {
q->ret_status = srslte_pdsch_codeword_decode(q->pdsch_ptr,
q->cfg,
&q->dl_sch,
q->softbuffer,
q->rnti,
q->data,
q->cw_idx,
q->tb_idx,
q->ack);
/* Post finish semaphore */
sem_post(&q->finish);
/* Wait for next loop */
sem_wait(&q->start);
}
sem_post(&q->finish);
pthread_exit(NULL);
return q;
}
/** Decodes the PDSCH from the received symbols
*/
int srslte_pdsch_decode(srslte_pdsch_t *q,
@ -776,11 +860,37 @@ int srslte_pdsch_decode(srslte_pdsch_t *q,
/* Decode only if transport block is enabled and the default ACK is not true */
if (cfg->grant.tb_en[tb_idx]) {
if (!acks[tb_idx]) {
int ret = srslte_pdsch_codeword_decode(q, cfg, softbuffers[tb_idx], rnti, data[tb_idx], cw_idx, tb_idx, &acks[tb_idx]);
int ret = SRSLTE_SUCCESS;
if (SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant) > 1 && tb_idx == 0 && q->coworker_ptr) {
srslte_pdsch_coworker_t *h = (srslte_pdsch_coworker_t *) q->coworker_ptr;
h->pdsch_ptr = q;
h->cfg = cfg;
h->softbuffer = softbuffers[tb_idx];
h->rnti = rnti;
h->data = data[tb_idx];
h->cw_idx = cw_idx;
h->tb_idx = tb_idx;
h->ack = &acks[tb_idx];
h->dl_sch.max_iterations = q->dl_sch.max_iterations;
h->started = true;
sem_post(&h->start);
} else {
ret = srslte_pdsch_codeword_decode(q,
cfg,
&q->dl_sch,
softbuffers[tb_idx],
rnti,
data[tb_idx],
cw_idx,
tb_idx,
&acks[tb_idx]);
}
/* Check if there has been any execution error */
if (ret) {
return ret;
/* Do Nothing */
}
}
@ -788,6 +898,21 @@ int srslte_pdsch_decode(srslte_pdsch_t *q,
}
}
if (q->coworker_ptr) {
srslte_pdsch_coworker_t *h = (srslte_pdsch_coworker_t *) q->coworker_ptr;
if (h->started) {
int err = sem_wait(&h->finish);
if (err) {
printf("SCH coworker: %s (nof_tb=%d)\n", strerror(errno), SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant));
}
if (h->ret_status) {
ERROR("PDSCH Coworker Decoder: Error decoding");
}
h->started = false;
}
}
pdsch_decode_debug(q, cfg, sf_symbols, ce);
return SRSLTE_SUCCESS;
@ -945,6 +1070,45 @@ float srslte_pdsch_last_noi(srslte_pdsch_t *q) {
}
}
int srslte_pdsch_enable_coworker(srslte_pdsch_t *q) {
int ret = SRSLTE_SUCCESS;
if (!q->coworker_ptr) {
srslte_pdsch_coworker_t *h = calloc(sizeof(srslte_pdsch_coworker_t), 1);
if (!h) {
ERROR("Allocating coworker");
ret = SRSLTE_ERROR;
goto clean;
}
q->coworker_ptr = h;
if (srslte_sch_init(&h->dl_sch)) {
ERROR("Initiating DL SCH");
ret = SRSLTE_ERROR;
goto clean;
}
if (sem_init(&h->start, 0, 0)) {
ERROR("Creating semaphore");
ret = SRSLTE_ERROR;
goto clean;
}
if (sem_init(&h->finish, 0, 0)) {
ERROR("Creating semaphore");
ret = SRSLTE_ERROR;
goto clean;
}
pthread_create(&h->pthread, NULL, srslte_pdsch_decode_thread, (void *) h);
}
clean:
if (ret) {
srslte_pdsch_disable_coworker(q);
}
return ret;
}
uint32_t srslte_pdsch_last_noi_cw(srslte_pdsch_t *q, uint32_t cw_idx) {
return q->last_nof_iterations[cw_idx];
}

View File

@ -60,6 +60,7 @@ int rv_idx[SRSLTE_MAX_CODEWORDS] = {0, 1};
uint16_t rnti = 1234;
uint32_t nof_rx_antennas = 1;
bool tb_cw_swap = false;
bool enable_coworker = false;
uint32_t pmi = 0;
char *input_file = NULL;
@ -79,12 +80,13 @@ void usage(char *prog) {
printf("\t-a nof_rx_antennas [Default %d]\n", nof_rx_antennas);
printf("\t-p pmi (multiplex only) [Default %d]\n", pmi);
printf("\t-w Swap Transport Blocks\n");
printf("\t-j Enable PDSCH decoder coworker\n");
printf("\t-v [set srslte_verbose to debug, default none]\n");
}
void parse_args(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "fmMcsrtRFpnawvx")) != -1) {
while ((opt = getopt(argc, argv, "fmMcsrtRFpnawvxj")) != -1) {
switch(opt) {
case 'f':
input_file = argv[optind];
@ -129,6 +131,9 @@ void parse_args(int argc, char **argv) {
case 'w':
tb_cw_swap = true;
break;
case 'j':
enable_coworker = true;
break;
case 'v':
srslte_verbose++;
break;
@ -470,6 +475,10 @@ int main(int argc, char **argv) {
int r=0;
srslte_pdsch_set_max_noi(&pdsch_rx, 10);
if (enable_coworker) {
srslte_pdsch_enable_coworker(&pdsch_rx);
}
gettimeofday(&t[1], NULL);
for (k = 0; k < M; k++) {
#ifdef DO_OFDM

View File

@ -45,6 +45,7 @@ typedef struct {
int16_t tx_buffer[CONVERT_BUFFER_SIZE];
bool rx_stream_enabled;
bool tx_stream_enabled;
srslte_rf_info_t info;
} rf_blade_handler_t;
srslte_rf_error_handler_t blade_error_handler = NULL;
@ -220,7 +221,14 @@ int rf_blade_open(char *args, void **h)
return status;
}
handler->rx_stream_enabled = false;
handler->tx_stream_enabled = false;
handler->tx_stream_enabled = false;
/* Set info structure */
handler->info.min_tx_gain = BLADERF_TXVGA2_GAIN_MIN;
handler->info.max_tx_gain = BLADERF_TXVGA2_GAIN_MAX;
handler->info.min_rx_gain = BLADERF_RXVGA2_GAIN_MIN;
handler->info.max_rx_gain = BLADERF_RXVGA2_GAIN_MAX;
return 0;
}
@ -336,6 +344,19 @@ double rf_blade_get_tx_gain(void *h)
return gain; // Add txvga1
}
srslte_rf_info_t *rf_blade_get_info(void *h)
{
srslte_rf_info_t *info = NULL;
if (h) {
rf_blade_handler_t *handler = (rf_blade_handler_t*) h;
info = &handler->info;
}
return info;
}
double rf_blade_set_rx_freq(void *h, double freq)
{
rf_blade_handler_t *handler = (rf_blade_handler_t*) h;

View File

@ -76,6 +76,8 @@ SRSLTE_API double rf_blade_get_rx_gain(void *h);
SRSLTE_API double rf_blade_get_tx_gain(void *h);
SRSLTE_API srslte_rf_info_t *rf_blade_get_info(void *h);
SRSLTE_API void rf_blade_suppress_stdout(void *h);
SRSLTE_API void rf_blade_register_error_handler(void *h,

View File

@ -47,6 +47,7 @@ typedef struct {
double (*srslte_rf_set_tx_gain)(void *h, 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);
double (*srslte_rf_set_rx_freq)(void *h, double freq);
double (*srslte_rf_set_tx_srate)(void *h, double freq);
double (*srslte_rf_set_tx_freq)(void *h, double freq);
@ -93,6 +94,7 @@ static rf_dev_t dev_uhd = {
rf_uhd_set_tx_gain,
rf_uhd_get_rx_gain,
rf_uhd_get_tx_gain,
rf_uhd_get_info,
rf_uhd_set_rx_freq,
rf_uhd_set_tx_srate,
rf_uhd_set_tx_freq,
@ -132,6 +134,7 @@ static rf_dev_t dev_blade = {
rf_blade_set_tx_gain,
rf_blade_get_rx_gain,
rf_blade_get_tx_gain,
rf_blade_get_info,
rf_blade_set_rx_freq,
rf_blade_set_tx_srate,
rf_blade_set_tx_freq,
@ -170,6 +173,7 @@ static rf_dev_t dev_soapy = {
rf_soapy_set_tx_gain,
rf_soapy_get_rx_gain,
rf_soapy_get_tx_gain,
rf_soapy_get_info,
rf_soapy_set_rx_freq,
rf_soapy_set_tx_srate,
rf_soapy_set_tx_freq,

View File

@ -227,6 +227,15 @@ double srslte_rf_get_tx_gain(srslte_rf_t *rf)
return ((rf_dev_t*) rf->dev)->srslte_rf_get_tx_gain(rf->handler);
}
srslte_rf_info_t *srslte_rf_get_info(srslte_rf_t *rf) {
srslte_rf_info_t *ret = NULL;
if (((rf_dev_t*) rf->dev)->srslte_rf_get_info) {
ret = ((rf_dev_t*) rf->dev)->srslte_rf_get_info(rf->handler);
}
return ret;
}
double srslte_rf_set_rx_freq(srslte_rf_t *rf, double freq)
{
return ((rf_dev_t*) rf->dev)->srslte_rf_set_rx_freq(rf->handler, freq);

View File

@ -46,6 +46,7 @@ typedef struct {
SoapySDRStream *txStream;
bool tx_stream_active;
bool rx_stream_active;
srslte_rf_info_t info;
} rf_soapy_handler_t;
@ -259,6 +260,14 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas)
printf(" - %s\n", sensors[i]);
}
/* Set static radio info */
SoapySDRRange tx_range = SoapySDRDevice_getGainRange(handler->device, SOAPY_SDR_TX, 0);
SoapySDRRange rx_range = SoapySDRDevice_getGainRange(handler->device, SOAPY_SDR_RX, 0);
handler->info.min_tx_gain = tx_range.minimum;
handler->info.max_tx_gain = tx_range.maximum;
handler->info.min_rx_gain = rx_range.minimum;
handler->info.max_rx_gain = rx_range.maximum;
return SRSLTE_SUCCESS;
}
@ -361,6 +370,17 @@ double rf_soapy_get_tx_gain(void *h)
}
srslte_rf_info_t * rf_soapy_get_info(void *h)
{
srslte_rf_info_t *info = NULL;
if (h) {
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;
info = &handler->info;
}
return info;
}
double rf_soapy_set_rx_freq(void *h, double freq)
{
rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h;

View File

@ -75,6 +75,8 @@ SRSLTE_API double rf_soapy_set_tx_gain(void *h,
SRSLTE_API double rf_soapy_get_tx_gain(void *h);
SRSLTE_API srslte_rf_info_t *rf_soapy_get_info(void *h);
SRSLTE_API void rf_soapy_suppress_stdout(void *h);
SRSLTE_API void rf_soapy_register_error_handler(void *h, srslte_rf_error_handler_t error_handler);

View File

@ -46,7 +46,7 @@ typedef struct {
uhd_rx_metadata_handle rx_md, rx_md_first;
uhd_tx_metadata_handle tx_md;
uhd_meta_range_handle rx_gain_range;
srslte_rf_info_t info;
size_t rx_nof_samples;
size_t tx_nof_samples;
double tx_rate;
@ -572,9 +572,20 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels)
uhd_rx_streamer_max_num_samps(handler->rx_stream, &handler->rx_nof_samples);
uhd_tx_streamer_max_num_samps(handler->tx_stream, &handler->tx_nof_samples);
uhd_meta_range_make(&handler->rx_gain_range);
uhd_usrp_get_rx_gain_range(handler->usrp, "", 0, handler->rx_gain_range);
uhd_meta_range_handle rx_gain_range = NULL;
uhd_meta_range_make(&rx_gain_range);
uhd_usrp_get_rx_gain_range(handler->usrp, "", 0, rx_gain_range);
uhd_meta_range_start(rx_gain_range, &handler->info.min_rx_gain);
uhd_meta_range_stop(rx_gain_range, &handler->info.max_rx_gain);
uhd_meta_range_free(&rx_gain_range);
uhd_meta_range_handle tx_gain_range = NULL;
uhd_meta_range_make(&tx_gain_range);
uhd_usrp_get_tx_gain_range(handler->usrp, "", 0, tx_gain_range);
uhd_meta_range_start(tx_gain_range, &handler->info.min_tx_gain);
uhd_meta_range_stop(tx_gain_range, &handler->info.max_tx_gain);
uhd_meta_range_free(&tx_gain_range);
// Make metadata objects for RX/TX
uhd_rx_metadata_make(&handler->rx_md);
@ -582,13 +593,7 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels)
uhd_tx_metadata_make(&handler->tx_md, false, 0, 0, false, false);
// Set starting gain to half maximum in case of using AGC
uhd_meta_range_handle gain_range;
uhd_meta_range_make(&gain_range);
uhd_usrp_get_rx_gain_range(handler->usrp, "", 0, gain_range);
double max_gain;
uhd_meta_range_stop(gain_range, &max_gain);
rf_uhd_set_rx_gain(handler, max_gain*0.7);
uhd_meta_range_free(&gain_range);
rf_uhd_set_rx_gain(handler, handler->info.max_tx_gain*0.7);
#if HAVE_ASYNC_THREAD
if (start_async_thread) {
@ -620,7 +625,6 @@ int rf_uhd_close(void *h)
uhd_tx_metadata_free(&handler->tx_md);
uhd_rx_metadata_free(&handler->rx_md_first);
uhd_rx_metadata_free(&handler->rx_md);
uhd_meta_range_free(&handler->rx_gain_range);
handler->async_thread_running = false;
pthread_join(handler->async_thread, NULL);
@ -722,6 +726,16 @@ double rf_uhd_get_tx_gain(void *h)
return gain;
}
srslte_rf_info_t *rf_uhd_get_info(void *h)
{
srslte_rf_info_t *info = NULL;
if (h) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
info = &handler->info;
}
return info;
}
double rf_uhd_set_rx_freq(void *h, double freq)
{
uhd_tune_request_t tune_request = {

View File

@ -81,6 +81,8 @@ SRSLTE_API double rf_uhd_get_rx_gain(void *h);
SRSLTE_API double rf_uhd_get_tx_gain(void *h);
SRSLTE_API srslte_rf_info_t *rf_uhd_get_info(void *h);
SRSLTE_API void rf_uhd_suppress_stdout(void *h);
SRSLTE_API void rf_uhd_register_error_handler(void *h, srslte_rf_error_handler_t error_handler);

View File

@ -140,11 +140,15 @@ void srslte_ue_sync_reset(srslte_ue_sync_t *q) {
q->frame_find_cnt = 0;
}
int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(void*, double), float init_gain_value) {
int srslte_ue_sync_start_agc(srslte_ue_sync_t *q,
double (set_gain_callback)(void *, double),
double min_gain,
double max_gain,
double init_gain_value) {
int n = srslte_agc_init_uhd(&q->agc, SRSLTE_AGC_MODE_PEAK_AMPLITUDE, 0, set_gain_callback, q->stream);
q->do_agc = n==0?true:false;
if (q->do_agc) {
srslte_agc_set_gain_range(&q->agc, min_gain, max_gain);
srslte_agc_set_gain(&q->agc, init_gain_value);
srslte_ue_sync_set_agc_period(q, 4);
}

View File

@ -470,6 +470,9 @@ void radio::register_error_handler(srslte_rf_error_handler_t h)
srslte_rf_register_error_handler(&rf_device, h);
}
srslte_rf_info_t *radio::get_info() {
return srslte_rf_get_info(&rf_device);
}
}

View File

@ -45,6 +45,7 @@ public:
~phch_worker();
void reset();
void set_common(phch_common *phy);
void enable_pdsch_coworker();
bool init(uint32_t max_prb, srslte::log *log, srslte::log *log_phy_lib_h, chest_feedback_itf *chest_loop);
bool set_cell(srslte_cell_t cell);

View File

@ -153,8 +153,9 @@ private:
bool initiated;
uint32_t nof_workers;
const static int MAX_WORKERS = 4;
uint32_t nof_coworkers;
const static int MAX_WORKERS = 3;
const static int DEFAULT_WORKERS = 2;
const static int SF_RECV_THREAD_PRIO = 1;

View File

@ -625,7 +625,12 @@ void phch_recv::set_agc_enable(bool enable)
do_agc = enable;
if (do_agc) {
if (running && radio_h) {
srslte_ue_sync_start_agc(&ue_sync, callback_set_rx_gain, radio_h->get_rx_gain());
srslte_rf_info_t *rf_info = radio_h->get_info();
srslte_ue_sync_start_agc(&ue_sync,
callback_set_rx_gain,
rf_info->min_rx_gain,
rf_info->max_rx_gain,
radio_h->get_rx_gain());
search_p.set_agc_enable(true);
} else {
fprintf(stderr, "Error setting AGC: PHY not initiatec\n");
@ -893,7 +898,12 @@ float phch_recv::search::get_last_cfo()
void phch_recv::search::set_agc_enable(bool enable) {
if (enable) {
srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, p->radio_h->get_rx_gain());
srslte_rf_info_t *rf_info = p->radio_h->get_info();
srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync,
callback_set_rx_gain,
rf_info->min_rx_gain,
rf_info->max_rx_gain,
p->radio_h->get_rx_gain());
} else {
fprintf(stderr, "Error stop AGC not implemented\n");
}

View File

@ -103,6 +103,10 @@ void phch_worker::reset()
rssi_read_cnt = 0;
}
void phch_worker::enable_pdsch_coworker() {
srslte_pdsch_enable_coworker(&ue_dl.pdsch);
}
void phch_worker::set_common(phch_common* phy_)
{
phy = phy_;

View File

@ -104,7 +104,7 @@ void phy::set_default_args(phy_args_t *args)
bool phy::check_args(phy_args_t *args)
{
if (args->nof_phy_threads > 3) {
if (args->nof_phy_threads > MAX_WORKERS * 2) {
log_h->console("Error in PHY args: nof_phy_threads must be 1, 2 or 3\n");
return false;
}
@ -139,6 +139,10 @@ bool phy::init(srslte::radio_multi* radio_handler, mac_interface_phy *mac, rrc_i
}
nof_workers = args->nof_phy_threads;
if (nof_workers > MAX_WORKERS) {
nof_coworkers = SRSLTE_MIN(nof_workers - MAX_WORKERS, MAX_WORKERS);
nof_workers = MAX_WORKERS;
}
this->log_phy_lib_h = (srslte::log*) log_vec[nof_workers];
srslte_phy_log_register_handler(this, srslte_phy_handler);
@ -160,6 +164,10 @@ void phy::run_thread() {
workers_pool.init_worker(i, &workers[i], WORKERS_THREAD_PRIO, args->worker_cpu_mask);
}
for (uint32_t i=0;i<nof_coworkers;i++) {
workers[i].enable_pdsch_coworker();
}
// Warning this must be initialized after all workers have been added to the pool
sf_recv.init(radio_handler, mac, rrc, &prach_buffer, &workers_pool, &workers_common, log_h, log_phy_lib_h, args->nof_rx_ant, SF_RECV_THREAD_PRIO, args->sync_cpu_affinity);

View File

@ -55,6 +55,11 @@ ue::~ue()
bool ue::init(all_args_t *args_) {
args = args_;
int nof_phy_threads = args->expert.phy.nof_phy_threads;
if (nof_phy_threads > 3) {
nof_phy_threads = 3;
}
if (!args->log.filename.compare("stdout")) {
logger = &logger_stdout;
} else {
@ -66,7 +71,7 @@ bool ue::init(all_args_t *args_) {
rf_log.init("RF ", logger);
// Create array of pointers to phy_logs
for (int i=0;i<args->expert.phy.nof_phy_threads;i++) {
for (int i=0;i<nof_phy_threads;i++) {
srslte::log_filter *mylog = new srslte::log_filter;
char tmp[16];
sprintf(tmp, "PHY%d",i);
@ -85,7 +90,7 @@ bool ue::init(all_args_t *args_) {
// Init logs
rf_log.set_level(srslte::LOG_LEVEL_INFO);
rf_log.info("Starting UE\n");
for (int i=0;i<args->expert.phy.nof_phy_threads;i++) {
for (int i=0;i<nof_phy_threads;i++) {
((srslte::log_filter*) phy_log[i])->set_level(level(args->log.phy_level));
}
@ -95,7 +100,7 @@ bool ue::init(all_args_t *args_) {
sprintf(tmp, "PHY_LIB");
lib_log->init(tmp, logger, true);
phy_log.push_back(lib_log);
((srslte::log_filter*) phy_log[args->expert.phy.nof_phy_threads])->set_level(level(args->log.phy_lib_level));
((srslte::log_filter*) phy_log[nof_phy_threads])->set_level(level(args->log.phy_lib_level));
mac_log.set_level(level(args->log.mac_level));
@ -106,7 +111,7 @@ bool ue::init(all_args_t *args_) {
gw_log.set_level(level(args->log.gw_level));
usim_log.set_level(level(args->log.usim_level));
for (int i=0;i<args->expert.phy.nof_phy_threads + 1;i++) {
for (int i=0;i<nof_phy_threads + 1;i++) {
((srslte::log_filter*) phy_log[i])->set_hex_limit(args->log.phy_hex_limit);
}
mac_log.set_hex_limit(args->log.mac_hex_limit);