diff --git a/cmake/modules/FindUHD.cmake b/cmake/modules/FindUHD.cmake index fc178030d..a5b8834cd 100644 --- a/cmake/modules/FindUHD.cmake +++ b/cmake/modules/FindUHD.cmake @@ -4,7 +4,7 @@ IF(NOT UHD_FOUND) FIND_PATH( UHD_INCLUDE_DIRS - NAMES uhd/config.hpp + NAMES uhd.h HINTS $ENV{UHD_DIR}/include PATHS /usr/local/include /usr/include diff --git a/cmake/modules/FindbladeRF.cmake b/cmake/modules/FindbladeRF.cmake new file mode 100644 index 000000000..b154a9cf1 --- /dev/null +++ b/cmake/modules/FindbladeRF.cmake @@ -0,0 +1,27 @@ +if(NOT BLADERF_FOUND) + pkg_check_modules (BLADERF_PKG libbladeRF) + find_path(BLADERF_INCLUDE_DIRS NAMES libbladeRF.h + PATHS + ${BLADERF_PKG_INCLUDE_DIRS} + /usr/include + /usr/local/include + ) + + find_library(BLADERF_LIBRARIES NAMES bladeRF + PATHS + ${BLADERF_PKG_LIBRARY_DIRS} + /usr/lib + /usr/local/lib + ) + +if(BLADERF_INCLUDE_DIRS AND BLADERF_LIBRARIES) + set(BLADERF_FOUND TRUE CACHE INTERNAL "libbladeRF found") + message(STATUS "Found libbladeRF: ${BLADERF_INCLUDE_DIRS}, ${BLADERF_LIBRARIES}") +else(BLADERF_INCLUDE_DIRS AND BLADERF_LIBRARIES) + set(BLADERF_FOUND FALSE CACHE INTERNAL "libbladeRF found") + message(STATUS "libbladeRF not found.") +endif(BLADERF_INCLUDE_DIRS AND BLADERF_LIBRARIES) + +mark_as_advanced(BLADERF_LIBRARIES BLADERF_INCLUDE_DIRS) + +endif(NOT BLADERF_FOUND) diff --git a/cmake/modules/FindopenLTE.cmake b/cmake/modules/FindopenLTE.cmake deleted file mode 100644 index e48758940..000000000 --- a/cmake/modules/FindopenLTE.cmake +++ /dev/null @@ -1,52 +0,0 @@ -# - Try to find openLTE's liblte - -find_package(PkgConfig) -pkg_check_modules(PC_OPENLTE QUIET srslte) -set(OPENLTE_DEFINITIONS ${PC_OPENLTE_CFLAGS_OTHER}) - -FIND_PATH( - OPENLTE_LIBLTE_DIRS - NAMES liblte_common.h typedefs.h - HINTS ${PC_OPENLTE_SRCDIR}/liblte/hdr - ${PC_OPENLTE_INCLUDEDIR} - ${PC_OPENLTE_INCLUDE_DIRS} - $ENV{OPENLTE_DIR}/liblte/hdr - PATHS /usr/local/include - /usr/include -) - -FIND_PATH( - OPENLTE_COMMON_DIRS - NAMES typedefs.h - HINTS ${PC_OPENLTE_SRCDIR}/cmn_hdr - ${PC_OPENLTE_INCLUDEDIR} - ${PC_OPENLTE_INCLUDE_DIRS} - $ENV{OPENLTE_DIR}/liblte/hdr - PATHS /usr/local/include - /usr/include -) - -FIND_LIBRARY( - OPENLTE_LIBRARIES - NAMES lte - HINTS ${PC_OPENLTE_BUILDDIR}/liblte - ${CMAKE_INSTALL_PREFIX}/lib - ${CMAKE_INSTALL_PREFIX}/lib64 - $ENV{OPENLTE_DIR}/lib - PATHS /usr/local/lib - /usr/local/lib64 - /usr/lib - /usr/lib64 -) - -IF(OPENLTE_LIBLTE_DIRS AND OPENLTE_COMMON_DIRS) - SET(OPENLTE_INCLUDE_DIRS ${OPENLTE_LIBLTE_DIRS} ${OPENLTE_COMMON_DIRS}) -ENDIF(OPENLTE_LIBLTE_DIRS AND OPENLTE_COMMON_DIRS) - -message(STATUS "OPENLTE LIBRARIES " ${OPENLTE_LIBRARIES}) -message(STATUS "OPENLTE INCLUDE DIRS " ${OPENLTE_INCLUDE_DIRS}) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENLTE DEFAULT_MSG OPENLTE_LIBRARIES OPENLTE_INCLUDE_DIRS) -MARK_AS_ADVANCED(OPENLTE_LIBRARIES OPENLTE_INCLUDE_DIRS) - diff --git a/cmake/modules/SRSLTEPackage.cmake b/cmake/modules/SRSLTEPackage.cmake index eb059e0b1..3fd26db8a 100644 --- a/cmake/modules/SRSLTEPackage.cmake +++ b/cmake/modules/SRSLTEPackage.cmake @@ -5,9 +5,9 @@ SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.6), libgcc1 (>= 1:4.1), libboost SET(CPACK_PACKAGE_CONTACT "Ismael Gomez ") SET(CPACK_PACKAGE_VENDOR "Software Radio Systems Limited") -SET(CPACK_PACKAGE_VERSION_MAJOR "0") -SET(CPACK_PACKAGE_VERSION_MINOR "1") -SET(CPACK_PACKAGE_VERSION_PATCH "0") +SET(CPACK_PACKAGE_VERSION_MAJOR ${SRSLTE_VERSION_MAJOR}) +SET(CPACK_PACKAGE_VERSION_MINOR ${SRSLTE_VERSION_MINOR}) +SET(CPACK_PACKAGE_VERSION_PATCH ${SRSLTE_VERSION_PATCH}) SET(VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") ######################################################################## diff --git a/cmake/modules/SRSLTEVersion.cmake b/cmake/modules/SRSLTEVersion.cmake index 86d6cbd8f..5f233cc2e 100644 --- a/cmake/modules/SRSLTEVersion.cmake +++ b/cmake/modules/SRSLTEVersion.cmake @@ -19,6 +19,6 @@ # SET(SRSLTE_VERSION_MAJOR 001) -SET(SRSLTE_VERSION_MINOR 000) +SET(SRSLTE_VERSION_MINOR 001) SET(SRSLTE_VERSION_PATCH 000) SET(SRSLTE_VERSION_STRING "${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR}.${SRSLTE_VERSION_PATCH}") diff --git a/srslte/CMakeLists.txt b/srslte/CMakeLists.txt index 53f0412f9..cb1c27107 100644 --- a/srslte/CMakeLists.txt +++ b/srslte/CMakeLists.txt @@ -43,6 +43,13 @@ ADD_CUSTOM_TARGET (add_srslte_headers SOURCES ${HEADERS_ALL}) # Find Dependencies ######################################################################## FIND_PACKAGE(UHD) +FIND_PACKAGE(bladeRF) + +IF(BLADERF_FOUND OR UHD_FOUND) + set(RF_FOUND TRUE CACHE INTERNAL "RF frontend found") +ELSE(BLADERF_FOUND OR UHD_FOUND) + set(RF_FOUND FALSE CACHE INTERNAL "RF frontend found") +ENDIF(BLADERF_FOUND OR UHD_FOUND) ######################################################################## # Add subdirectories diff --git a/srslte/examples/CMakeLists.txt b/srslte/examples/CMakeLists.txt index d2b446ef2..bf0f357e7 100644 --- a/srslte/examples/CMakeLists.txt +++ b/srslte/examples/CMakeLists.txt @@ -40,12 +40,12 @@ target_link_libraries(pdsch_ue srslte pthread) add_executable(pdsch_enodeb pdsch_enodeb.c) target_link_libraries(pdsch_enodeb srslte pthread) -IF(UHD_FOUND) - target_link_libraries(pdsch_ue srslte_uhd) - target_link_libraries(pdsch_enodeb srslte_uhd) -ELSE(UHD_FOUND) - add_definitions(-DDISABLE_UHD) -ENDIF(UHD_FOUND) +IF(RF_FOUND) + target_link_libraries(pdsch_ue srslte_rf) + target_link_libraries(pdsch_enodeb srslte_rf) +ELSE(RF_FOUND) + add_definitions(-DDISABLE_RF) +ENDIF(RF_FOUND) FIND_PACKAGE(SRSGUI) @@ -61,28 +61,28 @@ ENDIF(SRSGUI_FOUND) # These examples need the UHD driver ################################################################# -IF(UHD_FOUND) +IF(RF_FOUND) add_executable(cell_search cell_search.c) - target_link_libraries(cell_search srslte srslte_uhd) + target_link_libraries(cell_search srslte srslte_rf) add_executable(cell_measurement cell_measurement.c) - target_link_libraries(cell_measurement srslte srslte_uhd) + target_link_libraries(cell_measurement srslte srslte_rf) add_executable(usrp_capture usrp_capture.c) - target_link_libraries(usrp_capture srslte srslte_uhd) + target_link_libraries(usrp_capture srslte srslte_rf) add_executable(usrp_capture_sync usrp_capture_sync.c) - target_link_libraries(usrp_capture_sync srslte srslte_uhd) + target_link_libraries(usrp_capture_sync srslte srslte_rf) add_executable(usrp_txrx usrp_txrx.c) - target_link_libraries(usrp_txrx srslte srslte_uhd) + target_link_libraries(usrp_txrx srslte srslte_rf) - MESSAGE(STATUS " UHD examples will be installed.") + MESSAGE(STATUS " examples will be installed.") -ELSE(UHD_FOUND) - MESSAGE(STATUS " UHD examples NOT INSTALLED.") -ENDIF(UHD_FOUND) +ELSE(RF_FOUND) + MESSAGE(STATUS " examples will NOT BE INSTALLED.") +ENDIF(RF_FOUND) # Add subdirectories add_subdirectory(tutorial_examples) diff --git a/srslte/examples/cell_measurement.c b/srslte/examples/cell_measurement.c index 148d40a67..62084a335 100644 --- a/srslte/examples/cell_measurement.c +++ b/srslte/examples/cell_measurement.c @@ -36,8 +36,8 @@ #include #include "srslte/srslte.h" -#include "srslte/cuhd/cuhd.h" -#include "srslte/cuhd/cuhd_utils.h" +#include "srslte/rf/rf.h" +#include "srslte/rf/rf_utils.h" cell_search_cfg_t cell_detect_config = { 5000, // maximum number of frames to receive for MIB decoding @@ -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; } @@ -123,9 +123,9 @@ void sig_int_handler(int signo) } } -int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *q) { +int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *q) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return cuhd_recv(h, data, nsamples, 1); + return srslte_rf_recv(h, data, nsamples, 1); } enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state; @@ -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; + srslte_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 (cuhd_open(prog_args.uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); - exit(-1); - } - cuhd_set_rx_gain(uhd, prog_args.uhd_gain); + printf("Opening RF device...\n"); + if (srslte_rf_open(&rf, prog_args.rf_args)) { + fprintf(stderr, "Error opening rf\n"); + exit(-1); + } + if (prog_args.rf_gain > 0) { + srslte_rf_set_rx_gain(&rf, prog_args.rf_gain); } else { - printf("Opening UHD device with threaded RX Gain control ...\n"); - if (cuhd_open_th(prog_args.uhd_args, &uhd, false)) { - fprintf(stderr, "Error opening uhd\n"); + printf("Starting AGC thread...\n"); + if (srslte_rf_start_gain_thread(&rf, false)) { + fprintf(stderr, "Error opening rf\n"); exit(-1); } - cuhd_set_rx_gain(uhd, 50); + srslte_rf_set_rx_gain(&rf, 50); } sigset_t sigset; @@ -180,16 +180,18 @@ int main(int argc, char **argv) { sigprocmask(SIG_UNBLOCK, &sigset, NULL); signal(SIGINT, sig_int_handler); - cuhd_set_master_clock_rate(uhd, 30.72e6); + srslte_rf_set_master_clock_rate(&rf, 30.72e6); /* set receiver frequency */ - cuhd_set_rx_freq(uhd, (double) prog_args.uhd_freq); - cuhd_rx_wait_lo_locked(uhd); - printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000); + srslte_rf_set_rx_freq(&rf, (double) prog_args.rf_freq); + srslte_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 = cuhd_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 +208,13 @@ int main(int argc, char **argv) { int srate = srslte_sampling_freq_hz(cell.nof_prb); if (srate != -1) { if (srate < 10e6) { - cuhd_set_master_clock_rate(uhd, 4*srate); + srslte_rf_set_master_clock_rate(&rf, 4*srate); } else { - cuhd_set_master_clock_rate(uhd, srate); + srslte_rf_set_master_clock_rate(&rf, srate); } printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000); - float srate_uhd = cuhd_set_rx_srate(uhd, (double) srate); - if (srate_uhd != srate) { + float srate_rf = srslte_rf_set_rx_srate(&rf, (double) srate); + if (srate_rf != srate) { fprintf(stderr, "Could not set sampling rate\n"); exit(-1); } @@ -221,11 +223,11 @@ int main(int argc, char **argv) { exit(-1); } - INFO("Stopping UHD and flushing buffer...\n",0); - cuhd_stop_rx_stream(uhd); - cuhd_flush_buffer(uhd); + INFO("Stopping RF and flushing buffer...\n",0); + srslte_rf_stop_rx_stream(&rf); + srslte_rf_flush_buffer(&rf); - if (srslte_ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper, uhd)) { + if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); return -1; } @@ -261,7 +263,7 @@ int main(int argc, char **argv) { ce[i] = srslte_vec_malloc(sizeof(cf_t) * sf_re); } - cuhd_start_rx_stream(uhd); + srslte_rf_start_rx_stream(&rf); float rx_gain_offset = 0; @@ -333,10 +335,10 @@ int main(int argc, char **argv) { if ((nframes%100) == 0 || rx_gain_offset == 0) { - if (cuhd_has_rssi(uhd)) { - rx_gain_offset = 10*log10(rssi)-cuhd_get_rssi(uhd); + if (srslte_rf_has_rssi(&rf)) { + rx_gain_offset = 10*log10(rssi)-srslte_rf_get_rssi(&rf); } else { - rx_gain_offset = cuhd_get_rx_gain(uhd); + rx_gain_offset = srslte_rf_get_rx_gain(&rf); } } @@ -373,7 +375,7 @@ int main(int argc, char **argv) { } // Main loop srslte_ue_sync_free(&ue_sync); - cuhd_close(uhd); + srslte_rf_close(&rf); printf("\nBye\n"); exit(0); } diff --git a/srslte/examples/cell_search.c b/srslte/examples/cell_search.c index 7739ce9a7..6096b5c74 100644 --- a/srslte/examples/cell_search.c +++ b/srslte/examples/cell_search.c @@ -37,11 +37,11 @@ #include "srslte/srslte.h" -#include "srslte/cuhd/cuhd_utils.h" +#include "srslte/rf/rf_utils.h" -#ifndef DISABLE_UHD -#include "srslte/cuhd/cuhd.h" +#ifndef DISABLE_RF +#include "srslte/rf/rf.h" #endif #define MHZ 1000000 @@ -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++; @@ -123,9 +123,9 @@ void parse_args(int argc, char **argv) { } } -int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { +int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return cuhd_recv(h, data, nsamples, 1); + return srslte_rf_recv((srslte_rf_t*) h, data, nsamples, 1); } bool go_exit = false; @@ -138,9 +138,13 @@ void sig_int_handler(int signo) } } +double srslte_rf_set_rx_gain_wrapper(void *h, double f) { + return srslte_rf_set_rx_gain((srslte_rf_t*) h, f); +} + int main(int argc, char **argv) { int n; - void *uhd; + srslte_rf_t rf; srslte_ue_cellsearch_t cs; srslte_ue_cellsearch_result_t found_cells[3]; int nof_freqs; @@ -150,26 +154,26 @@ int main(int argc, char **argv) { parse_args(argc, argv); + printf("Opening RF device...\n"); + if (srslte_rf_open(&rf, rf_args)) { + fprintf(stderr, "Error opening rf\n"); + exit(-1); + } if (!config.init_agc) { - printf("Opening UHD device...\n"); - if (cuhd_open(uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); - exit(-1); - } - cuhd_set_rx_gain(uhd, uhd_gain); + srslte_rf_set_rx_gain(&rf, rf_gain); } else { - printf("Opening UHD device with threaded RX Gain control ...\n"); - if (cuhd_open_th(uhd_args, &uhd, false)) { - fprintf(stderr, "Error opening uhd\n"); + printf("Starting AGC thread...\n"); + if (srslte_rf_start_gain_thread(&rf, false)) { + fprintf(stderr, "Error opening rf\n"); exit(-1); } - cuhd_set_rx_gain(uhd, 50); + srslte_rf_set_rx_gain(&rf, 50); } - cuhd_set_master_clock_rate(uhd, 30.72e6); + srslte_rf_set_master_clock_rate(&rf, 30.72e6); - // Supress UHD messages - cuhd_suppress_stdout(); + // Supress RF messages + srslte_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;freqfile_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; @@ -118,13 +118,13 @@ 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_UHD - printf("\t-a UHD args [Default %s]\n", args->uhd_args); - printf("\t-g UHD fix RX gain [Default AGC]\n"); +#ifndef DISABLE_RF + 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 = strtod(argv[optind], NULL); 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); } @@ -240,11 +240,16 @@ void sig_int_handler(int signo) } } -#ifndef DISABLE_UHD -int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { +#ifndef DISABLE_RF +int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return cuhd_recv(h, data, nsamples, 1); + return srslte_rf_recv(h, data, nsamples, 1); } + +double srslte_rf_set_rx_gain_th_wrapper(void *h, double f) { + return srslte_rf_set_rx_gain_th((srslte_rf_t*) h, f); +} + #endif extern float mean_exec_time; @@ -264,8 +269,8 @@ int main(int argc, char **argv) { srslte_cell_t cell; int64_t sf_cnt; srslte_ue_mib_t ue_mib; -#ifndef DISABLE_UHD - void *uhd; +#ifndef DISABLE_RF + srslte_rf_t rf; #endif uint32_t nof_trials = 0; int n; @@ -290,24 +295,24 @@ int main(int argc, char **argv) { srslte_netsink_set_nonblocking(&net_sink_signal); } -#ifndef DISABLE_UHD +#ifndef DISABLE_RF if (!prog_args.input_file_name) { + printf("Opening RF device...\n"); + if (srslte_rf_open(&rf, prog_args.rf_args)) { + fprintf(stderr, "Error opening rf\n"); + exit(-1); + } /* Set receiver gain */ - if (prog_args.uhd_gain > 0) { - printf("Opening UHD device...\n"); - if (cuhd_open(prog_args.uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); - exit(-1); - } - cuhd_set_rx_gain(uhd, prog_args.uhd_gain); + if (prog_args.rf_gain > 0) { + srslte_rf_set_rx_gain(&rf, prog_args.rf_gain); } else { - printf("Opening UHD device with threaded RX Gain control ...\n"); - if (cuhd_open_th(prog_args.uhd_args, &uhd, false)) { - fprintf(stderr, "Error opening uhd\n"); + printf("Starting AGC thread...\n"); + if (srslte_rf_start_gain_thread(&rf, false)) { + fprintf(stderr, "Error opening rf\n"); exit(-1); } - cuhd_set_rx_gain(uhd, 50); + srslte_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); - cuhd_set_master_clock_rate(uhd, 30.72e6); + srslte_rf_set_master_clock_rate(&rf, 30.72e6); /* set receiver frequency */ - cuhd_set_rx_freq(uhd, (double) prog_args.uhd_freq); - cuhd_rx_wait_lo_locked(uhd); - printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000); + printf("Tunning receiver to %.3f MHz\n", prog_args.rf_freq/1000000); + srslte_rf_set_rx_freq(&rf, prog_args.rf_freq); + srslte_rf_rx_wait_lo_locked(&rf); uint32_t ntrial=0; do { - ret = cuhd_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) { - cuhd_set_master_clock_rate(uhd, 4*srate); + srslte_rf_set_master_clock_rate(&rf, 4*srate); } else { - cuhd_set_master_clock_rate(uhd, srate); + srslte_rf_set_master_clock_rate(&rf, srate); } printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000); - float srate_uhd = cuhd_set_rx_srate(uhd, (double) srate); - if (srate_uhd != srate) { + float srate_rf = srslte_rf_set_rx_srate(&rf, (double) srate); + if (srate_rf != srate) { fprintf(stderr, "Could not set sampling rate\n"); exit(-1); } @@ -357,9 +362,9 @@ int main(int argc, char **argv) { exit(-1); } - INFO("Stopping UHD and flushing buffer...\r",0); - cuhd_stop_rx_stream(uhd); - cuhd_flush_buffer(uhd); + INFO("Stopping RF and flushing buffer...\r",0); + srslte_rf_stop_rx_stream(&rf); + srslte_rf_flush_buffer(&rf); } #endif @@ -380,8 +385,8 @@ int main(int argc, char **argv) { } } else { -#ifndef DISABLE_UHD - if (srslte_ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper, uhd)) { +#ifndef DISABLE_RF + if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); exit(-1); } @@ -413,9 +418,9 @@ int main(int argc, char **argv) { } #endif -#ifndef DISABLE_UHD +#ifndef DISABLE_RF if (!prog_args.input_file_name) { - cuhd_start_rx_stream(uhd); + srslte_rf_start_rx_stream(&rf); } #endif @@ -424,9 +429,9 @@ int main(int argc, char **argv) { float rsrp=0.0, rsrq=0.0, noise=0.0; bool decode_pdsch = false; -#ifndef DISABLE_UHD - if (prog_args.uhd_gain < 0) { - srslte_ue_sync_start_agc(&ue_sync, cuhd_set_rx_gain_th, cell_detect_config.init_agc); +#ifndef DISABLE_RF + if (prog_args.rf_gain < 0) { + srslte_ue_sync_start_agc(&ue_sync, srslte_rf_set_rx_gain_th_wrapper, cell_detect_config.init_agc); } #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)); } @@ -540,7 +545,7 @@ int main(int argc, char **argv) { "PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%%\r", srslte_ue_sync_get_cfo(&ue_sync)/1000, - 10*log10(rsrp/noise), + 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), 100*(1-(float) ue_dl.nof_detected/nof_trials), (float) 100*ue_dl.pkt_errors/ue_dl.pkts_total); } @@ -589,10 +594,10 @@ int main(int argc, char **argv) { srslte_ue_dl_free(&ue_dl); srslte_ue_sync_free(&ue_sync); -#ifndef DISABLE_UHD +#ifndef DISABLE_RF if (!prog_args.input_file_name) { srslte_ue_mib_free(&ue_mib); - cuhd_close(uhd); + srslte_rf_close(&rf); } #endif printf("\nBye\n"); diff --git a/srslte/examples/tutorial_examples/CMakeLists.txt b/srslte/examples/tutorial_examples/CMakeLists.txt index d1ce1490e..cf139f515 100644 --- a/srslte/examples/tutorial_examples/CMakeLists.txt +++ b/srslte/examples/tutorial_examples/CMakeLists.txt @@ -26,10 +26,10 @@ IF(SRSGUI_FOUND AND UHD_FOUND) add_executable(pss pss.c) - target_link_libraries(pss srslte ${SRSGUI_LIBRARIES} srslte_uhd) + target_link_libraries(pss srslte ${SRSGUI_LIBRARIES} srslte_rf) add_executable(simple_tx simple_tx.c) - target_link_libraries(simple_tx srslte srslte_uhd) + target_link_libraries(simple_tx srslte srslte_rf) ENDIF(SRSGUI_FOUND AND UHD_FOUND) diff --git a/srslte/examples/tutorial_examples/pss.c b/srslte/examples/tutorial_examples/pss.c index 6640b3c0f..8a665d700 100644 --- a/srslte/examples/tutorial_examples/pss.c +++ b/srslte/examples/tutorial_examples/pss.c @@ -35,7 +35,7 @@ #include #include "srslte/srslte.h" -#include "srslte/cuhd/cuhd.h" +#include "srslte/rf/rf.h" #ifndef DISABLE_GRAPHICS @@ -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; + srslte_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 (cuhd_open(uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); + printf("Opening RF device...\n"); + if (srslte_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", cuhd_set_rx_srate(uhd, flen*2*100) / 1000000); - printf("Set RX gain: %.1f dB\n", cuhd_set_rx_gain(uhd, uhd_gain)); - printf("Set RX freq: %.2f MHz\n", cuhd_set_rx_freq(uhd, uhd_freq) / 1000000); - cuhd_rx_wait_lo_locked(uhd); - cuhd_start_rx_stream(uhd); + printf("Set RX rate: %.2f MHz\n", srslte_rf_set_rx_srate(&rf, flen*2*100) / 1000000); + printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, rf_freq) / 1000000); + srslte_rf_rx_wait_lo_locked(&rf); + srslte_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 = cuhd_recv(uhd, buffer, flen - peak_offset, 1); + n = srslte_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); - cuhd_close(uhd); + srslte_rf_close(&rf); printf("Ok\n"); exit(0); diff --git a/srslte/examples/tutorial_examples/simple_tx.c b/srslte/examples/tutorial_examples/simple_tx.c index ca5b15eed..c82b14748 100644 --- a/srslte/examples/tutorial_examples/simple_tx.c +++ b/srslte/examples/tutorial_examples/simple_tx.c @@ -35,8 +35,8 @@ #include "srslte/srslte.h" -#include "srslte/cuhd/cuhd.h" -void *uhd; +#include "srslte/rf/rf.h" +srslte_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])) { @@ -116,7 +116,7 @@ void parse_args(int argc, char **argv) { exit(-1); } } -#ifdef DISABLE_UHD +#ifdef DISABLE_RF if (!output_file_name) { usage(argv[0]); exit(-1); @@ -137,9 +137,9 @@ void base_init() { perror("malloc"); exit(-1); } - printf("Opening UHD device...\n"); - if (cuhd_open(uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); + printf("Opening RF device...\n"); + if (srslte_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); } - cuhd_close(&uhd); + srslte_rf_close(&rf); } @@ -172,7 +172,7 @@ int main(int argc, char **argv) { float sss_signal5[SRSLTE_SSS_LEN]; // for subframe 5 int i; -#ifdef DISABLE_UHD +#ifdef DISABLE_RF if (argc < 3) { usage(argv[0]); exit(-1); @@ -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", - cuhd_set_tx_srate(uhd, srslte_sampling_freq_hz(cell.nof_prb)) / 1000000); - printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, uhd_gain)); + srslte_rf_set_tx_srate(&rf, srslte_sampling_freq_hz(cell.nof_prb)) / 1000000); + printf("Set TX gain: %.1f dB\n", srslte_rf_set_tx_gain(&rf, rf_gain)); printf("Set TX freq: %.2f MHz\n", - cuhd_set_tx_freq(uhd, uhd_freq) / 1000000); + srslte_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); - cuhd_send(uhd, output_buffer, sf_n_samples, true); + srslte_vec_sc_prod_cfc(output_buffer, rf_amp, output_buffer, sf_n_samples); + srslte_rf_send(&rf, output_buffer, sf_n_samples, true); } } diff --git a/srslte/examples/usrp_capture.c b/srslte/examples/usrp_capture.c index 870c78d45..148a6f070 100644 --- a/srslte/examples/usrp_capture.c +++ b/srslte/examples/usrp_capture.c @@ -36,13 +36,13 @@ #include #include "srslte/srslte.h" -#include "srslte/cuhd/cuhd.h" +#include "srslte/rf/rf.h" #include "srslte/io/filesink.h" 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; + srslte_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 (cuhd_open(uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); + printf("Opening RF device...\n"); + if (srslte_rf_open(&rf, rf_args)) { + fprintf(stderr, "Error opening rf\n"); exit(-1); } - cuhd_set_master_clock_rate(uhd, 30.72e6); + srslte_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", cuhd_set_rx_freq(uhd, uhd_freq) / 1000000); - printf("Set RX gain: %.2f dB\n", cuhd_set_rx_gain(uhd, uhd_gain)); - float srate = cuhd_set_rx_srate(uhd, uhd_rate); - if (srate != uhd_rate) { + printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, rf_freq) / 1000000); + printf("Set RX gain: %.2f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + float srate = srslte_rf_set_rx_srate(&rf, rf_rate); + if (srate != rf_rate) { if (srate < 10e6) { - cuhd_set_master_clock_rate(uhd, 4*uhd_rate); + srslte_rf_set_master_clock_rate(&rf, 4*rf_rate); } else { - cuhd_set_master_clock_rate(uhd, uhd_rate); + srslte_rf_set_master_clock_rate(&rf, rf_rate); } - srate = cuhd_set_rx_srate(uhd, uhd_rate); - if (srate != uhd_rate) { - fprintf(stderr, "Errror setting samplign frequency %.2f MHz\n", uhd_rate*1e-6); + srate = srslte_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); - cuhd_rx_wait_lo_locked(uhd); - cuhd_start_rx_stream(uhd); + srslte_rf_rx_wait_lo_locked(&rf); + srslte_rf_start_rx_stream(&rf); while((sample_count < nof_samples || nof_samples == -1) && keep_running){ - n = cuhd_recv(uhd, buffer, buflen, 1); + n = srslte_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); - cuhd_close(uhd); + srslte_rf_close(&rf); printf("Ok - wrote %d samples\n", sample_count); exit(0); diff --git a/srslte/examples/usrp_capture_sync.c b/srslte/examples/usrp_capture_sync.c index 0ae297fd4..b7d7229d3 100644 --- a/srslte/examples/usrp_capture_sync.c +++ b/srslte/examples/usrp_capture_sync.c @@ -36,12 +36,12 @@ #include #include "srslte/srslte.h" -#include "srslte/cuhd/cuhd.h" +#include "srslte/rf/rf.h" 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,21 +92,21 @@ 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); } } -int cuhd_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { +int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return cuhd_recv(h, data, nsamples, 1); + return srslte_rf_recv(h, data, nsamples, 1); } int main(int argc, char **argv) { cf_t *buffer; int n; - void *uhd; + srslte_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 (cuhd_open(uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); + printf("Opening RF device...\n"); + if (srslte_rf_open(&rf, rf_args)) { + fprintf(stderr, "Error opening rf\n"); exit(-1); } - cuhd_set_master_clock_rate(uhd, 30.72e6); + srslte_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", cuhd_set_rx_freq(uhd, uhd_freq) / 1000000); - printf("Set RX gain: %.1f dB\n", cuhd_set_rx_gain(uhd, uhd_gain)); + printf("Set RX freq: %.6f MHz\n", srslte_rf_set_rx_freq(&rf, rf_freq) / 1000000); + printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); int srate = srslte_sampling_freq_hz(nof_prb); if (srate != -1) { if (srate < 10e6) { - cuhd_set_master_clock_rate(uhd, 4*srate); + srslte_rf_set_master_clock_rate(&rf, 4*srate); } else { - cuhd_set_master_clock_rate(uhd, srate); + srslte_rf_set_master_clock_rate(&rf, srate); } printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000); - float srate_uhd = cuhd_set_rx_srate(uhd, (double) srate); - if (srate_uhd != srate) { + float srate_rf = srslte_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); } - cuhd_rx_wait_lo_locked(uhd); - cuhd_start_rx_stream(uhd); + srslte_rf_rx_wait_lo_locked(&rf); + srslte_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, cuhd_recv_wrapper, uhd)) { + if (srslte_ue_sync_init(&ue_sync, cell, srslte_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); - cuhd_close(uhd); + srslte_rf_close(&rf); srslte_ue_sync_free(&ue_sync); printf("Ok - wrote %d subframes\n", subframe_count); diff --git a/srslte/examples/usrp_txrx.c b/srslte/examples/usrp_txrx.c index 2399d9b4a..11af41089 100644 --- a/srslte/examples/usrp_txrx.c +++ b/srslte/examples/usrp_txrx.c @@ -33,35 +33,37 @@ #include #include -#include "srslte/cuhd/cuhd.h" +#include "srslte/rf/rf.h" #include "srslte/srslte.h" 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=""; +int time_adv_samples = 0; +float tone_offset_hz = 1e6; +float rf_rx_gain=40, srslte_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-t Single tone offset (Hz) [Default %f]\n", tone_offset_hz); + 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", srslte_rf_tx_gain); + printf("\t-t Single tone offset (Hz) [Default %f]\n", tone_offset_hz); + printf("\t-T Time advance samples [Default %d]\n", time_adv_samples); 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); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "ioafgpt")) != -1) { + while ((opt = getopt(argc, argv, "ioafgGptT")) != -1) { switch (opt) { case 'a': - uhd_args = argv[optind]; + rf_args = argv[optind]; break; case 'o': output_filename = argv[optind]; @@ -72,14 +74,17 @@ void parse_args(int argc, char **argv) { case 't': tone_offset_hz = atof(argv[optind]); break; + case 'T': + time_adv_samples = atoi(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]); + srslte_rf_tx_gain = atof(argv[optind]); break; case 'p': nof_prb = atoi(argv[optind]); @@ -97,91 +102,91 @@ void parse_args(int argc, char **argv) { usage(argv[0]); exit(-1); } + if (time_adv_samples < 0) { + printf("Time advance must be positive\n"); + usage(argv[0]); + exit(-1); + } } int main(int argc, char **argv) { parse_args(argc, argv); uint32_t flen = srslte_sampling_freq_hz(nof_prb)/1000; - uint32_t nsamples_adv = 3000; - + cf_t *rx_buffer = malloc(sizeof(cf_t)*flen*nof_frames); if (!rx_buffer) { perror("malloc"); exit(-1); } - cf_t *tx_buffer = malloc(sizeof(cf_t)*(flen+nsamples_adv)); + cf_t *tx_buffer = malloc(sizeof(cf_t)*(flen+time_adv_samples)); if (!tx_buffer) { perror("malloc"); exit(-1); } - bzero(tx_buffer, sizeof(cf_t)*(flen+nsamples_adv)); + bzero(tx_buffer, sizeof(cf_t)*(flen+time_adv_samples)); cf_t *zeros = calloc(sizeof(cf_t),flen); if (!zeros) { perror("calloc"); exit(-1); } + + float time_adv_sec = (float) time_adv_samples/srslte_sampling_freq_hz(nof_prb); - // Send through UHD - void *uhd; - printf("Opening UHD device...\n"); - if (cuhd_open(uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); + // Send through RF + srslte_rf_t rf; + printf("Opening RF device...\n"); + if (srslte_rf_open(&rf, rf_args)) { + fprintf(stderr, "Error opening rf\n"); exit(-1); } - cuhd_set_master_clock_rate(uhd, 30.72e6); + srslte_rf_set_master_clock_rate(&rf, 30.72e6); int srate = srslte_sampling_freq_hz(nof_prb); if (srate < 10e6) { - cuhd_set_master_clock_rate(uhd, 4*srate); + srslte_rf_set_master_clock_rate(&rf, 4*srate); } else { - cuhd_set_master_clock_rate(uhd, srate); + srslte_rf_set_master_clock_rate(&rf, srate); } - cuhd_set_rx_srate(uhd, (double) srate); - cuhd_set_tx_srate(uhd, (double) srate); - + srslte_rf_set_rx_srate(&rf, (double) srate); + srslte_rf_set_tx_srate(&rf, (double) srate); + + printf("Subframe len: %d samples\n", flen); + printf("Time advance: %f us\n",time_adv_sec*1e6); printf("Set TX/RX rate: %.2f MHz\n", (float) srate / 1000000); - printf("Set RX gain: %.1f dB\n", cuhd_set_rx_gain(uhd, uhd_rx_gain)); - printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, uhd_tx_gain)); - printf("Set TX/RX freq: %.2f MHz\n", cuhd_set_rx_freq(uhd, uhd_freq) / 1000000); + printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_rx_gain)); + printf("Set TX gain: %.1f dB\n", srslte_rf_set_tx_gain(&rf, srslte_rf_tx_gain)); + printf("Set TX/RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, rf_freq) / 1000000); + srslte_rf_set_tx_freq(&rf, rf_freq); - cuhd_set_tx_freq_offset(uhd, uhd_freq, 8e6); sleep(1); if (input_filename) { - srslte_vec_load_file(input_filename, &tx_buffer[nsamples_adv], flen*sizeof(cf_t)); + srslte_vec_load_file(input_filename, &tx_buffer[time_adv_samples], flen*sizeof(cf_t)); } else { - for (int i=0;i -#include - -#include "srslte/config.h" - -typedef void (*cuhd_msg_handler_t)(const char*); - -SRSLTE_API int cuhd_open(char *args, - void **handler); - -SRSLTE_API int cuhd_open_th(char *args, - void **handler, - bool tx_gain_same_rx); - -SRSLTE_API int cuhd_close(void *h); - -SRSLTE_API int cuhd_start_rx_stream(void *h); - -SRSLTE_API int cuhd_start_rx_stream_nsamples(void *h, - uint32_t nsamples); - -SRSLTE_API int cuhd_stop_rx_stream(void *h); - -SRSLTE_API void cuhd_flush_buffer(void *h); - -SRSLTE_API bool cuhd_has_rssi(void *h); - -SRSLTE_API float cuhd_get_rssi(void *h); - -SRSLTE_API bool cuhd_rx_wait_lo_locked(void *h); - -SRSLTE_API void cuhd_set_master_clock_rate(void *h, - double rate); - -SRSLTE_API bool cuhd_is_master_clock_dynamic(void *h); - -SRSLTE_API double cuhd_set_rx_srate(void *h, - double freq); - -SRSLTE_API double cuhd_set_rx_gain(void *h, - double gain); - -SRSLTE_API void cuhd_set_tx_rx_gain_offset(void *h, - double offset); - -SRSLTE_API double cuhd_set_rx_gain_th(void *h, - double gain); - -SRSLTE_API double cuhd_set_tx_gain_th(void *h, - double gain); - -SRSLTE_API float cuhd_get_rx_gain_offset(void *h); - -SRSLTE_API double cuhd_get_rx_gain(void *h); - -SRSLTE_API double cuhd_get_tx_gain(void *h); - -SRSLTE_API void cuhd_suppress_stdout(); - -SRSLTE_API void cuhd_register_msg_handler(cuhd_msg_handler_t h); - -SRSLTE_API double cuhd_set_rx_freq(void *h, - double freq); - -SRSLTE_API double cuhd_set_rx_freq_offset(void *h, - double freq, - double off); - -SRSLTE_API double cuhd_set_rx_freq_offset(void *h, - double freq, - double off); - -SRSLTE_API int cuhd_recv(void *h, - void *data, - uint32_t nsamples, - bool blocking); - -SRSLTE_API int cuhd_recv_with_time(void *h, - void *data, - uint32_t nsamples, - bool blocking, - time_t *secs, - double *frac_secs); - -SRSLTE_API double cuhd_set_tx_srate(void *h, - double freq); - -SRSLTE_API double cuhd_set_tx_gain(void *h, - double gain); - -SRSLTE_API double cuhd_set_tx_freq(void *h, - double freq); - -SRSLTE_API double cuhd_set_tx_freq_offset(void *h, - double freq, - double offset); - -SRSLTE_API void cuhd_get_time(void *h, - time_t *secs, - double *frac_secs); - -SRSLTE_API int cuhd_send(void *h, - void *data, - uint32_t nsamples, - bool blocking); - -SRSLTE_API int cuhd_send2(void *h, - void *data, - uint32_t nsamples, - bool blocking, - bool start_of_burst, - bool end_of_burst); - -SRSLTE_API int cuhd_send(void *h, - void *data, - uint32_t nsamples, - bool blocking); - - -SRSLTE_API int cuhd_send_timed(void *h, - void *data, - int nsamples, - time_t secs, - double frac_secs); - -SRSLTE_API int cuhd_send_timed2(void *h, - void *data, - int nsamples, - time_t secs, - double frac_secs, - bool is_start_of_burst, - bool is_end_of_burst); - -#ifdef __cplusplus -} -#endif diff --git a/srslte/include/srslte/rf/rf.h b/srslte/include/srslte/rf/rf.h new file mode 100644 index 000000000..fd49f7d8d --- /dev/null +++ b/srslte/include/srslte/rf/rf.h @@ -0,0 +1,188 @@ +/** + * + * \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/. + * + */ + +#ifndef RF_H +#define RF_H + +#include +#include +#include +#include + +#include "srslte/config.h" + +typedef struct { + void *handler; + void *dev; + + // 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; + bool tx_gain_same_rx; + float tx_rx_gain_offset; +} srslte_rf_t; + +typedef struct { + float dc_gain; + float dc_phase; + float iq_i; + float iq_q; +} srslte_rf_cal_t; + +typedef struct { + enum { + SRSLTE_RF_ERROR_LATE, + SRSLTE_RF_ERROR_UNDERFLOW, + SRSLTE_RF_ERROR_OVERFLOW, + SRSLTE_RF_ERROR_OTHER + } type; + int opt; + const char *msg; +} srslte_rf_error_t; + +typedef void (*srslte_rf_error_handler_t)(srslte_rf_error_t error); + +SRSLTE_API int srslte_rf_open(srslte_rf_t *h, + char *args); + +SRSLTE_API int srslte_rf_open_devname(srslte_rf_t *h, + char *devname, + char *args); + +SRSLTE_API const char *srslte_rf_name(srslte_rf_t *h); + +SRSLTE_API int srslte_rf_start_gain_thread(srslte_rf_t *rf, + bool tx_gain_same_rx); + +SRSLTE_API int srslte_rf_close(srslte_rf_t *h); + +SRSLTE_API void srslte_rf_set_tx_cal(srslte_rf_t *h, srslte_rf_cal_t *cal); + +SRSLTE_API void srslte_rf_set_rx_cal(srslte_rf_t *h, srslte_rf_cal_t *cal); + +SRSLTE_API int srslte_rf_start_rx_stream(srslte_rf_t *h); + +SRSLTE_API int srslte_rf_stop_rx_stream(srslte_rf_t *h); + +SRSLTE_API void srslte_rf_flush_buffer(srslte_rf_t *h); + +SRSLTE_API bool srslte_rf_has_rssi(srslte_rf_t *h); + +SRSLTE_API float srslte_rf_get_rssi(srslte_rf_t *h); + +SRSLTE_API bool srslte_rf_rx_wait_lo_locked(srslte_rf_t *h); + +SRSLTE_API void srslte_rf_set_master_clock_rate(srslte_rf_t *h, + double rate); + +SRSLTE_API bool srslte_rf_is_master_clock_dynamic(srslte_rf_t *h); + +SRSLTE_API double srslte_rf_set_rx_srate(srslte_rf_t *h, + double freq); + +SRSLTE_API double srslte_rf_set_rx_gain(srslte_rf_t *h, + double gain); + +SRSLTE_API void srslte_rf_set_tx_rx_gain_offset(srslte_rf_t *h, + double offset); + +SRSLTE_API double srslte_rf_set_rx_gain_th(srslte_rf_t *h, + double gain); + +SRSLTE_API double srslte_rf_get_rx_gain(srslte_rf_t *h); + +SRSLTE_API double srslte_rf_get_tx_gain(srslte_rf_t *h); + +SRSLTE_API void srslte_rf_suppress_stdout(srslte_rf_t *h); + +SRSLTE_API void srslte_rf_register_error_handler(srslte_rf_t *h, + srslte_rf_error_handler_t error_handler); + +SRSLTE_API double srslte_rf_set_rx_freq(srslte_rf_t *h, + double freq); + +SRSLTE_API int srslte_rf_recv(srslte_rf_t *h, + void *data, + uint32_t nsamples, + bool blocking); + +SRSLTE_API int srslte_rf_recv_with_time(srslte_rf_t *h, + void *data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs); + +SRSLTE_API double srslte_rf_set_tx_srate(srslte_rf_t *h, + double freq); + +SRSLTE_API double srslte_rf_set_tx_gain(srslte_rf_t *h, + double gain); + +SRSLTE_API double srslte_rf_set_tx_freq(srslte_rf_t *h, + double freq); + +SRSLTE_API void srslte_rf_get_time(srslte_rf_t *h, + time_t *secs, + double *frac_secs); + +SRSLTE_API int srslte_rf_send(srslte_rf_t *h, + void *data, + uint32_t nsamples, + bool blocking); + +SRSLTE_API int srslte_rf_send2(srslte_rf_t *h, + void *data, + uint32_t nsamples, + bool blocking, + bool start_of_burst, + bool end_of_burst); + +SRSLTE_API int srslte_rf_send(srslte_rf_t *h, + void *data, + uint32_t nsamples, + bool blocking); + + +SRSLTE_API int srslte_rf_send_timed(srslte_rf_t *h, + void *data, + int nsamples, + time_t secs, + double frac_secs); + +SRSLTE_API int srslte_rf_send_timed2(srslte_rf_t *h, + void *data, + int nsamples, + time_t secs, + double frac_secs, + bool is_start_of_burst, + bool is_end_of_burst); + +#endif + diff --git a/srslte/include/srslte/cuhd/cuhd_utils.h b/srslte/include/srslte/rf/rf_utils.h similarity index 89% rename from srslte/include/srslte/cuhd/cuhd_utils.h rename to srslte/include/srslte/rf/rf_utils.h index 2fbb0baa5..6ca2777bb 100644 --- a/srslte/include/srslte/cuhd/cuhd_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 cuhd_rssi_scan(void *uhd, +SRSLTE_API int rf_rssi_scan(srslte_rf_t *rf, float *freqs, float *rssi, int nof_bands, double fs, int nsamp); -SRSLTE_API int cuhd_mib_decoder(void *uhd, +SRSLTE_API int rf_mib_decoder(srslte_rf_t *rf, cell_search_cfg_t *config, srslte_cell_t *cell); -SRSLTE_API int cuhd_cell_search(void *uhd, +SRSLTE_API int rf_cell_search(srslte_rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell); -SRSLTE_API int cuhd_search_and_decode_mib(void *uhd, +SRSLTE_API int rf_search_and_decode_mib(srslte_rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell); diff --git a/srslte/include/srslte/sync/sync.h b/srslte/include/srslte/sync/sync.h index b75fdc7a1..e564319f3 100644 --- a/srslte/include/srslte/sync/sync.h +++ b/srslte/include/srslte/sync/sync.h @@ -79,6 +79,7 @@ typedef struct SRSLTE_API { float mean_cfo; int cfo_i; bool find_cfo_i; + bool find_cfo_i_initiated; float cfo_ema_alpha; uint32_t nof_symbols; uint32_t cp_len; diff --git a/srslte/lib/CMakeLists.txt b/srslte/lib/CMakeLists.txt index eb3f2dc06..1b2cc2aa3 100644 --- a/srslte/lib/CMakeLists.txt +++ b/srslte/lib/CMakeLists.txt @@ -59,26 +59,53 @@ FILE(GLOB modules *) SET(SOURCES_ALL "") FOREACH (_module ${modules}) IF(IS_DIRECTORY ${_module}) - IF (NOT ${_module} MATCHES "cuhd") + 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 "cuhd") + ENDIF (NOT ${_module} MATCHES "rf") ENDIF(IS_DIRECTORY ${_module}) ENDFOREACH() ADD_LIBRARY(srslte SHARED ${SOURCES_ALL}) TARGET_LINK_LIBRARIES(srslte m ${FFTW3F_LIBRARIES}) +SET_TARGET_PROPERTIES(srslte + PROPERTIES VERSION ${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR} +) -IF(UHD_FOUND) - INCLUDE_DIRECTORIES(${UHD_INCLUDE_DIRS}) - LINK_DIRECTORIES(${UHD_LIBRARY_DIRS}) - ADD_LIBRARY(srslte_uhd SHARED ${CMAKE_CURRENT_SOURCE_DIR}/cuhd/src/cuhd_imp.cpp ${CMAKE_CURRENT_SOURCE_DIR}/cuhd/src/cuhd_utils.c) - TARGET_LINK_LIBRARIES(srslte_uhd ${UHD_LIBRARIES}) - INSTALL(TARGETS srslte_uhd DESTINATION ${LIBRARY_DIR}) - SRSLTE_SET_PIC(srslte_uhd) -ENDIF(UHD_FOUND) +IF(RF_FOUND) + # Include common RF files + SET(SOURCES_RF "") + LIST(APPEND SOURCES_RF "rf/src/rf_imp.c" "rf/src/rf_utils.c") + + IF (UHD_FOUND) + INCLUDE_DIRECTORIES(${UHD_INCLUDE_DIRS}) + LINK_DIRECTORIES(${UHD_LIBRARY_DIRS}) + add_definitions(-DENABLE_UHD) + LIST(APPEND SOURCES_RF "rf/src/rf_uhd_imp.c" "rf/src/uhd_c_api.cpp") + ENDIF (UHD_FOUND) + + IF (BLADERF_FOUND) + INCLUDE_DIRECTORIES(${BLADERF_INCLUDE_DIRS}) + add_definitions(-DENABLE_BLADERF) + LIST(APPEND SOURCES_RF "rf/src/rf_blade_imp.c") + ENDIF (BLADERF_FOUND) + + ADD_LIBRARY(srslte_rf SHARED ${SOURCES_RF}) + SET_TARGET_PROPERTIES(srslte_rf + PROPERTIES VERSION ${SRSLTE_VERSION_MAJOR}.${SRSLTE_VERSION_MINOR} + ) + + IF (UHD_FOUND) + TARGET_LINK_LIBRARIES(srslte_rf ${UHD_LIBRARIES}) + ENDIF (UHD_FOUND) + + IF (BLADERF_FOUND) + TARGET_LINK_LIBRARIES(srslte_rf ${BLADERF_LIBRARIES}) + ENDIF (BLADERF_FOUND) + + INSTALL(TARGETS srslte_rf DESTINATION ${LIBRARY_DIR}) + SRSLTE_SET_PIC(srslte_rf) +ENDIF(RF_FOUND) INSTALL(TARGETS srslte DESTINATION ${LIBRARY_DIR}) SRSLTE_SET_PIC(srslte) diff --git a/srslte/lib/agc/src/agc.c b/srslte/lib/agc/src/agc.c index 94357c8e3..3d971427a 100644 --- a/srslte/lib/agc/src/agc.c +++ b/srslte/lib/agc/src/agc.c @@ -124,11 +124,11 @@ void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) { if (!q->uhd_handler) { srslte_vec_sc_prod_cfc(signal, q->gain, signal, len); } else { - if (q->gain < 1) { - q->gain = 1.0; + if (gain_db < 0) { + gain_db = 0.0; } if (isinf(gain_db) || isnan(gain_db)) { - q->gain = 10.0; + gain_db = 10.0; } else { gain_uhd_db = q->set_gain_callback(q->uhd_handler, gain_db); q->gain = pow(10, gain_uhd_db/10); diff --git a/srslte/lib/cuhd/src/cuhd_handler.hpp b/srslte/lib/cuhd/src/cuhd_handler.hpp deleted file mode 100644 index 797488a1e..000000000 --- a/srslte/lib/cuhd/src/cuhd_handler.hpp +++ /dev/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 -#include - -class cuhd_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; -}; diff --git a/srslte/lib/cuhd/src/cuhd_imp.cpp b/srslte/lib/cuhd/src/cuhd_imp.cpp deleted file mode 100644 index e77c0e875..000000000 --- a/srslte/lib/cuhd/src/cuhd_imp.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include - -#include "cuhd_handler.hpp" -#include "srslte/cuhd/cuhd.h" -#include "srslte/srslte.h" - -//#define METADATA_VERBOSE - -cuhd_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) -{ - cuhd_handler *handler = static_cast < cuhd_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 cuhd_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 cuhd_start_rx_stream(void *h) -{ - cuhd_handler *handler = static_cast < cuhd_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 cuhd_stop_rx_stream(void *h) -{ - cuhd_handler *handler = static_cast < cuhd_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 cuhd_flush_buffer(void *h) -{ - int n; - _Complex float tmp[1024]; - do { - n = cuhd_recv(h, tmp, 1024, 0); - } while (n > 0); -} - -bool cuhd_has_rssi(void *h) { - cuhd_handler *handler = static_cast < cuhd_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 cuhd_get_rssi(void *h) { - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - if (cuhd_has_rssi(h)) { - uhd::sensor_value_t value = handler->usrp->get_rx_sensor("rssi"); - return value.to_real(); - } else { - return 0; - } -} - -int cuhd_start_rx_stream_nsamples(void *h, uint32_t nsamples) -{ - cuhd_handler *handler = static_cast < cuhd_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 cuhd_set_rx_gain_th(void *h, double gain) -{ - cuhd_handler *handler = static_cast < cuhd_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 cuhd_set_tx_gain_th(void *h, double gain) -{ - cuhd_handler *handler = static_cast < cuhd_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 cuhd_set_tx_rx_gain_offset(void *h, double offset) { - cuhd_handler *handler = static_cast < cuhd_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) { - cuhd_handler *handler = static_cast < cuhd_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; - cuhd_set_rx_gain(h, handler->cur_rx_gain); - } - if (handler->tx_gain_same_rx) { - cuhd_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; - cuhd_set_tx_gain(h, handler->cur_tx_gain); - } - pthread_mutex_unlock(&handler->mutex); - } -} - -float cuhd_get_rx_gain_offset(void *h) { - return 15; -} - -void cuhd_suppress_stdout() { - uhd::msg::register_handler(suppress_handler); -} - -void cuhd_register_msg_handler(cuhd_msg_handler_t h) -{ - msg_handler = h; - uhd::msg::register_handler(translate_handler); -} - -int cuhd_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 */ - cuhd_handler *handler = new cuhd_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 cuhd_open(char *args, void **h) { - return cuhd_open_(args, h, false, false); -} - -int cuhd_open_th(char *args, void **h, bool tx_gain_same_rx) { - return cuhd_open_(args, h, true, tx_gain_same_rx); -} - - -int cuhd_close(void *h) -{ - cuhd_stop_rx_stream(h); - /** Something else to close the USRP?? */ - return 0; -} - -void cuhd_set_master_clock_rate(void *h, double rate) { - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - if (handler->dynamic_rate) { - handler->usrp->set_master_clock_rate(rate); - } -} - -bool cuhd_is_master_clock_dynamic(void *h) { - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - return handler->dynamic_rate; -} - -double cuhd_set_rx_srate(void *h, double freq) -{ - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - handler->usrp->set_rx_rate(freq); - return handler->usrp->get_rx_rate(); -} - -double cuhd_set_rx_gain(void *h, double gain) -{ - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - handler->usrp->set_rx_gain(gain); - return handler->usrp->get_rx_gain(); -} - -double cuhd_get_rx_gain(void *h) -{ - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - return handler->usrp->get_rx_gain(); -} - -double cuhd_get_tx_gain(void *h) -{ - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - return handler->usrp->get_tx_gain(); -} - -double cuhd_set_rx_freq(void *h, double freq) -{ - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - handler->usrp->set_rx_freq(freq); - return freq; -} - -double cuhd_set_rx_freq_offset(void *h, double freq, double off) { - cuhd_handler* handler = static_cast(h); - handler->usrp->set_rx_freq(uhd::tune_request_t(freq, off)); - return handler->usrp->get_rx_freq(); -} - -int cuhd_recv(void *h, void *data, uint32_t nsamples, bool blocking) -{ - return cuhd_recv_with_time(h, data, nsamples, blocking, NULL, NULL); -} - -int cuhd_recv_with_time(void *h, - void *data, - uint32_t nsamples, - bool blocking, - time_t *secs, - double *frac_secs) -{ - cuhd_handler *handler = static_cast < cuhd_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 cuhd_set_tx_gain(void *h, double gain) -{ - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - handler->usrp->set_tx_gain(gain); - return gain; -} - -double cuhd_set_tx_srate(void *h, double freq) -{ - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - handler->usrp->set_tx_rate(freq); - handler->tx_rate = handler->usrp->get_tx_rate(); - return handler->tx_rate; -} - -double cuhd_set_tx_freq(void *h, double freq) -{ - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - handler->usrp->set_tx_freq(freq); - return handler->usrp->get_tx_freq(); -} - - -double cuhd_set_tx_freq_offset(void *h, double freq, double off) { - cuhd_handler* handler = static_cast(h); - handler->usrp->set_tx_freq(uhd::tune_request_t(freq, off)); - return handler->usrp->get_tx_freq(); -} - -void cuhd_get_time(void *h, time_t *secs, double *frac_secs) { - cuhd_handler *handler = static_cast < cuhd_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 cuhd_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) -{ - cuhd_handler* handler = static_cast(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 cuhd_send(void *h, void *data, uint32_t nsamples, bool blocking) -{ - return cuhd_send2(h, data, nsamples, blocking, true, true); -} - -int cuhd_send2(void *h, void *data, uint32_t nsamples, bool blocking, bool start_of_burst, bool end_of_burst) -{ - return cuhd_send_timed3(h, data, nsamples, 0, 0, false, blocking, start_of_burst, end_of_burst); -} - - -int cuhd_send_timed(void *h, - void *data, - int nsamples, - time_t secs, - double frac_secs) -{ - return cuhd_send_timed2(h, data, nsamples, secs, frac_secs, true, true); -} - -int cuhd_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 cuhd_send_timed3(h, data, nsamples, secs, frac_secs, true, true, is_start_of_burst, is_end_of_burst); -} diff --git a/srslte/lib/phch/test/CMakeLists.txt b/srslte/lib/phch/test/CMakeLists.txt index 0da0469e6..fd7dc4cb0 100644 --- a/srslte/lib/phch/test/CMakeLists.txt +++ b/srslte/lib/phch/test/CMakeLists.txt @@ -195,5 +195,5 @@ BuildMex(MEXNAME prach SOURCES prach_test_mex.c LIBRARIES srslte srslte_mex) IF(UHD_FOUND) ADD_EXECUTABLE(prach_test_usrp prach_test_usrp.c) - TARGET_LINK_LIBRARIES(prach_test_usrp srslte_uhd srslte) + TARGET_LINK_LIBRARIES(prach_test_usrp srslte_rf srslte) ENDIF(UHD_FOUND) diff --git a/srslte/lib/phch/test/prach_test_usrp.c b/srslte/lib/phch/test/prach_test_usrp.c index d01b4eb92..e9f266389 100644 --- a/srslte/lib/phch/test/prach_test_usrp.c +++ b/srslte/lib/phch/test/prach_test_usrp.c @@ -33,7 +33,7 @@ #include #include -#include "srslte/cuhd/cuhd.h" +#include "srslte/rf/rf.h" #include "srslte/srslte.h" #define MAX_LEN 70176 @@ -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; + srslte_rf_t uhd; printf("Opening UHD device...\n"); - if (cuhd_open(uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); + if (srslte_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", cuhd_set_rx_srate(uhd, srslte_sampling_freq_hz(nof_prb)) / 1000000); - printf("Set RX gain: %.1f dB\n", cuhd_set_rx_gain(uhd, uhd_gain)); - printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, uhd_gain)); - printf("Set TX/RX freq: %.2f MHz\n", cuhd_set_rx_freq(uhd, uhd_freq) / 1000000); - cuhd_set_tx_srate(uhd, srslte_sampling_freq_hz(nof_prb)); - cuhd_set_tx_freq_offset(uhd, uhd_freq, 8e6); + printf("Set TX/RX rate: %.2f MHz\n", srslte_rf_set_rx_srate(&uhd, srslte_sampling_freq_hz(nof_prb)) / 1000000); + printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&uhd, uhd_gain)); + printf("Set TX gain: %.1f dB\n", srslte_rf_set_tx_gain(&uhd, uhd_gain)); + printf("Set TX/RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&uhd, uhd_freq) / 1000000); + srslte_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; - cuhd_start_rx_stream(uhd); + srslte_rf_start_rx_stream(&uhd); uint32_t nframe=0; while(nframe +#include +#include +#include +#include + +#include "srslte/srslte.h" +#include "rf_blade_imp.h" +#include "srslte/rf/rf.h" + + +#define CONVERT_BUFFER_SIZE 240*1024 + +typedef struct { + struct bladerf *dev; + uint32_t rx_rate; + uint32_t tx_rate; + int16_t rx_buffer[CONVERT_BUFFER_SIZE]; + int16_t tx_buffer[CONVERT_BUFFER_SIZE]; + bool rx_stream_enabled; + bool tx_stream_enabled; +} rf_blade_handler_t; + +srslte_rf_error_handler_t blade_error_handler = NULL; + +void rf_blade_suppress_stdout(void *h) { + bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_SILENT); +} + +void rf_blade_register_error_handler(void *notused, srslte_rf_error_handler_t new_handler) +{ + new_handler = blade_error_handler; +} + +bool rf_blade_rx_wait_lo_locked(void *h) +{ + usleep(1000); + return true; +} + +const unsigned int num_buffers = 256; +const unsigned int ms_buffer_size_rx = 1024; +const unsigned int buffer_size_tx = 1024; +const unsigned int num_transfers = 32; +const unsigned int timeout_ms = 4000; + + +int rf_blade_start_tx_stream(void *h) +{ + int status; + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + + status = bladerf_sync_config(handler->dev, + BLADERF_MODULE_TX, + BLADERF_FORMAT_SC16_Q11_META, + num_buffers, + buffer_size_tx, + num_transfers, + timeout_ms); + if (status != 0) { + fprintf(stderr, "Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); + return status; + } + status = bladerf_enable_module(handler->dev, BLADERF_MODULE_TX, true); + if (status != 0) { + fprintf(stderr, "Failed to enable TX module: %s\n", bladerf_strerror(status)); + return status; + } + handler->tx_stream_enabled = true; + return 0; +} + +int rf_blade_start_rx_stream(void *h) +{ + int status; + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + + /* Configure the device's RX module for use with the sync interface. + * SC16 Q11 samples *with* metadata are used. */ + uint32_t buffer_size_rx = ms_buffer_size_rx*(handler->rx_rate/1000/1024); + + status = bladerf_sync_config(handler->dev, + BLADERF_MODULE_RX, + BLADERF_FORMAT_SC16_Q11_META, + num_buffers, + buffer_size_rx, + num_transfers, + timeout_ms); + if (status != 0) { + fprintf(stderr, "Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); + return status; + } + status = bladerf_sync_config(handler->dev, + BLADERF_MODULE_TX, + BLADERF_FORMAT_SC16_Q11_META, + num_buffers, + buffer_size_tx, + num_transfers, + timeout_ms); + if (status != 0) { + fprintf(stderr, "Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); + return status; + } + status = bladerf_enable_module(handler->dev, BLADERF_MODULE_RX, true); + if (status != 0) { + fprintf(stderr, "Failed to enable RX module: %s\n", bladerf_strerror(status)); + return status; + } + status = bladerf_enable_module(handler->dev, BLADERF_MODULE_TX, true); + if (status != 0) { + fprintf(stderr, "Failed to enable TX module: %s\n", bladerf_strerror(status)); + return status; + } + handler->rx_stream_enabled = true; + return 0; +} + +int rf_blade_stop_rx_stream(void *h) +{ + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + int status = bladerf_enable_module(handler->dev, BLADERF_MODULE_RX, false); + if (status != 0) { + fprintf(stderr, "Failed to enable RX module: %s\n", bladerf_strerror(status)); + return status; + } + status = bladerf_enable_module(handler->dev, BLADERF_MODULE_TX, false); + if (status != 0) { + fprintf(stderr, "Failed to enable TX module: %s\n", bladerf_strerror(status)); + return status; + } + handler->rx_stream_enabled = false; + handler->tx_stream_enabled = false; + return 0; +} + +void rf_blade_flush_buffer(void *h) +{ +} + +bool rf_blade_has_rssi(void *h) +{ + return false; +} + +float rf_blade_get_rssi(void *h) +{ + return 0; +} + +int rf_blade_open(char *args, void **h) +{ + *h = NULL; + + rf_blade_handler_t *handler = (rf_blade_handler_t*) malloc(sizeof(rf_blade_handler_t)); + if (!handler) { + perror("malloc"); + return -1; + } + *h = handler; + + printf("Opening bladeRF...\n"); + int status = bladerf_open(&handler->dev, args); + if (status) { + fprintf(stderr, "Unable to open device: %s\n", bladerf_strerror(status)); + return status; + } + + //bladerf_log_set_verbosity(BLADERF_LOG_LEVEL_VERBOSE); + + /* Configure the gains of the RX LNA and RX VGA1*/ + status = bladerf_set_lna_gain(handler->dev, BLADERF_LNA_GAIN_MAX); + if (status != 0) { + fprintf(stderr, "Failed to set RX LNA gain: %s\n", bladerf_strerror(status)); + return status; + } + status = bladerf_set_rxvga1(handler->dev, 27); + if (status != 0) { + fprintf(stderr, "Failed to set RX VGA1 gain: %s\n", bladerf_strerror(status)); + return status; + } + status = bladerf_set_txvga1(handler->dev, BLADERF_TXVGA1_GAIN_MAX); + if (status != 0) { + fprintf(stderr, "Failed to set TX VGA1 gain: %s\n", bladerf_strerror(status)); + return status; + } + handler->rx_stream_enabled = false; + handler->tx_stream_enabled = false; + return 0; +} + + +int rf_blade_close(void *h) +{ + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + bladerf_close(handler->dev); + return 0; +} + +void rf_blade_set_master_clock_rate(void *h, double rate) +{ +} + +bool rf_blade_is_master_clock_dynamic(void *h) +{ + return true; +} + +double rf_blade_set_rx_srate(void *h, double freq) +{ + uint32_t bw; + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + int status = bladerf_set_sample_rate(handler->dev, BLADERF_MODULE_RX, (uint32_t) freq, &handler->rx_rate); + if (status != 0) { + fprintf(stderr, "Failed to set samplerate = %u: %s\n", (uint32_t) freq, bladerf_strerror(status)); + return -1; + } + status = bladerf_set_bandwidth(handler->dev, BLADERF_MODULE_RX, handler->rx_rate, &bw); + if (status != 0) { + fprintf(stderr, "Failed to set bandwidth = %u: %s\n", handler->rx_rate, bladerf_strerror(status)); + return -1; + } + printf("Set RX sampling rate %.2f Mhz, filter BW: %.2f Mhz\n", (float) handler->rx_rate/1e6, (float) bw/1e6); + return (double) handler->rx_rate; +} + +double rf_blade_set_tx_srate(void *h, double freq) +{ + uint32_t bw; + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + int status = bladerf_set_sample_rate(handler->dev, BLADERF_MODULE_TX, (uint32_t) freq, &handler->tx_rate); + if (status != 0) { + fprintf(stderr, "Failed to set samplerate = %u: %s\n", (uint32_t) freq, bladerf_strerror(status)); + return -1; + } + status = bladerf_set_bandwidth(handler->dev, BLADERF_MODULE_TX, handler->tx_rate, &bw); + if (status != 0) { + fprintf(stderr, "Failed to set bandwidth = %u: %s\n", handler->tx_rate, bladerf_strerror(status)); + return -1; + } + return (double) handler->tx_rate; +} + +double rf_blade_set_rx_gain(void *h, double gain) +{ + int status; + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + status = bladerf_set_rxvga2(handler->dev, (int) gain); + if (status != 0) { + fprintf(stderr, "Failed to set RX VGA2 gain: %s\n", bladerf_strerror(status)); + return -1; + } + return rf_blade_get_rx_gain(h); +} + +double rf_blade_set_tx_gain(void *h, double gain) +{ + int status; + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + status = bladerf_set_txvga2(handler->dev, (int) gain); + if (status != 0) { + fprintf(stderr, "Failed to set TX VGA2 gain: %s\n", bladerf_strerror(status)); + return -1; + } + return rf_blade_get_tx_gain(h); +} + +double rf_blade_get_rx_gain(void *h) +{ + int status; + int gain; + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + status = bladerf_get_rxvga2(handler->dev, &gain); + if (status != 0) { + fprintf(stderr, "Failed to get RX VGA2 gain: %s\n", + bladerf_strerror(status)); + return -1; + } + return gain; // Add rxvga1 and LNA +} + +double rf_blade_get_tx_gain(void *h) +{ + int status; + int gain; + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + status = bladerf_get_txvga2(handler->dev, &gain); + if (status != 0) { + fprintf(stderr, "Failed to get TX VGA2 gain: %s\n", + bladerf_strerror(status)); + return -1; + } + return gain; // Add txvga1 +} + +double rf_blade_set_rx_freq(void *h, double freq) +{ + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + uint32_t f_int = (uint32_t) round(freq); + int status = bladerf_set_frequency(handler->dev, BLADERF_MODULE_RX, f_int); + if (status != 0) { + fprintf(stderr, "Failed to set samplerate = %u: %s\n", + (uint32_t) freq, bladerf_strerror(status)); + return -1; + } + return freq; +} + +double rf_blade_set_tx_freq(void *h, double freq) +{ + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + uint32_t f_int = (uint32_t) round(freq); + int status = bladerf_set_frequency(handler->dev, BLADERF_MODULE_TX, f_int); + if (status != 0) { + fprintf(stderr, "Failed to set samplerate = %u: %s\n", + (uint32_t) freq, bladerf_strerror(status)); + return -1; + } + + return freq; +} + +void rf_blade_set_tx_cal(void *h, srslte_rf_cal_t *cal) { + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_PHASE, cal->dc_gain); + bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_FPGA_GAIN, cal->dc_phase); + bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_I, cal->iq_i); + bladerf_set_correction(handler->dev, BLADERF_MODULE_TX, BLADERF_CORR_LMS_DCOFF_Q, cal->iq_q); +} + +void rf_blade_set_rx_cal(void *h, srslte_rf_cal_t *cal) { + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_PHASE, cal->dc_gain); + bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_FPGA_GAIN, cal->dc_phase); + bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_LMS_DCOFF_I, cal->iq_i); + bladerf_set_correction(handler->dev, BLADERF_MODULE_RX, BLADERF_CORR_LMS_DCOFF_Q, cal->iq_q); +} + + +static void timestamp_to_secs(uint32_t rate, uint64_t timestamp, time_t *secs, double *frac_secs) { + double totalsecs = (double) timestamp/rate; + time_t secs_i = (time_t) totalsecs; + if (secs) { + *secs = secs_i; + } + if (frac_secs) { + *frac_secs = totalsecs-secs_i; + } +} + +static void secs_to_timestamps(uint32_t rate, time_t secs, double frac_secs, uint64_t *timestamp) { + double totalsecs = (double) secs + frac_secs; + if (timestamp) { + *timestamp = rate * totalsecs; + } +} + +void rf_blade_get_time(void *h, time_t *secs, double *frac_secs) +{ + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + struct bladerf_metadata meta; + + int status = bladerf_get_timestamp(handler->dev, BLADERF_MODULE_RX, &meta.timestamp); + if (status != 0) { + fprintf(stderr, "Failed to get current RX timestamp: %s\n", + bladerf_strerror(status)); + } + timestamp_to_secs(handler->rx_rate, meta.timestamp, secs, frac_secs); +} + +int rf_blade_recv_with_time(void *h, + void *data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs) +{ + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + struct bladerf_metadata meta; + int status; + + memset(&meta, 0, sizeof(meta)); + meta.flags = BLADERF_META_FLAG_RX_NOW; + + if (2*nsamples > CONVERT_BUFFER_SIZE) { + fprintf(stderr, "RX failed: nsamples exceeds buffer size (%d>%d)\n", nsamples, CONVERT_BUFFER_SIZE); + return -1; + } + status = bladerf_sync_rx(handler->dev, handler->rx_buffer, nsamples, &meta, 2000); + if (status) { + fprintf(stderr, "RX failed: %s\n\n", bladerf_strerror(status)); + return -1; + } else if (meta.status & BLADERF_META_STATUS_OVERRUN) { + if (blade_error_handler) { + srslte_rf_error_t error; + error.opt = meta.actual_count; + error.type = SRSLTE_RF_ERROR_OVERFLOW; + blade_error_handler(error); + } else { + fprintf(stderr, "Overrun detected in scheduled RX. " + "%u valid samples were read.\n\n", meta.actual_count); + } + } + + timestamp_to_secs(handler->rx_rate, meta.timestamp, secs, frac_secs); + srslte_vec_convert_if(handler->rx_buffer, data, 2048, 2*nsamples); + + return nsamples; +} + +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) +{ + rf_blade_handler_t *handler = (rf_blade_handler_t*) h; + struct bladerf_metadata meta; + int status; + + if (!handler->tx_stream_enabled) { + rf_blade_start_tx_stream(h); + } + + if (2*nsamples > CONVERT_BUFFER_SIZE) { + fprintf(stderr, "TX failed: nsamples exceeds buffer size (%d>%d)\n", nsamples, CONVERT_BUFFER_SIZE); + return -1; + } + + srslte_vec_convert_fi(data, handler->tx_buffer, 2048, 2*nsamples); + + memset(&meta, 0, sizeof(meta)); + if (is_start_of_burst) { + if (has_time_spec) { + secs_to_timestamps(handler->tx_rate, secs, frac_secs, &meta.timestamp); + } else { + meta.flags |= BLADERF_META_FLAG_TX_NOW; + } + meta.flags |= BLADERF_META_FLAG_TX_BURST_START; + } + if (is_end_of_burst) { + meta.flags |= BLADERF_META_FLAG_TX_BURST_END; + } + status = bladerf_sync_tx(handler->dev, handler->tx_buffer, nsamples, &meta, 2000); + if (status == BLADERF_ERR_TIME_PAST) { + if (blade_error_handler) { + srslte_rf_error_t error; + error.type = SRSLTE_RF_ERROR_LATE; + blade_error_handler(error); + } else { + fprintf(stderr, "TX failed: %s\n", bladerf_strerror(status)); + } + } else if (status) { + fprintf(stderr, "TX failed: %s\n", bladerf_strerror(status)); + return status; + } else if (meta.status == BLADERF_META_STATUS_UNDERRUN) { + if (blade_error_handler) { + srslte_rf_error_t error; + error.type = SRSLTE_RF_ERROR_UNDERFLOW; + blade_error_handler(error); + } else { + fprintf(stderr, "TX warning: underflow detected.\n"); + } + } + + return nsamples; +} + diff --git a/srslte/lib/rf/src/rf_blade_imp.h b/srslte/lib/rf/src/rf_blade_imp.h new file mode 100644 index 000000000..e6d05804d --- /dev/null +++ b/srslte/lib/rf/src/rf_blade_imp.h @@ -0,0 +1,110 @@ +/** + * + * \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); + +SRSLTE_API int rf_blade_close(void *h); + +SRSLTE_API void rf_blade_set_tx_cal(void *h, srslte_rf_cal_t *cal); + +SRSLTE_API void rf_blade_set_rx_cal(void *h, srslte_rf_cal_t *cal); + +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 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_error_handler(void *h, + srslte_rf_error_handler_t error_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); + + diff --git a/srslte/lib/rf/src/rf_dev.h b/srslte/lib/rf/src/rf_dev.h new file mode 100644 index 000000000..01d858fa7 --- /dev/null +++ b/srslte/lib/rf/src/rf_dev.h @@ -0,0 +1,141 @@ +/** + * + * \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 (*srslte_rf_rx_wait_lo_locked) (void*); + int (*srslte_rf_start_rx_stream)(void *h); + int (*srslte_rf_stop_rx_stream)(void *h); + void (*srslte_rf_flush_buffer)(void *h); + bool (*srslte_rf_has_rssi)(void *h); + float (*srslte_rf_get_rssi)(void *h); + void (*srslte_rf_suppress_stdout)(void *h); + void (*srslte_rf_register_error_handler)(void *h, srslte_rf_error_handler_t error_handler); + int (*srslte_rf_open)(char *args, void **h); + int (*srslte_rf_close)(void *h); + void (*srslte_rf_set_master_clock_rate)(void *h, double rate); + bool (*srslte_rf_is_master_clock_dynamic)(void *h); + double (*srslte_rf_set_rx_srate)(void *h, double freq); + double (*srslte_rf_set_rx_gain)(void *h, double gain); + double (*srslte_rf_set_tx_gain)(void *h, double gain); + double (*srslte_rf_get_rx_gain)(void *h); + double (*srslte_rf_get_tx_gain)(void *h); + double (*srslte_rf_set_rx_freq)(void *h, double freq); + double (*srslte_rf_set_tx_srate)(void *h, double freq); + double (*srslte_rf_set_tx_freq)(void *h, double freq); + void (*srslte_rf_get_time)(void *h, time_t *secs, double *frac_secs); + int (*srslte_rf_recv_with_time)(void *h, void *data, uint32_t nsamples, + bool blocking, time_t *secs,double *frac_secs); + int (*srslte_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); + void (*srslte_rf_set_tx_cal)(void *h, srslte_rf_cal_t *cal); + + void (*srslte_rf_set_rx_cal)(void *h, srslte_rf_cal_t *cal); + +} 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_suppress_stdout, + rf_uhd_register_error_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, + rf_uhd_set_tx_cal, + rf_uhd_set_rx_cal +}; +#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_suppress_stdout, + rf_blade_register_error_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, + rf_blade_set_tx_cal, + rf_blade_set_rx_cal +}; +#endif + +static rf_dev_t *available_devices[] = { +#ifdef ENABLE_UHD + &dev_uhd, +#endif +#ifdef ENABLE_BLADERF + &dev_blade, +#endif + NULL +}; diff --git a/srslte/lib/rf/src/rf_imp.c b/srslte/lib/rf/src/rf_imp.c new file mode 100644 index 000000000..03c1cdaed --- /dev/null +++ b/srslte/lib/rf/src/rf_imp.c @@ -0,0 +1,309 @@ +/** + * + * \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 + +#include "srslte/rf/rf.h" +#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; +} + +double srslte_rf_set_rx_gain_th(srslte_rf_t *rf, double gain) +{ + if (gain > rf->new_rx_gain + 0.5 || gain < rf->new_rx_gain - 0.5) { + pthread_mutex_lock(&rf->mutex); + rf->new_rx_gain = gain; + pthread_cond_signal(&rf->cond); + pthread_mutex_unlock(&rf->mutex); + } + return gain; +} + +void srslte_rf_set_tx_rx_gain_offset(srslte_rf_t *rf, double offset) { + rf->tx_rx_gain_offset = offset; +} + +/* This thread listens for set_rx_gain commands to the USRP */ +static void* thread_gain_fcn(void *h) { + srslte_rf_t* rf = (srslte_rf_t*) h; + + while(1) { + pthread_mutex_lock(&rf->mutex); + while(rf->cur_rx_gain == rf->new_rx_gain) + { + pthread_cond_wait(&rf->cond, &rf->mutex); + } + if (rf->new_rx_gain != rf->cur_rx_gain) { + rf->cur_rx_gain = rf->new_rx_gain; + srslte_rf_set_rx_gain(h, rf->cur_rx_gain); + } + if (rf->tx_gain_same_rx) { + srslte_rf_set_tx_gain(h, rf->cur_rx_gain+rf->tx_rx_gain_offset); + } + pthread_mutex_unlock(&rf->mutex); + } + return NULL; +} + + +/* Create auxiliary thread and mutexes for AGC */ +int srslte_rf_start_gain_thread(srslte_rf_t *rf, bool tx_gain_same_rx) { + rf->tx_gain_same_rx = tx_gain_same_rx; + rf->tx_rx_gain_offset = 0.0; + if (pthread_mutex_init(&rf->mutex, NULL)) { + return -1; + } + if (pthread_cond_init(&rf->cond, NULL)) { + return -1; + } + if (pthread_create(&rf->thread_gain, NULL, thread_gain_fcn, rf)) { + perror("pthread_create"); + return -1; + } + return 0; +} + +const char* srslte_rf_get_devname(srslte_rf_t *rf) { + return ((rf_dev_t*) rf->dev)->name; +} + +int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args) { + /* Try to open the device if name is provided */ + if (devname) { + if (devname[0] != '\0') { + int i=0; + while(available_devices[i] != NULL) { + if (!strcmp(available_devices[i]->name, devname)) { + rf->dev = available_devices[i]; + return available_devices[i]->srslte_rf_open(args, &rf->handler); + } + 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]->srslte_rf_open(args, &rf->handler)) { + rf->dev = available_devices[i]; + return 0; + } + i++; + } + fprintf(stderr, "No compatible RF frontend found\n"); + return -1; +} + +void srslte_rf_set_tx_cal(srslte_rf_t *rf, srslte_rf_cal_t *cal) { + return ((rf_dev_t*) rf->dev)->srslte_rf_set_tx_cal(rf->handler, cal); +} + +void srslte_rf_set_rx_cal(srslte_rf_t *rf, srslte_rf_cal_t *cal) { + return ((rf_dev_t*) rf->dev)->srslte_rf_set_rx_cal(rf->handler, cal); +} + + +const char* srslte_rf_name(srslte_rf_t *rf) { + return ((rf_dev_t*) rf->dev)->name; +} + +bool srslte_rf_rx_wait_lo_locked(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_rx_wait_lo_locked(rf->handler); +} + +int srslte_rf_start_rx_stream(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_start_rx_stream(rf->handler); +} + +int srslte_rf_stop_rx_stream(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_stop_rx_stream(rf->handler); +} + +void srslte_rf_flush_buffer(srslte_rf_t *rf) +{ + ((rf_dev_t*) rf->dev)->srslte_rf_flush_buffer(rf->handler); +} + +bool srslte_rf_has_rssi(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_has_rssi(rf->handler); +} + +float srslte_rf_get_rssi(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_get_rssi(rf->handler); +} + +void srslte_rf_suppress_stdout(srslte_rf_t *rf) +{ + ((rf_dev_t*) rf->dev)->srslte_rf_suppress_stdout(rf->handler); +} + +void srslte_rf_register_error_handler(srslte_rf_t *rf, srslte_rf_error_handler_t error_handler) +{ + ((rf_dev_t*) rf->dev)->srslte_rf_register_error_handler(rf->handler, error_handler); +} + +int srslte_rf_open(srslte_rf_t *h, char *args) +{ + return srslte_rf_open_devname(h, NULL, args); +} + +int srslte_rf_close(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_close(rf->handler); +} + +void srslte_rf_set_master_clock_rate(srslte_rf_t *rf, double rate) +{ + ((rf_dev_t*) rf->dev)->srslte_rf_set_master_clock_rate(rf->handler, rate); +} + +bool srslte_rf_is_master_clock_dynamic(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_is_master_clock_dynamic(rf->handler); +} + +double srslte_rf_set_rx_srate(srslte_rf_t *rf, double freq) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_set_rx_srate(rf->handler, freq); +} + +double srslte_rf_set_rx_gain(srslte_rf_t *rf, double gain) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_set_rx_gain(rf->handler, gain); +} + +double srslte_rf_get_rx_gain(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_get_rx_gain(rf->handler); +} + +double srslte_rf_get_tx_gain(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_get_tx_gain(rf->handler); +} + +double srslte_rf_set_rx_freq(srslte_rf_t *rf, double freq) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_set_rx_freq(rf->handler, freq); +} + + +int srslte_rf_recv(srslte_rf_t *rf, void *data, uint32_t nsamples, bool blocking) +{ + return srslte_rf_recv_with_time(rf, data, nsamples, blocking, NULL, NULL); +} + +int srslte_rf_recv_with_time(srslte_rf_t *rf, + void *data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_recv_with_time(rf->handler, data, nsamples, blocking, secs, frac_secs); +} + +double srslte_rf_set_tx_gain(srslte_rf_t *rf, double gain) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_set_tx_gain(rf->handler, gain); +} + +double srslte_rf_set_tx_srate(srslte_rf_t *rf, double freq) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_set_tx_srate(rf->handler, freq); +} + +double srslte_rf_set_tx_freq(srslte_rf_t *rf, double freq) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_set_tx_freq(rf->handler, freq); +} + +void srslte_rf_get_time(srslte_rf_t *rf, time_t *secs, double *frac_secs) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_get_time(rf->handler, secs, frac_secs); +} + + +int srslte_rf_send_timed3(srslte_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)->srslte_rf_send_timed(rf->handler, data, nsamples, secs, frac_secs, + has_time_spec, blocking, is_start_of_burst, is_end_of_burst); +} + +int srslte_rf_send(srslte_rf_t *rf, void *data, uint32_t nsamples, bool blocking) +{ + return srslte_rf_send2(rf, data, nsamples, blocking, true, true); +} + +int srslte_rf_send2(srslte_rf_t *rf, void *data, uint32_t nsamples, bool blocking, bool start_of_burst, bool end_of_burst) +{ + return srslte_rf_send_timed3(rf, data, nsamples, 0, 0, false, blocking, start_of_burst, end_of_burst); +} + + +int srslte_rf_send_timed(srslte_rf_t *rf, + void *data, + int nsamples, + time_t secs, + double frac_secs) +{ + return srslte_rf_send_timed2(rf, data, nsamples, secs, frac_secs, true, true); +} + +int srslte_rf_send_timed2(srslte_rf_t *rf, + void *data, + int nsamples, + time_t secs, + double frac_secs, + bool is_start_of_burst, + bool is_end_of_burst) +{ + return srslte_rf_send_timed3(rf, data, nsamples, secs, frac_secs, true, true, is_start_of_burst, is_end_of_burst); +} diff --git a/srslte/lib/rf/src/rf_uhd_imp.c b/srslte/lib/rf/src/rf_uhd_imp.c new file mode 100644 index 000000000..639190211 --- /dev/null +++ b/srslte/lib/rf/src/rf_uhd_imp.c @@ -0,0 +1,523 @@ +/** + * + * \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 +#include +#include +#include +#include + +#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; + + uhd_meta_range_handle rx_gain_range; + 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 +} + +srslte_rf_error_handler_t uhd_error_handler = NULL; + +void msg_handler(const char *msg) +{ + srslte_rf_error_t error; + if(0 == strcmp(msg, "O")) { + error.type = SRSLTE_RF_ERROR_OVERFLOW; + } else if(0 == strcmp(msg, "D")) { + error.type = SRSLTE_RF_ERROR_OVERFLOW; + }else if(0 == strcmp(msg, "U")) { + error.type = SRSLTE_RF_ERROR_UNDERFLOW; + } else if(0 == strcmp(msg, "L")) { + error.type = SRSLTE_RF_ERROR_LATE; + } + if (uhd_error_handler) { + uhd_error_handler(error); + } +} + +void rf_uhd_suppress_stdout(void *h) { + rf_uhd_register_msg_handler_c(suppress_handler); +} + +void rf_uhd_register_error_handler(void *notused, srslte_rf_error_handler_t new_handler) +{ + uhd_error_handler = new_handler; + rf_uhd_register_msg_handler_c(msg_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;iusrp, 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_sensor_value_make_from_bool(&value_h, "", true, "True", "False"); + 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; +} + +void rf_uhd_set_tx_cal(void *h, srslte_rf_cal_t *cal) +{ + +} + +void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal) +{ + +} + + +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_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); + 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_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); + uhd_sensor_value_free(&value); + return val_out; +} + +int rf_uhd_open(char *args, void **h) +{ + if (h) { + *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); + + /* Set correct options for the USRP device */ + uhd_string_vector_handle devices_str; + uhd_string_vector_make(&devices_str); + uhd_usrp_find("", &devices_str); + + // Allow NULL parameter + if (args == NULL) { + args = ""; + } + + /* If device type or name not given in args, choose a B200 */ + if (args[0]=='\0') { + // If B200 is available, use it + if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) { + args = "type=b200,recv_frame_size=9232,send_frame_size=9232"; + } + } + + /* Create UHD handler */ + printf("Opening USRP with args: %s\n", args); + uhd_error error = uhd_usrp_make(&handler->usrp, args); + if (error) { + fprintf(stderr, "Error opening UHD: code %d\n", error); + return -1; + } + + 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) { + fprintf(stderr, "Error opening RX stream: %d\n", error); + return -1; + } + uhd_tx_streamer_make(&handler->tx_stream); + error = uhd_usrp_get_tx_stream(handler->usrp, &stream_args, handler->tx_stream); + if (error) { + fprintf(stderr, "Error opening TX stream: %d\n", error); + return -1; + } + + uhd_rx_streamer_max_num_samps(handler->rx_stream, &handler->rx_nof_samples); + uhd_tx_streamer_max_num_samps(handler->tx_stream, &handler->tx_nof_samples); + + uhd_meta_range_make(&handler->rx_gain_range); + uhd_usrp_get_rx_gain_range(handler->usrp, "", 0, handler->rx_gain_range); + + // 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); + + /* 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; + } else { + return SRSLTE_ERROR_INVALID_INPUTS; + } +} + + +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) +{ + + 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, 5.0, false, &rxd_samples); + + if (error) { + fprintf(stderr, "Error receiving from UHD: %d\n", error); + 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; + + 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) { + fprintf(stderr, "Error sending to UHD: %d\n", error); + 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); + } +} + diff --git a/srslte/lib/rf/src/rf_uhd_imp.h b/srslte/lib/rf/src/rf_uhd_imp.h new file mode 100644 index 000000000..240cfc8f0 --- /dev/null +++ b/srslte/lib/rf/src/rf_uhd_imp.h @@ -0,0 +1,108 @@ +/** + * + * \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 +#include + +#include "srslte/config.h" +#include "srslte/rf/rf.h" + +SRSLTE_API int rf_uhd_open(char *args, + void **handler); + +SRSLTE_API int rf_uhd_close(void *h); + +SRSLTE_API void rf_uhd_set_tx_cal(void *h, srslte_rf_cal_t *cal); + +SRSLTE_API void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal); + +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 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_error_handler(void *h, srslte_rf_error_handler_t error_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); + diff --git a/srslte/lib/cuhd/src/cuhd_utils.c b/srslte/lib/rf/src/rf_utils.c similarity index 74% rename from srslte/lib/cuhd/src/cuhd_utils.c rename to srslte/lib/rf/src/rf_utils.c index 1cf802fa8..bd3b6ca85 100644 --- a/srslte/lib/cuhd/src/cuhd_utils.c +++ b/srslte/lib/rf/src/rf_utils.c @@ -36,35 +36,35 @@ #include "srslte/srslte.h" -#include "srslte/cuhd/cuhd.h" -#include "srslte/cuhd/cuhd_utils.h" +#include "srslte/rf/rf.h" +#include "srslte/rf/rf_utils.h" -int cuhd_rssi_scan(void *uhd, float *freqs, float *rssi, int nof_bands, double fs, int nsamp) { +int rf_rssi_scan(srslte_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; } - cuhd_set_rx_gain(uhd, 20.0); - cuhd_set_rx_srate(uhd, fs); + srslte_rf_set_rx_gain(rf, 20.0); + srslte_rf_set_rx_srate(rf, fs); for (i=0;iid, cell->cp, cuhd_recv_wrapper_cs, uhd)) { + if (srslte_ue_mib_sync_init(&ue_mib, cell->id, cell->cp, srslte_rf_recv_wrapper_cs, (void*) rf)) { fprintf(stderr, "Error initiating srslte_ue_mib_sync\n"); goto clean_exit; } if (config->init_agc > 0) { - srslte_ue_sync_start_agc(&ue_mib.ue_sync, cuhd_set_rx_gain_th, config->init_agc); + srslte_ue_sync_start_agc(&ue_mib.ue_sync, srslte_rf_set_rx_gain_th_wrapper, config->init_agc); } int srate = srslte_sampling_freq_hz(SRSLTE_UE_MIB_NOF_PRB); INFO("Setting sampling frequency %.2f MHz for PSS search\n", (float) srate/1000000); - cuhd_set_rx_srate(uhd, (float) srate); + srslte_rf_set_rx_srate(rf, (float) srate); INFO("Starting receiver...\n", 0); - cuhd_start_rx_stream(uhd); + srslte_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); @@ -129,15 +133,15 @@ int cuhd_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell) clean_exit: - cuhd_stop_rx_stream(uhd); + srslte_rf_stop_rx_stream(rf); srslte_ue_mib_sync_free(&ue_mib); return ret; } -/** This function is simply a wrapper to the ue_cell_search module for cuhd devices +/** This function is simply a wrapper to the ue_cell_search module for rf devices */ -int cuhd_cell_search(void *uhd, cell_search_cfg_t *config, +int rf_cell_search(srslte_rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell) { int ret = SRSLTE_ERROR; @@ -146,7 +150,7 @@ int cuhd_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, cuhd_recv_wrapper_cs, uhd)) { + if (srslte_ue_cellsearch_init(&cs, srslte_rf_recv_wrapper_cs, (void*) rf)) { fprintf(stderr, "Error initiating UE cell detect\n"); return SRSLTE_ERROR; } @@ -159,14 +163,14 @@ int cuhd_cell_search(void *uhd, cell_search_cfg_t *config, } if (config->init_agc > 0) { - srslte_ue_sync_start_agc(&cs.ue_sync, cuhd_set_rx_gain_th, config->init_agc); + srslte_ue_sync_start_agc(&cs.ue_sync, srslte_rf_set_rx_gain_th_wrapper, config->init_agc); } INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000); - cuhd_set_rx_srate(uhd, SRSLTE_CS_SAMP_FREQ); + srslte_rf_set_rx_srate(rf, SRSLTE_CS_SAMP_FREQ); INFO("Starting receiver...\n", 0); - cuhd_start_rx_stream(uhd); + srslte_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; @@ -207,7 +211,7 @@ int cuhd_cell_search(void *uhd, cell_search_cfg_t *config, config->init_agc = srslte_agc_get_gain(&cs.ue_sync.agc); } - cuhd_stop_rx_stream(uhd); + srslte_rf_stop_rx_stream(rf); srslte_ue_cellsearch_free(&cs); return ret; @@ -219,15 +223,15 @@ int cuhd_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 cuhd_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(srslte_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 = cuhd_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 = cuhd_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; diff --git a/srslte/lib/rf/src/uhd_c_api.cpp b/srslte/lib/rf/src/uhd_c_api.cpp new file mode 100644 index 000000000..c7684aa23 --- /dev/null +++ b/srslte/lib/rf/src/uhd_c_api.cpp @@ -0,0 +1,46 @@ + + +/* This file implements a few features not currently provided by the UHD C-API */ +#include +#include + +extern "C" { +#include "srslte/rf/rf.h" +#include "uhd_c_api.h" +} + +static void (*handler)(const char*); + +void translate_handler(uhd::msg::type_t type, const std::string & msg) +{ + if(handler) + handler(msg.c_str()); +} + +void rf_uhd_register_msg_handler_c(void (*new_handler)(const char*)) +{ + 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); + (*md)->tx_metadata_cpp.has_time_spec = true; +} + +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; +} + diff --git a/srslte/lib/rf/src/uhd_c_api.h b/srslte/lib/rf/src/uhd_c_api.h new file mode 100644 index 000000000..263441975 --- /dev/null +++ b/srslte/lib/rf/src/uhd_c_api.h @@ -0,0 +1,11 @@ + +#include +#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(void (*new_handler)(const char*)); +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); diff --git a/srslte/lib/sync/src/sync.c b/srslte/lib/sync/src/sync.c index 23114254d..c43c8a3eb 100644 --- a/srslte/lib/sync/src/sync.c +++ b/srslte/lib/sync/src/sync.c @@ -66,6 +66,7 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, q->N_id_1 = 1000; q->cfo_i = 0; q->find_cfo_i = false; + q->find_cfo_i_initiated = false; q->cfo_ema_alpha = CFO_EMA_ALPHA; q->fft_size = fft_size; q->frame_size = frame_size; @@ -137,14 +138,17 @@ void srslte_sync_set_threshold(srslte_sync_t *q, float threshold) { void srslte_sync_cfo_i_detec_en(srslte_sync_t *q, bool enabled) { q->find_cfo_i = enabled; - for (int i=0;i<2;i++) { - int offset=(i==0)?-1:1; - if (srslte_pss_synch_init_fft_offset(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { - fprintf(stderr, "Error initializing PSS object\n"); - } - for (int t=0;tframe_size;t++) { - q->cfo_i_corr[i][t] = cexpf(-2*_Complex_I*M_PI*offset*(float) t/q->fft_size); + if (enabled && !q->find_cfo_i_initiated) { + for (int i=0;i<2;i++) { + int offset=(i==0)?-1:1; + if (srslte_pss_synch_init_fft_offset(&q->pss_i[i], q->max_offset, q->fft_size, offset)) { + fprintf(stderr, "Error initializing PSS object\n"); + } + for (int t=0;tframe_size;t++) { + q->cfo_i_corr[i][t] = cexpf(-2*_Complex_I*M_PI*offset*(float) t/q->fft_size); + } } + q->find_cfo_i_initiated = true; } } @@ -343,7 +347,6 @@ int srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32 fft_size_isvalid(q->fft_size)) { int peak_pos; - float correct_cfo = 0; ret = SRSLTE_SUCCESS; @@ -358,7 +361,7 @@ int srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32 float cfo = -carg(cp_corr_max) / M_PI / 2; /* compute cumulative moving average CFO */ - DEBUG("cp_offset_pos=%d, abs=%f, cfo=%f, mean_cfo=%f, nof_symb=%d\n", + INFO("cp_offset_pos=%d, abs=%f, cfo=%f, mean_cfo=%f, nof_symb=%d\n", cp_offset, cabs(cp_corr_max), cfo, q->mean_cfo, q->nof_symbols); if (q->mean_cfo) { q->mean_cfo = SRSLTE_VEC_EMA(cfo, q->mean_cfo, q->cfo_ema_alpha); @@ -367,16 +370,9 @@ int srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32 } /* Correct CFO with the averaged CFO estimation */ - correct_cfo = q->mean_cfo; - if (!q->find_cfo_i) { - correct_cfo = q->cfo_i + q->mean_cfo; - DEBUG("cfo_i disabled, correct_cfo=%d+%f=%f\n",q->cfo_i, q->mean_cfo, correct_cfo); - } - srslte_cfo_correct(&q->cfocorr, input, input, -correct_cfo / q->fft_size); + srslte_cfo_correct(&q->cfocorr, input, input, -q->mean_cfo / q->fft_size); } - - srslte_pss_synch_set_N_id_2(&q->pss, q->N_id_2); - + if (q->find_cfo_i && q->enable_cfo_corr) { float peak_value; float max_peak_value = -99; @@ -393,11 +389,11 @@ int srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32 } } if (q->cfo_i != 0) { - correct_cfo = q->cfo_i+q->mean_cfo; srslte_vec_prod_ccc(input, q->cfo_i_corr[q->cfo_i<0?0:1], input, q->frame_size); - DEBUG("Compensating cfo_i=%d, total_cfo=%f\n", q->cfo_i, correct_cfo); + INFO("Compensating cfo_i=%d\n", q->cfo_i); } } else { + srslte_pss_synch_set_N_id_2(&q->pss, q->N_id_2); peak_pos = srslte_pss_synch_find_pss(&q->pss, &input[find_offset], &q->peak_value); if (peak_pos < 0) { fprintf(stderr, "Error calling finding PSS sequence\n"); @@ -438,7 +434,7 @@ int srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32 } DEBUG("SYNC ret=%d N_id_2=%d find_offset=%d pos=%d peak=%.2f threshold=%.2f sf_idx=%d, CFO=%.3f KHz\n", - ret, q->N_id_2, find_offset, peak_pos, q->peak_value, q->threshold, q->sf_idx, 15*correct_cfo); + ret, q->N_id_2, find_offset, peak_pos, q->peak_value, q->threshold, q->sf_idx, 15*(q->cfo_i+q->mean_cfo)); } else if (srslte_N_id_2_isvalid(q->N_id_2)) { fprintf(stderr, "Must call srslte_sync_set_N_id_2() first!\n"); diff --git a/srslte/lib/sync/test/CMakeLists.txt b/srslte/lib/sync/test/CMakeLists.txt index 1eb40a72f..760b9de8b 100644 --- a/srslte/lib/sync/test/CMakeLists.txt +++ b/srslte/lib/sync/test/CMakeLists.txt @@ -33,7 +33,7 @@ ENDIF(SRSGUI_FOUND) IF(UHD_FOUND) ADD_EXECUTABLE(pss_usrp pss_usrp.c) - TARGET_LINK_LIBRARIES(pss_usrp srslte srslte_uhd) + TARGET_LINK_LIBRARIES(pss_usrp srslte srslte_rf) IF(SRSGUI_FOUND) target_link_libraries(pss_usrp ${SRSGUI_LIBRARIES}) ELSE(SRSGUI_FOUND) diff --git a/srslte/lib/sync/test/pss_usrp.c b/srslte/lib/sync/test/pss_usrp.c index 69daf50e1..e96a4379c 100644 --- a/srslte/lib/sync/test/pss_usrp.c +++ b/srslte/lib/sync/test/pss_usrp.c @@ -35,7 +35,7 @@ #include #include "srslte/srslte.h" -#include "srslte/cuhd/cuhd.h" +#include "srslte/rf/rf.h" #ifndef DISABLE_GRAPHICS @@ -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; + srslte_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 (cuhd_open(uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); + printf("Opening RF device...\n"); + if (srslte_rf_open(&rf, rf_args)) { + fprintf(stderr, "Error opening rf\n"); exit(-1); } if (srate < 10e6) { - cuhd_set_master_clock_rate(uhd, 4*srate); + srslte_rf_set_master_clock_rate(&rf, 4*srate); } else { - cuhd_set_master_clock_rate(uhd, srate); + srslte_rf_set_master_clock_rate(&rf, srate); } - printf("Set RX rate: %.2f MHz\n", cuhd_set_rx_srate(uhd, srate) / 1000000); - printf("Set RX gain: %.1f dB\n", cuhd_set_rx_gain(uhd, uhd_gain)); - printf("Set RX freq: %.2f MHz\n", cuhd_set_rx_freq(uhd, uhd_freq) / 1000000); - cuhd_rx_wait_lo_locked(uhd); + printf("Set RX rate: %.2f MHz\n", srslte_rf_set_rx_srate(&rf, srate) / 1000000); + printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_gain)); + printf("Set RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, rf_freq) / 1000000); + srslte_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); - cuhd_start_rx_stream(uhd); + srslte_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 = cuhd_recv(uhd, buffer, flen - peak_offset, 1); + n = srslte_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); - cuhd_close(uhd); + srslte_rf_close(&rf); printf("Ok\n"); exit(0); diff --git a/srslte/lib/ue/src/ue_ul.c b/srslte/lib/ue/src/ue_ul.c index dd04d555c..927a8c9d8 100644 --- a/srslte/lib/ue/src/ue_ul.c +++ b/srslte/lib/ue/src/ue_ul.c @@ -252,18 +252,18 @@ int pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t *format *format = SRSLTE_PUCCH_FORMAT_2; } // CQI + 1-bit ACK - else if (uci_data->uci_cqi_len == SRSLTE_PUCCH_MAX_BITS && uci_data->uci_ack_len == 1) { + else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1) { *format = SRSLTE_PUCCH_FORMAT_2A; pucch2_bits[0] = uci_data->uci_ack; } // CQI + 2-bit ACK - else if (uci_data->uci_cqi_len == SRSLTE_PUCCH_MAX_BITS && uci_data->uci_ack_len == 2) { + else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 2) { *format = SRSLTE_PUCCH_FORMAT_2B; pucch2_bits[0] = uci_data->uci_ack; pucch2_bits[1] = uci_data->uci_ack_2; } // CQI + 2-bit ACK + cyclic prefix - else if (uci_data->uci_cqi_len == SRSLTE_PUCCH_MAX_BITS && uci_data->uci_ack_len == 1 && SRSLTE_CP_ISEXT(cp)) { + else if (uci_data->uci_cqi_len > 0 && uci_data->uci_ack_len == 1 && SRSLTE_CP_ISEXT(cp)) { *format = SRSLTE_PUCCH_FORMAT_2B; pucch2_bits[0] = uci_data->uci_ack; pucch2_bits[1] = uci_data->uci_ack_2; diff --git a/srslte/lib/utils/src/vector.c b/srslte/lib/utils/src/vector.c index 2071d5265..12f416d9e 100644 --- a/srslte/lib/utils/src/vector.c +++ b/srslte/lib/utils/src/vector.c @@ -241,7 +241,7 @@ void srslte_vec_convert_if(int16_t *x, float *z, float scale, uint32_t len) { #ifndef HAVE_VOLK_CONVERT_IF_FUNCTION int i; for (i=0;i