aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorIan Buckley <github@ionconcepts.com>2015-03-09 11:20:56 -0700
committerAshish Chaudhari <ashish@ettus.com>2015-03-09 11:20:56 -0700
commitd9241b78d32402093c37ab7ce2f4336699219ed4 (patch)
tree4ca5dcae3226099d4d2770bee397969006dbae9c /host/lib
parent33edac343488fdd87337e308b277adca69f16819 (diff)
downloaduhd-d9241b78d32402093c37ab7ce2f4336699219ed4.tar.gz
uhd-d9241b78d32402093c37ab7ce2f4336699219ed4.tar.bz2
uhd-d9241b78d32402093c37ab7ce2f4336699219ed4.zip
B200: UHD support for FPGPIO connector on REV6+ boards.
- GPIO on UART connector all board Revs - Consolidated fpgpio_bitbang into fpgpio example and renamed it gpio - Changed FP_GPIO readback address to match X300
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp35
-rw-r--r--host/lib/usrp/b200/b200_impl.hpp7
-rw-r--r--host/lib/usrp/b200/b200_regs.hpp2
-rw-r--r--host/lib/usrp/cores/gpio_core_200.hpp9
-rw-r--r--host/lib/usrp/e300/e300_impl.cpp34
-rw-r--r--host/lib/usrp/e300/e300_impl.hpp6
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp35
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp6
8 files changed, 92 insertions, 42 deletions
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index 663696926..89af6a6e1 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2012-2014 Ettus Research LLC
+// Copyright 2012-2015 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -529,6 +529,19 @@ b200_impl::b200_impl(const device_addr_t &device_addr)
_tree->create<std::vector<std::string> >(mb_path / "clock_source" / "options").set(clock_sources);
////////////////////////////////////////////////////////////////////
+ // front panel gpio
+ ////////////////////////////////////////////////////////////////////
+ _radio_perifs[0].fp_gpio = gpio_core_200::make(_radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO);
+ BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map)
+ {
+ _tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / attr.second)
+ .set(0)
+ .subscribe(boost::bind(&b200_impl::set_fp_gpio, this, _radio_perifs[0].fp_gpio, attr.first, _1));
+ }
+ _tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / "READBACK")
+ .publish(boost::bind(&b200_impl::get_fp_gpio, this, _radio_perifs[0].fp_gpio));
+
+ ////////////////////////////////////////////////////////////////////
// dboard eeproms but not really
////////////////////////////////////////////////////////////////////
dboard_eeprom_t db_eeprom;
@@ -902,6 +915,26 @@ void b200_impl::set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &mb_eeprom)
}
+boost::uint32_t b200_impl::get_fp_gpio(gpio_core_200::sptr gpio)
+{
+ return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX));
+}
+
+void b200_impl::set_fp_gpio(gpio_core_200::sptr gpio, const gpio_attr_t attr, const boost::uint32_t value)
+{
+ switch (attr)
+ {
+ case CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value);
+ case DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value);
+ case OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value);
+ case ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value);
+ case ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value);
+ case ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value);
+ case ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value);
+ default: UHD_THROW_INVALID_CODE_PATH();
+ }
+}
+
/***********************************************************************
* Reference time and clock
**********************************************************************/
diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp
index 64d7aa7d0..cff767b4b 100644
--- a/host/lib/usrp/b200/b200_impl.hpp
+++ b/host/lib/usrp/b200/b200_impl.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2012-2015 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -156,6 +156,7 @@ private:
{
radio_ctrl_core_3000::sptr ctrl;
gpio_core_200_32wo::sptr atr;
+ gpio_core_200::sptr fp_gpio;
time_core_3000::sptr time64;
rx_vita_core_3000::sptr framer;
rx_dsp_core_3000::sptr ddc;
@@ -194,6 +195,9 @@ private:
void update_enables(void);
void update_atrs(void);
+ boost::uint32_t get_fp_gpio(gpio_core_200::sptr);
+ void set_fp_gpio(gpio_core_200::sptr, const gpio_attr_t, const boost::uint32_t);
+
double _tick_rate;
double get_tick_rate(void){return _tick_rate;}
double set_tick_rate(const double rate);
@@ -245,6 +249,7 @@ private:
//! Coercer, attached to the "rate/value" property on the rx dsps.
double coerce_rx_samp_rate(rx_dsp_core_3000::sptr, size_t, const double);
void update_rx_samp_rate(const size_t, const double);
+
//! Coercer, attached to the "rate/value" property on the tx dsps.
double coerce_tx_samp_rate(tx_dsp_core_3000::sptr, size_t, const double);
void update_tx_samp_rate(const size_t, const double);
diff --git a/host/lib/usrp/b200/b200_regs.hpp b/host/lib/usrp/b200/b200_regs.hpp
index 900651f94..8f2dd03f3 100644
--- a/host/lib/usrp/b200/b200_regs.hpp
+++ b/host/lib/usrp/b200/b200_regs.hpp
@@ -46,11 +46,13 @@ localparam SR_TX_DSP = 184;
localparam SR_TIME = 128;
localparam SR_RX_FMT = 136;
localparam SR_TX_FMT = 138;
+localparam SR_FP_GPIO = 200;
localparam RB32_TEST = 0;
localparam RB64_TIME_NOW = 8;
localparam RB64_TIME_PPS = 16;
localparam RB64_CODEC_READBACK = 24;
+localparam RB32_FP_GPIO = 32;
//pll constants
static const int AD9361_SLAVENO = (1 << 0);
diff --git a/host/lib/usrp/cores/gpio_core_200.hpp b/host/lib/usrp/cores/gpio_core_200.hpp
index 164437f40..a76cced01 100644
--- a/host/lib/usrp/cores/gpio_core_200.hpp
+++ b/host/lib/usrp/cores/gpio_core_200.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011,2014 Ettus Research LLC
+// Copyright 2011,2014,2015 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -20,10 +20,17 @@
#include <uhd/config.hpp>
#include <uhd/usrp/dboard_iface.hpp>
+#include <boost/assign.hpp>
#include <boost/cstdint.hpp>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <uhd/types/wb_iface.hpp>
+#include <map>
+
+typedef enum{CTRL,DDR,OUT,ATR_0X,ATR_RX,ATR_TX,ATR_XX} gpio_attr_t;
+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(CTRL,"CTRL")(DDR,"DDR")(OUT,"OUT")(ATR_0X,"ATR_0X")(ATR_RX,"ATR_RX")(ATR_TX,"ATR_TX")(ATR_XX,"ATR_XX");
class gpio_core_200 : boost::noncopyable{
public:
diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp
index ce94147e8..ac92f9a12 100644
--- a/host/lib/usrp/e300/e300_impl.cpp
+++ b/host/lib/usrp/e300/e300_impl.cpp
@@ -469,15 +469,14 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
// internal gpios
////////////////////////////////////////////////////////////////////
gpio_core_200::sptr fp_gpio = gpio_core_200::make(_radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO);
- const std::vector<std::string> gpio_attrs = boost::assign::list_of("CTRL")("DDR")("OUT")("ATR_0X")("ATR_RX")("ATR_TX")("ATR_XX");
- BOOST_FOREACH(const std::string &attr, gpio_attrs)
+ BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map)
{
- _tree->create<boost::uint32_t>(mb_path / "gpio" / "INT0" / attr)
- .subscribe(boost::bind(&e300_impl::_set_internal_gpio, this, fp_gpio, attr, _1))
+ _tree->create<boost::uint32_t>(mb_path / "gpio" / "INT0" / attr.second)
+ .subscribe(boost::bind(&e300_impl::_set_internal_gpio, this, fp_gpio, attr.first, _1))
.set(0);
}
_tree->create<boost::uint8_t>(mb_path / "gpio" / "INT0" / "READBACK")
- .publish(boost::bind(&e300_impl::_get_internal_gpio, this, fp_gpio, "READBACK"));
+ .publish(boost::bind(&e300_impl::_get_internal_gpio, this, fp_gpio));
////////////////////////////////////////////////////////////////////
@@ -576,32 +575,35 @@ e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
_tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_spec);
}
-boost::uint8_t e300_impl::_get_internal_gpio(
- gpio_core_200::sptr gpio,
- const std::string &)
+boost::uint8_t e300_impl::_get_internal_gpio(gpio_core_200::sptr gpio)
{
return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX));
}
void e300_impl::_set_internal_gpio(
gpio_core_200::sptr gpio,
- const std::string &attr,
+ const gpio_attr_t attr,
const boost::uint32_t value)
{
- if (attr == "CTRL")
+ switch (attr)
+ {
+ case CTRL:
return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value);
- else if (attr == "DDR")
+ case DDR:
return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value);
- else if (attr == "OUT")
+ case OUT:
return gpio->set_gpio_out(dboard_iface::UNIT_RX, value);
- else if (attr == "ATR_0X")
+ case ATR_0X:
return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value);
- else if (attr == "ATR_RX")
+ case ATR_RX:
return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value);
- else if (attr == "ATR_TX")
+ case ATR_TX:
return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value);
- else if (attr == "ATR_XX")
+ case ATR_XX:
return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value);
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
}
uhd::sensor_value_t e300_impl::_get_fe_pll_lock(const bool is_tx)
diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp
index c7d683f58..21aef215d 100644
--- a/host/lib/usrp/e300/e300_impl.hpp
+++ b/host/lib/usrp/e300/e300_impl.hpp
@@ -264,13 +264,11 @@ private: // methods
uhd::sensor_value_t _get_fe_pll_lock(const bool is_tx);
// internal gpios
- boost::uint8_t _get_internal_gpio(
- gpio_core_200::sptr,
- const std::string &);
+ boost::uint8_t _get_internal_gpio(gpio_core_200::sptr);
void _set_internal_gpio(
gpio_core_200::sptr gpio,
- const std::string &attr,
+ const gpio_attr_t attr,
const boost::uint32_t value);
private: // members
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index bf676b661..a82be543d 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2013-2014 Ettus Research LLC
+// Copyright 2013-2015 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -695,15 +695,14 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
// front panel gpio
////////////////////////////////////////////////////////////////////
mb.fp_gpio = gpio_core_200::make(mb.radio_perifs[0].ctrl, TOREG(SR_FP_GPIO), RB32_FP_GPIO);
- const std::vector<std::string> GPIO_ATTRS = boost::assign::list_of("CTRL")("DDR")("OUT")("ATR_0X")("ATR_RX")("ATR_TX")("ATR_XX");
- BOOST_FOREACH(const std::string &attr, GPIO_ATTRS)
+ BOOST_FOREACH(const gpio_attr_map_t::value_type attr, gpio_attr_map)
{
- _tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / attr)
+ _tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / attr.second)
.set(0)
- .subscribe(boost::bind(&x300_impl::set_fp_gpio, this, mb.fp_gpio, attr, _1));
+ .subscribe(boost::bind(&x300_impl::set_fp_gpio, this, mb.fp_gpio, attr.first, _1));
}
_tree->create<boost::uint32_t>(mb_path / "gpio" / "FP0" / "READBACK")
- .publish(boost::bind(&x300_impl::get_fp_gpio, this, mb.fp_gpio, "READBACK"));
+ .publish(boost::bind(&x300_impl::get_fp_gpio, this, mb.fp_gpio));
////////////////////////////////////////////////////////////////////
// register the time keepers - only one can be the highlander
@@ -1353,7 +1352,7 @@ void x300_impl::set_time_source_out(mboard_members_t &mb, const bool enb)
void x300_impl::update_clock_source(mboard_members_t &mb, const std::string &source)
{
//Optimize for the case when the current source is internal and we are trying
- //to set it to internal. This is the only case where we are guaranteed that
+ //to set it to internal. This is the only case where we are guaranteed that
//the clock has not gone away so we can skip setting the MUX and reseting the LMK.
if (not (mb.current_refclk_src == "internal" and source == "internal")) {
//Update the clock MUX on the motherboard to select the requested source
@@ -1534,20 +1533,24 @@ void x300_impl::set_mb_eeprom(i2c_iface::sptr i2c, const mboard_eeprom_t &mb_eep
* front-panel GPIO
**********************************************************************/
-boost::uint32_t x300_impl::get_fp_gpio(gpio_core_200::sptr gpio, const std::string &)
+boost::uint32_t x300_impl::get_fp_gpio(gpio_core_200::sptr gpio)
{
return boost::uint32_t(gpio->read_gpio(dboard_iface::UNIT_RX));
}
-void x300_impl::set_fp_gpio(gpio_core_200::sptr gpio, const std::string &attr, const boost::uint32_t value)
+void x300_impl::set_fp_gpio(gpio_core_200::sptr gpio, const gpio_attr_t attr, const boost::uint32_t value)
{
- if (attr == "CTRL") return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value);
- if (attr == "DDR") return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value);
- if (attr == "OUT") return gpio->set_gpio_out(dboard_iface::UNIT_RX, value);
- if (attr == "ATR_0X") return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value);
- if (attr == "ATR_RX") return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value);
- if (attr == "ATR_TX") return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value);
- if (attr == "ATR_XX") return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value);
+ switch (attr)
+ {
+ case CTRL: return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value);
+ case DDR: return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value);
+ case OUT: return gpio->set_gpio_out(dboard_iface::UNIT_RX, value);
+ case ATR_0X: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value);
+ case ATR_RX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value);
+ case ATR_TX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value);
+ case ATR_XX: return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, value);
+ default: UHD_THROW_INVALID_CODE_PATH();
+ }
}
/***********************************************************************
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 70c5dccb4..9ad060c85 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2013-2014 Ettus Research LLC
+// Copyright 2013-2015 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -360,8 +360,8 @@ private:
void check_fpga_compat(const uhd::fs_path &mb_path, uhd::wb_iface::sptr iface);
void update_atr_leds(gpio_core_200_32wo::sptr, const std::string &ant);
- boost::uint32_t get_fp_gpio(gpio_core_200::sptr, const std::string &);
- void set_fp_gpio(gpio_core_200::sptr, const std::string &, const boost::uint32_t);
+ boost::uint32_t get_fp_gpio(gpio_core_200::sptr);
+ void set_fp_gpio(gpio_core_200::sptr, const gpio_attr_t, const boost::uint32_t);
//**PRECONDITION**
//This function assumes that all the VITA times in "radios" are synchronized