/* devVme17k46.c */
/* devVme17k46.c - Device Support Routines for VME 17K46 */
/*
* Original Author: Makoto Tobiyama
* Current Author:
* Date: 15/Apr/98
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1997, KEKB.
*
*
* Modification Log:
* -----------------
* 15-Apr-98 Makoto Tobiyama (original)
*/
#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 <module_types.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <boRecord.h>
#include <biRecord.h>
#include <mbbiDirectRecord.h>
#include <mbboDirectRecord.h>
/* #define Base_IO 0x20000 */ /* Std. I/O Address */
struct Dvme17k46 {
unsigned short Ch1Cntl;
unsigned short Ch2Cntl;
unsigned short Ch1Stat;
unsigned short Ch2Stat;
short Ch1FWD;
short Ch1REF;
short Ch2FWD;
short Ch2REF;
};
#define Status Enable
static long init();
static long init_li_record();
static long init_mi_record();
static long init_mo_record();
static long read_longin();
static long read_mbbiDirect();
static long write_mbboDirect();
static int checkLink();
/* Create the dset for devLiK46 */
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_li_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_longin;
DEVSUPFUN special_linconv;
}devLiK46={
6,
NULL,
NULL,
init_li_record,
NULL,
read_longin,
NULL};
/* For devMbbiDK46 */
struct{
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_mi_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_mbbiDirect;
}devMbbiDK46={
5,
NULL,
NULL,
init_mi_record,
NULL,
read_mbbiDirect};
/* For devMbboDK46 */
struct{
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_mo_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN write_mbboDirect;
}devMbboDK46={
5,
NULL,
NULL,
init_mo_record,
NULL,
write_mbboDirect};
struct ioCard {
volatile struct Dvme17k46 *card; /* address of this card */
FAST_LOCK lock; /* semaphore */
};
#define CONST_NUM_LINKS 20
/* #define STATIC */
#define DEBUG_ON
static int debug_flag = 1;
static unsigned long Base_IO;
static int k46_num_links;
static struct ioCard cards[CONST_NUM_LINKS];
static int init_flag = 0;
static unsigned char fast_mask;
int devK46Config(ncards,a24base,init_set)
int ncards;
unsigned char init_set;
long a24base;
{
k46_num_links = ncards;
Base_IO = a24base;
printf("Vme17k46 NumLink= %d BaseIO= %x\n",k46_num_links,Base_IO);
fast_mask = init_set;
init(0);
}
static long init(after)
int after;
{
int cardNum, chanNum;
unsigned char probeVal[2];
volatile struct Dvme17k46 *p;
if (init_flag != 0 )
return(OK);
init_flag = 1;
if (sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,(char *)Base_IO,(char **)&p) == ERROR)
{
printf("Vme17k46: cannot find extended address space\n");
return(ERROR);
}
#ifdef DEBUG_ON
printf("devLiK46 (init) Called. pass = %d\n", after);
#endif
for (cardNum=0; cardNum< k46_num_links; cardNum++)
{
if ((vxMemProbe((char*) &(p->Ch1Cntl), WRITE, 2, &fast_mask)< OK) ||
(vxMemProbe((char*) &(p->Ch2Cntl), WRITE, 2, &fast_mask)< OK))
{
if (debug_flag >0 )
printf("No 17k46 with cardNum= %d\n probe= %x\n",cardNum,p);
cards[cardNum].card = NULL;
}
else
{
if (debug_flag >0)
printf("Found 17k46 with cardNum= %d\n address= %x initialized %x\n",cardNum,p,fast_mask);
cards[cardNum].card = p; /* Remember address of the board */
FASTLOCKINIT(&(cards[cardNum].lock));
FASTUNLOCK(&(cards[cardNum].lock)); /* Init the board lock */
}
p++;
}
return(OK);
}
static long init_li_record(plongin)
struct longinRecord *plongin;
{
return(0);
}
static long read_power(long power)
{
short temp;
temp = power<<4;
temp = temp/16;
return(temp);
}
static long read_longin(plongin)
struct longinRecord *plongin;
{
short cardN;
if (debug_flag >5)
printf("read_longin called...\n");
cardN = plongin->inp.value.vmeio.card;
if (debug_flag >5)
printf("read_longin called with card number of %d\n",cardN);
if (checkLink(cardN) == ERROR)
return(ERROR);
switch(plongin->inp.value.vmeio.signal){
case 0:
plongin->val = read_power(cards[cardN].card->Ch1FWD);
if (debug_flag >5)
printf("read_longin signal 0 Ch1FWD %d\n",
plongin->val);
break;
case 1:
plongin->val = read_power(cards[cardN].card->Ch1REF);
if (debug_flag >5)
printf("read_longin signal 0 Ch1REF %d\n",
plongin->val);
break;
case 2:
plongin->val = read_power(cards[cardN].card->Ch2FWD);
if (debug_flag >5)
printf("read_longin signal 0 Ch2FWD %d\n",
plongin->val);
break;
case 3:
plongin->val = read_power(cards[cardN].card->Ch2REF);
if (debug_flag >5)
printf("read_longin signal 0 Ch2REF %d\n",
plongin->val);
break;
default:
return(-1);
}
return(CONVERT);
}
static long init_mo_record(pmbbo)
struct mbboDirectRecord *pmbbo;
{
return(0);
}
static long write_mbboDirect(pmbbo)
struct mbboDirectRecord *pmbbo;
{
short cardN;
cardN = pmbbo->out.value.vmeio.card;
if (debug_flag >1)
printf("write_mbboDirect called with card %d\n",cardN);
if (checkLink(cardN) == ERROR)
return(ERROR);
FASTLOCK(&(cards[cardN].lock));
if (debug_flag >1)
printf("card locked...\n");
switch(pmbbo->out.value.vmeio.signal){
case 0: /* Ch1 cntl */
cards[cardN].card->Ch1Cntl = pmbbo->rval;
pmbbo->rbv=cards[cardN].card->Ch1Cntl;
break;
case 1: /* Ch2 cntl */
cards[cardN].card->Ch2Cntl = pmbbo->rval;
pmbbo->rbv=cards[cardN].card->Ch2Cntl;
break;
default:
FASTUNLOCK(&(cards[cardN].lock));
return(-1);
}
if (debug_flag >1)
printf("write complete \n");
FASTUNLOCK(&(cards[cardN].lock));
if (debug_flag >1)
printf("unlock card ...\n");
return(CONVERT);
}
static long init_mi_record(pmbbi)
struct MbbiDirectRecord *pmbbi;
{
return(0);
}
static long read_mbbiDirect(pmbbi)
struct mbbiDirectRecord *pmbbi;
{
short cardN;
cardN = pmbbi->inp.value.vmeio.card;
if (debug_flag >5)
printf("read_mbbiDirect called with card %d\n",cardN);
if (checkLink(cardN) == ERROR)
return(ERROR);
switch(pmbbi->inp.value.vmeio.signal){
case 0: /* Ch1 status */
pmbbi->rval = cards[cardN].card->Ch1Stat;
break;
case 1: /* Ch2 status */
pmbbi->rval = cards[cardN].card->Ch2Stat;
break;
default:
return(-1);
}
if (debug_flag >5)
printf("read complete \n");
return(CONVERT);
}
/**************************************************************************
*
* Make sure card number is valid
*
**************************************************************************/
static int checkLink(cardN)
short cardN;
{
if (cardN >= k46_num_links)
return(ERROR);
if (cards[cardN].card == NULL)
{
printf("No 17k46 with this number = %d\n",cardN);
return(ERROR);
}
if (debug_flag >10)
printf("Yes you have 17k46 with card No= %d\n",cardN);
return(OK);
}