/* devVme18k10KB2.c */
/* devVme18k10KB2.c - Device Support Routines for VME adc board */
/*
 *    
 *      Original Author: Makoto Tobiyama
 *      Current Author:
 *      Date:            30/Jul/2012
 *
 *      Experimental Physics and Industrial Control System (EPICS)
 *
 *      Copyright 1997, KEKB.
 *
 *
 * Modification Log:
 *      16/Apr/2015 : Add reflection memory support
 * -----------------
 */


#include<vxWorks.h>
#include <vxLib.h> #include <logLib.h> #include <sysLib.h> /* #include <memLib.h> */ #include <intLib.h>
#include<types.h>
#include <stdio.h>
#include<stdioLib.h>
#include<string.h>
/* #include <sys/time.h> */
#include<vme.h>
#include<dbDefs.h>
#include<dbAccess.h>
#include<recSup.h>
#include<devSup.h>
#include <recGbl.h> #include <alarm.h>
#include<link.h>
#include <iv.h>
#include<module_types.h>
#include<longinRecord.h>
#include<longoutRecord.h>
#include<boRecord.h>
#include<biRecord.h>
#include <aiRecord.h> #include <aoRecord.h>
#include<mbbiDirectRecord.h>
#include<mbboDirectRecord.h>
#include<waveformRecord.h>
#include <stringoutRecord.h> #include <stringinRecord.h>
#include<dbScan.h>
#include <epicsMutex.h> #include <epicsExport.h> #if 1 #include </cont/VxWorks/vw68/vxworks-6.8/target/config/mv5500/sysDma.h> #include </cont/VxWorks/vw68/vxworks-6.8/target/config/mv5500/universe.h> #include <vxLib.h> #include <time.h> #include <vxAtomicLib.h> #endif static void dmaCallBackCh0( void ); static void dmaCallBackCh1( void ); struct D18k10KB2 { unsigned long board_reset; unsigned long trig_enb; unsigned long mem_trig; unsigned long mem_size; unsigned long irq_enb; unsigned long adclk_dly; unsigned long adc_rst; unsigned long adrdpt_rst; unsigned long mem_cl; unsigned long fpga_out; unsigned long dum1[2]; unsigned long board_sts; unsigned long ad_sts; unsigned long rec_mode; unsigned long harmonic; unsigned long irq_no; unsigned long irq_id; unsigned long fpga_in; unsigned long dum2; unsigned long revision; unsigned long debug; unsigned long dum3[2]; unsigned long dum4[40]; unsigned long ad_data[64]; }; struct GREFMEM { epicsUInt8 control_reg[12288]; unsigned long R_MEML[2048]; unsigned long R_MEMH[2048]; unsigned long R_MEMDR[1024]; epicsUInt8 condition[4096]; epicsUInt32 delay[4096]; epicsUInt32 opccr_alarm; epicsUInt32 tmlc8_alarm; epicsUInt32 opccr_count; epicsUInt32 tmlc8_count; epicsUInt32 mrbcm_count; epicsUInt32 drbcm_count; epicsUInt32 positron_bunch; epicsUInt32 electron_bunch; epicsUInt8 operation[4064]; epicsUInt8 RESERVE[1003520]; };
#defineStatusEnable
static long init_all(); static long init_mi_record(); static long get_mbbi_int_info(); static long init_bo_record(); static long write_bo(); static long init_bi_record(); static long read_bi(); static long read_mbbiDirect(); static long init_wf_record(); static long read_wf_record(); static long init_lo_record(); static long write_longout(); static long init_li_record(); static long read_longin(); static long init_si_record(); static long read_si(); static long init_ao_record(); static long write_ao(); static void vme18k10KB2_isr(); static int checkLink(); /* Create the dset for devBo18k10KB2 */ struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN write_bo; }devBo18k10KB2={ 5, NULL, NULL, init_bo_record, NULL, write_bo }; epicsExportAddress(dset,devBo18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_bi_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_bi; }devBi18k10KB2={ 5, NULL, NULL, init_bi_record, NULL, read_bi }; epicsExportAddress(dset,devBi18k10KB2); /* For devMbbi18k10KB2 */ struct{ long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_mi_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_mbbiDirect; }devMbbi18k10KB2={ 5, NULL, NULL, init_mi_record, get_mbbi_int_info, read_mbbiDirect }; epicsExportAddress(dset,devMbbi18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_write; DEVSUPFUN conv; }devWf18k10KB2 ={ 6, NULL, NULL, init_wf_record, NULL, read_wf_record, NULL }; epicsExportAddress(dset,devWf18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN write_longout; DEVSUPFUN special_linconv; }devLo18k10KB2={ 6, NULL, NULL, init_lo_record, NULL, write_longout, NULL }; epicsExportAddress(dset,devLo18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_longin; DEVSUPFUN special_linconv; }devLi18k10KB2={ 6, NULL, NULL, init_li_record, NULL, read_longin, NULL}; epicsExportAddress(dset,devLi18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN write_ao; DEVSUPFUN special_linconv; }devAo18k10KB2={ 6, NULL, NULL, init_ao_record, NULL, write_ao, NULL }; epicsExportAddress(dset,devAo18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_si; DEVSUPFUN special_linconv; }devSi18k10KB2={ 6, NULL, NULL, init_si_record, NULL, read_si, NULL}; epicsExportAddress(dset,devSi18k10KB2); struct ioCard { volatile struct D18k10KB2 *card; /* address of this card */ epicsMutexId lock; /* semaphore */ IOSCANPVT ioscanpvt; }; struct memCard { volatile struct GREFMEM *rmem; epicsMutexId lock; }; #define CONST_NUM_LINKS 10 /* #define STATIC */ #define DEBUG_ON static int debug_flag = 0; static unsigned long Base_IO; static int D18k10KB2_num_links; volatile static struct ioCard cards[CONST_NUM_LINKS]; volatile static struct memCard mems; static int init_flag = 0; static unsigned short INT_VEC_BASE; static long HER_LIM,LER_LIM; static long HER_LIMA,LER_LIMA; static int LER_OVER_ONE =0; static int HER_OVER_ONE =0; static double cal_fac_bcm_H = 7.8125e-3; static double cal_fac_bcm_L = 7.8125e-3; static unsigned long BASE5565; /* static char *CARD5565; */ static epicsUInt8 bc_o[5120]; static epicsUInt32 Rmem_watchdog; static unsigned char int_level; #if 1 static unsigned long *gplTmpDataB; /* 256K Word * 4ch(256*1024*2*4/4) */ #endif /* #define R_MEM_LER ((void*)(CARD5565 + 0x3000)) #define R_MEM_HER ((void*)(CARD5565 + 0x5000)) */ int dev18k10KB2Config(ncards,a32base,irq,intvecbase) int ncards; long a32base; int irq; int intvecbase; { D18k10KB2_num_links = ncards; Base_IO = a32base; int_level= irq; INT_VEC_BASE=intvecbase; logMsg("dev18k10KB2 NumLink= %d BaseIO= %lx IRQ = %d INTVECBASE =%x\n",D18k10KB2_num_links,Base_IO,int_level,INT_VEC_BASE,0,0); init_all(0); return 0; } static long init_all(after) int after; { int cardNum, chanNum; unsigned char probeVal[4]; volatile struct D18k10KB2 *p; volatile struct GREFMEM *p2; unsigned short mem_pat; int rtn ; if (init_flag != 0 ) return(OK); init_flag = 1; #if 1 if ( sysVmeDmaInit() != OK ) { logMsg("sysVmeDmaInit() Error!!\n",0,0,0,0,0,0); return(ERROR); } logMsg("sysVmeDmaInit() OK!!\n",0,0,0,0,0,0); #endif if (sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,(char *)Base_IO,(char **)&p) == ERROR)
{ logMsg("18k10KB2: cannot find extended address space\n",0,0,0,0,0,0); return(ERROR); }
/* if (debug_flag >0) logMsg("18k10KB2 address %x\n",(int)p,0,0,0,0,0); */ for (cardNum=0; cardNum< D18k10KB2_num_links; cardNum++) { if (vxMemProbe((char*) &(p->board_reset), READ, 4, (char *)&probeVal[0])!= OK) { logMsg("No 18k10KB2 with cardNum= %d\n probe= %x\n",cardNum,(int)p,0,0,0,0);
cards[cardNum].card = NULL;
} else {
if (debug_flag >0)
logMsg("Found 18k10KB2 with cardNum= %d\n address= %x\n",cardNum,(int)p,0,0,0,0);
cards[cardNum].card = p; /* Remember address of the board */ scanIoInit(&(cards[cardNum].ioscanpvt)); logMsg("scan IO init %x\n",(int)cards[cardNum].ioscanpvt,0,0,0,0,0);
} if (debug_flag >0) logMsg("IntSet for 18K10KB with address %x\n",(int)p->irq_enb,0,0,0,0,0); p->irq_enb = 0x00; cards[cardNum].lock = epicsMutexMustCreate(); epicsMutexUnlock((cards[cardNum].lock)); /* Init the board lock */ p++; } gplTmpDataB = memalign( 256, 64*4 ); logMsg("init DMA setting\n",0,0,0,0,0,0); /* 256 x 4ch */ if (sysVmeDmaCnfgSet(DCTL_VDW_32 | DCTL_VCT_BLK, DCTL_VAS_A32, DCTL_PGM_DATA, DCTL_SUPER_SUP) != OK){ logMsg("devVme18k10KB2 error DMA setting\n",0,0,0,0,0,0);} BASE5565=0x0D000000; if (sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,(char *)BASE5565,(char **)&p2) == ERROR) { logMsg("devVme18k10KB2 : cannot find extended address space for RefMem\n",0,0,0,0,0,0); return(ERROR); } else { logMsg("devVme18k10KB2 allocated memory for RefMem\n",0,0,0,0,0,0); } if (vxMemProbe((char*) &(p2->mrbcm_count),READ, 4, (char *)&probeVal[0])!= OK) { logMsg("No refmem probe= %x\n",(int)p2,0,0,0,0,0);
mems.rmem = NULL;
} else { logMsg("Found Rmem\n",0,0,0,0,0,0); mems.rmem = p2; mems.lock = epicsMutexMustCreate(); epicsMutexUnlock((mems.lock)); } LER_LIM =(int)(1.6/cal_fac_bcm_L); HER_LIM =(int)(1.3/cal_fac_bcm_H); LER_LIMA = 253; HER_LIMA = 253; Rmem_watchdog = 0; mems.rmem->mrbcm_count = Rmem_watchdog; return(OK); } /****************************************************************** * * Interrupt service routine * *******************************************************************/ static void vme18k10KB2_isr(pmbbi)
struct mbbiDirectRecord*pmbbi;
{ unsigned char mode; short cardN; unsigned long ad; cardN = pmbbi->inp.value.vmeio.card; ad = (cards[cardN].card->ad_sts) & 0xff; cards[cardN].card->trig_enb = 0x0; scanIoRequest(cards[cardN].ioscanpvt); /* logMsg("18k10KB2 int called \n");*/ return; } /************************************************************************** * * BO Initialization (Called one time for each BO PowerUT card record) * **************************************************************************/ static long init_bo_record(pbo) struct boRecord *pbo; { pbo->mask = 1;
return(0);
} /************************************************************************** * * Perform a write operation from a BO record * **************************************************************************/ static long write_bo(pbo) struct boRecord *pbo; { short cardN; cardN = pbo->out.value.vmeio.card; if (checkLink(cardN) == ERROR) { logMsg("Error--- No 18k10KB2 for card %d\n",cardN,0,0,0,0,0); return(ERROR); } if (debug_flag>5) logMsg("BO\n",0,0,0,0,0,0); epicsMutexMustLock((cards[cardN].lock)); switch(pbo->out.value.vmeio.signal){ case 0 : /* board reset */ cards[cardN].card->board_reset = 0x1 & (pbo->val); break; case 1 : /* trg enable */ cards[cardN].card->trig_enb = 0x1 & (pbo->val); break; case 2 : /* adc reset */ cards[cardN].card->adc_rst = 0x1 & (pbo->val); break; case 3 : /* adrdpt_rst */ cards[cardN].card->adrdpt_rst = 0x1 & (pbo->val); break; case 4 : /* mem clear */ cards[cardN].card->mem_cl = 0x1 & (pbo->val); break; default: logMsg("write_bo called with card %d\n",cardN,0,0,0,0,0); break; } epicsMutexUnlock((cards[cardN].lock)); return(0); } static long init_bi_record(pbi) struct biRecord *pbi; { pbi->mask = 1; return(0); } static long read_bi(pbi) struct biRecord *pbi; { short cardN; cardN = pbi ->inp.value.vmeio.card; if (checkLink(cardN) == ERROR) return(ERROR); switch(pbi->inp.value.vmeio.signal){ case 0 : pbi->rval = cards[cardN].card->board_reset & pbi->mask; break; case 1 : pbi->rval = cards[cardN].card->trig_enb & pbi->mask; break; case 2 : pbi->rval = cards[cardN].card->adc_rst & pbi->mask; break; case 3 : pbi->rval = cards[cardN].card->adrdpt_rst & pbi->mask; break; case 4 : pbi->rval = cards[cardN].card->rec_mode & pbi->mask; break; default : break; } return(0); } static long init_lo_record(plongout) struct longoutRecord *plongout; { return(0); } static long write_longout(plongout) struct longoutRecord *plongout; { short cardN; cardN = plongout->out.value.vmeio.card; if (debug_flag >10) logMsg("write_lo called with card %d\n",cardN,0,0,0,0,0); if (checkLink(cardN) == ERROR) return(ERROR); epicsMutexMustLock((cards[cardN].lock)); switch(plongout->out.value.vmeio.signal){ case 0 : /* mem_trig */
cards[cardN].card->mem_trig = 0x3 & (plongout->val); break;
case 1 : /* mem_size */ cards[cardN].card->mem_size = 0x3 & (plongout ->val);
break;
case 2 : /* interrupt enable */
cards[cardN].card->irq_enb = 0x3 & (plongout -> val); break;
case 3 : /* adclk_dly */ cards[cardN].card->adclk_dly = 0x3f & (plongout->val); break; default: break; } epicsMutexUnlock((cards[cardN].lock)); return(OK); } static long init_li_record(plongin) struct longinRecord *plongin; { return(0); } static long read_longin(plongin) struct longinRecord *plongin; { short cardN; if (debug_flag >10) logMsg("read_longin called...\n",0,0,0,0,0,0); cardN = plongin->inp.value.vmeio.card; if (checkLink(cardN) == ERROR) return(ERROR); switch(plongin->inp.value.vmeio.signal){ case 0: /* mem_trig */ plongin->val = (cards[cardN].card->mem_trig) & 0x3; break; case 1: /* mem_size */ plongin->val = (cards[cardN].card->mem_size) & 0x3; break; case 2: /* IRQ_ENB */ plongin->val = (cards[cardN].card->irq_enb) & 0x3; break; case 3 : /* ADCLK_DLY */ plongin->val = (cards[cardN].card->adclk_dly) & 0x3f; break; case 4: /* harmonic */ plongin->val = (cards[cardN].card->harmonic) & 0x3;
break;
case 5: /* IRQ_NO */ plongin->val = (cards[cardN].card->irq_no) &0xff; break; case 6: /* irq_id */ plongin->val = (cards[cardN].card->irq_id) & 0xff; break; default: break; } return(OK); } static long init_ao_record(pao) struct aoRecord *pao; { pao->eslo = 1.0; return(0); } static long write_ao(pao) struct aoRecord *pao; { double f1; switch(pao->out.value.vmeio.signal){ case 0 : f1 = pao->val; LER_LIM = (int)(f1/cal_fac_bcm_L); break; case 1: f1 = pao->val; HER_LIM = (int)(f1/cal_fac_bcm_H); break; case 2 : f1 = pao->val; if (f1 <4e-3) f1= 8.1731422e-3; /* 7.44842e-3; */ cal_fac_bcm_L = f1; break; case 3 : f1 = pao->val;
/* 7.102273e-3 */
if (f1 <4e-3) f1=8.8861577e-3; cal_fac_bcm_H = f1; break; default : break; }
return(0); } static long init_mi_record(pmbbi)
struct mbbiDirectRecord*pmbbi;
{ short cardNum; short signal; cardNum = pmbbi->inp.value.vmeio.card; signal = pmbbi->inp.value.vmeio.signal; if (signal == 1) { if (intConnect(INUM_TO_IVEC(INT_VEC_BASE + cardNum),
(VOIDFUNCPTR)vme18k10KB2_isr, (int)pmbbi) != OK)
logMsg("devVme18k10KB2: Interrupt connect failed for card %d %x\n",pmbbi->inp.value.vmeio.card,(int)INUM_TO_IVEC(INT_VEC_BASE + cardNum),0,0,0,0); logMsg("intConnect 0x%x\n",(int)pmbbi,0,0,0,0,0);
sysIntEnable(int_level); logMsg("devVme18k10KB2 int set for int 0x%x\n",int_level,0,0,0,0,0); } return(0); } static long read_mbbiDirect(pmbbi) struct mbbiDirectRecord *pmbbi; { short cardN; cardN = pmbbi->inp.value.vmeio.card; if (debug_flag >5) logMsg("read_mbbiDirect called with card %d\n",cardN,0,0,0,0,0); if (checkLink(cardN) == ERROR) return(ERROR); switch(pmbbi->inp.value.vmeio.signal){ case 0: /* board_sts */ pmbbi->rval = (cards[cardN].card->board_sts) & 0x7f; break; case 1: /* AD_STS */ pmbbi->rval = (cards[cardN].card->ad_sts) & 0xff; break; default: break; } if (debug_flag >5) logMsg("mbbi read complete \n",0,0,0,0,0,0); return(OK); } static long get_mbbi_int_info(cmd,pmbbi,ppvt) int cmd; struct mbbiDirectRecord *pmbbi; IOSCANPVT *ppvt; { short cardN; unsigned char stat; cardN = pmbbi->inp.value.vmeio.card; *ppvt = cards[cardN].ioscanpvt; if (debug_flag >5) logMsg("mbbi_INT CALLED\n",0,0,0,0,0,0); return(0); } static long init_wf_record(pwf)
struct waveformRecord*pwf;
{ /* short cardNum; cardNum = pwf->inp.value.vmeio.card; if (intConnect(INUM_TO_IVEC(INT_VEC_BASE + cardNum),
(VOIDFUNCPTR)vme18k10KB2_isr, (int)pwf) != OK)
logMsg("devVme18k10KB2: Interrupt connect failed for card %d\n",pwf->inp.value.vmeio.card); logMsg("intConnect 0x%x\n",pwf);
sysIntEnable(int_level); logMsg("devVme18k10KB2 int set for int 0x%x\n",int_level); */ return(0); } static long read_wf_record(pwf)
struct waveformRecord*pwf;
{ short cardN; unsigned long a1,a2; long i,ii,jj,start,is; unsigned long temp_tpos; unsigned long uuu; float* f_thing = (float*)pwf->bptr; int over_flag = 0; int emer_flag = 0; int over_one; volatile int temp1,temp2,temp3; #if 1 STATUS iDmaStartRc; unsigned int p1=0,p2=0,p3=0,p4=0,pSta=0; #endif #if 1 struct timespec oTimeSpec1; struct timespec oTimeSpec2; struct timespec oTimeSpec3; struct timespec oTimeSpec4; struct timespec oTimeSpec5; /* clock_gettime( CLOCK_REALTIME, &oTimeSpec1 ); */ #endif cardN = pwf->inp.value.vmeio.card; if (debug_flag >5) logMsg("read_wf_record called with card number of %d\n",cardN,0,0,0,0,0); if (checkLink(cardN) == ERROR) return(ERROR); /* logMsg("Waveform type %x\n",pwf->ftvl,0,0,0,0,0); */ sysUnivVERRClr(); if(sysVmeDmaStatusGet(&pSta) != OK )
{ logMsg("sysVmeDmaStatusGet() Error!!\n", 0, 0, 0, 0, 0,0); }
if(sysVmeDmaCnfgGet(&p1,&p2,&p3,&p4) != OK )
{ logMsg("sysVmeDmaCnfgGet() Error!!\n", 0, 0, 0, 0, 0,0); }
VX_MEM_BARRIER_RW(); for (is=0;is<20;is++){
iDmaStartRc = sysVmeDmaV2LCopy( &cards[cardN].card->ad_data[0], gplTmpDataB+0, 64*4 );
if(iDmaStartRc != 0) { logMsg("-->sysVmeDmaV2LCopy() error!! Rc[%d] card[%d]\n", iDmaStartRc, cardN, 0, 0 ,0, 0 ); } if (cardN==0) { iDmaStartRc = sysVmeDmaL2VCopy( gplTmpDataB,&mems.rmem->R_MEML[is*64],64*4 ); } else { iDmaStartRc = sysVmeDmaL2VCopy( gplTmpDataB,&mems.rmem->R_MEMH[is*64],64*4 ); } for ( ii = 0; ii < 64 ; ii++ ) { bc_o[is*256+ii*4+0] = (unsigned char)( (gplTmpDataB[ii] >>24)&0xff); bc_o[is*256+ii*4+1] = (unsigned char)( (gplTmpDataB[ii] >>16)& 0xff); bc_o[is*256+ii*4+2] = (unsigned char)((gplTmpDataB[ii] >>8) &0xff); bc_o[is*256+ii*4+3] = (unsigned char)((gplTmpDataB[ii]) & 0xff);
} if (cardN ==0) /* for LER */ { over_one = 0; emer_flag =0; for (i=0; i<5120;i++) { f_thing[i]=cal_fac_bcm_L*bc_o[i]; if (bc_o[i]>LER_LIM) over_one =1; if (bc_o[i]>LER_LIMA) emer_flag =1; } if ((over_one == 1) && (LER_OVER_ONE==1)) { over_flag = 1; } else if (over_one == 1) { LER_OVER_ONE = 1; } else { LER_OVER_ONE = 0; over_flag = 0; } epicsMutexMustLock(mems.lock); for (i=0; i<5120;i++){ f_thing[i]=cal_fac_bcm_L * bc_o[i]; } epicsMutexUnlock(mems.lock); }
else { over_one = 0; emer_flag =0; for (i=0; i<5120;i++) { f_thing[i]=cal_fac_bcm_H*bc_o[i]; if (bc_o[i]>HER_LIM) over_one =1; if (bc_o[i]>HER_LIMA) emer_flag =1; } if ((over_one == 1) && (HER_OVER_ONE==1)) { over_flag = 1; } else if (over_one == 1) { HER_OVER_ONE = 1; } else { HER_OVER_ONE = 0; over_flag = 0; } epicsMutexMustLock(mems.lock); for (i=0; i<5120;i++){ f_thing[i]=cal_fac_bcm_L * bc_o[i]; } epicsMutexUnlock(mems.lock); }
} VX_MEM_BARRIER_RW(); if (Rmem_watchdog >32766) Rmem_watchdog=0; Rmem_watchdog++; mems.rmem->mrbcm_count = Rmem_watchdog; pwf->nord = 5120;
if (emer_flag >0) { recGblSetSevr(pwf,HIGH_ALARM,MAJOR_ALARM);}
else if (over_flag > 0) { recGblSetSevr(pwf,HIGH_ALARM,MINOR_ALARM);} else { recGblSetSevr(pwf,HIGH_ALARM,NO_ALARM); } if (debug_flag >4) logMsg("end of read\n",0,0,0,0,0,0);
cards[cardN].card->trig_enb = 0x1; #if 0 logMsg("ad_start[%d]\n",cardN,0,0,0,0,0); #endif return(0); } /* static long get_wf_int_info(cmd,pwf,ppvt) int cmd; struct waveformRecord *pwf; IOSCANPVT *ppvt; { short cardN; unsigned char stat; cardN = pwf->inp.value.vmeio.card; *ppvt = cards[cardN].ioscanpvt; if (debug_flag >5) logMsg("wf_INT CALLED\n"); return(0); } */ static long init_si_record(pstringin) struct stringinRecord *pstringin; { return 0; } static long read_si(pstringin) struct stringinRecord *pstringin; { long status = 0; short cardN; char t1[9],t2[9],t3[5],t4[14]; unsigned long fpga_rev; cardN = pstringin->inp.value.vmeio.card; if (checkLink(cardN) == ERROR) { logMsg("Error- No 18k10KB2 for card %d\n",cardN,0,0,0,0,0); return(ERROR); } switch(pstringin->inp.value.vmeio.signal){ case 0 : fpga_rev = cards[cardN].card->revision; logMsg("fpga rev =%ld\n",fpga_rev,0,0,0,0,0); /* fpga_rev = cards[cardN].card->dum1[0]; logMsg("dum1 =%ld\n",fpga_rev,0,0,0,0,0); fpga_rev = cards[cardN].card->dum1[1]; logMsg("dum2 =%ld\n",fpga_rev,0,0,0,0,0); fpga_rev = cards[cardN].card->fpga_out; logMsg("fpga out =%x\n",fpga_rev,0,0,0,0,0); */ sprintf(t1,"%2x ",fpga_rev>>24); sprintf(t2,"%02x ",(fpga_rev>>16) &(0xff)); sprintf(t3,"%x ",(fpga_rev>>12) &(0xf)); sprintf(t4,"%03x ",(fpga_rev) & (0xfff)); strcpy(pstringin->val,t1); strcat(pstringin->val,t2); strcat(pstringin->val,t3); strcat(pstringin->val,t4); break; } return(status); } /************************************************************************** * * Make sure card number is valid * **************************************************************************/ static int checkLink(cardN) short cardN; { if (cardN >= D18k10KB2_num_links) return(ERROR); if (cards[cardN].card == NULL) { logMsg("No 18K10KB with this number = %d\n",cardN,0,0,0,0,0); return(ERROR); } if (debug_flag >10) logMsg("Yes you have 18k10KB2 with card No= %d\n",cardN,0,0,0,0,0); return(OK); } static void dmaCallBackCh0( void ) { logMsg( "call dmaCallBackCh0\n",0,0,0,0,0,0 ); } static void dmaCallBackCh1( void ) { logMsg( "call dmaCallBackCh1\n", 0,0,0,0,0,0 ); } /* devVme18k10KB2.c */ /* devVme18k10KB2.c - Device Support Routines for VME adc board */ /* * * Original Author: Makoto Tobiyama * Current Author: * Date: 30/Jul/2012 * * Experimental Physics and Industrial Control System (EPICS) * * Copyright 1997, KEKB. * * * Modification Log: * 16/Apr/2015 : Add reflection memory support * ----------------- */
#include<vxWorks.h>
#include <vxLib.h>#include <logLib.h> #include <sysLib.h> /* #include <memLib.h> */ #include <intLib.h>
#include<types.h>
#include <stdio.h>
#include<stdioLib.h>
#include<string.h>
/* #include <sys/time.h> */
#include<vme.h>
#include<dbDefs.h>
#include<dbAccess.h>
#include<recSup.h>
#include<devSup.h>
#include <recGbl.h>#include <alarm.h>
#include<link.h>
#include <iv.h>
#include<module_types.h>
#include<longinRecord.h>
#include<longoutRecord.h>
#include<boRecord.h>
#include<biRecord.h>
#include <aiRecord.h>#include <aoRecord.h>
#include<mbbiDirectRecord.h>
#include<mbboDirectRecord.h>
#include<waveformRecord.h>
#include <stringoutRecord.h>#include <stringinRecord.h>
#include<dbScan.h>
#include <epicsMutex.h>#include <epicsExport.h> #if 1 #include </cont/VxWorks/vw68/vxworks-6.8/target/config/mv5500/sysDma.h> #include </cont/VxWorks/vw68/vxworks-6.8/target/config/mv5500/universe.h> #include <vxLib.h> #include <time.h> #include <vxAtomicLib.h> #endif static void dmaCallBackCh0( void ); static void dmaCallBackCh1( void ); struct D18k10KB2 { unsigned long board_reset; unsigned long trig_enb; unsigned long mem_trig; unsigned long mem_size; unsigned long irq_enb; unsigned long adclk_dly; unsigned long adc_rst; unsigned long adrdpt_rst; unsigned long mem_cl; unsigned long fpga_out; unsigned long dum1[2]; unsigned long board_sts; unsigned long ad_sts; unsigned long rec_mode; unsigned long harmonic; unsigned long irq_no; unsigned long irq_id; unsigned long fpga_in; unsigned long dum2; unsigned long revision; unsigned long debug; unsigned long dum3[2]; unsigned long dum4[40]; unsigned long ad_data[64]; }; struct GREFMEM { epicsUInt8 control_reg[12288]; unsigned long R_MEML[2048]; unsigned long R_MEMH[2048]; unsigned long R_MEMDR[1024]; epicsUInt8 condition[4096]; epicsUInt32 delay[4096]; epicsUInt32 opccr_alarm; epicsUInt32 tmlc8_alarm; epicsUInt32 opccr_count; epicsUInt32 tmlc8_count; epicsUInt32 mrbcm_count; epicsUInt32 drbcm_count; epicsUInt32 positron_bunch; epicsUInt32 electron_bunch; epicsUInt8 operation[4064]; epicsUInt8 RESERVE[1003520]; };
#defineStatusEnable
static long init_all(); static long init_mi_record(); static long get_mbbi_int_info(); static long init_bo_record(); static long write_bo(); static long init_bi_record(); static long read_bi(); static long read_mbbiDirect(); static long init_wf_record(); static long read_wf_record(); static long init_lo_record(); static long write_longout(); static long init_li_record(); static long read_longin(); static long init_si_record(); static long read_si(); static long init_ao_record(); static long write_ao(); static void vme18k10KB2_isr(); static int checkLink(); /* Create the dset for devBo18k10KB2 */ struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN write_bo; }devBo18k10KB2={ 5, NULL, NULL, init_bo_record, NULL, write_bo }; epicsExportAddress(dset,devBo18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_bi_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_bi; }devBi18k10KB2={ 5, NULL, NULL, init_bi_record, NULL, read_bi }; epicsExportAddress(dset,devBi18k10KB2); /* For devMbbi18k10KB2 */ struct{ long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_mi_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_mbbiDirect; }devMbbi18k10KB2={ 5, NULL, NULL, init_mi_record, get_mbbi_int_info, read_mbbiDirect }; epicsExportAddress(dset,devMbbi18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_write; DEVSUPFUN conv; }devWf18k10KB2 ={ 6, NULL, NULL, init_wf_record, NULL, read_wf_record, NULL }; epicsExportAddress(dset,devWf18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN write_longout; DEVSUPFUN special_linconv; }devLo18k10KB2={ 6, NULL, NULL, init_lo_record, NULL, write_longout, NULL }; epicsExportAddress(dset,devLo18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_longin; DEVSUPFUN special_linconv; }devLi18k10KB2={ 6, NULL, NULL, init_li_record, NULL, read_longin, NULL}; epicsExportAddress(dset,devLi18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN write_ao; DEVSUPFUN special_linconv; }devAo18k10KB2={ 6, NULL, NULL, init_ao_record, NULL, write_ao, NULL }; epicsExportAddress(dset,devAo18k10KB2); struct { long number; DEVSUPFUN report; DEVSUPFUN init; DEVSUPFUN init_record; DEVSUPFUN get_ioint_info; DEVSUPFUN read_si; DEVSUPFUN special_linconv; }devSi18k10KB2={ 6, NULL, NULL, init_si_record, NULL, read_si, NULL}; epicsExportAddress(dset,devSi18k10KB2); struct ioCard { volatile struct D18k10KB2 *card; /* address of this card */ epicsMutexId lock; /* semaphore */ IOSCANPVT ioscanpvt; }; struct memCard { volatile struct GREFMEM *rmem; epicsMutexId lock; }; #define CONST_NUM_LINKS 10 /* #define STATIC */ #define DEBUG_ON static int debug_flag = 0; static unsigned long Base_IO; static int D18k10KB2_num_links; volatile static struct ioCard cards[CONST_NUM_LINKS]; volatile static struct memCard mems; static int init_flag = 0; static unsigned short INT_VEC_BASE; static long HER_LIM,LER_LIM; static long HER_LIMA,LER_LIMA; static int LER_OVER_ONE =0; static int HER_OVER_ONE =0; static double cal_fac_bcm_H = 7.8125e-3; static double cal_fac_bcm_L = 7.8125e-3; static unsigned long BASE5565; /* static char *CARD5565; */ static epicsUInt8 bc_o[5120]; static epicsUInt32 Rmem_watchdog; static unsigned char int_level; #if 1 static unsigned long *gplTmpDataB; /* 256K Word * 4ch(256*1024*2*4/4) */ #endif /* #define R_MEM_LER ((void*)(CARD5565 + 0x3000)) #define R_MEM_HER ((void*)(CARD5565 + 0x5000)) */ int dev18k10KB2Config(ncards,a32base,irq,intvecbase) int ncards; long a32base; int irq; int intvecbase; { D18k10KB2_num_links = ncards; Base_IO = a32base; int_level= irq; INT_VEC_BASE=intvecbase; logMsg("dev18k10KB2 NumLink= %d BaseIO= %lx IRQ = %d INTVECBASE =%x\n",D18k10KB2_num_links,Base_IO,int_level,INT_VEC_BASE,0,0); init_all(0); return 0; } static long init_all(after) int after; { int cardNum, chanNum; unsigned char probeVal[4]; volatile struct D18k10KB2 *p; volatile struct GREFMEM *p2; unsigned short mem_pat; int rtn ; if (init_flag != 0 ) return(OK); init_flag = 1; #if 1 if ( sysVmeDmaInit() != OK ) { logMsg("sysVmeDmaInit() Error!!\n",0,0,0,0,0,0); return(ERROR); } logMsg("sysVmeDmaInit() OK!!\n",0,0,0,0,0,0); #endif if (sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,(char *)Base_IO,(char **)&p) == ERROR)
{ logMsg("18k10KB2: cannot find extended address space\n",0,0,0,0,0,0); return(ERROR); }
/* if (debug_flag >0) logMsg("18k10KB2 address %x\n",(int)p,0,0,0,0,0); */ for (cardNum=0; cardNum< D18k10KB2_num_links; cardNum++) { if (vxMemProbe((char*) &(p->board_reset), READ, 4, (char *)&probeVal[0])!= OK) { logMsg("No 18k10KB2 with cardNum= %d\n probe= %x\n",cardNum,(int)p,0,0,0,0);
cards[cardNum].card = NULL;
} else {
if (debug_flag >0)
logMsg("Found 18k10KB2 with cardNum= %d\n address= %x\n",cardNum,(int)p,0,0,0,0);
cards[cardNum].card = p; /* Remember address of the board */ scanIoInit(&(cards[cardNum].ioscanpvt)); logMsg("scan IO init %x\n",(int)cards[cardNum].ioscanpvt,0,0,0,0,0);
} if (debug_flag >0) logMsg("IntSet for 18K10KB with address %x\n",(int)p->irq_enb,0,0,0,0,0); p->irq_enb = 0x00; cards[cardNum].lock = epicsMutexMustCreate(); epicsMutexUnlock((cards[cardNum].lock)); /* Init the board lock */ p++; } gplTmpDataB = memalign( 256, 64*4 ); logMsg("init DMA setting\n",0,0,0,0,0,0); /* 256 x 4ch */ if (sysVmeDmaCnfgSet(DCTL_VDW_32 | DCTL_VCT_BLK, DCTL_VAS_A32, DCTL_PGM_DATA, DCTL_SUPER_SUP) != OK){ logMsg("devVme18k10KB2 error DMA setting\n",0,0,0,0,0,0);} BASE5565=0x0D000000; if (sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,(char *)BASE5565,(char **)&p2) == ERROR) { logMsg("devVme18k10KB2 : cannot find extended address space for RefMem\n",0,0,0,0,0,0); return(ERROR); } else { logMsg("devVme18k10KB2 allocated memory for RefMem\n",0,0,0,0,0,0); } if (vxMemProbe((char*) &(p2->mrbcm_count),READ, 4, (char *)&probeVal[0])!= OK) { logMsg("No refmem probe= %x\n",(int)p2,0,0,0,0,0);
mems.rmem = NULL;
} else { logMsg("Found Rmem\n",0,0,0,0,0,0); mems.rmem = p2; mems.lock = epicsMutexMustCreate(); epicsMutexUnlock((mems.lock)); } LER_LIM =(int)(1.6/cal_fac_bcm_L); HER_LIM =(int)(1.3/cal_fac_bcm_H); LER_LIMA = 253; HER_LIMA = 253; Rmem_watchdog = 0; mems.rmem->mrbcm_count = Rmem_watchdog; return(OK); } /****************************************************************** * * Interrupt service routine * *******************************************************************/ static void vme18k10KB2_isr(pmbbi)
struct mbbiDirectRecord*pmbbi;
{ unsigned char mode; short cardN; unsigned long ad; cardN = pmbbi->inp.value.vmeio.card; ad = (cards[cardN].card->ad_sts) & 0xff; cards[cardN].card->trig_enb = 0x0; scanIoRequest(cards[cardN].ioscanpvt); /* logMsg("18k10KB2 int called \n");*/ return; } /************************************************************************** * * BO Initialization (Called one time for each BO PowerUT card record) * **************************************************************************/ static long init_bo_record(pbo) struct boRecord *pbo; { pbo->mask = 1;
return(0);
} /************************************************************************** * * Perform a write operation from a BO record * **************************************************************************/ static long write_bo(pbo) struct boRecord *pbo; { short cardN; cardN = pbo->out.value.vmeio.card; if (checkLink(cardN) == ERROR) { logMsg("Error--- No 18k10KB2 for card %d\n",cardN,0,0,0,0,0); return(ERROR); } if (debug_flag>5) logMsg("BO\n",0,0,0,0,0,0); epicsMutexMustLock((cards[cardN].lock)); switch(pbo->out.value.vmeio.signal){ case 0 : /* board reset */ cards[cardN].card->board_reset = 0x1 & (pbo->val); break; case 1 : /* trg enable */ cards[cardN].card->trig_enb = 0x1 & (pbo->val); break; case 2 : /* adc reset */ cards[cardN].card->adc_rst = 0x1 & (pbo->val); break; case 3 : /* adrdpt_rst */ cards[cardN].card->adrdpt_rst = 0x1 & (pbo->val); break; case 4 : /* mem clear */ cards[cardN].card->mem_cl = 0x1 & (pbo->val); break; default: logMsg("write_bo called with card %d\n",cardN,0,0,0,0,0); break; } epicsMutexUnlock((cards[cardN].lock)); return(0); } static long init_bi_record(pbi) struct biRecord *pbi; { pbi->mask = 1; return(0); } static long read_bi(pbi) struct biRecord *pbi; { short cardN; cardN = pbi ->inp.value.vmeio.card; if (checkLink(cardN) == ERROR) return(ERROR); switch(pbi->inp.value.vmeio.signal){ case 0 : pbi->rval = cards[cardN].card->board_reset & pbi->mask; break; case 1 : pbi->rval = cards[cardN].card->trig_enb & pbi->mask; break; case 2 : pbi->rval = cards[cardN].card->adc_rst & pbi->mask; break; case 3 : pbi->rval = cards[cardN].card->adrdpt_rst & pbi->mask; break; case 4 : pbi->rval = cards[cardN].card->rec_mode & pbi->mask; break; default : break; } return(0); } static long init_lo_record(plongout) struct longoutRecord *plongout; { return(0); } static long write_longout(plongout) struct longoutRecord *plongout; { short cardN; cardN = plongout->out.value.vmeio.card; if (debug_flag >10) logMsg("write_lo called with card %d\n",cardN,0,0,0,0,0); if (checkLink(cardN) == ERROR) return(ERROR); epicsMutexMustLock((cards[cardN].lock)); switch(plongout->out.value.vmeio.signal){ case 0 : /* mem_trig */
cards[cardN].card->mem_trig = 0x3 & (plongout->val); break;
case 1 : /* mem_size */ cards[cardN].card->mem_size = 0x3 & (plongout ->val);
break;
case 2 : /* interrupt enable */
cards[cardN].card->irq_enb = 0x3 & (plongout -> val); break;
case 3 : /* adclk_dly */ cards[cardN].card->adclk_dly = 0x3f & (plongout->val); break; default: break; } epicsMutexUnlock((cards[cardN].lock)); return(OK); } static long init_li_record(plongin) struct longinRecord *plongin; { return(0); } static long read_longin(plongin) struct longinRecord *plongin; { short cardN; if (debug_flag >10) logMsg("read_longin called...\n",0,0,0,0,0,0); cardN = plongin->inp.value.vmeio.card; if (checkLink(cardN) == ERROR) return(ERROR); switch(plongin->inp.value.vmeio.signal){ case 0: /* mem_trig */ plongin->val = (cards[cardN].card->mem_trig) & 0x3; break; case 1: /* mem_size */ plongin->val = (cards[cardN].card->mem_size) & 0x3; break; case 2: /* IRQ_ENB */ plongin->val = (cards[cardN].card->irq_enb) & 0x3; break; case 3 : /* ADCLK_DLY */ plongin->val = (cards[cardN].card->adclk_dly) & 0x3f; break; case 4: /* harmonic */ plongin->val = (cards[cardN].card->harmonic) & 0x3;
break;
case 5: /* IRQ_NO */ plongin->val = (cards[cardN].card->irq_no) &0xff; break; case 6: /* irq_id */ plongin->val = (cards[cardN].card->irq_id) & 0xff; break; default: break; } return(OK); } static long init_ao_record(pao) struct aoRecord *pao; { pao->eslo = 1.0; return(0); } static long write_ao(pao) struct aoRecord *pao; { double f1; switch(pao->out.value.vmeio.signal){ case 0 : f1 = pao->val; LER_LIM = (int)(f1/cal_fac_bcm_L); break; case 1: f1 = pao->val; HER_LIM = (int)(f1/cal_fac_bcm_H); break; case 2 : f1 = pao->val; if (f1 <4e-3) f1= 8.1731422e-3; /* 7.44842e-3; */ cal_fac_bcm_L = f1; break; case 3 : f1 = pao->val;
/* 7.102273e-3 */
if (f1 <4e-3) f1=8.8861577e-3; cal_fac_bcm_H = f1; break; default : break; }
return(0); } static long init_mi_record(pmbbi)
struct mbbiDirectRecord*pmbbi;
{ short cardNum; short signal; cardNum = pmbbi->inp.value.vmeio.card; signal = pmbbi->inp.value.vmeio.signal; if (signal == 1) { if (intConnect(INUM_TO_IVEC(INT_VEC_BASE + cardNum),
(VOIDFUNCPTR)vme18k10KB2_isr, (int)pmbbi) != OK)
logMsg("devVme18k10KB2: Interrupt connect failed for card %d %x\n",pmbbi->inp.value.vmeio.card,(int)INUM_TO_IVEC(INT_VEC_BASE + cardNum),0,0,0,0); logMsg("intConnect 0x%x\n",(int)pmbbi,0,0,0,0,0);
sysIntEnable(int_level); logMsg("devVme18k10KB2 int set for int 0x%x\n",int_level,0,0,0,0,0); } return(0); } static long read_mbbiDirect(pmbbi) struct mbbiDirectRecord *pmbbi; { short cardN; cardN = pmbbi->inp.value.vmeio.card; if (debug_flag >5) logMsg("read_mbbiDirect called with card %d\n",cardN,0,0,0,0,0); if (checkLink(cardN) == ERROR) return(ERROR); switch(pmbbi->inp.value.vmeio.signal){ case 0: /* board_sts */ pmbbi->rval = (cards[cardN].card->board_sts) & 0x7f; break; case 1: /* AD_STS */ pmbbi->rval = (cards[cardN].card->ad_sts) & 0xff; break; default: break; } if (debug_flag >5) logMsg("mbbi read complete \n",0,0,0,0,0,0); return(OK); } static long get_mbbi_int_info(cmd,pmbbi,ppvt) int cmd; struct mbbiDirectRecord *pmbbi; IOSCANPVT *ppvt; { short cardN; unsigned char stat; cardN = pmbbi->inp.value.vmeio.card; *ppvt = cards[cardN].ioscanpvt; if (debug_flag >5) logMsg("mbbi_INT CALLED\n",0,0,0,0,0,0); return(0); } static long init_wf_record(pwf)
struct waveformRecord*pwf;
{ /* short cardNum; cardNum = pwf->inp.value.vmeio.card; if (intConnect(INUM_TO_IVEC(INT_VEC_BASE + cardNum),
(VOIDFUNCPTR)vme18k10KB2_isr, (int)pwf) != OK)
logMsg("devVme18k10KB2: Interrupt connect failed for card %d\n",pwf->inp.value.vmeio.card); logMsg("intConnect 0x%x\n",pwf);
sysIntEnable(int_level); logMsg("devVme18k10KB2 int set for int 0x%x\n",int_level); */ return(0); } static long read_wf_record(pwf)
struct waveformRecord*pwf;
{ short cardN; unsigned long a1,a2; long i,ii,jj,start,is; unsigned long temp_tpos; unsigned long uuu; float* f_thing = (float*)pwf->bptr; int over_flag = 0; int emer_flag = 0; int over_one; volatile int temp1,temp2,temp3; #if 1 STATUS iDmaStartRc; unsigned int p1=0,p2=0,p3=0,p4=0,pSta=0; #endif #if 1 struct timespec oTimeSpec1; struct timespec oTimeSpec2; struct timespec oTimeSpec3; struct timespec oTimeSpec4; struct timespec oTimeSpec5; /* clock_gettime( CLOCK_REALTIME, &oTimeSpec1 ); */ #endif cardN = pwf->inp.value.vmeio.card; if (debug_flag >5) logMsg("read_wf_record called with card number of %d\n",cardN,0,0,0,0,0); if (checkLink(cardN) == ERROR) return(ERROR); /* logMsg("Waveform type %x\n",pwf->ftvl,0,0,0,0,0); */ sysUnivVERRClr(); if(sysVmeDmaStatusGet(&pSta) != OK )
{ logMsg("sysVmeDmaStatusGet() Error!!\n", 0, 0, 0, 0, 0,0); }
if(sysVmeDmaCnfgGet(&p1,&p2,&p3,&p4) != OK )
{ logMsg("sysVmeDmaCnfgGet() Error!!\n", 0, 0, 0, 0, 0,0); }
VX_MEM_BARRIER_RW(); for (is=0;is<20;is++){
iDmaStartRc = sysVmeDmaV2LCopy( &cards[cardN].card->ad_data[0], gplTmpDataB+0, 64*4 );
if(iDmaStartRc != 0) { logMsg("-->sysVmeDmaV2LCopy() error!! Rc[%d] card[%d]\n", iDmaStartRc, cardN, 0, 0 ,0, 0 ); } if (cardN==0) { iDmaStartRc = sysVmeDmaL2VCopy( gplTmpDataB,&mems.rmem->R_MEML[is*64],64*4 ); } else { iDmaStartRc = sysVmeDmaL2VCopy( gplTmpDataB,&mems.rmem->R_MEMH[is*64],64*4 ); } for ( ii = 0; ii < 64 ; ii++ ) { bc_o[is*256+ii*4+0] = (unsigned char)( (gplTmpDataB[ii] >>24)&0xff); bc_o[is*256+ii*4+1] = (unsigned char)( (gplTmpDataB[ii] >>16)& 0xff); bc_o[is*256+ii*4+2] = (unsigned char)((gplTmpDataB[ii] >>8) &0xff); bc_o[is*256+ii*4+3] = (unsigned char)((gplTmpDataB[ii]) & 0xff);
} if (cardN ==0) /* for LER */ { over_one = 0; emer_flag =0; for (i=0; i<5120;i++) { f_thing[i]=cal_fac_bcm_L*bc_o[i]; if (bc_o[i]>LER_LIM) over_one =1; if (bc_o[i]>LER_LIMA) emer_flag =1; } if ((over_one == 1) && (LER_OVER_ONE==1)) { over_flag = 1; } else if (over_one == 1) { LER_OVER_ONE = 1; } else { LER_OVER_ONE = 0; over_flag = 0; } epicsMutexMustLock(mems.lock); for (i=0; i<5120;i++){ f_thing[i]=cal_fac_bcm_L * bc_o[i]; } epicsMutexUnlock(mems.lock); }
else { over_one = 0; emer_flag =0; for (i=0; i<5120;i++) { f_thing[i]=cal_fac_bcm_H*bc_o[i]; if (bc_o[i]>HER_LIM) over_one =1; if (bc_o[i]>HER_LIMA) emer_flag =1; } if ((over_one == 1) && (HER_OVER_ONE==1)) { over_flag = 1; } else if (over_one == 1) { HER_OVER_ONE = 1; } else { HER_OVER_ONE = 0; over_flag = 0; } epicsMutexMustLock(mems.lock); for (i=0; i<5120;i++){ f_thing[i]=cal_fac_bcm_L * bc_o[i]; } epicsMutexUnlock(mems.lock); }
} VX_MEM_BARRIER_RW(); if (Rmem_watchdog >32766) Rmem_watchdog=0; Rmem_watchdog++; mems.rmem->mrbcm_count = Rmem_watchdog; pwf->nord = 5120;
if (emer_flag >0) { recGblSetSevr(pwf,HIGH_ALARM,MAJOR_ALARM);}
else if (over_flag > 0) { recGblSetSevr(pwf,HIGH_ALARM,MINOR_ALARM);} else { recGblSetSevr(pwf,HIGH_ALARM,NO_ALARM); } if (debug_flag >4) logMsg("end of read\n",0,0,0,0,0,0);
cards[cardN].card->trig_enb = 0x1; #if 0 logMsg("ad_start[%d]\n",cardN,0,0,0,0,0); #endif return(0); } /* static long get_wf_int_info(cmd,pwf,ppvt) int cmd; struct waveformRecord *pwf; IOSCANPVT *ppvt; { short cardN; unsigned char stat; cardN = pwf->inp.value.vmeio.card; *ppvt = cards[cardN].ioscanpvt; if (debug_flag >5) logMsg("wf_INT CALLED\n"); return(0); } */ static long init_si_record(pstringin) struct stringinRecord *pstringin; { return 0; } static long read_si(pstringin) struct stringinRecord *pstringin; { long status = 0; short cardN; char t1[9],t2[9],t3[5],t4[14]; unsigned long fpga_rev; cardN = pstringin->inp.value.vmeio.card; if (checkLink(cardN) == ERROR) { logMsg("Error- No 18k10KB2 for card %d\n",cardN,0,0,0,0,0); return(ERROR); } switch(pstringin->inp.value.vmeio.signal){ case 0 : fpga_rev = cards[cardN].card->revision; logMsg("fpga rev =%ld\n",fpga_rev,0,0,0,0,0); /* fpga_rev = cards[cardN].card->dum1[0]; logMsg("dum1 =%ld\n",fpga_rev,0,0,0,0,0); fpga_rev = cards[cardN].card->dum1[1]; logMsg("dum2 =%ld\n",fpga_rev,0,0,0,0,0); fpga_rev = cards[cardN].card->fpga_out; logMsg("fpga out =%x\n",fpga_rev,0,0,0,0,0); */ sprintf(t1,"%2x ",fpga_rev>>24); sprintf(t2,"%02x ",(fpga_rev>>16) &(0xff)); sprintf(t3,"%x ",(fpga_rev>>12) &(0xf)); sprintf(t4,"%03x ",(fpga_rev) & (0xfff)); strcpy(pstringin->val,t1); strcat(pstringin->val,t2); strcat(pstringin->val,t3); strcat(pstringin->val,t4); break; } return(status); } /************************************************************************** * * Make sure card number is valid * **************************************************************************/ static int checkLink(cardN) short cardN; { if (cardN >= D18k10KB2_num_links) return(ERROR); if (cards[cardN].card == NULL) { logMsg("No 18K10KB with this number = %d\n",cardN,0,0,0,0,0); return(ERROR); } if (debug_flag >10) logMsg("Yes you have 18k10KB2 with card No= %d\n",cardN,0,0,0,0,0); return(OK); } static void dmaCallBackCh0( void ) { logMsg( "call dmaCallBackCh0\n",0,0,0,0,0,0 ); } static void dmaCallBackCh1( void ) { logMsg( "call dmaCallBackCh1\n", 0,0,0,0,0,0 ); }