Added bladeRF API skeleton. Moved uhd code into rf_uhd

master
ismagom 9 years ago
parent ba5b14ee3d
commit 96f7639ea0

@ -53,23 +53,23 @@ typedef struct {
int nof_subframes;
bool disable_plots;
int force_N_id_2;
char *uhd_args;
float uhd_freq;
float uhd_gain;
char *rf_args;
float rf_freq;
float rf_gain;
}prog_args_t;
void args_default(prog_args_t *args) {
args->nof_subframes = -1;
args->force_N_id_2 = -1; // Pick the best
args->uhd_args = "";
args->uhd_freq = -1.0;
args->uhd_gain = 50;
args->rf_args = "";
args->rf_freq = -1.0;
args->rf_gain = 50;
}
void usage(prog_args_t *args, char *prog) {
printf("Usage: %s [aglnv] -f rx_frequency (in Hz)\n", prog);
printf("\t-a UHD args [Default %s]\n", args->uhd_args);
printf("\t-g UHD RX gain [Default %.2f dB]\n", args->uhd_gain);
printf("\t-a RF args [Default %s]\n", args->rf_args);
printf("\t-g RF RX gain [Default %.2f dB]\n", args->rf_gain);
printf("\t-l Force N_id_2 [Default best]\n");
printf("\t-n nof_subframes [Default %d]\n", args->nof_subframes);
printf("\t-v [set srslte_verbose to debug, default none]\n");
@ -81,13 +81,13 @@ int parse_args(prog_args_t *args, int argc, char **argv) {
while ((opt = getopt(argc, argv, "aglnvf")) != -1) {
switch (opt) {
case 'a':
args->uhd_args = argv[optind];
args->rf_args = argv[optind];
break;
case 'g':
args->uhd_gain = atof(argv[optind]);
args->rf_gain = atof(argv[optind]);
break;
case 'f':
args->uhd_freq = atof(argv[optind]);
args->rf_freq = atof(argv[optind]);
break;
case 'n':
args->nof_subframes = atoi(argv[optind]);
@ -103,7 +103,7 @@ int parse_args(prog_args_t *args, int argc, char **argv) {
return -1;
}
}
if (args->uhd_freq < 0) {
if (args->rf_freq < 0) {
usage(args, argv[0]);
return -1;
}
@ -141,7 +141,7 @@ int main(int argc, char **argv) {
int64_t sf_cnt;
srslte_ue_sync_t ue_sync;
srslte_ue_mib_t ue_mib;
void *uhd;
rf_t rf;
srslte_ue_dl_t ue_dl;
srslte_ofdm_t fft;
srslte_chest_dl_t chest;
@ -158,20 +158,20 @@ int main(int argc, char **argv) {
exit(-1);
}
if (prog_args.uhd_gain > 0) {
printf("Opening UHD device...\n");
if (rf_open(prog_args.uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
if (prog_args.rf_gain > 0) {
printf("Opening RF device...\n");
if (rf_open(&rf, prog_args.rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_rx_gain(uhd, prog_args.uhd_gain);
rf_set_rx_gain(&rf, prog_args.rf_gain);
} else {
printf("Opening UHD device with threaded RX Gain control ...\n");
if (rf_open_th(prog_args.uhd_args, &uhd, false)) {
fprintf(stderr, "Error opening uhd\n");
printf("Opening RF device with threaded RX Gain control ...\n");
if (rf_open_th(&rf, prog_args.rf_args, false)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_rx_gain(uhd, 50);
rf_set_rx_gain(&rf, 50);
}
sigset_t sigset;
@ -180,16 +180,16 @@ int main(int argc, char **argv) {
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
signal(SIGINT, sig_int_handler);
rf_set_master_clock_rate(uhd, 30.72e6);
rf_set_master_clock_rate(&rf, 30.72e6);
/* set receiver frequency */
rf_set_rx_freq(uhd, (double) prog_args.uhd_freq);
rf_rx_wait_lo_locked(uhd);
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000);
rf_set_rx_freq(&rf, (double) prog_args.rf_freq);
rf_rx_wait_lo_locked(&rf);
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.rf_freq/1000000);
uint32_t ntrial=0;
do {
ret = rf_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell);
ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell);
if (ret < 0) {
fprintf(stderr, "Error searching for cell\n");
exit(-1);
@ -206,13 +206,13 @@ int main(int argc, char **argv) {
int srate = srslte_sampling_freq_hz(cell.nof_prb);
if (srate != -1) {
if (srate < 10e6) {
rf_set_master_clock_rate(uhd, 4*srate);
rf_set_master_clock_rate(&rf, 4*srate);
} else {
rf_set_master_clock_rate(uhd, srate);
rf_set_master_clock_rate(&rf, srate);
}
printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000);
float srate_uhd = rf_set_rx_srate(uhd, (double) srate);
if (srate_uhd != srate) {
float srate_rf = rf_set_rx_srate(&rf, (double) srate);
if (srate_rf != srate) {
fprintf(stderr, "Could not set sampling rate\n");
exit(-1);
}
@ -221,11 +221,11 @@ int main(int argc, char **argv) {
exit(-1);
}
INFO("Stopping UHD and flushing buffer...\n",0);
rf_stop_rx_stream(uhd);
rf_flush_buffer(uhd);
INFO("Stopping RF and flushing buffer...\n",0);
rf_stop_rx_stream(&rf);
rf_flush_buffer(&rf);
if (srslte_ue_sync_init(&ue_sync, cell, rf_recv_wrapper, uhd)) {
if (srslte_ue_sync_init(&ue_sync, cell, rf_recv_wrapper, (void*) &rf)) {
fprintf(stderr, "Error initiating ue_sync\n");
return -1;
}
@ -261,7 +261,7 @@ int main(int argc, char **argv) {
ce[i] = srslte_vec_malloc(sizeof(cf_t) * sf_re);
}
rf_start_rx_stream(uhd);
rf_start_rx_stream(&rf);
float rx_gain_offset = 0;
@ -333,10 +333,10 @@ int main(int argc, char **argv) {
if ((nframes%100) == 0 || rx_gain_offset == 0) {
if (rf_has_rssi(uhd)) {
rx_gain_offset = 10*log10(rssi)-rf_get_rssi(uhd);
if (rf_has_rssi(&rf)) {
rx_gain_offset = 10*log10(rssi)-rf_get_rssi(&rf);
} else {
rx_gain_offset = rf_get_rx_gain(uhd);
rx_gain_offset = rf_get_rx_gain(&rf);
}
}
@ -373,7 +373,7 @@ int main(int argc, char **argv) {
} // Main loop
srslte_ue_sync_free(&ue_sync);
rf_close(uhd);
rf_close(&rf);
printf("\nBye\n");
exit(0);
}

@ -70,13 +70,13 @@ struct cells {
};
struct cells results[1024];
float uhd_gain = 70.0;
char *uhd_args="";
float rf_gain = 70.0;
char *rf_args="";
void usage(char *prog) {
printf("Usage: %s [agsendtvb] -b band\n", prog);
printf("\t-a UHD args [Default %s]\n", uhd_args);
printf("\t-g UHD gain [Default %.2f dB]\n", uhd_gain);
printf("\t-a RF args [Default %s]\n", rf_args);
printf("\t-g RF gain [Default %.2f dB]\n", rf_gain);
printf("\t-s earfcn_start [Default All]\n");
printf("\t-e earfcn_end [Default All]\n");
printf("\t-n nof_frames_total [Default 100]\n");
@ -89,7 +89,7 @@ void parse_args(int argc, char **argv) {
while ((opt = getopt(argc, argv, "agsendtvb")) != -1) {
switch(opt) {
case 'a':
uhd_args = argv[optind];
rf_args = argv[optind];
break;
case 'b':
band = atoi(argv[optind]);
@ -107,7 +107,7 @@ void parse_args(int argc, char **argv) {
config.threshold = atof(argv[optind]);
break;
case 'g':
uhd_gain = atof(argv[optind]);
rf_gain = atof(argv[optind]);
break;
case 'v':
srslte_verbose++;
@ -125,7 +125,7 @@ void parse_args(int argc, char **argv) {
int rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) {
DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return rf_recv(h, data, nsamples, 1);
return rf_recv((rf_t*) h, data, nsamples, 1);
}
bool go_exit = false;
@ -138,9 +138,13 @@ void sig_int_handler(int signo)
}
}
double rf_set_rx_gain_wrapper(void *h, double f) {
return rf_set_rx_gain((rf_t*) h, f);
}
int main(int argc, char **argv) {
int n;
void *uhd;
rf_t rf;
srslte_ue_cellsearch_t cs;
srslte_ue_cellsearch_result_t found_cells[3];
int nof_freqs;
@ -151,25 +155,25 @@ int main(int argc, char **argv) {
parse_args(argc, argv);
if (!config.init_agc) {
printf("Opening UHD device...\n");
if (rf_open(uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
printf("Opening RF device...\n");
if (rf_open(&rf, rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_rx_gain(uhd, uhd_gain);
rf_set_rx_gain(&rf, rf_gain);
} else {
printf("Opening UHD device with threaded RX Gain control ...\n");
if (rf_open_th(uhd_args, &uhd, false)) {
fprintf(stderr, "Error opening uhd\n");
printf("Opening RF device with threaded RX Gain control ...\n");
if (rf_open_th(&rf, rf_args, false)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_rx_gain(uhd, 50);
rf_set_rx_gain(&rf, 50);
}
rf_set_master_clock_rate(uhd, 30.72e6);
rf_set_master_clock_rate(&rf, 30.72e6);
// Supress UHD messages
rf_suppress_stdout();
// Supress RF messages
rf_suppress_stdout(&rf);
nof_freqs = srslte_band_get_fd_band(band, channels, earfcn_start, earfcn_end, MAX_EARFCN);
if (nof_freqs < 0) {
@ -185,10 +189,10 @@ int main(int argc, char **argv) {
for (freq=0;freq<nof_freqs && !go_exit;freq++) {
/* set uhd_freq */
rf_set_rx_freq(uhd, (double) channels[freq].fd * MHZ);
rf_rx_wait_lo_locked(uhd);
INFO("Set uhd_freq to %.3f MHz\n", (double) channels[freq].fd * MHZ/1000000);
/* set rf_freq */
rf_set_rx_freq(&rf, (double) channels[freq].fd * MHZ);
rf_rx_wait_lo_locked(&rf);
INFO("Set rf_freq to %.3f MHz\n", (double) channels[freq].fd * MHZ/1000000);
printf("[%3d/%d]: EARFCN %d Freq. %.2f MHz looking for PSS.\n", freq, nof_freqs,
channels[freq].id, channels[freq].fd);fflush(stdout);
@ -199,7 +203,7 @@ int main(int argc, char **argv) {
bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t));
if (srslte_ue_cellsearch_init(&cs, rf_recv_wrapper, uhd)) {
if (srslte_ue_cellsearch_init(&cs, rf_recv_wrapper, (void*) &rf)) {
fprintf(stderr, "Error initiating UE cell detect\n");
exit(-1);
}
@ -211,13 +215,13 @@ int main(int argc, char **argv) {
srslte_ue_cellsearch_set_threshold(&cs, config.threshold);
}
if (config.init_agc) {
srslte_ue_sync_start_agc(&cs.ue_sync, rf_set_rx_gain, config.init_agc);
srslte_ue_sync_start_agc(&cs.ue_sync, rf_set_rx_gain_wrapper, config.init_agc);
}
INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000);
rf_set_rx_srate(uhd, SRSLTE_CS_SAMP_FREQ);
rf_set_rx_srate(&rf, SRSLTE_CS_SAMP_FREQ);
INFO("Starting receiver...\n", 0);
rf_start_rx_stream(uhd);
rf_start_rx_stream(&rf);
n = srslte_ue_cellsearch_scan(&cs, found_cells, NULL);
if (n < 0) {
@ -229,7 +233,7 @@ int main(int argc, char **argv) {
srslte_cell_t cell;
cell.id = found_cells[i].cell_id;
cell.cp = found_cells[i].cp;
int ret = rf_mib_decoder(uhd, &config, &cell);
int ret = rf_mib_decoder(&rf, &config, &cell);
if (ret < 0) {
fprintf(stderr, "Error decoding MIB\n");
exit(-1);
@ -266,7 +270,7 @@ int main(int argc, char **argv) {
printf("\nBye\n");
rf_close(uhd);
rf_close(&rf);
exit(0);
}

@ -42,9 +42,9 @@
#ifndef DISABLE_RF
#include "srslte/rf/rf.h"
void *uhd;
rf_t rf;
#else
#warning Compiling pdsch_ue with no UHD support
#warning Compiling pdsch_ue with no RF support
#endif
char *output_file_name = NULL;
@ -70,8 +70,8 @@ uint32_t cfi=2;
uint32_t mcs_idx = 1, last_mcs_idx = 1;
int nof_frames = -1;
char *uhd_args = "";
float uhd_amp = 0.8, uhd_gain = 70.0, uhd_freq = 2400000000;
char *rf_args = "";
float rf_amp = 0.8, rf_gain = 70.0, rf_freq = 2400000000;
bool null_file_sink=false;
srslte_filesink_t fsink;
@ -102,14 +102,14 @@ int prbset_orig = 0;
void usage(char *prog) {
printf("Usage: %s [agmfoncvpu]\n", prog);
#ifndef DISABLE_RF
printf("\t-a UHD args [Default %s]\n", uhd_args);
printf("\t-l UHD amplitude [Default %.2f]\n", uhd_amp);
printf("\t-g UHD TX gain [Default %.2f dB]\n", uhd_gain);
printf("\t-f UHD TX frequency [Default %.1f MHz]\n", uhd_freq / 1000000);
printf("\t-a RF args [Default %s]\n", rf_args);
printf("\t-l RF amplitude [Default %.2f]\n", rf_amp);
printf("\t-g RF TX gain [Default %.2f dB]\n", rf_gain);
printf("\t-f RF TX frequency [Default %.1f MHz]\n", rf_freq / 1000000);
#else
printf("\t UHD is disabled. CUHD library not available\n");
printf("\t RF is disabled.\n");
#endif
printf("\t-o output_file [Default USRP]\n");
printf("\t-o output_file [Default use RF board]\n");
printf("\t-m MCS index [Default %d]\n", mcs_idx);
printf("\t-n number of frames [Default %d]\n", nof_frames);
printf("\t-c cell id [Default %d]\n", cell.id);
@ -123,16 +123,16 @@ void parse_args(int argc, char **argv) {
while ((opt = getopt(argc, argv, "aglfmoncpvu")) != -1) {
switch (opt) {
case 'a':
uhd_args = argv[optind];
rf_args = argv[optind];
break;
case 'g':
uhd_gain = atof(argv[optind]);
rf_gain = atof(argv[optind]);
break;
case 'l':
uhd_amp = atof(argv[optind]);
rf_amp = atof(argv[optind]);
break;
case 'f':
uhd_freq = atof(argv[optind]);
rf_freq = atof(argv[optind]);
break;
case 'o':
output_file_name = argv[optind];
@ -171,12 +171,12 @@ void parse_args(int argc, char **argv) {
void base_init() {
/* init memory */
sf_buffer = malloc(sizeof(cf_t) * sf_n_re);
sf_buffer = srslte_vec_malloc(sizeof(cf_t) * sf_n_re);
if (!sf_buffer) {
perror("malloc");
exit(-1);
}
output_buffer = malloc(sizeof(cf_t) * sf_n_samples);
output_buffer = srslte_vec_malloc(sizeof(cf_t) * sf_n_samples);
if (!output_buffer) {
perror("malloc");
exit(-1);
@ -194,13 +194,13 @@ void base_init() {
}
} else {
#ifndef DISABLE_RF
printf("Opening UHD device...\n");
if (rf_open(uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
printf("Opening RF device...\n");
if (rf_open(&rf, rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
#else
printf("Error UHD not available. Select an output file\n");
printf("Error RF not available. Select an output file\n");
exit(-1);
#endif
}
@ -288,7 +288,7 @@ void base_free() {
}
} else {
#ifndef DISABLE_RF
rf_close(&uhd);
rf_close(&rf);
#endif
}
@ -516,13 +516,13 @@ int main(int argc, char **argv) {
int srate = srslte_sampling_freq_hz(cell.nof_prb);
if (srate != -1) {
if (srate < 10e6) {
rf_set_master_clock_rate(uhd, 4*srate);
rf_set_master_clock_rate(&rf, 4*srate);
} else {
rf_set_master_clock_rate(uhd, srate);
rf_set_master_clock_rate(&rf, srate);
}
printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000);
float srate_uhd = rf_set_tx_srate(uhd, (double) srate);
if (srate_uhd != srate) {
float srate_rf = rf_set_tx_srate(&rf, (double) srate);
if (srate_rf != srate) {
fprintf(stderr, "Could not set sampling rate\n");
exit(-1);
}
@ -530,9 +530,9 @@ int main(int argc, char **argv) {
fprintf(stderr, "Invalid number of PRB %d\n", cell.nof_prb);
exit(-1);
}
printf("Set TX gain: %.1f dB\n", rf_set_tx_gain(uhd, uhd_gain));
printf("Set TX gain: %.1f dB\n", rf_set_tx_gain(&rf, rf_gain));
printf("Set TX freq: %.2f MHz\n",
rf_set_tx_freq(uhd, uhd_freq) / 1000000);
rf_set_tx_freq(&rf, rf_freq) / 1000000);
}
#endif
@ -645,8 +645,8 @@ int main(int argc, char **argv) {
#ifndef DISABLE_RF
// FIXME
float norm_factor = (float) cell.nof_prb/15/sqrtf(pdsch_cfg.grant.nof_prb);
srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
rf_send2(uhd, output_buffer, sf_n_samples, true, start_of_burst, false);
srslte_vec_sc_prod_cfc(output_buffer, rf_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
rf_send2(&rf, output_buffer, sf_n_samples, true, start_of_burst, false);
start_of_burst=false;
#endif
}

@ -84,9 +84,9 @@ typedef struct {
uint32_t file_nof_prb;
uint32_t file_nof_ports;
uint32_t file_cell_id;
char *uhd_args;
float uhd_freq;
float uhd_gain;
char *rf_args;
float rf_freq;
float rf_gain;
int net_port;
char *net_address;
int net_port_signal;
@ -107,9 +107,9 @@ void args_default(prog_args_t *args) {
args->file_cell_id = 0;
args->file_offset_time = 0;
args->file_offset_freq = 0;
args->uhd_args = "";
args->uhd_freq = -1.0;
args->uhd_gain = -1.0;
args->rf_args = "";
args->rf_freq = -1.0;
args->rf_gain = -1.0;
args->net_port = -1;
args->net_address = "127.0.0.1";
args->net_port_signal = -1;
@ -119,12 +119,12 @@ void args_default(prog_args_t *args) {
void usage(prog_args_t *args, char *prog) {
printf("Usage: %s [agpPoOcildDnruv] -f rx_frequency (in Hz) | -i input_file\n", prog);
#ifndef DISABLE_RF
printf("\t-a UHD args [Default %s]\n", args->uhd_args);
printf("\t-g UHD fix RX gain [Default AGC]\n");
printf("\t-a RF args [Default %s]\n", args->rf_args);
printf("\t-g RF fix RX gain [Default AGC]\n");
#else
printf("\t UHD is disabled. CUHD library not available\n");
printf("\t RF is disabled.\n");
#endif
printf("\t-i input_file [Default USRP]\n");
printf("\t-i input_file [Default use RF board]\n");
printf("\t-o offset frequency correction (in Hz) for input file [Default %.1f Hz]\n", args->file_offset_freq);
printf("\t-O offset samples for input file [Default %d]\n", args->file_offset_time);
printf("\t-p nof_prb for input file [Default %d]\n", args->file_nof_prb);
@ -172,10 +172,10 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
args->file_cell_id = atoi(argv[optind]);
break;
case 'a':
args->uhd_args = argv[optind];
args->rf_args = argv[optind];
break;
case 'g':
args->uhd_gain = atof(argv[optind]);
args->rf_gain = atof(argv[optind]);
break;
case 'C':
args->disable_cfo = true;
@ -184,7 +184,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
args->time_offset = atoi(argv[optind]);
break;
case 'f':
args->uhd_freq = atof(argv[optind]);
args->rf_freq = atof(argv[optind]);
break;
case 'n':
args->nof_subframes = atoi(argv[optind]);
@ -221,7 +221,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) {
exit(-1);
}
}
if (args->uhd_freq < 0 && args->input_file_name == NULL) {
if (args->rf_freq < 0 && args->input_file_name == NULL) {
usage(args, argv[0]);
exit(-1);
}
@ -245,6 +245,11 @@ int rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *
DEBUG(" ---- Receive %d samples ---- \n", nsamples);
return rf_recv(h, data, nsamples, 1);
}
double rf_set_rx_gain_th_wrapper(void *h, double f) {
return rf_set_rx_gain_th((rf_t*) h, f);
}
#endif
extern float mean_exec_time;
@ -265,7 +270,7 @@ int main(int argc, char **argv) {
int64_t sf_cnt;
srslte_ue_mib_t ue_mib;
#ifndef DISABLE_RF
void *uhd;
rf_t rf;
#endif
uint32_t nof_trials = 0;
int n;
@ -294,20 +299,20 @@ int main(int argc, char **argv) {
if (!prog_args.input_file_name) {
/* Set receiver gain */
if (prog_args.uhd_gain > 0) {
if (prog_args.rf_gain > 0) {
printf("Opening UHD device...\n");
if (rf_open(prog_args.uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
if (rf_open(&rf, prog_args.rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_rx_gain(uhd, prog_args.uhd_gain);
rf_set_rx_gain(&rf, prog_args.rf_gain);
} else {
printf("Opening UHD device with threaded RX Gain control ...\n");
if (rf_open_th(prog_args.uhd_args, &uhd, false)) {
fprintf(stderr, "Error opening uhd\n");
if (rf_open_th(&rf, prog_args.rf_args, false)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_rx_gain(uhd, 50);
rf_set_rx_gain(&rf, 50);
cell_detect_config.init_agc = 50;
}
@ -317,16 +322,16 @@ int main(int argc, char **argv) {
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
signal(SIGINT, sig_int_handler);
rf_set_master_clock_rate(uhd, 30.72e6);
rf_set_master_clock_rate(&rf, 30.72e6);
/* set receiver frequency */
rf_set_rx_freq(uhd, (double) prog_args.uhd_freq);
rf_rx_wait_lo_locked(uhd);
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000);
rf_set_rx_freq(&rf, (double) prog_args.rf_freq);
rf_rx_wait_lo_locked(&rf);
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.rf_freq/1000000);
uint32_t ntrial=0;
do {
ret = rf_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell);
ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell);
if (ret < 0) {
fprintf(stderr, "Error searching for cell\n");
exit(-1);
@ -342,13 +347,13 @@ int main(int argc, char **argv) {
int srate = srslte_sampling_freq_hz(cell.nof_prb);
if (srate != -1) {
if (srate < 10e6) {
rf_set_master_clock_rate(uhd, 4*srate);
rf_set_master_clock_rate(&rf, 4*srate);
} else {
rf_set_master_clock_rate(uhd, srate);
rf_set_master_clock_rate(&rf, srate);
}
printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000);
float srate_uhd = rf_set_rx_srate(uhd, (double) srate);
if (srate_uhd != srate) {
float srate_rf = rf_set_rx_srate(&rf, (double) srate);
if (srate_rf != srate) {
fprintf(stderr, "Could not set sampling rate\n");
exit(-1);
}
@ -358,8 +363,8 @@ int main(int argc, char **argv) {
}
INFO("Stopping UHD and flushing buffer...\r",0);
rf_stop_rx_stream(uhd);
rf_flush_buffer(uhd);
rf_stop_rx_stream(&rf);
rf_flush_buffer(&rf);
}
#endif
@ -381,7 +386,7 @@ int main(int argc, char **argv) {
} else {
#ifndef DISABLE_RF
if (srslte_ue_sync_init(&ue_sync, cell, rf_recv_wrapper, uhd)) {
if (srslte_ue_sync_init(&ue_sync, cell, rf_recv_wrapper, (void*) &rf)) {
fprintf(stderr, "Error initiating ue_sync\n");
exit(-1);
}
@ -415,7 +420,7 @@ int main(int argc, char **argv) {
#ifndef DISABLE_RF
if (!prog_args.input_file_name) {
rf_start_rx_stream(uhd);
rf_start_rx_stream(&rf);
}
#endif
@ -425,8 +430,8 @@ int main(int argc, char **argv) {
bool decode_pdsch = false;
#ifndef DISABLE_RF
if (prog_args.uhd_gain < 0) {
srslte_ue_sync_start_agc(&ue_sync, rf_set_rx_gain_th, cell_detect_config.init_agc);
if (prog_args.rf_gain < 0) {
srslte_ue_sync_start_agc(&ue_sync, rf_set_rx_gain_th_wrapper, cell_detect_config.init_agc);
}
#endif
#ifdef PRINT_CHANGE_SCHEDULIGN
@ -531,7 +536,7 @@ int main(int argc, char **argv) {
// Plot and Printf
if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) {
float gain = prog_args.uhd_gain;
float gain = prog_args.rf_gain;
if (gain < 0) {
gain = 10*log10(srslte_agc_get_gain(&ue_sync.agc));
}
@ -592,7 +597,7 @@ int main(int argc, char **argv) {
#ifndef DISABLE_RF
if (!prog_args.input_file_name) {
srslte_ue_mib_free(&ue_mib);
rf_close(uhd);
rf_close(&rf);
}
#endif
printf("\nBye\n");

@ -47,8 +47,8 @@ void do_plots_sss(float *corr_m0, float *corr_m1);
bool disable_plots = false;
int cell_id = -1;
char *uhd_args="";
float uhd_gain=40.0, uhd_freq=-1.0;
char *rf_args="";
float rf_gain=40.0, rf_freq=-1.0;
int nof_frames = -1;
uint32_t fft_size=128;
float threshold = 0.4;
@ -57,8 +57,8 @@ srslte_cp_t cp=SRSLTE_CP_NORM;
void usage(char *prog) {
printf("Usage: %s [aedgtvnp] -f rx_frequency_hz -i cell_id\n", prog);
printf("\t-a UHD args [Default %s]\n", uhd_args);
printf("\t-g UHD Gain [Default %.2f dB]\n", uhd_gain);
printf("\t-a RF args [Default %s]\n", rf_args);
printf("\t-g RF Gain [Default %.2f dB]\n", rf_gain);
printf("\t-n nof_frames [Default %d]\n", nof_frames);
printf("\t-l N_id_2 to sync [Default use cell_id]\n");
printf("\t-e Extended CP [Default Normal]\n", fft_size);
@ -77,13 +77,13 @@ void parse_args(int argc, char **argv) {
while ((opt = getopt(argc, argv, "adgetvsfil")) != -1) {
switch (opt) {
case 'a':
uhd_args = argv[optind];
rf_args = argv[optind];
break;
case 'g':
uhd_gain = atof(argv[optind]);
rf_gain = atof(argv[optind]);
break;
case 'f':
uhd_freq = atof(argv[optind]);
rf_freq = atof(argv[optind]);
break;
case 't':
threshold = atof(argv[optind]);
@ -114,7 +114,7 @@ void parse_args(int argc, char **argv) {
exit(-1);
}
}
if (cell_id < 0 || uhd_freq < 0) {
if (cell_id < 0 || rf_freq < 0) {
usage(argv[0]);
exit(-1);
}
@ -124,7 +124,7 @@ void parse_args(int argc, char **argv) {
int main(int argc, char **argv) {
cf_t *buffer;
int frame_cnt, n;
void *uhd;
rf_t rf;
srslte_pss_synch_t pss;
srslte_cfo_t cfocorr, cfocorr64;
srslte_sss_synch_t sss;
@ -176,17 +176,17 @@ int main(int argc, char **argv) {
srslte_sss_synch_set_N_id_2(&sss, N_id_2);
printf("Opening UHD device...\n");
if (rf_open(uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
printf("Opening RF device...\n");
if (rf_open(&rf, rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
printf("N_id_2: %d\n", N_id_2);
printf("Set RX rate: %.2f MHz\n", rf_set_rx_srate(uhd, flen*2*100) / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(uhd, uhd_gain));
printf("Set RX freq: %.2f MHz\n", rf_set_rx_freq(uhd, uhd_freq) / 1000000);
rf_rx_wait_lo_locked(uhd);
rf_start_rx_stream(uhd);
printf("Set RX rate: %.2f MHz\n", rf_set_rx_srate(&rf, flen*2*100) / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(&rf, rf_gain));
printf("Set RX freq: %.2f MHz\n", rf_set_rx_freq(&rf, rf_freq) / 1000000);
rf_rx_wait_lo_locked(&rf);
rf_start_rx_stream(&rf);
printf("Frame length %d samples\n", flen);
printf("PSS detection threshold: %.2f\n", threshold);
@ -208,7 +208,7 @@ int main(int argc, char **argv) {
while(frame_cnt < nof_frames || nof_frames == -1) {
peak_offset = 0;
n = rf_recv(uhd, buffer, flen - peak_offset, 1);
n = rf_recv(&rf, buffer, flen - peak_offset, 1);
if (n < 0) {
fprintf(stderr, "Error receiving samples\n");
exit(-1);
@ -320,7 +320,7 @@ int main(int argc, char **argv) {
srslte_pss_synch_free(&pss);
free(buffer);
rf_close(uhd);
rf_close(&rf);
printf("Ok\n");
exit(0);

@ -35,8 +35,8 @@
#include "srslte/srslte.h"
#include "srslte/cuhd/cuhd.h"
void *uhd;
#include "srslte/rf/rf.h"
rf_t rf;
char *output_file_name = NULL;
@ -50,8 +50,8 @@ srslte_cell_t cell = {
};
char *uhd_args = "";
float uhd_amp = 0.5, uhd_gain = 30.0, uhd_freq = 2400000000;
char *rf_args = "";
float rf_amp = 0.5, rf_gain = 30.0, rf_freq = 2400000000;
bool null_file_sink=false;
srslte_filesink_t fsink;
@ -64,10 +64,10 @@ cf_t *sf_buffer = NULL, *output_buffer = NULL;
void usage(char *prog) {
printf("Usage: %s [algfmv]\n", prog);
printf("\t-a UHD args [Default %s]\n", uhd_args);
printf("\t-l UHD amplitude [Default %.2f]\n", uhd_amp);
printf("\t-g UHD TX gain [Default %.2f dB]\n", uhd_gain);
printf("\t-f UHD TX frequency [Default %.1f MHz]\n", uhd_freq / 1000000);
printf("\t-a RF args [Default %s]\n", rf_args);
printf("\t-l RF amplitude [Default %.2f]\n", rf_amp);
printf("\t-g RF TX gain [Default %.2f dB]\n", rf_gain);
printf("\t-f RF TX frequency [Default %.1f MHz]\n", rf_freq / 1000000);
printf("\t-m modulation (1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64) [Default BPSK]\n");
printf("\t-v [set srslte_verbose to debug, default none]\n");
}
@ -77,16 +77,16 @@ void parse_args(int argc, char **argv) {
while ((opt = getopt(argc, argv, "algfmv")) != -1) {
switch (opt) {
case 'a':
uhd_args = argv[optind];
rf_args = argv[optind];
break;
case 'g':
uhd_gain = atof(argv[optind]);
rf_gain = atof(argv[optind]);
break;
case 'l':
uhd_amp = atof(argv[optind]);
rf_amp = atof(argv[optind]);
break;
case 'f':
uhd_freq = atof(argv[optind]);
rf_freq = atof(argv[optind]);
break;
case 'm':
switch(atoi(argv[optind])) {
@ -137,9 +137,9 @@ void base_init() {
perror("malloc");
exit(-1);
}
printf("Opening UHD device...\n");
if (rf_open(uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
printf("Opening RF device...\n");
if (rf_open(&rf, rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
@ -161,7 +161,7 @@ void base_free() {
if (output_buffer) {
free(output_buffer);
}
rf_close(&uhd);
rf_close(&rf);
}
@ -196,10 +196,10 @@ int main(int argc, char **argv) {
srslte_sss_generate(sss_signal0, sss_signal5, cell.id);
printf("Set TX rate: %.2f MHz\n",
rf_set_tx_srate(uhd, srslte_sampling_freq_hz(cell.nof_prb)) / 1000000);
printf("Set TX gain: %.1f dB\n", rf_set_tx_gain(uhd, uhd_gain));
rf_set_tx_srate(&rf, srslte_sampling_freq_hz(cell.nof_prb)) / 1000000);
printf("Set TX gain: %.1f dB\n", rf_set_tx_gain(&rf, rf_gain));
printf("Set TX freq: %.2f MHz\n",
rf_set_tx_freq(uhd, uhd_freq) / 1000000);
rf_set_tx_freq(&rf, rf_freq) / 1000000);
uint32_t nbits;
@ -234,7 +234,7 @@ int main(int argc, char **argv) {
srslte_ofdm_tx_sf(&ifft, sf_buffer, output_buffer);
float norm_factor = (float) sqrtf(cell.nof_prb)/15;
srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
srslte_vec_sc_prod_cfc(output_buffer, rf_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb));
} else {
#endif
@ -248,8 +248,8 @@ int main(int argc, char **argv) {
// }
/* send to usrp */
srslte_vec_sc_prod_cfc(output_buffer, uhd_amp, output_buffer, sf_n_samples);
rf_send(uhd, output_buffer, sf_n_samples, true);
srslte_vec_sc_prod_cfc(output_buffer, rf_amp, output_buffer, sf_n_samples);
rf_send(&rf, output_buffer, sf_n_samples, true);
}
}

@ -41,8 +41,8 @@
static bool keep_running = true;
char *output_file_name;
char *uhd_args="";
float uhd_gain=40.0, uhd_freq=-1.0, uhd_rate=0.96e6;
char *rf_args="";
float rf_gain=40.0, rf_freq=-1.0, rf_rate=0.96e6;
int nof_samples = -1;
void int_handler(int dummy) {
@ -51,9 +51,9 @@ void int_handler(int dummy) {
void usage(char *prog) {
printf("Usage: %s [agrnv] -f rx_frequency_hz -o output_file\n", prog);
printf("\t-a UHD args [Default %s]\n", uhd_args);
printf("\t-g UHD Gain [Default %.2f dB]\n", uhd_gain);
printf("\t-r UHD Rate [Default %.6f Hz]\n", uhd_rate);
printf("\t-a RF args [Default %s]\n", rf_args);
printf("\t-g RF Gain [Default %.2f dB]\n", rf_gain);
printf("\t-r RF Rate [Default %.6f Hz]\n", rf_rate);
printf("\t-n nof_samples [Default %d]\n", nof_samples);
printf("\t-v srslte_verbose\n");
}
@ -66,16 +66,16 @@ void parse_args(int argc, char **argv) {
output_file_name = argv[optind];
break;
case 'a':
uhd_args = argv[optind];
rf_args = argv[optind];
break;
case 'g':
uhd_gain = atof(argv[optind]);
rf_gain = atof(argv[optind]);
break;
case 'r':
uhd_rate = atof(argv[optind]);
rf_rate = atof(argv[optind]);
break;
case 'f':
uhd_freq = atof(argv[optind]);
rf_freq = atof(argv[optind]);
break;
case 'n':
nof_samples = atoi(argv[optind]);
@ -88,7 +88,7 @@ void parse_args(int argc, char **argv) {
exit(-1);
}
}
if (uhd_freq < 0) {
if (rf_freq < 0) {
usage(argv[0]);
exit(-1);
}
@ -97,7 +97,7 @@ void parse_args(int argc, char **argv) {
int main(int argc, char **argv) {
cf_t *buffer;
int sample_count, n;
void *uhd;
rf_t rf;
srslte_filesink_t sink;
int32_t buflen;
@ -116,42 +116,42 @@ int main(int argc, char **argv) {
srslte_filesink_init(&sink, output_file_name, SRSLTE_COMPLEX_FLOAT_BIN);
printf("Opening UHD device...\n");
if (rf_open(uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
printf("Opening RF device...\n");
if (rf_open(&rf, rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_master_clock_rate(uhd, 30.72e6);
rf_set_master_clock_rate(&rf, 30.72e6);
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
printf("Set RX freq: %.2f MHz\n", rf_set_rx_freq(uhd, uhd_freq) / 1000000);
printf("Set RX gain: %.2f dB\n", rf_set_rx_gain(uhd, uhd_gain));
float srate = rf_set_rx_srate(uhd, uhd_rate);
if (srate != uhd_rate) {
printf("Set RX freq: %.2f MHz\n", rf_set_rx_freq(&rf, rf_freq) / 1000000);
printf("Set RX gain: %.2f dB\n", rf_set_rx_gain(&rf, rf_gain));
float srate = rf_set_rx_srate(&rf, rf_rate);
if (srate != rf_rate) {
if (srate < 10e6) {
rf_set_master_clock_rate(uhd, 4*uhd_rate);
rf_set_master_clock_rate(&rf, 4*rf_rate);
} else {
rf_set_master_clock_rate(uhd, uhd_rate);
rf_set_master_clock_rate(&rf, rf_rate);
}
srate = rf_set_rx_srate(uhd, uhd_rate);
if (srate != uhd_rate) {
fprintf(stderr, "Errror setting samplign frequency %.2f MHz\n", uhd_rate*1e-6);
srate = rf_set_rx_srate(&rf, rf_rate);
if (srate != rf_rate) {
fprintf(stderr, "Errror setting samplign frequency %.2f MHz\n", rf_rate*1e-6);
exit(-1);
}
}
printf("Correctly RX rate: %.2f MHz\n", srate*1e-6);
rf_rx_wait_lo_locked(uhd);
rf_start_rx_stream(uhd);
rf_rx_wait_lo_locked(&rf);
rf_start_rx_stream(&rf);
while((sample_count < nof_samples || nof_samples == -1)
&& keep_running){
n = rf_recv(uhd, buffer, buflen, 1);
n = rf_recv(&rf, buffer, buflen, 1);
if (n < 0) {
fprintf(stderr, "Error receiving samples\n");
exit(-1);
@ -163,7 +163,7 @@ int main(int argc, char **argv) {
srslte_filesink_free(&sink);
free(buffer);
rf_close(uhd);
rf_close(&rf);
printf("Ok - wrote %d samples\n", sample_count);
exit(0);

@ -40,8 +40,8 @@
static bool keep_running = true;
char *output_file_name = NULL;
char *uhd_args="";
float uhd_gain=60.0, uhd_freq=-1.0;
char *rf_args="";
float rf_gain=60.0, rf_freq=-1.0;
int nof_prb = 6;
int nof_subframes = -1;
int N_id_2 = -1;
@ -52,8 +52,8 @@ void int_handler(int dummy) {
void usage(char *prog) {
printf("Usage: %s [agrnv] -l N_id_2 -f rx_frequency_hz -o output_file\n", prog);
printf("\t-a UHD args [Default %s]\n", uhd_args);
printf("\t-g UHD Gain [Default %.2f dB]\n", uhd_gain);
printf("\t-a RF args [Default %s]\n", rf_args);
printf("\t-g RF Gain [Default %.2f dB]\n", rf_gain);
printf("\t-p nof_prb [Default %d]\n", nof_prb);
printf("\t-n nof_subframes [Default %d]\n", nof_subframes);
printf("\t-v verbose\n");
@ -67,16 +67,16 @@ void parse_args(int argc, char **argv) {
output_file_name = argv[optind];
break;
case 'a':
uhd_args = argv[optind];
rf_args = argv[optind];
break;
case 'g':
uhd_gain = atof(argv[optind]);
rf_gain = atof(argv[optind]);
break;
case 'p':
nof_prb = atoi(argv[optind]);
break;
case 'f':
uhd_freq = atof(argv[optind]);
rf_freq = atof(argv[optind]);
break;
case 'n':
nof_subframes = atoi(argv[optind]);
@ -92,7 +92,7 @@ void parse_args(int argc, char **argv) {
exit(-1);
}
}
if (uhd_freq < 0 || N_id_2 == -1 || output_file_name == NULL) {
if (&rf_freq < 0 || N_id_2 == -1 || output_file_name == NULL) {
usage(argv[0]);
exit(-1);
}
@ -106,7 +106,7 @@ int rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *
int main(int argc, char **argv) {
cf_t *buffer;
int n;
void *uhd;
rf_t rf;
srslte_filesink_t sink;
srslte_ue_sync_t ue_sync;
srslte_cell_t cell;
@ -117,30 +117,30 @@ int main(int argc, char **argv) {
srslte_filesink_init(&sink, output_file_name, SRSLTE_COMPLEX_FLOAT_BIN);
printf("Opening UHD device...\n");
if (rf_open(uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
printf("Opening RF device...\n");
if (rf_open(&rf, rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_master_clock_rate(uhd, 30.72e6);
rf_set_master_clock_rate(&rf, 30.72e6);
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
printf("Set RX freq: %.6f MHz\n", rf_set_rx_freq(uhd, uhd_freq) / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(uhd, uhd_gain));
printf("Set RX freq: %.6f MHz\n", rf_set_rx_freq(&rf, rf_freq) / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(&rf, rf_gain));
int srate = srslte_sampling_freq_hz(nof_prb);
if (srate != -1) {
if (srate < 10e6) {
rf_set_master_clock_rate(uhd, 4*srate);
rf_set_master_clock_rate(&rf, 4*srate);
} else {
rf_set_master_clock_rate(uhd, srate);
rf_set_master_clock_rate(&rf, srate);
}
printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000);
float srate_uhd = rf_set_rx_srate(uhd, (double) srate);
if (srate_uhd != srate) {
float srate_rf = rf_set_rx_srate(&rf, (double) srate);
if (srate_rf != srate) {
fprintf(stderr, "Could not set sampling rate\n");
exit(-1);
}
@ -148,15 +148,15 @@ int main(int argc, char **argv) {
fprintf(stderr, "Invalid number of PRB %d\n", nof_prb);
exit(-1);
}
rf_rx_wait_lo_locked(uhd);
rf_start_rx_stream(uhd);
rf_rx_wait_lo_locked(&rf);
rf_start_rx_stream(&rf);
cell.cp = SRSLTE_CP_NORM;
cell.id = N_id_2;
cell.nof_prb = nof_prb;
cell.nof_ports = 1;
if (srslte_ue_sync_init(&ue_sync, cell, rf_recv_wrapper, uhd)) {
if (srslte_ue_sync_init(&ue_sync, cell, rf_recv_wrapper, (void*) &rf)) {
fprintf(stderr, "Error initiating ue_sync\n");
exit(-1);
}
@ -191,7 +191,7 @@ int main(int argc, char **argv) {
}
srslte_filesink_free(&sink);
rf_close(uhd);
rf_close(&rf);
srslte_ue_sync_free(&ue_sync);
printf("Ok - wrote %d subframes\n", subframe_count);

@ -40,17 +40,17 @@ uint32_t nof_prb = 25;
uint32_t nof_frames = 20;
float tone_offset_hz = 0;
float uhd_rx_gain=40, uhd_tx_gain=40, uhd_freq=2.4e9;
char *uhd_args="";
float rf_rx_gain=40, rf_tx_gain=40, rf_freq=2.4e9;
char *rf_args="";
char *output_filename = NULL;
char *input_filename = NULL;
void usage(char *prog) {
printf("Usage: %s -o [rx_signal_file]\n", prog);
printf("\t-a UHD args [Default %s]\n", uhd_args);
printf("\t-f UHD TX/RX frequency [Default %.2f MHz]\n", uhd_freq/1e6);
printf("\t-g UHD RX gain [Default %.1f dB]\n", uhd_rx_gain);
printf("\t-G UHD TX gain [Default %.1f dB]\n", uhd_tx_gain);
printf("\t-a RF args [Default %s]\n", rf_args);
printf("\t-f RF TX/RX frequency [Default %.2f MHz]\n", rf_freq/1e6);
printf("\t-g RF RX gain [Default %.1f dB]\n", rf_rx_gain);
printf("\t-G RF TX gain [Default %.1f dB]\n", rf_tx_gain);
printf("\t-t Single tone offset (Hz) [Default %f]\n", tone_offset_hz);
printf("\t-i File name to read signal from [Default single tone]\n");
printf("\t-p Number of UL RB [Default %d]\n", nof_prb);
@ -61,7 +61,7 @@ void parse_args(int argc, char **argv) {
while ((opt = getopt(argc, argv, "ioafgpt")) != -1) {
switch (opt) {
case 'a':
uhd_args = argv[optind];
rf_args = argv[optind];
break;
case 'o':
output_filename = argv[optind];
@ -73,13 +73,13 @@ void parse_args(int argc, char **argv) {
tone_offset_hz = atof(argv[optind]);
break;
case 'f':
uhd_freq = atof(argv[optind]);
rf_freq = atof(argv[optind]);
break;
case 'g':
uhd_rx_gain = atof(argv[optind]);
rf_rx_gain = atof(argv[optind]);
break;
case 'G':
uhd_tx_gain = atof(argv[optind]);
rf_tx_gain = atof(argv[optind]);
break;
case 'p':
nof_prb = atoi(argv[optind]);
@ -124,31 +124,30 @@ int main(int argc, char **argv) {
exit(-1);
}
// Send through UHD
void *uhd;
printf("Opening UHD device...\n");
if (rf_open(uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
// Send through RF
rf_t rf;
printf("Opening RF device...\n");
if (rf_open(&rf, rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
rf_set_master_clock_rate(uhd, 30.72e6);
rf_set_master_clock_rate(&rf, 30.72e6);
int srate = srslte_sampling_freq_hz(nof_prb);
if (srate < 10e6) {
rf_set_master_clock_rate(uhd, 4*srate);
rf_set_master_clock_rate(&rf, 4*srate);
} else {
rf_set_master_clock_rate(uhd, srate);
rf_set_master_clock_rate(&rf, srate);
}
rf_set_rx_srate(uhd, (double) srate);
rf_set_tx_srate(uhd, (double) srate);
rf_set_rx_srate(&rf, (double) srate);
rf_set_tx_srate(&rf, (double) srate);
printf("Subframe len: %d samples\n", flen);
printf("Set TX/RX rate: %.2f MHz\n", (float) srate / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(uhd, uhd_rx_gain));
printf("Set TX gain: %.1f dB\n", rf_set_tx_gain(uhd, uhd_tx_gain));
printf("Set TX/RX freq: %.2f MHz\n", rf_set_rx_freq(uhd, uhd_freq) / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(&rf, rf_rx_gain));
printf("Set TX gain: %.1f dB\n", rf_set_tx_gain(&rf, rf_tx_gain));
printf("Set TX/RX freq: %.2f MHz\n", rf_set_rx_freq(&rf, rf_freq) / 1000000);
rf_set_tx_freq_offset(uhd, uhd_freq, 8e6);
sleep(1);
if (input_filename) {
@ -157,12 +156,12 @@ int main(int argc, char **argv) {
for (int i=0;i<flen-nsamples_adv;i++) {
tx_buffer[i+nsamples_adv] = cexpf(_Complex_I*2*M_PI*tone_offset_hz*(float) i/(float) srate);
}
srslte_vec_save_file("uhd_txrx_tone", tx_buffer, flen*sizeof(cf_t));
srslte_vec_save_file("rf_txrx_tone", tx_buffer, flen*sizeof(cf_t));
}
srslte_timestamp_t tstamp;
rf_start_rx_stream(uhd);
rf_start_rx_stream(&rf);
uint32_t nframe=0;
float burst_settle_time = (float) nsamples_adv/srslte_sampling_freq_hz(nof_prb);
@ -171,15 +170,15 @@ int main(int argc, char **argv) {
while(nframe<nof_frames) {
printf("Rx subframe %d\n", nframe);
rf_recv_with_time(uhd, &rx_buffer[flen*nframe], flen, true, &tstamp.full_secs, &tstamp.frac_secs);
rf_recv_with_time(&rf, &rx_buffer[flen*nframe], flen, true, &tstamp.full_secs, &tstamp.frac_secs);
nframe++;
if (nframe==9 || nframe==8) {
srslte_timestamp_add(&tstamp, 0, 2e-3-burst_settle_time);
if (nframe==8) {
//rf_send_timed2(uhd, zeros, flen, tstamp.full_secs, tstamp.frac_secs, true, false);
//rf_send_timed2(&rf, zeros, flen, tstamp.full_secs, tstamp.frac_secs, true, false);
printf("Transmitting zeros\n");
} else {
rf_send_timed2(uhd, tx_buffer, flen+nsamples_adv, tstamp.full_secs, tstamp.frac_secs, true, true);
rf_send_timed2(&rf, tx_buffer, flen+nsamples_adv, tstamp.full_secs, tstamp.frac_secs, true, true);
printf("Transmitting Signal\n");
}
}

@ -24,137 +24,127 @@
*
*/
#ifndef RF_H
#define RF_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/time.h>
#include <stdbool.h>
#include <stdint.h>
#include "srslte/config.h"
typedef struct {
void *handler;
void *dev;
} rf_t;
typedef void (*rf_msg_handler_t)(const char*);
SRSLTE_API int rf_open(char *args,
void **handler);
SRSLTE_API int rf_open(rf_t *h,
char *args);
SRSLTE_API int rf_open_th(char *args,
void **handler,
SRSLTE_API int rf_open_th(rf_t *h,
char *args,
bool tx_gain_same_rx);
SRSLTE_API int rf_close(void *h);
SRSLTE_API int rf_open_devname(rf_t *h,
char *devname,
char *args,
bool agc_thread,
bool tx_gain_same_rx);
SRSLTE_API int rf_start_rx_stream(void *h);
SRSLTE_API int rf_close(rf_t *h);
SRSLTE_API int rf_start_rx_stream_nsamples(void *h,
uint32_t nsamples);
SRSLTE_API int rf_start_rx_stream(rf_t *h);
SRSLTE_API int rf_stop_rx_stream(void *h);
SRSLTE_API int rf_stop_rx_stream(rf_t *h);
SRSLTE_API void rf_flush_buffer(void *h);
SRSLTE_API void rf_flush_buffer(rf_t *h);
SRSLTE_API bool rf_has_rssi(void *h);
SRSLTE_API bool rf_has_rssi(rf_t *h);
SRSLTE_API float rf_get_rssi(void *h);
SRSLTE_API float rf_get_rssi(rf_t *h);
SRSLTE_API bool rf_rx_wait_lo_locked(void *h);
SRSLTE_API bool rf_rx_wait_lo_locked(rf_t *h);
SRSLTE_API void rf_set_master_clock_rate(void *h,
SRSLTE_API void rf_set_master_clock_rate(rf_t *h,
double rate);
SRSLTE_API bool rf_is_master_clock_dynamic(void *h);
SRSLTE_API bool rf_is_master_clock_dynamic(rf_t *h);
SRSLTE_API double rf_set_rx_srate(void *h,
SRSLTE_API double rf_set_rx_srate(rf_t *h,
double freq);
SRSLTE_API double rf_set_rx_gain(void *h,
SRSLTE_API double rf_set_rx_gain(rf_t *h,
double gain);
SRSLTE_API void rf_set_tx_rx_gain_offset(void *h,
SRSLTE_API void rf_set_tx_rx_gain_offset(rf_t *h,
double offset);
SRSLTE_API double rf_set_rx_gain_th(void *h,
double gain);
SRSLTE_API double rf_set_tx_gain_th(void *h,
SRSLTE_API double rf_set_rx_gain_th(rf_t *h,
double gain);
SRSLTE_API float rf_get_rx_gain_offset(void *h);
SRSLTE_API double rf_get_rx_gain(rf_t *h);
SRSLTE_API double rf_get_rx_gain(void *h);
SRSLTE_API double rf_get_tx_gain(rf_t *h);
SRSLTE_API double rf_get_tx_gain(void *h);
SRSLTE_API void rf_suppress_stdout(rf_t *h);
SRSLTE_API void rf_suppress_stdout();
SRSLTE_API void rf_register_msg_handler(rf_t *h,
rf_msg_handler_t msg_handler);
SRSLTE_API void rf_register_msg_handler(rf_msg_handler_t h);
SRSLTE_API double rf_set_rx_freq(void *h,
SRSLTE_API double rf_set_rx_freq(rf_t *h,
double freq);
SRSLTE_API double rf_set_rx_freq_offset(void *h,
double freq,
double off);
SRSLTE_API double rf_set_rx_freq_offset(void *h,
double freq,
double off);
SRSLTE_API int rf_recv(void *h,
SRSLTE_API int rf_recv(rf_t *h,
void *data,
uint32_t nsamples,
bool blocking);
SRSLTE_API int rf_recv_with_time(void *h,
SRSLTE_API int rf_recv_with_time(rf_t *h,
void *data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs);
SRSLTE_API double rf_set_tx_srate(void *h,
SRSLTE_API double rf_set_tx_srate(rf_t *h,
double freq);
SRSLTE_API double rf_set_tx_gain(void *h,
SRSLTE_API double rf_set_tx_gain(rf_t *h,
double gain);
SRSLTE_API double rf_set_tx_freq(void *h,
SRSLTE_API double rf_set_tx_freq(rf_t *h,
double freq);
SRSLTE_API double rf_set_tx_freq_offset(void *h,
double freq,
double offset);
SRSLTE_API void rf_get_time(void *h,
SRSLTE_API void rf_get_time(rf_t *h,
time_t *secs,
double *frac_secs);
SRSLTE_API int rf_send(void *h,
SRSLTE_API int rf_send(rf_t *h,
void *data,
uint32_t nsamples,
bool blocking);
SRSLTE_API int rf_send2(void *h,
SRSLTE_API int rf_send2(rf_t *h,
void *data,
uint32_t nsamples,
bool blocking,
bool start_of_burst,
bool end_of_burst);
SRSLTE_API int rf_send(void *h,
SRSLTE_API int rf_send(rf_t *h,
void *data,
uint32_t nsamples,
bool blocking);
SRSLTE_API int rf_send_timed(void *h,
SRSLTE_API int rf_send_timed(rf_t *h,
void *data,
int nsamples,
time_t secs,
double frac_secs);
SRSLTE_API int rf_send_timed2(void *h,
SRSLTE_API int rf_send_timed2(rf_t *h,
void *data,
int nsamples,
time_t secs,
@ -162,6 +152,5 @@ SRSLTE_API int rf_send_timed2(void *h,
bool is_start_of_burst,
bool is_end_of_burst);
#ifdef __cplusplus
}
#endif

@ -62,8 +62,6 @@ FOREACH (_module ${modules})
IF (NOT ${_module} MATCHES "rf")
FILE(GLOB_RECURSE tmp "${_module}/src/*.c")
LIST(APPEND SOURCES_ALL ${tmp})
FILE(GLOB_RECURSE tmp2 "${_module}/src/*.cpp")
LIST(APPEND SOURCES_ALL ${tmp2})
ENDIF (NOT ${_module} MATCHES "rf")
ENDIF(IS_DIRECTORY ${_module})
ENDFOREACH()
@ -83,7 +81,9 @@ IF(RF_FOUND)
add_definitions(-DENABLE_BLADERF)
ENDIF (BLADERF_FOUND)
ADD_LIBRARY(srslte_rf SHARED ${CMAKE_CURRENT_SOURCE_DIR}/rf/src/rf_imp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rf/src/rf_utils.c)
FILE(GLOB_RECURSE cfiles "rf/src/*.c")
FILE(GLOB_RECURSE cppfiles "rf/src/*.cpp")
ADD_LIBRARY(srslte_rf SHARED ${cfiles} ${cppfiles})
IF (UHD_FOUND)
TARGET_LINK_LIBRARIES(srslte_rf ${UHD_LIBRARIES})

@ -140,19 +140,18 @@ int main(int argc, char **argv) {
cf_t *buffer = malloc(sizeof(cf_t)*flen*nof_frames);
// Send through UHD
void *uhd;
rf_t uhd;
printf("Opening UHD device...\n");
if (rf_open(uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
if (rf_open(&uhd, uhd_args)) {
fprintf(stderr, "Error opening &uhd\n");
exit(-1);
}
printf("Subframe len: %d samples\n", flen);
printf("Set TX/RX rate: %.2f MHz\n", rf_set_rx_srate(uhd, srslte_sampling_freq_hz(nof_prb)) / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(uhd, uhd_gain));
printf("Set TX gain: %.1f dB\n", rf_set_tx_gain(uhd, uhd_gain));
printf("Set TX/RX freq: %.2f MHz\n", rf_set_rx_freq(uhd, uhd_freq) / 1000000);
rf_set_tx_srate(uhd, srslte_sampling_freq_hz(nof_prb));
rf_set_tx_freq_offset(uhd, uhd_freq, 8e6);
printf("Set TX/RX rate: %.2f MHz\n", rf_set_rx_srate(&uhd, srslte_sampling_freq_hz(nof_prb)) / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(&uhd, uhd_gain));
printf("Set TX gain: %.1f dB\n", rf_set_tx_gain(&uhd, uhd_gain));
printf("Set TX/RX freq: %.2f MHz\n", rf_set_rx_freq(&uhd, uhd_freq) / 1000000);
rf_set_tx_srate(&uhd, srslte_sampling_freq_hz(nof_prb));
sleep(1);
cf_t *zeros = calloc(sizeof(cf_t),flen);
@ -164,20 +163,20 @@ int main(int argc, char **argv) {
srslte_timestamp_t tstamp;
rf_start_rx_stream(uhd);
rf_start_rx_stream(&uhd);
uint32_t nframe=0;
while(nframe<nof_frames) {
printf("Rx subframe %d\n", nframe);
rf_recv_with_time(uhd, &buffer[flen*nframe], flen, true, &tstamp.full_secs, &tstamp.frac_secs);
rf_recv_with_time(&uhd, &buffer[flen*nframe], flen, true, &tstamp.full_secs, &tstamp.frac_secs);
nframe++;
if (nframe==9 || nframe==8) {
srslte_timestamp_add(&tstamp, 0, 2e-3);
if (nframe==8) {
rf_send_timed2(uhd, zeros, flen, tstamp.full_secs, tstamp.frac_secs, true, false);
rf_send_timed2(&uhd, zeros, flen, tstamp.full_secs, tstamp.frac_secs, true, false);
printf("Transmitting zeros\n");
} else {
rf_send_timed2(uhd, preamble, flen, tstamp.full_secs, tstamp.frac_secs, true, true);
rf_send_timed2(&uhd, preamble, flen, tstamp.full_secs, tstamp.frac_secs, true, true);
printf("Transmitting PRACH\n");
}
}

@ -0,0 +1,153 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <libbladeRF.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "srslte/srslte.h"
#include "rf_blade_imp.h"
#include "srslte/rf/rf.h"
typedef struct {
} rf_blade_handler_t;
void rf_blade_suppress_stdout(void *h) {
}
void rf_blade_register_msg_handler(void *notused, rf_msg_handler_t new_handler)
{
}
bool rf_blade_rx_wait_lo_locked(void *h)
{
}
int rf_blade_start_rx_stream(void *h)
{
}
int rf_blade_stop_rx_stream(void *h)
{
}
void rf_blade_flush_buffer(void *h)
{
}
bool rf_blade_has_rssi(void *h) {
}
float rf_blade_get_rssi(void *h) {
}
double rf_blade_set_rx_gain_th(void *h, double gain)
{
}
void rf_blade_set_tx_rx_gain_offset(void *h, double offset) {
}
/* This thread listens for set_rx_gain commands to the USRP */
static void* thread_gain_fcn(void *h) {
}
int rf_blade_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same_rx)
{
}
int rf_blade_close(void *h)
{
}
void rf_blade_set_master_clock_rate(void *h, double rate) {
}
bool rf_blade_is_master_clock_dynamic(void *h) {
}
double rf_blade_set_rx_srate(void *h, double freq)
{
}
double rf_blade_set_tx_srate(void *h, double freq)
{
}
double rf_blade_set_rx_gain(void *h, double gain)
{
}
double rf_blade_set_tx_gain(void *h, double gain)
{
}
double rf_blade_get_rx_gain(void *h)
{
}
double rf_blade_get_tx_gain(void *h)
{
}
double rf_blade_set_rx_freq(void *h, double freq)
{
}
double rf_blade_set_tx_freq(void *h, double freq)
{
}
void rf_blade_get_time(void *h, time_t *secs, double *frac_secs) {
}
int rf_blade_recv_with_time(void *h,
void *data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs)
{
}
int rf_blade_send_timed(void *h,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst)
{
}

@ -0,0 +1,116 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include "srslte/config.h"
#include "srslte/rf/rf.h"
SRSLTE_API int rf_blade_open(char *args,
void **handler,
bool agc_thread,
bool tx_gain_same_rx);
SRSLTE_API int rf_blade_close(void *h);
SRSLTE_API int rf_blade_start_rx_stream(void *h);
SRSLTE_API int rf_blade_start_rx_stream_nsamples(void *h,
uint32_t nsamples);
SRSLTE_API int rf_blade_stop_rx_stream(void *h);
SRSLTE_API void rf_blade_flush_buffer(void *h);
SRSLTE_API bool rf_blade_has_rssi(void *h);
SRSLTE_API float rf_blade_get_rssi(void *h);
SRSLTE_API bool rf_blade_rx_wait_lo_locked(void *h);
SRSLTE_API void rf_blade_set_master_clock_rate(void *h,
double rate);
SRSLTE_API bool rf_blade_is_master_clock_dynamic(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 void rf_blade_set_tx_rx_gain_offset(void *h,
double offset);
SRSLTE_API double rf_blade_set_rx_gain_th(void *h,
double gain);
SRSLTE_API double rf_blade_set_tx_gain_th(void *h,
double gain);
SRSLTE_API float rf_blade_get_rx_gain_offset(void *h);
SRSLTE_API double rf_blade_get_rx_gain(void *h);
SRSLTE_API double rf_blade_get_tx_gain(void *h);
SRSLTE_API void rf_blade_suppress_stdout(void *h);
SRSLTE_API void rf_blade_register_msg_handler(void *h, rf_msg_handler_t msg_handler);
SRSLTE_API double rf_blade_set_rx_freq(void *h,
double freq);
SRSLTE_API int rf_blade_recv_with_time(void *h,
void *data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs);
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 double rf_blade_set_tx_freq(void *h,
double freq);
SRSLTE_API void rf_blade_get_time(void *h,
time_t *secs,
double *frac_secs);
SRSLTE_API int rf_blade_send_timed(void *h,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst);

@ -0,0 +1,139 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
/* RF frontend API */
typedef struct {
const char *name;
bool (*rf_rx_wait_lo_locked) (void*);
int (*rf_start_rx_stream)(void *h);
int (*rf_stop_rx_stream)(void *h);
void (*rf_flush_buffer)(void *h);
bool (*rf_has_rssi)(void *h);
float (*rf_get_rssi)(void *h);
double (*rf_set_rx_gain_th)(void *h, double gain);
void (*rf_set_tx_rx_gain_offset)(void *h, double offset);
void (*rf_suppress_stdout)(void *h);
void (*rf_register_msg_handler)(void *h, rf_msg_handler_t msg_handler);
int (*rf_open)(char *args, void **h, bool agc_thread, bool tx_gain_same_rx);
int (*rf_close)(void *h);
void (*rf_set_master_clock_rate)(void *h, double rate);
bool (*rf_is_master_clock_dynamic)(void *h);
double (*rf_set_rx_srate)(void *h, double freq);
double (*rf_set_rx_gain)(void *h, double gain);
double (*rf_set_tx_gain)(void *h, double gain);
double (*rf_get_rx_gain)(void *h);
double (*rf_get_tx_gain)(void *h);
double (*rf_set_rx_freq)(void *h, double freq);
double (*rf_set_tx_srate)(void *h, double freq);
double (*rf_set_tx_freq)(void *h, double freq);
void (*rf_get_time)(void *h, time_t *secs, double *frac_secs);
int (*rf_recv_with_time)(void *h, void *data, uint32_t nsamples,
bool blocking, time_t *secs,double *frac_secs);
int (*rf_send_timed)(void *h, void *data, int nsamples,
time_t secs, double frac_secs, bool has_time_spec,
bool blocking, bool is_start_of_burst, bool is_end_of_burst);
} rf_dev_t;
/* Define implementation for UHD */
#ifdef ENABLE_UHD
#include "rf_uhd_imp.h"
static rf_dev_t dev_uhd = {
"UHD",
rf_uhd_rx_wait_lo_locked,
rf_uhd_start_rx_stream,
rf_uhd_stop_rx_stream,
rf_uhd_flush_buffer,
rf_uhd_has_rssi,
rf_uhd_get_rssi,
rf_uhd_set_rx_gain_th,
rf_uhd_set_tx_rx_gain_offset,
rf_uhd_suppress_stdout,
rf_uhd_register_msg_handler,
rf_uhd_open,
rf_uhd_close,
rf_uhd_set_master_clock_rate,
rf_uhd_is_master_clock_dynamic,
rf_uhd_set_rx_srate,
rf_uhd_set_rx_gain,
rf_uhd_set_tx_gain,
rf_uhd_get_rx_gain,
rf_uhd_get_tx_gain,
rf_uhd_set_rx_freq,
rf_uhd_set_tx_srate,
rf_uhd_set_tx_freq,
rf_uhd_get_time,
rf_uhd_recv_with_time,
rf_uhd_send_timed
};
#endif
/* Define implementation for bladeRF */
#ifdef ENABLE_BLADERF
#include "rf_blade_imp.h"
static rf_dev_t dev_blade = {
"bladeRF",
rf_blade_rx_wait_lo_locked,
rf_blade_start_rx_stream,
rf_blade_stop_rx_stream,
rf_blade_flush_buffer,
rf_blade_has_rssi,
rf_blade_get_rssi,
rf_blade_set_rx_gain_th,
rf_blade_set_tx_rx_gain_offset,
rf_blade_suppress_stdout,
rf_blade_register_msg_handler,
rf_blade_open,
rf_blade_close,
rf_blade_set_master_clock_rate,
rf_blade_is_master_clock_dynamic,
rf_blade_set_rx_srate,
rf_blade_set_rx_gain,
rf_blade_set_tx_gain,
rf_blade_get_rx_gain,
rf_blade_get_tx_gain,
rf_blade_set_rx_freq,
rf_blade_set_tx_srate,
rf_blade_set_tx_freq,
rf_blade_get_time,
rf_blade_recv_with_time,
rf_blade_send_timed
};
#endif
static rf_dev_t *available_devices[] = {
#ifdef ENABLE_UHD
&dev_uhd,
#endif
#ifdef ENABLE_BLADERF
&dev_blade,
#endif
NULL
};

@ -1,55 +0,0 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 The srsLTE Developers. See the
* COPYRIGHT file at the top-level directory of this distribution.
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <uhd/usrp/multi_usrp.hpp>
#include <pthread.h>
class rf_handler {
public:
uhd::usrp::multi_usrp::sptr usrp;
uhd::rx_streamer::sptr rx_stream;
bool rx_stream_enable;
uhd::tx_streamer::sptr tx_stream;
// The following variables are for threaded RX gain control
pthread_t thread_gain;
pthread_cond_t cond;
pthread_mutex_t mutex;
double cur_rx_gain;
double new_rx_gain;
double cur_tx_gain;
double new_tx_gain;
bool tx_gain_same_rx;
float tx_rx_gain_offset;
uhd::gain_range_t rx_gain_range;
uhd::gain_range_t tx_gain_range;
size_t rx_nof_samples;
size_t tx_nof_samples;
double tx_rate;
bool dynamic_rate;
};

@ -0,0 +1,238 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <string.h>
#include "srslte/rf/rf.h"
#include "srslte/srslte.h"
#include "rf_dev.h"
bool rf_rx_wait_lo_locked(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_rx_wait_lo_locked(rf->handler);
}
int rf_start_rx_stream(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_start_rx_stream(rf->handler);
}
int rf_stop_rx_stream(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_stop_rx_stream(rf->handler);
}
void rf_flush_buffer(rf_t *rf)
{
((rf_dev_t*) rf->dev)->rf_flush_buffer(rf->handler);
}
bool rf_has_rssi(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_has_rssi(rf->handler);
}
float rf_get_rssi(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_get_rssi(rf->handler);
}
double rf_set_rx_gain_th(rf_t *rf, double gain)
{
return ((rf_dev_t*) rf->dev)->rf_set_rx_gain_th(rf->handler, gain);
}
void rf_set_tx_rx_gain_offset(rf_t *rf, double offset)
{
((rf_dev_t*) rf->dev)->rf_set_tx_rx_gain_offset(rf->handler, offset);
}
void rf_suppress_stdout(rf_t *rf)
{
((rf_dev_t*) rf->dev)->rf_suppress_stdout(rf->handler);
}
void rf_register_msg_handler(rf_t *rf, rf_msg_handler_t msg_handler)
{
((rf_dev_t*) rf->dev)->rf_register_msg_handler(rf->handler, msg_handler);
}
int rf_open_devname(rf_t *rf, char *devname, char *args, bool agc_thread, bool tx_gain_same_rx) {
/* Try to open the device if name is provided */
if (devname) {
int i=0;
while(available_devices[i] != NULL) {
if (!strcmp(available_devices[i]->name, devname)) {
rf->dev = &available_devices[i];
return available_devices[i]->rf_open(args, &rf->handler, agc_thread, tx_gain_same_rx);
}
}
}
/* If in auto mode, try to open in order of apperance in available_devices[] array */
int i=0;
while(available_devices[i] != NULL) {
if (!available_devices[i]->rf_open(args, &rf->handler, agc_thread, tx_gain_same_rx)) {
rf->dev = &available_devices[i];
return 0;
}
}
fprintf(stderr, "No compatible RF frontend found\n");
return -1;
}
int rf_open(rf_t *h, char *args)
{
return rf_open_devname(h, NULL, args, false, false);
}
int rf_open_th(rf_t *h, char *args, bool tx_gain_same_rx)
{
return rf_open_devname(h, NULL, args, false, tx_gain_same_rx);
}
int rf_close(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_close(rf->handler);
}
void rf_set_master_clock_rate(rf_t *rf, double rate)
{
((rf_dev_t*) rf->dev)->rf_set_master_clock_rate(rf->handler, rate);
}
bool rf_is_master_clock_dynamic(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_is_master_clock_dynamic(rf->handler);
}
double rf_set_rx_srate(rf_t *rf, double freq)
{
return ((rf_dev_t*) rf->dev)->rf_set_rx_srate(rf->handler, freq);
}
double rf_set_rx_gain(rf_t *rf, double gain)
{
return ((rf_dev_t*) rf->dev)->rf_set_rx_gain(rf->handler, gain);
}
double rf_get_rx_gain(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_get_rx_gain(rf->handler);
}
double rf_get_tx_gain(rf_t *rf)
{
return ((rf_dev_t*) rf->dev)->rf_get_tx_gain(rf->handler);
}
double rf_set_rx_freq(rf_t *rf, double freq)
{
return ((rf_dev_t*) rf->dev)->rf_set_rx_freq(rf->handler, freq);
}
int rf_recv(rf_t *rf, void *data, uint32_t nsamples, bool blocking)
{
return rf_recv_with_time(rf, data, nsamples, blocking, NULL, NULL);
}
int rf_recv_with_time(rf_t *rf,
void *data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs)
{
return ((rf_dev_t*) rf->dev)->rf_recv_with_time(rf->handler, data, nsamples, blocking, secs, frac_secs);
}
double rf_set_tx_gain(rf_t *rf, double gain)
{
return ((rf_dev_t*) rf->dev)->rf_set_tx_gain(rf->handler, gain);
}
double rf_set_tx_srate(rf_t *rf, double freq)
{
return ((rf_dev_t*) rf->dev)->rf_set_tx_srate(rf->handler, freq);
}
double rf_set_tx_freq(rf_t *rf, double freq)
{
return ((rf_dev_t*) rf->dev)->rf_set_tx_freq(rf->handler, freq);
}
void rf_get_time(rf_t *rf, time_t *secs, double *frac_secs)
{
return ((rf_dev_t*) rf->dev)->rf_get_time(rf->handler, secs, frac_secs);
}
int rf_send_timed3(rf_t *rf,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst)
{
return ((rf_dev_t*) rf->dev)->rf_send_timed(rf->handler, data, nsamples, secs, frac_secs,
has_time_spec, blocking, is_start_of_burst, is_end_of_burst);
}
int rf_send(rf_t *rf, void *data, uint32_t nsamples, bool blocking)
{
return rf_send2(rf, data, nsamples, blocking, true, true);
}
int rf_send2(rf_t *rf, void *data, uint32_t nsamples, bool blocking, bool start_of_burst, bool end_of_burst)
{
return rf_send_timed3(rf, data, nsamples, 0, 0, false, blocking, start_of_burst, end_of_burst);
}
int rf_send_timed(rf_t *rf,
void *data,
int nsamples,
time_t secs,
double frac_secs)
{
return rf_send_timed2(rf, data, nsamples, secs, frac_secs, true, true);
}
int rf_send_timed2(rf_t *rf,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool is_start_of_burst,
bool is_end_of_burst)
{
return rf_send_timed3(rf, data, nsamples, secs, frac_secs, true, true, is_start_of_burst, is_end_of_burst);
}

@ -1,521 +0,0 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <uhd/utils/thread_priority.hpp>
#include <uhd/usrp/multi_usrp.hpp>
#include <iostream>
#include <complex>
#include <cstdio>
#include <uhd/utils/msg.hpp>
#include <sys/time.h>
#include "rf_handler.hpp"
#include "srslte/rf/rf.h"
#include "srslte/srslte.h"
//#define METADATA_VERBOSE
rf_msg_handler_t msg_handler;
void suppress_handler(uhd::msg::type_t type, const std::string & msg)
{
//handle the message...
}
void translate_handler(uhd::msg::type_t type, const std::string & msg)
{
if(msg_handler)
msg_handler(msg.c_str());
}
typedef _Complex float complex_t;
#define SAMPLE_SZ sizeof(complex_t)
bool isLocked(void *h)
{
rf_handler *handler = static_cast < rf_handler * >(h);
std::vector < std::string > mb_sensors =
handler->usrp->get_mboard_sensor_names();
std::vector < std::string > rx_sensors =
handler->usrp->get_rx_sensor_names(0);
if (std::find(rx_sensors.begin(), rx_sensors.end(), "lo_locked") !=
rx_sensors.end()) {
return handler->usrp->get_rx_sensor("lo_locked", 0).to_bool();
} else if (std::find(mb_sensors.begin(), mb_sensors.end(), "ref_locked") !=
mb_sensors.end()) {
return handler->usrp->get_mboard_sensor("ref_locked", 0).to_bool();
} else {
usleep(500);
return true;
}
}
bool rf_rx_wait_lo_locked(void *h)
{
double report = 0.0;
while (isLocked(h) && report < 30.0) {
report += 0.1;
usleep(1000);
}
return isLocked(h);
}
int rf_start_rx_stream(void *h)
{
rf_handler *handler = static_cast < rf_handler * >(h);
uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
cmd.time_spec = handler->usrp->get_time_now();
cmd.stream_now = true;
handler->usrp->issue_stream_cmd(cmd);
return 0;
}
int rf_stop_rx_stream(void *h)
{
rf_handler *handler = static_cast < rf_handler * >(h);
uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
cmd.time_spec = handler->usrp->get_time_now();
cmd.stream_now = true;
handler->usrp->issue_stream_cmd(cmd);
return 0;
}
void rf_flush_buffer(void *h)
{
int n;
_Complex float tmp[1024];
do {
n = rf_recv(h, tmp, 1024, 0);
} while (n > 0);
}
bool rf_has_rssi(void *h) {
rf_handler *handler = static_cast < rf_handler * >(h);
std::vector < std::string > mb_sensors = handler->usrp->get_mboard_sensor_names();
std::vector < std::string > rx_sensors = handler->usrp->get_rx_sensor_names(0);
if (std::find(rx_sensors.begin(), rx_sensors.end(), "rssi") != rx_sensors.end()) {
return true;
} else {
return false;
}
}
float rf_get_rssi(void *h) {
rf_handler *handler = static_cast < rf_handler * >(h);
if (rf_has_rssi(h)) {
uhd::sensor_value_t value = handler->usrp->get_rx_sensor("rssi");
return value.to_real();
} else {
return 0;
}
}
int rf_start_rx_stream_nsamples(void *h, uint32_t nsamples)
{
rf_handler *handler = static_cast < rf_handler * >(h);
uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE);
cmd.time_spec = handler->usrp->get_time_now();
cmd.stream_now = true;
cmd.num_samps = nsamples;
handler->usrp->issue_stream_cmd(cmd);
return 0;
}
double rf_set_rx_gain_th(void *h, double gain)
{
rf_handler *handler = static_cast < rf_handler * >(h);
gain = handler->rx_gain_range.clip(gain);
if (gain > handler->new_rx_gain + 0.5 || gain < handler->new_rx_gain - 0.5) {
pthread_mutex_lock(&handler->mutex);
handler->new_rx_gain = gain;
pthread_cond_signal(&handler->cond);
pthread_mutex_unlock(&handler->mutex);
}
return gain;
}
double rf_set_tx_gain_th(void *h, double gain)
{
rf_handler *handler = static_cast < rf_handler * >(h);
gain = handler->tx_gain_range.clip(gain);
if (gain > handler->new_tx_gain + 0.5 || gain < handler->new_tx_gain - 0.5) {
pthread_mutex_lock(&handler->mutex);
handler->new_tx_gain = gain;
pthread_cond_signal(&handler->cond);
pthread_mutex_unlock(&handler->mutex);
}
return gain;
}
void rf_set_tx_rx_gain_offset(void *h, double offset) {
rf_handler *handler = static_cast < rf_handler * >(h);
handler->tx_rx_gain_offset = offset;
}
/* This thread listens for set_rx_gain commands to the USRP */
static void* thread_gain_fcn(void *h) {
rf_handler *handler = static_cast < rf_handler * >(h);
while(1) {
pthread_mutex_lock(&handler->mutex);
while(handler->cur_rx_gain == handler->new_rx_gain &&
handler->cur_tx_gain == handler->new_tx_gain)
{
pthread_cond_wait(&handler->cond, &handler->mutex);
}
if (handler->new_rx_gain != handler->cur_rx_gain) {
handler->cur_rx_gain = handler->new_rx_gain;
rf_set_rx_gain(h, handler->cur_rx_gain);
}
if (handler->tx_gain_same_rx) {
rf_set_tx_gain(h, handler->cur_rx_gain+handler->tx_rx_gain_offset);
} else if (handler->new_tx_gain != handler->cur_tx_gain) {
handler->cur_tx_gain = handler->new_tx_gain;
rf_set_tx_gain(h, handler->cur_tx_gain);
}
pthread_mutex_unlock(&handler->mutex);
}
}
float rf_get_rx_gain_offset(void *h) {
return 15;
}
void rf_suppress_stdout() {
uhd::msg::register_handler(suppress_handler);
}
void rf_register_msg_handler(rf_msg_handler_t h)
{
msg_handler = h;
uhd::msg::register_handler(translate_handler);
}
int rf_open_(char *args, void **h, bool create_thread_gain, bool tx_gain_same_rx)
{
*h = NULL;
/* Set priority to UHD threads */
uhd::set_thread_priority_safe();
/* Get multiusrp handler */
rf_handler *handler = new rf_handler();
std::string _args = std::string(args);
handler->usrp = uhd::usrp::multi_usrp::make(_args);// + ", recv_frame_size=9232,num_recv_frames=64,send_frame_size=9232,num_send_frames=64");
/* Initialize rx and tx stremers */
std::string otw, cpu;
otw = "sc16";
cpu = "fc32";
uhd::stream_args_t stream_args(cpu, otw);
handler->rx_stream = handler->usrp->get_rx_stream(stream_args);
handler->tx_stream = handler->usrp->get_tx_stream(stream_args);
handler->rx_nof_samples = handler->rx_stream->get_max_num_samps();
handler->tx_nof_samples = handler->tx_stream->get_max_num_samps();
handler->tx_gain_same_rx = tx_gain_same_rx;
handler->tx_rx_gain_offset = 0.0;
handler->rx_gain_range = handler->usrp->get_rx_gain_range();
handler->tx_gain_range = handler->usrp->get_tx_gain_range();
/* Create auxiliary thread and mutexes for AGC */
if (create_thread_gain) {
if (pthread_mutex_init(&handler->mutex, NULL)) {
return -1;
}
if (pthread_cond_init(&handler->cond, NULL)) {
return -1;
}
if (pthread_create(&handler->thread_gain, NULL, thread_gain_fcn, handler)) {
perror("pthread_create");
return -1;
}
}
/* Find out if the master clock rate is configurable */
double cur_clock = handler->usrp->get_master_clock_rate();
printf("Trying to dynamically change Master clock...\n");
handler->usrp->set_master_clock_rate(cur_clock/2);
if (handler->usrp->get_master_clock_rate() == cur_clock) {
handler->dynamic_rate = false;
/* Master clock rate is not configurable. Check if it is compatible with LTE */
int cur_clock_i = (int) cur_clock;
if (cur_clock_i % 1920000) {
fprintf(stderr, "Error: LTE sampling rates are not supported. Master clock rate is %.1f MHz\n", cur_clock/1e6);
return -1;
} else {
printf("Master clock is not configurable. Using standard symbol sizes and sampling rates.\n");
srslte_use_standard_symbol_size(true);
}
} else {
printf("Master clock is configurable. Using reduced symbol sizes and sampling rates.\n");
handler->dynamic_rate = true;
}
*h = handler;
return 0;
}
int rf_open(char *args, void **h) {
return rf_open_(args, h, false, false);
}
int rf_open_th(char *args, void **h, bool tx_gain_same_rx) {
return rf_open_(args, h, true, tx_gain_same_rx);
}
int rf_close(void *h)
{
rf_stop_rx_stream(h);
/** Something else to close the USRP?? */
return 0;
}
void rf_set_master_clock_rate(void *h, double rate) {
rf_handler *handler = static_cast < rf_handler * >(h);
if (handler->dynamic_rate) {
handler->usrp->set_master_clock_rate(rate);
}
}
bool rf_is_master_clock_dynamic(void *h) {
rf_handler *handler = static_cast < rf_handler * >(h);
return handler->dynamic_rate;
}
double rf_set_rx_srate(void *h, double freq)
{
rf_handler *handler = static_cast < rf_handler * >(h);
handler->usrp->set_rx_rate(freq);
return handler->usrp->get_rx_rate();
}
double rf_set_rx_gain(void *h, double gain)
{
rf_handler *handler = static_cast < rf_handler * >(h);
handler->usrp->set_rx_gain(gain);
return handler->usrp->get_rx_gain();
}
double rf_get_rx_gain(void *h)
{
rf_handler *handler = static_cast < rf_handler * >(h);
return handler->usrp->get_rx_gain();
}
double rf_get_tx_gain(void *h)
{
rf_handler *handler = static_cast < rf_handler * >(h);
return handler->usrp->get_tx_gain();
}
double rf_set_rx_freq(void *h, double freq)
{
rf_handler *handler = static_cast < rf_handler * >(h);
handler->usrp->set_rx_freq(freq);
return freq;
}
double rf_set_rx_freq_offset(void *h, double freq, double off) {
rf_handler* handler = static_cast<rf_handler*>(h);
handler->usrp->set_rx_freq(uhd::tune_request_t(freq, off));
return handler->usrp->get_rx_freq();
}
int rf_recv(void *h, void *data, uint32_t nsamples, bool blocking)
{
return rf_recv_with_time(h, data, nsamples, blocking, NULL, NULL);
}
int rf_recv_with_time(void *h,
void *data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs)
{
rf_handler *handler = static_cast < rf_handler * >(h);
uhd::rx_metadata_t md, md_first;
if (blocking) {
int n = 0, p;
complex_t *data_c = (complex_t *) data;
do {
size_t rx_samples = handler->rx_nof_samples;
if (rx_samples > nsamples - n) {
rx_samples = nsamples - n;
}
p = handler->rx_stream->recv(&data_c[n], rx_samples, n==0?md_first:md);
if (p == -1) {
return -1;
}
n += p;
#ifdef METADATA_VERBOSE
if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) {
std::cout << "\nError code: " << md.to_pp_string() << "\n\n";
}
#endif
} while (n < nsamples &&
md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE);
} else {
return handler->rx_stream->recv(data, nsamples, md, 0.0);
}
if (secs) {
*secs = md_first.time_spec.get_full_secs();
}
if (frac_secs) {
*frac_secs = md_first.time_spec.get_frac_secs();
}
return nsamples;
}
double rf_set_tx_gain(void *h, double gain)
{
rf_handler *handler = static_cast < rf_handler * >(h);
handler->usrp->set_tx_gain(gain);
return gain;
}
double rf_set_tx_srate(void *h, double freq)
{
rf_handler *handler = static_cast < rf_handler * >(h);
handler->usrp->set_tx_rate(freq);
handler->tx_rate = handler->usrp->get_tx_rate();
return handler->tx_rate;
}
double rf_set_tx_freq(void *h, double freq)
{
rf_handler *handler = static_cast < rf_handler * >(h);
handler->usrp->set_tx_freq(freq);
return handler->usrp->get_tx_freq();
}
double rf_set_tx_freq_offset(void *h, double freq, double off) {
rf_handler* handler = static_cast<rf_handler*>(h);
handler->usrp->set_tx_freq(uhd::tune_request_t(freq, off));
return handler->usrp->get_tx_freq();
}
void rf_get_time(void *h, time_t *secs, double *frac_secs) {
rf_handler *handler = static_cast < rf_handler * >(h);
uhd::time_spec_t now = handler->usrp->get_time_now();
if (secs) {
*secs = now.get_full_secs();
}
if (frac_secs) {
*frac_secs = now.get_frac_secs();
}
}
int rf_send_timed3(void *h,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst)
{
rf_handler* handler = static_cast<rf_handler*>(h);
uhd::tx_metadata_t md;
md.has_time_spec = has_time_spec;
if (has_time_spec) {
md.time_spec = uhd::time_spec_t(secs, frac_secs);
}
if (blocking) {
int n = 0, p;
complex_t *data_c = (complex_t *) data;
do {
size_t tx_samples = handler->tx_nof_samples;
// First packet is start of burst if so defined, others are never
if (n == 0) {
md.start_of_burst = is_start_of_burst;
} else {
md.start_of_burst = false;
}
// middle packets are never end of burst, last one as defined
if (nsamples - n > tx_samples) {
md.end_of_burst = false;
} else {
tx_samples = nsamples - n;
md.end_of_burst = is_end_of_burst;
}
p = handler->tx_stream->send(&data_c[n], tx_samples, md);
if (p == -1) {
return -1;
}
// Increase time spec
md.time_spec += tx_samples/handler->tx_rate;
n += p;
} while (n < nsamples);
return nsamples;
} else {
return handler->tx_stream->send(data, nsamples, md, 0.0);
}
}
int rf_send(void *h, void *data, uint32_t nsamples, bool blocking)
{
return rf_send2(h, data, nsamples, blocking, true, true);
}
int rf_send2(void *h, void *data, uint32_t nsamples, bool blocking, bool start_of_burst, bool end_of_burst)
{
return rf_send_timed3(h, data, nsamples, 0, 0, false, blocking, start_of_burst, end_of_burst);
}
int rf_send_timed(void *h,
void *data,
int nsamples,
time_t secs,
double frac_secs)
{
return rf_send_timed2(h, data, nsamples, secs, frac_secs, true, true);
}
int rf_send_timed2(void *h,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool is_start_of_burst,
bool is_end_of_burst)
{
return rf_send_timed3(h, data, nsamples, secs, frac_secs, true, true, is_start_of_burst, is_end_of_burst);
}

@ -0,0 +1,548 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <uhd.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "srslte/srslte.h"
#include "rf_uhd_imp.h"
#include "srslte/rf/rf.h"
#include "uhd_c_api.h"
typedef struct {
uhd_usrp_handle usrp;
uhd_rx_streamer_handle rx_stream;
uhd_tx_streamer_handle tx_stream;
uhd_rx_metadata_handle rx_md, rx_md_first;
uhd_tx_metadata_handle tx_md;
// The following variables are for threaded RX gain control
uhd_meta_range_handle rx_gain_range;
pthread_t thread_gain;
pthread_cond_t cond;
pthread_mutex_t mutex;
double cur_rx_gain;
double new_rx_gain;
bool tx_gain_same_rx;
float tx_rx_gain_offset;
size_t rx_nof_samples;
size_t tx_nof_samples;
double tx_rate;
bool dynamic_rate;
} rf_uhd_handler_t;
void suppress_handler(const char *x)
{
// do nothing
}
void rf_uhd_suppress_stdout(void *h) {
rf_uhd_register_msg_handler(h, suppress_handler);
}
void rf_uhd_register_msg_handler(void *notused, rf_msg_handler_t new_handler)
{
rf_uhd_register_msg_handler_c(new_handler);
}
static bool find_string(uhd_string_vector_handle h, char *str)
{
char buff[128];
size_t n;
uhd_string_vector_size(h, &n);
for (int i=0;i<n;i++) {
uhd_string_vector_at(h, i, buff, 128);
if (!strcmp(buff, str)) {
return true;
}
}
return false;
}
static bool isLocked(rf_uhd_handler_t *handler, char *sensor_name, uhd_sensor_value_handle *value_h)
{
bool val_out = false;
if (sensor_name) {
uhd_usrp_get_rx_sensor(handler->usrp, sensor_name, 0, value_h);
uhd_sensor_value_to_bool(*value_h, &val_out);
} else {
usleep(500);
val_out = true;
}
return val_out;
}
bool rf_uhd_rx_wait_lo_locked(void *h)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_string_vector_handle mb_sensors;
uhd_string_vector_handle rx_sensors;
char *sensor_name;
uhd_sensor_value_handle value_h;
uhd_string_vector_make(&mb_sensors);
uhd_string_vector_make(&rx_sensors);
uhd_usrp_get_mboard_sensor_names(handler->usrp, 0, &mb_sensors);
uhd_usrp_get_rx_sensor_names(handler->usrp, 0, &rx_sensors);
if (find_string(rx_sensors, "lo_locked")) {
sensor_name = "lo_locked";
} else if (find_string(mb_sensors, "ref_locked")) {
sensor_name = "ref_locked";
} else {
sensor_name = NULL;
}
double report = 0.0;
while (isLocked(handler, sensor_name, &value_h) && report < 30.0) {
report += 0.1;
usleep(1000);
}
bool val = isLocked(handler, sensor_name, &value_h);
uhd_string_vector_free(&mb_sensors);
uhd_string_vector_free(&rx_sensors);
uhd_sensor_value_free(&value_h);
return val;
}
int rf_uhd_start_rx_stream(void *h)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_stream_cmd_t stream_cmd = {
.stream_mode = UHD_STREAM_MODE_START_CONTINUOUS,
.stream_now = true
};
uhd_rx_streamer_issue_stream_cmd(handler->rx_stream, &stream_cmd);
return 0;
}
int rf_uhd_stop_rx_stream(void *h)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_stream_cmd_t stream_cmd = {
.stream_mode = UHD_STREAM_MODE_STOP_CONTINUOUS,
.stream_now = true
};
uhd_rx_streamer_issue_stream_cmd(handler->rx_stream, &stream_cmd);
return 0;
}
void rf_uhd_flush_buffer(void *h)
{
int n;
cf_t tmp[1024];
do {
n = rf_uhd_recv_with_time(h, tmp, 1024, 0, NULL, NULL);
} while (n > 0);
}
bool rf_uhd_has_rssi(void *h) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_string_vector_handle rx_sensors;
uhd_usrp_get_rx_sensor_names(handler->usrp, 0, &rx_sensors);
bool ret = find_string(rx_sensors, "rssi");
uhd_string_vector_free(&rx_sensors);
return ret;
}
float rf_uhd_get_rssi(void *h) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_sensor_value_handle value;
uhd_usrp_get_rx_sensor(handler->usrp, "rssi", 0, &value);
double val_out;
uhd_sensor_value_to_realnum(value, &val_out);
uhd_sensor_value_free(&value);
return val_out;
}
double rf_uhd_set_rx_gain_th(void *h, double gain)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
double gain_clipped;
uhd_meta_range_clip(handler->rx_gain_range, gain, true, &gain_clipped);
if (gain_clipped > handler->new_rx_gain + 0.5 || gain_clipped < handler->new_rx_gain - 0.5) {
pthread_mutex_lock(&handler->mutex);
handler->new_rx_gain = gain_clipped;
pthread_cond_signal(&handler->cond);
pthread_mutex_unlock(&handler->mutex);
}
return gain_clipped;
}
void rf_uhd_set_tx_rx_gain_offset(void *h, double offset) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
handler->tx_rx_gain_offset = offset;
}
/* This thread listens for set_rx_gain commands to the USRP */
static void* thread_gain_fcn(void *h) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
while(1) {
pthread_mutex_lock(&handler->mutex);
while(handler->cur_rx_gain == handler->new_rx_gain)
{
pthread_cond_wait(&handler->cond, &handler->mutex);
}
if (handler->new_rx_gain != handler->cur_rx_gain) {
handler->cur_rx_gain = handler->new_rx_gain;
rf_uhd_set_rx_gain(h, handler->cur_rx_gain);
}
if (handler->tx_gain_same_rx) {
rf_uhd_set_tx_gain(h, handler->cur_rx_gain+handler->tx_rx_gain_offset);
}
pthread_mutex_unlock(&handler->mutex);
}
return NULL;
}
int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same_rx)
{
char err_msg[256];
*h = NULL;
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) malloc(sizeof(rf_uhd_handler_t));
if (!handler) {
perror("malloc");
return -1;
}
*h = handler;
/* Set priority to UHD threads */
uhd_set_thread_priority(uhd_default_thread_priority, true);
/* Find available USRP devices in case args is empty */
if (args[0] == '\0') {
uhd_string_vector_handle devices_str;
uhd_string_vector_make(&devices_str);
uhd_usrp_find("", &devices_str);
if (find_string(devices_str, "b200")) {
// build args here
}
}
/* Create UHD handler */
uhd_error error = uhd_usrp_make(&handler->usrp, args);
if (error) {
uhd_usrp_last_error(handler->usrp, err_msg, 256);
fprintf(stderr, "Error opening UHD: %s\n", err_msg);
}
size_t channel = 0;
uhd_stream_args_t stream_args = {
.cpu_format = "fc32",
.otw_format = "sc16",
.args = "",
.channel_list = &channel,
.n_channels = 1
};
/* Initialize rx and tx stremers */
uhd_rx_streamer_make(&handler->rx_stream);
error = uhd_usrp_get_rx_stream(handler->usrp, &stream_args, handler->rx_stream);
if (error) {
uhd_rx_streamer_last_error(handler->rx_stream, err_msg, 256);
fprintf(stderr, "Error opening RX stream: %s\n", err_msg);
}
uhd_tx_streamer_make(&handler->tx_stream);
error = uhd_usrp_get_tx_stream(handler->usrp, &stream_args, handler->tx_stream);
if (error) {
uhd_tx_streamer_last_error(handler->tx_stream, err_msg, 256);
fprintf(stderr, "Error opening TX stream: %s\n", err_msg);
}
uhd_rx_streamer_num_channels(handler->rx_stream, &handler->rx_nof_samples);
uhd_tx_streamer_num_channels(handler->tx_stream, &handler->tx_nof_samples);
handler->tx_gain_same_rx = tx_gain_same_rx;
handler->tx_rx_gain_offset = 0.0;
uhd_meta_range_make(&handler->rx_gain_range);
uhd_usrp_get_rx_gain_range(handler->usrp, "", 0, handler->rx_gain_range);
// Make metadata objects for RX/TX
uhd_rx_metadata_make(&handler->rx_md);
uhd_rx_metadata_make(&handler->rx_md_first);
uhd_tx_metadata_make(&handler->tx_md, false, 0, 0, false, false);
/* Create auxiliary thread and mutexes for AGC */
if (create_thread_gain) {
if (pthread_mutex_init(&handler->mutex, NULL)) {
return -1;
}
if (pthread_cond_init(&handler->cond, NULL)) {
return -1;
}
if (pthread_create(&handler->thread_gain, NULL, thread_gain_fcn, handler)) {
perror("pthread_create");
return -1;
}
}
/* Find out if the master clock rate is configurable */
double cur_clock, new_clock;
uhd_usrp_get_master_clock_rate(handler->usrp, 0, &cur_clock);
printf("Trying to dynamically change Master clock...\n");
uhd_usrp_set_master_clock_rate(handler->usrp, cur_clock/2, 0);
uhd_usrp_get_master_clock_rate(handler->usrp, 0, &new_clock);
if (new_clock == cur_clock) {
handler->dynamic_rate = false;
/* Master clock rate is not configurable. Check if it is compatible with LTE */
int cur_clock_i = (int) cur_clock;
if (cur_clock_i % 1920000) {
fprintf(stderr, "Error: LTE sampling rates are not supported. Master clock rate is %.1f MHz\n", cur_clock/1e6);
return -1;
} else {
printf("Master clock is not configurable. Using standard symbol sizes and sampling rates.\n");
srslte_use_standard_symbol_size(true);
}
} else {
printf("Master clock is configurable. Using reduced symbol sizes and sampling rates.\n");
handler->dynamic_rate = true;
}
return 0;
}
int rf_uhd_close(void *h)
{
rf_uhd_stop_rx_stream(h);
/** Something else to close the USRP?? */
return 0;
}
void rf_uhd_set_master_clock_rate(void *h, double rate) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
if (handler->dynamic_rate) {
uhd_usrp_set_master_clock_rate(handler->usrp, rate, 0);
}
}
bool rf_uhd_is_master_clock_dynamic(void *h) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
return handler->dynamic_rate;
}
double rf_uhd_set_rx_srate(void *h, double freq)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_usrp_set_rx_rate(handler->usrp, freq, 0);
uhd_usrp_get_rx_rate(handler->usrp, 0, &freq);
return freq;
}
double rf_uhd_set_tx_srate(void *h, double freq)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_usrp_set_tx_rate(handler->usrp, freq, 0);
uhd_usrp_get_tx_rate(handler->usrp, 0, &freq);
handler->tx_rate = freq;
return freq;
}
double rf_uhd_set_rx_gain(void *h, double gain)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_usrp_set_rx_gain(handler->usrp, gain, 0, "");
uhd_usrp_get_rx_gain(handler->usrp, 0, "", &gain);
return gain;
}
double rf_uhd_set_tx_gain(void *h, double gain)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_usrp_set_tx_gain(handler->usrp, gain, 0, "");
uhd_usrp_get_tx_gain(handler->usrp, 0, "", &gain);
return gain;
}
double rf_uhd_get_rx_gain(void *h)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
double gain;
uhd_usrp_get_rx_gain(handler->usrp, 0, "", &gain);
return gain;
}
double rf_uhd_get_tx_gain(void *h)
{
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
double gain;
uhd_usrp_get_tx_gain(handler->usrp, 0, "", &gain);
return gain;
}
double rf_uhd_set_rx_freq(void *h, double freq)
{
uhd_tune_request_t tune_request = {
.target_freq = freq,
.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO,
.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO,
};
uhd_tune_result_t tune_result;
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_usrp_set_rx_freq(handler->usrp, &tune_request, 0, &tune_result);
uhd_usrp_get_rx_freq(handler->usrp, 0, &freq);
return freq;
}
double rf_uhd_set_tx_freq(void *h, double freq)
{
uhd_tune_request_t tune_request = {
.target_freq = freq,
.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO,
.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO,
};
uhd_tune_result_t tune_result;
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_usrp_set_tx_freq(handler->usrp, &tune_request, 0, &tune_result);
uhd_usrp_get_tx_freq(handler->usrp, 0, &freq);
return freq;
}
void rf_uhd_get_time(void *h, time_t *secs, double *frac_secs) {
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
uhd_usrp_get_time_now(handler->usrp, 0, secs, frac_secs);
}
int rf_uhd_recv_with_time(void *h,
void *data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs)
{
char err_msg[256];
rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h;
size_t rxd_samples;
uhd_rx_metadata_handle *md = &handler->rx_md_first;
if (blocking) {
int n = 0;
cf_t *data_c = (cf_t*) data;
do {
size_t rx_samples = handler->rx_nof_samples;
if (rx_samples > nsamples - n) {
rx_samples = nsamples - n;
}
void *buff = (void*) &data_c[n];
void **buffs_ptr = (void**) &buff;
uhd_error error = uhd_rx_streamer_recv(handler->rx_stream, buffs_ptr,
rx_samples, md, 3.0, false, &rxd_samples);
if (error) {
uhd_rx_streamer_last_error(handler->rx_stream, err_msg, 256);
fprintf(stderr, "Error receiving from UHD: %s\n", err_msg);
return -1;
}
md = &handler->rx_md;
n += rxd_samples;
} while (n < nsamples);
} else {
void **buffs_ptr = (void**) &data;
return uhd_rx_streamer_recv(handler->rx_stream, buffs_ptr,
nsamples, md, 0.0, false, &rxd_samples);
}
if (secs && frac_secs) {
uhd_rx_metadata_time_spec(handler->rx_md_first, secs, frac_secs);
}
return nsamples;
}
int rf_uhd_send_timed(void *h,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst)
{
rf_uhd_handler_t* handler = (rf_uhd_handler_t*) h;
char err_msg[256];
size_t txd_samples;
if (has_time_spec) {
uhd_tx_metadata_set_time_spec(&handler->tx_md, secs, frac_secs);
}
if (blocking) {
int n = 0;
cf_t *data_c = (cf_t*) data;
do {
size_t tx_samples = handler->tx_nof_samples;
// First packet is start of burst if so defined, others are never
if (n == 0) {
uhd_tx_metadata_set_start(&handler->tx_md, is_start_of_burst);
} else {
uhd_tx_metadata_set_start(&handler->tx_md, false);
}
// middle packets are never end of burst, last one as defined
if (nsamples - n > tx_samples) {
uhd_tx_metadata_set_end(&handler->tx_md, false);
} else {
tx_samples = nsamples - n;
uhd_tx_metadata_set_end(&handler->tx_md, is_end_of_burst);
}
void *buff = (void*) &data_c[n];
const void **buffs_ptr = (const void**) &buff;
uhd_error error = uhd_tx_streamer_send(handler->tx_stream, buffs_ptr,
tx_samples, &handler->tx_md, 3.0, &txd_samples);
if (error) {
uhd_tx_streamer_last_error(handler->tx_stream, err_msg, 256);
fprintf(stderr, "Error sending to UHD: %s\n", err_msg);
return -1;
}
// Increase time spec
uhd_tx_metadata_add_time_spec(&handler->tx_md, txd_samples/handler->tx_rate);
n += txd_samples;
} while (n < nsamples);
return nsamples;
} else {
const void **buffs_ptr = (const void**) &data;
uhd_tx_metadata_set_start(&handler->tx_md, is_start_of_burst);
uhd_tx_metadata_set_end(&handler->tx_md, is_end_of_burst);
return uhd_tx_streamer_send(handler->tx_stream, buffs_ptr, nsamples, &handler->tx_md, 0.0, &txd_samples);
}
}

@ -0,0 +1,117 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2015 Software Radio Systems Limited
*
* \section LICENSE
*
* This file is part of the srsLTE library.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include <stdbool.h>
#include <stdint.h>
#include "srslte/config.h"
#include "srslte/rf/rf.h"
SRSLTE_API int rf_uhd_open(char *args,
void **handler,
bool agc_thread,
bool tx_gain_same_rx);
SRSLTE_API int rf_uhd_close(void *h);
SRSLTE_API int rf_uhd_start_rx_stream(void *h);
SRSLTE_API int rf_uhd_start_rx_stream_nsamples(void *h,
uint32_t nsamples);
SRSLTE_API int rf_uhd_stop_rx_stream(void *h);
SRSLTE_API void rf_uhd_flush_buffer(void *h);
SRSLTE_API bool rf_uhd_has_rssi(void *h);
SRSLTE_API float rf_uhd_get_rssi(void *h);
SRSLTE_API bool rf_uhd_rx_wait_lo_locked(void *h);
SRSLTE_API void rf_uhd_set_master_clock_rate(void *h,
double rate);
SRSLTE_API bool rf_uhd_is_master_clock_dynamic(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 void rf_uhd_set_tx_rx_gain_offset(void *h,
double offset);
SRSLTE_API double rf_uhd_set_rx_gain_th(void *h,
double gain);
SRSLTE_API double rf_uhd_set_tx_gain_th(void *h,
double gain);
SRSLTE_API float rf_uhd_get_rx_gain_offset(void *h);
SRSLTE_API double rf_uhd_get_rx_gain(void *h);
SRSLTE_API double rf_uhd_get_tx_gain(void *h);
SRSLTE_API void rf_uhd_suppress_stdout(void *h);
SRSLTE_API void rf_uhd_register_msg_handler(void *h, rf_msg_handler_t msg_handler);
SRSLTE_API double rf_uhd_set_rx_freq(void *h,
double freq);
SRSLTE_API int rf_uhd_recv_with_time(void *h,
void *data,
uint32_t nsamples,
bool blocking,
time_t *secs,
double *frac_secs);
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 double rf_uhd_set_tx_freq(void *h,
double freq);
SRSLTE_API void rf_uhd_get_time(void *h,
time_t *secs,
double *frac_secs);
SRSLTE_API int rf_uhd_send_timed(void *h,
void *data,
int nsamples,
time_t secs,
double frac_secs,
bool has_time_spec,
bool blocking,
bool is_start_of_burst,
bool is_end_of_burst);

@ -88,6 +88,10 @@ int rf_recv_wrapper_cs(void *h, void *data, uint32_t nsamples, srslte_timestamp_
return rf_recv(h, data, nsamples, 1);
}
double rf_set_rx_gain_th_wrapper(void *h, double f) {
return rf_set_rx_gain_th((rf_t*) h, f);
}
/** This function is simply a wrapper to the ue_cell_search module for rf devices
* Return 1 if the MIB is decoded, 0 if not or -1 on error.
*/
@ -102,7 +106,7 @@ int rf_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell) {
}
if (config->init_agc > 0) {
srslte_ue_sync_start_agc(&ue_mib.ue_sync, rf_set_rx_gain_th, config->init_agc);
srslte_ue_sync_start_agc(&ue_mib.ue_sync, rf_set_rx_gain_th_wrapper, config->init_agc);
}
int srate = srslte_sampling_freq_hz(SRSLTE_UE_MIB_NOF_PRB);
@ -159,7 +163,7 @@ int rf_cell_search(void *uhd, cell_search_cfg_t *config,
}
if (config->init_agc > 0) {
srslte_ue_sync_start_agc(&cs.ue_sync, rf_set_rx_gain_th, config->init_agc);
srslte_ue_sync_start_agc(&cs.ue_sync, rf_set_rx_gain_th_wrapper, config->init_agc);
}
INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000);

@ -0,0 +1,45 @@
/* This file implements a few features not currently provided by the UHD C-API */
#include <uhd.h>
#include <uhd/usrp/multi_usrp.hpp>
extern "C" {
#include "srslte/rf/rf.h"
#include "uhd_c_api.h"
}
static rf_msg_handler_t msg_handler;
void translate_handler(uhd::msg::type_t type, const std::string & msg)
{
if(msg_handler)
msg_handler(msg.c_str());
}
void rf_uhd_register_msg_handler_c(rf_msg_handler_t new_handler)
{
msg_handler = new_handler;
uhd::msg::register_handler(translate_handler);
}
void uhd_tx_metadata_set_time_spec(uhd_tx_metadata_handle *md, time_t secs, double frac_secs)
{
(*md)->tx_metadata_cpp.time_spec = uhd::time_spec_t(secs, frac_secs);
}
void uhd_tx_metadata_set_start(uhd_tx_metadata_handle *md, bool is_start_of_burst)
{
(*md)->tx_metadata_cpp.start_of_burst = is_start_of_burst;
}
void uhd_tx_metadata_set_end(uhd_tx_metadata_handle *md, bool is_end_of_burst)
{
(*md)->tx_metadata_cpp.end_of_burst = is_end_of_burst;
}
void uhd_tx_metadata_add_time_spec(uhd_tx_metadata_handle *md, double frac_secs)
{
(*md)->tx_metadata_cpp.time_spec += frac_secs;
}

@ -0,0 +1,11 @@
#include <uhd.h>
#include "srslte/config.h"
#include "srslte/rf/rf.h"
/* Declare functions not currently provided by the C-API */
SRSLTE_API void rf_uhd_register_msg_handler_c(rf_msg_handler_t new_handler);
SRSLTE_API void uhd_tx_metadata_set_time_spec(uhd_tx_metadata_handle *md, time_t secs, double frac_secs);
SRSLTE_API void uhd_tx_metadata_set_start(uhd_tx_metadata_handle *md, bool is_start_of_burst);
SRSLTE_API void uhd_tx_metadata_set_end(uhd_tx_metadata_handle *md, bool is_end_of_burst);
SRSLTE_API void uhd_tx_metadata_add_time_spec(uhd_tx_metadata_handle *md, double frac_secs);

@ -47,8 +47,8 @@ void do_plots_sss(float *corr_m0, float *corr_m1);
bool disable_plots = false;
int cell_id = -1;
char *uhd_args="";
float uhd_gain=40.0, uhd_freq=-1.0;
char *rf_args="";
float rf_gain=40.0, rf_freq=-1.0;
int nof_frames = -1;
uint32_t fft_size=64;
float threshold = 0.4;
@ -57,8 +57,8 @@ srslte_cp_t cp=SRSLTE_CP_NORM;
void usage(char *prog) {
printf("Usage: %s [aedgtvnp] -f rx_frequency_hz -i cell_id\n", prog);
printf("\t-a UHD args [Default %s]\n", uhd_args);
printf("\t-g UHD Gain [Default %.2f dB]\n", uhd_gain);
printf("\t-a RF args [Default %s]\n", rf_args);
printf("\t-g RF Gain [Default %.2f dB]\n", rf_gain);
printf("\t-n nof_frames [Default %d]\n", nof_frames);
printf("\t-l N_id_2 to sync [Default use cell_id]\n");
printf("\t-e Extended CP [Default Normal]\n", fft_size);
@ -77,13 +77,13 @@ void parse_args(int argc, char **argv) {
while ((opt = getopt(argc, argv, "adgetvsfil")) != -1) {
switch (opt) {
case 'a':
uhd_args = argv[optind];
rf_args = argv[optind];
break;
case 'g':
uhd_gain = atof(argv[optind]);
rf_gain = atof(argv[optind]);
break;
case 'f':
uhd_freq = atof(argv[optind]);
rf_freq = atof(argv[optind]);
break;
case 't':
threshold = atof(argv[optind]);
@ -114,7 +114,7 @@ void parse_args(int argc, char **argv) {
exit(-1);
}
}
if (cell_id < 0 || uhd_freq < 0) {
if (cell_id < 0 || rf_freq < 0) {
usage(argv[0]);
exit(-1);
}
@ -124,7 +124,7 @@ void parse_args(int argc, char **argv) {
int main(int argc, char **argv) {
cf_t *buffer;
int frame_cnt, n;
void *uhd;
rf_t rf;
srslte_pss_synch_t pss;
srslte_cfo_t cfocorr, cfocorr64;
srslte_sss_synch_t sss;
@ -152,22 +152,22 @@ int main(int argc, char **argv) {
flen = srate*5/1000;
printf("Opening UHD device...\n");
if (rf_open(uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
printf("Opening RF device...\n");
if (rf_open(&rf, rf_args)) {
fprintf(stderr, "Error opening rf\n");
exit(-1);
}
if (srate < 10e6) {
rf_set_master_clock_rate(uhd, 4*srate);
rf_set_master_clock_rate(&rf, 4*srate);
} else {
rf_set_master_clock_rate(uhd, srate);
rf_set_master_clock_rate(&rf, srate);
}
printf("Set RX rate: %.2f MHz\n", rf_set_rx_srate(uhd, srate) / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(uhd, uhd_gain));
printf("Set RX freq: %.2f MHz\n", rf_set_rx_freq(uhd, uhd_freq) / 1000000);
rf_rx_wait_lo_locked(uhd);
printf("Set RX rate: %.2f MHz\n", rf_set_rx_srate(&rf, srate) / 1000000);
printf("Set RX gain: %.1f dB\n", rf_set_rx_gain(&rf, rf_gain));
printf("Set RX freq: %.2f MHz\n", rf_set_rx_freq(&rf, rf_freq) / 1000000);
rf_rx_wait_lo_locked(&rf);
buffer = malloc(sizeof(cf_t) * flen * 2);
if (!buffer) {
@ -197,7 +197,7 @@ int main(int argc, char **argv) {
printf("N_id_2: %d\n", N_id_2);
rf_start_rx_stream(uhd);
rf_start_rx_stream(&rf);
printf("Frame length %d samples\n", flen);
printf("PSS detection threshold: %.2f\n", threshold);
@ -218,7 +218,7 @@ int main(int argc, char **argv) {
ssync.fft_size = fft_size;
while(frame_cnt < nof_frames || nof_frames == -1) {
n = rf_recv(uhd, buffer, flen - peak_offset, 1);
n = rf_recv(&rf, buffer, flen - peak_offset, 1);
if (n < 0) {
fprintf(stderr, "Error receiving samples\n");
exit(-1);
@ -330,7 +330,7 @@ int main(int argc, char **argv) {
srslte_pss_synch_free(&pss);
free(buffer);
rf_close(uhd);
rf_close(&rf);
printf("Ok\n");
exit(0);

Loading…
Cancel
Save