示例#1
0
static long getIoIntInfo(int cmd, dbCommon *pr, IOSCANPVT *iopvt)
{
    devInt32Pvt *pPvt = (devInt32Pvt *)pr->dpvt;
    asynStatus status;
    const char *sizeString;

    /* If initCommon failed then pPvt->pint32 is NULL, return error */
    if (!pPvt->pint32) return -1;

    if (cmd == 0) {
        /* Add to scan list.  Register interrupts */
        asynPrint(pPvt->pasynUser, ASYN_TRACE_FLOW,
            "%s devAsynInt32::getIoIntInfo registering interrupt\n",
            pr->name);
        if (!pPvt->ringBuffer) {
            DBENTRY *pdbentry = dbAllocEntry(pdbbase);
            pPvt->ringBufferSize = DEFAULT_RING_BUFFER_SIZE;
            status = dbFindRecord(pdbentry, pr->name);
            if (status)
                asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR,
                    "%s devAsynInt32::getIoIntInfo error finding record\n",
                    pr->name);
            sizeString = dbGetInfo(pdbentry, "FIFO");
            if (sizeString) pPvt->ringBufferSize = atoi(sizeString);
            pPvt->ringBuffer = epicsRingBytesCreate(pPvt->ringBufferSize*sizeof(epicsInt32));
            if (!pPvt->ringBuffer)
                asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR,
                    "%s devAsynInt32::getIoIntInfo error creating ring buffer\n",
                    pr->name);
            else
                asynPrint(pPvt->pasynUser, ASYN_TRACE_FLOW,
                    "%s devAsynInt32::getIoIntInfo created ring buffer, size=%d\n",
                    pr->name, pPvt->ringBufferSize);
        }
        status = pPvt->pint32->registerInterruptUser(
           pPvt->int32Pvt,pPvt->pasynUser,
           pPvt->interruptCallback,pPvt,&pPvt->registrarPvt);
        if(status!=asynSuccess) {
            printf("%s devAsynInt32 registerInterruptUser %s\n",
                   pr->name,pPvt->pasynUser->errorMessage);
        }
    } else {
        asynPrint(pPvt->pasynUser, ASYN_TRACE_FLOW,
            "%s devAsynInt32::getIoIntInfo cancelling interrupt\n",
             pr->name);
        status = pPvt->pint32->cancelInterruptUser(pPvt->int32Pvt,
             pPvt->pasynUser,pPvt->registrarPvt);
        if(status!=asynSuccess) {
            printf("%s devAsynInt32 cancelInterruptUser %s\n",
                   pr->name,pPvt->pasynUser->errorMessage);
        }
    }
    *iopvt = pPvt->ioScanPvt;
    return 0;
}
示例#2
0
/** Constructor for the drvQuadEM class.
  * Calls constructor for the asynPortDriver base class.
  * \param[in] portName The name of the asyn port driver to be created.
  * \param[in] numParams The number of driver-specific parameters for the derived class
  * \param[in] ringBufferSize The number of samples to hold in the input ring buffer.
  *            This should be large enough to hold all the samples between reads of the
  *            device, e.g. 1 ms SampleTime and 1 second read rate = 1000 samples.
  *            If 0 then default of 2048 is used.
  */
drvQuadEM::drvQuadEM(const char *portName, int numParams, int ringBufferSize) 
   : asynNDArrayDriver(portName, 
                    QE_MAX_DATA+1, /* maxAddr */ 
                    NUM_QE_PARAMS + numParams,
                    0, 0,        /* maxBuffers, maxMemory, no limits */
                    asynInt32Mask | asynInt32ArrayMask | asynFloat64Mask | asynGenericPointerMask | asynDrvUserMask, /* Interface mask */
                    asynInt32Mask | asynInt32ArrayMask | asynFloat64Mask | asynGenericPointerMask,                   /* Interrupt mask */
                    ASYN_CANBLOCK | ASYN_MULTIDEVICE, /* asynFlags.  This driver blocks it is multi-device */
                    1, /* Autoconnect */
                    0, /* Default priority */
                    0) /* Default stack size*/ 
{
    int i;
    int status;
    const char *functionName = "drvQuadEM";
    asynUser *pasynUser;
    
    createParam(P_AcquireString,            asynParamInt32,         &P_Acquire);
    createParam(P_AcquireModeString,        asynParamInt32,         &P_AcquireMode);
    createParam(P_CurrentOffsetString,      asynParamFloat64,       &P_CurrentOffset);
    createParam(P_CurrentScaleString,       asynParamFloat64,       &P_CurrentScale);
    createParam(P_PositionOffsetString,     asynParamFloat64,       &P_PositionOffset);
    createParam(P_PositionScaleString,      asynParamFloat64,       &P_PositionScale);
    createParam(P_GeometryString,           asynParamInt32,         &P_Geometry);
    createParam(P_DoubleDataString,         asynParamFloat64,       &P_DoubleData);
    createParam(P_IntArrayDataString,       asynParamInt32Array,    &P_IntArrayData);
    createParam(P_RingOverflowsString,      asynParamInt32,         &P_RingOverflows);
    createParam(P_ReadDataString,           asynParamInt32,         &P_ReadData);
    createParam(P_PingPongString,           asynParamInt32,         &P_PingPong);
    createParam(P_IntegrationTimeString,    asynParamFloat64,       &P_IntegrationTime);
    createParam(P_SampleTimeString,         asynParamFloat64,       &P_SampleTime);
    createParam(P_RangeString,              asynParamInt32,         &P_Range);
    createParam(P_ResetString,              asynParamInt32,         &P_Reset);
    createParam(P_TriggerModeString,        asynParamInt32,         &P_TriggerMode);
    createParam(P_NumChannelsString,        asynParamInt32,         &P_NumChannels);
    createParam(P_BiasStateString,          asynParamInt32,         &P_BiasState);
    createParam(P_BiasVoltageString,        asynParamFloat64,       &P_BiasVoltage);
    createParam(P_BiasInterlockString,      asynParamInt32,         &P_BiasInterlock);
    createParam(P_HVSReadbackString,        asynParamInt32,         &P_HVSReadback);
    createParam(P_HVVReadbackString,        asynParamFloat64,       &P_HVVReadback);
    createParam(P_HVIReadbackString,        asynParamFloat64,       &P_HVIReadback);
    createParam(P_TemperatureString,        asynParamFloat64,       &P_Temperature);
    createParam(P_ReadStatusString,         asynParamInt32,         &P_ReadStatus);
    createParam(P_ResolutionString,         asynParamInt32,         &P_Resolution);
    createParam(P_ValuesPerReadString,      asynParamInt32,         &P_ValuesPerRead);
    createParam(P_NumAcquireString,         asynParamInt32,         &P_NumAcquire);
    createParam(P_NumAcquiredString,        asynParamInt32,         &P_NumAcquired);
    createParam(P_ReadFormatString,         asynParamInt32,         &P_ReadFormat);
    createParam(P_AveragingTimeString,      asynParamFloat64,       &P_AveragingTime);
    createParam(P_NumAverageString,         asynParamInt32,         &P_NumAverage);
    createParam(P_NumAveragedString,        asynParamInt32,         &P_NumAveraged);
    createParam(P_ModelString,              asynParamInt32,         &P_Model);
    createParam(P_FirmwareString,           asynParamOctet,         &P_Firmware);
    
    setIntegerParam(P_Acquire, 0);
    setIntegerParam(P_RingOverflows, 0);
    setIntegerParam(P_PingPong, 0);
    setDoubleParam(P_IntegrationTime, 0.);
    setIntegerParam(P_Range, 0);
    setIntegerParam(P_TriggerMode, 0);
    setIntegerParam(P_NumChannels, 4);
    numChannels_ = 4;
    setIntegerParam(P_BiasState, 0);
    setDoubleParam(P_BiasVoltage, 0.);
    setIntegerParam(P_Resolution, 16);
    setIntegerParam(P_ValuesPerRead, 1);
    setIntegerParam(P_ReadFormat, 0);
    for (i=0; i<QE_MAX_DATA; i++) {
        setDoubleParam(i, P_DoubleData, 0.0);
    }
    valuesPerRead_ = 1;
    
    if (ringBufferSize <= 0) ringBufferSize = QE_DEFAULT_RING_BUFFER_SIZE;
    
    ringBuffer_ = epicsRingBytesCreate(ringBufferSize * QE_MAX_DATA * sizeof(epicsFloat64));
    ringEvent_ = epicsEventCreate(epicsEventEmpty);

    /* Create the thread that does callbacks when the ring buffer has numAverage samples */
    status = (asynStatus)(epicsThreadCreate("drvQuadEMCallbackTask",
                          epicsThreadPriorityMedium,
                          epicsThreadGetStackSize(epicsThreadStackMedium),
                          (EPICSTHREADFUNC)::callbackTaskC,
                          this) == NULL);
    if (status) {
        printf("%s:%s: epicsThreadCreate failure, status=%d\n", driverName, functionName, status);
        return;
    }
    
    // This driver supports QE_MAX_DATA+1 addresses = 0-11 with autoConnect=1.  But there are only records
    // connected to addresses 0-3, so addresses 4-11 never show as "connected" since nothing ever calls
    // pasynManager->queueRequest.  So we do an exceptionConnect to each address so asynManager will show
    // them as connected.  Note that this is NOT necessary for the driver to function correctly, the
    // NDPlugins will still get called even for addresses that are not "connected".  It is just to
    // avoid confusion.
    for (i=0; i<QE_MAX_DATA+1; i++) {
        pasynUser = pasynManager->createAsynUser(0,0);
        pasynManager->connectDevice(pasynUser, portName, i);
        pasynManager->exceptionConnect(pasynUser);
    }
   
    epicsAtExit(exitHandlerC, this);
}