Merge pull request #34 from dls-controls/fix/wait-for-acquire

Now set ADAcquire parameter to 1 after detector acquisition has started
This commit is contained in:
Mark Rivers
2020-03-10 07:25:43 -05:00
committed by GitHub

View File

@@ -318,9 +318,9 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int cameraSeri
return;
}
//Define the polling periods for the status thread.
mPollingPeriod = 0.2; //seconds
mFastPollingPeriod = 0.05; //seconds
// Define the polling periods for the status thread.
mPollingPeriod = 0.2; // seconds
mFastPollingPeriod = 0.05; // seconds
mAcquiringData = 0;
@@ -639,16 +639,33 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value)
asynStatus status = asynSuccess;
static const char *functionName = "writeInt32";
//Set in param lib so the user sees a readback straight away. Save a backup in case of errors.
// Set in param lib so the user sees a readback straight away. Save a backup in case of errors.
getIntegerParam(function, &oldValue);
status = setIntegerParam(function, value);
if (function == ADAcquire) {
getIntegerParam(ADStatus, &adstatus);
if (value && (adstatus == ADStatusIdle)) {
// Start the acqusition here, then send an event to the dataTask at the end of this function
try {
// Set up acquisition
mAcquiringData = 1;
//We send an event at the bottom of this function.
status = setupAcquisition();
if (status != asynSuccess) throw std::string("Setup acquisition failed");
// Open the shutter if we control it
int adShutterMode;
getIntegerParam(ADShutterMode, &adShutterMode);
if (adShutterMode == ADShutterModeEPICS) {
ADDriver::setShutter(ADShutterOpen);
}
// Start acquisition
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
"%s:%s:, StartAcquisition()\n",
driverName, functionName);
checkStatus(StartAcquisition());
// Reset the counters
setIntegerParam(ADNumImagesCounter, 0);
setIntegerParam(ADNumExposuresCounter, 0);
} catch (const std::string &e) {
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s:%s: %s\n",
@@ -736,9 +753,6 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value)
status = ADDriver::writeInt32(pasynUser, value);
}
//For a successful write, clear the error message.
setStringParam(AndorMessage, " ");
/* Do callbacks so higher layers see any changes */
callParamCallbacks();
@@ -749,7 +763,7 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value)
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
"%s:%s:, Sending dataEvent to dataTask ...\n",
driverName, functionName);
//Also signal the data readout thread
// Also signal the data readout thread
epicsEventSignal(dataEvent);
}
@@ -761,6 +775,8 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value)
asynPrint(pasynUser, ASYN_TRACEIO_DRIVER,
"%s:%s: function=%d, value=%d\n",
driverName, functionName, function, value);
// For a successful write, clear the error message.
setStringParam(AndorMessage, " ");
return status;
}
@@ -1084,7 +1100,7 @@ void AndorCCD::statusTask(void)
printf("%s:%s: Status thread started...\n", driverName, functionName);
while(!mExiting) {
//Read timeout for polling freq.
// Read timeout for polling freq.
this->lock();
if (forcedFastPolls > 0) {
timeout = mFastPollingPeriod;
@@ -1103,10 +1119,10 @@ void AndorCCD::statusTask(void)
asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
"%s:%s: Got status event\n",
driverName, functionName);
//We got an event, rather than a timeout. This is because other software
//knows that data has arrived, or device should have changed state (parameters changed, etc.).
//Force a minimum number of fast polls, because the device status
//might not have changed in the first few polls
// We got an event, rather than a timeout. This is because other software
// knows that data has arrived, or device should have changed state (parameters changed, etc.).
// Force a minimum number of fast polls, because the device status
// might not have changed in the first few polls
forcedFastPolls = 5;
}
@@ -1114,17 +1130,17 @@ void AndorCCD::statusTask(void)
this->lock();
try {
//Only read these if we are not acquiring data
// Only read these if we are not acquiring data
if (!mAcquiringData) {
//Read cooler status
// Read cooler status
checkStatus(IsCoolerOn(&value));
status = setIntegerParam(AndorCoolerParam, value);
//Read temperature of CCD
// Read temperature of CCD
checkStatus(GetTemperatureF(&temperature));
status = setDoubleParam(ADTemperatureActual, temperature);
}
//Read detector status (idle, acquiring, error, etc.)
// Read detector status (idle, acquiring, error, etc.)
checkStatus(GetStatus(&value));
uvalue = static_cast<unsigned int>(value);
if (uvalue == ASIdle) {
@@ -1163,7 +1179,7 @@ void AndorCCD::statusTask(void)
callParamCallbacks();
this->unlock();
} //End of loop
} // End of loop
asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
"%s:%s: Status thread exiting ...\n",
driverName, functionName);
@@ -1511,7 +1527,7 @@ void AndorCCD::dataTask(void)
errorString = NULL;
//Wait for event from main thread to signal that data acquisition has started.
// Wait for event from main thread to signal that data acquisition has started.
this->unlock();
status = epicsEventWait(dataEvent);
if (mExiting)
@@ -1521,41 +1537,23 @@ void AndorCCD::dataTask(void)
driverName, functionName);
this->lock();
//Sanity check that main thread thinks we are acquiring data
// Sanity check that main thread thinks we are acquiring data
if (mAcquiringData) {
try {
status = setupAcquisition();
if (status != asynSuccess) continue;
getIntegerParam(ADShutterMode, &adShutterMode);
getIntegerParam(AndorReadOutMode, &readOutMode);
if (adShutterMode == ADShutterModeEPICS) {
ADDriver::setShutter(ADShutterOpen);
}
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
"%s:%s:, StartAcquisition()\n",
driverName, functionName);
checkStatus(StartAcquisition());
acquiring = 1;
} catch (const std::string &e) {
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s:%s: %s\n",
driverName, functionName, e.c_str());
continue;
}
//Read some parameters
// Read some parameters
getIntegerParam(ADShutterMode, &adShutterMode);
getIntegerParam(AndorReadOutMode, &readOutMode);
getIntegerParam(NDDataType, &itemp); dataType = (NDDataType_t)itemp;
getIntegerParam(NDAutoSave, &autoSave);
getIntegerParam(NDArrayCallbacks, &arrayCallbacks);
getIntegerParam(NDArraySizeX, &sizeX);
getIntegerParam(NDArraySizeY, &sizeY);
// Reset the counters
setIntegerParam(ADNumImagesCounter, 0);
setIntegerParam(ADNumExposuresCounter, 0);
callParamCallbacks();
// Set acquiring to 1
acquiring = 1;
} else {
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
"%s:%s:, Data thread is running but main thread thinks we are not acquiring.\n",
driverName, functionName);
// Set acquiring to 0
acquiring = 0;
}
@@ -1654,19 +1652,20 @@ void AndorCCD::dataTask(void)
}
}
}
// Close the shutter if we are controlling it
if (adShutterMode == ADShutterModeEPICS) {
ADDriver::setShutter(ADShutterClosed);
}
//Now clear main thread flag
// Now clear main thread flag
mAcquiringData = 0;
setIntegerParam(ADAcquire, 0);
//setIntegerParam(ADStatus, 0); //Dont set this as the status thread sets it.
/* Call the callbacks to update any changes */
callParamCallbacks();
} //End of loop
} // End of loop
mExited++;
this->unlock();
}
@@ -1955,7 +1954,7 @@ done:
}
//C utility functions to tie in with EPICS
// C utility functions to tie in with EPICS
static void andorStatusTaskC(void *drvPvt)
{