update of AltroChannelSelector component by Jason: added monitoring histograms, make...
[u/mrichter/AliRoot.git] / HLT / RCU / AliHLTAltroEncoder.cxx
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"
28 #include "TArrayC.h"
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),
44   fOrder(kUnknownOrder),
45   fpCDH(NULL),
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)
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),
76   fOrder(kUnknownOrder),
77   fpCDH(NULL),
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)
89 {
90   // see header file for class documentation
91 }
92
93 AliHLTAltroEncoder::~AliHLTAltroEncoder()
94 {
95   // see header file for class documentation
96   if (fpCDH) delete fpCDH;
97   fpCDH=NULL;
98
99   if (fpRCUTrailer) delete fpRCUTrailer;
100   fpRCUTrailer=NULL;
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) {
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);
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   }
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
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;
146   if(f32BitFormat == kTRUE){
147     if(fPointerToCurrentAltroHeader==NULL){
148       return -1; //Add correct error
149     }
150
151
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)
180     fChannelStart=f10bitWords;
181     fNumberOfAltroHeadersInPayload++;
182   }
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;
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
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     }
357   }
358   //  fPrevTimebin=AliHLTUInt16MAX;// resets the timebin number
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;
367   if (fOffset+2>=fBufferSize-(fpRCUTrailer?fpRCUTrailer->GetSize():0)) {
368     HLTWarning("buffer too small too add 10bit word: %d of %d byte(s) already used", fOffset, fBufferSize);
369     return -ENOSPC;
370   }
371
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   }
376
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;
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 }
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;
481       fCDHSize=size;
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   }
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   }
548   return fOffset;
549 }
550
551 void AliHLTAltroEncoder::Revert40BitWords(Int_t /*CDHSize*/, Int_t /*trailerSize*/)
552 {
553   // see headerfile for class documentation
554   HLTWarning("Revert40BitWords function no longer has any function, please remove this function call from your analysis");
555 }
556
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     }
637   }
638 }
639