Beispiel #1
0
// Called from ISR context
void SeqManager::doEndOfSequence(unsigned i)
{
    assert(i<hw.size());
    SeqHW* HW = hw[i];

    HW->running = false;

    SoftSequence *seq = HW->loaded;

    if(!seq) return;

    if(seq->committed.mode==Single) {
        seq->is_enabled = false;
    }

    seq->numEnd++;

    scanIoRequest(seq->onEnd);

    if(!seq->is_insync)
        seq->sync();

    if(seq->committed.mode==Single)
        scanIoRequest(seq->changed);
}
Beispiel #2
0
int drvACQ196_set_data_parsing(ST_STD_device *pSTDdev)
{
	ST_MASTER *pMaster = pSTDdev->pST_parentAdmin;

	pSTDdev->StatusDev &= ~TASK_SYSTEM_IDLE;
	pSTDdev->StatusDev |= TASK_POST_PROCESS;
	scanIoRequest(pSTDdev->ioScanPvt_status);
	printf("%s: start data parsing!\n", pSTDdev->taskName );
	if( !proc_dataChannelization( pSTDdev ) )
	{
		epicsPrintf("\n>>> drvACQ196_set_data_parsing(%s) : proc_dataChannelization() ... fail\n", pSTDdev->taskName);
		pSTDdev->StatusDev &= ~TASK_POST_PROCESS;
		pSTDdev->StatusDev |= DEV_CHANNELIZATION_FAIL;
		scanIoRequest(pSTDdev->ioScanPvt_status);
		pMaster->ErrorAdmin |= ERROR_AFTER_SHOT_PROCESS;
		scanIoRequest(pMaster->ioScanPvt_status);
		return WR_ERROR;
	}
	pSTDdev->StatusDev &= ~TASK_POST_PROCESS;
	pSTDdev->StatusDev |= TASK_SYSTEM_IDLE;

	scanIoRequest(pSTDdev->ioScanPvt_status);

	pSTDdev->StatusDev |= DEV_READY_TO_SAVE; /* if save PV put, then it cleared! */
	return WR_OK;
}
Beispiel #3
0
void
evgSoftSeq::abort(bool callBack) {
    if(!isLoaded() && !isEnabled())
        return;

    // Prevent re-trigger
    m_seqRam->setRunMode(Single);
    m_seqRam->setTrigSrc(None);

    m_seqRam->reset();
    m_isEnabled = false;
    if(mrmEVGSeqDebug)
        fprintf(stderr, "SS%u: Abort!\n",m_id);
    scanIoRequest(ioscanpvt);

    if(callBack) {
        /*
             * Satisfy any callback request pending on irqStop0 or irqStop1
             * recList. As no 'End of sequence' Intrrupt will be generated. 
             */
        if(m_seqRam->getId() == 0)
            callbackRequest(&m_owner->irqStop0_cb);
        else
            callbackRequest(&m_owner->irqStop1_cb);
    }
}
Beispiel #4
0
void
evgSoftSeq::load() {
    if(isLoaded())
        return;

    /* 
     * Assign the first avialable(unallocated) hardware sequenceRam to this soft
     * sequence if none is currently assingned.
     */
    for(unsigned int i = 0; i < m_seqRamMgr->numOfRams(); i++) {
        evgSeqRam* seqRamIter = m_seqRamMgr->getSeqRam(i);
        if( seqRamIter->alloc(this) )
            break;
    }

    if(isLoaded()) {
        // always need sync after loading
        m_isSynced = false;
        if(mrmEVGSeqDebug)
            fprintf(stderr, "SS%u: Load\n",m_id);
        sync(); 
        scanIoRequest(ioscanpvt);
    } else {
        char err[80];
        sprintf(err, "No SeqRam to load SoftSeq %d", getId());
        std::string strErr(err);
        throw std::runtime_error(strErr);
    }
}
Beispiel #5
0
LOCAL void drvTPG262_timeoutCallback(asynUser* pasynTPG262User)
{
    asynTPG262UserData* pasynTPG262UserData = (asynTPG262UserData*) pasynTPG262User->userPvt;
    drvTPG262Config* pdrvTPG262Config = (drvTPG262Config*) pasynTPG262UserData->pdrvTPG262Config;
    TPG262_read* pTPG262_read = (TPG262_read*) pdrvTPG262Config->pTPG262_read;

    pdrvTPG262Config->status |= TPG262STATUS_SETUNIT_MASK;
    pdrvTPG262Config->status |= TPG262STATUS_TIMEOUT_MASK;
    pdrvTPG262Config->status |= TPG262STATUS_GETGID_MASK;
    pdrvTPG262Config->status |= TPG262STATUS_GETPROGVER_MASK;

    epicsMutexLock(pdrvTPG262Config->lock);
    pdrvTPG262Config->cbCount =0;
    pdrvTPG262Config->timeoutCount++;
    pTPG262_read->gst0 = TPG262GST_TIMEOUT; 
    pTPG262_read->gst1 = TPG262GST_TIMEOUT;
    pTPG262_read->gst_str0 = tSenStList[vSenStList[pTPG262_read->gst0]];
    pTPG262_read->gst_str1 = tSenStList[vSenStList[pTPG262_read->gst1]];
    strcpy(pTPG262_read->gid_str0, TPG262GID_UNKNOWN_STR);
    strcpy(pTPG262_read->gid_str1, TPG262GID_UNKNOWN_STR);
    strcpy(pTPG262_read->progver_str, TPG262PROGVER_UNKNOWN_STR);
    epicsMutexUnlock(pdrvTPG262Config->lock);

    scanIoRequest(pdrvTPG262Config->ioScanPvt);

   return; 
}
Beispiel #6
0
static void devNI6123_AO_DAQ_MAX_VOLT(ST_execParam *pParam)
{
        ST_MASTER *pMaster = get_master();
        ST_STD_device *pSTDdev = (ST_STD_device*) ellFirst(pMaster->pList_DeviceTask);
        ST_NI6123 *pNI6123 = NULL;

        kLog (K_DATA,"[devNI6123_AO_DAQ_MAX_VOLT] minVolt(%f)\n", pParam->setValue);

        while(pSTDdev) {
                if (pSTDdev->StatusDev & TASK_ARM_ENABLED) {
                        kLog (K_DATA,"[devNI6123_AO_DAQ_MAX_VOLT] %s: System is armed! \n", pSTDdev->taskName);
                        notify_error (1, "System is armed!", pSTDdev->taskName );
                }
                else {
                        pNI6123 = pSTDdev->pUser;
                        pNI6123->maxVal = pParam->setValue;
                        scanIoRequest(pSTDdev->ioScanPvt_userCall);

                        kLog (K_DATA,"[devNI6123_AO_DAQ_MAX_VOLT] task(%s) maxVolt(%.f)\n",
                                        pSTDdev->taskName, pNI6123->maxVal);
                }

                pSTDdev = (ST_STD_device*) ellNext(&pSTDdev->node);
        }
}
Beispiel #7
0
static void checkMySync( ) {
    /* we use channel 0 on board 0 to check */
    MY_BOARD_SOFTWARE *pBoardSoft = myBoard_getSoftwareBoard( 0 );
    MY_RING_BUFFER *pRingBuffer =  &(pBoardSoft->channel_buffer[0]);

    int resetting = 0;
    if (getWriteIndexOfMyRingBuffer( pRingBuffer ) == 0) {
        resetting = 1;
    }
    int i;
    for (i = 0; i < mySyncTagGetNumberUsed(); ++i) {
        MY_SYNC_T *pMySync = mySyncTagGetSync( i );
        if (resetting) {
            pMySync->indexRead = 0;
            pMySync->indexNextRead = 0;
        } else {
            pMySync->indexRead = pMySync->indexNextRead;
            /* this will change indexNextRead if enough data */
            if (readDataFromMyRingBuffer(
                pRingBuffer,
                pMySync->indexRead,
                &(pMySync->indexNextRead),
                pMySync->numNewNeed,
                NULL,
                0,
                &(pMySync->numNewAvailable),
                &(pMySync->numWaiting)
            )) {
                scanIoRequest( pMySync->ioScanPvt );
            }
        }
    }
}
Beispiel #8
0
static void devNI6123_AO_DAQ_SAMPLEING_RATE(ST_execParam *pParam)
{
        ST_MASTER *pMaster = get_master();
        ST_STD_device *pSTDdev = (ST_STD_device*) ellFirst(pMaster->pList_DeviceTask);
        ST_NI6123 *pNI6123 = NULL;

        kLog (K_DATA,"[devNI6123_AO_DAQ_SAMPLEING_RATE] sampleRate(%f)\n", pParam->setValue);

        while(pSTDdev) {
                if (pSTDdev->StatusDev & TASK_ARM_ENABLED) {
                        kLog (K_DATA,"[devNI6123_AO_DAQ_SAMPLEING_RATE] %s: System is armed! \n", pSTDdev->taskName);
                        notify_error (1, "System is armed!", pSTDdev->taskName );
                }
                else {
                        pNI6123 = pSTDdev->pUser;
			if(pParam->setValue > pNI6123->sample_rateLimit){
				/*  Device Sampling Rate Limit Cut if User is over Sampling Rate Setting.  */
				pParam->setValue = pNI6123->sample_rateLimit;
			} else if(pParam->setValue <= 0){
				 pParam->setValue = 1;
			}
			pNI6123->sample_rate = pParam->setValue;
                        scanIoRequest(pSTDdev->ioScanPvt_userCall);

                        kLog (K_DATA,"[devNI6123_AO_DAQ_SAMPLEING_RATE] task(%s) sampleRate(%.f)\n",
                                        pSTDdev->taskName, pNI6123->sample_rate);
                }

                pSTDdev = (ST_STD_device*) ellNext(&pSTDdev->node);
        }
}
Beispiel #9
0
/* auto Run function */
static void devNI6123_BO_AUTO_RUN(ST_execParam *pParam)
{
        ST_MASTER *pMaster = get_master();
        ST_STD_device *pSTDdev = (ST_STD_device*) ellFirst(pMaster->pList_DeviceTask);
        ST_NI6123 *pNI6123 = NULL;

        kLog (K_TRACE, "[devNI6123_BO_AUTO_RUN] auto_run(%f)\n", pParam->setValue);

        if( pMaster->StatusAdmin & TASK_WAIT_FOR_TRIGGER ||
                        pMaster->StatusAdmin & TASK_IN_PROGRESS ) {
                kLog (K_ERR, "System is running! (0x%x)\n", pMaster->StatusAdmin);
                notify_error (1, "System is running! (0x%x)\n", pMaster->StatusAdmin);
                return;
        }

        if(pParam->setValue) {
                if( !(pMaster->StatusAdmin & TASK_SYSTEM_IDLE) ) {
                        kLog (K_ERR, "System is busy! (0x%x)\n", pMaster->StatusAdmin);
                        notify_error (1, "System is busy! (0x%x)\n", pMaster->StatusAdmin);
                        return;
                }
#if 0
		char strBuf[24];
		float stopT1;
	/*	remove this function because ECH has not LTU, so We donot use the DBproc_get function */
				if( pSTDdev->ST_Base.opMode == OPMODE_REMOTE ){
					DBproc_get (PV_LTU_TIG_T0_STR, strBuf);   //Get T0 from LTU
					DBproc_put (PV_START_TIG_T0_STR, strBuf);   //Set T0 from LTU
					sscanf(strBuf, "%f", &stopT1);
					stopT1 = pNI6123->sample_time - stopT1;
					sprintf(strBuf,"%f",stopT1);
					DBproc_put (PV_STOP_TIG_T1_STR, strBuf);   //Set T0 from LTU
				}
#endif
                while(pSTDdev) {
                        pSTDdev->StatusDev |= TASK_STANDBY;

                        pNI6123 = pSTDdev->pUser;
                        pNI6123->auto_run_flag = 1;

                        pSTDdev = (ST_STD_device*) ellNext(&pSTDdev->node);
                }
        }
        else if(!pParam->setValue) {
                while(pSTDdev) {
                        pNI6123 = pSTDdev->pUser;
                        pNI6123->auto_run_flag = 0;

                        pSTDdev = (ST_STD_device*) ellNext(&pSTDdev->node);
                }

                pMaster->n8EscapeWhile = 0;
                epicsThreadSleep(3.0);
                pMaster->n8EscapeWhile = 1;
                admin_all_taskStatus_reset();
                scanIoRequest(pMaster->ioScanPvt_status);
        }

        notify_refresh_master_status();
}
void Sim::run()
{
    Guard G(lock);
    while(!stop) {
        if(!doSim) {
            UnGuard U(G);
            event.wait();
            continue;
        }

        doSim = false;

        epicsTimeStamp start;
        epicsTimeGetCurrent(&start);

        try {
            std::auto_ptr<StateBase> state(machine->allocState());

            machine->propagate(state.get());

            valid = true;
        }catch(std::exception& e){
            last_msg = e.what();
            valid = false;
        }

        epicsTimeGetCurrent(&last_run);
        last_duration = epicsTimeDiffInSeconds(&last_run, &start);

        scanIoRequest(aftersim);
    }
}
Beispiel #11
0
void func_acq196_OP_MODE(void *pArg, double arg1, double arg2)
{
	ST_STD_device* pSTDdev = (ST_STD_device *)pArg;

	drvACQ196_status_reset(pSTDdev);
	scanIoRequest(pSTDdev->ioScanPvt_status);
}
Beispiel #12
0
static void devNI6250_AO_DAQ_GAIN(ST_execParam *pParam)
{
	ST_MASTER *pMaster = get_master();
	ST_STD_device *pSTDdev = (ST_STD_device*) ellFirst(pMaster->pList_DeviceTask);
	ST_NI6250 *pNI6250 = NULL;

	kLog (K_MON, "[devNI6250_AO_DAQ_GAIN] gain(%f)\n", pParam->setValue);

	while(pSTDdev) {
		if (pSTDdev->StatusDev & TASK_ARM_ENABLED) {
			kLog (K_ERR, "[devNI6250_AO_DAQ_GAIN] %s: System is armed! \n", pSTDdev->taskName);
			notify_error (1, "System is armed!", pSTDdev->taskName );		
		}
		else {
			pNI6250 = pSTDdev->pUser;
			pNI6250->gain = pParam->setValue;
			scanIoRequest(pSTDdev->ioScanPvt_userCall); 			

			kLog (K_DEBUG, "[devNI6250_AO_DAQ_GAIN] task(%s) gain(%.f)\n",
					pSTDdev->taskName, pNI6250->gain);
		}

		pSTDdev = (ST_STD_device*) ellNext(&pSTDdev->node);
	}
}
Beispiel #13
0
/**
 * @brief Thread function that periodically reads the scaler values
 * @param arg ignore. does not take arguments
 * @return nothing.
 */
void *thread_measure( void* arg)
{

    int i;

    while( 1 )
    {

        // Clear Counters
        for( i=0; i<n_vuproms; ++i) {
            start_measurement( &(vu[i]) );
        }

        usleep( sleep_time );

        // Save Counters
        for( i=0; i<n_vuproms; ++i) {
            stop_measurement( &(vu[i]) );
        }

        // copy values
        for( i=0; i<n_vuproms; ++i) {
            save_values( &(vu[i]) );
        }

        if( _iointr )
            scanIoRequest( ioinfo );

    }

    return NULL;
}
Beispiel #14
0
int drvACQ196_notify_InitCondition(ST_STD_device *pSTDdev)
{
	ST_ACQ196 *pAcq196 = (ST_ACQ196*)pSTDdev->pUser;

	if( (pAcq196->boardConfigure & ACQ196_SET_CLOCK_RATE) &&
		(pAcq196->boardConfigure & ACQ196_SET_R_BITMASK) &&
		(pAcq196->boardConfigure & ACQ196_SET_M_BITMASK) &&
		(pAcq196->boardConfigure & ACQ196_SET_L_BITMASK) &&
		(pAcq196->boardConfigure & ACQ196_SET_T0) &&
		(pAcq196->boardConfigure & ACQ196_SET_T1) &&
		(pAcq196->boardConfigure & ACQ196_SET_TAG) )
/*		(pAcq196->boardConfigure & ACQ196_SET_SHOT_NUM) )  */
	{
		if( pSTDdev->ST_Base.opMode == OPMODE_REMOTE )
			pSTDdev->StatusDev |= TASK_STANDBY;
		else {
			if( pAcq196->boardConfigure & ACQ196_SET_SHOT_NUM) {
				pSTDdev->StatusDev |= TASK_STANDBY;
/*				printf(" %s: ready, %x\n", pSTDdev->taskName, pSTDdev->StatusDev ); */
			} else {
				pSTDdev->StatusDev &= ~TASK_STANDBY;
/*				printf(" %s: not ready, %x\n", pSTDdev->taskName, pSTDdev->StatusDev ); */
				}
		}
	} else{
		pSTDdev->StatusDev &= ~TASK_STANDBY;
	}
	scanIoRequest(pSTDdev->ioScanPvt_status);

/*	notify_sys_ready(); */
	notify_refresh_master_status();
	
	return WR_OK;
}
void simRegDevCallback(void* arg)
{
    simRegDevMessage* msg = arg;
    regDevice *device = msg->device;
    regDevTransferComplete callback = msg->callback;
    int status;

    if (simRegDevDebug & (msg->isOutput ? DBG_OUT : DBG_IN))
        printf ("simRegDevCallback %s %s: copy %u bytes * %"Z"u elements\n",
        msg->user, device->name, msg->dlen, msg->nelem);
    epicsMutexLock(device->lock);
    if (device->connected == 0)
    {
        status = S_dev_noDevice;
    }
    else
    {
        regDevCopy(msg->dlen, msg->nelem, msg->src, msg->dest, msg->pmask, device->swap);
        status = S_dev_success;
    }
    msg->next = device->msgFreelist[msg->prio];
    device->msgFreelist[msg->prio] = msg;
    if (msg->isOutput)
    {
        /* We got new data: trigger all interested input records */
        if (simRegDevDebug & DBG_OUT)
            printf ("simRegDevCallback %s %s: trigger input records\n", msg->user, device->name);
        scanIoRequest(device->ioscanpvt);
    }
    epicsMutexUnlock(device->lock);
    if (simRegDevDebug & (msg->isOutput ? DBG_OUT : DBG_IN))
        printf ("simRegDevCallback %s %s: call back status=%d\n", msg->user, device->name, status);
    callback(msg->user, status);
}
int simRegDevSetStatus(
    const char* name,
    int connected)
{
    regDevice* device;

    if (!name)
    {
        printf ("usage: simRegDevSetStatus name, 0|1\n");
        return S_dev_badArgument;
    }
    device = regDevFind(name);
    if (!device)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevSetStatus: %s not found\n",
            name);
        return S_dev_noDevice;
    }
    if (device->magic != MAGIC)
    {
        errlogSevPrintf(errlogFatal,
            "simRegDevSetStatus: %s is not a simRegDev\n",
            name);
        return S_dev_wrongDevice;
    }
    device->connected = connected;
    if (simRegDevDebug >= 1)
        printf ("simRegDevSetStatus %s: trigger input records\n", device->name);
    scanIoRequest(device->ioscanpvt);
    return S_dev_success;
}
Beispiel #17
0
    void setTimestamp(const double *arr, epicsUInt32 count)
    {
        const double tmult = getTimeScale();
        times_t times(count);
        // check for monotonic
        // TODO: not handling overflow (HW supports controlled rollover w/ special 0xffffffff times)
        for(epicsUInt32 i=0; i<count; i++)
        {
            if(!finite(arr[i]) || arr[i]<0.0)
                throw std::runtime_error("times must be finite >=0");

            times[i] = (arr[i]*tmult)+0.5;

            if(i>0 && times[i]<=times[i-1])
                throw std::runtime_error("Non-monotonic timestamp array");
            else if(times[i]==0xffffffff)
                throw std::runtime_error("Time overflow, rollover not supported");
        }
        {
            SCOPED_LOCK(mutex);
            scratch.times.swap(times);
            is_committed = false;
        }
        DEBUG(4, ("Set times\n"));
        scanIoRequest(changed);
    }
Beispiel #18
0
static void devNI6123_AO_BEAM_PLUSE(ST_execParam *pParam)
{
	ST_MASTER *pMaster = get_master();
	ST_STD_device *pSTDdev = (ST_STD_device*) ellFirst(pMaster->pList_DeviceTask);
	ST_NI6123 *pNI6123 = NULL;

	kLog (K_TRACE, "[devNI6123_AO_BEAM_PLUSE] beam_pulse(%f)\n", pParam->setValue);

	while(pSTDdev) {
		if (pSTDdev->StatusDev & TASK_ARM_ENABLED) {
			kLog (K_ERR, "[devNI6123_AO_BEAM_PLUSE] %s: System is armed! \n", pSTDdev->taskName);
			notify_error (1, "System is armed!", pSTDdev->taskName );		
		}
		else {
			pNI6123 = pSTDdev->pUser;
			pNI6123->beam_pulse = pParam->setValue;
			scanIoRequest(pSTDdev->ioScanPvt_userCall); 			

			kLog (K_DEBUG, "[devNI6123_AO_BEAM_PLUSE] task(%s) pulse(%.f)\n",
					pSTDdev->taskName, pNI6123->beam_pulse);
		}

		pSTDdev = (ST_STD_device*) ellNext(&pSTDdev->node);
	}
}
Beispiel #19
0
LOCAL void devCallback(void * drvPvt)
{
    devPvt	*pdevPvt;

    pdevPvt = (devPvt *)(*pabDrv->getUserPvt)(drvPvt);
    if(!pdevPvt) return;
    scanIoRequest(pdevPvt->ioscanpvt);
}
Beispiel #20
0
/* Callback, registered with drvEtherIP, for input records.
 * Used _IF_ scan="I/O Event":
 * Driver has new value (or no value because of error), process record
 */
static void scan_callback(void *arg)
{
    dbCommon      *rec = (dbCommon *) arg;
    DevicePrivate *pvt = (DevicePrivate *)rec->dpvt;
    if (rec->tpro)
        printf("EIP scan_callback('%s')\n", rec->name);
    scanIoRequest(pvt->ioscanpvt);
}
int simRegDevWrite(
    regDevice *device,
    size_t offset,
    unsigned int dlen,
    size_t nelem,
    void* pdata,
    void* pmask,
    int prio,
    regDevTransferComplete callback,
    const char* user)
{
    if (!device || device->magic != MAGIC)
    {
        errlogSevPrintf(errlogMajor,
            "simRegDevWrite: illegal device handle\n");
        return S_dev_wrongDevice;
    }
    if (device->connected == 0)
    {
        return S_dev_noDevice;
    }
    if (simRegDevDebug & DBG_OUT)
    {
        size_t n;
        printf ("simRegDevWrite %s %s:%"Z"u: %u bytes * %"Z"u elements, prio=%d\n",
        user, device->name, offset, dlen, nelem, prio);
        for (n=0; n<nelem && n<10; n++)
        {
            switch (dlen)
            {
                case 1:
                    printf (" %02x",((epicsUInt8*)pdata)[n*dlen]);
                    break;
                case 2:
                    printf (" %04x",((epicsUInt16*)pdata)[n*dlen]);
                    break;
                case 4:
                    printf (" %08x",((epicsUInt32*)pdata)[n*dlen]);
                    break;
                case 8:
                    printf (" %08llx",((unsigned long long*)pdata)[n*dlen]);
                    break;
            }
        }
        printf ("\n");
    }

    if (nelem > 1 && device->lock)
        return simRegDevAsynTransfer(device, dlen, nelem, pdata,
            device->buffer+offset, pmask, prio, callback, user, TRUE);

    regDevCopy(dlen, nelem, pdata, device->buffer+offset, pmask, device->swap);
    /* We got new data: trigger all interested input records */
    if (simRegDevDebug & DBG_OUT)
        printf ("simRegDevWrite %s: trigger input records\n", device->name);
    scanIoRequest(device->ioscanpvt);
    return S_dev_success;
}
Beispiel #22
0
static void interruptCallbackAverage(void *drvPvt, asynUser *pasynUser,
                epicsFloat64 value)
{
    devPvt *pPvt = (devPvt *)drvPvt;
    dbCommon *pr = pPvt->pr;
    aiRecord *pai = (aiRecord *)pr;
    ringBufferElement *rp;
    int numToAverage;
    static const char *functionName="interruptCallbackAverage";

    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s %s::%s new value=%f\n",
        pr->name, driverName, functionName,value);
    if (!interruptAccept) return;
    epicsMutexLock(pPvt->devPvtLock);
    pPvt->numAverage++;
    pPvt->sum += value;
    /* We use the SVAL field to hold the number of values to average when SCAN=I/O Intr
     * We should be calling dbScanLock when accessing pPvt->isIOIntrScan and pai->sval but that leads to deadlocks
     * because we have the asynPortDriver lock in the driver, and we would be taking the scan lock
     * after the asynPortDriver lock, which is the opposite of normal record processing.
     * pPvt->isIOIntrScan is an int, so should be OK to read because write to it is atomic?
     * pai->sval is a double so it may not be completely safe to read without the lock? */
    if ((pPvt->isIOIntrScan)) {
        numToAverage = (int)(pai->sval + 0.5);
        if (numToAverage < 1) numToAverage = 1; 
        if (pPvt->numAverage >= numToAverage) {
            rp = &pPvt->ringBuffer[pPvt->ringHead];
            rp->value = pPvt->sum/pPvt->numAverage;
            pPvt->numAverage = 0;
            pPvt->sum = 0.;
            rp->time = pasynUser->timestamp;
            rp->status = pasynUser->auxStatus;
            rp->alarmStatus = pasynUser->alarmStatus;
            rp->alarmSeverity = pasynUser->alarmSeverity;
            pPvt->ringHead = (pPvt->ringHead==pPvt->ringSize) ? 0 : pPvt->ringHead+1;
            if (pPvt->ringHead == pPvt->ringTail) {
                /* There was no room in the ring buffer.  In the past we just threw away
                 * the new value.  However, it is better to remove the oldest value from the
                 * ring buffer and add the new one.  That way the final value the record receives
                 * is guaranteed to be the most recent value */
                pPvt->ringTail = (pPvt->ringTail==pPvt->ringSize) ? 0 : pPvt->ringTail+1;
                pPvt->ringBufferOverflows++;
            } /* End ring buffer full */
            else {
                /* We only need to request the record to process if we added a new
                 * element to the ring buffer, not if we just replaced an element. */
                scanIoRequest(pPvt->ioScanPvt);
            }  
        } /* End numAverage=SVAL, so time to compute average */
    } /* End SCAN=I/O Intr */
    else { 
        pPvt->result.status |= pasynUser->auxStatus;
        pPvt->result.alarmStatus = pasynUser->alarmStatus;
        pPvt->result.alarmSeverity = pasynUser->alarmSeverity;
    } 
    epicsMutexUnlock(pPvt->devPvtLock);
}
Beispiel #23
0
 void setTimestampResolution(epicsUInt32 val)
 {
     {
         SCOPED_LOCK(mutex);
         timeScale = val;
     }
     DEBUG(4, ("Set time scale\n"));
     scanIoRequest(changed);
 }
Beispiel #24
0
void
evgSoftSeq::setRunMode(SeqRunMode runMode) {
    if(runMode != m_runMode) {
        m_runMode = runMode;
        m_isCommited = false;
        if(mrmEVGSeqDebug>1)
            fprintf(stderr, "SS%u: Update Mode\n",m_id);
        scanIoRequest(ioscanpvt);
    }
}
Beispiel #25
0
void
evgSoftSeq::pause() {
    if( m_seqRam && m_seqRam->isEnabled() ) {
        m_seqRam->disable();
        m_isEnabled = false;
        if(mrmEVGSeqDebug)
            fprintf(stderr, "SS%u: Pause\n",m_id);
        scanIoRequest(ioscanpvt);
    }
}
Beispiel #26
0
void
evgSoftSeq::setTrigSrc(SeqTrigSrc trigSrc) {
    if(trigSrc != m_trigSrc) {
        m_trigSrc = trigSrc;
        m_isCommited = false;
        if(mrmEVGSeqDebug>1)
            fprintf(stderr, "SS%u: Update Trig\n",m_id);
        scanIoRequest(ioscanpvt);
    }
}
Beispiel #27
0
static void interruptCallbackInput(void *drvPvt, asynUser *pasynUser, 
                epicsInt32 value)
{
    devInt32Pvt *pPvt = (devInt32Pvt *)drvPvt;
    dbCommon *pr = pPvt->pr;
    int count, size = sizeof(epicsInt32);

    if (pPvt->bipolar && (value & pPvt->signBit)) value |= ~pPvt->mask;
    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s devAsynInt32::interruptCallbackInput new value=%d\n",
        pr->name, value);
    /* There is a problem.  A driver could be calling us with a value after
     * this record has registered for callbacks but before EPICS has set interruptAccept,
     * which means that scanIoRequest will return immediately.
     * This is very bad, because if we have pushed a value into the ring buffer
     * it won't get popped off because the record won't process.  The values
     * read the next time the record processes would then be stale.
     * We previously worked around this problem by waiting here for interruptAccept.
     * But that does not work if the callback is coming from the thread that is executing
     * iocInit, which can happen with synchronous drivers (ASYN_CANBLOCK=0) that do callbacks
     * when a value is written to them, which can happen in initRecord for an output record.
     * Instead we just return.  There will then be nothing in the ring buffer, so the first
     * read will do a read from the driver, which should be OK. */
    if (!interruptAccept) return;
    /* Note that we put a lock around epicsRingBytesPut and Get because we potentially have
     * more than one reader, since the reader is whatever thread is processing the record */
    epicsMutexLock(pPvt->mutexId);
    count = epicsRingBytesPut(pPvt->ringBuffer, (char *)&value, size);
    if (count != size) {
        /* There was no room in the ring buffer.  In the past we just threw away
         * the new value.  However, it is better to remove the oldest value from the
         * ring buffer and add the new one.  That way the final value the record receives
         * is guaranteed to be the most recent value */
        epicsInt32 dummy;
        count = epicsRingBytesGet(pPvt->ringBuffer, (char *)&dummy, size);
        if (count != size) {
            asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR,
                "%s devAsynInt32 interruptCallbackInput error, ring read failed\n",
                pPvt->pr->name);
        }
        count = epicsRingBytesPut(pPvt->ringBuffer, (char *)&value, size);
        if (count != size) {
            asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR,
                "%s devAsynInt32 interruptCallbackInput error, ring put failed\n",
                pPvt->pr->name);
        }
        pPvt->ringBufferOverflows++;
    } else {
        /* We only need to request the record to process if we added a 
         * new element to the ring buffer, not if we just replaced an element. */
        scanIoRequest(pPvt->ioScanPvt);
    }    
    epicsMutexUnlock(pPvt->mutexId);
}
Beispiel #28
0
 void setTrigSrc(epicsUInt32 src)
 {
     DEBUG(4, ("Setting trig src %x\n", (unsigned)src));
     {
         SCOPED_LOCK(mutex);
         scratch.src = src;
         is_committed = false;
     }
     DEBUG(4, ("Set trig src %x\n", (unsigned)src));
     scanIoRequest(changed);
 }
Beispiel #29
0
static
void xycom566isrcb(CALLBACK *cb)
{
  xy566 *card;
  epicsUInt16 csr;
  epicsUInt16 datacnt[32];
  epicsUInt16 dcnt;
  size_t i, ch;

  callbackGetUser(card,cb);

  epicsMutexMustLock(card->guard);

  /* clear number of data points */
  memset(datacnt,0,sizeof(datacnt));

  /* number of samples taken */
  dcnt=READ16(card->base, XY566_RAM);

  if(dcnt>256){
    /* Somehow the sequence was restart w/o resetting
     * the pointer, or changed by an outside program
     */
    dcnt=256;
    printf("Data longer then expected\n");
  }

  for(i=0;i<dcnt;i++){
    ch=card->seq[i]&0x1f;

    card->data[ch][datacnt[ch]]=READ16(card->data_base, XY566_DOFF(i));
    datacnt[ch]++;

    if( card->seq[i]&SEQ_END )
      break;
  }
  
  /* reset pointers */
  WRITE16(card->base, XY566_RAM, 0);
  WRITE8(card->base, XY566_SEQ, 0);

  csr=READ16(card->base, XY566_CSR);

  /* enable sequence controller */
  csr|=XY566_CSR_SEQ;

  WRITE16(card->base, XY566_CSR, csr);

  scanIoRequest(card->seq_irq);

  epicsMutexUnlock(card->guard);
}
Beispiel #30
0
void SoftSequence::load()
{
    SCOPED_LOCK(mutex);
    DEBUG(3, ("Loading %c\n", hw ? 'L' : 'U') );
    if(hw) {DEBUG(3, ("Skip\n")); return;}

    // find unused SeqHW
    {
        interruptLock L;

        is_insync = false; // paranoia

        for(size_t i=0, N=owner->hw.size(); i<N; i++) {
            SeqHW *temp = owner->hw[i];
            if(temp && !temp->loaded) {
                temp->loaded = this;
                hw = temp;
                break;
            }
        }

        if(hw) {
            // paranoia: disable any external trigger mappings
            owner->mapTriggerSrc(hw->idx, 0x02000000);

            if(!hw->disarm())
                sync();
        }
    }

    if(!hw) {
        last_err = "All HW Seq. in use";
        scanIoRequest(onErr);
        throw alarm_exception(MAJOR_ALARM, WRITE_ALARM);
    }

    scanIoRequest(changed);
    DEBUG(1, ("Loaded\n") );
}