ChimeraTK-DeviceAccess 03.29.00
Loading...
Searching...
No Matches
LNMBitRangeAccessPlugin.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
5#include "LNMAccessorPlugin.h"
9
10#include <boost/make_shared.hpp>
11
12#include <charconv>
13
14namespace ChimeraTK::LNMBackend {
15
16 /********************************************************************************************************************/
17 /********************************************************************************************************************/
18 /********************************************************************************************************************/
19
21 const LNMBackendRegisterInfo& info, size_t pluginIndex, const std::map<std::string, std::string>& parameters)
22 : AccessorPlugin<BitRangeAccessPlugin>(info, pluginIndex) {
23 try {
24 const auto& shift = parameters.at("shift");
25
26 // This is how you are supposed to use std::from_chars with std::string
27 // NOLINTNEXTLINE(unsafe-buffer-usage)
28 auto [suffix, ec]{std::from_chars(shift.data(), shift.data() + shift.size(), _shift)};
29 if(ec != std::errc()) {
30 throw ChimeraTK::logic_error("LogicalNameMappingBackend BitRangeAccessPlugin: " + info.getRegisterName() +
31 R"(: Unparseable parameter "shift".)");
32 }
33 }
34 catch(std::out_of_range&) {
35 throw ChimeraTK::logic_error("LogicalNameMappingBackend BitRangeAccessPlugin: " + info.getRegisterName() +
36 R"(: Missing parameter "shift".)");
37 }
38
39 try {
40 const auto& numberOfBits = parameters.at("numberOfBits");
41 // This is how you are supposed to use std::from_chars with std::string
42 // NOLINTNEXTLINE(unsafe-buffer-usage)
43 auto [suffix, ec]{std::from_chars(numberOfBits.data(), numberOfBits.data() + numberOfBits.size(), _numberOfBits)};
44 if(ec != std::errc()) {
45 throw ChimeraTK::logic_error("LogicalNameMappingBackend BitRangeAccessPlugin: " + info.getRegisterName() +
46 R"(: Unparseable parameter "numberOfBits".)");
47 }
48 }
49 catch(std::out_of_range&) {
50 throw ChimeraTK::logic_error("LogicalNameMappingBackend BitRangeAccessPlugin: " + info.getRegisterName() +
51 R"(: Missing parameter "numberOfBits".)");
52 }
53
54 if(const auto it = parameters.find("fractionalBits"); it != parameters.end()) {
55 // This is how you are supposed to use std::from_chars with std::string
56 // NOLINTNEXTLINE(unsafe-buffer-usage)
57 auto [suffix, ec]{
58 std::from_chars(it->second.data(), it->second.data() + it->second.size(), dataInterpretationFractionalBits)};
59 if(ec != std::errc()) {
60 throw ChimeraTK::logic_error("LogicalNameMappingBackend BitRangeAccessPlugin: " + info.getRegisterName() +
61 R"(: Unparseable parameter "fractionalBits".)");
62 }
63 }
64
65 if(const auto it = parameters.find("signed"); it != parameters.end()) {
66 std::stringstream ss(it->second);
67 Boolean value;
68 ss >> value;
70 }
71 }
72
73 /********************************************************************************************************************/
74
76 // We do not support wait_for_new_data with this decorator
79 // also remove raw-type info from DataDescriptor
81 }
82
83 /********************************************************************************************************************/
84
85 template<typename UserType, typename TargetType>
86 boost::shared_ptr<NDRegisterAccessor<UserType>> BitRangeAccessPlugin::decorateAccessor(
87 boost::shared_ptr<LogicalNameMappingBackend>& backend, boost::shared_ptr<NDRegisterAccessor<TargetType>>& target,
88 const UndecoratedParams& params) {
89 if constexpr(std::is_same_v<TargetType, uint64_t>) {
92 std::format("BitRangePlugin (on {}) Unsupported flags in {}", params._name, params._flags.serialize()));
93 }
94
95 // Resolve the correct target device
96 std::string devName = _info.deviceName;
97 boost::shared_ptr<DeviceBackend> targetDevice;
98 if(devName != "this") {
99 targetDevice = backend->_devices[devName];
100 }
101 else {
102 targetDevice = backend;
103 }
104
105 RegisterPath targetPath{params._name};
106
107 if(params._numberOfWords > 1 || params._wordOffsetInRegister != 0) {
108 throw ChimeraTK::logic_error("LNMBitRangeAccessPlugin: target must be scalar, register name: " + _info.name);
109 }
110
111 NumericAddressedRegisterInfo regInfo(_info.name, 1, 0, sizeof(uint64_t), 0, _numberOfBits,
115 regInfo.channels[0].bitOffset = _shift;
116
117 return boost::make_shared<detail::BitRangeAccessorDecorator<UserType, false>>(
118 targetDevice, targetPath, target, regInfo, 1, 0);
119 }
120
121 assert(false);
122
123 return {};
124 }
125
126} // namespace ChimeraTK::LNMBackend
void remove(AccessMode flag)
Remove the given flag from the set.
Definition AccessMode.cc:56
std::string serialize() const
Get a comma seperated list of all flag strings contained in the class.
Definition AccessMode.cc:68
bool has(AccessMode flag) const
Check if a certain flag is in the set.
Definition AccessMode.cc:20
Wrapper Class to avoid vector<bool> problems.
Definition Boolean.h:16
void setRawDataType(const DataType &d)
Set the raw data type.
@ none
The data type/concept does not exist, e.g. there is no raw transfer (do not confuse with Void)
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.
BitRangeAccessPlugin(const 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)
void doRegisterInfoUpdate() override
Implementation of the plugin specific register information update.
RegisterInfo structure for the LogicalNameMappingBackend.
RegisterPath getRegisterName() const override
Return full path name of the register (including modules)
AccessModeFlags supportedFlags
Supported AccessMode flags.
std::string deviceName
The target device alias.
bool isWriteable() const override
Return whether the register is writeable.
RegisterPath name
Name of the register.
N-dimensional register accessor.
std::vector< ChannelInfo > channels
Define per-channel information (bit interpretation etc.), 1D/scalars have exactly one entry.
Class to store a register path name.
Exception thrown when a logic error has occured.
Definition Exception.h:51
@ wait_for_new_data
Make any read blocking until new data has arrived since the last read.
@ raw
Raw access: disable any possible conversion from the original hardware data type into the given UserT...
Helper struct to hold extra parameters needed by some plugins, used in decorateAccessor()