DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
WIBEthFrame.hpp
Go to the documentation of this file.
1
14#ifndef FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_WIBETHFRAME_HPP_
15#define FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_WIBETHFRAME_HPP_
16
18
19#include <algorithm> // For std::min
20#include <cassert> // For assert()
21#include <cstdint> // For uint32_t etc
22#include <cstdio>
23#include <cstdlib>
24#include <stdexcept> // For std::out_of_range
25
27
35{
36public:
37 // ===============================================================
38 // Preliminaries
39 // ===============================================================
40
41 // The definition of the format is in terms of 64-bit words
42 typedef uint64_t word_t; // NOLINT
43
44 static constexpr int s_bits_per_adc = 14;
45 static constexpr int s_bits_per_word = 8 * sizeof(word_t);
46 static constexpr int s_time_samples_per_frame = 64;
47 static constexpr int s_channels_per_half_femb = 64;
48 static constexpr int s_half_fembs_per_frame = 1;
52
53
74
75 // ===============================================================
76 // Data members
77 // ===============================================================
80 // word_t adc_words[s_num_adc_words_per_ts][s_time_samples_per_frame]; // NOLINT
82
83 // ===============================================================
84 // Accessors
85 // ===============================================================
86
95 uint16_t get_adc(int i, int sample=0) const // NOLINT(build/unsigned)
96 {
97 if (i < 0 || i >= s_num_channels)
98 throw std::out_of_range("ADC index out of range");
99
100 // The index of the first (and sometimes only) word containing the required ADC value
101 int word_index = s_bits_per_adc * i / s_bits_per_word;
102 assert(word_index < s_num_adc_words_per_ts);
103 // Where in the word the lowest bit of our ADC value is located
104 int first_bit_position = (s_bits_per_adc * i) % s_bits_per_word;
105 // How many bits of our desired ADC are located in the `word_index`th word
106 int bits_from_first_word = std::min(s_bits_per_adc, s_bits_per_word - first_bit_position);
107 // uint16_t adc = adc_words[word_index][sample] >> first_bit_position; // NOLINT(build/unsigned)
108 uint16_t adc = adc_words[sample][word_index] >> first_bit_position; // NOLINT(build/unsigned)
109 // If we didn't get the full 14 bits from this word, we need the rest from the next word
110 if (bits_from_first_word < s_bits_per_adc) {
111 assert(word_index + 1 < s_num_adc_words_per_ts);
112 // adc |= adc_words[word_index + 1][sample] << bits_from_first_word;
113 adc |= adc_words[sample][word_index + 1] << bits_from_first_word;
114 }
115 // Mask out all but the lowest 14 bits;
116 return adc & 0x3FFFu;
117 }
118
122 void set_adc(int i, int sample, uint16_t val) // NOLINT(build/unsigned)
123 {
124 if (i < 0 || i >= s_num_channels)
125 throw std::out_of_range("ADC index out of range");
126 if (val >= (1 << s_bits_per_adc))
127 throw std::out_of_range("ADC value out of range");
128
129 // The index of the first (and sometimes only) word containing the required ADC value
130 int word_index = s_bits_per_adc * i / s_bits_per_word;
131 assert(word_index < s_num_adc_words);
132 // Where in the word the lowest bit of our ADC value is located
133 int first_bit_position = (s_bits_per_adc * i) % s_bits_per_word;
134 // How many bits of our desired ADC are located in the `word_index`th word
135 int bits_in_first_word = std::min(s_bits_per_adc, s_bits_per_word - first_bit_position);
136 uint64_t mask = (static_cast<uint64_t>(1) << first_bit_position) - 1;
137 adc_words[sample][word_index] = ((static_cast<uint64_t>(val) << first_bit_position) & ~mask) | (adc_words[sample][word_index] & mask);
138 // If we didn't put the full 14 bits in this word, we need to put the rest in the next word
139 if (bits_in_first_word < s_bits_per_adc) {
140 assert(word_index + 1 < s_num_adc_words);
141 mask = (1 << (s_bits_per_adc - bits_in_first_word)) - 1;
142 adc_words[sample][word_index + 1] = ((val >> bits_in_first_word) & mask) | (adc_words[sample][word_index + 1] & ~mask);
143 }
144 }
145
148 uint64_t get_timestamp() const // NOLINT(build/unsigned)
149 {
150 return daq_header.get_timestamp() ; // NOLINT(build/unsigned)
151 }
152
155 void set_timestamp(const uint64_t new_timestamp) // NOLINT(build/unsigned)
156 {
157 daq_header.timestamp = new_timestamp;
158 }
159
162 uint8_t get_channel() const // NOLINT(build/unsigned)
163 {
164 return header.channel ; // NOLINT(build/unsigned)
165 }
166
169 void set_channel(const uint8_t new_channel) // NOLINT(build/unsigned)
170 {
171 header.channel = new_channel;
172 }
173
174};
175
176} // namespace dunedaq::fddetdataformats
177
178#endif // FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_WIBETHFRAME_HPP_
Class for accessing raw WIB eth frames, as used in ProtoDUNE-II.
uint16_t get_adc(int i, int sample=0) const
Get the ith ADC value in the frame.
uint64_t get_timestamp() const
Get the starting 64-bit timestamp of the frame.
static constexpr int s_half_fembs_per_frame
void set_channel(const uint8_t new_channel)
Set the channel identifier of the frame.
word_t adc_words[s_time_samples_per_frame][s_num_adc_words_per_ts]
uint8_t get_channel() const
Get the channel identifier of the frame.
void set_adc(int i, int sample, uint16_t val)
Set the ith ADC value in the frame to val.
detdataformats::DAQEthHeader daq_header
static constexpr int s_time_samples_per_frame
void set_timestamp(const uint64_t new_timestamp)
Set the starting 64-bit timestamp of the frame.
static constexpr int s_num_adc_words_per_ts
static constexpr int s_channels_per_half_femb
DAQEthHeader is a versioned and unified structure for every FE electronics.