1 | #ifndef FACT_HeadersMiniFTM
|
---|
2 | #define FACT_HeadersMiniFTM
|
---|
3 |
|
---|
4 | #include <iosfwd>
|
---|
5 | #include <stdint.h>
|
---|
6 | #include <numeric> // accumulate
|
---|
7 | #include <algorithm>
|
---|
8 |
|
---|
9 | #include "HeadersFTM.h"
|
---|
10 |
|
---|
11 | namespace MiniFTM
|
---|
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 | return std::accumulate(&fReadWrite, &fReadWrite+11, uint8_t(0));
|
---|
75 | }
|
---|
76 |
|
---|
77 | bool isCrcValid() const
|
---|
78 | {
|
---|
79 | return fCrc == calcCrc();
|
---|
80 | }
|
---|
81 |
|
---|
82 | void print(std::ostream &out) const
|
---|
83 | {
|
---|
84 | out << std::hex;
|
---|
85 | out << Tools::Form("%04x|%02x|%04x|%016lx|%02x|%04x",
|
---|
86 | fStartBits, fReadWrite, fCommand, fData, fCrc, fStopBits);
|
---|
87 | out << std::dec;
|
---|
88 | }
|
---|
89 | } __attribute__((__packed__));
|
---|
90 |
|
---|
91 | inline std::ostream &operator<<(std::ostream &out, const BusData &d)
|
---|
92 | {
|
---|
93 | d.print(out);
|
---|
94 | return out;
|
---|
95 | }
|
---|
96 |
|
---|
97 | enum readwrite_t
|
---|
98 | {
|
---|
99 | kCmdRead = 0x00, // Command: Read
|
---|
100 | kCmdWrite = 0x04, // Command: Write
|
---|
101 | kCmdADM = 0x0e, // Automatic data mode (ADM) package
|
---|
102 | kCmdError = 0xff,
|
---|
103 | };
|
---|
104 |
|
---|
105 | enum trigger_t
|
---|
106 | {
|
---|
107 | kFixedRate = 0x00,
|
---|
108 | kExternal = 0x01,
|
---|
109 | kShutdown = 0x02,
|
---|
110 | kRandom = 0x10,
|
---|
111 |
|
---|
112 | kEnable = 0x00,
|
---|
113 | kDisable = 0x01,
|
---|
114 | };
|
---|
115 |
|
---|
116 | enum command_t
|
---|
117 | {
|
---|
118 | kRegProductId = 0x0000, // read only
|
---|
119 | kRegFirmwareId = 0x0100, // read only
|
---|
120 | kRegError = 0xa0a0, // read only
|
---|
121 |
|
---|
122 | kClockState = 0x0010, //
|
---|
123 | kClockEnable = kClockState|(kEnable<<8),
|
---|
124 | kClockDisable = kClockState|(kDisable<<8),
|
---|
125 | kClockShutdown = kClockState|(kShutdown<<8),
|
---|
126 |
|
---|
127 | kClockFrequency = 0x0011, // 2 byte, 14 bit
|
---|
128 |
|
---|
129 | kTriggerState = 0x0020,
|
---|
130 | kTriggerFixedRate = kTriggerState|(kFixedRate<<8),
|
---|
131 | kTriggerExternal = kTriggerState|(kExternal<<8),
|
---|
132 | kTriggerShutdown = kTriggerState|(kShutdown<<8),
|
---|
133 | kTriggerRandom = kTriggerState|(kRandom<<8),
|
---|
134 |
|
---|
135 | kTriggerRS485On = 0x0320,
|
---|
136 | kTriggerRS485Off = 0x0420,
|
---|
137 |
|
---|
138 | kTriggerFrequency = 0x0021, // 2 byte, 16 bit
|
---|
139 |
|
---|
140 | kConfiguration = 0x0022,
|
---|
141 |
|
---|
142 | kDelay = 0x0023, // 16 bit, anz takt zyklen
|
---|
143 | kDeadTime = 0x0024, // 16 bit, anz takt zyklen (artificial dead time)
|
---|
144 |
|
---|
145 | kFadReset = 0x0030,
|
---|
146 | kFadResetCycles = 0x0031, // 16 bit, length in cycles (>=10)
|
---|
147 | kFadResetActiveHi = 0x0032,
|
---|
148 |
|
---|
149 | kADC1 = 0x0040, // read only (2 byte, 10 bit)
|
---|
150 | kADC2 = 0x0041, // read only (2 byte, 10 bit)
|
---|
151 | kADCs = 0x0042, // read only (2x2 byte, 10 bit)
|
---|
152 |
|
---|
153 | kRS485Data = 0x0050, // 56 bit (last data sent, but counter increased by 1)
|
---|
154 | //kCmdRS485Crc = 0x51, // 8bit
|
---|
155 | //kCmdRS485EventType = 0x52, // 16bit
|
---|
156 | //kCmdRS485EventNumber = 0x53, // 32bit
|
---|
157 |
|
---|
158 | kSingleTrigger = 0x005e, // read only
|
---|
159 | kTriggerCounter = 0x005f, // read only
|
---|
160 |
|
---|
161 | kEnableADM = 0x0060, // Automatic data transmission
|
---|
162 | };
|
---|
163 |
|
---|
164 | enum error_t
|
---|
165 | {
|
---|
166 | kErrFrameStart = 0xba, // Start bytes wrong
|
---|
167 | kErrFrameStop = 0xbb, // Stop bytes wrong
|
---|
168 | kErrFrameCrc = 0xaa, // Checksum wrong
|
---|
169 | kErrUnknownCmd = 0x18, // Unknown command
|
---|
170 | kErrForbiddenCmd = 0x11, // Command not allowed
|
---|
171 | };
|
---|
172 |
|
---|
173 | // --------------------------------------------------------------------------
|
---|
174 |
|
---|
175 | struct Config
|
---|
176 | {
|
---|
177 | uint64_t fFirmwareId;
|
---|
178 | uint64_t fProductId;
|
---|
179 | uint8_t fClockState;
|
---|
180 | uint64_t fClockFrequency64;
|
---|
181 | double fClockFrequencyD;
|
---|
182 | uint8_t fTriggerState;
|
---|
183 | uint8_t fRS485OnOff;
|
---|
184 | uint64_t fTriggerFrequency64;
|
---|
185 | double fTriggerFrequencyD;
|
---|
186 | uint64_t fConfiguration;
|
---|
187 | uint64_t fRS485Data;
|
---|
188 |
|
---|
189 | Config() { memset(this, 0, sizeof(Config)); fClockState=0xff; fTriggerState=0xff; }
|
---|
190 |
|
---|
191 | void print(std::ostream &out) const
|
---|
192 | {
|
---|
193 | out << std::hex;
|
---|
194 | out << "Indentification: Product=0x" << fFirmwareId << " / Firmware=0x" << fProductId << '\n';
|
---|
195 | out << "Clock state: ";
|
---|
196 | switch (fClockState)
|
---|
197 | {
|
---|
198 | case kEnable: out << "<enabled>"; break;
|
---|
199 | case kDisable: out << "<disabled>"; break;
|
---|
200 | case kShutdown: out << "<shutdown>"; break;
|
---|
201 | default: out << "<unknown>";
|
---|
202 | }
|
---|
203 | out << " [0x" << uint16_t(fClockState) << "]\n";
|
---|
204 | out << "Clock frequency: " << fClockFrequencyD << " Hz [0x" << fClockFrequency64 << "] (DRS=" << fClockFrequencyD*2.048 << " kHz)\n";
|
---|
205 | out << "Trigger state: ";
|
---|
206 | switch (fTriggerState)
|
---|
207 | {
|
---|
208 | case kFixedRate: out << "<fixed rate>"; break;
|
---|
209 | case kExternal: out << "<external>"; break;
|
---|
210 | case kShutdown: out << "<off>"; break;
|
---|
211 | case kRandom: out << "<random>"; break;
|
---|
212 | default: out << "<unknown>";
|
---|
213 | }
|
---|
214 | out << " [0x" << uint16_t(fTriggerState) << "]\n";
|
---|
215 | out << "Trigger frequency: " << fTriggerFrequencyD << " Hz [0x" << fTriggerFrequency64 << "]\n";
|
---|
216 | out << "Configuration: Trigger ";
|
---|
217 | switch (fConfiguration&0x6)
|
---|
218 | {
|
---|
219 | case 0x02:
|
---|
220 | out << (fConfiguration?"<random>":"<fixed rate>");
|
---|
221 | break;
|
---|
222 | case 0x04:
|
---|
223 | out << "<external>";
|
---|
224 | break;
|
---|
225 |
|
---|
226 | case 0x06:
|
---|
227 | out << (fConfiguration&0x10?"<off[hi]>":"<off[lo]>");
|
---|
228 | break;
|
---|
229 | }
|
---|
230 | out << " [" << fConfiguration << "] RS485 <" << (fConfiguration&1?"on":"off") << ">\n";
|
---|
231 |
|
---|
232 | out << std::dec;
|
---|
233 | out << std::flush;
|
---|
234 | }
|
---|
235 | } __attribute__((__packed__));
|
---|
236 |
|
---|
237 | inline std::ostream &operator<<(std::ostream &out, const Config &c)
|
---|
238 | {
|
---|
239 | c.print(out);
|
---|
240 | return out;
|
---|
241 | }
|
---|
242 |
|
---|
243 | struct Temp
|
---|
244 | {
|
---|
245 | uint16_t fADC1; // 10 bit
|
---|
246 | uint16_t fADC2; // 10 bit
|
---|
247 | float fTemp1;
|
---|
248 | float fTemp2;
|
---|
249 |
|
---|
250 | Temp() { memset(this, 0, sizeof(Temp)); }
|
---|
251 |
|
---|
252 | void SetADC1(const uint16_t &adc)
|
---|
253 | {
|
---|
254 | fADC1 = adc;
|
---|
255 | fTemp1 = -(adc*3300./1024-2633)/13.6;
|
---|
256 | }
|
---|
257 | void SetADC2(const uint16_t &adc)
|
---|
258 | {
|
---|
259 | fADC2 = adc;
|
---|
260 | fTemp2 = -(adc*3300./1024-2633)/13.6;
|
---|
261 | }
|
---|
262 |
|
---|
263 | } __attribute__((__packed__));
|
---|
264 |
|
---|
265 | // ---------------------------------------------------------------
|
---|
266 |
|
---|
267 | struct RunType
|
---|
268 | {
|
---|
269 | uint16_t fTriggerRate;
|
---|
270 | std::string fTriggerType;
|
---|
271 | };
|
---|
272 |
|
---|
273 | };
|
---|
274 | #endif
|
---|