Пример #1
0
/**************************************************
* scalerEndOfGateISRSetup()
***************************************************/
STATIC int scalerEndOfGateISRSetup(int card)
{
	long status;
	volatile char *addr;
	volatile uint16 u16;

	Debug(5, "scalerEndOfGateISRSetup: Entry, card #%d\n", card);
	if (card >= scalerVS_total_cards) return(ERROR);
	addr = scalerVS_state[card]->localAddr;

	status = devConnectInterruptVME(vs_InterruptVector + card,
		(void *) &scalerEndOfGateISR, (void *)card);
	if (!RTN_SUCCESS(status)) {
		errPrintf(status, __FILE__, __LINE__, "Can't connect to vector %d\n",
			  vs_InterruptVector + card);
		return (ERROR);
	}

	/* write interrupt level to hardware, and tell EPICS to enable that level */
	u16 = readReg16(addr,IRQ_SETUP_OFFSET) & 0x0ff;
	/* OR in level for end-of-gate interrupt */
	writeReg16(addr,IRQ_SETUP_OFFSET, u16 | (vs_InterruptLevel << 8));
	status = devEnableInterruptLevelVME(vs_InterruptLevel);
	if (!RTN_SUCCESS(status)) {
		errPrintf(status, __FILE__, __LINE__,
			  "Can't enable enterrupt level %d\n", vs_InterruptLevel);
		return (ERROR);
	}
	Debug(5, "scalerEndOfGateISRSetup: Wrote interrupt level, %d, to hardware\n",
	      vs_InterruptLevel);

	/* Write interrupt vector to hardware */
	writeReg16(addr,IRQ_3_GATE_VECTOR_OFFSET, (uint16)(vs_InterruptVector + card));
	Debug(5, "scalerEndOfGateISRSetup: Wrote interrupt vector, %d, to hardware\n",
	      vs_InterruptVector + card);

	Debug(5, "scalerEndOfGateISRSetup: Read interrupt vector, %d, from hardware\n",
	      readReg16(addr,IRQ_3_GATE_VECTOR_OFFSET) & 0x0ff);

	Debug(5, "scalerEndOfGateISRSetup: Exit, card #%d\n", card);
	return (OK);
}
Пример #2
0
static void
inithooks(initHookState state) {
    epicsUInt8 lvl;
    switch(state) {
        case initHookAfterInterruptAccept:
            epicsAtExit(&evgShutdown, NULL);
            mrf::Object::visitObjects(&enableIRQ, 0);
            for(lvl=1; lvl<=7; ++lvl) {
                if (vme_level_mask&(1<<(lvl-1))) {
                    if(devEnableInterruptLevelVME(lvl)) {
                        printf("Failed to enable interrupt level %d\n",lvl);
                        return;
                    }
                }
            }

        break;

    /*
     * Enable interrupts after IOC has been started (this is need for cPCI version)
     *
     * Change by: tslejko
     * Reason: cPCI EVG support
     */
    case initHookAtIocRun:
        epicsAtExit(&evgShutdown, NULL);
        mrf::Object::visitObjects(&enableIRQ, 0);
        break;

    /*
     * callback for updating SFP info gets called here for the first time.
     */
    case initHookAfterCallbackInit:
        mrf::Object::visitObjects(&startSFPUpdate, 0);
        break;

    default:
        break;
    }
}
Пример #3
0
void
xycom566setup(
      int id,
      int cbase,
      int dbase,
      int level,
      int vec,
      int bipol
){
  xy566 *card;
  volatile epicsUInt8  **cb;
  volatile epicsUInt16 **db;
  epicsUInt16 junk;

  if(cbase<0 || cbase>0xffff){
    printf("config (A16) out of range\n");
    return;
  }
  if(dbase<0 || dbase>0xffffff){
    printf("data (A24) out of range\n");
    return;
  }

  if(level<0 || level>7){
    printf("Level out of range (0->7)\n");
    return;
  }
  if(vec<0 || vec>0xff){
    printf("Vector out of range (0->255)\n");
    return;
  }

  card=get566(id);
  if(!!card){
    printf("ID %d already exists\n",id);
    return;
  }

  card=malloc(sizeof(xy566));
  if(!card){
    printf("Out of memory!\n");
    return;
  }

  memset(&card->dlen,0,sizeof(card->dlen));
  memset(&card->cb_irq,0,sizeof(card->cb_irq));

  card->id=id;
  card->fail=0;
  card->clk_div=0; /* stc uninitialized */
  card->use_seq_clk=0;
  ellInit(&card->seq_ctor);

  if(!bipol)
    card->nchan=32;
  else
    card->nchan=16;
  card->ivec=vec;

  card->base_addr=cbase;
  card->data_addr=dbase;

  cb=&card->base;
  db=&card->data_base;

  if(devBusToLocalAddr(atVMEA16, card->base_addr, (volatile void **)cb)){
    printf("Failed to map A16 %lx for card %x\n", (unsigned long)card->base_addr,id);
    free(card);
    return;
  }

  if(devBusToLocalAddr(atVMEA24, card->data_addr, (volatile void **)db)){
    printf("Failed to map A24 %lx for card %x\n", (unsigned long)card->data_base,id);
    free(card);
    return;
  }

  if(devReadProbe(2, card->base+U16_XY566_CSR, &junk)){
    printf("Failed to read A16 %lx for card %x\n", (unsigned long)(card->base+U16_XY566_CSR),id);
    free(card);
    return;
  }

  if(devReadProbe(2, card->data_base, &junk)){
    printf("Failed to read A24 %lx for card %x\n", (unsigned long)(card->data_base),id);
    free(card);
    return;
  }

  WRITE16(card->base, XY566_CSR, XY566_CSR_RST); /* Reset */
  /* turn on green and red to indicate init start */
  WRITE16(card->base, XY566_CSR, XY566_CSR_GRN);

  WRITE16(card->base, XY566_RAM, 0);
  WRITE8(card->base, XY566_SEQ, 0);

  card->guard=epicsMutexMustCreate();
  scanIoInit(&card->seq_irq);
  callbackSetCallback(xycom566isrcb, &card->cb_irq);
  callbackSetPriority(priorityHigh, &card->cb_irq);
  callbackSetUser(card, &card->cb_irq);

  WRITE8(card->base, XY566_VEC, vec);

  devEnableInterruptLevelVME(level);
  assert(devConnectInterruptVME(vec, xycom566isr, card)==0);

  /* Configure card
   * Mode: continuous sequence (default)
   * 16 bit conversion (default)
   * sequence controller disable (will be enabled during drvsup init)
   */
  WRITE16(card->base, XY566_CSR,
    XY566_CSR_GRN);

  ellAdd(&xy566s,&card->node);
}