Line data Source code
1 : #include <charconv>
2 : #include <cib_utilities.h>
3 : #include <cstddef>
4 :
5 : namespace dunedaq::cibmodules {
6 :
7 : // some helper functions outside of the class
8 : // taken from the cib_data_utils
9 : namespace util {
10 :
11 : uint32_t
12 0 : bitmask(uint32_t highbit, uint32_t lowbit)
13 : {
14 : // sort the bit order or this fails miserably
15 0 : if (highbit < lowbit) {
16 0 : uint32_t tmp = lowbit;
17 0 : lowbit = highbit;
18 0 : highbit = tmp;
19 : }
20 :
21 0 : uint32_t i = ~0U;
22 0 : return ~(i << highbit << 1) & (i << lowbit);
23 : }
24 :
25 : // converts a masked unsigned value into a signed
26 : // the mask is always assumed to start at 0, so the value has to be shifted right until the lsb aligns with 0
27 : int32_t
28 0 : cast_to_signed(const uint32_t reg, const uint32_t mask)
29 : {
30 : // first find the msb in the mask. That will be the signed bit
31 0 : uint32_t msb = 0;
32 0 : int32_t res = 0;
33 0 : for (size_t bit = 31; bit > 0; bit--) {
34 0 : if ((1U << bit) & mask) {
35 : msb = bit;
36 : break;
37 : }
38 : }
39 : // check the msb of the register. That is the sign bit
40 0 : if ((1U << msb) & reg) {
41 : // spdlog::trace("MSB of the mask is {0}",msb);
42 :
43 0 : res = bitmask(31, msb + 1); // set all bits to 1 above the mask
44 0 : res = res | (reg & mask);
45 : // it is a negative value. Set the msb in the result
46 : } else {
47 : // it is a positive value. No need to set the sign bit, but still need to
48 : // apply the mask or we're carrying out the other bits that may be outside the mask
49 0 : res = (reg & mask);
50 : }
51 0 : return res;
52 : }
53 :
54 : int32_t
55 0 : get_m1(dunedaq::cib::daq::iols_trigger_t& t)
56 : {
57 0 : return cast_to_signed(t.pos_m1, t.bitmask_m1);
58 : }
59 :
60 : int32_t
61 0 : get_m2(dunedaq::cib::daq::iols_trigger_t& t)
62 : {
63 0 : uint32_t m2_lsb = t.pos_m2_lsb;
64 0 : uint32_t m2_msb = t.pos_m2_msb;
65 0 : uint32_t m2 = (m2_msb << 15) | m2_lsb;
66 : // the bitmask is the same
67 0 : return cast_to_signed(m2, t.bitmask_m2);
68 : }
69 :
70 : int32_t
71 0 : get_m3(dunedaq::cib::daq::iols_trigger_t& t)
72 : {
73 0 : return cast_to_signed(t.pos_m3, t.bitmask_m3);
74 : }
75 :
76 : bool
77 0 : parse_hex(std::string_view s, std::uint32_t& out)
78 : {
79 : // Optional 0x / 0X prefix
80 0 : if (s.size() >= 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
81 0 : s.remove_prefix(2);
82 :
83 : // Empty after stripping?
84 0 : if (s.empty())
85 : return false;
86 :
87 0 : auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), out, 16);
88 :
89 : // ec=={} means parse OK; ptr at end means no trailing garbage
90 0 : return ec == std::errc{} && ptr == s.data() + s.size();
91 : }
92 :
93 : } // namespace util
94 : } // namespace dunedaq::cibmodules
|