diff --git a/.gitignore b/.gitignore index 4aa4e966..1f73bdca 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,10 @@ build/* CMakeFiles/* Beamformer/build/* Beamformer/build/CMakeFiles/* -Sounder/CMakeFiles/* -Sounder/CMakeCache* +CC/Sounder/CMakeFiles/* +CC/Sounder/CMakeCache* +CC/Sounder/mufft +CC/Sounder/build sounder *.com diff --git a/CC/Sounder/BaseRadioSetUHD.cc b/CC/Sounder/BaseRadioSetUHD.cc index f6cadfa1..43916b9f 100644 --- a/CC/Sounder/BaseRadioSetUHD.cc +++ b/CC/Sounder/BaseRadioSetUHD.cc @@ -9,6 +9,12 @@ */ #include "include/BaseRadioSetUHD.h" +#include +#include +#include +#include +#include + #include "SoapySDR/Formats.h" #include "SoapySDR/Time.hpp" #include "include/RadioUHD.h" @@ -26,34 +32,36 @@ BaseRadioSetUHD::BaseRadioSetUHD(Config* cfg) : _cfg(cfg) { radioNotFound = false; std::vector radio_serial_not_found; + std::cout << "error found !!!" << std::endl; + // need to be further modified + MLPD_TRACE("num of cells are: %zu\n", _cfg->num_cells()); for (size_t c = 0; c < _cfg->num_cells(); c++) { size_t num_radios = _cfg->n_bs_sdrs()[c]; num_bs_antenntas[c] = num_radios * _cfg->bs_channel().length(); + MLPD_TRACE("num of bs antennas are: %zu\n", num_bs_antenntas[c]); MLPD_TRACE("Setting up radio: %zu, cells: %zu\n", num_radios, _cfg->num_cells()); - std::atomic_ulong thread_count = ATOMIC_VAR_INIT(num_radios); + std::atomic_ulong thread_count = ATOMIC_VAR_INIT(1); MLPD_TRACE("Init base radios: %zu\n", num_radios); - for (size_t i = 0; i < num_radios; i++) { - BaseRadioContext* context = new BaseRadioContext; - context->brs = this; - context->thread_count = &thread_count; - context->tid = i; - context->cell = c; + size_t i = 0; + BaseRadioContext* context = new BaseRadioContext; + context->brs = this; + context->thread_count = &thread_count; + context->tid = i; + context->cell = c; #ifdef THREADED_INIT - pthread_t init_thread_; - - if (pthread_create(&init_thread_, NULL, BaseRadioSetUHD::init_launch, - context) != 0) { - delete context; - throw std::runtime_error("BaseRadioSet - init thread create failed"); - } + pthread_t init_thread_; + if (pthread_create(&init_thread_, NULL, BaseRadioSetUHD::init_launch, + context) != 0) { + delete context; + throw std::runtime_error("BaseRadioSet - init thread create failed"); + } #else - init(context); + init(context); #endif - } // Wait for init while (thread_count.load() > 0) { @@ -71,65 +79,83 @@ BaseRadioSetUHD::BaseRadioSetUHD(Config* cfg) : _cfg(cfg) { dciqCalibrationProcUHD(1); } - thread_count.store(num_radios); - for (size_t i = 0; i < num_radios; i++) { - BaseRadioContext* context = new BaseRadioContext; - context->brs = this; - context->thread_count = &thread_count; - context->tid = i; - context->cell = c; + // write TDD schedule and beacons to FPFA buffers only for Iris + const auto clock_source = _cfg->getBsClockType(); + bsRadios->RawDev()->set_time_source(clock_source); + bsRadios->RawDev()->set_clock_source(clock_source); + bsRadios->RawDev()->set_time_unknown_pps(uhd::time_spec_t(0.0)); + MLPD_INFO( + "USRP BS Clock source requested %s, actual %s, Time Source requested " + "%s, actual %s\n", + clock_source.c_str(), + bsRadios->RawDev() + ->get_clock_source(uhd::usrp::multi_usrp::ALL_MBOARDS) + .c_str(), + clock_source.c_str(), + bsRadios->RawDev() + ->get_time_source(uhd::usrp::multi_usrp::ALL_MBOARDS) + .c_str()); + + // Wait for pps sync pulse + std::this_thread::sleep_for(std::chrono::seconds(1)); + + thread_count.store(1); + size_t ii = 0; + BaseRadioContext* context_config = new BaseRadioContext; + context_config->brs = this; + context_config->thread_count = &thread_count; + context_config->tid = ii; + context_config->cell = c; #ifdef THREADED_INIT - pthread_t configure_thread_; - if (pthread_create(&configure_thread_, NULL, - BaseRadioSetUHD::configure_launch, context) != 0) { - delete context; - throw std::runtime_error( - "BaseRadioSet - configure thread create failed"); - } + pthread_t configure_thread_; + if (pthread_create(&configure_thread_, NULL, + BaseRadioSetUHD::configure_launch, + context_config) != 0) { + delete context_config; + throw std::runtime_error("BaseRadioSet - configure thread create failed"); + } #else - configure(context); + configure(context_config); #endif - } while (thread_count.load() > 0) { } - auto channels = Utils::strToChannels(_cfg->bs_channel()); - - for (size_t i = 0; i < bsRadios->RawDev()->get_num_mboards(); i++) { - auto dev = bsRadios->RawDev(); - std::cout << _cfg->bs_sdr_ids().at(c).at(i) << ": Front end " + auto dev = bsRadios->RawDev(); + for (size_t index = 0; index < bsRadios->RawDev()->get_num_mboards(); + index++) { + std::cout << _cfg->bs_sdr_ids().at(c).at(index) << ": Front end " << dev->get_usrp_rx_info()["frontend"] << std::endl; - for (auto ch : channels) { - if (ch < dev->get_rx_num_channels()) { - printf("RX Channel %zu\n", ch); - printf("Actual RX sample rate: %fMSps...\n", - (dev->get_rx_rate(ch) / 1e6)); - printf("Actual RX frequency: %fGHz...\n", - (dev->get_rx_freq(ch) / 1e9)); - printf("Actual RX gain: %f...\n", (dev->get_rx_gain(ch))); - printf("Actual RX bandwidth: %fM...\n", - (dev->get_rx_bandwidth(ch) / 1e6)); - printf("Actual RX antenna: %s...\n", - (dev->get_rx_antenna(ch).c_str())); - } + } + size_t total_rx_channel = _cfg->num_bs_sdrs_all() * 2; + for (size_t ch = 0; ch < total_rx_channel; ch++) { + if (ch < dev->get_rx_num_channels()) { + std::cout << "RX Channel " << ch << std::endl; + std::cout << "Actual RX sample rate: " << (dev->get_rx_rate(ch) / 1e6) + << "MSps" << std::endl; + std::cout << "Actual RX frequency: " << (dev->get_rx_freq(ch) / 1e9) + << "GHz" << std::endl; + std::cout << "Actual RX gain: " << (dev->get_rx_gain(ch)) << std::endl; + std::cout << "Actual RX bandwidth: " + << (dev->get_rx_bandwidth(ch) / 1e6) << "M" << std::endl; + std::cout << "Actual RX antenna: " << dev->get_rx_antenna(ch).c_str() + << std::endl; } + } - for (auto ch : channels) { - if (ch < dev->get_tx_num_channels()) { - printf("TX Channel %zu\n", ch); - printf("Actual TX sample rate: %fMSps...\n", - (dev->get_tx_rate(ch) / 1e6)); - printf("Actual TX frequency: %fGHz...\n", - (dev->get_tx_freq(ch) / 1e9)); - printf("Actual TX gain: %f...\n", (dev->get_tx_gain(ch))); - printf("Actual TX bandwidth: %fM...\n", - (dev->get_tx_bandwidth(ch) / 1e6)); - printf("Actual TX antenna: %s...\n", - (dev->get_tx_antenna(ch).c_str())); - } + for (size_t ch = 0; ch < total_rx_channel; ch++) { + if (ch < dev->get_tx_num_channels()) { + std::cout << "TX Channel " << ch << std::endl; + std::cout << "Actual TX sample rate: " << (dev->get_tx_rate(ch) / 1e6) + << "MSps" << std::endl; + std::cout << "Actual TX frequency: " << (dev->get_tx_freq(ch) / 1e9) + << "GHz" << std::endl; + std::cout << "Actual TX gain: " << (dev->get_tx_gain(ch)) << std::endl; + std::cout << "Actual TX bandwidth: " + << (dev->get_tx_bandwidth(ch) / 1e6) << "M" << std::endl; + std::cout << "Actual TX antenna: " << (dev->get_tx_antenna(ch).c_str()) + << std::endl; } - std::cout << std::endl; } } @@ -166,13 +192,6 @@ BaseRadioSetUHD::BaseRadioSetUHD(Config* cfg) : _cfg(cfg) { // write TDD schedule and beacons to FPFA buffers only for Iris for (size_t c = 0; c < _cfg->num_cells(); c++) { - bsRadios->RawDev()->set_time_source("external", 0); - bsRadios->RawDev()->set_clock_source("external", 0); - uhd::time_spec_t time = uhd::time_spec_t::from_ticks(0, 1e9); - bsRadios->RawDev()->set_time_next_pps(time); - - // Wait for pps sync pulse - std::this_thread::sleep_for(std::chrono::seconds(2)); // Activate Rx and Tx streamers bsRadios->activateRecv(); bsRadios->activateXmit(); @@ -190,28 +209,52 @@ void* BaseRadioSetUHD::init_launch(void* in_context) { } void BaseRadioSetUHD::init(BaseRadioContext* context) { - int i = context->tid; int c = context->cell; std::atomic_ulong* thread_count = context->thread_count; delete context; MLPD_TRACE("Deleting context for tid: %d\n", i); - auto channels = Utils::strToChannels(_cfg->bs_channel()); std::map args; args["driver"] = "uhd"; - args["addr"] = _cfg->bs_sdr_ids().at(c).at(i); - std::cout << "Init bsRadios: " << args["addr"] << std::endl; - // } + size_t num_radios = _cfg->n_bs_sdrs()[c]; + std::vector address_list; + for (size_t i = 0; i < num_radios; i++) { + std::ostringstream oss; + oss << "addr" << i; + address_list.push_back(oss.str()); + args[address_list.at(i)] = _cfg->bs_sdr_ids().at(c).at(i); + } + args["timeout"] = "1000000"; try { - bsRadios = nullptr; - bsRadios = new RadioUHD(args, SOAPY_SDR_CS16, channels, _cfg); + size_t total_rx_channel; + + if (_cfg->bs_channel() == "AB") { + total_rx_channel = _cfg->num_bs_sdrs_all() * 2; + } else { + total_rx_channel = _cfg->num_bs_sdrs_all(); + } + std::vector new_channels(total_rx_channel); + if (_cfg->bs_channel() == "AB") { + for (size_t ii = 0; ii < total_rx_channel; ii++) { + new_channels[ii] = ii; + } + } else if (_cfg->bs_channel() == "A") { + for (size_t ii = 0; ii < total_rx_channel; ii++) { + new_channels[ii] = ii * 2; + } + } else { + for (size_t ii = 0; ii < total_rx_channel; ii++) { + new_channels[ii] = ii * 2 + 1; + } + } + + bsRadios = new RadioUHD(args, SOAPY_SDR_CS16, new_channels, _cfg); } catch (std::runtime_error& err) { - std::cerr << "Ignoring uhd device " << _cfg->bs_sdr_ids().at(c).at(i) - << std::endl; - // } + std::cerr << "Ignoring uhd device "; + // } if (bsRadios != nullptr) { MLPD_TRACE("Deleting radio ptr due to exception\n"); delete bsRadios; @@ -234,14 +277,22 @@ void BaseRadioSetUHD::configure(BaseRadioContext* context) { delete context; //load channels - auto channels = Utils::strToChannels(_cfg->bs_channel()); + std::cout << "num channels in BSradio are: " << _cfg->bs_channel() + << std::endl; RadioUHD* bsRadio = bsRadios; uhd::usrp::multi_usrp::sptr dev = bsRadio->RawDev(); - for (auto ch : channels) { - double rxgain = _cfg->rx_gain().at(ch); - double txgain = _cfg->tx_gain().at(ch); - bsRadios->dev_init(_cfg, ch, rxgain, txgain); + + auto total_rx_channel = _cfg->num_bs_sdrs_all() * 2; + + for (unsigned int ch = 0; ch < total_rx_channel; ch++) { + double rxgain = _cfg->rx_gain().at(0); + double txgain = _cfg->tx_gain().at(0); + + bsRadios->dev_init(_cfg, (ch), rxgain, txgain); } + + bsRadios->dev_init_set_freq(_cfg, total_rx_channel); + assert(thread_count->load() != 0); thread_count->store(thread_count->load() - 1); } @@ -277,7 +328,6 @@ void BaseRadioSetUHD::radioStop(void) { void BaseRadioSetUHD::radioTx(const void* const* buffs) { long long frameTime(0); - std::cout << "running tx 1" << std::endl; bsRadios->xmit(buffs, _cfg->samps_per_slot(), 0, frameTime); } @@ -291,10 +341,10 @@ int BaseRadioSetUHD::radioTx(size_t radio_id, size_t cell_id, w = bsRadios->xmit(buffs, _cfg->samps_per_slot(), flags, frameTimeNs); // } if (kDebugRadio) { - size_t chanMask; - long timeoutUs(0); - auto* dev = bsRadios->dev; - auto* txs = bsRadios->txs; + //size_t chanMask; + //long timeoutUs(0); + //auto* dev = bsRadios->dev; + //auto* txs = bsRadios->txs; // int s = dev->readStreamStatus(txs, chanMask, flags, frameTime, timeoutUs); // std::cout << "cell " << cell_id << " radio " << radio_id << " tx returned " // << w << " and status " << s << std::endl; @@ -347,7 +397,6 @@ int BaseRadioSetUHD::radioRx(size_t radio_id, size_t cell_id, int BaseRadioSetUHD::syncTimeOffsetUHD(bool measure_ref_radio, bool adjust_trigger) { - std::cout << "sync time being called" << std::endl; int num_radios = _cfg->n_bs_sdrs().at(0) - 1; if (num_radios < 1) { std::cout << "No need to sample calibrate with one Iris! skipping ..." diff --git a/CC/Sounder/CMakeLists.txt b/CC/Sounder/CMakeLists.txt index d8185293..8cc3157a 100644 --- a/CC/Sounder/CMakeLists.txt +++ b/CC/Sounder/CMakeLists.txt @@ -24,6 +24,10 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) STRING "Choose the type of build." FORCE) endif() +message(STATUS "Debug Flags: ${CMAKE_CXX_FLAGS_DEBUG}") +message(STATUS "Release Flags: ${CMAKE_CXX_FLAGS_RELEASE}") +message(STATUS "Compiling with CXX Flags: ${CMAKE_CXX_FLAGS}") + if(CMAKE_BUILD_TYPE MATCHES Debug) message(STATUS "Verbose Makefile") set( CMAKE_VERBOSE_MAKEFILE on ) @@ -51,10 +55,15 @@ else() set(CMAKE_CXX_STANDARD_REQUIRED ON) endif() -message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") -message(STATUS "Compiling with CXX Flags: ${CMAKE_CXX_FLAGS}") -message(STATUS "Debug Flags: ${CMAKE_CXX_FLAGS_DEBUG}") -message(STATUS "Release Flags: ${CMAKE_CXX_FLAGS_RELEASE}") +#Settable values +message(STATUS "\n-- ----- Configuration values -----") +message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}") +set(RADIO_TYPE SIMULATION CACHE STRING "RADIO_TYPE defaulting to 'SIMULATION', valid types are SIMULATION / SOAPY_IRIS / SOAPY_UHD / PURE_UHD") +message(STATUS "RADIO_TYPE: ${RADIO_TYPE}") +set(LOG_LEVEL "info" CACHE STRING "Console logging level (none/error/warn/info/frame/subframe/trace)") +message(STATUS "LOG_LEVEL: ${LOG_LEVEL}") +message(STATUS "--------------------------------\n--") + # Console logging level if(LOG_LEVEL STREQUAL "none") @@ -92,8 +101,6 @@ set(THREADS_PREFER_PTHREAD_FLAG TRUE) #find_package(Threads REQUIRED) message(STATUS "Using Pthread Library: ${CMAKE_THREAD_LIBS_INIT}: ${CMAKE_USE_PTHREADS_INIT}") -set(RADIO_TYPE SOAPY_IRIS CACHE STRING "RADIO_TYPE defaulting to 'SOAPY_IRIS', valid types are SOAPY_IRIS / SOAPY_UHD / PURE_UHD") -message(STATUS "RADIO_TYPE: ${RADIO_TYPE}") if(RADIO_TYPE STREQUAL PURE_UHD) message(STATUS "Enabled PURE_UHD radio") add_definitions(-DUSE_UHD) @@ -148,7 +155,6 @@ if (NOT HDF5_FOUND) endif() message(VERBOSE " HDF5 Includes: ${HDF5_INCLUDE_DIRS} Libraries: ${HDF5_LIBRARIES}") - set(directory "logs") file(MAKE_DIRECTORY ${directory}) @@ -208,3 +214,4 @@ target_link_libraries(sounder_module -lpthread --enable-threadsafe ${GFLAGS_LIBR -Wl,--no-whole-archive ${HDF5_LIBRARIES} ${SoapySDR_LIBRARIES}) + diff --git a/CC/Sounder/ClientRadioSetUHD.cc b/CC/Sounder/ClientRadioSetUHD.cc index f6c72d0e..f365f2e1 100644 --- a/CC/Sounder/ClientRadioSetUHD.cc +++ b/CC/Sounder/ClientRadioSetUHD.cc @@ -20,7 +20,6 @@ ClientRadioSetUHD::ClientRadioSetUHD(Config* cfg) : _cfg(cfg) { size_t num_radios = _cfg->num_cl_sdrs(); //load channels - std::cout << "channel is: " << _cfg->cl_channel() << std::endl; auto channels = Utils::strToChannels(_cfg->cl_channel()); // Update for UHD multi USRP radioNotFound = false; @@ -30,7 +29,7 @@ ClientRadioSetUHD::ClientRadioSetUHD(Config* cfg) : _cfg(cfg) { context->crs = this; context->thread_count = &thread_count; context->tid = i; -#ifdef THREADED_INIT +#if defined(THREADED_INIT) pthread_t init_thread_; if (pthread_create(&init_thread_, NULL, ClientRadioSetUHD::init_launch, @@ -87,8 +86,6 @@ ClientRadioSetUHD::ClientRadioSetUHD(Config* cfg) : _cfg(cfg) { (radio_->RawDev()->get_tx_antenna(ch).c_str())); } } - std::cout << "ClientRadioSetUHD Init Check" << std::endl; - std::cout << std::endl; // Update for UHD multi USRP if (radioNotFound == true) { @@ -96,15 +93,23 @@ ClientRadioSetUHD::ClientRadioSetUHD(Config* cfg) : _cfg(cfg) { "discovered in the network!" << std::endl; } else { - std::cout << "checking tx advance " << _cfg->tx_advance(0) << std::endl; - radio_->RawDev()->set_time_source("internal"); - radio_->RawDev()->set_clock_source("internal"); + const auto cl_clock_source = _cfg->getClClockType(0); + radio_->RawDev()->set_time_source(cl_clock_source); + radio_->RawDev()->set_clock_source(cl_clock_source); radio_->RawDev()->set_time_unknown_pps(uhd::time_spec_t(0.0)); + MLPD_INFO( + "USRP UE Clock source requested %s, actual %s, Time Source requested " + "%s, actual %s\n", + cl_clock_source.c_str(), + radio_->RawDev() + ->get_clock_source(uhd::usrp::multi_usrp::ALL_MBOARDS) + .c_str(), + cl_clock_source.c_str(), + radio_->RawDev() + ->get_time_source(uhd::usrp::multi_usrp::ALL_MBOARDS) + .c_str()); radio_->activateRecv(); radio_->activateXmit(); - - std::cout << "sync check" << std::endl; - std::cout << std::endl; MLPD_INFO("%s done!\n", __func__); } } @@ -133,7 +138,6 @@ void ClientRadioSetUHD::init(ClientRadioContext* context) { args["timeout"] = "1000000"; args["driver"] = "uhd"; args["addr"] = _cfg->cl_sdr_ids().at(i); - std::cout << "address i is " << i << std::endl; try { radio_ = nullptr; @@ -155,12 +159,14 @@ void ClientRadioSetUHD::init(ClientRadioContext* context) { } if (has_runtime_error == false) { for (auto ch : channels) { - std::cout << "check ch: " << ch << std::endl; auto new_ch = _cfg->cl_channel(); double rxgain = _cfg->cl_rxgain_vec().at(ch).at( i); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:108] double txgain = _cfg->cl_txgain_vec().at(ch).at( i); // w/CBRS 3.6GHz [0:105], 2.5GHZ [0:105] + + auto total_rx_channel = 2; + radio_->dev_init_set_freq(_cfg, total_rx_channel); radio_->dev_init(_cfg, ch, rxgain, txgain); } } diff --git a/CC/Sounder/RadioUHD.cc b/CC/Sounder/RadioUHD.cc index 07575260..f882428f 100644 --- a/CC/Sounder/RadioUHD.cc +++ b/CC/Sounder/RadioUHD.cc @@ -21,21 +21,30 @@ #include "uhd/utils/log_add.hpp" #endif -void RadioUHD::dev_init(Config* _cfg, int ch, double rxgain, double txgain) { +void RadioUHD::dev_init_set_freq(Config* _cfg, unsigned int total_channels) { + MLPD_INFO("setting frequency \n"); + dev_->clear_command_time(); + dev_->set_command_time(dev_->get_time_now() + uhd::time_spec_t(0.1)); + uhd::tune_request_t tune_request(_cfg->radio_rf_freq()); + // update for UHD multi USRP + for (unsigned int ch = 0; ch < total_channels; ch++) { + dev_->set_rx_freq(tune_request, ch); + dev_->set_tx_freq(tune_request, ch); + } + + std::this_thread::sleep_for(std::chrono::milliseconds( + 550)); //sleep 110ms (~10ms after retune occurs) to allow LO to lock + + dev_->clear_command_time(); +} + +void RadioUHD::dev_init([[maybe_unused]] Config* _cfg, int ch, double rxgain, + double txgain) { // these params are sufficient to set before DC offset and IQ imbalance calibration - std::cout << "radioUHD.cc being called" << std::endl; MLPD_INFO("Init USRP channel: %d\n", ch); // update for UHD multi USRP dev_->set_tx_antenna("TX/RX", ch); dev_->set_rx_antenna("TX/RX", ch); - uhd::tune_request_t tune_request(0); - dev_->set_rx_freq(tune_request, ch); - dev_->set_tx_freq(tune_request, ch); - - // update for UHD multi USRP - tune_request = _cfg->radio_rf_freq(); - dev_->set_rx_freq(tune_request, ch); - dev_->set_tx_freq(tune_request, ch); // update for UHD multi USRP dev_->set_rx_gain(std::min(31.5, rxgain), "PGA0", ch); @@ -77,10 +86,10 @@ RadioUHD::RadioUHD(const std::map& args, Config* _cfg) { dev_ = uhd::usrp::multi_usrp::make(args); if (dev_ == NULL) throw std::invalid_argument("error making UHD:Device\n"); - for (auto ch : channels) { - dev_->set_rx_rate(_cfg->rate(), ch); - dev_->set_tx_rate(_cfg->rate(), ch); - } + + dev_->set_rx_rate(_cfg->rate()); + dev_->set_tx_rate(_cfg->rate()); + const std::string& format = uhdFmt; std::string hostFormat; for (const char ch : format) { @@ -97,6 +106,7 @@ RadioUHD::RadioUHD(const std::map& args, } uhd::stream_args_t stream_args(hostFormat); + MLPD_TRACE("channel size is: %zu\n", channels.size()); stream_args.channels = channels; stream_args.args = args; if (args.count("WIRE") != 0) stream_args.otw_format = args.at("WIRE"); @@ -106,10 +116,8 @@ RadioUHD::RadioUHD(const std::map& args, stream_args1.args = args; if (args.count("WIRE") != 0) stream_args1.otw_format = args.at("WIRE"); - std::cout << "format is " << hostFormat << std::endl; - - rxs_ = dev_->get_rx_stream(stream_args); txs_ = dev_->get_tx_stream(stream_args1); + rxs_ = dev_->get_rx_stream(stream_args); } int RadioUHD::activateRecv(const long long rxTime, const size_t numSamps, @@ -141,8 +149,6 @@ int RadioUHD::activateRecv(const long long rxTime, const size_t numSamps, void RadioUHD::activateXmit(void) { std::cout << "activate xmit" << std::endl; // for USRP device start tx stream UHD_INIT_TIME_SEC sec in the future - std::cout << "no input yet, from example, seems no issue command is needed" - << std::endl; } void RadioUHD::deactivateRecv(void) { @@ -155,10 +161,7 @@ void RadioUHD::deactivateRecv(void) { rxs_->issue_stream_cmd(stream_cmd_1); } -void RadioUHD::deactivateXmit(void) { - std::cout << "no input yet, from example, seems no issue command is needed" - << std::endl; -} +void RadioUHD::deactivateXmit(void) {} RadioUHD::~RadioUHD(void) { deactivateRecv(); diff --git a/CC/Sounder/config.cc b/CC/Sounder/config.cc index 850c061b..5d04798b 100644 --- a/CC/Sounder/config.cc +++ b/CC/Sounder/config.cc @@ -17,10 +17,13 @@ #include "nlohmann/json.hpp" using json = nlohmann::json; -static size_t kFpgaTxRamSize = 4096; -static size_t kMaxSupportedFFTSize = 2048; -static size_t kMinSupportedFFTSize = 64; -static size_t kMaxSupportedCPSize = 128; +static constexpr size_t kFpgaTxRamSize = 4096; +static constexpr size_t kMaxSupportedFFTSize = 2048; +static constexpr size_t kMinSupportedFFTSize = 64; +static constexpr size_t kMaxSupportedCPSize = 128; + +static const std::string kDefaultBsClockType = "external"; +static const std::string kDefaultUeClockType = "internal"; Config::Config(const std::string& jsonfile, const std::string& directory, const bool bs_only, const bool client_only, const bool calibrate) @@ -124,6 +127,7 @@ Config::Config(const std::string& jsonfile, const std::string& directory, beacon_ch_ = beacon_ant_ % bs_sdr_ch_; max_frame_ = tddConf.value("max_frame", 0); bs_hw_framer_ = tddConf.value("bs_hw_framer", true); + bs_clock_type_ = tddConf.value("bs_clock_type", kDefaultBsClockType); // Load/Build BS and Client SDRs' Schedules bs_array_frames_.resize(num_cells_); @@ -191,20 +195,33 @@ Config::Config(const std::string& jsonfile, const std::string& directory, } else { if (client_present_ && tx_advance.size() != num_cl_sdrs_) { MLPD_ERROR("tx_advance size must be same as the number of clients!\n"); - exit(1); + std::exit(1); } tx_advance_.assign(tx_advance.begin(), tx_advance.end()); } + auto corr_scale = tddConf.value("corr_scale", json::array()); if (corr_scale.empty() == true) { corr_scale_.resize(num_cl_sdrs_, 1); } else { if (client_present_ && corr_scale.size() != num_cl_sdrs_) { - MLPD_ERROR("tx_advance size must be same as the number of clients!\n"); - exit(1); + MLPD_ERROR("corr_scale size must be same as the number of clients!\n"); + std::exit(1); } corr_scale_.assign(corr_scale.begin(), corr_scale.end()); } + + auto cl_clock_type = tddConf.value("cl_clock_type", json::array()); + if (tx_advance.empty() == true) { + cl_clock_type_.resize(num_cl_sdrs_, kDefaultUeClockType); + } else { + if (client_present_ && tx_advance.size() != num_cl_sdrs_) { + MLPD_ERROR("cl_clock_type size must be same as the number of clients!\n"); + std::exit(1); + } + cl_clock_type_.assign(cl_clock_type.begin(), cl_clock_type.end()); + } + ul_data_frame_num_ = tddConf.value("ul_data_frame_num", 1); dl_data_frame_num_ = tddConf.value("dl_data_frame_num", 1); @@ -322,10 +339,15 @@ Config::Config(const std::string& jsonfile, const std::string& directory, MLPD_INFO("Cores found %u ... \n", num_cores); if (bs_present_ == true && pilot_slot_per_frame_ + ul_slot_per_frame_ + dl_slot_per_frame_ > 0) { +#if defined(USE_UHD) + bs_rx_thread_num_ = 1; +#else bs_rx_thread_num_ = (num_cores >= (2 * RX_THREAD_NUM)) ? std::min(RX_THREAD_NUM, static_cast(num_bs_sdrs_all_)) : 1; +#endif + if (internal_measurement_ == true && ref_node_enable_ == true) { bs_rx_thread_num_ = 2; } diff --git a/CC/Sounder/files/special_conf/usrp-16QAM.json b/CC/Sounder/files/special_conf/usrp-16QAM.json index d69e7ed6..bab41cf2 100644 --- a/CC/Sounder/files/special_conf/usrp-16QAM.json +++ b/CC/Sounder/files/special_conf/usrp-16QAM.json @@ -1,33 +1,33 @@ { "serial_file" : "files/special_conf/usrp_16qam.json", - "frequency" : 2.5e9, - "channel" : "AB", - "rx_gain_a" : 15, - "tx_gain_a" : 15, - "rx_gain_b" : 15, - "tx_gain_b" : 15, + "frequency" : 1e9, + "channel" : "A", + "rx_gain_a" : 25, + "tx_gain_a" : 25, + "rx_gain_b" : 25, + "tx_gain_b" : 25, "sample_rate" : 5e6, - "modulation" : "64QAM", + "modulation" : "16QAM", "frame_schedule" : [ - "BGGPPGGGGUGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG" + "BGGGGGPGGGGUGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG" ], "max_frame" : 4000, "ofdm_symbol_per_slot" : 10, "fft_size" : 64, "cp_size" : 16, - "ofdm_tx_zero_prefix" : 160, - "ofdm_tx_zero_postfix" : 160, + "ofdm_tx_zero_prefix" : 1840, + "ofdm_tx_zero_postfix" : 120, "beamsweep" : true, - "ue_channel" : "AB", - "ue_rx_gain_a" : [15], - "ue_tx_gain_a" : [15], - "ue_rx_gain_b" : [15], - "ue_tx_gain_b" : [15], + "ue_channel" : "A", + "ue_rx_gain_a" : [75], + "ue_tx_gain_a" : [75], + "ue_rx_gain_b" : [75], + "ue_tx_gain_b" : [75], "ue_frame_schedule" : [ - "BGGPPGGGGUGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG" + "BGGGGGPGGGGUGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG" ], - "tx_advance" : [100], + "tx_advance" : [300], "hw_framer" : false, - "ue_modulation" : "64QAM", + "ue_modulation" : "16QAM", "frame_mode" : "free_running" } diff --git a/CC/Sounder/files/special_conf/usrp_16qam.json b/CC/Sounder/files/special_conf/usrp_16qam.json index 0389855d..caa0cf22 100644 --- a/CC/Sounder/files/special_conf/usrp_16qam.json +++ b/CC/Sounder/files/special_conf/usrp_16qam.json @@ -2,14 +2,20 @@ "BaseStations": { "BS0": { "sdr": [ - "192.168.30.2" - ] + "10.10.23.1", + "10.10.23.2", + "10.10.23.3", + "10.10.23.4", + "10.10.23.5", + "10.10.23.6", + "10.10.23.7", + "10.10.23.8" + ] } }, "Clients": { "sdr": [ - "192.168.70.2" + "10.10.23.5" ] } } - diff --git a/CC/Sounder/include/RadioUHD.h b/CC/Sounder/include/RadioUHD.h index e2f74c66..b7d7aa5c 100644 --- a/CC/Sounder/include/RadioUHD.h +++ b/CC/Sounder/include/RadioUHD.h @@ -38,8 +38,10 @@ class RadioUHD { void deactivateXmit(void); int getTriggers(void) const; - void dev_init(Config* _cfg, int ch, double rxgain, double txgain); + void dev_init([[maybe_unused]] Config* _cfg, int ch, double rxgain, + double txgain); void reset_DATA_clk_domain(void); + void dev_init_set_freq(Config* _cfg, unsigned int total_channels); }; #endif /* RADIOUHD_H_ */ diff --git a/CC/Sounder/include/config.h b/CC/Sounder/include/config.h index 5e42b037..d2619b0b 100644 --- a/CC/Sounder/include/config.h +++ b/CC/Sounder/include/config.h @@ -263,6 +263,11 @@ class Config { } inline size_t getTxFrameDelta() const { return tx_frame_delta_; } + inline const std::string getBsClockType() const { return bs_clock_type_; } + inline const std::string getClClockType(size_t ue_idx) const { + return cl_clock_type_.at(ue_idx); + } + size_t getNumAntennas(); size_t getMaxNumAntennas(); size_t getNumBsSdrs(); @@ -300,10 +305,11 @@ class Config { // common features double freq_; - double nco_; // baseband frequency controlled by NCO + // baseband frequency controlled by NCO + double nco_; double rate_; - double - radio_rf_freq_; // RF frequency set frame_modeon the radio after NCO adjustments + // RF frequency set frame_modeon the radio after NCO adjustments + double radio_rf_freq_; double bw_filter_; size_t fft_size_; size_t cp_size_; @@ -378,6 +384,7 @@ class Config { bool ref_node_enable_; size_t cal_ref_sdr_id_; size_t tx_frame_delta_; + std::string bs_clock_type_; // Clients features std::vector cl_sdr_ids_; @@ -391,6 +398,8 @@ class Config { bool cl_power_ramp_; int cl_power_ramp_lo_; int cl_power_ramp_hi_; + std::vector cl_clock_type_; + std::vector tx_advance_; std::vector corr_scale_; std::vector data_ind_; diff --git a/CC/Sounder/include/receiver.h b/CC/Sounder/include/receiver.h index 45d5456c..54747766 100644 --- a/CC/Sounder/include/receiver.h +++ b/CC/Sounder/include/receiver.h @@ -84,6 +84,10 @@ class Receiver { private: Config* config_; + size_t num_channels_buff_; + size_t num_channels_; + size_t num_radios_; + size_t radio_id_; #if defined(USE_UHD) ClientRadioSetUHD* client_radio_set_; diff --git a/CC/Sounder/main.cc b/CC/Sounder/main.cc index a1ebe288..fcc1fabe 100644 --- a/CC/Sounder/main.cc +++ b/CC/Sounder/main.cc @@ -42,7 +42,13 @@ int main(int argc, char* argv[]) { auto dg = std::make_unique(config.get()); dg->GenerateData(FLAGS_storepath); } else if (FLAGS_calibrate) { +#if defined(USE_UHD) + std::cout << "Radio calibrate function is not compatible with the radio " + "calibratate flag!" + << std::endl; +#else auto base_radio_set_ = std::make_unique(config.get(), true); +#endif } else { int cnt = 0; int maxTry = 2; diff --git a/CC/Sounder/receiver.cc b/CC/Sounder/receiver.cc index 7dffdf8f..fc00664e 100644 --- a/CC/Sounder/receiver.cc +++ b/CC/Sounder/receiver.cc @@ -58,11 +58,18 @@ Receiver::Receiver( config_->client_present() ? new ClientRadioSetUHD(config_) : nullptr; this->base_radio_set_ = config_->bs_present() ? new BaseRadioSetUHD(config_) : nullptr; + int cha = config_->bs_channel() == "AB" ? 2 : 1; + num_channels_buff_ = config_->num_bs_sdrs_all() * cha; + num_channels_ = config_->num_bs_sdrs_all() * cha; + num_radios_ = 1; #else this->client_radio_set_ = config_->client_present() ? new ClientRadioSet(config_) : nullptr; this->base_radio_set_ = config_->bs_present() ? new BaseRadioSet(config_, false) : nullptr; + num_channels_buff_ = 2; + num_channels_ = config_->bs_channel().length(); + num_radios_ = config_->num_bs_sdrs_all(); //config_->n_bs_sdrs()[0] #endif } catch (std::exception& e) { throw ReceiverException(e.what()); @@ -92,6 +99,7 @@ Receiver::Receiver( this->initBuffers(); MLPD_TRACE("Construction complete\n"); + std::cout << "receiver done\n"; } Receiver::~Receiver() { @@ -163,6 +171,7 @@ std::vector Receiver::startClientThreads(SampleBuffer* rx_buffer, client_threads[i] = cl_thread_; } } + std::cout << "finish start client threads" << std::endl; return client_threads; } @@ -211,10 +220,12 @@ void Receiver::go() { void Receiver::baseTxBeacon(int radio_id, int cell, int frame_id, long long base_time) { // prepare BS beacon in host buffer - std::vector beaconbuff(2); + std::vector beaconbuff(num_channels_buff_); + size_t num_channels = num_channels_; + if (config_->beam_sweep() == true) { size_t beacon_frame_slot = frame_id % config_->num_bs_antennas_all(); - for (size_t ch = 0; ch < config_->bs_sdr_ch(); ++ch) { + for (size_t ch = 0; ch < num_channels; ++ch) { size_t cell_radio_id = radio_id + config_->n_bs_sdrs_agg().at(cell); size_t cell_ant_id = cell_radio_id * config_->bs_sdr_ch(); int hdmd = CommsLib::hadamard2(beacon_frame_slot, cell_ant_id); @@ -227,7 +238,7 @@ void Receiver::baseTxBeacon(int radio_id, int cell, int frame_id, beaconbuff.at(bcn_ch) = config_->beacon_ci16().data(); if (config_->bs_sdr_ch() > 1) beaconbuff.at(1 - bcn_ch) = zeros_.at(0); } else { // set both channels to zeros - for (size_t ch = 0; ch < config_->bs_sdr_ch(); ++ch) + for (size_t ch = 0; ch < num_channels; ++ch) beaconbuff.at(ch) = zeros_.at(ch); } } @@ -248,7 +259,9 @@ int Receiver::baseTxData(int radio_id, int cell, int frame_id, size_t packetLength = sizeof(Packet) + config_->getPacketDataLength(); size_t tx_buffer_size = bs_tx_buffer_[radio_id].buffer.size() / packetLength; int flagsTxData; - std::vector dl_txbuff(2); + size_t num_channels = num_channels_; + std::vector dl_txbuff(num_channels_buff_); + Event_data event; if (tx_queue_.at(radio_id)->try_dequeue_from_producer(*tx_ptoks_.at(radio_id), event) == true) { @@ -260,7 +273,7 @@ int Receiver::baseTxData(int radio_id, int cell, int frame_id, if (config_->bs_hw_framer() == false) this->baseTxBeacon(radio_id, cell, event.frame_id, txFrameTime); for (size_t s = 0; s < config_->dl_slot_per_frame(); s++) { - for (size_t ch = 0; ch < config_->bs_sdr_ch(); ++ch) { + for (size_t ch = 0; ch < num_channels; ++ch) { char* cur_ptr_buffer = bs_tx_buffer_[radio_id].buffer.data() + (cur_offset * packetLength); Packet* pkt = reinterpret_cast(cur_ptr_buffer); @@ -346,8 +359,8 @@ void Receiver::loopRecv(int tid, int core_id, SampleBuffer* rx_buffer) { // use token to speed up moodycamel::ProducerToken local_ptok(*message_queue_); - - const size_t num_channels = config_->bs_channel().length(); + size_t num_channels = num_channels_; + std::cout << "num channels are: " << num_channels << std::endl; size_t packetLength = sizeof(Packet) + config_->getPacketDataLength(); int buffer_chunk_size = rx_buffer[0].buffer.size() / packetLength; int bs_tx_buff_size = kSampleBufferFrameNum * config_->slot_per_frame(); @@ -357,7 +370,8 @@ void Receiver::loopRecv(int tid, int core_id, SampleBuffer* rx_buffer) { std::atomic_int* pkt_buf_inuse = rx_buffer[tid].pkt_buf_inuse; char* buffer = rx_buffer[tid].buffer.data(); - size_t num_radios = config_->num_bs_sdrs_all(); //config_->n_bs_sdrs()[0] + size_t num_radios = num_radios_; + std::vector radio_ids_in_thread; if (config_->internal_measurement() && config_->ref_node_enable()) { if (tid == 0) @@ -397,13 +411,15 @@ void Receiver::loopRecv(int tid, int core_id, SampleBuffer* rx_buffer) { // read rx_offset to align the FPGA time of the BS // by performing dummy readStream() + std::vector samp_buffer(num_channels_buff_); std::vector> samp_buffer0(config_->samps_per_frame(), 0); - std::vector> samp_buffer1(config_->samps_per_frame(), - 0); - std::vector samp_buffer(2); samp_buffer[0] = samp_buffer0.data(); - if (num_channels == 2) samp_buffer[1] = samp_buffer1.data(); + if (num_channels > 1) { + for (size_t i = 1; i < num_channels; i++) { + samp_buffer[i] = samp_buffer0.data(); + } + } int cell = 0; // for UHD device, the first pilot should not have an END_BURST flag @@ -420,7 +436,11 @@ void Receiver::loopRecv(int tid, int core_id, SampleBuffer* rx_buffer) { break; } } +#if defined(USE_UHD) + size_t radio_id = 0; +#else size_t radio_id = it - config_->n_bs_sdrs_agg().at(cell); +#endif bs_sync_ret = -1; while (bs_sync_ret < 0) { bs_sync_ret = @@ -459,7 +479,11 @@ void Receiver::loopRecv(int tid, int core_id, SampleBuffer* rx_buffer) { } } +#if defined(USE_UHD) + size_t radio_id = 0; +#else size_t radio_id = it - config_->n_bs_sdrs_agg().at(cell); +#endif size_t num_packets = config_->internal_measurement() && @@ -925,11 +949,12 @@ void Receiver::clientSyncTxRx(int tid, int core_id, SampleBuffer* rx_buffer) { } //-------------------- New sync - const size_t beacon_detect_window = - static_cast(static_cast(config_->samps_per_slot()) * - kBeaconDetectWindowScaler); + // const size_t beacon_detect_window = + // static_cast(static_cast(config_->samps_per_slot()) * + // kBeaconDetectWindowScaler); + const size_t beacon_detect_window = config_->samps_per_frame() / 100; size_t sync_count = 0; - constexpr size_t kTargetSyncCount = 2; + constexpr size_t kTargetSyncCount = 1; assert(config_->samps_per_frame() >= beacon_detect_window); while ((sync_count < kTargetSyncCount) && config_->running()) { const ssize_t sync_index = clientSyncBeacon(tid, beacon_detect_window); @@ -1144,9 +1169,14 @@ ssize_t Receiver::clientSyncBeacon(size_t radio_id, size_t sample_window) { syncrxbuffs.push_back(syncbuffmem.at(ch).data()); } + int Beacon_interval = 20; while (config_->running() && (sync_index < 0)) { - const int rx_status = client_radio_set_->radioRx( - radio_id, syncrxbuffs.data(), sample_window, rx_time); + int rx_status = -1; + for (int find_beacon_retry = 0; find_beacon_retry < Beacon_interval; + find_beacon_retry++) { + rx_status = client_radio_set_->radioRx(radio_id, syncrxbuffs.data(), + sample_window, rx_time); + } if (rx_status < 0) { MLPD_ERROR("clientSyncBeacon [%zu]: BAD SYNC Received (%d/%zu) %lld\n", diff --git a/README.md b/README.md index 68cfe054..cd840e57 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ $ cd build $ cmake .. -DCMAKE_BUILD_TYPE=Release -DLOG_LEVEL=info && make -j $ cd ../ ``` -If you wish to switch to use the UHD impelentation (install necessary UHD packages [here](https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux)): +If you wish to switch to use the UHD impelentation (install necessary UHD packages [here](https://kb.ettus.com/Building_and_Installing_the_USRP_Open-Source_Toolchain_(UHD_and_GNU_Radio)_on_Linux), recommended setting is to use Ubuntu 20.4, Boost version 1.71 and UHD version of 4.1.0.4): ```sh $ cd build $ cmake .. -DRADIO_TYPE=PURE_UHD