mirror of https://github.com/PentHertz/srsLTE.git
Merge branch 'next' of github.com:softwareradiosystems/srsLTE into next
This commit is contained in:
commit
a75604eb0e
|
@ -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++) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue