3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /** @file AliHLTAltroEncoder.cxx
20 @author Matthias Richter
22 @brief Encoder class for 10/40bit Altro Data format
27 #include "AliHLTAltroEncoder.h"
29 /** ROOT macro for the implementation of ROOT specific class methods */
30 ClassImp(AliHLTAltroEncoder)
32 AliHLTAltroEncoder::AliHLTAltroEncoder()
36 fPrevTimebin(AliHLTUInt16MAX),
39 fChannel(AliHLTUInt16MAX),
45 // see header file for class documentation
47 // refer to README to build package
49 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
52 AliHLTAltroEncoder::AliHLTAltroEncoder(AliHLTUInt8_t* pBuffer, int iSize)
56 fPrevTimebin(AliHLTUInt16MAX),
59 fChannel(AliHLTUInt16MAX),
65 // see header file for class documentation
68 AliHLTAltroEncoder::~AliHLTAltroEncoder()
70 // see header file for class documentation
73 int AliHLTAltroEncoder::SetBuffer(AliHLTUInt8_t* pBuffer, int iSize)
75 // see header file for class documentation
82 int AliHLTAltroEncoder::AddSignal(AliHLTUInt16_t signal, AliHLTUInt16_t timebin)
84 // see header file for class documentation
86 if (fPrevTimebin!=AliHLTUInt16MAX) {
87 assert(fPrevTimebin!=timebin);
88 if (fOrder==kUnknownOrder) {
89 if (fPrevTimebin+1==timebin) fOrder=kAscending;
90 else if (fPrevTimebin==timebin+1) fOrder=kDescending;
92 if ((fOrder!=kAscending || fPrevTimebin+1!=timebin) &&
93 (fOrder!=kDescending || fPrevTimebin!=timebin+1)) {
94 // Finalize bunch and start new one
99 if (iResult>=0 && (iResult=Add10BitValue(signal))>=0) {
102 assert(fOffset*4<=f10bitWords*5);
103 fPrevTimebin=timebin;
107 int AliHLTAltroEncoder::SetChannel(AliHLTUInt16_t hwaddress)
109 // see header file for class documentation
111 int added10BitWords=0;
112 if (!fpBuffer) return -ENODEV;
113 if (fOffset+5>=fBufferSize) {
114 HLTWarning("buffer too small too finalize channel: %d of %d byte(s) already used", fOffset, fBufferSize);
119 (iResult=SetBunch())>=0) {
120 AliHLTUInt16_t length=f10bitWords-fChannelStart;
121 if ((iResult=Pad40Bit())<0) return iResult;
122 // 2 words for the SetBunch (end time and length) and the
123 // padded words to fill 40bit word
124 added10BitWords=iResult+2;
125 assert((length+iResult)%4==0);
126 //HLTInfo("%d %x", hwaddress, hwaddress);
127 fpBuffer[fOffset++]=hwaddress&0xff;
128 fpBuffer[fOffset++]=0xa0 | (hwaddress>>8)&0xf;
129 fpBuffer[fOffset++]=length&0xff;
130 fpBuffer[fOffset++]=0xa8 | (length>>8)&0x3;
131 fpBuffer[fOffset++]=0xaa;
133 fChannelStart=f10bitWords;
134 fChannels.push_back(hwaddress);
135 fPrevTimebin=AliHLTUInt16MAX;
137 if (iResult<0) return iResult;
138 return added10BitWords;
141 int AliHLTAltroEncoder::AddChannelSignal(AliHLTUInt16_t signal, AliHLTUInt16_t timebin, AliHLTUInt16_t hwaddress)
143 // see header file for class documentation
145 int added10BitWords=0;
146 if (fChannel==AliHLTUInt16MAX) {
148 } else if (fChannel!=hwaddress) {
149 iResult=SetChannel(fChannel);
150 added10BitWords=iResult;
155 if ((iResult=AddSignal(signal, timebin))>=0)
159 if (iResult<0) return iResult;
160 return added10BitWords;
163 int AliHLTAltroEncoder::GetTotal40bitWords()
165 // see header file for class documentation
166 if (fChannelStart!=f10bitWords) {
167 HLTWarning("unterminated channel found, check calling sequence");
169 assert(fChannelStart%4==0);
171 return fChannelStart;
174 int AliHLTAltroEncoder::SetBunch()
176 // see header file for class documentation
179 // return if the bunch has already been set
180 if (fBunchLength==0) return 0;
182 // fill time bin and bunch length
183 if ((iResult=Add10BitValue(fPrevTimebin))>=0) {
184 iResult=Add10BitValue(fBunchLength+2);
191 int AliHLTAltroEncoder::Add10BitValue(AliHLTUInt16_t value)
193 // see header file for class documentation
195 if (!fpBuffer) return -ENODEV;
196 if (fOffset+2>=fBufferSize) {
197 HLTWarning("buffer too small too add 10bit word: %d of %d byte(s) already used", fOffset, fBufferSize);
201 int bit=(f10bitWords%4)*10;
203 unsigned short maskLow=~((0xff<<shift)>>8);
204 //unsigned short maskHigh=~((0xff<<((bit+10)%8))>>8);
205 fpBuffer[fOffset++]|=maskLow&(value<<shift);
206 fpBuffer[fOffset]=(value&0x3ff)>>(8-shift);
208 if (f10bitWords%4==0) fOffset++;
213 int AliHLTAltroEncoder::Pad40Bit()
215 // see header file for class documentation
217 int added10BitWords=0;
218 while (iResult>=0 && f10bitWords%4!=0) {
219 if ((iResult=Add10BitValue(0x2aa))>=0) {
223 if (iResult<0) return iResult;
224 return added10BitWords;