diff --git a/src/dev/devAiDvx2502.c b/src/dev/devAiDvx2502.c new file mode 100644 index 000000000..f050c7900 --- /dev/null +++ b/src/dev/devAiDvx2502.c @@ -0,0 +1,127 @@ +/* devAiDvx2502.c */ +/* share/src/dev $Id$ */ + +/* devAiDvx2502.c - Device Support Routines */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +long init_record(); +long get_ioint_info(); +long read_ai(); +long special_linconv(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_ai; + DEVSUPFUN special_linconv; +} devAiDvx2502={ + 6, + NULL, + NULL, + init_record, + get_ioint_info, + read_ai, + special_linconv}; + + +static long init_record(pai) + struct aiRecord *pai; +{ + char message[100]; + short value; + struct vmeio *pvmeio; + long status; + + /* ai.inp must be an VME_IO */ + switch (pai->inp.type) { + case (VME_IO) : + break; + default : + strcpy(message,pai->name); + strcat(message,": devAiDvx2502 (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + + /* set linear conversion slope*/ + pai->eslo = (pai->eguf -pai->egul)/65535.0; + + /* call driver so that it configures card */ + pvmeio = (struct vmeio *)&(pai->inp.value); + if(status=ai_driver(pvmeio->card,pvmeio->signal,DVX2502,&value)) { + strcpy(message,pai->name); + strcat(message,": devAiDvx2502 (init_record) ai_driver error"); + errMessage(status,message); + return(status); + } + return(0); +} + +static long get_ioint_info(pai,io_type,card_type,card_number) + struct aiRecord *pai; + short *io_type; + short *card_type; + short *card_number; +{ + if(pai->inp.type != VME_IO) return(S_dev_badInpType); + *io_type = IO_AI; + *card_type = DVX2502; + *card_number = pai->inp.value.vmeio.card; + return(0); +} + +static long read_ai(pai) + struct aiRecord *pai; +{ + unsigned short value; + struct vmeio *pvmeio; + long status; + + + pvmeio = (struct vmeio *)&(pai->inp.value); + if(status=ai_driver(pvmeio->card,pvmeio->signal,DVX2502,&value)) + return(status); + *((unsigned short*)(&pai->rval))=value; + if(status==0 || status==-2) pai->rval = value; + if(status==-1) { + if(pai->nsevnsta = READ_ALARM; + pai->nsev = MAJOR_ALARM; + } + status=2; /*don't convert*/ + }else if(status==-2) { + status=0; + if(pai->nsevnsta = HW_LIMIT_ALARM; + pai->nsev = MAJOR_ALARM; + } + } + return(status); +} + +static long special_linconv(pai,after) + struct aiRecord *pai; + int after; +{ + + if(!after) return(0); + /* set linear conversion slope*/ + pai->eslo = (pai->eguf -pai->egul)/65535.0; + return(0); +} diff --git a/src/dev/devAiSoft.c b/src/dev/devAiSoft.c new file mode 100644 index 000000000..46125a2eb --- /dev/null +++ b/src/dev/devAiSoft.c @@ -0,0 +1,97 @@ +/* devAiSoft.c */ +/* share/src/dev $Id$ */ + +/* devAiSoft.c - Device Support Routines for soft Analog Input Records*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Create the dset for devAiSoft */ +long init_record(); +long read_ai(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_ai; + DEVSUPFUN special_linconv; +}devAiSoft={ + 6, + NULL, + NULL, + init_record, + NULL, + read_ai, + NULL}; + + +static long init_record(pai) + struct aiRecord *pai; +{ + char message[100]; + + /* ai.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pai->inp.type) { + case (CONSTANT) : + pai->val = pai->inp.value.value; + break; + case (PV_LINK) : + break; + case (DB_LINK) : + break; + case (CA_LINK) : + break; + default : + strcpy(message,pai->name); + strcat(message,": devAiSoft (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + /* Make sure record processing routine does not perform any conversion*/ + pai->linr=0; + return(0); +} + +static long read_ai(pai) + struct aiRecord *pai; +{ + char message[100]; + long status,options,nRequest; + + /* ai.inp must be a CONSTANT or a DB_LINK or a CA_LINK*/ + switch (pai->inp.type) { + case (CONSTANT) : + break; + case (DB_LINK) : + options=0; + nRequest=1; + (void)dbGetLink(&(pai->inp.value.db_link),pai,DBR_FLOAT, + &(pai->val),&options,&nRequest); + break; + case (CA_LINK) : + break; + default : + if(pai->nsevnsev = MAJOR_ALARM; + pai->nsta = SOFT_ALARM; + if(pai->stat!=SOFT_ALARM) { + strcpy(message,pai->name); + strcat(message,": devAiSoft (read_ai) Illegal INP field"); + errMessage(S_db_badField,message); + } + } + } + return(2); /*don't convert*/ +} diff --git a/src/dev/devAiTestAsyn.c b/src/dev/devAiTestAsyn.c new file mode 100644 index 000000000..bc03c5f7d --- /dev/null +++ b/src/dev/devAiTestAsyn.c @@ -0,0 +1,131 @@ +/* devAiTestAsyn.c */ +/* share/src/dev $Id$ */ + +/* devAiTestAsyn.c - Device Support Routines for testing asynchronous processing*/ + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Create the dset for devAiTestAsyn */ +long init_record(); +long read_ai(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_ai; + DEVSUPFUN special_linconv; +}devAiTestAsyn={ + 6, + NULL, + NULL, + init_record, + NULL, + read_ai, + NULL}; + +/* control block for callback*/ +struct callback { + void (*callback)(); + struct dbAddr dbAddr; + WDOG_ID wd_id; + short completion; +}; + +void callbackRequest(); + +static void myCallback(pcallback) + struct callback *pcallback; +{ + struct aiRecord *pai=(struct aiRecord *)(pcallback->dbAddr.precord); + + dbScanLock(pai); + pcallback->completion = TRUE; + pai->pact=0; + dbScanPassive(&(pcallback->dbAddr)); + dbScanUnlock(pai); +} + + + +static long init_record(pai) + struct aiRecord *pai; +{ + char message[100]; + struct callback *pcallback; + int precTypeIndex; + struct rset *prset; + + /* ai.inp must be a CONSTANT*/ + switch (pai->inp.type) { + case (CONSTANT) : + pcallback = (struct callback *)(calloc(1,sizeof(struct callback *))); + pai->dpvt = (caddr_t)pcallback; + pcallback->callback = myCallback; + if(dbNameToAddr(pai->name,&(pcallback->dbAddr))) { + logMsg("dbNameToAddr failed in init_record for devAiTestAsyn\n"); + exit(1); + } + pcallback->wd_id = wdCreate(); + pai->val = pai->inp.value.value; + break; + default : + strcpy(message,pai->name); + strcat(message,": devAiTestAsyn (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + /* Make sure record processing routine does not perform any conversion*/ + pai->linr=0; + return(0); +} + +static long read_ai(pai) + struct aiRecord *pai; +{ + char message[100]; + long status,options,nRequest; + struct callback *pcallback=(struct callback *)(pai->dpvt); + short wait_time; + + /* ai.inp must be a CONSTANT*/ + switch (pai->inp.type) { + case (CONSTANT) : + if(pcallback->completion==TRUE) { + printf("%s Completed\n",pai->name); + pcallback->completion=FALSE; + return(0); + } else { + wait_time = (short)(pai->val); + if(wait_time<=0) return(0); + printf("%s Starting asynchronous processing\n",pai->name); + wdStart(pcallback->wd_id,wait_time,callbackRequest,pcallback); + return(1); + } + default : + if(pai->nsevnsev = MAJOR_ALARM; + pai->nsta = SOFT_ALARM; + if(pai->stat!=SOFT_ALARM) { + strcpy(message,pai->name); + strcat(message,": devAiTestAsyn (read_ai) Illegal INP field"); + errMessage(S_db_badField,message); + } + } + } + return(0); +} diff --git a/src/dev/devAiXy566Di.c b/src/dev/devAiXy566Di.c new file mode 100644 index 000000000..889a5bf99 --- /dev/null +++ b/src/dev/devAiXy566Di.c @@ -0,0 +1,120 @@ +/* devAiXy566Di.c */ +/* share/src/dev $Id$ */ + +/* devAiXy566Di.c - Device Support Routines */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +long init_record(); +long read_ai(); +long special_linconv(); + + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_ai; + DEVSUPFUN special_linconv; +} devAiXy566Di={ + 6, + NULL, + NULL, + init_record, + NULL, + read_ai, + special_linconv}; + + +static long init_record(pai) + struct aiRecord *pai; +{ + char message[100]; + short value; + struct vmeio *pvmeio; + long status; + + /* ai.inp must be an VME_IO */ + switch (pai->inp.type) { + case (VME_IO) : + break; + default : + strcpy(message,pai->name); + strcat(message,": devAiXy566Di (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + + /* set linear conversion slope*/ + pai->eslo = (pai->eguf -pai->egul)/4095.0; + + /* call driver so that it configures card */ + pvmeio = (struct vmeio *)&(pai->inp.value); + if(status=ai_driver(pvmeio->card,pvmeio->signal,XY566DI,&value)) { + strcpy(message,pai->name); + strcat(message,": devAiXy566Di (init_record) ai_driver error"); + errMessage(status,message); + return(status); + } + return(0); +} + +static long read_ai(pai) + struct aiRecord *pai; +{ + short value; + struct vmeio *pvmeio; + long status; + + + pvmeio = (struct vmeio *)&(pai->inp.value); + status=ai_driver(pvmeio->card,pvmeio->signal,XY566DI,&value); + if(status==-1) { + status = 2; /* don't convert*/ + if(pai->nsevnsta = READ_ALARM; + pai->nsev = MAJOR_ALARM; + + } + return(status); + }else if(status==-2) { + status=0; + if(pai->nsevnsta = HW_LIMIT_ALARM; + pai->nsev = MAJOR_ALARM; + } + } + if(status!=0) return(status); + /*read into hardware as -0x7ff to +0x7ff */ + /* normalize to 0 - 0xfff */ + value = value + 0x800; + /* remove the sign bit */ + value &= 0xfff; + pai->rval = value; + return(status); +} + +static long special_linconv(pai,after) + struct aiRecord *pai; + int after; +{ + + if(!after) return(0); + /* set linear conversion slope*/ + pai->eslo = (pai->eguf -pai->egul)/4095.0; + return(0); +} diff --git a/src/dev/devAiXy566Se.c b/src/dev/devAiXy566Se.c new file mode 100644 index 000000000..cfdbd0792 --- /dev/null +++ b/src/dev/devAiXy566Se.c @@ -0,0 +1,113 @@ +/* devAiXy566Se.c */ +/* share/src/dev $Id$ */ + +/* devAiXy566Se.c - Device Support Routines */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +long init_record(); +long read_ai(); +long special_linconv(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_ai; + DEVSUPFUN special_linconv; +} devAiXy566Se={ + 6, + NULL, + NULL, + init_record, + NULL, + read_ai, + special_linconv}; + + +static long init_record(pai) + struct aiRecord *pai; +{ + char message[100]; + short value; + struct vmeio *pvmeio; + long status; + + /* ai.inp must be an VME_IO */ + switch (pai->inp.type) { + case (VME_IO) : + break; + default : + strcpy(message,pai->name); + strcat(message,": devAiXy566Se (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + + /* set linear conversion slope*/ + pai->eslo = (pai->eguf -pai->egul)/4095.0; + + /* call driver so that it configures card */ + pvmeio = (struct vmeio *)&(pai->inp.value); + if(status=ai_driver(pvmeio->card,pvmeio->signal,XY566SE,&value)) { + strcpy(message,pai->name); + strcat(message,": devAiXy566Se (init_record) ai_driver error"); + errMessage(status,message); + return(status); + } + return(0); +} + +static long read_ai(pai) + struct aiRecord *pai; +{ + short value; + struct vmeio *pvmeio; + long status; + + + pvmeio = (struct vmeio *)&(pai->inp.value); + status=ai_driver(pvmeio->card,pvmeio->signal,XY566SE,&value); + if(status==-1) { + status = 2; /*don't convert*/ + if(pai->nsevnsta = READ_ALARM; + pai->nsev = MAJOR_ALARM; + } + return(status); + }else if(status==-2) { + status=0; + if(pai->nsevnsta = HW_LIMIT_ALARM; + pai->nsev = MAJOR_ALARM; + } + } + if(status!=0) return(status); + pai->rval = value & 0xfff; + return(status); +} + +static long special_linconv(pai,after) + struct aiRecord *pai; + int after; +{ + + if(!after) return(0); + /* set linear conversion slope*/ + pai->eslo = (pai->eguf -pai->egul)/4095.0; + return(0); +} diff --git a/src/dev/devAoSoft.c b/src/dev/devAoSoft.c new file mode 100644 index 000000000..319d4a492 --- /dev/null +++ b/src/dev/devAoSoft.c @@ -0,0 +1,96 @@ +/* devAoSoft.c */ +/* share/src/dev $Id$ */ + +/* Device Support Routines for soft Analog Output Records*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Create the dset for devAoSoft */ +long init_record(); +long write_ao(); +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_ao; + DEVSUPFUN special_linconv; +}devAoSoft={ + 6, + NULL, + NULL, + init_record, + NULL, + write_ao, + NULL}; + + +static long init_record(pao) + struct aoRecord *pao; +{ + char message[100]; + + /* ao.out must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pao->out.type) { + case (CONSTANT) : + pao->val = pao->out.value.value; + break; + case (PV_LINK) : + break; + case (DB_LINK) : + break; + case (CA_LINK) : + break; + default : + strcpy(message,pao->name); + strcat(message,": devAoSoft (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + /* Make sure record processing routine does not perform any conversion*/ + pao->linr=0; + return(0); +} + +static long write_ao(pao) + struct aoRecord *pao; +{ + char message[100]; + long status,nRequest; + + /* ao.out must be a CONSTANT or a DB_LINK or a CA_LINK*/ + switch (pao->out.type) { + case (CONSTANT) : + break; + case (DB_LINK) : + nRequest=1; + (void)dbPutLink(&(pao->out.value.db_link),pao,DBR_FLOAT, + &(pao->val),&nRequest); + break; + case (CA_LINK) : + break; + default : + if(pao->nsevnsev = MAJOR_ALARM; + pao->nsta = SOFT_ALARM; + if(pao->stat!=SOFT_ALARM) { + strcpy(message,pao->name); + strcat(message,": devAoSoft (write_ao) Illegal INP field"); + errMessage(S_db_badField,message); + } + } + } + return(0); +} diff --git a/src/dev/devAoVmiVme4100.c b/src/dev/devAoVmiVme4100.c new file mode 100644 index 000000000..0f93fc800 --- /dev/null +++ b/src/dev/devAoVmiVme4100.c @@ -0,0 +1,134 @@ +/* devAoVmiVme4100.c.c */ +/* share/src/dev $Id$ */ + +/* Device Support Routines for VMI4100 analog output*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* The following must match the definition in choiceGbl.ascii */ +#define LINEAR 1 + +/* Create the dset for devAoAoVmiVme4100 */ +long init_record(); +long write_ao(); +long special_linconv(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_ao; + DEVSUPFUN special_linconv; +}devAoVmiVme4100={ + 6, + NULL, + NULL, + init_record, + NULL, + write_ao, + special_linconv}; + +void read_ao(); + + +static long init_record(pao) + struct aoRecord *pao; +{ + char message[100]; + short value; + struct vmeio *pvmeio; + + /* ao.out must be an VME_IO */ + switch (pao->out.type) { + case (VME_IO) : + break; + default : + strcpy(message,pao->name); + strcat(message,": devAoVmiVme4100 (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + + /* set linear conversion slope*/ + pao->eslo = (pao->eguf -pao->egul)/4095.0; + + /* call driver so that it configures card */ + read_ao(pao); + return(0); +} + +static long write_ao(pao) + struct aoRecord *pao; +{ + struct vmeio *pvmeio; + int status; + unsigned short value,rbvalue; + + + pvmeio = (struct vmeio *)&(pao->out.value); + value = pao->rval; + status = ao_driver(pvmeio->card,pvmeio->signal,pao->type,&value,&rbvalue); + if(status==0 || status==-2) pao->rbv = rbvalue; + if(status==-1) { + if(pao->nsevnsta = WRITE_ALARM; + pao->nsev = MAJOR_ALARM; + } + status=2; /*dont convert*/ + }else if(status==-2) { + status=0; + if(pao->nsevnsta = HW_LIMIT_ALARM; + pao->nsev = MAJOR_ALARM; + } + } + return(status); +} + + +static long special_linconv(pao,after) + struct aoRecord *pao; + int after; +{ + + if(!after) return(0); + /* set linear conversion slope*/ + pao->eslo = (pao->eguf -pao->egul)/4095.0; + return(0); +} + +static void read_ao(pao) +struct aoRecord *pao; +{ + int status; + unsigned short value; + struct vmeio *pvmeio = &pao->out.value.vmeio; + + /* get the value from the ao driver */ + ao_read(pvmeio->card,pvmeio->signal,pao->type,&value); + /* convert raw readback to egu */ + switch (pao->linr){ + case (LINEAR): + pao->rbv = (value * pao->eslo) + pao->egul; + break; + default: + pao->rbv = value; + } + pao->val = pao->rbv; + return; +} + diff --git a/src/dev/devBiMpv910.c b/src/dev/devBiMpv910.c new file mode 100644 index 000000000..3c87570b1 --- /dev/null +++ b/src/dev/devBiMpv910.c @@ -0,0 +1,91 @@ +/* devBiMpv910.c */ +/* share/src/dev $Id$ */ + +/* devBiMpv910.c - Device Support Routines for Burr Brown MPV 910 Binary input */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devAiBiMpv910 */ +long init_record(); +long read_bi(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_bi; +}devBiMpv910={ + 5, + NULL, + NULL, + init_record, + NULL, + read_bi}; +static long masks[] = { + 0x00000001,0x00000002,0x00000004,0x00000008, + 0x00000010,0x00000020,0x00000040,0x00000080, + 0x00000100,0x00000200,0x00000400,0x00000800, + 0x00001000,0x00002000,0x00004000,0x00008000, + 0x00010000,0x00020000,0x00040000,0x00080000, + 0x00100000,0x00200000,0x00400000,0x00800000, + 0x01000000,0x02000000,0x04000000,0x08000000, + 0x10000000,0x20000000,0x40000000,0x80000000, +}; + + +static long init_record(pbi) + struct biRecord *pbi; +{ + char message[100]; + short value; + struct vmeio *pvmeio; + + /* bi.inp must be an VME_IO */ + switch (pbi->inp.type) { + case (VME_IO) : + break; + default : + strcpy(message,pbi->name); + strcat(message,": devBiMpv910 (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long read_bi(pbi) + struct biRecord *pbi; +{ + struct vmeio *pvmeio; + int status; + long value; + + + pvmeio = (struct vmeio *)&(pbi->inp.value); + status = bi_driver(pvmeio->card,masks[pvmeio->signal],BB910,&value); + if(status==0) { + pbi->rval = value; + if(value == 0) pbi->val = 0; + else pbi->val = 1; + } else { + if(pbi->nsevnsta = READ_ALARM; + pbi->nsev = MAJOR_ALARM; + } + } + return(status); +} diff --git a/src/dev/devBiSoft.c b/src/dev/devBiSoft.c new file mode 100644 index 000000000..2d47c6755 --- /dev/null +++ b/src/dev/devBiSoft.c @@ -0,0 +1,94 @@ +/* devBiSoft.c */ +/* share/src/dev $Id$ */ + +/* devBiSoft.c - Device Support Routines for Soft Binary Input*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devBiSoft */ +long init_record(); +long read_bi(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_bi; +}devBiSoft={ + 5, + NULL, + NULL, + init_record, + NULL, + read_bi}; + + +static long init_record(pbi) + struct biRecord *pbi; +{ + char message[100]; + /* bi.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pbi->inp.type) { + case (CONSTANT) : + pbi->val = pbi->inp.value.value; + break; + case (PV_LINK) : + break; + case (DB_LINK) : + break; + case (CA_LINK) : + break; + default : + strcpy(message,pbi->name); + strcat(message,": devBiSoft (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long read_bi(pbi) + struct biRecord *pbi; +{ + char message[100]; + long status,options,nRequest; + + /* bi.inp must be a CONSTANT or a DB_LINK or a CA_LINK*/ + switch (pbi->inp.type) { + case (CONSTANT) : + break; + case (DB_LINK) : + options=0; + nRequest=1; + (void)dbGetLink(&(pbi->inp.value.db_link),pbi,DBR_SHORT, + &(pbi->val),&options,&nRequest); + break; + case (CA_LINK) : + break; + default : + if(pbi->nsevnsev = MAJOR_ALARM; + pbi->nsta = SOFT_ALARM; + if(pbi->stat!=SOFT_ALARM) { + strcpy(message,pbi->name); + strcat(message,": devBiSoft (read_bi) Illegal INP field"); + errMessage(S_db_badField,message); + } + } + } + return(0); +} diff --git a/src/dev/devBiXVme210.c b/src/dev/devBiXVme210.c new file mode 100644 index 000000000..ca6c2e2df --- /dev/null +++ b/src/dev/devBiXVme210.c @@ -0,0 +1,91 @@ +/* devBiXVme210.c */ +/* share/src/dev $Id$ */ + +/* devBiXVme210.c - Device Support Routines for XYcom 32 bit binary input*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devBiXVme210 */ +long init_record(); +long read_bi(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_bi; +}devBiXVme210={ + 5, + NULL, + NULL, + init_record, + NULL, + read_bi}; +static long masks[] = { + 0x00000001,0x00000002,0x00000004,0x00000008, + 0x00000010,0x00000020,0x00000040,0x00000080, + 0x00000100,0x00000200,0x00000400,0x00000800, + 0x00001000,0x00002000,0x00004000,0x00008000, + 0x00010000,0x00020000,0x00040000,0x00080000, + 0x00100000,0x00200000,0x00400000,0x00800000, + 0x01000000,0x02000000,0x04000000,0x08000000, + 0x10000000,0x20000000,0x40000000,0x80000000, +}; + + +static long init_record(pbi) + struct biRecord *pbi; +{ + char message[100]; + short value; + struct vmeio *pvmeio; + + /* bi.inp must be an VME_IO */ + switch (pbi->inp.type) { + case (VME_IO) : + break; + default : + strcpy(message,pbi->name); + strcat(message,": devBiXVme210 (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long read_bi(pbi) + struct biRecord *pbi; +{ + struct vmeio *pvmeio; + int status; + long value; + + + pvmeio = (struct vmeio *)&(pbi->inp.value); + status = bi_driver(pvmeio->card,masks[pvmeio->signal],XY210,&value); + if(status==0) { + pbi->rval = value; + if(value == 0) pbi->val = 0; + else pbi->val = 1; + } else { + if(pbi->nsevnsta = READ_ALARM; + pbi->nsev = MAJOR_ALARM; + } + } + return(status); +} diff --git a/src/dev/devBoMpv902.c b/src/dev/devBoMpv902.c new file mode 100644 index 000000000..cf1046980 --- /dev/null +++ b/src/dev/devBoMpv902.c @@ -0,0 +1,107 @@ +/* devBoMpv902.c */ +/* share/src/dev $Id$ */ + +/* devBoMpv902.c - Device Support Routines for Burr Brown MPV 902 Binary output */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devAiBoMpv902 */ +long init_record(); +long write_bo(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_bo; +}devBoMpv902={ + 5, + NULL, + NULL, + init_record, + NULL, + write_bo}; +static long masks[] = { + 0x00000001,0x00000002,0x00000004,0x00000008, + 0x00000010,0x00000020,0x00000040,0x00000080, + 0x00000100,0x00000200,0x00000400,0x00000800, + 0x00001000,0x00002000,0x00004000,0x00008000, + 0x00010000,0x00020000,0x00040000,0x00080000, + 0x00100000,0x00200000,0x00400000,0x00800000, + 0x01000000,0x02000000,0x04000000,0x08000000, + 0x10000000,0x20000000,0x40000000,0x80000000, +}; + + +static long init_record(pbo) + struct biRecord *pbo; +{ + char message[100]; + int value,status; + struct vmeio *pvmeio; + + /* bo.out must be an VME_IO */ + switch (pbo->out.type) { + case (VME_IO) : + pvmeio = (struct vmeio *)(&pbo->out.value); + /* read the value via bo driver */ + status = bo_read(pvmeio->card,masks[pvmeio->signal],&value,BB902); + if(status == 0) { + pbo->rbv = pbo->val = (value == 0)?0:1; + } else if(status == -1) { + strcpy(message,pbo->name); + strcat(message,": devBoMpv902 (init_record) card does not exist"); + errMessage(S_db_badField,message); + return(S_db_badField); + } else { + strcpy(message,pbo->name); + strcat(message,": devBoMpv902 (init_record) illegal device"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + break; + default : + strcpy(message,pbo->name); + strcat(message,": devBoMpv902 (init_record) Illegal OUT field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long write_bo(pbo) + struct biRecord *pbo; +{ + struct vmeio *pvmeio; + int status; + long value; + + + pvmeio = (struct vmeio *)&(pbo->out.value); + if(pbo->val == 0) pbo->rval = 0; + else pbo->rval = masks[pvmeio->signal]; + status = bo_driver(pvmeio->card,pbo->rval,masks[pvmeio->signal],BB902); + if(status==0) { + pbo->rbv = pbo->val; + } else { + if(pbo->nsevnsta = WRITE_ALARM; + pbo->nsev = MAJOR_ALARM; + } + } + return(status); +} diff --git a/src/dev/devBoSoft.c b/src/dev/devBoSoft.c new file mode 100644 index 000000000..b26815cac --- /dev/null +++ b/src/dev/devBoSoft.c @@ -0,0 +1,92 @@ +/* devBoSoft.c */ +/* share/src/dev $Id$ */ + +/* devBoSoft.c - Device Support Routines for Soft Binary Output*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devBoSoft */ +long init_record(); +long write_bo(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_bo; +}devBoSoft={ + 5, + NULL, + NULL, + init_record, + NULL, + write_bo}; + + +static long init_record(pbo) + struct boRecord *pbo; +{ + char message[100]; + /* bo.out must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pbo->out.type) { + case (CONSTANT) : + pbo->val = pbo->out.value.value; + break; + case (PV_LINK) : + break; + case (DB_LINK) : + break; + case (CA_LINK) : + break; + default : + strcpy(message,pbo->name); + strcat(message,": devBoSoft (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long write_bo(pbo) + struct boRecord *pbo; +{ + char message[100]; + long status; + + /* bo.out must be a CONSTANT or a DB_LINK or a CA_LINK*/ + switch (pbo->out.type) { + case (CONSTANT) : + break; + case (DB_LINK) : + nRequest=1; + (void)dbPutLink(&(pbo->out.value.db_link),pbo,DBR_SHORT,pbo->val,1L); + break; + case (CA_LINK) : + break; + default : + if(pbo->nsevnsev = MAJOR_ALARM; + pbo->nsta = SOFT_ALARM; + if(pbo->stat!=SOFT_ALARM) { + strcpy(message,pbo->name); + strcat(message,": devBoSoft (write_ai) Illegal INP field"); + errMessage(S_db_badField,message); + } + } + } + return(0); +} diff --git a/src/dev/devBoXVme220.c b/src/dev/devBoXVme220.c new file mode 100644 index 000000000..361242690 --- /dev/null +++ b/src/dev/devBoXVme220.c @@ -0,0 +1,105 @@ +/* devBoXVme220.c */ +/* share/src/dev $Id$ */ + +/* devBoXVme220.c - Device Support Routines for XYcom 32 bit binary output*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devAiBoXVme220 */ +long init_record(); +long write_bo(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_bo; +}devBoXVme220={ + 5, + NULL, + NULL, + init_record, + NULL, + write_bo}; +static long masks[] = { + 0x00000001,0x00000002,0x00000004,0x00000008, + 0x00000010,0x00000020,0x00000040,0x00000080, + 0x00000100,0x00000200,0x00000400,0x00000800, + 0x00001000,0x00002000,0x00004000,0x00008000, + 0x00010000,0x00020000,0x00040000,0x00080000, + 0x00100000,0x00200000,0x00400000,0x00800000, + 0x01000000,0x02000000,0x04000000,0x08000000, + 0x10000000,0x20000000,0x40000000,0x80000000, +}; + + +static long init_record(pbo) + struct biRecord *pbo; +{ + char message[100]; + int value,status; + struct vmeio *pvmeio; + + /* bo.out must be an VME_IO */ + switch (pbo->out.type) { + case (VME_IO) : + status = bo_read(pvmeio->card,masks[pvmeio->signal],&value,XY220); + if(status == 0) { + pbo->rbv = pbo->val = (value == 0)?0:1; + } else if(status == -1) { + strcpy(message,pbo->name); + strcat(message,": devBoXVme220 (init_record) card does not exist"); + errMessage(S_db_badField,message); + return(S_db_badField); + } else { + strcpy(message,pbo->name); + strcat(message,": devBoXVme220 (init_record) illegal device"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + break; + default : + strcpy(message,pbo->name); + strcat(message,": devBoXVme220 (init_record) Illegal OUT field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long write_bo(pbo) + struct biRecord *pbo; +{ + struct vmeio *pvmeio; + int status; + long value; + + + pvmeio = (struct vmeio *)&(pbo->out.value); + if(pbo->val == 0) pbo->rval = 0; + else pbo->rval = masks[pvmeio->signal]; + status = bo_driver(pvmeio->card,pbo->rval,masks[pvmeio->signal],XY220); + if(status==0) { + pbo->rbv = pbo->val; + } else { + if(pbo->nsevnsta = WRITE_ALARM; + pbo->nsev = MAJOR_ALARM; + } + } + return(status); +} diff --git a/src/dev/devMbbiMpv910.c b/src/dev/devMbbiMpv910.c new file mode 100644 index 000000000..0b5c408d0 --- /dev/null +++ b/src/dev/devMbbiMpv910.c @@ -0,0 +1,91 @@ +/* devMbbiMpv910.c */ +/* share/src/dev $Id$ */ + +/* devMbbiMpv910.c - Device Support Routines*/ +/* Burr Brown MPV 910 Multibit Binary input */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devAiMbbiMpv910 */ +long init_record(); +long read_mbbi(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_mbbi; +}devMbbiMpv910={ + 5, + NULL, + NULL, + init_record, + NULL, + read_mbbi}; +static long masks[] = { + 0x00000000, + 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, + 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, + 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, + 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, + 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, + 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, + 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff +}; + + +static long init_record(pmbbi) + struct mbbiRecord *pmbbi; +{ + char message[100]; + struct vmeio *pvmeio; + + /* mbbi.inp must be an VME_IO */ + switch (pmbbi->inp.type) { + case (VME_IO) : + pmbbi->mask = masks[pmbbi->nobt]<inp.value.vmeio.signal; + break; + default : + strcpy(message,pmbbi->name); + strcat(message,": devMbbiMpv910 (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long read_mbbi(pmbbi) + struct mbbiRecord *pmbbi; +{ + struct vmeio *pvmeio; + int status; + unsigned long value; + + + pvmeio = (struct vmeio *)&(pmbbi->inp.value); + status = bi_driver(pvmeio->card,masks[pvmeio->signal],BB910,&value); + if(status==0) { + pmbbi->rval = value; + } else { + if(pmbbi->nsevnsta = READ_ALARM; + pmbbi->nsev = MAJOR_ALARM; + } + } + return(status); +} diff --git a/src/dev/devMbbiSoft.c b/src/dev/devMbbiSoft.c new file mode 100644 index 000000000..3e26878d7 --- /dev/null +++ b/src/dev/devMbbiSoft.c @@ -0,0 +1,94 @@ +/* devMbbiSoft.c */ +/* share/src/dev $Id$ */ + +/* devMbbiSoft.c - Device Support Routines for Soft Multibit Binary Input*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devMbbiSoft */ +long init_record(); +long read_mbbi(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_mbbi; +}devMbbiSoft={ + 5, + NULL, + NULL, + init_record, + NULL, + read_mbbi}; + + +static long init_record(pmbbi) + struct mbbiRecord *pmbbi; +{ + char message[100]; + /* mbbi.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pmbbi->inp.type) { + case (CONSTANT) : + pmbbi->val = pmbbi->inp.value.value; + break; + case (PV_LINK) : + break; + case (DB_LINK) : + break; + case (CA_LINK) : + break; + default : + strcpy(message,pmbbi->name); + strcat(message,": devMbbiSoft (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long read_mbbi(pmbbi) + struct mbbiRecord *pmbbi; +{ + char message[100]; + long status,options,nRequest; + + /* mbbi.inp must be a CONSTANT or a DB_LINK or a CA_LINK*/ + switch (pmbbi->inp.type) { + case (CONSTANT) : + break; + case (DB_LINK) : + options=0; + nRequest=1; + (void)dbGetLink(&(pmbbi->inp.value.db_link),pmbbi,DBR_ULONG, + &(pmbbi->rval),&options,&nRequest); + break; + case (CA_LINK) : + break; + default : + if(pmbbi->nsevnsev = MAJOR_ALARM; + pmbbi->nsta = SOFT_ALARM; + if(pmbbi->stat!=SOFT_ALARM) { + strcpy(message,pmbbi->name); + strcat(message,": devMbbiSoft (read_mbbi) Illegal INP field"); + errMessage(S_db_badField,message); + } + } + } + return(0); +} diff --git a/src/dev/devMbbiXVme210.c b/src/dev/devMbbiXVme210.c new file mode 100644 index 000000000..b6a8e60f9 --- /dev/null +++ b/src/dev/devMbbiXVme210.c @@ -0,0 +1,91 @@ +/* devMbbiXVme210.c */ +/* share/src/dev $Id$ */ + +/* devMbbiXVme210.c - Device Support Routines */ +/* XYcom 32 bit Multibit binary input */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devAiMbbiXVme210 */ +long init_record(); +long read_mbbi(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_mbbi; +}devMbbiXVme210={ + 5, + NULL, + NULL, + init_record, + NULL, + read_mbbi}; +static long masks[] = { + 0x00000000, + 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, + 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, + 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, + 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, + 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, + 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, + 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff +}; + + +static long init_record(pmbbi) + struct mbbiRecord *pmbbi; +{ + char message[100]; + struct vmeio *pvmeio; + + /* mbbi.inp must be an VME_IO */ + switch (pmbbi->inp.type) { + case (VME_IO) : + pmbbi->mask = masks[pmbbi->nobt]<inp.value.vmeio.signal; + break; + default : + strcpy(message,pmbbi->name); + strcat(message,": devMbbiXVme210 (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long read_mbbi(pmbbi) + struct mbbiRecord *pmbbi; +{ + struct vmeio *pvmeio; + int status; + unsigned long value; + + + pvmeio = (struct vmeio *)&(pmbbi->inp.value); + status = bi_driver(pvmeio->card,masks[pvmeio->signal],XY210,&value); + if(status==0) { + pmbbi->rval = value; + } else { + if(pmbbi->nsevnsta = READ_ALARM; + pmbbi->nsev = MAJOR_ALARM; + } + } + return(status); +} diff --git a/src/dev/devMbboMpv902.c b/src/dev/devMbboMpv902.c new file mode 100644 index 000000000..5ec8d54fb --- /dev/null +++ b/src/dev/devMbboMpv902.c @@ -0,0 +1,115 @@ +/* devMbboMpv902.c */ +/* share/src/dev $Id$ */ + +/* devMbboMpv902.c - Device Support Routines */ +/* Burr Brown MPV 902 */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devAiMbboMpv902 */ +long init_record(); +long write_mbbo(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_mbbo; +}devMbboMpv902={ + 5, + NULL, + NULL, + init_record, + NULL, + write_mbbo}; +static long masks[] = { + 0x00000000, + 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, + 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, + 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, + 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, + 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, + 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, + 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff +}; + + +static long init_record(pmbbo) + struct mbboRecord *pmbbo; +{ + char message[100]; + unsigned long value; + struct vmeio *pvmeio; + int status; + + /* mbbo.out must be an VME_IO */ + switch (pmbbo->out.type) { + case (VME_IO) : + pvmeio = &(pmbbo->out.value.vmeio); + pmbbo->mask = masks[pmbbo->nobt]<signal; + status = bo_read(pvmeio->card,pmbbo->mask,&value,BB902); + if(status==0) pmbbo->rval = value>> pvmeio->signal; + break; + default : + strcpy(message,pmbbo->name); + strcat(message,": devMbboMpv902 (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long write_mbbo(pmbbo) + struct mbboRecord *pmbbo; +{ + struct vmeio *pvmeio; + int status; + unsigned long value; + + + pvmeio = &(pmbbo->out.value.vmeio); + if(pmbbo->sdef) { + unsigned long *pvalues = &(pmbbo->zrvl); + + if(pmbbo->val<0 || pmbbo->val>15) { + if(pmbbo->nsevnsta = SOFT_ALARM; + pmbbo->nsev = MAJOR_ALARM; + } + return(0); + } + value=pvalues[pmbbo->val]; + pmbbo->rval = value<signal; + } else pmbbo->rval = ((unsigned long)(pmbbo->val))<signal; + + status = bo_driver(pvmeio->card,pmbbo->rval,pmbbo->mask,BB902); + if(status==0) { + status = bo_read(pvmeio->card,pmbbo->mask,&value,BB902); + if(status==0) pmbbo->rval = value>> pvmeio->signal; + else if(pmbbo->nsevnsta = READ_ALARM; + pmbbo->nsev = MAJOR_ALARM; + } + } else { + if(pmbbo->nsevnsta = WRITE_ALARM; + pmbbo->nsev = MAJOR_ALARM; + } + } + return(status); +} diff --git a/src/dev/devMbboSoft.c b/src/dev/devMbboSoft.c new file mode 100644 index 000000000..72a766317 --- /dev/null +++ b/src/dev/devMbboSoft.c @@ -0,0 +1,91 @@ +/* devMbboSoft.c */ +/* share/src/dev $Id$ */ + +/* devMbboSoft.c - Device Support Routines for Soft Multibit Binary Output*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devMbboSoft */ +long init_record(); +long write_mbbo(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_mbbo; +}devMbboSoft={ + 5, + NULL, + NULL, + init_record, + NULL, + write_mbbo}; + + +static long init_record(pmbbo) + struct mbboRecord *pmbbo; +{ + char message[100]; + /* mbbo.out must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pmbbo->out.type) { + case (CONSTANT) : + pmbbo->val = pmbbo->out.value.value; + break; + case (PV_LINK) : + break; + case (DB_LINK) : + break; + case (CA_LINK) : + break; + default : + strcpy(message,pmbbo->name); + strcat(message,": devMbboSoft (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long write_mbbo(pmbbo) + struct mbboRecord *pmbbo; +{ + char message[100]; + + /* mbbo.out must be a CONSTANT or a DB_LINK or a CA_LINK*/ + switch (pmbbo->out.type) { + case (CONSTANT) : + break; + case (DB_LINK) : + (void)dbPutLink(&(pmbbo->out.value.db_link),pmbbo,DBR_ENUM, + &(pmbbo->val),1L); + break; + case (CA_LINK) : + break; + default : + if(pmbbo->nsevnsev = MAJOR_ALARM; + pmbbo->nsta = SOFT_ALARM; + if(pmbbo->stat!=SOFT_ALARM) { + strcpy(message,pmbbo->name); + strcat(message,": devMbboSoft (write_mbbo) Illegal INP field"); + errMessage(S_db_badField,message); + } + } + } + return(0); +} diff --git a/src/dev/devMbboXVme220.c b/src/dev/devMbboXVme220.c new file mode 100644 index 000000000..a66697305 --- /dev/null +++ b/src/dev/devMbboXVme220.c @@ -0,0 +1,115 @@ +/* devMbboXVme220.c */ +/* share/src/dev $Id$ */ + +/* devMbboXVme220.c - Device Support Routines */ +/* XYcom 32 bit binary output */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Create the dset for devAiMbboXVme220 */ +long init_record(); +long write_mbbo(); + +struct { + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN write_mbbo; +}devMbboXVme220={ + 5, + NULL, + NULL, + init_record, + NULL, + write_mbbo}; +static long masks[] = { + 0x00000000, + 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, + 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, + 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, + 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, + 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, + 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, + 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff +}; + + +static long init_record(pmbbo) + struct mbboRecord *pmbbo; +{ + char message[100]; + unsigned long value; + struct vmeio *pvmeio; + int status; + + /* mbbo.out must be an VME_IO */ + switch (pmbbo->out.type) { + case (VME_IO) : + pvmeio = &(pmbbo->out.value.vmeio); + pmbbo->mask = masks[pmbbo->nobt]<signal; + status = bo_read(pvmeio->card,pmbbo->mask,&value,BB902); + if(status==0) pmbbo->rval = value>> pvmeio->signal; + break; + default : + strcpy(message,pmbbo->name); + strcat(message,": devMbboXVme220 (init_record) Illegal INP field"); + errMessage(S_db_badField,message); + return(S_db_badField); + } + return(0); +} + +static long write_mbbo(pmbbo) + struct mbboRecord *pmbbo; +{ + struct vmeio *pvmeio; + int status; + unsigned long value; + + + pvmeio = &(pmbbo->out.value.vmeio); + if(pmbbo->sdef) { + unsigned long *pvalues = &(pmbbo->zrvl); + + if(pmbbo->val<0 || pmbbo->val>15) { + if(pmbbo->nsevnsta = SOFT_ALARM; + pmbbo->nsev = MAJOR_ALARM; + } + return(0); + } + value=pvalues[pmbbo->val]; + pmbbo->rval = value<signal; + } else pmbbo->rval = ((unsigned long)(pmbbo->val))<signal; + + status = bo_driver(pvmeio->card,pmbbo->rval,pmbbo->mask,BB902); + if(status==0) { + status = bo_read(pvmeio->card,pmbbo->mask,&value,BB902); + if(status==0) pmbbo->rval = value>> pvmeio->signal; + else if(pmbbo->nsevnsta = READ_ALARM; + pmbbo->nsev = MAJOR_ALARM; + } + } else { + if(pmbbo->nsevnsta = WRITE_ALARM; + pmbbo->nsev = MAJOR_ALARM; + } + } + return(status); +}