slsDetectorSoftware: Eiger server, added 3 commands, measuredperiod,measuredsubperiod, status trigger. measured period is in 10ns in det server, status trigger reads reg,sets bit and unsets bit

This commit is contained in:
maliakal_d 2018-08-10 19:14:05 +02:00
parent c934e92a41
commit 0018fa46f8
19 changed files with 282 additions and 40 deletions

View File

@ -121,6 +121,8 @@ enum detFuncs{
F_STORAGE_CELL_START, /** < storage cell start */
F_CHECK_VERSION, /** < check version compatibility */
F_SOFTWARE_TRIGGER, /** < software trigger */
/* Always append functions hereafter!!! */
/* Always append functions before!!! */

View File

@ -1,5 +1,5 @@
/** API versions */
#define APIRECEIVER 0x180517
#define APIEIGER 0x180528
#define APIEIGER 0x180810
#define APIJUNGFRAU 0x180628
#define APIGOTTHARD 0x180529

View File

@ -37,6 +37,7 @@ unsigned int Feb_Control_acquireNReadoutMode; //safe or parallel, half or full s
unsigned int Feb_Control_triggerMode; //internal timer, external start, external window, signal polarity (external trigger and enable)
unsigned int Feb_Control_externalEnableMode; //external enabling engaged and it's polarity
unsigned int Feb_Control_subFrameMode;
unsigned int Feb_Control_softwareTrigger;
unsigned int Feb_Control_nimages;
@ -1958,6 +1959,56 @@ int Feb_Control_GetRightFPGATemp(){
return (int)temperature;
}
int64_t Feb_Control_GetMeasuredPeriod() {
unsigned int sub_num = (Module_TopAddressIsValid(&modules[1])) ?
Module_GetTopLeftAddress (&modules[1]):
Module_GetBottomLeftAddress (&modules[1]);
unsigned int value = 0;
Feb_Interface_ReadRegister(sub_num,MEAS_PERIOD_REG, &value);
return value*10;
}
int64_t Feb_Control_GetSubMeasuredPeriod() {
unsigned int sub_num = (Module_TopAddressIsValid(&modules[1])) ?
Module_GetTopLeftAddress (&modules[1]):
Module_GetBottomLeftAddress (&modules[1]);
unsigned int value = 0;
Feb_Interface_ReadRegister(sub_num,MEAS_SUBPERIOD_REG, &value);
return value*10;
}
int Feb_Control_SoftwareTrigger() {
unsigned int orig_value = 0;
Feb_Interface_ReadRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS, &orig_value);
unsigned int cmd = orig_value | DAQ_REG_CHIP_CMDS_INT_TRIGGER;
if(Feb_Control_activated) {
// set trigger bit
#ifdef VERBOSE
cprintf(BLUE,"Setting Trigger, Register:0x%x\n",cmd);
#endif
if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,cmd,0,0)) {
cprintf(RED,"Warning: Could not give software trigger\n");
return 0;
}
// unset trigger bit
#ifdef VERBOSE
cprintf(BLUE,"Unsetting Trigger, Register:0x%x\n",orig_value);
#endif
if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,orig_value,0,0)) {
cprintf(RED,"Warning: Could not give software trigger\n");
return 0;
}
cprintf(BLUE,"Software Internal Trigger Sent!\n");
}
return 1;
}
uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
uint32_t value=0;

View File

@ -200,6 +200,11 @@ int Feb_Control_GetModuleNumber();
int Feb_Control_GetLeftFPGATemp();
int Feb_Control_GetRightFPGATemp();
int64_t Feb_Control_GetMeasuredPeriod();
int64_t Feb_Control_GetSubMeasuredPeriod();
int Feb_Control_SoftwareTrigger();
uint32_t Feb_Control_WriteRegister(uint32_t offset, uint32_t data);
uint32_t Feb_Control_ReadRegister(uint32_t offset);
#endif

View File

@ -22,10 +22,10 @@
#define DAQ_REG_RO_OFFSET 12
#define DAQ_REG_STATUS (0 + DAQ_REG_RO_OFFSET) //also pg and fifo status register
//temp so far
#define FEB_REG_STATUS (3 + DAQ_REG_RO_OFFSET)
#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)
#define MEAS_PERIOD_REG (DAQ_REG_RO_OFFSET + 5)
@ -64,7 +64,8 @@
#define DAQ_CHIP_CONTROLLER_QUARTER_SPEED 0x00080000 //everything at 50 MHz (25MHz ddr readout)
#define DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED 0x000c0000 //everything at ~200 kHz (200 kHz MHz ddr readout)
#define DAQ_FIFO_ENABLE 0x00100000
//#define DAQ_FIFO_ENABLE 0x00100000 commented out as it is not used anywhere
#define DAQ_REG_CHIP_CMDS_INT_TRIGGER 0x00100000
//direct chip commands to the DAQ_REG_CHIP_CMDS register
#define DAQ_NEXPOSURERS_SAFEST_MODE_ROW_CLK_BEFORE_MODE 0x00200000 //row clk is before main clk readout sequence

View File

@ -1,9 +1,9 @@
Path: slsDetectorsPackage/slsDetectorSoftware/eigerDetectorServer
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: 3b6ead77836f2b6d2a795a9a994259d1dc8c131d
Revision: 343
Branch: developer
Repsitory UUID: c934e92a41da49db07f8d3fed98d88dc39325401
Revision: 344
Branch: eigerfeature
Last Changed Author: Dhanya_Thattil
Last Changed Rev: 3943
Last Changed Date: 2018-07-17 16:15:43.000000002 +0200 ./Makefile.virtual
Last Changed Rev: 3976
Last Changed Date: 2018-08-10 17:34:43.000000002 +0200 ./FebRegisterDefs.h

View File

@ -1,6 +1,6 @@
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
#define GITREPUUID "3b6ead77836f2b6d2a795a9a994259d1dc8c131d"
#define GITREPUUID "c934e92a41da49db07f8d3fed98d88dc39325401"
#define GITAUTH "Dhanya_Thattil"
#define GITREV 0x3943
#define GITDATE 0x20180717
#define GITBRANCH "developer"
#define GITREV 0x3976
#define GITDATE 0x20180810
#define GITBRANCH "eigerfeature"

View File

@ -764,6 +764,16 @@ int64_t setTimer(enum timerIndex ind, int64_t val){
}
int64_t getTimeLeft(enum timerIndex ind) {
switch(ind){
case MEASURED_PERIOD: return Feb_Control_GetMeasuredPeriod();
case MEASURED_SUBPERIOD: return Feb_Control_GetSubMeasuredPeriod();
default:
cprintf(RED,"This timer left index (%d) not defined for Eiger\n",ind);
return -1;
}
}
@ -1579,6 +1589,12 @@ int stopStateMachine(){
#endif
}
int softwareTrigger() {
if (!Feb_Control_SoftwareTrigger())
return FAIL;
return OK;
}
int startReadOut(){

View File

@ -12,7 +12,7 @@
#include <stdint.h>
#define GOODBYE (-200)
#define REQUIRED_FIRMWARE_VERSION (21)
#define REQUIRED_FIRMWARE_VERSION (22)
#define IDFILECOMMAND "more /home/root/executables/detid.txt"
#define STATUS_IDLE 0

View File

@ -2290,6 +2290,56 @@ int multiSlsDetector::stopAcquisition() {
}
int multiSlsDetector::sendSoftwareTrigger() {
int i = 0;
int ret = OK;
int posmin = 0, posmax = detectors.size();
if (!threadpool) {
cout << "Error in creating threadpool. Exiting" << endl;
return FAIL;
} else {
int* iret[posmax - posmin];
for (int idet = posmin; idet < posmax; ++idet) {
if (idet != thisMultiDetector->masterPosition) {
iret[idet] = new int(OK);
Task* task = new Task(new func0_t<int>(&slsDetector::sendSoftwareTrigger,
detectors[idet], iret[idet]));
threadpool->add_task(task);
}
}
threadpool->startExecuting();
threadpool->wait_for_tasks_to_complete();
for (int idet = posmin; idet < posmax; ++idet) {
if (idet != thisMultiDetector->masterPosition) {
if (iret[idet] != NULL) {
if (*iret[idet] != OK)
ret = FAIL;
delete iret[idet];
} else
ret = FAIL;
if (detectors[idet]->getErrorMask())
setErrorMask(getErrorMask() | (1 << idet));
}
}
}
//master
int ret1 = OK;
i = thisMultiDetector->masterPosition;
if (thisMultiDetector->masterPosition >= 0) {
ret1 = detectors[i]->sendSoftwareTrigger();
if (detectors[i]->getErrorMask())
setErrorMask(getErrorMask() | (1 << i));
if (ret1 != OK)
ret = FAIL;
}
return ret;
}
int multiSlsDetector::startReadOut() {
unsigned int i = 0;
int ret = OK, ret1 = OK;

View File

@ -945,6 +945,12 @@ public:
*/
int stopAcquisition();
/**
* Give an internal software trigger to the detector (Eiger only)
* @return OK or FAIL
*/
int sendSoftwareTrigger();
/**
* Start readout (without exposure or interrupting exposure) (Mythen)
* @returns OK or FAIL

View File

@ -3621,7 +3621,6 @@ int slsDetector::cleanupAcquisition() {
int slsDetector::startAcquisition() {
int fnum=F_START_ACQUISITION;
int ret=FAIL;
char mess[MAX_STR_LENGTH]="";
@ -3644,9 +3643,6 @@ int slsDetector::startAcquisition() {
}
}
return ret;
}
@ -3691,6 +3687,35 @@ int slsDetector::stopAcquisition() {
}
int slsDetector::sendSoftwareTrigger() {
int fnum=F_SOFTWARE_TRIGGER;
int ret=FAIL;
char mess[MAX_STR_LENGTH]="";
#ifdef VERBOSE
std::cout<< "Sending software trigger "<< std::endl;
#endif
thisDetector->stoppedFlag=0;
if (thisDetector->onlineFlag==ONLINE_FLAG) {
if (connectControl() == OK){
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
if (ret==FAIL) {
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
std::cout<< "Detector returned error: " << mess << std::endl;
}
disconnectControl();
if (ret==FORCE_UPDATE)
updateDetector();
}
}
return ret;
}
int slsDetector::startReadOut() {
int fnum=F_START_READOUT;

View File

@ -1069,6 +1069,12 @@ public:
*/
int stopAcquisition();
/**
* Give an internal software trigger to the detector (Eiger only)
* @return OK or FAIL
*/
int sendSoftwareTrigger();
/**
* Start readout (without exposure or interrupting exposure) (Mythen)
* @returns OK or FAIL

View File

@ -193,7 +193,7 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) {
++i;
/*! \page acquisition
- <b> status [s] </b> starts or stops acquisition in detector in non blocking mode. When using stop acquisition and if acquisition is done, it will restream the stop packet from receiver (if data streaming in receiver is on). \c s: [\c start, \c stop]. \c Returns the detector status: [\c running, \c error, \c transmitting, \c finished, \c waiting, \c idle]. \c Returns \c (string)
- <b> status [s] </b> starts or stops acquisition in detector in non blocking mode. When using stop acquisition and if acquisition is done, it will restream the stop packet from receiver (if data streaming in receiver is on). Eiger can also provide an internal software trigger. \c s: [\c start, \c stop, \c trigger(EIGER only)]. \c Returns the detector status: [\c running, \c error, \c transmitting, \c finished, \c waiting, \c idle]. \c Returns \c (string)
*/
descrToFuncMap[i].m_pFuncName="status"; //
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdStatus;
@ -743,6 +743,20 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) {
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft;
++i;
/*! \page timing
- <b>measuredperiod</b> gets the measured frame period (time between last frame and the previous one) in s. For Eiger only. Makes sense only for acquisitions of more than 1 frame. \c Returns \c (double with 9 decimal digits)
*/
descrToFuncMap[i].m_pFuncName="measuredperiod"; //
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft;
++i;
/*! \page timing
- <b>measuredsubperiod</b> gets the measured subframe period (time between last subframe and the previous one) in s. For Eiger only and in 32 bit mode. \c Returns \c (double with 9 decimal digits)
*/
descrToFuncMap[i].m_pFuncName="measuredsubperiod"; //
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft;
++i;
/* speed */
/*! \page config
\section configspeed Speed
@ -2637,9 +2651,12 @@ string slsDetectorCommand::cmdStatus(int narg, char *args[], int action) {
if (string(args[1])=="start")
myDet->startAcquisition();
else if (string(args[1])=="stop") {
myDet->setReceiverOnline(ONLINE_FLAG);
myDet->setReceiverOnline(ONLINE_FLAG);//restream stop
myDet->stopAcquisition();
}
else if (string(args[1])=="trigger") {
myDet->sendSoftwareTrigger();
}
else
return string("unknown action");
}
@ -2671,7 +2688,7 @@ string slsDetectorCommand::helpStatus(int narg, char *args[], int action) {
os << string("busy \t gets the status of acquire- can be: 0 or 1. 0 for idle, 1 for running\n");
}
if (action==PUT_ACTION || action==HELP_ACTION) {
os << string("status \t controls the detector acquisition - can be start or stop. When using stop acquisition and if acquisition is done, it will restream the stop packet from receiver (if data streaming in receiver is on). \n");
os << string("status \t controls the detector acquisition - can be start or stop or trigger(EIGER only). When using stop acquisition and if acquisition is done, it will restream the stop packet from receiver (if data streaming in receiver is on). Eiger can also provide an internal software trigger\n");
os << string("busy i\t sets the status of acquire- can be: 0(idle) or 1(running).Command Acquire sets it to 1 at beignning of acquire and back to 0 at the end. Clear Flag for unexpected acquire terminations. \n");
}
return os.str();
@ -5777,6 +5794,10 @@ string slsDetectorCommand::cmdTimeLeft(int narg, char *args[], int action) {
index=MEASUREMENT_TIME;
else if (cmd=="nframes")
index=FRAMES_FROM_START;
else if (cmd=="measuredperiod")
index=MEASURED_PERIOD;
else if (cmd=="measuredsubperiod")
index=MEASURED_SUBPERIOD;
else
return string("could not decode timer ")+cmd;
@ -5786,13 +5807,13 @@ string slsDetectorCommand::cmdTimeLeft(int narg, char *args[], int action) {
}
myDet->setOnline(ONLINE_FLAG);
ret=myDet->getTimeLeft(index);
if (index==ACQUISITION_TIME || index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER || index==ACTUAL_TIME || index==MEASUREMENT_TIME)
if ((ret!=-1) && (index==ACQUISITION_TIME || index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER
|| index==ACTUAL_TIME || index==MEASUREMENT_TIME ||
MEASURED_PERIOD || MEASURED_SUBPERIOD))
rval=(double)ret*1E-9;
else rval=ret;
@ -5820,6 +5841,8 @@ string slsDetectorCommand::helpTimeLeft(int narg, char *args[], int action) {
os << "framesl \t gets the number of frames left" << std::endl;
os << "cyclesl \t gets the number of cycles left" << std::endl;
os << "probesl \t gets the number of probes left" << std::endl;
os << "measuredperiod \t gets the measured frame period (time between last frame and the previous one) in s. For Eiger only. Makes sense only for acquisitions of more than 1 frame." << std::endl;
os << "measuredsubperiod \t gets the measured subframe period (time between last subframe and the previous one) in s. For Eiger only and in 32 bit mode." << std::endl;
os << std::endl;
}

View File

@ -475,6 +475,13 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing {
int acquire(int delflag=1);
/**
* Give an internal software trigger to the detector (Eiger only)
* @return OK or FAIL
*/
virtual int sendSoftwareTrigger()=0;
// double* convertAngles(){return convertAngles(currentPosition);};
// virtual double* convertAngles(double pos)=0;

View File

@ -118,9 +118,7 @@ int executeTrimming(enum trimMode mode, int par1, int par2, int imod);
int selectStoragecellStart(int pos);
#endif
int64_t setTimer(enum timerIndex ind, int64_t val);
#ifndef EIGERD
int64_t getTimeLeft(enum timerIndex ind);
#endif
// parameters - channel, chip, module, settings
@ -255,6 +253,9 @@ int startStateMachine();
void* start_timer(void* arg);
#endif
int stopStateMachine();
#ifdef EIGERD
int softwareTrigger();
#endif
#ifndef JUNGFRAUD
int startReadOut();
#endif

View File

@ -210,6 +210,7 @@ const char* getFunctionName(enum detFuncs func) {
case F_AUTO_COMP_DISABLE: return "F_AUTO_COMP_DISABLE";
case F_STORAGE_CELL_START: return "F_STORAGE_CELL_START";
case F_CHECK_VERSION: return "F_CHECK_VERSION";
case F_SOFTWARE_TRIGGER: return "F_SOFTWARE_TRIGGER";
default: return "Unknown Function";
}
@ -295,6 +296,7 @@ void function_table() {
flist[F_AUTO_COMP_DISABLE] = &auto_comp_disable;
flist[F_STORAGE_CELL_START] = &storage_cell_start;
flist[F_CHECK_VERSION] = &check_version;
flist[F_SOFTWARE_TRIGGER] = &software_trigger;
// check
if (NUM_DET_FUNCTIONS >= TOO_MANY_FUNCTIONS_DEFINED) {
@ -2885,16 +2887,6 @@ int get_time_left(int file_des) {
sprintf(mess,"get timer left failed\n");
#ifdef EIGERD
//to receive any arguments
while (n > 0)
n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER);
ret = FAIL;
sprintf(mess,"Function (Get Timer Left) is not implemented for this detector\n");
cprintf(RED, "%s", mess);
#else
// receive arguments
enum timerIndex ind=0;
n = receiveData(file_des,&ind,sizeof(ind),INT32);
@ -2914,7 +2906,10 @@ int get_time_left(int file_des) {
#endif
switch(ind) {
#ifdef MYTHEND
#ifdef EIGERD
case MEASURED_PERIOD:
case MEASURED_SUBPERIOD:
#elif MYTHEND
case PROBES_NUMBER:
#elif JUNGFRAUD
case FRAMES_FROM_START:
@ -2924,6 +2919,7 @@ int get_time_left(int file_des) {
case PROBES_NUMBER:
case SAMPLES_JCTB:
#endif
#ifndef EIGERD
#ifndef JUNGFRAUD
case GATES_NUMBER:
#endif
@ -2935,6 +2931,7 @@ int get_time_left(int file_des) {
case PROGRESS:
case ACTUAL_TIME:
case MEASUREMENT_TIME:
#endif
retval=getTimeLeft(ind);
break;
default:
@ -2954,7 +2951,7 @@ int get_time_left(int file_des) {
#endif
if (ret==OK && differentClients)
ret=FORCE_UPDATE;
#endif
// ret could be swapped during sendData
ret1 = ret;
@ -5871,3 +5868,52 @@ int check_version(int file_des) {
// return ok / fail
return ret;
}
int software_trigger(int file_des) {
int ret=OK,ret1=OK;
int n=0;
sprintf(mess,"software trigger failed\n");
#ifndef EIGERD
//to receive any arguments
while (n > 0)
n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER);
ret = FAIL;
sprintf(mess,"Function (Software Trigger) is not implemented for this detector\n");
cprintf(RED, "%s", mess);
#else
// execute action
if (differentClients && lockStatus) {
ret = FAIL;
sprintf(mess,"Detector locked by %s\n",lastClientIP);
cprintf(RED, "Warning: %s", mess);
}
#ifdef SLS_DETECTOR_FUNCTION_LIST
else {
printf("Software Trigger\n");
ret=softwareTrigger();
if (ret==FAIL)
cprintf(RED, "Warning: %s", mess);
}
#endif
if (ret==OK && differentClients)
ret=FORCE_UPDATE;
#endif
// ret could be swapped during sendData
ret1 = ret;
// send ok / fail
n = sendData(file_des,&ret1,sizeof(ret),INT32);
// send return argument
if (ret==FAIL) {
n += sendData(file_des,mess,sizeof(mess),OTHER);
}
// return ok / fail
return ret;
}

View File

@ -96,5 +96,6 @@ int temp_event(int);
int auto_comp_disable(int);
int storage_cell_start(int);
int check_version(int);
int software_trigger(int);
#endif

View File

@ -114,6 +114,8 @@ public:
SUBFRAME_ACQUISITION_TIME, /**< subframe exposure time */
STORAGE_CELL_NUMBER, /**<number of storage cells */
SUBFRAME_PERIOD, /**< subframe period */
MEASURED_PERIOD, /**< measured period */
MEASURED_SUBPERIOD, /**< measured subperiod */
MAX_TIMERS
};