DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
WIB2Frame.hpp
Go to the documentation of this file.
1
12#ifndef FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_WIB2FRAME_HPP_
13#define FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_WIB2FRAME_HPP_
14
15#include <algorithm> // For std::min
16#include <cassert> // For assert()
17#include <cstdint> // For uint32_t etc
18#include <cstdio>
19#include <cstdlib>
20#include <stdexcept> // For std::out_of_range
21
23
31{
32public:
33 // ===============================================================
34 // Preliminaries
35 // ===============================================================
36
37 // The definition of the format is in terms of 32-bit words
38 typedef uint32_t word_t; // NOLINT
39
40 static constexpr int s_bits_per_adc = 14;
41 static constexpr int s_bits_per_word = 8 * sizeof(word_t);
42 static constexpr int s_u_channels_per_femb = 40;
43 static constexpr int s_v_channels_per_femb = 40;
44 static constexpr int s_x_channels_per_femb = 48;
46 static constexpr int s_fembs_per_frame = 2;
50
51
60
61 struct Trailer
62 {
63 word_t flex_bits : 16, tbd_1 : 1, tbd_2 : 1, ws : 1, psr_cal : 4, ready : 1, context_code : 8;
64 };
65
66 // ===============================================================
67 // Data members
68 // ===============================================================
72
73 // ===============================================================
74 // Accessors
75 // ===============================================================
76
89 uint16_t get_adc(int i) const // NOLINT(build/unsigned)
90 {
91 if (i < 0 || i >= s_num_channels)
92 throw std::out_of_range("ADC index out of range");
93
94 // The index of the first (and sometimes only) word containing the required ADC value
95 int word_index = s_bits_per_adc * i / s_bits_per_word;
96 assert(word_index < s_num_adc_words);
97 // Where in the word the lowest bit of our ADC value is located
98 int first_bit_position = (s_bits_per_adc * i) % s_bits_per_word;
99 // How many bits of our desired ADC are located in the `word_index`th word
100 int bits_from_first_word = std::min(s_bits_per_adc, s_bits_per_word - first_bit_position);
101 uint16_t adc = adc_words[word_index] >> first_bit_position; // NOLINT(build/unsigned)
102 // If we didn't get the full 14 bits from this word, we need the rest from the next word
103 if (bits_from_first_word < s_bits_per_adc) {
104 assert(word_index + 1 < s_num_adc_words);
105 adc |= adc_words[word_index + 1] << bits_from_first_word;
106 }
107 // Mask out all but the lowest 14 bits;
108 return adc & 0x3FFFu;
109 }
110
114 void set_adc(int i, uint16_t val) // NOLINT(build/unsigned)
115 {
116 if (i < 0 || i >= s_num_channels)
117 throw std::out_of_range("ADC index out of range");
118 if (val >= (1 << s_bits_per_adc))
119 throw std::out_of_range("ADC value out of range");
120
121 // The index of the first (and sometimes only) word containing the required ADC value
122 int word_index = s_bits_per_adc * i / s_bits_per_word;
123 assert(word_index < s_num_adc_words);
124 // Where in the word the lowest bit of our ADC value is located
125 int first_bit_position = (s_bits_per_adc * i) % s_bits_per_word;
126 // How many bits of our desired ADC are located in the `word_index`th word
127 int bits_in_first_word = std::min(s_bits_per_adc, s_bits_per_word - first_bit_position);
128 uint32_t mask = (1 << (first_bit_position)) - 1;
129 adc_words[word_index] = ((val << first_bit_position) & ~mask) | (adc_words[word_index] & mask);
130 // If we didn't put the full 14 bits in this word, we need to put the rest in the next word
131 if (bits_in_first_word < s_bits_per_adc) {
132 assert(word_index + 1 < s_num_adc_words);
133 mask = (1 << (s_bits_per_adc - bits_in_first_word)) - 1;
134 adc_words[word_index + 1] = ((val >> bits_in_first_word) & mask) | (adc_words[word_index + 1] & ~mask);
135 }
136 }
137
140 uint64_t get_timestamp() const // NOLINT(build/unsigned)
141 {
142 return (uint64_t)header.timestamp_1 | ((uint64_t)header.timestamp_2 << 32); // NOLINT(build/unsigned)
143 }
144
147 void set_timestamp(const uint64_t new_timestamp) // NOLINT(build/unsigned)
148 {
149 header.timestamp_1 = new_timestamp;
150 header.timestamp_2 = new_timestamp >> 32;
151 }
152
153
154
155};
156
157} // namespace dunedaq::fddetdataformats
158
159#endif // FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_WIB2FRAME_HPP_
160
161// Local Variables:
162// c-basic-offset: 2
163// End:
Class for accessing raw WIB v2 frames, as used in ProtoDUNE-SP-II.
Definition WIB2Frame.hpp:31
void set_timestamp(const uint64_t new_timestamp)
Set the 64-bit timestamp of the frame.
static constexpr int s_num_ch_per_frame
Definition WIB2Frame.hpp:49
static constexpr int s_x_channels_per_femb
Definition WIB2Frame.hpp:44
static constexpr int s_v_channels_per_femb
Definition WIB2Frame.hpp:43
static constexpr int s_num_channels
Definition WIB2Frame.hpp:47
uint16_t get_adc(int i) const
Get the ith ADC value in the frame.
Definition WIB2Frame.hpp:89
static constexpr int s_channels_per_femb
Definition WIB2Frame.hpp:45
static constexpr int s_u_channels_per_femb
Definition WIB2Frame.hpp:42
uint64_t get_timestamp() const
Get the 64-bit timestamp of the frame.
word_t adc_words[s_num_adc_words]
Definition WIB2Frame.hpp:70
static constexpr int s_fembs_per_frame
Definition WIB2Frame.hpp:46
void set_adc(int i, uint16_t val)
Set the ith ADC value in the frame to val.
static constexpr int s_bits_per_adc
Definition WIB2Frame.hpp:40
static constexpr int s_bits_per_word
Definition WIB2Frame.hpp:41
static constexpr int s_num_adc_words
Definition WIB2Frame.hpp:48