summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/types/tune.cpp18
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp35
-rw-r--r--host/lib/usrp/mboard_eeprom.cpp58
-rw-r--r--host/lib/usrp/tune_helper.cpp26
-rw-r--r--host/lib/usrp/usrp1/clock_ctrl.cpp14
-rw-r--r--host/lib/usrp/usrp1/mboard_impl.cpp4
-rw-r--r--host/lib/usrp/usrp1/usrp1_ctrl.cpp26
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp38
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.cpp23
-rw-r--r--host/lib/usrp/usrp_e100/clock_ctrl.cpp19
-rw-r--r--host/lib/usrp/usrp_e100/mboard_impl.cpp4
11 files changed, 201 insertions, 64 deletions
diff --git a/host/lib/types/tune.cpp b/host/lib/types/tune.cpp
index 601bc20e8..154f0990f 100644
--- a/host/lib/types/tune.cpp
+++ b/host/lib/types/tune.cpp
@@ -23,7 +23,7 @@ using namespace uhd;
tune_request_t::tune_request_t(double target_freq):
target_freq(target_freq),
- inter_freq_policy(POLICY_AUTO),
+ rf_freq_policy(POLICY_AUTO),
dsp_freq_policy(POLICY_AUTO)
{
/* NOP */
@@ -31,8 +31,8 @@ tune_request_t::tune_request_t(double target_freq):
tune_request_t::tune_request_t(double target_freq, double lo_off):
target_freq(target_freq),
- inter_freq_policy(POLICY_MANUAL),
- inter_freq(target_freq + lo_off),
+ rf_freq_policy(POLICY_MANUAL),
+ rf_freq(target_freq + lo_off),
dsp_freq_policy(POLICY_AUTO)
{
/* NOP */
@@ -41,12 +41,12 @@ tune_request_t::tune_request_t(double target_freq, double lo_off):
std::string tune_result_t::to_pp_string(void) const{
return str(boost::format(
"Tune Result:\n"
- " Target Intermediate Freq: %f (MHz)\n"
- " Actual Intermediate Freq: %f (MHz)\n"
- " Target DSP Freq Shift: %f (MHz)\n"
- " Actual DSP Freq Shift: %f (MHz)\n"
+ " Target RF Freq: %f (MHz)\n"
+ " Actual RF Freq: %f (MHz)\n"
+ " Target DSP Freq: %f (MHz)\n"
+ " Actual DSP Freq: %f (MHz)\n"
)
- % (target_inter_freq/1e6) % (actual_inter_freq/1e6)
- % (target_dsp_freq/1e6) % (actual_dsp_freq/1e6)
+ % (target_rf_freq/1e6) % (actual_rf_freq/1e6)
+ % (target_dsp_freq/1e6) % (actual_dsp_freq/1e6)
);
}
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
index 725b5cc03..231757365 100644
--- a/host/lib/usrp/dboard/db_rfx.cpp
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -121,6 +121,22 @@ private:
bool get_locked(dboard_iface::unit_t unit){
return (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0;
}
+
+ /*!
+ * Read the RSSI from the aux adc
+ * \return the rssi in dB
+ */
+ double get_rssi(void){
+ //RSSI from VAGC vs RF Power, Fig 34, pg 13
+ double max_power = -3.0;
+
+ //constants for the rssi calculation
+ static const double min_v = 0.35, max_v = 1.0;
+ static const double rssi_dyn_range = 60;
+ //calculate the rssi from the voltage
+ double voltage = this->get_iface()->read_aux_adc(dboard_iface::UNIT_RX, dboard_iface::AUX_ADC_B);
+ return max_power - rssi_dyn_range*(voltage - min_v)/(max_v - min_v);
+ }
};
/***********************************************************************
@@ -454,12 +470,19 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){
return;
case SUBDEV_PROP_SENSOR:
- UHD_ASSERT_THROW(key.name == "lo_locked");
- val = sensor_value_t("LO", this->get_locked(dboard_iface::UNIT_RX), "locked", "unlocked");
- return;
-
- case SUBDEV_PROP_SENSOR_NAMES:
- val = prop_names_t(1, "lo_locked");
+ if (key.name == "lo_locked")
+ val = sensor_value_t("LO", this->get_locked(dboard_iface::UNIT_RX), "locked", "unlocked");
+ else if ((key.name == "rssi") and (get_rx_id() != 0x0024))
+ val = sensor_value_t("RSSI", this->get_rssi(), "dBm");
+ else
+ UHD_THROW_INVALID_CODE_PATH();
+ return;
+
+ case SUBDEV_PROP_SENSOR_NAMES:{
+ prop_names_t names = list_of("lo_locked");
+ if (get_rx_id() != 0x0024) names.push_back("rssi");
+ val = names;
+ }
return;
case SUBDEV_PROP_BANDWIDTH:
diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp
index 869a38478..297de990f 100644
--- a/host/lib/usrp/mboard_eeprom.cpp
+++ b/host/lib/usrp/mboard_eeprom.cpp
@@ -23,6 +23,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include <algorithm>
+#include <iostream>
#include <cstddef>
using namespace uhd;
@@ -181,6 +182,7 @@ static const size_t B000_SERIAL_LEN = 8;
static const uhd::dict<std::string, boost::uint8_t> USRP_B000_OFFSETS = boost::assign::map_list_of
("serial", 0xf8)
("name", 0xf8 - NAME_MAX_LEN)
+ ("mcr", 0xf8 - NAME_MAX_LEN - sizeof(boost::uint32_t))
;
static void load_b000(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
@@ -193,6 +195,21 @@ static void load_b000(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
mb_eeprom["name"] = bytes_to_string(iface.read_eeprom(
B000_EEPROM_ADDR, USRP_B000_OFFSETS["name"], NAME_MAX_LEN
));
+
+ //extract master clock rate as a 32-bit uint in Hz
+ boost::uint32_t master_clock_rate;
+ const byte_vector_t rate_bytes = iface.read_eeprom(
+ B000_EEPROM_ADDR, USRP_B000_OFFSETS["mcr"], sizeof(master_clock_rate)
+ );
+ std::copy(
+ rate_bytes.begin(), rate_bytes.end(), //input
+ reinterpret_cast<boost::uint8_t *>(&master_clock_rate) //output
+ );
+ master_clock_rate = ntohl(master_clock_rate);
+ if (master_clock_rate > 1e6 and master_clock_rate < 1e9){
+ mb_eeprom["mcr"] = boost::lexical_cast<std::string>(master_clock_rate);
+ }
+ else mb_eeprom["mcr"] = "";
}
static void store_b000(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
@@ -207,6 +224,19 @@ static void store_b000(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
B000_EEPROM_ADDR, USRP_B000_OFFSETS["name"],
string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)
);
+
+ //store the master clock rate as a 32-bit uint in Hz
+ if (mb_eeprom.has_key("mcr")){
+ boost::uint32_t master_clock_rate = boost::uint32_t(boost::lexical_cast<double>(mb_eeprom["mcr"]));
+ master_clock_rate = htonl(master_clock_rate);
+ const byte_vector_t rate_bytes(
+ reinterpret_cast<const boost::uint8_t *>(&master_clock_rate),
+ reinterpret_cast<const boost::uint8_t *>(&master_clock_rate) + sizeof(master_clock_rate)
+ );
+ iface.write_eeprom(
+ B000_EEPROM_ADDR, USRP_B000_OFFSETS["mcr"], rate_bytes
+ );
+ }
}
/***********************************************************************
* Implementation of E100 load/store
@@ -222,7 +252,8 @@ struct e100_eeprom_map{
unsigned char env_var[16];
unsigned char env_setting[64];
unsigned char serial[10];
- unsigned char name[NAME_MAX_LEN];
+ unsigned char name[16];
+ unsigned char mcr[sizeof(float)];
};
template <typename T> static const byte_vector_t to_bytes(const T &item){
@@ -254,6 +285,20 @@ static void load_e100(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
load_e100_string_xx(env_setting);
load_e100_string_xx(serial);
load_e100_string_xx(name);
+
+ //extract the master clock rate
+ float master_clock_rate = 0;
+ const byte_vector_t rate_bytes = iface.read_eeprom(
+ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, mcr), sizeof(master_clock_rate)
+ );
+ std::copy(
+ rate_bytes.begin(), rate_bytes.end(), //source
+ reinterpret_cast<boost::uint8_t *>(&master_clock_rate) //destination
+ );
+ if (master_clock_rate > 1e6 and master_clock_rate < 1e9){
+ mb_eeprom["mcr"] = boost::lexical_cast<std::string>(master_clock_rate);
+ }
+ else mb_eeprom["mcr"] = "";
}
static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
@@ -289,6 +334,17 @@ static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
store_e100_string_xx(serial);
store_e100_string_xx(name);
+ //store the master clock rate
+ if (mb_eeprom.has_key("mcr")){
+ const float master_clock_rate = float(boost::lexical_cast<double>(mb_eeprom["mcr"]));
+ const byte_vector_t rate_bytes(
+ reinterpret_cast<const boost::uint8_t *>(&master_clock_rate),
+ reinterpret_cast<const boost::uint8_t *>(&master_clock_rate) + sizeof(master_clock_rate)
+ );
+ iface.write_eeprom(
+ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, mcr), rate_bytes
+ );
+ }
}
/***********************************************************************
diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp
index 9637301ad..264e6c04b 100644
--- a/host/lib/usrp/tune_helper.cpp
+++ b/host/lib/usrp/tune_helper.cpp
@@ -49,28 +49,28 @@ static tune_result_t tune_xx_subdev_and_dsp(
}
//------------------------------------------------------------------
- //-- set the intermediate frequency depending upon the IF policy
+ //-- set the RF frequency depending upon the policy
//------------------------------------------------------------------
- double target_inter_freq = 0.0;
- switch (tune_request.inter_freq_policy){
+ double target_rf_freq = 0.0;
+ switch (tune_request.rf_freq_policy){
case tune_request_t::POLICY_AUTO:
- target_inter_freq = tune_request.target_freq + lo_offset;
- subdev_freq_proxy = target_inter_freq;
+ target_rf_freq = tune_request.target_freq + lo_offset;
+ subdev_freq_proxy = target_rf_freq;
break;
case tune_request_t::POLICY_MANUAL:
- target_inter_freq = tune_request.inter_freq;
- subdev_freq_proxy = target_inter_freq;
+ target_rf_freq = tune_request.rf_freq;
+ subdev_freq_proxy = target_rf_freq;
break;
case tune_request_t::POLICY_NONE: break; //does not set
}
- double actual_inter_freq = subdev_freq_proxy.as<double>();
+ double actual_rf_freq = subdev_freq_proxy.as<double>();
//------------------------------------------------------------------
//-- calculate the dsp freq, only used with automatic policy
//------------------------------------------------------------------
- double target_dsp_freq = actual_inter_freq - tune_request.target_freq;
+ double target_dsp_freq = actual_rf_freq - tune_request.target_freq;
//invert the sign on the dsp freq given the following conditions
if (unit == dboard_iface::UNIT_TX) target_dsp_freq *= -1.0;
@@ -96,8 +96,8 @@ static tune_result_t tune_xx_subdev_and_dsp(
//-- load and return the tune result
//------------------------------------------------------------------
tune_result_t tune_result;
- tune_result.target_inter_freq = target_inter_freq;
- tune_result.actual_inter_freq = actual_inter_freq;
+ tune_result.target_rf_freq = target_rf_freq;
+ tune_result.actual_rf_freq = actual_rf_freq;
tune_result.target_dsp_freq = target_dsp_freq;
tune_result.actual_dsp_freq = actual_dsp_freq;
return tune_result;
@@ -107,13 +107,13 @@ static double derive_freq_from_xx_subdev_and_dsp(
dboard_iface::unit_t unit, wax::obj subdev, wax::obj dsp
){
//extract actual dsp and IF frequencies
- double actual_inter_freq = subdev[SUBDEV_PROP_FREQ].as<double>();
+ double actual_rf_freq = subdev[SUBDEV_PROP_FREQ].as<double>();
double actual_dsp_freq = dsp[DSP_PROP_FREQ_SHIFT].as<double>();
//invert the sign on the dsp freq given the following conditions
if (unit == dboard_iface::UNIT_TX) actual_dsp_freq *= -1.0;
- return actual_inter_freq - actual_dsp_freq;
+ return actual_rf_freq - actual_dsp_freq;
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp1/clock_ctrl.cpp b/host/lib/usrp/usrp1/clock_ctrl.cpp
index df5353b54..154e6a316 100644
--- a/host/lib/usrp/usrp1/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp1/clock_ctrl.cpp
@@ -16,6 +16,9 @@
//
#include "clock_ctrl.hpp"
+#include <boost/lexical_cast.hpp>
+#include <boost/format.hpp>
+#include <iostream>
using namespace uhd;
@@ -31,6 +34,17 @@ class usrp1_clock_ctrl_impl : public usrp1_clock_ctrl {
public:
usrp1_clock_ctrl_impl(usrp1_iface::sptr iface): _iface(iface){
this->set_master_clock_freq(default_master_clock_rate);
+ try{
+ if (not _iface->mb_eeprom["mcr"].empty()){
+ std::cout << "Read FPGA clock rate from EEPROM setting." << std::endl;
+ const double master_clock_rate = boost::lexical_cast<double>(_iface->mb_eeprom["mcr"]);
+ std::cout << boost::format("Initializing FPGA clock to %fMHz...") % (master_clock_rate/1e6) << std::endl;
+ this->set_master_clock_freq(master_clock_rate);
+ }
+ }
+ catch(const std::exception &e){
+ std::cerr << "Error setting FPGA clock rate from EEPROM: " << e.what() << std::endl;
+ }
}
void set_master_clock_freq(double freq){
diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp
index 870956568..eecae3fa7 100644
--- a/host/lib/usrp/usrp1/mboard_impl.cpp
+++ b/host/lib/usrp/usrp1/mboard_impl.cpp
@@ -378,6 +378,10 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)
return;
case MBOARD_PROP_CLOCK_RATE:
+ std::cerr << "Helpful message:" << std::endl;
+ std::cerr << " I see that you are setting the master clock rate from the API." << std::endl;
+ std::cerr << " You may find it more convenient to burn this setting into the EEPROM." << std::endl;
+ std::cerr << " See the application notes for USRP1 for further instructions." << std::endl;
_clock_ctrl->set_master_clock_freq(val.as<double>());
return;
diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.cpp b/host/lib/usrp/usrp1/usrp1_ctrl.cpp
index 22e9fd1ce..c6be28f5f 100644
--- a/host/lib/usrp/usrp1/usrp1_ctrl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_ctrl.cpp
@@ -201,18 +201,19 @@ public:
}
void usrp_init(void){
- /* not calling because this causes junk to come at init
- * and it does not seem to be necessary to call anyway
+ //disable
usrp_rx_enable(false);
- usrp_rx_reset(true);
- usrp_rx_reset(false);
- usrp_rx_enable(true);
- */
-
usrp_tx_enable(false);
+
+ //toggle resets
+ usrp_rx_reset(true);
usrp_tx_reset(true);
+ usrp_rx_reset(false);
usrp_tx_reset(false);
- usrp_tx_enable(true);
+
+ //enable
+ //usrp_rx_enable(true); //dont enable, enable means dont work
+ //usrp_tx_enable(true);
}
void usrp_load_fpga(std::string filestring)
@@ -234,6 +235,8 @@ public:
throw uhd::io_error("usrp_load_fpga: cannot open fpga input file");
}
+ usrp_fpga_reset(true); //holding the fpga in reset while loading
+
if (usrp_control_write_cmd(VRQ_FPGA_LOAD, 0, FL_BEGIN) < 0) {
throw uhd::io_error("usrp_load_fpga: fpga load error");
}
@@ -252,6 +255,9 @@ public:
}
usrp_set_fpga_hash(hash);
+
+ usrp_fpga_reset(false); //done loading, take fpga out of reset
+
file.close();
if (load_img_msg) std::cout << " done" << std::endl;
}
@@ -355,6 +361,10 @@ public:
UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RX_RESET, on, 0) >= 0);
}
+ void usrp_fpga_reset(bool on)
+ {
+ UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RESET, on, 0) >= 0);
+ }
int usrp_control_write(boost::uint8_t request,
boost::uint16_t value,
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 7705037dd..8582fca38 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -194,9 +194,25 @@ usrp2_mboard_impl::~usrp2_mboard_impl(void){
void usrp2_mboard_impl::update_clock_config(void){
boost::uint32_t pps_flags = 0;
+ //slave mode overrides clock config settings
+ if (not _mimo_clocking_mode_is_master){
+ _clock_config.ref_source = clock_config_t::REF_MIMO;
+ _clock_config.pps_source = clock_config_t::PPS_MIMO;
+ }
+
//translate pps source enums
switch(_clock_config.pps_source){
- case clock_config_t::PPS_SMA: pps_flags |= U2_FLAG_TIME64_PPS_SMA; break;
+ case clock_config_t::PPS_MIMO:
+ _iface->poke32(_iface->regs.time64_mimo_sync,
+ (1 << 8) | (mimo_clock_sync_delay_cycles & 0xff)
+ );
+ break;
+
+ case clock_config_t::PPS_SMA:
+ _iface->poke32(_iface->regs.time64_mimo_sync, 0);
+ pps_flags |= U2_FLAG_TIME64_PPS_SMA;
+ break;
+
default: throw uhd::value_error("unhandled clock configuration pps source");
}
@@ -217,6 +233,7 @@ void usrp2_mboard_impl::update_clock_config(void){
switch(_clock_config.ref_source){
case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x12); break;
case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break;
+ case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break;
default: throw uhd::value_error("unhandled clock configuration reference source");
}
_clock_ctrl->enable_external_ref(true); //USRP2P has an internal 10MHz TCXO
@@ -227,6 +244,7 @@ void usrp2_mboard_impl::update_clock_config(void){
switch(_clock_config.ref_source){
case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x10); break;
case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break;
+ case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break;
default: throw uhd::value_error("unhandled clock configuration reference source");
}
_clock_ctrl->enable_external_ref(_clock_config.ref_source != clock_config_t::REF_INT);
@@ -235,12 +253,11 @@ void usrp2_mboard_impl::update_clock_config(void){
case usrp2_iface::USRP_NXXX: break;
}
- //Handle the serdes clocking based on master/slave mode:
- // - Masters always drive the clock over serdes.
- // - Slaves always lock to this serdes clock.
- // - Slaves lock their time over the serdes.
+ //masters always drive the clock over serdes
+ _clock_ctrl->enable_mimo_clock_out(_mimo_clocking_mode_is_master);
+
+ //set the mimo clock delay over the serdes
if (_mimo_clocking_mode_is_master){
- _clock_ctrl->enable_mimo_clock_out(true);
switch(_iface->get_rev()){
case usrp2_iface::USRP_N200:
case usrp2_iface::USRP_N210:
@@ -253,15 +270,6 @@ void usrp2_mboard_impl::update_clock_config(void){
default: break; //not handled
}
- _iface->poke32(_iface->regs.time64_mimo_sync, 0);
- }
- else{
- _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15);
- _clock_ctrl->enable_external_ref(true);
- _clock_ctrl->enable_mimo_clock_out(false);
- _iface->poke32(_iface->regs.time64_mimo_sync,
- (1 << 8) | (mimo_clock_sync_delay_cycles & 0xff)
- );
}
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp
index 2d1f901d7..9c3fb9268 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.cpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.cpp
@@ -165,7 +165,7 @@ struct mtu_result_t{
size_t recv_mtu, send_mtu;
};
-static mtu_result_t determine_mtu(const std::string &addr){
+static mtu_result_t determine_mtu(const std::string &addr, const mtu_result_t &user_mtu){
udp_simple::sptr udp_sock = udp_simple::make_connected(
addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT)
);
@@ -173,8 +173,8 @@ static mtu_result_t determine_mtu(const std::string &addr){
//The FPGA offers 4K buffers, and the user may manually request this.
//However, multiple simultaneous receives (2DSP slave + 2DSP master),
//require that buffering to be used internally, and this is a safe setting.
- boost::uint8_t buffer[2000];
- usrp2_ctrl_data_t *ctrl_data = reinterpret_cast<usrp2_ctrl_data_t *>(buffer);
+ std::vector<boost::uint8_t> buffer(std::max(user_mtu.recv_mtu, user_mtu.send_mtu));
+ usrp2_ctrl_data_t *ctrl_data = reinterpret_cast<usrp2_ctrl_data_t *>(&buffer.front());
static const double echo_timeout = 0.020; //20 ms
//test holler - check if its supported in this fw version
@@ -186,8 +186,8 @@ static mtu_result_t determine_mtu(const std::string &addr){
if (ntohl(ctrl_data->id) != USRP2_CTRL_ID_HOLLER_BACK_DUDE)
throw uhd::not_implemented_error("holler protocol not implemented");
- size_t min_recv_mtu = sizeof(usrp2_ctrl_data_t), max_recv_mtu = sizeof(buffer);
- size_t min_send_mtu = sizeof(usrp2_ctrl_data_t), max_send_mtu = sizeof(buffer);
+ size_t min_recv_mtu = sizeof(usrp2_ctrl_data_t), max_recv_mtu = user_mtu.recv_mtu;
+ size_t min_send_mtu = sizeof(usrp2_ctrl_data_t), max_send_mtu = user_mtu.send_mtu;
while (min_recv_mtu < max_recv_mtu){
@@ -248,19 +248,20 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){
device_addrs_t device_args = separate_device_addr(device_addr);
+ //extract the user's requested MTU size or default
+ mtu_result_t user_mtu;
+ user_mtu.recv_mtu = size_t(device_addr.cast<double>("recv_frame_size", udp_simple::mtu));
+ user_mtu.send_mtu = size_t(device_addr.cast<double>("recv_frame_size", udp_simple::mtu));
+
try{
//calculate the minimum send and recv mtu of all devices
- mtu_result_t mtu = determine_mtu(device_args[0]["addr"]);
+ mtu_result_t mtu = determine_mtu(device_args[0]["addr"], user_mtu);
for (size_t i = 1; i < device_args.size(); i++){
- mtu_result_t mtu_i = determine_mtu(device_args[i]["addr"]);
+ mtu_result_t mtu_i = determine_mtu(device_args[i]["addr"], user_mtu);
mtu.recv_mtu = std::min(mtu.recv_mtu, mtu_i.recv_mtu);
mtu.send_mtu = std::min(mtu.send_mtu, mtu_i.send_mtu);
}
- //use the discovered mtu or clip the users requested mtu
- mtu.recv_mtu = std::min(size_t(device_addr.cast<double>("recv_frame_size", 9000)), mtu.recv_mtu);
- mtu.send_mtu = std::min(size_t(device_addr.cast<double>("send_frame_size", 9000)), mtu.send_mtu);
-
device_addr["recv_frame_size"] = boost::lexical_cast<std::string>(mtu.recv_mtu);
device_addr["send_frame_size"] = boost::lexical_cast<std::string>(mtu.send_mtu);
diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp
index 1ac2b804c..2e3eb5cb9 100644
--- a/host/lib/usrp/usrp_e100/clock_ctrl.cpp
+++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp
@@ -184,7 +184,24 @@ public:
this->use_internal_ref();
- this->set_fpga_clock_rate(DEFAULT_OUTPUT_RATE); //initialize to something
+ //initialize the FPGA clock to something
+ bool fpga_clock_initialized = false;
+ try{
+ if (not _iface->mb_eeprom["mcr"].empty()){
+ std::cout << "Read FPGA clock rate from EEPROM setting." << std::endl;
+ const double master_clock_rate = boost::lexical_cast<double>(_iface->mb_eeprom["mcr"]);
+ std::cout << boost::format("Initializing FPGA clock to %fMHz...") % (master_clock_rate/1e6) << std::endl;
+ this->set_fpga_clock_rate(master_clock_rate);
+ fpga_clock_initialized = true;
+ }
+ }
+ catch(const std::exception &e){
+ std::cerr << "Error setting FPGA clock rate from EEPROM: " << e.what() << std::endl;
+ }
+ if (not fpga_clock_initialized){ //was not set... use the default rate
+ std::cout << boost::format("Initializing FPGA clock to %fMHz...") % (DEFAULT_OUTPUT_RATE/1e6) << std::endl;
+ this->set_fpga_clock_rate(DEFAULT_OUTPUT_RATE);
+ }
this->enable_test_clock(ENABLE_THE_TEST_OUT);
this->enable_rx_dboard_clock(false);
diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp
index 29e3c5da2..5f4a208d3 100644
--- a/host/lib/usrp/usrp_e100/mboard_impl.cpp
+++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp
@@ -207,6 +207,10 @@ void usrp_e100_impl::mboard_set(const wax::obj &key, const wax::obj &val){
return;
case MBOARD_PROP_CLOCK_RATE:
+ std::cerr << "Helpful message:" << std::endl;
+ std::cerr << " I see that you are setting the master clock rate from the API." << std::endl;
+ std::cerr << " You may find it more convenient to burn this setting into the EEPROM." << std::endl;
+ std::cerr << " See the application notes for USRP-E1XX for further instructions." << std::endl;
_clock_ctrl->set_fpga_clock_rate(val.as<double>());
return;