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
|
|
)
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|