ChimeraTK-DeviceAccess  03.18.00
testLMapBitRangePlugin.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 "TransferGroup.h"
5 #define BOOST_TEST_DYN_LINK
6 #define BOOST_TEST_MODULE LMapBitRangePluginTest
7 #include <boost/test/unit_test.hpp>
8 using namespace boost::unit_test_framework;
9 
10 #include "Device.h"
11 
12 using namespace ChimeraTK;
13 
14 BOOST_AUTO_TEST_SUITE(LMapBitRangeTestSuite)
15 
16 /**********************************************************************************************************************/
17 
18 BOOST_AUTO_TEST_CASE(testSimpleRead) {
20  device.open("(logicalNameMap?map=bitRangeReadPlugin.xlmap)");
21 
22  auto accTarget = device.getScalarRegisterAccessor<int>("SimpleScalar");
23 
24  auto accRangedHi = device.getScalarRegisterAccessor<uint16_t>("HiByte");
25  auto accRangedMid = device.getScalarRegisterAccessor<uint16_t>("MidByte");
26  auto accRangedLo = device.getScalarRegisterAccessor<uint16_t>("LoByte");
27 
28  accTarget.setAndWrite(0x1f0f);
29 
30  accRangedLo.read();
31  accRangedHi.read();
32  accRangedMid.read();
33 
34  BOOST_TEST(accRangedLo == 0x0f);
35  BOOST_TEST(accRangedHi == 0x1f);
36  BOOST_TEST(accRangedMid == 0xf0);
37 
38  TransferGroup group;
39  group.addAccessor(accRangedLo);
40  group.addAccessor(accRangedHi);
41 
42  accTarget.setAndWrite(0);
43  group.read();
44  BOOST_TEST(accRangedLo == 0);
45  BOOST_TEST(accRangedHi == 0);
46 
47  accTarget.setAndWrite(0x5a1f);
48  group.read();
49  BOOST_TEST(accRangedLo == 0x1f);
50  BOOST_TEST(accRangedHi == 0x5a);
51 }
52 
53 BOOST_AUTO_TEST_CASE(testSimpleWrite) {
55  device.open("(logicalNameMap?map=bitRangeReadPlugin.xlmap)");
56 
57  auto accTarget = device.getScalarRegisterAccessor<int>("SimpleScalar");
58 
59  auto accRangedHi = device.getScalarRegisterAccessor<uint16_t>("HiByte");
60  auto accRangedMid = device.getScalarRegisterAccessor<uint16_t>("MidByte");
61  auto accRangedLo = device.getScalarRegisterAccessor<uint16_t>("LoByte");
62 
63  accTarget.setAndWrite(0x1f0f);
64  accRangedHi = 0x76;
65  accRangedHi.write();
66 
67  accRangedMid.read();
68  BOOST_TEST(accRangedMid == 0x60);
69  accTarget.read();
70  BOOST_TEST(accTarget == 0x760f);
71 
72  // Use of overlapping ranges in transfer groups is undefined, so only use
73  // the distinct accessors
74  auto group = TransferGroup();
75  group.addAccessor(accRangedLo);
76  group.addAccessor(accRangedHi);
77 
78  accRangedHi = 0x75;
79  accRangedLo = 0x80;
80 
81  group.write();
82  accTarget.read();
83 
84  BOOST_TEST(accTarget == 0x7580);
85 
86  // Add overlapping accessor to group, check that the group cannot be written anymore
87  group.addAccessor(accRangedMid);
88  BOOST_CHECK_THROW(group.write(), ChimeraTK::logic_error);
89 }
90 
91 /**********************************************************************************************************************/
92 
93 BOOST_AUTO_TEST_CASE(testAccessorSanity) {
95  device.open("(logicalNameMap?map=bitRangeReadPlugin.xlmap)");
96 
97  // Manual test for spec B.2.4
98  // Accessor too small for the configured number of bits
99  auto accTarget = device.getScalarRegisterAccessor<int>("SimpleScalar");
100 
101  auto accMiddle = device.getScalarRegisterAccessor<int8_t>("Middle");
102  accTarget.setAndWrite(0x1fff);
103  accMiddle.read();
104  BOOST_TEST(accMiddle == 127);
105  BOOST_CHECK(accMiddle.dataValidity() == ChimeraTK::DataValidity::faulty);
106 
107  // The Number of bits requested from the target register is larger than the register
108  auto accTooLarge = device.getScalarRegisterAccessor<int16_t>("TooLarge");
109  accTooLarge.setAndWrite(0xff1);
110  accTarget.read();
111  BOOST_CHECK(accTarget == std::numeric_limits<int16_t>::max());
112 
113  // The number of bits requested is smaller than what is available in the user type and the value
114  // written in the accessor is larger than maximum value in those bits
115  accTarget.setAndWrite(0);
116 
117  auto accMiddle2 = device.getScalarRegisterAccessor<int16_t>("MidByte");
118  accMiddle2.setAndWrite(0x100);
119  accTarget.read();
120  BOOST_TEST(accTarget == 0x0ff0);
121  // FIXME: This is currently not implemented in the plugin, because it needs changes in the fixed point converter
122  // see https://redmine.msktools.desy.de/issues/12912
123  // BOOST_CHECK(accMiddle2.dataValidity() == ChimeraTK::DataValidity::faulty);
124 }
125 
126 /**********************************************************************************************************************/
127 
128 BOOST_AUTO_TEST_CASE(testMathPluginChaining) {
130  // Regression test that you can chain the bit range plugin with the math plugin
131  // The LoByteClamped register is the low-byte of SimpleScalar, but has a math plugin
132  // chained that will clamp the written value
133  device.open("(logicalNameMap?map=bitRangeReadPlugin.xlmap)");
134 
135  auto accTarget = device.getScalarRegisterAccessor<int>("SimpleScalar");
136  accTarget.setAndWrite(0x1fff);
137 
138  // Write some value in range (range is 0-5).
139  auto accClamped = device.getScalarRegisterAccessor<int8_t>("LoByteClamped");
140  accClamped.setAndWrite(0x01);
141  accTarget.read();
142  // Check that the value is passed through correctly and that the upper byte is unchanged.
143  BOOST_TEST(accTarget == 0x1f01);
144  BOOST_CHECK(accTarget.dataValidity() == ChimeraTK::DataValidity::ok);
145 
146  // Write some value outside of the range clamped by the math plugin.
147  accClamped.setAndWrite(55);
148  accTarget.read();
149 
150  // Check that the value is passed through the math plugin (clamped to max) and that the upper byte is unchanged.
151  BOOST_TEST(accTarget == 0x1f05);
152  BOOST_CHECK(accTarget.dataValidity() == ChimeraTK::DataValidity::ok);
153 }
154 
155 /**********************************************************************************************************************/
156 
157 BOOST_AUTO_TEST_CASE(testBitExtraction) {
159  device.open("(logicalNameMap?map=bitRangeReadPlugin.xlmap)");
160 
161  auto accTarget = device.getScalarRegisterAccessor<int>("SimpleScalar");
162  accTarget.setAndWrite(0x5555);
163 
164  auto accRangedHi = device.getScalarRegisterAccessor<uint16_t>("HiByte");
165 
166  auto accBit0 = device.getScalarRegisterAccessor<ChimeraTK::Boolean>("Bit0");
167  auto accBit1 = device.getScalarRegisterAccessor<ChimeraTK::Boolean>("Bit1");
168  auto accBit2 = device.getScalarRegisterAccessor<ChimeraTK::Boolean>("Bit2");
169  auto accBit3 = device.getScalarRegisterAccessor<ChimeraTK::Boolean>("Bit3");
170 
171  // See that the bits we get match the value we have
172  accBit0.read();
173  accBit1.read();
174  accBit2.read();
175  accBit3.read();
176 
177  BOOST_TEST(accBit0);
178  BOOST_TEST(!accBit1);
179  BOOST_TEST(accBit2);
180  BOOST_TEST(!accBit3);
181 
182  // Write to the part that is not mapped to single bits
183  // make sure the single bits are not modified
184  accRangedHi.setAndWrite(0x11);
185  accTarget.read();
186 
187  BOOST_TEST(accTarget == 0x1155);
188 
189  accBit0.read();
190  accBit1.read();
191  accBit2.read();
192  accBit3.read();
193 
194  BOOST_TEST(accBit0);
195  BOOST_TEST(!accBit1);
196  BOOST_TEST(accBit2);
197  BOOST_TEST(!accBit3);
198 
199  // Toggle single bits, make sure that this does not spread across the rest of the bits
200  accBit1.setAndWrite(true);
201  accBit3.setAndWrite(true);
202 
203  accTarget.read();
204 
205  BOOST_TEST(accTarget == 0x115F);
206  accRangedHi.read();
207  BOOST_TEST(accRangedHi == 0x11);
208 }
209 
210 /**********************************************************************************************************************/
211 
212 BOOST_AUTO_TEST_CASE(testDataDescription) {
214  device.open("(logicalNameMap?map=bitRangeReadPlugin.xlmap)");
215 
216  auto accTarget = device.getScalarRegisterAccessor<int>("SimpleScalar");
217  accTarget.setAndWrite(0x5555);
218 
219  auto accLo = device.getScalarRegisterAccessor<uint8_t>("LoByte");
220  auto accLoSigned = device.getScalarRegisterAccessor<int8_t>("LowerSigned");
221 
222  accLo.read();
223  accLoSigned.read();
224  BOOST_TEST(accLo == 85);
225  BOOST_TEST(accLoSigned == 85);
226 
227  accTarget.setAndWrite(0x5580);
228 
229  accLo.read();
230  accLoSigned.read();
231 
232  BOOST_TEST(int(accLo) == 128);
233  BOOST_TEST(int(accLoSigned) == -128);
234 
235  accTarget.setAndWrite(0x5555);
236  auto accFixed = device.getScalarRegisterAccessor<float>("LowerFixedPoint");
237  accFixed.read();
238  BOOST_TEST(accFixed == 5.3125);
239 }
240 
241 /**********************************************************************************************************************/
242 
243 BOOST_AUTO_TEST_SUITE_END()
TransferGroup.h
device
ctk::Device device
Definition: testExceptionDummyDevice.cc:18
ChimeraTK::DataValidity::faulty
@ faulty
The data is considered valid.
ChimeraTK::TransferGroup::addAccessor
void addAccessor(TransferElementAbstractor &accessor)
Add a register accessor to the group.
Definition: TransferGroup.cc:305
ChimeraTK::TransferGroup
Group multiple data accessors to efficiently trigger data transfers on the whole group.
Definition: TransferGroup.h:26
ChimeraTK::TransferGroup::read
void read()
Trigger read transfer for all accessors in the group.
Definition: TransferGroup.cc:44
ChimeraTK::DataValidity::ok
@ ok
Device.h
ChimeraTK::Device
Class allows to read/write registers from device.
Definition: Device.h:39
ChimeraTK::Device::open
void open(std::string const &aliasName)
Open a device by the given alias name from the DMAP file.
Definition: Device.cc:58
ChimeraTK::Device::getScalarRegisterAccessor
ScalarRegisterAccessor< UserType > getScalarRegisterAccessor(const RegisterPath &registerPathName, size_t wordOffsetInRegister=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a ScalarRegisterObject object for the given register.
Definition: Device.h:263
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::Boolean
Wrapper Class to avoid vector<bool> problems.
Definition: SupportedUserTypes.h:21
ChimeraTK::logic_error
Exception thrown when a logic error has occured.
Definition: Exception.h:51
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(testSimpleRead)
Definition: testLMapBitRangePlugin.cc:18