/* DevVmeFIR.c */
/* devVmeFIR.c - Device Support Routines for VME bunch current board */
/*
* Original Author: Makoto Tobiyama
* Current Author:
* Date: 23/Dec/98
* Modified
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1997, KEKB.
*
*
* Modification Log:
* -----------------
*/
#include <vxWorks.h>
#include <types.h>
#include <stdioLib.h>
#include <string.h>
#include <vme.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <recSup.h>
#include <devSup.h>
#include <devCamac.h>
#include <link.h>
#include <iv.h>
#include <module_types.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <boRecord.h>
#include <biRecord.h>
#include <mbbiDirectRecord.h>
#include <mbboDirectRecord.h>
#include <waveformRecord.h>
#include <dbScan.h>
/* #define Base_IO 0x20000 */ /* Std. I/O Address */
#define NUM_INT_CHAN 8
/*
struct DvmeFIR {
unsigned long board0[10240];
unsigned long dum0[6144];
unsigned long board1[10240];
unsigned long dum1[6144];
unsigned long board2[10240];
unsigned long dum2[6144];
unsigned long board3[10240];
unsigned long dum3[6144];
unsigned long board4[10240];
unsigned long dum4[6144];
unsigned long board5[10240];
unsigned long dum5[6144];
unsigned long board6[10240];
unsigned long dum6[6144];
unsigned long board7[10240];
unsigned long dum7[6144];
unsigned long board8[10240];
unsigned long dum8[6144];
unsigned long board9[10240];
unsigned long dum9[6144];
unsigned long board10[10240];
unsigned long dumA[6144];
unsigned long board11[10240];
unsigned long dumB[6144];
unsigned long board12[10240];
unsigned long dumC[6144];
unsigned long board13[10240];
unsigned long dumD[6144];
unsigned long board14[10240];
unsigned long dumE[6144];
unsigned long board15[10240];
unsigned long dumF[6144];
unsigned long board16[10240];
unsigned long dum10[6144];
unsigned long board17[10240];
unsigned long dum11[6144];
unsigned long board18[10240];
unsigned long dum12[6144];
unsigned long board19[10240];
unsigned long dum13[6144];
unsigned long board20[10240];
unsigned long dum14[6144];
unsigned long board21[10240];
unsigned long dum15[6144];
unsigned long board22[10240];
unsigned long dum16[6144];
unsigned long board23[10240];
unsigned long dum17[6144];
unsigned long board24[10240];
unsigned long dum18[6144];
unsigned long board25[10240];
unsigned long dum19[6144];
unsigned long board26[10240];
unsigned long dum1A[6144];
unsigned long board27[10240];
unsigned long dum1B[6144];
unsigned long board28[10240];
unsigned long dum1C[6144];
unsigned long board29[10240];
unsigned long dum1D[6144];
unsigned long board30[10240];
unsigned long dum1E[6144];
unsigned long board31[10240];
unsigned long dum1F[6144];
unsigned short cntl1;
unsigned short dum20;
unsigned short cntl2;
unsigned short dum21;
unsigned short stop1;
unsigned short dum22;
unsigned short stop2;
unsigned short dum23;
unsigned long dummy[524284];
};
*/
/* struct DvmeFIR {
unsigned long board[32][16384];
unsigned short cntl1;
unsigned short dum20;
unsigned short cntl2;
unsigned short dum21;
unsigned short stop1;
unsigned short dum22;
unsigned short stop2;
unsigned short dum23;
unsigned long dummy[524284];
};*/
struct DvmeFIR {
unsigned long board[32][16384];
unsigned long cntl1;
unsigned long tap1;
unsigned long tap2;
unsigned short dummy1;
unsigned short dummy2;
unsigned long dummy[524284];
};
#define Status Enable
static long init_all();
static long init_bo_record();
static long init_bi_record();
static long write_bo();
static long read_bi();
static long read_longin();
static long init_lo_recored();
static long write_longout();
static long init_wf_record();
static long read_wf_record();
static int checkLink();
struct {
long number;
DEVSUPFUN report; /* used by dbior */
DEVSUPFUN init; /* called 1 time before & after all reco
rds */
DEVSUPFUN init_record; /* called 1 time for each record */
DEVSUPFUN get_ioint_info; /* used for COS processing */
DEVSUPFUN read_bi; /* input command goes here */
}devBiVmeFIR={
5,
NULL,
NULL,
init_bi_record,
NULL,
read_bi
};
/* Create the dset for devBoVmeFIR */
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN write_bo;
}devBoVmeFIR={
5,
NULL,
NULL,
init_bo_record,
NULL,
write_bo
};
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_longin;
DEVSUPFUN special_linconv;
}devLiVmeFIR={
6,
NULL,
NULL,
NULL,
NULL,
read_longin,
NULL};
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN write_longout;
DEVSUPFUN special_linconv;
}devLoVmeFIR={
6,
NULL,
NULL,
NULL,
NULL,
write_longout,
NULL};
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_write;
DEVSUPFUN conv;
}devWfVmeFIR ={
6,
NULL,
NULL,
init_wf_record,
NULL,
read_wf_record,
NULL
};
struct ioCard {
volatile struct DvmeFIR *card; /* address of this card */
FAST_LOCK lock; /* semaphore */
};
#define CONST_NUM_LINKS 2
/* #define STATIC */
#define DEBUG_ON
static int debug_flag = 1;
static unsigned long Base_IO;
static int vmeFIR_num_links;
static struct ioCard cards[CONST_NUM_LINKS];
static unsigned short card_reg_1[CONST_NUM_LINKS];
static int init_flag = 0;
static int fast_flag = 1;
/* static unsigned long (*data)[32]; */
int devVmeFIRConfig(ncards,a32base)
int ncards;
long a32base;
{
vmeFIR_num_links = ncards;
Base_IO = a32base;
logMsg("devVmeFIR NumLink= %d BaseIO= %x\n",vmeFIR_num_links,Base_IO);
init_all(0);
}
static long init_all(after)
int after;
{
int cardNum, chanNum;
unsigned char probeVal[2];
volatile struct DvmeFIR *p;
if (init_flag != 0 )
return(OK);
init_flag = 1;
/* data = (unsigned long (*)[32])calloc(10240*32,sizeof(long));
if (data == NULL)
{
logMsg("Cannot allocate buffer\n");
return(ERROR);
}
*/
if (sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,(char *)Base_IO,(char **)&p) == ERROR)
{
logMsg("VmeFIR: cannot find extended address space\n");
return(ERROR);
}
for (cardNum=0; cardNum< vmeFIR_num_links; cardNum++)
{
if (vxMemProbe((char*) &(p->cntl1), READ, 2, &probeVal[0])< OK)
{
if (debug_flag >0 )
logMsg("No vmeFIR with cardNum= %d\n probe= %x\n",cardNum,p);
cards[cardNum].card = NULL;
}
else
{
if (debug_flag >0)
logMsg("Found vmeFIR with cardNum= %d\n address= %x\n",cardNum,p);
cards[cardNum].card = p; /* Remember address of the board */
card_reg_1[cardNum]=0x06;
cards[cardNum].card->cntl1 = card_reg_1[cardNum];;
FASTLOCKINIT(&(cards[cardNum].lock));
FASTUNLOCK(&(cards[cardNum].lock)); /* Init the board lock */
}
p++;
}
return(OK);
}
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)
{
logMsg("Error--- No vmeFIR for card %d\n",cardN);
return(ERROR);
}
switch(pbi->inp.value.vmeio.signal){
case 0 : /* filter ON=0, OFF=1 */
pbi->rval = cards[cardN].card->tap1 & pbi->mask;
break;
case 1 : /* clock status No=0, OK=1 --- reverse */
pbi->rval = !(((cards[cardN].card->tap1)>>1) & pbi->mask);
break;
case 2 : /* Fan OK Break=0 OK=1 --- reverse */
pbi->rval = !(((cards[cardN].card->tap1)>>2) & pbi->mask);
break;
case 3 : /* Sync or asinc asinc=0, sync=1 --- reverse */
pbi->rval =!(((cards[cardN].card->tap1)>>3) & pbi->mask);
break;
case 4 : /* calc mode calc = 0 , through = 1 */
pbi->rval =(((cards[cardN].card->tap1)>>4) & pbi->mask);
break;
case 5 : /* x2 = 1 --- reverse */
pbi->rval =!(((cards[cardN].card->tap1)>>5)& pbi->mask);
break;
case 6 : /* x4 = 1 --- reverse */
pbi->rval =!(((cards[cardN].card->tap1)>>6)& pbi->mask);
break;
case 7 : /* x8 = 1 --- reverse */
pbi->rval =!(((cards[cardN].card->tap1)>>7)& pbi->mask);
break;
}
return(0);
}
/**************************************************************************
*
* 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 vmeFIR for card %d\n",cardN);
return(ERROR);
}
FASTLOCK(&(cards[cardN].lock));
switch(pbo->out.value.vmeio.signal){
case 0 : /* filter on =0 */
card_reg_1[cardN]= (card_reg_1[cardN] & 0xfffe) | (pbo->rval & 0x1);
cards[cardN].card->cntl1 = card_reg_1[cardN];
break;
case 1 : /* calc enable = 0 */
card_reg_1[cardN]= (card_reg_1[cardN] & 0xfffd) | ((pbo->rval & 0x1)<<1);
cards[cardN].card->cntl1 = card_reg_1[cardN];
break;
case 2 : /* sync = 1 -- reverse */
card_reg_1[cardN]= (card_reg_1[cardN] & 0xfffb) | (!(pbo->rval & 0x1)<<2);
cards[cardN].card->cntl1 = card_reg_1[cardN];
break;
case 3 : /* x1 */
card_reg_1[cardN]=(card_reg_1[cardN]&0xff07) | 0x08;
cards[cardN].card->cntl1 = card_reg_1[cardN];
break;
case 4 : /* x2 */
card_reg_1[cardN]=(card_reg_1[cardN]&0xff07) | 0x10;
cards[cardN].card->cntl1 = card_reg_1[cardN];
break;
case 5 : /* x4 */
card_reg_1[cardN]=(card_reg_1[cardN]&0xff07) | 0x20;
cards[cardN].card->cntl1 = card_reg_1[cardN];
break;
case 6 : /* x8 */
card_reg_1[cardN]=(card_reg_1[cardN]&0xff07) | 0x40;
cards[cardN].card->cntl1 = card_reg_1[cardN];
break;
case 7 : /* through */
card_reg_1[cardN]=(card_reg_1[cardN]&0xff07) | 0xF0;
cards[cardN].card->cntl1 = card_reg_1[cardN];
break;
}
FASTUNLOCK(&(cards[cardN].lock));
return(0);
}
static long write_longout(plongout)
struct longoutRecord *plongout;
{
short cardN;
cardN = plongout->out.value.vmeio.card;
if (debug_flag >10)
logMsg("write_longout called with card %d\n",cardN);
if (checkLink(cardN) == ERROR)
return(ERROR);
FASTLOCK(&(cards[cardN].lock));
switch (plongout->out.value.vmeio.signal){
case 0: /* tap1 */
cards[cardN].card->tap1 = plongout->val;
break;
case 1: /* tap2 */
cards[cardN].card->tap2 = plongout->val;
break;
case 2: /* int delay */
card_reg_1[cardN]=(card_reg_1[cardN] & 0xff) | (plongout->val)<<8;
cards[cardN].card->cntl1 = card_reg_1[cardN];
break;
case 3: /* total conf */
cards[cardN].card->cntl1 = plongout->val;
break;
}
FASTUNLOCK(&(cards[cardN].lock));
return(CONVERT);
}
static long init_li_record(plongin)
struct longinRecord *plongin;
{
return(0);
}
static long read_longin(plongin)
struct longinRecord *plongin;
{
short cardN;
cardN = plongin->inp.value.vmeio.card;
if (debug_flag >10)
logMsg("read_longin called with card number of %d\n",cardN);
if (checkLink(cardN) == ERROR)
return(ERROR);
switch (plongin->inp.value.vmeio.signal){
case 0: /* tap2 */
plongin->val = cards[cardN].card->tap2;
break;
case 1: /* status */
plongin->val = cards[cardN].card->tap1;
break;
}
return(CONVERT);
}
static long init_wf_record(pwf)
struct waveformRecord *pwf;
{
return(0);
}
static long read_wf_record(pwf)
struct waveformRecord *pwf;
{
short cardN;
int i,j,k;
unsigned long int a1;
unsigned short* us_thing = (unsigned short*)pwf->bptr;
if (debug_flag >5)
logMsg("read_wf_record called...\n");
cardN = pwf->inp.value.vmeio.card;
if (debug_flag >5)
logMsg("read_wf_record called with card number of %d\n",cardN);
if (checkLink(cardN) == ERROR)
return(ERROR);
cards[cardN].card->cntl1 = 0x01 ;
switch(pwf->ftvl)
{
case DBF_USHORT:
{
switch (pwf->inp.value.vmeio.signal)
{
case 0:
for (j=0; j<32; j++)
for (i=0;i<80; i++)
{
(unsigned long)a1 = (unsigned long)(cards[cardN].card->board[j][i]);
us_thing[j*2+i*64] = (short)(a1 & 0xff);
us_thing[j*2+1+i*64] = (short)(a1 & 0xff0000)>>16;
};
break;
case 1:
for (j=0; j<32; j++)
for (i=0;i<80; i++)
{
a1 = cards[cardN].card->board[j][i];
us_thing[i*32+j] = (a1 & 0xff);
us_thing[i*32+j+1] = (a1 & 0xff0000)>>16;
};
for (k=1; k<4; k++)
for (j=0; j<32; j++)
for (i=0;i<80; i++)
{
a1 = cards[cardN].card->board[j][i+80*k];
us_thing[i*32+j] += (a1 & 0xff);
us_thing[i*32+1+j] += (a1 & 0xff0000)>>16;
};
break;
case 2:
for (j=0; j<32; j++)
for (i=0;i<80; i++)
{
a1 = cards[cardN].card->board[j][i];
us_thing[i*32+j] = (a1 & 0xff);
us_thing[i*32+1+j] = (a1 & 0xff0000)>>16;
};
for (k=1; k<64; k++)
for (j=0; j<32; j++)
for (i=0;i<80; i++)
{
a1 = cards[cardN].card->board[j][i+80*k];
us_thing[i*32+j] += (a1 & 0xff);
us_thing[i*32+1+j] += (a1 & 0xff0000)>>16;
};
break;
}
}
pwf->nord=5120;
break;
case DBF_SHORT:
default:
logMsg("devVmeFIR: Invalid data type\n");
}
cards[cardN].card->cntl1 = 0x01;
if (debug_flag > 5)
logMsg("devVmeFIR:end\n");
return(0);
}
/*
static long read_wf_record(pwf)
struct waveformRecord *pwf;
{
short cardN;
int i,j,k;
unsigned long int a1;
unsigned short* us_thing = (unsigned short*)pwf->bptr;
float* f_thing = (float*)pwf->bptr;
if (debug_flag >4)
logMsg("read_wf_record called...\n");
cardN = pwf->inp.value.vmeio.card;
if (debug_flag >5)
logMsg("read_wf_record called with card number of %d\n",cardN);
if (checkLink(cardN) == ERROR)
return(ERROR);
cards[cardN].card->cntl1 = 0x01 ;
switch(pwf->ftvl)
{
case DBF_USHORT:
{
switch (pwf->inp.value.vmeio.signal)
{
case 0:
for (j=0; j<8; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i];
us_thing[j*4+i*32]= (a1 & 0xff);
us_thing[j*4+i*32+1] = (a1 & 0xff0000)>>16;
us_thing[j*4+i*32+2] = (a1 & 0xff00)>>8;
us_thing[j*4+i*32+3] = (a1 >>24);
};
if (debug_flag >4) logMsg("end of read\n");
break;
case 1:
for (j=0; j<8; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i];
us_thing[j*4+i*32]= (a1 & 0xff);
us_thing[j*4+i*32+1] = (a1 & 0xff0000)>>16;
us_thing[j*4+i*32+2] = (a1 & 0xff00)>>8;
us_thing[j*4+i*32+3] = (a1 >>24);
};
for (k=1; k<4; k++)
for (j=0; j<8; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i+160*k];
us_thing[j*4+i*32] += (a1 & 0xff);
us_thing[j*4+i*32+1] += (a1 & 0xff0000)>>16;
us_thing[j*4+i*32+2] += (a1 & 0xff00)>>8;
us_thing[j*4+i*32+3] += (a1 >>24);
};
break;
case 2:
for (j=0; j<8; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i];
us_thing[j*4+i*32] = (a1 & 0xff);
us_thing[j*4+i*32+1] = (a1 & 0xff0000)>>16;
us_thing[j*4+i*32+2] = (a1 & 0xff00)>>8;
us_thing[j*4+i*32+3] = (a1 >>24);
};
for (k=1; k<64; k++)
for (j=0; j<32; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i+160*k];
us_thing[j*4+i*32] += (a1 & 0xff);
us_thing[j*4+i*32+1] += (a1 & 0xff0000)>>16;
us_thing[j*4+i*32+2] += (a1 & 0xff00)>>8;
us_thing[j*4+i*32+3] += (a1 >>24);
};
break;
}
}
pwf->nord=5120;
break;
case DBF_FLOAT:
{
switch (pwf->inp.value.vmeio.signal)
{
case 0:
for (j=0; j<8; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i];
f_thing[j*4+i*32]= (a1 & 0xff)*1.0;
f_thing[j*4+i*32+1] = 1.0*((a1 & 0xff0000)>>16);
f_thing[j*4+i*32+2] = 1.0*((a1 & 0xff00)>>8);
f_thing[j*4+i*32+3] = 1.0*((a1 >>24));
};
if (debug_flag >4) logMsg("end of read\n");
break;
case 1:
for (j=0; j<8; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i];
f_thing[j*4+i*32]= 1.0*(a1 & 0xff);
f_thing[j*4+i*32+1] = 1.0*((a1 & 0xff0000)>>16);
f_thing[j*4+i*32+2] = 1.0*((a1 & 0xff00)>>8);
f_thing[j*4+i*32+3] = 1.0*((a1 >>24));
};
for (k=1; k<4; k++)
for (j=0; j<8; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i+160*k];
f_thing[j*4+i*32] += 1.0*(a1 & 0xff);
f_thing[j*4+i*32+1] += 1.0*((a1 & 0xff0000)>>16);
f_thing[j*4+i*32+2] += 1.0*((a1 & 0xff00)>>8);
f_thing[j*4+i*32+3] += 1.0*(a1 >>24);
};
break;
case 2:
for (j=0; j<8; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i];
f_thing[j*4+i*32] = 1.0*(a1 & 0xff);
f_thing[j*4+i*32+1] = 1.0*((a1 & 0xff0000)>>16);
f_thing[j*4+i*32+2] = 1.0*((a1 & 0xff00)>>8);
f_thing[j*4+i*32+3] = 1.0*(a1 >>24);
};
for (k=1; k<64; k++)
for (j=0; j<32; j++)
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i+160*k];
f_thing[j*4+i*32] += 1.0*(a1 & 0xff);
f_thing[j*4+i*32+1] += 1.0*((a1 & 0xff0000)>>16);
f_thing[j*4+i*32+2] += 1.0*((a1 & 0xff00)>>8);
f_thing[j*4+i*32+3] += 1.0*(a1 >>24);
};
break;
}
}
pwf->nord=5120;
break;
default:
logMsg("devVmeFIR: Invalid data type\n");
}
cards[cardN].card->cntl1 = 0x01;
cards[cardN].card->cntl1 = 0x09;
cards[cardN].card->cntl1 = 0x0c;
if (debug_flag > 4)
logMsg("devVmeFIR:end\n");
return(0);
}
*/
#define ADDING 0
#define DELETING 1
/* 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;
cards[cardN].card->cntl1 = 0x01;
cards[cardN].card->cntl1 = 0x09;
cards[cardN].card->cntl1 = 0x0c;
if (debug_flag >1) logMsg("wf_INT CALLED\n");
return(0);
}
*/
/**************************************************************************
*
* Make sure card number is valid
*
**************************************************************************/
static int checkLink(cardN)
short cardN;
{
if (cardN >= vmeFIR_num_links)
return(ERROR);
if (cards[cardN].card == NULL)
{
logMsg("No VMEFIR with this number = %d\n",cardN);
return(ERROR);
}
if (debug_flag >10)
logMsg("Yes you have vmeFIR with card No= %d\n",cardN);
return(OK);
}