EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: AreaDetector: PVs from driver created parameters not updating
From: Mark Rivers via Tech-talk <tech-talk at aps.anl.gov>
To: David Vine <dvine at sigray.com>, Mark Rivers <rivers at cars.uchicago.edu>
Cc: "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov>
Date: Tue, 1 Sep 2020 13:12:17 +0000
Hi David,


Please ignore my previous response.  The functions that were missing callParamCallbacks() are only called at initialization, and so callParamCallbacks() will be quickly called by some other function.


Your actual problem is your db template file.  All of your input records need to have SCAN=I/O Intr.  That is what causes the records to process in response to the callback from the driver to device support.  Right now they don't have a SCAN field entry at all, so they are Passive and will never be processed.


Mark



________________________________
From: Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of Mark Rivers via Tech-talk <tech-talk at aps.anl.gov>
Sent: Monday, August 31, 2020 8:30 PM
To: David Vine
Cc: tech-talk at aps.anl.gov
Subject: Re: AreaDetector: PVs from driver created parameters not updating

Hi David,

In your functions updateCamInfo() and updateGrabberInfo() you are not calling callParamCallbacks(), but you need to do that.  There may also be other places you need to add that call.

Mark


Sent from my iPhone

On Aug 31, 2020, at 7:23 PM, David Vine via Tech-talk <tech-talk at aps.anl.gov> wrote:


Hi all,

PVs associated with parameters I created in my driver don't update.

For example in my driver I can use setIntegerParam and getIntegerParam to set and get parameters that are created in the driver with createParam and it works fine. But the PVs associated with those parameters don't update.

When PVs are updated externally through MEDM the driver responds ok.

Any advice would be appreciated.

Below is the:

  1.  cpp
  2.  db template
  3.  ioc boot output

##########
##raptor.cpp##
##########
/* This is a driver for the Raptor Photonics Eagle XV camera. It uses the EPIX
 * fram grabber over Camera Link bus.
 *
 * Author: D. J. Vine
 * Date: 8/1/2020
 *
 */

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <chrono>
#include <bitset>
#include <mutex>
#include <string>

#include <epicsEvent.h>
#include <epicsTime.h>
#include <epicsThread.h>
#include <iocsh.h>
#include <epicsString.h>
#include <epicsExit.h>
#include <epicsExport.h>

#include "xcliball.h"

#include <ADDriver.h>

#define RaptorFPGABootOkString "R_FPGA_BOOT"  /**< (asynInt32, r/w) FPGA booted ok */
#define RaptorFanEnabledString "R_FAN_ENABLED"  /**< (asynInt32, r/w) Camera fan enabled */
#define RaptorOverTempString "R_OVERTEMP"  /**< (asynInt32, r/o) Overtemp >80deg C triggered */
#define RaptorTECEnabledString "R_TEC_ENABLED"  /**< (asynInt32, r/w) Enable TEC */
#define RaptorADCSpeedString "R_ADC_SPEED"  /**< (asynInt32, r/w) Camera ADC speed (10, 20, 40 MHz)*/
#define RaptorReadOutModeString "R_READOUT_MODE"  /**< (asynInt32, r/w) Camera data or test pattern */
#define RaptorPCBTempString "R_PCB_TEMP"  /**< (asynFloat64, r/o) Camera PCB temp */
#define RaptorSiliconTempString "R_SILICON_TEMP"  /**< (asynFloat64, r/o) Sensor temperature */
#define RaptorEMGainString "R_EM_GAIN"  /**< (asynInt32, r/w) Em gain */
#define RaptorFrameTransferModeString "R_FRAME_TX"  /**< (asynInt32, r/w) Enable frame transfer mode */
#define GrabberNumBuffersString "G_NUM_BUFFERS"  /**< (asynInt32, r/o) The "number of image frame buffers" */
#define GrabberDriverIdString "G_DRIVER_ID"  /**< (asynOctet, r/o) The identification string of the PIXCI frame grabber */
#define GrabberIncludeIdString "G_INCLUDE_ID"  /**< (asynOctet, r/o) Identification string of the current include files */
#define GrabberLibraryIdString "G_LIBRARY_ID"  /**< (asynOctet, r/o) Identification string of the current frame grabber library. */
#define GrabberMemSizeString "G_MEM_SIZE"  /**< (asynInt32, r/o) Size (B) of frame buffer memory */
#define GrabberModelString "G_MODEL"  /**< (asynInt32, r/o) Model designation of frame grabber */
#define GrabberSubModelString "G_SUBMODEL"  /**< (asynInt32, r/o) Submodel of frame grabber */
#define GrabberUnitsString "G_UNITS"  /**< (asynInt32, r/o) Number of frame grabbers installed */

static const char* driverName = "raptor";
std::mutex raptorSerialPort;

class raptor : public ADDriver
{
public:
raptor(const char* portName, int maxBuffers, size_t maxMemory, int priority, int stackSize, const char* formatFile);

/* Virtual methods to override from ADDriver */
virtual asynStatus writeInt32( asynUser *pasynUser, epicsInt32 value) override;
virtual asynStatus writeFloat64( asynUser *pasynUser, epicsFloat64 value) override;

void imageGrabTask();
void shutdown();
void tempTask();
void asynImageCallback();
void report(FILE *fp, int details);

protected:
int raptorFPGABootOk;
#define FIRST_RAPTOR_PARAM raptorFPGABootOk
int raptorFanEnabled;
int raptorOverTemp;
int raptorTECEnabled;
int raptorADCSpeed;
int raptorReadOutMode;
int raptorPCBTemp;
int raptorSiliconTemp;
int raptorEMGainSetPoint;
int raptorFrameTransferMode;
int grabberNumBuffers;
int grabberDriverId;
int grabberIncludeId;
int grabberLibraryId;
int grabberMemSize;
int grabberModel;
int grabberSubModel;
int grabberUnits;
#define LAST_RAPTOR_PARAM grabberUnits

private:
asynStatus grabImage(int lastBuffer);
asynStatus startCapture();
asynStatus stopCapture();
static asynStatus handleCamLinkError(std::string source, int32_t rapStatus);
static std::vector<uint8_t> writeRead(std::vector<uint8_t> cmd, uint32_t numBytesExpected, std::string msg, uint32_t timeout);
static asynStatus readByteAddress(uint8_t addr, uint8_t &value, std::string msg="");
static asynStatus writeByteAddress(uint8_t addr, uint8_t value, std::string msg="");
asynStatus setExposureTime(double exposureTime);
asynStatus getExposureTime(double &exposureTime);
asynStatus updateGrabberInfo();
asynStatus writeStatus(uint8_t status, std::string msg);
asynStatus writeFPGAStatus(uint8_t value, std::string msg);
asynStatus updateFPGAStatus();
asynStatus updateManufacturerData();
asynStatus getSensorTemp(double &value);
asynStatus getPCBTemp(double &value);
asynStatus getTECSP(double &tecSP);
asynStatus setTECSP(double tecSP);
uint16_t   convertTempToCounts(double temp, uint16_t AdcCountsZero, uint16_t AdcCalForty);
double     convertCountsToTemp(uint16_t counts, uint16_t DacCountsZero, uint16_t DacCountsForty);
asynStatus setTECState(bool state);
asynStatus setReadoutMode(uint8_t mode);
asynStatus getReadoutClock(uint8_t &value);
asynStatus setReadoutClock(uint8_t value);
void report();
asynStatus abortCurrentExposure(void);
asynStatus updateCamInfo();
asynStatus readTickUnits(void);
asynStatus readTickNow(uint64_t &nowTime);
asynStatus updateTimeRemaining(uint64_t imageStartTicks, double &timeRemaining);


asynStatus openCamera(void);
asynStatus initCamera(void);
asynStatus disconnectCamera();

int exiting_;
epicsEventId startEventId_;
NDArray *pRaw_;

uint16_t DacCalZero;
uint16_t DacCalForty;
uint16_t AdcCalZero;
uint16_t AdcCalForty;
uint16_t serialNumber;
uint8_t  buildDate[3];
char     buildCode[5];
double   secondsPerTick;
double   readoutTime = 0.688;

const char* formatFile;
std::string fmtFile = formatFile;
};

#define NUM_RAPTOR_PARAMS ((int)(&LAST_RAPTOR_PARAM-&FIRST_RAPTOR_PARAM+1))

/* Configuration function to configure one camera
 *
 * This function needs to be called once for each camera used by the IOC. A
 * call to this function instantiates one object of the Tucsen class.
 * \param[in] portName asyn port to assign to the camera
 * \param[in] maxBuffers Maximum number of NDArray objects (image buffers) this
 *            driver is allowed to allocate.
 *            0 = unlimited
 * \param[in] maxMemory Maximum memort (in bytes) that this driver is allowed
 *            to allocate.
 *            0=unlimited
 * \param[in] priority The epics thread priority for this driver. 0= asyn
 *            default.
 * \param[in] stackSize The size of the stack of the EPICS port thread. 0=use
 *            asyn default.
 */
extern "C" int raptorConfig(const char *portName, int maxBuffers, size_t maxMemory, int priority, int stackSize, const char* formatFile)
{
new raptor(portName, maxBuffers, maxMemory, priority, stackSize, formatFile);
return asynSuccess;
}

static void c_shutdown(void *arg)
{
raptor *r = (raptor *)arg;
r->shutdown();
}

static void imageGrabTaskC(void *drvPvt)
{
raptor *r = (raptor *)drvPvt;
r->imageGrabTask();
}

static void tempReadTaskC(void *drvPvt)
{
raptor *r = (raptor *)drvPvt;
r->tempTask();
}

static void asyncImageCallbackC(void *drvPvt)
{
raptor *r = (raptor *)drvPvt;
r->asynImageCallback();
}

/* Constructor for Raptor class */
raptor::raptor(const char *portName, int maxBuffers, size_t maxMemory, int priority, int stackSize, const char* formatFile)
: ADDriver( portName, 1, NUM_RAPTOR_PARAMS, maxBuffers, maxMemory, asynEnumMask, asynEnumMask, ASYN_CANBLOCK | ASYN_MULTIDEVICE, 1, priority, stackSize),
 exiting_(0), pRaw_(NULL), formatFile(formatFile)
{
static const char *functionName = "raptor";

asynStatus status;
int traceMask = ASYN_TRACE_ERROR;
pasynTrace->setTraceMask(pasynUserSelf, traceMask);

createParam(RaptorFPGABootOkString,        asynParamInt32, &raptorFPGABootOk);
createParam(RaptorFanEnabledString,        asynParamInt32, &raptorFanEnabled);
createParam(RaptorOverTempString,   asynParamInt32, &raptorOverTemp);
createParam(RaptorTECEnabledString,        asynParamInt32, &raptorTECEnabled);
createParam(RaptorADCSpeedString,          asynParamInt32, &raptorADCSpeed);
createParam(RaptorReadOutModeString,       asynParamInt32, &raptorReadOutMode);
createParam(RaptorPCBTempString,           asynParamFloat64, &raptorPCBTemp);
createParam(RaptorSiliconTempString,       asynParamFloat64, &raptorSiliconTemp);
createParam(RaptorEMGainString,            asynParamInt32, &raptorEMGainSetPoint);
createParam(RaptorFrameTransferModeString, asynParamInt32, &raptorFrameTransferMode);
createParam(GrabberNumBuffersString,   asynParamInt32, &grabberNumBuffers);
createParam(GrabberDriverIdString,         asynParamOctet, &grabberDriverId);
createParam(GrabberIncludeIdString,        asynParamOctet, &grabberIncludeId);
createParam(GrabberLibraryIdString,        asynParamOctet, &grabberLibraryId);
createParam(GrabberMemSizeString,   asynParamFloat64, &grabberMemSize);
createParam(GrabberModelString,            asynParamInt32, &grabberModel);
createParam(GrabberSubModelString,         asynParamInt32, &grabberSubModel);
createParam(GrabberUnitsString,   asynParamInt32, &grabberUnits);

/* Set initial values for some parameters */
setIntegerParam(NDDataType, NDUInt16);
setIntegerParam(NDColorMode, NDColorModeMono);
setIntegerParam(NDArraySizeZ, 1);
setIntegerParam(ADMinX, 0);
setIntegerParam(ADMinY, 0);
setIntegerParam(ADSizeX, pxd_imageXdim());
setIntegerParam(ADSizeY, pxd_imageYdim());
setStringParam(ADManufacturer, "Raptor Photonics");
setIntegerParam(ADMaxSizeX, pxd_imageXdim());
setIntegerParam(ADMaxSizeY, pxd_imageYdim());
setIntegerParam(NDArraySizeX, pxd_imageXdim());
setIntegerParam(NDArraySizeY, pxd_imageYdim());
setIntegerParam(NDArraySize, pxd_imageXdim()*pxd_imageYdim()*pxd_imageCdim());
setIntegerParam(grabberUnits, 999);
callParamCallbacks();
int32_t value;
getIntegerParam(grabberUnits, &value);
std::cout << "Grabberunits: " << value << std::endl;

status = openCamera();
status = initCamera();

if(status){
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s:%s: camera connection failed (%d)\n",
driverName, functionName, status);
report(stdout, 1);
exit(1);
}

startEventId_ = epicsEventCreate(epicsEventEmpty);

/* Launch image read task */
asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s: create image read thread\n",
driverName, functionName);
epicsThreadCreate("RaptorImageReadTask",
epicsThreadPriorityMedium,
epicsThreadGetStackSize(epicsThreadStackMedium),
imageGrabTaskC, this);

/* Launch temp task */
asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s: create temp read thread\n",
driverName, functionName);

epicsThreadCreate("RaptorTempReadTask",
epicsThreadPriorityMedium,
epicsThreadGetStackSize(epicsThreadStackMedium),
tempReadTaskC, this);

/* Launch shutdown task */
epicsAtExit(c_shutdown, this);

return;
}

void raptor::shutdown(void)
{
exiting_=1;
disconnectCamera();
}

asynStatus raptor::openCamera(void){
static const char* functionName = "openCamera";
int rapStatus;

asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s: opening grabber\n",
driverName, functionName);

printf("Format file: %s\n", formatFile);
rapStatus = pxd_PIXCIopen("", "default", formatFile);
if (rapStatus<0){
handleCamLinkError("pixci open", rapStatus);
return asynError;
}
rapStatus = pxd_serialConfigure(0x1, 0, 115200, 8, 0, 1, 0, 0, 0);
if (rapStatus<0){
handleCamLinkError("serial configure", rapStatus);
return asynError;
}

return asynSuccess;
}

asynStatus raptor::initCamera(void){
writeStatus(0x56, "Set ack and checksum"); //Set ack and checksum
updateFPGAStatus();
updateManufacturerData();
updateCamInfo();
updateGrabberInfo();
report();
return asynSuccess;
}

asynStatus raptor::updateCamInfo(void){
lock();
setIntegerParam(ADMaxSizeX, pxd_imageXdim());
setIntegerParam(ADSizeX, pxd_imageXdim());
setIntegerParam(NDArraySizeX, pxd_imageXdim());
setIntegerParam(ADMaxSizeY, pxd_imageYdim());
setIntegerParam(ADSizeY, pxd_imageYdim());
setIntegerParam(NDArraySizeY, pxd_imageYdim());
setIntegerParam(NDArraySize, pxd_imageCdim()*pxd_imageXdim()*pxd_imageYdim());
setIntegerParam(NDDataType, NDUInt16);
setIntegerParam(NDColorMode, NDColorModeMono);
setIntegerParam(NDNDimensions, 2);
setIntegerParam(ADBinX, 1);
setIntegerParam(ADBinY, 1);
setIntegerParam(grabberUnits, 999);

unlock();
return asynSuccess;
}

asynStatus raptor::updateGrabberInfo(){
int numBuffers = pxd_imageZdim();
std::string driverId   = pxd_infoDriverId();
std::string includeId  = pxd_infoIncludeId();
std::string libraryId  = pxd_infoLibraryId();
double memSize    = (double)pxd_infoMemsize(0x1)/(1024.*1024.);
int model      = pxd_infoModel(0x1);
int subModel   = pxd_infoSubmodel(0x1);
int units      = pxd_infoUnits();

lock();
asynStatus status = setIntegerParam(grabberNumBuffers, numBuffers);
status = setStringParam(grabberDriverId, driverId);
status = setStringParam(grabberIncludeId, includeId);
status = setStringParam(grabberLibraryId, libraryId);
status = setDoubleParam(grabberMemSize, memSize);
status = setIntegerParam(grabberModel, model);
status = setIntegerParam(grabberSubModel, subModel);
status = setIntegerParam(grabberUnits, units);
unlock();
return status;
}

asynStatus raptor::writeStatus(uint8_t value, std::string msg){
std::string functionName = "writeStatus";
std::vector<uint8_t> statusMesg = {0x4F, value, 0x50};

std::lock_guard<std::mutex> lg(raptorSerialPort);
std::vector<uint8_t> reply = writeRead(statusMesg, 1, msg, 500);

if ((reply.size()==0)||(reply[0]!=0x50)){
std::cerr << driverName << ":" << functionName
<< " writing status failed." << std::endl;
return asynError;
}
return asynSuccess;
}



asynStatus raptor::updateFPGAStatus(){
std::string functionName = "updateFPGAStatus";

uint8_t fpgaStatus[1];
bool tecEnabled       = false;
bool overTemp         = false;
if (!readByteAddress(0x00, fpgaStatus[0], "Read fpga status")){
tecEnabled = (fpgaStatus[0]&0x01)?true:false;
overTemp   = (fpgaStatus[0]&0x02)?true:false;
} else {
return asynError;
}
lock();
asynStatus status = setIntegerParam(raptorTECEnabled, tecEnabled);
status = setIntegerParam(raptorOverTemp, overTemp);
callParamCallbacks();
unlock();
return status;
}

asynStatus raptor::updateManufacturerData(){
std::string functionName = "updateManufacturerData";
asynStatus status;
std::vector<uint8_t> addrCmd = {0x53, 0xAE, 0x05, 0x01, 0x00, 0x00, 0x02, 0x00, 0x50};
std::vector<uint8_t> confCmd = {0x53, 0xAF, 0x12, 0x50};

writeStatus(0x57, "Turn eeprom comms on"); // Enable FPGA EEPROM comms
raptorSerialPort.lock();
std::vector<uint8_t> reply =  writeRead(addrCmd, 1, "Get manufacturer data", 500);
raptorSerialPort.unlock();
if ((reply.size()==2)&&(reply[0]==0x50)){
raptorSerialPort.lock();
reply = writeRead(confCmd, 18, "", 500);
raptorSerialPort.unlock();

if (reply.size()>=18){
serialNumber = reply[0] | reply[1]<<8;
buildDate[0] = reply[2];
buildDate[1] = reply[3];
buildDate[2] = reply[4];
buildCode[0] = reply[5];
buildCode[1] = reply[6];
buildCode[2] = reply[7];
buildCode[3] = reply[8];
buildCode[4] = reply[9];
AdcCalZero   = reply[10] | reply[11] << 8;
AdcCalForty  = reply[12] | reply[13] << 8;
DacCalZero   = reply[14] | reply[15] << 8;
DacCalForty  = reply[16] | reply[17] << 8;

lock();
status = setStringParam(ADModel, "Eagle XV");
status = setStringParam(ADSerialNumber, std::to_string(serialNumber));
status = setStringParam(ADSDKVersion, pxd_infoDriverId());
unlock();
}
} else {
return asynError;
}
writeStatus(0x56, "Turn EEPROM comms off"); // Disable FPGA EEPROM comms
return status;
}

asynStatus raptor::getSensorTemp(double &value){
uint8_t tempBytes[2] = {0};
if (!readByteAddress(0x6E, tempBytes[1])&&
   !readByteAddress(0x6F, tempBytes[0])){
uint16_t tempCounts = (uint16_t)tempBytes[0]+
(uint16_t)tempBytes[1]*0x100;
value = convertCountsToTemp(tempCounts, AdcCalZero, AdcCalForty);
return asynSuccess;
} else {
return asynError;
}
}

asynStatus raptor::getPCBTemp(double &value){
uint8_t tempBytes[2] = {0};
if (!readByteAddress(0x70, tempBytes[1])&&
   !readByteAddress(0x71, tempBytes[0])){
uint16_t tempCounts = (uint16_t)tempBytes[0]+
(uint16_t)tempBytes[1]*0x100;
value = convertCountsToTemp(tempCounts, AdcCalZero, AdcCalForty);
return asynSuccess;
} else {
return asynError;
}
}

asynStatus raptor::getTECSP(double &value){
uint8_t tempBytes[2] = {0};
if (!readByteAddress(0x03, tempBytes[1])&&
   !readByteAddress(0x04, tempBytes[0])){
uint16_t tempCounts = (uint16_t)tempBytes[0]+
(uint16_t)tempBytes[1]*0x100;
value = convertCountsToTemp(tempCounts, AdcCalZero, AdcCalForty);
return asynSuccess;
} else {
return asynError;
}
}

asynStatus raptor::setTECSP(double value){
uint16_t tempCounts = convertTempToCounts(value, DacCalZero, DacCalForty);
uint8_t msb = (uint8_t)((tempCounts>>8)&0xFF);
uint8_t lsb = (uint8_t)((tempCounts   )&0xFF);
asynStatus status = writeByteAddress(0x03, msb);
status            = writeByteAddress(0x04, lsb);
return status;
}

uint16_t raptor::convertTempToCounts(double temp, uint16_t DacCalZero, uint16_t DacCalForty){
double slope = 40.0/(DacCalForty-DacCalZero);
double intercept = 0. - slope * DacCalZero;

return (temp-intercept)/slope;
}

double raptor::convertCountsToTemp(uint16_t counts, uint16_t AdcCalZero, uint16_t AdcCalForty){
double slope = 40./(AdcCalForty-AdcCalZero);
double intercept = 0. - slope*AdcCalZero;

return intercept + slope*counts;
}

asynStatus raptor::setTECState(bool state){
uint8_t fpgaStatus[1];
if (!readByteAddress(0x00, fpgaStatus[0], "Read fpga status")){
if (state==true){
fpgaStatus[0] |= 0x01;
} else {
fpgaStatus[0] ^= 0x01;
}
writeByteAddress(0x00, fpgaStatus[0]);
} else {
return asynError;
}
return asynSuccess;
}

asynStatus raptor::setReadoutMode(uint8_t mode){
asynStatus status;
if (mode==1){
status = writeByteAddress(0xF7, 0x04);
} else {
status = writeByteAddress(0xF1, 0x01);
}
return status;
}

asynStatus raptor::getReadoutClock(uint8_t &value){
uint8_t adcSpeed[2] = {0};
if (!readByteAddress(0xA3, adcSpeed[1])&&
   !readByteAddress(0xA4, adcSpeed[0])){
if ((adcSpeed[1]==0x02)&(adcSpeed[0]==0x02)){
value = 0; // 2MHz
} else if ((adcSpeed[1]==0x43)&(adcSpeed[0]==0x80)){
value=1; //75kHz
}
return asynSuccess;
} else {
return asynError;
}
}

asynStatus raptor::setReadoutClock(uint8_t value){
asynStatus status;
if (value==0){ //2MHz
status = writeByteAddress(0xA3, 0x02);
status = writeByteAddress(0xA4, 0x02);
} else if (value==1){ //75kHz
status = writeByteAddress(0xA3, 0x43);
status = writeByteAddress(0xA4, 0x80);
}
return status;
}

asynStatus raptor::abortCurrentExposure(void){
uint8_t triggerMode[1];
if (asynSuccess==readByteAddress(0xD4, triggerMode[0], "Abort get trigger")){
triggerMode[0] = (triggerMode[0] | 0x08);
asynStatus status = writeByteAddress(0xD4, triggerMode[0], "Abort set trigger");
return status;
} else {
return asynError;
}
}

void raptor::report()
{
printf("Serial number: %d\n", serialNumber);
printf("Build date: %d/%d/%d\n", buildDate[0], buildDate[1], buildDate[2]);
printf("Build code: %s\n", buildCode);
printf("Bit depth: %d\n", pxd_imageBdim());
printf("Color dimensions: %d\n", pxd_imageCdim());
printf("Size X: %d\n", pxd_imageXdim());
printf("Size Y: %d\n", pxd_imageYdim());
printf("Num buffers: %d\n", pxd_imageZdim());
printf("Driver Id: %s\n", pxd_infoDriverId());
printf("Include Id: %s\n", pxd_infoIncludeId());
printf("Library Id: %s\n", pxd_infoLibraryId());
printf("Memory size: %3.2f\n", (double)(pxd_infoMemsize(0x1)/(1024.*1024.)));
printf("Model: %d\n", pxd_infoModel(0x1));
printf("SubModel: %d\n", pxd_infoSubmodel(0x1));
printf("Units: %d\n", pxd_infoUnits());

printf("\n\nTemp calibration\n");
printf("ADC Cal  0: %d\n", AdcCalZero);
printf("ADC Cal 40: %d\n", AdcCalForty);
printf("DAC Cal  0: %d\n", DacCalZero);
printf("DAC Cal 40: %d\n", DacCalForty);

return;
}

void raptor::report(FILE *fp, int details)
{
fprintf(fp, "Serial number: %d\n", serialNumber);
fprintf(fp, "Build date: %d/%d/%d\n", buildDate[0], buildDate[1], buildDate[2]);
fprintf(fp, "Build code: %s\n", buildCode);
fprintf(fp, "Bit depth: %d\n", pxd_imageBdim());
fprintf(fp, "Color dimensions: %d\n", pxd_imageCdim());
fprintf(fp, "Size X: %d\n", pxd_imageXdim());
fprintf(fp, "Size Y: %d\n", pxd_imageYdim());
fprintf(fp, "Num buffers: %d\n", pxd_imageZdim());
fprintf(fp, "Driver Id: %s\n", pxd_infoDriverId());
fprintf(fp, "Include Id: %s\n", pxd_infoIncludeId());
fprintf(fp, "Library Id: %s\n", pxd_infoLibraryId());
fprintf(fp, "Memory size: %3.2f\n", (double)(pxd_infoMemsize(0x1)/(1024.*1024.)));
fprintf(fp, "Model: %d\n", pxd_infoModel(0x1));
fprintf(fp, "SubModel: %d\n", pxd_infoSubmodel(0x1));
fprintf(fp, "Units: %d\n", pxd_infoUnits());

fprintf(fp, "\n\nTemp calibration\n");
fprintf(fp, "ADC Cal  0: %d\n", AdcCalZero);
fprintf(fp, "ADC Cal 40: %d\n", AdcCalForty);
fprintf(fp, "DAC Cal  0: %d\n", DacCalZero);
fprintf(fp, "DAC Cal 40: %d\n", DacCalForty);

ADDriver::report(fp, details);
return;
}

asynStatus raptor::disconnectCamera(void){
int acquiring;
asynStatus status;

// Check if acquiring
status = getIntegerParam(ADAcquire, &acquiring);

// If necessary stop acquisition
if (status==asynSuccess && acquiring){
int rapStatus = pxd_goAbortLive(0x1);
if (rapStatus!=0){
handleCamLinkError("Stop acquisition", rapStatus);
}
}

int rapStatus = pxd_PIXCIclose();
if (rapStatus!=0){
handleCamLinkError("PIXCI close", rapStatus);
}
return asynSuccess;
}

asynStatus raptor::startCapture()
{
static const char* functionName = "startCapture";
if (pxd_goneLive(0x1,0)==0){
lock();
asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s: Begin capture.\n",
driverName, functionName);
setIntegerParam(ADNumImagesCounter, 0);
callParamCallbacks();
unlock();
epicsEventSignal(startEventId_);
} else {
printf("Already acquiring\n");
}
return asynSuccess;
}

asynStatus raptor::stopCapture()
{
static const char* functionName = "stopCapture";
pxd_goAbortLive(0x1);
abortCurrentExposure();

lock();
asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s: Stop capture.\n",
driverName, functionName);
setIntegerParam(ADAcquire, 0);
setIntegerParam(ADStatus, ADStatusIdle);
callParamCallbacks();
unlock();
return asynSuccess;
}

void raptor::tempTask(void){
double pcbTemp, sensorTemp, tecSP;
while (!exiting_){
getPCBTemp(pcbTemp);
getSensorTemp(sensorTemp);
getTECSP(tecSP);
lock();
setDoubleParam(raptorPCBTemp, pcbTemp);
setDoubleParam(raptorSiliconTemp, sensorTemp);
setDoubleParam(ADTemperature, tecSP);
setDoubleParam(ADTemperatureActual, sensorTemp);
callParamCallbacks();
unlock();
epicsThreadSleep(1.0);
}
}

asynStatus raptor::handleCamLinkError(std::string source, int32_t rapStatus){
std::string errMsg ("", 256);

pxd_mesgFaultText(0x1, &errMsg[0], errMsg.size());
std::cout << "Error " << source << ": " << errMsg << pxd_mesgErrorCode(rapStatus) << "(" << rapStatus << ")" << std::endl;
return asynSuccess;
}


std::vector<uint8_t> raptor::writeRead(std::vector<uint8_t> cmd, uint32_t numBytesExpected, std::string msg, uint32_t timeout){
typedef std::chrono::high_resolution_clock Clock;
int rapStatus;
std::vector<uint8_t> reply;

// Do checksum
uint8_t checksumByte = 0;
for (uint32_t i=0; i<cmd.size(); i++){
checksumByte ^= cmd[i];
}
cmd.push_back(checksumByte);

pxd_serialFlush(0x1, 0, 1, 1);
rapStatus = pxd_serialWrite(0x1, 0, reinterpret_cast<char*>(cmd.data()), cmd.size());
if (rapStatus!=0){
handleCamLinkError("Serial write", rapStatus);
} else {
uint32_t numBytesRead = 0;
uint8_t rcvBuf[256];
numBytesExpected+=1; //Checksum
std::chrono::high_resolution_clock::time_point then = Clock::now();
std::chrono::high_resolution_clock::time_point now  = Clock::now();
while ((numBytesRead<numBytesExpected)&&
      (std::chrono::duration_cast<std::chrono::milliseconds>(now-then).count()<timeout)){

rapStatus = pxd_serialRead(0x1, 0, reinterpret_cast<char*>(&rcvBuf), 8);
      if (rapStatus>0){
for (int i=0; i<rapStatus; i++){
reply.push_back(rcvBuf[i]);
}
} else if (rapStatus==0){
usleep(2000);
} else if (rapStatus<0){
handleCamLinkError("Serial read", rapStatus);
}
now  = Clock::now();
numBytesRead += rapStatus;
}
}
if (reply.size()!=numBytesExpected){
std::cout << "Warning: num bytes less than expected" << std::endl;
std::cout << "Reply size: " << reply.size() << " Expected: " << numBytesExpected << std::endl;
}
uint8_t retCode=0;
std::string errMsg ("");
retCode = reply[reply.size()-2]; // Checksum
switch (retCode){
case 0x50: break;
case 0x51: errMsg = "Timeout"; break;
case 0x52: errMsg = "Checksum"; break;
case 0x53: errMsg = "Internal error"; break;
case 0x54: errMsg = "Unknown message"; break;
case 0x55: errMsg = "EEPROM busy"; break;
default: errMsg = "Unexpected reply:"; break;
}
if (errMsg.length()>0){
std::cout << "Serial write error: " << errMsg << " (" << std::hex << (int)retCode << ")" << std::endl;
}

uint8_t sentCS = cmd[cmd.size()-1];
uint8_t rcvdCS = reply[reply.size()-1];
if (sentCS!=rcvdCS){
std::cout << "Warning: checksum doesn't match" << std::hex << (int)sentCS << (int)rcvdCS << std::endl;
}

return reply;
}

asynStatus raptor::readByteAddress(uint8_t addr, uint8_t &value, std::string msg){
asynStatus status;
std::vector<uint8_t> addrCmd = {0x53, 0xE0, 0x01, addr, 0x50};
std::vector<uint8_t> confCmd = {0x53, 0xE1, 0x01, 0x50};

std::lock_guard<std::mutex> lg(raptorSerialPort);
std::vector<uint8_t> reply = writeRead(addrCmd, 1, msg, 500);
if (reply.size()>0){
reply = writeRead(confCmd, 2, "", 500);

if (reply.size()>=1){
value = (uint8_t)reply[0];
status = asynSuccess;
} else {
std::cout << "Error reading byte address: 0x" << std::hex << addr << std::endl;
status = asynError;
}
}
return status;
}

asynStatus raptor::writeByteAddress(uint8_t addr, uint8_t value, std::string msg){
asynStatus status;
std::vector<uint8_t> addrCmd = {0x53, 0xE0, 0x02, addr, value, 0x50};

std::lock_guard<std::mutex> lg(raptorSerialPort);
std::vector<uint8_t> reply = writeRead(addrCmd, 1, msg, 500);

if ((reply.size()==0)||reply[0]!=0x50){
std::cout << "Error writing byte address: 0x" << std::hex << addr << std::endl;
status = asynError;
} else {
status = asynSuccess;
}

return status;
}

asynStatus raptor::getExposureTime(double &expTime){
uint8_t expTimeBytes[5] = {0};
if (!readByteAddress(0xED, expTimeBytes[0], "Read exposure time") &&
!readByteAddress(0xEE, expTimeBytes[1]) &&
!readByteAddress(0xEF, expTimeBytes[2]) &&
!readByteAddress(0xF0, expTimeBytes[3]) &&
!readByteAddress(0xF1, expTimeBytes[4]) ){
uint64_t expTimeCounts = (uint64_t)expTimeBytes[4] +
(uint64_t)expTimeBytes[3]*0x000000100 +
(uint64_t)expTimeBytes[2]*0x000010000 +
(uint64_t)expTimeBytes[1]*0x001000000 +
(uint64_t)expTimeBytes[0]*0x100000000;

expTime = (double)(expTimeCounts * 25e-9);
return asynSuccess;
} else {
return asynError;
}
}

asynStatus raptor::setExposureTime(double expTime){
uint64_t expTimeCounts = (uint64_t)(expTime/25e-9);
uint8_t msb = (uint8_t)((expTimeCounts>>32)&0xFF);
uint8_t b3  = (uint8_t)((expTimeCounts>>24)&0xFF);
uint8_t b2  = (uint8_t)((expTimeCounts>>16)&0xFF);
uint8_t b1  = (uint8_t)((expTimeCounts>> 8)&0xFF);
uint8_t lsb = (uint8_t)((expTimeCounts    )&0xFF);

asynStatus status;
status = writeByteAddress(0xED, msb, "Set exposure time");
status = writeByteAddress(0xEE,  b3 );
status = writeByteAddress(0xEF,  b2 );
status = writeByteAddress(0xF0,  b1 );
status = writeByteAddress(0xF1, lsb );
return status;
}

asynStatus raptor::readTickUnits(){
uint32_t units[2];

int rapStatus = pxd_infoSysTicksUnits(units);
if (rapStatus<0){
handleCamLinkError("readTickUnits", rapStatus);
return asynError;
}
secondsPerTick = (double)units[0]/(units[1]*1.0E6);
return asynSuccess;
}


asynStatus raptor::readTickNow(uint64_t &now){
uint32_t ticks[2];

int rapStatus = pxd_infoSysTicks(ticks);
if (rapStatus<0){
handleCamLinkError("readTickNow", rapStatus);
return asynError;
}
now = (uint64_t)ticks[0] | ((uint64_t)(ticks[1]) << 32);
return asynSuccess;
}

asynStatus raptor::writeInt32( asynUser *pasynUser, epicsInt32 value)
{
static const char* functionName = "writeInt32";
int function = pasynUser->reason;
const char* paramName;
asynStatus status;

getParamName(function, &paramName);
status = setIntegerParam(function, value);
std::cout << paramName << " " << function << " " << value << std::endl;

int maxSizeX = pxd_imageXdim();
int maxSizeY = pxd_imageYdim();

if (function==ADAcquire){
if(value){
status = startCapture();
} else {
status = stopCapture();
}
} else if (function==ADMinX){
// Value between 0 and MaxX-1
if (value<0){
value = 0;
} else if (value>=maxSizeX-1){
value=maxSizeX-1;
}
status = setIntegerParam(function, value);
} else if (function==ADMinY){
// Value between 0 and MaxY-1
if (value<0){
value = 0;
} else if (value>=maxSizeY-1){
value=maxSizeY-1;
}
status = setIntegerParam(function, value);
} else if (function==ADSizeX){
int minX;
getIntegerParam(ADMinX, &minX);
if (value<1){
value = 1;
} else if (value+minX>maxSizeX){
value=maxSizeX-minX;
}
setIntegerParam(NDArraySizeX, value);
status = setIntegerParam(function, value);
} else if (function==ADSizeY){
int minY;
getIntegerParam(ADMinY, &minY);
if (value<1){
value = 1;
} else if (value+minY>maxSizeY){
value=maxSizeY-minY;
}
setIntegerParam(NDArraySizeY, value);
status = setIntegerParam(function, value);
} else if (function==ADBinX){
if (value<1){
value=1;
} else if (value>64){
value=64;
}
status = setIntegerParam(function, value);
} else if (function==ADBinY){
if (value<1){
value=1;
} else if (value>64){
value=64;
}
status = setIntegerParam(function, value);
} else if (function==raptorTECEnabled){
if (value==1){
setTECState(true);
} else if (value==0){
setTECState(false);
}
} else if (function==raptorADCSpeed){
setReadoutClock(value);
uint8_t value_rbv;
getReadoutClock(value_rbv);
setIntegerParam(raptorADCSpeed, value_rbv);
} else {
if (function<FIRST_RAPTOR_PARAM){
status = ADDriver::writeInt32(pasynUser, value);
}
}

asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s: function=%d, value=%d, status=%d\n",
driverName, functionName, function, value, status);
callParamCallbacks();
return status;
}

asynStatus raptor::writeFloat64(asynUser *pasynUser, epicsFloat64 value){
const char* paramName;
asynStatus status;

int function = pasynUser->reason;
getParamName(function, &paramName);
status = setDoubleParam(function, value);
std::cout << paramName << " " << function << " " << value << std::endl;

if (function==ADAcquireTime){
setExposureTime(value);
} else if (function==ADTemperature){
setTECSP(value);
} else {
if (function < FIRST_RAPTOR_PARAM){
status = ADDriver::writeFloat64(pasynUser, value);
}
}
callParamCallbacks();
return status;
}

asynStatus raptor::updateTimeRemaining(uint64_t imageStartTicks, double &timeRemaining){
uint64_t nowTime;
        readTickNow(nowTime);
uint64_t diff = nowTime-imageStartTicks;
if (!(secondsPerTick>0)){
readTickUnits();
}
double acquireTime;
lock();
getDoubleParam(ADAcquireTime, &acquireTime);
unlock();
double timeElapsed = diff*secondsPerTick;
timeRemaining = acquireTime+readoutTime-timeElapsed;
}

void raptor::imageGrabTask(void){
static const char* functionName = "imageGrabTask";
epicsTimeStamp startTime;
int acquire;
int imageMode;
int rapStatus;
int imageCounter;
int numImages;
int numImagesCounter;
int arrayCallbacks;
int lastBuf = pxd_capturedBuffer(0x1);
int fieldCount = pxd_capturedFieldCount(0x1);
asynStatus status;
typedef std::chrono::duration<int,std::milli> millisecs_t ;
uint64_t imageStartTicks;

lock();

while(1){
/* Is acquisition active */
getIntegerParam(ADAcquire, &acquire);

/* If we are not acquiring wait for a semaphore  that is given when
* acquisition is started */
if(!acquire){
setIntegerParam(ADStatus, ADStatusIdle);
callParamCallbacks();

asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s: Waiting for acquisition to start.\n",
driverName, functionName);
unlock();
epicsEventWait(startEventId_);
readTickNow(imageStartTicks);
lock();
setIntegerParam(ADStatus, ADStatusWaiting);
callParamCallbacks();
rapStatus = pxd_goLiveSeq(0x1, 1, pxd_imageZdim(), 1, 0, pxd_imageIdim());
if (rapStatus<0){
handleCamLinkError("Start acquisition", rapStatus);
}
abortCurrentExposure(); // Workaround because first image takes longer than it should
asynPrint(pasynUserSelf, ASYN_TRACEIO_DRIVER,
"%s:%s: Acquisition started.\n",
driverName, functionName);
setIntegerParam(ADNumImagesCounter, 0);
callParamCallbacks();
}
// Wait for new buffer
getIntegerParam(ADAcquire, &acquire);
setIntegerParam(ADStatus, ADStatusAcquire);
unlock();
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
uint32_t cnt = 0;
uint32_t sleepTime = 2000;
double timeRemaining = 0.0;
while(lastBuf==pxd_capturedBuffer(0x1)&&(pxd_goneLive(0x1, 0)>0)){
usleep(sleepTime);
if (((cnt*sleepTime)%100000)==0){
updateTimeRemaining(imageStartTicks, timeRemaining);
std::cout <<  "Time remaining: " << timeRemaining << std::endl;
}
cnt++;
if (timeRemaining<readoutTime){
lock();
setIntegerParam(ADStatus, ADStatusReadout);
callParamCallbacks();
unlock();
}
}
readTickNow(imageStartTicks);
std::cout << "Buf: " << pxd_capturedBuffer(0x1) << std::endl;
std::cout << "Field: " << pxd_capturedFieldCount(0x1) << std::endl;
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
millisecs_t duration( std::chrono::duration_cast<millisecs_t>(end-start) ) ;
std::cout << "Acq time: " << std::dec << duration.count() << " milliseconds.\n" ;
lock();
if (pxd_capturedBuffer(0x1)!=lastBuf){
lastBuf = pxd_capturedBuffer(0x1);
fieldCount = pxd_capturedFieldCount(0x1);

/* Get the current time */
epicsTimeGetCurrent(&startTime);
status = grabImage(lastBuf);
if (status==asynError){
if (pRaw_) pRaw_->release();
pRaw_ = NULL;
continue;
}

getIntegerParam(NDArrayCounter, &imageCounter);
getIntegerParam(ADNumImages, &numImages);
getIntegerParam(ADNumImagesCounter, &numImagesCounter);
getIntegerParam(ADImageMode, &imageMode);
getIntegerParam(NDArrayCallbacks, &arrayCallbacks);
imageCounter++;
numImagesCounter++;
setIntegerParam(NDArrayCounter, imageCounter);
setIntegerParam(ADNumImagesCounter, numImagesCounter);
callParamCallbacks();

if (arrayCallbacks){
doCallbacksGenericPointer(pRaw_, NDArrayData, 0);
}

if (pRaw_)pRaw_->release();
pRaw_ = NULL;
if ((imageMode==ADImageSingle)||((imageMode==ADImageMultiple)&&(numImagesCounter>=numImages))){
status = stopCapture();
}
} else {
lastBuf = pxd_capturedBuffer(0x1);
fieldCount = pxd_capturedFieldCount(0x1);
}
}
}

asynStatus raptor::grabImage(int lastBuf)
{
static const char* functionName = "grabImage";
size_t dims[2];
NDDataType_t dataType;
NDColorMode_t colorMode;
unsigned int dataBufSize;
signed long rapStatus = 0;
int count;

setIntegerParam(ADStatus, ADStatusReadout);
callParamCallbacks();

dims[0] = pxd_imageXdim();
dims[1] = pxd_imageYdim();;
std::vector<uint16_t> monoBuf16(dims[0]*dims[1]);
dataType = NDUInt16;
colorMode = NDColorModeMono;
setIntegerParam(NDArraySizeX, dims[0]);
setIntegerParam(NDArraySizeY, dims[1]);
setIntegerParam(NDArraySize, monoBuf16.size()*sizeof(monoBuf16[0]));
setIntegerParam(NDDataType, dataType);
setIntegerParam(NDColorMode, colorMode);
callParamCallbacks();
pRaw_ = pNDArrayPool->alloc(2, dims, dataType, 0, NULL);
if (!pRaw_){
setIntegerParam(ADStatus, ADStatusAborting);
callParamCallbacks();
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s:%s: Unable to allocate buffer\n",
driverName, functionName);
setIntegerParam(ADAcquire, 0);
return asynError;
}
rapStatus = pxd_readushort(0x1, lastBuf, 0, 0, dims[0], dims[1], monoBuf16.data(), monoBuf16.size(), "Grey");
if (rapStatus<0){
handleCamLinkError("Read data from camera", rapStatus);
}
if (pRaw_){
memcpy(pRaw_->pData, monoBuf16.data(), monoBuf16.size()*sizeof(monoBuf16[0]));
}

getIntegerParam(NDArrayCounter, &count);
if (pRaw_){
pRaw_->uniqueId = count;
updateTimeStamp(&pRaw_->epicsTS);
pRaw_->timeStamp = pRaw_->epicsTS.secPastEpoch+pRaw_->epicsTS.nsec/1e9;
getAttributes(pRaw_->pAttributeList);
pRaw_->pAttributeList->add("ColorMode", "Color Mode", NDAttrInt32, &colorMode);
}


setIntegerParam(ADStatus, ADStatusIdle);
callParamCallbacks();
return asynSuccess;
}

static const iocshArg configArg0 = {"Port name",   iocshArgString};
static const iocshArg configArg1 = {"maxBuffers",  iocshArgInt};
static const iocshArg configArg2 = {"maxMemory",   iocshArgInt};
static const iocshArg configArg3 = {"priority",    iocshArgInt};
static const iocshArg configArg4 = {"stackSize",   iocshArgInt};
static const iocshArg configArg5 = {"Format file", iocshArgString};
static const iocshArg * const configArgs [] = {&configArg0,
      &configArg1,
      &configArg2,
      &configArg3,
      &configArg4,
              &configArg5};
static const iocshFuncDef configRaptor = {"raptorConfig", 6, configArgs};
static void configCallFunc(const iocshArgBuf *args)
{
raptorConfig(args[0].sval, args[1].ival, args[2].ival,
            args[3].ival, args[4].ival, args[5].sval);
}

static void raptorRegister(void)
{
iocshRegister(&configRaptor, configCallFunc);
}

extern "C" {
epicsExportRegistrar(raptorRegister);
}
##########
##raptor.template##
##########
# David Vine
# July 20, 2020

include "ADBase.template"

record(mbbi, "$(P)$(R)FPGABootOk_RBV")
{
    field(ZRST, "Not ok")
    field(ZRVL, "0")
field(ONST, "Ok")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_FPGA_BOOT")
}

record(mbbo, "$(P)$(R)FanEnable")
{
    field(ZRST, "Disable")
    field(ZRVL, "0")
field(ONST, "Enable")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_FAN_ENABLED")
}

record(mbbi, "$(P)$(R)FanEnable_RBV")
{
    field(ZRST, "Disable")
    field(ZRVL, "0")
field(ONST, "Enable")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_FAN_ENABLED")
}

record(mbbi, "$(P)$(R)OverTemp_RBV")
{
    field(ZRST, "No")
    field(ZRVL, "0")
field(ONST, "Yes")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_OVERTEMP")
}

record(mbbo, "$(P)$(R)TECEnable")
{
    field(ZRST, "Disable")
    field(ZRVL, "0")
field(ONST, "Enable")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_TEC_ENABLED")
}

record(mbbi, "$(P)$(R)TECEnable_RBV")
{
    field(ZRST, "Disable")
    field(ZRVL, "0")
field(ONST, "Enable")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_TEC_ENABLED")
}

record(mbbo, "$(P)$(R)ADCSpeed")
{
    field(ZRST, "2 MHz")
    field(ZRVL, "0")
field(ONST, "75 kHz")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_ADC_SPEED")
}

record(mbbi, "$(P)$(R)ADCSpeed_RBV")
{
    field(ZRST, "2 MHz")
    field(ZRVL, "0")
field(ONST, "75 kHz")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_ADC_SPEED")
}

record(mbbo, "$(P)$(R)ReadoutMode")
{
field(DESC, "Select sensor or test pattern output")
    field(ZRST, "Sensor")
    field(ZRVL, "0")
field(ONST, "Test Pattern")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_READOUT_MODE")
}

record(mbbi, "$(P)$(R)ReadoutMode_RBV")
{
    field(ZRST, "Sensor")
    field(ZRVL, "0")
field(ONST, "Test Pattern")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_READOUT_MODE")
}

record(ai, "$(P)$(R)PCBTemp_RBV")
{
field(DTYP, "asynFloat64")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_PCB_TEMP")
}

record(ai, "$(P)$(R)SensorTemp_RBV")
{
field(DTYP, "asynFloat64")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_SILICON_TEMP")
}

record(mbbo, "$(P)$(R)FrameTransfer")
{
    field(ZRST, "Disable")
    field(ZRVL, "0")
field(ONST, "Enable")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_FRAME_TX")
}

record(mbbi, "$(P)$(R)FrameTransfer_RBV")
{
    field(ZRST, "Disable")
    field(ZRVL, "0")
field(ONST, "Enable")
field(ONVL, "1")
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))R_FRAME_TX")
}

record(ai, "$(P)$(G)NumBuffers_RBV")
{
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))G_NUM_BUFFERS")
}

record(stringin, "$(P)$(G)DriverID_RBV")
{
field(DTYP, "asynOctetRead")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))G_DRIVER_ID")
}

record(stringin, "$(P)$(G)IncludeID_RBV")
{
field(DTYP, "asynOctetRead")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))G_INCLUDE_ID")
}

record(stringin, "$(P)$(G)LibraryID_RBV")
{
field(DTYP, "asynOctetRead")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))G_LIBRARY_ID")
}

record(ai, "$(P)$(G)MemSize_RBV")
{
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))G_MEM_SIZE")
}

record(ai, "$(P)$(G)Model_RBV")
{
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))G_MODEL")
}

record(ai, "$(P)$(G)SubModel_RBV")
{
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))G_SUBMODEL")
}

record(ai, "$(P)$(G)NumUnits_RBV")
{
field(DTYP, "asynInt32")
field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))G_UNITS")
}
##########
##ioc boot output##
##########
< envPaths
epicsEnvSet("IOC","iocRaptor")
epicsEnvSet("TOP","/opt/epics/synApps/support/areaDetector-master/ADRaptor/iocs/raptorIOC")
epicsEnvSet("ADRAPTOR","/opt/epics/synApps/support/areaDetector-master/ADRaptor/iocs/raptorIOC/../..")
epicsEnvSet("SUPPORT","/opt/epics/synApps/support")
epicsEnvSet("ASYN","/opt/epics/synApps/support/asyn-R4-38")
epicsEnvSet("AREA_DETECTOR","/opt/epics/synApps/support/areaDetector-master")
epicsEnvSet("ADSUPPORT","/opt/epics/synApps/support/areaDetector-master/ADSupport")
epicsEnvSet("ADCORE","/opt/epics/synApps/support/areaDetector-master/ADCore")
epicsEnvSet("AUTOSAVE","/opt/epics/synApps/support/autosave-R5-10")
epicsEnvSet("BUSY","/opt/epics/synApps/support/busy-R1-7-2")
epicsEnvSet("CALC","/opt/epics/synApps/support/calc-R3-7-3")
epicsEnvSet("SNCSEQ","/opt/epics/synApps/support/seq-2-2-6")
epicsEnvSet("SSCAN","/opt/epics/synApps/support/sscan-R2-11-3")
epicsEnvSet("DEVIOCSTATS","/opt/epics/synApps/support/iocStats-3-1-16")
epicsEnvSet("EPICS_BASE","/opt/epics/base")
errlogInit(20000)
dbLoadDatabase("/opt/epics/synApps/support/areaDetector-master/ADRaptor/iocs/raptorIOC/dbd/raptorApp.dbd")
raptorApp_registerRecordDeviceDriver(pdbbase)
# Prefix for all records
epicsEnvSet("PREFIX", "RAPTOR1:")
# The port name for the detector
epicsEnvSet("PORT",   "RAPTOR")
# The camera number in the system
epicsEnvSet("CAMERA", "0")
# The queue size for all plugins
epicsEnvSet("QSIZE",  "21")
# The maximim image width; used for row profiles in the NDPluginStats plugin
epicsEnvSet("XSIZE",  "1024")
# The maximim image height; used for column profiles in the NDPluginStats plugin
epicsEnvSet("YSIZE",  "1024")
# The maximum number of time seried points in the NDPluginStats plugin
epicsEnvSet("NCHANS", "2048")
# The maximum number of frames buffered in the NDPluginCircularBuff plugin
epicsEnvSet("CBUFFS", "500")
# The search path for database files
epicsEnvSet("EPICS_DB_INCLUDE_PATH", "/opt/epics/synApps/support/areaDetector-master/ADCore/db")
# raptorConfig(const char *portName, int maxBuffers, size_t maxMemory, int priority, int stackSize,
# int baud, int bits, int parity, int stop, const char* formatFile)
raptorConfig("RAPTOR", 0, 0, 0, 0, "/opt/epics/synApps/support/areaDetector-master/ADRaptor/iocs/raptorIOC/../../raptorSupport/eagle64.fmt")
Grabberunits: 999
Format file: /opt/epics/synApps/support/areaDetector-master/ADRaptor/iocs/raptorIOC/../../raptorSupport/eagle64.fmt
Warning: num bytes less than expected
Reply size: 20 Expected: 19
Serial number: 10009
Build date: 26/7/18
Build code: Larne
Bit depth: 16
Color dimensions: 1
Size X: 1056
Size Y: 1027
Num buffers: 15
Driver Id: PIXCI(R) 64 Bit Driver V3.8.01 [20.01.30.132346]4.15.0-65-generic
Include Id: PIXCI(R) 64 Bit Library 3.08.01 [20.02.25]
Library Id: PIXCI(R) 64 Bit Library 3.08.01 [20.02.25]
Memory size: 32.00
Model: 38
SubModel: 65288
Units: 1


Temp calibration
ADC Cal  0: 1055
ADC Cal 40: 829
DAC Cal  0: 2039
DAC Cal 40: 2582
dbLoadRecords("/opt/epics/synApps/support/areaDetector-master/ADRaptor/iocs/raptorIOC/../../db/raptor.template", "P=RAPTOR1:,R=cam1:,G=grab1:,PORT=RAPTOR,ADDR=0,TIMEOUT=1")
# Create a standard arrays plugin
NDStdArraysConfigure("Image1", 5, 0, "RAPTOR", 0, 0)
# Make NELEMENTS in the following be a little bigger than 2048*2048
# Use the following command for 32-bit images.  This is needed for 32-bit detectors or for 16-bit detectors in acccumulate mode if it would overflow 16 bits
#dbLoadRecords("$(ADCORE)/db/NDStdArrays.template", "P=$(PREFIX),R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT),TYPE=Int32,FTVL=LONG,NELEMENTS=5600000")
# Use the following command for 16-bit images.  This can be used for 16-bit detector as long as accumulate mode would not result in 16-bit overflow
dbLoadRecords("/opt/epics/synApps/support/areaDetector-master/ADCore/db/NDStdArrays.template", "P=RAPTOR1:,R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR,TYPE=Int16,FTVL=SHORT,NELEMENTS=5600000")
# Load all other plugins using commonPlugins.cmd
< /opt/epics/synApps/support/areaDetector-master/ADCore/iocBoot/commonPlugins.cmd
# This is an example file for creating plugins
# It uses the following environment variable macros
# Many of the parameters defined in this file are also in commonPlugins_settings.req so if autosave is being
# use the autosave value will replace the value passed to this file.
# $(PREFIX)      Prefix for all records
# $(PORT)        The port name for the detector.  In autosave.
# $(QSIZE)       The queue size for all plugins.  In autosave.
# $(XSIZE)       The maximum image width; used to set the maximum size for row profiles in the NDPluginStats plugin and 1-D FFT
#                   profiles in NDPluginFFT.
# $(YSIZE)       The maximum image height; used to set the maximum size for column profiles in the NDPluginStats plugin
# $(NCHANS)      The maximum number of time series points in the NDPluginStats, NDPluginROIStats, and NDPluginAttribute plugins
# $(CBUFFS)      The maximum number of frames buffered in the NDPluginCircularBuff plugin
# $(MAX_THREADS) The maximum number of threads for plugins which can run in multiple threads. Defaults to 5.
# Create a netCDF file saving plugin
NDFileNetCDFConfigure("FileNetCDF1", 21, 0, "RAPTOR", 0)
dbLoadRecords("NDFileNetCDF.template","P=RAPTOR1:,R=netCDF1:,PORT=FileNetCDF1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create a TIFF file saving plugin
NDFileTIFFConfigure("FileTIFF1", 21, 0, "RAPTOR", 0)
dbLoadRecords("NDFileTIFF.template",  "P=RAPTOR1:,R=TIFF1:,PORT=FileTIFF1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create a JPEG file saving plugin
NDFileJPEGConfigure("FileJPEG1", 21, 0, "RAPTOR", 0)
dbLoadRecords("NDFileJPEG.template",  "P=RAPTOR1:,R=JPEG1:,PORT=FileJPEG1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create a NeXus file saving plugin
NDFileNexusConfigure("FileNexus1", 21, 0, "RAPTOR", 0)
dbLoadRecords("NDFileNexus.template", "P=RAPTOR1:,R=Nexus1:,PORT=FileNexus1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create an HDF5 file saving plugin
NDFileHDF5Configure("FileHDF1", 21, 0, "RAPTOR", 0)
dbLoadRecords("NDFileHDF5.template",  "P=RAPTOR1:,R=HDF1:,PORT=FileHDF1,ADDR=0,TIMEOUT=1,XMLSIZE=2048,NDARRAY_PORT=RAPTOR")
# Create a Magick file saving plugin
#NDFileMagickConfigure("FileMagick1", $(QSIZE), 0, "$(PORT)", 0)
#dbLoadRecords("NDFileMagick.template","P=$(PREFIX),R=Magick1:,PORT=FileMagick1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
# Create 4 ROI plugins
NDROIConfigure("ROI1", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDROI.template",       "P=RAPTOR1:,R=ROI1:,  PORT=ROI1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
NDROIConfigure("ROI2", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDROI.template",       "P=RAPTOR1:,R=ROI2:,  PORT=ROI2,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
NDROIConfigure("ROI3", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDROI.template",       "P=RAPTOR1:,R=ROI3:,  PORT=ROI3,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
NDROIConfigure("ROI4", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDROI.template",       "P=RAPTOR1:,R=ROI4:,  PORT=ROI4,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create 8 ROIStat plugins
NDROIStatConfigure("ROISTAT1", 21, 0, "RAPTOR", 0, 8, 0, 0, 0, 0, 5)
dbLoadRecords("NDROIStat.template",   "P=RAPTOR1:,R=ROIStat1:  ,PORT=ROISTAT1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=RAPTOR1:,R=ROIStat1:1:,PORT=ROISTAT1,ADDR=0,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=RAPTOR1:,R=ROIStat1:2:,PORT=ROISTAT1,ADDR=1,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=RAPTOR1:,R=ROIStat1:3:,PORT=ROISTAT1,ADDR=2,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=RAPTOR1:,R=ROIStat1:4:,PORT=ROISTAT1,ADDR=3,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=RAPTOR1:,R=ROIStat1:5:,PORT=ROISTAT1,ADDR=4,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=RAPTOR1:,R=ROIStat1:6:,PORT=ROISTAT1,ADDR=5,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=RAPTOR1:,R=ROIStat1:7:,PORT=ROISTAT1,ADDR=6,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDROIStatN.template",  "P=RAPTOR1:,R=ROIStat1:8:,PORT=ROISTAT1,ADDR=7,TIMEOUT=1,NCHANS=2048")
# Create a processing plugin
NDProcessConfigure("PROC1", 21, 0, "RAPTOR", 0, 0, 0)
dbLoadRecords("NDProcess.template",   "P=RAPTOR1:,R=Proc1:,  PORT=PROC1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create a TIFF file plugin to read dark and flatfield images into the processing plugin
NDFileTIFFConfigure("PROC1TIFF", 21, 0, "RAPTOR", 0)
dbLoadRecords("NDFileTIFF.template",  "P=RAPTOR1:,R=Proc1:TIFF:,PORT=PROC1TIFF,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create a scatter plugin
NDScatterConfigure("SCATTER1", 21, 0, "RAPTOR", 0, 0, 0)
dbLoadRecords("NDScatter.template",   "P=RAPTOR1:,R=Scatter1:,  PORT=SCATTER1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create a gather plugin with 8 ports
NDGatherConfigure("GATHER1", 21, 0, 8, 0, 0)
dbLoadRecords("NDGather.template",   "P=RAPTOR1:,R=Gather1:, PORT=GATHER1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDGatherN.template",   "P=RAPTOR1:,R=Gather1:, N=1, PORT=GATHER1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDGatherN.template",   "P=RAPTOR1:,R=Gather1:, N=2, PORT=GATHER1,ADDR=1,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDGatherN.template",   "P=RAPTOR1:,R=Gather1:, N=3, PORT=GATHER1,ADDR=2,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDGatherN.template",   "P=RAPTOR1:,R=Gather1:, N=4, PORT=GATHER1,ADDR=3,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDGatherN.template",   "P=RAPTOR1:,R=Gather1:, N=5, PORT=GATHER1,ADDR=4,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDGatherN.template",   "P=RAPTOR1:,R=Gather1:, N=6, PORT=GATHER1,ADDR=5,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDGatherN.template",   "P=RAPTOR1:,R=Gather1:, N=7, PORT=GATHER1,ADDR=6,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDGatherN.template",   "P=RAPTOR1:,R=Gather1:, N=8, PORT=GATHER1,ADDR=7,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create 5 statistics plugins
NDStatsConfigure("STATS1", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=RAPTOR1:,R=Stats1:,  PORT=STATS1,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=RAPTOR")
NDTimeSeriesConfigure("STATS1_TS", 21, 0, "STATS1", 1, 23)
dbLoadRecords("/opt/epics/synApps/support/areaDetector-master/ADCore/db/NDTimeSeries.template",  "P=RAPTOR1:,R=Stats1:TS:, PORT=STATS1_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS1,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")
NDStatsConfigure("STATS2", 21, 0, "ROI1",    0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=RAPTOR1:,R=Stats2:,  PORT=STATS2,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=RAPTOR")
NDTimeSeriesConfigure("STATS2_TS", 21, 0, "STATS2", 1, 23)
dbLoadRecords("/opt/epics/synApps/support/areaDetector-master/ADCore/db/NDTimeSeries.template",  "P=RAPTOR1:,R=Stats2:TS:, PORT=STATS2_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS2,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")
NDStatsConfigure("STATS3", 21, 0, "ROI2",    0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=RAPTOR1:,R=Stats3:,  PORT=STATS3,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=RAPTOR")
NDTimeSeriesConfigure("STATS3_TS", 21, 0, "STATS3", 1, 23)
dbLoadRecords("/opt/epics/synApps/support/areaDetector-master/ADCore/db/NDTimeSeries.template",  "P=RAPTOR1:,R=Stats3:TS:, PORT=STATS3_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS3,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")
NDStatsConfigure("STATS4", 21, 0, "ROI3",    0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=RAPTOR1:,R=Stats4:,  PORT=STATS4,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=RAPTOR")
NDTimeSeriesConfigure("STATS4_TS", 21, 0, "STATS4", 1, 23)
dbLoadRecords("/opt/epics/synApps/support/areaDetector-master/ADCore/db/NDTimeSeries.template",  "P=RAPTOR1:,R=Stats4:TS:, PORT=STATS4_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS4,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")
NDStatsConfigure("STATS5", 21, 0, "ROI4",    0, 0, 0, 0, 0, 5)
dbLoadRecords("NDStats.template",     "P=RAPTOR1:,R=Stats5:,  PORT=STATS5,ADDR=0,TIMEOUT=1,HIST_SIZE=256,XSIZE=1024,YSIZE=1024,NCHANS=2048,NDARRAY_PORT=RAPTOR")
NDTimeSeriesConfigure("STATS5_TS", 21, 0, "STATS5", 1, 23)
dbLoadRecords("/opt/epics/synApps/support/areaDetector-master/ADCore/db/NDTimeSeries.template",  "P=RAPTOR1:,R=Stats5:TS:, PORT=STATS5_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=STATS5,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")
# Create a transform plugin
NDTransformConfigure("TRANS1", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDTransform.template", "P=RAPTOR1:,R=Trans1:,  PORT=TRANS1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create an overlay plugin with 8 overlays
NDOverlayConfigure("OVER1", 21, 0, "RAPTOR", 0, 8, 0, 0, 0, 0, 5)
dbLoadRecords("NDOverlay.template", "P=RAPTOR1:,R=Over1:, PORT=OVER1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDOverlayN.template","P=RAPTOR1:,R=Over1:1:,NAME=ROI1,   SHAPE=1,O=Over1:,XPOS=RAPTOR1:ROI1:MinX_RBV,YPOS=RAPTOR1:ROI1:MinY_RBV,XSIZE=RAPTOR1:ROI1:SizeX_RBV,YSIZE=RAPTOR1:ROI1:SizeY_RBV,PORT=OVER1,ADDR=0,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=RAPTOR1:,R=Over1:2:,NAME=ROI2,   SHAPE=1,O=Over1:,XPOS=RAPTOR1:ROI2:MinX_RBV,YPOS=RAPTOR1:ROI2:MinY_RBV,XSIZE=RAPTOR1:ROI2:SizeX_RBV,YSIZE=RAPTOR1:ROI2:SizeY_RBV,PORT=OVER1,ADDR=1,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=RAPTOR1:,R=Over1:3:,NAME=ROI3,   SHAPE=1,O=Over1:,XPOS=RAPTOR1:ROI3:MinX_RBV,YPOS=RAPTOR1:ROI3:MinY_RBV,XSIZE=RAPTOR1:ROI3:SizeX_RBV,YSIZE=RAPTOR1:ROI3:SizeY_RBV,PORT=OVER1,ADDR=2,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=RAPTOR1:,R=Over1:4:,NAME=ROI4,   SHAPE=1,O=Over1:,XPOS=RAPTOR1:ROI4:MinX_RBV,YPOS=RAPTOR1:ROI4:MinY_RBV,XSIZE=RAPTOR1:ROI4:SizeX_RBV,YSIZE=RAPTOR1:ROI4:SizeY_RBV,PORT=OVER1,ADDR=3,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=RAPTOR1:,R=Over1:5:,NAME=Cursor1,SHAPE=1,O=Over1:,XPOS=junk,                  YPOS=junk,                  XSIZE=junk,                   YSIZE=junk,                   PORT=OVER1,ADDR=4,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=RAPTOR1:,R=Over1:6:,NAME=Cursor2,SHAPE=1,O=Over1:,XPOS=junk,                  YPOS=junk,                  XSIZE=junk,                   YSIZE=junk,                   PORT=OVER1,ADDR=5,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=RAPTOR1:,R=Over1:7:,NAME=Box1,   SHAPE=1,O=Over1:,XPOS=junk,                  YPOS=junk,                  XSIZE=junk,                   YSIZE=junk,                   PORT=OVER1,ADDR=6,TIMEOUT=1")
dbLoadRecords("NDOverlayN.template","P=RAPTOR1:,R=Over1:8:,NAME=Box2,   SHAPE=1,O=Over1:,XPOS=junk,                  YPOS=junk,                  XSIZE=junk,                   YSIZE=junk,                   PORT=OVER1,ADDR=7,TIMEOUT=1")
# Create 2 color conversion plugins
NDColorConvertConfigure("CC1", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDColorConvert.template", "P=RAPTOR1:,R=CC1:,  PORT=CC1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
NDColorConvertConfigure("CC2", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDColorConvert.template", "P=RAPTOR1:,R=CC2:,  PORT=CC2,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create a circular buffer plugin
NDCircularBuffConfigure("CB1", 21, 0, "RAPTOR", 0, 500, 0)
dbLoadRecords("NDCircularBuff.template", "P=RAPTOR1:,R=CB1:,  PORT=CB1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=RAPTOR")
# Create an NDAttribute plugin with 8 attributes
NDAttrConfigure("ATTR1", 21, 0, "RAPTOR", 0, 8, 0, 0, 0)
dbLoadRecords("NDAttribute.template",  "P=RAPTOR1:,R=Attr1:,    PORT=ATTR1,ADDR=0,TIMEOUT=1,NCHANS=2048,NDARRAY_PORT=RAPTOR")
dbLoadRecords("NDAttributeN.template", "P=RAPTOR1:,R=Attr1:1:,  PORT=ATTR1,ADDR=0,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=RAPTOR1:,R=Attr1:2:,  PORT=ATTR1,ADDR=1,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=RAPTOR1:,R=Attr1:3:,  PORT=ATTR1,ADDR=2,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=RAPTOR1:,R=Attr1:4:,  PORT=ATTR1,ADDR=3,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=RAPTOR1:,R=Attr1:5:,  PORT=ATTR1,ADDR=4,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=RAPTOR1:,R=Attr1:6:,  PORT=ATTR1,ADDR=5,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=RAPTOR1:,R=Attr1:7:,  PORT=ATTR1,ADDR=6,TIMEOUT=1,NCHANS=2048")
dbLoadRecords("NDAttributeN.template", "P=RAPTOR1:,R=Attr1:8:,  PORT=ATTR1,ADDR=7,TIMEOUT=1,NCHANS=2048")
NDTimeSeriesConfigure("ATTR1_TS", 21, 0, "ATTR1", 1, 8)
dbLoadRecords("/opt/epics/synApps/support/areaDetector-master/ADCore/db/NDTimeSeries.template",  "P=RAPTOR1:,R=Attr1:TS:, PORT=ATTR1_TS,ADDR=0,TIMEOUT=1,NDARRAY_PORT=ATTR1,NDARRAY_ADDR=1,NCHANS=2048,ENABLED=1")
# Create an FFT plugin
NDFFTConfigure("FFT1", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDFFT.template", "P=RAPTOR1:, R=FFT1:, PORT=FFT1, ADDR=0, TIMEOUT=1, NDARRAY_PORT=RAPTOR, NAME=FFT1, NCHANS=1024")
# Create 2 Codec plugins
NDCodecConfigure("CODEC1", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDCodec.template", "P=RAPTOR1:, R=Codec1:, PORT=CODEC1, ADDR=0, TIMEOUT=1, NDARRAY_PORT=RAPTOR")
NDCodecConfigure("CODEC2", 21, 0, "RAPTOR", 0, 0, 0, 0, 0, 5)
dbLoadRecords("NDCodec.template", "P=RAPTOR1:, R=Codec2:, PORT=CODEC2, ADDR=0, TIMEOUT=1, NDARRAY_PORT=RAPTOR")
set_requestfile_path("./")
set_requestfile_path("/opt/epics/synApps/support/areaDetector-master/ADCore/ADApp/Db")
set_requestfile_path("/opt/epics/synApps/support/areaDetector-master/ADCore/iocBoot")
set_savefile_path("./autosave")
set_pass0_restoreFile("auto_settings.sav")
set_pass1_restoreFile("auto_settings.sav")
save_restoreSet_status_prefix("RAPTOR1:")
dbLoadRecords("/opt/epics/synApps/support/autosave-R5-10/asApp/Db/save_restoreStatus.db", "P=RAPTOR1:")
# Optional: load NDPluginPva plugin
#NDPvaConfigure("PVA1", $(QSIZE), 0, "$(PORT)", 0, $(PREFIX)Pva1:Image, 0, 0, 0)
#dbLoadRecords("NDPva.template",  "P=$(PREFIX),R=Pva1:, PORT=PVA1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
# Must start PVA server if this is enabled
#startPVAServer
# Optional: load ffmpegServer plugin
#ffmpegServerConfigure(8081)
#ffmpegStreamConfigure("FfmStream1", 2, 0, "$(PORT)", 0, -1, 0)
#dbLoadRecords("$(FFMPEGSERVER)/db/ffmpegStream.template", "P=$(PREFIX),R=ffmstream1:,PORT=FfmStream1,NDARRAY_PORT=$(PORT)")
#ffmpegFileConfigure("FfmFile1", 16, 0, "$(PORT)", 0, -1, 0)
#dbLoadRecords("$(FFMPEGSERVER)/db/ffmpegFile.template", "P=$(PREFIX),R=ffmfile1:,PORT=FfmFile1,NDARRAY_PORT=$(PORT)")
# Optional: load NDPluginEdge plugin
#NDEdgeConfigure("EDGE1", $(QSIZE), 0, "$(PORT)", 0, 0, 0, 0)
#dbLoadRecords("$(ADPLUGINEDGE)/db/NDEdge.template",  "P=$(PREFIX),R=Edge1:, PORT=EDGE1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
#set_requestfile_path("$(ADPLUGINEDGE)/edgeApp/Db")
# Optional: load NDPluginCV plugin
#NDCVConfigure("CV1", $(QSIZE), 0, "$(PORT)", 0, 0, 0, 0, 0, $(MAX_THREADS=5))
#dbLoadRecords("$(ADCOMPVISION)/db/NDCV.template",  "P=$(PREFIX),R=CV1:, PORT=CV1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
#set_requestfile_path("$(ADCOMPVISION)/adcvApp/Db")
# Optional: load NDPluginBar plugin
#NDBarConfigure("BAR1", $(QSIZE), 0, "$(PORT)", 0, 0, 0, 0, 0, $(MAX_THREADS=5))
#dbLoadRecords("$(ADPLUGINBAR)/db/NDBar.template",  "P=$(PREFIX),R=Bar1:, PORT=BAR1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT)")
#set_requestfile_path("$(ADPLUGINBAR)/barApp/Db")
# Optional: load scan records
#dbLoadRecords("$(SSCAN)/sscanApp/Db/scan.db", "P=$(PREFIX),MAXPTS1=2000,MAXPTS2=200,MAXPTS3=20,MAXPTS4=10,MAXPTSH=10")
#set_requestfile_path("$(SSCAN)/sscanApp/Db")
# Optional: load sseq record for acquisition sequence
#dbLoadRecords("$(CALC)/calcApp/Db/sseqRecord.db", "P=$(PREFIX), S=AcquireSequence")
#set_requestfile_path("$(CALC)/calcApp/Db")
# Optional: load devIocStats records (requires DEVIOCSTATS module)
#dbLoadRecords("$(DEVIOCSTATS)/db/iocAdminSoft.db", "IOC=$(PREFIX)")
# Optional: load alive record (requires ALIVE module)
#dbLoadRecords("$(ALIVE)/aliveApp/Db/alive.db", "P=$(PREFIX),RHOST=192.168.1.254")
# Set the callback queue size to 5000, up from default of 2000 in base.
# This can be needed to avoid errors "callbackRequest: cbLow ring buffer full".
callbackSetQueueSize(5000)
set_requestfile_path("/opt/epics/synApps/support/areaDetector-master/ADRaptor/iocs/raptorIOC/../../raptorApp/Db")
#asynSetTraceMask("$(PORT)",0,9)
asynSetTraceIOMask("RAPTOR",0,4)
iocInit()
Starting iocInit
############################################################################
## EPICS R3.15.6
## EPICS Base built Oct  1 2019
############################################################################
reboot_restore: entry for file 'auto_settings.sav'
reboot_restore: Found filename 'auto_settings.sav' in restoreFileList.
*** restoring from './autosave/auto_settings.sav' at initHookState 6 (before record/device init) ***
reboot_restore: done with file 'auto_settings.sav'

reboot_restore: entry for file 'auto_settings.sav'
reboot_restore: Found filename 'auto_settings.sav' in restoreFileList.
*** restoring from './autosave/auto_settings.sav' at initHookState 7 (after record/device init) ***
reboot_restore: done with file 'auto_settings.sav'

ACQ_TIME 77 1
ACQ_PERIOD 78 0
GAIN 60 1
SHUTTER_OPEN_DELAY 86 0
SHUTTER_CLOSE_DELAY 87 0
TEMPERATURE 88 96.1062
BIN_X 61 1
BIN_Y 62 1
MIN_X 63 0
MIN_Y 64 0
SIZE_X 65 1056
SIZE_Y 66 1027
NEXPOSURES 73 1
NIMAGES 75 1
DATA_TYPE 17 3
COLOR_MODE 18 0
FRAME_TYPE 71 0
IMAGE_MODE 72 2
TRIGGER_MODE 81 0
SHUTTER_MODE 85 0
WAIT_FOR_PLUGINS 10 0
ARRAY_CALLBACKS 52 1
REVERSE_X 69 0
REVERSE_Y 70 0
SHUTTER_CONTROL 82 0
iocRun: All initialization complete
# save things every thirty seconds
create_monitor_set("auto_settings.req", 30,"P=RAPTOR1:")
save_restore:readReqFile: unable to open file tucsen_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
save_restore:readReqFile: unable to open file sseq_settings.req. Exiting.
#asynSetTraceMask($(PORT), 0, 255)
epics> auto_settings.sav: 1156 of 1156 PV's connected

[https://static1.squarespace.com/static/56de1f4a2fe1318cf0aacc98/t/5d9e0fa57996446a078a8e1a/1570639781104/Logo_gmail_small.png?format=300w]

This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error, please notify the system manager. This message contains confidential information and is intended only for the individual named. If you are not the named addressee, you should not disseminate, distribute or copy this email. Please notify the sender immediately by email if you have received this email by mistake and delete this email from your system. If you are not the intended recipient, you are notified that disclosing, copying, distributing or taking any action in reliance on the contents of this information is strictly prohibited

Replies:
running gateway on mac Vivian O'Dell via Tech-talk
References:
AreaDetector: PVs from driver created parameters not updating David Vine via Tech-talk
Re: AreaDetector: PVs from driver created parameters not updating Mark Rivers via Tech-talk

Navigate by Date:
Prev: Case insensitive macros in streamDevice protocol file O'Hea, James (DLSLtd, RAL, LSCI) via Tech-talk
Next: running gateway on mac Vivian O'Dell via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
Navigate by Thread:
Prev: Re: AreaDetector: PVs from driver created parameters not updating Mark Rivers via Tech-talk
Next: running gateway on mac Vivian O'Dell via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  <20202021  2022  2023  2024 
ANJ, 01 Sep 2020 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·