#ifndef FACT_HeadersFPGAFTM #define FACT_HeadersFPGAFTM #include #include #include // accumulate #include #include "HeadersFTM.h" namespace FPGAFTM { namespace State { /*********** FTM ********** enum StateMachine { kDisconnected = 1, kConnected, kIdle, kValid, kTriggerOn, kConfiguring1, kConfiguring2, kConfigured1, kConfigured2, kConfigError1 = 0x101, kConfigError2 = 0x102, //kConfigError3 = 0x103, }; */ enum states_t { kDisconnected = FTM::State::kDisconnected, kConnected = FTM::State::kConnected, //kIdle kValid = FTM::State::kValid, kTriggerOn = FTM::State::kTriggerOn, kConfiguring = FTM::State::kConfiguring1, //kConfiguring2, kConfigured = FTM::State::kConfigured1, //kConfigured2, //kConfigError1 = 0x101, //kConfigError2 = 0x102, //kConfigError3 = 0x103, }; }; // ---------------------------------------------------------------------- struct BusData { uint16_t fStartBits; uint8_t fReadWrite; uint16_t fCommand; uint64_t fData; uint8_t fCrc; uint16_t fStopBits; BusData(uint8_t rw, uint16_t cmd, uint64_t dat) : fStartBits(0xffff), fReadWrite(rw), fCommand(cmd), fData(dat), fStopBits(0xffff) { fCrc = calcCrc(); } uint32_t id() const { return (fReadWrite<<16)|fCommand; } uint8_t calcCrc() const { // FIXME: FIX IN minifrmctrl -- old! return std::accumulate(&fReadWrite, &fReadWrite+11, uint8_t(0)); } bool isCrcValid() const { return fCrc == calcCrc(); } void print(std::ostream &out) const { out << std::hex; out << Tools::Form("%04x|%02x|%04x|%016lx|%02x|%04x", fStartBits, fReadWrite, fCommand, fData, fCrc, fStopBits); out << std::dec; } } __attribute__((__packed__)); inline std::ostream &operator<<(std::ostream &out, const BusData &d) { d.print(out); return out; } enum readwrite_t { kCmdRead = 0x00, // Command: Read kCmdWrite = 0x04, // Command: Write kCmdADM = 0x0e, // Automatic data mode (ADM) package kCmdError = 0xff, }; enum trigger_t { kInternal = 0x00, kExternal = 0x01, kShutdown = 0x02, //kRandom = 0x10, kEnable = 0x00, kDisable = 0x01, }; enum mask_t { kMaskExtIn = 0x02, kMaskDspIn = 0x04, kMaskExtInDelay = 0x08, kMaskDspInDelay = 0x10, kMaskInternal = 0x20, kMaskButton = 0x40, kMaskSingle = 0x80 }; enum command_t { kRegProductId = 0x0000, // read only kRegFirmwareId = 0x0100, // read only kClockState = 0x0010, kClockEnable = kClockState|(kEnable<<8), kClockDisable = kClockState|(kDisable<<8), kClockShutdown = kClockState|(kShutdown<<8), kClockFrequency = 0x0011, // 2 byte, 14 bit kClockMeasure = 0x0012, // 2 byte, 14 bit kTimerState = 0x0014, // read/write kTimerEnable = kTimerState|(kEnable<<8), kTimerDisable = kTimerState|(kDisable<<8), kTimerShutdown = kTimerState|(kShutdown<<8), kTimerFrequency = 0x0015, kTimerMeasure = 0x0016, kTriggerState = 0x0020, kTriggerInternal = kTriggerState|(kInternal<<8), kTriggerExternal = kTriggerState|(kExternal<<8), kTriggerShutdown = kTriggerState|(kShutdown<<8), //kTriggerRandom = kTriggerState|(kRandom<<8), kTriggerPeriod = 0x0021, kTriggerSourceMask = 0x0022, /* kTriggerOutState = 0x0024, kTriggerOutInt = kTriggerOutState|(...), kTriggerOutExt = kTriggerOutState|(...), kTriggerOutIntDelayed = kTriggerOutState|(...), kTriggerOutExtDelayed = kTriggerOutState|(...), */ kTriggerHoldOff = 0x0025, kTriggerOutSourceMask = 0x0026, kTriggerDspDelay = 0x0028, // 10bit kTriggerExtDelay = 0x0029, // 10bit kTriggerOutDelay = 0x002e, // 10bit kFadResetLo = 0x0030, kFadResetHi = 0x0130, kTriggerInhibitState = 0x0032, kTriggerInhibitEnable = 0x0132, kTriggerInhibitDisable= 0x0032, kTriggerInhibitTime = 0x0033, kADC1 = 0x0040, // read only (2 byte, 10 bit) kRS485Data = 0x0050, // 56 bit (last data sent, but counter increased by 1) kSingleTrigger = 0x005e, // read only kOnTime = 0x0060, // Automatic data transmission kSoftReset = 0x01ff, kHardReset = 0x02ff, }; enum error_t { kErrFrameStart = 0xba, // Start bytes wrong kErrFrameStop = 0xbb, // Stop bytes wrong kErrFrameCrc = 0xaa, // Checksum wrong kErrUnknownCmd = 0x18, // Unknown command kErrForbiddenCmd = 0x11, // Command not allowed kErrTempReadCmd = 0x20, // Temperature reading failes (ignored) kErrTempReadBusy = 0x40, // Temperature reading busy (ignored) }; // -------------------------------------------------------------------------- struct Config { // WARNING: Update the DIM service if you do any update to this header! uint64_t fFirmwareId; uint64_t fProductId; uint8_t fClockState; uint64_t fClockFrequency64; double fClockFrequencyD; uint8_t fTimerState; uint64_t fTimerFrequency64; double fTimerFrequencyD; uint8_t fTriggerState; uint8_t fTriggerSourceMask; uint8_t fTriggerOutSourceMask; uint16_t fTriggerDspDelay; // 2.5ns uint16_t fTriggerExtDelay; // 2.5ns uint16_t fTriggerOutDelay; // 2.5ns uint32_t fTriggerPeriod32; uint32_t fTriggerHoldOff24; uint8_t fTriggerInhibitState; uint16_t fTriggerInhibitTime; //5ns Config() { memset(this, 0, sizeof(Config)); fClockState=0xff; fTriggerState=0xff; } std::string mask(const uint8_t &mask) const { std::string rc; if (mask&kMaskExtIn) rc += "EXTin "; if (mask&kMaskDspIn) rc += "DSPin "; if (mask&kMaskExtInDelay) rc += "EXTin-delay "; if (mask&kMaskDspInDelay) rc += "DSPin-delay "; if (mask&kMaskInternal) rc += "internal "; if (mask&kMaskButton) rc += "button "; if (mask&kMaskSingle) rc += "single "; return rc; } void print(std::ostream &out) const { out << std::hex; out << "Indentification: Product=0x" << fFirmwareId << " / Firmware=0x" << fProductId << '\n'; out << "Clock state: "; switch (fClockState) { case kEnable: out << ""; break; case kDisable: out << ""; break; case kShutdown: out << ""; break; default: out << ""; } out << " [0x" << uint16_t(fClockState) << "]\n"; out << "Clock frequency: " << fClockFrequencyD << " Hz [0x" << fClockFrequency64 << "] (DRS=" << fClockFrequencyD*2.048 << " kHz)\n"; out << "Timer state: "; switch (fTimerState) { case kEnable: out << ""; break; case kDisable: out << ""; break; case kShutdown: out << ""; break; default: out << ""; } out << " [0x" << uint16_t(fTimerState) << "]\n"; out << "Timer frequency: " << fTimerFrequencyD << " Hz [0x" << fTimerFrequency64 << "]\n"; out << "Trigger state: "; switch (fTriggerState) { case kInternal: out << ""; break; case kExternal: out << ""; break; case kShutdown: out << ""; break; //case kRandom: out << ""; break; default: out << ""; } out << " [0x" << uint16_t(fTriggerState) << "]\n"; out << "Trigger frequency: " << 1e6/fTriggerPeriod32 << "Hz [" << fTriggerPeriod32 << "]\n"; out << "Trigger Masks: "; out << std::hex; out << "[source:" << uint32_t(fTriggerSourceMask) << "] " << mask(fTriggerSourceMask); out << "[out-source:" << uint32_t(fTriggerOutSourceMask) << "] " << mask(fTriggerOutSourceMask); out << '\n'; out << "Trigger hold off: " << fTriggerHoldOff24 << " us\n"; out << "Trigger delays: "; out << "DSP=" << fTriggerDspDelay*2.5 << "ns "; out << "EXT=" << fTriggerExtDelay*2.5 << "ns "; out << "OUT=" << fTriggerOutDelay*2.5 << "ns\n"; out << "Trig.inhibit state: "; switch (fTriggerInhibitState) { case kEnable: out << ""; break; case kDisable: out << ""; break; default: out << ""; } out << '\n'; out << "Trig.inhibit time: "<< fTriggerInhibitTime*5.0 << "ns "; out << std::endl; /* out << "Configuration: Trigger "; switch (fConfiguration&0x6) { case 0x02: out << (fConfiguration?"":""); break; case 0x04: out << ""; break; case 0x06: out << (fConfiguration&0x10?"":""); break; } out << " [" << fConfiguration << "] RS485 <" << (fConfiguration&1?"on":"off") << ">\n"; */ out << std::dec; out << std::flush; } } __attribute__((__packed__)); inline std::ostream &operator<<(std::ostream &out, const Config &c) { c.print(out); return out; } struct Data { // WARNING: Update the DIM service if you do any update to this header! uint32_t fRunTime; // [10ns] uint32_t fDeadTime; // [10ns] uint32_t fTriggerCounter; // As sent through RS485 uint32_t fClockFrequency; // measured Hz uint32_t fTimerFrequency; // measured Hz uint16_t fADC1; // 10 bit float fTemp1; Data() { memset(this, 0, sizeof(Data)); } void SetADC1(const uint16_t &adc) { fADC1 = adc; fTemp1 = adc*0.0625;//-(adc*3300./1024-2633)/13.6; } void print(std::ostream &out) const { out << Tools::Form("On Time: Total=%.2fus Veto=%.2fus (%.1f%%)\n", fRunTime*0.01, fDeadTime*0.01, 100.*fDeadTime/fRunTime); out << Tools::Form("Trigger: Counter= %016lx\n", fTriggerCounter); out << Tools::Form("Drequencies: Clock=%d Hz, Timer=%d Hz\n", fClockFrequency, fTimerFrequency); out << Tools::Form("Temperature: %.1f degC\n", fTemp1); out << std::flush; } } __attribute__((__packed__)); inline std::ostream &operator<<(std::ostream &out, const Data &d) { d.print(out); return out; } // --------------------------------------------------------------- struct RunType { std::string fTriggerType; uint32_t fTriggerPeriod; uint16_t fTriggerSourceMask; uint16_t fTriggerOutSourceMask; uint16_t fTriggerDspDelay; uint16_t fTriggerExtDelay; uint16_t fTriggerOutDelay; uint32_t fTriggerHoldOff; }; }; #endif