ChimeraTK-DeviceAccess 03.29.00
Loading...
Searching...
No Matches
testLMapBackend.cpp
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#define BOOST_TEST_DYN_LINK
5#define BOOST_TEST_MODULE LMapBackendTest
6#include <boost/test/unit_test.hpp>
7using namespace boost::unit_test_framework;
8
9#include "Device.h"
12#include "TransferGroup.h"
13#include "UnifiedBackendTest.h"
14
15using namespace ChimeraTK;
16
17BOOST_AUTO_TEST_SUITE(LMapBackendTestSuite)
18
19/**********************************************************************************************************************/
20
21BOOST_AUTO_TEST_CASE(testExceptions) {
22 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
24 BOOST_CHECK(device.isOpened() == false);
25 device.open("LMAP0");
26 BOOST_CHECK(device.isOpened() == true);
27 // you must always be able to re-open a backend. It should try to re-connect, if applicable.
28 device.open();
29 BOOST_CHECK(device.isOpened() == true);
30 device.open("LMAP0");
31 BOOST_CHECK(device.isOpened() == true);
32
33 int data = 0;
34
35 BOOST_CHECK_THROW(device.write("Channel3", data), ChimeraTK::logic_error);
36
37 BOOST_CHECK_THROW(
38 std::ignore = device.getOneDRegisterAccessor<int>("ExceedsNumberOfChannels"), ChimeraTK::logic_error);
39 BOOST_CHECK_NO_THROW(std::ignore = device.getOneDRegisterAccessor<int>("LastChannelInRegister"));
40
41 BOOST_CHECK(device.isOpened() == true);
42 device.close();
43 BOOST_CHECK(device.isOpened() == false);
44 device.close();
45 BOOST_CHECK(device.isOpened() == false);
46}
47
48/**********************************************************************************************************************/
49
50BOOST_AUTO_TEST_CASE(testCatalogue) {
51 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
53
54 device.open("LMAP0");
55
57
58 auto info = catalogue.getRegister("SingleWord");
59 BOOST_CHECK(info.getRegisterName() == "/SingleWord");
60 BOOST_CHECK(info.getNumberOfElements() == 1);
61 BOOST_CHECK(info.getNumberOfChannels() == 1);
62 BOOST_CHECK(info.getNumberOfDimensions() == 0);
63
64 info = catalogue.getRegister("FullArea");
65 BOOST_CHECK(info.getRegisterName() == "/FullArea");
66 BOOST_CHECK(info.getNumberOfElements() == 0x400);
67 BOOST_CHECK(info.getNumberOfChannels() == 1);
68 BOOST_CHECK(info.getNumberOfDimensions() == 1);
69
70 info = catalogue.getRegister("PartOfArea");
71 BOOST_CHECK(info.getRegisterName() == "/PartOfArea");
72 BOOST_CHECK(info.getNumberOfElements() == 20);
73 BOOST_CHECK(info.getNumberOfChannels() == 1);
74 BOOST_CHECK(info.getNumberOfDimensions() == 1);
75
76 ChimeraTK::Device target1;
77 target1.open("PCIE3");
78 ChimeraTK::TwoDRegisterAccessor<int32_t> accTarget = target1.getTwoDRegisterAccessor<int32_t>("TEST/NODMA");
79 unsigned int nSamples = accTarget[3].size();
80
81 info = catalogue.getRegister("Channel3");
82 BOOST_CHECK(info.getRegisterName() == "/Channel3");
83 BOOST_CHECK(info.getNumberOfElements() == nSamples);
84 BOOST_CHECK(info.getNumberOfChannels() == 1);
85 BOOST_CHECK(info.getNumberOfDimensions() == 1);
86
87 info = catalogue.getRegister("Constant2");
88 BOOST_CHECK(info.getRegisterName() == "/Constant2");
89 BOOST_CHECK(info.getNumberOfElements() == 1);
90 BOOST_CHECK(info.getNumberOfChannels() == 1);
91 BOOST_CHECK(info.getNumberOfDimensions() == 0);
92
93 info = catalogue.getRegister("/MyModule/SomeSubmodule/Variable");
94 BOOST_CHECK(info.getRegisterName() == "/MyModule/SomeSubmodule/Variable");
95 BOOST_CHECK(info.getNumberOfElements() == 1);
96 BOOST_CHECK(info.getNumberOfChannels() == 1);
97 BOOST_CHECK(info.getNumberOfDimensions() == 0);
98
99 // std::unordered_set<std::string> targetDevices = lmap.getTargetDevices();
100 // BOOST_CHECK(targetDevices.size() == 2);
101 // BOOST_CHECK(targetDevices.count("PCIE2") == 1);
102 // BOOST_CHECK(targetDevices.count("PCIE3") == 1);
103
104 device.close();
105}
106
107/**********************************************************************************************************************/
108
109BOOST_AUTO_TEST_CASE(testReadWriteConstant) {
110 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
112
113 device.open("LMAP0");
114 BOOST_CHECK(device.read<int>("Constant") == 42);
115
116 BOOST_CHECK_THROW(device.write("Constant", 0), ChimeraTK::logic_error);
117
118 BOOST_CHECK(device.read<int>("Constant") == 42);
119
120 // test with buffering register accessor
121 auto acc = device.getOneDRegisterAccessor<int32_t>("Constant");
122 BOOST_CHECK(acc.getNElements() == 1);
123 BOOST_CHECK(acc[0] == 0); // values are only available after the first read, otherwise there is the value after
124 // construction (= int32_t() aka. 0)
125 acc.read();
126 BOOST_CHECK(acc[0] == 42);
127 BOOST_CHECK_THROW(acc.write(), ChimeraTK::logic_error);
128
129 auto acc2 = device.getOneDRegisterAccessor<int32_t>("Constant");
130 auto acc3 = device.getOneDRegisterAccessor<int32_t>("Constant2");
131
132 boost::shared_ptr<NDRegisterAccessor<int32_t>> impl, impl2, impl3;
133 impl = boost::dynamic_pointer_cast<NDRegisterAccessor<int32_t>>(acc.getHighLevelImplElement());
134 impl2 = boost::dynamic_pointer_cast<NDRegisterAccessor<int32_t>>(acc2.getHighLevelImplElement());
135 impl3 = boost::dynamic_pointer_cast<NDRegisterAccessor<int32_t>>(acc3.getHighLevelImplElement());
136
137 // BOOST_CHECK( impl->mayReplaceOther(impl2) == true ); // this is
138 // currently always set to false, since it doesn't really make any
139 // difference...
140 BOOST_CHECK(impl->mayReplaceOther(impl3) == false);
141
142 auto arrayConstant = device.getOneDRegisterAccessor<int>("/ArrayConstant");
143 BOOST_CHECK_EQUAL(arrayConstant.getNElements(), 5);
144 BOOST_CHECK_EQUAL(arrayConstant[0], 0);
145 BOOST_CHECK_EQUAL(arrayConstant[1], 0);
146 BOOST_CHECK_EQUAL(arrayConstant[2], 0);
147 BOOST_CHECK_EQUAL(arrayConstant[3], 0);
148 BOOST_CHECK_EQUAL(arrayConstant[4], 0);
149 arrayConstant.read();
150 BOOST_CHECK_EQUAL(arrayConstant[0], 1111);
151 BOOST_CHECK_EQUAL(arrayConstant[1], 2222);
152 BOOST_CHECK_EQUAL(arrayConstant[2], 3333);
153 BOOST_CHECK_EQUAL(arrayConstant[3], 4444);
154 BOOST_CHECK_EQUAL(arrayConstant[4], 5555);
155 BOOST_CHECK_THROW(arrayConstant.write(), ChimeraTK::logic_error);
156
157 auto partOfArrayConstant = device.getOneDRegisterAccessor<int>("/ArrayConstant", 2, 1);
158 BOOST_CHECK_EQUAL(partOfArrayConstant.getNElements(), 2);
159 BOOST_CHECK_EQUAL(partOfArrayConstant[0], 0);
160 BOOST_CHECK_EQUAL(partOfArrayConstant[1], 0);
161 partOfArrayConstant.read();
162 BOOST_CHECK_EQUAL(partOfArrayConstant[0], 2222);
163 BOOST_CHECK_EQUAL(partOfArrayConstant[1], 3333);
164 BOOST_CHECK_THROW(partOfArrayConstant.write(), ChimeraTK::logic_error);
165
166 device.close();
167}
168
169/**********************************************************************************************************************/
170
171BOOST_AUTO_TEST_CASE(testReadWriteVariable) {
172 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
174
175 device.open("LMAP0");
176
177 // test with buffering register accessor
178 auto acc = device.getOneDRegisterAccessor<int32_t>("/MyModule/SomeSubmodule/Variable");
179 auto acc2 = device.getOneDRegisterAccessor<int32_t>("/MyModule/SomeSubmodule/Variable");
180 BOOST_CHECK(acc.getVersionNumber() == VersionNumber(nullptr));
181 BOOST_CHECK(acc2.getVersionNumber() == VersionNumber(nullptr));
182 BOOST_CHECK(acc.getNElements() == 1);
183 BOOST_CHECK(acc[0] == 0);
184 BOOST_CHECK(acc2[0] == 0);
185 acc.read();
186 BOOST_CHECK(acc[0] == 2);
187 acc[0] = 3;
188 BOOST_CHECK(acc[0] == 3);
189 BOOST_CHECK(acc2[0] == 0);
190 acc.write();
191 acc2.read();
192 BOOST_CHECK(acc[0] == 3);
193 BOOST_CHECK(acc2[0] == 3);
194
195 // test array access
196 auto arrayVariable = device.getOneDRegisterAccessor<int>("/ArrayVariable");
197 BOOST_CHECK_EQUAL(arrayVariable.getNElements(), 6);
198 BOOST_CHECK_EQUAL(arrayVariable[0], 0);
199 BOOST_CHECK_EQUAL(arrayVariable[1], 0);
200 BOOST_CHECK_EQUAL(arrayVariable[2], 0);
201 BOOST_CHECK_EQUAL(arrayVariable[3], 0);
202 BOOST_CHECK_EQUAL(arrayVariable[4], 0);
203 BOOST_CHECK_EQUAL(arrayVariable[5], 0);
204 arrayVariable.read();
205 BOOST_CHECK_EQUAL(arrayVariable[0], 11);
206 BOOST_CHECK_EQUAL(arrayVariable[1], 22);
207 BOOST_CHECK_EQUAL(arrayVariable[2], 33);
208 BOOST_CHECK_EQUAL(arrayVariable[3], 44);
209 BOOST_CHECK_EQUAL(arrayVariable[4], 55);
210 BOOST_CHECK_EQUAL(arrayVariable[5], 66);
211 arrayVariable = std::vector<int>({6, 5, 4, 3, 2, 1});
212 arrayVariable.write();
213 BOOST_CHECK_EQUAL(arrayVariable[0], 6);
214 BOOST_CHECK_EQUAL(arrayVariable[1], 5);
215 BOOST_CHECK_EQUAL(arrayVariable[2], 4);
216 BOOST_CHECK_EQUAL(arrayVariable[3], 3);
217 BOOST_CHECK_EQUAL(arrayVariable[4], 2);
218 BOOST_CHECK_EQUAL(arrayVariable[5], 1);
219 arrayVariable = std::vector<int>({0, 0, 0, 0, 0, 0});
220 arrayVariable.read();
221 BOOST_CHECK_EQUAL(arrayVariable[0], 6);
222 BOOST_CHECK_EQUAL(arrayVariable[1], 5);
223 BOOST_CHECK_EQUAL(arrayVariable[2], 4);
224 BOOST_CHECK_EQUAL(arrayVariable[3], 3);
225 BOOST_CHECK_EQUAL(arrayVariable[4], 2);
226 BOOST_CHECK_EQUAL(arrayVariable[5], 1);
227
228 auto partOfArrayVariable = device.getOneDRegisterAccessor<int>("/ArrayVariable", 3, 2);
229 BOOST_CHECK_EQUAL(partOfArrayVariable.getNElements(), 3);
230 BOOST_CHECK_EQUAL(partOfArrayVariable[0], 0);
231 BOOST_CHECK_EQUAL(partOfArrayVariable[1], 0);
232 BOOST_CHECK_EQUAL(partOfArrayVariable[2], 0);
233 partOfArrayVariable.read();
234 BOOST_CHECK_EQUAL(partOfArrayVariable[0], 4);
235 BOOST_CHECK_EQUAL(partOfArrayVariable[1], 3);
236 BOOST_CHECK_EQUAL(partOfArrayVariable[2], 2);
237 partOfArrayVariable = std::vector<int>({42, 120, 31415});
238 partOfArrayVariable.write();
239 BOOST_CHECK_EQUAL(partOfArrayVariable[0], 42);
240 BOOST_CHECK_EQUAL(partOfArrayVariable[1], 120);
241 BOOST_CHECK_EQUAL(partOfArrayVariable[2], 31415);
242 partOfArrayVariable = std::vector<int>({0, 0, 0});
243 partOfArrayVariable.read();
244 BOOST_CHECK_EQUAL(partOfArrayVariable[0], 42);
245 BOOST_CHECK_EQUAL(partOfArrayVariable[1], 120);
246 BOOST_CHECK_EQUAL(partOfArrayVariable[2], 31415);
247
248 BOOST_CHECK_EQUAL(arrayVariable[0], 6);
249 BOOST_CHECK_EQUAL(arrayVariable[1], 5);
250 BOOST_CHECK_EQUAL(arrayVariable[2], 4);
251 BOOST_CHECK_EQUAL(arrayVariable[3], 3);
252 BOOST_CHECK_EQUAL(arrayVariable[4], 2);
253 BOOST_CHECK_EQUAL(arrayVariable[5], 1);
254 arrayVariable.read();
255 BOOST_CHECK_EQUAL(arrayVariable[0], 6);
256 BOOST_CHECK_EQUAL(arrayVariable[1], 5);
257 BOOST_CHECK_EQUAL(arrayVariable[2], 42);
258 BOOST_CHECK_EQUAL(arrayVariable[3], 120);
259 BOOST_CHECK_EQUAL(arrayVariable[4], 31415);
260 BOOST_CHECK_EQUAL(arrayVariable[5], 1);
261
262 device.close();
263}
264
265/**********************************************************************************************************************/
266
267BOOST_AUTO_TEST_CASE(testReadWriteRegister) {
268 std::vector<int> area(1024);
269
270 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
271 ChimeraTK::Device device, target1;
272
273 target1.open("PCIE2");
274 device.open("LMAP0");
275 // single word
276 target1.write("BOARD.WORD_USER", 120);
277 BOOST_CHECK(device.read<int>("SingleWord") == 120);
278
279 target1.write("BOARD.WORD_USER", 66);
280 BOOST_CHECK(device.read<int>("SingleWord") == 66);
281
282 device.write("SingleWord", 42);
283 BOOST_CHECK(target1.read<int>("BOARD.WORD_USER") == 42);
284
285 device.write("SingleWord", 12);
286 BOOST_CHECK(target1.read<int>("BOARD.WORD_USER") == 12);
287
288 // area
289 for(int i = 0; i < 1024; i++) area[i] = 12345 + 3 * i;
290 target1.write("ADC.AREA_DMAABLE", area);
291 area = device.read<int>("FullArea", 1024);
292 for(int i = 0; i < 1024; i++) BOOST_CHECK(area[i] == 12345 + 3 * i);
293
294 for(int i = 0; i < 1024; i++) area[i] = -876543210 + 42 * i;
295 target1.write("ADC.AREA_DMAABLE", area);
296 area = device.read<int>("FullArea", 1024);
297 for(int i = 0; i < 1024; i++) BOOST_CHECK(area[i] == -876543210 + 42 * i);
298
299 for(int i = 0; i < 1024; i++) area[i] = 12345 + 3 * i;
300 device.write("FullArea", area);
301 area = target1.read<int>("ADC.AREA_DMAABLE", 1024);
302 for(int i = 0; i < 1024; i++) BOOST_CHECK(area[i] == 12345 + 3 * i);
303
304 for(int i = 0; i < 1024; i++) area[i] = -876543210 + 42 * i;
305 device.write("FullArea", area);
306 area = target1.read<int>("ADC.AREA_DMAABLE", 1024);
307 for(int i = 0; i < 1024; i++) BOOST_CHECK(area[i] == -876543210 + 42 * i);
308
309 device.close();
310}
311
312/**********************************************************************************************************************/
313
314BOOST_AUTO_TEST_CASE(testReadWriteRange) {
315 std::vector<int> area(1024);
316
317 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
318 ChimeraTK::Device device, target1;
319
320 device.open("LMAP0");
321 target1.open("PCIE2");
322
323 for(int i = 0; i < 1024; i++) area[i] = 0;
324 for(int i = 0; i < 20; i++) area[i + 10] = 12345 + 3 * i;
325 target1.write("ADC.AREA_DMAABLE", area);
326 area = device.read<int>("PartOfArea", 20);
327 for(int i = 0; i < 20; i++) BOOST_CHECK(area[i] == 12345 + 3 * i);
328
329 area.resize(1024);
330 for(int i = 0; i < 1024; i++) area[i] = 0;
331 for(int i = 0; i < 20; i++) area[i + 10] = -876543210 + 42 * i;
332 target1.write("ADC.AREA_DMAABLE", area);
333 for(int i = 0; i < 1024; i++) area[i] = 0;
334 area = device.read<int>("PartOfArea", 20);
335 for(int i = 0; i < 20; i++) BOOST_CHECK(area[i] == -876543210 + 42 * i);
336
337 device.close();
338}
339
340/**********************************************************************************************************************/
341
342BOOST_AUTO_TEST_CASE(testRegisterAccessorForRegister) {
343 std::vector<int> area(1024);
344 int index;
345
346 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
347 ChimeraTK::Device device, target1;
348
349 device.open("LMAP0");
350 target1.open("PCIE2");
351
352 auto acc = device.getOneDRegisterAccessor<int32_t>("FullArea");
353 BOOST_CHECK(!acc.isReadOnly());
354 BOOST_CHECK(acc.isReadable());
355 BOOST_CHECK(acc.isWriteable());
356
357 auto acc2 = device.getOneDRegisterAccessor<int32_t>("PartOfArea");
358
359 boost::shared_ptr<NDRegisterAccessor<int32_t>> impl, impl2;
360 impl = boost::dynamic_pointer_cast<NDRegisterAccessor<int32_t>>(acc.getHighLevelImplElement());
361 impl2 = boost::dynamic_pointer_cast<NDRegisterAccessor<int32_t>>(acc2.getHighLevelImplElement());
362
363 BOOST_CHECK(impl != impl2);
364 BOOST_CHECK(impl2->mayReplaceOther(impl) == false);
365 BOOST_CHECK(impl->mayReplaceOther(impl2) == false);
366
367 const ChimeraTK::OneDRegisterAccessor<int32_t> acc_const = acc;
368
369 // reading via [] operator
370 for(int i = 0; i < 1024; i++) area[i] = 12345 + 3 * i;
371 target1.write("ADC.AREA_DMAABLE", area);
372 acc.read();
373 for(int i = 0; i < 1024; i++) BOOST_CHECK(acc[i] == 12345 + 3 * i);
374
375 for(int i = 0; i < 1024; i++) area[i] = -876543210 + 42 * i;
376 target1.write("ADC.AREA_DMAABLE", area);
377 acc.read();
378 for(int i = 0; i < 1024; i++) BOOST_CHECK(acc[i] == -876543210 + 42 * i);
379
380 // writing via [] operator
381 for(int i = 0; i < 1024; i++) acc[i] = 12345 + 3 * i;
382 acc.write();
383 area = target1.read<int>("ADC.AREA_DMAABLE", 1024);
384 for(int i = 0; i < 1024; i++) BOOST_CHECK(area[i] == 12345 + 3 * i);
385
386 for(int i = 0; i < 1024; i++) acc[i] = -876543210 + 42 * i;
387 acc.write();
388 area = target1.read<int>("ADC.AREA_DMAABLE", 1024);
389 for(int i = 0; i < 1024; i++) BOOST_CHECK(area[i] == -876543210 + 42 * i);
390
391 // reading via iterator
392 index = 0;
393 for(auto it = acc.begin(); it != acc.end(); ++it) {
394 BOOST_CHECK(*it == -876543210 + 42 * index);
395 ++index;
396 }
397 BOOST_CHECK(index == 1024);
398
399 // reading via const_iterator
400 index = 0;
401 for(auto it = acc_const.begin(); it != acc_const.end(); ++it) {
402 BOOST_CHECK(*it == -876543210 + 42 * index);
403 ++index;
404 }
405 BOOST_CHECK(index == 1024);
406
407 // reading via reverse_iterator
408 index = 1024;
409 for(auto it = acc.rbegin(); it != acc.rend(); ++it) {
410 --index;
411 BOOST_CHECK(*it == -876543210 + 42 * index);
412 }
413 BOOST_CHECK(index == 0);
414
415 // reading via const_reverse_iterator
416 index = 1024;
417 for(auto it = acc_const.rbegin(); it != acc_const.rend(); ++it) {
418 --index;
419 BOOST_CHECK(*it == -876543210 + 42 * index);
420 }
421 BOOST_CHECK(index == 0);
422
423 // swap with std::vector
424 std::vector<int32_t> vec(1024);
425 acc.swap(vec);
426 for(unsigned int i = 0; i < vec.size(); i++) {
427 BOOST_CHECK(vec[i] == -876543210 + 42 * static_cast<signed>(i));
428 }
429
430 device.close();
431}
432
433/**********************************************************************************************************************/
434
435BOOST_AUTO_TEST_CASE(testRegisterAccessorForRange) {
436 std::vector<int> area(1024);
437 int index;
438
439 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
440 ChimeraTK::Device device, target1;
441
442 device.open("LMAP0");
443 target1.open("PCIE2");
444
445 auto acc = device.getOneDRegisterAccessor<int32_t>("PartOfArea");
446 BOOST_CHECK(acc.isReadOnly() == false);
447 BOOST_CHECK(acc.isReadable());
448 BOOST_CHECK(acc.isWriteable());
449
450 const ChimeraTK::OneDRegisterAccessor<int32_t> acc_const = acc;
451
452 for(int i = 0; i < 20; i++) area[i + 10] = 12345 + 3 * i;
453 target1.write("ADC.AREA_DMAABLE", area);
454 acc.read();
455 for(int i = 0; i < 20; i++) BOOST_CHECK(acc[i] == 12345 + 3 * i);
456
457 for(int i = 0; i < 20; i++) area[i + 10] = -876543210 + 42 * i;
458 target1.write("ADC.AREA_DMAABLE", area);
459 acc.read();
460 for(int i = 0; i < 20; i++) BOOST_CHECK(acc[i] == -876543210 + 42 * i);
461
462 // reading via iterator
463 index = 0;
464 for(auto it = acc.begin(); it != acc.end(); ++it) {
465 BOOST_CHECK(*it == -876543210 + 42 * index);
466 ++index;
467 }
468 BOOST_CHECK(index == 20);
469
470 // reading via const_iterator
471 index = 0;
472 for(auto it = acc_const.begin(); it != acc_const.end(); ++it) {
473 BOOST_CHECK(*it == -876543210 + 42 * index);
474 ++index;
475 }
476 BOOST_CHECK(index == 20);
477
478 // reading via reverse_iterator
479 index = 20;
480 for(auto it = acc.rbegin(); it != acc.rend(); ++it) {
481 --index;
482 BOOST_CHECK(*it == -876543210 + 42 * index);
483 }
484 BOOST_CHECK(index == 0);
485
486 // reading via const_reverse_iterator
487 index = 20;
488 for(auto it = acc_const.rbegin(); it != acc_const.rend(); ++it) {
489 --index;
490 BOOST_CHECK(*it == -876543210 + 42 * index);
491 }
492 BOOST_CHECK(index == 0);
493
494 // writing
495 for(int i = 0; i < 20; i++) acc[i] = 24507 + 33 * i;
496 acc.write();
497 area = target1.read<int>("ADC.AREA_DMAABLE", 1024);
498 for(int i = 0; i < 20; i++) BOOST_CHECK(area[i + 10] == 24507 + 33 * i);
499
500 device.close();
501}
502
503/**********************************************************************************************************************/
504
505BOOST_AUTO_TEST_CASE(testRegisterAccessorForChannel) {
506 std::vector<int> area(1024);
507
508 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
509 ChimeraTK::Device device, target1;
510
511 device.open("LMAP0");
512 target1.open("PCIE3");
513
514 auto acc3 = device.getOneDRegisterAccessor<int32_t>("Channel3");
515 auto acc4 = device.getOneDRegisterAccessor<int32_t>("Channel4");
516
517 auto acc3_2 = device.getOneDRegisterAccessor<int32_t>("Channel3");
518
519 boost::shared_ptr<NDRegisterAccessor<int32_t>> impl3, impl4, impl3_2;
520 impl3 = boost::dynamic_pointer_cast<NDRegisterAccessor<int32_t>>(acc3.getHighLevelImplElement());
521 impl4 = boost::dynamic_pointer_cast<NDRegisterAccessor<int32_t>>(acc4.getHighLevelImplElement());
522 impl3_2 = boost::dynamic_pointer_cast<NDRegisterAccessor<int32_t>>(acc3_2.getHighLevelImplElement());
523 BOOST_CHECK(impl3->mayReplaceOther(impl3_2) == true);
524 BOOST_CHECK(impl3->mayReplaceOther(impl4) == false);
525
526 auto accTarget = target1.getTwoDRegisterAccessor<int32_t>("TEST/NODMA");
527 unsigned int nSamples = accTarget[3].size();
528 BOOST_CHECK(accTarget[4].size() == nSamples);
529 BOOST_CHECK(acc3.getNElements() == nSamples);
530 BOOST_CHECK(acc4.getNElements() == nSamples);
531
532 // fill target register
533 for(unsigned int i = 0; i < nSamples; i++) {
534 accTarget[3][i] = 3000 + i;
535 accTarget[4][i] = 4000 - i;
536 }
537 accTarget.write();
538
539 // clear channel accessor buffers
540 for(unsigned int i = 0; i < nSamples; i++) {
541 acc3[i] = 0;
542 acc4[i] = 0;
543 }
544
545 // read channel accessors
546 acc3.read();
547 for(unsigned int i = 0; i < nSamples; i++) {
548 BOOST_CHECK(acc3[i] == (signed)(3000 + i));
549 BOOST_CHECK(acc4[i] == 0);
550 }
551 acc4.read();
552 for(unsigned int i = 0; i < nSamples; i++) {
553 BOOST_CHECK(acc3[i] == (signed)(3000 + i));
554 BOOST_CHECK(acc4[i] == (signed)(4000 - i));
555 }
556
557 // read via iterators
558 unsigned int idx = 0;
559 for(auto it = acc3.begin(); it != acc3.end(); ++it) {
560 BOOST_CHECK(*it == (signed)(3000 + idx));
561 ++idx;
562 }
563 BOOST_CHECK(idx == nSamples);
564
565 // read via const iterators
566 const ChimeraTK::OneDRegisterAccessor<int32_t>& acc3_const = acc3;
567 idx = 0;
568 for(auto it = acc3_const.begin(); it != acc3_const.end(); ++it) {
569 BOOST_CHECK(*it == (signed)(3000 + idx));
570 ++idx;
571 }
572 BOOST_CHECK(idx == nSamples);
573
574 // read via reverse iterators
575 idx = nSamples;
576 for(auto it = acc3.rbegin(); it != acc3.rend(); ++it) {
577 --idx;
578 BOOST_CHECK(*it == (signed)(3000 + idx));
579 }
580 BOOST_CHECK(idx == 0);
581
582 // read via reverse const iterators
583 idx = nSamples;
584 for(auto it = acc3_const.rbegin(); it != acc3_const.rend(); ++it) {
585 --idx;
586 BOOST_CHECK(*it == (signed)(3000 + idx));
587 }
588 BOOST_CHECK(idx == 0);
589
590 // swap into other vector
591 std::vector<int> someVector(nSamples);
592 acc3.swap(someVector);
593 for(unsigned int i = 0; i < nSamples; i++) {
594 BOOST_CHECK(someVector[i] == (signed)(3000 + i));
595 }
596
597 // write channel registers fails
598 BOOST_CHECK(acc3.isReadOnly());
599 BOOST_CHECK(acc3.isReadable());
600 BOOST_CHECK(acc3.isWriteable() == false);
601
602 BOOST_CHECK(acc4.isReadOnly());
603 BOOST_CHECK(acc4.isReadable());
604 BOOST_CHECK(acc4.isWriteable() == false);
605
606 BOOST_CHECK_THROW(acc3.write(), ChimeraTK::logic_error);
607 BOOST_CHECK_THROW(acc4.write(), ChimeraTK::logic_error);
608
609 device.close();
610}
611
612/**********************************************************************************************************************/
613
614BOOST_AUTO_TEST_CASE(testRegisterAccessorForBit) {
615 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
617
618 device.open("LMAP0");
619
620 auto bitField = device.getScalarRegisterAccessor<int>("/MyModule/SomeSubmodule/Variable");
621 auto bit0 = device.getScalarRegisterAccessor<uint8_t>("/Bit0ofVar");
622 auto bit1 = device.getScalarRegisterAccessor<uint16_t>("/Bit1ofVar");
623 auto bit2 = device.getScalarRegisterAccessor<int32_t>("/Bit2ofVar");
624 auto bit3 = device.getScalarRegisterAccessor<std::string>("/Bit3ofVar");
625
626 bitField = 0;
627 bitField.write();
628
629 bit0.read();
630 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
631 bit1.read();
632 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
633 bit2.read();
634 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
635 bit3.read();
636 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
637
638 bitField = 1;
639 bitField.write();
640
641 bit0.read();
642 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
643 bit1.read();
644 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
645 bit2.read();
646 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
647 bit3.read();
648 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
649
650 bitField = 2;
651 bitField.write();
652
653 bit0.read();
654 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
655 bit1.read();
656 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 1);
657 bit2.read();
658 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
659 bit3.read();
660 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
661
662 bitField = 3;
663 bitField.write();
664
665 bit0.read();
666 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
667 bit1.read();
668 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 1);
669 bit2.read();
670 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
671 bit3.read();
672 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
673
674 bitField = 4;
675 bitField.write();
676
677 bit0.read();
678 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
679 bit1.read();
680 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
681 bit2.read();
682 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 1);
683 bit3.read();
684 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
685
686 bitField = 8;
687 bitField.write();
688
689 bit0.read();
690 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
691 bit1.read();
692 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
693 bit2.read();
694 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
695 bit3.read();
696 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "1");
697
698 bitField = 15;
699 bitField.write();
700
701 bit0.read();
702 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
703 bit1.read();
704 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 1);
705 bit2.read();
706 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 1);
707 bit3.read();
708 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "1");
709
710 bitField = 16;
711 bitField.write();
712
713 bit0.read();
714 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
715 bit1.read();
716 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
717 bit2.read();
718 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
719 bit3.read();
720 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
721
722 bitField = 17;
723 bitField.write();
724
725 bit0.read();
726 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
727 bit1.read();
728 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
729 bit2.read();
730 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
731 bit3.read();
732 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
733
734 bitField = 1;
735 bitField.write();
736
737 bit0.read();
738 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
739 bit1.read();
740 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
741 bit2.read();
742 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
743 bit3.read();
744 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
745
746 bit2 = 1;
747 bit2.write();
748 bitField.read();
749 BOOST_CHECK_EQUAL(static_cast<int>(bitField), 5);
750
751 bit1 = 1;
752 bit1.write();
753 bitField.read();
754 BOOST_CHECK_EQUAL(static_cast<int>(bitField), 7);
755
756 bit0 = 0;
757 bit0.write();
758 bitField.read();
759 BOOST_CHECK_EQUAL(static_cast<int>(bitField), 6);
760
761 bit3 = "1";
762 bit3.write();
763 bitField.read();
764 BOOST_CHECK_EQUAL(static_cast<int>(bitField), 14);
765
766 // Test with TransferGroup
767 TransferGroup group;
768 group.addAccessor(bit0);
769 group.addAccessor(bit1);
770 group.addAccessor(bit2);
771 group.addAccessor(bit3);
772
773 bitField = 0;
774 bitField.write();
775
776 group.read();
777 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
778 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
779 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
780 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
781
782 bitField = 1;
783 bitField.write();
784
785 group.read();
786 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
787 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
788 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
789 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
790
791 bitField = 2;
792 bitField.write();
793
794 group.read();
795 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
796 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 1);
797 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
798 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
799
800 bitField = 3;
801 bitField.write();
802
803 group.read();
804 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
805 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 1);
806 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
807 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
808
809 bitField = 4;
810 bitField.write();
811
812 group.read();
813 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
814 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
815 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 1);
816 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
817
818 bitField = 8;
819 bitField.write();
820
821 group.read();
822 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
823 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
824 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
825 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "1");
826
827 bitField = 15;
828 bitField.write();
829
830 group.read();
831 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
832 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 1);
833 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 1);
834 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "1");
835
836 bitField = 16;
837 bitField.write();
838
839 group.read();
840 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 0);
841 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
842 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
843 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
844
845 bitField = 17;
846 bitField.write();
847
848 group.read();
849 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
850 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
851 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
852 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
853
854 bitField = 1;
855 bitField.write();
856
857 group.read();
858 BOOST_CHECK_EQUAL(static_cast<uint8_t>(bit0), 1);
859 BOOST_CHECK_EQUAL(static_cast<uint16_t>(bit1), 0);
860 BOOST_CHECK_EQUAL(static_cast<int32_t>(bit2), 0);
861 BOOST_CHECK_EQUAL(static_cast<std::string>(bit3), "0");
862
863 bit2 = 1;
864 group.write();
865 bitField.read();
866 BOOST_CHECK_EQUAL(static_cast<int>(bitField), 5);
867
868 bit1 = 1;
869 group.write();
870 bitField.read();
871 BOOST_CHECK_EQUAL(static_cast<int>(bitField), 7);
872
873 bit0 = 0;
874 group.write();
875 bitField.read();
876 BOOST_CHECK_EQUAL(static_cast<int>(bitField), 6);
877
878 bit3 = "1";
879 group.write();
880 bitField.read();
881 BOOST_CHECK_EQUAL(static_cast<int>(bitField), 14);
882
883 device.close();
884}
885
886/**********************************************************************************************************************/
887
889 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
891 device.open("LMAP0");
892
893 BOOST_CHECK(device.readDeviceInfo().find("Logical name mapping file:") == 0);
894 device.close();
895}
896
897/**********************************************************************************************************************/
898
899BOOST_AUTO_TEST_CASE(testParameters) {
900 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
902
903 device.open("PARAMS0");
904
905 BOOST_CHECK_EQUAL(device.read<int>("SingleWordWithParams"), 42);
906}
907
908/**********************************************************************************************************************/
909
910BOOST_AUTO_TEST_CASE(testAccessorPlugins) {
911 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
912 ChimeraTK::Device device, target, jsonSrc;
913
914 device.open("LMAP0");
915 target.open("PCIE2");
916 jsonSrc.open("JSRC");
917
918 // test scalar register with multiply plugin
919 auto wordUser = target.getScalarRegisterAccessor<int32_t>("BOARD.WORD_USER");
920 auto wordUserScaled = device.getScalarRegisterAccessor<double>("SingleWord_Scaled");
921
922 wordUser = 2;
923 wordUser.write();
924 wordUserScaled.read();
925 BOOST_CHECK_CLOSE(double(wordUserScaled), 2 * 4.2, 0.001);
926
927 wordUser = 3;
928 wordUser.write();
929 wordUserScaled.read();
930 BOOST_CHECK_CLOSE(double(wordUserScaled), 3 * 4.2, 0.001);
931
932 wordUserScaled = 10 / 4.2;
933 wordUserScaled.write();
934 wordUser.read();
935 BOOST_CHECK_EQUAL(int(wordUser), 10);
936
937 wordUserScaled = 5.4 / 4.2; // rounding down
938 wordUserScaled.write();
939 wordUser.read();
940 BOOST_CHECK_EQUAL(int(wordUser), 5);
941
942 wordUserScaled = 3.6 / 4.2; // rounding up
943 wordUserScaled.write();
944 wordUser.read();
945 BOOST_CHECK_EQUAL(int(wordUser), 4);
946
947 wordUserScaled = -5.4 / 4.2; // rounding down
948 wordUserScaled.write();
949 wordUser.read();
950 BOOST_CHECK_EQUAL(int(wordUser), -5);
951
952 wordUserScaled = -3.6 / 4.2; // rounding up
953 wordUserScaled.write();
954 wordUser.read();
955 BOOST_CHECK_EQUAL(int(wordUser), -4);
956
957 // test scalar register with two multiply plugins
958 auto wordUserScaledTwice = device.getScalarRegisterAccessor<double>("SingleWord_Scaled_Twice");
959
960 wordUser = 2;
961 wordUser.write();
962 wordUserScaledTwice.read();
963 BOOST_CHECK_CLOSE(double(wordUserScaledTwice), 2 * 6, 0.001);
964
965 wordUser = 3;
966 wordUser.write();
967 wordUserScaledTwice.read();
968 BOOST_CHECK_CLOSE(double(wordUserScaledTwice), 3 * 6, 0.001);
969
970 wordUserScaledTwice = 10. / 6.;
971 wordUserScaledTwice.write();
972 wordUser.read();
973 BOOST_CHECK_EQUAL(int(wordUser), 10);
974
975 // test array register with multiply plugin
976 auto area = target.getOneDRegisterAccessor<int32_t>("ADC.AREA_DMAABLE");
977 auto areaScaled = device.getOneDRegisterAccessor<double>("FullArea_Scaled");
978
979 BOOST_CHECK_EQUAL(area.getNElements(), 1024);
980 BOOST_CHECK_EQUAL(areaScaled.getNElements(), 1024);
981
982 for(int i = 0; i < 1024; ++i) area[i] = 100 + i;
983 area.write();
984 areaScaled.read();
985 for(int i = 0; i < 1024; ++i) BOOST_CHECK_CLOSE(areaScaled[i], (100 + i) * 0.5, 0.001);
986
987 for(int i = 0; i < 1024; ++i) areaScaled[i] = (-100 + i) / 0.5;
988 areaScaled.write();
989 area.read();
990 for(int i = 0; i < 1024; ++i) BOOST_CHECK_EQUAL(area[i], -100 + i);
991
992 // test setDescription plugin: both engineering unit and description are overwritten
993 // Catalogue info must already carry the values before an accessor is created, so tooling can view them.
994 {
995 auto info = device.getRegisterCatalogue().getRegister("CustomUnitDescription");
996 BOOST_TEST(info.getUnit() == "mV");
997 BOOST_TEST(info.getDescription() == "A custom description");
998 }
999 auto customUnitDesc = device.getScalarRegisterAccessor<double>("CustomUnitDescription");
1000 BOOST_TEST(customUnitDesc.getUnit() == "mV");
1001 BOOST_TEST(customUnitDesc.getDescription() == "A custom description");
1002
1003 // test setDescription plugin: only engineering unit is overwritten, description stays as in target
1004 // (here the target is a map-based NumericAddressed register whose info carries no unit/description,
1005 // so the non-overwritten catalogue field stays empty; the accessor reflects the target accessor)
1006 {
1007 auto info = device.getRegisterCatalogue().getRegister("CustomUnitOnly");
1008 BOOST_TEST(info.getUnit() == "mA");
1009 BOOST_TEST(info.getDescription() == "");
1010 }
1011 auto customUnitOnly = device.getScalarRegisterAccessor<double>("CustomUnitOnly");
1012 BOOST_TEST(customUnitOnly.getUnit() == "mA");
1013 BOOST_TEST(customUnitOnly.getDescription() == wordUser.getDescription());
1014
1015 // test setDescription plugin: only description is overwritten, engineering unit stays as in target
1016 {
1017 auto info = device.getRegisterCatalogue().getRegister("CustomDescriptionOnly");
1018 BOOST_TEST(info.getDescription() == "Only description overwritten");
1019 BOOST_TEST(info.getUnit() == "");
1020 }
1021 auto customDescriptionOnly = device.getScalarRegisterAccessor<double>("CustomDescriptionOnly");
1022 BOOST_TEST(customDescriptionOnly.getDescription() == "Only description overwritten");
1023 BOOST_TEST(customDescriptionOnly.getUnit() == wordUser.getUnit());
1024
1025 // test setDescription plugin on a target coming from a JSON map file
1026 // Verify the description coming from the JSON file is NOT overwritten when the plugin
1027 // only overwrites the engineering unit.
1028 auto jsonTarget = jsonSrc.getScalarRegisterAccessor<double>("SomeTopLevelRegister");
1029 BOOST_TEST(jsonTarget.getUnit() == "mV");
1030 BOOST_TEST(jsonTarget.getDescription() == "This is an example register");
1031
1032 // only engineeringUnit is overwritten -> the JSON description must be preserved in catalogue and accessor
1033 {
1034 auto info = device.getRegisterCatalogue().getRegister("JsonUnitOnly");
1035 BOOST_TEST(info.getUnit() == "V");
1036 BOOST_TEST(info.getDescription() == "This is an example register");
1037 }
1038 auto jsonUnitOnly = device.getScalarRegisterAccessor<double>("JsonUnitOnly");
1039 BOOST_TEST(jsonUnitOnly.getUnit() == "V");
1040 BOOST_TEST(jsonUnitOnly.getDescription() == "This is an example register");
1041
1042 // only description is overwritten -> the JSON unit must be preserved
1043 {
1044 auto info = device.getRegisterCatalogue().getRegister("JsonDescriptionOnly");
1045 BOOST_TEST(info.getDescription() == "Overwritten by plugin");
1046 BOOST_TEST(info.getUnit() == "mV");
1047 }
1048 auto jsonDescriptionOnly = device.getScalarRegisterAccessor<double>("JsonDescriptionOnly");
1049 BOOST_TEST(jsonDescriptionOnly.getDescription() == "Overwritten by plugin");
1050 BOOST_TEST(jsonDescriptionOnly.getUnit() == "mV");
1051
1052 // overwrite description of 2D area while extracting channel via 'redirectedChannel'; keep unit
1053 // note, we accept that if name/description/unit for that _channel_ already exists in .jmap, it will not be
1054 // available when extracting from the 2D area.
1055 {
1056 auto info = device.getRegisterCatalogue().getRegister("Channel4");
1057 BOOST_TEST(info.getDescription() == "A custom description");
1058 BOOST_TEST(info.getUnit() == "mA");
1059 }
1060 auto channel4 = device.getOneDRegisterAccessor<int32_t>("Channel4");
1061 BOOST_TEST(channel4.getDescription() == "A custom description");
1062 BOOST_TEST(channel4.getUnit() == "mA");
1063}
1064
1065/**********************************************************************************************************************/
1066BOOST_AUTO_TEST_CASE(testIsFunctional) {
1067 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
1068 auto exceptionDummyBackend = boost::dynamic_pointer_cast<ExceptionDummy>(
1069 BackendFactory::getInstance().createBackend("(ExceptionDummy:1?map=test3.map)"));
1070
1071 Device d{"LMAP1"};
1072 d.open();
1073 BOOST_CHECK(d.isFunctional() == true);
1074
1075 d.setException("Test Exception");
1076 BOOST_CHECK(d.isFunctional() == false);
1077
1078 d.open();
1079 BOOST_CHECK(d.isFunctional() == true);
1080
1081 d.close();
1082 BOOST_CHECK(d.isFunctional() == false);
1083}
1084
1085/**********************************************************************************************************************/
1086
1087BOOST_AUTO_TEST_CASE(testWithTransferGroup) {
1088 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
1089 ChimeraTK::Device device, target1, target2;
1090
1091 device.open("LMAP0");
1093 a[0].replace(device.getOneDRegisterAccessor<int>("SingleWord"));
1094 a[1].replace(device.getOneDRegisterAccessor<int>("FullArea"));
1095 a[2].replace(device.getOneDRegisterAccessor<int>("PartOfArea"));
1096 a[3].replace(device.getOneDRegisterAccessor<int>("Channel3"));
1097 a[4].replace(device.getOneDRegisterAccessor<int>("Channel4"));
1098 a[5].replace(device.getOneDRegisterAccessor<int>("Constant"));
1099
1100 // obtain the private pointers to the implementation of the accessor
1101 boost::shared_ptr<NDRegisterAccessor<int>> impl[6];
1102 for(int i = 0; i < 6; i++) {
1103 impl[i] = boost::dynamic_pointer_cast<NDRegisterAccessor<int>>(a[i].getHighLevelImplElement());
1104 }
1105
1106 // somewhat redundant check: underlying hardware accessors are different for
1107 // all accessors
1108 for(int i = 0; i < 6; i++) {
1109 BOOST_CHECK(impl[i]->getHardwareAccessingElements().size() == 1);
1110 for(int k = i + 1; k < 6; k++) {
1111 BOOST_CHECK(impl[i]->getHardwareAccessingElements()[0] != impl[k]->getHardwareAccessingElements()[0]);
1112 }
1113 }
1114
1115 // add accessors to the transfer group
1116 TransferGroup group;
1117 for(int i = 0; i < 6; i++) {
1118 group.addAccessor(a[i]);
1119 }
1120
1121 // now some accessors share the same underlying accessor
1122 BOOST_CHECK(impl[3]->getHardwareAccessingElements()[0] == impl[4]->getHardwareAccessingElements()[0]);
1123 BOOST_CHECK(impl[1]->getHardwareAccessingElements()[0] == impl[2]->getHardwareAccessingElements()[0]);
1124
1125 // the others are still different
1126 BOOST_CHECK(impl[0]->getHardwareAccessingElements()[0] != impl[1]->getHardwareAccessingElements()[0]);
1127 BOOST_CHECK(impl[0]->getHardwareAccessingElements()[0] != impl[3]->getHardwareAccessingElements()[0]);
1128 BOOST_CHECK(impl[0]->getHardwareAccessingElements()[0] != impl[5]->getHardwareAccessingElements()[0]);
1129 BOOST_CHECK(impl[1]->getHardwareAccessingElements()[0] != impl[3]->getHardwareAccessingElements()[0]);
1130 BOOST_CHECK(impl[1]->getHardwareAccessingElements()[0] != impl[5]->getHardwareAccessingElements()[0]);
1131 BOOST_CHECK(impl[3]->getHardwareAccessingElements()[0] != impl[5]->getHardwareAccessingElements()[0]);
1132
1133 // write some stuff to the registers via the target device
1134 // Note: there is only one DMA area in the PCIE dummy which are shared by the
1135 // registers accessed by t2 and t3. We
1136 // therefore cannot test those register at the same time!
1137 target1.open("PCIE2");
1138 target2.open("PCIE3");
1139 auto t1 = target1.getOneDRegisterAccessor<int>("BOARD.WORD_USER");
1140 auto t2 = target1.getOneDRegisterAccessor<int>("ADC.AREA_DMAABLE");
1141 auto t3 = target2.getTwoDRegisterAccessor<int>("TEST/NODMA");
1142
1143 t1[0] = 120;
1144 t1.write();
1145 for(unsigned int i = 0; i < t2.getNElements(); i++) {
1146 t2[i] = 67890 + 66 * signed(i);
1147 }
1148 t2.write();
1149
1150 // read it back via the transfer group
1151 group.read();
1152
1153 BOOST_CHECK(a[0][0] == 120);
1154
1155 BOOST_CHECK(t2.getNElements() == a[1].getNElements());
1156 for(unsigned int i = 0; i < t2.getNElements(); i++) {
1157 BOOST_CHECK(a[1][i] == 67890 + 66 * signed(i));
1158 }
1159
1160 BOOST_CHECK(a[2].getNElements() == 20);
1161 for(unsigned int i = 0; i < a[2].getNElements(); i++) {
1162 BOOST_CHECK(a[2][i] == 67890 + 66 * signed(i + 10));
1163 }
1164
1165 BOOST_CHECK(a[5][0] == 42);
1166
1167 // write something to the multiplexed 2d register
1168 for(unsigned int i = 0; i < t3.getNChannels(); i++) {
1169 for(unsigned int k = 0; k < t3[i].size(); k++) {
1170 t3[i][k] = signed(i * 10 + k);
1171 }
1172 }
1173 t3.write();
1174
1175 // read it back via transfer group
1176 group.read();
1177
1178 BOOST_CHECK(a[3].getNElements() == t3[3].size());
1179 for(unsigned int i = 0; i < a[3].getNElements(); i++) {
1180 BOOST_CHECK(a[3][i] == 3 * 10 + signed(i));
1181 }
1182
1183 BOOST_CHECK(a[4].getNElements() == t3[4].size());
1184 for(unsigned int i = 0; i < a[4].getNElements(); i++) {
1185 BOOST_CHECK(a[4][i] == 4 * 10 + signed(i));
1186 }
1187
1188 // check that writing to the group fails (has read-only elements)
1189 BOOST_CHECK_THROW(group.write(), ChimeraTK::logic_error);
1190}
1191
1192/**********************************************************************************************************************/
1193
1194BOOST_AUTO_TEST_CASE(TestInvolvedBackendIDs) {
1195 BackendFactory::getInstance().setDMapFilePath("logicalnamemap.dmap");
1196 ChimeraTK::Device device("LMAP0");
1197 ChimeraTK::Device target1("PCIE2");
1198 ChimeraTK::Device target2("PCIE3");
1199 ChimeraTK::Device jsonSrc("JSRC");
1200
1201 // This actually is a test for the default implementation in DeviceBackendImpl,
1202 // which does not have it's own tests as it cannot be instantiated.
1203 auto ids1 = target1.getInvolvedBackendIDs();
1204 BOOST_TEST(ids1.size() == 1);
1205 BOOST_TEST(ids1.contains(target1.getBackend()->getBackendID()));
1206
1207 // The real test for the LMapBackend
1208 auto deviceIDs = device.getInvolvedBackendIDs();
1209 BOOST_TEST(deviceIDs.size() == 4);
1210 BOOST_TEST(deviceIDs.contains(target1.getBackend()->getBackendID()));
1211 BOOST_TEST(deviceIDs.contains(target2.getBackend()->getBackendID()));
1212 BOOST_TEST(deviceIDs.contains(jsonSrc.getBackend()->getBackendID()));
1213 BOOST_TEST(deviceIDs.contains(device.getBackend()->getBackendID()));
1214}
1215
1216/**********************************************************************************************************************/
1217
1218BOOST_AUTO_TEST_SUITE_END()
int t2[(((64 *GB - 1) % 671088649)==268434537) &&(((TB -(64 *GB - 1)+255) % 1792151290)==305159546) ? 1 :-1]
static BackendFactory & getInstance()
Static function to get an instance of factory.
void setDMapFilePath(std::string dMapFilePath)
This function sets the _DMapFilePath.
Class allows to read/write registers from device.
Definition Device.h:39
TwoDRegisterAccessor< UserType > getTwoDRegisterAccessor(const RegisterPath &registerPathName, size_t numberOfElements=0, size_t elementsOffset=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a TwoDRegisterAccessor object for the given register.
Definition Device.h:286
bool isOpened() const
Check if the device is currently opened.
Definition Device.cc:73
std::set< DeviceBackend::BackendID > getInvolvedBackendIDs()
Recursively obtain the set of all backend IDs that are used withing the device.
Definition Device.cc:117
void close()
Close the device.
Definition Device.cc:66
boost::shared_ptr< DeviceBackend > getBackend()
Obtain the backend.
Definition Device.cc:111
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
RegisterCatalogue getRegisterCatalogue() const
Return the register catalogue with detailed information on all registers.
Definition Device.cc:22
std::string readDeviceInfo() const
Return a device information string.
Definition Device.cc:36
OneDRegisterAccessor< UserType > getOneDRegisterAccessor(const RegisterPath &registerPathName, size_t numberOfWords=0, size_t wordOffsetInRegister=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a OneDRegisterAccessor object for the given register.
Definition Device.h:276
UserType read(const RegisterPath &registerPathName, const AccessModeFlags &flags=AccessModeFlags({})) const
Inefficient convenience function to read a single-word register without obtaining an accessor.
Definition Device.h:296
void open(std::string const &aliasName)
Open a device by the given alias name from the DMAP file.
Definition Device.cc:58
void write(const RegisterPath &registerPathName, UserType value, const AccessModeFlags &flags=AccessModeFlags({}))
Inefficient convenience function to write a single-word register without obtaining an accessor.
Definition Device.h:317
void replace(const NDRegisterAccessorAbstractor< UserType > &newAccessor)
Assign a new accessor to this NDRegisterAccessorAbstractor.
Accessor class to read and write registers transparently by using the accessor object like a vector o...
unsigned int getNElements()
Return number of elements/samples in the register.
Catalogue of register information.
RegisterInfo getRegister(const RegisterPath &registerPathName) const
Get register information for a given full path name.
const boost::shared_ptr< TransferElement > & getHighLevelImplElement()
Obtain the highest level implementation TransferElement.
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 write(VersionNumber versionNumber={})
Trigger write transfer for all accessors in the group.
void read()
Trigger read transfer for all accessors in the group.
Accessor class to read and write 2D registers.
Class for generating and holding version numbers without exposing a numeric representation.
Exception thrown when a logic error has occured.
Definition Exception.h:51
ctk::Device device
BOOST_AUTO_TEST_CASE(testExceptions)