409 lines
7.5 KiB
C
409 lines
7.5 KiB
C
/* base/src/drv $Id$ */
|
||
/*
|
||
*
|
||
* HP E1404A VXI bus slot zero translator
|
||
* device dependent routines
|
||
*
|
||
* share/src/drv/@(#)drvHp1404a.c 1.7 8/27/93
|
||
*
|
||
* Author Jeffrey O. Hill
|
||
* Date 030692
|
||
*
|
||
* Experimental Physics and Industrial Control System (EPICS)
|
||
*
|
||
* Copyright 1991, the Regents of the University of California,
|
||
* and the University of Chicago Board of Governors.
|
||
*
|
||
* This software was produced under U.S. Government contracts:
|
||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||
*
|
||
* Initial development by:
|
||
* The Controls and Automation Group (AT-8)
|
||
* Ground Test Accelerator
|
||
* Accelerator Technology Division
|
||
* Los Alamos National Laboratory
|
||
*
|
||
* Co-developed with
|
||
* The Controls and Computing Group
|
||
* Accelerator Systems Division
|
||
* Advanced Photon Source
|
||
* Argonne National Laboratory
|
||
*
|
||
* Modification Log:
|
||
* -----------------
|
||
* .01 joh 073092 Added msg device support & interrupt shutdown for
|
||
* soft reboots
|
||
* .02 joh 082792 converted to ANSI C
|
||
* .03 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
|
||
*
|
||
*
|
||
*
|
||
*/
|
||
|
||
static char *sccsId = "@(#)drvHp1404a.c 1.7\t8/27/93";
|
||
|
||
#include <vxWorks.h>
|
||
#include <iv.h>
|
||
#include <intLib.h>
|
||
#include <rebootLib.h>
|
||
|
||
#include <devLib.h>
|
||
#include <drvEpvxi.h>
|
||
#include <drvHp1404a.h>
|
||
|
||
LOCAL unsigned long hpE1404DriverID;
|
||
|
||
struct hpE1404_config{
|
||
void (*pSignalCallback)(int16_t signal);
|
||
};
|
||
|
||
#define TLTRIG(N) (1<<(N))
|
||
#define ECLTRIG(N) (1<<((N)+8))
|
||
|
||
/*
|
||
* enable int when signal register is written
|
||
*/
|
||
#define HP1404A_INT_ENABLE 0x0008
|
||
#define HP1404A_INT_DISABLE 0x0000
|
||
|
||
/*
|
||
*
|
||
* tag the device dependent registers
|
||
*/
|
||
#define IRQ_enable dir.w.dd.reg.ddx1a
|
||
#define MSG_status dir.w.dd.reg.ddx1e
|
||
#define fp_trig_drive dir.w.dd.reg.ddx2a
|
||
#define bp_trig_drive dir.w.dd.reg.ddx22
|
||
#define signal_read dir.r.dd.reg.ddx10
|
||
|
||
#define hpE1404PConfig(LA, PC) \
|
||
epvxiFetchPConfig((LA), hpE1404DriverID, (PC))
|
||
|
||
LOCAL void hpE1404InitLA(
|
||
unsigned la
|
||
);
|
||
|
||
LOCAL int hpE1404ShutDown(
|
||
void
|
||
);
|
||
|
||
LOCAL void hpE1404ShutDownLA(
|
||
unsigned la
|
||
);
|
||
|
||
LOCAL void hpE1404IOReport(
|
||
unsigned la,
|
||
unsigned level
|
||
);
|
||
|
||
LOCAL void hpE1404Int(
|
||
unsigned la
|
||
);
|
||
|
||
|
||
|
||
/*
|
||
*
|
||
* hpE1404Init
|
||
*
|
||
*/
|
||
hpE1404Stat hpE1404Init(void)
|
||
{
|
||
hpE1404Stat status;
|
||
|
||
status = rebootHookAdd(hpE1404ShutDown);
|
||
if(status<0){
|
||
status = S_dev_internal;
|
||
errMessage(status, "rebootHookAdd() failed");
|
||
return status;
|
||
}
|
||
|
||
hpE1404DriverID = epvxiUniqueDriverID();
|
||
|
||
status = epvxiRegisterMakeName(
|
||
VXI_MAKE_HP,
|
||
"Hewlett-Packard");
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
}
|
||
status = epvxiRegisterModelName(
|
||
VXI_MAKE_HP,
|
||
VXI_HP_MODEL_E1404_REG_SLOT0,
|
||
"Slot Zero Translator (reg)");
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
}
|
||
status = epvxiRegisterModelName(
|
||
VXI_MAKE_HP,
|
||
VXI_HP_MODEL_E1404_REG,
|
||
"Translator (reg)");
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
}
|
||
status = epvxiRegisterModelName(
|
||
VXI_MAKE_HP,
|
||
VXI_HP_MODEL_E1404_MSG,
|
||
"Translator (msg)");
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
}
|
||
|
||
{
|
||
epvxiDeviceSearchPattern dsp;
|
||
|
||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||
dsp.make = VXI_MAKE_HP;
|
||
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
|
||
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
return status;
|
||
}
|
||
|
||
dsp.model = VXI_HP_MODEL_E1404_REG;
|
||
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
return status;
|
||
}
|
||
}
|
||
|
||
return VXI_SUCCESS;
|
||
}
|
||
|
||
|
||
/*
|
||
*
|
||
* hpE1404ShutDown()
|
||
*
|
||
*
|
||
*/
|
||
LOCAL int hpE1404ShutDown(void)
|
||
{
|
||
hpE1404Stat status;
|
||
epvxiDeviceSearchPattern dsp;
|
||
|
||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||
dsp.make = VXI_MAKE_HP;
|
||
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
|
||
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
return ERROR;
|
||
}
|
||
|
||
dsp.model = VXI_HP_MODEL_E1404_REG;
|
||
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
return ERROR;
|
||
}
|
||
return OK;
|
||
}
|
||
|
||
|
||
/*
|
||
*
|
||
* hpE1404ShutDownLA()
|
||
*
|
||
*
|
||
*/
|
||
LOCAL
|
||
void hpE1404ShutDownLA(
|
||
unsigned la
|
||
)
|
||
{
|
||
struct vxi_csr *pcsr;
|
||
|
||
pcsr = VXIBASE(la);
|
||
|
||
pcsr->IRQ_enable = HP1404A_INT_DISABLE;
|
||
}
|
||
|
||
|
||
/*
|
||
*
|
||
* hpE1404InitLA()
|
||
*
|
||
*/
|
||
LOCAL
|
||
void hpE1404InitLA(
|
||
unsigned la
|
||
)
|
||
{
|
||
struct hpE1404_config *pc;
|
||
struct vxi_csr *pcsr;
|
||
hpE1404Stat status;
|
||
|
||
status = epvxiOpen(
|
||
la,
|
||
hpE1404DriverID,
|
||
sizeof(*pc),
|
||
hpE1404IOReport);
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
return;
|
||
}
|
||
|
||
pcsr = VXIBASE(la);
|
||
|
||
status = hpE1404PConfig(la, pc);
|
||
if(status){
|
||
errMessage(status, NULL);
|
||
epvxiClose(la, hpE1404DriverID);
|
||
return;
|
||
}
|
||
|
||
/*
|
||
* set the self test status to passed for
|
||
* the message based device
|
||
*/
|
||
pcsr->MSG_status = VXIPASS<<2;
|
||
|
||
intConnect(
|
||
INUM_TO_IVEC(la),
|
||
hpE1404Int,
|
||
la);
|
||
|
||
/*
|
||
* enable int when signal register is written
|
||
*/
|
||
pcsr->IRQ_enable = HP1404A_INT_ENABLE;
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
/*
|
||
*
|
||
* hpE1404SignalConnect()
|
||
*
|
||
*/
|
||
hpE1404Stat hpE1404SignalConnect(
|
||
unsigned la,
|
||
void (*pSignalCallback)(int16_t signal)
|
||
)
|
||
{
|
||
hpE1404Stat s;
|
||
struct hpE1404_config *pc;
|
||
|
||
s = hpE1404PConfig(la, pc);
|
||
if(s){
|
||
return s;
|
||
}
|
||
|
||
pc->pSignalCallback = pSignalCallback;
|
||
|
||
return VXI_SUCCESS;
|
||
}
|
||
|
||
|
||
/*
|
||
*
|
||
* hpE1404Int()
|
||
*
|
||
*/
|
||
LOCAL
|
||
void hpE1404Int(
|
||
unsigned la
|
||
)
|
||
{
|
||
hpE1404Stat s;
|
||
struct vxi_csr *pcsr;
|
||
unsigned short signal;
|
||
struct hpE1404_config *pc;
|
||
|
||
s = hpE1404PConfig(la, pc);
|
||
if(s){
|
||
errMessage(s, NULL);
|
||
return;
|
||
}
|
||
|
||
/*
|
||
* vector is only D8 so we cant check the cause of the int
|
||
* (signal cause is assumed since that was all that was enabled)
|
||
*/
|
||
|
||
pcsr = VXIBASE(la);
|
||
|
||
signal = pcsr->signal_read;
|
||
|
||
if(pc->pSignalCallback){
|
||
(*pc->pSignalCallback)(signal);
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
*
|
||
* hpE1404RouteTriggerECL
|
||
*
|
||
*/
|
||
hpE1404Stat hpE1404RouteTriggerECL(
|
||
unsigned la, /* slot zero device logical address */
|
||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||
/* a 1 enables a trigger */
|
||
/* a 0 disables a trigger */
|
||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||
/* a 1 sources the front panel */
|
||
/* a 0 sources the back plane */
|
||
)
|
||
{
|
||
struct vxi_csr *pcsr;
|
||
|
||
pcsr = VXIBASE(la);
|
||
|
||
pcsr->fp_trig_drive = (io_map&enable_map)<<8;
|
||
pcsr->bp_trig_drive = ((~io_map)&enable_map)<<8;
|
||
|
||
return VXI_SUCCESS;
|
||
}
|
||
|
||
|
||
/*
|
||
*
|
||
*
|
||
* hpE1404RouteTriggerTTL
|
||
*
|
||
*
|
||
*/
|
||
hpE1404Stat hpE1404RouteTriggerTTL(
|
||
unsigned la, /* slot zero device logical address */
|
||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||
/* a 1 enables a trigger */
|
||
/* a 0 disables a trigger */
|
||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||
/* a 1 sources the front panel */
|
||
/* a 0 sources the back plane */
|
||
)
|
||
{
|
||
struct vxi_csr *pcsr;
|
||
|
||
pcsr = VXIBASE(la);
|
||
|
||
pcsr->fp_trig_drive = io_map&enable_map;
|
||
pcsr->bp_trig_drive = (~io_map)&enable_map;
|
||
|
||
return VXI_SUCCESS;
|
||
}
|
||
|
||
|
||
/*
|
||
*
|
||
* hpE1404IOReport()
|
||
*
|
||
*
|
||
*/
|
||
LOCAL
|
||
void hpE1404IOReport(
|
||
unsigned la,
|
||
unsigned level
|
||
)
|
||
{
|
||
|
||
|
||
|
||
|
||
}
|