ROOTANA
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 
17 static uint8_t getUint8(const void* ptr, int offset)
18 {
19  return *(uint8_t*)(((char*)ptr)+offset);
20 }
21 
22 static 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 
28 static 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
35 static 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 
47 void 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 
134 int Alpha16Packet::PacketType(const void*ptr, int bklen8)
135 {
136  return getUint8(ptr, 0);
137 }
138 
139 int Alpha16Packet::PacketVersion(const void*ptr, int bklen8)
140 {
141  return getUint8(ptr, 1);
142 }
143 
144 uint32_t Alpha16Packet::PacketTimestamp(const void*ptr, int bklen8)
145 {
146  return getUint32(ptr, 18);
147 }
148 
149 int 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 
174 void 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 
232 void Alpha16EVB::Configure(int runno)
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
287 void 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
298 bool 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 };
305 static const int chanmap_top[] = { 7, 15, 6, 14, 5, 13, 4, 12, 3, 11, 2, 10, 1, 9, 0, 8 };
306 static const int chanmap_bot[] = { 8, 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7 };
307 
308 void 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 
376 const 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
439 Alpha16Event* 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
471 Alpha16Event* 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
int length
Definition: Alpha16.h:30
int nsamples
Definition: Alpha16.h:28
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
int xcrc16
Definition: Alpha16.h:31
int moduleId
Definition: Alpha16.h:25
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
int checksum
Definition: Alpha16.h:29