| 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
|
|---|