eiger server: quad, interrupt subframe, reg left and right (#45)

* eiger server: quad, interrupt subframe, reg left and right

*  eiger server: beb can fail in setting up quad, quad and gap pixels
This commit is contained in:
Dhanya Thattil 2019-08-06 10:12:34 +02:00 committed by Erik Fröjdh
parent e17de0609c
commit d72b6c3659
25 changed files with 463 additions and 105 deletions

View File

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

View File

@ -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) {
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);
Beb_SetDetectorPosition(Beb_positions);
}
return Beb_SetDetectorPosition(Beb_positions);
}
int Beb_GetQuad() {

View File

@ -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);

View File

@ -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, &regVal)) {
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;
}
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;
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;
}
}
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, &regVal)) {
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, &regVal)) {
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;
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;
}
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;
// right registers only
else if (offset >= 0x200) {
run[0] = 1;
actualOffset = offset - 0x200;
}
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;
// left registers only
else {
run[1] = 1;
actualOffset = offset - 0x100;
}
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;
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;
}
printf("Read bottom left addr: 0x%08x\n", value1);
if (value != value1)
value = -1;
}
return value;
}
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;
}

View File

@ -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);

View File

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

View File

@ -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));

View File

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

View File

@ -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);

View File

@ -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,7 +4125,11 @@ int set_quad(int file_des) {
#else
// only set
if (Server_VerifyLock() == OK) {
setQuad(arg);
if (setQuad(arg) == FAIL) {
ret = FAIL;
sprintf(mess, "Could not set quad.\n");
FILE_LOG(logERROR,(mess));
} else {
int retval = getQuad();
if (arg != retval) {
ret = FAIL;
@ -4111,6 +4137,7 @@ int set_quad(int file_des) {
FILE_LOG(logERROR,(mess));
}
}
}
#endif
return Server_SendResult(file_des, INT32, UPDATE, NULL, 0);
}
@ -4131,3 +4158,57 @@ int get_quad(int file_des) {
#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));
}

View File

@ -107,3 +107,5 @@ int set_starting_frame_number(int);
int get_starting_frame_number(int);
int set_quad(int);
int get_quad(int);
int set_interrupt_subframe(int);
int get_interrupt_subframe(int);

View File

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

View File

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

View File

@ -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<int>(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

View File

@ -1526,6 +1526,21 @@ int slsDetector::setReadOutFlags(readOutFlags flag) {
return shm()->roFlags;
}
void slsDetector::setInterruptSubframe(const bool enable) {
int arg = static_cast<int>(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<bool>(retval);
}
uint32_t slsDetector::writeRegister(uint32_t addr, uint32_t val) {
uint32_t args[]{addr, val};
uint32_t retval = -1;

View File

@ -383,6 +383,13 @@ slsDetectorCommand::slsDetectorCommand(multiSlsDetector *det) {
descrToFuncMap[i].m_pFuncPtr = &slsDetectorCommand::cmdAdvanced;
++i;
/*! \page config
- <b>interruptsubframe [i]</b> 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
- <b>extsig [flag]</b> 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,6 +4744,14 @@ std::string slsDetectorCommand::cmdAdvanced(int narg, const char * const args[],
return std::string("unknown");
} 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;
@ -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;

View File

@ -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 <int> * 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;

View File

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

View File

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

View File

@ -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 <int> * 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) {
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));
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));
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));
if (group3) {
(*((uint32_t*)srcgp3)) = (*((uint32_t*)srcgp3))/2; (*((uint32_t*)dstgp3)) = (*((uint32_t*)srcgp3));
}
break;
}
srcptr += b1line;

View File

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

View File

@ -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);

View File

@ -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";

View File

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