aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport/nirio/niriok_proxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/transport/nirio/niriok_proxy.cpp')
-rw-r--r--host/lib/transport/nirio/niriok_proxy.cpp290
1 files changed, 29 insertions, 261 deletions
diff --git a/host/lib/transport/nirio/niriok_proxy.cpp b/host/lib/transport/nirio/niriok_proxy.cpp
index ac8faf0a4..cc2daba22 100644
--- a/host/lib/transport/nirio/niriok_proxy.cpp
+++ b/host/lib/transport/nirio/niriok_proxy.cpp
@@ -15,25 +15,11 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
-
#include <uhd/transport/nirio/niriok_proxy.h>
+#include <uhd/transport/nirio/niriok_proxy_impl_v1.h>
+#include <uhd/transport/nirio/niriok_proxy_impl_v2.h>
#include <cstring>
-#define NI_VENDOR_NUM 0x1093
-
-#define VERSION_BUILD_SHIFT 0
-#define VERSION_PHASE_SHIFT 14
-#define VERSION_MAINT_SHIFT 16
-#define VERSION_UPGRD_SHIFT 20
-#define VERSION_MAJOR_SHIFT 24
-#define VERSION_BUILD_MASK 0x00003FFF
-#define VERSION_PHASE_MASK 0x0000C000
-#define VERSION_MAINT_MASK 0x000F0000
-#define VERSION_UPGRD_MASK 0x00F00000
-#define VERSION_MAJOR_MASK 0xFF000000
-
-#define GET_FIFO_MEMORY_TYPE(fifo_inst) (static_cast<uint16_t>(0x0100 | static_cast<uint16_t>(fifo_inst)))
-
#ifdef __clang__
#pragma GCC diagnostic push ignored "-Wmissing-field-initializers"
#elif defined(__GNUC__)
@@ -42,6 +28,9 @@
namespace uhd { namespace niusrprio
{
+ // initialization of static members
+ boost::shared_mutex niriok_proxy::_synchronization;
+
//-------------------------------------------------------
// niriok_proxy
//-------------------------------------------------------
@@ -51,258 +40,37 @@ namespace uhd { namespace niusrprio
niriok_proxy::~niriok_proxy()
{
- close();
- }
-
- nirio_status niriok_proxy::open(const std::string& interface_path)
- {
- if (interface_path.empty()) return NiRio_Status_ResourceNotFound;
-
- //close if already open.
- close();
-
- nirio_status status = NiRio_Status_Success;
- nirio_status_chain(nirio_driver_iface::rio_open(
- interface_path, _device_handle), status);
- if (nirio_status_not_fatal(status)) {
- nirio_status_chain(nirio_driver_iface::rio_ioctl(_device_handle,
- nirio_driver_iface::NIRIO_IOCTL_POST_OPEN,
- NULL, 0, NULL, 0), status);
- nirio_driver_iface::nirio_ioctl_packet_t out(&_interface_num, sizeof(_interface_num), 0);
- nirio_status_chain(nirio_driver_iface::rio_ioctl(_device_handle,
- nirio_driver_iface::NIRIO_IOCTL_GET_IFACE_NUM,
- NULL, 0,
- &out, sizeof(out)), status);
-
- if (nirio_status_fatal(status)) close();
- }
- return status;
- }
-
- void niriok_proxy::close(void)
- {
- if(nirio_driver_iface::rio_isopen(_device_handle))
- {
- nirio_driver_iface::rio_ioctl(
- _device_handle, nirio_driver_iface::NIRIO_IOCTL_PRE_CLOSE, NULL, 0, NULL, 0);
- nirio_driver_iface::rio_close(_device_handle);
- }
- }
-
- nirio_status niriok_proxy::reset()
- {
- 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::RESET;
-
- return sync_operation(&in, sizeof(in), &out, sizeof(out));
- }
-
- nirio_status niriok_proxy::get_cached_session(
- uint32_t& session)
- {
- nirio_driver_iface::nirio_ioctl_packet_t out(&session, sizeof(session), 0);
- return nirio_driver_iface::rio_ioctl(_device_handle,
- nirio_driver_iface::NIRIO_IOCTL_GET_SESSION,
- NULL, 0,
- &out, sizeof(out));
}
+
+ niriok_proxy::sptr niriok_proxy::make_and_open(const std::string& interface_path)
+ {
+ nirio_status status;
+
+ /*
+ niriok_proxy_impl_v1 supports NI-RIO 13.0
+ niriok_proxy_impl_v2 supports NI-RIO 14.0 and later
- nirio_status niriok_proxy::get_version(
- nirio_version_t type,
- uint32_t& major,
- uint32_t& upgrade,
- uint32_t& maintenance,
- char& phase,
- uint32_t& build)
- {
- nirio_device_attr_32_t version_attr = (type==CURRENT)?CURRENT_VERSION:OLDEST_COMPATIBLE_VERSION;
- uint32_t raw_version = 0;
- nirio_status status = get_attribute(version_attr, raw_version);
-
- major = (raw_version & VERSION_MAJOR_MASK) >> VERSION_MAJOR_SHIFT;
- upgrade = (raw_version & VERSION_UPGRD_MASK) >> VERSION_UPGRD_SHIFT;
- maintenance = (raw_version & VERSION_MAINT_MASK) >> VERSION_MAINT_SHIFT;
- build = (raw_version & VERSION_BUILD_MASK) >> VERSION_BUILD_SHIFT;
-
- uint32_t phase_num = (raw_version & VERSION_PHASE_MASK) >> VERSION_PHASE_SHIFT;
- switch (phase_num) {
- case 0: phase = 'd'; break;
- case 1: phase = 'a'; break;
- case 2: phase = 'b'; break;
- case 3: phase = 'f'; break;
- }
-
- return status;
- }
+ We must dynamically determine which version of the RIO kernel we are
+ interfacing to. Opening the interface will fail if there is a version
+ incompatibility, so we try to open successively newer interface
+ proxies until it succeeds.
+ */
- nirio_status niriok_proxy::sync_operation(
- const void *writeBuffer,
- size_t writeBufferLength,
- void *readBuffer,
- size_t readBufferLength)
- {
- nirio_driver_iface::nirio_ioctl_packet_t out(readBuffer, readBufferLength, 0);
- nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
- nirio_driver_iface::NIRIO_IOCTL_SYNCOP,
- writeBuffer, writeBufferLength,
- &out, sizeof(out));
- if (nirio_status_fatal(ioctl_status)) return ioctl_status;
-
- return out.statusCode;
- }
-
- nirio_status niriok_proxy::get_attribute(
- const nirio_device_attr_32_t attribute,
- uint32_t& attrValue)
- {
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
+ sptr proxy_v1(new niriok_proxy_impl_v1);
+ status = proxy_v1->open(interface_path);
- in.function = nirio_driver_iface::NIRIO_FUNC::GET32;
- in.params.attribute32.attribute = attribute;
+ if (nirio_status_not_fatal(status))
+ return proxy_v1;
- nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out));
-
- attrValue = out.params.attribute32.value;
- return status;
- }
-
- nirio_status niriok_proxy::get_attribute(
- const nirio_device_attr_str_t attribute,
- char *buf,
- const uint32_t bufLen,
- uint32_t& stringLen)
- {
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
- nirio_driver_iface::init_syncop_out_params(out, buf, bufLen);
-
- in.function = nirio_driver_iface::NIRIO_FUNC::GET_STRING;
- in.params.attributeStr.attribute = attribute;
-
- nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out));
-
- stringLen = out.params.stringLength;
- return status;
- }
-
- nirio_status niriok_proxy::set_attribute(
- const nirio_device_attr_32_t attribute,
- const uint32_t value)
- {
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
+ sptr proxy_v2(new niriok_proxy_impl_v2);
+ status = proxy_v2->open(interface_path);
- in.function = nirio_driver_iface::NIRIO_FUNC::SET32;
- in.params.attribute32.attribute = attribute;
- in.params.attribute32.value = value;
+ if (nirio_status_not_fatal(status))
+ return proxy_v2;
- return sync_operation(&in, sizeof(in), &out, sizeof(out));
- }
-
- nirio_status niriok_proxy::set_attribute(
- const nirio_device_attr_str_t attribute,
- const char* const buffer)
- {
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- nirio_driver_iface::init_syncop_in_params(in, buffer, strlen(buffer) + 1);
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
-
- in.function = nirio_driver_iface::NIRIO_FUNC::SET_STRING;
- in.params.attributeStr.attribute = attribute;
-
- return sync_operation(&in, sizeof(in), &out, sizeof(out));
- }
-
- nirio_status niriok_proxy::peek(uint32_t offset, uint32_t& value)
- {
- if (offset % 4 != 0) return NiRio_Status_MisalignedAccess;
-
- 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::IO;
- in.subfunction = nirio_driver_iface::NIRIO_IO::PEEK32;
- in.params.io.offset = offset;
-
- nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out));
- value = out.params.io.value.value32;
- return status;
- }
-
- nirio_status niriok_proxy::peek(uint32_t offset, uint64_t& value)
- {
- if (offset % 8 != 0) return NiRio_Status_MisalignedAccess;
-
- 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::IO;
- in.subfunction = nirio_driver_iface::NIRIO_IO::PEEK64;
- in.params.io.offset = offset;
-
- nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out));
- value = out.params.io.value.value64;
- return status;
- }
-
- nirio_status niriok_proxy::poke(uint32_t offset, const uint32_t& value)
- {
- if (offset % 4 != 0) return NiRio_Status_MisalignedAccess;
-
- 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::IO;
- in.subfunction = nirio_driver_iface::NIRIO_IO::POKE32;
- in.params.io.offset = offset;
- in.params.io.value.value32 = value;
-
- return sync_operation(&in, sizeof(in), &out, sizeof(out));
- }
-
- nirio_status niriok_proxy::poke(uint32_t offset, const uint64_t& value)
- {
- if (offset % 8 != 0) return NiRio_Status_MisalignedAccess;
-
- 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::IO;
- in.subfunction = nirio_driver_iface::NIRIO_IO::POKE64;
- in.params.io.offset = offset;
- in.params.io.value.value64 = value;
-
- return sync_operation(&in, sizeof(in), &out, sizeof(out));
- }
-
- nirio_status niriok_proxy::map_fifo_memory(
- uint32_t fifo_instance,
- size_t size,
- nirio_driver_iface::rio_mmap_t& map)
- {
- return nirio_driver_iface::rio_mmap(_device_handle,
- GET_FIFO_MEMORY_TYPE(fifo_instance),
- size, true, map);
- }
-
- nirio_status niriok_proxy::unmap_fifo_memory(
- nirio_driver_iface::rio_mmap_t& map)
- {
- 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));
- }
+ throw uhd::runtime_error("Unable to detect a supported version of the NI-RIO kernel interface.");
+
+ }
}}
#ifdef __GNUC__