diff options
author | eklai <eric@skysafe.io> | 2020-01-23 18:47:28 -0800 |
---|---|---|
committer | atrnati <54334261+atrnati@users.noreply.github.com> | 2020-02-18 07:21:24 -0600 |
commit | d7304cc724de43b0d61d5b9d61a528d58898f004 (patch) | |
tree | 05304ad4d65c507c6d43fcbc407c566c351053c3 /host/examples/gpio.cpp | |
parent | c0a6bb1720a3db8ac9a40bdd5ca19de8be40d500 (diff) | |
download | uhd-d7304cc724de43b0d61d5b9d61a528d58898f004.tar.gz uhd-d7304cc724de43b0d61d5b9d61a528d58898f004.tar.bz2 uhd-d7304cc724de43b0d61d5b9d61a528d58898f004.zip |
x300: add front-panel GPIO source control
Adds a ZPU register to control the FP GPIO source. These are 2bits
per GPIO pin, totalling 24 bits. 0 corresponds to RF-A, 1 corresponds
to RF-B. The following Python code will control the upper 6 bits of the
front-panel GPIO from the B-side radio on an X300:
>>> import uhd
>>> U = uhd.usrp.MultiUSRP("type=x300")
>>> U.get_gpio_src_banks()
['FP0']
>>> U.get_gpio_src("FP0")
['RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA',
'RFA', 'RFA']
>>> U.set_gpio_src("FP0", ['RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA',
'RFB', 'RFB', 'RFB', 'RFB', 'RFB', 'RFB'])
>>> U.get_gpio_src("FP0")
['RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFB', 'RFB', 'RFB', 'RFB',
'RFB', 'RFB']
>>> # Make all GPIOs outputs:
>>> U.set_gpio_attr("FP0A", "DDR", 0xFFF)
>>> U.set_gpio_attr("FP0B", "DDR", 0xFFF)
>>> # Control all GPIOs from software (not ATR):
>>> U.set_gpio_attr("FP0A", "CTRL", 0x000)
>>> U.set_gpio_attr("FP0B", "CTRL", 0x000)
>>> # Bottom 3 pins go high from radio A
>>> U.set_gpio_attr("FP0A", "OUT", 0x007)
>>> # Top 3 pins go high from radio B
>>> U.set_gpio_attr("FP0B", "OUT", 0xE00)
Amends the gpio.cpp example to allow switching the source.
Co-authored-by: Brent Stapleton <brent.stapleton@ettus.com>
Diffstat (limited to 'host/examples/gpio.cpp')
-rw-r--r-- | host/examples/gpio.cpp | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/host/examples/gpio.cpp b/host/examples/gpio.cpp index fdd65349e..779fc1fa0 100644 --- a/host/examples/gpio.cpp +++ b/host/examples/gpio.cpp @@ -1,6 +1,7 @@ // // Copyright 2014-15 Ettus Research LLC // Copyright 2018 Ettus Research, a National Instruments Company +// Copyright 2020 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: GPL-3.0-or-later // @@ -48,8 +49,11 @@ // ATR_TX - Output values to be set when transmitting // ATR_XX - Output values to be set when operating in full duplex // This code below contains examples of setting all these registers. On -// devices with multiple radios, the ATR for the front panel GPIO is driven -// by the state of the first radio (0 or A). +// devices with multiple radios, the ATR driver for the front panel GPIO +// defaults to the state of the first radio (0 or A). This can be changed +// on a bit-by-bit basis by writing to the register: +// The ATR source can also be controlled, ie. drive from Radio0 or Radio1. +// SRC - Source (RFA=Radio0, RFB=Radio1, etc.) // // The UHD API // The multi_usrp::set_gpio_attr() method is the UHD API for configuring and @@ -57,8 +61,9 @@ // bank - the name of the GPIO bank (typically "FP0" for front panel GPIO, // "TX<n>" for TX daughter card GPIO, or // "RX<n>" for RX daughter card GPIO) -// attr - attribute (register) to change ("DDR", "OUT", "CTRL", "ATR_0X", -// "ATR_RX", "ATR_TX", "ATR_XX") +// attr - attribute (register) to change ("SRC", "DDR", "OUT", "CTRL", +// "ATR_0X", "ATR_RX", "ATR_TX", +// "ATR_XX") // value - the value to be set // mask - a mask indicating which bits in the specified attribute register are // to be changed (default is all bits). @@ -71,6 +76,7 @@ #include <stdlib.h> #include <boost/format.hpp> #include <boost/program_options.hpp> +#include <boost/tokenizer.hpp> #include <chrono> #include <csignal> #include <iostream> @@ -127,6 +133,13 @@ void output_reg_values(const std::string bank, % to_bit_string(gpio_bits, num_bits)) << std::endl; } + // GPIO Src + const auto gpio_src = usrp->get_gpio_src(bank); + std::cout << boost::format("%10s:") % "SRC: "; + for (auto src : gpio_src) { + std::cout << " " << src; + } + std::cout << std::endl; } int UHD_SAFE_MAIN(int argc, char* argv[]) @@ -137,9 +150,12 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) double rx_rate, tx_rate, dwell; std::string gpio; size_t num_bits; + std::string src_str; std::string ctrl_str; std::string ddr_str; std::string out_str; + std::string tx_subdev_spec; + std::string rx_subdev_spec; // setup the program options po::options_description desc("Allowed options"); @@ -147,6 +163,8 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) desc.add_options() ("help", "help message") ("args", po::value<std::string>(&args)->default_value(""), "multi uhd device address args") + ("tx_subdev_spec", po::value<std::string>(&tx_subdev_spec)->default_value(""), "A:0, B:0, or A:0 B:0") + ("rx_subdev_spec", po::value<std::string>(&rx_subdev_spec)->default_value(""), "A:0, B:0, or A:0 B:0") ("repeat", "repeat loop until Ctrl-C is pressed") ("list-banks", "print list of banks before running tests") ("cpu", po::value<std::string>(&cpu)->default_value(GPIO_DEFAULT_CPU_FORMAT), "cpu data format") @@ -157,6 +175,7 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) ("bank", po::value<std::string>(&gpio)->default_value(GPIO_DEFAULT_GPIO), "name of gpio bank") ("bits", po::value<size_t>(&num_bits)->default_value(GPIO_DEFAULT_NUM_BITS), "number of bits in gpio bank") ("bitbang", "single test case where user sets values for CTRL, DDR, and OUT registers") + ("src", po::value<std::string>(&src_str), "GPIO SRC reg value") ("ddr", po::value<std::string>(&ddr_str)->default_value(GPIO_DEFAULT_DDR), "GPIO DDR reg value") ("out", po::value<std::string>(&out_str)->default_value(GPIO_DEFAULT_OUT), "GPIO OUT reg value") ; @@ -187,6 +206,18 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) } std::cout << "Using GPIO bank: " << gpio << std::endl; + // subdev spec + if (tx_subdev_spec != "") + usrp->set_tx_subdev_spec(tx_subdev_spec); + if (rx_subdev_spec != "") + usrp->set_rx_subdev_spec(rx_subdev_spec); + std::cout << boost::format(" rx_subdev_spec: %s") + % usrp->get_rx_subdev_spec(0).to_string() + << std::endl; + std::cout << boost::format(" tx_subdev_spec: %s") + % usrp->get_tx_subdev_spec(0).to_string() + << std::endl; + // print out initial unconfigured state of FP GPIO std::cout << "Initial GPIO values:" << std::endl; output_reg_values(gpio, usrp, num_bits); @@ -227,6 +258,15 @@ int UHD_SAFE_MAIN(int argc, char* argv[]) ddr |= GPIO_BIT(4); } + // set GPIO driver source + if (vm.count("src")) { + std::vector<std::string> gpio_src; + typedef boost::char_separator<char> separator; + boost::tokenizer<separator> tokens(src_str, separator(" ")); + std::copy(tokens.begin(), tokens.end(), std::back_inserter(gpio_src)); + usrp->set_gpio_src(gpio, gpio_src); + } + // set data direction register (DDR) usrp->set_gpio_attr(gpio, "DDR", ddr, mask); |