From b86007249b2e5b20fa2a0f6260ef285a6a292c06 Mon Sep 17 00:00:00 2001 From: ismagom Date: Thu, 10 Dec 2015 17:27:03 +0100 Subject: [PATCH] Tested new UHD interface with srsLTE examples --- srslte/examples/cell_measurement.c | 2 + srslte/examples/pdsch_ue.c | 10 ++--- srslte/include/srslte/rf/rf_utils.h | 9 ++-- srslte/lib/rf/src/rf_imp.c | 64 ++++++++++++++++++----------- srslte/lib/rf/src/rf_uhd_imp.c | 54 ++++++++++++++---------- srslte/lib/rf/src/rf_utils.c | 48 +++++++++++----------- 6 files changed, 108 insertions(+), 79 deletions(-) diff --git a/srslte/examples/cell_measurement.c b/srslte/examples/cell_measurement.c index f37282f38..6d83c56a7 100644 --- a/srslte/examples/cell_measurement.c +++ b/srslte/examples/cell_measurement.c @@ -187,6 +187,8 @@ int main(int argc, char **argv) { rf_rx_wait_lo_locked(&rf); printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.rf_freq/1000000); + cell_detect_config.init_agc = (prog_args.rf_gain<0); + uint32_t ntrial=0; do { ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell); diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index f9669dca1..05adf37d7 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -50,7 +50,7 @@ cell_search_cfg_t cell_detect_config = { 10.0 // threshold }; #else -#warning Compiling pdsch_ue with no UHD support +#warning Compiling pdsch_ue with no RF support #endif //#define STDOUT_COMPACT @@ -300,14 +300,14 @@ int main(int argc, char **argv) { /* Set receiver gain */ if (prog_args.rf_gain > 0) { - printf("Opening UHD device...\n"); + 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(&rf, prog_args.rf_gain); } else { - printf("Opening UHD device with threaded RX Gain control ...\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); @@ -325,9 +325,9 @@ int main(int argc, char **argv) { rf_set_master_clock_rate(&rf, 30.72e6); /* set receiver frequency */ + printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.rf_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 { @@ -362,7 +362,7 @@ int main(int argc, char **argv) { exit(-1); } - INFO("Stopping UHD and flushing buffer...\r",0); + INFO("Stopping RF and flushing buffer...\r",0); rf_stop_rx_stream(&rf); rf_flush_buffer(&rf); } diff --git a/srslte/include/srslte/rf/rf_utils.h b/srslte/include/srslte/rf/rf_utils.h index 3e5192d47..101309200 100644 --- a/srslte/include/srslte/rf/rf_utils.h +++ b/srslte/include/srslte/rf/rf_utils.h @@ -26,6 +26,7 @@ #include "srslte/srslte.h" +#include "srslte/rf/rf.h" typedef struct SRSLTE_API { uint32_t max_frames_pbch; // maximum number of 5ms frames to capture for MIB decoding @@ -34,23 +35,23 @@ typedef struct SRSLTE_API { float init_agc; // 0 or negative to disable AGC } cell_search_cfg_t; -SRSLTE_API int rf_rssi_scan(void *uhd, +SRSLTE_API int rf_rssi_scan(rf_t *rf, float *freqs, float *rssi, int nof_bands, double fs, int nsamp); -SRSLTE_API int rf_mib_decoder(void *uhd, +SRSLTE_API int rf_mib_decoder(rf_t *rf, cell_search_cfg_t *config, srslte_cell_t *cell); -SRSLTE_API int rf_cell_search(void *uhd, +SRSLTE_API int rf_cell_search(rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell); -SRSLTE_API int rf_search_and_decode_mib(void *uhd, +SRSLTE_API int rf_search_and_decode_mib(rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell); diff --git a/srslte/lib/rf/src/rf_imp.c b/srslte/lib/rf/src/rf_imp.c index aeadc9025..137f10f89 100644 --- a/srslte/lib/rf/src/rf_imp.c +++ b/srslte/lib/rf/src/rf_imp.c @@ -30,6 +30,44 @@ #include "srslte/srslte.h" #include "rf_dev.h" +int rf_get_available_devices(char **devnames, int max_strlen) { + int i=0; + while(available_devices[i]->name) { + strncpy(devnames[i], available_devices[i]->name, max_strlen); + i++; + } + return i; +} + + +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); + } + i++; + } + printf("Device %s not found. Switching to auto mode\n", devname); + } + + /* If in auto mode or provided device not found, 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; + } + i++; + } + fprintf(stderr, "No compatible RF frontend found\n"); + return -1; +} + + bool rf_rx_wait_lo_locked(rf_t *rf) { return ((rf_dev_t*) rf->dev)->rf_rx_wait_lo_locked(rf->handler); @@ -80,30 +118,6 @@ 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); @@ -111,7 +125,7 @@ int rf_open(rf_t *h, char *args) 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); + return rf_open_devname(h, NULL, args, true, tx_gain_same_rx); } int rf_close(rf_t *rf) diff --git a/srslte/lib/rf/src/rf_uhd_imp.c b/srslte/lib/rf/src/rf_uhd_imp.c index 83f1815b4..a6b9eda9b 100644 --- a/srslte/lib/rf/src/rf_uhd_imp.c +++ b/srslte/lib/rf/src/rf_uhd_imp.c @@ -79,7 +79,7 @@ static bool find_string(uhd_string_vector_handle h, char *str) uhd_string_vector_size(h, &n); for (int i=0;iusrp, 0, &mb_sensors); uhd_usrp_get_rx_sensor_names(handler->usrp, 0, &rx_sensors); @@ -125,7 +124,7 @@ bool rf_uhd_rx_wait_lo_locked(void *h) } double report = 0.0; - while (isLocked(handler, sensor_name, &value_h) && report < 30.0) { + while (!isLocked(handler, sensor_name, &value_h) && report < 30.0) { report += 0.1; usleep(1000); } @@ -173,6 +172,7 @@ void rf_uhd_flush_buffer(void *h) bool rf_uhd_has_rssi(void *h) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; uhd_string_vector_handle rx_sensors; + uhd_string_vector_make(&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); @@ -182,6 +182,7 @@ bool rf_uhd_has_rssi(void *h) { float rf_uhd_get_rssi(void *h) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; uhd_sensor_value_handle value; + uhd_sensor_value_make_from_realnum(&value, "rssi", 0, "dBm", "%f"); uhd_usrp_get_rx_sensor(handler->usrp, "rssi", 0, &value); double val_out; uhd_sensor_value_to_realnum(value, &val_out); @@ -229,6 +230,8 @@ static void* thread_gain_fcn(void *h) { return NULL; } +static char uhd_args[1024]; + int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same_rx) { char err_msg[256]; @@ -244,24 +247,31 @@ int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same /* 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 + /* Set correct options for the USRP device */ + uhd_string_vector_handle devices_str; + uhd_string_vector_make(&devices_str); + uhd_usrp_find("", &devices_str); + + /* If device type or name not given in args, choose a B200 */ + if (!strstr(args, "type") && !strstr(args, "name")) { + // If B200 is available, use it + if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) { + snprintf(uhd_args, 1024, "type=b200,recv_frame_size=9232,num_recv_frames=64,send_frame_size=9232,num_send_frames=64,%s", args); } + // If we explicitly define a B200 but do not give frame arguments, define them + } else if (strstr(args, "type=b200") && !strstr(args, "recv_frame_size")) { + snprintf(uhd_args, 1024, "recv_frame_size=9232,num_recv_frames=64,send_frame_size=9232,num_send_frames=64,%s", args); } /* Create UHD handler */ - uhd_error error = uhd_usrp_make(&handler->usrp, args); + printf("Opening USRP with args: %s\n", uhd_args); + uhd_error error = uhd_usrp_make(&handler->usrp, uhd_args); if (error) { uhd_usrp_last_error(handler->usrp, err_msg, 256); fprintf(stderr, "Error opening UHD: %s\n", err_msg); + return -1; } - + size_t channel = 0; uhd_stream_args_t stream_args = { .cpu_format = "fc32", @@ -277,17 +287,19 @@ int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same if (error) { uhd_rx_streamer_last_error(handler->rx_stream, err_msg, 256); fprintf(stderr, "Error opening RX stream: %s\n", err_msg); + return -1; } 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); + return -1; } - uhd_rx_streamer_num_channels(handler->rx_stream, &handler->rx_nof_samples); - uhd_tx_streamer_num_channels(handler->tx_stream, &handler->tx_nof_samples); - + uhd_rx_streamer_max_num_samps(handler->rx_stream, &handler->rx_nof_samples); + uhd_tx_streamer_max_num_samps(handler->tx_stream, &handler->tx_nof_samples); + handler->tx_gain_same_rx = tx_gain_same_rx; handler->tx_rx_gain_offset = 0.0; uhd_meta_range_make(&handler->rx_gain_range); @@ -306,13 +318,12 @@ int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same 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); @@ -334,7 +345,7 @@ int rf_uhd_open(char *args, void **h, bool create_thread_gain, bool tx_gain_same printf("Master clock is configurable. Using reduced symbol sizes and sampling rates.\n"); handler->dynamic_rate = true; } - + return 0; } @@ -459,7 +470,7 @@ int rf_uhd_recv_with_time(void *h, 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; } @@ -467,6 +478,7 @@ int rf_uhd_recv_with_time(void *h, 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); diff --git a/srslte/lib/rf/src/rf_utils.c b/srslte/lib/rf/src/rf_utils.c index 15950fec4..d045cac0f 100644 --- a/srslte/lib/rf/src/rf_utils.c +++ b/srslte/lib/rf/src/rf_utils.c @@ -39,32 +39,32 @@ #include "srslte/rf/rf.h" #include "srslte/rf/rf_utils.h" -int rf_rssi_scan(void *uhd, float *freqs, float *rssi, int nof_bands, double fs, int nsamp) { +int rf_rssi_scan(rf_t *rf, float *freqs, float *rssi, int nof_bands, double fs, int nsamp) { int i, j; int ret = -1; - _Complex float *buffer; + cf_t *buffer; double f; - buffer = calloc(nsamp, sizeof(_Complex float)); + buffer = calloc(nsamp, sizeof(cf_t)); if (!buffer) { goto free_and_exit; } - rf_set_rx_gain(uhd, 20.0); - rf_set_rx_srate(uhd, fs); + rf_set_rx_gain(rf, 20.0); + rf_set_rx_srate(rf, fs); for (i=0;iid, cell->cp, rf_recv_wrapper_cs, uhd)) { + if (srslte_ue_mib_sync_init(&ue_mib, cell->id, cell->cp, rf_recv_wrapper_cs, (void*) rf)) { fprintf(stderr, "Error initiating srslte_ue_mib_sync\n"); goto clean_exit; } @@ -111,10 +111,10 @@ int rf_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell) { int srate = srslte_sampling_freq_hz(SRSLTE_UE_MIB_NOF_PRB); INFO("Setting sampling frequency %.2f MHz for PSS search\n", (float) srate/1000000); - rf_set_rx_srate(uhd, (float) srate); + rf_set_rx_srate(rf, (float) srate); INFO("Starting receiver...\n", 0); - rf_start_rx_stream(uhd); + rf_start_rx_stream(rf); /* Find and decody MIB */ ret = srslte_ue_mib_sync_decode(&ue_mib, config->max_frames_pss, bch_payload, &cell->nof_ports, NULL); @@ -133,7 +133,7 @@ int rf_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell) { clean_exit: - rf_stop_rx_stream(uhd); + rf_stop_rx_stream(rf); srslte_ue_mib_sync_free(&ue_mib); return ret; @@ -141,7 +141,7 @@ clean_exit: /** This function is simply a wrapper to the ue_cell_search module for rf devices */ -int rf_cell_search(void *uhd, cell_search_cfg_t *config, +int rf_cell_search(rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell) { int ret = SRSLTE_ERROR; @@ -150,7 +150,7 @@ int rf_cell_search(void *uhd, cell_search_cfg_t *config, bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); - if (srslte_ue_cellsearch_init(&cs, rf_recv_wrapper_cs, uhd)) { + if (srslte_ue_cellsearch_init(&cs, rf_recv_wrapper_cs, (void*) rf)) { fprintf(stderr, "Error initiating UE cell detect\n"); return SRSLTE_ERROR; } @@ -167,10 +167,10 @@ int rf_cell_search(void *uhd, cell_search_cfg_t *config, } 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); /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ uint32_t max_peak_cell = 0; @@ -211,7 +211,7 @@ int rf_cell_search(void *uhd, cell_search_cfg_t *config, config->init_agc = srslte_agc_get_gain(&cs.ue_sync.agc); } - rf_stop_rx_stream(uhd); + rf_stop_rx_stream(rf); srslte_ue_cellsearch_free(&cs); return ret; @@ -223,15 +223,15 @@ int rf_cell_search(void *uhd, cell_search_cfg_t *config, * 0 if no cell was found or MIB could not be decoded, * -1 on error */ -int rf_search_and_decode_mib(void *uhd, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell) +int rf_search_and_decode_mib(rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell) { int ret = SRSLTE_ERROR; printf("Searching for cell...\n"); - ret = rf_cell_search(uhd, config, force_N_id_2, cell); + ret = rf_cell_search(rf, config, force_N_id_2, cell); if (ret > 0) { printf("Decoding PBCH for cell %d (N_id_2=%d)\n", cell->id, cell->id%3); - ret = rf_mib_decoder(uhd, config, cell); + ret = rf_mib_decoder(rf, config, cell); if (ret < 0) { fprintf(stderr, "Could not decode PBCH from CELL ID %d\n", cell->id); return SRSLTE_ERROR;