Project
Loading...
Searching...
No Matches
RCUTrailer.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#include <cfloat>
12#include <cmath>
13#include <iostream>
14#include <fmt/format.h>
15#include <fairlogger/Logger.h>
17#include "PHOSBase/RCUTrailer.h"
18
19using namespace o2::phos;
20
21RCUTrailer::RCUTrailer(const gsl::span<const uint32_t> payloadwords)
22{
23 constructFromRawPayload(payloadwords);
24}
25
27{
28 mRCUId = -1;
29 mFirmwareVersion = 0;
30 mTrailerSize = 0;
31 mPayloadSize = 0;
32 mFECERRA = 0;
33 mFECERRB = 0;
34 mERRREG2 = 0;
35 mERRREG3 = 0;
36 mActiveFECsA = 0;
37 mActiveFECsB = 0;
38 mAltroCFG1 = 0;
39 mAltroCFG2 = 0;
40 mIsInitialized = false;
41}
42
43void RCUTrailer::constructFromRawPayload(const gsl::span<const uint32_t> payloadwords)
44{
45 reset();
46 int index = payloadwords.size();
47 if (index < 1) { //
48 throw Error(Error::ErrorType_t::DECODING_INVALID, "zero payload");
49 }
50 auto word = payloadwords[--index];
51 if ((word >> 30) != 3) {
52 throw Error(Error::ErrorType_t::DECODING_INVALID, "Last RCU trailer word not found!");
53 }
54 mFirmwareVersion = (word >> 16) & 0xFF;
55
56 mRCUId = (int)((word >> 7) & 0x1FF);
57 int trailerSize = (word & 0x7F);
58
59 if (trailerSize < 2 || trailerSize > index + 1) { //one word already read -> index is smaller
60 throw Error(Error::ErrorType_t::SIZE_INVALID, fmt::format("Invalid trailer size found (%d bytes) !", trailerSize * 4).data());
61 }
62 mTrailerSize = trailerSize;
63
64 trailerSize -= 2; // Cut first and last trailer words as they are handled separately
65 for (; trailerSize > 0; trailerSize--) {
66 word = payloadwords[--index];
67 if ((word >> 30) != 2) {
68 LOG(error) << "Missing RCU trailer identifier pattern!";
69 continue;
70 }
71 int parCode = (word >> 26) & 0xF;
72 int parData = word & 0x3FFFFFF;
73 switch (parCode) {
74 case 1:
75 // ERR_REG1
76 mFECERRA = ((parData >> 13) & 0x1FFF) << 7;
77 mFECERRB = ((parData & 0x1FFF)) << 7;
78 break;
79 case 2:
80 // ERR_REG2
81 mERRREG2 = parData & 0x1FF;
82 break;
83 case 3:
84 // ERR_REG3
85 mERRREG3 = parData & 0x1FFFFFF;
86 break;
87 case 4:
88 // FEC_RO_A
89 mActiveFECsA = parData & 0xFFFF;
90 break;
91 case 5:
92 // FEC_RO_B
93 mActiveFECsB = parData & 0xFFFF;
94 break;
95 case 6:
96 // RDO_CFG1
97 mAltroCFG1 = parData & 0xFFFFF;
98 break;
99 case 7:
100 // RDO_CFG2
101 mAltroCFG2 = parData & 0x1FFFFFF;
102 break;
103 default:
104 LOG(error) << "Undefined parameter code " << parCode << ", ignore it !";
105 break;
106 }
107 }
108 mPayloadSize = payloadwords[--index] & 0x3FFFFFF;
109 mIsInitialized = true;
110}
111
113{
114 unsigned char fq = (mAltroCFG2 >> 5) & 0xF;
115 double tSample;
116 switch (fq) {
117 case 0:
118 // 20 MHz
119 tSample = 2.0;
120 break;
121 case 1:
122 // 10 Mhz
123 tSample = 4.0;
124 break;
125 case 2:
126 // 5 MHz
127 tSample = 8.;
128 break;
129 default:
130 throw Error(Error::ErrorType_t::SAMPLINGFREQ_INVALID, fmt::format("Invalid sampling frequency value %d !", int(fq)).data());
131 }
132
133 return tSample * o2::constants::lhc::LHCBunchSpacingNS * 1.e-9;
134}
135
136void RCUTrailer::setTimeSample(double timesample)
137{
138 int fq = 0;
139 if (std::abs(timesample - 50) < DBL_EPSILON) {
140 fq = 0;
141 } else if (std::abs(timesample - 100) < DBL_EPSILON) {
142 fq = 1;
143 } else if (std::abs(timesample - 200) < DBL_EPSILON) {
144 fq = 2;
145 } else {
146 throw Error(Error::ErrorType_t::SAMPLINGFREQ_INVALID, fmt::format("invalid time sample: %f", timesample).data());
147 }
148 mAltroCFG2 = (mAltroCFG2 & 0x1F) | fq << 5;
149}
150
152{
153 double tSample = getTimeSample(),
154 phase = ((double)(mAltroCFG2 & 0x1F)) * o2::constants::lhc::LHCBunchSpacingNS * 1.e-9;
155 if (phase >= tSample) {
156 throw Error(Error::ErrorType_t::L1PHASE_INVALID, fmt::format("Invalid L1 trigger phase (%e s (phase) >= %e s (sampling time)) !", phase, tSample).data());
157 }
158 return phase;
159}
160
161void RCUTrailer::setL1Phase(double l1phase)
162{
163 int phase = l1phase / 25.;
164 mAltroCFG2 = (mAltroCFG2 & 0x1E0) | phase;
165}
166
167std::vector<uint32_t> RCUTrailer::encode() const
168{
169 std::vector<uint32_t> encoded;
170 encoded.emplace_back(mPayloadSize | 2 << 30);
171 encoded.emplace_back(mAltroCFG2 | 7 << 26 | 2 << 30);
172 encoded.emplace_back(mAltroCFG1 | 6 << 26 | 2 << 30);
173 encoded.emplace_back(mActiveFECsB | 5 << 26 | 2 << 30);
174 encoded.emplace_back(mActiveFECsA | 4 << 26 | 2 << 30);
175 encoded.emplace_back(mERRREG3 | 3 << 26 | 2 << 30);
176 encoded.emplace_back(mERRREG2 | 2 << 26 | 2 << 30);
177 encoded.emplace_back(mFECERRB >> 7 | (mFECERRA >> 7) << 13 | 1 << 26 | 2 << 30);
178
179 uint32_t lasttrailerword = 3 << 30 | mFirmwareVersion << 16 | mRCUId << 7 | (encoded.size() + 1);
180 encoded.emplace_back(lasttrailerword);
181
182 return encoded;
183}
184
185void RCUTrailer::printStream(std::ostream& stream) const
186{
187 std::vector<std::string> errors;
188 double timesample = -1., l1phase = -1.;
189 try {
190 timesample = getTimeSample();
191 } catch (Error& e) {
192 errors.push_back(e.what());
193 }
194 try {
195 l1phase = getL1Phase();
196 } catch (Error& e) {
197 errors.push_back(e.what());
198 }
199
200 stream << "RCU trailer (Format version 2):\n"
201 << "==================================================\n"
202 << "RCU ID: " << mRCUId << "\n"
203 << "Firmware version: " << int(mFirmwareVersion) << "\n"
204 << "Trailer size: " << mTrailerSize << "\n"
205 << "Payload size: " << mPayloadSize << "\n"
206 << "FECERRA: 0x" << std::hex << mFECERRA << "\n"
207 << "FECERRB: 0x" << std::hex << mFECERRB << "\n"
208 << "ERRREG2: 0x" << std::hex << mERRREG2 << "\n"
209 << "#channels skipped due to address mismatch: " << std::dec << getNumberOfChannelAddressMismatch() << "\n"
210 << "#channels skipped due to bad block length: " << std::dec << getNumberOfChannelLengthMismatch() << "\n"
211 << "Active FECs (branch A): 0x" << std::hex << mActiveFECsA << "\n"
212 << "Active FECs (branch B): 0x" << std::hex << mActiveFECsB << "\n"
213 << "Baseline corr: 0x" << std::hex << int(getBaselineCorrection()) << "\n"
214 << "Number of presamples: " << std::dec << int(getNumberOfPresamples()) << "\n"
215 << "Number of postsamples: " << std::dec << int(getNumberOfPostsamples()) << "\n"
216 << "Second baseline corr: " << (hasSecondBaselineCorr() ? "yes" : "no") << "\n"
217 << "GlitchFilter: " << std::dec << int(getGlitchFilter()) << "\n"
218 << "Number of non-ZS postsamples: " << std::dec << int(getNumberOfNonZeroSuppressedPostsamples()) << "\n"
219 << "Number of non-ZS presamples: " << std::dec << int(getNumberOfNonZeroSuppressedPresamples()) << "\n"
220 << "Number of ALTRO buffers: " << std::dec << getNumberOfAltroBuffers() << "\n"
221 << "Number of pretrigger samples: " << std::dec << int(getNumberOfPretriggerSamples()) << "\n"
222 << "Number of samples per channel: " << std::dec << getNumberOfSamplesPerChannel() << "\n"
223 << "Sparse readout: " << (isSparseReadout() ? "yes" : "no") << "\n"
224 << "AltroCFG1: 0x" << std::hex << mAltroCFG1 << "\n"
225 << "AltroCFG2: 0x" << std::hex << mAltroCFG2 << "\n"
226 << "Sampling time: " << std::scientific << timesample << " s\n"
227 << "L1 Phase: " << std::scientific << l1phase << " s\n"
228 << std::dec << std::fixed;
229 if (errors.size()) {
230 stream << "Errors: \n"
231 << "-------------------------------------------------\n";
232 for (const auto& e : errors) {
233 stream << e << "\n";
234 }
235 }
236 stream << "==================================================\n";
237}
238
239RCUTrailer RCUTrailer::constructFromPayloadWords(const gsl::span<const uint32_t> payloadwords)
240{
242 result.constructFromRawPayload(payloadwords);
243 return result;
244}
245
246std::ostream& o2::phos::operator<<(std::ostream& stream, const o2::phos::RCUTrailer& trailer)
247{
248 trailer.printStream(stream);
249 return stream;
250}
uint64_t phase
Definition RawEventData.h:7
Header to collect LHC related constants.
Error handling of the.
Definition RCUTrailer.h:61
@ SAMPLINGFREQ_INVALID
Invalid sampling frequency.
@ DECODING_INVALID
Invalid words during decoding.
const char * what() const noexcept override
Access to the error message.
Definition RCUTrailer.h:85
Information stored in the RCU trailer.
Definition RCUTrailer.h:56
void reset()
Reset the RCU trailer.
RCUTrailer()=default
Constructor.
bool getNumberOfAltroBuffers() const
Definition RCUTrailer.h:144
unsigned char getGlitchFilter() const
Definition RCUTrailer.h:140
static RCUTrailer constructFromPayloadWords(const gsl::span< const uint32_t > payloadwords)
unsigned short getNumberOfChannelAddressMismatch() const
Definition RCUTrailer.h:133
void printStream(std::ostream &stream) const
Prints the contents of the RCU trailer data.
void setTimeSample(double timesample)
set time sample
bool isSparseReadout() const
Definition RCUTrailer.h:147
unsigned char getNumberOfNonZeroSuppressedPostsamples() const
Definition RCUTrailer.h:141
void constructFromRawPayload(const gsl::span< const uint32_t > payloadwords)
Decode RCU trailer from the 32-bit words in the raw buffer.
unsigned char getNumberOfPresamples() const
Definition RCUTrailer.h:137
bool hasSecondBaselineCorr() const
Definition RCUTrailer.h:139
double getTimeSample() const
Access to the sampling time.
unsigned short getNumberOfSamplesPerChannel() const
Definition RCUTrailer.h:146
std::vector< uint32_t > encode() const
void setL1Phase(double l1phase)
Set the L1 phase.
double getL1Phase() const
Access to the L1 phase.
unsigned char getNumberOfPostsamples() const
Definition RCUTrailer.h:138
unsigned short getNumberOfChannelLengthMismatch() const
Definition RCUTrailer.h:134
unsigned char getNumberOfPretriggerSamples() const
Definition RCUTrailer.h:145
unsigned char getBaselineCorrection() const
Definition RCUTrailer.h:135
unsigned char getNumberOfNonZeroSuppressedPresamples() const
Definition RCUTrailer.h:142
GLuint64EXT * result
Definition glcorearb.h:5662
GLuint index
Definition glcorearb.h:781
GLboolean * data
Definition glcorearb.h:298
GLuint GLuint stream
Definition glcorearb.h:1806
constexpr double LHCBunchSpacingNS
std::ostream & operator<<(std::ostream &in, const BadChannelsMap &bcm)
Printing bad channel map on the stream.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"