DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
TDEEthFrame.hpp
Go to the documentation of this file.
1
13#ifndef FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_TDEETHFRAME_HPP_
14#define FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_TDEETHFRAME_HPP_
15
17
18#include <algorithm> // For std::min
19#include <cassert> // For assert()
20#include <cstdint> // For uint32_t etc
21#include <cstdio>
22#include <cstdlib>
23#include <stdexcept> // For std::out_of_range
24
26
34{
35public:
36 // ===============================================================
37 // Preliminaries
38 // ===============================================================
39
40 // The definition of the format is in terms of 64-bit words
41 typedef uint64_t word_t; // NOLINT
42
43 static constexpr int s_bits_per_adc = 14;
44 static constexpr int s_bits_per_word = 8 * sizeof(word_t);
45 static constexpr int s_time_samples_per_frame = 64;
46 static constexpr int s_channels_per_half_femb = 64;
47 static constexpr int s_half_fembs_per_frame = 1;
51
52
54 {
55 uint64_t reserved : 26;
56 uint64_t tde_errors : 16;
57 uint64_t tde_header : 10;
58 uint64_t version : 4;
59 uint64_t channel : 8;
60 uint64_t TAItime : 64;
61 };
62
63 // ===============================================================
64 // Data members
65 // ===============================================================
68 // word_t adc_words[s_num_adc_words_per_ts][s_time_samples_per_frame]; // NOLINT
70
71 // ===============================================================
72 // Accessors
73 // ===============================================================
74
83 uint16_t get_adc(int i, int sample=0) const // NOLINT(build/unsigned)
84 {
85 if (i < 0 || i >= s_num_channels)
86 throw std::out_of_range("ADC index out of range");
87
88 // The index of the first (and sometimes only) word containing the required ADC value
89 int word_index = s_bits_per_adc * i / s_bits_per_word;
90 assert(word_index < s_num_adc_words_per_ts);
91 // Where in the word the lowest bit of our ADC value is located
92 int first_bit_position = (s_bits_per_adc * i) % s_bits_per_word;
93 // How many bits of our desired ADC are located in the `word_index`th word
94 int bits_from_first_word = std::min(s_bits_per_adc, s_bits_per_word - first_bit_position);
95 // uint16_t adc = adc_words[word_index][sample] >> first_bit_position; // NOLINT(build/unsigned)
96 uint16_t adc = adc_words[sample][word_index] >> first_bit_position; // NOLINT(build/unsigned)
97 // If we didn't get the full 14 bits from this word, we need the rest from the next word
98 if (bits_from_first_word < s_bits_per_adc) {
99 assert(word_index + 1 < s_num_adc_words_per_ts);
100 // adc |= adc_words[word_index + 1][sample] << bits_from_first_word;
101 adc |= adc_words[sample][word_index + 1] << bits_from_first_word;
102 }
103 // Mask out all but the lowest 14 bits;
104 return adc & 0x3FFFu;
105 }
106
110 void set_adc(int i, int sample, uint16_t val) // NOLINT(build/unsigned)
111 {
112 if (i < 0 || i >= s_num_channels)
113 throw std::out_of_range("ADC index out of range");
114 if (val >= (1 << s_bits_per_adc))
115 throw std::out_of_range("ADC value out of range");
116
117 // The index of the first (and sometimes only) word containing the required ADC value
118 int word_index = s_bits_per_adc * i / s_bits_per_word;
119 assert(word_index < s_num_adc_words);
120 // Where in the word the lowest bit of our ADC value is located
121 int first_bit_position = (s_bits_per_adc * i) % s_bits_per_word;
122 // How many bits of our desired ADC are located in the `word_index`th word
123 int bits_in_first_word = std::min(s_bits_per_adc, s_bits_per_word - first_bit_position);
124 uint64_t mask = (static_cast<uint64_t>(1) << first_bit_position) - 1;
125 adc_words[sample][word_index] = ((static_cast<uint64_t>(val) << first_bit_position) & ~mask) | (adc_words[sample][word_index] & mask);
126 // If we didn't put the full 14 bits in this word, we need to put the rest in the next word
127 if (bits_in_first_word < s_bits_per_adc) {
128 assert(word_index + 1 < s_num_adc_words);
129 mask = (1 << (s_bits_per_adc - bits_in_first_word)) - 1;
130 adc_words[sample][word_index + 1] = ((val >> bits_in_first_word) & mask) | (adc_words[sample][word_index + 1] & ~mask);
131 }
132 }
133
136 uint64_t get_timestamp() const // NOLINT(build/unsigned)
137 {
138 return daq_header.get_timestamp() ; // NOLINT(build/unsigned)
139 }
140
143 void set_timestamp(const uint64_t new_timestamp) // NOLINT(build/unsigned)
144 {
145 daq_header.timestamp = new_timestamp;
146 }
147
150 uint8_t get_channel() const // NOLINT(build/unsigned)
151 {
152 return header.channel ; // NOLINT(build/unsigned)
153 }
154
157 void set_channel(const uint8_t new_channel) // NOLINT(build/unsigned)
158 {
159 header.channel = new_channel;
160 }
161
162};
163
164} // namespace dunedaq::fddetdataformats
165
166#endif // FDDETDATAFORMATS_INCLUDE_FDDETDATAFORMATS_TDEETHFRAME_HPP_
Class for accessing raw WIB eth frames, as used in ProtoDUNE-II.
static constexpr int s_channels_per_half_femb
void set_channel(const uint8_t new_channel)
Set 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.
static constexpr int s_time_samples_per_frame
uint8_t get_channel() const
Get the channel identifier of the frame.
static constexpr int s_num_adc_words_per_ts
void set_timestamp(const uint64_t new_timestamp)
Set the starting 64-bit timestamp of the frame.
detdataformats::DAQEthHeader daq_header
uint64_t get_timestamp() const
Get the starting 64-bit timestamp of the frame.
uint16_t get_adc(int i, int sample=0) const
Get the ith ADC value in the frame.
word_t adc_words[s_time_samples_per_frame][s_num_adc_words_per_ts]
static constexpr int s_half_fembs_per_frame
DAQEthHeader is a versioned and unified structure for every FE electronics.