@@ -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 */
104104Xspress3::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