Beispiel #1
0
static asynStatus connect(const char *port, int addr,
   asynUser **ppasynUser, const char *drvInfo)
{
    ioPvt         *pioPvt;
    asynUser      *pasynUser;
    asynStatus    status;
    asynInterface *pasynInterface;

    pioPvt = (ioPvt *)callocMustSucceed(1, sizeof(ioPvt),"asynInt32SyncIO");
    pasynUser = pasynManager->createAsynUser(0,0);
    pasynUser->userPvt = pioPvt;
    *ppasynUser = pasynUser;
    status = pasynManager->connectDevice(pasynUser, port, addr);    
    if (status != asynSuccess) {
        return status;
    }
    pasynInterface = pasynManager->findInterface(pasynUser, asynCommonType, 1);
    if (!pasynInterface) {
       epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
           "port does not implement interface %s",asynCommonType);
       return asynError;
    }
    pioPvt->pasynCommon = (asynCommon *)pasynInterface->pinterface;
    pioPvt->pcommonPvt = pasynInterface->drvPvt;
    pasynInterface = pasynManager->findInterface(pasynUser, asynInt32Type, 1);
    if (!pasynInterface) {
       epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
           "port does not implement interface %s",asynInt32Type);
       return asynError;
    }
    pioPvt->pasynInt32 = (asynInt32 *)pasynInterface->pinterface;
    pioPvt->int32Pvt = pasynInterface->drvPvt;
    if(drvInfo) {
        /* Check for asynDrvUser interface */
        pasynInterface = pasynManager->findInterface(pasynUser,asynDrvUserType,1);
        if(pasynInterface) {
            asynDrvUser *pasynDrvUser;
            void       *drvPvt;
            pasynDrvUser = (asynDrvUser *)pasynInterface->pinterface;
            drvPvt = pasynInterface->drvPvt;
            status = pasynDrvUser->create(drvPvt,pasynUser,drvInfo,0,0);
            if(status==asynSuccess) {
                pioPvt->pasynDrvUser = pasynDrvUser;
                pioPvt->drvUserPvt = drvPvt;
            } else {
                return status;
            }
        }
    }
    return asynSuccess ;
}
static long initFields(epicsEnum16 *pft, epicsUInt32 *pno, epicsUInt32 *pne,
    const char **fldnames, void **pval, void **povl)
{
    int i;
    long status = 0;

    for (i = 0; i < NUM_ARGS; i++, pft++, pno++, pne++, pval++) {
        epicsUInt32 num;
        epicsUInt32 flen;

        if (*pft > DBF_ENUM)
            *pft = DBF_CHAR;

        if (*pno == 0)
            *pno = 1;

        flen = dbValueSize(*pft);
        num = *pno * flen;

        if (num > MAX_ARRAY_SIZE) {
            epicsPrintf("Link %s - Array too large! %d Bytes (max: %d)\n", fldnames[i], num, MAX_ARRAY_SIZE);
            *pno = num = 0;
            status = S_db_errArg;
        } else
            *pval = (char *)callocMustSucceed(*pno, flen,
                "aSubRecord::init_record");

        *pne = *pno;

        if (povl) {
            if (num)
                *povl = (char *)callocMustSucceed(*pno, flen,
                    "aSubRecord::init_record");
            povl++;
        }
    }
    return status;
}
Beispiel #3
0
GPHENTRY * epicsShareAPI gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid)
{
    ELLLIST **paplist;
    ELLLIST *plist;
    GPHENTRY *pgphNode;
    int hash;

    if (pgphPvt == NULL) return NULL;
    paplist = pgphPvt->paplist;
    hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0);
    hash = epicsStrHash(name, hash) & pgphPvt->mask;

    epicsMutexMustLock(pgphPvt->lock);
    plist = paplist[hash];
    if (plist == NULL) {
        plist = callocMustSucceed(1, sizeof(ELLLIST), "gphAdd");
        ellInit(plist);
        paplist[hash] = plist;
    }

    pgphNode = (GPHENTRY *) ellFirst(plist);
    while (pgphNode) {
        if (pvtid == pgphNode->pvtid &&
                strcmp(name, pgphNode->name) == 0) {
            epicsMutexUnlock(pgphPvt->lock);
            return NULL;
        }
        pgphNode = (GPHENTRY *) ellNext((ELLNODE *)pgphNode);
    }

    pgphNode = callocMustSucceed(1, sizeof(GPHENTRY), "gphAdd");
    pgphNode->name = name;
    pgphNode->pvtid = pvtid;
    ellAdd(plist, (ELLNODE *)pgphNode);

    epicsMutexUnlock(pgphPvt->lock);
    return (pgphNode);
}
Beispiel #4
0
void epicsShareAPI gphInitPvt(gphPvt **ppvt, int size)
{
    gphPvt *pgphPvt;

    if (size & (size - 1)) {
        printf("gphInitPvt: %d is not a power of 2\n", size);
        size = DEFAULT_SIZE;
    }

    if (size < MIN_SIZE)
        size = MIN_SIZE;

    if (size > MAX_SIZE)
        size = MAX_SIZE;

    pgphPvt = callocMustSucceed(1, sizeof(gphPvt), "gphInitPvt");
    pgphPvt->size = size;
    pgphPvt->mask = size - 1;
    pgphPvt->paplist = callocMustSucceed(size, sizeof(ELLLIST *), "gphInitPvt");
    pgphPvt->lock = epicsMutexMustCreate();
    *ppvt = pgphPvt;
    return;
}
Beispiel #5
0
dbStateId dbStateCreate(const char *name)
{
    dbStateId id;

    if ((id = dbStateFind(name)))
        return id;

    id = callocMustSucceed(1, sizeof(dbState), "createDbState");
    id->name = epicsStrDup(name);
    id->lock = epicsMutexMustCreate();
    ellAdd(&states, &id->node);

    return id;
}
/* Test re-queueing a job while it is running.
 * Check that a single job won't run concurrently.
 */
static void testreadd(void) {
    epicsThreadPoolConfig conf;
    epicsThreadPool *pool;
    readdPriv *priv=callocMustSucceed(1, sizeof(*priv), "testcleanup priv");
    readdPriv *priv2=callocMustSucceed(1, sizeof(*priv), "testcleanup priv");

    testDiag("testreadd");

    priv->done=epicsEventMustCreate(epicsEventEmpty);
    priv->count=5;
    priv2->done=epicsEventMustCreate(epicsEventEmpty);
    priv2->count=5;

    epicsThreadPoolConfigDefaults(&conf);
    conf.maxThreads = 2;
    testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL);
    if(!pool)
        return;

    testOk1((priv->job=epicsJobCreate(pool, &readdjob, priv))!=NULL);
    testOk1((priv2->job=epicsJobCreate(pool, &readdjob, priv2))!=NULL);

    testOk1(epicsJobQueue(priv->job)==0);
    testOk1(epicsJobQueue(priv2->job)==0);
    epicsEventMustWait(priv->done);
    epicsEventMustWait(priv2->done);

    testOk1(epicsThreadPoolNThreads(pool)==2);
    testDiag("epicsThreadPoolNThreads = %d", epicsThreadPoolNThreads(pool));

    epicsThreadPoolDestroy(pool);
    epicsEventDestroy(priv->done);
    epicsEventDestroy(priv2->done);
    free(priv);
    free(priv2);

}
Beispiel #7
0
void epicsShareAPI iocshRegisterVariable (const iocshVarDef *piocshVarDef)
{
    struct iocshVariable *l, *p, *n;
    int i;
    int found;

    iocshTableLock ();
    while ((piocshVarDef != NULL)
        && (piocshVarDef->name != NULL)
        && (*piocshVarDef->name != '\0')) {
        if (iocshVariableHead == NULL)
            iocshRegister(&varFuncDef,varCallFunc);
        found = 0;
        for (l = NULL, p = iocshVariableHead ; p != NULL ; l = p, p = p->next) {
            i = strcmp (piocshVarDef->name, p->pVarDef->name);
            if (i == 0) {
                errlogPrintf("Warning: iocshRegisterVariable redefining %s.\n",
                    piocshVarDef->name);
                p->pVarDef = piocshVarDef;
                found = 1;
                break;
            }
            if (i < 0)
                break;
        }
        if (!found) {
            n = (struct iocshVariable *) callocMustSucceed(1, sizeof *n,
                "iocshRegisterVariable");
            if (!registryAdd(iocshVarID, piocshVarDef->name, (void *)n)) {
                free(n);
                iocshTableUnlock();
                errlogPrintf("iocshRegisterVariable failed to add %s.\n",
                    piocshVarDef->name);
                return;
            }
            if (l == NULL) {
                n->next = iocshVariableHead;
                iocshVariableHead = n;
            }
            else {
                n->next = l->next;
                l->next = n;
            }
            n->pVarDef = piocshVarDef;
        }
        piocshVarDef++;
    }
    iocshTableUnlock ();
}
epicsShareFunc epicsMessageQueueId epicsShareAPI epicsMessageQueueCreate(
    unsigned int capacity,
    unsigned int maxMessageSize)
{
    epicsMessageQueueId pmsg;
    unsigned int slotBytes, slotLongs;

    assert(capacity != 0);
    pmsg = (epicsMessageQueueId)callocMustSucceed(1, sizeof(*pmsg), "epicsMessageQueueCreate");
    pmsg->capacity = capacity;
    pmsg->maxMessageSize = maxMessageSize;
    slotLongs = 1 + ((maxMessageSize + sizeof(unsigned long) - 1) / sizeof(unsigned long));
    slotBytes = slotLongs * sizeof(unsigned long);
    pmsg->buf = (unsigned long *)callocMustSucceed(pmsg->capacity, slotBytes, "epicsMessageQueueCreate");
    pmsg->inPtr = pmsg->outPtr = pmsg->firstMessageSlot = (char *)&pmsg->buf[0];
    pmsg->lastMessageSlot = (char *)&pmsg->buf[(capacity - 1) * slotLongs];
    pmsg->full = false;
    pmsg->slotSize = slotBytes;
    pmsg->mutex = epicsMutexMustCreate();
    ellInit(&pmsg->sendQueue);
    ellInit(&pmsg->receiveQueue);
    ellInit(&pmsg->eventFreeList);
    return pmsg;
}
Beispiel #9
0
epicsShareFunc void epicsShareAPI errlogAddListener(
    errlogListener listener, void *pPrivate)
{
    listenerNode *plistenerNode;

    errlogInit(0);
    if (pvtData.atExit)
        return;

    plistenerNode = callocMustSucceed(1,sizeof(listenerNode),
        "errlogAddListener");
    epicsMutexMustLock(pvtData.listenerLock);
    plistenerNode->listener = listener;
    plistenerNode->pPrivate = pPrivate;
    ellAdd(&pvtData.listenerList,&plistenerNode->node);
    epicsMutexUnlock(pvtData.listenerLock);
}
Beispiel #10
0
bufRxManager::bufRxManager(const std::string& n, unsigned int qdepth, unsigned int bsize)
  :dataBufRx(n)
  ,guard()
  ,onerror(defaulterr)
  ,onerror_arg(NULL)
  ,m_bsize(bsize ? bsize : 2048)
{
    ellInit(&dispatch);
    ellInit(&freebufs);
    ellInit(&usedbufs);

    CBINIT(&received_cb, priorityMedium, &bufRxManager::received, this);

    for(unsigned int i=0; i<qdepth; i++) {
        buffer *t=(buffer*)callocMustSucceed(1, sizeof(buffer)-1+m_bsize, "bufRxManager buffer");
        ellAdd(&freebufs, &t->node);
    }
}
Beispiel #11
0
// Called by the IOC command "ADC_Ethercat_Sampler"
static void Configure_Sampler(char * port, int channel, char * sample, char * cycle)
{
    sampler_config_t * conf = (sampler_config_t *)callocMustSucceed
        (1, sizeof(sampler_config_t), "can't allocate sampler config buffer");
    if(port == NULL || sample == NULL)
    {
        printf("adc configure error: port %p sample %p\n", port, sample);
        return;
    }
    conf->port = strdup(port);
    conf->channel = channel;
    conf->sample = strdup(sample);
    if(cycle != NULL)
    {
        conf->cycle = strdup(cycle);
    }
    ellAdd(&sampler_configs, &conf->node);
}
epicsShareFunc int testPmacAsynIPPort(const char *portName, int readTimeout)
{
    myData        *pPvt;
    asynUser      *pasynUser;
    asynStatus    status;
    int           addr=0;
    asynInterface *pasynInterface;

    pPvt = (myData *)callocMustSucceed(1, sizeof(myData), "testPmacAsynIPPort");
    pPvt->mutexId = epicsMutexCreate();
    pPvt->portName = epicsStrDup(portName);
    pasynUser = pasynManager->createAsynUser(0,0);
    pasynUser->userPvt = pPvt;
    status = pasynManager->connectDevice(pasynUser,portName,addr);
    if(status!=asynSuccess) {
        printf("testPmacAsynIPPort: can't connect to port %s: %s\n", portName, pasynUser->errorMessage);
        return -1;
    }
    pasynInterface = pasynManager->findInterface(
       pasynUser,asynOctetType,1);
    if(!pasynInterface) {
        printf("testPmacAsynIPPort: %s driver not supported\n",asynOctetType);
        return -1;
    }
    if (readTimeout == 0) 
        pPvt->readTimeout = READ_TIMEOUT;
    else 
        pPvt->readTimeout = (double)readTimeout;
    pPvt->pasynOctet = (asynOctet *)pasynInterface->pinterface;
    pPvt->octetPvt = pasynInterface->drvPvt;
    status = pPvt->pasynOctet->registerInterruptUser(
                 pPvt->octetPvt, pasynUser,
                 connectionCallback,pPvt,&pPvt->registrarPvt);
    if(status!=asynSuccess) {
        printf("testPmacAsynIPPort: devAsynOctet registerInterruptUser %s\n",
               pasynUser->errorMessage);
        return -1;       
    }

    asynPrint(pasynUser,ASYN_TRACE_FLOW, "Done testPmacAsynIPPort OK\n");
    
    testHandler(pPvt);
    return 0;
}
epicsShareFunc epicsMessageQueueId epicsShareAPI
epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize)
{
    rtems_status_code sc;
    epicsMessageQueueId id = (epicsMessageQueueId)callocMustSucceed(1, sizeof(*id), "epicsMessageQueueCreate");
    rtems_interrupt_level level;
    static char c1 = 'a';
    static char c2 = 'a';
    static char c3 = 'a';
    
    sc = rtems_message_queue_create (rtems_build_name ('Q', c3, c2, c1),
        capacity,
        maximumMessageSize,
        RTEMS_FIFO|RTEMS_LOCAL,
        &id->id);
    if (sc != RTEMS_SUCCESSFUL) {
        errlogPrintf ("Can't create message queue: %s\n", rtems_status_text (sc));
        return NULL;
    }
    id->maxSize = maximumMessageSize;
    id->localBuf = NULL;
    rtems_interrupt_disable (level);
    if (c1 == 'z') {
        if (c2 == 'z') {
            if (c3 == 'z') {
                c3 = 'a';
            }
            else {
                c3++;
            }
            c2 = 'a';
        }
        else {
            c2++;
        }
        c1 = 'a';
    }
    else {
        c1++;
    }
    rtems_interrupt_enable (level);
    return id;
}
Beispiel #14
0
/** Constructor for NDPluginOverlay; most parameters are simply passed to NDPluginDriver::NDPluginDriver.
  * After calling the base class constructor this method sets reasonable default values for all of the
  * ROI parameters.
  * \param[in] portName The name of the asyn port driver to be created.
  * \param[in] queueSize The number of NDArrays that the input queue for this plugin can hold when
  *            NDPluginDriverBlockingCallbacks=0.  Larger queues can decrease the number of dropped arrays,
  *            at the expense of more NDArray buffers being allocated from the underlying driver's NDArrayPool.
  * \param[in] blockingCallbacks Initial setting for the NDPluginDriverBlockingCallbacks flag.
  *            0=callbacks are queued and executed by the callback thread; 1 callbacks execute in the thread
  *            of the driver doing the callbacks.
  * \param[in] NDArrayPort Name of asyn port driver for initial source of NDArray callbacks.
  * \param[in] NDArrayAddr asyn port driver address for initial source of NDArray callbacks.
  * \param[in] maxOverlays The maximum number ofoverlays this plugin supports. 1 is minimum.
  * \param[in] maxBuffers The maximum number of NDArray buffers that the NDArrayPool for this driver is
  *            allowed to allocate. Set this to -1 to allow an unlimited number of buffers.
  * \param[in] maxMemory The maximum amount of memory that the NDArrayPool for this driver is
  *            allowed to allocate. Set this to -1 to allow an unlimited amount of memory.
  * \param[in] priority The thread priority for the asyn port driver thread if ASYN_CANBLOCK is set in asynFlags.
  * \param[in] stackSize The stack size for the asyn port driver thread if ASYN_CANBLOCK is set in asynFlags.
  */
NDPluginOverlay::NDPluginOverlay(const char *portName, int queueSize, int blockingCallbacks,
                         const char *NDArrayPort, int NDArrayAddr, int maxOverlays,
                         int maxBuffers, size_t maxMemory,
                         int priority, int stackSize)
    /* Invoke the base class constructor */
    : NDPluginDriver(portName, queueSize, blockingCallbacks,
                   NDArrayPort, NDArrayAddr, maxOverlays, NUM_NDPLUGIN_OVERLAY_PARAMS, maxBuffers, maxMemory,
                   asynGenericPointerMask,
                   asynGenericPointerMask,
                   ASYN_MULTIDEVICE, 1, priority, stackSize)
{
    static const char *functionName = "NDPluginOverlay";


    this->maxOverlays = maxOverlays;
    this->pOverlays = (NDOverlay_t *)callocMustSucceed(maxOverlays, sizeof(*this->pOverlays), functionName);

    createParam(NDPluginOverlayMaxSizeXString,      asynParamInt32, &NDPluginOverlayMaxSizeX);
    createParam(NDPluginOverlayMaxSizeYString,      asynParamInt32, &NDPluginOverlayMaxSizeY);
    createParam(NDPluginOverlayNameString,          asynParamOctet, &NDPluginOverlayName);
    createParam(NDPluginOverlayUseString,           asynParamInt32, &NDPluginOverlayUse);
    createParam(NDPluginOverlayPositionXString,     asynParamInt32, &NDPluginOverlayPositionX);
    createParam(NDPluginOverlayPositionYString,     asynParamInt32, &NDPluginOverlayPositionY);
    createParam(NDPluginOverlaySizeXString,         asynParamInt32, &NDPluginOverlaySizeX);
    createParam(NDPluginOverlaySizeYString,         asynParamInt32, &NDPluginOverlaySizeY);
    createParam(NDPluginOverlayWidthXString,        asynParamInt32, &NDPluginOverlayWidthX);
    createParam(NDPluginOverlayWidthYString,        asynParamInt32, &NDPluginOverlayWidthY);
    createParam(NDPluginOverlayShapeString,         asynParamInt32, &NDPluginOverlayShape);
    createParam(NDPluginOverlayDrawModeString,      asynParamInt32, &NDPluginOverlayDrawMode);
    createParam(NDPluginOverlayRedString,           asynParamInt32, &NDPluginOverlayRed);
    createParam(NDPluginOverlayGreenString,         asynParamInt32, &NDPluginOverlayGreen);
    createParam(NDPluginOverlayBlueString,          asynParamInt32, &NDPluginOverlayBlue);
    createParam(NDPluginOverlayTimeStampFormatString, asynParamOctet, &NDPluginOverlayTimeStampFormat);
    createParam(NDPluginOverlayFontString,          asynParamInt32, &NDPluginOverlayFont);
    createParam(NDPluginOverlayDisplayTextString,   asynParamOctet, &NDPluginOverlayDisplayText);      

    /* Set the plugin type string */
    setStringParam(NDPluginDriverPluginType, "NDPluginOverlay");

    /* Try to connect to the array port */
    connectToArrayPort();
}
Beispiel #15
0
int testDone(void) {
    int status = 0;
    
    epicsMutexMustLock(testLock);
    if (perlHarness) {
	if (!planned) printf("1..%d\n", tested);
    } else {
	if (planned && tested > planned) {
	    printf("\nRan %d tests but only planned for %d!\n", tested, planned);
	    status = 2;
	} else if (planned && tested < planned) {
	    printf("\nPlanned %d tests but only ran %d\n", planned, tested);
	    status = 2;
	}
	printf("\n    Results\n    =======\n       Tests: %-3d\n", tested);
	if (tested) {
	    testResult("Passed", passed);
	    if (bonus) testResult("Todo Passes", bonus);
	    if (failed) {
		testResult("Failed", failed);
		status = 1;
	    }
	    if (skipped) testResult("Skipped", skipped);
	}
    }
    if (Harness) {
        if (failed) {
            testFailure *fault = callocMustSucceed(1, sizeof(testFailure),
                "testDone calloc");
            fault->name     = testing;
            fault->tests    = tested;
            fault->failures = failed;
            fault->skips    = skipped;
            ellAdd(&faults, &fault->node);
        }
        Programs++;
        Tests += tested;
    }
    epicsMutexUnlock(testLock);
    return (status);
}
int XPSInterpose(const char *portName)
{
    XPSInterposePvt *pPvt;
    asynInterface *drvUserPrev;
    asynStatus status;

    pPvt = callocMustSucceed(1, sizeof(*pPvt), "XPSInterpose");
    pPvt->portName = epicsStrDup(portName);

    pPvt->drvUser.interfaceType = asynDrvUserType;
    pPvt->drvUser.pinterface  = (void *)&XPSDrvUser;
    pPvt->drvUser.drvPvt = pPvt;

    status = pasynManager->interposeInterface(portName, -1, &pPvt->drvUser, &drvUserPrev);
    if (status != asynSuccess) {
        errlogPrintf("XPSInterpose ERROR: calling interpose interface.\n");
        return -1;
    }
    pPvt->drvUserPrev = drvUserPrev->pinterface;
    pPvt->drvUserPrevPvt = drvUserPrev->drvPvt;
    return(asynSuccess);
}
Beispiel #17
0
static long createRingBuffer(dbCommon *pr)
{
    devPvt *pPvt = (devPvt *)pr->dpvt;
    asynStatus status;
    const char *sizeString;
    
    if (!pPvt->ringBuffer) {
        DBENTRY *pdbentry = dbAllocEntry(pdbbase);
        pPvt->ringSize = DEFAULT_RING_BUFFER_SIZE;
        status = dbFindRecord(pdbentry, pr->name);
        if (status) {
            asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR,
                "%s devAsynFloat64::createRingBufffer error finding record\n",
                pr->name);
            return -1;
        }
        sizeString = dbGetInfo(pdbentry, "asyn:FIFO");
        if (sizeString) pPvt->ringSize = atoi(sizeString);
        pPvt->ringBuffer = callocMustSucceed(pPvt->ringSize+1, sizeof *pPvt->ringBuffer, "devAsynFloat64::createRingBuffer");
    }
    return asynSuccess;
}
Beispiel #18
0
epicsMutexOSD * epicsMutexOsdCreate(void) {
    epicsMutexOSD *pmutex;
    int status;

    pmutex = callocMustSucceed(1, sizeof(*pmutex), "epicsMutexOsdCreate");
    status = pthread_mutexattr_init(&pmutex->mutexAttr);
    checkStatusQuit(status,"pthread_mutexattr_init", "epicsMutexOsdCreate");

#if defined _POSIX_THREAD_PRIO_INHERIT
    status = pthread_mutexattr_setprotocol(&pmutex->mutexAttr,
        PTHREAD_PRIO_INHERIT);
    if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocal");
#endif /*_POSIX_THREAD_PRIO_INHERIT*/

    status = pthread_mutexattr_settype(&pmutex->mutexAttr,
        PTHREAD_MUTEX_RECURSIVE);
    if (errVerbose) checkStatus(status, "pthread_mutexattr_settype");

    status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr);
    checkStatusQuit(status, "pthread_mutex_init", "epicsMutexOsdCreate");
    return pmutex;
}
Beispiel #19
0
static long init_record(waveformRecord *prec, int pass)
{
    struct wfdset *pdset;

    if (pass==0) {
        if (prec->nelm <= 0)
            prec->nelm = 1;
        if (prec->ftvl > DBF_ENUM)
            prec->ftvl = DBF_UCHAR;
        prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl),
                                       "waveform calloc failed");
        if (prec->nelm == 1) {
            prec->nord = 1;
        } else {
            prec->nord = 0;
        }
        return 0;
    }

    /* wf.siml must be a CONSTANT or a PV_LINK or a DB_LINK */
    if (prec->siml.type == CONSTANT) {
        recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
    }

    /* must have dset defined */
    if (!(pdset = (struct wfdset *)(prec->dset))) {
        recGblRecordError(S_dev_noDSET,(void *)prec,"wf: init_record");
        return S_dev_noDSET;
    }
    /* must have read_wf function defined */
    if ((pdset->number < 5) || (pdset->read_wf == NULL)) {
        recGblRecordError(S_dev_missingSup,(void *)prec,"wf: init_record");
        return S_dev_missingSup;
    }
    if (! pdset->init_record) return 0;

    return (*pdset->init_record)(prec);
}
Beispiel #20
0
/*
 * Register a command
 */
void epicsShareAPI iocshRegister (const iocshFuncDef *piocshFuncDef,
    iocshCallFunc func)
{
    struct iocshCommand *l, *p, *n;
    int i;

    iocshTableLock ();
    for (l = NULL, p = iocshCommandHead ; p != NULL ; l = p, p = p->next) {
        i = strcmp (piocshFuncDef->name, p->pFuncDef->name);
        if (i == 0) {
            p->pFuncDef = piocshFuncDef;
            p->func = func;
            iocshTableUnlock ();
            return;
        }
        if (i < 0)
            break;
    }
    n = (struct iocshCommand *) callocMustSucceed (1, sizeof *n,
        "iocshRegister");
    if (!registryAdd(iocshCmdID, piocshFuncDef->name, (void *)n)) {
        free (n);
        iocshTableUnlock ();
        errlogPrintf ("iocshRegister failed to add %s\n", piocshFuncDef->name);
        return;
    }
    if (l == NULL) {
        n->next = iocshCommandHead;
        iocshCommandHead = n;
    }
    else {
        n->next = l->next;
        l->next = n;
    }
    n->pFuncDef = piocshFuncDef;
    n->func = func;
    iocshTableUnlock ();
}
/****************************************************************************
 * Define public interface methods
 ****************************************************************************/
int drvAsynCoherentSDG(const char* myport,const char* ioport,int ioaddr)
{
    Port* pport;
    int len,i,j,eomReason;
    char inpBuf[BUFFER_SIZE];
    asynUser* pasynUser;
    asynOctet* pasynOctet;
    asynFloat64* pasynFloat64;
    asynUInt32Digital* pasynUInt32;

    if( pports )
    {
        printf("drvAsynCoherentSDG:init %s: interface already established\n",myport);
        return( -1 );
    }

    if( pasynOctetSyncIO->connect(ioport,ioaddr,&pasynUser,NULL) )
    {
        printf("drvAsynCoherentSDG:init %s: cannot connect to asyn port %s\n",myport,ioport);
        return( -1 );
    }

    i = strlen(myport)+1;
    j = strlen(ioport)+1;

    len = i+j+sizeof(Port)+sizeof(asynFloat64)+sizeof(asynUInt32Digital)+sizeof(asynOctet);
    pport = (Port*)callocMustSucceed(len,sizeof(char),"drvAsynCoherentSDG");

    pasynUInt32   = (asynUInt32Digital*)(pport + 1);
    pasynFloat64  = (asynFloat64*)(pasynUInt32 + 1);
    pasynOctet    = (asynOctet*)(pasynFloat64 + 1);
    pport->myport = (char*)(pasynOctet + 1);
    pport->ioport = (char*)(pport->myport + i);

    pport->ioaddr    = ioaddr;
    pport->pasynUser = pasynUser;
    pport->syncLock  = epicsMutexMustCreate();
    strcpy(pport->myport,myport);
    strcpy(pport->ioport,ioport);

    if( pasynManager->registerPort(myport,ASYN_MULTIDEVICE|ASYN_CANBLOCK,1,0,0) )
    {
        printf("drvAsynCoherentSDG::init %s: failure to register port\n",myport);

        return( -1 );
    }

    pport->asynCommon.interfaceType = asynCommonType;
    pport->asynCommon.pinterface = &common;
    pport->asynCommon.drvPvt = pport;

    if( pasynManager->registerInterface(myport,&pport->asynCommon) )
    {
        printf("drvAsynCoherentSDG::init %s: failure to register asynCommon\n",myport);

        return( -1 );
    }

    pport->asynDrvUser.interfaceType = asynDrvUserType;
    pport->asynDrvUser.pinterface = &drvuser;
    pport->asynDrvUser.drvPvt = pport;

    if( pasynManager->registerInterface(myport,&pport->asynDrvUser) )
    {
        printf("drvAsynCoherentSDG::init %s: failure to register asynDrvUser\n",myport);

        return( -1 );
    }

    pasynFloat64->read = readFloat64;
    pasynFloat64->write = writeFloat64;
    pport->asynFloat64.interfaceType = asynFloat64Type;
    pport->asynFloat64.pinterface = pasynFloat64;
    pport->asynFloat64.drvPvt = pport;

    if( pasynFloat64Base->initialize(myport,&pport->asynFloat64) )
    {
        printf("drvAsynCoherentSDG::init %s: failure to initialize asynFloat64Base\n",myport);

        return( -1 );
    }

    pasynUInt32->read = readUInt32;
    pasynUInt32->write = writeUInt32;
    pport->asynUInt32.interfaceType = asynUInt32DigitalType;
    pport->asynUInt32.pinterface = pasynUInt32;
    pport->asynUInt32.drvPvt = pport;

    if( pasynUInt32DigitalBase->initialize(myport,&pport->asynUInt32) )
    {
        printf("drvAsynCoherentSDG::init %s: failure to initialize asynUInt32DigitalBase\n",myport);

        return( -1 );
    }

    pasynOctet->flush = flushOctet;
    pasynOctet->read  = readOctet;
    pasynOctet->write = writeOctet;
    pport->asynOctet.drvPvt = pport;
    pport->asynOctet.pinterface = pasynOctet;
    pport->asynOctet.interfaceType = asynOctetType;

    if( pasynOctetBase->initialize(myport,&pport->asynOctet,0,0,0) )
    {
        printf("drvAsynCoherentSDG::init %s: failure to initialize asynOctetBase\n",myport);

        return( -1 );
    }

    /* Status query */
    if( writeRead(pport,pasynUser,"status?",inpBuf,sizeof(inpBuf),&eomReason) )
    {
        printf("drvAsynCoherentSDG::init %s: failure to acquire status\n",myport);
        strcpy(pport->ident,"*COMM FAILED*");

        return( -1 );
    }
    else
        strcpy(pport->ident,"Coherent SDG");

    /* Complete initialization */
    pport->init=1;
    for( i=0; i<commandLen; ++i ) commandTable[i].pport=pport;

    pports = pport;
    return( 0 );
}
Beispiel #22
0
static long initCommon(dbCommon *pr, DBLINK *plink,
    userCallback processCallback,interruptCallbackFloat64 interruptCallback)
{
    devPvt *pPvt;
    asynStatus status;
    asynUser *pasynUser;
    asynInterface *pasynInterface;

    pPvt = callocMustSucceed(1, sizeof(*pPvt), "devAsynFloat64::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->parseLink(pasynUser, plink,
                &pPvt->portName, &pPvt->addr,&pPvt->userParam);
    if (status != asynSuccess) {
        printf("%s devAsynFloat64::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 devAsynFloat64::initCommon connectDevice failed %s\n",
                     pr->name, pasynUser->errorMessage);
        goto bad;
    }
    status = pasynManager->canBlock(pPvt->pasynUser, &pPvt->canBlock);
    if (status != asynSuccess) {
        printf("%s devAsynFloat64::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 devAsynFloat64::initCommon drvUserCreate %s\n",
                     pr->name, pasynUser->errorMessage);
            goto bad;
        }
    }
    /* Get interface asynFloat64 */
    pasynInterface = pasynManager->findInterface(pasynUser, asynFloat64Type, 1);
    if (!pasynInterface) {
        printf("%s devAsynFloat64::initCommon findInterface asynFloat64Type %s\n",
                     pr->name,pasynUser->errorMessage);
        goto bad;
    }
    pPvt->pfloat64 = pasynInterface->pinterface;
    pPvt->float64Pvt = pasynInterface->drvPvt;

    /* Initialize synchronous interface */
    status = pasynFloat64SyncIO->connect(pPvt->portName, pPvt->addr,
                 &pPvt->pasynUserSync, pPvt->userParam);
    if (status != asynSuccess) {
        printf("%s devAsynFloat64::initCommon Float64SyncIO->connect failed %s\n",
               pr->name, pPvt->pasynUserSync->errorMessage);
        goto bad;
    }

    scanIoInit(&pPvt->ioScanPvt);
    pPvt->interruptCallback = interruptCallback;

    /* 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 devAsynFloat64::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->pfloat64->registerInterruptUser(
               pPvt->float64Pvt,pPvt->pasynUser,
               pPvt->interruptCallback,pPvt,&pPvt->registrarPvt);
            if(status!=asynSuccess) {
                printf("%s devAsynFloat64::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;
}
int AIMConfig(
    const char *portName, int address, int port, int maxChans,
    int maxSignals, int maxSequences, char *ethernetDevice)
{
    unsigned char enet_address[6];
    int status;
    int retries = 0;
    mcaAIMPvt *pPvt;

    pPvt = callocMustSucceed(1, sizeof(mcaAIMPvt), "AIMConfig");
    status = nmc_initialize(ethernetDevice);
    if (status != 0) {
        errlogPrintf("AIMConfig: nmc_initialize failed for device %s status=%d\n",
                     ethernetDevice, status);
        return(ERROR);
    }

    /* Copy parameters to object private */
    pPvt->exists = 1;
    pPvt->maxChans = maxChans;
    pPvt->nchans = maxChans;
    pPvt->maxSignals = maxSignals;
    pPvt->maxSequences = maxSequences;
    /* Copy the module ADC port number. Subtract 1 to convert from */
    /* user units to device units  */
    pPvt->adc = port - 1;
    /* Set reasonable defaults for other parameters */
    pPvt->plive   = 0;
    pPvt->preal   = 0;
    pPvt->ptotal  = 0;
    pPvt->ptschan = 0;
    pPvt->ptechan = 0;
    pPvt->acqmod  = 1;
    pPvt->acquiring = 0;
    
    /* Maximum time to use old status info before a new query is sent. Only used 
     * if signal!=0, typically with multiplexors. 0.1 seconds  */
    pPvt->maxStatusTime = 0.1;
    /* Compute the module Ethernet address */
    nmc_build_enet_addr(address, enet_address);

    /* Find the particular module on the net - may have to retry in case
       the module database is still being built after initialisation.
       This is not possible to resolve other than by waiting, since there are
       an unknown number of modules on the local subnet, and they can reply
       to the initial inquiry broadcast in an arbitrary order. */
    do {
	status = nmc_findmod_by_addr(&pPvt->module, enet_address);
	epicsThreadSleep(0.1);
    } while ((status != OK) && (retries++ < 5));

    if (status != OK) {
        errlogPrintf("AIMConfig ERROR: cannot find module on the network!\n");
        return (ERROR);
    }

    /* Buy the module (make this IOC own it) */
    status = nmc_buymodule(pPvt->module, 0);
    if (status != OK) {
        errlogPrintf("AIMConfig ERROR: cannot buy module, someone else owns it!\n");
        return (ERROR);
    }

    /* Allocate memory in the AIM, get base address */
    status = nmc_allocate_memory(pPvt->module,
                    pPvt->maxChans * pPvt->maxSignals * pPvt->maxSequences * 4,
                    &pPvt->base_address);
    if (status != OK) {
        errlogPrintf("AIMConfig ERROR: cannot allocate required memory in AIM\n");
        return (ERROR);
    }
    pPvt->seq_address = pPvt->base_address;

    pPvt->ethernetDevice = epicsStrDup(ethernetDevice);
    pPvt->portName = epicsStrDup(portName);

    /*
     *  Link with higher level routines
     */
    pPvt->common.interfaceType = asynCommonType;
    pPvt->common.pinterface  = (void *)&mcaAIMCommon;
    pPvt->common.drvPvt = pPvt;
    pPvt->int32.interfaceType = asynInt32Type;
    pPvt->int32.pinterface  = (void *)&mcaAIMInt32;
    pPvt->int32.drvPvt = pPvt;
    pPvt->float64.interfaceType = asynFloat64Type;
    pPvt->float64.pinterface  = (void *)&mcaAIMFloat64;
    pPvt->float64.drvPvt = pPvt;
    pPvt->int32Array.interfaceType = asynInt32ArrayType;
    pPvt->int32Array.pinterface  = (void *)&mcaAIMInt32Array;
    pPvt->int32Array.drvPvt = pPvt;
    pPvt->drvUser.interfaceType = asynDrvUserType;
    pPvt->drvUser.pinterface  = (void *)&mcaAIMDrvUser;
    pPvt->drvUser.drvPvt = pPvt;
    status = pasynManager->registerPort(pPvt->portName,
                                        ASYN_MULTIDEVICE | ASYN_CANBLOCK,
                                        1,  /* autoconnect */
                                        0,  /* medium priority */
                                        0); /* default stacksize */
    if (status != asynSuccess) {
        errlogPrintf("AIMConfig ERROR: Can't register myself.\n");
        return -1;
    }
    status = pasynManager->registerInterface(pPvt->portName, &pPvt->common);
    if (status != asynSuccess) {
        errlogPrintf("AIMConfig: Can't register common.\n");
        return -1;
    }
    status = pasynInt32Base->initialize(pPvt->portName, &pPvt->int32);
    if (status != asynSuccess) {
        errlogPrintf("AIMConfig: Can't register int32.\n");
        return -1;
    }

    status = pasynFloat64Base->initialize(pPvt->portName, &pPvt->float64);
    if (status != asynSuccess) {
        errlogPrintf("AIMConfig: Can't register float64.\n");
        return -1;
    }

    status = pasynInt32ArrayBase->initialize(pPvt->portName, &pPvt->int32Array);
    if (status != asynSuccess) {
        errlogPrintf("AIMConfig: Can't register int32Array.\n");
        return -1;
    }

    status = pasynManager->registerInterface(pPvt->portName,&pPvt->drvUser);
    if (status != asynSuccess) {
        errlogPrintf("AIMConfig ERROR: Can't register drvUser\n");
        return -1;
    }
    return(0);
}
static long init_record(mbbiDirectRecord *pmbbiDirect)
{
  struct link *plink = &pmbbiDirect->inp;
  int size;
  char *buf;
  char *pC;
  F3RP61_MBBIDIRECT_DPVT *dpvt;
  M3IO_ACCESS_COM *pacom;
  M3IO_ACCESS_REG *pdrly;
  int unitno, slotno, cpuno, start;
  char device;

  if (pmbbiDirect->inp.type != INST_IO) {
    recGblRecordError(S_db_badField,(void *)pmbbiDirect,
                      "devMbbiDirectF3RP61 (init_record) Illegal INP field");
    pmbbiDirect->pact = 1;
    return(S_db_badField);
  }

  size = strlen(plink->value.instio.string) + 1;
  buf = (char *) callocMustSucceed(size, sizeof(char), "calloc failed");
  strncpy(buf, plink->value.instio.string, size);
  buf[size - 1] = '\0';

  pC = strchr(buf, ':');
  if (pC) {
    *pC++ = '\0';
    if (sscanf(pC, "U%d,S%d,X%d", &unitno, &slotno, &start) < 3) {
      errlogPrintf("devMbbiDirectF3RP61: can't get interrupt source address for %s\n",
                   pmbbiDirect->name);
      pmbbiDirect->pact = 1;
      return (-1);
    }
    if (f3rp61_register_io_interrupt((dbCommon *) pmbbiDirect, unitno, slotno, start) < 0) {
      errlogPrintf("devMbbiDirectF3RP61: can't register I/O interrupt for %s\n",
                   pmbbiDirect->name);
      pmbbiDirect->pact = 1;
      return (-1);
    }
  }
  if (sscanf(buf, "U%d,S%d,%c%d", &unitno, &slotno, &device, &start) < 4) {
    if (sscanf(buf, "CPU%d,R%d", &cpuno, &start) < 2) {
      if (sscanf(buf, "%c%d", &device, &start) < 2) {
        errlogPrintf("devMbbiDirectF3RP61: can't get I/O address for %s\n", pmbbiDirect->name);
        pmbbiDirect->pact = 1;
        return (-1);
      }
      else if (device != 'W' && device != 'L' && device != 'R' && device != 'E') {
        errlogPrintf("devMbbiDirectF3RP61: unsupported device \'%c\' for %s\n", device,
                     pmbbiDirect->name);
        pmbbiDirect->pact = 1;
        return (-1);
      }
    }
    else {
      device = 'r';
    }
  }

  if (!(device == 'X' || device == 'Y' || device == 'A' || device == 'r' ||
        device == 'W' || device == 'L' || device == 'M' || device == 'R' ||
        device == 'E')) {
    errlogPrintf("devMbbiDirectF3RP61: illegal I/O address for %s\n",
                 pmbbiDirect->name);
    pmbbiDirect->pact = 1;
    return (-1);
  }

  dpvt = (F3RP61_MBBIDIRECT_DPVT *) callocMustSucceed(1,
                                                      sizeof(F3RP61_MBBIDIRECT_DPVT),
                                                      "calloc failed");
  dpvt->device = device;

  if (device == 'r') {
    pacom = &dpvt->u.acom;
    pacom->cpuno = (unsigned short) cpuno;
    pacom->start = (unsigned short) start;
    pacom->count = (unsigned short) 1;
  }
  else if (device == 'W' || device == 'L' || device == 'R' || device == 'E') {
    pacom = &dpvt->u.acom;
    pacom->start = (unsigned short) start;
  }
  else {
    pdrly = &dpvt->u.drly;
    pdrly->unitno = (unsigned short) unitno;
    pdrly->slotno = (unsigned short) slotno;
    pdrly->start = (unsigned short) start;
    pdrly->count = (unsigned short) 1;
  }

  pmbbiDirect->dpvt = dpvt;

  return(0);
}
Beispiel #25
0
/*
 * Configure and register a generic serial device
 */
epicsShareFunc int
drvAsynSerialPortConfigure(char *portName,
                     char *ttyName,
                     unsigned int priority,
                     int noAutoConnect,
                     int noProcessEos)
{
    ttyController_t *tty;
    asynStatus status;


    /*
     * Check arguments
     */
    if (portName == NULL) {
        printf("Port name missing.\n");
        return -1;
    }
    if (ttyName == NULL) {
        printf("TTY name missing.\n");
        return -1;
    }

    if(!pserialBase) serialBaseInit();
    /*
     * Create a driver
     */
    tty = (ttyController_t *)callocMustSucceed(1, sizeof(*tty), "drvAsynSerialPortConfigure()");

    /*
     * Create timeout mechanism
     */
     tty->timer = epicsTimerQueueCreateTimer(
         pserialBase->timerQueue, timeoutHandler, tty);
     if(!tty->timer) {
        printf("drvAsynSerialPortConfigure: Can't create timer.\n");
        return -1;
    }
    tty->fd = -1;
    tty->serialDeviceName = epicsStrDup(ttyName);
    tty->portName = epicsStrDup(portName);

    /*
     * Set defaults
     */
    tty->termios.c_cflag = CS8 | CLOCAL | CREAD;
    tty->baud = 9600;
#ifndef vxWorks
    tty->termios.c_iflag = IGNBRK | IGNPAR;
    tty->termios.c_oflag = 0;
    tty->termios.c_lflag = 0;
    tty->termios.c_cc[VMIN] = 0;
    tty->termios.c_cc[VTIME] = 0;
    tty->termios.c_cc[VSTOP]  = 0x13; /* ^S */
    tty->termios.c_cc[VSTART] = 0x11; /* ^Q */

    cfsetispeed(&tty->termios, B9600);
    cfsetospeed(&tty->termios, B9600);
#endif

    /*
     *  Link with higher level routines
     */
    tty->common.interfaceType = asynCommonType;
    tty->common.pinterface  = (void *)&asynCommonMethods;
    tty->common.drvPvt = tty;
    tty->option.interfaceType = asynOptionType;
    tty->option.pinterface  = (void *)&asynOptionMethods;
    tty->option.drvPvt = tty;
    if (pasynManager->registerPort(tty->portName,
                                   ASYN_CANBLOCK,
                                   !noAutoConnect,
                                   priority,
                                   0) != asynSuccess) {
        printf("drvAsynSerialPortConfigure: Can't register myself.\n");
        ttyCleanup(tty);
        return -1;
    }
    status = pasynManager->registerInterface(tty->portName,&tty->common);
    if(status != asynSuccess) {
        printf("drvAsynSerialPortConfigure: Can't register common.\n");
        ttyCleanup(tty);
        return -1;
    }
    status = pasynManager->registerInterface(tty->portName,&tty->option);
    if(status != asynSuccess) {
        printf("drvAsynSerialPortConfigure: Can't register option.\n");
        ttyCleanup(tty);
        return -1;
    }
    tty->octet.interfaceType = asynOctetType;
    tty->octet.pinterface  = &asynOctetMethods;
    tty->octet.drvPvt = tty;
    status = pasynOctetBase->initialize(tty->portName,&tty->octet,
                             (noProcessEos ? 0 : 1),(noProcessEos ? 0 : 1),1);
    if(status != asynSuccess) {
        printf("drvAsynSerialPortConfigure: Can't register octet.\n");
        ttyCleanup(tty);
        return -1;
    }
    tty->pasynUser = pasynManager->createAsynUser(0,0);
    status = pasynManager->connectDevice(tty->pasynUser,tty->portName,-1);
    if(status != asynSuccess) {
        printf("connectDevice failed %s\n",tty->pasynUser->errorMessage);
        ttyCleanup(tty);
        return -1;
    }
    return 0;
}
Beispiel #26
0
static long initCommon(dbCommon *pr, DBLINK *plink,
    userCallback processCallback,interruptCallbackInt32 interruptCallback)
{
    devInt32Pvt *pPvt;
    asynStatus status;
    asynUser *pasynUser;
    asynInterface *pasynInterface;
    epicsUInt32 mask=0;
    int nbits;

    pPvt = callocMustSucceed(1, sizeof(*pPvt), "devAsynInt32::initCommon");
    pr->dpvt = pPvt;
    pPvt->pr = pr;
    /* Create asynUser */
    pasynUser = pasynManager->createAsynUser(processCallback, 0);
    pasynUser->userPvt = pPvt;
    pPvt->pasynUser = pasynUser;
    pPvt->mutexId = epicsMutexCreate();
 
    /* Parse the link to get addr and port */
    /* We accept 2 different link syntax (@asyn(...) and @asynMask(...)
     * If parseLink returns an error then try parseLinkMask. */
    status = pasynEpicsUtils->parseLink(pasynUser, plink, 
                &pPvt->portName, &pPvt->addr, &pPvt->userParam);
    if (status != asynSuccess) {
        status = pasynEpicsUtils->parseLinkMask(pasynUser, plink, 
                &pPvt->portName, &pPvt->addr, &mask, &pPvt->userParam);
    }
    if (status != asynSuccess) {
        printf("%s devAsynInt32::initCommon  %s\n",
                     pr->name, pasynUser->errorMessage);
        goto bad;
    }
    
    /* Parse nbits if it was specified */
    nbits = (int)mask;
    if (nbits) {
        if (nbits < 0) {
            nbits = -nbits;
            pPvt->bipolar = 1;
        }
        pPvt->signBit = (epicsInt32) ldexp(1.0, nbits-1);
        pPvt->mask = pPvt->signBit*2 - 1;
        if (pPvt->bipolar) {
            pPvt->deviceLow = ~(pPvt->mask/2)+1;
            pPvt->deviceHigh = (pPvt->mask/2);
        } else {
            pPvt->deviceLow = 0;
            pPvt->deviceHigh = pPvt->mask;
        }
    }
            
    /* Connect to device */
    status = pasynManager->connectDevice(pasynUser, pPvt->portName, pPvt->addr);
    if (status != asynSuccess) {
        printf("%s devAsynInt32::initCommon connectDevice failed %s\n",
                     pr->name, pasynUser->errorMessage);
        goto bad;
    }
    status = pasynManager->canBlock(pPvt->pasynUser, &pPvt->canBlock);
    if (status != asynSuccess) {
        printf("%s devAsynInt32::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 devAsynInt32::initCommon drvUserCreate %s\n",
                     pr->name, pasynUser->errorMessage);
            goto bad;
        }
    }
    /* Get interface asynInt32 */
    pasynInterface = pasynManager->findInterface(pasynUser, asynInt32Type, 1);
    if (!pasynInterface) {
        printf("%s devAsynInt32::initCommon findInterface asynInt32Type %s\n",
                     pr->name,pasynUser->errorMessage);
        goto bad;
    }
    pPvt->pint32 = pasynInterface->pinterface;
    pPvt->int32Pvt = pasynInterface->drvPvt;
    scanIoInit(&pPvt->ioScanPvt);
    pPvt->interruptCallback = interruptCallback;
    /* Initialize synchronous interface */
    status = pasynInt32SyncIO->connect(pPvt->portName, pPvt->addr, 
                 &pPvt->pasynUserSync, pPvt->userParam);
    if (status != asynSuccess) {
        printf("%s devAsynInt32::initCommon Int32SyncIO->connect failed %s\n",
               pr->name, pPvt->pasynUserSync->errorMessage);
        goto bad;
    }
    return 0;
bad:
   pr->pact=1;
   return -1;
}
/*
 * Configure and register a generic serial device
 */
epicsShareFunc int
drvAsynSerialPortConfigure(char *portName,
                     char *ttyName,
                     unsigned int priority,
                     int noAutoConnect,
                     int noProcessEos)
{
    ttyController_t *tty;
    asynStatus status;


    /*
     * Check arguments
     */
    if (portName == NULL) {
        printf("Port name missing.\n");
        return -1;
    }
    if (ttyName == NULL) {
        printf("TTY name missing.\n");
        return -1;
    }

    if(!pserialBase) serialBaseInit();
    /*
     * Create a driver
     */
    tty = (ttyController_t *)callocMustSucceed(1, sizeof(*tty), "drvAsynSerialPortConfigure()");

    /*
     * Create timeout mechanism
     */
     tty->timer = epicsTimerQueueCreateTimer(
         pserialBase->timerQueue, timeoutHandler, tty);
     if(!tty->timer) {
        printf("drvAsynSerialPortConfigure: Can't create timer.\n");
        return -1;
    }
    tty->commHandle = INVALID_HANDLE_VALUE;
    tty->serialDeviceName = epicsStrDup(ttyName);
    tty->portName = epicsStrDup(portName);

    /*
     *  Link with higher level routines
     */
    tty->common.interfaceType = asynCommonType;
    tty->common.pinterface  = (void *)&asynCommonMethods;
    tty->common.drvPvt = tty;
    tty->option.interfaceType = asynOptionType;
    tty->option.pinterface  = (void *)&asynOptionMethods;
    tty->option.drvPvt = tty;
    if (pasynManager->registerPort(tty->portName,
                                   ASYN_CANBLOCK,
                                   !noAutoConnect,
                                   priority,
                                   0) != asynSuccess) {
        printf("drvAsynSerialPortConfigure: Can't register myself.\n");
        ttyCleanup(tty);
        return -1;
    }
    status = pasynManager->registerInterface(tty->portName,&tty->common);
    if(status != asynSuccess) {
        printf("drvAsynSerialPortConfigure: Can't register common.\n");
        ttyCleanup(tty);
        return -1;
    }
    status = pasynManager->registerInterface(tty->portName,&tty->option);
    if(status != asynSuccess) {
        printf("drvAsynSerialPortConfigure: Can't register option.\n");
        ttyCleanup(tty);
        return -1;
    }
    tty->octet.interfaceType = asynOctetType;
    tty->octet.pinterface  = &asynOctetMethods;
    tty->octet.drvPvt = tty;
    status = pasynOctetBase->initialize(tty->portName,&tty->octet,
                             (noProcessEos ? 0 : 1),(noProcessEos ? 0 : 1),1);
    if(status != asynSuccess) {
        printf("drvAsynSerialPortConfigure: Can't register octet.\n");
        ttyCleanup(tty);
        return -1;
    }
    tty->pasynUser = pasynManager->createAsynUser(0,0);
    status = pasynManager->connectDevice(tty->pasynUser,tty->portName,-1);
    if(status != asynSuccess) {
        printf("connectDevice failed %s\n",tty->pasynUser->errorMessage);
        ttyCleanup(tty);
        return -1;
    }
    return 0;
}
Beispiel #28
0
int RontecConfig(const char *portName, char *serialPort, int serialPortAddress)
{
    int status;
    mcaRontecPvt *pPvt;

    pPvt = callocMustSucceed(1, sizeof(mcaRontecPvt), "RontecConfig");

    status = pasynOctetSyncIO->connect(serialPort, serialPortAddress, &pPvt->pasynUser, NULL);
    
    if (status != 0) {
        errlogPrintf("RontecConfig: can't connect to serial port %s, status=%d\n",
                     serialPort, status);
        return(-1);
    }

    /* Copy parameters to object private */
    pPvt->exists = 1;
    pPvt->maxChans = RONTEC_MAXCHANS;
    pPvt->nchans = pPvt->maxChans;
    pPvt->binning  = 1;
    /* Set reasonable defaults for other parameters */
    pPvt->plive   = 0;
    pPvt->preal   = 0;
    pPvt->ptotal  = 0;
    pPvt->ptschan = 0;
    pPvt->ptechan = 0;
    pPvt->acquiring = 0;
    
    pPvt->serialPort = epicsStrDup(serialPort);
    pPvt->portName = epicsStrDup(portName);

    /* Get the input EOS to be able to reset it later */
    pasynOctetSyncIO->getInputEos(pPvt->pasynUser, pPvt->inputEos, sizeof(pPvt->inputEos), &pPvt->inputEosLen);
    /* Initial settings for Rontec */
    sendMessage(pPvt, "$SM 4,0", NULL);  /* Send 4 bytes/channel, don't clear after sending */

    /*
     *  Link with higher level routines
     */
    pPvt->common.interfaceType = asynCommonType;
    pPvt->common.pinterface  = (void *)&mcaRontecCommon;
    pPvt->common.drvPvt = pPvt;
    pPvt->int32.interfaceType = asynInt32Type;
    pPvt->int32.pinterface  = (void *)&mcaRontecInt32;
    pPvt->int32.drvPvt = pPvt;
    pPvt->float64.interfaceType = asynFloat64Type;
    pPvt->float64.pinterface  = (void *)&mcaRontecFloat64;
    pPvt->float64.drvPvt = pPvt;
    pPvt->int32Array.interfaceType = asynInt32ArrayType;
    pPvt->int32Array.pinterface  = (void *)&mcaRontecInt32Array;
    pPvt->int32Array.drvPvt = pPvt;
    pPvt->drvUser.interfaceType = asynDrvUserType;
    pPvt->drvUser.pinterface  = (void *)&mcaRontecDrvUser;
    pPvt->drvUser.drvPvt = pPvt;
    status = pasynManager->registerPort(pPvt->portName,
                                        ASYN_MULTIDEVICE | ASYN_CANBLOCK,
                                        1,  /* autoconnect */
                                        0,  /* medium priority */
                                        0); /* default stacksize */
    if (status != asynSuccess) {
        errlogPrintf("RontecConfig ERROR: Can't register myself.\n");
        return -1;
    }
    status = pasynManager->registerInterface(pPvt->portName, &pPvt->common);
    if (status != asynSuccess) {
        errlogPrintf("RontecConfig: Can't register common.\n");
        return -1;
    }
    status = pasynInt32Base->initialize(pPvt->portName, &pPvt->int32);
    if (status != asynSuccess) {
        errlogPrintf("RontecConfig: Can't register int32.\n");
        return -1;
    }

    status = pasynFloat64Base->initialize(pPvt->portName, &pPvt->float64);
    if (status != asynSuccess) {
        errlogPrintf("RontecConfig: Can't register float64.\n");
        return -1;
    }

    status = pasynInt32ArrayBase->initialize(pPvt->portName, &pPvt->int32Array);
    if (status != asynSuccess) {
        errlogPrintf("RontecConfig: Can't register int32Array.\n");
        return -1;
    }

    status = pasynManager->registerInterface(pPvt->portName,&pPvt->drvUser);
    if (status != asynSuccess) {
        errlogPrintf("RontecConfig ERROR: Can't register drvUser\n");
        return -1;
    }
    return(0);
}
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, &registrarPvt);
        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;
}
Beispiel #30
0
static long init_record(longinRecord *plongin)
{
  struct link *plink = &plongin->inp;
  int size;
  char *buf;
  char *pC;
  F3RP61_LI_DPVT *dpvt;
  M3IO_ACCESS_COM *pacom;
  M3IO_ACCESS_REG *pdrly;
  int unitno, slotno, cpuno, start;
  char device;
  char option = 'W';
  int uword = 0;
  int lng = 0;
  int BCD = 0;

  if (plongin->inp.type != INST_IO) {
    recGblRecordError(S_db_badField,(void *)plongin,
		      "devLiF3RP61 (init_record) Illegal INP field");
    plongin->pact = 1;
    return(S_db_badField);
  }

  size = strlen(plink->value.instio.string) + 1;
  buf = (char *) callocMustSucceed(size, sizeof(char), "calloc failed");
  strncpy(buf, plink->value.instio.string, size);
  buf[size - 1] = '\0';

  /* Parse option*/
  pC = strchr(buf, '&');
  if (pC) {
    *pC++ = '\0';
    if (sscanf(pC, "%c", &option) < 1) {
      errlogPrintf("devLiF3RP61: can't get option for %s\n", plongin->name);
      plongin->pact = 1;
      return (-1);
    }
    if (option == 'U') {
      uword = 1; /* uword flag is used for the possible double option case */
    }
    else if (option == 'L') {
    	lng = 1;
    }
    else if (option == 'B') {
        BCD = 1; /* flag is used for the possible double/triple option case */
    }
    else { /* Option not recognized*/
    	errlogPrintf("devLiF3RP61: illegal option for %s\n", plongin->name);
    	plongin->pact = 1;
    	return (-1);
    }
  }

  /* Parse for possible interrupt source*/
  pC = strchr(buf, ':');
  if (pC) {
    *pC++ = '\0';
    if (sscanf(pC, "U%d,S%d,X%d", &unitno, &slotno, &start) < 3) {
      errlogPrintf("devLiF3RP61: can't get interrupt source address for %s\n", plongin->name);
      plongin->pact = 1;
      return (-1);
    }
    if (f3rp61_register_io_interrupt((dbCommon *) plongin, unitno, slotno, start) < 0) {
      errlogPrintf("devLiF3RP61: can't register I/O interrupt for %s\n", plongin->name);
      plongin->pact = 1;
      return (-1);
    }
  }

  /* Parse device*/
  if (sscanf(buf, "U%d,S%d,%c%d", &unitno, &slotno, &device, &start) < 4) {
    if (sscanf(buf, "CPU%d,R%d", &cpuno, &start) < 2) {
      if (sscanf(buf, "%c%d", &device, &start) < 2) {
    	  errlogPrintf("devLiF3RP61: can't get I/O address for %s\n", plongin->name);
    	  plongin->pact = 1;
    	  return (-1);
      }
      else if (device != 'W' && device != 'R') {
    	  errlogPrintf("devLiF3RP61: unsupported device \'%c\' for %s\n", device,
		     plongin->name);
    	  	 plongin->pact = 1;
      }
    }
    else {
      device = 'r';	/* Corresponds to accessing shared memory using 'Old Interface'*/
    }
  }

  /* Check device validity*/
  if (!(device == 'X' || device == 'Y' || device == 'A' || device == 'r' ||
	device == 'W' || device == 'R')) {
	  errlogPrintf("devLiF3RP61: illegal I/O address for %s\n", plongin->name);
	  plongin->pact = 1;
	  return (-1);
  }

  /* Create private data storage area*/
  dpvt = (F3RP61_LI_DPVT *) callocMustSucceed(1,
					      sizeof(F3RP61_LI_DPVT),
					      "calloc failed");
  dpvt->device = device;
  dpvt->option = option;
  dpvt->uword = uword;
  dpvt->lng = lng;
  dpvt->BCD = BCD;

  if (device == 'r') {	/* Shared registers - Using 'Old' interface*/
    pacom = &dpvt->u.acom;
    pacom->cpuno = (unsigned short) cpuno;
    pacom->start = (unsigned short) start;
    pacom->count = (unsigned short) 1;
  }
  else if (device == 'W' || device == 'R') {	/* Shared registers - Using 'New' interface*/
    pacom = &dpvt->u.acom;
    pacom->start = (unsigned short) start;
    switch (option) {
    case 'L':
      pacom->count = 2;
      break;
    default:
      pacom->count = 1;
    }
  }
  else {							/* Registers and I/Os of specific modules (X, Y and A)*/
    pdrly = &dpvt->u.drly;
    pdrly->unitno = (unsigned short) unitno;
    pdrly->slotno = (unsigned short) slotno;
    pdrly->start = (unsigned short) start;
    pdrly->count = (unsigned short) 1;
  }

  plongin->dpvt = dpvt;

  return(0);
}