aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2017-05-09 10:30:31 -0700
committerMartin Braun <martin.braun@ettus.com>2017-05-24 10:41:23 -0700
commit91dff1fbdd5bf7c1afd83182ddce43ed2bec63da (patch)
treea8294daf38fc611312d3c3045f05853a5220a192
parent4fc9efd1f5f39caddfb40dd3daffcfb08854f9e0 (diff)
downloaduhd-91dff1fbdd5bf7c1afd83182ddce43ed2bec63da.tar.gz
uhd-91dff1fbdd5bf7c1afd83182ddce43ed2bec63da.tar.bz2
uhd-91dff1fbdd5bf7c1afd83182ddce43ed2bec63da.zip
rfnoc: Backported GPIO controls on radio blocks
-rw-r--r--host/include/uhd/rfnoc/radio_ctrl.hpp49
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.cpp63
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.hpp4
3 files changed, 115 insertions, 1 deletions
diff --git a/host/include/uhd/rfnoc/radio_ctrl.hpp b/host/include/uhd/rfnoc/radio_ctrl.hpp
index 984ddf864..be22c6e5e 100644
--- a/host/include/uhd/rfnoc/radio_ctrl.hpp
+++ b/host/include/uhd/rfnoc/radio_ctrl.hpp
@@ -120,11 +120,13 @@ public:
*/
virtual double get_rx_frequency(const size_t chan) /* const */ = 0;
- /*! Tune the RX LO for channel \p.
+ /*! Tune the RX LO for channel \p chan.
*
* This function will attempt to tune as close as possible, and return a
* coerced value of the actual tuning result.
*
+ * \param freq Requested LO frequency
+ * \param chan Channel number.
* \return The actual LO frequency.
*/
virtual double set_rx_frequency(const double freq, const size_t chan) = 0;
@@ -211,6 +213,51 @@ public:
*/
virtual time_spec_t get_time_last_pps() = 0;
+ /*! Returns the list of GPIO banks that are associated with this radio.
+ *
+ * \returns list of GPIO bank names
+ */
+ virtual std::vector<std::string> get_gpio_banks() const = 0;
+
+ /*!
+ * Set a GPIO attribute on a particular GPIO bank.
+ * Possible attribute names:
+ * - CTRL - 1 for ATR mode 0 for GPIO mode
+ * - DDR - 1 for output 0 for input
+ * - OUT - GPIO output level (not ATR mode)
+ * - ATR_0X - ATR idle state
+ * - ATR_RX - ATR receive only state
+ * - ATR_TX - ATR transmit only state
+ * - ATR_XX - ATR full duplex state
+ * \param bank the name of a GPIO bank (e.g., FP0)
+ * \param attr the name of a GPIO attribute (e.g., CTRL)
+ * \param value the new value for this GPIO bank
+ * \param mask the bit mask to effect which pins are changed
+ */
+ virtual void set_gpio_attr(
+ const std::string &bank,
+ const std::string &attr,
+ const uint32_t value,
+ const uint32_t mask
+ ) = 0;
+
+ /*!
+ * Get a GPIO attribute on a particular GPIO bank.
+ * Possible attribute names:
+ * - CTRL - 1 for ATR mode 0 for GPIO mode
+ * - DDR - 1 for output 0 for input
+ * - OUT - GPIO output level (not ATR mode)
+ * - ATR_0X - ATR idle state
+ * - ATR_RX - ATR receive only state
+ * - ATR_TX - ATR transmit only state
+ * - ATR_XX - ATR full duplex state
+ * - READBACK - readback input GPIOs
+ * \param bank the name of a GPIO bank
+ * \param attr the name of a GPIO attribute
+ * \return the value set for this attribute
+ */
+ virtual uint32_t get_gpio_attr(const std::string &bank, const std::string &attr) = 0;
+
/*!
* Get a list of possible LO stage names
* \param chan the channel index 0 to N-1
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
index e98980e5c..daae309c3 100644
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
+++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
@@ -30,6 +30,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/make_shared.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
+#include <boost/assign/list_of.hpp>
using namespace uhd;
using namespace uhd::usrp;
@@ -522,6 +523,68 @@ double x300_radio_ctrl_impl::get_output_samp_rate(size_t chan)
return _rx_fe_map.at(chan).core->get_output_rate();
}
+std::vector<std::string> x300_radio_ctrl_impl::get_gpio_banks() const
+{
+ std::vector<std::string> banks = boost::assign::list_of("RX")("TX");
+ // These pairs are the same, but RXA/TXA are from pre-rfnoc era and are kept for backward compat:
+ banks.push_back("RX"+_radio_slot);
+ banks.push_back("TX"+_radio_slot);
+ if (_fp_gpio) {
+ banks.push_back("FP0");
+ }
+ return banks;
+}
+
+void x300_radio_ctrl_impl::set_gpio_attr(
+ const std::string &bank,
+ const std::string &attr,
+ const uint32_t value,
+ const uint32_t mask
+) {
+ if (bank == "FP0" and _fp_gpio) {
+ const uint32_t current = _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get();
+ const uint32_t new_value = (current & ~mask) | (value & mask);
+ _tree->access<uint32_t>(fs_path("gpio") / bank / attr).set(new_value);
+ return;
+ }
+ if (bank.size() > 2 and bank[1] == 'X')
+ {
+ const std::string name = bank.substr(2);
+ const dboard_iface::unit_t unit = (bank[0] == 'R')? dboard_iface::UNIT_RX : dboard_iface::UNIT_TX;
+ dboard_iface::sptr iface = _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get();
+ if (attr == "CTRL") iface->set_pin_ctrl(unit, uint16_t(value), uint16_t(mask));
+ if (attr == "DDR") iface->set_gpio_ddr(unit, uint16_t(value), uint16_t(mask));
+ if (attr == "OUT") iface->set_gpio_out(unit, uint16_t(value), uint16_t(mask));
+ if (attr == "ATR_0X") iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask));
+ if (attr == "ATR_RX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask));
+ if (attr == "ATR_TX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask));
+ if (attr == "ATR_XX") iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask));
+ }
+}
+
+uint32_t x300_radio_ctrl_impl::get_gpio_attr(
+ const std::string &bank,
+ const std::string &attr
+) {
+ if (bank == "FP0" and _fp_gpio) {
+ return uint32_t(_tree->access<uint64_t>(fs_path("gpio") / bank / attr).get());
+ }
+ if (bank.size() > 2 and bank[1] == 'X') {
+ const std::string name = bank.substr(2);
+ const dboard_iface::unit_t unit = (bank[0] == 'R')? dboard_iface::UNIT_RX : dboard_iface::UNIT_TX;
+ dboard_iface::sptr iface = _tree->access<dboard_iface::sptr>(fs_path("dboards") / name / "iface").get();
+ if (attr == "CTRL") return iface->get_pin_ctrl(unit);
+ if (attr == "DDR") return iface->get_gpio_ddr(unit);
+ if (attr == "OUT") return iface->get_gpio_out(unit);
+ if (attr == "ATR_0X") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_IDLE);
+ if (attr == "ATR_RX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY);
+ if (attr == "ATR_TX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY);
+ if (attr == "ATR_XX") return iface->get_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX);
+ if (attr == "READBACK") return iface->read_gpio(unit);
+ }
+ return 0;
+}
+
/****************************************************************************
* Radio control and setup
***************************************************************************/
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
index 4340bcc4f..9e3f298d8 100644
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
+++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.hpp
@@ -80,6 +80,10 @@ public:
size_t get_chan_from_dboard_fe(const std::string &fe, const direction_t dir);
std::string get_dboard_fe_from_chan(const size_t chan, const direction_t dir);
+ std::vector<std::string> get_gpio_banks() const;
+ void set_gpio_attr(const std::string &bank, const std::string &attr, const uint32_t value, const uint32_t mask);
+ uint32_t get_gpio_attr(const std::string &bank, const std::string &attr);
+
double get_output_samp_rate(size_t port);
/************************************************************************