/** Called when asyn clients call pasynInt32->write(). * This function performs actions for some parameters, including NDReadFile, NDWriteFile and NDFileCapture. * For other parameters it calls NDPluginDriver::writeInt32 to see if that method understands the parameter. * For all parameters it sets the value in the parameter library and calls any registered callbacks.. * \param[in] pasynUser pasynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus NDPluginFile::writeInt32(asynUser *pasynUser, epicsInt32 value) { int function = pasynUser->reason; asynStatus status = asynSuccess; const char* functionName = "writeInt32"; /* Set the parameter in the parameter library. */ status = (asynStatus) setIntegerParam(function, value); if (function == NDWriteFile) { if (value) { /* Call the callbacks so the status changes */ callParamCallbacks(); if (this->pArrays[0]) { status = writeFileBase(); } else { asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s:%s: ERROR, no valid array to write", driverName, functionName); status = asynError; } /* Set the flag back to 0, since this could be a busy record */ setIntegerParam(NDWriteFile, 0); } } else if (function == NDReadFile) { if (value) { /* Call the callbacks so the status changes */ callParamCallbacks(); status = readFileBase(); /* Set the flag back to 0, since this could be a busy record */ setIntegerParam(NDReadFile, 0); } } else if (function == NDFileCapture) { /* Must call doCapture if capturing was just started or stopped */ status = doCapture(value); } else { /* This was not a parameter that this driver understands, try the base class */ if (function <= LAST_NDPLUGIN_PARAM) status = NDPluginDriver::writeInt32(pasynUser, value); } /* Do callbacks so higher layers see any changes */ status = callParamCallbacks(); if (status) asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s:%s error, status=%d function=%d, value=%d\n", driverName, functionName, status, function, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, value=%d\n", driverName, functionName, function, value); return status; }
asynStatus NDPluginFile::writeNDArray(asynUser *pasynUser, void *genericPointer) { NDArray *pArray = (NDArray *)genericPointer; asynStatus status = asynSuccess; //static const char *functionName = "writeNDArray"; this->pArrays[0] = pArray; setIntegerParam(NDFileWriteMode, NDFileModeSingle); status = writeFileBase(); /* Do callbacks so higher layers see any changes */ status = callParamCallbacks(); return status; }
/** Called when asyn clients call pasynInt32->write(). * This function performs actions for some parameters, including NDReadFile, NDWriteFile and NDFileCapture. * For other parameters it calls NDPluginDriver::writeInt32 to see if that method understands the parameter. * For all parameters it sets the value in the parameter library and calls any registered callbacks.. * \param[in] pasynUser pasynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus NDPluginFile::writeInt32(asynUser *pasynUser, epicsInt32 value) { int function = pasynUser->reason; asynStatus status = asynSuccess; static const char* functionName = "writeInt32"; /* Set the parameter in the parameter library. */ status = (asynStatus) setIntegerParam(function, value); if (function == NDWriteFile) { if (value) { /* Call the callbacks so the status changes */ callParamCallbacks(); if (this->pArrays[0]) { status = writeFileBase(); } else { asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s::%s: ERROR, no valid array to write", driverName, functionName); status = asynError; } /* Set the flag back to 0, since this could be a busy record */ setIntegerParam(NDWriteFile, 0); } } else if (function == NDReadFile) { if (value) { /* Call the callbacks so the status changes */ callParamCallbacks(); status = readFileBase(); /* Set the flag back to 0, since this could be a busy record */ setIntegerParam(NDReadFile, 0); } } else if (function == NDFileCapture) { if (value) { // Started capture or stream // Reset the value temporarily until the doCapture() has called the // inherited openFile() method and the writer is in a good state to // start writing frames. // See comments on: https://github.com/areaDetector/ADCore/pull/100 setIntegerParam(NDFileCapture, 0); /* Latch the NDFileLazyOpen parameter so that we don't need to care * if the user modifies this parameter before first frame has arrived. */ int paramFileLazyOpen = 0; getIntegerParam(NDFileLazyOpen, ¶mFileLazyOpen); this->lazyOpen = (paramFileLazyOpen != 0); /* So far everything is OK, so we just clear the FileWriteStatus parameters */ setIntegerParam(NDFileWriteStatus, NDFileWriteOK); setStringParam(NDFileWriteMessage, ""); setStringParam(NDFullFileName, ""); } /* Must call doCapture if capturing was just started or stopped */ status = doCapture(value); if (status == asynSuccess) { if (this->lazyOpen) setStringParam(NDFileWriteMessage, "Lazy Open..."); setIntegerParam(NDFileCapture, value); } else { setIntegerParam(NDFileCapture, 0); } } else { /* This was not a parameter that this driver understands, try the base class */ status = NDPluginDriver::writeInt32(pasynUser, value); } /* Do callbacks so higher layers see any changes */ status = callParamCallbacks(); if (status) asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s::%s error, status=%d function=%d, value=%d\n", driverName, functionName, status, function, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s::%s: function=%d, value=%d\n", driverName, functionName, function, value); return status; }
/** Callback function that is called by the NDArray driver with new NDArray data. * Saves a single file if NDFileWriteMode=NDFileModeSingle and NDAutoSave=1. * Stores array in a capture buffer if NDFileWriteMode=NDFileModeCapture and NDFileCapture=1. * Appends data to an open file if NDFileWriteMode=NDFileModeStream and NDFileCapture=1. * In capture or stream mode if the desired number of arrays has been saved (NDFileNumCaptured=NDFileNumCapture) * then it stops capture or streaming. * \param[in] pArray The NDArray from the callback. */ void NDPluginFile::processCallbacks(NDArray *pArray) { int fileWriteMode, autoSave, capture; int arrayCounter; int numCapture, numCaptured; asynStatus status = asynSuccess; //static const char* functionName = "processCallbacks"; /* First check if the callback is really for this file saving plugin */ if (!this->attrIsProcessingRequired(pArray->pAttributeList)) return; /* Most plugins want to increment the arrayCounter each time they are called, which NDPluginDriver * does. However, for this plugin we only want to increment it when we actually got a callback we were * supposed to save. So we save the array counter before calling base method, increment it here */ getIntegerParam(NDArrayCounter, &arrayCounter); /* Call the base class method */ NDPluginDriver::beginProcessCallbacks(pArray); getIntegerParam(NDAutoSave, &autoSave); getIntegerParam(NDFileCapture, &capture); getIntegerParam(NDFileWriteMode, &fileWriteMode); getIntegerParam(NDFileNumCapture, &numCapture); getIntegerParam(NDFileNumCaptured, &numCaptured); /* We always keep the last array so read() can use it. * Release previous one, reserve new one */ if (this->pArrays[0]) this->pArrays[0]->release(); pArray->reserve(); this->pArrays[0] = pArray; switch(fileWriteMode) { case NDFileModeSingle: if (autoSave) { arrayCounter++; writeFileBase(); } break; case NDFileModeCapture: if (capture) { if (numCaptured < numCapture && this->isFrameValid(pArray)) { this->pNDArrayPool->copy(pArray, this->pCapture[numCaptured++], 1); arrayCounter++; setIntegerParam(NDFileNumCaptured, numCaptured); } if (numCaptured == numCapture) { if (autoSave) { writeFileBase(); } capture = 0; setIntegerParam(NDFileCapture, capture); } } break; case NDFileModeStream: if (capture) { arrayCounter++; status = writeFileBase(); if (status == asynSuccess) { numCaptured++; setIntegerParam(NDFileNumCaptured, numCaptured); } if (numCaptured == numCapture) { doCapture(0); } } break; } /* Update the parameters. */ setIntegerParam(NDArrayCounter, arrayCounter); callParamCallbacks(); }