/* devRPV100.c */
/* devRPV100.c - Device Support Routines for VME RPV-100 */
/* Octal 100MHz visual scaler
/*
* Original Author: M. Tobiyama
* Current Author: M. Tobiyama
* Date:
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1997, KEKB.
*
*
* Modification Log:
* -----------------
* ver0.0 06/Jul/2005 M.Tobiyama
*/
#include <vxWorks.h>
#include <types.h>
#include <stdioLib.h>
#include <string.h>
#include <iv.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 <fast_lock.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <boRecord.h>
#include <biRecord.h>
#include <mbbiDirectRecord.h>
#include <mbboDirectRecord.h>
#include <dbScan.h>
struct DRPV100 {
unsigned short ch0up;
unsigned short ch0dn;
unsigned short ch1up;
unsigned short ch1dn;
unsigned short ch2up;
unsigned short ch2dn;
unsigned short ch3up;
unsigned short ch3dn;
unsigned short ch4up;
unsigned short ch4dn;
unsigned short ch5up;
unsigned short ch5dn;
unsigned short ch6up;
unsigned short ch6dn;
unsigned short ch7up;
unsigned short ch7dn;
unsigned short dum1[111];
unsigned short reset;
unsigned short dum2[128];
};
#define Status Enable
int devRPV100Config();
static long init_all();
static long init_mo_record();
static long write_mbboDirect();
static long init_li_record();
static long read_longin();
static int checkLink();
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_li_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_longin;
DEVSUPFUN special_linconv;
}devLiRPV100={
6,
NULL,
NULL,
init_li_record,
NULL,
read_longin,
NULL};
struct{
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_mo_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN write_mbboDirect;
}devMbboRPV100={
5,
NULL,
NULL,
init_mo_record,
NULL,
write_mbboDirect};
struct ioCard {
volatile struct DRPV100 *card; /* address of this card */
FAST_LOCK lock; /* semaphore */
};
#define CONST_NUM_LINKS 10
/* #define STATIC */
#define DEBUG_ON
static int debug_flag = 0;
static unsigned long Base_IO;
static int rpv100_num_links;
static struct ioCard cards[CONST_NUM_LINKS];
static int init_flag = 0;
int devRPV100Config(ncards,a16base)
int ncards;
long a16base;
{
rpv100_num_links = ncards;
Base_IO = a16base;
logMsg("RPV100 NumLink= %d BaseIO= %x\n",rpv100_num_links,Base_IO);
init_all(0);
}
static long init_all(after)
int after;
{
int cardNum, chanNum;
int i,j;
unsigned char probeVal[2];
unsigned short p1;
volatile struct DRPV100 *p;
if (init_flag != 0 )
return(OK);
init_flag = 1;
if (sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,(char *)Base_IO,(char **)&p) == ERROR)
{
logMsg("VME RPV100: cannot find A16 address space\n");
return(ERROR);
}
for (cardNum=0; cardNum< rpv100_num_links; cardNum++)
{
if (vxMemProbe((char*) &(p->ch0up), READ, 2, &probeVal)!=OK)
{
logMsg("No RPV100 with cardNum= %d\n probe= %x\n",cardNum,p);
cards[cardNum].card = NULL;
}
else
{
p->reset = 0xff; /* reset all */
if (debug_flag >0)
logMsg("Found RPV100 with cardNum= %d address= %x\n",cardNum,p);
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 unsigned long bcdtodec(unsigned short a)
{
unsigned long result;
result =
(a >>15)*8000 +
((a >>14)& 0x1) * 4000 +
((a >>13)& 0x1) * 2000 +
((a >>12)& 0x1) * 1000 +
((a >>11)& 0x1) * 800 +
((a >>10)& 0x1) * 400 +
((a >> 9)& 0x1) * 200 +
((a >> 8)& 0x1) * 100 +
((a >> 7)& 0x1) * 80 +
((a >> 6)& 0x1) * 40 +
((a >> 5)& 0x1) * 20 +
((a >> 4)& 0x1) * 10 +
((a >> 3)& 0x1) * 8 +
((a >> 2)& 0x1) * 4 +
((a >> 1)& 0x1) * 2 +
((a & 0x1));
return result;
}
static long read_longin(plongin)
struct longinRecord *plongin;
{
short cardN;
if (debug_flag >5)
logMsg("read_longin called...\n");
cardN = plongin->inp.value.vmeio.card;
if (debug_flag >5)
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: /* ch 0*/
plongin->val = bcdtodec(cards[cardN].card->ch0up)*10000+bcdtodec(cards[cardN].card->ch0dn);
break;
case 1: /* ch 1*/
plongin->val = bcdtodec(cards[cardN].card->ch1up)*10000+bcdtodec(cards[cardN].card->ch1dn);
break;
case 2: /* ch 2*/
plongin->val = bcdtodec(cards[cardN].card->ch2up)*10000+bcdtodec(cards[cardN].card->ch2dn);
break;
case 3: /* ch 3*/
plongin->val = bcdtodec(cards[cardN].card->ch3up)*10000+bcdtodec(cards[cardN].card->ch3dn);
break;
case 4: /* ch 4*/
plongin->val = bcdtodec(cards[cardN].card->ch4up)*10000+bcdtodec(cards[cardN].card->ch4dn);
break;
case 5: /* ch 5*/
plongin->val = bcdtodec(cards[cardN].card->ch5up)*10000+bcdtodec(cards[cardN].card->ch5dn);
break;
case 6: /* ch 6*/
plongin->val = bcdtodec(cards[cardN].card->ch6up)*10000+bcdtodec(cards[cardN].card->ch6dn);
break;
case 7: /* ch 7*/
plongin->val = bcdtodec(cards[cardN].card->ch7up)*10000+bcdtodec(cards[cardN].card->ch7dn);
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 >5)
logMsg("write_mbboDirect called with card %d\n",cardN);
if (checkLink(cardN) == ERROR)
return(ERROR);
FASTLOCK(&(cards[cardN].lock));
if (debug_flag >5)
logMsg("card locked...\n");
cards[cardN].card->reset = pmbbo->rval;
pmbbo->rbv=pmbbo->rval;
if (debug_flag >5)
logMsg("write complete \n");
FASTUNLOCK(&(cards[cardN].lock));
if (debug_flag >5)
logMsg("unlock card ...\n");
return(CONVERT);
}
/**************************************************************************
*
* Make sure card number is valid
*
**************************************************************************/
static int checkLink(cardN)
short cardN;
{
if (cardN >= rpv100_num_links)
return(ERROR);
if (cards[cardN].card == NULL)
{
logMsg("No RPV100 with this number = %d\n",cardN);
return(ERROR);
}
if (debug_flag >10)
logMsg("Yes you have RPV100 with card No= %d\n",cardN);
return(OK);
}