Project
Loading...
Searching...
No Matches
BareElinkEncoder.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_BARE_ELINK_ENCODER_H
13#define O2_MCH_RAW_BARE_ELINK_ENCODER_H
14
15#include "Assertions.h"
16#include "BitSet.h"
17#include "ElinkEncoder.h"
18#include "EncoderImplHelper.h"
22#include "NofBits.h"
23#include <fmt/format.h>
24#include <fmt/printf.h>
25#include <gsl/span>
26#include <iostream>
27#include <vector>
28
29namespace o2::mch::raw
30{
31
36
37template <typename CHARGESUM>
38class ElinkEncoder<BareFormat, CHARGESUM>
39{
40 public:
48 explicit ElinkEncoder(uint8_t elinkId, int phase = 0);
49
55 void addChannelData(uint8_t chId, const std::vector<SampaCluster>& data);
56
57 void addHeartbeat(uint20_t bunchCrossing);
58
60 void clear();
61
64 void fillWithSync(int upto);
65
67 bool get(int i) const;
68
70 int len() const;
71
73 void resetLocalBunchCrossing();
74
77 uint64_t range(int a, int b) const;
78
79 private:
80 void append(bool value);
81 void append(const SampaCluster& sc);
82 void append10(uint16_t value);
83 void append20(uint32_t value);
84 void append50(uint64_t value);
85 void appendCharges(const SampaCluster& sc);
86 void assertPhase();
87 void assertSync();
88 uint64_t nofSync() const { return mNofSync; }
89
90 private:
91 uint8_t mElinkId; //< Elink id 0..39
92 BitSet mBitSet; //< bitstream
93 uint64_t mNofSync; //< number of sync words seen so far
94 int mSyncIndex; //< at which sync bit position should the next fillWithSync start
95 uint64_t mNofBitSeen; //< total number of bits seen so far
96 int mPhase; //< initial number of bits
97 uint32_t mLocalBunchCrossing; //< bunchcrossing to be used in header
98};
99
100namespace
101{
102const BitSet sync(sampaSync().uint64(), 50);
103}
104
105template <typename CHARGESUM>
107 int phase)
108 : mElinkId(elinkId),
109 mBitSet{},
110 mNofSync{0},
111 mSyncIndex{0},
112 mNofBitSeen{0},
113 mLocalBunchCrossing{0},
114 mPhase{phase}
115{
116 impl::assertIsInRange("elinkId", elinkId, 0, 39);
117
118 // the phase is used to "simulate" a possible different timing alignment between elinks.
119
120 if (phase < 0) {
121 mPhase = static_cast<int>(rand() % 20);
122 }
123
124 for (int i = 0; i < mPhase; i++) {
125 // filling the phase with random bits
126 append(static_cast<bool>(rand() % 2));
127 }
128}
129
130template <typename CHARGESUM>
131void ElinkEncoder<BareFormat, CHARGESUM>::addChannelData(uint8_t chId, const std::vector<SampaCluster>& data)
132{
133 if (data.empty()) {
134 throw std::invalid_argument("cannot add empty data");
135 }
136 assertSync();
137 assertNotMixingClusters<CHARGESUM>(data);
138
139 auto header = impl::buildSampaHeader(mElinkId, chId, data);
140
141 append50(header.uint64());
142
143 for (const auto& s : data) {
144 append(s);
145 }
146}
147
148template <typename CHARGESUM>
150{
151 uint8_t chipAddress = impl::computeChipAddress(mElinkId, 0);
152 SampaHeader sh = sampaHeartbeat(chipAddress, bunchCrossing);
153 append50(sh.uint64());
154}
155
157template <typename CHARGESUM>
159{
160 append10(sc.nofSamples());
161 append10(sc.sampaTime);
162 appendCharges(sc);
163}
164
166template <typename CHARGESUM>
167void ElinkEncoder<BareFormat, CHARGESUM>::append(bool value)
168{
169 mBitSet.append(value);
170 mNofBitSeen++;
171}
172
174template <typename CHARGESUM>
175void ElinkEncoder<BareFormat, CHARGESUM>::append10(uint16_t value)
176{
177 mBitSet.append(value, 10);
178 mNofBitSeen += 10;
179}
180
182template <typename CHARGESUM>
183void ElinkEncoder<BareFormat, CHARGESUM>::append20(uint32_t value)
184{
185 mBitSet.append(value, 20);
186 mNofBitSeen += 20;
187}
188
190template <typename CHARGESUM>
191void ElinkEncoder<BareFormat, CHARGESUM>::append50(uint64_t value)
192{
193 mBitSet.append(value, 50);
194 mNofBitSeen += 50;
195}
196
197template <typename CHARGESUM>
198void ElinkEncoder<BareFormat, CHARGESUM>::assertSync()
199{
200 bool firstSync = (mNofSync == 0);
201
202 // if mSyncIndex is not zero it means
203 // we have a pending sync to finish to transmit
204 // (said otherwise we're not aligned to an expected 50bits mark)
205 bool pendingSync = (mSyncIndex != 0);
206
207 if (firstSync || pendingSync) {
208 for (int i = mSyncIndex; i < 50; i++) {
209 append(sync.get(i));
210 }
211 mSyncIndex = 0;
212 if (firstSync) {
213 mNofSync++;
214 }
215 }
216}
217
218template <typename CHARGESUM>
220{
221 // we are not resetting the global counters mNofSync, mNofBitSeen,
222 // just the bit stream
223 mBitSet.clear();
224}
225
226template <typename CHARGESUM>
228{
229 auto d = upto - len();
230 mSyncIndex = circularAppend(mBitSet, sync, mSyncIndex, d);
231 mNofSync += d / 50;
232 mNofBitSeen += d;
233}
234
235template <typename CHARGESUM>
237{
238 impl::assertIsInRange("i", i, 0, len() - 1);
239 return mBitSet.get(i);
240}
241
242template <typename CHARGESUM>
244{
245 return mBitSet.len();
246}
247
248template <typename CHARGESUM>
250{
251 return mBitSet.subset(a, b).uint64(0, b - a + 1);
252}
253
254template <typename CHARGESUM>
256{
257 mLocalBunchCrossing = mPhase;
258}
259
260} // namespace o2::mch::raw
261
262#endif
uint64_t phase
Definition RawEventData.h:7
int32_t i
void appendCharges(const SampaCluster &sc)
SampaHeader is the 50-bits header word used in Sampa data transmission protocol.
Definition SampaHeader.h:51
constexpr uint64_t uint64() const
return the header as a 64-bits integer
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLenum GLint * range
Definition glcorearb.h:1899
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLboolean * data
Definition glcorearb.h:298
GLenum GLenum GLsizei len
Definition glcorearb.h:4232
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
uint16_t computeChipAddress(uint8_t elinkId, DualSampaChannelId chId)
SampaHeader buildSampaHeader(uint8_t elinkId, DualSampaChannelId chId, gsl::span< const SampaCluster > data)
int assertIsInRange(std::string what, uint64_t value, uint64_t min, uint64_t max)
Definition Assertions.h:20
SampaHeader sampaHeartbeat(uint8_t elinkId, uint20_t bunchCrossing)
Heartbeat packet.
int circularAppend(BitSet &bs, const BitSet &ringBuffer, int startBit, int n)
Definition BitSet.cxx:421
SampaHeader sampaSync()
The 50-bits Sampa SYNC word.
void append(const char *msg, std::string &to)
uint32_t uint20_t
Definition DataFormats.h:68
Piece of data for one Sampa channel.
uint16_t nofSamples() const
vec clear()