Project
Loading...
Searching...
No Matches
UserLogicEndpointDecoder.h
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
12#ifndef O2_MCH_RAW_USERLOGIC_ENDPOINT_DECODER_H
13#define O2_MCH_RAW_USERLOGIC_ENDPOINT_DECODER_H
14
15#include <array>
18#include <gsl/span>
19#include <fmt/printf.h>
20#include <fmt/format.h>
21#include "MakeArray.h"
22#include "Assertions.h"
23#include <iostream>
24#include <boost/multiprecision/cpp_int.hpp>
26#include "PayloadDecoder.h"
27#include "Debug.h"
29
30namespace o2::mch::raw
31{
32
36
37template <typename CHARGESUM, int VERSION>
38class UserLogicEndpointDecoder : public PayloadDecoder<UserLogicEndpointDecoder<CHARGESUM, VERSION>>
39{
40 public:
42
46 UserLogicEndpointDecoder(uint16_t feeId,
47 std::function<std::optional<uint16_t>(FeeLinkId id)> fee2SolarMapper,
48 DecodedDataHandlers decodedDataHandlers);
49
53
59 size_t append(Payload bytes);
61
66
68 void reset();
70
71 private:
72 uint16_t mFeeId;
73 std::function<std::optional<uint16_t>(FeeLinkId id)> mFee2SolarMapper;
74 DecodedDataHandlers mDecodedDataHandlers;
75 std::map<uint16_t, std::array<ElinkDecoder, 40>> mElinkDecoders;
76 int mNofGbtWordsSeens;
77};
78
79using namespace o2::mch::raw;
80using namespace boost::multiprecision;
81
82template <typename CHARGESUM, int VERSION>
84 std::function<std::optional<uint16_t>(FeeLinkId id)> fee2SolarMapper,
85 DecodedDataHandlers decodedDataHandlers)
86 : PayloadDecoder<UserLogicEndpointDecoder<CHARGESUM, VERSION>>(decodedDataHandlers),
87 mFeeId{feeId},
88 mFee2SolarMapper{fee2SolarMapper},
89 mDecodedDataHandlers(decodedDataHandlers),
90 mNofGbtWordsSeens{0}
91{
92}
93
94template <typename CHARGESUM, int VERSION>
96{
97 if (buffer.size() % 8) {
98 throw std::invalid_argument("buffer size should be a multiple of 8");
99 }
100 size_t n{0};
101
102 for (size_t i = 0; i < buffer.size(); i += 8) {
103 uint64_t word = (static_cast<uint64_t>(buffer[i + 0])) |
104 (static_cast<uint64_t>(buffer[i + 1]) << 8) |
105 (static_cast<uint64_t>(buffer[i + 2]) << 16) |
106 (static_cast<uint64_t>(buffer[i + 3]) << 24) |
107 (static_cast<uint64_t>(buffer[i + 4]) << 32) |
108 (static_cast<uint64_t>(buffer[i + 5]) << 40) |
109 (static_cast<uint64_t>(buffer[i + 6]) << 48) |
110 (static_cast<uint64_t>(buffer[i + 7]) << 56);
111
112 if (word == 0xFEEDDEEDFEEDDEED) {
113 continue;
114 }
115
116 ULHeaderWord<VERSION> ulword{word};
117
118 int gbt = ulword.linkID;
119
120 // The User Logic uses the condition gbt=15 to identify special control and diagnostics words
121 // that are generated internally and do not contain data coming from the front-end electronics.
122 if (gbt == 15) {
123 // TODO: the exact format of the UL control words is still being defined and tested,
124 // hence proper decoding will be implemented once the format is finalized.
125 // For the moment we simply avoid throwing an exception when linkID is equal to 15
126 continue;
127 } else {
128 if (gbt < 0 || gbt > 11) {
129 SampaErrorHandler handler = mDecodedDataHandlers.sampaErrorHandler;
130 if (handler) {
131 DsElecId dsId{static_cast<uint16_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0)};
132 handler(dsId, -1, ErrorBadLinkID);
133 continue;
134 } else {
135 throw fmt::format("warning : out-of-range gbt {} word={:08X}\n", gbt, word);
136 }
137 }
138 }
139
140 // Get the corresponding decoders array, or allocate it if does not exist yet
141 auto d = mElinkDecoders.find(gbt);
142 if (d == mElinkDecoders.end()) {
143
144 // Compute the (feeId, linkId) pair...
145 FeeLinkId feeLinkId(mFeeId, gbt);
146 // ... and get the solar from it
147 auto solarId = mFee2SolarMapper(feeLinkId);
148
149 if (!solarId.has_value()) {
150 SampaErrorHandler handler = mDecodedDataHandlers.sampaErrorHandler;
151 if (handler) {
152 DsElecId dsId{static_cast<uint16_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0)};
153 handler(dsId, -1, ErrorUnknownLinkID);
154 continue;
155 } else {
156 throw std::logic_error(fmt::format("{} Could not get solarId from feeLinkId={}\n", __PRETTY_FUNCTION__, asString(feeLinkId)));
157 }
158 }
159
160 mElinkDecoders.emplace(static_cast<uint16_t>(gbt),
161 impl::makeArray<40>([solarId, *this](size_t i) {
162 DsElecId dselec{solarId.value(), static_cast<uint8_t>(i / 5), static_cast<uint8_t>(i % 5)};
163 return ElinkDecoder(dselec, mDecodedDataHandlers);
164 }));
165 d = mElinkDecoders.find(gbt);
166 }
167
168 uint16_t dsid = ulword.dsID;
169 if (dsid > 39) {
170 SampaErrorHandler handler = mDecodedDataHandlers.sampaErrorHandler;
171 if (handler) {
172 DsElecId dsId{static_cast<uint16_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0)};
173 handler(dsId, -1, ErrorBadELinkID);
174 continue;
175 } else {
176 throw fmt::format("warning : out-of-range DS ID {} word={:08X}\n", dsid, word);
177 }
178 }
179
180 int8_t error = ulword.error;
181 bool incomplete = ulword.incomplete > 0;
182 uint64_t data50 = ulword.data;
183
184 d->second.at(dsid).append(data50, error, incomplete);
185 n += 8;
186 }
187 return n;
188}
189
190template <typename CHARGESUM, int VERSION>
192{
193 for (auto& arrays : mElinkDecoders) {
194 for (auto& d : arrays.second) {
195 d.reset();
196 }
197 }
198}
199} // namespace o2::mch::raw
200#endif
int32_t i
Decoder for MCH Raw Data Format.
A UserLogicEndpointDecoder groups 12 x (40 UserLogicElinkDecoder objects)
size_t append(Payload bytes)
Append the equivalent n 64-bits words bytes size (=n) must be a multiple of 8.
UserLogicEndpointDecoder(uint16_t feeId, std::function< std::optional< uint16_t >(FeeLinkId id)> fee2SolarMapper, DecodedDataHandlers decodedDataHandlers)
GLdouble n
Definition glcorearb.h:1982
GLuint buffer
Definition glcorearb.h:655
const GLuint * arrays
Definition glcorearb.h:1314
std::string asString(const SampaCluster &sc)
std::function< void(DsElecId dsId, int8_t chip, uint32_t error)> SampaErrorHandler