aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAshish Chaudhari <ashish@ettus.com>2014-10-10 17:24:40 -0700
committerAshish Chaudhari <ashish@ettus.com>2014-10-10 17:24:40 -0700
commitcca10287170e8ad50740791e7cbe715b642c2a87 (patch)
treec2ba1fe383b94a1f49d9a79f5301582567330dcf
parentf30c5fee2a8d05f424ae1d733d0d99006eff930c (diff)
downloaduhd-cca10287170e8ad50740791e7cbe715b642c2a87.tar.gz
uhd-cca10287170e8ad50740791e7cbe715b642c2a87.tar.bz2
uhd-cca10287170e8ad50740791e7cbe715b642c2a87.zip
x300,nirio: Added support for NI-RIO 14.0
- Split niriok_proxy interfaces to support NI-RIO <=13.0 and >=14.0 kernel interfaces - Fixed multi-session race conditions by synchronizing niriok_proxy access - Fixed bug switching from NI LV-FPGA access to UHD access by changing how devices are hashed into a reservation table - Fixed calculation of FRAC values for CBX and SBX LO tuning by rounding instead of truncating - Fixed bug that was not setting two MSBs for band select configuration of CBX LO - Submitting on behalf of Patrick Sisterhen, Matthew Crymble
-rw-r--r--host/include/uhd/transport/nirio/nirio_driver_iface.h364
-rw-r--r--host/include/uhd/transport/nirio/nirio_fifo.h24
-rw-r--r--host/include/uhd/transport/nirio/nirio_fifo.ipp170
-rw-r--r--host/include/uhd/transport/nirio/nirio_resource_manager.h33
-rw-r--r--host/include/uhd/transport/nirio/niriok_proxy.h288
-rw-r--r--host/include/uhd/transport/nirio/niriok_proxy_impl_v1.h485
-rw-r--r--host/include/uhd/transport/nirio/niriok_proxy_impl_v2.h410
-rw-r--r--host/include/uhd/transport/nirio/niusrprio_session.h4
-rw-r--r--host/lib/device.cpp13
-rw-r--r--host/lib/transport/nirio/CMakeLists.txt2
-rwxr-xr-xhost/lib/transport/nirio/lvbitx/process-lvbitx.py28
-rw-r--r--host/lib/transport/nirio/nirio_driver_iface_linux.cpp11
-rw-r--r--host/lib/transport/nirio/nirio_resource_manager.cpp33
-rw-r--r--host/lib/transport/nirio/niriok_proxy.cpp290
-rw-r--r--host/lib/transport/nirio/niriok_proxy_impl_v1.cpp494
-rw-r--r--host/lib/transport/nirio/niriok_proxy_impl_v2.cpp647
-rw-r--r--host/lib/transport/nirio/niusrprio_session.cpp36
-rw-r--r--host/lib/transport/nirio_zero_copy.cpp30
-rw-r--r--host/lib/usrp/common/adf435x_common.cpp3
-rw-r--r--host/lib/usrp/x300/x300_fw_ctrl.cpp22
-rw-r--r--host/lib/usrp/x300/x300_impl.cpp13
-rw-r--r--host/lib/usrp/x300/x300_impl.hpp2
-rw-r--r--host/utils/nirio_programmer.cpp47
23 files changed, 2487 insertions, 962 deletions
diff --git a/host/include/uhd/transport/nirio/nirio_driver_iface.h b/host/include/uhd/transport/nirio/nirio_driver_iface.h
index 5b430b43d..83afd816a 100644
--- a/host/include/uhd/transport/nirio/nirio_driver_iface.h
+++ b/host/include/uhd/transport/nirio/nirio_driver_iface.h
@@ -76,370 +76,6 @@ const uint32_t NIRIO_IOCTL_PRE_CLOSE =
FILE_READ_ACCESS); ///< Called before closing a session
-// -------------------------------
-// Function Codes: defined as integers rather than enums because they
-// are going to be carried accross boundaries so size matters
-
-namespace NIRIO_FUNC
-{
- const uint32_t GET32 = 0x00000001;
- const uint32_t SET32 = 0x00000002;
- const uint32_t SET_DRIVER_CONFIG = 0x00000007;
- const uint32_t FIFO = 0x00000008;
- const uint32_t IO = 0x0000000A;
- const uint32_t FIFO_STOP_ALL = 0x0000000C;
- const uint32_t ADD_RESOURCE = 0x0000000D;
- const uint32_t GET_STRING = 0x0000000E;
- const uint32_t SET_STRING = 0x0000000F;
- const uint32_t DOWNLOAD = 0x00000013;
- const uint32_t RESET = 0x00000014;
-}
-
-namespace NIRIO_RESOURCE
-{
- const uint32_t INPUT_FIFO = 0xD0000001;
- const uint32_t OUTPUT_FIFO = 0xD0000002;
-}
-
-namespace NIRIO_FIFO
-{
- const uint32_t CONFIGURE = 0x80000001;
- const uint32_t START = 0x80000002;
- const uint32_t STOP = 0x80000003;
- const uint32_t READ = 0x80000004;
- const uint32_t WRITE = 0x80000005;
- const uint32_t WAIT = 0x80000006;
- const uint32_t GRANT = 0x80000007;
-}
-
-namespace NIRIO_IO
-{
- const uint32_t POKE64 = 0xA0000005;
- const uint32_t POKE32 = 0xA0000006;
- const uint32_t POKE16 = 0xA0000007;
- const uint32_t POKE8 = 0xA0000008;
- const uint32_t PEEK64 = 0xA0000009;
- const uint32_t PEEK32 = 0xA000000A;
- const uint32_t PEEK16 = 0xA000000B;
- const uint32_t PEEK8 = 0xA000000C;
- const uint32_t READ_BLOCK = 0xA000000D;
- const uint32_t WRITE_BLOCK = 0xA000000E;
- const uint32_t GET_IO_WINDOW = 0xA000000F;
- const uint32_t GET_IO_WINDOW_SIZE = 0xA0000010;
-}
-
-struct nirio_ioctl_packet_t {
- nirio_ioctl_packet_t(
- void* const _outBuf,
- const uint32_t _outSize,
- const int32_t _statusCode)
- {
- outBuf._64BitField = 0;
- outBuf.pointer = _outBuf;
- outSize = _outSize;
- statusCode = _statusCode;
- };
-
- union {
- void* pointer;
- uint64_t _64BitField;
- } outBuf;
-
- uint32_t outSize;
- int32_t statusCode;
-};
-
-struct nirio_ioctl_block_t
-{
- uint64_t inBuf;
- uint64_t outBuf;
- uint32_t inBufLength;
- uint32_t outBufLength;
- uint32_t bytesReturned;
- uint32_t padding;
-};
-
-struct nirio_syncop_in_params_t
-{
- uint32_t function;
- uint32_t subfunction;
-
- union
- {
- struct
- {
- uint32_t attribute;
- uint32_t value;
- } attribute32;
-
- struct
- {
- uint32_t attribute;
- uint64_t value;
- } attribute64;
-
- struct
- {
- uint32_t attribute;
- } attributeStr;
-
- struct
- {
- uint32_t attribute;
- } download;
-
- union
- {
- struct
- {
- uint32_t reserved_field_0_0_0;
- } reserved_field_0_0;
- struct
- {
- uint32_t reserved_field_0_1_0;
- uint32_t reserved_field_0_1_1;
- } reserved_field_0_1;
- struct
- {
- uint32_t reserved_field_0_2_0;
- } reserved_field_0_2;
- } reserved_field_0;
-
- union
- {
- struct
- {
- uint32_t channel;
- uint32_t baseAddress;
- uint32_t depthInSamples;
- uint32_t version;
- } fifo;
- struct
- {
- uint32_t channel;
- uint32_t baseAddress;
- uint32_t depthInSamples;
- uint32_t version;
- uint32_t scalarType;
- uint32_t bitWidth;
- } fifoWithDataType;
- struct
- {
- uint64_t rangeBaseAddress;
- uint32_t rangeSizeInBytes;
- uint32_t rangeAttribute;
- } atomic; // obsolete
- } add;
-
- struct
- {
- uint32_t channel;
-
- union
- {
- struct
- {
- uint32_t requestedDepth;
- uint8_t requiresActuals;
- } config;
- struct
- {
- uint32_t timeout;
- } read;
- struct
- {
- uint32_t timeout;
- uint32_t scalarType;
- uint32_t bitWidth;
- } readWithDataType;
- struct
- {
- uint32_t timeout;
- } write;
- struct
- {
- uint32_t timeout;
- uint32_t scalarType;
- uint32_t bitWidth;
- } writeWithDataType;
- struct
- {
- uint32_t elementsRequested;
- uint32_t scalarType;
- uint32_t bitWidth;
- uint32_t timeout;
- uint8_t output;
- } wait;
- struct
- {
- uint32_t elements;
- } grant;
- } op;
- } fifo;
-
- struct
- {
- uint64_t reserved_field_1_0;
- uint32_t reserved_field_1_1;
- uint32_t reserved_field_1_2;
- } reserved_field_1; // Obsolete
-
- struct
- {
- uint32_t offset;
- union
- {
- uint64_t value64;
- uint32_t value32;
- uint16_t value16;
- uint8_t value8;
- } value;
- union
- {
- uint32_t sizeToMap;
- } memoryMappedIoWindow;
- } io;
-
- struct
- {
- uint32_t reserved_field_2_0;
- uint32_t reserved_field_2_1;
- } reserved_field_2;
-
- struct
- {
- uint32_t reserved_field_3_0;
- } reserved_field_3;
-
- union
- {
- struct
- {
- uint32_t reserved_field_4_0;
- int32_t reserved_field_4_1;
- } wait;
- } reserved_field_4;
-
- } params;
-
- uint32_t inbufByteLen;
-
- union
- {
- const void* pointer;
- uint64_t _64BitField;
- } inbuf;
-};
-
-static inline void init_syncop_in_params(nirio_syncop_in_params_t& param, const void* const buf, const uint32_t len)
-{
- param.inbuf._64BitField = 0;
- param.inbuf.pointer = buf;
- param.inbufByteLen = len;
-}
-
-
-struct nirio_syncop_out_params_t
-{
- union
- {
- struct
- {
- uint32_t value;
- } attribute32;
-
- struct
- {
- uint64_t value;
- } attribute64;
-
- union
- {
- struct
- {
- uint32_t reserved_field_0_0;
- } enable;
- } reserved_field_0;
-
- struct
- {
- union
- {
- struct
- {
- uint32_t actualDepth;
- uint32_t actualSize;
- } config;
- struct
- {
- uint32_t numberRead;
- uint32_t numberRemaining;
- } read;
- struct
- {
- uint32_t numberRemaining;
- } write;
- struct
- {
- union
- {
- void* pointer;
- uint64_t _64BitField;
- } elements;
- } wait;
- } op;
- } fifo;
-
- struct
- {
- union
- {
- union
- {
- uint64_t value64;
- uint32_t value32;
- uint16_t value16;
- uint8_t value8;
- } value;
- union
- {
- void* memoryMappedAddress;
- uint64_t _64BitField;
- } memoryMappedIoWindow;
- union
- {
- uint32_t size;
- } memoryMappedIoWindowSize;
- };
- } io;
-
- uint32_t stringLength;
-
- struct
- {
- uint32_t reserved_field_1_0;
- } reserved_field_1;
-
- } params;
-
- uint32_t outbufByteLen;
-
- union
- {
- void* pointer;
- uint64_t _64BitField;
- } outbuf;
-};
-
-static inline void init_syncop_out_params(nirio_syncop_out_params_t& param, void* buf, uint32_t len)
-{
- param.outbuf._64BitField = 0;
- param.outbuf.pointer = buf;
- param.outbufByteLen = len;
-}
-
-
-
//Device handle definition
#if defined(UHD_PLATFORM_LINUX)
typedef int rio_dev_handle_t;
diff --git a/host/include/uhd/transport/nirio/nirio_fifo.h b/host/include/uhd/transport/nirio/nirio_fifo.h
index 14ebeeff9..c424275fc 100644
--- a/host/include/uhd/transport/nirio/nirio_fifo.h
+++ b/host/include/uhd/transport/nirio/nirio_fifo.h
@@ -31,25 +31,9 @@
namespace uhd { namespace niusrprio {
-enum fifo_direction_t {
- INPUT_FIFO,
- OUTPUT_FIFO
-};
-
-enum nirio_scalar_t {
- SCALAR_I8 = 1UL,
- SCALAR_I16 = 2UL,
- SCALAR_I32 = 3UL,
- SCALAR_I64 = 4UL,
- SCALAR_U8 = 5UL,
- SCALAR_U16 = 6UL,
- SCALAR_U32 = 7UL,
- SCALAR_U64 = 8UL
-};
-
struct datatype_info_t {
- datatype_info_t(nirio_scalar_t t, uint32_t w):scalar_type(t),width(w) {}
- nirio_scalar_t scalar_type;
+ datatype_info_t(nirio_scalar_type_t t, uint32_t w):scalar_type(t),width(w) {}
+ nirio_scalar_type_t scalar_type;
uint32_t width;
};
@@ -60,7 +44,7 @@ public:
typedef boost::shared_ptr< nirio_fifo<data_t> > sptr;
nirio_fifo(
- niriok_proxy& riok_proxy,
+ niriok_proxy::sptr riok_proxy,
fifo_direction_t direction,
const std::string& name,
uint32_t fifo_instance);
@@ -122,7 +106,7 @@ private: //Members
size_t _acquired_pending;
nirio_driver_iface::rio_mmap_t _mem_map;
boost::recursive_mutex _mutex;
- niriok_proxy* _riok_proxy_ptr;
+ niriok_proxy::sptr _riok_proxy_ptr;
uint64_t _expected_xfer_count;
uint32_t _dma_base_addr;
diff --git a/host/include/uhd/transport/nirio/nirio_fifo.ipp b/host/include/uhd/transport/nirio/nirio_fifo.ipp
index 437e3a1fc..ca6486e30 100644
--- a/host/include/uhd/transport/nirio/nirio_fifo.ipp
+++ b/host/include/uhd/transport/nirio/nirio_fifo.ipp
@@ -23,7 +23,7 @@
template <typename data_t>
nirio_fifo<data_t>::nirio_fifo(
- niriok_proxy& riok_proxy,
+ niriok_proxy::sptr riok_proxy,
fifo_direction_t direction,
const std::string& name,
uint32_t fifo_instance) :
@@ -34,12 +34,12 @@ nirio_fifo<data_t>::nirio_fifo(
_state(UNMAPPED),
_acquired_pending(0),
_mem_map(),
- _riok_proxy_ptr(&riok_proxy),
+ _riok_proxy_ptr(riok_proxy),
_expected_xfer_count(0),
_dma_base_addr(0)
{
nirio_status status = 0;
- nirio_status_chain(_riok_proxy_ptr->set_attribute(ADDRESS_SPACE, BUS_INTERFACE), status);
+ nirio_status_chain(_riok_proxy_ptr->set_attribute(RIO_ADDRESS_SPACE, BUS_INTERFACE), status);
uint32_t base_addr, addr_space_word;
nirio_status_chain(_riok_proxy_ptr->peek(0x1C, base_addr), status);
nirio_status_chain(_riok_proxy_ptr->peek(0xC, addr_space_word), status);
@@ -63,27 +63,24 @@ nirio_status nirio_fifo<data_t>::initialize(
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
if (_state == UNMAPPED) {
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
+
+ uint32_t actual_depth_u32 = 0;
+ uint32_t actual_size_u32 = 0;
//Forcefully stop the fifo if it is running
- in.function = nirio_driver_iface::NIRIO_FUNC::FIFO;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP;
- in.params.fifo.channel = _fifo_channel;
- _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); //Cleanup operation. Ignore status.
+ _riok_proxy_ptr->stop_fifo(_fifo_channel); //Cleanup operation. Ignore status.
//Configure the FIFO now that we know it is stopped
- in.function = nirio_driver_iface::NIRIO_FUNC::FIFO;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::CONFIGURE;
- in.params.fifo.channel = _fifo_channel;
- in.params.fifo.op.config.requestedDepth = static_cast<uint32_t>(requested_depth);
- in.params.fifo.op.config.requiresActuals = 1;
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
-
+ status = _riok_proxy_ptr->configure_fifo(
+ _fifo_channel,
+ static_cast<uint32_t>(requested_depth),
+ 1,
+ actual_depth_u32,
+ actual_size_u32);
if (nirio_status_fatal(status)) return status;
- actual_depth = out.params.fifo.op.config.actualDepth;
- actual_size = out.params.fifo.op.config.actualSize;
+ actual_depth = static_cast<size_t>(actual_depth_u32);
+ actual_size = static_cast<size_t>(actual_size_u32);
status = _riok_proxy_ptr->map_fifo_memory(_fifo_channel, actual_size, _mem_map);
@@ -121,15 +118,8 @@ nirio_status nirio_fifo<data_t>::start()
if (_state == STARTED) {
//Do nothing. Already started.
} else if (_state == MAPPED) {
- 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;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::START;
- in.params.fifo.channel = _fifo_channel;
-
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
+ status = _riok_proxy_ptr->start_fifo(_fifo_channel);
if (nirio_status_not_fatal(status)) {
_state = STARTED;
_acquired_pending = 0;
@@ -152,15 +142,7 @@ nirio_status nirio_fifo<data_t>::stop()
if (_state == STARTED) {
if (_acquired_pending > 0) release(_acquired_pending);
- 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;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP;
-
- in.params.fifo.channel = _fifo_channel;
-
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
+ status = _riok_proxy_ptr->stop_fifo(_fifo_channel);
_state = MAPPED; //Assume teardown succeeded
}
@@ -182,27 +164,24 @@ nirio_status nirio_fifo<data_t>::acquire(
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
if (_state == STARTED) {
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- uint32_t stuffed[2];
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
- init_syncop_out_params(out, stuffed, sizeof(stuffed));
-
- in.function = nirio_driver_iface::NIRIO_FUNC::FIFO;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::WAIT;
-
- in.params.fifo.channel = _fifo_channel;
- in.params.fifo.op.wait.elementsRequested = static_cast<uint32_t>(elements_requested);
- in.params.fifo.op.wait.scalarType = static_cast<uint32_t>(_datatype_info.scalar_type);
- in.params.fifo.op.wait.bitWidth = _datatype_info.width * 8;
- in.params.fifo.op.wait.output = _fifo_direction == OUTPUT_FIFO;
- in.params.fifo.op.wait.timeout = timeout;
-
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
+ uint32_t elements_acquired_u32 = 0;
+ uint32_t elements_remaining_u32 = 0;
+ void* elements_buffer = static_cast<void*>(elements);
+ status = _riok_proxy_ptr->wait_on_fifo(
+ _fifo_channel,
+ static_cast<uint32_t>(elements_requested),
+ static_cast<uint32_t>(_datatype_info.scalar_type),
+ _datatype_info.width * 8,
+ timeout,
+ _fifo_direction == OUTPUT_FIFO,
+ elements_buffer,
+ elements_acquired_u32,
+ elements_remaining_u32);
if (nirio_status_not_fatal(status)) {
- elements = static_cast<data_t*>(out.params.fifo.op.wait.elements.pointer);
- elements_acquired = stuffed[0];
- elements_remaining = stuffed[1];
+ elements = static_cast<data_t*>(elements_buffer);
+ elements_acquired = static_cast<size_t>(elements_acquired_u32);
+ elements_remaining = static_cast<size_t>(elements_remaining_u32);
_acquired_pending = elements_acquired;
if (UHD_NIRIO_RX_FIFO_XFER_CHECK_EN &&
@@ -229,16 +208,9 @@ nirio_status nirio_fifo<data_t>::release(const size_t elements)
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
if (_state == STARTED) {
- 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;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::GRANT;
-
- in.params.fifo.channel = _fifo_channel;
- in.params.fifo.op.grant.elements = static_cast<uint32_t>(elements);
-
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
+ status = _riok_proxy_ptr->grant_fifo(
+ _fifo_channel,
+ static_cast<uint32_t>(elements));
_acquired_pending = 0;
} else {
status = NiRio_Status_ResourceNotInitialized;
@@ -261,24 +233,16 @@ nirio_status nirio_fifo<data_t>::read(
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
if (_state == STARTED) {
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
- init_syncop_out_params(out, buf, num_elements * _datatype_info.width);
-
- in.function = nirio_driver_iface::NIRIO_FUNC::FIFO;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::READ;
-
- in.params.fifo.channel = _fifo_channel;
- in.params.fifo.op.readWithDataType.timeout = timeout;
- in.params.fifo.op.readWithDataType.scalarType = static_cast<uint32_t>(_datatype_info.scalar_type);
- in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8;
-
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
-
- if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) {
- num_read = out.params.fifo.op.read.numberRead;
- num_remaining = out.params.fifo.op.read.numberRemaining;
- }
+ status = _riok_proxy_ptr->read_fifo(
+ _fifo_channel,
+ num_elements,
+ static_cast<void*>(buf),
+ _datatype_info.width,
+ static_cast<uint32_t>(_datatype_info.scalar_type),
+ _datatype_info.width * 8,
+ timeout,
+ num_read,
+ num_remaining);
} else {
status = NiRio_Status_ResourceNotInitialized;
}
@@ -299,23 +263,15 @@ nirio_status nirio_fifo<data_t>::write(
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
if (_state == STARTED) {
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- init_syncop_in_params(in, buf, num_elements * _datatype_info.width);
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
-
- in.function = nirio_driver_iface::NIRIO_FUNC::FIFO;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::WRITE;
-
- in.params.fifo.channel = _fifo_channel;
- in.params.fifo.op.writeWithDataType.timeout = timeout;
- in.params.fifo.op.readWithDataType.scalarType = static_cast<uint32_t>(_datatype_info.scalar_type);
- in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8;
-
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
-
- if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) {
- num_remaining = out.params.fifo.op.write.numberRemaining;
- }
+ status = _riok_proxy_ptr->write_fifo(
+ _fifo_channel,
+ num_elements,
+ buf,
+ _datatype_info.width,
+ static_cast<uint32_t>(_datatype_info.scalar_type),
+ _datatype_info.width * 8,
+ timeout,
+ num_remaining);
} else {
status = NiRio_Status_ResourceNotInitialized;
}
@@ -374,49 +330,49 @@ nirio_status nirio_fifo<data_t>::_ensure_transfer_completed(uint32_t timeout_ms)
template <>
inline datatype_info_t nirio_fifo<int8_t>::_get_datatype_info()
{
- return datatype_info_t(SCALAR_I8, 1);
+ return datatype_info_t(RIO_SCALAR_TYPE_IB, 1);
}
template <>
inline datatype_info_t nirio_fifo<int16_t>::_get_datatype_info()
{
- return datatype_info_t(SCALAR_I16, 2);
+ return datatype_info_t(RIO_SCALAR_TYPE_IW, 2);
}
template <>
inline datatype_info_t nirio_fifo<int32_t>::_get_datatype_info()
{
- return datatype_info_t(SCALAR_I32, 4);
+ return datatype_info_t(RIO_SCALAR_TYPE_IL, 4);
}
template <>
inline datatype_info_t nirio_fifo<int64_t>::_get_datatype_info()
{
- return datatype_info_t(SCALAR_I64, 8);
+ return datatype_info_t(RIO_SCALAR_TYPE_IQ, 8);
}
template <>
inline datatype_info_t nirio_fifo<uint8_t>::_get_datatype_info()
{
- return datatype_info_t(SCALAR_U8, 1);
+ return datatype_info_t(RIO_SCALAR_TYPE_UB, 1);
}
template <>
inline datatype_info_t nirio_fifo<uint16_t>::_get_datatype_info()
{
- return datatype_info_t(SCALAR_U16, 2);
+ return datatype_info_t(RIO_SCALAR_TYPE_UW, 2);
}
template <>
inline datatype_info_t nirio_fifo<uint32_t>::_get_datatype_info()
{
- return datatype_info_t(SCALAR_U32, 4);
+ return datatype_info_t(RIO_SCALAR_TYPE_UL, 4);
}
template <>
inline datatype_info_t nirio_fifo<uint64_t>::_get_datatype_info()
{
- return datatype_info_t(SCALAR_U64, 8);
+ return datatype_info_t(RIO_SCALAR_TYPE_UQ, 8);
}
#ifdef __GNUC__
diff --git a/host/include/uhd/transport/nirio/nirio_resource_manager.h b/host/include/uhd/transport/nirio/nirio_resource_manager.h
index 8c0e373d7..c71f1c8aa 100644
--- a/host/include/uhd/transport/nirio/nirio_resource_manager.h
+++ b/host/include/uhd/transport/nirio/nirio_resource_manager.h
@@ -50,35 +50,7 @@ struct nirio_register_info_t {
typedef std::vector<nirio_register_info_t> nirio_register_info_vtr;
-struct nirio_fifo_info_t {
- nirio_fifo_info_t(
- uint32_t arg_channel,
- const char* arg_name,
- fifo_direction_t arg_direction,
- uint32_t arg_base_addr,
- uint32_t arg_depth,
- nirio_scalar_t arg_scalar_type,
- uint32_t arg_width,
- uint32_t arg_version) :
- channel(arg_channel),
- name(arg_name),
- direction(arg_direction),
- base_addr(arg_base_addr),
- depth(arg_depth),
- scalar_type(arg_scalar_type),
- width(arg_width),
- version(arg_version)
- {}
- uint32_t channel;
- std::string name;
- fifo_direction_t direction;
- uint32_t base_addr;
- uint32_t depth;
- nirio_scalar_t scalar_type;
- uint32_t width;
- uint32_t version;
-};
typedef std::vector<nirio_fifo_info_t> nirio_fifo_info_vtr;
@@ -86,7 +58,8 @@ typedef std::vector<nirio_fifo_info_t> nirio_fifo_info_vtr;
class nirio_resource_manager
{
public:
- nirio_resource_manager(niriok_proxy& proxy);
+ nirio_resource_manager();
+ void set_proxy(niriok_proxy::sptr proxy);
virtual ~nirio_resource_manager();
nirio_status initialize(const nirio_register_info_vtr& reg_info_vtr, const nirio_fifo_info_vtr& fifo_info_vtr);
@@ -137,7 +110,7 @@ private:
nirio_status _set_driver_config();
nirio_fifo_info_t* _lookup_fifo_info(const char* fifo_name);
- niriok_proxy& _kernel_proxy;
+ niriok_proxy::sptr _kernel_proxy;
fifo_info_map_t _fifo_info_map;
register_info_map_t _reg_info_map;
};
diff --git a/host/include/uhd/transport/nirio/niriok_proxy.h b/host/include/uhd/transport/nirio/niriok_proxy.h
index 85eaf3167..5ea796dec 100644
--- a/host/include/uhd/transport/nirio/niriok_proxy.h
+++ b/host/include/uhd/transport/nirio/niriok_proxy.h
@@ -21,38 +21,38 @@
#include <stdint.h>
#include <boost/smart_ptr.hpp>
#include <boost/noncopyable.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_lock_guard.hpp>
#include <uhd/transport/nirio/nirio_driver_iface.h>
#include <uhd/transport/nirio/nirio_quirks.h>
+#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)))
+
+#define READER_LOCK \
+ boost::shared_lock_guard<boost::shared_mutex> reader_lock(_synchronization);
+
+#define WRITER_LOCK \
+ boost::lock_guard<boost::shared_mutex> writer_lock(_synchronization);
+
+
namespace uhd { namespace niusrprio
{
enum nirio_version_t { CURRENT, OLDEST_COMPATIBLE };
- enum nirio_device_attr_32_t {
- INTERFACE_NUMBER = 1UL,
- PRODUCT_NUMBER = 2UL,
- VENDOR_NUMBER = 3UL,
- SERIAL_NUMBER = 4UL,
- BUS_NUMBER = 10UL,
- DEVICE_NUMBER = 11UL,
- FUNCTION_NUMBER = 12UL,
- CURRENT_VERSION = 14UL,
- OLDEST_COMPATIBLE_VERSION = 15UL,
- ADDRESS_SPACE = 25UL,
- IS_FPGA_PROGRAMMED = 48UL,
- DEFAULT_FPGA_SIGNATURE_OFFSET = 53UL,
- DEFAULT_FPGA_RESET_OFFSET = 54UL,
- DEFAULT_FPGA_RESET_SIZE = 55UL,
- DEFAULT_FPGA_CONTROL_OFFSET = 56UL,
- DEFAULT_FPGA_INTERRUPT_OFFSET = 57UL,
- };
-
- enum nirio_device_attr_str_t {
- PRODUCT_NAME = 0UL,
- FPGA_TARGET_CLASS = 6UL,
- SAVED_BITFILE = 7UL,
- };
-
enum nirio_addr_space_t {
INVALID = 0,
BUS_INTERFACE = 1,
@@ -60,101 +60,247 @@ namespace uhd { namespace niusrprio
BAR_WINDOW = 3,
};
+ typedef uint64_t nirio_u64_t;
+ typedef uint32_t nirio_u32_t;
+ typedef uint16_t nirio_u16_t;
+ typedef uint8_t nirio_u8_t;
+ typedef int32_t nirio_i32_t;
+
+ typedef enum {
+ RIO_PRODUCT_NUMBER = 2UL, // 200
+ RIO_CURRENT_VERSION = 14UL, // 220
+ RIO_OLDEST_COMPATIBLE_VERSION = 15UL, // 220
+ RIO_ADDRESS_SPACE = 25UL, // 230
+ RIO_IS_FPGA_PROGRAMMED = 48UL, // 300
+ RIO_FPGA_DEFAULT_SIGNATURE_OFFSET = 53UL, // 300 Default Offsets for FPGA
+ // registers. Supplied by
+ // the board driver on device
+ // start.
+ } nirio_device_attribute32_t;
+
+ typedef enum {
+ RIO_SCALAR_TYPE_IB = 1UL,
+ RIO_SCALAR_TYPE_IW = 2UL,
+ RIO_SCALAR_TYPE_IL = 3UL,
+ RIO_SCALAR_TYPE_IQ = 4UL,
+ RIO_SCALAR_TYPE_UB = 5UL,
+ RIO_SCALAR_TYPE_UW = 6UL,
+ RIO_SCALAR_TYPE_UL = 7UL,
+ RIO_SCALAR_TYPE_UQ = 8UL,
+ } nirio_scalar_type_t;
+
+ static inline nirio_scalar_type_t map_int_to_scalar_type(uint32_t scalar_type_as_int)
+ {
+ switch (scalar_type_as_int)
+ {
+ case 1: return RIO_SCALAR_TYPE_IB;
+ case 2: return RIO_SCALAR_TYPE_IW;
+ case 3: return RIO_SCALAR_TYPE_IL;
+ case 4: return RIO_SCALAR_TYPE_IQ;
+ case 5: return RIO_SCALAR_TYPE_UB;
+ case 6: return RIO_SCALAR_TYPE_UW;
+ case 7: return RIO_SCALAR_TYPE_UL;
+ case 8: return RIO_SCALAR_TYPE_UQ;
+ default: UHD_ASSERT_THROW(false); return RIO_SCALAR_TYPE_UL;
+ }
+ }
+
+ enum fifo_direction_t {
+ INPUT_FIFO,
+ OUTPUT_FIFO
+ };
+
+ struct nirio_fifo_info_t {
+ nirio_fifo_info_t(
+ uint32_t arg_channel,
+ const char* arg_name,
+ fifo_direction_t arg_direction,
+ uint32_t arg_base_addr,
+ uint32_t arg_depth,
+ nirio_scalar_type_t arg_scalar_type,
+ uint32_t arg_bitWidth,
+ int32_t arg_integerWordLength,
+ uint32_t arg_version) :
+ channel(arg_channel),
+ name(arg_name),
+ direction(arg_direction),
+ base_addr(arg_base_addr),
+ depth(arg_depth),
+ scalar_type(arg_scalar_type),
+ bitWidth(arg_bitWidth),
+ integerWordLength(arg_integerWordLength),
+ version(arg_version)
+ {}
+
+ uint32_t channel;
+ std::string name;
+ fifo_direction_t direction;
+ uint32_t base_addr;
+ uint32_t depth;
+ nirio_scalar_type_t scalar_type;
+ uint32_t bitWidth;
+ int32_t integerWordLength;
+ uint32_t version;
+ };
class UHD_API niriok_proxy : public boost::noncopyable {
public:
- typedef boost::shared_ptr<niriok_proxy> sptr;
+ struct nirio_ioctl_packet_t {
+ nirio_ioctl_packet_t(
+ void* const _outBuf,
+ const uint32_t _outSize,
+ const int32_t _statusCode)
+ {
+ outBuf._64BitField = 0;
+ outBuf.pointer = _outBuf;
+ outSize = _outSize;
+ statusCode = _statusCode;
+ };
+
+ union {
+ void* pointer;
+ uint64_t _64BitField;
+ } outBuf;
+
+ uint32_t outSize;
+ int32_t statusCode;
+ };
+ typedef boost::shared_ptr<niriok_proxy> sptr;
+
+ static sptr make_and_open(const std::string& interface_path);
niriok_proxy();
virtual ~niriok_proxy();
//File operations
- nirio_status open(const std::string& interface_path);
- void close(void);
+ virtual nirio_status open(const std::string& interface_path) = 0;
+ virtual void close(void) = 0;
- nirio_status reset();
+ virtual nirio_status reset() = 0;
- inline uint32_t get_interface_num() { return _interface_num; }
+ uint32_t get_interface_num() { return _interface_num; }
- nirio_status get_cached_session(
- uint32_t& session);
+ virtual nirio_status get_cached_session(
+ uint32_t& session) = 0;
- nirio_status get_version(
+ virtual nirio_status get_version(
nirio_version_t type,
uint32_t& major,
uint32_t& upgrade,
uint32_t& maintenance,
char& phase,
- uint32_t& build);
-
- nirio_status sync_operation(
- const void *writeBuffer,
- size_t writeBufferLength,
- void *readBuffer,
- size_t readBufferLength);
-
- nirio_status get_attribute(
- const nirio_device_attr_32_t attribute,
- uint32_t& attrValue);
+ uint32_t& build) = 0;
- nirio_status get_attribute(
- const nirio_device_attr_str_t attribute,
- char* buf,
- const uint32_t bufLen,
- uint32_t& stringLen);
+ virtual nirio_status get_attribute(
+ const nirio_device_attribute32_t attribute,
+ uint32_t& attrValue) = 0;
- nirio_status set_attribute(
- const nirio_device_attr_32_t attribute,
- const uint32_t value);
+ virtual nirio_status set_attribute(
+ const nirio_device_attribute32_t attribute,
+ const uint32_t value) = 0;
- nirio_status set_attribute(
- const nirio_device_attr_str_t attribute,
- const char* const buffer);
+ virtual nirio_status peek(uint32_t offset, uint32_t& value) = 0;
- nirio_status peek(uint32_t offset, uint32_t& value);
+ virtual nirio_status peek(uint32_t offset, uint64_t& value) = 0;
- nirio_status peek(uint32_t offset, uint64_t& value);
+ virtual nirio_status poke(uint32_t offset, const uint32_t& value) = 0;
- nirio_status poke(uint32_t offset, const uint32_t& value);
+ virtual nirio_status poke(uint32_t offset, const uint64_t& value) = 0;
- nirio_status poke(uint32_t offset, const uint64_t& value);
-
- nirio_status map_fifo_memory(
+ virtual nirio_status map_fifo_memory(
uint32_t fifo_instance,
size_t size,
- nirio_driver_iface::rio_mmap_t& map);
+ nirio_driver_iface::rio_mmap_t& map) = 0;
- nirio_status unmap_fifo_memory(
- nirio_driver_iface::rio_mmap_t& map);
+ virtual nirio_status unmap_fifo_memory(
+ nirio_driver_iface::rio_mmap_t& map) = 0;
- nirio_status stop_all_fifos();
+ virtual nirio_status stop_all_fifos() = 0;
nirio_quirks& get_rio_quirks() {
return _rio_quirks;
}
- private: //Members
+ virtual nirio_status add_fifo_resource(const nirio_fifo_info_t& fifo_info) = 0;
+
+ virtual nirio_status set_device_config() = 0;
+
+ virtual nirio_status start_fifo(
+ uint32_t channel) = 0;
+
+ virtual nirio_status stop_fifo(
+ uint32_t channel) = 0;
+
+ virtual nirio_status configure_fifo(
+ uint32_t channel,
+ uint32_t requested_depth,
+ uint8_t requires_actuals,
+ uint32_t& actual_depth,
+ uint32_t& actual_size) = 0;
+
+ virtual nirio_status wait_on_fifo(
+ uint32_t channel,
+ uint32_t elements_requested,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint8_t output,
+ void*& data_pointer,
+ uint32_t& elements_acquired,
+ uint32_t& elements_remaining) = 0;
+
+ virtual nirio_status grant_fifo(
+ uint32_t channel,
+ uint32_t elements_to_grant) = 0;
+
+ virtual nirio_status read_fifo(
+ uint32_t channel,
+ uint32_t elements_to_read,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_read,
+ uint32_t& number_remaining) = 0;
+
+ virtual nirio_status write_fifo(
+ uint32_t channel,
+ uint32_t elements_to_write,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_remaining) = 0;
+
+ protected: //Members
nirio_driver_iface::rio_dev_handle_t _device_handle;
uint32_t _interface_num;
nirio_quirks _rio_quirks;
+
+ static boost::shared_mutex _synchronization;
+
+ // protected close function that doesn't acquire synchronization lock
+ virtual void _close() = 0;
};
class niriok_scoped_addr_space : public boost::noncopyable {
public:
- explicit niriok_scoped_addr_space(niriok_proxy& proxy, nirio_addr_space_t addr_space, nirio_status& status) :
+ explicit niriok_scoped_addr_space(niriok_proxy::sptr proxy, nirio_addr_space_t addr_space, nirio_status& status) :
driver_proxy(proxy)
{
- cache_status = driver_proxy.get_attribute(ADDRESS_SPACE, cached_addr_space);
- nirio_status_chain(driver_proxy.set_attribute(ADDRESS_SPACE, addr_space), status);
+ cache_status = driver_proxy->get_attribute(RIO_ADDRESS_SPACE, cached_addr_space);
+ nirio_status_chain(driver_proxy->set_attribute(RIO_ADDRESS_SPACE, addr_space), status);
}
~niriok_scoped_addr_space() {
if (nirio_status_not_fatal(cache_status))
- driver_proxy.set_attribute(ADDRESS_SPACE, cached_addr_space);
+ driver_proxy->set_attribute(RIO_ADDRESS_SPACE, cached_addr_space);
}
private:
- niriok_proxy& driver_proxy;
+ niriok_proxy::sptr driver_proxy;
uint32_t cached_addr_space;
nirio_status cache_status;
};
diff --git a/host/include/uhd/transport/nirio/niriok_proxy_impl_v1.h b/host/include/uhd/transport/nirio/niriok_proxy_impl_v1.h
new file mode 100644
index 000000000..173d43ed6
--- /dev/null
+++ b/host/include/uhd/transport/nirio/niriok_proxy_impl_v1.h
@@ -0,0 +1,485 @@
+//
+// Copyright 2013-2014 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_NIRIO_NIRIO_PROXY_IMPL_V1_H
+#define INCLUDED_UHD_TRANSPORT_NIRIO_NIRIO_PROXY_IMPL_V1_H
+
+#include <boost/smart_ptr.hpp>
+#include <boost/noncopyable.hpp>
+#include <uhd/transport/nirio/nirio_driver_iface.h>
+#include <uhd/transport/nirio/nirio_quirks.h>
+#include <uhd/transport/nirio/niriok_proxy.h>
+
+namespace uhd { namespace niusrprio
+{
+ /*
+ This file defines the types, enumerations, and classes needed to
+ directly access a subset of the NI-RIO kernel interface.
+ These definitions are specific to NI-RIO versions < 14.0. These
+ are not compatible with NI-RIO 14.0 and later.
+ */
+
+ class UHD_API niriok_proxy_impl_v1 : virtual public niriok_proxy {
+ public:
+
+ // -------------------------------
+ // Function Codes: defined as integers rather than enums because they
+ // are going to be carried accross boundaries so size matters
+
+ struct NIRIO_FUNC
+ {
+ static const uint32_t GET32 = 0x00000001;
+ static const uint32_t SET32 = 0x00000002;
+ static const uint32_t SET_DRIVER_CONFIG = 0x00000007;
+ static const uint32_t FIFO = 0x00000008;
+ static const uint32_t IO = 0x0000000A;
+ static const uint32_t FIFO_STOP_ALL = 0x0000000C;
+ static const uint32_t ADD_RESOURCE = 0x0000000D;
+ static const uint32_t GET_STRING = 0x0000000E;
+ static const uint32_t SET_STRING = 0x0000000F;
+ static const uint32_t DOWNLOAD = 0x00000013;
+ static const uint32_t RESET = 0x00000014;
+ };
+
+ struct NIRIO_RESOURCE
+ {
+ static const uint32_t INPUT_FIFO = 0xD0000001;
+ static const uint32_t OUTPUT_FIFO = 0xD0000002;
+ };
+
+ struct NIRIO_FIFO
+ {
+ static const uint32_t CONFIGURE = 0x80000001;
+ static const uint32_t START = 0x80000002;
+ static const uint32_t STOP = 0x80000003;
+ static const uint32_t READ = 0x80000004;
+ static const uint32_t WRITE = 0x80000005;
+ static const uint32_t WAIT = 0x80000006;
+ static const uint32_t GRANT = 0x80000007;
+ };
+
+ struct NIRIO_IO
+ {
+ static const uint32_t POKE64 = 0xA0000005;
+ static const uint32_t POKE32 = 0xA0000006;
+ static const uint32_t POKE16 = 0xA0000007;
+ static const uint32_t POKE8 = 0xA0000008;
+ static const uint32_t PEEK64 = 0xA0000009;
+ static const uint32_t PEEK32 = 0xA000000A;
+ static const uint32_t PEEK16 = 0xA000000B;
+ static const uint32_t PEEK8 = 0xA000000C;
+ static const uint32_t READ_BLOCK = 0xA000000D;
+ static const uint32_t WRITE_BLOCK = 0xA000000E;
+ static const uint32_t GET_IO_WINDOW = 0xA000000F;
+ static const uint32_t GET_IO_WINDOW_SIZE = 0xA0000010;
+ };
+
+ struct nirio_syncop_in_params_t
+ {
+ uint32_t function;
+ uint32_t subfunction;
+
+ union
+ {
+ struct
+ {
+ uint32_t attribute;
+ uint32_t value;
+ } attribute32;
+
+ struct
+ {
+ uint32_t attribute;
+ uint64_t value;
+ } attribute64;
+
+ struct
+ {
+ uint32_t attribute;
+ } attributeStr;
+
+ struct
+ {
+ uint32_t attribute;
+ } download;
+
+ union
+ {
+ struct
+ {
+ uint32_t reserved_field_0_0_0;
+ } reserved_field_0_0;
+ struct
+ {
+ uint32_t reserved_field_0_1_0;
+ uint32_t reserved_field_0_1_1;
+ } reserved_field_0_1;
+ struct
+ {
+ uint32_t reserved_field_0_2_0;
+ } reserved_field_0_2;
+ } reserved_field_0;
+
+ union
+ {
+ struct
+ {
+ uint32_t channel;
+ uint32_t baseAddress;
+ uint32_t depthInSamples;
+ uint32_t version;
+ } fifo;
+ struct
+ {
+ uint32_t channel;
+ uint32_t baseAddress;
+ uint32_t depthInSamples;
+ uint32_t version;
+ uint32_t scalarType;
+ uint32_t bitWidth;
+ } fifoWithDataType;
+ struct
+ {
+ uint64_t rangeBaseAddress;
+ uint32_t rangeSizeInBytes;
+ uint32_t rangeAttribute;
+ } atomic; // obsolete
+ } add;
+
+ struct
+ {
+ uint32_t channel;
+
+ union
+ {
+ struct
+ {
+ uint32_t requestedDepth;
+ uint8_t requiresActuals;
+ } config;
+ struct
+ {
+ uint32_t timeout;
+ } read;
+ struct
+ {
+ uint32_t timeout;
+ uint32_t scalarType;
+ uint32_t bitWidth;
+ } readWithDataType;
+ struct
+ {
+ uint32_t timeout;
+ } write;
+ struct
+ {
+ uint32_t timeout;
+ uint32_t scalarType;
+ uint32_t bitWidth;
+ } writeWithDataType;
+ struct
+ {
+ uint32_t elementsRequested;
+ uint32_t scalarType;
+ uint32_t bitWidth;
+ uint32_t timeout;
+ uint8_t output;
+ } wait;
+ struct
+ {
+ uint32_t elements;
+ } grant;
+ } op;
+ } fifo;
+
+ struct
+ {
+ uint64_t reserved_field_1_0;
+ uint32_t reserved_field_1_1;
+ uint32_t reserved_field_1_2;
+ } reserved_field_1; // Obsolete
+
+ struct
+ {
+ uint32_t offset;
+ union
+ {
+ uint64_t value64;
+ uint32_t value32;
+ uint16_t value16;
+ uint8_t value8;
+ } value;
+ union
+ {
+ uint32_t sizeToMap;
+ } memoryMappedIoWindow;
+ } io;
+
+ struct
+ {
+ uint32_t reserved_field_2_0;
+ uint32_t reserved_field_2_1;
+ } reserved_field_2;
+
+ struct
+ {
+ uint32_t reserved_field_3_0;
+ } reserved_field_3;
+
+ union
+ {
+ struct
+ {
+ uint32_t reserved_field_4_0;
+ int32_t reserved_field_4_1;
+ } wait;
+ } reserved_field_4;
+
+ } params;
+
+ uint32_t inbufByteLen;
+
+ union
+ {
+ const void* pointer;
+ uint64_t _64BitField;
+ } inbuf;
+ };
+
+ static inline void init_syncop_in_params(nirio_syncop_in_params_t& param, const void* const buf, const uint32_t len)
+ {
+ param.inbuf._64BitField = 0;
+ param.inbuf.pointer = buf;
+ param.inbufByteLen = len;
+ }
+
+
+ struct nirio_syncop_out_params_t
+ {
+ union
+ {
+ struct
+ {
+ uint32_t value;
+ } attribute32;
+
+ struct
+ {
+ uint64_t value;
+ } attribute64;
+
+ union
+ {
+ struct
+ {
+ uint32_t reserved_field_0_0;
+ } enable;
+ } reserved_field_0;
+
+ struct
+ {
+ union
+ {
+ struct
+ {
+ uint32_t actualDepth;
+ uint32_t actualSize;
+ } config;
+ struct
+ {
+ uint32_t numberRead;
+ uint32_t numberRemaining;
+ } read;
+ struct
+ {
+ uint32_t numberRemaining;
+ } write;
+ struct
+ {
+ union
+ {
+ void* pointer;
+ uint64_t _64BitField;
+ } elements;
+ } wait;
+ } op;
+ } fifo;
+
+ struct
+ {
+ union
+ {
+ union
+ {
+ uint64_t value64;
+ uint32_t value32;
+ uint16_t value16;
+ uint8_t value8;
+ } value;
+ union
+ {
+ void* memoryMappedAddress;
+ uint64_t _64BitField;
+ } memoryMappedIoWindow;
+ union
+ {
+ uint32_t size;
+ } memoryMappedIoWindowSize;
+ };
+ } io;
+
+ uint32_t stringLength;
+
+ struct
+ {
+ uint32_t reserved_field_1_0;
+ } reserved_field_1;
+
+ } params;
+
+ uint32_t outbufByteLen;
+
+ union
+ {
+ void* pointer;
+ uint64_t _64BitField;
+ } outbuf;
+ };
+
+
+ static inline void init_syncop_out_params(nirio_syncop_out_params_t& param, void* buf, uint32_t len)
+ {
+ param.outbuf._64BitField = 0;
+ param.outbuf.pointer = buf;
+ param.outbufByteLen = len;
+ }
+
+ niriok_proxy_impl_v1();
+ virtual ~niriok_proxy_impl_v1();
+
+ //File operations
+ virtual nirio_status open(const std::string& interface_path);
+ virtual void close(void);
+
+ virtual nirio_status reset();
+
+ virtual nirio_status get_cached_session(
+ uint32_t& session);
+
+ virtual nirio_status get_version(
+ nirio_version_t type,
+ uint32_t& major,
+ uint32_t& upgrade,
+ uint32_t& maintenance,
+ char& phase,
+ uint32_t& build);
+
+ virtual nirio_status get_attribute(
+ const nirio_device_attribute32_t attribute,
+ uint32_t& attrValue);
+
+ virtual nirio_status set_attribute(
+ const nirio_device_attribute32_t attribute,
+ const uint32_t value);
+
+ virtual nirio_status peek(uint32_t offset, uint32_t& value);
+
+ virtual nirio_status peek(uint32_t offset, uint64_t& value);
+
+ virtual nirio_status poke(uint32_t offset, const uint32_t& value);
+
+ virtual nirio_status poke(uint32_t offset, const uint64_t& value);
+
+ virtual nirio_status map_fifo_memory(
+ uint32_t fifo_instance,
+ size_t size,
+ nirio_driver_iface::rio_mmap_t& map);
+
+ virtual nirio_status unmap_fifo_memory(
+ nirio_driver_iface::rio_mmap_t& map);
+
+ virtual nirio_status stop_all_fifos();
+
+ virtual nirio_status add_fifo_resource(const nirio_fifo_info_t& fifo_info);
+
+ virtual nirio_status set_device_config();
+
+ virtual nirio_status start_fifo(
+ uint32_t channel);
+
+ virtual nirio_status stop_fifo(
+ uint32_t channel);
+
+ virtual nirio_status configure_fifo(
+ uint32_t channel,
+ uint32_t requested_depth,
+ uint8_t requires_actuals,
+ uint32_t& actual_depth,
+ uint32_t& actual_size);
+
+ virtual nirio_status wait_on_fifo(
+ uint32_t channel,
+ uint32_t elements_requested,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint8_t output,
+ void*& data_pointer,
+ uint32_t& elements_acquired,
+ uint32_t& elements_remaining);
+
+ virtual nirio_status grant_fifo(
+ uint32_t channel,
+ uint32_t elements_to_grant);
+
+ virtual nirio_status read_fifo(
+ uint32_t channel,
+ uint32_t elements_to_read,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_read,
+ uint32_t& number_remaining);
+
+ virtual nirio_status write_fifo(
+ uint32_t channel,
+ uint32_t elements_to_write,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_remaining);
+
+ protected:
+ // protected close function that doesn't acquire synchronization lock
+ virtual void _close();
+
+ private:
+ nirio_status sync_operation(
+ const void *writeBuffer,
+ size_t writeBufferLength,
+ void *readBuffer,
+ size_t readBufferLength);
+
+ };
+
+}}
+
+#endif /* INCLUDED_UHD_TRANSPORT_NIRIO_NIRIO_PROXY_IMPL_V1_H */
diff --git a/host/include/uhd/transport/nirio/niriok_proxy_impl_v2.h b/host/include/uhd/transport/nirio/niriok_proxy_impl_v2.h
new file mode 100644
index 000000000..333ab4348
--- /dev/null
+++ b/host/include/uhd/transport/nirio/niriok_proxy_impl_v2.h
@@ -0,0 +1,410 @@
+//
+// Copyright 2013-2014 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_NIRIO_NIRIO_PROXY_IMPL_V2_H
+#define INCLUDED_UHD_TRANSPORT_NIRIO_NIRIO_PROXY_IMPL_V2_H
+
+#include <boost/smart_ptr.hpp>
+#include <boost/noncopyable.hpp>
+#include <uhd/transport/nirio/nirio_driver_iface.h>
+#include <uhd/transport/nirio/nirio_quirks.h>
+#include <uhd/transport/nirio/niriok_proxy.h>
+
+#if __GNUC__
+ typedef uint64_t tAlignedU64 __attribute__ ((aligned(8)));
+#else
+ typedef uint64_t tAlignedU64;
+#endif
+
+namespace uhd { namespace niusrprio
+{
+ /*
+ This file defines the types, enumerations, and classes needed to
+ directly access a subset of the NI-RIO kernel interface.
+ These definitions are specific to NI-RIO versions >= 14.0. These
+ are not compatible with NI-RIO versions older than 14.0.
+ */
+
+ #define IOCTL(type, function, access) \
+ CTL_CODE((0x8000+type), (0x800+function), METHOD_BUFFERED, access)
+
+ #define IOCTL_ACCESS_ANY (FILE_ANY_ACCESS)
+ #define IOCTL_ACCESS_READ (FILE_READ_ACCESS)
+ #define IOCTL_ACCESS_WRITE (FILE_WRITE_ACCESS)
+ #define IOCTL_ACCESS_RW (FILE_READ_ACCESS | FILE_WRITE_ACCESS)
+
+ #define IOCTL_TRANSPORT_GET32 IOCTL(0, 0, IOCTL_ACCESS_READ)
+ #define IOCTL_TRANSPORT_SET32 IOCTL(0, 1, IOCTL_ACCESS_WRITE)
+ #define IOCTL_TRANSPORT_GET_STRING IOCTL(0, 2, IOCTL_ACCESS_READ)
+ #define IOCTL_TRANSPORT_SET_STRING IOCTL(0, 3, IOCTL_ACCESS_WRITE)
+ #define IOCTL_TRANSPORT_RESET IOCTL(1, 1, IOCTL_ACCESS_WRITE)
+ #define IOCTL_TRANSPORT_ADD_INPUT_FIFO_RESOURCE IOCTL(2, 0, IOCTL_ACCESS_ANY)
+ #define IOCTL_TRANSPORT_ADD_OUTPUT_FIFO_RESOURCE IOCTL(2, 1, IOCTL_ACCESS_ANY)
+ #define IOCTL_TRANSPORT_SET_DEVICE_CONFIG IOCTL(2, 3, IOCTL_ACCESS_WRITE)
+ #define IOCTL_TRANSPORT_FIFO_CONFIG IOCTL(4, 0, IOCTL_ACCESS_ANY)
+ #define IOCTL_TRANSPORT_FIFO_START IOCTL(4, 1, IOCTL_ACCESS_ANY)
+ #define IOCTL_TRANSPORT_FIFO_STOP IOCTL(4, 2, IOCTL_ACCESS_ANY)
+ #define IOCTL_TRANSPORT_FIFO_READ IOCTL(4, 3, IOCTL_ACCESS_READ)
+ #define IOCTL_TRANSPORT_FIFO_WRITE IOCTL(4, 4, IOCTL_ACCESS_WRITE)
+ #define IOCTL_TRANSPORT_FIFO_WAIT IOCTL(4, 5, IOCTL_ACCESS_ANY)
+ #define IOCTL_TRANSPORT_FIFO_GRANT IOCTL(4, 6, IOCTL_ACCESS_ANY)
+ #define IOCTL_TRANSPORT_FIFO_STOP_ALL IOCTL(4, 7, IOCTL_ACCESS_ANY)
+ #define IOCTL_TRANSPORT_PEEK64 IOCTL(5, 2, IOCTL_ACCESS_READ)
+ #define IOCTL_TRANSPORT_PEEK32 IOCTL(5, 3, IOCTL_ACCESS_READ)
+ #define IOCTL_TRANSPORT_POKE64 IOCTL(5, 6, IOCTL_ACCESS_WRITE)
+ #define IOCTL_TRANSPORT_POKE32 IOCTL(5, 7, IOCTL_ACCESS_WRITE)
+ #define IOCTL_TRANSPORT_POST_OPEN IOCTL(8, 0, IOCTL_ACCESS_ANY)
+ #define IOCTL_TRANSPORT_PRE_CLOSE IOCTL(8, 1, IOCTL_ACCESS_ANY)
+
+ typedef struct {
+ nirio_scalar_type_t scalarType;
+ nirio_u32_t bitWidth;
+ nirio_i32_t integerWordLength;
+ } nirio_fifo_data_type_t;
+
+ class UHD_API niriok_proxy_impl_v2 : virtual public niriok_proxy {
+ public:
+ typedef struct in_transport_get32
+ {
+ nirio_device_attribute32_t attribute;
+ int32_t status;
+ } in_transport_get32_t;
+ typedef struct out_transport_get32
+ {
+ uint32_t retVal__;
+ int32_t status;
+ } out_transport_get32_t;
+ typedef struct in_transport_set32
+ {
+ nirio_device_attribute32_t attribute;
+ uint32_t value;
+ int32_t status;
+ } in_transport_set32_t;
+ typedef struct out_transport_set32
+ {
+ int32_t status;
+ } out_transport_set32_t;
+ typedef struct out_transport_get_string
+ {
+ uint32_t stringLen;
+ int32_t status;
+ } out_transport_get_string_t;
+ typedef struct out_transport_set_string
+ {
+ int32_t status;
+ } out_transport_set_string_t;
+ typedef struct in_transport_reset
+ {
+ int32_t status;
+ } in_transport_reset_t;
+ typedef struct out_transport_reset
+ {
+ int32_t status;
+ } out_transport_reset_t;
+ typedef struct in_transport_add_input_fifo_resource
+ {
+ uint32_t channel;
+ uint32_t baseAddress;
+ uint32_t depthInSamples;
+ nirio_fifo_data_type_t dataType;
+ uint32_t version;
+ int32_t status;
+ } in_transport_add_input_fifo_resource_t;
+ typedef struct out_transport_addInputFifo_resource
+ {
+ int32_t status;
+ } out_transport_add_input_fifo_resource_t;
+ typedef struct in_transport_addOutputFifo_resource
+ {
+ uint32_t channel;
+ uint32_t baseAddress;
+ uint32_t depthInSamples;
+ nirio_fifo_data_type_t dataType;
+ uint32_t version;
+ int32_t status;
+ } in_transport_add_output_fifo_resource_t;
+ typedef struct out_transport_addOutputFifo_resource
+ {
+ int32_t status;
+ } out_transport_add_output_fifo_resource_t;
+ typedef struct in_transport_setDevice_config
+ {
+ uint32_t attribute;
+ int32_t status;
+ } in_transport_set_device_config_t;
+ typedef struct out_transport_setDevice_config
+ {
+ int32_t status;
+ } out_transport_set_device_config_t;
+ typedef struct in_transport_fifo_config
+ {
+ uint32_t channel;
+ tAlignedU64 requestedDepth;
+ int32_t status;
+ } in_transport_fifo_config_t;
+ typedef struct out_transport_fifo_config
+ {
+ tAlignedU64 actualDepth;
+ tAlignedU64 actualSize;
+ int32_t status;
+ } out_transport_fifo_config_t;
+ typedef struct in_transport_fifo_start
+ {
+ uint32_t channel;
+ int32_t status;
+ } in_transport_fifo_start_t;
+ typedef struct out_transport_fifo_start
+ {
+ int32_t status;
+ } out_transport_fifo_start_t;
+ typedef struct in_transport_fifo_stop
+ {
+ uint32_t channel;
+ int32_t status;
+ } in_transport_fifo_stop_t;
+ typedef struct out_transport_fifo_stop
+ {
+ int32_t status;
+ } out_transport_fifo_stop_t;
+ typedef struct in_transport_fifo_read
+ {
+ uint32_t channel;
+ tAlignedU64 buf;
+ uint32_t numberElements;
+ nirio_fifo_data_type_t dataType;
+ uint32_t timeout;
+ int32_t status;
+ } in_transport_fifo_read_t;
+ typedef struct out_transport_fifo_read
+ {
+ uint32_t read;
+ uint32_t remaining;
+ int32_t status;
+ } out_transport_fifo_read_t;
+ typedef struct in_transport_fifo_write
+ {
+ uint32_t channel;
+ tAlignedU64 buf;
+ uint32_t numberElements;
+ nirio_fifo_data_type_t dataType;
+ uint32_t timeout;
+ int32_t status;
+ } in_transport_fifo_write_t;
+ typedef struct out_transport_fifo_write
+ {
+ uint32_t remaining;
+ int32_t status;
+ } out_transport_fifo_write_t;
+ typedef struct in_transport_fifo_wait
+ {
+ uint32_t channel;
+ tAlignedU64 elementsRequested;
+ nirio_fifo_data_type_t dataType;
+ bool output;
+ uint32_t timeout;
+ int32_t status;
+ } in_transport_fifo_wait_t;
+ typedef struct out_transport_fifo_wait
+ {
+ tAlignedU64 elements;
+ tAlignedU64 elementsAcquired;
+ tAlignedU64 elementsRemaining;
+ int32_t status;
+ } out_transport_fifo_wait_t;
+ typedef struct in_transport_fifo_grant
+ {
+ uint32_t channel;
+ tAlignedU64 elements;
+ int32_t status;
+ } in_transport_fifo_grant_t;
+ typedef struct out_transport_fifo_grant
+ {
+ int32_t status;
+ } out_transport_fifo_grant_t;
+ typedef struct in_transport_fifoStop_all
+ {
+ int32_t status;
+ } in_transport_fifo_stop_all_t;
+ typedef struct out_transport_fifoStop_all
+ {
+ int32_t status;
+ } out_transport_fifo_stop_all_t;
+ typedef struct in_transport_peek64
+ {
+ uint32_t offset;
+ int32_t status;
+ } in_transport_peek64_t;
+ typedef struct out_transport_peek64
+ {
+ tAlignedU64 retVal__;
+ int32_t status;
+ } out_transport_peek64_t;
+ typedef struct in_transport_peek32
+ {
+ uint32_t offset;
+ int32_t status;
+ } in_transport_peek32_t;
+ typedef struct out_transport_peek32
+ {
+ uint32_t retVal__;
+ int32_t status;
+ } out_transport_peek32_t;
+ typedef struct in_transport_poke64
+ {
+ uint32_t offset;
+ tAlignedU64 value;
+ int32_t status;
+ } in_transport_poke64_t;
+ typedef struct out_transport_poke64
+ {
+ int32_t status;
+ } out_transport_poke64_t;
+ typedef struct in_transport_poke32
+ {
+ uint32_t offset;
+ uint32_t value;
+ int32_t status;
+ } in_transport_poke32_t;
+ typedef struct out_transport_poke32
+ {
+ int32_t status;
+ } out_transport_poke32_t;
+ typedef struct in_transport_post_open
+ {
+ int32_t status;
+ } in_transport_post_open_t;
+ typedef struct out_transport_post_open
+ {
+ int32_t status;
+ } out_transport_post_open_t;
+ typedef struct in_transport_pre_close
+ {
+ int32_t status;
+ } in_transport_pre_close_t;
+ typedef struct out_transport_pre_close
+ {
+ int32_t status;
+ } out_transport_pre_close_t;
+
+ niriok_proxy_impl_v2();
+ virtual ~niriok_proxy_impl_v2();
+
+ //File operations
+ virtual nirio_status open(const std::string& interface_path);
+ virtual void close(void);
+
+ virtual nirio_status reset();
+
+ virtual nirio_status get_cached_session(
+ uint32_t& session);
+
+ virtual nirio_status get_version(
+ nirio_version_t type,
+ uint32_t& major,
+ uint32_t& upgrade,
+ uint32_t& maintenance,
+ char& phase,
+ uint32_t& build);
+
+ virtual nirio_status get_attribute(
+ const nirio_device_attribute32_t attribute,
+ uint32_t& attrValue);
+
+ virtual nirio_status set_attribute(
+ const nirio_device_attribute32_t attribute,
+ const uint32_t value);
+
+ virtual nirio_status peek(uint32_t offset, uint32_t& value);
+
+ virtual nirio_status peek(uint32_t offset, uint64_t& value);
+
+ virtual nirio_status poke(uint32_t offset, const uint32_t& value);
+
+ virtual nirio_status poke(uint32_t offset, const uint64_t& value);
+
+ virtual nirio_status map_fifo_memory(
+ uint32_t fifo_instance,
+ size_t size,
+ nirio_driver_iface::rio_mmap_t& map);
+
+ virtual nirio_status unmap_fifo_memory(
+ nirio_driver_iface::rio_mmap_t& map);
+
+ virtual nirio_status stop_all_fifos();
+
+ virtual nirio_status add_fifo_resource(const nirio_fifo_info_t& fifo_info);
+
+ virtual nirio_status set_device_config();
+
+ virtual nirio_status start_fifo(
+ uint32_t channel);
+
+ virtual nirio_status stop_fifo(
+ uint32_t channel);
+
+ virtual nirio_status configure_fifo(
+ uint32_t channel,
+ uint32_t requested_depth,
+ uint8_t requires_actuals,
+ uint32_t& actual_depth,
+ uint32_t& actual_size);
+
+ virtual nirio_status wait_on_fifo(
+ uint32_t channel,
+ uint32_t elements_requested,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint8_t output,
+ void*& data_pointer,
+ uint32_t& elements_acquired,
+ uint32_t& elements_remaining);
+
+ virtual nirio_status grant_fifo(
+ uint32_t channel,
+ uint32_t elements_to_grant);
+
+ virtual nirio_status read_fifo(
+ uint32_t channel,
+ uint32_t elements_to_read,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_read,
+ uint32_t& number_remaining);
+
+ virtual nirio_status write_fifo(
+ uint32_t channel,
+ uint32_t elements_to_write,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_remaining);
+
+ protected:
+ // protected close function that doesn't acquire synchronization lock
+ virtual void _close();
+
+ };
+
+}}
+
+#endif /* INCLUDED_UHD_TRANSPORT_NIRIO_NIRIO_PROXY_IMPL_V2_H */
diff --git a/host/include/uhd/transport/nirio/niusrprio_session.h b/host/include/uhd/transport/nirio/niusrprio_session.h
index a684d98ae..246888175 100644
--- a/host/include/uhd/transport/nirio/niusrprio_session.h
+++ b/host/include/uhd/transport/nirio/niusrprio_session.h
@@ -91,7 +91,7 @@ public:
return create_rx_fifo(_lvbitx->get_input_fifo_names()[fifo_instance], fifo);
}
- niriok_proxy& get_kernel_proxy() {
+ UHD_INLINE niriok_proxy::sptr get_kernel_proxy() {
return _riok_proxy;
}
@@ -112,7 +112,7 @@ private:
nifpga_lvbitx::sptr _lvbitx;
std::string _interface_path;
bool _session_open;
- niriok_proxy _riok_proxy;
+ niriok_proxy::sptr _riok_proxy;
nirio_resource_manager _resource_manager;
usrprio_rpc::usrprio_rpc_client _rpc_client;
boost::recursive_mutex _session_mutex;
diff --git a/host/lib/device.cpp b/host/lib/device.cpp
index 453781510..006ea6ec8 100644
--- a/host/lib/device.cpp
+++ b/host/lib/device.cpp
@@ -47,9 +47,16 @@ static size_t hash_device_addr(
){
//combine the hashes of sorted keys/value pairs
size_t hash = 0;
- BOOST_FOREACH(const std::string &key, uhd::sorted(dev_addr.keys())){
- boost::hash_combine(hash, key);
- boost::hash_combine(hash, dev_addr[key]);
+
+ if(dev_addr.has_key("resource")) {
+ boost::hash_combine(hash, "resource");
+ boost::hash_combine(hash, dev_addr["resource"]);
+ }
+ else {
+ BOOST_FOREACH(const std::string &key, uhd::sorted(dev_addr.keys())){
+ boost::hash_combine(hash, key);
+ boost::hash_combine(hash, dev_addr[key]);
+ }
}
return hash;
}
diff --git a/host/lib/transport/nirio/CMakeLists.txt b/host/lib/transport/nirio/CMakeLists.txt
index 5f12e91df..99beda056 100644
--- a/host/lib/transport/nirio/CMakeLists.txt
+++ b/host/lib/transport/nirio/CMakeLists.txt
@@ -33,6 +33,8 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/nifpga_lvbitx.cpp
${CMAKE_CURRENT_SOURCE_DIR}/niusrprio_session.cpp
${CMAKE_CURRENT_SOURCE_DIR}/niriok_proxy.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/niriok_proxy_impl_v1.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/niriok_proxy_impl_v2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/nirio_resource_manager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/status.cpp
)
diff --git a/host/lib/transport/nirio/lvbitx/process-lvbitx.py b/host/lib/transport/nirio/lvbitx/process-lvbitx.py
index a3d88d0bb..ab9625608 100755
--- a/host/lib/transport/nirio/lvbitx/process-lvbitx.py
+++ b/host/lib/transport/nirio/lvbitx/process-lvbitx.py
@@ -101,6 +101,31 @@ codegen_transform['control_list'] = control_list
codegen_transform['indicator_list'] = indicator_list
# Enumerate FIFOs
+
+# This function takes a SubType string as specified in an lvbitx file and finds the
+# corresponding nirio_scalar_type_t value.
+def map_SubType_to_ScalarType(SubType):
+ if SubType == 'I8':
+ ScalarType = 'RIO_SCALAR_TYPE_IB'
+ elif SubType == 'I16':
+ ScalarType = 'RIO_SCALAR_TYPE_IW'
+ elif SubType == 'I32':
+ ScalarType = 'RIO_SCALAR_TYPE_IL'
+ elif SubType == 'I64':
+ ScalarType = 'RIO_SCALAR_TYPE_IQ'
+ elif SubType == 'U8':
+ ScalarType = 'RIO_SCALAR_TYPE_UB'
+ elif SubType == 'U16':
+ ScalarType = 'RIO_SCALAR_TYPE_UW'
+ elif SubType == 'U32':
+ ScalarType = 'RIO_SCALAR_TYPE_UL'
+ elif SubType == 'U64':
+ ScalarType = 'RIO_SCALAR_TYPE_UQ'
+ else:
+ print 'ERROR: No corresponding nirio_scalar_type_t value for SubType ' + SubType + ' .'
+ sys.exit(1)
+ return ScalarType;
+
nifpga_metadata = root.find('Project').find('CompilationResultsTree').find('CompilationResults').find('NiFpga')
dma_channel_list = nifpga_metadata.find('DmaChannelAllocationList')
reg_block_list = nifpga_metadata.find('RegisterBlockList')
@@ -133,8 +158,9 @@ for dma_channel in dma_channel_list:
fifo_init_seq += direction + ', '
fifo_init_seq += str.lower(base_addr) + ', '
fifo_init_seq += dma_channel.find('NumberOfElements').text + ', '
- fifo_init_seq += 'SCALAR_' + dma_channel.find('DataType').find('SubType').text + ', '
+ fifo_init_seq += map_SubType_to_ScalarType(dma_channel.find('DataType').find('SubType').text) + ', '
fifo_init_seq += dma_channel.find('DataType').find('WordLength').text + ', '
+ fifo_init_seq += dma_channel.find('DataType').find('IntegerWordLength').text + ', '
fifo_init_seq += bitstream_version
fifo_init_seq += ')); //' + fifo_name
diff --git a/host/lib/transport/nirio/nirio_driver_iface_linux.cpp b/host/lib/transport/nirio/nirio_driver_iface_linux.cpp
index b1f4bb49f..cccf4f8f9 100644
--- a/host/lib/transport/nirio/nirio_driver_iface_linux.cpp
+++ b/host/lib/transport/nirio/nirio_driver_iface_linux.cpp
@@ -25,6 +25,17 @@
namespace nirio_driver_iface {
+struct nirio_ioctl_block_t
+{
+ uint64_t inBuf;
+ uint64_t outBuf;
+ uint32_t inBufLength;
+ uint32_t outBufLength;
+ uint32_t bytesReturned;
+ uint32_t padding;
+};
+
+
nirio_status rio_open(
const std::string& device_path,
rio_dev_handle_t& device_handle)
diff --git a/host/lib/transport/nirio/nirio_resource_manager.cpp b/host/lib/transport/nirio/nirio_resource_manager.cpp
index 85e789087..e56670de0 100644
--- a/host/lib/transport/nirio/nirio_resource_manager.cpp
+++ b/host/lib/transport/nirio/nirio_resource_manager.cpp
@@ -27,11 +27,16 @@
namespace uhd { namespace niusrprio
{
-nirio_resource_manager::nirio_resource_manager(
- niriok_proxy& proxy) : _kernel_proxy(proxy), _fifo_info_map(), _reg_info_map()
+nirio_resource_manager::nirio_resource_manager():_fifo_info_map(), _reg_info_map()
{
}
+void nirio_resource_manager::set_proxy(niriok_proxy::sptr proxy)
+{
+ _kernel_proxy = proxy;
+}
+
+
nirio_resource_manager::~nirio_resource_manager()
{
finalize();
@@ -78,32 +83,12 @@ nirio_status nirio_resource_manager::get_register_offset(
nirio_status nirio_resource_manager::_add_fifo_resource(
const nirio_fifo_info_t& fifo_info)
{
- 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::ADD_RESOURCE;
- in.subfunction = (fifo_info.direction == OUTPUT_FIFO) ?
- nirio_driver_iface::NIRIO_RESOURCE::OUTPUT_FIFO :
- nirio_driver_iface::NIRIO_RESOURCE::INPUT_FIFO;
-
- in.params.add.fifoWithDataType.channel = fifo_info.channel;
- in.params.add.fifoWithDataType.baseAddress = fifo_info.base_addr;
- in.params.add.fifoWithDataType.depthInSamples = fifo_info.depth;
- in.params.add.fifoWithDataType.scalarType = fifo_info.scalar_type;
- in.params.add.fifoWithDataType.bitWidth = fifo_info.width;
- in.params.add.fifoWithDataType.version = fifo_info.version;
-
- return _kernel_proxy.sync_operation(&in, sizeof(in), &out, sizeof(out));
+ return _kernel_proxy->add_fifo_resource(fifo_info);
}
nirio_status nirio_resource_manager::_set_driver_config()
{
- 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::SET_DRIVER_CONFIG;
- in.subfunction = 0;
-
- return _kernel_proxy.sync_operation(&in, sizeof(in), &out, sizeof(out));
+ return _kernel_proxy->set_device_config();
}
nirio_fifo_info_t* nirio_resource_manager::_lookup_fifo_info(const char* fifo_name) {
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__
diff --git a/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp b/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp
new file mode 100644
index 000000000..7ef0e3645
--- /dev/null
+++ b/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp
@@ -0,0 +1,494 @@
+//
+// Copyright 2013-2014 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+
+#include <uhd/transport/nirio/niriok_proxy_impl_v1.h>
+#include <cstring>
+
+#ifdef __clang__
+ #pragma GCC diagnostic push ignored "-Wmissing-field-initializers"
+#elif defined(__GNUC__)
+ #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+namespace uhd { namespace niusrprio
+{
+ //-------------------------------------------------------
+ // niriok_proxy_impl_v1
+ //-------------------------------------------------------
+ niriok_proxy_impl_v1::niriok_proxy_impl_v1()
+ {
+ }
+
+ niriok_proxy_impl_v1::~niriok_proxy_impl_v1()
+ {
+ close();
+ }
+
+ nirio_status niriok_proxy_impl_v1::open(const std::string& interface_path)
+ {
+ WRITER_LOCK
+
+ if (interface_path.empty()) return NiRio_Status_ResourceNotFound;
+
+ //close if already open.
+ // use non-locking _close since we already have the lock
+ _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_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_impl_v1::close(void)
+ {
+ WRITER_LOCK
+
+ _close();
+ }
+
+ // this protected _close doesn't acquire the lock, so it can be used in methods
+ // that already have the lock
+ void niriok_proxy_impl_v1::_close()
+ {
+
+ 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_impl_v1::reset()
+ {
+ READER_LOCK
+
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::RESET;
+
+ return sync_operation(&in, sizeof(in), &out, sizeof(out));
+ }
+
+ nirio_status niriok_proxy_impl_v1::get_cached_session(
+ uint32_t& session)
+ {
+ READER_LOCK
+
+ 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));
+ }
+
+ nirio_status niriok_proxy_impl_v1::get_version(
+ nirio_version_t type,
+ uint32_t& major,
+ uint32_t& upgrade,
+ uint32_t& maintenance,
+ char& phase,
+ uint32_t& build)
+ {
+ nirio_device_attribute32_t version_attr = (type==CURRENT)?RIO_CURRENT_VERSION:RIO_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;
+ }
+
+ nirio_status niriok_proxy_impl_v1::sync_operation(
+ const void *writeBuffer,
+ size_t writeBufferLength,
+ void *readBuffer,
+ size_t readBufferLength)
+ {
+ READER_LOCK
+
+ 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_impl_v1::get_attribute(
+ const nirio_device_attribute32_t attribute,
+ uint32_t& attrValue)
+ {
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::GET32;
+ in.params.attribute32.attribute = static_cast <uint32_t> (attribute);
+
+ nirio_status status = sync_operation(&in, sizeof(in), &out, sizeof(out));
+
+ attrValue = out.params.attribute32.value;
+ return status;
+ }
+
+ nirio_status niriok_proxy_impl_v1::set_attribute(
+ const nirio_device_attribute32_t attribute,
+ const uint32_t value)
+ {
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::SET32;
+ in.params.attribute32.attribute = static_cast <uint32_t> (attribute);
+ in.params.attribute32.value = value;
+
+ return sync_operation(&in, sizeof(in), &out, sizeof(out));
+ }
+
+ nirio_status niriok_proxy_impl_v1::peek(uint32_t offset, uint32_t& value)
+ {
+ if (offset % 4 != 0) return NiRio_Status_MisalignedAccess;
+
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::IO;
+ in.subfunction = 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_impl_v1::peek(uint32_t offset, uint64_t& value)
+ {
+ if (offset % 8 != 0) return NiRio_Status_MisalignedAccess;
+
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::IO;
+ in.subfunction = 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_impl_v1::poke(uint32_t offset, const uint32_t& value)
+ {
+ if (offset % 4 != 0) return NiRio_Status_MisalignedAccess;
+
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::IO;
+ in.subfunction = 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_impl_v1::poke(uint32_t offset, const uint64_t& value)
+ {
+ if (offset % 8 != 0) return NiRio_Status_MisalignedAccess;
+
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::IO;
+ in.subfunction = 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_impl_v1::map_fifo_memory(
+ uint32_t fifo_instance,
+ size_t size,
+ nirio_driver_iface::rio_mmap_t& map)
+ {
+ READER_LOCK
+
+ return nirio_driver_iface::rio_mmap(_device_handle,
+ GET_FIFO_MEMORY_TYPE(fifo_instance),
+ size, true, map);
+ }
+
+ nirio_status niriok_proxy_impl_v1::unmap_fifo_memory(
+ nirio_driver_iface::rio_mmap_t& map)
+ {
+ READER_LOCK
+
+ return nirio_driver_iface::rio_munmap(map);
+ }
+
+ nirio_status niriok_proxy_impl_v1::stop_all_fifos()
+ {
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::FIFO_STOP_ALL;
+
+ return sync_operation(&in, sizeof(in), &out, sizeof(out));
+ }
+
+ nirio_status niriok_proxy_impl_v1::add_fifo_resource(const nirio_fifo_info_t& fifo_info)
+ {
+ niriok_proxy_impl_v1::nirio_syncop_in_params_t in = {};
+ niriok_proxy_impl_v1::nirio_syncop_out_params_t out = {};
+
+ in.function = niriok_proxy_impl_v1::NIRIO_FUNC::ADD_RESOURCE;
+ in.subfunction = (fifo_info.direction == OUTPUT_FIFO) ?
+ niriok_proxy_impl_v1::NIRIO_RESOURCE::OUTPUT_FIFO :
+ niriok_proxy_impl_v1::NIRIO_RESOURCE::INPUT_FIFO;
+
+ in.params.add.fifoWithDataType.channel = fifo_info.channel;
+ in.params.add.fifoWithDataType.baseAddress = fifo_info.base_addr;
+ in.params.add.fifoWithDataType.depthInSamples = fifo_info.depth;
+ in.params.add.fifoWithDataType.scalarType = static_cast <uint32_t> (fifo_info.scalar_type);
+ in.params.add.fifoWithDataType.bitWidth = fifo_info.bitWidth;
+ in.params.add.fifoWithDataType.version = fifo_info.version;
+ //fifo_info.integerWordLength is not needed by the v1 kernel interface
+
+ return sync_operation(&in, sizeof(in), &out, sizeof(out));
+ }
+
+ nirio_status niriok_proxy_impl_v1::set_device_config()
+ {
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = niriok_proxy_impl_v1::NIRIO_FUNC::SET_DRIVER_CONFIG;
+ in.subfunction = 0;
+
+ return sync_operation(&in, sizeof(in), &out, sizeof(out));
+ }
+
+ nirio_status niriok_proxy_impl_v1::start_fifo(
+ uint32_t channel)
+ {
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::FIFO;
+ in.subfunction = NIRIO_FIFO::START;
+
+ in.params.fifo.channel = channel;
+
+ return sync_operation(&in, sizeof(in), &out, sizeof(out));
+ }
+
+ nirio_status niriok_proxy_impl_v1::stop_fifo(
+ uint32_t channel)
+ {
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::FIFO;
+ in.subfunction = NIRIO_FIFO::STOP;
+
+ in.params.fifo.channel = channel;
+
+ return sync_operation(&in, sizeof(in), &out, sizeof(out));
+ }
+
+ nirio_status niriok_proxy_impl_v1::configure_fifo(
+ uint32_t channel,
+ uint32_t requested_depth,
+ uint8_t requires_actuals,
+ uint32_t& actual_depth,
+ uint32_t& actual_size)
+ {
+ nirio_status status = NiRio_Status_Success;
+
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::FIFO;
+ in.subfunction = NIRIO_FIFO::CONFIGURE;
+
+ in.params.fifo.channel = channel;
+ in.params.fifo.op.config.requestedDepth = requested_depth;
+ in.params.fifo.op.config.requiresActuals = requires_actuals;
+
+ status = sync_operation(&in, sizeof(in), &out, sizeof(out));
+ if (nirio_status_fatal(status)) return status;
+
+ actual_depth = out.params.fifo.op.config.actualDepth;
+ actual_size = out.params.fifo.op.config.actualSize;
+
+ return status;
+ }
+
+ nirio_status niriok_proxy_impl_v1::wait_on_fifo(
+ uint32_t channel,
+ uint32_t elements_requested,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint8_t output,
+ void*& data_pointer,
+ uint32_t& elements_acquired,
+ uint32_t& elements_remaining)
+ {
+ nirio_status status = NiRio_Status_Success;
+
+ nirio_syncop_in_params_t in = {};
+ uint32_t stuffed[2];
+ nirio_syncop_out_params_t out = {};
+ init_syncop_out_params(out, stuffed, sizeof(stuffed));
+
+ in.function = NIRIO_FUNC::FIFO;
+ in.subfunction = NIRIO_FIFO::WAIT;
+
+ in.params.fifo.channel = channel;
+ in.params.fifo.op.wait.elementsRequested = elements_requested;
+ in.params.fifo.op.wait.scalarType = scalar_type;
+ in.params.fifo.op.wait.bitWidth = bit_width;
+ in.params.fifo.op.wait.output = output;
+ in.params.fifo.op.wait.timeout = timeout;
+
+ status = sync_operation(&in, sizeof(in), &out, sizeof(out));
+ if (nirio_status_fatal(status)) return status;
+
+ data_pointer = out.params.fifo.op.wait.elements.pointer;
+ elements_acquired = stuffed[0];
+ elements_remaining = stuffed[1];
+
+ return status;
+ }
+
+ nirio_status niriok_proxy_impl_v1::grant_fifo(
+ uint32_t channel,
+ uint32_t elements_to_grant)
+ {
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::FIFO;
+ in.subfunction = NIRIO_FIFO::GRANT;
+
+ in.params.fifo.channel = channel;
+ in.params.fifo.op.grant.elements = elements_to_grant;
+
+ return sync_operation(&in, sizeof(in), &out, sizeof(out));
+ }
+
+ nirio_status niriok_proxy_impl_v1::read_fifo(
+ uint32_t channel,
+ uint32_t elements_to_read,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_read,
+ uint32_t& number_remaining)
+ {
+ nirio_status status = NiRio_Status_Success;
+
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
+ init_syncop_out_params(out, buffer, elements_to_read * buffer_datatype_width);
+
+ in.function = NIRIO_FUNC::FIFO;
+ in.subfunction = NIRIO_FIFO::READ;
+
+ in.params.fifo.channel = channel;
+ in.params.fifo.op.readWithDataType.timeout = timeout;
+ in.params.fifo.op.readWithDataType.scalarType = scalar_type;
+ in.params.fifo.op.readWithDataType.bitWidth = bit_width;
+
+ status = sync_operation(&in, sizeof(in), &out, sizeof(out));
+ if (nirio_status_fatal(status) && (status != NiRio_Status_FifoTimeout)) return status;
+
+ number_read = out.params.fifo.op.read.numberRead;
+ number_remaining = out.params.fifo.op.read.numberRemaining;
+
+ return status;
+ }
+
+ nirio_status niriok_proxy_impl_v1::write_fifo(
+ uint32_t channel,
+ uint32_t elements_to_write,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_remaining)
+ {
+ nirio_status status = NiRio_Status_Success;
+
+ nirio_syncop_in_params_t in = {};
+ init_syncop_in_params(in, buffer, elements_to_write * buffer_datatype_width);
+ nirio_syncop_out_params_t out = {};
+
+ in.function = NIRIO_FUNC::FIFO;
+ in.subfunction = NIRIO_FIFO::WRITE;
+
+ in.params.fifo.channel = channel;
+ in.params.fifo.op.writeWithDataType.timeout = timeout;
+ in.params.fifo.op.writeWithDataType.scalarType = scalar_type;
+ in.params.fifo.op.writeWithDataType.bitWidth = bit_width;
+
+ status = sync_operation(&in, sizeof(in), &out, sizeof(out));
+ if (nirio_status_fatal(status) && (status != NiRio_Status_FifoTimeout)) return status;
+
+ number_remaining = out.params.fifo.op.write.numberRemaining;
+
+ return status;
+ }
+
+}}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif
diff --git a/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp b/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp
new file mode 100644
index 000000000..09daa7862
--- /dev/null
+++ b/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp
@@ -0,0 +1,647 @@
+//
+// Copyright 2013-2014 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+
+#include <uhd/transport/nirio/niriok_proxy_impl_v2.h>
+#include <cstring>
+
+#ifdef __clang__
+ #pragma GCC diagnostic push ignored "-Wmissing-field-initializers"
+#elif defined(__GNUC__)
+ #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+namespace uhd { namespace niusrprio
+{
+ //-------------------------------------------------------
+ // niriok_proxy_impl_v2
+ //-------------------------------------------------------
+ niriok_proxy_impl_v2::niriok_proxy_impl_v2()
+ {
+ }
+
+ niriok_proxy_impl_v2::~niriok_proxy_impl_v2()
+ {
+ close();
+ }
+
+ nirio_status niriok_proxy_impl_v2::open(const std::string& interface_path)
+ {
+ WRITER_LOCK
+
+ if (interface_path.empty()) return NiRio_Status_ResourceNotFound;
+
+ //close if already open.
+ // use non-locking _close since we already have the lock
+ _close();
+
+ in_transport_post_open_t in = {};
+ out_transport_post_open_t out = {};
+
+ in.status = NiRio_Status_Success;
+
+ 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,
+ IOCTL_TRANSPORT_POST_OPEN,
+ &in, sizeof(in), &out, sizeof(out)), status);
+ if (nirio_status_fatal(status)) _close();
+ }
+ return status;
+ }
+
+ void niriok_proxy_impl_v2::close(void)
+ {
+ WRITER_LOCK
+
+ _close();
+ }
+
+ // this protected _close doesn't acquire the lock, so it can be used in methods
+ // that already have the lock
+ void niriok_proxy_impl_v2::_close()
+ {
+ if(nirio_driver_iface::rio_isopen(_device_handle))
+ {
+ in_transport_pre_close_t in = {};
+ out_transport_pre_close_t out = {};
+
+ in.status = NiRio_Status_Success;
+
+ nirio_driver_iface::rio_ioctl(
+ _device_handle, IOCTL_TRANSPORT_PRE_CLOSE, &in, sizeof(in), &out, sizeof(out));
+ nirio_driver_iface::rio_close(_device_handle);
+ }
+ }
+
+ nirio_status niriok_proxy_impl_v2::reset()
+ {
+ READER_LOCK
+
+ in_transport_reset_t in = {};
+ out_transport_reset_t out = {};
+
+ in.status = NiRio_Status_Success;
+
+ nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_RESET,
+ &in, sizeof(in), &out, sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::get_cached_session(
+ uint32_t& session)
+ {
+ READER_LOCK
+
+ 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));
+ }
+
+ nirio_status niriok_proxy_impl_v2::get_version(
+ nirio_version_t type,
+ uint32_t& major,
+ uint32_t& upgrade,
+ uint32_t& maintenance,
+ char& phase,
+ uint32_t& build)
+ {
+ nirio_device_attribute32_t version_attr = (type==CURRENT)?RIO_CURRENT_VERSION:RIO_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;
+ }
+
+ nirio_status niriok_proxy_impl_v2::get_attribute(
+ const nirio_device_attribute32_t attribute,
+ uint32_t& attrValue)
+ {
+ READER_LOCK
+
+ in_transport_get32_t in = {};
+ out_transport_get32_t out = {};
+
+ in.attribute = attribute;
+ in.status = NiRio_Status_Success;
+
+ nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_GET32,
+ &in, sizeof(in),
+ &out, sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ attrValue = out.retVal__;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::set_attribute(
+ const nirio_device_attribute32_t attribute,
+ const uint32_t value)
+ {
+ READER_LOCK
+
+ in_transport_set32_t in = {};
+ out_transport_set32_t out = {};
+
+ in.attribute = attribute;
+ in.value = value;
+ in.status = NiRio_Status_Success;
+
+ nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_SET32,
+ &in, sizeof(in),
+ &out, sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::peek(uint32_t offset, uint32_t& value)
+ {
+ READER_LOCK
+
+ if (offset % 4 != 0) return NiRio_Status_MisalignedAccess;
+
+ in_transport_peek32_t in = {};
+ out_transport_peek32_t out = {};
+
+ in.offset = offset;
+ in.status = NiRio_Status_Success;
+
+ nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_PEEK32,
+ &in, sizeof(in),
+ &out, sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ value = out.retVal__;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::peek(uint32_t offset, uint64_t& value)
+ {
+ READER_LOCK
+
+ if (offset % 8 != 0) return NiRio_Status_MisalignedAccess;
+ in_transport_peek64_t in = {};
+ out_transport_peek64_t out = {};
+
+ in.offset = offset;
+ in.status = NiRio_Status_Success;
+
+ nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_PEEK64,
+ &in, sizeof(in),
+ &out, sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ value = out.retVal__;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::poke(uint32_t offset, const uint32_t& value)
+ {
+ READER_LOCK
+
+ if (offset % 4 != 0) return NiRio_Status_MisalignedAccess;
+
+ in_transport_poke32_t in = {};
+ out_transport_poke32_t out = {};
+
+ in.offset = offset;
+ in.value = value;
+ in.status = NiRio_Status_Success;
+
+ nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_POKE32,
+ &in, sizeof(in),
+ &out, sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::poke(uint32_t offset, const uint64_t& value)
+ {
+ READER_LOCK
+
+ if (offset % 8 != 0) return NiRio_Status_MisalignedAccess;
+
+ in_transport_poke64_t in = {};
+ out_transport_poke64_t out = {};
+
+ in.offset = offset;
+ in.value = value;
+ in.status = NiRio_Status_Success;
+
+ nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_POKE64,
+ &in, sizeof(in),
+ &out, sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::map_fifo_memory(
+ uint32_t fifo_instance,
+ size_t size,
+ nirio_driver_iface::rio_mmap_t& map)
+ {
+ READER_LOCK
+
+ return nirio_driver_iface::rio_mmap(_device_handle,
+ GET_FIFO_MEMORY_TYPE(fifo_instance),
+ size, true, map);
+ }
+
+ nirio_status niriok_proxy_impl_v2::unmap_fifo_memory(
+ nirio_driver_iface::rio_mmap_t& map)
+ {
+ READER_LOCK
+
+ return nirio_driver_iface::rio_munmap(map);
+ }
+
+ nirio_status niriok_proxy_impl_v2::stop_all_fifos()
+ {
+ READER_LOCK
+
+ nirio_status ioctl_status = NiRio_Status_Success;
+ in_transport_fifo_stop_all_t in = {};
+ out_transport_fifo_stop_all_t out = {};
+
+ in.status = NiRio_Status_Success;
+
+ ioctl_status =
+ nirio_driver_iface::rio_ioctl(
+ _device_handle,
+ IOCTL_TRANSPORT_FIFO_STOP_ALL,
+ &in,
+ sizeof(in),
+ &out,
+ sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::add_fifo_resource(const nirio_fifo_info_t& fifo_info)
+ {
+ READER_LOCK
+
+ nirio_status status = NiRio_Status_Success;
+ nirio_status ioctl_status = NiRio_Status_Success;
+
+ switch(fifo_info.direction)
+ {
+ case INPUT_FIFO:
+ {
+ in_transport_add_input_fifo_resource_t in = {};
+ out_transport_add_input_fifo_resource_t out = {};
+
+ in.channel = fifo_info.channel;
+ in.baseAddress = fifo_info.base_addr;
+ in.depthInSamples = fifo_info.depth;
+ in.dataType.scalarType = fifo_info.scalar_type;
+ in.dataType.bitWidth = fifo_info.bitWidth;
+ in.dataType.integerWordLength = fifo_info.integerWordLength;
+ in.version = fifo_info.version;
+ in.status = NiRio_Status_Success;
+
+ ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_ADD_INPUT_FIFO_RESOURCE,
+ &in, sizeof(in),
+ &out, sizeof(out));
+
+ status = nirio_status_fatal(ioctl_status) ? ioctl_status : out.status;
+ break;
+ }
+ case OUTPUT_FIFO:
+ {
+ in_transport_add_output_fifo_resource_t in = {};
+ out_transport_add_output_fifo_resource_t out = {};
+
+ in.channel = fifo_info.channel;
+ in.baseAddress = fifo_info.base_addr;
+ in.depthInSamples = fifo_info.depth;
+ in.dataType.scalarType = fifo_info.scalar_type;
+ in.dataType.bitWidth = fifo_info.bitWidth;
+ in.dataType.integerWordLength = fifo_info.integerWordLength;
+ in.version = fifo_info.version;
+ in.status = NiRio_Status_Success;
+
+ ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_ADD_OUTPUT_FIFO_RESOURCE,
+ &in, sizeof(in),
+ &out, sizeof(out));
+
+ status = nirio_status_fatal(ioctl_status) ? ioctl_status : out.status;
+ break;
+ }
+ default:
+ status = NiRio_Status_SoftwareFault;
+ }
+
+ return status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::set_device_config()
+ {
+ READER_LOCK
+
+ nirio_status ioctl_status = NiRio_Status_Success;
+
+ in_transport_set_device_config_t in = {};
+ out_transport_set_device_config_t out = {};
+
+ in.attribute = 0; //this is unused in the kernel
+ in.status = NiRio_Status_Success;
+
+ ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
+ IOCTL_TRANSPORT_SET_DEVICE_CONFIG,
+ &in, sizeof(in),
+ &out, sizeof(out));
+
+ return nirio_status_fatal(ioctl_status) ? ioctl_status : out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::start_fifo(
+ uint32_t channel)
+ {
+ READER_LOCK
+
+ nirio_status ioctl_status = NiRio_Status_Success;
+ in_transport_fifo_start_t in = {};
+ out_transport_fifo_start_t out = {};
+
+ in.channel = channel;
+ in.status = NiRio_Status_Success;
+
+ ioctl_status =
+ nirio_driver_iface::rio_ioctl(
+ _device_handle,
+ IOCTL_TRANSPORT_FIFO_START,
+ &in,
+ sizeof(in),
+ &out,
+ sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::stop_fifo(
+ uint32_t channel)
+ {
+ READER_LOCK
+
+ nirio_status ioctl_status = NiRio_Status_Success;
+ in_transport_fifo_stop_t in = {};
+ out_transport_fifo_stop_t out = {};
+
+ in.channel = channel;
+ in.status = NiRio_Status_Success;
+
+ ioctl_status =
+ nirio_driver_iface::rio_ioctl(
+ _device_handle,
+ IOCTL_TRANSPORT_FIFO_STOP,
+ &in,
+ sizeof(in),
+ &out,
+ sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::configure_fifo(
+ uint32_t channel,
+ uint32_t requested_depth,
+ uint8_t requires_actuals,
+ uint32_t& actual_depth,
+ uint32_t& actual_size)
+ {
+ READER_LOCK
+
+ nirio_status ioctl_status = NiRio_Status_Success;
+ in_transport_fifo_config_t in = {};
+ out_transport_fifo_config_t out = {};
+
+ in.channel = channel;
+ in.requestedDepth = requested_depth;
+ in.status = NiRio_Status_Success;
+
+ ioctl_status =
+ nirio_driver_iface::rio_ioctl(
+ _device_handle,
+ IOCTL_TRANSPORT_FIFO_CONFIG,
+ &in,
+ sizeof(in),
+ &out,
+ sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ UHD_ASSERT_THROW(out.actualDepth <= std::numeric_limits<uint32_t>::max());
+ actual_depth = static_cast<uint32_t>(out.actualDepth);
+ UHD_ASSERT_THROW(out.actualSize <= std::numeric_limits<uint32_t>::max());
+ actual_size = static_cast<uint32_t>(out.actualSize);
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::wait_on_fifo(
+ uint32_t channel,
+ uint32_t elements_requested,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint8_t output,
+ void*& data_pointer,
+ uint32_t& elements_acquired,
+ uint32_t& elements_remaining)
+ {
+ READER_LOCK
+
+ nirio_status ioctl_status = NiRio_Status_Success;
+ in_transport_fifo_wait_t in = {};
+ out_transport_fifo_wait_t out = {};
+
+ in.channel = channel;
+ in.elementsRequested = elements_requested;
+ in.dataType.scalarType = map_int_to_scalar_type(scalar_type);
+ in.dataType.bitWidth = bit_width;
+ in.dataType.integerWordLength = bit_width; // same as bit_width for all types except fixed point, which is not supported
+ in.output = (output != 0);
+ in.timeout = timeout;
+ in.status = NiRio_Status_Success;
+
+ ioctl_status =
+ nirio_driver_iface::rio_ioctl(
+ _device_handle,
+ IOCTL_TRANSPORT_FIFO_WAIT,
+ &in,
+ sizeof(in),
+ &out,
+ sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ data_pointer = reinterpret_cast<void*>(out.elements);
+ UHD_ASSERT_THROW(out.elementsAcquired <= std::numeric_limits<uint32_t>::max());
+ elements_acquired = static_cast<uint32_t>(out.elementsAcquired);
+ UHD_ASSERT_THROW(out.elementsRemaining <= std::numeric_limits<uint32_t>::max());
+ elements_remaining = static_cast<uint32_t>(out.elementsRemaining);
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::grant_fifo(
+ uint32_t channel,
+ uint32_t elements_to_grant)
+ {
+ READER_LOCK
+
+ nirio_status ioctl_status = NiRio_Status_Success;
+ in_transport_fifo_grant_t in = {};
+ out_transport_fifo_grant_t out = {};
+
+ in.channel = channel;
+ in.elements = elements_to_grant;
+ in.status = NiRio_Status_Success;
+
+ ioctl_status =
+ nirio_driver_iface::rio_ioctl(
+ _device_handle,
+ IOCTL_TRANSPORT_FIFO_GRANT,
+ &in,
+ sizeof(in),
+ &out,
+ sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::read_fifo(
+ uint32_t channel,
+ uint32_t elements_to_read,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_read,
+ uint32_t& number_remaining)
+ {
+ READER_LOCK
+
+ nirio_status ioctl_status = NiRio_Status_Success;
+ in_transport_fifo_read_t in = {};
+ out_transport_fifo_read_t out = {};
+
+ in.channel = channel;
+ in.buf = reinterpret_cast<tAlignedU64>(buffer);
+ in.numberElements = elements_to_read;
+ in.dataType.scalarType = map_int_to_scalar_type(scalar_type);
+ in.dataType.bitWidth = bit_width;
+ in.dataType.integerWordLength = bit_width; // same as bit_width for all types except fixed point, which is not supported
+ in.timeout = timeout;
+ in.status = NiRio_Status_Success;
+
+ ioctl_status =
+ nirio_driver_iface::rio_ioctl(
+ _device_handle,
+ IOCTL_TRANSPORT_FIFO_READ,
+ &in,
+ sizeof(in),
+ &out,
+ sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ number_read = out.read;
+ number_remaining = out.remaining;
+ return out.status;
+ }
+
+ nirio_status niriok_proxy_impl_v2::write_fifo(
+ uint32_t channel,
+ uint32_t elements_to_write,
+ void* buffer,
+ uint32_t buffer_datatype_width,
+ uint32_t scalar_type,
+ uint32_t bit_width,
+ uint32_t timeout,
+ uint32_t& number_remaining)
+ {
+ READER_LOCK
+
+ nirio_status ioctl_status = NiRio_Status_Success;
+ in_transport_fifo_write_t in = {};
+ out_transport_fifo_write_t out = {};
+
+ in.channel = channel;
+ in.buf = reinterpret_cast<tAlignedU64>(buffer);
+ in.numberElements = elements_to_write;
+ in.dataType.scalarType = map_int_to_scalar_type(scalar_type);
+ in.dataType.bitWidth = bit_width;
+ in.dataType.integerWordLength = bit_width; // same as bit_width for all types except fixed point, which is not supported
+ in.timeout = timeout;
+ in.status = NiRio_Status_Success;
+
+ ioctl_status =
+ nirio_driver_iface::rio_ioctl(
+ _device_handle,
+ IOCTL_TRANSPORT_FIFO_WRITE,
+ &in,
+ sizeof(in),
+ &out,
+ sizeof(out));
+ if (nirio_status_fatal(ioctl_status)) return ioctl_status;
+
+ number_remaining = out.remaining;
+ return out.status;
+ }
+
+}}
+
+#ifdef __GNUC__
+ #pragma GCC diagnostic pop
+#endif
diff --git a/host/lib/transport/nirio/niusrprio_session.cpp b/host/lib/transport/nirio/niusrprio_session.cpp
index 97d764736..5463e3502 100644
--- a/host/lib/transport/nirio/niusrprio_session.cpp
+++ b/host/lib/transport/nirio/niusrprio_session.cpp
@@ -32,9 +32,11 @@ namespace uhd { namespace niusrprio {
niusrprio_session::niusrprio_session(const std::string& resource_name, const std::string& rpc_port_name) :
_resource_name(resource_name),
_session_open(false),
- _resource_manager(_riok_proxy),
+ _resource_manager(),
_rpc_client("localhost", rpc_port_name)
{
+ _riok_proxy = create_kernel_proxy(resource_name,rpc_port_name);
+ _resource_manager.set_proxy(_riok_proxy);
}
niusrprio_session::~niusrprio_session()
@@ -66,7 +68,7 @@ nirio_status niusrprio_session::open(
nirio_status_chain(_rpc_client.get_ctor_status(), status);
//Get a handle to the kernel driver
nirio_status_chain(_rpc_client.niusrprio_get_interface_path(_resource_name, _interface_path), status);
- nirio_status_chain(_riok_proxy.open(_interface_path), status);
+ nirio_status_chain(_riok_proxy->open(_interface_path), status);
if (nirio_status_not_fatal(status)) {
//Bitfile build for a particular LVFPGA interface will have the same signature
@@ -132,12 +134,8 @@ niriok_proxy::sptr niusrprio_session::create_kernel_proxy(
std::string interface_path;
nirio_status_chain(temp_rpc_client.niusrprio_get_interface_path(resource_name, interface_path), status);
- niriok_proxy::sptr proxy;
- if (nirio_status_not_fatal(status)) {
- proxy.reset(new niriok_proxy());
- if (proxy) nirio_status_chain(proxy->open(interface_path), status);
- }
-
+ niriok_proxy::sptr proxy = niriok_proxy::make_and_open(interface_path);
+
return proxy;
}
@@ -146,12 +144,12 @@ nirio_status niusrprio_session::_verify_signature()
//Validate the signature using the kernel proxy
nirio_status status = NiRio_Status_Success;
boost::uint32_t sig_offset = 0;
- nirio_status_chain(_riok_proxy.get_attribute(DEFAULT_FPGA_SIGNATURE_OFFSET, sig_offset), status);
+ nirio_status_chain(_riok_proxy->get_attribute(RIO_FPGA_DEFAULT_SIGNATURE_OFFSET, sig_offset), status);
niriok_scoped_addr_space(_riok_proxy, FPGA, status);
std::string signature;
for (boost::uint32_t i = 0; i < 8; i++) {
boost::uint32_t quarter_sig;
- nirio_status_chain(_riok_proxy.peek(sig_offset, quarter_sig), status);
+ nirio_status_chain(_riok_proxy->peek(sig_offset, quarter_sig), status);
signature += boost::str(boost::format("%08x") % quarter_sig);
}
@@ -172,7 +170,7 @@ std::string niusrprio_session::_read_bitstream_checksum()
std::string usr_signature;
for (boost::uint32_t i = 0; i < FPGA_USR_SIG_REG_SIZE; i+=4) {
boost::uint32_t quarter_sig;
- nirio_status_chain(_riok_proxy.peek(FPGA_USR_SIG_REG_BASE + i, quarter_sig), status);
+ nirio_status_chain(_riok_proxy->peek(FPGA_USR_SIG_REG_BASE + i, quarter_sig), status);
usr_signature += boost::str(boost::format("%08x") % quarter_sig);
}
boost::to_upper(usr_signature);
@@ -193,7 +191,7 @@ nirio_status niusrprio_session::_write_bitstream_checksum(const std::string& che
} catch (std::exception&) {
quarter_sig = 0;
}
- nirio_status_chain(_riok_proxy.poke(FPGA_USR_SIG_REG_BASE + i, quarter_sig), status);
+ nirio_status_chain(_riok_proxy->poke(FPGA_USR_SIG_REG_BASE + i, quarter_sig), status);
}
return status;
}
@@ -206,14 +204,14 @@ nirio_status niusrprio_session::_ensure_fpga_ready()
//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);
+ 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);
+ 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
@@ -224,27 +222,27 @@ nirio_status niusrprio_session::_ensure_fpga_ready()
//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);
+ _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);
+ _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();
+ _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);
+ 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);
+ 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;
}
diff --git a/host/lib/transport/nirio_zero_copy.cpp b/host/lib/transport/nirio_zero_copy.cpp
index 3bb822720..7ba8cb4c8 100644
--- a/host/lib/transport/nirio_zero_copy.cpp
+++ b/host/lib/transport/nirio_zero_copy.cpp
@@ -145,27 +145,27 @@ public:
size_t actual_depth = 0, actual_size = 0;
//Disable DMA streams in case last shutdown was unclean (cleanup, so don't status chain)
- _proxy().poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);
- _proxy().poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);
+ _proxy()->poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);
+ _proxy()->poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);
_wait_until_stream_ready();
//Configure frame width
nirio_status_chain(
- _proxy().poke(PCIE_TX_DMA_REG(DMA_FRAME_SIZE_REG, _fifo_instance),
+ _proxy()->poke(PCIE_TX_DMA_REG(DMA_FRAME_SIZE_REG, _fifo_instance),
static_cast<uint32_t>(_xport_params.send_frame_size/sizeof(fifo_data_t))),
status);
nirio_status_chain(
- _proxy().poke(PCIE_RX_DMA_REG(DMA_FRAME_SIZE_REG, _fifo_instance),
+ _proxy()->poke(PCIE_RX_DMA_REG(DMA_FRAME_SIZE_REG, _fifo_instance),
static_cast<uint32_t>(_xport_params.recv_frame_size/sizeof(fifo_data_t))),
status);
//Config 32-bit word flipping and enable DMA streams
nirio_status_chain(
- _proxy().poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance),
+ _proxy()->poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance),
DMA_CTRL_SW_BUF_U32 | DMA_CTRL_ENABLED),
status);
nirio_status_chain(
- _proxy().poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance),
+ _proxy()->poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance),
DMA_CTRL_SW_BUF_U32 | DMA_CTRL_ENABLED),
status);
@@ -190,7 +190,7 @@ public:
actual_depth, actual_size),
status);
- _proxy().get_rio_quirks().add_tx_fifo(_fifo_instance);
+ _proxy()->get_rio_quirks().add_tx_fifo(_fifo_instance);
nirio_status_chain(_recv_fifo->start(), status);
nirio_status_chain(_send_fifo->start(), status);
@@ -217,11 +217,11 @@ public:
virtual ~nirio_zero_copy_impl()
{
- _proxy().get_rio_quirks().remove_tx_fifo(_fifo_instance);
+ _proxy()->get_rio_quirks().remove_tx_fifo(_fifo_instance);
//Disable DMA streams (cleanup, so don't status chain)
- _proxy().poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);
- _proxy().poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);
+ _proxy()->poke(PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);
+ _proxy()->poke(PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), DMA_CTRL_DISABLED);
_flush_rx_buff();
@@ -259,7 +259,7 @@ public:
private:
- UHD_INLINE niriok_proxy& _proxy() { return _fpga_session->get_kernel_proxy(); }
+ UHD_INLINE niriok_proxy::sptr _proxy() { return _fpga_session->get_kernel_proxy(); }
UHD_INLINE void _flush_rx_buff()
{
@@ -297,10 +297,10 @@ private:
boost::posix_time::time_duration elapsed;
nirio_status status = NiRio_Status_Success;
- nirio_status_chain(_proxy().peek(
+ nirio_status_chain(_proxy()->peek(
PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status);
tx_busy = (reg_data & DMA_STATUS_BUSY);
- nirio_status_chain(_proxy().peek(
+ nirio_status_chain(_proxy()->peek(
PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status);
rx_busy = (reg_data & DMA_STATUS_BUSY);
@@ -309,10 +309,10 @@ private:
do {
boost::this_thread::sleep(boost::posix_time::microsec(50)); //Avoid flooding the bus
elapsed = boost::posix_time::microsec_clock::local_time() - start_time;
- nirio_status_chain(_proxy().peek(
+ nirio_status_chain(_proxy()->peek(
PCIE_TX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status);
tx_busy = (reg_data & DMA_STATUS_BUSY);
- nirio_status_chain(_proxy().peek(
+ nirio_status_chain(_proxy()->peek(
PCIE_RX_DMA_REG(DMA_CTRL_STATUS_REG, _fifo_instance), reg_data), status);
rx_busy = (reg_data & DMA_STATUS_BUSY);
} while (
diff --git a/host/lib/usrp/common/adf435x_common.cpp b/host/lib/usrp/common/adf435x_common.cpp
index 972a69388..9b362a4d9 100644
--- a/host/lib/usrp/common/adf435x_common.cpp
+++ b/host/lib/usrp/common/adf435x_common.cpp
@@ -17,6 +17,7 @@
#include "adf435x_common.hpp"
+#include <boost/math/special_functions/round.hpp>
#include <uhd/types/tune_request.hpp>
#include <uhd/utils/log.hpp>
#include <cmath>
@@ -96,7 +97,7 @@ adf435x_tuning_settings tune_adf435x_synth(
//Fractional-N calculation
MOD = 4095; //max fractional accuracy
- FRAC = static_cast<boost::uint16_t>((feedback_freq/pfd_freq - N)*MOD);
+ FRAC = static_cast<boost::uint16_t>(boost::math::round((feedback_freq/pfd_freq - N)*MOD));
if (constraints.force_frac0) {
if (FRAC > (MOD / 2)) { //Round integer such that actual freq is closest to target
N++;
diff --git a/host/lib/usrp/x300/x300_fw_ctrl.cpp b/host/lib/usrp/x300/x300_fw_ctrl.cpp
index 804d23f51..3a8d984fb 100644
--- a/host/lib/usrp/x300/x300_fw_ctrl.cpp
+++ b/host/lib/usrp/x300/x300_fw_ctrl.cpp
@@ -187,16 +187,16 @@ private:
class x300_ctrl_iface_pcie : public x300_ctrl_iface
{
public:
- x300_ctrl_iface_pcie(niriok_proxy& drv_proxy):
+ x300_ctrl_iface_pcie(niriok_proxy::sptr drv_proxy):
_drv_proxy(drv_proxy)
{
nirio_status status = 0;
- nirio_status_chain(_drv_proxy.set_attribute(ADDRESS_SPACE, BUS_INTERFACE), status);
+ nirio_status_chain(_drv_proxy->set_attribute(RIO_ADDRESS_SPACE, 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.
boost::uint32_t pcie_fpga_signature = 0;
- _drv_proxy.peek(FPGA_PCIE_SIG_REG, pcie_fpga_signature);
+ _drv_proxy->peek(FPGA_PCIE_SIG_REG, pcie_fpga_signature);
if (pcie_fpga_signature != FPGA_X3xx_SIG_VALUE)
throw uhd::io_error("cannot create x300_ctrl_iface_pcie. incorrect/no fpga image");
@@ -209,7 +209,7 @@ public:
do {
boost::this_thread::sleep(boost::posix_time::microsec(500)); //Avoid flooding the bus
elapsed = boost::posix_time::microsec_clock::local_time() - start_time;
- nirio_status_chain(_drv_proxy.peek(PCIE_ZPU_STATUS_REG(0), reg_data), status);
+ nirio_status_chain(_drv_proxy->peek(PCIE_ZPU_STATUS_REG(0), reg_data), status);
} while (
nirio_status_not_fatal(status) &&
(reg_data & PCIE_ZPU_STATUS_SUSPENDED) &&
@@ -232,12 +232,12 @@ protected:
boost::posix_time::ptime start_time = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration elapsed;
- nirio_status_chain(_drv_proxy.poke(PCIE_ZPU_DATA_REG(addr), data), status);
+ nirio_status_chain(_drv_proxy->poke(PCIE_ZPU_DATA_REG(addr), data), status);
if (nirio_status_not_fatal(status)) {
do {
boost::this_thread::sleep(boost::posix_time::microsec(50)); //Avoid flooding the bus
elapsed = boost::posix_time::microsec_clock::local_time() - start_time;
- nirio_status_chain(_drv_proxy.peek(PCIE_ZPU_STATUS_REG(addr), reg_data), status);
+ nirio_status_chain(_drv_proxy->peek(PCIE_ZPU_STATUS_REG(addr), reg_data), status);
} while (
nirio_status_not_fatal(status) &&
((reg_data & (PCIE_ZPU_STATUS_BUSY | PCIE_ZPU_STATUS_SUSPENDED)) != 0) &&
@@ -257,18 +257,18 @@ protected:
boost::posix_time::ptime start_time = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration elapsed;
- nirio_status_chain(_drv_proxy.poke(PCIE_ZPU_READ_REG(addr), PCIE_ZPU_READ_START), status);
+ nirio_status_chain(_drv_proxy->poke(PCIE_ZPU_READ_REG(addr), PCIE_ZPU_READ_START), status);
if (nirio_status_not_fatal(status)) {
do {
boost::this_thread::sleep(boost::posix_time::microsec(50)); //Avoid flooding the bus
elapsed = boost::posix_time::microsec_clock::local_time() - start_time;
- nirio_status_chain(_drv_proxy.peek(PCIE_ZPU_STATUS_REG(addr), reg_data), status);
+ nirio_status_chain(_drv_proxy->peek(PCIE_ZPU_STATUS_REG(addr), reg_data), status);
} while (
nirio_status_not_fatal(status) &&
((reg_data & (PCIE_ZPU_STATUS_BUSY | PCIE_ZPU_STATUS_SUSPENDED)) != 0) &&
elapsed.total_milliseconds() < READ_TIMEOUT_IN_MS);
}
- nirio_status_chain(_drv_proxy.peek(PCIE_ZPU_DATA_REG(addr), reg_data), status);
+ nirio_status_chain(_drv_proxy->peek(PCIE_ZPU_DATA_REG(addr), reg_data), status);
if (nirio_status_fatal(status))
throw uhd::io_error("x300 fw peek32 - hardware IO error");
@@ -284,7 +284,7 @@ protected:
}
private:
- niriok_proxy& _drv_proxy;
+ niriok_proxy::sptr _drv_proxy;
static const boost::uint32_t READ_TIMEOUT_IN_MS = 10;
static const boost::uint32_t INIT_TIMEOUT_IN_MS = 5000;
};
@@ -294,7 +294,7 @@ wb_iface::sptr x300_make_ctrl_iface_enet(uhd::transport::udp_simple::sptr udp)
return wb_iface::sptr(new x300_ctrl_iface_enet(udp));
}
-wb_iface::sptr x300_make_ctrl_iface_pcie(niriok_proxy& drv_proxy)
+wb_iface::sptr x300_make_ctrl_iface_pcie(niriok_proxy::sptr drv_proxy)
{
return wb_iface::sptr(new x300_ctrl_iface_pcie(drv_proxy));
}
diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp
index 1494a100e..b4286ee79 100644
--- a/host/lib/usrp/x300/x300_impl.cpp
+++ b/host/lib/usrp/x300/x300_impl.cpp
@@ -171,8 +171,8 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu
default:
continue;
}
-
- niriok_proxy kernel_proxy;
+
+ niriok_proxy::sptr kernel_proxy = niriok_proxy::make_and_open(dev_info.interface_path);
//Attempt to read the name from the EEPROM and perform filtering.
//This operation can throw due to compatibility mismatch.
@@ -192,7 +192,6 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu
if (get_pcie_zpu_iface_registry().has_key(resource_d)) {
zpu_ctrl = get_pcie_zpu_iface_registry()[resource_d].lock();
} else {
- kernel_proxy.open(dev_info.interface_path);
zpu_ctrl = x300_make_ctrl_iface_pcie(kernel_proxy);
//We don't put this zpu_ctrl in the registry because we need
//a persistent niriok_proxy associated with the object
@@ -220,7 +219,6 @@ static device_addrs_t x300_find_pcie(const device_addr_t &hint, bool explicit_qu
new_addr["name"] = "";
new_addr["serial"] = "";
}
- kernel_proxy.close();
//filter the discovered device below by matching optional keys
std::string resource_i = hint.has_key("resource") ? hint["resource"] : "";
@@ -403,7 +401,6 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
have a valid USRP X3x0, NI USRP-294xR or NI USRP-295xR device and that all the device \
driver have been loaded.");
}
-
//Load the lvbitx onto the device
UHD_MSG(status) << boost::format("Using LVBITX bitfile %s...\n") % lvbitx->get_bitfile_path();
mb.rio_fpga_interface.reset(new niusrprio_session(dev_addr["resource"], rpc_port_name));
@@ -412,7 +409,7 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t &dev_addr)
//Tell the quirks object which FIFOs carry TX stream data
const boost::uint32_t tx_data_fifos[2] = {X300_RADIO_DEST_PREFIX_TX, X300_RADIO_DEST_PREFIX_TX + 3};
- mb.rio_fpga_interface->get_kernel_proxy().get_rio_quirks().register_tx_streams(tx_data_fifos);
+ mb.rio_fpga_interface->get_kernel_proxy()->get_rio_quirks().register_tx_streams(tx_data_fifos);
_tree->create<double>(mb_path / "link_max_rate").set(X300_MAX_RATE_PCIE);
}
@@ -1303,7 +1300,7 @@ boost::uint32_t x300_impl::allocate_sid(mboard_members_t &mb, const sid_config_t
if (xport_path == "nirio") {
boost::uint32_t router_config_word = ((_sid_framer & 0xff) << 16) | //Return SID
get_pcie_dma_channel(config.router_dst_there, config.dst_prefix); //Dest
- mb.rio_fpga_interface->get_kernel_proxy().poke(PCIE_ROUTER_REG(0), router_config_word);
+ mb.rio_fpga_interface->get_kernel_proxy()->poke(PCIE_ROUTER_REG(0), router_config_word);
}
UHD_LOG << std::hex
@@ -1683,7 +1680,7 @@ x300_impl::x300_mboard_t x300_impl::get_mb_type_from_pcie(const std::string& res
niriok_proxy::sptr discovery_proxy =
niusrprio_session::create_kernel_proxy(resource, rpc_port);
if (discovery_proxy) {
- nirio_status_chain(discovery_proxy->get_attribute(PRODUCT_NUMBER, pid), status);
+ nirio_status_chain(discovery_proxy->get_attribute(RIO_PRODUCT_NUMBER, pid), status);
discovery_proxy->close();
if (nirio_status_not_fatal(status)) {
//The PCIe ID -> MB mapping may be different from the EEPROM -> MB mapping
diff --git a/host/lib/usrp/x300/x300_impl.hpp b/host/lib/usrp/x300/x300_impl.hpp
index 8abdee48c..924cb61a4 100644
--- a/host/lib/usrp/x300/x300_impl.hpp
+++ b/host/lib/usrp/x300/x300_impl.hpp
@@ -137,7 +137,7 @@ uhd::usrp::dboard_iface::sptr x300_make_dboard_iface(const x300_dboard_iface_con
uhd::uart_iface::sptr x300_make_uart_iface(uhd::wb_iface::sptr iface);
uhd::wb_iface::sptr x300_make_ctrl_iface_enet(uhd::transport::udp_simple::sptr udp);
-uhd::wb_iface::sptr x300_make_ctrl_iface_pcie(uhd::niusrprio::niriok_proxy& drv_proxy);
+uhd::wb_iface::sptr x300_make_ctrl_iface_pcie(uhd::niusrprio::niriok_proxy::sptr drv_proxy);
class x300_impl : public uhd::device
{
diff --git a/host/utils/nirio_programmer.cpp b/host/utils/nirio_programmer.cpp
index 199c08130..43ec1ff43 100644
--- a/host/utils/nirio_programmer.cpp
+++ b/host/utils/nirio_programmer.cpp
@@ -142,8 +142,7 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- niriok_proxy dev_proxy;
- dev_proxy.open(interface_path);
+ niriok_proxy::sptr dev_proxy = niriok_proxy::make_and_open(interface_path);
if (poke_tokens_str != ""){
std::stringstream ss;
@@ -158,9 +157,9 @@ int main(int argc, char *argv[])
niriok_scoped_addr_space(dev_proxy, poke_tokens[0]=="c"?BUS_INTERFACE:FPGA, status);
if (poke_tokens[0]=="z") {
- nirio_status_chain(dev_proxy.poke(poke_addr, (uint32_t)0x70000 + poke_addr), status);
+ nirio_status_chain(dev_proxy->poke(poke_addr, (uint32_t)0x70000 + poke_addr), status);
} else {
- nirio_status_chain(dev_proxy.poke(poke_addr, poke_data), status);
+ nirio_status_chain(dev_proxy->poke(poke_addr, poke_data), status);
}
printf("[POKE] %s:0x%x <= 0x%x (%u)\n", poke_tokens[0]=="c"?"Chinch":(poke_tokens[0]=="z"?"ZPU":"FPGA"), poke_addr, poke_data, poke_data);
}
@@ -176,13 +175,13 @@ int main(int argc, char *argv[])
niriok_scoped_addr_space(dev_proxy, peek_tokens[0]=="c"?BUS_INTERFACE:FPGA, status);
uint32_t reg_val;
if (peek_tokens[0]=="z") {
- nirio_status_chain(dev_proxy.poke((uint32_t)0x60000 + peek_addr, (uint32_t)0), status);
+ nirio_status_chain(dev_proxy->poke((uint32_t)0x60000 + peek_addr, (uint32_t)0), status);
do {
- nirio_status_chain(dev_proxy.peek((uint32_t)0x60000 + peek_addr, reg_val), status);
+ nirio_status_chain(dev_proxy->peek((uint32_t)0x60000 + peek_addr, reg_val), status);
} while (reg_val != 0);
- nirio_status_chain(dev_proxy.peek((uint32_t)0x70000 + peek_addr, reg_val), status);
+ nirio_status_chain(dev_proxy->peek((uint32_t)0x70000 + peek_addr, reg_val), status);
} else {
- nirio_status_chain(dev_proxy.peek(peek_addr, reg_val), status);
+ nirio_status_chain(dev_proxy->peek(peek_addr, reg_val), status);
}
printf("[PEEK] %s:0x%x = 0x%x (%u)\n", peek_tokens[0]=="c"?"Chinch":(peek_tokens[0]=="z"?"ZPU":"FPGA"), peek_addr, reg_val, reg_val);
@@ -192,34 +191,34 @@ int main(int argc, char *argv[])
if (vm.count("stats")){
printf("[Interface %u]\n", interface_num);
uint32_t attr_val;
- nirio_status_chain(dev_proxy.get_attribute(IS_FPGA_PROGRAMMED, attr_val), status);
+ nirio_status_chain(dev_proxy->get_attribute(RIO_IS_FPGA_PROGRAMMED, attr_val), status);
printf("* Is FPGA Programmed? = %s\n", (attr_val==1)?"YES":"NO");
std::string signature;
for (int i = 0; i < 4; i++) {
- nirio_status_chain(dev_proxy.peek(0x3FFF4, attr_val), status);
+ nirio_status_chain(dev_proxy->peek(0x3FFF4, attr_val), status);
signature += boost::str(boost::format("%08x") % attr_val);
}
printf("* FPGA Signature = %s\n", signature.c_str());
std::string checksum;
for (int i = 0; i < 4; i++) {
- nirio_status_chain(dev_proxy.peek(0x40030 + (i * 4), attr_val), status);
+ nirio_status_chain(dev_proxy->peek(0x40030 + (i * 4), attr_val), status);
checksum += boost::str(boost::format("%08x") % attr_val);
}
printf("* FPGA Bitstream Checksum = %s\n", checksum.c_str());
uint32_t reg_val;
- nirio_status_chain(dev_proxy.set_attribute(ADDRESS_SPACE, BUS_INTERFACE), status);
- nirio_status_chain(dev_proxy.peek(0, reg_val), status);
+ nirio_status_chain(dev_proxy->set_attribute(RIO_ADDRESS_SPACE, BUS_INTERFACE), status);
+ nirio_status_chain(dev_proxy->peek(0, reg_val), status);
printf("* Chinch Signature = %x\n", reg_val);
- nirio_status_chain(dev_proxy.set_attribute(ADDRESS_SPACE, FPGA), status);
- nirio_status_chain(dev_proxy.peek(0, reg_val), status);
+ nirio_status_chain(dev_proxy->set_attribute(RIO_ADDRESS_SPACE, FPGA), status);
+ nirio_status_chain(dev_proxy->peek(0, reg_val), status);
printf("* PCIe FPGA Signature = %x\n", reg_val);
printf("\n[DMA Stream Stats]\n");
- nirio_status_chain(dev_proxy.set_attribute(ADDRESS_SPACE, FPGA), status);
+ nirio_status_chain(dev_proxy->set_attribute(RIO_ADDRESS_SPACE, FPGA), status);
printf("------------------------------------------------------------------------------------------------");
printf("\nChannel => |");
@@ -229,42 +228,42 @@ int main(int argc, char *argv[])
printf("\n------------------------------------------------------------------------------------------------");
printf("\nTX Status |");
for (uint32_t i = 0; i < 6; i++) {
- nirio_status_chain(dev_proxy.peek(0x40200 + (i * 16), reg_val), status);
+ nirio_status_chain(dev_proxy->peek(0x40200 + (i * 16), reg_val), status);
printf("%s |", reg_val==0 ? " Good" : " Error");
}
printf("\nRX Status |");
for (uint32_t i = 0; i < 6; i++) {
- nirio_status_chain(dev_proxy.peek(0x40400 + (i * 16), reg_val), status);
+ nirio_status_chain(dev_proxy->peek(0x40400 + (i * 16), reg_val), status);
printf("%s |", reg_val==0 ? " Good" : " Error");
}
printf("\nTX Frm Size |");
for (uint32_t i = 0; i < 6; i++) {
- nirio_status_chain(dev_proxy.peek(0x40204 + (i * 16), reg_val), status);
+ nirio_status_chain(dev_proxy->peek(0x40204 + (i * 16), reg_val), status);
printf("%11u |", reg_val);
}
printf("\nRX Frm Size |");
for (uint32_t i = 0; i < 6; i++) {
- nirio_status_chain(dev_proxy.peek(0x40404 + (i * 16), reg_val), status);
+ nirio_status_chain(dev_proxy->peek(0x40404 + (i * 16), reg_val), status);
printf("%11u |", reg_val);
}
printf("\nTX Pkt Count |");
for (uint32_t i = 0; i < 6; i++) {
- nirio_status_chain(dev_proxy.peek(0x4020C + (i * 16), reg_val), status);
+ nirio_status_chain(dev_proxy->peek(0x4020C + (i * 16), reg_val), status);
printf("%11u |", reg_val);
}
printf("\nTX Samp Count |");
for (uint32_t i = 0; i < 6; i++) {
- nirio_status_chain(dev_proxy.peek(0x40208 + (i * 16), reg_val), status);
+ nirio_status_chain(dev_proxy->peek(0x40208 + (i * 16), reg_val), status);
printf("%11u |", reg_val);
}
printf("\nRX Pkt Count |");
for (uint32_t i = 0; i < 6; i++) {
- nirio_status_chain(dev_proxy.peek(0x4040C + (i * 16), reg_val), status);
+ nirio_status_chain(dev_proxy->peek(0x4040C + (i * 16), reg_val), status);
printf("%11u |", reg_val);
}
printf("\nRX Samp Count |");
for (uint32_t i = 0; i < 6; i++) {
- nirio_status_chain(dev_proxy.peek(0x40408 + (i * 16), reg_val), status);
+ nirio_status_chain(dev_proxy->peek(0x40408 + (i * 16), reg_val), status);
printf("%11u |", reg_val);
}
printf("\n------------------------------------------------------------------------------------------------\n");