Ejemplo n.º 1
0
static void outputCallbackCallback(CALLBACK *pcb)
{
    devPvt *pPvt; 
    static const char *functionName="outputCallbackCallback";

    callbackGetUser(pPvt, pcb);
    {
        dbCommon *pr = pPvt->pr;
        dbScanLock(pr);
        epicsMutexLock(pPvt->devPvtLock);
        pPvt->newOutputCallbackValue = 1;
        dbProcess(pr);
        if (pPvt->newOutputCallbackValue != 0) {
            /* We called dbProcess but the record did not process, perhaps because PACT was 1 
             * Need to remove ring buffer element */
            asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, 
                "%s %s::%s warning dbProcess did not process record, PACT=%d\n", 
                pr->name, driverName, functionName,pr->pact);
            getCallbackValue(pPvt);
            pPvt->newOutputCallbackValue = 0;
        }
        epicsMutexUnlock(pPvt->devPvtLock);
        dbScanUnlock(pr);
    }
}
Ejemplo n.º 2
0
static void queueItDelayed(CALLBACK * pvt)
{
    devPvt     *pdevPvt;
    asynStatus status;
    dbCommon   *precord;
    asynUser   *pasynUser;

    callbackGetUser(pdevPvt,pvt);
    precord = pdevPvt->precord;
    pasynUser = pdevPvt->pasynUser;
    precord = pdevPvt->precord;
    status = pasynManager->queueRequest(pasynUser,asynQueuePriorityMedium,0.0);
    if(status!=asynSuccess) {
        asynPrint(pdevPvt->pasynUser, ASYN_TRACE_ERROR,
            "%s queueRequest failed %s\n",
            precord->name,pasynUser->errorMessage);
        recGblSetSevr(precord,READ_ALARM,INVALID_ALARM);
        status = pasynManager->unblockProcessCallback(pasynUser,pdevPvt->blockAll);
        if(status!=asynSuccess) {
            asynPrint(pdevPvt->pasynUser, ASYN_TRACE_ERROR,
                "%s queueRequest failed %s\n",
                precord->name,pasynUser->errorMessage);
        }
        callbackRequestProcessCallback(
            &pdevPvt->processCallback,precord->prio,precord);
    }
}
Ejemplo n.º 3
0
static void myCallback_devBoSyncSoft(CALLBACK *p_callback)
{
  struct dbCommon *precord;
  CONTEXT *p_myContext;
  struct rset *prset;

  callbackGetUser(precord,p_callback);

  #ifdef DEBUG1
  printf( __FILE__ "[%d] -> %s (%s)\n", __LINE__, __func__, precord->name );
  #endif

  p_myContext=(CONTEXT *)precord->dpvt;
  prset = (struct rset *)(precord->rset);

  dbScanLock(precord);
  (*prset->process)(precord);
  dbScanUnlock(precord);

  #ifdef DEBUG1
  printf( __FILE__ "[%d] <- %s\n", __LINE__, __func__ );
  #endif

  return;
}
Ejemplo n.º 4
0
static void eventCallback(CALLBACK *pcallback)
{
    scan_list *psl;

    callbackGetUser(psl, pcallback);
    scanList(psl);
}
Ejemplo n.º 5
0
static void myCallback(CALLBACK *pCallback)
{
    myPvt *pmyPvt;
    epicsTimeStamp now;
    double delay, error;

    epicsTimeGetCurrent(&now);
    callbackGetUser(pmyPvt, pCallback);

    if (pmyPvt->pass++ == 0) {
        delay = 0.0;
        error = epicsTimeDiffInSeconds(&now, &pmyPvt->start);
        pmyPvt->start = now;
        callbackRequestDelayed(&pmyPvt->cb2, pmyPvt->delay);
    } else if (pmyPvt->pass == 2) {
        double diff = epicsTimeDiffInSeconds(&now, &pmyPvt->start);
        delay = pmyPvt->delay;
        error = fabs(delay - diff);
    } else {
        testFail("pass = %d for delay = %f", pmyPvt->pass, pmyPvt->delay);
        return;
    }
    testOk(error < 0.05, "delay %f seconds, callback time error %f",
        delay, error);
}
Ejemplo n.º 6
0
void
bufRxManager::received(CALLBACK* cb)
{
    void *vptr;
    callbackGetUser(vptr,cb);
    bufRxManager &self=*static_cast<bufRxManager*>(vptr);

    SCOPED_LOCK2(self.guard, G);

    while(true) {
        ELLNODE *node=ellGet(&self.usedbufs);

        if (!node)
            break;
        buffer *buf=CONTAINER(node, buffer, node);

        G.unlock();

        for(ELLNODE *cur=ellFirst(&self.dispatch); cur; cur=ellNext(cur)) {
            listener *action=CONTAINER(cur, listener, node);
            (action->fn)(action->fnarg, 0, buf->used, buf->data);
        }

        G.lock();

        ellAdd(&self.freebufs, &buf->node);
    };
}
Ejemplo n.º 7
0
static void notifyCallback(CALLBACK *pcallback)
{
    processNotify *ppn = NULL;
    dbCommon  *precord;
    notifyPvt *pnotifyPvt;

    callbackGetUser(ppn,pcallback);
    pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt;
    precord = dbChannelRecord(ppn->chan);
    dbScanLock(precord);
    epicsMutexMustLock(pnotifyGlobal->lock);
    assert(precord->ppnr);
    assert(pnotifyPvt->state == notifyRestartCallbackRequested ||
           pnotifyPvt->state == notifyUserCallbackRequested);
    assert(ellCount(&pnotifyPvt->waitList) == 0);
    if (pnotifyPvt->cancelWait) {
        if (pnotifyPvt->state == notifyRestartCallbackRequested) {
            restartCheck(precord->ppnr);
        }
        epicsEventSignal(pnotifyPvt->cancelEvent);
        epicsMutexUnlock(pnotifyGlobal->lock);
        dbScanUnlock(precord);
        return;
    }
    if(pnotifyPvt->state == notifyRestartCallbackRequested) {
        processNotifyCommon(ppn, precord);
        return;
    }
    /* All done. Clean up and call userCallback */
    pnotifyPvt->state = notifyUserCallbackActive;
    assert(precord->ppn!=ppn);
    callDone(precord, ppn);
}
Ejemplo n.º 8
0
static void srqCallback(CALLBACK *pcallback)
{
    niport *pniport;

    callbackGetUser(pniport,pcallback);
    if(!pniport->srqEnabled) return;
    pasynGpib->srqHappened(pniport->asynGpibPvt);
}
Ejemplo n.º 9
0
static void ProcessCallback(CALLBACK *pcallback)
{
    dbCommon *pRec;

    callbackGetUser(pRec, pcallback);
    if (!pRec) return;
    dbScanLock(pRec);
    (*pRec->rset->process)(pRec);
    dbScanUnlock(pRec);
}
Ejemplo n.º 10
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);
}
Ejemplo n.º 11
0
/* ---------------------------------------------------------------------- */
void myCallback_devAiAsyncGpib(CALLBACK *p_callback) {
  struct dbCommon *p_record;
  struct rset *p_rset;

  dsetLog(3, __FILE__ "[%d] -> %s \n", __LINE__, __func__ );

  callbackGetUser(p_record,p_callback);
  p_rset=(struct rset *)(p_record->rset);
  dbScanLock(p_record);	
  (*p_rset->process)(p_record);	
  dbScanUnlock(p_record);	

  dsetLog(3,  __FILE__ "[%d] <- %s \n", __LINE__, __func__ );
}
Ejemplo n.º 12
0
static void checkLinksCallback(CALLBACK *arg)
{

    calcoutRecord *prec;
    rpvtStruct   *prpvt;

    callbackGetUser(prec, arg);
    prpvt = prec->rpvt;

    dbScanLock((dbCommon *)prec);
    prpvt->cbScheduled = 0;
    checkLinks(prec);
    dbScanUnlock((dbCommon *)prec);

}
Ejemplo n.º 13
0
static void myCallback_devMbboAsyncSerial(CALLBACK *p_callback) {
  struct dbCommon *p_record;
  struct rset *p_rset;

  callbackGetUser(p_record,p_callback);
  dsetLog(3,__FILE__ "[%d] -> %s(%s)\n", __LINE__, __func__, p_record->name );

  p_rset=(struct rset *)(p_record->rset);
  dbScanLock(p_record);	
  (*p_rset->process)(p_record);
  dbScanUnlock(p_record);		

  dsetLog(3, __FILE__ "[%d] <- %s\n", __LINE__, __func__);

  return;
} 
Ejemplo n.º 14
0
static void myCallback_devAiAsyncGpib(CALLBACK *pcallback) {
  struct dbCommon *precord;
  struct rset *prset;

  dsetLog(3,__FILE__ "[%d] -> %s \n", __LINE__, __func__ );

  callbackGetUser(precord,pcallback);/* Get record attached to callback */
  prset=(struct rset *)(precord->rset);/* get deviceRecord->rset	*/

  dbScanLock(precord);
  (*prset->process)(precord);
  dbScanUnlock(precord);

  dsetLog(3,__FILE__ "[%d] <- %s \n", __LINE__, __func__ );
  return;
}
Ejemplo n.º 15
0
static void myCallback(CALLBACK *pcallback)
{
    ASDBCALLBACK	*pasdbcallback = (ASDBCALLBACK *)pcallback;
    subRecord	*precord;
    struct rset		*prset;

    callbackGetUser(precord,pcallback);
    prset=(struct rset *)(precord->rset);
    precord->val = 0.0;
    if(pasdbcallback->status) {
	recGblSetSevr(precord,READ_ALARM,precord->brsv);
	recGblRecordError(pasdbcallback->status,precord,"asInit Failed");
    }
    dbScanLock((dbCommon *)precord);
    (*prset->process)((dbCommon *)precord);
    dbScanUnlock((dbCommon *)precord);
}
Ejemplo n.º 16
0
LOCAL void myCallback(CALLBACK *pCallback)
{
    ab1771IXRecord *precord;
    recordPvt	  *precordPvt;
    int           callLock;

    callbackGetUser(precord,pCallback);
    callLock = interruptAccept;
    if(callLock)dbScanLock((void *)precord);
    precordPvt = precord->dpvt;
    precordPvt->status = (*pabDrv->getStatus)(precordPvt->drvPvt);
    if(precordPvt->status!=abSuccess) {
        switch(precordPvt->msgState) {
	case msgStateWaitInit:
	case msgStateWaitGet:
	    precordPvt->msgState = msgStateInit;
	    break;
        default:
	    errlogPrintf("ILLEGAL myCallback state: record %s\n",precord->name);
	    break;
        }
	issueError(precord,errAb,0);
    } else {
        precordPvt->err = errOK;
        switch(precordPvt->msgState) {
	case msgStateWaitInit:
	    precordPvt->msgState = msgStateGet;
	    break;;
	case msgStateWaitGet:
	    setValMsg(precord,0);
	    msgCompleteGet(precord);
	    issueAsynCallback(precord);
            break;;
        default:
	    errlogPrintf("ILLEGAL myCallback state: record %s\n",precord->name);
	    break;
	}
	if(precordPvt->err == errOK) switch(precordPvt->msgState) {
	    case msgStateInit: msgInit(precord); break;
	    case msgStateGet: msgGet(precord); break;
	    default: break;
	}
    }
    if(precordPvt->err != errOK) issueAsynCallback(precord);
    if(callLock)dbScanUnlock((void *)precord);
}
Ejemplo n.º 17
0
static void myCallback(CALLBACK *pCallback)
{
    myPvt *pmyPvt;

    callbackGetUser(pmyPvt, pCallback);
    
    pmyPvt->pass++;

    if (pmyPvt->pass == 1) {
        epicsTimeGetCurrent(&pmyPvt->pass1Time);
        callbackRequestDelayed(&pmyPvt->cb2, pmyPvt->delay);
    } else if (pmyPvt->pass == 2) {
        epicsTimeGetCurrent(&pmyPvt->pass2Time);
    } else {
        pmyPvt->resultFail = 1;
        return;
    }
}
Ejemplo n.º 18
0
void prng_cb(CALLBACK* cb)
{
  aiRecord* prec;
  struct prngState* priv;
  struct rset* prset;
  epicsInt32 raw;

  callbackGetUser(prec,cb);
  prset=(struct rset*)prec->rset;
  priv=prec->dpvt;

  raw=rand_r(&priv->seed);

  dbScanLock((dbCommon*)prec);
  prec->rval=raw;
  (*prset->process)(prec);
  dbScanUnlock((dbCommon*)prec);
}
Ejemplo n.º 19
0
/*****************************************************************************
 *
 * Link-group processing function.
 *
 * if the input link is not a constant
 *   call dbGetLink() to get the link value
 * else
 *   get the value from the DOV field
 * call dbPutLink() to forward the value to destination location
 * call processNextLink() to schedule the processing of the next link-group
 *
 * NOTE:
 *   dbScanLock is NOT held for prec when this function is called!!
 *
 ******************************************************************************/
static void processCallback(CALLBACK *arg)
{
  callbackSeq *pcb;
  seqRecord *prec;
  double	myDouble;

  callbackGetUser(pcb,arg);
  prec = pcb->pseqRecord;
  dbScanLock((struct dbCommon *)prec);

  if (seqRecDebug > 5)
    printf("processCallback(%s) processing field index %d\n", prec->name, pcb->index+1);

  /* Save the old value */
  myDouble = pcb->plinks[pcb->index]->dov;

  dbGetLink(&(pcb->plinks[pcb->index]->dol), DBR_DOUBLE,
	&(pcb->plinks[pcb->index]->dov),0,0);

  recGblGetTimeStamp(prec);

  /* Dump the value to the destination field */
  dbPutLink(&(pcb->plinks[pcb->index]->lnk), DBR_DOUBLE,
	&(pcb->plinks[pcb->index]->dov),1);

  if (myDouble != pcb->plinks[pcb->index]->dov)
  {
    if (seqRecDebug > 0)
      printf("link %d changed from %f to %f\n", pcb->index, myDouble, pcb->plinks[pcb->index]->dov);
    db_post_events(prec, &pcb->plinks[pcb->index]->dov, DBE_VALUE|DBE_LOG);
  }
  else
  {
    if (seqRecDebug > 0)
      printf("link %d not changed... %f\n", pcb->index, pcb->plinks[pcb->index]->dov);
  }

  /* Find the 'next' link-seq that is ready for processing. */
  pcb->index++;
  processNextLink(prec);

  dbScanUnlock((struct dbCommon *)prec);
  return;
}
Ejemplo n.º 20
0
static void checkLinksCallback(CALLBACK *pcallback)
{
    acalcoutRecord	*pcalc;
    rpvtStruct		*prpvt;

    callbackGetUser(pcalc, pcallback);
    prpvt = (rpvtStruct *)pcalc->rpvt;
    
	if (!interruptAccept) {
		/* Can't call dbScanLock yet.  Schedule another CALLBACK */
		prpvt->wd_id_1_LOCK = 1;  /* make sure */
		callbackRequestDelayed(&prpvt->checkLinkCb,.5);
	} else {
	    dbScanLock((struct dbCommon *)pcalc);
	    prpvt->wd_id_1_LOCK = 0;
	    checkLinks(pcalc);
	    dbScanUnlock((struct dbCommon *)pcalc);
	}
}
Ejemplo n.º 21
0
void
evgMrm::process_eos1_cb(CALLBACK *pCallback) {
    void* pVoid;
    evgSeqRam* seqRam;

    callbackGetUser(pVoid, pCallback);
    seqRam = (evgSeqRam*)pVoid;
    if(!seqRam)
        return;

    {
        interruptLock ig;
        if(seqRam->m_owner->irqStop1_queued==2)
            BITSET32(seqRam->m_owner->getRegAddr(), IrqEnable, EVG_IRQ_STOP_RAM(1));
        seqRam->m_owner->irqStop1_queued=0;
    }

    seqRam->process_eos();
}
Ejemplo n.º 22
0
static void myCallback_devAiAsyncSerial(CALLBACK *p_callback) {
  struct dbCommon *p_record;
  struct rset *p_rset;

  #ifdef DEBUG1
  printf(__FILE__ "[%d] -> %s\n", __LINE__, __func__ );
  #endif

  callbackGetUser(p_record,p_callback);
  p_rset=(struct rset *)(p_record->rset);
  dbScanLock(p_record);	
  (*p_rset->process)(p_record);
  dbScanUnlock(p_record);		

  #ifdef DEBUG1
  printf( __FILE__ "[%d] <- %s\n", __LINE__, __func__);
  #endif

  return;

} /* end_of_myCallback */
Ejemplo n.º 23
0
static void myCallbackFunc(CALLBACK *arg)
{
    myCallback *pcallback;
    boRecord *prec;

    callbackGetUser(pcallback,arg);
    prec=(boRecord *)pcallback->precord;
    dbScanLock((struct dbCommon *)prec);
    if(prec->pact) {
	if((prec->val==1) && (prec->high>0)){
	    myCallback *pcallback;
	    pcallback = (myCallback *)(prec->rpvt);
            callbackSetPriority(prec->prio, &pcallback->callback);
            callbackRequestDelayed(&pcallback->callback,(double)prec->high);
	}
    } else {
	prec->val = 0;
	dbProcess((struct dbCommon *)prec);
    }
    dbScanUnlock((struct dbCommon *)prec);
}
Ejemplo n.º 24
0
/*----------------------------------------------------------------------*/
static void myCallback_devAoAsyncGpib( CALLBACK *pcallback)
{
  struct dbCommon *precord;
  struct rset *prset;

  callbackGetUser(precord,pcallback);

  #ifdef DEBUG1
  printf( __FILE__ "[%d] -> %s(%s)\n", __LINE__ , __func__, precord->name);
  #endif

  prset = (struct rset *)(precord->rset);
  
  dbScanLock(precord);
  (*prset->process)(precord);
  dbScanUnlock(precord);

  #ifdef DEBUG1
  printf( __FILE__ "[%d] <- %s\n", __LINE__, __func__);
  #endif
}
Ejemplo n.º 25
0
void
evgMrm::process_inp_cb(CALLBACK *pCallback) {
    void* pVoid;
    callbackGetUser(pVoid, pCallback);
    evgMrm* evg = (evgMrm*)pVoid;

    {
        interruptLock ig;
        if(evg->irqExtInp_queued==2)
            BITSET32(evg->getRegAddr(), IrqEnable, EVG_IRQ_EXT_INP);
        evg->irqExtInp_queued=0;
    }
     
    epicsUInt32 data = evg->sendTimestamp();
    if(!data)
        return;

    for(int i = 0; i < 32; data <<= 1, i++) {
        if( data & 0x80000000 )
            evg->getSoftEvt()->setEvtCode(MRF_EVENT_TS_SHIFT_1);
        else
            evg->getSoftEvt()->setEvtCode(MRF_EVENT_TS_SHIFT_0);
    }
}
Ejemplo n.º 26
0
/***************************************************
* scalerVS_arm()
* Make scaler ready to count.  If ARM output is connected
* to ARM input, and GATE permits, the scaler will
* actually start counting.
****************************************************/
STATIC long scalerVS_arm(scalerRecord *psr, int val)
{
	devScalerPvt *dpvt = psr->dpvt;
	int card = dpvt->card;
	volatile char *addr;
	volatile uint16 u16;
	int i, j, retry, read_again, numBad, numGood;

	Debug2(1, "scalerVS_arm: card %d, val %d\n", card, val);

	if (card >= scalerVS_total_cards) return(ERROR);
	addr = scalerVS_state[card]->localAddr;
	callbackGetUser(psr, scalerVS_state[card]->pcallback);

	/* disable end-of-gate interrupt */
	u16 = readReg16(addr,IRQ_SETUP_OFFSET);
	writeReg16(addr,IRQ_SETUP_OFFSET, u16 & 0x07ff);

	if (val) {
		/*** start counting ***/

		/* reset counters, overflows, and overflow-IRQ source */
		writeReg16(addr,RESET_ALL_COUNTERS_OFFSET, (uint16)1);
		/* clear other IRQ's */
		writeReg16(addr,CLEAR_INTERRUPT_2_3_OFFSET, (uint16)3);

		/** Set up and enable interrupts **/
		/* Write interrupt vector to hardware */
		writeReg16(addr,IRQ_3_GATE_VECTOR_OFFSET, (uint16)(vs_InterruptVector + card));
		Debug(10,"scalerVS_arm: irq vector=%d\n", (int)readReg16(addr,IRQ_3_GATE_VECTOR_OFFSET) & 0x00ff);

		/* set end-of-gate interrupt level, and enable the interrupt */
 		u16 = readReg16(addr, IRQ_SETUP_OFFSET);
		u16 = (u16 & 0x0ff) | (vs_InterruptLevel << 8) | 0x800;
		writeReg16(addr, IRQ_SETUP_OFFSET, u16);


		/*
		 * How do I make sure the internal-gate counter is zero, and that it
		 * won't start counting as soon as ARM goes TRUE?
		 */

		/* clear hardware-done flag */
		scalerVS_state[card]->done = 0;

		/* enable all channels */
		writeReg16(addr, COUNT_ENABLE_OFFSET, 1);	/* any write enables */

		/* arm scaler */
		writeReg16(addr, ARM_OFFSET, 1);	/* any write sets ARM */

		/* Make sure trigger mode is set for internal gate. */
		/* (This was already done in write_preset().  It's ok to do it again.) */
 		u16 = readReg16(addr, CLOCK_TRIG_MODE_OFFSET);
		writeReg16(addr, CLOCK_TRIG_MODE_OFFSET, u16 | 0x0010);

		/* trigger gate */
		if (devScaler_VS_check_trig) {
			for (i=0, retry=1; retry && i<devScaler_VS_trig_retries; i++) {
				writeReg16(addr, TRIG_GATE_OFFSET, 1); /* any write triggers gate */
				/*
				 * Check status register bit 9 to make sure internal gate is open.
				 * Repeat reading until we get the same value devScaler_VS_trig_reads
				 * times in a row.
				 */
				for (read_again = 1; read_again; ) {
					for (j=0, numBad=numGood=0; j<devScaler_VS_trig_reads; j++) {
						u16 = readReg16(addr, STATUS_OFFSET);
						if (u16 & 0x0200) numGood++; else numBad++;
					}
					if (numBad == devScaler_VS_trig_reads) {
						/* we believe the gate did NOT get triggered */
						retry = 1; read_again = 0;
					} else if (numGood == devScaler_VS_trig_reads) {
						/* we believe the gate got triggered */
						retry = 0; read_again = 0;
					}
				}
			}
			if (retry) {
				printf("scalerVS_arm: %d trigger attempts apparently failed\n", i);
			} else if (i >= devScaler_VS_trig_retry_report) {
				Debug(1,"scalerVS_arm: trigger succeeded after %d retries.\n", i);
			}
		} else {
			writeReg16(addr, TRIG_GATE_OFFSET, 1); /* any write triggers gate */
		}

		Debug2(5,"scalerVS_arm: gate open; SR=0x%x; irq vector=%d\n",
			readReg16(addr, STATUS_OFFSET),
			(int)readReg16(addr,IRQ_3_GATE_VECTOR_OFFSET) & 0x00ff);

	} else {
		/*** stop counting ***/
		/* disarm scaler */
		writeReg16(addr, DISARM_OFFSET, 1);	/* any write resets ARM */

		/*
		 * Stop counter (change trigger mode from internal gate to external gate
		 * (external gate should be 1?)
		 */
		u16 = readReg16(addr, CLOCK_TRIG_MODE_OFFSET);
		writeReg16(addr, CLOCK_TRIG_MODE_OFFSET, u16 & 0x000f);

		/* set hardware-done flag */
		scalerVS_state[card]->done = 1;

	}

	return(0);
}
Ejemplo n.º 27
0
/***************************************************
* scalerVS_write_preset()
* This hardware has no preset capability, but we can set a time gate.
* What we do here is put the hardware in "trigger" mode, set the gate-clock
* frequency and the number of gate-clock periods to count for.  We're going to
* get called once for each channel, but we do all the real work on the first call.
* From then on, we just make sure the presets are zero, and fix them if they aren't.
****************************************************/
STATIC long scalerVS_write_preset(scalerRecord *psr, int signal, long val)
{
 	devScalerPvt *dpvt = psr->dpvt;
	int card = dpvt->card;
	epicsInt32 *ppreset;
	unsigned short *pgate;
	volatile char *addr;
	unsigned short gate_freq_ix;
	double gate_time, gate_freq, gate_periods;

	if (devScaler_VSDebug >= 5) {
		printf("%s(%d):",__FILE__,__LINE__);
		printf("scalerVS_write_preset: card %d, signal %d, val %ld\n", card, signal, val);
	}

	if (card >= scalerVS_total_cards) return(ERROR);
	if (signal >= MAX_SCALER_CHANNELS) return(ERROR);

	addr = scalerVS_state[card]->localAddr;
	callbackGetUser(psr, scalerVS_state[card]->pcallback);

	if (signal > 0) {
		if (val != 0) {
			ppreset = &(psr->pr1);
			ppreset[signal] = 0;
			db_post_events(psr,&(ppreset[signal]),DBE_VALUE);
			pgate = &(psr->g1);
			pgate[signal] = 0;
			db_post_events(psr,&(pgate[signal]),DBE_VALUE);
		}
		return(0);
	}

	if (psr->g1 != 1) {
		psr->g1 = 1;
		db_post_events(psr,&(psr->g1),DBE_VALUE);
	}

	/*** set count time ***/
	gate_time = val / psr->freq;
	/*
	 * find largest gate-clock frequency that will allow us to specify the
	 * requested count time with the 16-bit gate-preset register.  Note that
	 * the scaler counts for one extra clock cycle, so we allow 0xffff + 1
	 * = 65536 cycles.
	 */
	gate_freq_ix = 0;
	do {
		gate_freq = gate_freq_table[gate_freq_ix];
		gate_periods =  gate_time * gate_freq;
		if (devScaler_VSDebug >= 10) {
		        printf("%s(%d):",__FILE__,__LINE__);
			printf("scalerVS_write_preset: try f=%.0f, n=%.0f, ix=%d\n",
				gate_freq, gate_periods, gate_freq_ix);	
		}
	} while ((gate_periods > 65536) && (++gate_freq_ix < GATE_FREQ_TABLE_LENGTH));

	if ((gate_periods < 4) && (gate_freq_ix == 0)) {
		/* The scaler can't count this short.  Just count as short as possible */
		printf("devScaler_VS: min. counting time is 4E-7 seconds.\n");
	}

	/* docs recommend min of 4 periods; we're going to subtract 1 before writing. */
	if (gate_periods < 5) gate_periods = 5;

	if ((gate_periods > 65536) && (gate_freq_ix >= GATE_FREQ_TABLE_LENGTH)) {
		/* The scaler can't count this long.  Just count as long as possible */
		printf("devScaler_VS: max. counting time is 655.36 seconds.\n");
		gate_periods = 65536;
		gate_freq_ix = GATE_FREQ_TABLE_LENGTH - 1;
	}

	/* set clock frequency, and specify that software should trigger gate-start */
	writeReg16(addr, CLOCK_TRIG_MODE_OFFSET, gate_freq_bits[gate_freq_ix] | 0x10);

	/* Set the gate-size register to the number of clock periods to count. */
	/* Scaler must be in trigger mode at the time gate size is written. */
	/* Docs say to specify (desired_clock_periods - 1) */
	writeReg16(addr, INTERNAL_GATE_SIZE_OFFSET, (uint16)(gate_periods-1));

	/* save preset and frequency mask in scalerVS_state */
	scalerVS_state[card]->gate_periods = gate_periods;
	scalerVS_state[card]->gate_freq_ix = gate_freq_ix;

	/* tell record what preset and clock rate we're using  */
	psr->pr1 = gate_periods;
	psr->freq = gate_freq_table[gate_freq_ix];

	Debug2(10,"scalerVS_write_preset: gate_periods=%f, gate_freq=%f\n",
		gate_periods, gate_freq);

	return(0);
}