aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authormichael-west <michael.west@ettus.com>2014-07-30 11:54:26 -0700
committermichael-west <michael.west@ettus.com>2014-07-30 11:54:26 -0700
commit35fc42f9fcbc5a791bdabc92086a51a2279563f1 (patch)
treefd053dd7e462fd49759ae255334de6d5c5aefd59 /host
parentbca5edb57979983a9eb8d6cd1016961552ad217c (diff)
parenteafae66c030aa86e9da127de4f6d5ec4fd641c59 (diff)
downloaduhd-35fc42f9fcbc5a791bdabc92086a51a2279563f1.tar.gz
uhd-35fc42f9fcbc5a791bdabc92086a51a2279563f1.tar.bz2
uhd-35fc42f9fcbc5a791bdabc92086a51a2279563f1.zip
Merge branch 'maint' into uhd/bug492
Conflicts: host/lib/usrp/b200/b200_impl.cpp
Diffstat (limited to 'host')
-rw-r--r--host/CMakeLists.txt4
-rw-r--r--host/cmake/Modules/UHDVersion.cmake2
-rw-r--r--host/examples/rx_ascii_art_dft.cpp2
-rw-r--r--host/examples/rx_samples_to_file.cpp2
-rw-r--r--host/examples/rx_samples_to_udp.cpp2
-rw-r--r--host/examples/tx_samples_from_file.cpp2
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp32
-rw-r--r--host/lib/usrp/cores/rx_dsp_core_200.cpp3
-rw-r--r--host/lib/usrp/cores/rx_dsp_core_3000.cpp2
-rw-r--r--host/lib/usrp/gps_ctrl.cpp45
-rw-r--r--host/lib/usrp/x300/x300_fw_uart.cpp93
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp31
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp10
13 files changed, 174 insertions, 56 deletions
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt
index 1973f7b0a..2c574c54f 100644
--- a/host/CMakeLists.txt
+++ b/host/CMakeLists.txt
@@ -210,8 +210,8 @@ UHD_INSTALL(FILES
# Images download directory for utils/uhd_images_downloader.py
########################################################################
-SET(UHD_IMAGES_MD5SUM "fb5b36972c453e5b7954879873bbcf74")
-SET(UHD_IMAGES_DOWNLOAD_SRC "http://files.ettus.com/binaries/maint_images/archive/uhd-images_003.007.001-20-g468e7f35.zip")
+SET(UHD_IMAGES_MD5SUM "68f8d472a4c9de881d450691fa7222cf")
+SET(UHD_IMAGES_DOWNLOAD_SRC "http://files.ettus.com/binaries/maint_images/archive/uhd-images_003.007.002-rc1.zip")
########################################################################
# Register top level components
diff --git a/host/cmake/Modules/UHDVersion.cmake b/host/cmake/Modules/UHDVersion.cmake
index 00b3029ea..f8e68f9e2 100644
--- a/host/cmake/Modules/UHDVersion.cmake
+++ b/host/cmake/Modules/UHDVersion.cmake
@@ -27,7 +27,7 @@ FIND_PACKAGE(Git QUIET)
########################################################################
SET(UHD_VERSION_MAJOR 003)
SET(UHD_VERSION_MINOR 007)
-SET(UHD_VERSION_PATCH 001)
+SET(UHD_VERSION_PATCH 002)
########################################################################
# Set up trimmed version numbers for DLL resource files and packages
diff --git a/host/examples/rx_ascii_art_dft.cpp b/host/examples/rx_ascii_art_dft.cpp
index 85cf8b50c..564a9e749 100644
--- a/host/examples/rx_ascii_art_dft.cpp
+++ b/host/examples/rx_ascii_art_dft.cpp
@@ -55,7 +55,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
("frame-rate", po::value<double>(&frame_rate)->default_value(5), "frame rate of the display (fps)")
("ref-lvl", po::value<float>(&ref_lvl)->default_value(0), "reference level for the display (dB)")
("dyn-rng", po::value<float>(&dyn_rng)->default_value(60), "dynamic range for the display (dB)")
- ("ref", po::value<std::string>(&ref)->default_value("internal"), "waveform type (internal, external, mimo)")
+ ("ref", po::value<std::string>(&ref)->default_value("internal"), "reference source (internal, external, mimo)")
("int-n", "tune USRP with integer-N tuning")
;
po::variables_map vm;
diff --git a/host/examples/rx_samples_to_file.cpp b/host/examples/rx_samples_to_file.cpp
index de3640794..e196b8592 100644
--- a/host/examples/rx_samples_to_file.cpp
+++ b/host/examples/rx_samples_to_file.cpp
@@ -231,7 +231,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
("ant", po::value<std::string>(&ant), "daughterboard antenna selection")
("subdev", po::value<std::string>(&subdev), "daughterboard subdevice specification")
("bw", po::value<double>(&bw), "daughterboard IF filter bandwidth in Hz")
- ("ref", po::value<std::string>(&ref)->default_value("internal"), "waveform type (internal, external, mimo)")
+ ("ref", po::value<std::string>(&ref)->default_value("internal"), "reference source (internal, external, mimo)")
("wirefmt", po::value<std::string>(&wirefmt)->default_value("sc16"), "wire format (sc8 or sc16)")
("setup", po::value<double>(&setup_time)->default_value(1.0), "seconds of setup time")
("progress", "periodically display short-term bandwidth")
diff --git a/host/examples/rx_samples_to_udp.cpp b/host/examples/rx_samples_to_udp.cpp
index 2f62652e0..e397dbbf9 100644
--- a/host/examples/rx_samples_to_udp.cpp
+++ b/host/examples/rx_samples_to_udp.cpp
@@ -52,7 +52,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
("bw", po::value<double>(&bw), "daughterboard IF filter bandwidth in Hz")
("port", po::value<std::string>(&port)->default_value("7124"), "server udp port")
("addr", po::value<std::string>(&addr)->default_value("192.168.1.10"), "resolvable server address")
- ("ref", po::value<std::string>(&ref)->default_value("internal"), "waveform type (internal, external, mimo)")
+ ("ref", po::value<std::string>(&ref)->default_value("internal"), "reference source (internal, external, mimo)")
("int-n", "tune USRP with integer-N tuning")
;
po::variables_map vm;
diff --git a/host/examples/tx_samples_from_file.cpp b/host/examples/tx_samples_from_file.cpp
index f911c446e..3293f8bd4 100644
--- a/host/examples/tx_samples_from_file.cpp
+++ b/host/examples/tx_samples_from_file.cpp
@@ -88,7 +88,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
("ant", po::value<std::string>(&ant), "daughterboard antenna selection")
("subdev", po::value<std::string>(&subdev), "daughterboard subdevice specification")
("bw", po::value<double>(&bw), "daughterboard IF filter bandwidth in Hz")
- ("ref", po::value<std::string>(&ref)->default_value("internal"), "waveform type (internal, external, mimo)")
+ ("ref", po::value<std::string>(&ref)->default_value("internal"), "reference source (internal, external, mimo)")
("wirefmt", po::value<std::string>(&wirefmt)->default_value("sc16"), "wire format (sc8 or sc16)")
("delay", po::value<double>(&delay)->default_value(0.0), "specify a delay between repeated transmission of file")
("repeat", "repeatedly transmit file")
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index f2b3885e6..f88d787ca 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -427,7 +427,7 @@ b200_impl::b200_impl(const device_addr_t &device_addr)
//setup time source props
_tree->create<std::string>(mb_path / "time_source" / "value")
.subscribe(boost::bind(&b200_impl::update_time_source, this, _1));
- static const std::vector<std::string> time_sources = boost::assign::list_of("none")("external")("gpsdo");
+ static const std::vector<std::string> time_sources = boost::assign::list_of("none")("internal")("external")("gpsdo");
_tree->create<std::vector<std::string> >(mb_path / "time_source" / "options").set(time_sources);
//setup reference source props
_tree->create<std::string>(mb_path / "clock_source" / "value")
@@ -464,10 +464,6 @@ b200_impl::b200_impl(const device_addr_t &device_addr)
_tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(rx_spec);
_tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_spec);
- //init to internal clock and time source
- _tree->access<std::string>(mb_path / "clock_source/value").set("internal");
- _tree->access<std::string>(mb_path / "time_source/value").set("none");
-
//GPS installed: use external ref, time, and init time spec
if (_gps and _gps->gps_detected())
{
@@ -482,6 +478,10 @@ b200_impl::b200_impl(const device_addr_t &device_addr)
time_spec_t pps_time = _tree->access<time_spec_t>(mb_path / "time" / "pps").get();
for (size_t i = 0; i < 10 && _tree->access<time_spec_t>(mb_path / "time" / "pps").get() == pps_time; i++)
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
+ } else {
+ //init to internal clock and time source
+ _tree->access<std::string>(mb_path / "clock_source/value").set("internal");
+ _tree->access<std::string>(mb_path / "time_source/value").set("internal");
}
}
@@ -686,10 +686,10 @@ void b200_impl::enforce_tick_rate_limits(size_t chan_count, double tick_rate, co
else
{
const double max_tick_rate = ((chan_count <= 1) ? AD9361_1_CHAN_CLOCK_RATE_MAX : AD9361_2_CHAN_CLOCK_RATE_MAX);
- if (tick_rate > max_tick_rate)
+ if (tick_rate - max_tick_rate >= 1.0)
{
throw uhd::value_error(boost::str(
- boost::format("current master clock rate (%.2f MHz) exceeds maximum possible master clock rate (%.2f MHz) when using %d %s channels")
+ boost::format("current master clock rate (%.6f MHz) exceeds maximum possible master clock rate (%.6f MHz) when using %d %s channels")
% (tick_rate/1e6)
% (max_tick_rate/1e6)
% chan_count
@@ -701,12 +701,12 @@ void b200_impl::enforce_tick_rate_limits(size_t chan_count, double tick_rate, co
double b200_impl::set_tick_rate(const double rate)
{
- UHD_MSG(status) << "Asking for clock rate " << rate/1e6 << " MHz\n";
+ UHD_MSG(status) << (boost::format("Asking for clock rate %.6f MHz\n") % (rate/1e6));
check_tick_rate_with_current_streamers(rate); // Defined in b200_io_impl.cpp
_tick_rate = _codec_ctrl->set_clock_rate(rate);
- UHD_MSG(status) << "Actually got clock rate " << _tick_rate/1e6 << " MHz\n";
+ UHD_MSG(status) << (boost::format("Actually got clock rate %.6f MHz\n") % (_tick_rate/1e6));
//reset after clock rate change
this->reset_codec_dcm();
@@ -791,11 +791,17 @@ void b200_impl::update_clock_source(const std::string &source)
void b200_impl::update_time_source(const std::string &source)
{
- if (source == "none"){}
- else if (source == "external"){}
- else if (source == "gpsdo"){}
+ boost::uint32_t value = 0;
+ if (source == "none")
+ value = 3;
+ else if (source == "internal")
+ value = 2;
+ else if (source == "external")
+ value = 1;
+ else if (source == "gpsdo")
+ value = 0;
else throw uhd::key_error("update_time_source: unknown source: " + source);
- _local_ctrl->poke32(TOREG(SR_CORE_PPS_SEL), (source == "external")? 1 : 0);
+ _local_ctrl->poke32(TOREG(SR_CORE_PPS_SEL), value);
}
/***********************************************************************
diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp
index 2fdc220b5..2e5ca8e7a 100644
--- a/host/lib/usrp/cores/rx_dsp_core_200.cpp
+++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp
@@ -176,7 +176,8 @@ public:
//determine which half-band filters are activated
int hb0 = 0, hb1 = 0;
- if (decim % 2 == 0){
+ // hb0 can only be enabled if the rate will be decimated by at least 2 between the CIC and hb1
+ if (decim >= 4 && decim % 2 == 0){
hb0 = 1;
decim /= 2;
}
diff --git a/host/lib/usrp/cores/rx_dsp_core_3000.cpp b/host/lib/usrp/cores/rx_dsp_core_3000.cpp
index 584dd6a94..07399d462 100644
--- a/host/lib/usrp/cores/rx_dsp_core_3000.cpp
+++ b/host/lib/usrp/cores/rx_dsp_core_3000.cpp
@@ -177,7 +177,7 @@ public:
void update_scalar(void){
const double factor = 1.0 + std::max(ceil_log2(_scaling_adjustment), 0.0);
- const double target_scalar = (1 << 15)*_scaling_adjustment/_dsp_extra_scaling/factor;
+ const double target_scalar = (1 << (_is_b200 ? 17 : 15))*_scaling_adjustment/_dsp_extra_scaling/factor;
const boost::int32_t actual_scalar = boost::math::iround(target_scalar);
_fxpt_scalar_correction = target_scalar/actual_scalar*factor; //should be small
_iface->poke32(REG_DSP_RX_SCALE_IQ, actual_scalar);
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index d327a84f9..f4d5cd8e8 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2011,2014 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
@@ -17,6 +17,7 @@
#include <uhd/usrp/gps_ctrl.hpp>
#include <uhd/utils/msg.hpp>
+#include <uhd/utils/log.hpp>
#include <uhd/exception.hpp>
#include <uhd/types/sensors.hpp>
#include <boost/algorithm/string.hpp>
@@ -62,6 +63,27 @@ private:
return std::string();
}
+ static bool is_nmea_checksum_ok(std::string nmea)
+ {
+ if (nmea.length() < 5 || nmea[0] != '$' || nmea[nmea.length()-3] != '*')
+ return false;
+
+ std::stringstream ss;
+ boost::uint32_t string_crc;
+ boost::uint32_t calculated_crc = 0;
+
+ // get crc from string
+ ss << std::hex << nmea.substr(nmea.length()-2, 2);
+ ss >> string_crc;
+
+ // calculate crc
+ for (size_t i = 1; i < nmea.length()-3; i++)
+ calculated_crc ^= nmea[i];
+
+ // return comparison
+ return (string_crc == calculated_crc);
+ }
+
std::string update_cached_sensors(const std::string sensor) {
if(not gps_detected() || (gps_type != GPS_TYPE_INTERNAL_GPSDO)) {
UHD_MSG(error) << "get_stat(): unsupported GPS or no GPS detected";
@@ -70,24 +92,36 @@ private:
const std::list<std::string> list = boost::assign::list_of("GPGGA")("GPRMC")("SERVO");
static const boost::regex status_regex("\\d\\d-\\d\\d-\\d\\d");
+ static const boost::regex gp_msg_regex("^\\$GP.*,\\*[0-9A-F]{2}$");
std::map<std::string,std::string> msgs;
// Get all GPSDO messages available
// Creating a map here because we only want the latest of each message type
for (std::string msg = _recv(); msg.length(); msg = _recv())
{
- if (msg.length() < 6)
- continue;
-
// Strip any end of line characters
erase_all(msg, "\r");
erase_all(msg, "\n");
+ if (msg.length() < 6)
+ {
+ UHD_LOGV(regularly) << __FUNCTION__ << ": Short NMEA string: " << msg << std::endl;
+ continue;
+ }
+
// Look for SERVO message
if (boost::regex_search(msg, status_regex, boost::regex_constants::match_continuous))
+ {
msgs["SERVO"] = msg;
- else
+ }
+ else if (boost::regex_match(msg, gp_msg_regex) and is_nmea_checksum_ok(msg))
+ {
msgs[msg.substr(1,5)] = msg;
+ }
+ else
+ {
+ UHD_LOGV(regularly) << __FUNCTION__ << ": Malformed NMEA string: " << msg << std::endl;
+ }
}
boost::system_time time = boost::get_system_time();
@@ -131,7 +165,6 @@ public:
}
else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response
else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate
- sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
}
if((i_heard_some_nmea) && (gps_type != GPS_TYPE_INTERNAL_GPSDO)) gps_type = GPS_TYPE_GENERIC_NMEA;
diff --git a/host/lib/usrp/x300/x300_fw_uart.cpp b/host/lib/usrp/x300/x300_fw_uart.cpp
index 943b2d9fa..b0fae124d 100644
--- a/host/lib/usrp/x300/x300_fw_uart.cpp
+++ b/host/lib/usrp/x300/x300_fw_uart.cpp
@@ -38,6 +38,8 @@ struct x300_uart_iface : uart_iface
rxpool = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_ADDR));
txpool = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_TX_ADDR));
poolsize = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_WORDS32));
+ _rxcache.resize(poolsize);
+ _last_device_rxoffset = rxoffset;
//this->write_uart("HELLO UART\n");
//this->read_uart(0.1);
}
@@ -54,6 +56,7 @@ struct x300_uart_iface : uart_iface
void write_uart(const std::string &buff)
{
+ boost::mutex::scoped_lock(_write_mutex);
BOOST_FOREACH(const char ch, buff)
{
if (ch == '\n') this->putchar('\r');
@@ -63,39 +66,99 @@ struct x300_uart_iface : uart_iface
int getchar(void)
{
- if (_iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX)) != rxoffset)
+ if (rxoffset == _last_device_rxoffset)
+ return -1;
+
+ rxoffset++;
+ return static_cast<int>(_rxcache[(rxoffset/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF);
+ }
+
+ void update_cache(void)
+ {
+ boost::uint32_t device_rxoffset = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX));
+ boost::uint32_t delta = device_rxoffset - rxoffset;
+
+ while (delta)
{
- const int shift = ((rxoffset%4) * 8);
- const char ch = _iface->peek32(SR_ADDR(rxpool, rxoffset/4)) >> shift;
- rxoffset = (rxoffset + 1) % (poolsize*4);
- return ch;
+ if (delta >= poolsize*4)
+ {
+ // all the data is new - reload the entire cache
+ for (boost::uint32_t i = 0; i < poolsize; i++)
+ _rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i));
+
+ // set rxoffset to the end of the first string
+ rxoffset = device_rxoffset - (poolsize*4) + 1;
+ while (static_cast<char>((_rxcache[(rxoffset/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF)) != '\n')
+ ++rxoffset;
+
+ // clear the partial string in the buffer;
+ _rxbuff.clear();
+ }
+ else if (rxoffset == _last_device_rxoffset)
+ {
+ // new data was added - refresh the portion of the cache that was updated
+ for (boost::uint32_t i = ((_last_device_rxoffset+1)/4) % poolsize; i != (((device_rxoffset)/4)+1) % poolsize; i = (i+1) % poolsize)
+ {
+ _rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i));
+ }
+ } else {
+ // there is new data, but we aren't done with what we have - check back later
+ break;
+ }
+
+ _last_device_rxoffset = device_rxoffset;
+
+ // check again to see if anything changed while we were updating the cache
+ device_rxoffset = _iface->peek32(SR_ADDR(X300_FW_SHMEM_BASE, X300_FW_SHMEM_UART_RX_INDEX));
+ delta = device_rxoffset - rxoffset;
}
- return -1;
}
std::string read_uart(double timeout)
{
+ boost::mutex::scoped_lock(_read_mutex);
const boost::system_time exit_time = boost::get_system_time() + boost::posix_time::microseconds(long(timeout*1e6));
std::string buff;
+
while (true)
{
- const int ch = this->getchar();
- if (ch == -1)
+ // Update cache
+ this->update_cache();
+
+ // Get available characters
+ for (int ch = this->getchar(); ch != -1; ch = this->getchar())
{
- if (boost::get_system_time() > exit_time) break;
- boost::this_thread::sleep(boost::posix_time::milliseconds(1));
- continue;
+ // skip carriage returns
+ if (ch == '\r')
+ continue;
+
+ // store character to buffer
+ _rxbuff += std::string(1, (char)ch);
+
+ // newline found - return string
+ if (ch == '\n')
+ {
+ buff = _rxbuff;
+ _rxbuff.clear();
+ return buff;
+ }
}
- if (ch == '\r') continue;
- buff += std::string(1, (char)ch);
- if (ch == '\n') break;
+
+ // no more characters - check time
+ if (boost::get_system_time() > exit_time)
+ break;
}
- //UHD_VAR(buff);
+
return buff;
}
wb_iface::sptr _iface;
boost::uint32_t rxoffset, txoffset, txword32, rxpool, txpool, poolsize;
+ boost::uint32_t _last_device_rxoffset;
+ std::vector<boost::uint32_t> _rxcache;
+ std::string _rxbuff;
+ boost::mutex _read_mutex;
+ boost::mutex _write_mutex;
};
uart_iface::sptr x300_make_uart_iface(wb_iface::sptr iface)
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index fdf216cf2..3561bc2f1 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -841,8 +841,9 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
try {
wait_for_ref_locked(mb.zpu_ctrl, 1.0);
} catch (uhd::exception::runtime_error &e) {
- UHD_MSG(warning) << "Clock reference failed to lock to internal source during device initialization. " <<
- "Check for the lock before operation or ignore this warning if using another clock source." << std::endl;
+ // Ignore for now - It can sometimes take longer than 1 second to lock and that is OK.
+ //UHD_MSG(warning) << "Clock reference failed to lock to internal source during device initialization. " <<
+ // "Check for the lock before operation or ignore this warning if using another clock source." << std::endl;
}
_tree->access<std::string>(mb_path / "time_source" / "value").set("internal");
UHD_MSG(status) << "References initialized to internal sources" << std::endl;
@@ -1079,9 +1080,13 @@ void x300_impl::setup_radio(const size_t mb_i, const std::string &slot_name)
this->update_atr_leds(mb.radio_perifs[radio_index].leds, ""); //init anyway, even if never called
//bind frontend corrections to the dboard freq props
+ const fs_path db_tx_fe_path = db_path / "tx_frontends";
+ BOOST_FOREACH(const std::string &name, _tree->list(db_tx_fe_path)) {
+ _tree->access<double>(db_tx_fe_path / name / "freq" / "value")
+ .subscribe(boost::bind(&x300_impl::set_tx_fe_corrections, this, mb_path, slot_name, _1));
+ }
const fs_path db_rx_fe_path = db_path / "rx_frontends";
- BOOST_FOREACH(const std::string &name, _tree->list(db_rx_fe_path))
- {
+ BOOST_FOREACH(const std::string &name, _tree->list(db_rx_fe_path)) {
_tree->access<double>(db_rx_fe_path / name / "freq" / "value")
.subscribe(boost::bind(&x300_impl::set_rx_fe_corrections, this, mb_path, slot_name, _1));
}
@@ -1092,6 +1097,11 @@ void x300_impl::set_rx_fe_corrections(const uhd::fs_path &mb_path, const std::st
apply_rx_fe_corrections(this->get_tree()->subtree(mb_path), fe_name, lo_freq);
}
+void x300_impl::set_tx_fe_corrections(const uhd::fs_path &mb_path, const std::string &fe_name, const double lo_freq)
+{
+ apply_tx_fe_corrections(this->get_tree()->subtree(mb_path), fe_name, lo_freq);
+}
+
boost::uint32_t get_pcie_dma_channel(boost::uint8_t destination, boost::uint8_t prefix)
{
static const boost::uint32_t RADIO_GRP_SIZE = 3;
@@ -1108,8 +1118,7 @@ x300_impl::both_xports_t x300_impl::make_transport(
const boost::uint8_t& destination,
const boost::uint8_t& prefix,
const uhd::device_addr_t& args,
- boost::uint32_t& sid
-)
+ boost::uint32_t& sid)
{
mboard_members_t &mb = _mb[mb_index];
both_xports_t xports;
@@ -1131,12 +1140,12 @@ x300_impl::both_xports_t x300_impl::make_transport(
if (mb.xport_path == "nirio") {
default_buff_args.send_frame_size =
(prefix == X300_RADIO_DEST_PREFIX_TX)
- ? X300_PCIE_DATA_FRAME_SIZE
+ ? X300_PCIE_TX_DATA_FRAME_SIZE
: X300_PCIE_MSG_FRAME_SIZE;
default_buff_args.recv_frame_size =
(prefix == X300_RADIO_DEST_PREFIX_RX)
- ? X300_PCIE_DATA_FRAME_SIZE
+ ? X300_PCIE_RX_DATA_FRAME_SIZE
: X300_PCIE_MSG_FRAME_SIZE;
default_buff_args.num_send_frames =
@@ -1206,10 +1215,10 @@ x300_impl::both_xports_t x300_impl::make_transport(
<< std::endl;
}
- size_t system_max_send_frame_size = (size_t) _max_frame_sizes.send_frame_size;
- size_t system_max_recv_frame_size = (size_t) _max_frame_sizes.recv_frame_size;
+ size_t system_max_send_frame_size = (size_t) _max_frame_sizes.send_frame_size;
+ size_t system_max_recv_frame_size = (size_t) _max_frame_sizes.recv_frame_size;
- // Make sure frame sizes do not exceed the max available value supported by UHD
+ // Make sure frame sizes do not exceed the max available value supported by UHD
default_buff_args.send_frame_size =
(prefix == X300_RADIO_DEST_PREFIX_TX)
? std::min(system_max_send_frame_size, X300_10GE_DATA_FRAME_MAX_SIZE)
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 80f3e8faa..578e96383 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -63,7 +63,11 @@ static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib
static const double X300_RX_SW_BUFF_FULL_FACTOR = 0.90; //Buffer should ideally be 90% full.
static const size_t X300_RX_FC_REQUEST_FREQ = 32; //per flow-control window
-static const size_t X300_PCIE_DATA_FRAME_SIZE = 8192; //bytes
+//The FIFO closest to the DMA controller is 1023 elements deep for RX and 1029 elements deep for TX
+//where an element is 8 bytes. For best throughput ensure that the data frame fits in these buffers.
+//Also ensure that the kernel has enough frames to hold buffered TX and RX data
+static const size_t X300_PCIE_RX_DATA_FRAME_SIZE = 8184; //bytes
+static const size_t X300_PCIE_TX_DATA_FRAME_SIZE = 8192; //bytes
static const size_t X300_PCIE_DATA_NUM_FRAMES = 2048;
static const size_t X300_PCIE_MSG_FRAME_SIZE = 256; //bytes
static const size_t X300_PCIE_MSG_NUM_FRAMES = 32;
@@ -207,7 +211,7 @@ private:
//perifs in each radio
radio_perifs_t radio_perifs[2]; //!< This is hardcoded s.t. radio_perifs[0] points to slot A and [1] to B
uhd::usrp::dboard_eeprom_t db_eeproms[8];
- //! Return the index of a radio component, given a slot name. This means DSPs, radio_perifs
+ //! Return the index of a radio component, given a slot name. This means DSPs, radio_perifs
size_t get_radio_index(const std::string &slot_name) {
UHD_ASSERT_THROW(slot_name == "A" or slot_name == "B");
return slot_name == "A" ? 0 : 1;
@@ -317,6 +321,8 @@ private:
uhd::dict<std::string, uhd::usrp::dboard_iface::sptr> _dboard_ifaces;
void set_rx_fe_corrections(const uhd::fs_path &mb_path, const std::string &fe_name, const double lo_freq);
+ void set_tx_fe_corrections(const uhd::fs_path &mb_path, const std::string &fe_name, const double lo_freq);
+
/*! Update the IQ MUX settings for the radio peripheral according to given subdev spec.
*