-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCStackUnpacker.cpp.orig
205 lines (156 loc) · 5.37 KB
/
CStackUnpacker.cpp.orig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
This software is Copyright by the Board of Trustees of Michigan
State University (c) Copyright 2005.
You may use this software under the terms of the GNU public license
(GPL). The terms of this license are described at:
http://www.gnu.org/licenses/gpl.txt
Author:
Ron Fox
NSCL
Michigan State University
East Lansing, MI 48824-1321
*/
#include <config.h>
#include "CStackUnpacker.h"
#include "CModuleUnpacker.h"
#include "C785Unpacker.h"
#include "CNADC2530Unpacker.h"
#include "CMADC32Unpacker.h"
#include "CV1x90Unpacker.h"
#include "CV977Unpacker.h"
#include "CParamMapCommand.h"
#include "CStackMapCommand.h"
#include "CMASE.h"
#include "CHINP.h"
#include "CPSD.h"
#include <Event.h>
#include <TCLAnalyzer.h>
#include <Analyzer.h>
#include <BufferDecoder.h>
#include <iostream>
using namespace std;
// Constants
static const UShort_t VMUSB_STACKID_MASK(0xe000);
static const UShort_t VMUSB_STACKID_SHIFT(13);
static const UShort_t VMUSB_CONTINUE(0x1000);
static const UShort_t VMUSB_LENGTH(0x0fff);
// Local and class static data:
static C785Unpacker unpack785;
static CNADC2530Unpacker unpackNADC2530;
static CMADC32Unpacker unpackMADC32;
static CV1x90Unpacker unpackV1x90;
static CV977Unpacker unpackV977;
static CMASE unpackMase;
static CHINP unpackHINP;
static CPSD unpackPSD;
// table of unpackers for each type of module.
CModuleUnpacker* CStackUnpacker::m_unpackers[] =
{
&unpack785,
&unpackNADC2530,
&unpackMADC32,
&unpackV1x90,
&unpackV977,
&unpackMase,
&unpack785, // CAEN Dual range placeholder
&unpackHINP,
&unpackPSD
};
//////////////////////////////////////////////////////////////////////////////////
// Canonicals:
// The ones we have ar no-ops.
CStackUnpacker::CStackUnpacker() {}
CStackUnpacker::~CStackUnpacker() {}
////////////////////////////////////////////////////////////////////////////////////
// The unpacker itself.
//
/*!
Unpacks the data from a VM-USB event
- The event is assembled into a fector of unsigned 16 bit words.. along the way
extracting the stack id.
- The stack map is fetched and the parameter maps in order are used to determine
which module unpackers to invoke for each chunk of data in the event.
\param pEvent - Pointer to the raw data.
\param rEvent - The 'array' of parameters in which to unpack the data.
\param rAnalyzer - Reference to the analyzer. This is really a Tcl Analyzer and is
used to set the size of the event (in bytes).
\param rDecoder - Reference to the buffer decoder which is not used at all atually.
\return Bool_t
\retval kfTRUE - The unpacker succeeded. Remaining event processors can be called.
\retval kfFALSE - The unpacker failed. The remaining event processors should not be called.
*/
Bool_t
CStackUnpacker::operator()(const Address_t pEvent,
CEvent& rEvent,
CAnalyzer& rAnalyzer,
CBufferDecoder& rDecoder)
{
CTclAnalyzer& analyzer(dynamic_cast<CTclAnalyzer&>(rAnalyzer));
TranslatorPointer<UShort_t> p(*(rDecoder.getBufferTranslator()), pEvent);
vector<uint16_t> event;
StackInfo info;
info = assembleEvent(p, event);
int stackId = info.s_stackNumber;
analyzer.SetEventSize((info.s_stackSize)*sizeof(uint16_t)); // +1 for the header.
// Get our stack map:
const CStackMapCommand::stackMap& myMap(CStackMapCommand::getMap(stackId));
// Unpack each module in the stack:
unsigned int offset = 0;
for (int i = 0; i < myMap.size(); i++) {
CParamMapCommand::AdcMapping* pMap = myMap[i];
int moduleType = pMap->type;
CModuleUnpacker* pUnpacker = m_unpackers[moduleType];
offset = (*pUnpacker)(rEvent, event, offset, pMap);
}
// Burn up any remaining 0xfff's at the end of the event:
while(offset < event.size()) {
if (event[offset] == 0xffff) {
offset++;
}
else {
break;
}
}
// Something went wrong if we didn't burn up the entire event:
if (offset != event.size()) {
cerr << "**WARNING** Event not entirely decoded by unpackers\n";
cerr << " Event will not be histogrammed, proceeding with next event\n";
return kfFALSE;
}
return kfTRUE;
}
//////////////////////////////////////////////////////////////////////////////////
// Utilties
/*
Assemble an event from the VMUSB event fragments. While we're at it,
extract the stack id and return it to the caller.
*/
CStackUnpacker::StackInfo
CStackUnpacker::assembleEvent(TranslatorPointer<UShort_t>&p,
vector<uint16_t>& event)
{
StackInfo result;
bool done = false;
int stackId = -1;
size_t totalSize = 0;
while(!done) {
// Decode the header:
uint16_t header = *p; ++p;
done = (header & VMUSB_CONTINUE) == 0;
int fragmentSize = header & VMUSB_LENGTH;
totalSize++; // headers are a word of size...
// only pull the stackid out of the first header (just in case).
if (stackId < 0) {
stackId = (header & VMUSB_STACKID_MASK) >> VMUSB_STACKID_SHIFT;
}
// Append the fragment to the event vector
for (int i=0; i < fragmentSize; i++) {
uint16_t datum = *p; ++p;
event.push_back(datum);
}
totalSize += fragmentSize; // Words in the fragment...
}
result.s_stackNumber = stackId;
result.s_stackSize = totalSize;
return result;
}