]>
Commit | Line | Data |
---|---|---|
768be5c3 | 1 | // $Id$ |
2 | ||
3 | //************************************************************************** | |
4 | //* This file is property of and copyright by the ALICE HLT Project * | |
5 | //* ALICE Experiment at CERN, All rights reserved. * | |
6 | //* * | |
7 | //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * | |
8 | //* for The ALICE HLT Project. * | |
9 | //* * | |
10 | //* Permission to use, copy, modify and distribute this software and its * | |
11 | //* documentation strictly for non-commercial purposes is hereby granted * | |
12 | //* without fee, provided that the above copyright notice appears in all * | |
13 | //* copies and that both the copyright notice and this permission notice * | |
14 | //* appear in the supporting documentation. The authors make no claims * | |
15 | //* about the suitability of this software for any purpose. It is * | |
16 | //* provided "as is" without express or implied warranty. * | |
17 | //************************************************************************** | |
18 | ||
19 | /** @file AliHLTAltroEncoder.cxx | |
20 | @author Matthias Richter | |
21 | @date | |
22 | @brief Encoder class for 10/40bit Altro Data format | |
23 | */ | |
24 | ||
25 | #include <cassert> | |
26 | #include <cerrno> | |
27 | #include "AliHLTAltroEncoder.h" | |
4a7578f5 | 28 | #include "TArrayC.h" |
768be5c3 | 29 | |
30 | /** ROOT macro for the implementation of ROOT specific class methods */ | |
31 | ClassImp(AliHLTAltroEncoder) | |
32 | ||
33 | AliHLTAltroEncoder::AliHLTAltroEncoder() | |
34 | : | |
35 | fpBuffer(NULL), | |
36 | fBufferSize(0), | |
37 | fPrevTimebin(AliHLTUInt16MAX), | |
38 | fBunchLength(0), | |
39 | fChannelStart(0), | |
40 | fChannel(AliHLTUInt16MAX), | |
41 | fChannels(), | |
42 | fOffset(0), | |
43 | f10bitWords(0), | |
4a7578f5 | 44 | fOrder(kUnknownOrder), |
45 | fpCDH(NULL), | |
c9f914a3 | 46 | fCDHSize(0), |
47 | fpRCUTrailer(NULL), | |
48 | f32BitFormat(kFALSE), | |
49 | fPointerToCurrentAltroHeader(NULL), | |
50 | fPointerToCurrentBunchWord(NULL), | |
51 | fWordLocationOfBunchCount(0), | |
52 | fNumberOfAltroHeadersInPayload(0), | |
53 | fFillWord(kFALSE), | |
54 | fDDLid(0), | |
55 | fSlice(0), | |
56 | fPartition(0) | |
768be5c3 | 57 | { |
58 | // see header file for class documentation | |
59 | // or | |
60 | // refer to README to build package | |
61 | // or | |
62 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
63 | } | |
64 | ||
65 | AliHLTAltroEncoder::AliHLTAltroEncoder(AliHLTUInt8_t* pBuffer, int iSize) | |
66 | : | |
67 | fpBuffer(pBuffer), | |
68 | fBufferSize(iSize), | |
69 | fPrevTimebin(AliHLTUInt16MAX), | |
70 | fBunchLength(0), | |
71 | fChannelStart(0), | |
72 | fChannel(AliHLTUInt16MAX), | |
73 | fChannels(), | |
74 | fOffset(0), | |
75 | f10bitWords(0), | |
4a7578f5 | 76 | fOrder(kUnknownOrder), |
77 | fpCDH(NULL), | |
c9f914a3 | 78 | fCDHSize(0), |
79 | fpRCUTrailer(NULL), | |
80 | f32BitFormat(kFALSE), | |
81 | fPointerToCurrentAltroHeader(NULL), | |
82 | fPointerToCurrentBunchWord(NULL), | |
83 | fWordLocationOfBunchCount(0), | |
84 | fNumberOfAltroHeadersInPayload(0), | |
85 | fFillWord(kFALSE), | |
86 | fDDLid(0), | |
87 | fSlice(0), | |
88 | fPartition(0) | |
768be5c3 | 89 | { |
90 | // see header file for class documentation | |
91 | } | |
92 | ||
93 | AliHLTAltroEncoder::~AliHLTAltroEncoder() | |
94 | { | |
95 | // see header file for class documentation | |
4a7578f5 | 96 | if (fpCDH) delete fpCDH; |
97 | fpCDH=NULL; | |
98 | ||
99 | if (fpRCUTrailer) delete fpRCUTrailer; | |
100 | fpRCUTrailer=NULL; | |
768be5c3 | 101 | } |
102 | ||
103 | int AliHLTAltroEncoder::SetBuffer(AliHLTUInt8_t* pBuffer, int iSize) | |
104 | { | |
105 | // see header file for class documentation | |
106 | fpBuffer=pBuffer; | |
107 | fBufferSize=iSize; | |
108 | ||
109 | return 0; | |
110 | } | |
111 | ||
112 | int AliHLTAltroEncoder::AddSignal(AliHLTUInt16_t signal, AliHLTUInt16_t timebin) | |
113 | { | |
114 | // see header file for class documentation | |
115 | int iResult=0; | |
116 | if (fPrevTimebin!=AliHLTUInt16MAX) { | |
e782da36 | 117 | if (fPrevTimebin==timebin){ |
118 | HLTWarning("timebin missmatch, two subsequent signals with identical time added, ignoring signal %d at time %d", signal, timebin); | |
119 | return -EINVAL; | |
120 | } | |
121 | //assert(fPrevTimebin!=timebin); | |
768be5c3 | 122 | if (fOrder==kUnknownOrder) { |
123 | if (fPrevTimebin+1==timebin) fOrder=kAscending; | |
124 | else if (fPrevTimebin==timebin+1) fOrder=kDescending; | |
125 | } | |
126 | if ((fOrder!=kAscending || fPrevTimebin+1!=timebin) && | |
127 | (fOrder!=kDescending || fPrevTimebin!=timebin+1)) { | |
128 | // Finalize bunch and start new one | |
129 | iResult=SetBunch(); | |
130 | } | |
131 | } | |
132 | ||
133 | if (iResult>=0 && (iResult=Add10BitValue(signal))>=0) { | |
134 | fBunchLength++; | |
135 | } | |
4a7578f5 | 136 | // HLTDebug("fOffset: %d (fOffset-32)*4: %d f10bitWords*5 %d", fOffset,(fOffset-32)*4,f10bitWords*5); |
137 | assert((fOffset-(fpCDH?fpCDH->GetSize():0)*4)<=f10bitWords*5);//32 is here size of CDH 8 32bit words | |
768be5c3 | 138 | fPrevTimebin=timebin; |
139 | return iResult; | |
140 | } | |
141 | ||
142 | int AliHLTAltroEncoder::SetChannel(AliHLTUInt16_t hwaddress) | |
143 | { | |
144 | // see header file for class documentation | |
145 | int iResult=0; | |
c9f914a3 | 146 | if(f32BitFormat == kTRUE){ |
147 | if(fPointerToCurrentAltroHeader==NULL){ | |
148 | return -1; //Add correct error | |
149 | } | |
150 | ||
768be5c3 | 151 | |
c9f914a3 | 152 | SetBunch();//finalize the last bunch |
153 | ||
154 | f10bitWords-=2;//remove the two words that was reserved for the next bunch | |
155 | ||
156 | // set all bits in the altro header to 0 | |
157 | for(Int_t i=0;i<4;i++){ | |
158 | fPointerToCurrentAltroHeader[i]=0; | |
159 | } | |
160 | //set the HW address to bit 0-15 | |
161 | fPointerToCurrentAltroHeader[0]=hwaddress&0xff; // copy the first 8 bits | |
162 | fPointerToCurrentAltroHeader[1]=(hwaddress>>8)&0xff; // copy the last 8 bits | |
163 | ||
164 | // set number of 10 bit words to bit 16-28 | |
165 | AliHLTUInt16_t length= f10bitWords - fChannelStart; | |
166 | fPointerToCurrentAltroHeader[2]= length&0xff; // copy the first 8 bits | |
167 | fPointerToCurrentAltroHeader[3]= (length>>8)&0xf; // copy the last 4 bits | |
168 | ||
169 | ||
170 | //fill up with fillwords | |
171 | while((f10bitWords%3) != 0){ | |
172 | fFillWord=kTRUE; | |
173 | Add10BitValue(0); | |
174 | } | |
175 | fFillWord= kFALSE; | |
176 | ||
177 | // Set the error bit to 0 (bit 29) and the bit 30 and 31 to 10(mark that this is the altro header) | |
178 | // These three bits are already zero, so in effect it is only bit 31 which is set to 1 | |
179 | fPointerToCurrentAltroHeader[3] |= 0x40; // (0x80 = 1 0 0 0 0 0 0 0) | |
768be5c3 | 180 | fChannelStart=f10bitWords; |
c9f914a3 | 181 | fNumberOfAltroHeadersInPayload++; |
768be5c3 | 182 | } |
c9f914a3 | 183 | else{ |
184 | int added10BitWords=0; | |
185 | if (!fpBuffer) return -ENODEV; | |
186 | if (fOffset+5>=fBufferSize-(fpRCUTrailer?fpRCUTrailer->GetSize():0)) { | |
187 | HLTWarning("buffer too small too finalize channel: %d of %d byte(s) already used", fOffset, fBufferSize); | |
188 | return -ENOSPC; | |
189 | } | |
190 | ||
191 | if (iResult>=0 && | |
192 | (iResult=SetBunch())>=0) { | |
193 | AliHLTUInt16_t length=f10bitWords-fChannelStart; | |
194 | if ((iResult=Pad40Bit())<0) return iResult; | |
195 | // 2 words for the SetBunch (end time and length) and the | |
196 | // padded words to fill 40bit word | |
197 | added10BitWords=iResult+2; | |
198 | assert((length+iResult)%4==0); | |
199 | //HLTInfo("%d %x", hwaddress, hwaddress); | |
200 | fpBuffer[fOffset++]=hwaddress&0xff; | |
201 | fpBuffer[fOffset++]=0xa0 | ((hwaddress>>8)&0xf); | |
202 | fpBuffer[fOffset++]=length&0xff; | |
203 | fpBuffer[fOffset++]=0xa8 | ((length>>8)&0x3); | |
204 | fpBuffer[fOffset++]=0xaa; | |
205 | f10bitWords+=4; | |
206 | fChannelStart=f10bitWords; | |
207 | fChannels.push_back(hwaddress); | |
208 | fPrevTimebin=AliHLTUInt16MAX; | |
209 | } | |
210 | if (iResult<0) return iResult; | |
211 | ||
212 | return added10BitWords; | |
213 | } | |
214 | return 0; | |
768be5c3 | 215 | } |
216 | ||
217 | int AliHLTAltroEncoder::AddChannelSignal(AliHLTUInt16_t signal, AliHLTUInt16_t timebin, AliHLTUInt16_t hwaddress) | |
218 | { | |
219 | // see header file for class documentation | |
220 | int iResult=0; | |
221 | int added10BitWords=0; | |
222 | if (fChannel==AliHLTUInt16MAX) { | |
223 | fChannel=hwaddress; | |
224 | } else if (fChannel!=hwaddress) { | |
225 | iResult=SetChannel(fChannel); | |
226 | added10BitWords=iResult; | |
227 | fChannel=hwaddress; | |
228 | } | |
229 | ||
230 | if (iResult>=0) { | |
231 | if ((iResult=AddSignal(signal, timebin))>=0) | |
232 | added10BitWords++; | |
233 | } | |
234 | ||
235 | if (iResult<0) return iResult; | |
236 | return added10BitWords; | |
237 | } | |
238 | ||
239 | int AliHLTAltroEncoder::GetTotal40bitWords() | |
240 | { | |
241 | // see header file for class documentation | |
242 | if (fChannelStart!=f10bitWords) { | |
243 | HLTWarning("unterminated channel found, check calling sequence"); | |
244 | } | |
245 | assert(fChannelStart%4==0); | |
246 | ||
247 | return fChannelStart; | |
248 | } | |
249 | ||
250 | int AliHLTAltroEncoder::SetBunch() | |
251 | { | |
252 | // see header file for class documentation | |
253 | int iResult=0; | |
254 | ||
255 | // return if the bunch has already been set | |
256 | if (fBunchLength==0) return 0; | |
257 | ||
258 | // fill time bin and bunch length | |
c9f914a3 | 259 | if(f32BitFormat == kTRUE){ |
260 | if(fWordLocationOfBunchCount==3){ | |
261 | //means we have to put the n10bitWords into word 3 | |
262 | //of the 32 bit word and the timebin value into word 2 | |
263 | fBunchLength+=2;//takes the n10bitwords and the timebin value into account | |
264 | ||
265 | //insert the first 4 bits of the 10 bit word into the end of 8bit word 3. | |
266 | fPointerToCurrentBunchWord[2] |= (fBunchLength<<4)&0xf0; | |
267 | ||
268 | //insert the last 6 bits of the 10 bit word into the beginning of 8bitword 4 | |
269 | fPointerToCurrentBunchWord[3] |= (fBunchLength>>4)&0x3f; | |
270 | ||
271 | //set the timebin value | |
272 | //insert the first 6 bits of the 10bitword into the end of 8bit word 2 | |
273 | fPointerToCurrentBunchWord[1] |= ((fPrevTimebin+fBunchLength-3)<<2)&0xfc; | |
274 | //insert the last 4 bits of the 10bitWord into the beginning of 8bit word 3 | |
275 | fPointerToCurrentBunchWord[2] |= ((fPrevTimebin+fBunchLength-3)>>6)&0xf; | |
276 | // set the bunch word pointer and which word the n10bitwords are in | |
277 | fPointerToCurrentBunchWord = &fpBuffer[fOffset]; | |
278 | fWordLocationOfBunchCount = 3-f10bitWords%3; | |
279 | if(fWordLocationOfBunchCount<3){ | |
280 | fOffset+=4; | |
281 | fpBuffer[fOffset]=0; | |
282 | fpBuffer[fOffset+1]=0; | |
283 | fpBuffer[fOffset+2]=0; | |
284 | fpBuffer[fOffset+3]=0; | |
285 | } | |
286 | f10bitWords+=2;// makes room for the n10bitwords and the timebin | |
287 | fBunchLength=0; | |
288 | } | |
289 | else if(fWordLocationOfBunchCount==2){ | |
290 | //means we have to put the n10bitWords into word 2 of the 32 bit word | |
291 | //and the timebin value into word 1 | |
292 | ||
293 | fBunchLength+=2;//takes the n10bitwords and the timebin value into account | |
294 | ||
295 | //insert the first 6 bits of the 10 bit word into the end of 8bit word 2. | |
296 | fPointerToCurrentBunchWord[1] |= (fBunchLength<<2)&0xfc; | |
297 | ||
298 | //insert the last 4 bits of the 10 bit word into the beginning of 8bitword 3 | |
299 | fPointerToCurrentBunchWord[2] |= (fBunchLength>>6)&0xf; | |
300 | ||
301 | //set the timebin value | |
302 | //insert the first 8 bits of the 10bitword into the end of 8bit word 1 | |
303 | fPointerToCurrentBunchWord[0] |= (fPrevTimebin+fBunchLength-3)&0xff; | |
304 | //insert the last 2 bits of the 10bitWord into the beginning of 8bit word 2 | |
305 | fPointerToCurrentBunchWord[1] |= ((fPrevTimebin+fBunchLength-3)>>8)&0x3; | |
306 | // set the bunch word pointer and which word the n10bitwords are in | |
307 | fPointerToCurrentBunchWord = &fpBuffer[fOffset]; | |
308 | fWordLocationOfBunchCount = 3-f10bitWords%3; | |
309 | if(fWordLocationOfBunchCount<3){ | |
310 | fOffset+=4; | |
311 | fpBuffer[fOffset]=0; | |
312 | fpBuffer[fOffset+1]=0; | |
313 | fpBuffer[fOffset+2]=0; | |
314 | fpBuffer[fOffset+3]=0; | |
315 | } | |
316 | f10bitWords+=2;// makes room for the n10bitwords and the timebin | |
317 | fBunchLength=0; | |
318 | } | |
319 | else if(fWordLocationOfBunchCount==1){ | |
320 | //means we have to put the n10bitWords into word 1 of the 32 bit word | |
321 | //and the timebin value into word 3 of the next 32 bit word | |
322 | ||
323 | fBunchLength+=2;//takes the n10bitwords and the timebin value into account | |
324 | ||
325 | //insert the first 8 bits of the 10 bit word into the beginning of 8bit word 1. | |
326 | fPointerToCurrentBunchWord[0] |= fBunchLength&0xff; | |
327 | ||
328 | //insert the last 2 bits of the 10 bit word into the beginning of 8bitword 2 | |
329 | fPointerToCurrentBunchWord[1] |= (fBunchLength>>8)&0x3; | |
330 | ||
331 | //set the timebin value | |
332 | //insert the first 4 bits of the 10bitword into the end of 8bit word 7 | |
333 | fPointerToCurrentBunchWord[6] |= ((fPrevTimebin+fBunchLength-3)<<4)&0xf0; | |
334 | //insert the last 6 bits of the 10bitWord into the beginning of 8bit word 8 | |
335 | fPointerToCurrentBunchWord[7] |= ((fPrevTimebin+fBunchLength-3)>>4)&0x3f; | |
336 | // set the bunch word pointer and which word the n10bitwords are in | |
337 | fPointerToCurrentBunchWord = &fpBuffer[fOffset]; | |
338 | fWordLocationOfBunchCount = 3-f10bitWords%3; | |
339 | if(fWordLocationOfBunchCount<3){ | |
340 | fOffset+=4; | |
341 | fpBuffer[fOffset]=0; | |
342 | fpBuffer[fOffset+1]=0; | |
343 | fpBuffer[fOffset+2]=0; | |
344 | fpBuffer[fOffset+3]=0; | |
345 | } | |
346 | f10bitWords+=2;// makes room for the n10bitwords and the timebin | |
347 | fBunchLength=0; | |
348 | } | |
349 | ||
350 | } | |
351 | else{ | |
352 | if ((iResult=Add10BitValue(fPrevTimebin))>=0) { | |
353 | iResult=Add10BitValue(fBunchLength+2); | |
354 | fBunchLength=0; | |
355 | iResult=2; | |
356 | } | |
768be5c3 | 357 | } |
c9f914a3 | 358 | // fPrevTimebin=AliHLTUInt16MAX;// resets the timebin number |
768be5c3 | 359 | return iResult; |
360 | } | |
361 | ||
362 | int AliHLTAltroEncoder::Add10BitValue(AliHLTUInt16_t value) | |
363 | { | |
364 | // see header file for class documentation | |
365 | int iResult=0; | |
366 | if (!fpBuffer) return -ENODEV; | |
4a7578f5 | 367 | if (fOffset+2>=fBufferSize-(fpRCUTrailer?fpRCUTrailer->GetSize():0)) { |
768be5c3 | 368 | HLTWarning("buffer too small too add 10bit word: %d of %d byte(s) already used", fOffset, fBufferSize); |
369 | return -ENOSPC; | |
370 | } | |
371 | ||
c9f914a3 | 372 | if(value>1023){ |
373 | HLTError("10 bit value cannot be larger than 1023, something is wrong."); | |
374 | return -1; //TODO find better error | |
375 | } | |
768be5c3 | 376 | |
c9f914a3 | 377 | if(f32BitFormat == kFALSE){ |
378 | int bit=(f10bitWords%4)*10; | |
379 | int shift=bit%8; | |
380 | unsigned short maskLow=~((0xff<<shift)>>8); | |
381 | //unsigned short maskHigh=~((0xff<<((bit+10)%8))>>8); | |
382 | if (bit==0) fpBuffer[fOffset]=0; | |
383 | fpBuffer[fOffset++]|=maskLow&(value<<shift); | |
384 | fpBuffer[fOffset]=(value&0x3ff)>>(8-shift); | |
385 | f10bitWords++; | |
386 | if (f10bitWords%4==0) fOffset++; | |
387 | return iResult; | |
388 | } | |
389 | else{ | |
390 | if(f10bitWords == fChannelStart){ //means that there is a new channel(or the first) | |
391 | fPointerToCurrentAltroHeader = &fpBuffer[fOffset]; // set a pointer to the beginning of the altro header | |
392 | ||
393 | fOffset+=4; //Makes space for the altro header in front of the altrodata (1 32 bit word) | |
394 | ||
395 | fpBuffer[fOffset]=0; | |
396 | fpBuffer[fOffset+1]=0; | |
397 | fpBuffer[fOffset+2]=0; | |
398 | fpBuffer[fOffset+3]=0; | |
399 | ||
400 | //set the pointer to the bunch currently being filled | |
401 | //it is always in the 3d 10 bit word when a new channel has started. | |
402 | fPointerToCurrentBunchWord = &fpBuffer[fOffset]; | |
403 | fWordLocationOfBunchCount=3; | |
404 | //make room for the n10BitWords, and the timebin value | |
405 | // fOffset+=2; | |
406 | f10bitWords+=2; | |
407 | } | |
408 | ||
409 | int bit=20-(f10bitWords%3)*10; | |
410 | ||
411 | if(bit ==20){//means we should fill the third word | |
412 | //set bits 25-32 to 0, this also takes care of setting the marker (00) at the end. | |
413 | fpBuffer[fOffset+3] = 0; | |
414 | //copy the last 6 bits of the signal into the first 6 bits of 8BitWord 3 | |
415 | fpBuffer[fOffset+3] |= (value>>4)&0x3f; | |
416 | //set bits 17-24 to 0 | |
417 | fpBuffer[fOffset+2]=0; | |
418 | //copy the first 4 bits of the signal into the last 4 bits of 8BitWord 2 | |
419 | fpBuffer[fOffset+2] |= (value<<4)&0xf0; | |
420 | f10bitWords++; | |
421 | } | |
422 | else if(bit == 10){//means we should fill the middle (2nd) word | |
423 | //copy the last 4 bits of the signal into the first 4 bits of 8BitWord 2 | |
424 | fpBuffer[fOffset+2] |= (value>>6)&0xf; | |
425 | //set bits 8-16 to 0 | |
426 | fpBuffer[fOffset+1]=0; | |
427 | //copy the first 6 bits of the signal into the last 6 bits of 8BitWord 1 | |
428 | fpBuffer[fOffset+1] |= (value<<2)&0xfc; | |
429 | f10bitWords++; | |
430 | } | |
431 | else if(bit == 0){ | |
432 | //set bits 0-7 to 0 | |
433 | fpBuffer[fOffset]=0; | |
434 | //copy the last 2 bits of the signal into the first 2 bits of 8BitWord 1 | |
435 | fpBuffer[fOffset+1] |= (value>>8)&0x3; | |
436 | //copy the first 8 bits of the signal into the first 8 bits of 8BitWord 0 | |
437 | fpBuffer[fOffset] |= value&0xff; | |
438 | f10bitWords++; | |
439 | if(fFillWord == kFALSE){ | |
440 | fOffset += 4; // only increase when the last word is added | |
441 | fpBuffer[fOffset]=0; | |
442 | fpBuffer[fOffset+1]=0; | |
443 | fpBuffer[fOffset+2]=0; | |
444 | fpBuffer[fOffset+3]=0; | |
445 | } | |
446 | } | |
447 | } | |
448 | return f10bitWords; | |
768be5c3 | 449 | } |
450 | ||
451 | int AliHLTAltroEncoder::Pad40Bit() | |
452 | { | |
453 | // see header file for class documentation | |
454 | int iResult=0; | |
455 | int added10BitWords=0; | |
456 | while (iResult>=0 && f10bitWords%4!=0) { | |
457 | if ((iResult=Add10BitValue(0x2aa))>=0) { | |
458 | added10BitWords++; | |
459 | } | |
460 | } | |
461 | if (iResult<0) return iResult; | |
462 | return added10BitWords; | |
463 | } | |
4a7578f5 | 464 | |
465 | int AliHLTAltroEncoder::SetCDH(AliHLTUInt8_t* pCDH,int size) | |
466 | { | |
467 | // see header file for class documentation | |
468 | int iResult=0; | |
469 | if (fOffset>0) { | |
470 | HLTError("CDH can only be set prior to data"); | |
471 | iResult=-EFAULT; | |
472 | } | |
473 | if (size>0 && pCDH){ | |
474 | if (fpCDH == NULL){ | |
475 | fpCDH = new TArrayC(0); | |
476 | } | |
477 | if (fpCDH){ | |
478 | fpCDH->Set(0); | |
479 | fpCDH->Set(size, (const char*)pCDH); | |
480 | fOffset=size; | |
c9f914a3 | 481 | fCDHSize=size; |
4a7578f5 | 482 | } else { |
483 | iResult=-ENOMEM; | |
484 | } | |
485 | } else { | |
486 | iResult=-EINVAL; | |
487 | } | |
488 | return iResult; | |
489 | } | |
490 | ||
491 | int AliHLTAltroEncoder::SetRCUTrailer(AliHLTUInt8_t* pRCUTrailer,int size) | |
492 | { | |
493 | // see header file for class documentation | |
494 | int iResult=0; | |
495 | if (size>0 && pRCUTrailer){ | |
496 | if (fpRCUTrailer == NULL){ | |
497 | fpRCUTrailer = new TArrayC(0); | |
498 | } | |
499 | if (fpRCUTrailer){ | |
500 | fpRCUTrailer->Set(0); | |
501 | fpRCUTrailer->Set(size, (const char*)pRCUTrailer); | |
502 | } else { | |
503 | iResult=-ENOMEM; | |
504 | } | |
505 | } else { | |
506 | iResult=-EINVAL; | |
507 | } | |
508 | return iResult; | |
509 | } | |
510 | ||
511 | int AliHLTAltroEncoder::SetLength() | |
512 | { | |
513 | // see header file for class documentation | |
514 | int iResult=0; | |
515 | if (fChannel!=AliHLTUInt16MAX && (iResult=SetChannel(fChannel))<0) { | |
516 | HLTError("error finalizing channel"); | |
517 | return iResult; | |
518 | } | |
519 | ||
520 | if (fpRCUTrailer && fOffset+fpRCUTrailer->GetSize()<fBufferSize) { | |
521 | // copy the trailer | |
522 | AliHLTUInt32_t* pTgt=reinterpret_cast<AliHLTUInt32_t*>(fpBuffer+fOffset); | |
523 | memcpy(pTgt, fpRCUTrailer->GetArray(), fpRCUTrailer->GetSize()); | |
524 | // set number of 10bit words | |
525 | *pTgt=GetTotal40bitWords(); | |
526 | fOffset+=fpRCUTrailer->GetSize(); | |
527 | } | |
528 | if (fpCDH && fOffset>fpCDH->GetSize()) { | |
529 | memcpy(fpBuffer, fpCDH->GetArray(), fpCDH->GetSize()); | |
530 | AliHLTUInt32_t* pCdhSize=reinterpret_cast<AliHLTUInt32_t*>(fpBuffer); | |
531 | *pCdhSize=fOffset;//set the first word in the header to be the fOffset(number of bytes added) | |
532 | HLTDebug("Size set in the header: %d",*pCdhSize); | |
533 | } | |
c9f914a3 | 534 | if(f32BitFormat == kTRUE){ |
535 | //set all bits to 1 in the first 32 bit of the cdh | |
536 | ||
537 | //word 0 | |
538 | fpBuffer[0] |= 0xff; | |
539 | fpBuffer[1] |= 0xff; | |
540 | fpBuffer[2] |= 0xff; | |
541 | fpBuffer[3] |= 0xff; | |
542 | ||
543 | //word 3 | |
544 | fpBuffer[14] =0; | |
545 | fpBuffer[14] |= 0x2; | |
546 | ||
547 | } | |
4a7578f5 | 548 | return fOffset; |
549 | } | |
a912b63b | 550 | |
c9f914a3 | 551 | void AliHLTAltroEncoder::Revert40BitWords(Int_t /*CDHSize*/, Int_t /*trailerSize*/) |
a912b63b | 552 | { |
553 | // see headerfile for class documentation | |
c9f914a3 | 554 | HLTWarning("Revert40BitWords function no longer has any function, please remove this function call from your analysis"); |
555 | } | |
a912b63b | 556 | |
c9f914a3 | 557 | void AliHLTAltroEncoder::PrintDebug() |
558 | { | |
559 | int n32bitWords = fOffset/4; | |
560 | int word8Counter = 0; | |
561 | Bool_t isAnAltroHeader=kFALSE; | |
562 | Bool_t isData=kFALSE; | |
563 | Bool_t isCDH=kFALSE; | |
564 | Bool_t isTrailer=kFALSE; | |
565 | ||
566 | for(Int_t n32bit=0;n32bit<n32bitWords;n32bit++){ | |
567 | isAnAltroHeader=kFALSE; | |
568 | isData=kFALSE; | |
569 | isCDH=kFALSE; | |
570 | isTrailer=kFALSE; | |
571 | for(Int_t w=0;w<4;w++){ | |
572 | Int_t wordPosition = 4-word8Counter%4; | |
573 | AliHLTUInt8_t word = fpBuffer[n32bit*4+wordPosition-1]; | |
574 | ||
575 | if(n32bit < fCDHSize/4){ | |
576 | isCDH = kTRUE; | |
577 | } | |
578 | else if(wordPosition==4 && (word & 0x80)==0 && (word & 0x40)!=0){//means we have a altroheader | |
579 | isAnAltroHeader=kTRUE; | |
580 | } | |
581 | else if(wordPosition==4 && (word & 0x80)==0 && (word & 0x40)==0){//means we have data | |
582 | isData=kTRUE; | |
583 | } | |
584 | else if(wordPosition==4 && (word & 0x80) !=0 && (word & 0x40)==0){//means we have trailer | |
585 | isTrailer=kTRUE; | |
586 | } | |
587 | else if(wordPosition==4 && (word & 0x80) !=0 && (word & 0x40) !=0){//means we have trailer (last trailer word) | |
588 | isTrailer=kTRUE; | |
589 | } | |
590 | for(int n=7; n>=0; n--){ | |
591 | if(isAnAltroHeader == kTRUE){ | |
592 | if((wordPosition == 4 && n==5) || (wordPosition == 4 && n==4) /*|| wordPosition == 4 && n==0*/){ | |
593 | printf("\t"); | |
594 | } | |
595 | if(wordPosition == 2 && n==7){ | |
596 | printf("\t"); | |
597 | } | |
598 | } | |
599 | else if(isData == kTRUE){ | |
600 | if(wordPosition == 4 && n==5){ | |
601 | printf("\t"); | |
602 | } | |
603 | if(wordPosition == 3 && n==3){ | |
604 | printf("\t"); | |
605 | } | |
606 | if(wordPosition == 2 && n==1){ | |
607 | printf("\t"); | |
608 | } | |
609 | } | |
610 | else if(isTrailer == kTRUE){ | |
611 | if(wordPosition == 4 && n==5){ | |
612 | printf("\t"); | |
613 | } | |
614 | } | |
615 | //print the byte values | |
616 | if((((word>>n)<<7)&0x80) != 0){ | |
617 | printf("1"); | |
618 | } | |
619 | else{ | |
620 | printf("0"); | |
621 | } | |
622 | } | |
623 | word8Counter++; | |
624 | } | |
625 | if(isCDH == kTRUE){ | |
626 | printf("\t CDH %d\n",n32bit); | |
627 | } | |
628 | else if(isAnAltroHeader == kTRUE){ | |
629 | printf("\t AltroHeader \n"); | |
630 | } | |
631 | else if(isData == kTRUE){ | |
632 | printf("\t Data \n"); | |
633 | } | |
634 | else if(isTrailer == kTRUE){ | |
635 | printf("\t Trailer \n"); | |
636 | } | |
a912b63b | 637 | } |
a912b63b | 638 | } |
c9f914a3 | 639 |