Пример #1
0
/*Constructor */
drvSIS3801::drvSIS3801(const char *portName, int baseAddress, int interruptVector, int interruptLevel, 
                       int maxChans, int maxSignals)
  :  drvSIS38XX(portName, maxChans, maxSignals)

{
  int status;
  epicsUInt32 controlStatusReg;
  epicsUInt32 moduleID;
  static const char* functionName="SIS3801";

  setIntegerParam(SIS38XXModel_, MODEL_SIS3801);
  
  /* Call devLib to get the system address that corresponds to the VME
   * base address of the board.
   */
  status = devRegisterAddress("drvSIS3801",
                               SIS3801_ADDRESS_TYPE,
                               (size_t)baseAddress,
                               SIS3801_BOARD_SIZE,
                               (volatile void **)&registers_);

  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: %s, Can't register VME address %p\n", 
              driverName, functionName, portName, baseAddress);
    return;
  }
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: Registered VME address: 0x%lX to local address: %p size: 0x%X\n", 
            driverName, functionName, (long)baseAddress, registers_, SIS3801_BOARD_SIZE);

  /* Probe VME bus to see if card is there */
  status = devReadProbe(4, (char *) &registers_->csr_reg,
                       (char *) &controlStatusReg);
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: devReadProbe failure = %d\n", 
              driverName, functionName, status);
    return;
  }

  /* Get the module info from the card */
  moduleID = (registers_->irq_reg & 0xFFFF0000) >> 16;
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: module ID=%x\n", 
            driverName, functionName, moduleID);
  firmwareVersion_ = (registers_->irq_reg & 0x0000F000) >> 12;
  setIntegerParam(SIS38XXFirmware_, firmwareVersion_);
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: firmware=%d\n",
            driverName, functionName, firmwareVersion_);

  // Create the mutex used to lock access to the FIFO
  fifoLockId_ = epicsMutexCreate();

  /* Reset card */
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: resetting port %s\n", 
            driverName, functionName, portName);
  registers_->key_reset_reg = 1;

  /* Clear FIFO */
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
           "%s:%s: clearing FIFO\n",
           driverName, functionName);
  resetFIFO();

  setControlStatusReg();

  /* Initialize board in MCS mode */
  setAcquireMode(ACQUIRE_MODE_MCS);

  /* Set number of readout channels to maxSignals
   * Assumes that the lower channels will be used first, and the only unused
   * channels will be at the upper end of the channel range.
   * Create a mask with zeros in the rightmost maxSignals bits,
   * 1 in all higher order bits. */
  registers_->copy_disable_reg = 0xffffffff<<maxSignals_;
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW,
            "%s:%s: setting copy disable register=0x%08x\n",
            driverName, functionName, 0xffffffff<<maxSignals_);

  /* Set up the interrupt service routine */
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: interruptServiceRoutine pointer %p\n",
            driverName, functionName, intFuncC);

  status = devConnectInterruptVME(interruptVector, intFuncC, this);
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: Can't connect to vector % d\n", 
              driverName, functionName, interruptVector);
    return;
  }
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: Connected interrupt vector: %d\n\n",
            driverName, functionName, interruptVector);
  
  /* Write interrupt level to hardware */
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: irq before setting IntLevel= 0x%x\n", 
            driverName, functionName, registers_->irq_reg);

  registers_->irq_reg |= (interruptLevel << 8);

  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: irq after setting IntLevel= 0x%x\n", 
             driverName, functionName, registers_->irq_reg);

  registers_->irq_reg |= interruptVector;

  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "m%s:%s: irq config register after setting interrupt vector = 0x%08x\n", 
            driverName, functionName, registers_->irq_reg);

  /* Create the thread that reads the FIFO */
  if (epicsThreadCreate("SIS3801FIFOThread",
                         epicsThreadPriorityLow,
                         epicsThreadGetStackSize(epicsThreadStackMedium),
                         (EPICSTHREADFUNC)readFIFOThreadC,
                         this) == NULL) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: epicsThreadCreate failure\n", 
              driverName, functionName);
    return;
  }
  else
    asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: epicsThreadCreate success\n", 
            driverName, functionName);

  erase();

  /* Enable interrupts in hardware */  
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: irq before enabling interrupts= 0x%08x\n", 
            driverName, functionName, registers_->irq_reg);

  enableInterrupts();

  /* Enable interrupt level in EPICS */
  status = devEnableInterruptLevel(intVME, interruptLevel);
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: Can't enable enterrupt level %d\n", 
              driverName, functionName, interruptLevel);
    return;
  }
  
  exists_ = true;
  return;
}
Пример #2
0
/***************************************************
* initialize all software and hardware
* scaler_init()
****************************************************/
STATIC long scaler_init(int after)
{
	volatile char *localAddr;
	unsigned long status;
	void *baseAddr;
	int card, i;
	uint32 probeValue = 0;
 
	Debug(2,"scaler_init(): entry, after = %d\n", after);
	if (after || (vsc_num_cards == 0)) return(0);

	/* allocate scaler_state structures, array of pointers */
	if (scaler_state == NULL) {
	scaler_state = (struct scaler_state **)
				calloc(1, vsc_num_cards * sizeof(struct scaler_state *));

		scaler_total_cards=0;
		for (card=0; card<vsc_num_cards; card++) {
		    scaler_state[card] = (struct scaler_state *)
					calloc(1, sizeof(struct scaler_state));
		}
	}

	/* Check out the hardware. */
	for (card=0; card<vsc_num_cards; card++) {
		baseAddr = (void *)(vsc_addrs + card*CARD_ADDRESS_SPACE);

		/* Can we reserve the required block of VME address space? */
		status = devRegisterAddress(__FILE__, atVMEA32, (size_t)baseAddr,
			CARD_ADDRESS_SPACE, (volatile void **)&localAddr);
		if (!RTN_SUCCESS(status)) {
			errPrintf(status, __FILE__, __LINE__,
				"Can't register 0x%x-byte block at address %p\n", CARD_ADDRESS_SPACE, baseAddr);
			return (ERROR);
		}

		if (devReadProbe(4,(volatile void *)(localAddr+DATA_0_OFFSET),(void*)&probeValue)) {
			printf("no VSC card at %p\n",localAddr);
			return(0);
		}
		
		/* Declare victory. */
		Debug(2,"scaler_init: we own 256 bytes starting at %p\n",localAddr);
		scaler_state[card]->localAddr = localAddr;
		scaler_total_cards++;

		/* reset this card */
		writeReg16(localAddr,RESET_OFFSET,0);

		/* get this card's identification */
		scaler_state[card]->ident = readReg16(localAddr,REV_SERIAL_NO_OFFSET);
		Debug(3,"scaler_init: Serial # = %d\n", scaler_state[card]->ident);
		scaler_state[card]->card_exists = 1;

		/* get this card's type (8 or 16 channels?) */
		Debug(2,"scaler_init:Base Address=0x%8.8x\n",(int)baseAddr);
		Debug(2,"scaler_init:Local Address=0x%8.8x\n",(int)localAddr);
		scaler_state[card]->num_channels =  readReg16(localAddr,MODULE_TYPE_OFFSET) & 0x18;
		Debug(3,"scaler_init: nchan = %d\n", scaler_state[card]->num_channels);
		if (scaler_state[card]->num_channels < 8) {
		    scaler_state[card]->card_exists = 0;
		    continue;
		}
		for (i=0; i<MAX_SCALER_CHANNELS; i++) {
			scaler_state[card]->preset[i] = 0;
		}
	}

	Debug(3,"scaler_init: Total cards = %d\n\n",scaler_total_cards);

#ifdef vxWorks
    if (epicsAtExit(scaler_shutdown, 0) < 0)
		epicsPrintf ("scaler_init: epicsAtExit() failed\n"); 
#endif

	Debug(3, "%s", "scaler_init: scalers initialized\n");
	return(0);
}
Пример #3
0
LOCAL int initialise (
    const char *cardParams,
    void **pprivate,
    epicsUInt16 carrier
) {
    int params, status, mSize = 0;
    epicsUInt32 ioBase, mOrig = 0, mBase, mEnd, addr;
    volatile void *ptr;
    char *ioPtr, *mPtr = NULL;
    int space, slot;
    private_t *private;
    static const int offset[IO_SPACES][SLOTS] = {
	{ PROM_A, PROM_B, PROM_C, PROM_D },
	{ REGS_A, REGS_B, REGS_C, REGS_D }
    };

    if (cardParams == NULL ||
	strlen(cardParams) == 0) {
	/* No params or empty string, use manufacturers default settings */
	ioBase = 0x6000;
	mBase = 0xd0000000;
	params = 2;	/* Pretend, mBase is in A32 space */
    } else {
	params = sscanf(cardParams, "%i,%i,%i", &ioBase, &mBase, &mSize);
	if (params < 1 || params > 3 ||
	    ioBase > 0xfc00 || ioBase & 0x03ff ||
	    (params == 2 && mBase & 0x01ffffff) ||
	    (params == 3 && mBase & 0xff01ffff) ||
	    mSize < 0 || mSize > 2048 || mSize & 63) {
	    return S_IPAC_badAddress;
	}
    }

    if (devRegisterAddress("VIPC616", atVMEA16, ioBase, EXTENT, &ptr)) {
	return S_IPAC_badAddress;
    }
    ioPtr = (char *) ptr;              /* ioPtr points to ioBase in A16 space */

    if (params == 1) {
	/* No memory, just the A16 I/O space */
	mSize = 0;
	status = OK;
    } else if (params == 2) {
	/* A32 space, 8Mb allocated per module */
	mSize = 8 << 20;
	status = devRegisterAddress("VIPC616", atVMEA32, mBase,
				       mSize * SLOTS, &ptr);
	mPtr = (char *) ptr;            /* mPtr points to mBase in A32 space */
	mOrig = mBase;
      } else {
	/* A24 space, module size given, some slots may be hidden */
	mSize = mSize << 10;	    /* Convert size from K to Bytes */
	mEnd = (mBase & ~(mSize * SLOTS - 1)) + mSize * SLOTS;
	if (mSize) {
	    status = devRegisterAddress("VIPC616", atVMEA24, mBase,
					mEnd - mBase, &ptr);
	    mPtr = (char *) ptr;        /* mPtr points to mBase in A24 space */
	    mOrig = mBase & ~(mSize * SLOTS - 1);
	} else {
	    status = 0;
	}
    }
    if (status) {
	return S_IPAC_badAddress;
    }

    private = malloc(sizeof (private_t));
Пример #4
0
void omsMAXv::initialize(const char* portName, int numAxes, int cardNo, const char* initString, int prio,
                int stackSz, unsigned int vmeAddr, int intrVector, int level, epicsAddressType vmeAddrType, int paramCount)
{

    const char* functionName = "initialize";
    long status;
    void* probeAddr;

    Debug(32, "omsMAXv::initialize: start initialize\n" );

    controllerType = epicsStrDup("MAXv");

    // TODO check if cardNo has already been used
    this->cardNo = cardNo;
    if(cardNo < 0 || cardNo >= MAXv_NUM_CARDS){
        printf("invalid cardNo: %d", cardNo);
        return;
    }

    epicsUInt8 *startAddr;
    epicsUInt8 *endAddr;
    epicsUInt32 boardAddrSize = 0;

    if (vmeAddrType == atVMEA16)
        boardAddrSize = 0x1000;
    else if (vmeAddrType == atVMEA24)
        boardAddrSize = 0x10000;
    else if (vmeAddrType == atVMEA32)
        boardAddrSize = 0x1000000;

    // if vmeAddr == 1 Setup/Config is used and not Config2
    if (vmeAddr == 1)
        probeAddr = baseAddress + (cardNo * boardAddrSize);
    else
        probeAddr = (void*) vmeAddr;

    startAddr = (epicsUInt8 *) probeAddr;
    endAddr = startAddr + boardAddrSize;

    Debug(64, "motor_init: devNoResponseProbe() on addr %p\n", probeAddr);

    /* Scan memory space to assure card id */
    while (startAddr < endAddr) {
        status = devNoResponseProbe(vmeAddrType, (size_t) startAddr, 2);
        if (status != S_dev_addressOverlap) {
            errlogPrintf("%s:%s:%s: Card NOT found in specified address range! \n",
                                driverName, functionName, portName);
            enabled = false;
            return;
        }
        startAddr += (boardAddrSize / 10);
    }

    status = devRegisterAddress(controllerType, vmeAddrType,
                                (size_t) probeAddr, boardAddrSize,
                                (volatile void **) &pmotor);
    Debug(64, "motor_init: devRegisterAddress() status = %d\n", (int) status);

    if (status) {
        errlogPrintf("%s:%s:%s: Can't register address 0x%lx \n",
                        driverName, functionName, portName, (long unsigned int) probeAddr);
        return;
    }

    Debug(64, "motor_init: pmotor = %p\n", pmotor);

    int loopCount=15;
    while (loopCount && (pmotor->firmware_status.Bits.initializing == 1)){
        Debug(1, "MAXv port %s still initializing; status = 0x%x\n",
                portName, (unsigned int) pmotor->firmware_status.All);
        epicsThreadSleep(0.2);
        --loopCount;
    }

    Debug(64, "motor_init: check if card is ready\n");

    if (pmotor->firmware_status.Bits.running == 0)
        errlogPrintf("MAXv port %s is NOT running; status = 0x%x\n",
                portName, (unsigned int) pmotor->firmware_status.All);

    Debug(64, "motor_init: init card\n");

    FIRMWARE_STATUS fwStatus;
    fwStatus.All = pmotor->firmware_status.All;
    Debug(64, "motor_init: firmware status register: 0x%x\n", fwStatus.All);

    pmotor->IACK_vector = intrVector;

    pmotor->status1_flag.All = 0xFFFFFFFF;
    pmotor->status2_flag = 0xFFFFFFFF;
    /* Disable all interrupts */
    pmotor->status1_irq_enable.All = 0;
    pmotor->status2_irq_enable = 0;

    Debug(64, "motor_init: clear all interrupt\n");
    //sendOnly("IC");

    Debug(64, "motor_init: firmware version\n");

    /* get FirmwareVersion */
    if(getFirmwareVersion() != asynSuccess) {
        errlogPrintf("%s:%s:%s: unable to talk to controller card %d\n",
                        driverName, functionName, portName, cardNo);
        return;
    }

    if (fwMinor < 30 ){
        errlogPrintf("%s:%s:%s: This Controllers Firmware Version %d.%d is not supported, version 1.30 or higher is mandatory\n",
                        driverName, functionName, portName, fwMajor, fwMinor);
    }

    Debug(64, "motor_init: send init string\n");

    if( Init(initString, 1) != asynSuccess) {
        errlogPrintf("%s:%s:%s: unable to send initstring to controller card %d\n",
                        driverName, functionName, portName, cardNo);
        return;
    }

    useWatchdog = true;

    if (watchdogOK()) {
        Debug(64, "motor_init: enable interrupts ( vector=%d, level=%d) \n", intrVector, level);
        /* Enable interrupt-when-done if selected */
        if (intrVector) motorIsrSetup((unsigned int)intrVector, level);
    }
    else
        return;

    if (epicsAtExit(&omsMAXv::resetOnExit, this))
        errlogPrintf("%s:%s:%s: card %d, unable to register exit function\n",
                        driverName, functionName, portName, cardNo);

    return;
}
Пример #5
0
int ni1014Config(char *portNameA,char *portNameB,
    int base, int vector, int level, int priority, int noAutoConnect)
{
    niport *pniportArray[2] = {0,0};
    int    size;
    int    indPort,nports;
    long   status;

    if(nloopsPerMicrosecond==0)
	initAuxmrWait();

    nports = (portNameB==0 || strlen(portNameB)==0) ? 1 : 2;
    for(indPort=0; indPort<nports; indPort++) {
        niport *pniport;

        size = sizeof(niport);
        size += (indPort==0) ? strlen(portNameA) : strlen(portNameB);
        size += 1;
        pniport = callocMustSucceed(size,sizeof(char),"ni1014Config");
        pniportArray[indPort] = pniport;
        pniport->portName = (char *)(pniport+1);
        strcpy(pniport->portName,((indPort==0) ? portNameA : portNameB));
        pniport->base = base;
        pniport->vector = vector;
        pniport->level = level;
        pniport->eos = -1;
        pniport->waitForInterrupt = epicsEventMustCreate(epicsEventEmpty);
        callbackSetCallback(srqCallback,&pniport->callback);
        callbackSetUser(pniport,&pniport->callback);
        status = devRegisterAddress("drvNi1014", atVMEA16, pniport->base,
            PORT_REGISTER_SIZE/2,(volatile void **)&pniport->registers);
        if(status) {
            printf("%s ni1014Config devRegisterAddress failed\n",pniport->portName);
            return(-1);
        }
        /* attach the interrupt handler routines */
        status = devConnectInterrupt(intVME,pniport->vector,
            ni1014,(void *)pniport);
        if(status) {
            errMessage(status,"ni1014: devConnectInterrupt");
            return -1;
        }
        status = devConnectInterrupt(intVME,pniport->vector+1,
            ni1014Err,(void *)pniport);
        if(status) {
            errMessage(status,"ni1014: devConnectInterrupt");
            return -1;
        }
        status = devEnableInterruptLevel(intVME,pniport->level);
        if(status) {
            errMessage(status,"ni1014: devEnableInterruptLevel");
            return -1;
        }
        pniport->isPortA = (indPort==0) ? 1 : 0;
        pniport->asynGpibPvt = pasynGpib->registerPort(pniport->portName,
            ASYN_MULTIDEVICE|ASYN_CANBLOCK,
            !noAutoConnect,&gpibPort,pniport,priority,0);
        base = base + PORT_REGISTER_SIZE;
        vector += 2;
    }
    return 0;
}
Пример #6
0
/** Constructor for the drvAPS_EM class.
  * Calls the constructor for the drvQuadEM base class.
  * \param[in] portName The name of the asyn port driver to be created.
  * \param[in] baseAddr A24 base address of the VME card
  * \param[in] fiberChannel Address [0-3] of the fiber channel connected to the electrometer
  * \param[in] unidigName Name of asynPort for the Ip-Unidig driver if it is being used to generate interrupts
  * \param[in] unidigChan Channel number [0-23] of the Ip-Unidig connected to the APS_EM pulse output, if Ip-Unidig is being used.
  * \param[in] unidigDrvInfo  The drvInfo field for the data callback of the ipUnidig driver. 
  *            If not specified then asynUser->reason=0 is used.
  * \param[in] ringBufferSize The number of samples to hold in the input ring buffer.
  *            This should be large enough to hold all the samples between reads of the
  *            device, e.g. 1 ms SampleTime and 1 second read rate = 1000 samples.
  *            If 0 then default of 2048 is used.
  */
drvAPS_EM::drvAPS_EM(const char *portName, unsigned short *baseAddr, int fiberChannel,
                     const char *unidigName, int unidigChan, char *unidigDrvInfo, int ringBufferSize)
   : drvQuadEM(portName, 0, ringBufferSize),
    unidigChan_(unidigChan),
    pUInt32DigitalPvt_(NULL),
    pUInt32RegistrarPvt_(NULL)
{
    asynInterface *pasynInterface;
    asynDrvUser *pdrvUser;
    unsigned long probeVal;
    epicsUInt32 mask;
    asynStatus status;
    static const char *functionName = "drvAPS_EM";
    
    readingsAveraged_ = 0;

    if ((unidigName != 0) && (strlen(unidigName) != 0) && (strcmp(unidigName, "0") != 0)) {
        /* Create asynUser */
        pUInt32DAsynUser_ = pasynManager->createAsynUser(0, 0);

        /* Connect to device */
        status = pasynManager->connectDevice(pUInt32DAsynUser_, 
                                             unidigName, unidigChan_);
        if (status != asynSuccess) {
            errlogPrintf("initQuadEM: connectDevice failed for ipUnidig\n");
            goto error;
        }

        /* Get the asynUInt32DigitalCallback interface */
        pasynInterface = pasynManager->findInterface(pUInt32DAsynUser_, 
                                                   asynUInt32DigitalType, 1);
        if (!pasynInterface) {
            errlogPrintf("%s:%s:, find asynUInt32Digital interface failed\n", driverName, functionName);
            goto error;
        }
        pUInt32Digital_ = (asynUInt32Digital *)pasynInterface->pinterface;
        pUInt32DigitalPvt_ = pasynInterface->drvPvt;
        
        /* If the drvInfo is specified then call drvUserCreate, else assume asynUser->reason=0 */
        if (unidigDrvInfo) {
            pasynInterface = pasynManager->findInterface(pUInt32DAsynUser_, 
                                                         asynDrvUserType, 1);
            if (!pasynInterface) {
                errlogPrintf("%s:%s:, find asynDrvUser interface failed\n", driverName, functionName);
            goto error;
            }
            pdrvUser = (asynDrvUser *)pasynInterface->pinterface;
            status = pdrvUser->create(pasynInterface->drvPvt, pUInt32DAsynUser_, unidigDrvInfo, NULL, 0);
            if (status != asynSuccess) {
                errlogPrintf("%s:%s: drvUser->create failed for ipUnidig\n", driverName, functionName);
                goto error;
            }
        } else {
            pUInt32DAsynUser_->reason = 0;
        }
    }
 
    if ((fiberChannel >= 4) || (fiberChannel < 0)) {
        errlogPrintf("%s:%s:: Invalid channel # %d \n", driverName, functionName, fiberChannel);
        goto error;
    }

    if (baseAddr >= (unsigned short *)MAX_A24_ADDRESS) {
        errlogPrintf("%s:%s:: Invalid Module Address %p \n", driverName, functionName, baseAddr);
        goto error;
    }

    /* The channel # goes in bits 5 and 6 */
    baseAddr = (unsigned short *)((int)baseAddr | ((fiberChannel << 5) & 0x60));
    if (devRegisterAddress("APS_EM", atVMEA24, (int)baseAddr, 16, 
                           (volatile void**)&baseAddress_) != 0) {
        baseAddress_ = NULL;
        errlogPrintf("%s:%s: A24 Address map failed\n", driverName, functionName);
        goto error;
    }

    if (devReadProbe(4, (char *)baseAddress_, (char *)&probeVal) != 0 ) {
        errlogPrintf("%s:%s:: devReadProbe failed for address %p\n", 
                     driverName, functionName, baseAddress_);
        baseAddress_ = NULL;
        goto error;
    }

    if (pUInt32DigitalPvt_ == NULL) {
        if (epicsThreadCreate("APS_EMPoller",
                              epicsThreadPriorityMedium,
                              epicsThreadGetStackSize(epicsThreadStackMedium),
                              (EPICSTHREADFUNC)pollerThreadC,
                              this) == NULL) {
            errlogPrintf("%s:%s: quadEMPoller epicsThreadCreate failure\n", driverName, functionName);
        goto error;
        }
    }
    else {
        /* Make sure interrupts are enabled on the falling edge of the 
         * quadEM output pulse */
        pUInt32Digital_->getInterrupt(pUInt32DigitalPvt_, 
                                     pUInt32DAsynUser_, &mask,
                                     interruptOnOneToZero);
        mask |= 1 << unidigChan_;
        pUInt32Digital_->setInterrupt(pUInt32DigitalPvt_, 
                                    pUInt32DAsynUser_, mask,
                                    interruptOnOneToZero);
    }
    
    /* Set the model */
    setIntegerParam(P_Model, QE_ModelAPS_EM);
    
    /* Set the range, ping-pong and integration time to reasonable defaults */
    setRange(0);
    setPingPong(0);
    setIntegrationTime(0.001); 

    /* Send the initial settings to the board to get it talking to the 
     * electometer. These settings will be overridden by the database values 
     * when the database initializes */
    reset();
    
    /* Calling readStatus() will compute the sampleTime, which must be done before iocInit
     * or fast feedback won't work. */
    readStatus();
    
    error:
    return;
}
Пример #7
0
epicsStatus
mrmEvgSetupVME (
    const char* id,         // Card Identifier
    epicsInt32  slot,       // VME slot
    epicsUInt32 vmeAddress, // Desired VME address in A24 space
    epicsInt32  irqLevel,   // Desired interrupt level
    epicsInt32  irqVector,  // Desired interrupt vector number
    bool ignoreVersion)     // Ignore errors due to firmware checks
{
    volatile epicsUInt8* regCpuAddr = 0;
    volatile epicsUInt8* regCpuAddr2 = 0; //function 2 of regmap (fanout/concentrator specifics)
    struct VMECSRID info;
    deviceInfoT deviceInfo;

    info.board = 0; info.revision = 0; info.vendor = 0;

    deviceInfo.bus.busType = busType_vme;
    deviceInfo.bus.vme.slot = slot;
    deviceInfo.bus.vme.address = vmeAddress;
    deviceInfo.bus.vme.irqLevel = irqLevel;
    deviceInfo.bus.vme.irqVector = irqVector;
    deviceInfo.series = series_unknown;


    int status; // a variable to hold function return statuses

    try {
        if(mrf::Object::getObject(id)){
            errlogPrintf("ID %s already in use\n",id);
            return -1;
        }

        volatile unsigned char* csrCpuAddr; // csrCpuAddr is VME-CSR space CPU address for the board
        csrCpuAddr = //devCSRProbeSlot(slot);
                     devCSRTestSlot(vmeEvgIDs,slot,&info); //FIXME: add support for EVM id

        if(!csrCpuAddr) {
            errlogPrintf("No EVG in slot %d\n",slot);
            return -1;
        }

        epicsPrintf("##### Setting up MRF EVG in VME Slot %d #####\n",slot);
        epicsPrintf("Found Vendor: %08x\nBoard: %08x\nRevision: %08x\n",
                info.vendor, info.board, info.revision);

        epicsUInt32 xxx = CSRRead32(csrCpuAddr + CSR_FN_ADER(1));
        if(xxx)
            epicsPrintf("Warning: EVG not in power on state! (%08x)\n", xxx);

        /*Setting the base address of Register Map on VME Board (EVG)*/
        CSRSetBase(csrCpuAddr, 1, vmeAddress, VME_AM_STD_SUP_DATA);

        {
            epicsUInt32 temp=CSRRead32((csrCpuAddr) + CSR_FN_ADER(1));

            if(temp != CSRADER((epicsUInt32)vmeAddress,VME_AM_STD_SUP_DATA)) {
                errlogPrintf("Failed to set CSR Base address in ADER1.  Check VME bus and card firmware version.\n");
                return -1;
            }
        }

        /* Create a static string for the card description (needed by vxWorks) */
        char *Description = allocSNPrintf(40, "EVG-%d '%s' slot %d",
                                          info.board & MRF_BID_SERIES_MASK,
                                          id, slot);

        /*Register VME address and get corresponding CPU address */
        status = devRegisterAddress (
            Description,                           // Event Generator card description
            atVMEA24,                              // A24 Address space
            vmeAddress,                            // Physical address of register space
            EVG_REGMAP_SIZE,                       // Size of card's register space
            (volatile void **)(void *)&regCpuAddr  // Local address of card's register map
        );


        if(status) {
            errlogPrintf("Failed to map VME address %08x\n", vmeAddress);
            return -1;
        }


        epicsUInt32 version = checkVersion(regCpuAddr, 0x3);
        epicsPrintf("Firmware version: %08x\n", version);

        if(version == 0){
            if(ignoreVersion) {
                epicsPrintf("Ignoring version error.\n");
            }
            else {
                return -1;
            }
        }


        /* Set the base address of Register Map for function 2, if we have the right firmware version  */
        if(version >= EVG_FCT_MIN_FIRMWARE) {
            deviceInfo.series = series_300;
            CSRSetBase(csrCpuAddr, 2, vmeAddress+EVG_REGMAP_SIZE, VME_AM_STD_SUP_DATA);
            {
                epicsUInt32 temp=CSRRead32((csrCpuAddr) + CSR_FN_ADER(2));

                if(temp != CSRADER((epicsUInt32)vmeAddress+EVG_REGMAP_SIZE,VME_AM_STD_SUP_DATA)) {
                    epicsPrintf("Failed to set CSR Base address in ADER2 for FCT register mapping.  Check VME bus and card firmware version.\n");
                    return -1;
                }
            }

            /* Create a static string for the card description (needed by vxWorks) */
            char *Description = allocSNPrintf(40, "EVG-%d FOUT'%s' slot %d",
                                              info.board & MRF_BID_SERIES_MASK,
                                              id, slot);

             status = devRegisterAddress (
                Description,                           // Event Generator card description
                atVMEA24,                              // A24 Address space
                vmeAddress+EVG_REGMAP_SIZE,            // Physical address of register space
                EVG_REGMAP_SIZE*2,                     // Size of card's register space
                (volatile void **)(void *)&regCpuAddr2 // Local address of card's register map
            );

            if(status) {
                errlogPrintf("Failed to map VME address %08x for FCT mapping\n", vmeAddress);
                return -1;
            }
        }
        else {
            deviceInfo.series = series_230;
        }

        evgMrm* evg = new evgMrm(id, deviceInfo, regCpuAddr, regCpuAddr2, NULL);

        if(irqLevel > 0 && irqVector >= 0) {
            /*Configure the Interrupt level and vector on the EVG board*/
            CSRWrite8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_LEVEL, irqLevel&0x7);
            CSRWrite8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_VECTOR, irqVector&0xff);

            epicsPrintf("IRQ Level: %d\nIRQ Vector: %d\n",
                CSRRead8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_LEVEL),
                CSRRead8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_VECTOR)
            );


            epicsPrintf("csrCpuAddr : %p\nregCpuAddr : %p\nreCpuAddr2 : %p\n",csrCpuAddr, regCpuAddr, regCpuAddr2);

            /*Disable the interrupts and enable them at the end of iocInit via initHooks*/
            WRITE32(regCpuAddr, IrqFlag, READ32(regCpuAddr, IrqFlag));
            WRITE32(regCpuAddr, IrqEnable, 0);

            // VME IRQ level will be enabled later during iocInit()
            vme_level_mask |= 1 << ((irqLevel&0x7)-1);

            /*Connect Interrupt handler to vector*/
            if(devConnectInterruptVME(irqVector & 0xff, &evgMrm::isr_vme, evg)){
                errlogPrintf("ERROR:Failed to connect VME IRQ vector %d\n"
                                                         ,irqVector&0xff);
                delete evg;
                return -1;
            }
        }
    } catch(std::exception& e) {
        errlogPrintf("Error: %s\n",e.what());
        errlogFlush();
        return -1;
    }
    errlogFlush();
    return 0;

} //mrmEvgSetupVME
Пример #8
0
/*Constructor */
drvSIS3820::drvSIS3820(const char *portName, int baseAddress, int interruptVector, int interruptLevel, 
                       int maxChans, int maxSignals, bool useDma, int fifoBufferWords)
  :  drvSIS38XX(portName, maxChans, maxSignals),
     useDma_(useDma)
{
  int status;
  epicsUInt32 controlStatusReg;
  epicsUInt32 moduleID;
  static const char* functionName="SIS3820";
  
  setIntegerParam(SIS38XXModel_, MODEL_SIS3820);
  
  /* Call devLib to get the system address that corresponds to the VME
   * base address of the board.
   */
  status = devRegisterAddress("drvSIS3820",
                               SIS3820_ADDRESS_TYPE,
                               (size_t)baseAddress,
                               SIS3820_BOARD_SIZE,
                               (volatile void **)&registers_);

  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: %s, Can't register VME address 0x%x\n", 
              driverName, functionName, portName, baseAddress);
    return;
  }
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: Registered VME address: 0x%x to local address: %p size: 0x%X\n", 
            driverName, functionName, baseAddress, registers_, SIS3820_BOARD_SIZE);

  /* Call devLib to get the system address that corresponds to the VME
   * FIFO address of the board.
   */
  fifoBaseVME_ = (epicsUInt32 *)(baseAddress + SIS3820_FIFO_BASE);
  status = devRegisterAddress("drvSIS3820",
                              SIS3820_ADDRESS_TYPE,
                              (size_t)fifoBaseVME_,
                              SIS3820_FIFO_BYTE_SIZE,
                              (volatile void **)&fifoBaseCPU_);

  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: %s, Can't register FIFO address 0x%x\n", 
              driverName, functionName, portName, baseAddress + SIS3820_FIFO_BASE);
    return;
  }

  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: Registered VME FIFO address: %p to local address: %p size: 0x%X\n", 
            driverName, functionName, fifoBaseVME_, 
            fifoBaseCPU_, SIS3820_FIFO_BYTE_SIZE);

  /* Probe VME bus to see if card is there */
  status = devReadProbe(4, (char *) &(registers_->control_status_reg),
                       (char *) &controlStatusReg);
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: devReadProbe failure for address %p = %d\n", 
              driverName, functionName, &registers_->control_status_reg, status);
    return;
  }

  /* Get the module info from the card */
  moduleID = (registers_->moduleID_reg & 0xFFFF0000) >> 16;
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: module ID=%x\n", 
            driverName, functionName, moduleID);
  firmwareVersion_ = registers_->moduleID_reg & 0x0000FFFF;
  setIntegerParam(SIS38XXFirmware_, firmwareVersion_);
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: firmware=%d\n",
            driverName, functionName, firmwareVersion_);

  // Allocate FIFO readout buffer
  // fifoBufferWords input argument is in words, must be less than SIS3820_FIFO_WORD_SIZE
  if (fifoBufferWords == 0) fifoBufferWords = SIS3820_FIFO_WORD_SIZE;
  if (fifoBufferWords > SIS3820_FIFO_WORD_SIZE) fifoBufferWords = SIS3820_FIFO_WORD_SIZE;
  fifoBufferWords_ = fifoBufferWords;
#ifdef vxWorks
  fifoBuffer_ = (epicsUInt32*) memalign(8, fifoBufferWords_*sizeof(epicsUInt32));
#else
  void *ptr;
  status = posix_memalign(&ptr, 8, fifoBufferWords_*sizeof(epicsUInt32));
  if(status != 0) {
    printf("Error: posix_memalign status = %d\n", status);
  }
  fifoBuffer_ = (epicsUInt32*)ptr;
#endif
  if (fifoBuffer_ == NULL) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: posix_memalign failure for fifoBuffer_ = %d\n", 
              driverName, functionName, status);
    return;
  }
  
  dmaDoneEventId_ = epicsEventCreate(epicsEventEmpty);
  // Create the DMA ID
  if (useDma_) {
    dmaId_ = sysDmaCreate(dmaCallbackC, (void*)this);
    if (dmaId_ == 0 || (int)dmaId_ == -1) {
      asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
                "%s:%s: sysDmaCreate failed, errno=%d. Disabling use of DMA.\n",
                driverName, functionName, errno);
      useDma_ = false;
    }
  }
 
  /* Reset card */
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: resetting port %s\n", 
            driverName, functionName, portName);
  registers_->key_reset_reg = 1;

  /* Clear FIFO */
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
           "%s:%s: clearing FIFO\n",
           driverName, functionName);
  resetFIFO();
  
  // Disable 25MHz test pulses and test mode
  registers_->control_status_reg = CTRL_COUNTER_TEST_25MHZ_DISABLE;
  registers_->control_status_reg = CTRL_COUNTER_TEST_MODE_DISABLE;

  /* Set up the interrupt service routine */
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: interruptServiceRoutine pointer %p\n",
            driverName, functionName, intFuncC);

  status = devConnectInterruptVME(interruptVector, intFuncC, this);
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: Can't connect to vector % d\n", 
              driverName, functionName, interruptVector);
    return;
  }
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: Connected interrupt vector: %d\n\n",
            driverName, functionName, interruptVector);
  
  /* Write interrupt level to hardware */
  registers_->irq_config_reg &= ~SIS3820_IRQ_LEVEL_MASK;
  registers_->irq_config_reg |= (interruptLevel << 8);
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: irq after setting IntLevel= 0x%x\n", 
             driverName, functionName, registers_->irq_config_reg);

  /* Write interrupt vector to hardware */
  registers_->irq_config_reg &= ~SIS3820_IRQ_VECTOR_MASK;
  registers_->irq_config_reg |= interruptVector;
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: irq = 0x%08x\n", 
            driverName, functionName, registers_->irq_config_reg);
            
  /* Initialize board in MCS mode. This will also set the initial value of the operation mode register. */
  setAcquireMode(ACQUIRE_MODE_MCS);

  /* Create the thread that reads the FIFO */
  if (epicsThreadCreate("SIS3820FIFOThread",
                         epicsThreadPriorityLow,
                         epicsThreadGetStackSize(epicsThreadStackMedium),
                         (EPICSTHREADFUNC)readFIFOThreadC,
                         this) == NULL) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: epicsThreadCreate failure\n", 
              driverName, functionName);
    return;
  }
  else
    asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: epicsThreadCreate success\n", 
            driverName, functionName);

  erase();

  /* Enable interrupts in hardware */  
  asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, 
            "%s:%s: irq before enabling interrupts= 0x%08x\n", 
            driverName, functionName, registers_->irq_config_reg);

  registers_->irq_config_reg |= SIS3820_IRQ_ENABLE;

  /* Enable interrupt level in EPICS */
  status = devEnableInterruptLevel(intVME, interruptLevel);
  if (status) {
    asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
              "%s:%s: Can't enable enterrupt level %d\n", 
              driverName, functionName, interruptLevel);
    return;
  }
  
  exists_ = true;
  return;
}
Пример #9
0
/***************************************************
* initialize all software and hardware
* scalerVS_init()
****************************************************/
STATIC long scalerVS_init(int after)
{
	volatile char *localAddr;
	unsigned long status;
	char *baseAddr;
	int card, card_type;
	uint32 probeValue = 0;

	Debug(2,"scalerVS_init(): entry, after = %d\n", after);
	if (after || (vs_num_cards == 0)) return(0);

	/* allocate scalerVS_state structures, array of pointers */
	if (scalerVS_state == NULL) {
    	scalerVS_state = (struct scalerVS_state **)
				calloc(1, vs_num_cards * sizeof(struct scalerVS_state *));

		scalerVS_total_cards=0;
		for (card=0; card<vs_num_cards; card++) {
		    scalerVS_state[card] = (struct scalerVS_state *)
					calloc(1, sizeof(struct scalerVS_state));
		}
	}

	/* Check out the hardware. */
	for (card=0; card<vs_num_cards; card++) {
		baseAddr = (char *)(vs_addrs + card*CARD_ADDRESS_SPACE);

		/* Can we reserve the required block of VME address space? */
		status = devRegisterAddress(__FILE__, atVMEA16, (size_t)baseAddr,
			CARD_ADDRESS_SPACE, (volatile void **)&localAddr);
		if (!RTN_SUCCESS(status)) {
			errPrintf(status, __FILE__, __LINE__,
				"Can't register 2048-byte block in VME A16 at address %p\n", baseAddr);
			return (ERROR);
		}

		if (devReadProbe(4,(volatile void *)(localAddr+READ_XFER_REG_OFFSET),(void*)&probeValue)) {
			printf("scalerVS_init: no VSxx card at %p\n",localAddr);
			return(0);
		}
		
		/* Declare victory. */
		Debug(2,"scalerVS_init: we own 2048 bytes in VME A16 starting at %p\n", localAddr);
		scalerVS_state[card]->localAddr = localAddr;
		scalerVS_total_cards++;

		/* reset this card */
		/* any write to this address causes reset */
		writeReg16(localAddr,MASTER_RESET_OFFSET,0);
		/* get this card's type and serial number */
		scalerVS_state[card]->ident = readReg16(localAddr,ID_OFFSET);
		Debug(3,"scalerVS_init: Serial # = %d\n", scalerVS_state[card]->ident & 0x3FF);

		/* get this card's type */
		card_type = scalerVS_state[card]->ident >> 10;
		if ((card_type > 22) || (card_type < 16)) {
			errPrintf(status, __FILE__, __LINE__, "unrecognized module\n");
			scalerVS_state[card]->num_channels = 0;
			scalerVS_state[card]->card_exists = 0;
			/*
			 * Something's wrong with this card, but we still count it in scalerVS_total_cards.
			 * A bad card retains its address space; otherwise we can't talk to the next one.
			 */
		} else {
			scalerVS_state[card]->num_channels = VS_module_types[card_type-16].num_channels;
			scalerVS_state[card]->card_exists = 1;
		}
		Debug(3,"scalerVS_init: nchan = %d\n", scalerVS_state[card]->num_channels);
	}

	Debug(3,"scalerVS_init: Total cards = %d\n\n",scalerVS_total_cards);

#ifdef vxWorks
    if (epicsAtExit(scalerVS_shutdown, 0) < 0)
		epicsPrintf ("scalerVS_init: epicsAtExit() failed\n");
#endif
	Debug(3,"%s", "scalerVS_init: scalers initialized\n");
	return(0);
}