diff options
author | Trung N Tran <trung.tran@ettus.com> | 2018-02-21 13:28:50 -0800 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-02-21 16:59:46 -0800 |
commit | 21cc92016c4d5c3ae99e8fb49c04793feb51c21e (patch) | |
tree | 81126a5bbd40ee9e468361d8341806b9380cc398 /host | |
parent | cf7667fe71c961a4656ddb961302cc5a7e5570ed (diff) | |
download | uhd-21cc92016c4d5c3ae99e8fb49c04793feb51c21e.tar.gz uhd-21cc92016c4d5c3ae99e8fb49c04793feb51c21e.tar.bz2 uhd-21cc92016c4d5c3ae99e8fb49c04793feb51c21e.zip |
usrp: Add set_gpio_attr overload that use string
1/ multi_usrp.hpp; multi_usrp.cpp: added new functions
- set_gpio_attr() that allow user to set certain attribute by string
value.
- get_gpio_string_attr() return string type value of certain attribute.
2/ gpio_defs.hpp; gpio_atr_3000.cpp : added new definition of SRC attribute.
This commit enable user to use multi_usrp api to set_gpio_attr using string
value. This is helpful; because the attribute can represent more than two state
as of old API. This enable user to set SRC (source) that drive each GPIO bank's
pin. Source can be either processing unit(PS) or radio frontend logic from FPGA
logic.
Diffstat (limited to 'host')
-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")) |