diff options
author | Martin Braun <martin.braun@ettus.com> | 2017-01-30 09:40:02 +0100 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-01-30 09:40:02 +0100 |
commit | 211c590f594f83dc8b5fc724d49c1c8d7207d2f2 (patch) | |
tree | 16b03b97da7c61930053a0b8699a36d36e9857b2 /host/lib/usrp/x300 | |
parent | 207903d343f6cb520d86e62c2ebee2e847546f7b (diff) | |
parent | 75e6ae59b3f4832372c08d7da390c5fdcc283067 (diff) | |
download | uhd-211c590f594f83dc8b5fc724d49c1c8d7207d2f2.tar.gz uhd-211c590f594f83dc8b5fc724d49c1c8d7207d2f2.tar.bz2 uhd-211c590f594f83dc8b5fc724d49c1c8d7207d2f2.zip |
Merge branch 'maint'
Diffstat (limited to 'host/lib/usrp/x300')
-rw-r--r-- | host/lib/usrp/x300/x300_fw_uart.cpp | 33 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 31 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_impl.hpp | 5 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_radio_ctrl_impl.cpp | 11 |
4 files changed, 55 insertions, 25 deletions
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) |