asynStatus daedataDriver::writeArray(asynUser *pasynUser, const char* functionName, T *value, size_t nElements) { int function = pasynUser->reason; asynStatus status = asynSuccess; const char *paramName = NULL; getParamName(function, ¶mName); try { if (function == P_CHANNEL_POSITION) { m_udp->writeData(0x400, value, nElements, true, pasynUser); doCallbacksInt32Array(value, nElements, P_CHANNEL_POSITION, 0); } else { throw std::runtime_error("invalid parameter"); } asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, name=%s\n", driverName, functionName, function, paramName); return asynSuccess; } catch(const std::exception& ex) { epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d, name=%s, error=%s", driverName, functionName, status, function, paramName, ex.what()); return asynError; } }
asynStatus isisdaeDriver::readInt32Array(asynUser *pasynUser, epicsInt32 *value, size_t nElements, size_t *nIn) { asynStatus stat = readArray(pasynUser, "readInt32Array", value, nElements, nIn); callParamCallbacks(); // this flushes P_ErrMsgs doCallbacksInt32Array(value, *nIn, pasynUser->reason, 0); return stat; }
/** Callback task that runs as a separate thread. */ void testErrors::callbackTask(void) { asynStatus currentStatus; int itemp; epicsInt32 iVal; epicsFloat64 dVal; int i; char octetValue[20]; /* Loop forever */ while (1) { lock(); getIntegerParam(P_StatusReturn, &itemp); currentStatus = (asynStatus)itemp; getIntegerParam(P_Int32Value, &iVal); iVal++; if (iVal > 15) iVal=0; setIntegerParam(P_Int32Value, iVal); setParamStatus(P_Int32Value, currentStatus); getDoubleParam(P_Float64Value, &dVal); dVal += 0.1; setDoubleParam(P_Float64Value, dVal); setParamStatus(P_Float64Value, currentStatus); sprintf(octetValue, "%.1f", dVal); setParamStatus(P_UInt32DigitalValue, currentStatus); setStringParam(P_OctetValue, octetValue); setParamStatus(P_OctetValue, currentStatus); setParamStatus(P_Float64ArrayValue, currentStatus); for (i=0; i<MAX_ARRAY_POINTS; i++) { int8ArrayValue_[i] = iVal; int16ArrayValue_[i] = iVal; int32ArrayValue_[i] = iVal; float32ArrayValue_[i] = (epicsFloat32)dVal; float64ArrayValue_[i] = dVal; } callParamCallbacks(); setParamStatus(P_Int8ArrayValue, currentStatus); doCallbacksInt8Array(int8ArrayValue_, MAX_ARRAY_POINTS, P_Int8ArrayValue, 0); setParamStatus(P_Int16ArrayValue, currentStatus); doCallbacksInt16Array(int16ArrayValue_, MAX_ARRAY_POINTS, P_Int16ArrayValue, 0); setParamStatus(P_Int32ArrayValue, currentStatus); doCallbacksInt32Array(int32ArrayValue_, MAX_ARRAY_POINTS, P_Int32ArrayValue, 0); setParamStatus(P_Float32ArrayValue, currentStatus); doCallbacksFloat32Array(float32ArrayValue_, MAX_ARRAY_POINTS, P_Float32ArrayValue, 0); setParamStatus(P_Float64ArrayValue, currentStatus); doCallbacksFloat64Array(float64ArrayValue_, MAX_ARRAY_POINTS, P_Float64ArrayValue, 0); unlock(); epicsThreadSleep(CALLBACK_PERIOD); } }
/** Array generation ask that runs as a separate thread. When the P_RunStop parameter is set to 1 * it periodically generates a burst of arrays. */ void testArrayRingBuffer::arrayGenTask(void) { double loopDelay; int runStop; int i, j; int burstLength; double burstDelay; int maxArrayLength; int arrayLength; lock(); /* Loop forever */ getIntegerParam(P_MaxArrayLength, &maxArrayLength); while (1) { getDoubleParam(P_LoopDelay, &loopDelay); getDoubleParam(P_BurstDelay, &burstDelay); getIntegerParam(P_RunStop, &runStop); // Release the lock while we wait for a command to start or wait for updateTime unlock(); if (runStop) epicsEventWaitWithTimeout(eventId_, loopDelay); else (void)epicsEventWait(eventId_); // Take the lock again lock(); /* runStop could have changed while we were waiting */ getIntegerParam(P_RunStop, &runStop); if (!runStop) continue; getIntegerParam(P_ArrayLength, &arrayLength); if (arrayLength > maxArrayLength) { arrayLength = maxArrayLength; setIntegerParam(P_ArrayLength, arrayLength); } getIntegerParam(P_BurstLength, &burstLength); for (i=0; i<burstLength; i++) { for (j=0; j<arrayLength; j++) { pData_[j] = i; } setIntegerParam(P_ScalarData, i); callParamCallbacks(); doCallbacksInt32Array(pData_, arrayLength, P_ArrayData, 0); if (burstDelay > 0.0) epicsThreadSleep(burstDelay); } } }
/** Callback task that runs as a separate thread. */ void testErrors::callbackTask(void) { asynStatus currentStatus; int itemp; epicsInt32 iVal; epicsUInt32 uiVal; epicsFloat64 dVal; int i; char octetValue[20]; /* Loop forever */ while (1) { lock(); updateTimeStamp(); getIntegerParam(P_StatusReturn, &itemp); currentStatus = (asynStatus)itemp; getIntegerParam(P_Int32Value, &iVal); iVal++; if (iVal > 64) iVal=0; setIntegerParam(P_Int32Value, iVal); setParamStatus( P_Int32Value, currentStatus); getIntegerParam(P_BinaryInt32Value, &iVal); iVal++; if (iVal > 1) iVal=0; setIntegerParam(P_BinaryInt32Value, iVal); setParamStatus( P_BinaryInt32Value, currentStatus); getIntegerParam(P_MultibitInt32Value, &iVal); iVal++; if (iVal > MAX_INT32_ENUMS-1) iVal=0; setIntegerParam(P_MultibitInt32Value, iVal); setParamStatus( P_MultibitInt32Value, currentStatus); getUIntDigitalParam(P_UInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK); uiVal++; if (uiVal > 64) uiVal=0; setUIntDigitalParam(P_UInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK); setParamStatus( P_UInt32DigitalValue, currentStatus); getUIntDigitalParam(P_BinaryUInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK); uiVal++; if (uiVal > 1) uiVal=0; setUIntDigitalParam(P_BinaryUInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK); setParamStatus( P_BinaryUInt32DigitalValue, currentStatus); getUIntDigitalParam(P_MultibitUInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK); uiVal++; if (uiVal > MAX_UINT32_ENUMS-1) uiVal=0; setUIntDigitalParam(P_MultibitUInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK); setParamStatus( P_MultibitUInt32DigitalValue, currentStatus); getDoubleParam(P_Float64Value, &dVal); dVal += 0.1; setDoubleParam(P_Float64Value, dVal); setParamStatus(P_Float64Value, currentStatus); sprintf(octetValue, "%.1f", dVal); setStringParam(P_OctetValue, octetValue); setParamStatus(P_OctetValue, currentStatus); for (i=0; i<MAX_ARRAY_POINTS; i++) { int8ArrayValue_[i] = iVal; int16ArrayValue_[i] = iVal; int32ArrayValue_[i] = iVal; float32ArrayValue_[i] = (epicsFloat32)dVal; float64ArrayValue_[i] = dVal; } callParamCallbacks(); setParamStatus(P_Int8ArrayValue, currentStatus); setParamStatus(P_Int16ArrayValue, currentStatus); setParamStatus(P_Int32ArrayValue, currentStatus); setParamStatus(P_Float32ArrayValue, currentStatus); setParamStatus(P_Float64ArrayValue, currentStatus); doCallbacksInt8Array(int8ArrayValue_, MAX_ARRAY_POINTS, P_Int8ArrayValue, 0); doCallbacksInt16Array(int16ArrayValue_, MAX_ARRAY_POINTS, P_Int16ArrayValue, 0); doCallbacksInt32Array(int32ArrayValue_, MAX_ARRAY_POINTS, P_Int32ArrayValue, 0); doCallbacksFloat32Array(float32ArrayValue_, MAX_ARRAY_POINTS, P_Float32ArrayValue, 0); doCallbacksFloat64Array(float64ArrayValue_, MAX_ARRAY_POINTS, P_Float64ArrayValue, 0); unlock(); epicsEventWait(eventId_); } }
/** This function computes the sums, diffs and positions, and does callbacks * \param[in] raw Array of raw current readings */ void drvQuadEM::computePositions(epicsFloat64 raw[QE_MAX_INPUTS]) { int i; int count; int numAverage; int ringOverflows; int geometry; epicsFloat64 currentOffset[QE_MAX_INPUTS]; epicsFloat64 currentScale[QE_MAX_INPUTS]; epicsFloat64 positionOffset[2]; epicsFloat64 positionScale[2]; epicsInt32 intData[QE_MAX_DATA]; epicsFloat64 doubleData[QE_MAX_DATA]; epicsFloat64 denom; static const char *functionName = "computePositions"; getIntegerParam(P_Geometry, &geometry); // If the ring buffer is full then remove the oldest entry if (epicsRingBytesFreeBytes(ringBuffer_) < (int)sizeof(doubleData)) { count = epicsRingBytesGet(ringBuffer_, (char *)&doubleData, sizeof(doubleData)); ringCount_--; getIntegerParam(P_RingOverflows, &ringOverflows); ringOverflows++; setIntegerParam(P_RingOverflows, ringOverflows); } for (i=0; i<QE_MAX_INPUTS; i++) { getDoubleParam(i, P_CurrentOffset, ¤tOffset[i]); getDoubleParam(i, P_CurrentScale, ¤tScale[i]); doubleData[i] = raw[i]*currentScale[i] - currentOffset[i]; } for (i=0; i<2; i++) { getDoubleParam(i, P_PositionOffset, &positionOffset[i]); getDoubleParam(i, P_PositionScale, &positionScale[i]); } doubleData[QESumAll] = doubleData[QECurrent1] + doubleData[QECurrent2] + doubleData[QECurrent3] + doubleData[QECurrent4]; if (geometry == QEGeometrySquare) { doubleData[QESumX] = doubleData[QESumAll]; doubleData[QESumY] = doubleData[QESumAll]; doubleData[QEDiffX] = (doubleData[QECurrent2] + doubleData[QECurrent3]) - (doubleData[QECurrent1] + doubleData[QECurrent4]); doubleData[QEDiffY] = (doubleData[QECurrent1] + doubleData[QECurrent2]) - (doubleData[QECurrent3] + doubleData[QECurrent4]); } else { doubleData[QESumX] = doubleData[QECurrent1] + doubleData[QECurrent2]; doubleData[QESumY] = doubleData[QECurrent3] + doubleData[QECurrent4]; doubleData[QEDiffX] = doubleData[QECurrent2] - doubleData[QECurrent1]; doubleData[QEDiffY] = doubleData[QECurrent4] - doubleData[QECurrent3]; } denom = doubleData[QESumX]; if (denom == 0.) denom = 1.; doubleData[QEPositionX] = (positionScale[0] * doubleData[QEDiffX] / denom) - positionOffset[0]; denom = doubleData[QESumY]; if (denom == 0.) denom = 1.; doubleData[QEPositionY] = (positionScale[1] * doubleData[QEDiffY] / denom) - positionOffset[1]; count = epicsRingBytesPut(ringBuffer_, (char *)&doubleData, sizeof(doubleData)); ringCount_++; if (count != sizeof(doubleData)) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: error writing ring buffer, count=%d, should be %d\n", driverName, functionName, count, (int)sizeof(doubleData)); } getIntegerParam(P_NumAverage, &numAverage); if (numAverage > 0) { if (ringCount_ >= numAverage) { triggerCallbacks(); } } for (i=0; i<QE_MAX_DATA; i++) { intData[i] = (epicsInt32)doubleData[i]; setDoubleParam(i, P_DoubleData, doubleData[i]); callParamCallbacks(i); } doCallbacksInt32Array(intData, QE_MAX_DATA, P_IntArrayData, 0); }