Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds idle status notification to data thread #45

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 47 additions & 4 deletions andorApp/src/andorCCD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; i<MAX_ADC_SPEEDS; i++) {
mADCSpeeds[i].EnumValue = i;
Expand Down Expand Up @@ -687,6 +694,12 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value)
status = asynError;
}
}
else if (value && (adstatus != ADStatusIdle)) {
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s::%s STATUS CONFLICT, acquire flag switched on before detector was ready for it! \n", driverName, functionName);
status = asynError;
}

if (!value && (adstatus != ADStatusIdle)) {
try {
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions andorApp/src/andorCCD.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class AndorCCD : public ADDriver {

epicsEventId statusEvent;
epicsEventId dataEvent;
epicsEventId idleEvent;
double mPollingPeriod;
double mFastPollingPeriod;
unsigned int mAcquiringData;
Expand Down