Skip to content

Commit 4b4d2fe

Browse files
committed
better wait at frame0 for getNumFramesRead() to return 0, with a max time to wait
1 parent 662ab03 commit 4b4d2fe

File tree

1 file changed

+65
-48
lines changed

1 file changed

+65
-48
lines changed

xspress3App/src/xspress3Epics.cpp

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ using std::endl;
5454

5555
//Defining enums for custom trigger modes
5656
#ifndef XSP3_GTIMA_SRC_SOFT_INT
57-
#define XSP3_GTIMA_SRC_SOFT_INT 8 //!< Time frame incremented by software and reset by internal timeframe.
57+
#define XSP3_GTIMA_SRC_SOFT_INT 8 //!< Time frame incremented by software and reset by internal timeframe.
5858
#endif
5959
#ifndef XSP3_GTIMA_SRC_TTL_INT
60-
#define XSP3_GTIMA_SRC_TTL_INT 9 //!< Time frame incremented by TTL and reset by internal timeframe.
60+
#define XSP3_GTIMA_SRC_TTL_INT 9 //!< Time frame incremented by TTL and reset by internal timeframe.
6161
#endif
6262

6363
//Definitions of static class data members
@@ -99,7 +99,7 @@ static void xsp3DataTaskC(void *drvPvt);
9999
* @param maxMemory Used by asynPortDriver (set to -1 for unlimited)
100100
* @param debug This debug flag is passed to xsp3_config in the Xspress API (0 or 1)
101101
* @param simTest 0 or 1. Set to 1 to run up this driver in simulation mode.
102-
* @param circBuffer 0 or 1. Set to run with cirular buffer enabled. Required when more than 12216 frames per acquisition
102+
* @param circBuffer 0 or 1. Set to run with cirular buffer enabled. Required when more than 12216 frames per acquisition
103103
*/
104104
Xspress3::Xspress3(const char *portName, int numChannels, int numCards, const char *baseIP, int maxFrames, int maxDriverFrames, int maxSpectra, int maxBuffers, size_t maxMemory, int debug, int simTest, int circBuffer)
105105
: ADDriver(portName,
@@ -422,7 +422,7 @@ asynStatus Xspress3::connect(void)
422422
status = asynError;
423423
}
424424
printf("xsp3_clocks_setup: Measured frequency %.2f MHz\n", float(xsp3_status)/1.0e6);
425-
425+
426426

427427
// Limit frames for Mini > 1 channel
428428
if (generation == 2 && numChannels_ > 1) {
@@ -434,7 +434,7 @@ asynStatus Xspress3::connect(void)
434434
paramStatus = ((setIntegerParam(xsp3NumFramesConfigParam, 100001) == asynSuccess) && paramStatus);
435435
paramStatus = ((setIntegerParam(xsp3NumFramesDriverParam, 100001) == asynSuccess) && paramStatus);
436436
}
437-
437+
438438
}
439439

440440
// Restore settings from a file
@@ -757,7 +757,7 @@ asynStatus Xspress3::restoreSettings(void)
757757
/*
758758
* We need to now update the channel control registers based on whether we want to use
759759
* playback data or real data signals.
760-
*
760+
*
761761
* This is to handle the case where the settings files includes playback data, but the
762762
* user wants the run flags to get real data. When the settings files are loaded the
763763
* playback data means that the data source for each channel is set to playback data
@@ -1181,7 +1181,7 @@ asynStatus Xspress3::mapTriggerMode(int mode, int invert_f0, int invert_veto, in
11811181
{
11821182
asynStatus status = asynSuccess;
11831183
const char *functionName = "Xspress3::mapTriggerMode";
1184-
1184+
11851185
if (mode == mbboTriggerFIXED_) {
11861186
*apiMode = XSP3_GTIMA_SRC_FIXED;
11871187
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s Trigger Mode XSP3_GTIMA_SRC_FIXED, value: %d\n",
@@ -1212,12 +1212,12 @@ asynStatus Xspress3::mapTriggerMode(int mode, int invert_f0, int invert_veto, in
12121212
functionName, XSP3_GTIMA_SRC_LVDS_BOTH);
12131213
} else if (mode == mbboTriggerSOFTINTERNAL_) {
12141214
*apiMode = XSP3_GTIMA_SRC_SOFT_INT;
1215-
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s Trigger Mode XSP3_GTIMA_SRC_SOFT_INT , value: %d\n",
1216-
functionName, XSP3_GTIMA_SRC_SOFT_INT );
1215+
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s Trigger Mode XSP3_GTIMA_SRC_SOFT_INT , value: %d\n",
1216+
functionName, XSP3_GTIMA_SRC_SOFT_INT );
12171217
} else if (mode == mbboTriggerTTLINTERNAL_) {
12181218
*apiMode = XSP3_GTIMA_SRC_TTL_INT;
1219-
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s Trigger Mode XSP3_GTIMA_SRC_TTL_INT , value: %d\n",
1220-
functionName, XSP3_GTIMA_SRC_TTL_INT );
1219+
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s Trigger Mode XSP3_GTIMA_SRC_TTL_INT , value: %d\n",
1220+
functionName, XSP3_GTIMA_SRC_TTL_INT );
12211221
} else {
12221222
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s ERROR: Mapping an unknown trigger mode. mode: %d\n", functionName, mode);
12231223
setStringParam(ADStatusMessage, "ERROR Unknown Trigger Mode");
@@ -1365,7 +1365,7 @@ asynStatus Xspress3::writeInt32(asynUser *pasynUser, epicsInt32 value)
13651365
}
13661366
}
13671367
}
1368-
1368+
13691369
else if (function == xsp3NumChannelsParam) {
13701370
asynPrint(this->pasynUserSelf, ASYN_TRACE_FLOW, "%s Set Number Of Channels.\n", functionName);
13711371
getIntegerParam(xsp3MaxNumChannelsParam, &xsp3_num_channels);
@@ -1539,7 +1539,7 @@ asynStatus Xspress3::writeInt32(asynUser *pasynUser, epicsInt32 value)
15391539
else if (function == xsp3DtcEnableParam) {
15401540
// Turning on DTC changes array type to float
15411541
if (value == 1) setIntegerParam(NDDataType, NDFloat64);
1542-
else setIntegerParam(NDDataType, NDUInt32);;
1542+
else setIntegerParam(NDDataType, NDUInt32);;
15431543
}
15441544

15451545
else {
@@ -1561,8 +1561,8 @@ asynStatus Xspress3::writeInt32(asynUser *pasynUser, epicsInt32 value)
15611561
status = (asynStatus) setIntegerParam(addr, function, value);
15621562
if (status!=asynSuccess) {
15631563
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
1564-
"%s Error Setting Parameter. Asyn addr: %d, asynUser->reason: %d, value: %d\n",
1565-
functionName, addr, function, value);
1564+
"%s Error Setting Parameter. Asyn addr: %d, asynUser->reason: %d, value: %d\n",
1565+
functionName, addr, function, value);
15661566
return(status);
15671567
}
15681568

@@ -1622,7 +1622,7 @@ asynStatus Xspress3::writeOctet(asynUser *pasynUser, const char *value,
16221622
} else {
16231623
/* If this parameter belongs to a base class call its method */
16241624
if (function < XSP3_FIRST_DRIVER_COMMAND) {
1625-
status = asynNDArrayDriver::writeOctet(pasynUser, value, nChars, nActual);
1625+
status = asynNDArrayDriver::writeOctet(pasynUser, value, nChars, nActual);
16261626
}
16271627
}
16281628

@@ -1638,8 +1638,8 @@ asynStatus Xspress3::writeOctet(asynUser *pasynUser, const char *value,
16381638

16391639
if (status) {
16401640
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
1641-
"%s Error Setting Parameter. asynUser->reason: %d\n",
1642-
functionName, function);
1641+
"%s Error Setting Parameter. asynUser->reason: %d\n",
1642+
functionName, function);
16431643
}
16441644

16451645
*nActual = nChars;
@@ -1669,11 +1669,11 @@ asynStatus Xspress3::checkSaveDir(const char *dirName)
16691669
if (status != asynError) {
16701670
while ((d = readdir(dir)) != NULL) {
16711671
if (++countFiles > 2) {
1672-
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s ERROR: Files Already Exist In This Directory.\n", functionName);
1673-
setStringParam(ADStatusMessage, "ERROR Files Already Exist In This Directory.");
1674-
setIntegerParam(ADStatus, ADStatusError);
1675-
status = asynError;
1676-
break;
1672+
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, "%s ERROR: Files Already Exist In This Directory.\n", functionName);
1673+
setStringParam(ADStatusMessage, "ERROR Files Already Exist In This Directory.");
1674+
setIntegerParam(ADStatus, ADStatusError);
1675+
status = asynError;
1676+
break;
16771677
}
16781678
}
16791679
}
@@ -1710,7 +1710,7 @@ asynStatus Xspress3::checkHistBusy(int checkTimes)
17101710
while (notBusyCount<2) {
17111711
for (int chan=0; chan<numChannels; chan++) {
17121712
if ((xsp3->histogram_is_any_busy(xsp3_handle_)) == 0) {
1713-
++notBusyChan;
1713+
++notBusyChan;
17141714
}
17151715
}
17161716
if (notBusyChan == numChannels) {
@@ -1828,8 +1828,8 @@ bool Xspress3::readFrame(u_int32_t* pSCA, u_int32_t* pMCAData, int frameNumber,
18281828
setIntegerParam(NDArrayCounter, frameNumber);
18291829
xsp3Status = xsp3->scaler_read(this->xsp3_handle_, pSCA, 0, 0, frameNumber, XSP3_SW_NUM_SCALERS, this->numChannels_, 1);
18301830
if (xsp3Status != XSP3_OK) {
1831-
checkStatus(xsp3Status, "xsp3_scaler_read", functionName);
1832-
error = true;
1831+
checkStatus(xsp3Status, "xsp3_scaler_read", functionName);
1832+
error = true;
18331833
}
18341834
else
18351835
{
@@ -1909,9 +1909,9 @@ void Xspress3::writeOutScas(void *&pSCA, int numChannels, NDDataType_t dataType)
19091909
allevt = pScaData[3];
19101910
dtperc = 100.0*(allevt*(evtwidth+1) + resets)/ctime;
19111911
dtfact = ctime/(ctime - (allevt*(evtwidth+1) + resets));
1912-
//printf(":D> chan=%i, event_width=%.1f DTpercent=%.3f, DTfactor=%.6f", chan, evtwidth, dtperc, dtfact);
1913-
setDoubleParam(chan, xsp3ChanDTPercentParam, static_cast<epicsFloat64>(dtperc));
1914-
setDoubleParam(chan, xsp3ChanDTFactorParam, static_cast<epicsFloat64>(dtfact));
1912+
//printf(":D> chan=%i, event_width=%.1f DTpercent=%.3f, DTfactor=%.6f", chan, evtwidth, dtperc, dtfact);
1913+
setDoubleParam(chan, xsp3ChanDTPercentParam, static_cast<epicsFloat64>(dtperc));
1914+
setDoubleParam(chan, xsp3ChanDTFactorParam, static_cast<epicsFloat64>(dtfact));
19151915
}
19161916

19171917
pScaData += XSP3_SW_NUM_SCALERS;
@@ -1937,11 +1937,11 @@ void Xspress3::writeOutScas(void *&pSCA, int numChannels, NDDataType_t dataType)
19371937
allevt = 1.0*pScaData[3];
19381938
dtperc = 100.0*(allevt*(evtwidth+1) + resets)/ctime;
19391939
dtfact = ctime/(ctime - (allevt*(evtwidth+1) + resets));
1940-
// printf(":I> chan=%i, event_width=%.1f DTpercent=%.3f, DTfactor=%.6f\n", chan, evtwidth, dtperc, dtfact);
1941-
// setDoubleParam(chan, xsp3ChanDTPercentParam, static_cast<epicsFloat64>(dtperc));
1942-
// setDoubleParam(chan, xsp3ChanDTFactorParam, static_cast<epicsFloat64>(dtfact));
1943-
setDoubleParam(chan, xsp3ChanDTPercentParam, dtperc);
1944-
setDoubleParam(chan, xsp3ChanDTFactorParam, dtfact);
1940+
// printf(":I> chan=%i, event_width=%.1f DTpercent=%.3f, DTfactor=%.6f\n", chan, evtwidth, dtperc, dtfact);
1941+
// setDoubleParam(chan, xsp3ChanDTPercentParam, static_cast<epicsFloat64>(dtperc));
1942+
// setDoubleParam(chan, xsp3ChanDTFactorParam, static_cast<epicsFloat64>(dtfact));
1943+
setDoubleParam(chan, xsp3ChanDTPercentParam, dtperc);
1944+
setDoubleParam(chan, xsp3ChanDTFactorParam, dtfact);
19451945
}
19461946
pScaData += XSP3_SW_NUM_SCALERS;
19471947
}
@@ -2106,7 +2106,8 @@ static void xsp3DataTaskC(void *xspAD)
21062106
bool acquire=false;
21072107
bool aborted=false;
21082108
bool error=false;
2109-
2109+
bool notready=false;
2110+
int notready_count;
21102111
int numChannels, maxSpectra, frameNumber, numFrames=0, acquired, lastAcquired;
21112112
//int frame_count, last_frame_count, frame_counter, frames_remaining, frame_offset;
21122113
size_t dims[2];
@@ -2135,9 +2136,25 @@ static void xsp3DataTaskC(void *xspAD)
21352136
numChannels = dims[1];
21362137
numFrames = pXspAD->getNumFramesToAcquire();
21372138
pXspAD->xspAsynPrint(ASYN_TRACE_FLOW, "Collect %d frames\n", numFrames);
2138-
// printf("data task acquire=%d, numframes=%d / frameNumber=%d\n", (int)acquire, numFrames, frameNumber);
2139+
//printf("data task acquire=%d, numframes=%d / frameNumber=%d\n", (int)acquire, numFrames, frameNumber);
2140+
2141+
// add check that getNumFrames returns 0 for the 0th frame.
2142+
// using this counter to indicate "ready to read frame" seems
2143+
// fragile at frames 0 and 1.
2144+
if (acquire && (frameNumber == 0) ) {
2145+
notready_count = 0;
2146+
notready = pXspAD->getNumFramesRead();
2147+
while (notready) {
2148+
usleep(100);
2149+
notready = pXspAD->getNumFramesRead();
2150+
notready_count +=1;
2151+
if (notready_count > 5000) {
2152+
notready = 0;
2153+
}
2154+
}
2155+
}
21392156
while (acquire && (frameNumber < numFrames)) {
2140-
if (acquired == 0) { usleep(25000); }
2157+
usleep(2);
21412158
acquired = pXspAD->getNumFramesRead();
21422159
if (frameNumber < acquired) {
21432160
lastAcquired = acquired;
@@ -2237,17 +2254,17 @@ extern "C" {
22372254
static const iocshArg xspress3ConfigArg10 = {"Sim Test", iocshArgInt};
22382255
static const iocshArg xspress3ConfigArg11 = {"Circular Buffer", iocshArgInt};
22392256
static const iocshArg * const xspress3ConfigArgs[] = {&xspress3ConfigArg0,
2240-
&xspress3ConfigArg1,
2241-
&xspress3ConfigArg2,
2242-
&xspress3ConfigArg3,
2243-
&xspress3ConfigArg4,
2244-
&xspress3ConfigArg5,
2245-
&xspress3ConfigArg6,
2246-
&xspress3ConfigArg7,
2247-
&xspress3ConfigArg8,
2248-
&xspress3ConfigArg9,
2249-
&xspress3ConfigArg10,
2250-
&xspress3ConfigArg11};
2257+
&xspress3ConfigArg1,
2258+
&xspress3ConfigArg2,
2259+
&xspress3ConfigArg3,
2260+
&xspress3ConfigArg4,
2261+
&xspress3ConfigArg5,
2262+
&xspress3ConfigArg6,
2263+
&xspress3ConfigArg7,
2264+
&xspress3ConfigArg8,
2265+
&xspress3ConfigArg9,
2266+
&xspress3ConfigArg10,
2267+
&xspress3ConfigArg11};
22512268

22522269

22532270
static const iocshFuncDef configXspress3 = {"xspress3Config", 12, xspress3ConfigArgs};

0 commit comments

Comments
 (0)