diff options
-rw-r--r-- | host/include/uhd/usrp/gpio_defs.hpp | 149 | ||||
-rw-r--r-- | host/include/uhd/usrp/multi_usrp.hpp | 54 | ||||
-rw-r--r-- | host/lib/usrp/cores/gpio_atr_3000.cpp | 5 | ||||
-rw-r--r-- | host/lib/usrp/multi_usrp.cpp | 194 |
4 files changed, 341 insertions, 61 deletions
diff --git a/host/include/uhd/usrp/gpio_defs.hpp b/host/include/uhd/usrp/gpio_defs.hpp index 9fca3f185..18ccc0834 100644 --- a/host/include/uhd/usrp/gpio_defs.hpp +++ b/host/include/uhd/usrp/gpio_defs.hpp @@ -14,46 +14,117 @@ #include <map> namespace uhd { namespace usrp { namespace gpio_atr { + static const std::string GPIO_ATTR_SRC = "SRC"; + //! Attribute name for GPIO control. + static const std::string GPIO_ATTR_CTRL = "CTRL"; + //! Attribute name for GPIO data direction register. + static const std::string GPIO_ATTR_DDR = "DDR"; + //! Attribute name for GPIO ouput value. + static const std::string GPIO_ATTR_OUT = "OUT"; + //! Attribute name for GPIO ATR idle state register. + static const std::string GPIO_ATTR_ATR0X = "ATR_0X"; + //! Attribute name for GPIO ATR receive only register. + static const std::string GPIO_ATTR_ATRRX = "ATR_RX"; + //! Attribute name for GPIO ATR transmit only register. + static const std::string GPIO_ATTR_ATRTX = "ATR_TX"; + //! Attribute name for GPIO ATR full duplex state register. + static const std::string GPIO_ATTR_ATRXX = "ATR_XX"; + //! Attribute name for GPIO READBACK register. + static const std::string GPIO_ATTR_READBACK = "READBACK"; -enum gpio_atr_reg_t { - ATR_REG_IDLE = int('i'), - ATR_REG_TX_ONLY = int('t'), - ATR_REG_RX_ONLY = int('r'), - ATR_REG_FULL_DUPLEX = int('f') -}; - -enum gpio_atr_mode_t { - MODE_ATR = 0, //Output driven by the auto-transmit-receive engine - MODE_GPIO = 1 //Output value is static -}; - -enum gpio_ddr_t { - DDR_INPUT = 0, - DDR_OUTPUT = 1 -}; - -enum gpio_attr_t { - GPIO_CTRL, - GPIO_DDR, - GPIO_OUT, - GPIO_ATR_0X, - GPIO_ATR_RX, - GPIO_ATR_TX, - GPIO_ATR_XX -}; - -typedef std::map<gpio_attr_t, std::string> gpio_attr_map_t; - -static const gpio_attr_map_t gpio_attr_map = - boost::assign::map_list_of - (GPIO_CTRL, "CTRL") - (GPIO_DDR, "DDR") - (GPIO_OUT, "OUT") - (GPIO_ATR_0X, "ATR_0X") - (GPIO_ATR_RX, "ATR_RX") - (GPIO_ATR_TX, "ATR_TX") - (GPIO_ATR_XX, "ATR_XX") -; + enum gpio_atr_reg_t { + ATR_REG_IDLE = int('i'), + ATR_REG_TX_ONLY = int('t'), + ATR_REG_RX_ONLY = int('r'), + ATR_REG_FULL_DUPLEX = int('f') + }; + + enum gpio_atr_mode_t { + MODE_ATR = 0, //Output driven by the auto-transmit-receive engine + MODE_GPIO = 1 //Output value is static + }; + + enum gpio_ddr_t { + DDR_INPUT = 0, + DDR_OUTPUT = 1 + }; + + enum gpio_attr_t { + GPIO_SRC, + GPIO_CTRL, + GPIO_DDR, + GPIO_OUT, + GPIO_ATR_0X, + GPIO_ATR_RX, + GPIO_ATR_TX, + GPIO_ATR_XX, + GPIO_READBACK + }; + + + typedef std::map<gpio_attr_t, std::string> gpio_attr_map_t; + + static const gpio_attr_map_t gpio_attr_map = { + {GPIO_SRC, GPIO_ATTR_SRC}, + {GPIO_CTRL, GPIO_ATTR_CTRL}, + {GPIO_DDR, GPIO_ATTR_DDR}, + {GPIO_OUT, GPIO_ATTR_OUT}, + {GPIO_ATR_0X, GPIO_ATTR_ATR0X}, + {GPIO_ATR_RX, GPIO_ATTR_ATRRX}, + {GPIO_ATR_TX, GPIO_ATTR_ATRTX}, + {GPIO_ATR_XX, GPIO_ATTR_ATRXX}, + {GPIO_READBACK, GPIO_ATTR_READBACK} + }; + + static const std::map<gpio_attr_t, std::map<uint32_t, std::string>> attr_value_map = { + {GPIO_CTRL, {{0, "ATR"}, {1, "GPIO"}}}, + {GPIO_DDR, {{0, "INPUT"}, {1, "OUTPUT"}}} + }; + static const std::map<std::string, gpio_attr_t> gpio_attr_rev_map ={ + {GPIO_ATTR_SRC, GPIO_SRC}, + {GPIO_ATTR_CTRL, GPIO_CTRL}, + {GPIO_ATTR_DDR, GPIO_DDR}, + {GPIO_ATTR_OUT, GPIO_OUT}, + {GPIO_ATTR_ATR0X, GPIO_ATR_0X}, + {GPIO_ATTR_ATRRX, GPIO_ATR_RX}, + {GPIO_ATTR_ATRTX, GPIO_ATR_TX}, + {GPIO_ATTR_ATRXX, GPIO_ATR_XX}, + { GPIO_ATTR_READBACK, GPIO_READBACK} + }; + + static const gpio_attr_map_t default_attr_value_map ={ + {GPIO_SRC, "RADIO_0/0"}, + {GPIO_CTRL, "GPIO"}, + {GPIO_DDR, "INPUT"} + }; + static const std::map<std::string, uint32_t> gpio_level_map = { + {"HIGH", 1}, + {"LOW", 0}, + {"ON", 1}, + {"OFF", 0}, + {"TRUE", 1}, + {"FALSE", 0} + }; + static const std::map<std::string, uint32_t> gpio_direction = { + {"OUT", 1}, + {"IN", 0}, + {"OUTPUT", 1}, + {"INPUT", 0} + }; + static const std::map<std::string, uint32_t> gpio_ctrl_mode = { + {"ATR", 0}, + {"GPIO", 1} + }; + static const std::map<std::string,std::map<std::string, uint32_t>> gpio_attr_value_pair = { + {GPIO_ATTR_CTRL, gpio_ctrl_mode}, + {GPIO_ATTR_DDR, gpio_direction}, + {GPIO_ATTR_OUT, gpio_level_map}, + {GPIO_ATTR_ATR0X, gpio_level_map}, + {GPIO_ATTR_ATRRX, gpio_level_map}, + {GPIO_ATTR_ATRTX, gpio_level_map}, + {GPIO_ATTR_ATRXX, gpio_level_map}, + {GPIO_ATTR_READBACK, gpio_level_map} + }; }}} //namespaces diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index d23d73e2c..2490cc7f8 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -1312,6 +1312,33 @@ public: virtual void set_gpio_attr(const std::string &bank, const std::string &attr, const uint32_t value, const uint32_t mask = 0xffffffff, const size_t mboard = 0) = 0; /*! + * Set a GPIO attribute on a particular GPIO bank. + * Possible attribute names: + * - SRC - "PS" for handling by processing system + * - "RADIO_N/M" for handling by radio block with N is in [0..Number of Radio]; M is in [0..Number of port per Radio] + * - CTRL - "ATR" for ATR mode + * - "GPIO" for GPIO mode + * - DDR - "OUT" for output + * - "IN" for input + * - OUT - a string of numbers representing GPIO output level (not ATR mode) + * - "HIGH"or "LOW" as GPIO output level that apply for each bit mask that is 1 + * - ATR_0X - a string of numbers representing a value of the ATR idle state register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR idle state register + * - ATR_RX - a string of numbers representing a value of a ATR receive only state register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR receive only state register + * - ATR_TX - a string of numbers representing a value of the ATR transmit only state register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR transmit only state register + * - ATR_XX - a string of numbers representing a value of the ATR full duplex state register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR full duplex state register + * \param bank the name of a GPIO bank + * \param attr the name of a GPIO attribute + * \param value the new value for this GPIO bank + * \param mask the bit mask to effect which pins are changed + * \param mboard the motherboard index 0 to M-1 + */ + virtual void set_gpio_attr(const std::string &bank, const std::string &attr, const std::string &value, const uint32_t mask = 0xffffffff, const size_t mboard = 0) = 0; + + /*! * Get a GPIO attribute on a particular GPIO bank. * Possible attribute names: * - CTRL - 1 for ATR mode 0 for GPIO mode @@ -1329,6 +1356,33 @@ public: */ virtual uint32_t get_gpio_attr(const std::string &bank, const std::string &attr, const size_t mboard = 0) = 0; + /*! + * Get a GPIO attribute on a particular GPIO bank. + * Possible attribute names: + * - SRC - "PS" for handling by processing system + * - "RADIO_N/M" for handling by radio block with N is in [0..Number of Radio]; M is in [0..Number of port per Radio] + * - CTRL - "ATR" for ATR mode + * - "GPIO" for GPIO mode + * - DDR - "OUT" for output + * - "IN" for input + * - OUT - a string of numbers representing GPIO output level (not ATR mode) + * - "HIGH"or "LOW" as GPIO output level that apply for each bit mask that is 1 + * - ATR_0X - a string of numbers representing a value of the ATR idle state register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR idle state register + * - ATR_RX - a string of numbers representing a value of a ATR receive only state register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR receive only state register + * - ATR_TX - a string of numbers representing a value of the ATR transmit only state register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR transmit only state register + * - ATR_XX - a string of numbers representing a value of the ATR full duplex state register + * - "HIGH" or "LOW" as a value set on each bit on of the ATR full duplex state register + * - READBACK - readback input GPIOs + * \param bank the name of a GPIO bank + * \param attr the name of a GPIO attribute + * \param mboard the motherboard index 0 to M-1 + * \return the value set for this attribute in vector of strings + */ + virtual std::vector<std::string> get_gpio_string_attr(const std::string &bank, const std::string &attr, const size_t mboard = 0) = 0; + /******************************************************************* * Register IO methods ******************************************************************/ diff --git a/host/lib/usrp/cores/gpio_atr_3000.cpp b/host/lib/usrp/cores/gpio_atr_3000.cpp index 1649d27bb..6e5df02ed 100644 --- a/host/lib/usrp/cores/gpio_atr_3000.cpp +++ b/host/lib/usrp/cores/gpio_atr_3000.cpp @@ -121,6 +121,8 @@ public: //call. This API does not have a mask so it configures all bits at the same time. switch (attr) { + case GPIO_SRC: + throw uhd::runtime_error("Can't set GPIO source by GPIO ATR interface."); case GPIO_CTRL: set_atr_mode(MODE_ATR, value); //Configure mode=ATR for all bits that are set set_atr_mode(MODE_GPIO, ~value); //Configure mode=GPIO for all bits that are unset @@ -149,6 +151,9 @@ public: //Only set bits that are driven by the ATR engine set_atr_reg(ATR_REG_FULL_DUPLEX, value); break; + case GPIO_READBACK: + //This is readonly register, ignore on set. + break; default: UHD_THROW_INVALID_CODE_PATH(); } diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 53dd23425..593cff4dc 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -7,7 +7,7 @@ #include <uhd/property_tree.hpp> #include <uhd/usrp/multi_usrp.hpp> - +#include <uhd/usrp/gpio_defs.hpp> #include <uhd/exception.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/math.hpp> @@ -24,6 +24,7 @@ #include <boost/algorithm/string.hpp> #include <algorithm> #include <cmath> +#include <bitset> using namespace uhd; using namespace uhd::usrp; @@ -1860,51 +1861,200 @@ public: void set_gpio_attr(const std::string &bank, const std::string &attr, const uint32_t value, const uint32_t mask, const size_t mboard) { + std::vector<std::string> attr_value; if (_tree->exists(mb_root(mboard) / "gpio" / bank)) { - const uint32_t current = _tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr).get(); - const uint32_t new_value = (current & ~mask) | (value & mask); - _tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr).set(new_value); - return; + if (_tree->exists(mb_root(mboard) / "gpio" / bank / attr)){ + gpio_atr::gpio_attr_t attr_type = gpio_atr::gpio_attr_rev_map.at(attr); + switch (attr_type){ + case gpio_atr::GPIO_SRC: + throw uhd::runtime_error("Can't set SRC attribute using u32int_t value"); + break; + case gpio_atr::GPIO_CTRL: + case gpio_atr::GPIO_DDR:{ + attr_value = _tree->access<std::vector<std::string>>(mb_root(mboard) / "gpio" / bank / attr).get(); + UHD_ASSERT_THROW(attr_value.size() <= 32); + std::bitset<32> bit_mask = std::bitset<32>(mask); + std::bitset<32> bit_value = std::bitset<32>(value); + for (size_t i = 0 ; i < bit_mask.size();i++){ + if (bit_mask[i] == 1){ + attr_value[i] = gpio_atr::attr_value_map.at(attr_type).at(bit_value[i]); + } + } + _tree->access<std::vector<std::string>>(mb_root(mboard) / "gpio" / bank / attr).set(attr_value); + } + break; + default:{ + const uint32_t current = _tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr).get(); + const uint32_t new_value = (current & ~mask) | (value & mask); + _tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr).set(new_value); + } + break; + } + return; + }else{ + throw uhd::runtime_error(str(boost::format( + "The hardware has no gpio attribute: %s:\n") % attr)); + } + } + 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>(mb_root(mboard) / "dboards" / name / "iface").get(); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_CTRL)) iface->set_pin_ctrl(unit, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_DDR)) iface->set_gpio_ddr(unit, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_OUT)) iface->set_gpio_out(unit, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_0X)) iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_RX)) iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_TX)) iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_XX)) iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_SRC)){ + throw uhd::runtime_error("Setting gpio source does not supported in daughter board."); + } + } + throw uhd::runtime_error(str(boost::format( + "The hardware has no gpio bank: %s:\n") % bank)); + } + + void set_gpio_attr(const std::string &bank, const std::string &attr, const std::string &str_value , const uint32_t mask, const size_t mboard) + { + + gpio_atr::gpio_attr_t attr_type = gpio_atr::gpio_attr_rev_map.at(attr); + + if (_tree->exists(mb_root(mboard) / "gpio" / bank)) + { + if (_tree->exists(mb_root(mboard) / "gpio" / bank / attr)){ + + switch (attr_type){ + case gpio_atr::GPIO_SRC: + case gpio_atr::GPIO_CTRL: + case gpio_atr::GPIO_DDR:{ + std::vector<std::string> attr_value = _tree->access<std::vector<std::string>>(mb_root(mboard) / "gpio" / bank / attr).get(); + UHD_ASSERT_THROW(attr_value.size() <= 32); + std::bitset<32> bit_mask = std::bitset<32>(mask); + for (size_t i = 0 ; i < bit_mask.size(); i++){ + if (bit_mask[i] == 1){ + attr_value[i] = str_value; + } + } + _tree->access<std::vector<std::string>>(mb_root(mboard) / "gpio" / bank / attr).set(attr_value); + } + break; + default:{ + uint32_t value = gpio_atr::gpio_attr_value_pair.at(attr).at(str_value) == 0 ? -1 : 0; + const uint32_t current = _tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr).get(); + const uint32_t new_value = (current & ~mask) | (value & mask); + _tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr).set(new_value); + } + break; + } + + return; + }else{ + throw uhd::runtime_error(str(boost::format( + "The hardware has no gpio attribute: %s:\n") % attr)); + } } if (bank.size() > 2 and bank[1] == 'X') { + uint32_t value = gpio_atr::gpio_attr_value_pair.at(attr).at(str_value) == 0 ? -1 : 0; 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>(mb_root(mboard) / "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)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_CTRL)) iface->set_pin_ctrl(unit, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_DDR)) iface->set_gpio_ddr(unit, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_OUT)) iface->set_gpio_out(unit, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_0X)) iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_RX)) iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_TX)) iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_ATR_XX)) iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, uint16_t(value), uint16_t(mask)); + if (attr == gpio_atr::gpio_attr_map.at(gpio_atr::GPIO_SRC)){ + throw uhd::runtime_error("Setting gpio source does not supported in daughter board."); + } } + throw uhd::runtime_error(str(boost::format("The hardware has no gpio bank: %s:\n") % bank)); } uint32_t get_gpio_attr(const std::string &bank, const std::string &attr, const size_t mboard) { + std::vector<std::string> str_val; + if (_tree->exists(mb_root(mboard) / "gpio" / bank)) { - return uint32_t(_tree->access<uint64_t>(mb_root(mboard) / "gpio" / bank / attr).get()); + if (_tree->exists(mb_root(mboard) / "gpio" / bank / attr)){ + gpio_atr::gpio_attr_t attr_type = gpio_atr::gpio_attr_rev_map.at(attr); + switch (attr_type){ + case gpio_atr::GPIO_SRC: + throw uhd::runtime_error("Can't set SRC attribute using u32int_t value"); + case gpio_atr::GPIO_CTRL: + case gpio_atr::GPIO_DDR:{ + str_val = _tree->access<std::vector<std::string>>(mb_root(mboard) / "gpio" / bank / attr).get(); + uint32_t val = 0; + for(size_t i = 0 ; i < str_val.size() ; i++){ + val += usrp::gpio_atr::gpio_attr_value_pair.at(attr).at(str_val[i])<<i; + } + return val; + } + default:{ + return uint32_t(_tree->access<uint64_t>(mb_root(mboard) / "gpio" / bank / attr).get()); + } + } + + return 0; + }else{ + throw uhd::runtime_error(str(boost::format("The hardware has no gpio attribute: %s:\n") % attr)); + } } 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>(mb_root(mboard) / "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 == "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; + throw uhd::runtime_error(str(boost::format("The hardware has no gpio bank: %s:\n") % bank)); + } + std::vector<std::string> get_gpio_string_attr(const std::string &bank, const std::string &attr, const size_t mboard) + { + gpio_atr::gpio_attr_t attr_type = gpio_atr::gpio_attr_rev_map.at(attr); + std::vector<std::string> str_val = std::vector<std::string>(32, gpio_atr::default_attr_value_map.at(attr_type)); + if (_tree->exists(mb_root(mboard) / "gpio" / bank)) + { + if (_tree->exists(mb_root(mboard) / "gpio" / bank / attr)) + { + gpio_atr::gpio_attr_t attr_type = gpio_atr::gpio_attr_rev_map.at(attr); + switch (attr_type){ + case gpio_atr::GPIO_SRC: + case gpio_atr::GPIO_CTRL: + case gpio_atr::GPIO_DDR:{ + return _tree->access<std::vector<std::string>>(mb_root(mboard) / "gpio" / bank / attr).get(); + } + default:{ + uint32_t value = uint32_t(_tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr).get()); + std::bitset<32> bit_value = std::bitset<32>(value); + for (size_t i = 0; i < bit_value.size(); i++) + { + str_val[i] = bit_value[i] == 0 ? "LOW" : "HIGH"; + } + return str_val; + } + } + } + else + { + throw uhd::runtime_error(str(boost::format("The hardware has no gpio attribute: %s:\n") % attr)); + } + } + throw uhd::runtime_error(str(boost::format("The hardware has no support for given gpio bank name: %s:\n") % bank)); } - void write_register(const std::string &path, const uint32_t field, const uint64_t value, const size_t mboard) { if (_tree->exists(mb_root(mboard) / "registers")) |