From dc39f0562249f7a0461292b01df300f4cd60a847 Mon Sep 17 00:00:00 2001 From: Gregory Gay Date: Thu, 2 Dec 2021 11:40:52 +0000 Subject: [PATCH] Adds idle status notification to data thread --- andorApp/src/andorCCD.cpp | 51 ++++++++++++++++++++++++++++++++++++--- andorApp/src/andorCCD.h | 1 + 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index dbfa10c8..8f2dde51 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -175,6 +175,13 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int cameraSeri return; } + // Use this to signal the data acquisition task that the detector status has been updated. + this->idleEvent = epicsEventMustCreate(epicsEventEmpty); + if (!this->idleEvent) { + printf("%s:%s epicsEventCreate failure for idle event\n", driverName, functionName); + return; + } + // Initialize ADC enums for (i=0; ipasynUserSelf, ASYN_TRACE_FLOW, @@ -1113,6 +1126,7 @@ void AndorCCD::statusTask(void) { int value = 0; float temperature; + unsigned int prev_uvalue = 0; unsigned int uvalue = 0; unsigned int status = 0; double timeout = 0.0; @@ -1197,6 +1211,15 @@ void AndorCCD::statusTask(void) setStringParam(AndorMessage, e.c_str()); } + // Signal the data acquisition thread when the detector status has been updated from 'Acquire' to 'Idle' + if ((prev_uvalue == ASAcquiring) && (uvalue == ASIdle)) { + epicsEventSignal(idleEvent); + } + + // Update the previous status record with the new detector status value + if (prev_uvalue != uvalue) { + prev_uvalue = uvalue; + } /* Call the callbacks to update any changes */ callParamCallbacks(); this->unlock(); @@ -1680,13 +1703,33 @@ void AndorCCD::dataTask(void) ADDriver::setShutter(ADShutterClosed); } - // Now clear main thread flag - mAcquiringData = 0; + + + // Update the detector status before the next acquisition gets triggered + epicsEventSignal(statusEvent); + + // Wait to receive an event confirming that the detector status has been updated to 'Idle' + // (without it, the next acquisition may be triggered before the detector status is updated + // --> see writeInt32 loop hole on line 773) + this->unlock(); + status = epicsEventWait(idleEvent); + if (status == epicsEventWaitOK) { + asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, + "%s:%s: Got idle transition event\n", driverName, functionName); + } + if (mExiting) + break; + this->lock(); + + // Switch the aquisition flag off setIntegerParam(ADAcquire, 0); - //setIntegerParam(ADStatus, 0); //Dont set this as the status thread sets it. - /* Call the callbacks to update any changes */ + // Call the callbacks to update any changes related to the data task callParamCallbacks(); + + // Now clear the main thread flag + mAcquiringData = 0; + } // End of loop mExited++; this->unlock(); diff --git a/andorApp/src/andorCCD.h b/andorApp/src/andorCCD.h index 0dbf2100..fd3feede 100755 --- a/andorApp/src/andorCCD.h +++ b/andorApp/src/andorCCD.h @@ -198,6 +198,7 @@ class AndorCCD : public ADDriver { epicsEventId statusEvent; epicsEventId dataEvent; + epicsEventId idleEvent; double mPollingPeriod; double mFastPollingPeriod; unsigned int mAcquiringData;