1 | #ifndef FACT_HeadersFPGAFTM
|
---|
2 | #define FACT_HeadersFPGAFTM
|
---|
3 |
|
---|
4 | #include <iosfwd>
|
---|
5 | #include <stdint.h>
|
---|
6 | #include <numeric> // accumulate
|
---|
7 | #include <algorithm>
|
---|
8 |
|
---|
9 | #include "HeadersFTM.h"
|
---|
10 |
|
---|
11 | namespace FPGAFTM
|
---|
12 | {
|
---|
13 | namespace State
|
---|
14 | {
|
---|
15 | /*********** FTM **********
|
---|
16 | enum StateMachine
|
---|
17 | {
|
---|
18 | kDisconnected = 1,
|
---|
19 | kConnected,
|
---|
20 | kIdle,
|
---|
21 | kValid,
|
---|
22 | kTriggerOn,
|
---|
23 | kConfiguring1,
|
---|
24 | kConfiguring2,
|
---|
25 | kConfigured1,
|
---|
26 | kConfigured2,
|
---|
27 |
|
---|
28 | kConfigError1 = 0x101,
|
---|
29 | kConfigError2 = 0x102,
|
---|
30 | //kConfigError3 = 0x103,
|
---|
31 | };
|
---|
32 | */
|
---|
33 |
|
---|
34 | enum states_t
|
---|
35 | {
|
---|
36 | kDisconnected = FTM::State::kDisconnected,
|
---|
37 | kConnected = FTM::State::kConnected,
|
---|
38 | //kIdle
|
---|
39 | kValid = FTM::State::kValid,
|
---|
40 | kTriggerOn = FTM::State::kTriggerOn,
|
---|
41 | kConfiguring = FTM::State::kConfiguring1,
|
---|
42 | //kConfiguring2,
|
---|
43 | kConfigured = FTM::State::kConfigured1,
|
---|
44 | //kConfigured2,
|
---|
45 |
|
---|
46 | //kConfigError1 = 0x101,
|
---|
47 | //kConfigError2 = 0x102,
|
---|
48 | //kConfigError3 = 0x103,
|
---|
49 | };
|
---|
50 | };
|
---|
51 |
|
---|
52 | // ----------------------------------------------------------------------
|
---|
53 |
|
---|
54 | struct BusData
|
---|
55 | {
|
---|
56 | uint16_t fStartBits;
|
---|
57 | uint8_t fReadWrite;
|
---|
58 | uint16_t fCommand;
|
---|
59 | uint64_t fData;
|
---|
60 | uint8_t fCrc;
|
---|
61 | uint16_t fStopBits;
|
---|
62 |
|
---|
63 | BusData(uint8_t rw, uint16_t cmd, uint64_t dat)
|
---|
64 | : fStartBits(0xffff), fReadWrite(rw), fCommand(cmd),
|
---|
65 | fData(dat), fStopBits(0xffff)
|
---|
66 | {
|
---|
67 | fCrc = calcCrc();
|
---|
68 | }
|
---|
69 |
|
---|
70 | uint32_t id() const { return (fReadWrite<<16)|fCommand; }
|
---|
71 |
|
---|
72 | uint8_t calcCrc() const
|
---|
73 | {
|
---|
74 | // FIXME: FIX IN minifrmctrl -- old!
|
---|
75 | return std::accumulate(&fReadWrite, &fReadWrite+11, uint8_t(0));
|
---|
76 | }
|
---|
77 |
|
---|
78 | bool isCrcValid() const
|
---|
79 | {
|
---|
80 | return fCrc == calcCrc();
|
---|
81 | }
|
---|
82 |
|
---|
83 | void print(std::ostream &out) const
|
---|
84 | {
|
---|
85 | out << std::hex;
|
---|
86 | out << Tools::Form("%04x|%02x|%04x|%016lx|%02x|%04x",
|
---|
87 | fStartBits, fReadWrite, fCommand, fData, fCrc, fStopBits);
|
---|
88 | out << std::dec;
|
---|
89 | }
|
---|
90 | } __attribute__((__packed__));
|
---|
91 |
|
---|
92 | inline std::ostream &operator<<(std::ostream &out, const BusData &d)
|
---|
93 | {
|
---|
94 | d.print(out);
|
---|
95 | return out;
|
---|
96 | }
|
---|
97 |
|
---|
98 | enum readwrite_t
|
---|
99 | {
|
---|
100 | kCmdRead = 0x00, // Command: Read
|
---|
101 | kCmdWrite = 0x04, // Command: Write
|
---|
102 | kCmdADM = 0x0e, // Automatic data mode (ADM) package
|
---|
103 | kCmdError = 0xff,
|
---|
104 | };
|
---|
105 |
|
---|
106 | enum trigger_t
|
---|
107 | {
|
---|
108 | kInternal = 0x00,
|
---|
109 | kExternal = 0x01,
|
---|
110 | kShutdown = 0x02,
|
---|
111 | //kRandom = 0x10,
|
---|
112 |
|
---|
113 | kEnable = 0x00,
|
---|
114 | kDisable = 0x01,
|
---|
115 | };
|
---|
116 |
|
---|
117 | enum mask_t
|
---|
118 | {
|
---|
119 | kMaskExtIn = 0x02,
|
---|
120 | kMaskDspIn = 0x04,
|
---|
121 | kMaskExtInDelay = 0x08,
|
---|
122 | kMaskDspInDelay = 0x10,
|
---|
123 | kMaskInternal = 0x20,
|
---|
124 | kMaskButton = 0x40,
|
---|
125 | kMaskSingle = 0x80
|
---|
126 | };
|
---|
127 |
|
---|
128 | enum command_t
|
---|
129 | {
|
---|
130 | kRegProductId = 0x0000, // read only
|
---|
131 | kRegFirmwareId = 0x0100, // read only
|
---|
132 |
|
---|
133 | kClockState = 0x0010,
|
---|
134 | kClockEnable = kClockState|(kEnable<<8),
|
---|
135 | kClockDisable = kClockState|(kDisable<<8),
|
---|
136 | kClockShutdown = kClockState|(kShutdown<<8),
|
---|
137 |
|
---|
138 | kClockFrequency = 0x0011, // 2 byte, 14 bit
|
---|
139 | kClockMeasure = 0x0012, // 2 byte, 14 bit
|
---|
140 |
|
---|
141 | kTimerState = 0x0014, // read/write
|
---|
142 | kTimerEnable = kTimerState|(kEnable<<8),
|
---|
143 | kTimerDisable = kTimerState|(kDisable<<8),
|
---|
144 | kTimerShutdown = kTimerState|(kShutdown<<8),
|
---|
145 |
|
---|
146 | kTimerFrequency = 0x0015,
|
---|
147 | kTimerMeasure = 0x0016,
|
---|
148 |
|
---|
149 | kTriggerState = 0x0020,
|
---|
150 | kTriggerInternal = kTriggerState|(kInternal<<8),
|
---|
151 | kTriggerExternal = kTriggerState|(kExternal<<8),
|
---|
152 | kTriggerShutdown = kTriggerState|(kShutdown<<8),
|
---|
153 | //kTriggerRandom = kTriggerState|(kRandom<<8),
|
---|
154 |
|
---|
155 | kTriggerPeriod = 0x0021,
|
---|
156 | kTriggerSourceMask = 0x0022,
|
---|
157 |
|
---|
158 | /*
|
---|
159 | kTriggerOutState = 0x0024,
|
---|
160 | kTriggerOutInt = kTriggerOutState|(...),
|
---|
161 | kTriggerOutExt = kTriggerOutState|(...),
|
---|
162 | kTriggerOutIntDelayed = kTriggerOutState|(...),
|
---|
163 | kTriggerOutExtDelayed = kTriggerOutState|(...),
|
---|
164 | */
|
---|
165 |
|
---|
166 | kTriggerHoldOff = 0x0025,
|
---|
167 |
|
---|
168 | kTriggerOutSourceMask = 0x0026,
|
---|
169 |
|
---|
170 | kTriggerDspDelay = 0x0028, // 10bit
|
---|
171 | kTriggerExtDelay = 0x0029, // 10bit
|
---|
172 | kTriggerOutDelay = 0x002e, // 10bit
|
---|
173 |
|
---|
174 | kFadResetLo = 0x0030,
|
---|
175 | kFadResetHi = 0x0130,
|
---|
176 |
|
---|
177 | kTriggerInhibitState = 0x0032,
|
---|
178 | kTriggerInhibitEnable = 0x0132,
|
---|
179 | kTriggerInhibitDisable= 0x0032,
|
---|
180 | kTriggerInhibitTime = 0x0033,
|
---|
181 |
|
---|
182 |
|
---|
183 | kADC1 = 0x0040, // read only (2 byte, 10 bit)
|
---|
184 |
|
---|
185 | kRS485Data = 0x0050, // 56 bit (last data sent, but counter increased by 1)
|
---|
186 |
|
---|
187 | kSingleTrigger = 0x005e, // read only
|
---|
188 |
|
---|
189 | kOnTime = 0x0060, // Automatic data transmission
|
---|
190 |
|
---|
191 | kSoftReset = 0x01ff,
|
---|
192 | kHardReset = 0x02ff,
|
---|
193 | };
|
---|
194 |
|
---|
195 | enum error_t
|
---|
196 | {
|
---|
197 | kErrFrameStart = 0xba, // Start bytes wrong
|
---|
198 | kErrFrameStop = 0xbb, // Stop bytes wrong
|
---|
199 | kErrFrameCrc = 0xaa, // Checksum wrong
|
---|
200 | kErrUnknownCmd = 0x18, // Unknown command
|
---|
201 | kErrForbiddenCmd = 0x11, // Command not allowed
|
---|
202 | kErrTempReadCmd = 0x20, // Temperature reading failes (ignored)
|
---|
203 | kErrTempReadBusy = 0x40, // Temperature reading busy (ignored)
|
---|
204 | };
|
---|
205 |
|
---|
206 | // --------------------------------------------------------------------------
|
---|
207 |
|
---|
208 | struct Config
|
---|
209 | {
|
---|
210 | // WARNING: Update the DIM service if you do any update to this header!
|
---|
211 | uint64_t fFirmwareId;
|
---|
212 | uint64_t fProductId;
|
---|
213 | uint8_t fClockState;
|
---|
214 | uint64_t fClockFrequency64;
|
---|
215 | double fClockFrequencyD;
|
---|
216 | uint8_t fTimerState;
|
---|
217 | uint64_t fTimerFrequency64;
|
---|
218 | double fTimerFrequencyD;
|
---|
219 | uint8_t fTriggerState;
|
---|
220 | uint8_t fTriggerSourceMask;
|
---|
221 | uint8_t fTriggerOutSourceMask;
|
---|
222 | uint16_t fTriggerDspDelay; // 2.5ns
|
---|
223 | uint16_t fTriggerExtDelay; // 2.5ns
|
---|
224 | uint16_t fTriggerOutDelay; // 2.5ns
|
---|
225 | uint32_t fTriggerPeriod32;
|
---|
226 | uint32_t fTriggerHoldOff24;
|
---|
227 | uint8_t fTriggerInhibitState;
|
---|
228 | uint16_t fTriggerInhibitTime; //5ns
|
---|
229 |
|
---|
230 | Config() { memset(this, 0, sizeof(Config)); fClockState=0xff; fTriggerState=0xff; }
|
---|
231 |
|
---|
232 | std::string mask(const uint8_t &mask) const
|
---|
233 | {
|
---|
234 | std::string rc;
|
---|
235 |
|
---|
236 | if (mask&kMaskExtIn)
|
---|
237 | rc += "EXTin ";
|
---|
238 | if (mask&kMaskDspIn)
|
---|
239 | rc += "DSPin ";
|
---|
240 | if (mask&kMaskExtInDelay)
|
---|
241 | rc += "EXTin-delay ";
|
---|
242 | if (mask&kMaskDspInDelay)
|
---|
243 | rc += "DSPin-delay ";
|
---|
244 | if (mask&kMaskInternal)
|
---|
245 | rc += "internal ";
|
---|
246 | if (mask&kMaskButton)
|
---|
247 | rc += "button ";
|
---|
248 | if (mask&kMaskSingle)
|
---|
249 | rc += "single ";
|
---|
250 |
|
---|
251 | return rc;
|
---|
252 | }
|
---|
253 |
|
---|
254 | void print(std::ostream &out) const
|
---|
255 | {
|
---|
256 | out << std::hex;
|
---|
257 | out << "Indentification: Product=0x" << fFirmwareId << " / Firmware=0x" << fProductId << '\n';
|
---|
258 | out << "Clock state: ";
|
---|
259 | switch (fClockState)
|
---|
260 | {
|
---|
261 | case kEnable: out << "<enabled>"; break;
|
---|
262 | case kDisable: out << "<disabled>"; break;
|
---|
263 | case kShutdown: out << "<shutdown>"; break;
|
---|
264 | default: out << "<unknown>";
|
---|
265 | }
|
---|
266 | out << " [0x" << uint16_t(fClockState) << "]\n";
|
---|
267 | out << "Clock frequency: " << fClockFrequencyD << " Hz [0x" << fClockFrequency64 << "] (DRS=" << fClockFrequencyD*2.048 << " kHz)\n";
|
---|
268 | out << "Timer state: ";
|
---|
269 | switch (fTimerState)
|
---|
270 | {
|
---|
271 | case kEnable: out << "<enabled>"; break;
|
---|
272 | case kDisable: out << "<disabled>"; break;
|
---|
273 | case kShutdown: out << "<shutdown>"; break;
|
---|
274 | default: out << "<unknown>";
|
---|
275 | }
|
---|
276 | out << " [0x" << uint16_t(fTimerState) << "]\n";
|
---|
277 | out << "Timer frequency: " << fTimerFrequencyD << " Hz [0x" << fTimerFrequency64 << "]\n";
|
---|
278 | out << "Trigger state: ";
|
---|
279 | switch (fTriggerState)
|
---|
280 | {
|
---|
281 | case kInternal: out << "<internal>"; break;
|
---|
282 | case kExternal: out << "<external>"; break;
|
---|
283 | case kShutdown: out << "<off>"; break;
|
---|
284 | //case kRandom: out << "<random>"; break;
|
---|
285 | default: out << "<unknown>";
|
---|
286 | }
|
---|
287 | out << " [0x" << uint16_t(fTriggerState) << "]\n";
|
---|
288 | out << "Trigger frequency: " << 1e6/fTriggerPeriod32 << "Hz [" << fTriggerPeriod32 << "]\n";
|
---|
289 | out << "Trigger Masks: ";
|
---|
290 |
|
---|
291 | out << std::hex;
|
---|
292 | out << "[source:" << uint32_t(fTriggerSourceMask) << "] " << mask(fTriggerSourceMask);
|
---|
293 | out << "[out-source:" << uint32_t(fTriggerOutSourceMask) << "] " << mask(fTriggerOutSourceMask);
|
---|
294 | out << '\n';
|
---|
295 |
|
---|
296 | out << "Trigger hold off: " << fTriggerHoldOff24 << " us\n";
|
---|
297 | out << "Trigger delays: ";
|
---|
298 | out << "DSP=" << fTriggerDspDelay*2.5 << "ns ";
|
---|
299 | out << "EXT=" << fTriggerExtDelay*2.5 << "ns ";
|
---|
300 | out << "OUT=" << fTriggerOutDelay*2.5 << "ns\n";
|
---|
301 |
|
---|
302 | out << "Trig.inhibit state: ";
|
---|
303 | switch (fTriggerInhibitState)
|
---|
304 | {
|
---|
305 | case kEnable: out << "<enabled>"; break;
|
---|
306 | case kDisable: out << "<disabled>"; break;
|
---|
307 | default: out << "<unknown>";
|
---|
308 | }
|
---|
309 | out << '\n';
|
---|
310 | out << "Trig.inhibit time: "<< fTriggerInhibitTime*5.0 << "ns ";
|
---|
311 | out << std::endl;
|
---|
312 | /*
|
---|
313 | out << "Configuration: Trigger ";
|
---|
314 | switch (fConfiguration&0x6)
|
---|
315 | {
|
---|
316 | case 0x02:
|
---|
317 | out << (fConfiguration?"<random>":"<fixed rate>");
|
---|
318 | break;
|
---|
319 | case 0x04:
|
---|
320 | out << "<external>";
|
---|
321 | break;
|
---|
322 |
|
---|
323 | case 0x06:
|
---|
324 | out << (fConfiguration&0x10?"<off[hi]>":"<off[lo]>");
|
---|
325 | break;
|
---|
326 | }
|
---|
327 | out << " [" << fConfiguration << "] RS485 <" << (fConfiguration&1?"on":"off") << ">\n";
|
---|
328 | */
|
---|
329 | out << std::dec;
|
---|
330 | out << std::flush;
|
---|
331 | }
|
---|
332 | } __attribute__((__packed__));
|
---|
333 |
|
---|
334 | inline std::ostream &operator<<(std::ostream &out, const Config &c)
|
---|
335 | {
|
---|
336 | c.print(out);
|
---|
337 | return out;
|
---|
338 | }
|
---|
339 |
|
---|
340 | struct Data
|
---|
341 | {
|
---|
342 | // WARNING: Update the DIM service if you do any update to this header!
|
---|
343 | uint32_t fRunTime; // [10ns]
|
---|
344 | uint32_t fDeadTime; // [10ns]
|
---|
345 |
|
---|
346 | uint32_t fTriggerCounter; // As sent through RS485
|
---|
347 |
|
---|
348 | uint32_t fClockFrequency; // measured Hz
|
---|
349 | uint32_t fTimerFrequency; // measured Hz
|
---|
350 |
|
---|
351 | uint16_t fADC1; // 10 bit
|
---|
352 | float fTemp1;
|
---|
353 |
|
---|
354 | Data() { memset(this, 0, sizeof(Data)); }
|
---|
355 |
|
---|
356 | void SetADC1(const uint16_t &adc)
|
---|
357 | {
|
---|
358 | fADC1 = adc;
|
---|
359 | fTemp1 = adc*0.0625;//-(adc*3300./1024-2633)/13.6;
|
---|
360 | }
|
---|
361 |
|
---|
362 | void print(std::ostream &out) const
|
---|
363 | {
|
---|
364 | out << Tools::Form("On Time: Total=%.2fus Veto=%.2fus (%.1f%%)\n", fRunTime*0.01, fDeadTime*0.01, 100.*fDeadTime/fRunTime);
|
---|
365 | out << Tools::Form("Trigger: Counter= %016lx\n", fTriggerCounter);
|
---|
366 | out << Tools::Form("Drequencies: Clock=%d Hz, Timer=%d Hz\n", fClockFrequency, fTimerFrequency);
|
---|
367 | out << Tools::Form("Temperature: %.1f degC\n", fTemp1);
|
---|
368 | out << std::flush;
|
---|
369 | }
|
---|
370 |
|
---|
371 | } __attribute__((__packed__));
|
---|
372 |
|
---|
373 | inline std::ostream &operator<<(std::ostream &out, const Data &d)
|
---|
374 | {
|
---|
375 | d.print(out);
|
---|
376 | return out;
|
---|
377 | }
|
---|
378 |
|
---|
379 | // ---------------------------------------------------------------
|
---|
380 |
|
---|
381 | struct RunType
|
---|
382 | {
|
---|
383 | std::string fTriggerType;
|
---|
384 |
|
---|
385 | uint32_t fTriggerPeriod;
|
---|
386 | uint16_t fTriggerSourceMask;
|
---|
387 | uint16_t fTriggerOutSourceMask;
|
---|
388 | uint16_t fTriggerDspDelay;
|
---|
389 | uint16_t fTriggerExtDelay;
|
---|
390 | uint16_t fTriggerOutDelay;
|
---|
391 | uint32_t fTriggerHoldOff;
|
---|
392 | };
|
---|
393 |
|
---|
394 | };
|
---|
395 | #endif
|
---|