Project
Loading...
Searching...
No Matches
LinkDecoder.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
16
17#include "MIDRaw/LinkDecoder.h"
18
21#include "MIDRaw/ELinkManager.h"
22#include "MIDRaw/FEEIdConfig.h"
23#include "MIDRaw/Utils.h"
24
25namespace o2
26{
27namespace mid
28{
29namespace impl
30{
31
33{
34 public:
35 GBTUserLogicDecoderImplV2(uint16_t ulFeeId, bool isDebugMode = false, const ElectronicsDelay& electronicsDelay = ElectronicsDelay(), const FEEIdConfig& feeIdConfig = FEEIdConfig())
36 {
37 mElinkManager.init(ulFeeId, isDebugMode, false, electronicsDelay, feeIdConfig);
38 mELinkDecoder.setBareDecoder(false);
39 }
40
41 void operator()(gsl::span<const uint8_t> payload, uint32_t orbit, uint32_t trigger, std::vector<ROBoard>& data, std::vector<ROFRecord>& rofs)
42 {
44 mElinkManager.set(orbit, trigger);
45 // for (auto& byte : payload) {
46 auto it = payload.begin();
47 auto end = payload.end();
48 while (it != end) {
49 if (mELinkDecoder.isZero(*it)) {
50 // The e-link decoder is empty, meaning that we expect a new board.
51 // The first byte of the board should have the STARTBIT on.
52 // If this is not the case, we move to the next byte.
53 // Notice that the payload has zeros until the end of the 256 bits word:
54 // a) when moving from the regional high to regional low
55 // b) at the end of the HBF
56 ++it;
57 continue;
58 }
59
60 if (mELinkDecoder.add(it, end)) {
61 mElinkManager.onDone(mELinkDecoder, data, rofs);
62 mELinkDecoder.reset();
63 }
64 }
65 }
66
67 private:
68 ELinkDecoder mELinkDecoder{};
69 ELinkManager mElinkManager{};
70};
71
73{
74 public:
75 GBTUserLogicDecoderImplV1(uint16_t feeId, bool isDebugMode = false, const ElectronicsDelay& electronicsDelay = ElectronicsDelay())
76 {
78 mOffset = 8 * crateparams::getGBTIdInCrate(feeId);
79 mElinkManager.init(feeId, isDebugMode, true, electronicsDelay);
80 }
81
82 void operator()(gsl::span<const uint8_t> payload, uint32_t orbit, uint32_t trigger, std::vector<ROBoard>& data, std::vector<ROFRecord>& rofs)
83 {
85 mElinkManager.set(orbit, trigger);
86 // for (auto& byte : payload) {
87 auto it = payload.begin();
88 auto end = payload.end();
89 while (it != end) {
90 if (mELinkDecoder.isZero(*it)) {
91 // The e-link decoder is empty, meaning that we expect a new board.
92 // The first byte of the board should have the STARTBIT on.
93 // If this is not the case, we move to the next byte.
94 // Notice that the payload has zeros until the end of the 256 bits word:
95 // a) when moving from the regional high to regional low
96 // b) at the end of the HBF
97 ++it;
98 continue;
99 }
100
101 if (mELinkDecoder.add(it, end)) {
102 mElinkManager.onDone(mELinkDecoder, mCrateId, mOffset + mELinkDecoder.getId() % 8, data, rofs);
103 mELinkDecoder.reset();
104 }
105 }
106 }
107
108 private:
109 uint8_t mCrateId{0};
110 uint8_t mOffset{0};
111 ELinkDecoder mELinkDecoder{};
112 ELinkManager mElinkManager{};
113};
114
116{
117 public:
118 GBTBareDecoderImplV1(uint16_t feeId, bool isDebugMode = false, uint8_t mask = 0xFF, const ElectronicsDelay& electronicsDelay = ElectronicsDelay()) : mIsDebugMode(isDebugMode), mMask(mask)
119 {
121 mElinkManager.init(feeId, isDebugMode, true, electronicsDelay);
122 auto crateId = crateparams::getCrateIdFromGBTUniqueId(feeId);
123 auto offset = 8 * crateparams::getGBTIdInCrate(feeId);
124 for (int ilink = 0; ilink < 10; ++ilink) {
125 mBoardUniqueIds.emplace_back(raw::makeUniqueLocID(crateId, offset + ilink % 8));
126 }
127 }
128
129 void operator()(gsl::span<const uint8_t> payload, uint32_t orbit, uint32_t trigger, std::vector<ROBoard>& data, std::vector<ROFRecord>& rofs)
130 {
132 mElinkManager.set(orbit, trigger);
133 mData = &data;
134 mROFs = &rofs;
135
136 uint8_t byte = 0;
137 size_t ilink = 0, linkMask = 0, byteOffset = 0;
138
139 for (int ireg = 0; ireg < 2; ++ireg) {
140 byteOffset = 5 * ireg;
141 if (mIsDebugMode) {
142 ilink = 8 + ireg;
143 linkMask = (1 << ilink);
144 for (size_t idx = byteOffset + 4; idx < payload.size(); idx += 16) {
145 byte = payload[idx];
146 if ((mIsFeeding & linkMask) || byte) {
147 processRegDebug(ilink, byte);
148 }
149 }
150 }
151 for (int ib = 0; ib < 4; ++ib) {
152 ilink = ib + 4 * ireg;
153 linkMask = (1 << ilink);
154 if (mMask & linkMask) {
155 for (size_t idx = byteOffset + ib; idx < payload.size(); idx += 16) {
156 byte = payload[idx];
157 if ((mIsFeeding & linkMask) || byte) {
158 processLoc(ilink, byte);
159 }
160 }
161 }
162 }
163 }
164 }
165
166 private:
167 void processLoc(size_t ilink, uint8_t byte)
168 {
170 auto& decoder = mElinkManager.getDecoder(mBoardUniqueIds[ilink], true);
171 if (decoder.getNBytes() > 0) {
172 decoder.addAndComputeSize(byte);
173 if (decoder.isComplete()) {
174 mElinkManager.onDone(decoder, mBoardUniqueIds[ilink], *mData, *mROFs);
175 decoder.reset();
176 mIsFeeding &= (~(1 << ilink));
177 }
178 } else if ((byte & (raw::sSTARTBIT | raw::sCARDTYPE)) == (raw::sSTARTBIT | raw::sCARDTYPE)) {
179 decoder.add(byte);
180 mIsFeeding |= (1 << ilink);
181 }
182 }
183
184 void processRegDebug(size_t ilink, uint8_t byte)
185 {
187 auto& decoder = mElinkManager.getDecoder(mBoardUniqueIds[ilink], false);
188 if (decoder.getNBytes() > 0) {
189 decoder.add(byte);
190 if (decoder.isComplete()) {
191 mElinkManager.onDone(decoder, mBoardUniqueIds[ilink], *mData, *mROFs);
192 decoder.reset();
193 mIsFeeding &= (~(1 << ilink));
194 }
195 } else if (byte & raw::sSTARTBIT) {
196 decoder.add(byte);
197 mIsFeeding |= (1 << ilink);
198 }
199 }
200
201 bool mIsDebugMode{false};
202 uint8_t mMask{0xFF};
203 uint16_t mIsFeeding{0};
204 ELinkManager mElinkManager{};
205 std::vector<uint8_t> mBoardUniqueIds{};
206 std::vector<ROBoard>* mData{nullptr};
207 std::vector<ROFRecord>* mROFs{nullptr};
208};
209
210} // namespace impl
211
212void LinkDecoder::process(gsl::span<const uint8_t> payload, uint32_t orbit, uint32_t trigger, std::vector<ROBoard>& data, std::vector<ROFRecord>& rofs)
213{
215 mDecode(payload, orbit, trigger, data, rofs);
216}
217
218std::unique_ptr<LinkDecoder> createGBTDecoder(const o2::header::RDHAny& rdh, uint16_t feeId, bool isDebugMode, uint8_t mask, const ElectronicsDelay& electronicsDelay)
219{
221 if (raw::isBare(rdh)) {
222 return std::make_unique<LinkDecoder>(impl::GBTBareDecoderImplV1(feeId, isDebugMode, mask, electronicsDelay));
223 }
224 std::cout << "Error: GBT decoder not defined for UL. Please use Link decoder instead" << std::endl;
225 return nullptr;
226}
227
228std::unique_ptr<LinkDecoder> createLinkDecoder(const o2::header::RDHAny& rdh, uint16_t feeId, bool isDebugMode, uint8_t mask, const ElectronicsDelay& electronicsDelay, const FEEIdConfig& feeIdConfig)
229{
231 if (raw::isBare(rdh)) {
232 return std::make_unique<LinkDecoder>(impl::GBTBareDecoderImplV1(feeId, isDebugMode, mask, electronicsDelay));
233 }
234 return std::make_unique<LinkDecoder>(impl::GBTUserLogicDecoderImplV2(feeId, isDebugMode, electronicsDelay, feeIdConfig));
235}
236
237std::unique_ptr<LinkDecoder> createLinkDecoder(uint16_t feeId, bool isBare, bool isDebugMode, uint8_t mask, const ElectronicsDelay& electronicsDelay, const FEEIdConfig& feeIdConfig)
238{
240 if (isBare) {
241 return std::make_unique<LinkDecoder>(impl::GBTBareDecoderImplV1(feeId, isDebugMode, mask, electronicsDelay));
242 }
243 return std::make_unique<LinkDecoder>(impl::GBTUserLogicDecoderImplV2(feeId, isDebugMode, electronicsDelay, feeIdConfig));
244}
245
246} // namespace mid
247} // namespace o2
MID RO crate parameters.
Raw data utilities for MID.
MID e-link data shaper manager.
Hardware Id to FeeId mapper.
uint64_t orbit
Definition RawEventData.h:6
Class interface for the MID link decoder.
Structure to store the readout board information.
bool isZero(uint8_t byte) const
Checks if this is a zero.
void add(const uint8_t byte)
Adds a byte.
void setBareDecoder(bool isBare)
uint8_t getId() const
Gets the card ID.
void addAndComputeSize(const uint8_t byte)
ELinkDecoder & getDecoder(uint8_t boardUniqueId, bool isLoc)
Returns the decoder.
void init(uint16_t feeId, bool isDebugMode, bool isBare=false, const ElectronicsDelay &electronicsDelay=ElectronicsDelay(), const FEEIdConfig &feeIdConfig=FEEIdConfig())
void onDone(const ELinkDecoder &decoder, uint8_t boardUniqueId, std::vector< ROBoard > &data, std::vector< ROFRecord > &rofs)
Main function to be executed when decoding is done.
void set(uint32_t orbit, uint32_t trigger)
void process(gsl::span< const uint8_t > payload, uint32_t orbit, uint32_t trigger, std::vector< ROBoard > &data, std::vector< ROFRecord > &rofs)
std::function< void(gsl::span< const uint8_t >, uint32_t orbit, uint32_t trigger, std::vector< ROBoard > &data, std::vector< ROFRecord > &rofs)> mDecode
Definition LinkDecoder.h:48
void operator()(gsl::span< const uint8_t > payload, uint32_t orbit, uint32_t trigger, std::vector< ROBoard > &data, std::vector< ROFRecord > &rofs)
GBTBareDecoderImplV1(uint16_t feeId, bool isDebugMode=false, uint8_t mask=0xFF, const ElectronicsDelay &electronicsDelay=ElectronicsDelay())
GBTUserLogicDecoderImplV1(uint16_t feeId, bool isDebugMode=false, const ElectronicsDelay &electronicsDelay=ElectronicsDelay())
void operator()(gsl::span< const uint8_t > payload, uint32_t orbit, uint32_t trigger, std::vector< ROBoard > &data, std::vector< ROFRecord > &rofs)
GBTUserLogicDecoderImplV2(uint16_t ulFeeId, bool isDebugMode=false, const ElectronicsDelay &electronicsDelay=ElectronicsDelay(), const FEEIdConfig &feeIdConfig=FEEIdConfig())
void operator()(gsl::span< const uint8_t > payload, uint32_t orbit, uint32_t trigger, std::vector< ROBoard > &data, std::vector< ROFRecord > &rofs)
GLuint GLuint end
Definition glcorearb.h:469
GLboolean * data
Definition glcorearb.h:298
GLintptr offset
Definition glcorearb.h:660
GLint GLuint mask
Definition glcorearb.h:291
uint8_t itsSharedClusterMap uint8_t
uint8_t getCrateIdFromGBTUniqueId(uint16_t gbtUniqueId)
Gets the crate ID from the GBT unique ID.
uint8_t getGBTIdInCrate(uint16_t gbtUniqueId)
Gets the link ID in crate from the RO ID.
uint8_t makeUniqueLocID(uint8_t crateId, uint8_t locId)
Definition ROBoard.h:86
bool isBare(const o2::header::RDHAny &rdh)
Test if the data comes from the common logic.
Definition Utils.h:31
std::unique_ptr< LinkDecoder > createGBTDecoder(const o2::header::RDHAny &rdh, uint16_t feeId, bool isDebugMode, uint8_t mask, const ElectronicsDelay &electronicsDelay)
std::unique_ptr< LinkDecoder > createLinkDecoder(const o2::header::RDHAny &rdh, uint16_t feeId, bool isDebugMode, uint8_t mask, const ElectronicsDelay &electronicsDelay, const FEEIdConfig &feeIdConfig)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...