aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/e300
diff options
context:
space:
mode:
authorAshish Chaudhari <ashish@ettus.com>2015-03-17 13:52:29 -0700
committerAshish Chaudhari <ashish@ettus.com>2015-03-17 13:52:29 -0700
commit6a34824ad10eaa2d2b642b959f278f6c4e326d6d (patch)
tree1aa582ee8e5cef716b59ec4deb3a8e5f4f532929 /host/lib/usrp/e300
parent5682321efa26bb97f5d0c37d8e9921fc11a9b923 (diff)
parent306b5243e12af0db493856ad8397abac9835db0c (diff)
downloaduhd-6a34824ad10eaa2d2b642b959f278f6c4e326d6d.tar.gz
uhd-6a34824ad10eaa2d2b642b959f278f6c4e326d6d.tar.bz2
uhd-6a34824ad10eaa2d2b642b959f278f6c4e326d6d.zip
Merge branch 'master' into ashish/vivado
Diffstat (limited to 'host/lib/usrp/e300')
-rw-r--r--host/lib/usrp/e300/e300_eeprom_manager.cpp4
-rw-r--r--host/lib/usrp/e300/e300_impl.cpp36
-rw-r--r--host/lib/usrp/e300/e300_impl.hpp8
-rw-r--r--host/lib/usrp/e300/e300_io_impl.cpp48
-rw-r--r--host/lib/usrp/e300/e300_network.cpp18
-rw-r--r--host/lib/usrp/e300/e300_remote_codec_ctrl.cpp76
-rw-r--r--host/lib/usrp/e300/e300_remote_codec_ctrl.hpp10
-rw-r--r--host/lib/usrp/e300/e300_sensor_manager.hpp2
-rw-r--r--host/lib/usrp/e300/e300_spi.cpp6
-rw-r--r--host/lib/usrp/e300/e300_ublox_control_impl.cpp2
10 files changed, 174 insertions, 36 deletions
diff --git a/host/lib/usrp/e300/e300_eeprom_manager.cpp b/host/lib/usrp/e300/e300_eeprom_manager.cpp
index dad6741f5..778e3150c 100644
--- a/host/lib/usrp/e300/e300_eeprom_manager.cpp
+++ b/host/lib/usrp/e300/e300_eeprom_manager.cpp
@@ -21,7 +21,7 @@
namespace uhd { namespace usrp { namespace e300 {
-static const std::string _bytes_to_string(const uint8_t* bytes, size_t max_len)
+static const std::string _bytes_to_string(const boost::uint8_t* bytes, size_t max_len)
{
std::string out;
for (size_t i = 0; i < max_len; i++) {
@@ -31,7 +31,7 @@ static const std::string _bytes_to_string(const uint8_t* bytes, size_t max_len)
return out;
}
-static void _string_to_bytes(const std::string &string, size_t max_len, uint8_t* buffer)
+static void _string_to_bytes(const std::string &string, size_t max_len, boost::uint8_t* buffer)
{
byte_vector_t bytes;
const size_t len = std::min(string.size(), max_len);
diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp
index ac6294d5a..8be3e47c9 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 GPIO_CTRL:
return gpio->set_pin_ctrl(dboard_iface::UNIT_RX, value);
- else if (attr == "DDR")
+ case GPIO_DDR:
return gpio->set_gpio_ddr(dboard_iface::UNIT_RX, value);
- else if (attr == "OUT")
+ case GPIO_OUT:
return gpio->set_gpio_out(dboard_iface::UNIT_RX, value);
- else if (attr == "ATR_0X")
+ case GPIO_ATR_0X:
return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, value);
- else if (attr == "ATR_RX")
+ case GPIO_ATR_RX:
return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, value);
- else if (attr == "ATR_TX")
+ case GPIO_ATR_TX:
return gpio->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, value);
- else if (attr == "ATR_XX")
+ case GPIO_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)
@@ -1028,6 +1030,8 @@ void e300_impl::_setup_radio(const size_t dspno)
_tree->create<int>(rf_fe_path / "sensors"); //empty TODO
_tree->create<sensor_value_t>(rf_fe_path / "sensors" / "lo_locked")
.publish(boost::bind(&e300_impl::_get_fe_pll_lock, this, direction == "tx"));
+ _tree->create<sensor_value_t>(rf_fe_path / "sensors" / "temp")
+ .publish(boost::bind(&ad9361_ctrl::get_temperature, _codec_ctrl));
BOOST_FOREACH(const std::string &name, ad9361_ctrl::get_gain_names(key))
{
_tree->create<meta_range_t>(rf_fe_path / "gains" / name / "range")
diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp
index a4170ee42..21aef215d 100644
--- a/host/lib/usrp/e300/e300_impl.hpp
+++ b/host/lib/usrp/e300/e300_impl.hpp
@@ -70,6 +70,8 @@ static std::string E300_SERVER_I2C_PORT = "21761";
static std::string E300_SERVER_SENSOR_PORT = "21762";
static const double E300_RX_SW_BUFF_FULLNESS = 0.9; //Buffer should be half full
+static const size_t E300_RX_FC_REQUEST_FREQ = 32; // per flow ctrl window
+static const size_t E300_TX_FC_RESPONSE_FREQ = 8; // per flow ctrl window
// crossbar settings
static const boost::uint8_t E300_RADIO_DEST_PREFIX_TX = 0;
@@ -262,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/e300/e300_io_impl.cpp b/host/lib/usrp/e300/e300_io_impl.cpp
index dcb6f2afe..fa4915ed1 100644
--- a/host/lib/usrp/e300/e300_io_impl.cpp
+++ b/host/lib/usrp/e300/e300_io_impl.cpp
@@ -25,6 +25,7 @@
#include <uhd/transport/bounded_buffer.hpp>
#include <boost/bind.hpp>
#include <uhd/utils/tasks.hpp>
+#include <uhd/utils/log.hpp>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
@@ -226,6 +227,18 @@ void e300_impl::_handle_overflow(
}
}
+static size_t get_rx_flow_control_window(size_t frame_size, size_t sw_buff_size, double fullness_factor)
+{
+ if (fullness_factor < 0.01 || fullness_factor > 1) {
+ throw uhd::value_error("recv_buff_fullness must be between 0.01 and 1 inclusive (1% to 100%)");
+ }
+
+ size_t window_in_pkts = (static_cast<size_t>(sw_buff_size * fullness_factor) / frame_size);
+ if (window_in_pkts == 0) {
+ throw uhd::value_error("recv_buff_size must be larger than the recv_frame_size.");
+ }
+ return window_in_pkts;
+}
static void handle_rx_flowctrl(
const boost::uint32_t sid,
@@ -457,25 +470,38 @@ rx_streamer::sptr e300_impl::get_rx_stream(const uhd::stream_args_t &args_)
id.num_outputs = 1;
my_streamer->set_converter(id);
+ perif.framer->clear();
perif.framer->set_nsamps_per_packet(spp); //seems to be a good place to set this
perif.framer->set_sid((data_sid << 16) | (data_sid >> 16));
perif.framer->setup(args);
perif.ddc->setup(args);
+
+ // flow control setup
+ const size_t frame_size = data_xports.recv->get_recv_frame_size();
+ const size_t num_frames = data_xports.recv->get_num_recv_frames();
+ const size_t fc_window = get_rx_flow_control_window(
+ frame_size,num_frames * frame_size,
+ E300_RX_SW_BUFF_FULLNESS);
+ const size_t fc_handle_window = std::max<size_t>(1, fc_window / E300_RX_FC_REQUEST_FREQ);
+
+ UHD_LOG << "RX Flow Control Window = " << fc_window
+ << ", RX Flow Control Handler Window = "
+ << fc_handle_window << std::endl;
+
+ perif.framer->configure_flow_control(fc_window);
+ boost::shared_ptr<e300_rx_fc_cache_t> fc_cache(new e300_rx_fc_cache_t());
+
my_streamer->set_xport_chan_get_buff(stream_i, boost::bind(
&zero_copy_if::get_recv_buff, data_xports.recv, _1
), true /*flush*/);
my_streamer->set_overflow_handler(stream_i,
- boost::bind(&rx_vita_core_3000::handle_overflow, perif.framer)
+ boost::bind(&e300_impl::_handle_overflow, this, boost::ref(perif),
+ boost::weak_ptr<uhd::rx_streamer>(my_streamer))
);
- //setup flow control
- const size_t fc_window = data_xports.recv->get_num_recv_frames();
- perif.framer->configure_flow_control(fc_window);
- boost::shared_ptr<e300_rx_fc_cache_t> fc_cache(new e300_rx_fc_cache_t());
my_streamer->set_xport_handle_flowctrl(stream_i,
boost::bind(&handle_rx_flowctrl, data_sid, data_xports.send, fc_cache, _1),
- static_cast<size_t>(static_cast<double>(fc_window) * E300_RX_SW_BUFF_FULLNESS),
- true/*init*/);
+ fc_handle_window, true/*init*/);
my_streamer->set_issue_stream_cmd(stream_i,
boost::bind(&rx_vita_core_3000::issue_stream_command, perif.framer, _1)
@@ -564,7 +590,13 @@ tx_streamer::sptr e300_impl::get_tx_stream(const uhd::stream_args_t &args_)
//flow control setup
const size_t fc_window = data_xports.send->get_num_send_frames();
- perif.deframer->configure_flow_control(0/*cycs off*/, fc_window/8/*pkts*/);
+ const size_t fc_handle_window = std::max<size_t>(1, fc_window/E300_TX_FC_RESPONSE_FREQ);
+
+ UHD_LOG << "TX Flow Control Window = " << fc_window
+ << ", TX Flow Control Handler Window = "
+ << fc_handle_window << std::endl;
+
+ perif.deframer->configure_flow_control(0/*cycs off*/, fc_handle_window/*pkts*/);
boost::shared_ptr<e300_tx_fc_cache_t> fc_cache(new e300_tx_fc_cache_t());
fc_cache->stream_channel = stream_i;
fc_cache->device_channel = args.channels[stream_i];
diff --git a/host/lib/usrp/e300/e300_network.cpp b/host/lib/usrp/e300/e300_network.cpp
index bb904773b..cb06a5740 100644
--- a/host/lib/usrp/e300/e300_network.cpp
+++ b/host/lib/usrp/e300/e300_network.cpp
@@ -227,6 +227,24 @@ static void e300_codec_ctrl_tunnel(
case codec_xact_t::ACTION_GET_RSSI:
out->rssi = _codec_ctrl->get_rssi(which_str).to_real();
break;
+ case codec_xact_t::ACTION_GET_TEMPERATURE:
+ out->temp = _codec_ctrl->get_temperature().to_real();
+ break;
+ case codec_xact_t::ACTION_SET_DC_OFFSET_AUTO:
+ _codec_ctrl->set_dc_offset_auto(which_str, in->use_dc_correction == 1);
+ break;
+ case codec_xact_t::ACTION_SET_IQ_BALANCE_AUTO:
+ _codec_ctrl->set_iq_balance_auto(which_str, in->use_iq_correction == 1);
+ case codec_xact_t::ACTION_SET_AGC:
+ _codec_ctrl->set_agc(which_str, in->use_agc == 1);
+ break;
+ case codec_xact_t::ACTION_SET_AGC_MODE:
+ if(in->agc_mode == 0) {
+ _codec_ctrl->set_agc_mode(which_str, "slow");
+ } else if (in->agc_mode == 1) {
+ _codec_ctrl->set_agc_mode(which_str, "fast");
+ }
+ break;
default:
UHD_MSG(status) << "Got unknown request?!" << std::endl;
//Zero out actions to fail this request on client
diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
index ed8131e2f..871885a7b 100644
--- a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
+++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
@@ -116,10 +116,84 @@ public:
_args.bits = uhd::htonx<boost::uint32_t>(0);
_transact();
-
return sensor_value_t("RSSI", _retval.rssi, "dB");
}
+ sensor_value_t get_temperature()
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_GET_TEMPERATURE);
+ _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_NONE); /*Unused*/
+ _args.bits = uhd::htonx<boost::uint32_t>(0);
+
+ _transact();
+ return sensor_value_t("temp", _retval.temp, "C");
+ }
+
+ void set_dc_offset_auto(const std::string &which, const bool on)
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_SET_DC_OFFSET_AUTO);
+ if (which == "TX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX1);
+ else if (which == "TX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX2);
+ else if (which == "RX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX1);
+ else if (which == "RX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX2);
+ else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
+ _args.use_dc_correction = on ? 1 : 0;
+
+ _transact();
+ }
+
+ void set_iq_balance_auto(const std::string &which, const bool on)
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_SET_IQ_BALANCE_AUTO);
+ if (which == "TX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX1);
+ else if (which == "TX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX2);
+ else if (which == "RX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX1);
+ else if (which == "RX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX2);
+ else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
+ _args.use_iq_correction = on ? 1 : 0;
+
+ _transact();
+ }
+
+ void set_agc(const std::string &which, bool enable)
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_SET_AGC);
+ if (which == "TX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX1);
+ else if (which == "TX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX2);
+ else if (which == "RX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX1);
+ else if (which == "RX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX2);
+ else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
+ _args.use_agc = enable ? 1 : 0;
+
+ _transact();
+ }
+
+ void set_agc_mode(const std::string &which, const std::string &mode)
+ {
+ _clear();
+ _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_SET_AGC_MODE);
+
+ if (which == "TX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX1);
+ else if (which == "TX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX2);
+ else if (which == "RX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX1);
+ else if (which == "RX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX2);
+ else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
+
+ if(mode == "slow") {
+ _args.agc_mode = 0;
+ } else if (mode == "fast") {
+ _args.agc_mode = 1;
+ } else {
+ throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect agc mode.");
+ }
+
+ _transact();
+ }
+
private:
void _transact() {
{
diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp
index cbc4b52d2..459d0ec55 100644
--- a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp
+++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp
@@ -34,6 +34,11 @@ public:
double gain;
double freq;
double rssi;
+ double temp;
+ boost::uint32_t use_dc_correction;
+ boost::uint32_t use_iq_correction;
+ boost::uint32_t use_agc;
+ boost::uint32_t agc_mode;
boost::uint64_t bits;
};
@@ -44,6 +49,11 @@ public:
static const boost::uint32_t ACTION_TUNE = 13;
static const boost::uint32_t ACTION_SET_LOOPBACK = 14;
static const boost::uint32_t ACTION_GET_RSSI = 15;
+ static const boost::uint32_t ACTION_GET_TEMPERATURE = 16;
+ static const boost::uint32_t ACTION_SET_DC_OFFSET_AUTO = 17;
+ static const boost::uint32_t ACTION_SET_IQ_BALANCE_AUTO = 18;
+ static const boost::uint32_t ACTION_SET_AGC = 19;
+ static const boost::uint32_t ACTION_SET_AGC_MODE = 20;
//Values for "which"
static const boost::uint32_t CHAIN_NONE = 0;
diff --git a/host/lib/usrp/e300/e300_sensor_manager.hpp b/host/lib/usrp/e300/e300_sensor_manager.hpp
index 9c060b19a..09f889251 100644
--- a/host/lib/usrp/e300/e300_sensor_manager.hpp
+++ b/host/lib/usrp/e300/e300_sensor_manager.hpp
@@ -62,7 +62,7 @@ public:
// Note: This is a hack
static boost::uint32_t pack_float_in_uint32_t(const float &v)
{
- const boost::uint32_t *cast = reinterpret_cast<const uint32_t*>(&v);
+ const boost::uint32_t *cast = reinterpret_cast<const boost::uint32_t*>(&v);
return *cast;
}
diff --git a/host/lib/usrp/e300/e300_spi.cpp b/host/lib/usrp/e300/e300_spi.cpp
index 9a2daf4a7..2722d7f53 100644
--- a/host/lib/usrp/e300/e300_spi.cpp
+++ b/host/lib/usrp/e300/e300_spi.cpp
@@ -82,13 +82,13 @@ public:
int ret(0);
struct spi_ioc_transfer tr;
- uint8_t *tx_data = reinterpret_cast<uint8_t *>(&data);
+ boost::uint8_t *tx_data = reinterpret_cast<boost::uint8_t *>(&data);
UHD_ASSERT_THROW(num_bits == 24);
- uint8_t tx[] = {tx_data[2], tx_data[1], tx_data[0]};
+ boost::uint8_t tx[] = {tx_data[2], tx_data[1], tx_data[0]};
- uint8_t rx[3];
+ boost::uint8_t rx[3];
tr.tx_buf = (unsigned long) &tx[0];
tr.rx_buf = (unsigned long) &rx[0];
tr.len = num_bits >> 3;
diff --git a/host/lib/usrp/e300/e300_ublox_control_impl.cpp b/host/lib/usrp/e300/e300_ublox_control_impl.cpp
index a0ec10271..0f56fdb67 100644
--- a/host/lib/usrp/e300/e300_ublox_control_impl.cpp
+++ b/host/lib/usrp/e300/e300_ublox_control_impl.cpp
@@ -498,7 +498,7 @@ control::sptr control::make(const std::string &node, const size_t baud_rate)
#else
using namespace uhd::usrp::gps::ublox::ubx;
-control::sptr control::make(const std::string &node, const size_t baud_rate)
+control::sptr control::make(const std::string& /* node */, const size_t /* baud_rate */)
{
throw uhd::assertion_error("control::sptr::make: !E300_NATIVE");
}