ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
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>
8using namespace boost::unit_test_framework;
9
10#include "Device.h"
11
12using namespace ChimeraTK;
13
14BOOST_AUTO_TEST_SUITE(LMapBitRangeTestSuite)
15
16/**********************************************************************************************************************/
17
18BOOST_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
53BOOST_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
93BOOST_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
128BOOST_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
157BOOST_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
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
212BOOST_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
243BOOST_AUTO_TEST_SUITE_END()
Wrapper Class to avoid vector<bool> problems.
Class allows to read/write registers from device.
Definition Device.h:39
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:266
void open(std::string const &aliasName)
Open a device by the given alias name from the DMAP file.
Definition Device.cc:58
Group multiple data accessors to efficiently trigger data transfers on the whole group.
void addAccessor(TransferElementAbstractor &accessor)
Add a register accessor to the group.
void read()
Trigger read transfer for all accessors in the group.
Exception thrown when a logic error has occured.
Definition Exception.h:51
@ faulty
The data is considered valid.
ctk::Device device
BOOST_AUTO_TEST_CASE(testSimpleRead)