Merge branch 'ICSHWI-12773_acquision_refactor' into 'dev'

ICSHWI-12773: Acquision Refactor

See merge request epics-modules/adhama!9
This commit is contained in:
Douglas Araujo
2023-06-07 06:18:23 +00:00
5 changed files with 145 additions and 130 deletions
+1
View File
@@ -38,6 +38,7 @@ endif
REQUIRED += adcore
REQUIRED += busy
REQUIRED += seq
############################################################################
+75 -34
View File
@@ -90,32 +90,36 @@ record(mbbi, "$(P)$(R)ColorMode_RBV") {
field(SVVL, "")
}
record(longin, "$(P)$(R)ArrayCounter_RBV")
record("*", "$(P)$(R)AcquirePeriod_RBV")
{
field(FLNK, "$(P)$(R)#EVRTimeProc.PROC")
field(FLNK, "$(P)$(R)#EVRAcquireTime-S.PROC PP MS")
}
record(ai, "$(P)$(R)#EVRTimeProc") {
record(calcout, "$(P)$(R)#EVRAcquireTime-S") {
field(DESC, "Set EVR acquire time in seconds")
field(CALC, "A=0?B:A*B")
field(INPA, "$(P)$(R)AcquirePeriod_RBV")
field(INPB, "88052500")
field(OUT, "$(EVR):PS-1-Div-SP PP")
}
record(stringin, "$(P)$(R)#EVRTimeProc") {
field(DESC, "Start proce the EVRTime record")
field(TSEL, "$(EVR):Evt$(E)Cnt-I.TIME")
field(DTYP, "Soft Timestamp")
field(FLNK, "$(P)$(R)EVRTime-R.PROC")
field(SDIS, "$(EVR):Evt$(E)Cnt-I CP MS")
field(DISV, "-1")
field(TSEL, "$(EVR):Evt$(E)Cnt-I.TIME")
field(INP, "@%s.%f")
field(FLNK, "$(P)$(R)EVRTime-R.PROC PP MS")
}
record(calc, "$(P)$(R)EVRTime-R") {
# holds TS value in 'sec.nsec' format
record(stringout, "$(P)$(R)EVRTime-R") {
field(DESC, "EPICS epoch EVRTime timestamp")
field(CALC, "a+b")
field(INPA, "631152000")
field(INPB, "$(P)$(R)#EVRTimeProc")
}
record(ai, "$(P)$(R)TimeStamp-RB") {
field(DESC, "DCAM Timestamp when trigger received")
field(DTYP, "asynFloat64")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))H_TIMESTAMP")
field(PREC, "3")
field(SCAN, "I/O Intr")
field(PINI, "YES")
field(DOL, "$(P)$(R)#EVRTimeProc MS")
field(OMSL, "closed_loop")
field(DTYP, "asynOctetWrite")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))EVR_TIMESTAMP")
}
record(ai, "$(P)$(R)FrameRate-R") {
@@ -124,7 +128,45 @@ record(ai, "$(P)$(R)FrameRate-R") {
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))H_FRAMERATE")
field(PREC, "2")
field(SCAN, "I/O Intr")
field(PINI, "YES")
}
record(seq, "$(P)$(R)#SoftSeqDisable") {
field(SELM, "All")
# Disable sequencer 0
field(DOL1, "1")
field(LNK1, "$(EVR):SoftSeq-0-Disable-Cmd CP")
}
record(seq, "$(P)$(R)#SoftSeqEnable") {
field(SELM, "All")
# reset prescaler
field(DOL1, "123")
field(LNK1, "$(EVR):Evt-ResetPS-SP PP")
field(DOL2, "123")
field(LNK2, "$(EVR):EvtCode-SP.PROC PP")
# Enable sequencer 0
field(LNK3, "$(EVR):SoftSeq-0-Enable-Cmd.PROC PP")
}
record("*", "$(P)$(R)Acquire")
{
field(FLNK, "$(P)$(R)#CalcSoftSeqCtrl PP MS")
}
record(calcout, "$(P)$(R)#CalcSoftSeqCtrl") {
field(DESC, "Calc software sequencer control")
field(CALC, "(A = 1 && B = 1) ? 1 : 0")
field(INPA, "$(P)$(R)Acquire")
field(INPB, "$(P)$(R)TriggerSource-RB")
field(OOPT, "On Change")
field(OUT, "$(P)$(R)#SoftSeqControl.PROC")
}
record(fanout, "$(P)$(R)#SoftSeqControl") {
field(SELM, "Specified")
field(SELL, "$(P)$(R)#CalcSoftSeqCtrl")
field(LNK0, "$(P)$(R)#SoftSeqDisable PP")
field(LNK1, "$(P)$(R)#SoftSeqEnable PP")
}
##########################################################################
@@ -315,21 +357,20 @@ record(mbbi, "$(P)$(R)BitPerChannel-RB") {
##########################################################################
# Trigger source (mode 4)
record(mbbo, "$(P)$(R)TriggerSource-S") {
field(DESC,"")
field(PINI, "YES")
field(DTYP, "asynInt32")
field(ZRVL, "1")
field(ZRST, "Internal")
field(ONVL, "2")
field(ONST, "External")
field(TWVL, "3")
field(TWST, "Software")
field(THVL, "4")
field(THST, "Master Pulse")
# field(DRVL, "1")
# field(DRVH, "4")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))H_TRIGGER_SOURCE")
field(VAL, "1")
field(DESC,"")
field(PINI, "YES")
field(DTYP, "asynInt32")
field(ZRVL, "1")
field(ZRST, "Internal")
field(ONVL, "2")
field(ONST, "External")
field(TWVL, "3")
field(TWST, "Software")
field(THVL, "4")
field(THST, "Master Pulse")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))H_TRIGGER_SOURCE")
field(VAL, "1")
field(FLNK, "$(P)$(R)AcquirePeriod.PROC PP MS")
}
record(mbbi, "$(P)$(R)TriggerSource-RB") {
+56 -92
View File
@@ -183,8 +183,8 @@ Hama::Hama(const char* portName, int cameraId, int maxBuffers, size_t maxMemory,
createParam( hImageDetectorPixelNumVertString, asynParamInt32, &hImageDetectorPixelNumVert);
createParam( hTimeStampProducerString, asynParamInt32, &hTimeStampProducer);
createParam( hFrameStampProducerString, asynParamInt32, &hFrameStampProducer);
createParam( hTimeStampString, asynParamFloat64, &hTimeStamp);
createParam(evrTimeStampString, asynParamOctet, &evrTimeStamp);
setIntegerParam(NDArrayCallbacks, 1);
callParamCallbacks();
@@ -789,10 +789,9 @@ void Hama::imageTask(){
epicsTimeStamp prevAcqTime, currentAcqTime;
double elapsedTime;
//static const char *functionName = "imageTask";
int triggerMode = DCAMPROP_TRIGGERSOURCE__INTERNAL;
lock();
while(1) {
getIntegerParam(ADAcquire, &acquire);
if(!acquire) {
@@ -800,38 +799,29 @@ void Hama::imageTask(){
unlock();
status = epicsEventWait(startEvent_);
puts("Starting request received");
lock();
/* We are acquiring. */
//acquireStatusError = 0;
setIntegerParam(ADStatus, ADStatusAcquire);
status = startAcquire();
epicsTimeGetCurrent(&prevAcqTime);
printf("Status: %d\n", status);
if (status != asynSuccess) {
//acquireStatusError = 1;
epicsThreadSleep(.1);
}
else {
setIntegerParam(ADStatus, ADStatusAcquire);
acquire = 1;
/* Get the current time */
prevAcquisitionCount = 0;
setIntegerParam(ADNumImagesCounter, 0);
}
}
/* Added this delay for the thread not to hog the processor. No need to run on full speed. */
//epicsThreadSleep(0.001);
// get image transfer status.
unlock();
imageTransferStatus(m_hdcam, captransferinfo);
lock();
if (prevAcquisitionCount < (uint64_t)captransferinfo.nFrameCount) {
//printf("nFrameCount: %d, nNewestFrameIndex: %d\n", captransferinfo.nFrameCount, captransferinfo.nNewestFrameIndex);
printf("nFrameCount: %d\n", captransferinfo.nFrameCount);
prevAcquisitionCount = captransferinfo.nFrameCount;
// get image information
@@ -855,30 +845,30 @@ void Hama::imageTask(){
count++;
setIntegerParam(NDArrayCounter, count);
int32 ts_sec = 0, ts_microsec = 0;
epicsUInt32 ts_sec = 0, ts_microsec = 0;
accessCapturedImage(m_hdcam, captransferinfo.nNewestFrameIndex, image,
width * 2, width, height, ts_sec, ts_microsec);
double exposure_time, readout_time, timestamp;
//double _readouttime, _internal_frameinternal, _cyclictriggerperiod, _mintriggerblanking;
//dcamprop_getvalue(m_hdcam, DCAM_IDPROP_TIMING_READOUTTIME, &_readouttime);
//dcamprop_getvalue(m_hdcam, DCAM_IDPROP_INTERNAL_FRAMEINTERVAL, &_internal_frameinternal);
//dcamprop_getvalue(m_hdcam, DCAM_IDPROP_TIMING_CYCLICTRIGGERPERIOD, &_cyclictriggerperiod);
//dcamprop_getvalue(m_hdcam, DCAM_IDPROP_TIMING_MINTRIGGERBLANKING, &_mintriggerblanking);
//printf("DCAM_IDPROP_TIMING_READOUTTIME: %f\n", _readouttime);
//printf("DCAM_IDPROP_INTERNAL_FRAMEINTERVAL: %f\n", _internal_frameinternal);
//printf("DCAM_IDPROP_TIMING_CYCLICTRIGGERPERIOD: %f\n", _cyclictriggerperiod);
//printf("DCAM_IDPROP_TIMING_MINTRIGGERBLANKING: %f\n", _mintriggerblanking);
dcamprop_getvalue(m_hdcam, DCAM_IDPROP_TIMING_READOUTTIME, &readout_time);
dcamprop_getvalue(m_hdcam, DCAM_IDPROP_EXPOSURETIME, &exposure_time);
timestamp = (ts_sec + ts_microsec / 1.0e6) - (exposure_time + readout_time);
status = setDoubleParam(hTimeStamp, timestamp);
printf("readout_time: %f - exposure_time: %f\n", readout_time, exposure_time);
//printf("Timestamp from camera: %f\n", (ts_sec + ts_microsec / 1.0e6));
//printf("Timestamp from camera with correction: %f\n", timestamp);
getIntegerParam(hTriggerSource, &triggerMode);
if (triggerMode == DCAMPROP_TRIGGERSOURCE__EXTERNAL) {
char buf[256];
getStringParam(evrTimeStamp, 256, buf);
// remember parsed timestamp values
sscanf(buf, "%u.%u", &mTimeStampSec, &mTimeStampNsec);
timestamp = mTimeStampSec + mTimeStampNsec / 1.e9;
printf("mTimeStampSec: %u - mTimeStampNsec: %u\n", mTimeStampSec, mTimeStampNsec);
printf("Timestamp from evr: %f\n", timestamp);
} else {
timestamp = (ts_sec + ts_microsec / 1.0e6) - (exposure_time + readout_time);
printf("Timestamp from camera: %f\n", timestamp);
}
epicsTimeGetCurrent(&currentAcqTime);
elapsedTime = epicsTimeDiffInSeconds(&currentAcqTime, &prevAcqTime);
@@ -899,7 +889,7 @@ void Hama::imageTask(){
if(pImage) {
pImage->uniqueId = count;
pImage->timeStamp = ts_sec + (ts_microsec / 1.0e6);
pImage->timeStamp = timestamp;
updateTimeStamp(&pImage->epicsTS);
memcpy(pImage->pData, (epicsUInt16 *)image, pImage->dataSize);
@@ -922,8 +912,8 @@ void Hama::imageTask(){
setShutter(0);
stopAcquire();
setIntegerParam(ADAcquire, 0);
setIntegerParam(ADStatus, ADStatusIdle);
}
callParamCallbacks();
}
}
@@ -1131,10 +1121,7 @@ return status;
//============================================================================
asynStatus Hama::writeInt32(asynUser *pasynUser, epicsInt32 value){
//printf("[DEBUG]::writeInt32\t");
asynStatus Hama::writeInt32(asynUser *pasynUser, epicsInt32 value) {
asynStatus status = asynSuccess;
const char* functionName = "writeInt32";
const char* paramName;
@@ -1151,19 +1138,18 @@ asynStatus Hama::writeInt32(asynUser *pasynUser, epicsInt32 value){
status = setIntegerParam(index, value);
if (index == ADAcquire) {
printf("[DEBUG]::writeInit32 ADAcquire\n");
if (value) {
if (index == ADAcquire) {
if (value && adstatus != ADStatusAcquire) {
/* Send an event to wake up the acq task.*/
puts("Requested acquire start event. Sending acquire start event signal to thread");
epicsEventSignal(this->startEvent_);
}
else if (!value && (adstatus == ADStatusAcquire || adstatus == ADStatusError)) {
else if (!value && (adstatus == ADStatusAcquire || adstatus == ADStatusError || adstatus == ADStatusWaiting)) {
/* This was a command to stop acquisition */
setShutter(0);
stopAcquire();
setIntegerParam(ADStatus, ADStatusAborted);
stopAcquire();
}
}
}
/*
else if (index == ADMaxSizeX_RBV) {
dcamprop_setvalue(m_hdcam, DETECTOR_PIXEL_NUM_HORZ, value);
@@ -1618,9 +1604,9 @@ asynStatus Hama::writeInt32(asynUser *pasynUser, epicsInt32 value){
printf("[+DEBUG]:: ADDriver::writeInit32 %s\n", paramName);
//ADDriver::writeInt32(pasynUser, value);
}
else{
printf("[-DEBUG]::function writeInt32 did not find a parameter index = %d, %s\n", index, paramName);
}
//else{
// printf("[-DEBUG]::function writeInt32 did not find a parameter index = %d, %s\n", index, paramName);
//}
}
setIntegerParam(index, value);
@@ -1656,35 +1642,27 @@ asynStatus Hama::writeFloat64(asynUser *pasynUser, epicsFloat64 value){
//-- Feature
if(index == ADAcquireTime) {
printf("[DEBUG]::function ADAcquireTime from camera: %f\n", value);
status = setFeature(DCAM_IDPROP_EXPOSURETIME, value);
m_err = dcamprop_setgetvalue(m_hdcam, DCAM_IDPROP_EXPOSURETIME, &dvalue);
if(failed(m_err)) {
printError(m_hdcam, m_err, "dcamprop_setgetvalue()", "IDPROP:0x%08x, VALUE:%f\n", index, dvalue);
status = asynError;
}
/* int trigger_mode = 0;
getIntegerParam(hTriggerSource, &trigger_mode);
int trigger_mode = 0;
double acquire_period = 0;
status = getDoubleParam(ADAcquirePeriod, &acquire_period);
status = getIntegerParam(hTriggerSource, &trigger_mode);
if (trigger_mode != DCAMPROP_TRIGGERSOURCE__EXTERNAL) {
status = setFeature(DCAM_IDPROP_EXPOSURETIME, value);
m_err = dcamprop_setgetvalue(m_hdcam, DCAM_IDPROP_EXPOSURETIME, &dvalue);
if(failed(m_err)) {
printError(m_hdcam, m_err, "dcamprop_setgetvalue()", "IDPROP:0x%08x, VALUE:%f\n", index, dvalue);
if (trigger_mode == DCAMPROP_TRIGGERSOURCE__EXTERNAL) {
if (value >= acquire_period) status = asynError;
else {
status = setFeature(DCAM_IDPROP_EXPOSURETIME, value);
}
}
double acquire_period = 0;
status = getDoubleParam(ADAcquirePeriod, &acquire_period);
else {
status = setFeature(DCAM_IDPROP_EXPOSURETIME, value);
if (value >= acquire_period) {
status = setDoubleParam(ADAcquirePeriod, 0);
status = setFeature(DCAM_IDPROP_TRIGGERSOURCE, DCAMPROP_TRIGGERSOURCE__INTERNAL);
status = setIntegerParam(hTriggerSource, DCAMPROP_TRIGGERSOURCE__INTERNAL);
callParamCallbacks();
}
}
else status = asynError;
*/
}
}
else if(index == ADAcquirePeriod) {
@@ -1693,13 +1671,11 @@ asynStatus Hama::writeFloat64(asynUser *pasynUser, epicsFloat64 value){
int trigger_mode = 0;
getIntegerParam(hTriggerSource, &trigger_mode);
m_err = dcamprop_getvalue(m_hdcam, DCAM_IDPROP_EXPOSURETIME, &dvalue);
if (trigger_mode != DCAMPROP_TRIGGERSOURCE__EXTERNAL) {
m_err = dcamprop_getvalue(m_hdcam, DCAM_IDPROP_EXPOSURETIME, &dvalue);
if (value <= dvalue) {
status = setFeature(DCAM_IDPROP_TRIGGERSOURCE, DCAMPROP_TRIGGERSOURCE__INTERNAL);
status = setIntegerParam(hTriggerSource, DCAMPROP_TRIGGERSOURCE__INTERNAL);
value = 0;
}
else {
status = setFeature(DCAM_IDPROP_TRIGGERSOURCE, DCAMPROP_TRIGGERSOURCE__MASTERPULSE);
@@ -1712,7 +1688,9 @@ asynStatus Hama::writeFloat64(asynUser *pasynUser, epicsFloat64 value){
status = setIntegerParam(hMasterPulseMode, DCAMPROP_MASTERPULSE_MODE__CONTINUOUS);
}
}
else status = asynError;
else {
if (value <= dvalue) status = asynError;
}
}
//-- Trigger
@@ -1816,9 +1794,6 @@ else if (index == hInternalLineInterval) {
status = ADDriver::writeFloat64(pasynUser, value);
printf("[+DEBUG]:: ADDriver::writeInit32 %s\n", paramName);
}
else{
printf("[-DEBUG]::function writeFloat64 did not find a parameter index = %d, %s\n", index, paramName);
}
}
if (status)
@@ -2093,7 +2068,6 @@ int Hama::disconnectCamera(void){
int Hama::allocateBuffers(unsigned int nBuffers) {
m_err = dcambuf_alloc(m_hdcam, nBuffers);
if(failed(m_err)) {
puts("banana");
printError(m_hdcam, m_err, "dcambuf_alloc()");
return asynError;
}
@@ -2113,8 +2087,14 @@ return 0;
asynStatus Hama::stopAcquire(void)
{
asynStatus status = asynSuccess;
dcamcap_stop(m_hdcam);
m_err = dcamcap_stop(m_hdcam);
if(failed(m_err)) {
printError(m_hdcam, m_err, "dcamcap_stop()");
status = asynError;
}
printf("Stop Capture\n");
freeBuffers();
return status;
}
@@ -2135,21 +2115,6 @@ asynStatus Hama::startAcquire(void)
printError(m_hdcam, m_err, "dcamcap_start()");
status = asynError;
}
else {
printf( "\nStart Capture\n" );
// set wait param
DCAMWAIT_START waitstart;
memset( &waitstart, 0, sizeof(waitstart) );
waitstart.size = sizeof(waitstart);
waitstart.eventmask = DCAMWAIT_CAPEVENT_FRAMEREADY;
waitstart.timeout = DCAMWAIT_TIMEOUT_INFINITE;
m_err = dcamwait_start(hwait, &waitstart);
if(failed(m_err)) {
printError(m_hdcam, m_err, "dcamwait_start()");
status = asynError;
}
}
return status;
}
@@ -2165,7 +2130,7 @@ inline void* memcpy_s( void* dst, size_t dstsize, const void* src, size_t srclen
//============================================================================
asynStatus Hama::accessCapturedImage(HDCAM hdcam, int32 iFrame, void* buf,
int32 rowbytes, int32 cx, int32 cy,
int32& ts_sec, int32& ts_microsec)
epicsUInt32& ts_sec, epicsUInt32& ts_microsec)
{
DCAMERR err;
@@ -2282,7 +2247,6 @@ asynStatus Hama::imageTransferStatus(HDCAM hdcam, DCAMCAP_TRANSFERINFO &captrans
}
if(captransferinfo.nFrameCount < 1) {
printf( "not capture image\n" );
return asynError;
}
+6 -4
View File
@@ -128,7 +128,7 @@
#define hImageDetectorPixelNumVertString "H_IMAGE_DETECTOR_PIXEL_NUM_VERT" /* asynInt32 ro */
#define hTimeStampProducerString "H_TIMESTAMP_PRODUCER" /* asynInt32 ro */
#define hFrameStampProducerString "H_FRAMESTAMP_PRODUCER" /* asynInt32 ro */
#define hTimeStampString "H_TIMESTAMP" /* asynFloat64 ro */
#define evrTimeStampString "EVR_TIMESTAMP"
// For some reason these two addresses are not defined in the dcamapi4 neither in dcamprop.h
#define DETECTOR_PIXEL_NUM_HORZ 0x00420830
@@ -151,6 +151,8 @@ public:
int readParameter(int paramIndex);
int readParameterStr(int paramIndex);
epicsUInt32 mTimeStampSec;
epicsUInt32 mTimeStampNsec;
void imageTask();
void temperatureTask();
@@ -265,9 +267,9 @@ protected:
int hImageDetectorPixelNumVert;
int hTimeStampProducer;
int hFrameStampProducer;
int evrTimeStamp;
//----
int hTimeStamp;
//#define LAST_HAMA_PARAM hTimeStamp
//#define LAST_HAMA_PARAM evrTimeStamp
private:
@@ -288,7 +290,7 @@ private:
asynStatus startAcquire(void);
asynStatus stopAcquire(void);
void getImageInformation(HDCAM hdcam, int32& pixeltype, int32& width, int32& rowbytes, int32& height, int32& framebytes);
asynStatus accessCapturedImage(HDCAM hdcam, int32 iFrame, void* buf, int32 rowbytes, int32 cx, int32 cy, int32& ts_sec, int32& ts_microsec);
asynStatus accessCapturedImage(HDCAM hdcam, int32 iFrame, void* buf, int32 rowbytes, int32 cx, int32 cy, epicsUInt32& ts_sec, epicsUInt32& ts_microsec);
asynStatus imageTransferStatus(HDCAM hdcam, DCAMCAP_TRANSFERINFO &captransferinfo);
// wrapper functions for dcamapi
+7
View File
@@ -1,6 +1,7 @@
# This should be a test startup script
require adhama
require adpluginkafka
require seq
epicsEnvSet("PREFIX", "Hama:")
@@ -65,11 +66,17 @@ dbpf Hama:cam1:PoolUsedMem.SCAN 0
dbpf Hama:image1:EnableCallbacks 1
dbpf Hama:Kfk1:EnableCallbacks 1
dbpf Hama:cam1:AcquireTime .05
#dbpf Hama:cam1:TriggerSource-S 1 # external
#dbpf Hama:cam1:NumImages 10
#dbpf Hama:cam1:ImageMode 1
#dbpf Hama:cam1:TriggerPolarity-S # 2-positive, 1-negative
epicsThreadSleep(1.0)
dbl > pv.list
#
# END of st.cmd
#