diff options
author | Martin Braun <martin.braun@ettus.com> | 2017-05-23 13:53:45 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-12-22 15:03:58 -0800 |
commit | 4b00bc4d698910eb0643a4533a27f715cfb5b434 (patch) | |
tree | b54ac1aa3c6699bf4330cd897c2934e9f63f6d25 /host/lib/usrp/dboard/eiscat | |
parent | 65713fa6f5dd534da1dcc34a7fb4baeeccc5d4c8 (diff) | |
download | uhd-4b00bc4d698910eb0643a4533a27f715cfb5b434.tar.gz uhd-4b00bc4d698910eb0643a4533a27f715cfb5b434.tar.bz2 uhd-4b00bc4d698910eb0643a4533a27f715cfb5b434.zip |
eiscat: Numerous modification for testing beamforming
Diffstat (limited to 'host/lib/usrp/dboard/eiscat')
-rw-r--r-- | host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.cpp | 136 | ||||
-rw-r--r-- | host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp | 38 |
2 files changed, 158 insertions, 16 deletions
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<double>(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<int>(get_arg_path("choose_beams", 0) / "value") + .add_coerced_subscriber([this](int choose_beams){ + this->set_beam_selection(choose_beams); + }) + .update() + ; + _tree->access<bool>(get_arg_path("enable_firs", 0) / "value") + .add_coerced_subscriber([this](int enable){ + this->enable_firs(bool(enable)); + }) + .update() + ; + _tree->access<bool>(get_arg_path("enable_counter", 0) / "value") + .add_coerced_subscriber([this](int enable){ + this->enable_counter(bool(enable)); + }) + .update() + ; + _tree->access<int>(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<size_t>(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<int>("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<<enb.first); } } - UHD_LOG_TRACE("EISCAT", str(boost::format("check_radio_config(): Setting channel enables to 0x%02X") % chan_enables)); + UHD_LOG_TRACE("EISCAT", str( + boost::format("check_radio_config(): Setting channel enables to 0x%02X") + % chan_enables + )); sr_write("SR_RX_STREAM_ENABLE", chan_enables); return true; @@ -440,6 +500,58 @@ void eiscat_radio_ctrl_impl::set_antenna_gain( sr_write(SR_ANTENNA_GAIN_BASE + antenna_idx, fixpoint_gain); } +void eiscat_radio_ctrl_impl::configure_beams(uint32_t reg_value) +{ + UHD_LOGGER_TRACE("EISCAT") + << "Selecting " << + ((reg_value & EISCAT_CONTRIB_UPPER) ? "upper" : "lower") << " beams."; + UHD_LOGGER_TRACE("EISCAT") + << ((reg_value & EISCAT_SKIP_NEIGHBOURS) ? "Disabling" : "Enabling") + << " neighbour contributions."; + UHD_LOGGER_TRACE("EISCAT") + << ((reg_value & EISCAT_BYPASS_MATRIX) ? "Disabling" : "Enabling") + << " FIR matrix."; + UHD_LOGGER_TRACE("EISCAT") + << ((reg_value & EISCAT_OUTPUT_COUNTER) ? "Enabling" : "Disabling") + << " counter."; + UHD_LOG_TRACE("EISCAT", str( + boost::format("Setting SR_BEAMS_TO_NEIGHBOR to 0x%08X.") + % reg_value + )); + sr_write("SR_BEAMS_TO_NEIGHBOR", reg_value); +} + +void eiscat_radio_ctrl_impl::set_beam_selection(int beam_selection) +{ + const uint32_t old_value = user_reg_read32(RB_CHOOSE_BEAMS); + const uint32_t new_value = + (old_value & (~uint32_t(EISCAT_CONTRIB_UPPER|EISCAT_SKIP_NEIGHBOURS))) + | (uint32_t(beam_selection) + & uint32_t(EISCAT_CONTRIB_UPPER|EISCAT_SKIP_NEIGHBOURS)) + ; + configure_beams(new_value); +} + +void eiscat_radio_ctrl_impl::enable_firs(bool enable) +{ + const uint32_t old_value = user_reg_read32(RB_CHOOSE_BEAMS); + const uint32_t new_value = enable ? + (old_value & ~EISCAT_BYPASS_MATRIX) + : old_value | EISCAT_BYPASS_MATRIX + ; + configure_beams(new_value); +} + +void eiscat_radio_ctrl_impl::enable_counter(bool enable) +{ + const uint32_t old_value = user_reg_read32(RB_CHOOSE_BEAMS); + const uint32_t new_value = enable ? + old_value | EISCAT_OUTPUT_COUNTER + : (old_value & ~EISCAT_OUTPUT_COUNTER) + ; + configure_beams(new_value); +} + /**************************************************************************** * Registry ***************************************************************************/ diff --git a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp index cb45208ce..46b9410cd 100644 --- a/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp +++ b/host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp @@ -54,11 +54,17 @@ public: * Valid antenna values: * - BF: This is the default. Will apply the beamforming matrix in whatever * state it currently is. - * - Rx0...Rx15: Will mux the antenna signal 0...15 straight to this - * channel. Note that this will disable the FIR matrix entirely. + * - RX0...RX15: Will mux the antenna signal 0...15 straight to this + * channel. Note that this will disable the FIR matrix entirely, and will + * also disable contributions from other USRPs. * - BF0...BF15: Will configure the FIR filter matrix such that only the - * contributions from antenna 0...15 are passed to this channel. - * + * contributions from antenna 0...15 are passed to this channel. This + * should produce the same signal as RX0..RX15, reduced by 12 dB (because + * the FIR matri needs to account for bit growth from adding 16 channels) + * - FI$idx: Here, $idx is a number (the filter index, hence the name). + * This will apply filter index $idx to all input channels. Useful for + * testing actual beamforming applications, when the same signal is + * applied to all inputs. * * \throws uhd::value_error if the antenna value was not valid */ @@ -125,6 +131,30 @@ private: const double normalized_gain ); + /*! Directly writes a value to the beam configuration register. + */ + void configure_beams(uint32_t reg_value); + + /*! Controls selection of beams coming from the FIR matrix. + * + * The following values are allowed: + * - 0: We stream the lower 5 beams, plus the neighbours contribution + * - 1: We stream the upper 5 beams, plus the neighbours contribution + * - 2: We stream the lower 5 beams, without the neighbours contribution + * - 3: We stream the upper 5 beams, without the neighbours contribution + */ + void set_beam_selection(int beam_selection); + + /*! Controls if we're using the FIR matrix + * + * If this is false, the beam selection is irrelevant. + */ + void enable_firs(bool enable); + + /*! Enables counter instead of JESD core output + */ + void enable_counter(bool enable); + /*! The number of channels this block outputs * * This is *not* the number of antennas, but the number of streams a single |