aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300/x300_mb_controller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/x300/x300_mb_controller.cpp')
-rw-r--r--host/lib/usrp/x300/x300_mb_controller.cpp105
1 files changed, 91 insertions, 14 deletions
diff --git a/host/lib/usrp/x300/x300_mb_controller.cpp b/host/lib/usrp/x300/x300_mb_controller.cpp
index fd70526ab..28567e62e 100644
--- a/host/lib/usrp/x300/x300_mb_controller.cpp
+++ b/host/lib/usrp/x300/x300_mb_controller.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Ettus Research, a National Instruments Brand
+// Copyright 2019-2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
@@ -26,7 +26,7 @@ constexpr uint32_t ADC_SELF_TEST_DURATION = 100; // ms
// When these regs are fixed, there is another fixme below to actually init the
// timekeepers
-constexpr uint32_t TK_NUM_TIMEKEEPERS = 12; //Read-only
+constexpr uint32_t TK_NUM_TIMEKEEPERS = 12; // Read-only
constexpr uint32_t TK_REG_BASE = 100;
constexpr uint32_t TK_REG_OFFSET = 48;
constexpr uint32_t TK_REG_TICKS_NOW_LO = 0x00; // Read-only
@@ -41,6 +41,11 @@ constexpr uint32_t TK_REG_TICKS_PERIOD_HI = 0x20; // Read-Write
constexpr char LOG_ID[] = "X300::MB_CTRL";
+constexpr char GPIO_SRC_BANK[] = "FP0";
+constexpr char GPIO_SRC_RFA[] = "RFA";
+constexpr char GPIO_SRC_RFB[] = "RFB";
+constexpr size_t GPIO_SRC_NUM_PINS = 12;
+
} // namespace
@@ -75,7 +80,9 @@ x300_mb_controller::x300_mb_controller(const size_t hw_rev,
const size_t num_tks = _zpu_ctrl->peek32(SR_ADDR(SET0_BASE, TK_NUM_TIMEKEEPERS));
for (size_t i = 0; i < num_tks; i++) {
- register_timekeeper(i, std::make_shared<x300_timekeeper>(i, _zpu_ctrl, clock_ctrl->get_master_clock_rate()));
+ register_timekeeper(i,
+ std::make_shared<x300_timekeeper>(
+ i, _zpu_ctrl, clock_ctrl->get_master_clock_rate()));
}
init_gps();
@@ -107,8 +114,7 @@ void x300_mb_controller::x300_timekeeper::set_ticks_now(const uint64_t ticks)
get_tk_addr(TK_REG_TICKS_EVENT_LO), narrow_cast<uint32_t>(ticks & 0xFFFFFFFF));
_zpu_ctrl->poke32(
get_tk_addr(TK_REG_TICKS_EVENT_HI), narrow_cast<uint32_t>(ticks >> 32));
- _zpu_ctrl->poke32(
- get_tk_addr(TK_REG_TICKS_CTRL), narrow_cast<uint32_t>(0x1));
+ _zpu_ctrl->poke32(get_tk_addr(TK_REG_TICKS_CTRL), narrow_cast<uint32_t>(0x1));
}
void x300_mb_controller::x300_timekeeper::set_ticks_next_pps(const uint64_t ticks)
@@ -117,16 +123,15 @@ void x300_mb_controller::x300_timekeeper::set_ticks_next_pps(const uint64_t tick
get_tk_addr(TK_REG_TICKS_EVENT_LO), narrow_cast<uint32_t>(ticks & 0xFFFFFFFF));
_zpu_ctrl->poke32(
get_tk_addr(TK_REG_TICKS_EVENT_HI), narrow_cast<uint32_t>(ticks >> 32));
- _zpu_ctrl->poke32(
- get_tk_addr(TK_REG_TICKS_CTRL), narrow_cast<uint32_t>(0x2));
+ _zpu_ctrl->poke32(get_tk_addr(TK_REG_TICKS_CTRL), narrow_cast<uint32_t>(0x2));
}
void x300_mb_controller::x300_timekeeper::set_period(const uint64_t period_ns)
{
_zpu_ctrl->poke32(get_tk_addr(TK_REG_TICKS_PERIOD_LO),
narrow_cast<uint32_t>(period_ns & 0xFFFFFFFF));
- _zpu_ctrl->poke32(get_tk_addr(TK_REG_TICKS_PERIOD_HI),
- narrow_cast<uint32_t>(period_ns >> 32));
+ _zpu_ctrl->poke32(
+ get_tk_addr(TK_REG_TICKS_PERIOD_HI), narrow_cast<uint32_t>(period_ns >> 32));
}
uint32_t x300_mb_controller::x300_timekeeper::get_tk_addr(const uint32_t tk_addr)
@@ -247,8 +252,8 @@ void x300_mb_controller::set_clock_source(const std::string& source)
.str());
} else {
// TODO: Re-enable this warning when we figure out a reliable lock time
- // UHD_LOGGER_WARNING("X300::MB_CTRL") << "Reference clock failed to lock to " +
- // source + " during device initialization. " <<
+ // UHD_LOGGER_WARNING("X300::MB_CTRL") << "Reference clock failed to lock
+ // to " + source + " during device initialization. " <<
// "Check for the lock before operation or ignore this warning if using
// another clock source." ;
}
@@ -311,7 +316,8 @@ void x300_mb_controller::set_sync_source(
set_sync_source(sync_args);
}
-void x300_mb_controller::set_sync_source(const device_addr_t& sync_source) {
+void x300_mb_controller::set_sync_source(const device_addr_t& sync_source)
+{
if (sync_source.has_key("clock_source")) {
set_clock_source(sync_source["clock_source"]);
}
@@ -338,8 +344,7 @@ std::vector<device_addr_t> x300_mb_controller::get_sync_sources()
{"external", "internal"},
{"external", "external"},
{"gpsdo", "gpsdo"},
- {"gpsdo", "internal"}
- };
+ {"gpsdo", "internal"}};
// Now convert to vector of device_addr_t
std::vector<device_addr_t> sync_sources;
@@ -484,6 +489,78 @@ bool x300_mb_controller::synchronize(std::vector<mb_controller::sptr>& mb_contro
throw uhd::runtime_error(err_str);
}
+std::vector<std::string> x300_mb_controller::get_gpio_banks() const
+{
+ return {GPIO_SRC_BANK};
+}
+
+std::vector<std::string> x300_mb_controller::get_gpio_srcs(const std::string& bank) const
+{
+ if (bank != GPIO_SRC_BANK) {
+ UHD_LOG_ERROR(LOG_ID,
+ "Invalid GPIO source bank: " << bank << ". Only supported bank is "
+ << GPIO_SRC_BANK);
+ throw uhd::runtime_error(
+ std::string("Invalid GPIO source bank: ") + GPIO_SRC_BANK);
+ }
+ return {GPIO_SRC_RFA, GPIO_SRC_RFB};
+}
+
+std::vector<std::string> x300_mb_controller::get_gpio_src(const std::string& bank)
+{
+ if (bank != GPIO_SRC_BANK) {
+ UHD_LOG_ERROR(LOG_ID,
+ "Invalid GPIO source bank: " << bank << ". Only supported bank is "
+ << GPIO_SRC_BANK);
+ throw uhd::runtime_error(
+ std::string("Invalid GPIO source bank: ") + GPIO_SRC_BANK);
+ }
+ uint32_t fp_gpio_src = _zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_FP_GPIO_SRC));
+ const auto gpio_srcs = get_gpio_srcs(bank);
+ std::vector<std::string> gpio_src;
+ for (size_t ii = 0; ii < GPIO_SRC_NUM_PINS; ++ii) {
+ const uint32_t this_src = (fp_gpio_src >> (2 * ii)) & 0x3;
+ if (this_src > 1) {
+ UHD_LOG_WARNING(LOG_ID,
+ "get_gpio_src() read back invalid GPIO source index: "
+ << this_src << ". Falling back to " << (this_src & 0x1));
+ }
+ gpio_src.push_back(gpio_srcs[this_src & 0x1]);
+ }
+ return gpio_src;
+}
+
+void x300_mb_controller::set_gpio_src(
+ const std::string& bank, const std::vector<std::string>& srcs)
+{
+ if (srcs.size() > GPIO_SRC_NUM_PINS) {
+ UHD_LOG_WARNING(LOG_ID, "set_gpio_src(): Provided more sources than pins!");
+ }
+ uint32_t fp_gpio_src = _zpu_ctrl->peek32(SR_ADDR(SET0_BASE, ZPU_RB_FP_GPIO_SRC));
+ size_t pins_configured = 0;
+
+ const auto gpio_srcs = get_gpio_srcs(bank);
+ for (auto src : srcs) {
+ const uint32_t pins = [src]() {
+ if (src == GPIO_SRC_RFA) {
+ return 0;
+ }
+ if (src == GPIO_SRC_RFB) {
+ return 1;
+ }
+ UHD_LOG_ERROR(LOG_ID, "Invalid GPIO source provided: " << src);
+ throw uhd::runtime_error("Invalid GPIO source provided!");
+ }();
+ uint32_t pin_mask = ~(uint32_t(0x3) << (2 * pins_configured));
+ fp_gpio_src = (fp_gpio_src & pin_mask) | (pins << 2 * pins_configured);
+ pins_configured++;
+ if (pins_configured > GPIO_SRC_NUM_PINS) {
+ break;
+ }
+ }
+ _zpu_ctrl->poke32(SR_ADDR(SET0_BASE, ZPU_SR_FP_GPIO_SRC), fp_gpio_src);
+}
+
/******************************************************************************
* Private Methods
*****************************************************************************/