Add support for Vertical Shift Period

This commit is contained in:
Michael Dunning
2017-11-05 18:13:10 -08:00
parent afc7109cd2
commit 81138d5a18
4 changed files with 97 additions and 2 deletions
+15
View File
@@ -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")
+1
View File
@@ -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)
+59 -1
View File
@@ -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; i<MAX_VS_PERIODS; i++) {
mVSPeriods[i].EnumValue = i;
mVSPeriods[i].EnumString = (char *)calloc(MAX_ENUM_STRING_SIZE, sizeof(char));
}
// Initialize camera
try {
printf("%s:%s: initializing camera\n",
@@ -197,6 +204,7 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int shamrockID
checkStatus(SetReadMode(ARImage));
checkStatus(SetImage(binX, binY, minX+1, minX+sizeX, minY+1, minY+sizeY));
checkStatus(GetShutterMinTimes(&mMinShutterCloseTime, &mMinShutterOpenTime));
checkStatus(GetFastestRecommendedVSSpeed(&mVSIndex, &mVSPeriod));
mCapabilities.ulSize = sizeof(mCapabilities);
checkStatus(GetCapabilities(&mCapabilities));
callParamCallbacks();
@@ -254,6 +262,8 @@ AndorCCD::AndorCCD(const char *portName, const char *installPath, int shamrockID
setupADCSpeeds();
setupPreAmpGains();
setupVerticalShiftPeriods();
status |= setIntegerParam(AndorVerticalShiftPeriod, mVSIndex);
status |= setupShutter(-1);
callParamCallbacks();
@@ -397,6 +407,14 @@ asynStatus AndorCCD::readEnum(asynUser *pasynUser, char *strings[], int values[]
severities[i] = 0;
}
}
else if (function == AndorVerticalShiftPeriod) {
for (i=0; ((i<mNumVSPeriods) && (i<(int)nElements)); i++) {
if (strings[i]) free(strings[i]);
strings[i] = epicsStrDup(mVSPeriods[i].EnumString);
values[i] = mVSPeriods[i].EnumValue;
severities[i] = 0;
}
}
else {
*nIn = 0;
return asynError;
@@ -436,6 +454,25 @@ void AndorCCD::setupADCSpeeds()
}
}
void AndorCCD::setupVerticalShiftPeriods()
{
int i, numVSPeriods;
float VSPeriod;
AndorVSPeriod_t *pPeriod = mVSPeriods;
mNumVSPeriods = 0;
checkStatus(GetNumberVSSpeeds(&numVSPeriods));
for (i=0; i<numVSPeriods; i++) {
checkStatus(GetVSSpeed(i, &VSPeriod));
pPeriod->Index = 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; i<mNumVSPeriods; i++) {
fprintf(fp, " Index=%d, Period=%f [us per pixel shift]\n",
mVSPeriods[i].EnumValue, mVSPeriods[i].Period);
}
fprintf(fp, " Fastest recommended Vertical Shift Period:\n");
checkStatus(GetFastestRecommendedVSSpeed(&vsIndex, &vsPeriod));
fprintf(fp, " Index=%d, Period=%f [us per pixel shift]\n", vsIndex, vsPeriod);
fprintf(fp, " Capabilities\n");
fprintf(fp, " AcqModes=0x%X\n", (int)mCapabilities.ulAcqModes);
fprintf(fp, " ReadModes=0x%X\n", (int)mCapabilities.ulReadModes);
@@ -585,7 +634,8 @@ asynStatus AndorCCD::writeInt32(asynUser *pasynUser, epicsInt32 value)
(function == ADTriggerMode) || (function == AndorEmGain) ||
(function == AndorEmGainMode) || (function == AndorEmGainAdvanced) ||
(function == AndorAdcSpeed) || (function == AndorPreAmpGain) ||
(function == AndorReadOutMode) || (function == AndorFrameTransferMode)) {
(function == AndorReadOutMode) || (function == AndorFrameTransferMode) ||
(function == AndorVerticalShiftPeriod)) {
status = setupAcquisition();
if (function == AndorAdcSpeed) setupPreAmpGains();
if (status != asynSuccess) setIntegerParam(function, oldValue);
@@ -1009,6 +1059,7 @@ asynStatus AndorCCD::setupAcquisition()
AndorADCSpeed_t *pSpeed;
int readOutMode;
int frameTransferMode;
int verticalShiftPeriod;
static const char *functionName = "setupAcquisition";
if (!mInitOK) {
@@ -1099,6 +1150,8 @@ asynStatus AndorCCD::setupAcquisition()
setIntegerParam(NDArraySizeY, sizeY/binY);
getIntegerParam(AndorFrameTransferMode, &frameTransferMode);
getIntegerParam(AndorVerticalShiftPeriod, &verticalShiftPeriod);
try {
asynPrint(this->pasynUserSelf, 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) {
+22 -1
View File
@@ -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;