diff options
author | eklai <eric@skysafe.io> | 2018-12-14 09:57:07 -0800 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2019-08-22 09:58:48 -0700 |
commit | 916f318badcadb25810b11bfc2a91e792378015f (patch) | |
tree | 6e0f6b16c685e3ec78325006fd1646adcfac1f7d | |
parent | 0fccb00d6ba7d85f2bc11df5d1948b6c521cb8f6 (diff) | |
download | uhd-916f318badcadb25810b11bfc2a91e792378015f.tar.gz uhd-916f318badcadb25810b11bfc2a91e792378015f.tar.bz2 uhd-916f318badcadb25810b11bfc2a91e792378015f.zip |
x300: fix x300 GPIO ATR property tree access type
In x300_radio_ctrl_impl.cpp, the GPIO attributes GPIO_SRC,
GPIO_CTRL, and GPIO_DDR are initialized as with vector<string>
values in the property tree. However, they are accessed in
set_gpio_attr() and get_gpio_attr() as vector<uint32_t>, which
will crash. This commit changes these access methods to be
consistent with the attribute value types.
This is not an issue for those who use the multi-usrp
interface, since that interface's set_gpio_attr() and
get_gpio_attr() methods are implemented with the correct typing
for GPIO_SRC, GPIO_CTRL, and GPIO_DDR.
-rw-r--r-- | host/lib/usrp/x300/x300_radio_ctrl_impl.cpp | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp index b61e64800..c280f77c5 100644 --- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp +++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp @@ -21,6 +21,7 @@ #include <boost/make_shared.hpp> #include <chrono> #include <thread> +#include <bitset> using namespace uhd; using namespace uhd::usrp; @@ -676,11 +677,34 @@ void x300_radio_ctrl_impl::set_gpio_attr(const std::string& bank, 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; + std::vector<std::string> attr_value; + const auto attr_type = usrp::gpio_atr::gpio_attr_rev_map.at(attr); + switch (attr_type) { + case usrp::gpio_atr::GPIO_SRC: + case usrp::gpio_atr::GPIO_CTRL: + case usrp::gpio_atr::GPIO_DDR: { + attr_value = + _tree->access<std::vector<std::string>>(fs_path("gpio") / bank / attr) + .get(); + std::bitset<32> bit_mask = std::bitset<32>(mask); + std::bitset<32> new_value = std::bitset<32>(value); + for (size_t i = 0; i < bit_mask.size(); i++) { + if (bit_mask[i] == 1) { + attr_value[i] = + usrp::gpio_atr::attr_value_map.at(attr_type).at(new_value[i]); + } + } + _tree->access<std::vector<std::string>>(fs_path("gpio") / bank / attr) + .set(attr_value); + return; + } break; + default: { + const uint32_t curr_value = + _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get(); + uint32_t new_value = (curr_value & ~mask) | (value & mask); + _tree->access<uint32_t>(fs_path("gpio") / bank / attr).set(new_value); + } break; + } } if (bank.size() > 2 and bank[1] == 'X') { const std::string name = bank.substr(2); @@ -713,7 +737,26 @@ 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()); + const auto attr_type = usrp::gpio_atr::gpio_attr_rev_map.at(attr); + switch(attr_type) { + case usrp::gpio_atr::GPIO_SRC: + case usrp::gpio_atr::GPIO_CTRL: + case usrp::gpio_atr::GPIO_DDR: { + auto str_val = + _tree->access<std::vector<std::string>>( + fs_path("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; + } + break; + default: { + return _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get(); + } + break; + } } if (bank.size() > 2 and bank[1] == 'X') { const std::string name = bank.substr(2); |