Merge pull request #250 from slsdetectorgroup/stopacq

Stopacq
This commit is contained in:
Dhanya Thattil
2021-07-01 14:37:02 +02:00
committed by GitHub
25 changed files with 163 additions and 58 deletions

View File

@ -67,9 +67,6 @@ exposed to Python through pybind11.
.. autoclass:: readoutMode
:undoc-members:
.. autoclass:: masterFlags
:undoc-members:
.. autoclass:: burstMode
:undoc-members:

View File

@ -219,7 +219,7 @@ The enums can be found in slsdet.enums
>>> [e for e in dir(slsdet.enums) if not e.startswith('_')]
['burstMode', 'clockIndex', 'dacIndex',
'detectorSettings', 'detectorType', 'dimension', 'externalSignalFlag',
'fileFormat', 'frameDiscardPolicy', 'masterFlags',
'fileFormat', 'frameDiscardPolicy',
'readoutMode', 'runStatus', 'speedLevel', 'timingMode',
'timingSourceType']

View File

@ -12,7 +12,6 @@ dacIndex = _slsdet.slsDetectorDefs.dacIndex
detectorSettings = _slsdet.slsDetectorDefs.detectorSettings
clockIndex = _slsdet.slsDetectorDefs.clockIndex
readoutMode = _slsdet.slsDetectorDefs.readoutMode
masterFlags = _slsdet.slsDetectorDefs.masterFlags
burstMode = _slsdet.slsDetectorDefs.burstMode
timingSourceType = _slsdet.slsDetectorDefs.timingSourceType
M3_GainCaps = _slsdet.slsDetectorDefs.M3_GainCaps

View File

@ -255,12 +255,6 @@ void init_enums(py::module &m) {
.value("QUARTER_SPEED", slsDetectorDefs::speedLevel::QUARTER_SPEED)
.export_values();
py::enum_<slsDetectorDefs::masterFlags>(Defs, "masterFlags")
.value("NO_MASTER", slsDetectorDefs::masterFlags::NO_MASTER)
.value("IS_MASTER", slsDetectorDefs::masterFlags::IS_MASTER)
.value("IS_SLAVE", slsDetectorDefs::masterFlags::IS_SLAVE)
.export_values();
py::enum_<slsDetectorDefs::burstMode>(Defs, "burstMode")
.value("BURST_INTERNAL", slsDetectorDefs::burstMode::BURST_INTERNAL)
.value("BURST_EXTERNAL", slsDetectorDefs::burstMode::BURST_EXTERNAL)

View File

@ -251,12 +251,12 @@ int Beb_IsTransmitting(int *retval, int tengiga, int waitForDelay) {
int maxtimer = (MAX(MAX(l_txndelaycounter, l_framedelaycounter),
MAX(r_txndelaycounter, r_framedelaycounter))) /
100; // counter values in 10 ns
printf("Will wait for %d us\n", maxtimer);
printf("Beb: Will wait for %d us\n", maxtimer);
usleep(maxtimer);
}
// wait for 1 ms
else {
printf("Will wait for 1 ms\n");
printf("Beb: Will wait for 1 ms\n");
usleep(1 * 1000);
}
@ -1109,7 +1109,7 @@ int Beb_StopAcquisition() {
// open file pointer
int fd = Beb_open(&csp0base, XPAR_CMD_GENERATOR);
if (fd < 0) {
LOG(logERROR, ("Beb Stop Acquisition FAIL\n"));
LOG(logERROR, ("Beb Reset FAIL\n"));
return 0;
} else {
// find value
@ -1126,7 +1126,7 @@ int Beb_StopAcquisition() {
Beb_Write32(csp0base, (RIGHT_OFFSET + STOP_ACQ_OFFSET),
(valuer & (~STOP_ACQ_BIT)));
LOG(logINFO, ("Beb Stop Acquisition OK\n"));
LOG(logINFO, ("Beb: Reset done\n"));
// close file pointer
Beb_close(fd, csp0base);
}

View File

@ -709,6 +709,32 @@ int Feb_Control_AcquisitionInProgress() {
return STATUS_IDLE;
}
int Feb_Control_ProcessingInProgress() {
unsigned int regr = 0, regl = 0;
// deactivated should return end of processing
if (!Feb_Control_activated)
return IDLE;
if (!Feb_Interface_ReadRegister(Feb_Control_rightAddress, FEB_REG_STATUS,
&regr)) {
LOG(logERROR, ("Could not read right FEB_REG_STATUS to get feb "
"processing status\n"));
return STATUS_ERROR;
}
if (!Feb_Interface_ReadRegister(Feb_Control_leftAddress, FEB_REG_STATUS,
&regl)) {
LOG(logERROR, ("Could not read left FEB_REG_STATUS to get feb "
"processing status\n"));
return STATUS_ERROR;
}
// processing done
if ((regr | regl) & FEB_REG_STATUS_ACQ_DONE_MSK) {
return STATUS_IDLE;
}
// processing running
return STATUS_RUNNING;
}
int Feb_Control_AcquisitionStartedBit() {
unsigned int status_reg_r = 0, status_reg_l = 0;
// deactivated should return acquisition started/ready
@ -817,7 +843,7 @@ int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us) {
}
int Feb_Control_Reset() {
LOG(logINFO, ("Reset daq\n"));
LOG(logINFO, ("Feb: Reset daq\n"));
if (Feb_Control_activated) {
if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),
DAQ_REG_CTRL, 0, 0, 0) ||
@ -996,7 +1022,48 @@ int Feb_Control_StartAcquisition() {
return 1;
}
int Feb_Control_StopAcquisition() { return Feb_Control_Reset(); }
int Feb_Control_StopAcquisition() {
if (Feb_Control_activated) {
// sends last frames from fifo
unsigned int orig_value = 0;
if (!Feb_Interface_ReadRegister(Feb_Control_AddressToAll(),
DAQ_REG_CTRL, &orig_value)) {
LOG(logERROR, ("Could not read DAQ_REG_CTRL to stop acquisition "
"(send complete frames)\n"));
return 0;
}
if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),
DAQ_REG_CTRL,
orig_value | DAQ_CTRL_STOP, 0, 0)) {
LOG(logERROR, ("Could not send last frames.\n"));
return 0;
}
LOG(logINFO, ("Feb: Command to Flush out images from fifo\n"));
// wait for feb processing to be done
int is_processing = Feb_Control_ProcessingInProgress();
int check_error = 0;
while (is_processing != STATUS_IDLE) {
usleep(500);
is_processing = Feb_Control_ProcessingInProgress();
// check error only 5 times (ensuring it is not something that
// happens sometimes)
if (is_processing == STATUS_ERROR) {
if (check_error == 5)
break;
check_error++;
} // reset check_error for next time
else
check_error = 0;
}
LOG(logINFO, ("Feb: Processing done (to stop acq)\n"));
return 0;
}
return 1;
}
int Feb_Control_IsReadyForTrigger(int *readyForTrigger) {
unsigned int addr[2] = {Feb_Control_leftAddress, Feb_Control_rightAddress};

View File

@ -40,6 +40,7 @@ unsigned int *Feb_Control_GetTrimbits();
// acquisition
int Feb_Control_AcquisitionInProgress();
int Feb_Control_ProcessingInProgress();
int Feb_Control_AcquisitionStartedBit();
int Feb_Control_WaitForStartedFlag(int sleep_time_us, int prev_flag);
int Feb_Control_WaitForFinishedFlag(int sleep_time_us, int tempLock);

View File

@ -30,10 +30,13 @@
#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 FEB_REG_STATUS_WAIT_FOR_TRGGR_OFST (5)
#define FEB_REG_STATUS_WAIT_FOR_TRGGR_MSK (0x00000001 << FEB_REG_STATUS_WAIT_FOR_TRGGR_OFST)
#define FEB_REG_STATUS_ACQ_DONE_OFST (6)
#define FEB_REG_STATUS_ACQ_DONE_MSK (0x00000001 << FEB_REG_STATUS_ACQ_DONE_OFST)
#define FEB_REG_STATUS_TEMP_OFST (16)
#define FEB_REG_STATUS_TEMP_MSK (0x0000FFFF << FEB_REG_STATUS_TEMP_OFST)
@ -44,7 +47,8 @@
#define DAQ_CTRL_RESET 0x80000000
#define DAQ_CTRL_START 0x40000000
#define ACQ_CTRL_START 0x50000000 // this is 0x10000000 (acq) | 0x40000000 (daq)
#define DAQ_CTRL_STOP 0x00000000
#define DAQ_CTRL_STOP 0x08000000 // sends last complete frame
#define DAQ_CTRL_DONE 0x00000040 // data processing done in feb
// direct chip commands to the DAQ_REG_CHIP_CMDS register
#define DAQ_SET_STATIC_BIT 0x00000001

View File

@ -46,7 +46,6 @@ int on_dst = 0;
int dst_requested[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
enum masterFlags masterMode = IS_SLAVE;
int top = 0;
int master = 0;
int normal = 0;
@ -1413,6 +1412,8 @@ int setHighVoltage(int val) {
/* parameters - timing, extsig */
int isMaster() { return master; }
void setTiming(enum timingMode arg) {
int ret = 0;
switch (arg) {
@ -2387,19 +2388,43 @@ int stopStateMachine() {
return OK;
#else
sharedMemory_lockLocalLink();
if ((Feb_Control_StopAcquisition() != STATUS_IDLE) ||
(!Beb_StopAcquisition())) {
// sends last frames from fifo and wait for feb processing done
if ((Feb_Control_StopAcquisition() != STATUS_IDLE)) {
LOG(logERROR, ("failed to stop acquisition\n"));
sharedMemory_unlockLocalLink();
return FAIL;
}
sharedMemory_unlockLocalLink();
// wait for beb to finish sending packets
int isTransmitting = 1;
while (isTransmitting) {
// wait for beb to send out all packets
if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 1) == FAIL) {
LOG(logERROR, ("failed to stop beb acquisition\n"));
return FAIL;
}
if (isTransmitting) {
printf("Transmitting...\n");
}
}
LOG(logINFO, ("Beb: Detector has sent all data (stop)\n"));
// reset feb and beb
sharedMemory_lockLocalLink();
Feb_Control_Reset();
sharedMemory_unlockLocalLink();
if (!Beb_StopAcquisition()) {
LOG(logERROR, ("failed to stop acquisition\n"));
return FAIL;
}
// ensure all have same starting frame numbers
uint64_t retval = 0;
if (Beb_GetNextFrameNumber(&retval, send_to_ten_gig) == -2) {
Beb_SetNextFrameNumber(retval + 1);
}
LOG(logINFOBLUE, ("Stopping state machine complete\n\n"));
return OK;
#endif
}
@ -2510,6 +2535,21 @@ void readFrame(int *ret, char *mess) {
// wait for detector to send
int isTransmitting = 1;
while (isTransmitting) {
// wait for feb processing to be done
sharedMemory_lockLocalLink();
int i = Feb_Control_ProcessingInProgress();
sharedMemory_unlockLocalLink();
if (i == STATUS_ERROR) {
strcpy(mess, "Could not read feb processing done register\n");
*ret = (int)FAIL;
return;
}
if (i == RUNNING) {
LOG(logINFOBLUE, ("Status: TRANSMITTING (feb processing)\n"));
isTransmitting = 1;
}
// wait for beb to send out all packets
if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 1) == FAIL) {
strcpy(mess, "Could not read delay counters\n");
*ret = (int)FAIL;
@ -2519,7 +2559,7 @@ void readFrame(int *ret, char *mess) {
printf("Transmitting...\n");
}
}
LOG(logINFO, ("Detector has sent all data\n"));
LOG(logINFO, ("Beb: Detector has sent all data (acquire)\n"));
LOG(logINFOGREEN, ("Acquisition successfully finished\n"));
#endif
}

View File

@ -55,7 +55,7 @@ int ipPacketSize = 0;
int udpPacketSize = 0;
// master slave configuration (for 25um)
int masterflags = NO_MASTER;
int master = 0;
int masterdefaultdelay = 62;
int patternphase = 0;
int adcphase = 0;
@ -364,6 +364,8 @@ void initStopServer() {
#ifdef VIRTUAL
sharedMemory_setStop(0);
#endif
// to get master from file
readConfigFile();
}
/* set up detector */
@ -621,14 +623,12 @@ int readConfigFile() {
// key is master/ slave flag
if (!strcasecmp(key, "masterflags")) {
if (!strcasecmp(value, "is_master")) {
masterflags = IS_MASTER;
master = 1;
LOG(logINFOBLUE, ("\tMaster\n"));
} else if (!strcasecmp(value, "is_slave")) {
masterflags = IS_SLAVE;
LOG(logINFOBLUE, ("\tSlave\n"));
} else if (!strcasecmp(value, "no_master")) {
masterflags = NO_MASTER;
LOG(logINFOBLUE, ("\tNo Master\n"));
} else if ((!strcasecmp(value, "is_slave")) ||
(!strcasecmp(value, "no_master"))) {
master = 0;
LOG(logINFOBLUE, ("\tSlave or No Master\n"));
} else {
LOG(logERROR,
("\tCould not scan masterflags %s value from config file\n",
@ -705,7 +705,7 @@ void setMasterSlaveConfiguration() {
return;
// master configuration
if (masterflags == IS_MASTER) {
if (master) {
// master default delay set, so reset delay
setDelayAfterTrigger(0);
@ -876,7 +876,7 @@ int setDelayAfterTrigger(int64_t val) {
return FAIL;
}
LOG(logINFO, ("Setting delay after trigger %lld ns\n", (long long int)val));
if (masterflags == IS_MASTER) {
if (master) {
val += masterdefaultdelay;
LOG(logINFO, ("\tActual Delay (master): %lld\n", (long long int)val));
}
@ -900,7 +900,7 @@ int setDelayAfterTrigger(int64_t val) {
int64_t getDelayAfterTrigger() {
int64_t retval =
get64BitReg(SET_DELAY_LSB_REG, SET_DELAY_MSB_REG) / (1E-9 * CLK_FREQ);
if (masterflags == IS_MASTER) {
if (master) {
LOG(logDEBUG1,
("\tActual Delay read (master): %lld\n", (long long int)retval));
retval -= masterdefaultdelay;
@ -924,7 +924,7 @@ int64_t getPeriodLeft() {
int64_t getDelayAfterTriggerLeft() {
int64_t retval =
get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG) / (1E-9 * CLK_FREQ);
if (masterflags == IS_MASTER) {
if (master) {
LOG(logDEBUG1,
("\tGetting Actual delay (master): %lld\n", (long long int)retval));
retval -= masterdefaultdelay;
@ -1201,6 +1201,8 @@ int setHighVoltage(int val) {
/* parameters - timing, extsig */
int isMaster() { return master; }
void setTiming(enum timingMode arg) {
u_int32_t addr = EXT_SIGNAL_REG;
switch (arg) {
@ -1451,7 +1453,7 @@ int configureMAC() {
setExpTime(900 * 1000);
// take an image
if (masterflags == IS_MASTER)
if (master)
usleep(1 * 1000 * 1000); // required to ensure master starts
// acquisition only after slave has changed
// to basic parameters and is waiting

View File

@ -1395,12 +1395,13 @@ int setHighVoltage(int val) {
return highvoltage;
}
/* parameters - timing */
int isMaster() {
return !((bus_r(SYSTEM_STATUS_REG) & SYSTEM_STATUS_SLV_BRD_DTCT_MSK) >>
SYSTEM_STATUS_SLV_BRD_DTCT_OFST);
}
/* parameters - timing */
void setTiming(enum timingMode arg) {
if (!isMaster() && arg == AUTO_TIMING)

View File

@ -347,6 +347,9 @@ int getADC(enum ADCINDEX ind);
int setHighVoltage(int val);
// parameters - timing, extsig
#if defined(MYTHEN3D) || defined(EIGERD) || defined(GOTTHARDD)
int isMaster();
#endif
#ifdef GOTTHARD2D
void updatingRegisters();
#endif
@ -354,7 +357,6 @@ void setTiming(enum timingMode arg);
enum timingMode getTiming();
#ifdef MYTHEN3D
void setInitialExtSignals();
int isMaster();
int setGainCaps(int caps);
int getGainCaps();
int setChipStatusRegister(int csr);

View File

@ -8156,7 +8156,7 @@ int get_master(int file_des) {
LOG(logDEBUG1, ("Getting master\n"));
#ifndef MYTHEN3D
#if !defined(MYTHEN3D) && !defined(EIGERD) && !defined(GOTTHARDD)
functionNotImplemented();
#else
retval = isMaster();

View File

@ -488,12 +488,14 @@ class Detector {
void stopReceiver();
/** Non blocking: start detector acquisition. Status changes to RUNNING or
* WAITING and automatically returns to idle at the end of acquisition. */
* WAITING and automatically returns to idle at the end of acquisition.
[Mythen3] Master starts acquisition first */
void startDetector();
/** [Mythen3] Non blocking: start detector readout of counters in chip.
* Status changes to TRANSMITTING and automatically returns to idle at the
* end of readout. */
* end of readout.
[Eiger] Master stops acquisition last */
void startDetectorReadout();
/** Non blocking: Abort detector acquisition. Status changes to IDLE or
@ -1310,6 +1312,7 @@ class Detector {
* (internal gating). Gate index: 0-2, -1 for all */
Result<std::array<ns, 3>> getGateDelayForAllGates(Positions pos = {}) const;
/** [Eiger][Mythen3][Gotthard1] via stop server **/
Result<bool> getMaster(Positions pos = {}) const;
// TODO! check if we really want to expose this !!!!!

View File

@ -677,16 +677,16 @@ void Detector::startDetector() {
auto detector_type = getDetectorType().squash();
if (detector_type == defs::MYTHEN3 && size() > 1) {
auto is_master = getMaster();
std::vector<int> master;
int masterPosition = 0;
std::vector<int> slaves;
for (int i = 0; i < size(); ++i) {
if (is_master[i])
master.push_back(i);
masterPosition = i;
else
slaves.push_back(i);
}
pimpl->Parallel(&Module::startAcquisition, slaves);
pimpl->Parallel(&Module::startAcquisition, master);
pimpl->Parallel(&Module::startAcquisition, {masterPosition});
} else {
pimpl->Parallel(&Module::startAcquisition, {});
}

View File

@ -1999,7 +1999,7 @@ std::array<time::ns, 3> Module::getGateDelayForAllGates() const {
return sendToDetector<std::array<time::ns, 3>>(F_GET_GATE_DELAY_ALL_GATES);
}
bool Module::isMaster() const { return sendToDetector<int>(F_GET_MASTER); }
bool Module::isMaster() const { return sendToDetectorStop<int>(F_GET_MASTER); }
int Module::getChipStatusRegister() const {
return sendToDetector<int>(F_GET_CSR);

View File

@ -375,9 +375,6 @@ typedef struct {
/** chip speed */
enum speedLevel { FULL_SPEED, HALF_SPEED, QUARTER_SPEED };
/** hierarchy in multi-detector structure, if any */
enum masterFlags { NO_MASTER, IS_MASTER, IS_SLAVE };
/**
* burst mode for gotthard2
*/
@ -394,14 +391,14 @@ typedef struct {
*/
enum timingSourceType { TIMING_INTERNAL, TIMING_EXTERNAL };
//gain caps Mythen3
// gain caps Mythen3
enum M3_GainCaps {
M3_C10pre= 1<<7,
M3_C15sh = 1<<10,
M3_C30sh = 1<<11,
M3_C50sh = 1<<12,
M3_C225ACsh = 1<<13,
M3_C15pre = 1<<14,
M3_C10pre = 1 << 7,
M3_C15sh = 1 << 10,
M3_C30sh = 1 << 11,
M3_C50sh = 1 << 12,
M3_C225ACsh = 1 << 13,
M3_C15pre = 1 << 14,
};
#ifdef __cplusplus
@ -636,9 +633,6 @@ typedef struct {
#ifdef __cplusplus
// TODO! discuss this
#include <vector> //hmm... but currently no way around
namespace sls {

View File

@ -9,4 +9,5 @@
#define APIJUNGFRAU 0x210621
#define APIMYTHEN3 0x210621
#define APIMOENCH 0x210621
#define APIEIGER 0x210625
#define APIEIGER 0x210701