aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
Diffstat (limited to 'host')
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_constants.hpp2
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp132
2 files changed, 127 insertions, 7 deletions
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp
index 4df645c33..151e68220 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_constants.hpp
@@ -12,7 +12,7 @@
#include <cstddef>
static constexpr size_t FPGPIO_MASTER_RADIO = 0;
-
+static constexpr size_t TOTAL_RADIO_PORTS = 4;
static constexpr double AD9371_RX_MIN_BANDWIDTH = 20.0e6; // HZ
static constexpr double AD9371_RX_MAX_BANDWIDTH = 100.0e6; // HZ
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp
index c781fbfe9..5b0eb60d1 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_init.cpp
@@ -13,7 +13,9 @@
#include <uhd/transport/chdr.hpp>
#include <vector>
#include <string>
-
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
using namespace uhd;
using namespace uhd::rfnoc;
@@ -37,6 +39,40 @@ namespace {
};
}
+//! Helper function to extract single value of port number.
+//
+// Each GPIO pins can be controlled by each radio output ports.
+// This function convert the format of attribute "Radio_N_M"
+// to a single value port number = N*number_of_port_per_radio + M
+
+uint32_t extract_port_number(std::string radio_src_string, uhd::property_tree::sptr ptree){
+ std::string s_val = "0";
+ std::vector<std::string> radio_strings;
+ boost::algorithm::split(
+ radio_strings,
+ radio_src_string,
+ boost::is_any_of("_/"),
+ boost::token_compress_on);
+ boost::to_lower(radio_strings[0]);
+ if (radio_strings.size()<3) {
+ throw uhd::runtime_error(str(boost::format("%s is an invalid GPIO source string.") % radio_src_string));
+ }
+ size_t radio_num = std::stoi(radio_strings[1]);
+ size_t port_num = std::stoi(radio_strings[2]);
+ if (radio_strings[0] != "radio") {
+ throw uhd::runtime_error("Front panel GPIO bank can only accept a radio block as its driver.");
+ }
+ std::string radio_port_out = "Radio_"+ radio_strings[1] + "/ports/out";
+ std::string radio_port_path = radio_port_out + "/"+ radio_strings[2];
+ auto found = ptree->exists(fs_path("xbar")/ radio_port_path);
+ if (not found){
+ throw uhd::runtime_error(str(boost::format(
+ "Could not find radio port %s.\n") % radio_port_path));
+ }
+ size_t port_size = ptree->list(fs_path("xbar")/ radio_port_out).size();
+ return radio_num*port_size + port_num;
+}
+
void magnesium_radio_ctrl_impl::_init_defaults()
{
UHD_LOG_TRACE(unique_id(), "Initializing defaults...");
@@ -190,11 +226,9 @@ void magnesium_radio_ctrl_impl::_init_peripherals()
usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL
);
}
- if (get_block_id().get_block_count() == FPGPIO_MASTER_RADIO) {
- UHD_LOG_TRACE(unique_id(), "Initializing front-panel GPIO control...")
- _fp_gpio = usrp::gpio_atr::gpio_atr_3000::make(
- _get_ctrl(0), regs::sr_addr(regs::FP_GPIO), regs::RB_FP_GPIO);
- }
+ UHD_LOG_TRACE(unique_id(), "Initializing front-panel GPIO control...")
+ _fp_gpio = usrp::gpio_atr::gpio_atr_3000::make(
+ _get_ctrl(0), regs::sr_addr(regs::FP_GPIO), regs::RB_FP_GPIO);
}
void magnesium_radio_ctrl_impl::_init_frontend_subtree(
@@ -739,8 +773,94 @@ void magnesium_radio_ctrl_impl::_init_prop_tree()
.set_publisher([this](){ return this->get_rate(); })
;
}
+
+ // *****FP_GPIO************************
+ for(const auto& attr: usrp::gpio_atr::gpio_attr_map) {
+ if (not _tree->exists(fs_path("gpio") / "FP0" / attr.second)){
+ switch (attr.first){
+ case usrp::gpio_atr::GPIO_SRC:
+ //FIXME: move this creation of this branch of ptree out side of radio impl;
+ // since there's no data dependency between radio and SRC setting for FP0
+ _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second)
+ .set(std::vector<std::string>(
+ 32,
+ usrp::gpio_atr::default_attr_value_map.at(attr.first)))
+ .add_coerced_subscriber([this, attr](
+ const std::vector<std::string> str_val){
+ uint32_t radio_src_value = 0;
+ uint32_t master_value = 0;
+ for(size_t i = 0 ; i<str_val.size(); i++){
+ if(str_val[i] == "PS"){
+ master_value += 1<<i;;
+ }else{
+ auto port_num = extract_port_number(str_val[i],_tree);
+ radio_src_value =(1<<(2*i))*port_num + radio_src_value;
+ }
+ }
+ _rpcc->notify_with_token("set_fp_gpio_master", master_value);
+ _rpcc->notify_with_token("set_fp_gpio_radio_src", radio_src_value);
+ });
+ break;
+ case usrp::gpio_atr::GPIO_CTRL:
+ case usrp::gpio_atr::GPIO_DDR:
+ _tree->create<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second)
+ .set(std::vector<std::string>(
+ 32,
+ usrp::gpio_atr::default_attr_value_map.at(attr.first)))
+ .add_coerced_subscriber([this, attr](
+ const std::vector<std::string> str_val){
+ uint32_t val = 0;
+ for(size_t i = 0 ; i < str_val.size() ; i++){
+ val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i;
+ }
+ _fp_gpio->set_gpio_attr(attr.first, val);
+ });
+ break;
+ case usrp::gpio_atr::GPIO_READBACK:{
+ _tree->create<uint32_t>(fs_path("gpio") / "FP0" / attr.second)
+ .set_publisher([this](){
+ return _fp_gpio->read_gpio();
+ }
+ );
+ }
+ break;
+ default:
+ _tree->create<uint32_t>(fs_path("gpio") / "FP0" / attr.second)
+ .set(0)
+ .add_coerced_subscriber([this, attr](const uint32_t val){
+ _fp_gpio->set_gpio_attr(attr.first, val);
+ });
+ }
+ }else{
+ switch (attr.first){
+ case usrp::gpio_atr::GPIO_SRC:
+ break;
+ case usrp::gpio_atr::GPIO_CTRL:
+ case usrp::gpio_atr::GPIO_DDR:
+ _tree->access<std::vector<std::string>>(fs_path("gpio") / "FP0" / attr.second)
+ .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first)))
+ .add_coerced_subscriber([this, attr](const std::vector<std::string> str_val){
+ uint32_t val = 0;
+ for(size_t i = 0 ; i < str_val.size() ; i++){
+ val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i;
+ }
+ _fp_gpio->set_gpio_attr(attr.first, val);
+ });
+ break;
+ case usrp::gpio_atr::GPIO_READBACK:
+ break;
+ default:
+ _tree->access<uint32_t>(fs_path("gpio") / "FP0" / attr.second)
+ .set(0)
+ .add_coerced_subscriber([this, attr](const uint32_t val){
+ _fp_gpio->set_gpio_attr(attr.first, val);
+ });
+ }
+ }
+ }
}
+
void magnesium_radio_ctrl_impl::_init_mpm_sensors(
const direction_t dir,
const size_t chan_idx