aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/dboard/eiscat
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2017-05-23 13:53:45 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:03:58 -0800
commit4b00bc4d698910eb0643a4533a27f715cfb5b434 (patch)
treeb54ac1aa3c6699bf4330cd897c2934e9f63f6d25 /host/lib/usrp/dboard/eiscat
parent65713fa6f5dd534da1dcc34a7fb4baeeccc5d4c8 (diff)
downloaduhd-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.cpp136
-rw-r--r--host/lib/usrp/dboard/eiscat/eiscat_radio_ctrl_impl.hpp38
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