/** Constructor for the testErrors class. * Calls constructor for the asynPortDriver base class. * \param[in] portName The name of the asyn port driver to be created. */ testErrors::testErrors(const char *portName) : asynPortDriver(portName, 1, /* maxAddr */ (int)NUM_PARAMS, /* Interface mask */ asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask | asynOctetMask | asynInt8ArrayMask | asynInt16ArrayMask | asynInt32ArrayMask | asynFloat32ArrayMask | asynFloat64ArrayMask | asynOptionMask | asynEnumMask | asynDrvUserMask, /* Interrupt mask */ asynInt32Mask | asynFloat64Mask | asynUInt32DigitalMask | asynOctetMask | asynInt8ArrayMask | asynInt16ArrayMask | asynInt32ArrayMask | asynFloat32ArrayMask | asynFloat64ArrayMask | asynEnumMask, 0, /* asynFlags. This driver does not block and it is not multi-device, so flag is 0 */ 1, /* Autoconnect */ 0, /* Default priority */ 0) /* Default stack size*/ { asynStatus status; int i; const char *functionName = "testErrors"; createParam(P_StatusReturnString, asynParamInt32, &P_StatusReturn); createParam(P_EnumOrderString, asynParamInt32, &P_EnumOrder); createParam(P_Int32ValueString, asynParamInt32, &P_Int32Value); createParam(P_Float64ValueString, asynParamFloat64, &P_Float64Value); createParam(P_UInt32DigitalValueString, asynParamUInt32Digital, &P_UInt32DigitalValue); createParam(P_OctetValueString, asynParamOctet, &P_OctetValue); createParam(P_Int8ArrayValueString, asynParamInt8Array, &P_Int8ArrayValue); createParam(P_Int16ArrayValueString, asynParamInt16Array, &P_Int16ArrayValue); createParam(P_Int32ArrayValueString, asynParamInt32Array, &P_Int32ArrayValue); createParam(P_Float32ArrayValueString, asynParamFloat32Array, &P_Float32ArrayValue); createParam(P_Float64ArrayValueString, asynParamFloat64Array, &P_Float64ArrayValue); for (i=0; i<MAX_INT32_ENUMS; i++) { int32EnumStrings_[i] = (char*)calloc(MAX_ENUM_STRING_SIZE, sizeof(char)); } for (i=0; i<MAX_UINT32_ENUMS; i++) { uint32EnumStrings_[i] = (char*)calloc(MAX_ENUM_STRING_SIZE, sizeof(char)); } setIntegerParam(P_StatusReturn, asynSuccess); setIntegerParam(P_Int32Value, 0); setDoubleParam(P_Float64Value, 0.0); setIntegerParam(P_EnumOrder, 0); setEnums(); // Need to force callbacks with the interruptMask once setUIntDigitalParam(P_UInt32DigitalValue, (epicsUInt32)0x0, 0xFFFFFFFF, 0xFFFFFFFF); /* Create the thread that computes the waveforms in the background */ status = (asynStatus)(epicsThreadCreate("testErrorsTask", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC)::callbackTask, this) == NULL); if (status) { printf("%s:%s: epicsThreadCreate failure\n", driverName, functionName); return; } }
static void interruptCallbackEnumBo(void *drvPvt, asynUser *pasynUser, char *strings[], int values[], int severities[], size_t nElements) { devPvt *pPvt = (devPvt *)drvPvt; boRecord *pr = (boRecord *)pPvt->pr; if (!interruptAccept) return; dbScanLock((dbCommon*)pr); setEnums((char*)&pr->znam, NULL, &pr->zsv, strings, NULL, severities, nElements, 2); db_post_events(pr, &pr->val, DBE_PROPERTY); dbScanUnlock((dbCommon*)pr); }
static void interruptCallbackEnumMbbo(void *drvPvt, asynUser *pasynUser, char *strings[], int values[], int severities[], size_t nElements) { devPvt *pPvt = (devPvt *)drvPvt; mbboRecord *pr = (mbboRecord *)pPvt->pr; if (!interruptAccept) return; dbScanLock((dbCommon*)pr); setEnums((char*)&pr->zrst, (int*)&pr->zrvl, &pr->zrsv, strings, values, severities, nElements, MAX_ENUM_STATES); db_post_events(pr, &pr->val, DBE_PROPERTY); dbScanUnlock((dbCommon*)pr); }
/** Called when asyn clients call pasynInt32->write(). * This function sends a signal to the simTask thread if the value of P_Run has changed. * 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 testErrors::writeInt32(asynUser *pasynUser, epicsInt32 value) { int function = pasynUser->reason; asynStatus status = asynSuccess; int itemp; const char *paramName; const char* functionName = "writeInt32"; /* Fetch the parameter string name for use in debugging */ getParamName(function, ¶mName); /* Set the parameter value in the parameter library. */ setIntegerParam(function, value); if (function == P_DoUpdate) { epicsEventSignal(eventId_); } else if (function == P_StatusReturn) { } else if (function == P_EnumOrder) { setEnums(); } else { /* Set the parameter status in the parameter library except for the above commands with always return OK */ /* Get the current error status */ getIntegerParam(P_StatusReturn, &itemp); status = (asynStatus)itemp; setParamStatus(function, status); } /* Do callbacks so higher layers see any changes */ callParamCallbacks(); if (status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d, name=%s, value=%d", driverName, functionName, status, function, paramName, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, name=%s, value=%d\n", driverName, functionName, function, paramName, value); return status; }
static long initCommon(dbCommon *pr, DBLINK *plink, userCallback processCallback,interruptCallbackUInt32Digital interruptCallback, interruptCallbackEnum callbackEnum, int maxEnums, char *pFirstString, int *pFirstValue, epicsEnum16 *pFirstSeverity) { devPvt *pPvt; asynStatus status; asynUser *pasynUser; asynInterface *pasynInterface; pPvt = callocMustSucceed(1, sizeof(*pPvt), "devAsynUInt32Digital::initCommon"); pr->dpvt = pPvt; pPvt->pr = pr; /* Create asynUser */ pasynUser = pasynManager->createAsynUser(processCallback, 0); pasynUser->userPvt = pPvt; pPvt->pasynUser = pasynUser; pPvt->ringBufferLock = epicsMutexCreate(); /* Parse the link to get addr and port */ status = pasynEpicsUtils->parseLinkMask(pasynUser, plink, &pPvt->portName, &pPvt->addr, &pPvt->mask,&pPvt->userParam); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon %s\n", pr->name, pasynUser->errorMessage); goto bad; } /* Connect to device */ status = pasynManager->connectDevice(pasynUser, pPvt->portName, pPvt->addr); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon connectDevice failed %s\n", pr->name, pasynUser->errorMessage); goto bad; } status = pasynManager->canBlock(pPvt->pasynUser, &pPvt->canBlock); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon canBlock failed %s\n", pr->name, pasynUser->errorMessage); goto bad; } /*call drvUserCreate*/ pasynInterface = pasynManager->findInterface(pasynUser,asynDrvUserType,1); if(pasynInterface && pPvt->userParam) { asynDrvUser *pasynDrvUser; void *drvPvt; pasynDrvUser = (asynDrvUser *)pasynInterface->pinterface; drvPvt = pasynInterface->drvPvt; status = pasynDrvUser->create(drvPvt,pasynUser,pPvt->userParam,0,0); if(status!=asynSuccess) { printf("%s devAsynUInt32Digital::initCommon drvUserCreate %s\n", pr->name, pasynUser->errorMessage); goto bad; } } /* Get interface asynUInt32Digital */ pasynInterface = pasynManager->findInterface(pasynUser, asynUInt32DigitalType, 1); if (!pasynInterface) { printf("%s devAsynUInt32Digital::initCommon " "findInterface asynUInt32DigitalType %s\n", pr->name,pasynUser->errorMessage); goto bad; } pPvt->puint32 = pasynInterface->pinterface; pPvt->uint32Pvt = pasynInterface->drvPvt; /* Initialize synchronous interface */ status = pasynUInt32DigitalSyncIO->connect(pPvt->portName, pPvt->addr, &pPvt->pasynUserSync, pPvt->userParam); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon UInt32DigitalSyncIO->connect failed %s\n", pr->name, pPvt->pasynUserSync->errorMessage); goto bad; } pPvt->interruptCallback = interruptCallback; scanIoInit(&pPvt->ioScanPvt); /* Initialize asynEnum interfaces */ pasynInterface = pasynManager->findInterface(pPvt->pasynUser,asynEnumType,1); if (pasynInterface && (maxEnums > 0)) { size_t numRead; asynEnum *pasynEnum = pasynInterface->pinterface; void *registrarPvt; status = pasynEnumSyncIO->connect(pPvt->portName, pPvt->addr, &pPvt->pasynUserEnumSync, pPvt->userParam); if (status != asynSuccess) { printf("%s devAsynUInt32Digital::initCommon EnumSyncIO->connect failed %s\n", pr->name, pPvt->pasynUserEnumSync->errorMessage); goto bad; } status = pasynEnumSyncIO->read(pPvt->pasynUserEnumSync, pPvt->enumStrings, pPvt->enumValues, pPvt->enumSeverities, maxEnums, &numRead, pPvt->pasynUser->timeout); if (status == asynSuccess) { setEnums(pFirstString, pFirstValue, pFirstSeverity, pPvt->enumStrings, pPvt->enumValues, pPvt->enumSeverities, numRead, maxEnums); } status = pasynEnum->registerInterruptUser( pasynInterface->drvPvt, pPvt->pasynUser, callbackEnum, pPvt, ®istrarPvt); if(status!=asynSuccess) { printf("%s devAsynUInt32Digital enum registerInterruptUser %s\n", pr->name,pPvt->pasynUser->errorMessage); } } /* If the info field "asyn:READBACK" is 1 and interruptCallback is not NULL * then register for callbacks on output records */ if (interruptCallback) { int enableCallbacks=0; const char *callbackString; DBENTRY *pdbentry = dbAllocEntry(pdbbase); status = dbFindRecord(pdbentry, pr->name); if (status) { asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s devAsynUInt32Digital::initCommon error finding record\n", pr->name); goto bad; } callbackString = dbGetInfo(pdbentry, "asyn:READBACK"); if (callbackString) enableCallbacks = atoi(callbackString); if (enableCallbacks) { status = createRingBuffer(pr); if (status!=asynSuccess) goto bad; status = pPvt->puint32->registerInterruptUser( pPvt->uint32Pvt,pPvt->pasynUser, pPvt->interruptCallback,pPvt,pPvt->mask, &pPvt->registrarPvt); if(status!=asynSuccess) { printf("%s devAsynUInt32Digital::initRecord error calling registerInterruptUser %s\n", pr->name,pPvt->pasynUser->errorMessage); } } } return INIT_OK; bad: recGblSetSevr(pr,LINK_ALARM,INVALID_ALARM); pr->pact=1; return INIT_ERROR; }