aboutsummaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
Diffstat (limited to 'host/include')
-rw-r--r--host/include/uhd/transport/nirio/nirio_fifo.h6
-rw-r--r--host/include/uhd/transport/nirio/nirio_fifo.ipp234
-rw-r--r--host/include/uhd/transport/nirio/nirio_quirks.h4
3 files changed, 147 insertions, 97 deletions
diff --git a/host/include/uhd/transport/nirio/nirio_fifo.h b/host/include/uhd/transport/nirio/nirio_fifo.h
index f7abb396f..fc1de245d 100644
--- a/host/include/uhd/transport/nirio/nirio_fifo.h
+++ b/host/include/uhd/transport/nirio/nirio_fifo.h
@@ -104,16 +104,20 @@ public:
uint32_t& num_remaining);
private: //Methods
- bool _is_initialized();
datatype_info_t _get_datatype_info();
nirio_status _get_transfer_count(uint64_t& transfer_count);
nirio_status _ensure_transfer_completed(uint32_t timeout_ms);
private: //Members
+ enum fifo_state_t {
+ UNMAPPED, MAPPED, STARTED
+ };
+
std::string _name;
fifo_direction_t _fifo_direction;
uint32_t _fifo_channel;
datatype_info_t _datatype_info;
+ fifo_state_t _state;
size_t _acquired_pending;
nirio_driver_iface::rio_mmap_t _mem_map;
boost::recursive_mutex _mutex;
diff --git a/host/include/uhd/transport/nirio/nirio_fifo.ipp b/host/include/uhd/transport/nirio/nirio_fifo.ipp
index 80a0c2a89..437e3a1fc 100644
--- a/host/include/uhd/transport/nirio/nirio_fifo.ipp
+++ b/host/include/uhd/transport/nirio/nirio_fifo.ipp
@@ -31,6 +31,7 @@ nirio_fifo<data_t>::nirio_fifo(
_fifo_direction(direction),
_fifo_channel(fifo_instance),
_datatype_info(_get_datatype_info()),
+ _state(UNMAPPED),
_acquired_pending(0),
_mem_map(),
_riok_proxy_ptr(&riok_proxy),
@@ -61,28 +62,37 @@ nirio_status nirio_fifo<data_t>::initialize(
if (!_riok_proxy_ptr) return NiRio_Status_ResourceNotInitialized;
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
+ if (_state == UNMAPPED) {
+ nirio_driver_iface::nirio_syncop_in_params_t in = {};
+ nirio_driver_iface::nirio_syncop_out_params_t out = {};
- //Forcefully stop the fifo if it is running
- in.function = nirio_driver_iface::NIRIO_FUNC::FIFO;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP;
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
+ //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.
- in.function = nirio_driver_iface::NIRIO_FUNC::FIFO;
- in.subfunction = nirio_driver_iface::NIRIO_FIFO::CONFIGURE;
+ //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));
- 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;
+ if (nirio_status_fatal(status)) return status;
- status = _riok_proxy_ptr->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;
- actual_depth = out.params.fifo.op.config.actualDepth;
- actual_size = out.params.fifo.op.config.actualSize;
+ status = _riok_proxy_ptr->map_fifo_memory(_fifo_channel, actual_size, _mem_map);
- status = _riok_proxy_ptr->map_fifo_memory(_fifo_channel, actual_size, _mem_map);
+ if (nirio_status_not_fatal(status)) {
+ _state = MAPPED;
+ }
+ } else {
+ status = NiRio_Status_SoftwareFault;
+ }
return status;
}
@@ -90,9 +100,13 @@ template <typename data_t>
void nirio_fifo<data_t>::finalize()
{
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
- if (!_mem_map.is_null()) {
- stop();
+
+ //If the FIFO is started, the stop will change the state to MAPPED.
+ stop();
+
+ if (_state == MAPPED) {
_riok_proxy_ptr->unmap_fifo_memory(_mem_map);
+ _state = UNMAPPED; //Assume teardown succeeded
}
}
@@ -104,16 +118,25 @@ nirio_status nirio_fifo<data_t>::start()
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
+ 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.function = nirio_driver_iface::NIRIO_FUNC::FIFO;
+ in.subfunction = nirio_driver_iface::NIRIO_FIFO::START;
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
- if (nirio_status_not_fatal(status)) {
- _acquired_pending = 0;
- _expected_xfer_count = 0;
+ in.params.fifo.channel = _fifo_channel;
+
+ status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
+ if (nirio_status_not_fatal(status)) {
+ _state = STARTED;
+ _acquired_pending = 0;
+ _expected_xfer_count = 0;
+ }
+ } else {
+ status = NiRio_Status_ResourceNotInitialized;
}
return status;
}
@@ -125,15 +148,22 @@ nirio_status nirio_fifo<data_t>::stop()
if (!_riok_proxy_ptr) return NiRio_Status_ResourceNotInitialized;
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
- 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 = {};
+ 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.function = nirio_driver_iface::NIRIO_FUNC::FIFO;
+ in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP;
- status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
+ in.params.fifo.channel = _fifo_channel;
+
+ status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
+
+ _state = MAPPED; //Assume teardown succeeded
+ }
return status;
}
@@ -151,36 +181,40 @@ nirio_status nirio_fifo<data_t>::acquire(
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
- 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));
-
- 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];
- _acquired_pending = elements_acquired;
-
- if (UHD_NIRIO_RX_FIFO_XFER_CHECK_EN &&
- _riok_proxy_ptr->get_rio_quirks().rx_fifo_xfer_check_en() &&
- get_direction() == INPUT_FIFO
- ) {
- _expected_xfer_count += static_cast<uint64_t>(elements_requested * sizeof(data_t));
- status = _ensure_transfer_completed(timeout);
+ 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));
+
+ 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];
+ _acquired_pending = elements_acquired;
+
+ if (UHD_NIRIO_RX_FIFO_XFER_CHECK_EN &&
+ _riok_proxy_ptr->get_rio_quirks().rx_fifo_xfer_check_en() &&
+ get_direction() == INPUT_FIFO
+ ) {
+ _expected_xfer_count += static_cast<uint64_t>(elements_requested * sizeof(data_t));
+ status = _ensure_transfer_completed(timeout);
+ }
}
+ } else {
+ status = NiRio_Status_ResourceNotInitialized;
}
return status;
@@ -194,17 +228,21 @@ nirio_status nirio_fifo<data_t>::release(const size_t elements)
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
- nirio_driver_iface::nirio_syncop_in_params_t in = {};
- nirio_driver_iface::nirio_syncop_out_params_t out = {};
+ 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.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);
+ 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));
- _acquired_pending = 0;
+ status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));
+ _acquired_pending = 0;
+ } else {
+ status = NiRio_Status_ResourceNotInitialized;
+ }
return status;
}
@@ -222,23 +260,27 @@ nirio_status nirio_fifo<data_t>::read(
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
- 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);
+ 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.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;
+ 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));
+ 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;
+ 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;
+ }
+ } else {
+ status = NiRio_Status_ResourceNotInitialized;
}
return status;
@@ -256,22 +298,26 @@ nirio_status nirio_fifo<data_t>::write(
boost::unique_lock<boost::recursive_mutex> lock(_mutex);
- 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 = {};
+ 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.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;
+ 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));
+ 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;
+ if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) {
+ num_remaining = out.params.fifo.op.write.numberRemaining;
+ }
+ } else {
+ status = NiRio_Status_ResourceNotInitialized;
}
return status;
diff --git a/host/include/uhd/transport/nirio/nirio_quirks.h b/host/include/uhd/transport/nirio/nirio_quirks.h
index 326eeeb8c..ed4f72e7f 100644
--- a/host/include/uhd/transport/nirio/nirio_quirks.h
+++ b/host/include/uhd/transport/nirio/nirio_quirks.h
@@ -24,8 +24,8 @@
//Quirk#1: We need to verify RX zero-copy data transfers from the RIO
// driver if we are in full duplex mode.
-// This option allows disabling this quirk by compiling it out.
-#define UHD_NIRIO_RX_FIFO_XFER_CHECK_EN 1
+// This option allows enabling this quirk.
+#define UHD_NIRIO_RX_FIFO_XFER_CHECK_EN 0
namespace uhd { namespace niusrprio {