From 4b00bc4d698910eb0643a4533a27f715cfb5b434 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Tue, 23 May 2017 13:53:45 -0700 Subject: eiscat: Numerous modification for testing beamforming --- .../usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp | 136 +++++++++++++++++++-- .../usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp | 38 +++++- 2 files changed, 158 insertions(+), 16 deletions(-) (limited to 'host/lib/usrp/dboard') diff --git a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp index dfee25acd..df7fdba8e 100644 --- a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp +++ b/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp @@ -33,6 +33,8 @@ using namespace uhd::rfnoc; namespace { const size_t SR_ANTENNA_GAIN_BASE = 204; const size_t SR_ANTENNA_SELECT_BASE = 192; // Note: On other dboards, 192 is DB_GPIO address space + const size_t RB_CHOOSE_BEAMS = 10; + const double EISCAT_TICK_RATE = 208e6; // Hz const double EISCAT_RADIO_RATE = 104e6; // Hz @@ -53,7 +55,13 @@ namespace { const size_t EISCAT_NUM_FIR_TAPS = 10; const size_t EISCAT_NUM_FIR_SETS = 1024; // BRAM must be at least EISCAT_NUM_FIR_TAPS * EISCAT_NUM_FIR_SETS const size_t EISCAT_FIR_INDEX_IMPULSE = 1002; - const size_t EISCAT_FIR_INDEX_ZEROS = 1003; // FIXME + const size_t EISCAT_FIR_INDEX_ZEROS = 1003; + + const uint32_t EISCAT_CONTRIB_LOWER = 0<<0; + const uint32_t EISCAT_CONTRIB_UPPER = 1<<0; + const uint32_t EISCAT_SKIP_NEIGHBOURS = 1<<1; + const uint32_t EISCAT_BYPASS_MATRIX = 1<<2; + const uint32_t EISCAT_OUTPUT_COUNTER = 1<<3; }; @@ -77,11 +85,38 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(eiscat_radio_ctrl) for (size_t i = 0; i < EISCAT_NUM_ANTENNAS; i++) { _tree->access(get_arg_path("gain", i) / "value") .set_coercer([](double gain){ return std::max(-1.0, std::min(1.0, gain)); }) - .add_coerced_subscriber([this, i](double gain){ this->set_antenna_gain(i, gain); }) + .add_coerced_subscriber([this, i](double gain){ + this->set_antenna_gain(i, gain); + }) .set(EISCAT_DEFAULT_NORM_GAIN) ; } + /**** Add subscribers for our special properties ************************/ + _tree->access(get_arg_path("choose_beams", 0) / "value") + .add_coerced_subscriber([this](int choose_beams){ + this->set_beam_selection(choose_beams); + }) + .update() + ; + _tree->access(get_arg_path("enable_firs", 0) / "value") + .add_coerced_subscriber([this](int enable){ + this->enable_firs(bool(enable)); + }) + .update() + ; + _tree->access(get_arg_path("enable_counter", 0) / "value") + .add_coerced_subscriber([this](int enable){ + this->enable_counter(bool(enable)); + }) + .update() + ; + _tree->access(get_arg_path("configure_beams", 0) / "value") + .add_coerced_subscriber([this](int reg_value){ + this->configure_beams(uint32_t(reg_value)); + }) // No update! + ; + /**** Set up legacy compatible properties ******************************/ // For use with multi_usrp APIs etc. // For legacy prop tree init: @@ -185,18 +220,14 @@ void eiscat_radio_ctrl_impl::set_rx_antenna(const std::string &ant, const size_t UHD_LOG_TRACE("EISCAT", "Setting antenna to 'BF' (which is a no-op)"); return; } - if (ant.size() < 3 or ant.size() > 4 - or (ant.substr(0, 2) != "Rx" - and ant.substr(0, 2) != "RX" - and ant.substr(0, 2) != "BF")) { + if (ant.size() < 3) { throw uhd::value_error(str( boost::format("EISCAT: Invalid antenna selection: %s") % ant )); } - bool use_fir_matrix = (ant.substr(0, 2) == "BF"); - + const std::string ant_mode = ant.substr(0, 2); const size_t antenna_idx = [&ant](){ try { return boost::lexical_cast(ant.substr(2)); @@ -208,7 +239,7 @@ void eiscat_radio_ctrl_impl::set_rx_antenna(const std::string &ant, const size_t } }(); - if (use_fir_matrix) { + if (ant_mode == "BF") { UHD_LOG_TRACE("EISCAT", str( boost::format("Setting port %d to only receive on antenna %d via FIR matrix") % port % antenna_idx @@ -236,13 +267,39 @@ void eiscat_radio_ctrl_impl::set_rx_antenna(const std::string &ant, const size_t ); } } - } else { + enable_firs(true); + } else if (ant_mode == "RX" or ant_mode == "Rx") { set_arg("choose_beams", 6); UHD_LOG_TRACE("EISCAT", str( boost::format("Setting port %d to only receive on antenna %d directly") % port % antenna_idx )); - sr_write(SR_ANTENNA_SELECT_BASE + port, antenna_idx); + enable_firs(false); + } else if (ant_mode == "FI") { + UHD_LOG_TRACE("EISCAT", str( + boost::format("Setting port %d to filter index %d on all antennas.") + % port % antenna_idx + )); + // Note: antenna_idx is not indexing a physical antenna in this scenario. + // TODO: When we have a way to select neighbour contributions, we will + // need to calculate the beam_index as a function of the port *and* if + // we're the left or right USRP + const size_t beam_index = port; + uhd::time_spec_t send_now(0.0); + for (size_t i = 0; i < EISCAT_NUM_ANTENNAS; i++) { + select_filter( + beam_index, + i, + antenna_idx, + send_now + ); + } + enable_firs(true); + } else { + throw uhd::value_error(str( + boost::format("EISCAT: Invalid antenna selection: %s") + % ant + )); } } @@ -325,7 +382,10 @@ bool eiscat_radio_ctrl_impl::check_radio_config() chan_enables |= (1<