diff options
Diffstat (limited to 'host/lib/transport/nirio')
| -rw-r--r-- | host/lib/transport/nirio/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | host/lib/transport/nirio/nifpga_lvbitx.cpp | 16 | ||||
| -rw-r--r-- | host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp (renamed from host/lib/transport/nirio/nirio_driver_iface_macos.cpp) | 0 | ||||
| -rw-r--r-- | host/lib/transport/nirio/niriok_proxy.cpp | 10 | ||||
| -rw-r--r-- | host/lib/transport/nirio/niusrprio_session.cpp | 57 | ||||
| -rw-r--r-- | host/lib/transport/nirio/rpc/rpc_client.cpp | 5 |
6 files changed, 92 insertions, 6 deletions
diff --git a/host/lib/transport/nirio/CMakeLists.txt b/host/lib/transport/nirio/CMakeLists.txt index 6a33da6c5..5f12e91df 100644 --- a/host/lib/transport/nirio/CMakeLists.txt +++ b/host/lib/transport/nirio/CMakeLists.txt @@ -39,10 +39,8 @@ LIBUHD_APPEND_SOURCES( IF(WIN32) LIBUHD_APPEND_SOURCES(${CMAKE_CURRENT_SOURCE_DIR}/nirio_driver_iface_win.cpp) -ELSE(WIN32) - IF(APPLE) - LIBUHD_APPEND_SOURCES(${CMAKE_CURRENT_SOURCE_DIR}/nirio_driver_iface_macos.cpp) - ELSE(APPLE) - LIBUHD_APPEND_SOURCES(${CMAKE_CURRENT_SOURCE_DIR}/nirio_driver_iface_linux.cpp) - ENDIF(APPLE) +ELSEIF(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") #Built-in variable encompasses all UNIX-like systems + LIBUHD_APPEND_SOURCES(${CMAKE_CURRENT_SOURCE_DIR}/nirio_driver_iface_linux.cpp) +ELSE() + LIBUHD_APPEND_SOURCES(${CMAKE_CURRENT_SOURCE_DIR}/nirio_driver_iface_unsupported.cpp) ENDIF(WIN32) diff --git a/host/lib/transport/nirio/nifpga_lvbitx.cpp b/host/lib/transport/nirio/nifpga_lvbitx.cpp index 289a44d4a..b87d87a8d 100644 --- a/host/lib/transport/nirio/nifpga_lvbitx.cpp +++ b/host/lib/transport/nirio/nifpga_lvbitx.cpp @@ -16,6 +16,7 @@ // #include <uhd/transport/nirio/nifpga_lvbitx.h> +#include <cstdlib> #include <string> #include <iostream> #include <fstream> @@ -109,6 +110,21 @@ std::string nifpga_lvbitx::_get_fpga_images_dir(const std::string search_paths) std::vector<std::string> search_path_vtr; boost::split(search_path_vtr, search_paths, boost::is_any_of(",")); + // + // Add the value of the UHD_IMAGES_DIR environment variable to the list of + // directories searched for a LVBITX image. + // + char* uhd_images_dir; +#ifdef UHD_PLATFORM_WIN32 + size_t len; + errno_t err = _dupenv_s(&uhd_images_dir, &len, "UHD_IMAGES_DIR"); + if(not err and uhd_images_dir != NULL) search_path_vtr.push_back(std::string(uhd_images_dir)); + free(uhd_images_dir); +#else + uhd_images_dir = getenv("UHD_IMAGES_DIR"); + if(uhd_images_dir != NULL) search_path_vtr.push_back(std::string(uhd_images_dir)); +#endif + std::string lvbitx_dir; //Traverse through the list of search paths. Priority: lexical BOOST_FOREACH(std::string& search_path, search_path_vtr) { diff --git a/host/lib/transport/nirio/nirio_driver_iface_macos.cpp b/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp index 1a1142525..1a1142525 100644 --- a/host/lib/transport/nirio/nirio_driver_iface_macos.cpp +++ b/host/lib/transport/nirio/nirio_driver_iface_unsupported.cpp diff --git a/host/lib/transport/nirio/niriok_proxy.cpp b/host/lib/transport/nirio/niriok_proxy.cpp index 031623c9a..ac8faf0a4 100644 --- a/host/lib/transport/nirio/niriok_proxy.cpp +++ b/host/lib/transport/nirio/niriok_proxy.cpp @@ -293,6 +293,16 @@ namespace uhd { namespace niusrprio { return nirio_driver_iface::rio_munmap(map); } + + nirio_status niriok_proxy::stop_all_fifos() + { + nirio_driver_iface::nirio_syncop_in_params_t in = {}; + nirio_driver_iface::nirio_syncop_out_params_t out = {}; + + in.function = nirio_driver_iface::NIRIO_FUNC::FIFO_STOP_ALL; + + return sync_operation(&in, sizeof(in), &out, sizeof(out)); + } }} #ifdef __GNUC__ diff --git a/host/lib/transport/nirio/niusrprio_session.cpp b/host/lib/transport/nirio/niusrprio_session.cpp index a07bc4fdf..97d764736 100644 --- a/host/lib/transport/nirio/niusrprio_session.cpp +++ b/host/lib/transport/nirio/niusrprio_session.cpp @@ -77,6 +77,8 @@ nirio_status niusrprio_session::open( std::string lvbitx_checksum(_lvbitx->get_bitstream_checksum()); boost::uint16_t download_fpga = (force_download || (_read_bitstream_checksum() != lvbitx_checksum)) ? 1 : 0; + nirio_status_chain(_ensure_fpga_ready(), status); + nirio_status_chain(_rpc_client.niusrprio_open_session( _resource_name, bitfile_path, signature, download_fpga), status); _session_open = nirio_status_not_fatal(status); @@ -196,4 +198,59 @@ nirio_status niusrprio_session::_write_bitstream_checksum(const std::string& che return status; } +nirio_status niusrprio_session::_ensure_fpga_ready() +{ + nirio_status status = NiRio_Status_Success; + niriok_scoped_addr_space(_riok_proxy, BUS_INTERFACE, status); + + //Verify that the Ettus FPGA loaded in the device. This may not be true if the + //user is switching to UHD after using LabVIEW FPGA. In that case skip this check. + boost::uint32_t pcie_fpga_signature = 0; + nirio_status_chain(_riok_proxy.peek(FPGA_PCIE_SIG_REG, pcie_fpga_signature), status); + //@TODO: Remove X300 specific constants for future products + if (pcie_fpga_signature != FPGA_X3xx_SIG_VALUE) { + return status; + } + + boost::uint32_t reg_data = 0xffffffff; + nirio_status_chain(_riok_proxy.peek(FPGA_STATUS_REG, reg_data), status); + if (nirio_status_not_fatal(status) && (reg_data & FPGA_STATUS_DMA_ACTIVE_MASK)) + { + //In case this session was re-initialized *immediately* after the previous + //there is a small chance that the server is still finishing up cleaning up + //the DMA FIFOs. We currently don't have any feedback from the driver regarding + //this state so just wait. + boost::this_thread::sleep(boost::posix_time::milliseconds(FPGA_READY_TIMEOUT_IN_MS)); + + //Disable all FIFOs in the FPGA + for (size_t i = 0; i < _lvbitx->get_input_fifo_count(); i++) { + _riok_proxy.poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, i), DMA_CTRL_DISABLED); + } + for (size_t i = 0; i < _lvbitx->get_output_fifo_count(); i++) { + _riok_proxy.poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, i), DMA_CTRL_DISABLED); + } + + //Disable all FIFOs in the kernel driver + _riok_proxy.stop_all_fifos(); + + boost::posix_time::ptime start_time = boost::posix_time::microsec_clock::local_time(); + boost::posix_time::time_duration elapsed; + do { + boost::this_thread::sleep(boost::posix_time::milliseconds(10)); //Avoid flooding the bus + elapsed = boost::posix_time::microsec_clock::local_time() - start_time; + nirio_status_chain(_riok_proxy.peek(FPGA_STATUS_REG, reg_data), status); + } while ( + nirio_status_not_fatal(status) && + (reg_data & FPGA_STATUS_DMA_ACTIVE_MASK) && + elapsed.total_milliseconds() < FPGA_READY_TIMEOUT_IN_MS); + + nirio_status_chain(_riok_proxy.peek(FPGA_STATUS_REG, reg_data), status); + if (nirio_status_not_fatal(status) && (reg_data & FPGA_STATUS_DMA_ACTIVE_MASK)) { + return NiRio_Status_FifoReserved; + } + } + + return status; +} + }} diff --git a/host/lib/transport/nirio/rpc/rpc_client.cpp b/host/lib/transport/nirio/rpc/rpc_client.cpp index f8dc26b50..0c4b8fe3c 100644 --- a/host/lib/transport/nirio/rpc/rpc_client.cpp +++ b/host/lib/transport/nirio/rpc/rpc_client.cpp @@ -104,6 +104,11 @@ rpc_client::rpc_client ( } catch (boost::exception&) { UHD_LOG << "rpc_client connection request cancelled/aborted." << std::endl; _exec_err.assign(boost::asio::error::connection_aborted, boost::asio::error::get_system_category()); +#if BOOST_VERSION < 104700 + } catch (std::exception& e) { + UHD_LOG << "rpc_client connection error: " << e.what() << std::endl; + _exec_err.assign(boost::asio::error::connection_aborted, boost::asio::error::get_system_category()); +#endif } } |
