#ifndef FACT_HeadersMiniFTM #define FACT_HeadersMiniFTM #include #include #include // accumulate #include #include "HeadersFTM.h" namespace MiniFTM { 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 { 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 { kFixedRate = 0x00, kExternal = 0x01, kShutdown = 0x02, kRandom = 0x10, kEnable = 0x00, kDisable = 0x01, }; enum command_t { kRegProductId = 0x0000, // read only kRegFirmwareId = 0x0100, // read only kRegError = 0xa0a0, // read only kClockState = 0x0010, // kClockEnable = kClockState|(kEnable<<8), kClockDisable = kClockState|(kDisable<<8), kClockShutdown = kClockState|(kShutdown<<8), kClockFrequency = 0x0011, // 2 byte, 14 bit kTriggerState = 0x0020, kTriggerFixedRate = kTriggerState|(kFixedRate<<8), kTriggerExternal = kTriggerState|(kExternal<<8), kTriggerShutdown = kTriggerState|(kShutdown<<8), kTriggerRandom = kTriggerState|(kRandom<<8), kTriggerRS485On = 0x0320, kTriggerRS485Off = 0x0420, kTriggerFrequency = 0x0021, // 2 byte, 16 bit kConfiguration = 0x0022, kDelay = 0x0023, // 16 bit, anz takt zyklen kDeadTime = 0x0024, // 16 bit, anz takt zyklen (artificial dead time) kFadReset = 0x0030, kFadResetCycles = 0x0031, // 16 bit, length in cycles (>=10) kFadResetActiveHi = 0x0032, kADC1 = 0x0040, // read only (2 byte, 10 bit) kADC2 = 0x0041, // read only (2 byte, 10 bit) kADCs = 0x0042, // read only (2x2 byte, 10 bit) kRS485Data = 0x0050, // 56 bit (last data sent, but counter increased by 1) //kCmdRS485Crc = 0x51, // 8bit //kCmdRS485EventType = 0x52, // 16bit //kCmdRS485EventNumber = 0x53, // 32bit kSingleTrigger = 0x005e, // read only kTriggerCounter = 0x005f, // read only kEnableADM = 0x0060, // Automatic data transmission }; 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 }; // -------------------------------------------------------------------------- struct Config { uint64_t fFirmwareId; uint64_t fProductId; uint8_t fClockState; uint64_t fClockFrequency64; double fClockFrequencyD; uint8_t fTriggerState; uint8_t fRS485OnOff; uint64_t fTriggerFrequency64; double fTriggerFrequencyD; uint64_t fConfiguration; uint64_t fRS485Data; Config() { memset(this, 0, sizeof(Config)); fClockState=0xff; fTriggerState=0xff; } 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 << "Trigger state: "; switch (fTriggerState) { case kFixedRate: 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: " << fTriggerFrequencyD << " Hz [0x" << fTriggerFrequency64 << "]\n"; 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 Temp { uint16_t fADC1; // 10 bit uint16_t fADC2; // 10 bit float fTemp1; float fTemp2; Temp() { memset(this, 0, sizeof(Temp)); } void SetADC1(const uint16_t &adc) { fADC1 = adc; fTemp1 = -(adc*3300./1024-2633)/13.6; } void SetADC2(const uint16_t &adc) { fADC2 = adc; fTemp2 = -(adc*3300./1024-2633)/13.6; } } __attribute__((__packed__)); // --------------------------------------------------------------- struct RunType { uint16_t fTriggerRate; std::string fTriggerType; }; }; #endif