ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
LNMMonostableTriggerPlugin.cc
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
4#include "LNMAccessorPlugin.h"
6
7#include <boost/make_shared.hpp>
8
9#include <thread>
10
11namespace ChimeraTK::LNMBackend {
12
13 /********************************************************************************************************************/
14
16 LNMBackendRegisterInfo info, size_t pluginIndex, const std::map<std::string, std::string>& parameters)
17 : AccessorPlugin(info, pluginIndex) {
18 // extract parameters
19 if(parameters.find("milliseconds") == parameters.end()) {
21 "LogicalNameMappingBackend MonostableTriggerPluginPlugin: Missing parameter 'milliseconds'.");
22 }
23 _milliseconds = std::stod(parameters.at("milliseconds"));
24 if(parameters.find("active") != parameters.end()) {
25 _active = std::stoul(parameters.at("active"));
26 }
27 if(parameters.find("inactive") != parameters.end()) {
28 _inactive = std::stoul(parameters.at("inactive"));
29 }
30
31 // Change register info to write-only and data type nodata
32 info.readable = false;
34 }
35
36 /********************************************************************************************************************/
37
44
45 /********************************************************************************************************************/
46
47 template<typename UserType>
50
52 double milliseconds, uint32_t active, uint32_t inactive)
53 : ChimeraTK::NDRegisterAccessorDecorator<UserType, uint32_t>(target), _delay(milliseconds), _active(active),
54 _inactive(inactive) {
55 // make sure the target register is writeable and scalar
56 if(!_target->isWriteable()) {
58 "LogicalNameMappingBackend MonostableTriggerPluginPlugin: Cannot target non-writeable register.");
59 }
60 if(_target->getNumberOfChannels() > 1 || _target->getNumberOfSamples() > 1) {
62 "LogicalNameMappingBackend MonostableTriggerPluginPlugin: Cannot target non-scalar registers.");
63 }
64 }
65
66 [[nodiscard]] bool isReadable() const override { return false; }
67
68 void doPreRead(TransferType) override {
69 throw ChimeraTK::logic_error("LogicalNameMappingBackend MonostableTriggerPluginPlugin: Reading is not allowed.");
70 }
71
72 void doPostRead(TransferType, bool /*hasNewData*/) override {}
73
74 void doPreWrite(TransferType /*type*/, VersionNumber versionNumber) override {
75 _target->accessData(0, 0) = _active;
76 _target->setDataValidity(this->_dataValidity);
77 _target->preWrite(TransferType::write, versionNumber);
78 }
79
80 bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber) override;
81 bool doWriteTransferDestructively(ChimeraTK::VersionNumber versionNumber) override;
82
83 void doPostWrite(TransferType, VersionNumber versionNumber) override {
84 _target->postWrite(TransferType::write, versionNumber);
85 }
86
87 std::chrono::duration<double, std::milli> _delay;
88 uint32_t _active, _inactive;
89
91
92 using ChimeraTK::NDRegisterAccessorDecorator<UserType, uint32_t>::_target;
93 };
94
95 template<typename UserType>
97 // Note: since we have called _target->preWrite() in our doPreWrite(), there cannot be a logic_error at this point
98 // any more. This also holds for the second transfer initiated here: if the first transfer is allowed, so is the
99 // second. In case the target backend screws this up, we will run into std::terminate.
100
101 bool a = _target->writeTransfer(versionNumber);
102 _target->postWrite(TransferType::write, versionNumber);
103
104 std::this_thread::sleep_for(_delay);
105
106 _target->accessData(0, 0) = _inactive;
107 _target->preWrite(TransferType::write, versionNumber);
108 dataLossInInactivate = _target->writeTransfer(versionNumber);
109 return a || dataLossInInactivate;
110 }
111
112 template<typename UserType>
114 ChimeraTK::VersionNumber versionNumber) {
115 return doWriteTransfer(versionNumber);
116 }
117
118 /********************************************************************************************************************/
119
120 template<typename UserType, typename TargetType>
121 boost::shared_ptr<NDRegisterAccessor<UserType>> MonostableTriggerPlugin::decorateAccessor(
122 boost::shared_ptr<LogicalNameMappingBackend>&, boost::shared_ptr<NDRegisterAccessor<TargetType>>& target,
123 const UndecoratedParams&) {
124 if constexpr(std::is_same<TargetType, uint32_t>::value) {
125 return boost::make_shared<MonostableTriggerPluginDecorator<UserType>>(target, _milliseconds, _active, _inactive);
126 }
127
128 assert(false);
129
130 return {};
131 }
132} // namespace ChimeraTK::LNMBackend
void remove(AccessMode flag)
Remove the given flag from the set.
Definition AccessMode.cc:56
Class describing the actual payload data format of a register in an abstract manner.
LNMBackendRegisterInfo _info
RegisterInfo describing the the target register for which this plugin instance should work.
Base class for plugins that modify the behaviour of accessors in the logical name mapping backend.
void doRegisterInfoUpdate() override
Implementation of the plugin specific register information update.
MonostableTriggerPlugin(LNMBackendRegisterInfo info, size_t pluginIndex, const std::map< std::string, std::string > &parameters)
boost::shared_ptr< NDRegisterAccessor< UserType > > decorateAccessor(boost::shared_ptr< LogicalNameMappingBackend > &backend, boost::shared_ptr< NDRegisterAccessor< TargetType > > &target, const UndecoratedParams &accessorParams)
RegisterInfo structure for the LogicalNameMappingBackend.
AccessModeFlags supportedFlags
Supported AccessMode flags.
bool readable
Flag if the register is readable.
Base class for decorators of the NDRegisterAccessor.
N-dimensional register accessor.
std::vector< std::vector< UserType > > buffer_2D
Buffer of converted data elements.
DataValidity _dataValidity
The validity of the data in the application buffer.
bool writeTransfer(ChimeraTK::VersionNumber versionNumber)
Write the data to the device.
Class for generating and holding version numbers without exposing a numeric representation.
Exception thrown when a logic error has occured.
Definition Exception.h:51
@ raw
Raw access: disable any possible conversion from the original hardware data type into the given UserT...
TransferType
Used to indicate the applicable operation on a Transferelement.
void doPostRead(TransferType, bool) override
Backend specific implementation of postRead().
bool doWriteTransferDestructively(ChimeraTK::VersionNumber versionNumber) override
Implementation version of writeTransferDestructively().
void doPreRead(TransferType) override
Backend specific implementation of preRead().
bool doWriteTransfer(ChimeraTK::VersionNumber versionNumber) override
Implementation version of writeTransfer().
bool isReadable() const override
Check if transfer element is readable.
MonostableTriggerPluginDecorator(const boost::shared_ptr< ChimeraTK::NDRegisterAccessor< uint32_t > > &target, double milliseconds, uint32_t active, uint32_t inactive)
void doPostWrite(TransferType, VersionNumber versionNumber) override
Backend specific implementation of postWrite().
void doPreWrite(TransferType, VersionNumber versionNumber) override
Backend specific implementation of preWrite().
Helper struct to hold extra parameters needed by some plugins, used in decorateAccessor()