source: trunk/FACT++/src/HeadersFAD.h@ 11279

Last change on this file since 11279 was 11210, checked in by tbretz, 13 years ago
Moved coding and decoding of the 12 bit temperature to the conversion from and to network byte order.
File size: 13.9 KB
Line 
1#ifndef FACT_HeadersFAD
2#define FACT_HeadersFAD
3
4#ifdef __cplusplus
5#include <ostream>
6
7// For debugging
8#include <iostream>
9
10#include "ByteOrder.h"
11
12// ====================================================================
13
14namespace FAD
15{
16#endif
17 enum Enable
18 {
19 kCmdDrsEnable = 0x0600, // CMD_DENABLE/CMD_DISABLE
20 kCmdDwrite = 0x0800, // CMD_DWRITE_RUN/CMD_DWRITE_STOP
21 kCmdSclk = 0x1000, // CMD_SCLK_ON/OFF
22 kCmdSrclk = 0x1500, // CMD_SRCLK_ON/OFF
23 kCmdTriggerLine = 0x1800, // CMD_TRIGGERS_ON/CMD_TRIGGERS_OFF
24 kCmdContTrigger = 0x1f00,
25 kCmdRun = 0x2200, // CMD_Start/Stop
26 kCmdBusy = 0x2400, //
27 kCmdResetTriggerId = 0x2A00, //
28 kCmdSocket = 0x3000, // CMD_mode_command/CMD_mode_all_sockets
29 kCmdSingleTrigger = 0xA000, // CMD_Trigger
30 };
31
32 enum Commands
33 {
34 kCmdWriteExecute = 0x0400, // Configure FAD with the current config ram
35
36 kCmdWrite = 0x0500, // write to Config-RAM
37 kCmdWriteRoi = kCmdWrite|0x00, // Baseaddress ROI-Values
38 kCmdWriteDac = kCmdWrite|0x24, // Baseaddress DAC-Values
39
40 kCmdWriteRate = kCmdWrite|0x2c, // Continous trigger rate
41 kCmdWriteRunNumberMSW = kCmdWrite|0x2d, // Run Number most significant word
42 kCmdWriteRunNumberLSW = kCmdWrite|0x2e, // Run Number least significant word
43
44 /*
45 kCmdRead = 0x0a00, // read from Config-RAM
46 kCmdReadRoi = kCmdRead|0x00, // Baseaddress ROI-Values
47 kCmdReadDac = kCmdRead|0x24, // Baseaddress DAC-Values
48 */
49
50 kCmdPhaseIncrease = 0x1200, // CMD_PS_DIRINC
51 kCmdPhaseDecrease = 0x1300, // CMD_PS_DIRDEC
52 kCmdPhaseApply = 0x1400, // CMD_PS_DO
53 kCmdPhaseReset = 0x1700, // CMD_PS_RESET
54 };
55
56 enum States
57 {
58 // State Machine states
59 kOffline = 1,
60 kDisconnected,
61 kConnecting,
62 kConnected
63 };
64
65 enum
66 {
67 kMaxBins = 1024,
68 kNumTemp = 4,
69 kNumDac = 8,
70 kNumChips = 4,
71 kNumChannelsPerChip = 9,
72 kNumChannels = kNumChips*kNumChannelsPerChip,
73 };
74
75 enum
76 {
77 kMaxRegAddr = 0xff, // Highest address in config-ram
78 kMaxRegValue = 0xffff,
79 kMaxDacAddr = kNumDac-1,
80 kMaxDacValue = 0xffff,
81 kMaxRoiAddr = kNumChannels-1,
82 kMaxRoiValue = kMaxBins,
83 kMaxRunNumber = 0xffffffff,
84 };
85
86 enum
87 {
88 kDelimiterStart = 0xfb01,
89 kDelimiterEnd = 0x04fe,
90 };
91
92 // --------------------------------------------------------
93
94 struct EventHeader
95 {
96#ifdef __cplusplus
97 enum Bits
98 {
99 kDenable = 1<<11,
100 kDwrite = 1<<10,
101 //kRefClkTooHigh = 1<< 9,
102 kRefClkTooLow = 1<< 8,
103 kDcmLocked = 1<< 7,
104 kDcmReady = 1<< 6,
105 kSpiSclk = 1<< 5,
106 kBusy = 1<< 4, // Busy enabled
107 kTriggerLine = 1<< 3, // Trigger line enabled
108 kContTrigger = 1<< 2, // Cont trigger enabled
109 kSock17 = 1<< 1, // Socket 1-7 for data transfer
110 };
111#endif
112 // Einmalig: (new header changes entry in array --> send only if array changed)
113 // ----------------------------------
114 // Event builder stores an array with all available values.
115 // Disconnected boards are removed (replaced by def values)
116 // Any received header information is immediately put in the array.
117 // The array is transmitted whenever it changes.
118 // This will usually happen only very rarely when a new connection
119 // is opened.
120 //
121 // Array[40] of BoardId
122 // Array[40] of Version
123 // Array[40] of DNA
124
125 // Slow changes: (new header changes entry in array --> send only if arra changed)
126 // -------------------------------------------
127 // Event builder stores an array with all available values.
128 // Disconnected boards can be kept in the arrays.
129 // Any received header information is immediately put in the array.
130 // The array is transmitted whenever it changes.
131 //
132 // Connection status (disconnected, connecting, connected) / Array[40]
133 // Consistency of PLLLCK / Array[ 40] of PLLLCK
134 // Consistency of Trigger type / Array[ 40] of trigger type
135 // Consistency of ROI / Array[1440] of ROI
136 // Consistency of RefClock / Array[ 40] of ref clock
137 // Consistency of DAC values / Array[ 400] of DAC values
138 // Consistency of run number / Array[ 40] of Run numbers
139
140 // Fast changes (new header changes value --> send only if something changed)
141 // -------------------
142 // Event builder stores an internal array of all boards and
143 // transmits the min/max values determined from the array
144 // only if they have changed. Disconnected boards are not considered.
145 //
146 // Maximum/minimum Event counter of all boards in memory + board id
147 // Maximum/minimum time stamp of all boards in memory + board id
148 // Maximum/minimum temp of all boards in memory + board id
149
150 // Unknown:
151 // ------------------
152 // Trigger Id ?
153 // TriggerGeneratorPrescaler ?
154 // Number of Triggers to generate ?
155
156
157 // ------------------------------------------------------------
158
159 uint16_t fStartDelimiter; // 0x04FE
160 uint16_t fPackageLength;
161 uint16_t fVersion;
162 uint16_t fStatus;
163 //
164 uint16_t fTriggerCrc; // Receiver timeout / CRC ; 1 byte each
165 uint16_t fTriggerType;
166 uint32_t fTriggerId;
167 //
168 uint32_t fEventCounter;
169 uint32_t fFreqRefClock;
170 //
171 uint16_t fBoardId;
172 uint16_t fAdcClockPhaseShift;
173 uint16_t fNumTriggersToGenerate;
174 uint16_t fTriggerGeneratorPrescaler;
175 //
176 uint64_t fDNA; // Xilinx DNA
177 //
178 uint32_t fTimeStamp;
179 uint32_t fRunNumber;
180 //
181 int16_t fTempDrs[kNumTemp]; // In units of 1/16 deg(?)
182 //
183 uint16_t fDac[kNumDac];
184 //
185#ifdef __cplusplus
186 EventHeader() { init(*this); }
187 EventHeader(const uint16_t *ptr)
188 {
189 *this = std::vector<uint16_t>(ptr, ptr+sizeof(EventHeader)/2);
190 }
191
192 void operator=(const std::vector<uint16_t> &vec)
193 {
194 ntohcpy(vec, *this);
195
196 Reverse(((uint16_t*)fEventCounter));
197 Reverse(((uint16_t*)fEventCounter)+1);
198
199 Reverse(&fEventCounter);
200
201 Reverse(((uint16_t*)fTriggerId));
202 Reverse(((uint16_t*)fTriggerId)+1);
203
204 Reverse(&fTriggerId);
205
206 Reverse(((uint16_t*)fFreqRefClock));
207 Reverse(((uint16_t*)fFreqRefClock)+1);
208
209 Reverse(&fFreqRefClock);
210
211 Reverse(((uint16_t*)&fTimeStamp));
212 Reverse(((uint16_t*)&fTimeStamp)+1);
213
214 Reverse(&fTimeStamp);
215
216 Reverse(((uint16_t*)&fRunNumber));
217 Reverse(((uint16_t*)&fRunNumber)+1);
218
219 Reverse(&fRunNumber);
220 Reverse(&fDNA);
221
222 for (int i=0; i<kNumTemp; i++)
223 {
224 fTempDrs[i] =
225 (fTempDrs[i]&0x8000) ?
226 ((fTempDrs[i]&0x007fff)^0xffffffff) :
227 (fTempDrs[i]&0x007fff);
228 fTempDrs[i]>>=3;
229 }
230
231 }
232
233 std::vector<uint16_t> HtoN() const
234 {
235 EventHeader h(*this);
236
237 Reverse(((uint16_t*)h.fEventCounter));
238 Reverse(((uint16_t*)h.fEventCounter)+1);
239
240 Reverse(&h.fEventCounter);
241
242 Reverse(((uint16_t*)h.fFreqRefClock));
243 Reverse(((uint16_t*)h.fFreqRefClock)+1);
244
245 Reverse(&h.fFreqRefClock);
246
247 Reverse(((uint16_t*)&h.fTimeStamp));
248 Reverse(((uint16_t*)&h.fTimeStamp)+1);
249
250 Reverse(&h.fTimeStamp);
251
252 Reverse(((uint16_t*)&h.fRunNumber));
253 Reverse(((uint16_t*)&h.fRunNumber)+1);
254
255 Reverse(&h.fRunNumber);
256 Reverse(&h.fDNA);
257
258 for (int i=0; i<kNumTemp; i++)
259 {
260 h.fTempDrs[i] <<= 3;
261 h.fTempDrs[i] = ((h.fTempDrs[i]&0x800000) ?
262 (((h.fTempDrs[i]^0xffffffff)&0x007fff)|0x8000) :
263 (h.fTempDrs[i]&0x007fff));
264 }
265
266 return htoncpy(h);
267 }
268
269 float GetTemp(int i) const { return fTempDrs[i]/16.; }
270
271 /*
272 float GetTemp(int i) const
273 {
274 return (((fTempDrs[i]&0x8000) ?
275 ((fTempDrs[i]&0x007fff)^0xffffffff)
276 : (fTempDrs[i]&0x007fff))>>3)/16.; }*/
277
278 uint8_t PLLLCK() const { return fStatus>>12; }
279
280 bool HasDenable() const { return fStatus&kDenable; }
281 bool HasDwrite() const { return fStatus&kDwrite; }
282// bool IsRefClockTooHigh() const { return fStatus&kRefClkTooHigh; }
283 bool IsRefClockTooLow() const { return fStatus&kRefClkTooLow; }
284 bool IsDcmLocked() const { return fStatus&kDcmLocked; }
285 bool IsDcmReady() const { return fStatus&kDcmReady; }
286 bool HasSpiSclk() const { return fStatus&kSpiSclk; }
287 bool HasBusy() const { return fStatus&kBusy; }
288 bool HasTriggerEnabled() const { return fStatus&kTriggerLine; }
289 bool HasContTriggerEnabled() const { return fStatus&kContTrigger; }
290 bool IsInSock17Mode() const { return fStatus&kSock17; }
291
292 uint16_t Crate() const { return fBoardId>>8; }
293 uint16_t Board() const { return fBoardId&0xff; }
294
295 uint16_t Id() const { return Crate()*10+Board(); }
296
297 void Enable(Bits pos, bool enable=true)
298 {
299 if (enable)
300 fStatus |= pos;
301 else
302 fStatus &= ~pos;
303 }
304
305 void clear() { reset(*this); }
306 void print(std::ostream &out) const;
307#endif
308
309 } __attribute__((__packed__));
310
311 struct ChannelHeader
312 {
313 uint16_t fId;
314 uint16_t fStartCell;
315 uint16_t fRegionOfInterest;
316 uint16_t fDummy;
317 // uint16_t fData[];
318
319#ifdef __cplusplus
320 ChannelHeader() { init(*this); }
321
322 void operator=(const std::vector<uint16_t> &vec)
323 {
324 ntohcpy(vec, *this);
325 }
326
327 std::vector<uint16_t> HtoN() const
328 {
329 ChannelHeader h(*this);
330 return htoncpy(h);
331 }
332
333 void clear() { reset(*this); }
334 void print(std::ostream &out) const;
335
336 uint16_t Chip() const { return fId>>4; }
337 uint16_t Channel() const { return fId&0xf; }
338#endif
339 } __attribute__((__packed__));
340
341 // Package ends with:
342 // 0x4242
343 // 0x04fe
344/*
345 struct DimPassport
346 {
347 uint32_t fTimeStamp;
348
349 uint16_t fVersion;
350 uint16_t fBoardId;
351 uint64_t fDNA; // Xilinx DNA
352
353 DimPassport(const EventHeader &h) :
354 fTimeStamp(h.fTimeStamp),
355 fVersion(h.fVersion),
356 fBoardId(h.fBoardId),
357 fDNA(h.fDNA)
358 {
359 }
360
361 } __attribute__((__packed__));
362
363 struct DimSetup
364 {
365 uint32_t fTimeStamp;
366
367 uint32_t fFreqRefClock;
368 uint16_t fStatus;
369 uint16_t fAdcClockPhaseShift;
370 uint16_t fNumTriggersToGenerate;
371 uint16_t fTriggerGeneratorPrescaler;
372 uint16_t fDac[kNumDac];
373
374 DimSetup(const EventHeader &h) :
375 fTimeStamp(h.fTimeStamp),
376 fFreqRefClock(h.fFreqRefClock),
377 fStatus(h.fStatus),
378 fAdcClockPhaseShift(h.fAdcClockPhaseShift),
379 fNumTriggersToGenerate(h.fNumTriggersToGenerate),
380 fTriggerGeneratorPrescaler(h.fTriggerGeneratorPrescaler)
381 {
382 memcpy(fDac, h.fDac, sizeof(fDac));
383 }
384
385 uint8_t PLLLCK() const { return fStatus>>12; }
386
387 bool HasDenable() const { return fStatus&EventHeader::kDenable; }
388 bool HasDwrite() const { return fStatus&EventHeader::kDwrite; }
389 bool IsRefClockTooHigh() const { return fStatus&EventHeader::kRefClkTooHigh; }
390 bool IsRefClockTooLow() const { return fStatus&EventHeader::kRefClkTooLow; }
391 bool IsDcmLocked() const { return fStatus&EventHeader::kDcmLocked; }
392 bool IsDcmReady() const { return fStatus&EventHeader::kDcmReady; }
393 bool HasSpiSclk() const { return fStatus&EventHeader::kSpiSclk; }
394
395 } __attribute__((__packed__));
396
397 struct DimTemperatures
398 {
399 uint32_t fTimeStamp;
400
401 float fTempDrs[kNumTemp];
402
403 DimTemperatures(const EventHeader &h) :
404 fTimeStamp(h.fTimeStamp)
405 {
406 for (int i=0; i<kNumTemp; i++)
407 fTempDrs[i] = h.GetTemp(i);
408 }
409
410 } __attribute__((__packed__));;
411
412 struct DimEventHeader
413 {
414 uint32_t fTimeStamp;
415
416 uint32_t fRunNumber;
417 uint32_t fEventCounter;
418 uint16_t fTriggerCrc;
419 uint16_t fTriggerType;
420 uint32_t fTriggerId;
421
422 DimEventHeader(const EventHeader &h) :
423 fTimeStamp(h.fTimeStamp),
424 fRunNumber(h.fRunNumber),
425 fEventCounter(h.fEventCounter),
426 fTriggerCrc(h.fTriggerCrc),
427 fTriggerType(h.fTriggerType),
428 fTriggerId(h.fTriggerId)
429 {
430 }
431
432 } __attribute__((__packed__));
433*/
434 // --------------------------------------------------------------------
435#ifdef __cplusplus
436 inline std::ostream &operator<<(std::ostream &out, const EventHeader &h)
437 {
438 h.print(out);
439 return out;
440 }
441
442 inline std::ostream &operator<<(std::ostream &out, const ChannelHeader &h)
443 {
444 h.print(out);
445 return out;
446 }
447#endif
448
449#ifdef __cplusplus
450};
451#endif
452
453#endif
Note: See TracBrowser for help on using the repository browser.