diff options
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"); |