diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index 026c0e0..39c1aa7 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -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(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) {