diff --git a/slsDetectorGui/src/qDrawPlot.cpp b/slsDetectorGui/src/qDrawPlot.cpp index 6558f3eee..2784f9e0a 100755 --- a/slsDetectorGui/src/qDrawPlot.cpp +++ b/slsDetectorGui/src/qDrawPlot.cpp @@ -90,7 +90,7 @@ void qDrawPlot::SetupPlots() { break; case slsDetectorDefs::EIGER: if (myDet->getQuad()) { - nPixelsX = myDet->getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::X) / 2; + nPixelsX = (myDet->getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::X) / 2) - 1; nPixelsY = myDet->getTotalNumberOfChannelsInclGapPixels(slsDetectorDefs::Y) * 2; } break; diff --git a/slsDetectorServers/eigerDetectorServer/Beb.c b/slsDetectorServers/eigerDetectorServer/Beb.c index 605b904ce..d3585e56d 100755 --- a/slsDetectorServers/eigerDetectorServer/Beb.c +++ b/slsDetectorServers/eigerDetectorServer/Beb.c @@ -1190,11 +1190,12 @@ void Beb_SetDetectorNumber(uint32_t detid) { FILE_LOG(logINFO, ("Detector id %d set in UDP Header\n\n", detid)); } -void Beb_SetQuad(int value) { - if (value >= 0) { - Beb_quadEnable = (value == 0 ? 0 : 1); - Beb_SetDetectorPosition(Beb_positions); - } +int Beb_SetQuad(int value) { + if (value < 0) + return OK; + FILE_LOG(logINFO, ("Setting Quad to %d in Beb\n", value)); + Beb_quadEnable = (value == 0 ? 0 : 1); + return Beb_SetDetectorPosition(Beb_positions); } int Beb_GetQuad() { diff --git a/slsDetectorServers/eigerDetectorServer/Beb.h b/slsDetectorServers/eigerDetectorServer/Beb.h index 36d2c0ca7..fd9b280c2 100755 --- a/slsDetectorServers/eigerDetectorServer/Beb.h +++ b/slsDetectorServers/eigerDetectorServer/Beb.h @@ -74,7 +74,7 @@ int Beb_Test(unsigned int beb_number); int Beb_GetBebFPGATemp(); void Beb_SetDetectorNumber(uint32_t detid); -void Beb_SetQuad(int value); +int Beb_SetQuad(int value); int Beb_GetQuad(); int Beb_SetDetectorPosition(int pos[]); int Beb_SetStartingFrameNumber(uint64_t value); diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.c b/slsDetectorServers/eigerDetectorServer/FebControl.c index 8babb7aa0..a66a540b0 100755 --- a/slsDetectorServers/eigerDetectorServer/FebControl.c +++ b/slsDetectorServers/eigerDetectorServer/FebControl.c @@ -2014,61 +2014,171 @@ int Feb_Control_SoftwareTrigger() { return 1; } +int Feb_Control_SetInterruptSubframe(int val) { + FILE_LOG(logINFO, ("Setting Interrupt Subframe to %d\n", val)); -uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data) { - uint32_t value=0; - if (Module_TopAddressIsValid(&modules[1])) { - if (!Feb_Interface_WriteRegister(Module_GetTopRightAddress (&modules[1]),offset, data,0, 0)) { - FILE_LOG(logERROR, ("Could not read tr value. Value read:%d\n", value)); - value = 0; + // they need to be written separately because the left and right registers have different values for this particular register + uint32_t offset = DAQ_REG_HRDWRE; + uint32_t regVal = 0; + char side[2][10] = {"right", "left"}; + char isTop[10]; strcpy(isTop, Module_TopAddressIsValid(&modules[1]) ? "top" : "bottom"); + unsigned int addr[2]; + addr[0] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopRightAddress (&modules[1]) : Module_GetBottomRightAddress (&modules[1]); + addr[1] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopLeftAddress (&modules[1]) : Module_GetBottomLeftAddress (&modules[1]); + + int iloop = 0; + for(iloop = 0; iloop < 2; ++iloop) { + // get previous value to keep it + if(!Feb_Interface_ReadRegister(addr[iloop], offset, ®Val)) { + FILE_LOG(logERROR, ("Could not read %s %s interrupt subframe\n", isTop, side[iloop])); + return 0; } - if(!Feb_Interface_WriteRegister(Module_GetTopLeftAddress (&modules[1]),offset, data,0, 0)) { - FILE_LOG(logERROR, ("Could not read tl value. Value read:%d\n", value)); - value = 0; - } - } else { - if (!Feb_Interface_WriteRegister(Module_GetBottomRightAddress (&modules[1]),offset, data,0, 0)) { - FILE_LOG(logERROR, ("Could not read br value. Value read:%d\n", value)); - value = 0; + uint32_t data = ((val == 0) ? (regVal &~ DAQ_REG_HRDWRE_INTRRPT_SF_MSK) : (regVal | DAQ_REG_HRDWRE_INTRRPT_SF_MSK)); + if(!Feb_Interface_WriteRegister(addr[iloop], offset, data, 0, 0)) { + FILE_LOG(logERROR, ("Could not write 0x%x to %s %s interrupt subframe addr 0x%x\n", data, isTop, side[iloop], offset)); + return 0; } - if(!Feb_Interface_WriteRegister(Module_GetBottomLeftAddress (&modules[1]),offset, data,0, 0)) { - FILE_LOG(logERROR, ("Could not read bl value. Value read:%d\n", value)); - value = 0; - } } - return Feb_Control_ReadRegister(offset); + return 1; +} + +int Feb_Control_GetInterruptSubframe() { + // they need to be written separately because the left and right registers have different values for this particular register + uint32_t offset = DAQ_REG_HRDWRE; + uint32_t regVal = 0; + + char side[2][10] = {"right", "left"}; + char isTop[10]; strcpy(isTop, Module_TopAddressIsValid(&modules[1]) ? "top" : "bottom"); + unsigned int addr[2]; + addr[0] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopRightAddress (&modules[1]) : Module_GetBottomRightAddress (&modules[1]); + addr[1] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopLeftAddress (&modules[1]) : Module_GetBottomLeftAddress (&modules[1]); + uint32_t value[2] = {0, 0}; + + int iloop = 0; + for(iloop = 0; iloop < 2; ++iloop) { + if(!Feb_Interface_ReadRegister(addr[iloop], offset, ®Val)) { + FILE_LOG(logERROR, ("Could not read back %s %s interrupt subframe\n", isTop, side[iloop])); + return -1; + } + value[iloop] = (regVal & DAQ_REG_HRDWRE_INTRRPT_SF_MSK) >> DAQ_REG_HRDWRE_INTRRPT_SF_OFST; + } + + // inconsistent + if (value[0] != value[1]) { + FILE_LOG(logERROR, ("Inconsistent values of interrupt subframe betweeen left %d and right %d\n", value[0], value[1])); + return -1; + } + return value[0]; +} + +int Feb_Control_SetQuad(int val) { + // no bottom for quad + if (!Module_TopAddressIsValid(&modules[1])) { + return 1; + } + uint32_t offset = DAQ_REG_HRDWRE; + FILE_LOG(logINFO, ("Setting Quad to %d in Feb\n", val)); + unsigned int addr = Module_GetTopRightAddress (&modules[1]); + uint32_t regVal = 0; + if(!Feb_Interface_ReadRegister(addr, offset, ®Val)) { + FILE_LOG(logERROR, ("Could not read top right quad reg\n")); + return 0; + } + uint32_t data = ((val == 0) ? (regVal &~ DAQ_REG_HRDWRE_OW_MSK) : ((regVal | DAQ_REG_HRDWRE_OW_MSK) &~ DAQ_REG_HRDWRE_TOP_MSK)); + if(!Feb_Interface_WriteRegister(addr, offset, data, 0, 0)) { + FILE_LOG(logERROR, ("Could not write 0x%x to top right quad addr 0x%x\n", data, offset)); + return 0; + } + return 1; } -uint32_t Feb_Control_ReadRegister(uint32_t offset) { - uint32_t value=0; - uint32_t value1=0; - if (Module_TopAddressIsValid(&modules[1])) { - if (!Feb_Interface_ReadRegister(Module_GetTopRightAddress (&modules[1]),offset, &value)) { - FILE_LOG(logERROR, ("Could not read value. Value read:%d\n", value)); - value = 0; - } - printf("Read top right addr: 0x%08x\n", value); - if(!Feb_Interface_ReadRegister(Module_GetTopLeftAddress (&modules[1]),offset, &value1)) { - FILE_LOG(logERROR, (RED,"Could not read value. Value read:%d\n", value1)); - value1 = 0; - } - printf("Read top left addr: 0x%08x\n", value1); - if (value != value1) - value = -1; - } else { - if (!Feb_Interface_ReadRegister(Module_GetBottomRightAddress (&modules[1]),offset, &value)) { - FILE_LOG(logERROR, ("Could not read value. Value read:%d\n", value)); - value = 0; - } - printf("Read bottom right addr: 0x%08x\n", value); - if(!Feb_Interface_ReadRegister(Module_GetBottomLeftAddress (&modules[1]),offset, &value1)) { - FILE_LOG(logERROR, (RED,"Could not read value. Value read:%d\n", value1)); - value1 = 0; - } - printf("Read bottom left addr: 0x%08x\n", value1); - if (value != value1) - value = -1; +int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) { + uint32_t actualOffset = offset; + char side[2][10] = {"right", "left"}; + char isTop[10]; strcpy(isTop, Module_TopAddressIsValid(&modules[1]) ? "top" : "bottom"); + unsigned int addr[2]; + addr[0] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopRightAddress (&modules[1]) : Module_GetBottomRightAddress (&modules[1]); + addr[1] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopLeftAddress (&modules[1]) : Module_GetBottomLeftAddress (&modules[1]); + + int run[2] = {0, 0}; + // both registers + if (offset < 0x100) { + run[0] = 1; + run[1] = 1; + } + // right registers only + else if (offset >= 0x200) { + run[0] = 1; + actualOffset = offset - 0x200; + } + // left registers only + else { + run[1] = 1; + actualOffset = offset - 0x100; } - return value; + + int iloop = 0; + for(iloop = 0; iloop < 2; ++iloop) { + if(run[iloop]) { + FILE_LOG(logINFO, ("Writing 0x%x to %s %s 0x%x\n", data, isTop, side[iloop], actualOffset)); + if(!Feb_Interface_WriteRegister(addr[iloop],actualOffset, data, 0, 0)) { + FILE_LOG(logERROR, ("Could not write 0x%x to %s %s addr 0x%x\n", data, isTop, side[iloop], actualOffset)); + return 0; + } + } + } + + return 1; +} + + +int Feb_Control_ReadRegister(uint32_t offset, uint32_t* retval) { + uint32_t actualOffset = offset; + char side[2][10] = {"right", "left"}; + char isTop[10]; strcpy(isTop, Module_TopAddressIsValid(&modules[1]) ? "top" : "bottom"); + unsigned int addr[2]; + addr[0] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopRightAddress (&modules[1]) : Module_GetBottomRightAddress (&modules[1]); + addr[1] = Module_TopAddressIsValid(&modules[1]) ? Module_GetTopLeftAddress (&modules[1]) : Module_GetBottomLeftAddress (&modules[1]); + uint32_t value[2] = {0, 0}; + + int run[2] = {0, 0}; + // both registers + if (offset < 0x100) { + run[0] = 1; + run[1] = 1; + } + // right registers only + else if (offset >= 0x200) { + run[0] = 1; + actualOffset = offset - 0x200; + } + // left registers only + else { + run[1] = 1; + actualOffset = offset - 0x100; + } + + int iloop = 0; + for(iloop = 0; iloop < 2; ++iloop) { + if(run[iloop]) { + if(!Feb_Interface_ReadRegister(addr[iloop],actualOffset, &value[iloop])) { + FILE_LOG(logERROR, ("Could not read from %s %s addr 0x%x\n", isTop, side[iloop], actualOffset)); + return 0; + } + FILE_LOG(logINFO, ("Read 0x%x from %s %s 0x%x\n", value[iloop], isTop, side[iloop], actualOffset)); + *retval = value[iloop]; + // if not the other (left, not right OR right, not left), return the value + if (!run[iloop ? 0 : 1]) { + return 1; + } + } + } + + // Inconsistent values + if (value[0] != value[1]) { + FILE_LOG(logERROR, ("Inconsistent values read from left 0x%x and right 0x%x\n", value[0], value[1])); + return 0; + } + return 1; } diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.h b/slsDetectorServers/eigerDetectorServer/FebControl.h index 2e65666fd..dc46431d5 100755 --- a/slsDetectorServers/eigerDetectorServer/FebControl.h +++ b/slsDetectorServers/eigerDetectorServer/FebControl.h @@ -151,7 +151,11 @@ int64_t Feb_Control_GetMeasuredPeriod(); int64_t Feb_Control_GetSubMeasuredPeriod(); int Feb_Control_SoftwareTrigger(); +int Feb_Control_SetInterruptSubframe(int val); +int Feb_Control_GetInterruptSubframe(); +int Feb_Control_SetQuad(int val); -uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data); -uint32_t Feb_Control_ReadRegister(uint32_t offset); + +int Feb_Control_WriteRegister(uint32_t offset, uint32_t data); +int Feb_Control_ReadRegister(uint32_t offset, uint32_t* retval); diff --git a/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h b/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h index 686771347..87e78dacc 100755 --- a/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h +++ b/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h @@ -14,8 +14,16 @@ #define DAQ_REG_SUBFRAME_EXPOSURES 6 #define DAQ_REG_SUBFRAME_PERIOD 7 //also pg and fifo status register +#define DAQ_REG_HRDWRE 12 -#define DAQ_REG_RO_OFFSET 12 +#define DAQ_REG_HRDWRE_OW_OFST (0) +#define DAQ_REG_HRDWRE_OW_MSK (0x00000001 << DAQ_REG_HRDWRE_OW_OFST) +#define DAQ_REG_HRDWRE_TOP_OFST (1) +#define DAQ_REG_HRDWRE_TOP_MSK (0x00000001 << DAQ_REG_HRDWRE_TOP_OFST) +#define DAQ_REG_HRDWRE_INTRRPT_SF_OFST (3) +#define DAQ_REG_HRDWRE_INTRRPT_SF_MSK (0x00000001 << DAQ_REG_HRDWRE_INTRRPT_SF_OFST) + +#define DAQ_REG_RO_OFFSET 20 #define DAQ_REG_STATUS (DAQ_REG_RO_OFFSET + 0) //also pg and fifo status register #define FEB_REG_STATUS (DAQ_REG_RO_OFFSET + 3) #define MEAS_SUBPERIOD_REG (DAQ_REG_RO_OFFSET + 4) diff --git a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer index 9d18f2e85..f86126441 100755 Binary files a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer and b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer differ diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c index e8e80bcad..c08edbe7e 100755 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -464,19 +464,25 @@ void setupDetector() { /* advanced read/write reg */ -uint32_t writeRegister(uint32_t offset, uint32_t data) { +int writeRegister(uint32_t offset, uint32_t data) { #ifdef VIRTUAL - return 0; + return OK; #else - return Feb_Control_WriteRegister(offset, data); + if(!Feb_Control_WriteRegister(offset, data)) { + return FAIL; + } + return OK; #endif } -uint32_t readRegister(uint32_t offset) { +int readRegister(uint32_t offset, uint32_t* retval) { #ifdef VIRTUAL - return 0; + return OK; #else - return Feb_Control_ReadRegister(offset); + if(!Feb_Control_ReadRegister(offset, retval)) { + return FAIL; + } + return OK; #endif } @@ -1310,10 +1316,19 @@ int setDetectorPosition(int pos[]) { #endif } -void setQuad(int value) { +int setQuad(int value) { + if (value < 0) { + return OK; + } #ifndef VIRTUAL - Beb_SetQuad(value); + if (Beb_SetQuad(value) == FAIL) { + return FAIL; + } + if (!Feb_Control_SetQuad(value)) { + return FAIL; + } #endif + return OK; } int getQuad() { @@ -1324,6 +1339,25 @@ int getQuad() { #endif } +int setInterruptSubframe(int value) { + if(value < 0) + return FAIL; +#ifndef VIRTUAL + if(!Feb_Control_SetInterruptSubframe(value)) { + return FAIL; + } + return OK; +#endif +} + +int getInterruptSubframe() { +#ifdef VIRTUAL + return 0; +#else + return Feb_Control_GetInterruptSubframe(); +#endif +} + int enableTenGigabitEthernet(int val) { if (val!=-1) { FILE_LOG(logINFO, ("Setting 10Gbe: %d\n", (val > 0) ? 1 : 0)); diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h index 7939cc0b4..7eb16292e 100755 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h @@ -1,7 +1,7 @@ #pragma once #include "sls_detector_defs.h" -#define REQUIRED_FIRMWARE_VERSION (22) +#define REQUIRED_FIRMWARE_VERSION (24) #define IDFILECOMMAND "more /home/root/executables/detid.txt" #define STATUS_IDLE 0 diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h index 62df10a67..ff45791f7 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h @@ -74,8 +74,8 @@ int setDefaultDacs(); // advanced read/write reg #ifdef EIGERD -uint32_t writeRegister(uint32_t offset, uint32_t data); -uint32_t readRegister(uint32_t offset); +int writeRegister(uint32_t offset, uint32_t data); +int readRegister(uint32_t offset, uint32_t* retval); #elif GOTTHARDD uint32_t writeRegister16And32(uint32_t offset, uint32_t data); //FIXME its not there in ctb or moench? uint32_t readRegister16And32(uint32_t offset); @@ -250,8 +250,10 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32 int setDetectorPosition(int pos[]); #endif #ifdef EIGERD -void setQuad(int value); +int setQuad(int value); int getQuad(); +int setInterruptSubframe(int value); +int getInterruptSubframe(); #endif #if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(EIGERD) int enableTenGigabitEthernet(int val); diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c index 98b56c868..4bfa279da 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c @@ -246,6 +246,8 @@ const char* getFunctionName(enum detFuncs func) { case F_GET_STARTING_FRAME_NUMBER: return "F_GET_STARTING_FRAME_NUMBER"; case F_SET_QUAD: return "F_SET_QUAD"; case F_GET_QUAD: return "F_GET_QUAD"; + case F_SET_INTERRUPT_SUBFRAME: return "F_SET_INTERRUPT_SUBFRAME"; + case F_GET_INTERRUPT_SUBFRAME: return "F_GET_INTERRUPT_SUBFRAME"; default: return "Unknown Function"; } } @@ -332,6 +334,8 @@ void function_table() { flist[F_GET_STARTING_FRAME_NUMBER] = &get_starting_frame_number; flist[F_SET_QUAD] = &set_quad; flist[F_GET_QUAD] = &get_quad; + flist[F_SET_INTERRUPT_SUBFRAME] = &set_interrupt_subframe; + flist[F_GET_INTERRUPT_SUBFRAME] = &get_interrupt_subframe; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -1116,11 +1120,23 @@ int write_register(int file_des) { if (Server_VerifyLock() == OK) { #ifdef GOTTHARDD retval = writeRegister16And32(addr, val); +#elif EIGERD + if(writeRegister(addr, val) == FAIL) { + ret = FAIL; + sprintf(mess,"Could not write to register 0x%x.\n", addr); + FILE_LOG(logERROR,(mess)); + } else { + if(readRegister(addr, &retval) == FAIL) { + ret = FAIL; + sprintf(mess,"Could not read register 0x%x.\n", addr); + FILE_LOG(logERROR,(mess)); + } + } #else retval = writeRegister(addr, val); #endif // validate - if (retval != val) { + if (ret == OK && retval != val) { ret = FAIL; sprintf(mess,"Could not write to register 0x%x. Wrote 0x%x but read 0x%x\n", addr, val, retval); FILE_LOG(logERROR,(mess)); @@ -1148,6 +1164,12 @@ int read_register(int file_des) { // get #ifdef GOTTHARDD retval = readRegister16And32(addr); +#elif EIGERD + if(readRegister(addr, &retval) == FAIL) { + ret = FAIL; + sprintf(mess,"Could not read register 0x%x.\n", addr); + FILE_LOG(logERROR,(mess)); + } #else retval = readRegister(addr); #endif @@ -4103,13 +4125,18 @@ int set_quad(int file_des) { #else // only set if (Server_VerifyLock() == OK) { - setQuad(arg); - int retval = getQuad(); - if (arg != retval) { + if (setQuad(arg) == FAIL) { ret = FAIL; - sprintf(mess, "Could not set quad. Set %d, but read %d\n", retval, arg); + sprintf(mess, "Could not set quad.\n"); FILE_LOG(logERROR,(mess)); - } + } else { + int retval = getQuad(); + if (arg != retval) { + ret = FAIL; + sprintf(mess, "Could not set quad. Set %d, but read %d\n", retval, arg); + FILE_LOG(logERROR,(mess)); + } + } } #endif return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); @@ -4130,4 +4157,58 @@ int get_quad(int file_des) { FILE_LOG(logDEBUG1, ("Quad retval: %u\n", retval)); #endif return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); +} + +int set_interrupt_subframe(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = 0; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logINFO, ("Setting interrupt subframe: %u\n", arg)); + +#ifndef EIGERD + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + if(setInterruptSubframe(arg) == FAIL) { + ret = FAIL; + sprintf(mess, "Could not set Intertupt Subframe in FEB.\n"); + FILE_LOG(logERROR,(mess)); + } else { + int retval = getInterruptSubframe(); + if (arg != retval) { + ret = FAIL; + sprintf(mess, "Could not set Intertupt Subframe. Set %d, but read %d\n", retval, arg); + FILE_LOG(logERROR,(mess)); + } + } + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); +} + +int get_interrupt_subframe(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int retval = -1; + + FILE_LOG(logDEBUG1, ("Getting interrupt subframe\n")); + +#ifndef EIGERD + functionNotImplemented(); +#else + // get only + retval = getInterruptSubframe(); + if (retval == -1) { + ret = FAIL; + sprintf(mess, "Could not get Intertupt Subframe or inconsistent values between left and right. \n"); + FILE_LOG(logERROR,(mess)); + } else { + FILE_LOG(logDEBUG1, ("Interrupt subframe retval: %u\n", retval)); + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); } \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h index f7f8c7fb5..25feabf82 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h @@ -106,4 +106,6 @@ int set_external_sampling(int); int set_starting_frame_number(int); int get_starting_frame_number(int); int set_quad(int); -int get_quad(int); \ No newline at end of file +int get_quad(int); +int set_interrupt_subframe(int); +int get_interrupt_subframe(int); \ No newline at end of file diff --git a/slsDetectorSoftware/include/multiSlsDetector.h b/slsDetectorSoftware/include/multiSlsDetector.h index f4598817a..3d90a48fe 100755 --- a/slsDetectorSoftware/include/multiSlsDetector.h +++ b/slsDetectorSoftware/include/multiSlsDetector.h @@ -819,6 +819,20 @@ class multiSlsDetector : public virtual slsDetectorDefs { */ int setReadOutFlags(readOutFlags flag = GET_READOUT_FLAGS, int detPos = -1); + /** + * Set Interrupt last sub frame (Only for Eiger) + * @param enable true if interrupt last subframe set, else false + * @param detPos -1 for all detectors in list or specific detector position + */ + void setInterruptSubframe(const bool enable, int detPos = -1); + + /** + * Get Interrupt last sub frame (Only for Eiger) + * @param detPos -1 for all detectors in list or specific detector position + * @returns 1 if interrupt last subframe set, else 0, -1 different values + */ + int getInterruptSubframe(int detPos = -1); + /** * Write in a register. For Advanced users * @param addr address of register diff --git a/slsDetectorSoftware/include/slsDetector.h b/slsDetectorSoftware/include/slsDetector.h index 7b7529e59..eae096901 100755 --- a/slsDetectorSoftware/include/slsDetector.h +++ b/slsDetectorSoftware/include/slsDetector.h @@ -758,6 +758,18 @@ class slsDetector : public virtual slsDetectorDefs{ */ int setReadOutFlags(readOutFlags flag = GET_READOUT_FLAGS); + /** + * Set Interrupt last sub frame (Only for Eiger) + * @param enable true if interrupt last subframe set, else false + */ + void setInterruptSubframe(const bool enable); + + /** + * Get Interrupt last sub frame (Only for Eiger) + * @returns true if interrupt last subframe set, else false + */ + bool getInterruptSubframe(); + /** * Write in a register. For Advanced users * @param addr address of register diff --git a/slsDetectorSoftware/src/multiSlsDetector.cpp b/slsDetectorSoftware/src/multiSlsDetector.cpp index ce38c7d90..c7b7dfab0 100755 --- a/slsDetectorSoftware/src/multiSlsDetector.cpp +++ b/slsDetectorSoftware/src/multiSlsDetector.cpp @@ -1374,6 +1374,27 @@ int multiSlsDetector::setReadOutFlags(readOutFlags flag, int detPos) { return sls::minusOneIfDifferent(r); } +void multiSlsDetector::setInterruptSubframe(const bool enable, int detPos) { + // single + if (detPos >= 0) { + detectors[detPos]->setInterruptSubframe(enable); + } + + // multi + parallelCall(&slsDetector::setInterruptSubframe, enable); +} + +int multiSlsDetector::getInterruptSubframe(int detPos) { + // single + if (detPos >= 0) { + return static_cast(detectors[detPos]->getInterruptSubframe()); + } + + // multi + auto r = parallelCall(&slsDetector::getInterruptSubframe); + return sls::minusOneIfDifferent(r); +} + uint32_t multiSlsDetector::writeRegister(uint32_t addr, uint32_t val, int detPos) { // single diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index f439f7861..213d428d6 100755 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -1526,6 +1526,21 @@ int slsDetector::setReadOutFlags(readOutFlags flag) { return shm()->roFlags; } +void slsDetector::setInterruptSubframe(const bool enable) { + int arg = static_cast(enable); + FILE_LOG(logDEBUG1) << "Setting Interrupt subframe to " << arg; + sendToDetector(F_SET_INTERRUPT_SUBFRAME, arg, nullptr); +} + +bool slsDetector::getInterruptSubframe() { + int retval = -1; + FILE_LOG(logDEBUG1) << "Getting Interrupt subframe"; + sendToDetector(F_GET_INTERRUPT_SUBFRAME, nullptr, retval); + FILE_LOG(logDEBUG1) << "Interrupt subframe: " << retval; + return static_cast(retval); +} + + uint32_t slsDetector::writeRegister(uint32_t addr, uint32_t val) { uint32_t args[]{addr, val}; uint32_t retval = -1; diff --git a/slsDetectorSoftware/src/slsDetectorCommand.cpp b/slsDetectorSoftware/src/slsDetectorCommand.cpp index 8c4831cd8..423af2813 100755 --- a/slsDetectorSoftware/src/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/src/slsDetectorCommand.cpp @@ -383,6 +383,13 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) { descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced; ++i; + /*! \page config + - interruptsubframe [i] sets/gets the interrupt subframe flag. Setting it to 1 will interrupt the last subframe at the required exposure time. By default, this is disabled and set to 0, ie. it will wait for the last sub frame to finish exposing. Used for EIGER in 32 bit mode only. \c Returns \c (int). + */ + descrToFuncMap[i].m_pFuncName="interruptsubframe"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced; + ++i; + /*! \page config - extsig [flag] sets/gets the mode of the external signal. Options: \c off, \c gate_in_active_high, \c gate_in_active_low, \c trigger_in_rising_edge, \c trigger_in_falling_edge, \c ro_trigger_in_rising_edge, \c ro_trigger_in_falling_edge, \c gate_out_active_high, \c gate_out_active_low, \c trigger_out_rising_edge, \c trigger_out_falling_edge, \c ro_trigger_out_rising_edge, @@ -4737,7 +4744,15 @@ std::string slsDetectorCommand::cmdAdvanced(int narg, const char * const args[], return std::string("unknown"); - } else if (cmd == "extsig") { + } else if (cmd=="interruptsubframe") { + if (action==PUT_ACTION) { + int ival = -1; + if (!sscanf(args[1],"%d",&ival)) + return std::string("could not scan interrupt sub frame parameter ") + std::string(args[1]); + myDet->setInterruptSubframe(ival > 0 ? true : false); + } + return std::to_string(myDet->getInterruptSubframe()); + } else if (cmd == "extsig") { externalSignalFlag flag = GET_EXTERNAL_SIGNAL_FLAG; if (action == PUT_ACTION) { @@ -4858,7 +4873,7 @@ std::string slsDetectorCommand::helpAdvanced(int action) { os << "extsig mode \t sets the mode of the external signal. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl; os << "flags mode \t sets the readout flags to mode. can be none, storeinram, tot, continous, parallel, nonparallel, digital, analog_digital, overlow, nooverflow, unknown." << std::endl; - + os << "interruptsubframe flag \t sets the interrupt subframe flag. Setting it to 1 will interrupt the last subframe at the required exposure time. By default, this is disabled and set to 0, ie. it will wait for the last sub frame to finish exposing. Used for EIGER in 32 bit mode only." << std::endl; os << "programfpga f \t programs the fpga with file f (with .pof extension)." << std::endl; os << "resetfpga f \t resets fpga, f can be any value" << std::endl; os << "copydetectorserver s p \t copies the detector server s via tftp from pc with hostname p and changes respawn server. Not for Eiger. " << std::endl; @@ -4874,6 +4889,7 @@ std::string slsDetectorCommand::helpAdvanced(int action) { os << "extsig \t gets the mode of the external signal. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl; os << "flags \t gets the readout flags. can be none, storeinram, tot, continous, parallel, nonparallel, digital, analog_digital, overflow, nooverflow, unknown" << std::endl; + os << "interruptsubframe \t gets the interrupt subframe flag. Setting it to 1 will interrupt the last subframe at the required exposure time. By default, this is disabled and set to 0, ie. it will wait for the last sub frame to finish exposing. Used for EIGER in 32 bit mode only." << std::endl; os << "led \t returns led status (0 off, 1 on)" << std::endl; os << "powerchip \t gets if the chip has been powered on or off" << std::endl; os << "auto_comp_disable \t Currently not implemented. gets if the automatic comparator diable mode is enabled/disabled" << std::endl; diff --git a/slsReceiverSoftware/include/DataProcessor.h b/slsReceiverSoftware/include/DataProcessor.h index 678a3ff25..9c5febfdb 100755 --- a/slsReceiverSoftware/include/DataProcessor.h +++ b/slsReceiverSoftware/include/DataProcessor.h @@ -39,6 +39,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { * @param act pointer to activated * @param depaden pointer to deactivated padding enable * @param sm pointer to silent mode + * @param qe pointer to quad Enable * @param cdl pointer to vector or ctb digital bits enable * @param cdo pointer to digital bits offset * @param cad pointer to ctb analog databytes @@ -46,7 +47,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat* ftype, bool fwenable, bool* mfwenable, bool* dsEnable, bool* gpEnable, uint32_t* dr, uint32_t* freq, uint32_t* timer, - bool* fp, bool* act, bool* depaden, bool* sm, + bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, std::vector * cdl, int* cdo, int* cad); /** @@ -368,6 +369,9 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { /** Silent Mode */ bool* silentMode; + /** quad enable */ + bool* quadEnable; + /** frame padding */ bool* framePadding; diff --git a/slsReceiverSoftware/include/GeneralData.h b/slsReceiverSoftware/include/GeneralData.h index 464ffe544..87ad410d0 100755 --- a/slsReceiverSoftware/include/GeneralData.h +++ b/slsReceiverSoftware/include/GeneralData.h @@ -178,8 +178,10 @@ public: /** * Enable Gap Pixels changes member variables * @param enable true if gap pixels enable, else false + * @param dr dynamic range + * @param q quad enable */ - virtual void SetGapPixelsEnable(bool b, int dr) { + virtual void SetGapPixelsEnable(bool b, int dr, bool q) { FILE_LOG(logERROR) << "SetGapPixelsEnable is a generic function that should be overloaded by a derived class"; }; @@ -463,13 +465,17 @@ class EigerData : public GeneralData { * Enable Gap Pixels changes member variables * @param enable true if gap pixels enable, else false * @param dr dynamic range + * @param q quad enable */ - void SetGapPixelsEnable(bool b, int dr) { + void SetGapPixelsEnable(bool b, int dr, bool q) { if (dr == 4) b = 0; switch((int)b) { case 1: nPixelsX = (256 * 2) + 3; + if (q) { + nPixelsX = (256 * 2) + 2; + } nPixelsY = 256 + 1; imageSize = nPixelsX * nPixelsY * ((dr > 16) ? 4 : // 32 bit ((dr > 8) ? 2 : // 16 bit diff --git a/slsReceiverSoftware/include/slsReceiverImplementation.h b/slsReceiverSoftware/include/slsReceiverImplementation.h index b50f1309b..1ffd04a46 100755 --- a/slsReceiverSoftware/include/slsReceiverImplementation.h +++ b/slsReceiverSoftware/include/slsReceiverImplementation.h @@ -399,8 +399,9 @@ class slsReceiverImplementation : private virtual slsDetectorDefs { /** * Set Quad type Enable (eiger and hardware specific) * @param true if quad enabled, else false + * @return OK or FAIL */ - void setQuad(const bool b); + int setQuad(const bool b); /** * Set readout flags (eiger, chiptestboard, moench) diff --git a/slsReceiverSoftware/src/DataProcessor.cpp b/slsReceiverSoftware/src/DataProcessor.cpp index ea0a9bc37..766a3d72e 100755 --- a/slsReceiverSoftware/src/DataProcessor.cpp +++ b/slsReceiverSoftware/src/DataProcessor.cpp @@ -27,7 +27,7 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f, fileFormat* ftype, bool fwenable, bool* mfwenable, bool* dsEnable, bool* gpEnable, uint32_t* dr, uint32_t* freq, uint32_t* timer, - bool* fp, bool* act, bool* depaden, bool* sm, + bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, std::vector * cdl, int* cdo, int* cad) : ThreadObject(ind), @@ -49,6 +49,7 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f, activated(act), deactivatedPaddingEnable(depaden), silentMode(sm), + quadEnable(qe), framePadding(fp), ctbDbitList(cdl), ctbDbitOffset(cdo), @@ -558,29 +559,31 @@ void DataProcessor::InsertGapPixels(char* buf, uint32_t dr) { memset(tempBuffer, 0xFF, generalData->imageSize); + int rightChip = ((*quadEnable) ? 0 : index); // quad enable, then faking both to be left chips const uint32_t nx = generalData->nPixelsX; const uint32_t ny = generalData->nPixelsY; const uint32_t npx = nx * ny; - + bool group3 = (*quadEnable) ? false : true; // if quad enabled, no last line for left chips char* srcptr = nullptr; char* dstptr = nullptr; const uint32_t b1px = generalData->imageSize / (npx); // not double as not dealing with 4 bit mode const uint32_t b2px = 2 * b1px; - const uint32_t b1pxofst = (index != 0 ? b1px : 0); // left fpga (index 0) has no extra 1px offset, but right fpga has + const uint32_t b1pxofst = (rightChip == 0 ? 0 : b1px); // left fpga (rightChip 0) has no extra 1px offset, but right fpga has const uint32_t b1chip = 256 * b1px; const uint32_t b1line = (nx * b1px); + const uint32_t bgroup3chip = b1chip + (group3 ? b1px : 0); // copying line by line srcptr = buf; - dstptr = tempBuffer + b1line + b1pxofst; // left fpga (index 0) has no extra 1px offset, but right fpga has + dstptr = tempBuffer + b1line + b1pxofst; // left fpga (rightChip 0) has no extra 1px offset, but right fpga has for (uint32_t i = 0; i < (ny-1); ++i) { memcpy(dstptr, srcptr, b1chip); srcptr += b1chip; dstptr += (b1chip + b2px); memcpy(dstptr, srcptr, b1chip); srcptr += b1chip; - dstptr += (b1chip + b1px); + dstptr += bgroup3chip; } // vertical filling of values @@ -597,28 +600,36 @@ void DataProcessor::InsertGapPixels(char* buf, uint32_t dr) { dstgp1 = srcgp1 + b1px; srcgp2 = srcgp1 + b3px; dstgp2 = dstgp1 + b1px; - if (index == 0u) { - srcgp3 = srcptr + b1line - b2px; - dstgp3 = srcgp3 + b1px; - } else { - srcgp3 = srcptr + b1px; - dstgp3 = srcptr; + if (group3) { + if (rightChip == 0u) { + srcgp3 = srcptr + b1line - b2px; + dstgp3 = srcgp3 + b1px; + } else { + srcgp3 = srcptr + b1px; + dstgp3 = srcptr; + } } switch (dr) { case 8: (*((uint8_t*)srcgp1)) = (*((uint8_t*)srcgp1))/2; (*((uint8_t*)dstgp1)) = (*((uint8_t*)srcgp1)); (*((uint8_t*)srcgp2)) = (*((uint8_t*)srcgp2))/2; (*((uint8_t*)dstgp2)) = (*((uint8_t*)srcgp2)); - (*((uint8_t*)srcgp3)) = (*((uint8_t*)srcgp3))/2; (*((uint8_t*)dstgp3)) = (*((uint8_t*)srcgp3)); + if (group3) { + (*((uint8_t*)srcgp3)) = (*((uint8_t*)srcgp3))/2; (*((uint8_t*)dstgp3)) = (*((uint8_t*)srcgp3)); + } break; case 16: (*((uint16_t*)srcgp1)) = (*((uint16_t*)srcgp1))/2; (*((uint16_t*)dstgp1)) = (*((uint16_t*)srcgp1)); (*((uint16_t*)srcgp2)) = (*((uint16_t*)srcgp2))/2; (*((uint16_t*)dstgp2)) = (*((uint16_t*)srcgp2)); - (*((uint16_t*)srcgp3)) = (*((uint16_t*)srcgp3))/2; (*((uint16_t*)dstgp3)) = (*((uint16_t*)srcgp3)); + if (group3) { + (*((uint16_t*)srcgp3)) = (*((uint16_t*)srcgp3))/2; (*((uint16_t*)dstgp3)) = (*((uint16_t*)srcgp3)); + } break; default: (*((uint32_t*)srcgp1)) = (*((uint32_t*)srcgp1))/2; (*((uint32_t*)dstgp1)) = (*((uint32_t*)srcgp1)); (*((uint32_t*)srcgp2)) = (*((uint32_t*)srcgp2))/2; (*((uint32_t*)dstgp2)) = (*((uint32_t*)srcgp2)); - (*((uint32_t*)srcgp3)) = (*((uint32_t*)srcgp3))/2; (*((uint32_t*)dstgp3)) = (*((uint32_t*)srcgp3)); + if (group3) { + (*((uint32_t*)srcgp3)) = (*((uint32_t*)srcgp3))/2; (*((uint32_t*)dstgp3)) = (*((uint32_t*)srcgp3)); + } break; } srcptr += b1line; diff --git a/slsReceiverSoftware/src/slsReceiverImplementation.cpp b/slsReceiverSoftware/src/slsReceiverImplementation.cpp index 33b65a213..e78f25f9e 100755 --- a/slsReceiverSoftware/src/slsReceiverImplementation.cpp +++ b/slsReceiverSoftware/src/slsReceiverImplementation.cpp @@ -501,7 +501,7 @@ int slsReceiverImplementation::setGapPixelsEnable(const bool b) { gapPixelsEnable = b; // side effects - generalData->SetGapPixelsEnable(b, dynamicRange); + generalData->SetGapPixelsEnable(b, dynamicRange, quadEnable); for (const auto &it : dataProcessor) it->SetPixelDimension(); if (SetupFifoStructure() == FAIL) @@ -512,10 +512,17 @@ int slsReceiverImplementation::setGapPixelsEnable(const bool b) { } -void slsReceiverImplementation::setQuad(const bool b) { +int slsReceiverImplementation::setQuad(const bool b) { if (quadEnable != b) { quadEnable = b; + generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, b); + // to update npixelsx, npixelsy in file writer + for (const auto &it : dataProcessor) + it->SetPixelDimension(); + if (SetupFifoStructure() == FAIL) + return FAIL; + if (!quadEnable) { for (const auto &it : dataStreamer) { it->SetNumberofDetectors(numDet); @@ -533,6 +540,7 @@ void slsReceiverImplementation::setQuad(const bool b) { } } FILE_LOG(logINFO) << "Quad Enable: " << quadEnable; + return OK; } int slsReceiverImplementation::setReadOutFlags(const readOutFlags f) { @@ -750,7 +758,7 @@ int slsReceiverImplementation::setNumberofUDPInterfaces(const int n) { fileWriteEnable, &masterFileWriteEnable, &dataStreamEnable, &gapPixelsEnable, &dynamicRange, &streamingFrequency, &streamingTimerInMs, &framePadding, &activated, - &deactivatedPaddingEnable, &silentMode, &ctbDbitList, + &deactivatedPaddingEnable, &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes)); dataProcessor[i]->SetGeneralData(generalData); } catch (...) { @@ -1085,7 +1093,7 @@ int slsReceiverImplementation::setDynamicRange(const uint32_t i) { if (dynamicRange != i) { dynamicRange = i; generalData->SetDynamicRange(i, tengigaEnable); - generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange); + generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable); // to update npixelsx, npixelsy in file writer for (const auto &it : dataProcessor) it->SetPixelDimension(); @@ -1103,6 +1111,7 @@ int slsReceiverImplementation::setTenGigaEnable(const bool b) { switch (myDetectorType) { case EIGER: generalData->SetTenGigaEnable(b, dynamicRange); + generalData->SetGapPixelsEnable(gapPixelsEnable, dynamicRange, quadEnable); break; case MOENCH: generalData->setImageSize(adcEnableMask, numberOfAnalogSamples, @@ -1240,7 +1249,7 @@ int slsReceiverImplementation::setDetectorType(const detectorType d) { &masterFileWriteEnable, &dataStreamEnable, &gapPixelsEnable, &dynamicRange, &streamingFrequency, &streamingTimerInMs, &framePadding, &activated, &deactivatedPaddingEnable, - &silentMode, &ctbDbitList, &ctbDbitOffset, + &silentMode, &quadEnable, &ctbDbitList, &ctbDbitOffset, &ctbAnalogDataBytes)); } catch (...) { FILE_LOG(logERROR) diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index d773613f4..b7bc792d5 100755 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -1314,7 +1314,10 @@ int slsReceiverTCPIPInterface::set_quad_type(Interface &socket) { if (quadEnable >= 0) { VerifyIdle(socket); FILE_LOG(logDEBUG1) << "Setting quad:" << quadEnable; - impl()->setQuad(quadEnable == 0 ? false : true); + ret = impl()->setQuad(quadEnable == 0 ? false : true); + if (ret == FAIL) { + throw RuntimeError("Could not set Quad due to fifo structure"); + } } int retval = impl()->getQuad() ? 1 : 0; validate(quadEnable, retval, "set quad", DEC); diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index e1bf69644..593d4110a 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -91,6 +91,8 @@ enum detFuncs{ F_GET_STARTING_FRAME_NUMBER, F_SET_QUAD, F_GET_QUAD, + F_SET_INTERRUPT_SUBFRAME, + F_GET_INTERRUPT_SUBFRAME, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 128, /**< detector function should not exceed this (detector server should not compile anyway) */ @@ -236,6 +238,8 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_STARTING_FRAME_NUMBER: return "F_GET_STARTING_FRAME_NUMBER"; case F_SET_QUAD: return "F_SET_QUAD"; case F_GET_QUAD: return "F_GET_QUAD"; + case F_SET_INTERRUPT_SUBFRAME: return "F_SET_INTERRUPT_SUBFRAME"; + case F_GET_INTERRUPT_SUBFRAME: return "F_GET_INTERRUPT_SUBFRAME"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 4f9d99b0f..21f7c5e05 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -3,8 +3,8 @@ #define APIMOENCH 0x181108 #define APICTB 0x190604 #define APIGOTTHARD 0x190715 -#define APIEIGER 0x190723 #define APILIB 0x190723 #define APIRECEIVER 0x190722 #define APIGUI 0x190723 #define APIJUNGFRAU 0x190730 +#define APIEIGER 0x190731