aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/usrp3/x300/x300_main.c37
-rw-r--r--host/CMakeLists.txt4
-rw-r--r--host/cmake/debian/changelog23
-rw-r--r--host/docs/usrp_e3x0.dox1
-rw-r--r--host/lib/experts/expert_container.cpp4
-rwxr-xr-xhost/lib/ic_reg_maps/gen_adf5355_regs.py8
-rw-r--r--host/lib/usrp/common/adf5355.cpp45
-rw-r--r--host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp2
-rw-r--r--host/lib/usrp/device3/device3_io_impl.cpp1
-rw-r--r--host/lib/usrp/gps_ctrl.cpp10
-rw-r--r--host/lib/usrp/x300/x300_fw_uart.cpp33
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp31
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp5
-rw-r--r--host/lib/usrp/x300/x300_radio_ctrl_impl.cpp11
-rw-r--r--host/utils/query_gpsdo_sensors.cpp99
15 files changed, 184 insertions, 130 deletions
diff --git a/firmware/usrp3/x300/x300_main.c b/firmware/usrp3/x300/x300_main.c
index c5e4fc88a..459f7b0b1 100644
--- a/firmware/usrp3/x300/x300_main.c
+++ b/firmware/usrp3/x300/x300_main.c
@@ -217,30 +217,28 @@ void handle_udp_mtu_detect(
/***********************************************************************
* Deal with host claims and claim timeout
**********************************************************************/
-static void handle_claim(void)
+static void handle_claim(uint32_t ticks_now)
{
+ static const uint32_t CLAIM_TIMEOUT = 2*CPU_CLOCK; // 2 seconds
+ static uint32_t ticks_last_claim = 0;
static uint32_t last_time = 0;
- static size_t timeout = 0;
- //time is 0 if the claim was forfeit
- if (shmem[X300_FW_SHMEM_CLAIM_TIME] == 0)
+ // Claim status can only change if the claim is active or the claim is renewed.
+ if (shmem[X300_FW_SHMEM_CLAIM_STATUS] != 0 &&
+ (shmem[X300_FW_SHMEM_CLAIM_TIME] == 0 ||
+ ticks_now - ticks_last_claim > CLAIM_TIMEOUT))
{
- shmem[X300_FW_SHMEM_CLAIM_STATUS] = 0;
+ // the claim was released or timed out
+ shmem[X300_FW_SHMEM_CLAIM_STATUS] = 0;
+ last_time = shmem[X300_FW_SHMEM_CLAIM_TIME];
}
- //if the time changes, reset timeout
else if (last_time != shmem[X300_FW_SHMEM_CLAIM_TIME])
{
+ // claim was renewed
shmem[X300_FW_SHMEM_CLAIM_STATUS] = 1;
- timeout = 0;
+ last_time = shmem[X300_FW_SHMEM_CLAIM_TIME];
+ ticks_last_claim = ticks_now;
}
- //otherwise increment for timeout
- else timeout++;
-
- //always stash the last seen time
- last_time = shmem[X300_FW_SHMEM_CLAIM_TIME];
-
- //the claim has timed out after 2 seconds
- if (timeout > 200) shmem[X300_FW_SHMEM_CLAIM_STATUS] = 0;
}
/***********************************************************************
@@ -419,8 +417,14 @@ int main(void)
while(true)
{
- //jobs that happen once every 10ms
const uint32_t ticks_now = wb_peek32(SR_ADDR(RB0_BASE, RB_COUNTER));
+
+ // handle the claim every time because any packet processed could
+ // have claimed or released the device and we want the claim status
+ // to be updated immediately to make it atomic from the host perspective
+ handle_claim(ticks_now);
+
+ //jobs that happen once every 10ms
const uint32_t ticks_passed = ticks_now - last_cronjob;
static const uint32_t tick_delta = CPU_CLOCK/100;
if (ticks_passed > tick_delta)
@@ -428,7 +432,6 @@ int main(void)
poll_sfpp_status(0); // Every so often poll XGE Phy to look for SFP+ hotplug events.
poll_sfpp_status(1); // Every so often poll XGE Phy to look for SFP+ hotplug events.
//handle_link_state(); //deal with router table update
- handle_claim(); //deal with the host claim register
update_leds(); //run the link and activity leds
garp(); //send periodic garps
last_cronjob = ticks_now;
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt
index 40c92b856..a7274a451 100644
--- a/host/CMakeLists.txt
+++ b/host/CMakeLists.txt
@@ -357,8 +357,8 @@ UHD_INSTALL(FILES
#{{{IMG_SECTION
# This section is written automatically by /images/create_imgs_package.py
# Any manual changes in here will be overwritten.
-SET(UHD_IMAGES_MD5SUM "9641027408a4bbd478ad221d3dae1cfd")
-SET(UHD_IMAGES_DOWNLOAD_SRC "uhd-images_003.010.001.001-rc1.zip")
+SET(UHD_IMAGES_MD5SUM "e5ac0830665a6c77a46ba0ae32f9fa11")
+SET(UHD_IMAGES_DOWNLOAD_SRC "uhd-images_003.010.001.001-release.zip")
#}}}
########################################################################
diff --git a/host/cmake/debian/changelog b/host/cmake/debian/changelog
index 94ee3885a..5dea31b00 100644
--- a/host/cmake/debian/changelog
+++ b/host/cmake/debian/changelog
@@ -1,3 +1,26 @@
+uhd (3.10.1.1-0ubuntu1) trusty; urgency=low
+
+ - Docs: The protocol for Gen-3 devices is now consistently referred to as CHDR.
+ - X300: Fixed EEPROM corruption bug (happened when two processes would access
+ find routines on the same device at the same time). Improved initialization
+ time. CE clock is now 214 MHz. Fixed channel list generation. Find routines
+ now more lenient in case one devices fails (others can still be found then).
+ Improve PCIe behaviour. Fix timed commands for non-TwinRX dboards. Improve
+ AXI Interconnect (faster, improved build timing).
+ - N230: Use second_addr (like X300).
+ - C API: Added UHD_VERSION macro. Fixed online rate change.
+ - Utils: Minor fixes to uhd_images_downloader.
+ - Build/CMake: Fixed some Py3k build issues. Fixed many compiler warnings. Allow
+ to specify package names.
+ - RFNoC: Fixed sampling rate mismatch error. Noc-Shell uses a non-cascaded 2-clk
+ FIFO. Increase default FIFO sizes on DUC and DDC blocks.
+ - UBX: Force on RX driver to eliminate transient.
+ - Transport code: Fixed memory leak.
+ - FPGA repository: Merged usrp3_rfnoc and usrp3 directories again. Cleaned up
+ superfluous files. Clean separation between Gen-3 and other devices in usrp3.
+
+ -- Ettus Research <packages@ettus.com> Thu, 26 Jan 2017 04:15:56 -0800
+
uhd (3.10.1.0-0ubuntu1) trusty; urgency=low
- Fixed multiple compiler warnings
diff --git a/host/docs/usrp_e3x0.dox b/host/docs/usrp_e3x0.dox
index 470f6a26b..929b9f635 100644
--- a/host/docs/usrp_e3x0.dox
+++ b/host/docs/usrp_e3x0.dox
@@ -18,7 +18,6 @@
- FPGA Capabilities:
- 2 RX DDC chains in FPGA
- 2 TX DUC chain in FPGA
- - Timed commands in FPGA
- Timed sampling in FPGA
- 16-bit fixed point sample mode (sc16)
diff --git a/host/lib/experts/expert_container.cpp b/host/lib/experts/expert_container.cpp
index b9c78f9f5..853e3e4b7 100644
--- a/host/lib/experts/expert_container.cpp
+++ b/host/lib/experts/expert_container.cpp
@@ -100,7 +100,7 @@ public:
{
boost::lock_guard<boost::recursive_mutex> resolve_lock(_resolve_mutex);
boost::lock_guard<boost::mutex> lock(_mutex);
- EX_LOG(0, str(boost::format("resolve_from(%s)") % node_name));
+ EX_LOG(0, "resolve_from (overridden to resolve_all)");
// Do a full resolve of the graph
// Not optimizing the traversal using node_name to reduce experts complexity
_resolve_helper("", "", false);
@@ -110,7 +110,7 @@ public:
{
boost::lock_guard<boost::recursive_mutex> resolve_lock(_resolve_mutex);
boost::lock_guard<boost::mutex> lock(_mutex);
- EX_LOG(0, str(boost::format("resolve_to(%s)") % node_name));
+ EX_LOG(0, "resolve_to (overridden to resolve_all)");
// Do a full resolve of the graph
// Not optimizing the traversal using node_name to reduce experts complexity
_resolve_helper("", "", false);
diff --git a/host/lib/ic_reg_maps/gen_adf5355_regs.py b/host/lib/ic_reg_maps/gen_adf5355_regs.py
index 9644f2e53..a69f126cc 100755
--- a/host/lib/ic_reg_maps/gen_adf5355_regs.py
+++ b/host/lib/ic_reg_maps/gen_adf5355_regs.py
@@ -26,7 +26,7 @@ REGS_TMPL="""\
########################################################################
int_16_bit 0[4:19] 0
prescaler 0[20] 0 4_5, 8_9
-autocal_en 0[21] 0 disabled, enabled
+autocal_en 0[21] 1 disabled, enabled
reg0_reserved0 0[22:31] 0x000
########################################################################
## address 1
@@ -53,13 +53,13 @@ counter_reset 4[4] 0 disabled, enabled
cp_three_state 4[5] 0 disabled, enabled
power_down 4[6] 0 disabled, enabled
pd_polarity 4[7] 1 negative, positive
-mux_logic 4[8] 0 1_8V, 3_3V
+mux_logic 4[8] 1 1_8V, 3_3V
ref_mode 4[9] 0 single, diff
<% current_setting_enums = ', '.join(map(lambda x: '_'.join(("%0.2fma"%(round(x*31.27 + 31.27)/100)).split('.')), range(0,16))) %>\
charge_pump_current 4[10:13] 0 ${current_setting_enums}
double_buff_div 4[14] 0 disabled, enabled
r_counter_10_bit 4[15:24] 0
-reference_divide_by_2 4[25] 1 disabled, enabled
+reference_divide_by_2 4[25] 0 disabled, enabled
reference_doubler 4[26] 0 disabled, enabled
muxout 4[27:29] 1 3state, dvdd, dgnd, rdiv, ndiv, analog_ld, dld, reserved
reg4_reserved0 4[30:31] 0
@@ -91,7 +91,7 @@ frac_n_ld_precision 7[5:6] 0 5ns, 6ns, 8ns, 12ns
loss_of_lock_mode 7[7] 0 disabled, enabled
ld_cyc_count 7[8:9] 0 1024, 2048, 4096, 8192
reg7_reserved0 7[10:24] 0x0
-le_sync 7[25] 0 disabled, le_synced_to_refin
+le_sync 7[25] 1 disabled, le_synced_to_refin
reg7_reserved1 7[26:31] 0x4
########################################################################
## address 8
diff --git a/host/lib/usrp/common/adf5355.cpp b/host/lib/usrp/common/adf5355.cpp
index ee9d1d1d9..e3fd66bc2 100644
--- a/host/lib/usrp/common/adf5355.cpp
+++ b/host/lib/usrp/common/adf5355.cpp
@@ -62,43 +62,14 @@ public:
_pfd_freq(0.0),
_fb_after_divider(false)
{
- _regs.counter_reset = adf5355_regs_t::COUNTER_RESET_DISABLED;
- _regs.cp_three_state = adf5355_regs_t::CP_THREE_STATE_DISABLED;
- _regs.power_down = adf5355_regs_t::POWER_DOWN_DISABLED;
- _regs.pd_polarity = adf5355_regs_t::PD_POLARITY_POSITIVE;
- _regs.mux_logic = adf5355_regs_t::MUX_LOGIC_3_3V;
- _regs.ref_mode = adf5355_regs_t::REF_MODE_SINGLE;
- _regs.muxout = adf5355_regs_t::MUXOUT_DLD;
- _regs.double_buff_div = adf5355_regs_t::DOUBLE_BUFF_DIV_DISABLED;
-
- _regs.rf_out_a_enabled = adf5355_regs_t::RF_OUT_A_ENABLED_ENABLED;
- _regs.rf_out_b_enabled = adf5355_regs_t::RF_OUT_B_ENABLED_DISABLED;
- _regs.mute_till_lock_detect = adf5355_regs_t::MUTE_TILL_LOCK_DETECT_MUTE_DISABLED;
- _regs.ld_mode = adf5355_regs_t::LD_MODE_FRAC_N;
- _regs.frac_n_ld_precision = adf5355_regs_t::FRAC_N_LD_PRECISION_5NS;
- _regs.ld_cyc_count = adf5355_regs_t::LD_CYC_COUNT_1024;
- _regs.le_sync = adf5355_regs_t::LE_SYNC_LE_SYNCED_TO_REFIN;
- _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED;
- _regs.reference_divide_by_2 = adf5355_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
- _regs.reference_doubler = adf5355_regs_t::REFERENCE_DOUBLER_DISABLED;
- _regs.autocal_en = adf5355_regs_t::AUTOCAL_EN_ENABLED;
- _regs.prescaler = adf5355_regs_t::PRESCALER_4_5;
+ // TODO This is a hardware specific value, but can be made the default in the ic_reg_map
_regs.charge_pump_current = adf5355_regs_t::CHARGE_PUMP_CURRENT_0_94MA;
- _regs.gated_bleed = adf5355_regs_t::GATED_BLEED_DISABLED;
- _regs.negative_bleed = adf5355_regs_t::NEGATIVE_BLEED_ENABLED;
- _regs.feedback_select = adf5355_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
- _regs.output_power = adf5355_regs_t::OUTPUT_POWER_5DBM;
+ // TODO cleanup these magic numbers
_regs.cp_bleed_current = 2;
_regs.r_counter_10_bit = 8;
-
- _regs.ld_cyc_count = adf5355_regs_t::LD_CYC_COUNT_1024;
- _regs.loss_of_lock_mode = adf5355_regs_t::LOSS_OF_LOCK_MODE_DISABLED;
- _regs.frac_n_ld_precision = adf5355_regs_t::FRAC_N_LD_PRECISION_5NS;
- _regs.ld_mode = adf5355_regs_t::LD_MODE_FRAC_N;
-
_regs.vco_band_div = 3;
_regs.timeout = 11;
_regs.auto_level_timeout = 30;
@@ -108,6 +79,14 @@ public:
_regs.adc_conversion = adf5355_regs_t::ADC_CONVERSION_ENABLED;
_regs.adc_enable = adf5355_regs_t::ADC_ENABLE_ENABLED;
+
+ // TODO Needs to be enabled for phase resync
+ _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED;
+
+ // TODO Default should be divided, but there seems to be a bug preventing that. Needs rechecking
+ _regs.feedback_select = adf5355_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
+
+ // TODO 0 is an invalid value for this field. Setting to 1 seemed to break phase sync, needs retesting.
_regs.phase_resync_clk_div = 0;
}
@@ -193,7 +172,9 @@ public:
//-----------------------------------------------------------
//Phase resync
- _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED; // Disabled during development
+ // TODO Renable here, in initialization, or through separate set_phase_resync(bool enable) function
+ _regs.phase_resync = adf5355_regs_t::PHASE_RESYNC_DISABLED;
+
_regs.phase_adjust = adf5355_regs_t::PHASE_ADJUST_DISABLED;
_regs.sd_load_reset = adf5355_regs_t::SD_LOAD_RESET_ON_REG0_UPDATE;
_regs.phase_resync_clk_div = static_cast<uint16_t>(
diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp
index dfbea9917..346f39589 100644
--- a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp
+++ b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp
@@ -106,6 +106,8 @@ public:
_config_lo2_route(i==0?LO_CONFIG_CH1:LO_CONFIG_CH2);
_lo1_iface[i]->set_output_power(adf5355_iface::OUTPUT_POWER_5DBM);
_lo1_iface[i]->set_reference_freq(TWINRX_DESIRED_REFERENCE_FREQ);
+ // Divided feedback did not appear to be correctly implemented during bringup. Necessary for phase resync
+// _lo1_iface[i]->set_feedback_select(adf5355_iface::FB_SEL_DIVIDED);
_lo1_iface[i]->set_muxout_mode(adf5355_iface::MUXOUT_DLD);
_lo1_iface[i]->set_frequency(3e9, 1.0e3);
_lo2_iface[i]->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED);
diff --git a/host/lib/usrp/device3/device3_io_impl.cpp b/host/lib/usrp/device3/device3_io_impl.cpp
index bb98b1031..2f2e778c9 100644
--- a/host/lib/usrp/device3/device3_io_impl.cpp
+++ b/host/lib/usrp/device3/device3_io_impl.cpp
@@ -808,6 +808,7 @@ tx_streamer::sptr device3_impl::get_tx_stream(const uhd::stream_args_t &args_)
)
);
+ blk_ctrl->sr_write(uhd::rfnoc::SR_CLEAR_RX_FC, 0xc1ea12, block_port);
blk_ctrl->sr_write(uhd::rfnoc::SR_RESP_IN_DST_SID, xport.recv_sid.get_dst(), block_port);
UHD_STREAMER_LOG() << "[TX Streamer] resp_in_dst_sid == " << boost::format("0x%04X") % xport.recv_sid.get_dst() << std::endl;
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index 28f5a28cd..f4a42af34 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -92,7 +92,7 @@ private:
sentences[which].get<2>() = true;
}
} catch(std::exception &e) {
- UHD_MSG(warning) << "get_sentence: " << e.what();
+ UHD_LOGV(often) << "get_sentence: " << e.what();
}
if (not sentence.empty() or now > exit_time)
@@ -134,7 +134,7 @@ private:
}
void update_cache() {
- if(not gps_detected() or (_gps_type != GPS_TYPE_INTERNAL_GPSDO)) {
+ if(not gps_detected()) {
return;
}
@@ -352,11 +352,11 @@ private:
return gps_time;
} catch(std::exception &e) {
- UHD_MSG(warning) << "get_time: " << e.what();
+ UHD_LOGV(often) << "get_time: " << e.what();
error_cnt++;
}
}
- throw uhd::value_error("Timeout after no valid message found");
+ throw uhd::value_error("get_time: Timeout after no valid message found");
return gps_time; //keep gcc from complaining
}
@@ -379,7 +379,7 @@ private:
else
return (get_token(reply, 6) != "0");
} catch(std::exception &e) {
- UHD_MSG(warning) << "locked: " << e.what();
+ UHD_LOGV(often) << "locked: " << e.what();
error_cnt++;
}
}
diff --git a/host/lib/usrp/x300/x300_fw_uart.cpp b/host/lib/usrp/x300/x300_fw_uart.cpp
index 6e7425c4d..a2cbcc908 100644
--- a/host/lib/usrp/x300/x300_fw_uart.cpp
+++ b/host/lib/usrp/x300/x300_fw_uart.cpp
@@ -76,8 +76,9 @@ struct x300_uart_iface : uart_iface
if (rxoffset == _last_device_rxoffset)
return -1;
+ int ret = static_cast<int>(_rxcache[((rxoffset)/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF);
rxoffset++;
- return static_cast<int>(_rxcache[(rxoffset/4) % poolsize] >> ((rxoffset%4)*8) & 0xFF);
+ return ret;
}
void update_cache(void)
@@ -91,30 +92,42 @@ struct x300_uart_iface : uart_iface
{
// all the data is new - reload the entire cache
for (uint32_t i = 0; i < poolsize; i++)
+ {
_rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i));
+ }
+
+ // set the head to the same character as the current device
+ // offset (tail) one loop earlier
+ rxoffset = device_rxoffset - (poolsize*4);
+
+ // set the tail to the current device offset
+ _last_device_rxoffset = device_rxoffset;
- // 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;
+ // the string at the head is a partial, so skip it
+ for (int c = getchar(); c != '\n' and c != -1; c = getchar()) {}
- // clear the partial string in the buffer;
+ // clear the partial string in the buffer, if any
_rxbuff.clear();
}
else if (rxoffset == _last_device_rxoffset)
{
// new data was added - refresh the portion of the cache that was updated
- for (uint32_t i = ((_last_device_rxoffset+1)/4) % poolsize; i != (((device_rxoffset)/4)+1) % poolsize; i = (i+1) % poolsize)
+ for (uint32_t i = (_last_device_rxoffset/4) % poolsize;
+ i != ((device_rxoffset/4)+1) % poolsize;
+ i = (i+1) % poolsize)
{
_rxcache[i] = _iface->peek32(SR_ADDR(rxpool, i));
}
- } else {
+
+ // set the tail to the current device offset
+ _last_device_rxoffset = device_rxoffset;
+ }
+ 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;
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 8164c79b6..aa54c2228 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -1529,13 +1529,32 @@ void x300_impl::claimer_loop(wb_iface::sptr iface)
x300_impl::claim_status_t x300_impl::claim_status(wb_iface::sptr iface)
{
- //If timed out, then device is definitely unclaimed
- if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0)
- return UNCLAIMED;
+ claim_status_t claim_status = CLAIMED_BY_OTHER; // Default to most restrictive
+ boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::seconds(1);
+ while (boost::get_system_time() < timeout_time)
+ {
+ //If timed out, then device is definitely unclaimed
+ if (iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_STATUS)) == 0)
+ {
+ claim_status = UNCLAIMED;
+ break;
+ }
- //otherwise check claim src to determine if another thread with the same src has claimed the device
- uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC));
- return (hash == get_process_hash() ? CLAIMED_BY_US : CLAIMED_BY_OTHER);
+ //otherwise check claim src to determine if another thread with the same src has claimed the device
+ uint32_t hash = iface->peek32(X300_FW_SHMEM_ADDR(X300_FW_SHMEM_CLAIM_SRC));
+ if (hash == 0)
+ {
+ // A non-zero claim status and an empty hash means the claim might
+ // be in the process of being released. This is possible because
+ // older firmware takes a long time to update the status. Wait and
+ // check status again.
+ boost::this_thread::sleep(boost::posix_time::milliseconds(5));
+ continue;
+ }
+ claim_status = (hash == get_process_hash() ? CLAIMED_BY_US : CLAIMED_BY_OTHER);
+ break;
+ }
+ return claim_status;
}
void x300_impl::claim(wb_iface::sptr iface)
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 55b055d44..d082ab76a 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -54,10 +54,7 @@ static const size_t X300_RX_SW_BUFF_SIZE_ETH_MACOS = 0x100000; //1Mib
//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
-// This is a temporary solution: We're throttling PCIe MTU to avoid
-// underruns on Tx. Once we solve it on the FPGA side, need revert this commit.
-static const size_t X300_PCIE_TX_DATA_FRAME_SIZE = 3000; //bytes
+static const size_t X300_PCIE_TX_DATA_FRAME_SIZE = 8184; //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 = 64;
diff --git a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
index f4ad0d035..9bf61f998 100644
--- a/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
+++ b/host/lib/usrp/x300/x300_radio_ctrl_impl.cpp
@@ -126,8 +126,7 @@ UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(x300_radio_ctrl)
// Bind the daughterboard command time to the motherboard level property
////////////////////////////////////////////////////////////////
- if (_tree->exists(fs_path("time") / "cmd") and
- _tree->exists(fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(i).db_fe_name / "time" / "cmd"))) {
+ if (_tree->exists(fs_path("time") / "cmd")) {
_tree->access<time_spec_t>(fs_path("time") / "cmd")
.add_coerced_subscriber(boost::bind(&x300_radio_ctrl_impl::set_fe_cmd_time, this, _1, i));
}
@@ -180,9 +179,11 @@ double x300_radio_ctrl_impl::set_rate(double rate)
void x300_radio_ctrl_impl::set_fe_cmd_time(const time_spec_t &time, const size_t chan)
{
- _tree->access<time_spec_t>(
- fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd")
- ).set(time);
+ if (_tree->exists(fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd"))) {
+ _tree->access<time_spec_t>(
+ fs_path("dboards" / _radio_slot / "rx_frontends" / _rx_fe_map.at(chan).db_fe_name / "time" / "cmd")
+ ).set(time);
+ }
}
void x300_radio_ctrl_impl::set_tx_antenna(const std::string &ant, const size_t chan)
diff --git a/host/utils/query_gpsdo_sensors.cpp b/host/utils/query_gpsdo_sensors.cpp
index 7420e62e9..6c2ec0bd1 100644
--- a/host/utils/query_gpsdo_sensors.cpp
+++ b/host/utils/query_gpsdo_sensors.cpp
@@ -120,67 +120,83 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
return EXIT_FAILURE;
}
- // Explicitly set time source to gpsdo
- boost::this_thread::sleep(boost::posix_time::seconds(1));
+ std::cout << "\nSetting the reference clock source to \"gpsdo\"...\n";
try {
- usrp->set_time_source("gpsdo");
+ usrp->set_clock_source("gpsdo");
} catch (uhd::value_error &e) {
- std::cout << "could not set the time source to \"gpsdo\"; error was:" <<std::endl;
+ std::cout << "could not set the clock source to \"gpsdo\"; error was:" <<std::endl;
std::cout << e.what() << std::endl;
std::cout << "trying \"external\"..." <<std::endl;
- try {
- usrp->set_time_source("external");
+ try{
+ usrp->set_clock_source("external");
} catch (uhd::value_error&) {
std::cout << "\"external\" failed, too." << std::endl;
}
}
- std::cout<< std::endl << "Time source is now " << usrp->get_time_source(0) << std::endl;
+ std::cout<< std::endl << "Clock source is now " << usrp->get_clock_source(0) << std::endl;
- //Check for GPS lock
- uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked",0);
- if(not gps_locked.to_bool()) {
- std::cout << boost::format("\nGPS does not have lock. Wait a few minutes and try again.\n");
- std::cout << boost::format("NMEA strings and device time may not be accurate until lock is achieved.\n\n");
+ //Check for 10 MHz lock
+ if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) {
+ uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0);
+ for (size_t i = 0; not ref_locked.to_bool() and i < 100; i++) {
+ boost::this_thread::sleep(boost::posix_time::milliseconds(100));
+ ref_locked = usrp->get_mboard_sensor("ref_locked",0);
+ }
+ if(not ref_locked.to_bool()) {
+ std::cout << boost::format("USRP NOT Locked to GPSDO 10 MHz Reference.\n");
+ std::cout << boost::format("Double check installation instructions (N2X0/E1X0 only): https://www.ettus.com/content/files/gpsdo-kit_4.pdf\n\n");
+ return EXIT_FAILURE;
+ } else {
+ std::cout << boost::format("USRP Locked to GPSDO 10 MHz Reference.\n");
+ }
} else {
- std::cout << boost::format("GPS Locked");
+ std::cout << boost::format("ref_locked sensor not present on this board.\n");
}
- std::cout << "\nSetting the reference clock source to \"gpsdo\"...\n";
+ // Explicitly set time source to gpsdo
try {
- usrp->set_clock_source("gpsdo");
+ usrp->set_time_source("gpsdo");
} catch (uhd::value_error &e) {
- std::cout << "could not set the clock source to \"gpsdo\"; error was:" <<std::endl;
+ std::cout << "could not set the time source to \"gpsdo\"; error was:" <<std::endl;
std::cout << e.what() << std::endl;
std::cout << "trying \"external\"..." <<std::endl;
- try{
- usrp->set_clock_source("external");
+ try {
+ usrp->set_time_source("external");
} catch (uhd::value_error&) {
std::cout << "\"external\" failed, too." << std::endl;
}
}
- std::cout<< std::endl << "Clock source is now " << usrp->get_clock_source(0) << std::endl;
+ std::cout << std::endl << "Time source is now " << usrp->get_time_source(0) << std::endl;
print_notes();
+ // The TCXO has a long warm up time, so wait up to 30 seconds for sensor data to show up
+ std::cout << "Waiting for the GPSDO to warm up..." << std::endl;
+ for (size_t i = 0; i < 300; i++) {
+ try {
+ usrp->get_mboard_sensor("gps_locked",0);
+ break;
+ } catch (std::exception &) {}
+ boost::this_thread::sleep(boost::posix_time::milliseconds(100));
+ }
+ try {
+ usrp->get_mboard_sensor("gps_locked",0);
+ } catch (std::exception &) {
+ std::cout << "No response from GPSDO in 30 seconds" << std::endl;
+ return EXIT_FAILURE;
+ }
+ std::cout << "The GPSDO is warmed up and talking." << std::endl;
- //Check for 10 MHz lock
- if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end()) {
- uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("ref_locked",0);
- if(not gps_locked.to_bool()) {
- std::cout << boost::format("USRP NOT Locked to GPSDO 10 MHz Reference.\n");
- std::cout << boost::format("Double check installation instructions (N2X0/E1X0 only): https://www.ettus.com/content/files/gpsdo-kit_4.pdf\n\n");
- std::cout << boost::format("Locking the internal reference to the GPSDO might take a second to reach stability. Retrying in 10 s...\n\n");
- boost::this_thread::sleep(boost::posix_time::seconds(10));
- }
- if(usrp->get_mboard_sensor("ref_locked",0).to_bool()) {
- std::cout << boost::format("USRP Locked to GPSDO 10 MHz Reference.\n");
- }
+ //Check for GPS lock
+ uhd::sensor_value_t gps_locked = usrp->get_mboard_sensor("gps_locked",0);;
+ if(not gps_locked.to_bool()) {
+ std::cout << boost::format("\nGPS does not have lock. Wait a few minutes and try again.\n");
+ std::cout << boost::format("NMEA strings and device time may not be accurate until lock is achieved.\n\n");
} else {
- std::cout << boost::format("ref_locked sensor not present on this board.\n");
+ std::cout << boost::format("GPS Locked");
}
//Check PPS and compare UHD device time to GPS time
- boost::this_thread::sleep(boost::posix_time::seconds(1));
uhd::sensor_value_t gps_time = usrp->get_mboard_sensor("gps_time");
uhd::time_spec_t last_pps_time = usrp->get_time_last_pps();
@@ -189,13 +205,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
long long pps_seconds = last_pps_time.to_ticks(1.0);
if(pps_seconds != gps_seconds) {
- std::cout << boost::format("\nGPS and UHD Device time are NOT aligned;\nlast_pps: %ld vs gps: %ld. Trying to set the device time to GPS time...")
- % pps_seconds % gps_seconds
+ std::cout << "\nTrying to align the device time to GPS time..."
<< std::endl;
- //full next after next second
- uhd::time_spec_t next_pps_time(gps_seconds + 2.0);
- //instruct the USRP to wait for the next PPS edge, then set the new time on the following PPS
- usrp->set_time_unknown_pps(next_pps_time);
+ //set the device time to the GPS time
+ //getting the GPS time returns just after the PPS edge, so just add a
+ //second and set the device time at the next PPS edge
+ usrp->set_time_next_pps(uhd::time_spec_t(gps_time.to_int() + 1.0));
//allow some time to make sure the PPS has come…
boost::this_thread::sleep(boost::posix_time::milliseconds(1100));
//…then ask
@@ -203,14 +218,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
pps_seconds = usrp->get_time_last_pps().to_ticks(1.0);
}
- std::cout << boost::format("last_pps: %ld vs gps: %ld.")
- % pps_seconds % gps_seconds
- << std::endl;
if (pps_seconds == gps_seconds) {
std::cout << boost::format("GPS and UHD Device time are aligned.\n");
} else {
std::cout << boost::format("Could not align UHD Device time to GPS time. Giving up.\n");
}
+ std::cout << boost::format("last_pps: %ld vs gps: %ld.")
+ % pps_seconds % gps_seconds
+ << std::endl;
//print NMEA strings
try {