diff --git a/RELEASE.md b/RELEASE.md index edce3d6..2bc3f55 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -29,6 +29,7 @@ R2-5 (July XXX, 2016) * Enforce minimum values of ADShutterOpenDelay and ADShutterCloseDelay based on query of SDK. * Fix bug when setting MinX and MinY with binning. There was an incorrect factor of 2 present. Thanks to Hinko Kocevar for this fix. +* Add support for Full Vertical Binning (FVB) readout mode. R2-4 (September 15, 2015) ---- diff --git a/andorApp/Db/andorCCD.template b/andorApp/Db/andorCCD.template index 8a11143..f5cb3f4 100644 --- a/andorApp/Db/andorCCD.template +++ b/andorApp/Db/andorCCD.template @@ -358,6 +358,29 @@ record(bi, "$(P)$(R)AndorEMGainAdvanced_RBV") field(SCAN, "I/O Intr") } +record(mbbo, "$(P)$(R)AndorReadOutMode") +{ + field(PINI, "YES") + field(DTYP, "asynInt32") + field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))ANDOR_READOUT_MODE") + field(ZRST, "FVB") + field(ZRVL, "0") + field(ONST, "Image") + field(ONVL, "4") + field(VAL, "4") +} + +record(mbbi, "$(P)$(R)AndorReadOutMode_RBV") +{ + field(DTYP, "asynInt32") + field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))ANDOR_READOUT_MODE") + field(ZRST, "FVB") + field(ZRVL, "0") + field(ONST, "Image") + field(ONVL, "4") + field(SCAN, "I/O Intr") +} + #Records in ADBase that do not apply to Andor record(mbbo, "$(P)$(R)ColorMode") diff --git a/andorApp/Db/andorCCD_settings.req b/andorApp/Db/andorCCD_settings.req index a20827b..15c7547 100644 --- a/andorApp/Db/andorCCD_settings.req +++ b/andorApp/Db/andorCCD_settings.req @@ -5,6 +5,7 @@ $(P)$(R)AndorShutterExTTL $(P)$(R)PALFilePath $(P)$(R)AndorPreAmpGain $(P)$(R)AndorADCSpeed +$(P)$(R)AndorReadOutMode file "ADBase_settings.req", P=$(P), R=$(R) file "NDFile_settings.req", P=$(P), R=$(R) diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index fcb72d0..202f75a 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -140,6 +140,7 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int shamrockID createParam(AndorEmGainAdvancedString, asynParamInt32, &AndorEmGainAdvanced); createParam(AndorAdcSpeedString, asynParamInt32, &AndorAdcSpeed); createParam(AndorBaselineClampString, asynParamInt32, &AndorBaselineClamp); + createParam(AndorReadOutModeString, asynParamInt32, &AndorReadOutMode); // Create the epicsEvent for signaling to the status task when parameters should have changed. // This will cause it to do a poll immediately, rather than wait for the poll time period. @@ -223,6 +224,7 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int shamrockID status |= setIntegerParam(AndorShutterMode, AShutterAuto); status |= setDoubleParam(ADShutterOpenDelay, 0.); status |= setDoubleParam(ADShutterCloseDelay, 0.); + status |= setIntegerParam(AndorReadOutMode, ARImage); setupADCSpeeds(); setupPreAmpGains(); @@ -553,9 +555,9 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) (function == ADBinX) || (function == ADBinY) || (function == ADMinX) || (function == ADMinY) || (function == ADSizeX) || (function == ADSizeY) || - (function == ADTriggerMode) || (function == AndorEmGain) || + (function == ADTriggerMode) || (function == AndorEmGain) || (function == AndorEmGainMode)|| (function == AndorEmGainAdvanced) || - (function == AndorAdcSpeed)) { + (function == AndorAdcSpeed) || (function == AndorReadOutMode)) { status = setupAcquisition(); if (function == AndorAdcSpeed) setupPreAmpGains(); if (status != asynSuccess) setIntegerParam(function, oldValue); @@ -724,7 +726,6 @@ asynStatus AndorCCD::setupShutter(int command) int openTime, closeTime; int shutterExTTL; int shutterMode; - AndorCapabilities capabilities; asynStatus status=asynSuccess; static const char *functionName = "setupShutter"; @@ -757,9 +758,7 @@ asynStatus AndorCCD::setupShutter(int command) } try { - capabilities.ulSize = sizeof(capabilities); - checkStatus(GetCapabilities(&capabilities)); - if (capabilities.ulFeatures & AC_FEATURES_SHUTTER) { + if (mCapabilities.ulFeatures & AC_FEATURES_SHUTTER) { asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s:, SetShutter(%d,%d,%d,%d)\n", driverName, functionName, shutterExTTL, shutterMode, closeTime, openTime); @@ -983,12 +982,15 @@ asynStatus AndorCCD::setupAcquisition() int emGainAdvanced; int FKOffset; AndorADCSpeed_t *pSpeed; + int readOutMode; static const char *functionName = "setupAcquisition"; if (!mInitOK) { return asynDisabled; } + // Get current readout mode + getIntegerParam(AndorReadOutMode, &readOutMode); getIntegerParam(ADImageMode, &imageMode); getIntegerParam(ADNumExposures, &numExposures); if (numExposures <= 0) { @@ -1033,6 +1035,11 @@ asynStatus AndorCCD::setupAcquisition() getIntegerParam(ADSizeY, &sizeY); getIntegerParam(ADMaxSizeX, &maxSizeX); getIntegerParam(ADMaxSizeY, &maxSizeY); + if (readOutMode == ARFullVerticalBinning) { + // Set maximum binning but do not update parameter, this preserves ADBinY + // when going back to Image readout mode. + binY = maxSizeY; + } if (minX > (maxSizeX - binX)) { minX = maxSizeX - binX; setIntegerParam(ADMinX, minX); @@ -1062,6 +1069,11 @@ asynStatus AndorCCD::setupAcquisition() setIntegerParam(NDArraySizeY, sizeY/binY); try { + asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, + "%s:%s:, SetReadMode(%d)\n", + driverName, functionName, readOutMode); + checkStatus(SetReadMode(readOutMode)); + asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s:, SetTriggerMode(%d)\n", driverName, functionName, triggerMode); @@ -1082,16 +1094,18 @@ asynStatus AndorCCD::setupAcquisition() driverName, functionName, pSpeed->AmpIndex, pSpeed->HSSpeedIndex); checkStatus(SetHSSpeed(pSpeed->AmpIndex, pSpeed->HSSpeedIndex)); - asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, - "%s:%s:, SetImage(%d,%d,%d,%d,%d,%d)\n", - driverName, functionName, binX, binY, minX+1, minX+sizeX, minY+1, minY+sizeY); - checkStatus(SetImage(binX, binY, minX+1, minX+sizeX, minY+1, minY+sizeY)); + if (readOutMode == ARImage) { + asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, + "%s:%s:, SetImage(%d,%d,%d,%d,%d,%d)\n", + driverName, functionName, binX, binY, minX+1, minX+sizeX, minY+1, minY+sizeY); + checkStatus(SetImage(binX, binY, minX+1, minX+sizeX, minY+1, minY+sizeY)); + } asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s:, SetExposureTime(%f)\n", driverName, functionName, mAcquireTime); checkStatus(SetExposureTime(mAcquireTime)); - + // Check if camera has EM gain capability before setting modes or EM gain if ((int)mCapabilities.ulEMGainCapability > 0) { asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, @@ -1099,21 +1113,21 @@ asynStatus AndorCCD::setupAcquisition() driverName, functionName, emGainMode); checkStatus(SetEMGainMode(emGainMode)); } - + if ((int)mCapabilities.ulEMGainCapability > 0) { asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s:, SetEMGainAdvanced(%d)\n", driverName, functionName, emGainAdvanced); checkStatus(SetEMAdvanced(emGainAdvanced)); } - + if ((int)mCapabilities.ulEMGainCapability > 0) { asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s:, SetEMCCDGain(%d)\n", driverName, functionName, emGain); checkStatus(SetEMCCDGain(emGain)); } - + switch (imageMode) { case ADImageSingle: if (numExposures == 1) { diff --git a/andorApp/src/andorCCD.h b/andorApp/src/andorCCD.h index a892e62..de4d578 100755 --- a/andorApp/src/andorCCD.h +++ b/andorApp/src/andorCCD.h @@ -33,6 +33,7 @@ #define AndorEmGainAdvancedString "ANDOR_EM_GAIN_ADVANCED" #define AndorAdcSpeedString "ANDOR_ADC_SPEED" #define AndorBaselineClampString "ANDOR_BASELINE_CLAMP" +#define AndorReadOutModeString "ANDOR_READOUT_MODE" /** * Structure defining an ADC speed for the ADAndor driver. @@ -94,7 +95,8 @@ class AndorCCD : public ADDriver { int AndorEmGainAdvanced; int AndorAdcSpeed; int AndorBaselineClamp; - #define LAST_ANDOR_PARAM AndorBaselineClamp + int AndorReadOutMode; + #define LAST_ANDOR_PARAM AndorReadOutMode private: diff --git a/documentation/andorDoc.html b/documentation/andorDoc.html index 812fb01..66886b7 100755 --- a/documentation/andorDoc.html +++ b/documentation/andorDoc.html @@ -10,7 +10,7 @@
The Andor module includes a separate driver to control the Andor Shamrock spectrographs. @@ -613,7 +614,7 @@ ANDOR_BASELINE_CLAMP