ROOTANA
Loading...
Searching...
No Matches
Alpha16.cxx
Go to the documentation of this file.
1//
2// ALPHA-g TPC
3//
4// GRIF-16/ALPHA-16 ADC functions
5//
6// Class functions for Alpha16.h
7//
8
9#include "Alpha16.h"
10
11#include <stdio.h>
12#include <string.h>
13#include <assert.h>
14
15#define MEMZERO(array) memset((array),0,sizeof(array))
16
17static uint8_t getUint8(const void* ptr, int offset)
18{
19 return *(uint8_t*)(((char*)ptr)+offset);
20}
21
22static uint16_t getUint16(const void* ptr, int offset)
23{
24 uint8_t *ptr8 = (uint8_t*)(((char*)ptr)+offset);
25 return ((ptr8[0]<<8) | ptr8[1]);
26}
27
28static uint32_t getUint32(const void* ptr, int offset)
29{
30 uint8_t *ptr8 = (uint8_t*)(((char*)ptr)+offset);
31 return (ptr8[0]<<24) | (ptr8[1]<<16) | (ptr8[2]<<8) | ptr8[3];
32}
33
34// CRC16 from http://stackoverflow.com/questions/10564491/function-to-calculate-a-crc16-checksum
35static unsigned short crc16(const unsigned char* data_p, unsigned char length){
36 unsigned char x;
37 unsigned short crc = 0xFFFF;
38
39 while (length--){
40 x = crc >> 8 ^ *data_p++;
41 x ^= x>>4;
42 crc = (crc << 8) ^ ((unsigned short)(x << 12)) ^ ((unsigned short)(x <<5)) ^ ((unsigned short)x);
43 }
44 return crc;
45}
46
47void Alpha16Packet::Unpack(const void*ptr, int bklen8)
48{
49 /*
50 ALPHA16 UDP packet data format from Bryerton: this is packet version 1:
51
52 Date: Mon, 20 Jun 2016 15:07:08 -0700
53 From bryerton@triumf.ca Mon Jun 20 15:07:05 2016
54 From: Bryerton Shaw <bryerton@triumf.ca>
55 To: Konstantin Olchanski <olchansk@triumf.ca>
56 Subject: Re: eta on udp data?
57
58 Hi Konstantin,
59
60 Just trying to iron out one last bug, it was (is?) locking up if I
61 saturated the link, but I think I just resolved that! So we ve got all
62 16 channels outputting pretty steadily up to 40kHz or so, if I reduce
63 it to 3 channels, we can get 150+ kHz event rates per channel.
64
65 I am going to add a checksum onto the packet structure but it looks as
66 follows, broken down by BYTE offset
67
68 0 Packet Type - Currently fixed at0x01
69 1 Packet Version - Currently fixed at0x01
70 2 Accepted Trigger MSB - Inside the firmware logic Accepted Trigger is unsigned 32bits, providing the lower 16bits here for useful as a dropped UDP packet check
71 3 Accepted Trigger LSB
72 4 MSB Hardware ID - Currently the lower 48 bits of the ArriaV ChipID. It will be the MAC address shortly however
73 5 "" ""
74 6 "" ""
75 7 "" ""
76 8 "" ""
77 9 LSB Hardware ID
78 10 Build Timestamp (UNIX timestamp, aka seconds since Jan 01, 1980 UTC)
79 11 "" ""
80 12 "" ""
81 13 "" ""
82 14 0x00
83 15 0x00
84 16 MSB Event Timestamp
85 17 "" ""
86 18 "" ""
87 19 "" ""
88 20 "" ""
89 21 LSB Event Timestamp
90 22 MSB Trigger Offset - Trigger Point in relation to the start of the waveform packet. Signed 32bit integer
91 23
92 24
93 25 LSB Trigger Offset
94 26 ModuleID - Logical Identifier for the Alpha16 board. unsigned byte
95 27 [7] Channel Type - Either 0 or 1, for BScint or Anode. The MSB of this byte
96 27 [6:0] Channel ID - Unsigned 7bits, identifies the ADC channel (0-15) used
97 28 MSB Sample Count - Unsigned 16 bit value indicating the number of samples (1-N)
98 29 LSB Sample Count
99 30 MSB First Waveform Sample - Signed 16 bit value
100 31 LSB First Waveform Sample
101 ....
102 30 + (SampleCount*2) MSB Checksum
103 31 + (SampleCount*2) LSB Checksum
104
105 I will give you the checksum details in a moment, I am just adding it in
106 now. Most likely will be a crc16 based on 1+x^2+x^15+x^16 .
107 The byte positions may not be ideal, but we can sort that out.
108
109 Cheers,
110
111 Bryerton
112 */
113
114 bankLength = bklen8;
115 packetType = getUint8(ptr, 0);
116 packetVersion = getUint8(ptr, 1);
117 acceptedTrigger = getUint16(ptr, 2);
118 hardwareId = getUint32(ptr, 4);
119 buildTimestamp = getUint32(ptr, 10);
120 //int zero = getUint16(ptr, 14);
121 eventTimestamp = getUint32(ptr, 18);
122 triggerOffset = getUint32(ptr, 22);
123 moduleId = getUint8(ptr, 26);
124 int chanX = getUint8(ptr, 27);
125 channelType = chanX & 0x80;
126 channelId = chanX & 0x7F;
127 nsamples = getUint16(ptr, 28);
128 checksum = getUint16(ptr, 30 + nsamples*2);
129 length = 32 + nsamples*2;
130
131 xcrc16 = crc16((const unsigned char*)ptr, 32 + nsamples*2);
132}
133
134int Alpha16Packet::PacketType(const void*ptr, int bklen8)
135{
136 return getUint8(ptr, 0);
137}
138
139int Alpha16Packet::PacketVersion(const void*ptr, int bklen8)
140{
141 return getUint8(ptr, 1);
142}
143
144uint32_t Alpha16Packet::PacketTimestamp(const void*ptr, int bklen8)
145{
146 return getUint32(ptr, 18);
147}
148
149int Alpha16Packet::PacketChannel(const void*ptr, int bklen8)
150{
151 int chanX = getUint8(ptr, 27);
152 //int channelType = chanX & 0x80;
153 int channelId = chanX & 0x7F;
154 return channelId;
155}
156
158{
159 printf("ALPHA16 data packet:\n");
160 printf(" packet type: 0x%02x (%d)\n", packetType, packetType);
161 printf(" packet version: 0x%02x (%d)\n", packetVersion, packetVersion);
162 printf(" hwid: 0x%08x\n", hardwareId);
163 printf(" buildts: 0x%08x\n", buildTimestamp);
164 printf(" mod id: 0x%02x\n", moduleId);
165 printf(" trig no: 0x%04x (%d)\n", acceptedTrigger, acceptedTrigger);
166 printf(" event ts: 0x%08x (%d)\n", eventTimestamp, eventTimestamp);
167 printf(" trig offset: %d\n", triggerOffset);
168 printf(" channel: type: %d, id: %d\n", channelType, channelId);
169 printf(" nsamples: %d\n", nsamples);
170 printf(" checksum: 0x%04x, computed checksum 0x%04x\n", checksum, xcrc16);
171 printf("length: %d, bank length %d\n", length, bankLength);
172};
173
174void Alpha16Waveform::Unpack(const void* bkptr, int bklen8)
175{
176 int nsamples = getUint16(bkptr, 28);
177
178 this->reserve(nsamples);
179 this->clear();
180
181 //printf("Unpacking: "); Print();
182 for (int i=0; i<nsamples; i++) {
183 int16_t v = getUint16(bkptr, 30 + i*2);
184 //printf("sample %d: 0x%02x (%d)\n", i, v, v);
185 this->push_back(v);
186 }
187};
188
190{
191 Reset();
192}
193
195{
196 eventNo = 0;
197 eventTime = 0;
198 prevEventTime = 0;
201 numChan = 0;
202 error = false;
203 complete = false;
204}
205
207{
208}
209
211{
212 printf("ALPHA16 event: %d, time %.0f (incr %.0f), channels: %d, error %d, complete %d\n", eventNo, eventTime, eventTime - prevEventTime, numChan, error, complete);
213}
214
216{
217 Reset();
218}
219
221{
222 //printf("Alpha16EVB::Reset!\n");
223 fEventCount = 0;
224 fHaveEventTs = false;
226 fLastEventTs = 0;
227 fConfModMap.clear();
228 fConfNumChan = 0;
229 fConfNumSamples = 0;
230}
231
233{
234 const int modmap[][20] = {
235 { 269, 1, 2, 3, 4, 5, 6, 7, 8, 0 },
236 { 264, 1, 2, 3, 4, -5, -6, -7, -8, 0 },
237 { 257, 1, 2, 3, 4, -18, -6, -7, -8, 9, 10, 11, 12, 17, 14, 15, 16, 0 },
238 { 245, 1, 2, 3, 4, -19, -6, -7, -8, 9, 10, 11, 12, 18, 14, 15, 16, 0 },
239 { 238, 1, 2, 9, 4, -10, -6, -14, -19, 0 },
240 { 227, 14, 19, 9, 4, -10, -6, -7, -8, 0 },
241 { 220, 1, 2, 9, 4, -10, -6, -7, -8, 0 },
242 { 218, 1, 2, 8, 4, -9, -10, -11, -12, 0 },
243 { 194, 1, 2, 13, 4, -9, -10, -11, -12, 0 },
244 { 186, 1, 2, 12, 4, -10, -15, -17, -18, 0 },
245 { 184, -9, -12, -4, -11, -10, -15, -17, -18, 0 },
246 { 183, -9, -12, -4, -11, -14, -10, -15, -18, 0 },
247 { 180, -9, -12, -4, -7, -8, -10, -15, -16, 0 },
248 { 177, 9, 12, 4, 7, 8, 10, 15, 16, 0 },
249 { 173, 9, 12, 4, 6, 8, 10, 15, 16, 0 },
250 { 171, 9, 12, 4, 19, 8, 10, 15, 16, 0 },
251 { 158, 1, 2, 4, 7, -8, -10, -15, -16, 0 },
252 { 154, -1, -2, -4, -7, -8, -10, -15, -16, 0 },
253 { 151, 1, 2, 4, 7, 8, 10, 15, 16, 0 },
254 { 147, 1, 2, 3, 4, 6, 7, 8, 16, 0 },
255 { 140, 4, 10, 13, 15, 1, 16, 17, 2, 0 },
256 { 0 }
257 };
258
259 // ensure modmap is sorted by run number in descending order
260
261 for (int i=0; modmap[i][0] != 0; i++) {
262 assert(modmap[i][0] > modmap[i+1][0]);
263 }
264
265 int imap = -1;
266
267 for (int i=0; modmap[i][0] != 0; i++) {
268 if (runno >= modmap[i][0]) {
269 imap = i;
270 break;
271 }
272 }
273
274 assert(imap >= 0);
275
276 printf("Alpha16EVB::Configure: for run %d found map index %d for run %d\n", runno, imap, modmap[imap][0]);
277
278 fConfModMap.clear();
279 for (int j=1; modmap[imap][j] != 0; j++) {
280 fConfModMap.push_back(modmap[imap][j]);
281 }
282
284}
285
286#if 0
287void Alpha16EVB::Print() const
288{
289 printf("EVB contents:\n");
290 for (unsigned i=0; i<fEvents.size(); i++) {
291 printf("Entry %d: ", i);
292 fEvents[i]->Print();
293 }
294}
295#endif
296
297#if 0
298bool Alpha16EVB::Match(const Alpha16Event* e, int imodule, uint32_t udpTs)
299{
300 return (e->udpEventTs[imodule] == udpTs);
301}
302#endif
303
304//static const int chanmap_top[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
305static const int chanmap_top[] = { 7, 15, 6, 14, 5, 13, 4, 12, 3, 11, 2, 10, 1, 9, 0, 8 };
306static const int chanmap_bot[] = { 8, 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7 };
307
308void Alpha16EVB::AddBank(Alpha16Event* e, int xmodule, const void* bkptr, int bklen)
309{
310 int ymodule = -1;
311 int top_bot = 0;
312
313 for (unsigned x=0; x<fConfModMap.size(); x++)
314 if (fConfModMap[x] == xmodule) {
315 ymodule = x;
316 top_bot = 1;
317 break;
318 } else if (fConfModMap[x] == -xmodule) {
319 ymodule = x;
320 top_bot = -1;
321 break;
322 }
323
324 if (ymodule < 0)
325 return;
326
327 int xchan = Alpha16Packet::PacketChannel(bkptr, bklen);
328
329 if (xchan<0 || xchan >= NUM_CHAN_ALPHA16) {
330 // invalid channel number
331 e->error = true;
332 return;
333 }
334
335 int ychan = -1;
336
337 if (top_bot < 0)
338 for (int i=0; i<16; i++)
339 if (chanmap_bot[i] == xchan) {
340 ychan = i;
341 break;
342 }
343
344 if (top_bot > 0)
345 for (int i=0; i<16; i++)
346 if (chanmap_top[i] == xchan) {
347 ychan = i;
348 break;
349 }
350
351 assert(ychan>=0);
352
353 int chan = ymodule*NUM_CHAN_ALPHA16 + ychan;
354
355 if (e->udpPresent[chan]) {
356 // duplicate udp packet
357 e->error = true;
358 return;
359 }
360
361 e->udpPacket[chan].Unpack(bkptr, bklen);
362 e->waveform[chan].Unpack(bkptr, bklen);
363 e->udpPresent[chan] = true;
364 e->udpEventTs[chan] = e->udpPacket[chan].eventTimestamp;
365 e->numChan++;
366}
367
369{
370 Alpha16Event *e = new Alpha16Event();
371 fEventCount++;
372 e->eventNo = fEventCount;
373 return e;
374}
375
376const double TSCLK = 0.1; // GHz
377
379{
380 int count = 0;
381 unsigned num_samples = 0;
382
383 for (int i=0; i<MAX_ALPHA16 * NUM_CHAN_ALPHA16; i++) {
384 if (e->udpPresent[i]) {
385 count++;
386 if (num_samples == 0)
387 num_samples = e->waveform[i].size();
388 if (e->waveform[i].size() != num_samples) {
389 // wrong number of ADC samples
390 e->error = true;
391 }
392 }
393 }
394
395 if (fConfNumSamples == 0)
396 fConfNumSamples = num_samples;
397
398 if ((int)num_samples != fConfNumSamples) {
399 // wrong number of ADC samples
400 e->error = true;
401 }
402
403 if ((count == fConfNumChan) && (e->numChan == fConfNumChan)) {
404 e->complete = true;
405 }
406
407 if (!fHaveEventTs && e->complete) {
408 fHaveEventTs = true;
409 // set timestamp offsets from the first complete event
410 for (int i=0; i<MAX_ALPHA16 * NUM_CHAN_ALPHA16; i++) {
411 if (e->udpPresent[i]) {
412 fFirstEventTs[i] = e->udpEventTs[i];
413 printf("XXX %d -> 0x%08x\n", i, fFirstEventTs[i]);
414 }
415 }
416 }
417
418 if (fHaveEventTs && e->complete) {
419 uint32_t ets = 0;
420 // check timestamps
421 for (int i=0; i<MAX_ALPHA16 * NUM_CHAN_ALPHA16; i++) {
422 if (e->udpPresent[i]) {
423 uint32_t ts = e->udpEventTs[i] - fFirstEventTs[i];
424 if (ets == 0)
425 ets = ts;
426 if (ts != ets && ts != ets+1 && ts+1 != ets) {
427 printf("ts mismatch %d: 0x%08x vs 0x%08x diff %d\n", i, ts, ets, ts-ets);
428 e->error = true;
429 }
430 }
431 }
432 e->eventTime = ets/TSCLK;
434 fLastEventTs = ets;
435 }
436}
437
438#if 0
439Alpha16Event* Alpha16EVB::FindEvent(int imodule, uint32_t udpTs)
440{
441 // loop over buffered events, look for match
442
443 for (unsigned i=0; i<fEvents.size(); i++) {
444 if (Match(fEvents[i], imodule, udpTs)) {
445 return fEvents[i];
446 }
447 }
448
449 Alpha16Event *e = new Alpha16Event();
450 fEventCount++;
451 e->eventNo = fEventCount;
452 e->udpEventTs[imodule] = udpTs;
453 if (fFirstEventTs[imodule] == 0) {
454 fFirstEventTs[imodule] = udpTs;
455 fLastEventTs[imodule] = fFirstEventTs[imodule];
456 }
457 e->eventTs = udpTs - fFirstEventTs[imodule];
458 e->prevEventTs = fLastEventTs[imodule] - fFirstEventTs[imodule];
459
460 fLastEventTs[imodule] = udpTs;
461
462 //printf("Event %d ts 0x%08x: new!\n", e->eventNo, e->eventTs);
463
464 fEvents.push_front(e);
465
466 return e;
467}
468#endif
469
470#if 0
471Alpha16Event* Alpha16EVB::GetNextEvent()
472{
473 if (fEvents.size() < 1)
474 return NULL;
475
476 Alpha16Event* e = fEvents.back();
477
478 if (e->complete || fEvents.size() > 10) {
479 fEvents.pop_back();
480 return e;
481 }
482
483 return NULL;
484}
485#endif
486
487/* emacs
488 * Local Variables:
489 * tab-width: 8
490 * c-basic-offset: 3
491 * indent-tabs-mode: nil
492 * End:
493 */
static uint8_t getUint8(const void *ptr, int offset)
Definition Alpha16.cxx:17
static uint16_t getUint16(const void *ptr, int offset)
Definition Alpha16.cxx:22
static unsigned short crc16(const unsigned char *data_p, unsigned char length)
Definition Alpha16.cxx:35
static uint32_t getUint32(const void *ptr, int offset)
Definition Alpha16.cxx:28
static const int chanmap_bot[]
Definition Alpha16.cxx:306
#define MEMZERO(array)
Definition Alpha16.cxx:15
static const int chanmap_top[]
Definition Alpha16.cxx:305
const double TSCLK
Definition Alpha16.cxx:376
#define MAX_ALPHA16
Definition Alpha16.h:50
#define NUM_CHAN_ALPHA16
Definition Alpha16.h:51
void Unpack(const void *bkptr, int bklen8)
Definition Alpha16.cxx:174
void CheckEvent(Alpha16Event *e)
Definition Alpha16.cxx:378
Alpha16Event * NewEvent()
Definition Alpha16.cxx:368
void Reset()
Definition Alpha16.cxx:220
int fEventCount
Definition Alpha16.h:79
uint32_t fLastEventTs
Definition Alpha16.h:84
void Configure(int runno)
Definition Alpha16.cxx:232
int fConfNumChan
Definition Alpha16.h:86
uint32_t fFirstEventTs[MAX_ALPHA16 *NUM_CHAN_ALPHA16]
Definition Alpha16.h:82
bool fHaveEventTs
Definition Alpha16.h:81
void AddBank(Alpha16Event *e, int imodule, const void *bkptr, int bklen)
Definition Alpha16.cxx:308
std::vector< int > fConfModMap
Definition Alpha16.h:89
int fConfNumSamples
Definition Alpha16.h:87
uint32_t udpEventTs[MAX_ALPHA16 *NUM_CHAN_ALPHA16]
Definition Alpha16.h:60
int eventNo
Definition Alpha16.h:55
bool udpPresent[MAX_ALPHA16 *NUM_CHAN_ALPHA16]
Definition Alpha16.h:59
void Reset()
Definition Alpha16.cxx:194
Alpha16Packet udpPacket[MAX_ALPHA16 *NUM_CHAN_ALPHA16]
Definition Alpha16.h:62
int numChan
Definition Alpha16.h:65
void Print() const
Definition Alpha16.cxx:210
Alpha16Waveform waveform[MAX_ALPHA16 *NUM_CHAN_ALPHA16]
Definition Alpha16.h:63
double prevEventTime
Definition Alpha16.h:57
double eventTime
Definition Alpha16.h:56
bool complete
Definition Alpha16.h:68
bool error
Definition Alpha16.h:67
int channelType
Definition Alpha16.h:26
int acceptedTrigger
Definition Alpha16.h:20
uint32_t triggerOffset
Definition Alpha16.h:24
static int PacketVersion(const void *ptr, int bklen8)
Definition Alpha16.cxx:139
int packetVersion
Definition Alpha16.h:19
uint32_t buildTimestamp
Definition Alpha16.h:22
static int PacketChannel(const void *ptr, int bklen8)
Definition Alpha16.cxx:149
int channelId
Definition Alpha16.h:27
int packetType
Definition Alpha16.h:18
static uint32_t PacketTimestamp(const void *ptr, int bklen8)
Definition Alpha16.cxx:144
void Unpack(const void *bkptr, int bklen8)
Definition Alpha16.cxx:47
int bankLength
Definition Alpha16.h:17
uint32_t eventTimestamp
Definition Alpha16.h:23
void Print() const
Definition Alpha16.cxx:157
uint32_t hardwareId
Definition Alpha16.h:21
static int PacketType(const void *ptr, int bklen8)
Definition Alpha16.cxx:134