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