ChimeraTK-DeviceAccess 03.26.00
Loading...
Searching...
No Matches
NumericAddressedBackendMuxedRegisterAccessor.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#pragma once
4
5#include "Exception.h"
9#include "RawConverter.h"
10
11#include <boost/shared_ptr.hpp>
12
13namespace ChimeraTK {
14
15 constexpr auto MULTIPLEXED_SEQUENCE_PREFIX = "AREA_MULTIPLEXED_SEQUENCE_";
16 constexpr auto SEQUENCE_PREFIX = "SEQUENCE_";
17
18 constexpr auto MEM_MULTIPLEXED_PREFIX = "MEM_MULTIPLEXED_";
19
20 /********************************************************************************************************************/
21
22 namespace detail {
23
25 template<typename DATA_TYPE>
26 struct pitched_iterator {
27 // standard iterator traits
28 using iterator_category = std::random_access_iterator_tag;
29 using value_type = DATA_TYPE;
30 using difference_type = std::ptrdiff_t;
31 using pointer = DATA_TYPE*;
32 using reference = DATA_TYPE&;
33
34 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
35 pitched_iterator(void* begin, size_t pitch) : _ptr(reinterpret_cast<std::byte*>(begin)), _pitch(pitch) {}
36
37 template<typename OTHER_DATA_TYPE>
38 explicit pitched_iterator(pitched_iterator<OTHER_DATA_TYPE>& other) : _ptr(other._ptr), _pitch(other._pitch) {}
39
40 pitched_iterator& operator++() {
41 _ptr += _pitch;
42 return *this;
43 }
44 pitched_iterator operator++(int) {
45 pitched_iterator retval = *this;
46 ++(*this);
47 return retval;
48 }
49 pitched_iterator operator+(size_t n) { return pitched_iterator(_ptr + n * _pitch, _pitch); }
50 bool operator==(pitched_iterator other) const { return _ptr == other._ptr; }
51 bool operator!=(pitched_iterator other) const { return !(*this == other); }
52 size_t operator-(pitched_iterator other) const { return _ptr - other._ptr; }
53 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
54 DATA_TYPE& operator*() const { return *reinterpret_cast<DATA_TYPE*>(_ptr); }
55
56 private:
57 std::byte* _ptr;
58 const size_t _pitch;
59
60 template<typename OTHER_DATA_TYPE>
61 friend struct pitched_iterator;
62 };
63
64 } // namespace detail
65
66 /********************************************************************************************************************/
70 template<class UserType>
72 public:
73 NumericAddressedBackendMuxedRegisterAccessor(const RegisterPath& registerPathName, size_t numberOfElements,
74 size_t elementsOffset, const boost::shared_ptr<DeviceBackend>& _backend);
75
76 void doReadTransferSynchronously() override;
77
78 void doPostRead(TransferType type, bool hasNewData) override;
79
80 template<typename UserType2, typename RawType, RawConverter::SignificantBitsCase sc,
81 RawConverter::FractionalCase fc, bool isSigned>
83
84 bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber) override;
85
86 void doPreWrite(TransferType type, VersionNumber versionNumber) override;
87
88 template<typename UserType2, typename RawType, RawConverter::SignificantBitsCase sc,
89 RawConverter::FractionalCase fc, bool isSigned>
91
92 void doPreRead(TransferType) override {
93 if(!_ioDevice->isOpen()) throw ChimeraTK::logic_error("Device not opened.");
94 }
95
96 [[nodiscard]] bool mayReplaceOther(const boost::shared_ptr<TransferElement const>& other) const override {
97 auto rhsCasted = boost::dynamic_pointer_cast<const NumericAddressedBackendMuxedRegisterAccessor<UserType>>(other);
98 if(rhsCasted.get() == this) {
99 return false;
100 }
101 if(!rhsCasted) return false;
102 if(_ioDevice != rhsCasted->_ioDevice) return false;
103 if(_registerInfo != rhsCasted->_registerInfo) return false;
104 // No need to compare converters, since they are derived from registerInfo and UserType.
105 return true;
106 }
107
108 [[nodiscard]] bool isReadOnly() const override { return isReadable() && !isWriteable(); }
109
110 [[nodiscard]] bool isReadable() const override { return _registerInfo.isReadable(); }
111
112 [[nodiscard]] bool isWriteable() const override { return _registerInfo.isWriteable(); }
113
114 protected:
115 std::vector<std::unique_ptr<RawConverter::ConverterLoopHelper>> _converterLoopHelpers;
116
118 boost::shared_ptr<NumericAddressedBackend> _ioDevice;
119
120 std::vector<int32_t> _ioBuffer;
121
123
124 std::vector<detail::pitched_iterator<int32_t>> _startIterators;
125 std::vector<detail::pitched_iterator<int32_t>> _endIterators;
126
127 std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() override {
128 return {boost::enable_shared_from_this<TransferElement>::shared_from_this()};
129 }
130
131 std::list<boost::shared_ptr<TransferElement>> getInternalElements() override { return {}; }
132
133 void replaceTransferElement(boost::shared_ptr<TransferElement> /*newElement*/) override {} // LCOV_EXCL_LINE
134
135 using NDRegisterAccessor<UserType>::buffer_2D;
137 };
138
139 /********************************************************************************************************************/
140
142
143 /********************************************************************************************************************/
144
145} // namespace ChimeraTK
#define DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(TemplateClass)
N-dimensional register accessor.
std::vector< std::vector< UserType > > buffer_2D
Buffer of converted data elements.
Implementation of the NDRegisterAccessor for NumericAddressedBackends for multiplexd 2D registers.
void doPreWriteImpl(RawConverter::Converter< UserType2, RawType, sc, fc, isSigned > converter, size_t channelIndex)
bool mayReplaceOther(const boost::shared_ptr< TransferElement const > &other) const override
Check whether the TransferElement can be used in places where the TransferElement "other" is currentl...
void doPostReadImpl(RawConverter::Converter< UserType2, RawType, sc, fc, isSigned > converter, size_t channelIndex)
bool isWriteable() const override
Check if transfer element is writeable.
void doReadTransferSynchronously() override
Implementation version of readTransfer() for synchronous reads.
std::vector< std::unique_ptr< RawConverter::ConverterLoopHelper > > _converterLoopHelpers
bool isReadOnly() const override
Check if transfer element is read only, i.e.
void doPostRead(TransferType type, bool hasNewData) override
Backend specific implementation of postRead().
bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber) override
Implementation version of writeTransfer().
void doPreWrite(TransferType type, VersionNumber versionNumber) override
Backend specific implementation of preWrite().
void doPreRead(TransferType) override
Backend specific implementation of preRead().
std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements() override
Obtain the underlying TransferElements with actual hardware access.
std::list< boost::shared_ptr< TransferElement > > getInternalElements() override
Obtain the full list of TransferElements internally used by this TransferElement.
bool isReadable() const override
Check if transfer element is readable.
boost::shared_ptr< NumericAddressedBackend > _ioDevice
The device from (/to) which to perform the DMA transfer.
void replaceTransferElement(boost::shared_ptr< TransferElement >) override
Search for all underlying TransferElements which are considered identical (see sameRegister()) with t...
bool isReadable() const override
Return whether the register is readable.
bool isWriteable() const override
Return whether the register is writeable.
Converter class for conversions from raw to cooked values.
Class to store a register path name.
boost::shared_ptr< DeviceBackend > _exceptionBackend
The backend to which the runtime_errors are reported via DeviceBackend::setException().
Class for generating and holding version numbers without exposing a numeric representation.
Exception thrown when a logic error has occured.
Definition Exception.h:51
std::string operator+(const std::string &leftHandSide, const RegisterPath &rightHandSide)
non-member + operator for RegisterPath: concatenate with normal strings.
TransferType
Used to indicate the applicable operation on a Transferelement.
RegisterPath operator*(const RegisterPath &leftHandSide, int rightHandSide)