From afc7109cd2cf244577f4d690741f5055685da63e Mon Sep 17 00:00:00 2001 From: Michael Dunning Date: Sat, 4 Nov 2017 11:24:07 -0700 Subject: [PATCH 1/5] Add support for Frame Transfer Mode --- andorApp/Db/andorCCD.template | 19 +++++++++++++++++++ andorApp/Db/andorCCD_settings.req | 1 + andorApp/src/andorCCD.cpp | 30 ++++++++++++++++++++---------- andorApp/src/andorCCD.h | 4 +++- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/andorApp/Db/andorCCD.template b/andorApp/Db/andorCCD.template index 63b1c4f..cd0c6c1 100644 --- a/andorApp/Db/andorCCD.template +++ b/andorApp/Db/andorCCD.template @@ -387,6 +387,25 @@ record(mbbi, "$(P)$(R)AndorReadOutMode_RBV") field(SCAN, "I/O Intr") } +# Frame Transfer Mode +record(bo, "$(P)$(R)AndorFTMode") +{ + field(PINI, "1") + field(DTYP, "asynInt32") + field(ZNAM, "Disabled") + field(ONAM, "Enabled") + field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))ANDOR_FT_MODE") +} + +record(bi, "$(P)$(R)AndorFTMode_RBV") +{ + field(DTYP, "asynInt32") + field(ZNAM, "Disabled") + field(ONAM, "Enabled") + field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))ANDOR_FT_MODE") + 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 cf7395d..f966548 100644 --- a/andorApp/Db/andorCCD_settings.req +++ b/andorApp/Db/andorCCD_settings.req @@ -9,6 +9,7 @@ $(P)$(R)AndorEMGainMode $(P)$(R)AndorEMGainAdvanced $(P)$(R)AndorADCSpeed $(P)$(R)AndorReadOutMode +$(P)$(R)AndorFTMode 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 7272a25..2ce9a87 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -153,6 +153,7 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int shamrockID createParam(AndorAdcSpeedString, asynParamInt32, &AndorAdcSpeed); createParam(AndorBaselineClampString, asynParamInt32, &AndorBaselineClamp); createParam(AndorReadOutModeString, asynParamInt32, &AndorReadOutMode); + createParam(AndorFrameTransferModeString, asynParamInt32, &AndorFrameTransferMode); // 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. @@ -249,6 +250,7 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int shamrockID status |= setDoubleParam(ADShutterOpenDelay, 0.); status |= setDoubleParam(ADShutterCloseDelay, 0.); status |= setIntegerParam(AndorReadOutMode, ARImage); + status |= setIntegerParam(AndorFrameTransferMode, 0); setupADCSpeeds(); setupPreAmpGains(); @@ -574,16 +576,16 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) } } } - else if ((function == ADNumExposures) || (function == ADNumImages) || - (function == ADImageMode) || - (function == ADBinX) || (function == ADBinY) || - (function == ADMinX) || (function == ADMinY) || - (function == ADSizeX) || (function == ADSizeY) || - (function == ADReverseX) || (function == ADReverseY) || - (function == ADTriggerMode) || (function == AndorEmGain) || - (function == AndorEmGainMode)|| (function == AndorEmGainAdvanced) || - (function == AndorAdcSpeed) || (function == AndorPreAmpGain) || - (function == AndorReadOutMode)) { + else if ((function == ADNumExposures) || (function == ADNumImages) || + (function == ADImageMode) || + (function == ADBinX) || (function == ADBinY) || + (function == ADMinX) || (function == ADMinY) || + (function == ADSizeX) || (function == ADSizeY) || + (function == ADReverseX) || (function == ADReverseY) || + (function == ADTriggerMode) || (function == AndorEmGain) || + (function == AndorEmGainMode) || (function == AndorEmGainAdvanced) || + (function == AndorAdcSpeed) || (function == AndorPreAmpGain) || + (function == AndorReadOutMode) || (function == AndorFrameTransferMode)) { status = setupAcquisition(); if (function == AndorAdcSpeed) setupPreAmpGains(); if (status != asynSuccess) setIntegerParam(function, oldValue); @@ -1006,6 +1008,7 @@ asynStatus AndorCCD::setupAcquisition() int FKOffset; AndorADCSpeed_t *pSpeed; int readOutMode; + int frameTransferMode; static const char *functionName = "setupAcquisition"; if (!mInitOK) { @@ -1094,6 +1097,8 @@ asynStatus AndorCCD::setupAcquisition() // for the actual size of the image, so we must compute it. setIntegerParam(NDArraySizeX, sizeX/binX); setIntegerParam(NDArraySizeY, sizeY/binY); + + getIntegerParam(AndorFrameTransferMode, &frameTransferMode); try { asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, @@ -1165,6 +1170,11 @@ asynStatus AndorCCD::setupAcquisition() checkStatus(SetEMCCDGain(emGain)); } + asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, + "%s:%s:, SetFrameTransferMode(%d)\n", + driverName, functionName, frameTransferMode); + checkStatus(SetFrameTransferMode(frameTransferMode)); + switch (imageMode) { case ADImageSingle: if (numExposures == 1) { diff --git a/andorApp/src/andorCCD.h b/andorApp/src/andorCCD.h index cfa2dec..625ab6a 100755 --- a/andorApp/src/andorCCD.h +++ b/andorApp/src/andorCCD.h @@ -35,6 +35,7 @@ #define AndorAdcSpeedString "ANDOR_ADC_SPEED" #define AndorBaselineClampString "ANDOR_BASELINE_CLAMP" #define AndorReadOutModeString "ANDOR_READOUT_MODE" +#define AndorFrameTransferModeString "ANDOR_FT_MODE" /** * Structure defining an ADC speed for the ADAndor driver. @@ -97,7 +98,8 @@ class AndorCCD : public ADDriver { int AndorAdcSpeed; int AndorBaselineClamp; int AndorReadOutMode; - #define LAST_ANDOR_PARAM AndorReadOutMode + int AndorFrameTransferMode; + #define LAST_ANDOR_PARAM AndorFrameTransferMode private: From 81138d5a18fed14a6c145aed53668826b4858d2d Mon Sep 17 00:00:00 2001 From: Michael Dunning Date: Sun, 5 Nov 2017 18:13:10 -0800 Subject: [PATCH 2/5] Add support for Vertical Shift Period --- andorApp/Db/andorCCD.template | 15 ++++++++ andorApp/Db/andorCCD_settings.req | 1 + andorApp/src/andorCCD.cpp | 60 ++++++++++++++++++++++++++++++- andorApp/src/andorCCD.h | 23 +++++++++++- 4 files changed, 97 insertions(+), 2 deletions(-) diff --git a/andorApp/Db/andorCCD.template b/andorApp/Db/andorCCD.template index cd0c6c1..441492d 100644 --- a/andorApp/Db/andorCCD.template +++ b/andorApp/Db/andorCCD.template @@ -406,6 +406,21 @@ record(bi, "$(P)$(R)AndorFTMode_RBV") field(SCAN, "I/O Intr") } +# The Vertical Shift Period enum values are constructed at run-time based on camera capabilities +record(mbbo, "$(P)$(R)AndorVSPeriod") +{ + field(PINI, "1") + field(DTYP, "asynInt32") + field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))ANDOR_VS_PERIOD") +} + +record(mbbi, "$(P)$(R)AndorVSPeriod_RBV") +{ + field(DTYP, "asynInt32") + field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))ANDOR_VS_PERIOD") + 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 f966548..ae4b090 100644 --- a/andorApp/Db/andorCCD_settings.req +++ b/andorApp/Db/andorCCD_settings.req @@ -10,6 +10,7 @@ $(P)$(R)AndorEMGainAdvanced $(P)$(R)AndorADCSpeed $(P)$(R)AndorReadOutMode $(P)$(R)AndorFTMode +$(P)$(R)AndorVSPeriod 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 2ce9a87..1b6140e 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -154,6 +154,7 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int shamrockID createParam(AndorBaselineClampString, asynParamInt32, &AndorBaselineClamp); createParam(AndorReadOutModeString, asynParamInt32, &AndorReadOutMode); createParam(AndorFrameTransferModeString, asynParamInt32, &AndorFrameTransferMode); + createParam(AndorVerticalShiftPeriodString, asynParamInt32, &AndorVerticalShiftPeriod); // 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. @@ -182,6 +183,12 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int shamrockID mPreAmpGains[i].EnumString = (char *)calloc(MAX_ENUM_STRING_SIZE, sizeof(char)); } + // Initialize Vertical Shift Period enums + for (i=0; iIndex = i; + pPeriod->Period = VSPeriod; + epicsSnprintf(pPeriod->EnumString, MAX_ENUM_STRING_SIZE, + "%.2f us", VSPeriod); + mNumVSPeriods++; + if (mNumVSPeriods >= MAX_VS_PERIODS) return; + pPeriod++; + } +} /** Report status of the driver. @@ -457,6 +494,8 @@ void AndorCCD::report(FILE *fp, int details) unsigned int uIntParam5; unsigned int uIntParam6; AndorADCSpeed_t *pSpeed; + int vsIndex; + float vsPeriod; static const char *functionName = "report"; fprintf(fp, "Andor CCD port=%s\n", this->portName); @@ -498,6 +537,16 @@ void AndorCCD::report(FILE *fp, int details) fprintf(fp, " Index=%d, Gain=%f\n", mPreAmpGains[i].EnumValue, mPreAmpGains[i].Gain); } + + fprintf(fp, " Vertical Shift Periods available: %d\n", mNumVSPeriods); + for (i=0; ipasynUserSelf, ASYN_TRACE_FLOW, @@ -1175,6 +1228,11 @@ asynStatus AndorCCD::setupAcquisition() driverName, functionName, frameTransferMode); checkStatus(SetFrameTransferMode(frameTransferMode)); + asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, + "%s:%s:, SetVSSpeed(%d)\n", + driverName, functionName, verticalShiftPeriod); + checkStatus(SetVSSpeed(verticalShiftPeriod)); + switch (imageMode) { case ADImageSingle: if (numExposures == 1) { diff --git a/andorApp/src/andorCCD.h b/andorApp/src/andorCCD.h index 625ab6a..1603fb5 100755 --- a/andorApp/src/andorCCD.h +++ b/andorApp/src/andorCCD.h @@ -20,6 +20,7 @@ #define MAX_ENUM_STRING_SIZE 26 #define MAX_ADC_SPEEDS 16 #define MAX_PREAMP_GAINS 16 +#define MAX_VS_PERIODS 16 #define AndorCoolerParamString "ANDOR_COOLER" #define AndorTempStatusMessageString "ANDOR_TEMP_STAT" @@ -36,6 +37,7 @@ #define AndorBaselineClampString "ANDOR_BASELINE_CLAMP" #define AndorReadOutModeString "ANDOR_READOUT_MODE" #define AndorFrameTransferModeString "ANDOR_FT_MODE" +#define AndorVerticalShiftPeriodString "ANDOR_VS_PERIOD" /** * Structure defining an ADC speed for the ADAndor driver. @@ -61,6 +63,16 @@ typedef struct { int EnumValue; } AndorPreAmpGain_t; +/* + * Structure defining a Vertical Shift Period for the ADAndor driver. + */ +typedef struct { + float Period; + int Index; + char *EnumString; + int EnumValue; +} AndorVSPeriod_t; + /** * Driver for Andor CCD cameras using version 2 of their SDK; inherits from ADDriver class in ADCore. * @@ -99,7 +111,8 @@ class AndorCCD : public ADDriver { int AndorBaselineClamp; int AndorReadOutMode; int AndorFrameTransferMode; - #define LAST_ANDOR_PARAM AndorFrameTransferMode + int AndorVerticalShiftPeriod; + #define LAST_ANDOR_PARAM AndorVerticalShiftPeriod private: @@ -109,6 +122,7 @@ class AndorCCD : public ADDriver { void saveDataFrame(int frameNumber); void setupADCSpeeds(); void setupPreAmpGains(); + void setupVerticalShiftPeriods(); unsigned int SaveAsSPE(char *fullFileName); /** * Additional image mode to those in ADImageMode_t @@ -195,6 +209,13 @@ class AndorCCD : public ADDriver { int mNumPreAmpGains; AndorPreAmpGain_t mPreAmpGains[MAX_PREAMP_GAINS]; + // Vertical Shift Period parameters + int mTotalVSPeriods; + int mNumVSPeriods; + int mVSIndex; + float mVSPeriod; + AndorVSPeriod_t mVSPeriods[MAX_VS_PERIODS]; + //Shutter control parameters float mAcquireTime; float mAcquirePeriod; From 6d2be9f6b0cbd3ed0b74205b0761ab9bd65bcd3c Mon Sep 17 00:00:00 2001 From: Michael Dunning Date: Sun, 5 Nov 2017 19:46:29 -0800 Subject: [PATCH 3/5] Add try/catch block for call to SetBaselineClamp() --- andorApp/src/andorCCD.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/andorApp/src/andorCCD.cpp b/andorApp/src/andorCCD.cpp index 1b6140e..47b1a52 100755 --- a/andorApp/src/andorCCD.cpp +++ b/andorApp/src/andorCCD.cpp @@ -668,7 +668,14 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value) status = setupShutter(-1); } else if (function == AndorBaselineClamp) { - checkStatus(SetBaselineClamp(value)); + try { + checkStatus(SetBaselineClamp(value)); + } catch (const std::string &e) { + asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, + "%s:%s: %s\n", + driverName, functionName, e.c_str()); + status = asynError; + } } else { status = ADDriver::writeInt32(pasynUser, value); From d69c97e28ca98c53b701cccd4d786959c75a32f6 Mon Sep 17 00:00:00 2001 From: Michael Dunning Date: Tue, 12 Dec 2017 11:03:30 -0800 Subject: [PATCH 4/5] Update documentation --- documentation/andorDoc.html | 53 ++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/documentation/andorDoc.html b/documentation/andorDoc.html index 6a9bbd1..a9ad5b2 100755 --- a/documentation/andorDoc.html +++ b/documentation/andorDoc.html @@ -48,11 +48,12 @@
  • Support for all of the Andor shutter modes
  • Support for reading the detectors with 16-bit or 32-bit depth
  • Saving files using the Andor SDK and/or with the standard areaDetector plugins
  • -
  • Change the ADC sampling speed (0.05MHz and 2.5MHz on the iKon)
  • +
  • Change the ADC sampling speed (0.05MHz and 2.5MHz on the iKon) and the Vertical Shift Period
  • Set a region of interest (a smaller region can be read out faster)
  • Set and monitor the CCD temperature
  • Electron Multiplying (EM) Gain on supported detectors
  • Support for selecting between Full Vertical Binning (FVB) and Image readout modes
  • +
  • Support for Frame Transfer mode
  • The Andor module includes a separate driver to control the Andor Shamrock spectrographs. @@ -716,6 +717,56 @@ mbbo
    mbbi + + + AndorFTMode + + asynInt32 + + R/W + + Set Frame Transfer mode. Choices are: +

      +
    • Disabled
    • +
    • Enabled
    • +
    + Note: Only available on supported CCDs. + + + ANDOR_FT_MODE + + AndorFTMode
    + AndorFTMode_RBV + + bo
    + bi + + + + AndorVSPeriod + + asynInt32 + + R/W + + Sets Vetical Shift Period, in units of microseconds per pixel shift.
    + Choices are constructed at runtime. For example, the choices for an iDus are: +
      +
    • 4.25 us
    • +
    • 8.25 us
    • +
    • 16.25 us
    • +
    • 32.25 us
    • +
    • 64.25 us
    • +
    + + ANDOR_VS_PERIOD + + AndorVSPeriod
    + AndorVSPeriod_RBV + + mbbo
    + mbbi +

    From 5daf4e2e74b2b59cd80d4b878529732644a00d30 Mon Sep 17 00:00:00 2001 From: Michael Dunning Date: Tue, 12 Dec 2017 11:08:52 -0800 Subject: [PATCH 5/5] Update RELEASE.md --- RELEASE.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RELEASE.md b/RELEASE.md index 748dd0f..529bc43 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -22,6 +22,11 @@ files respectively, in the configure/ directory of the appropriate release of th Release Notes ============= +RX-X () +---- +* Added support for Frame Transfer mode. +* Added support for setting the Vertical Shift Period. + R2-6 (July 4, 2017) ---- * Changed from using TinyXml to libxml2. This is used when saving SPE files. This change was made