diff --git a/src/drv/ansi/Makefile b/src/drv/ansi/Makefile deleted file mode 100644 index 784cf01d0..000000000 --- a/src/drv/ansi/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -TOP=../../.. - -include $(TOP)/config/CONFIG_BASE - -include $(TOP)/config/RULES_ARCHS - diff --git a/src/drv/ansi/Makefile.Vx b/src/drv/ansi/Makefile.Vx deleted file mode 100644 index d614e0aec..000000000 --- a/src/drv/ansi/Makefile.Vx +++ /dev/null @@ -1,48 +0,0 @@ -# -# $Id$ -# - -TOP = ../../../.. -include $(TOP)/config/CONFIG_BASE - -INC += canBus.h -INC += drvAb.h -INC += drvAt5Vxi.h -INC += drvEpvxi.h -INC += drvHp1404a.h -INC += drvHpe1368a.h -INC += drvIpac.h -INC += drvKscV215.h -INC += drvMz8310.h -INC += drvStc.h -INC += drvTip810.h -INC += epvxi.h -INC += ipModules.h -INC += ipic.h -INC += pca82c200.h - -SRCS.c += ../drvAb.c -SRCS.c += ../drvAt5Vxi.c -SRCS.c += ../drvEpvxi.c -SRCS.c += ../drvEpvxiMsg.c -SRCS.c += ../drvHp1404a.c -SRCS.c += ../drvHpe1368a.c -SRCS.c += ../drvHpe1445a.c -SRCS.c += ../drvKscV215.c -SRCS.c += ../drvMz8310.c -SRCS.c += ../drvStc.c -#SRCS.c += ../drvCaenV265.c - -SRCS.c += ../drvVipc310.c -SRCS.c += ../drvVipc610.c -SRCS.c += ../drvIpMv162.c -SRCS.c += ../drvIpac.c -SRCS.c += ../drvTip810.c -#SRCS.c += ../drvVmic2534.c - -PROD = $(SRCS.c:../%.c=%.o) - -MAN3 = drvEpvxi.3 - -include $(TOP)/config/RULES.Vx - diff --git a/src/drv/ansi/VXI_SETUP_README b/src/drv/ansi/VXI_SETUP_README deleted file mode 100644 index 74b39714e..000000000 --- a/src/drv/ansi/VXI_SETUP_README +++ /dev/null @@ -1,30 +0,0 @@ - -The CPU030 may need to have the nivxi path set correctly: - From the vxWorks shell type "vxitedit" - take option 2 - take option 3 - type list - type modify 0 - type in the correct path when promped - (the path should end in nivxi - and should traverse the niCpu030 - directories shipped with the 030 - ie something of the form "???/config/niCPU030/nivxi" - type save - type exit - . - . - . - - -You may may need to setup front panel to backplane trigger -routing: - -To take a TTL input and map it to VXI backplane ECL trigger 0 -type in (to the vxWorks shell): - -epvxiRouteTriggerECL(, 1, 0) - -where specifies the card with the -front panel trigger connection. - diff --git a/src/drv/ansi/canBus.h b/src/drv/ansi/canBus.h deleted file mode 100644 index 8b8829380..000000000 --- a/src/drv/ansi/canBus.h +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - canBus.h - -Description: - CANBUS specific constants - -Author: - Andrew Johnson -Created: - 25 July 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#ifndef INCcanBusH -#define INCcanBusH - - -#define CAN_IDENTIFIERS 2048 -#define CAN_DATA_SIZE 8 - -#define CAN_BUS_OK 0 -#define CAN_BUS_ERROR 1 -#define CAN_BUS_OFF 2 - - -#ifndef M_can -#define M_can (811<<16) -#endif - -#define S_can_badMessage (M_can| 1) /*illegal CAN message contents*/ -#define S_can_badAddress (M_can| 2) /*CAN address syntax error*/ -#define S_can_noDevice (M_can| 3) /*CAN bus name does not exist*/ - -typedef struct { - ushort_t identifier; /* 0 .. 2047 with holes! */ - enum { - SEND = 0, RTR = 1 - } rtr; /* Remote Transmission Request */ - uchar_t length; /* 0 .. 8 */ - uchar_t data[CAN_DATA_SIZE]; -} canMessage_t; - -typedef struct { - char *busName; - int timeout; - ushort_t identifier; - ushort_t offset; - signed int parameter; - void *canBusID; -} canIo_t; - -typedef void canMsgCallback_t(void *pprivate, canMessage_t *pmessage); -typedef void canSigCallback_t(void *pprivate, int status); - -extern int canOpen(char *busName, void **pcanBusID); -extern int canRead(void *canBusID, canMessage_t *pmessage, int timeout); -extern int canWrite(void *canBusID, canMessage_t *pmessage, int timeout); -extern int canMessage(void *canBusID, ushort_t identifier, - canMsgCallback_t callback, void *pprivate); -extern int canSignal(void *canBusID, canSigCallback_t callback, void *pprivate); -extern int canIoParse(char *canString, canIo_t *pcanIo); - - -#endif /* INCcanBusH */ - diff --git a/src/drv/ansi/drvAb.c b/src/drv/ansi/drvAb.c deleted file mode 100644 index 454ed11b0..000000000 --- a/src/drv/ansi/drvAb.c +++ /dev/null @@ -1,1891 +0,0 @@ -/* drvAb.c - Driver Support Routines for Allen Bradley */ -/* - * Interface to the Allen-Bradley Remote Serial IO - * - * Author: Bob Dalesio - * Date: 6-21-88 - * Major Revision March 1995. Bob Dalesio and Marty Kraimer - * - * 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 - * - * Notes: - * 1. This driver uses Asynchronous Communications to the AB scanner - * The manual description for this type of interface is - * misleading in the area of interrupt handling. - * 2. We are using double slot addressing - * The database uses card numbers 0-11 to address slots 1-12 - * It is possible to use 1 slot and 1/2 slot addressing. - * For 1 slot addressing assign card=slot*2 - * For 1/2 slot addressing assign card = slot*4 - * 3. The binary io is memory mapped and the analog io is handled through - * block transfers of whole cards of data. - * 4. The driver spawns a task for each 6008 card in VME and scans cards as - * the database claims they exist - there is no way to poll the hardware - * to determine what is present. - * 4. A flag is used to limit the requests to the analog input modules. This - * assures that only one request is outstanding at any time. - * - * Modification Log: - * ----------------- - * .19 08-01-89 lrd changed sc_queue and bt_queue to always set - * length to 0 for compatibility with PLC-5 - * communication - * .26 10-17-89 cbf added logic to see if the scanner was using the - * dual port when we had it locked. it is! - * **************************************************************************** - * * Many of the above were needed to work around problems in the * - * * 6008-SV firmware. These problems have been reported to Allen- * - * * Bradley and fixes are promised. The PROMs we are presently using * - * * are both labeled "91332-501". U63 chksum = A7A1. U64 chksum = 912B * - * * (Series A, Revision C.) * - * **************************************************************************** - * .27 12-11-89 cbf new PROMs implemented which allow output image - * table to be preserved during SYSTEM RESET. - * This driver is still compatible with the old - * firmware also. - * A piece of code was added to store the firmware - * revision level in array ab_firmware_info. - * .28 12-11-89 cbf With the new firmware, the scanner no longer - * uses the dual port when we have it locked so - * the tests for this condition have been removed. - * .29 01-23-90 cbf In the previous rev of this driver we made an - * attempt to build a scan list automatically by - * waiting until the periodic scan task had asked - * for data from each needed adapter. - * This scheme caused problems with the - * the initialization of BOs and AOs, because they - * were not initially in the scan list and so - * could not be read at initialization. - * In this rev, that code has been removed and the - * scan list is always built to include all - * eight possible adapters. This has some - * performance implications because each - * non-existant adapter which appears in the scan - * list adds an extra 12 ms to each I/O scan time - * for the 6008SV. The decreased performance does - * not appear to be very significant, however. - * The 6008SV front panel "SER" LED blinks if not - * all adapters in the scan list are responding. - * With this rev of the driver, the light will - * therefore be blinking. - **************************************************************************** - ** Allen-Bradley has given us a new firmware revision. - ** This revision allows the reset of the scanner without using the - ** sysReset on the VME backplane. It also maintains the output image table - ** for the binary outputs. This reset is used to recover from a scanner - ** fault, where the 6008 firmware deadends - ab_reset provides this - ** function. * - ***************************************************************************** - * .41 05-16-91 lrd have the ab_scan_task driver analog outputs - * periodically as well as on change - * .56 06-30-93 mrk After 3 attempts to queue request reinitialize - * .64 09-16-93 mrk ab_reset: all links; only reset scanner. - * ???????????? ??? fix scaling on IXE 4-20 Milli amp - * .65 04-04-94 lrd return the value for overrange and underrange - * .66 04-04-94 lrd put the binary change of state into the AB scan task - * .67 04-04-94 lrd support N serial cards - * - put all link and adapter information into structure - * - allocate structures as needed - * .68 09-29-94 lrd removed historical comments of no current significance - * .69 10-20-94 lrd moved all I/O board specific stuff up to the device layer - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "task_params.h" -#include "dbScan.h" -#include "drvSup.h" -#include "taskwd.h" -#include "module_types.h" -#include "devLib.h" -#include "drvAb.h" - - - -#define maxCmdTrys 3 -#define AB_INT_LEVEL 5 -#define MAX_AB_ADAPTERS 8 -#define MAX_GROUPS_PER_ADAPTER 8 -#define MAX_CARDS_PER_ADAPTER 16 - -/*Definitions for dual ported memory on scanner interface card*/ -/* Command Word */ -#define AUTO_CONF 0x10 -#define SCAN_LIST 0x11 -#define SET_UP 0x13 -#define SET_MODE 0x20 -#define LINK_STATUS 0x21 -#define AB_READ 0x01 -#define AB_WRITE 0x02 -/* osw - operating status word definitions */ -#define PROGRAM_MODE 0x01 /* program/reset mode */ -#define TEST_MODE 0x02 /* test/reset mode */ -#define RUN_MODE 0x04 /* run mode */ -#define DEBUG_MODE 0x08 /* we are debugging */ -#define UNSOLICITED_BT 0x10 /* detected block xfer we didn't want */ -#define BTS_QUEUED 0x20 /* block xfers queued */ -#define ADAPTER_FAULT 0x40 /* at least one faulted adapter list */ -#define ADAP_FLT_CHNG 0x80 /* Adapter status change*/ -/* Confirmation Status Word */ -#define SCANNER_POWERUP 0x90 /* power up status */ -#define BT_ACCEPTED 0x2f /* block trans accepted by scanner */ -#define BT_QUEUE_FULL 0x14 /* Queue Full*/ -#define BT_TIMEOUT 0x23 /* block transfer timeout */ -/* these are used for the SET_UP command */ -#define DEF_RATE 0x01 /* default baud rate 57.6K */ -#define FAST_RATE 0x02 /* 115.2 KB */ -#define NO_CHANGE 0xff /* no change */ -#define DEBUG 0x01 /* debug - turn off watchdog timer */ -#define AB_INT_ENABLE 0x00 /* interrupt enabled */ -#define AB_SYSFAIL_DISABLE 0x01 /* disable VMEbus SYSFAIL signal */ - -/* DUAL PORTED MEMORY AREA DEFINITION */ -/* mail box definition */ -typedef volatile struct dp_mbox{ - unsigned short conf_stat; /* confirmation status word */ - unsigned short command; /* command word */ - unsigned short address; /* module address */ - unsigned short bt_tag; /* block transfer tag number */ - unsigned short resv[9]; /* 18 bytes reserved */ - unsigned char dummy; - unsigned char fl_lock; /* semaphore word byte */ - unsigned short data_len; /* length of data sent/returned */ - unsigned short msg[64]; /*mail box message */ -}dp_mbox; - -/* entire region with the mailbox */ -typedef volatile struct ab_region { - unsigned short oit[64]; /* output image table */ - unsigned short iit[64]; /* input image table */ - unsigned short osw; /* operating status word */ - dp_mbox mail; /* dual port mail box */ - unsigned short gda[1872-66]; /* unused part gen data area */ - unsigned short sys_fail_set1; /* 1st byte to recover from SYSFAIL */ - unsigned short sys_fail_set2; /* 2nd byte to recover from SYSFAIL */ - unsigned char vmeid[60]; /* scanner id */ - unsigned short sc_intr; /* to interrupt the scanner */ - unsigned short sc_pad; /* last word in scanner shared mem */ -}ab_region; - -typedef struct { - abStatus btStatus; - unsigned short cmd; - unsigned short msg_len; - unsigned short *pmsg; - /* The following field is only used for cardType = typeBt */ - WDOG_ID wdId; /*For Timeout */ -}btInfo; - -typedef enum { - stateInit,stateInitBTwait,stateCountdown,stateBT,stateBTwait -}scanState; -typedef struct { - scanState state; - unsigned short update_rate; - unsigned short *pread_msg; - unsigned short *pwrite_msg; - unsigned short read_msg_len; - unsigned short write_msg_len; - unsigned short state_cnt; /* number of consecutive time in state*/ - unsigned short down_cnt; /* down_counter for scanning */ - unsigned short bt_to; /* data transfer timed out */ - unsigned short bt_fail; /*block transfer bad status*/ - unsigned short init_ctr; /* number times the card initialized*/ -}scanInfo; - -typedef struct { - unsigned short link; - unsigned short adapter; - unsigned short card; - cardType type; - const char *card_name; - abNumBits nBits; - BOOL needsUpdate; - BOOL active; - abStatus status; - SEM_ID card_sem; - btInfo *pbtInfo; - scanInfo *pscanInfo; - void *userPvt; - void (*callback)(void *pcard); /*user's callback routine*/ - void (*bocallback)(void *pcard); /*user's callback routine*/ - unsigned long diprev; -}ab_card; - -typedef struct{ - unsigned short adapter; - BOOL adapter_online; - BOOL adapter_status_change; - ab_card **papcard; /*pointer to array of pointers*/ - SEM_ID adapter_sem; /* request talk to scanner*/ -}ab_adapter; - -typedef struct { - void *base_address; - unsigned short baud_rate; - unsigned short int_vector; - unsigned short int_level; - unsigned short autoconfig; - unsigned short scan_list_len; - unsigned char scan_list[64]; -} ab_config; - -typedef struct { - unsigned short list_len; - unsigned short status[32]; - unsigned char list[64]; -}ab_link_status; - -typedef struct{ - unsigned short link; - unsigned short ab_disable; - SEM_ID request_sem; /* request talk to scanner*/ - SEM_ID ab_cmd_sem; /* transfer complete semaphore */ - SEM_ID ab_data_sem; /* transfer complete semaphore */ - int abScanId; /* id of the Allen-Bradley scan task */ - int abDoneId; /* id of the Allen-Bradley done task */ - unsigned short sclock_to; /* Timeout trying to lock mailbox*/ - unsigned short sccmd_to; /* command timeout on semTake*/ - unsigned short sc_fail; /* Scanner Command Failure*/ - unsigned short intr_cnt; /* interrupt counter*/ - unsigned short intrSec; /* interrupts per second */ - unsigned short bt_cnt; /* Block Transfer counter*/ - unsigned short btSec; /* block transfers per second*/ - ab_config *pconfig; - char firmware_info[96]; /* NOTE: available only temporarily */ - ab_region *vme_addr; /* ptr to the memory of interface */ - ab_adapter **papadapter; - ab_link_status *plink_status; - BOOL initialCallback; - BOOL initialized; -}ab_link; - -/*Local variables and function prototypes*/ -LOCAL ab_link **pab_links=NULL; -LOCAL unsigned int max_ab_6008s = 2; - -/* forward references */ -LOCAL void *abCalloc(size_t nobj,size_t size); -LOCAL ab_link *allocLink(unsigned short link); -LOCAL void ab_intr(int link); -LOCAL int sc_lock(ab_link *plink); -LOCAL int sc_waitcmd(ab_link *plink); -LOCAL void sc_conferr(ab_link *plink); -LOCAL void sc_unlock(ab_link *plink); -LOCAL void uctrans (unsigned char *from,unsigned char *to,unsigned short n); -LOCAL void ustrans (unsigned short *from,unsigned short *to, - unsigned short nwords); -LOCAL void di_read(ab_card *pcard,unsigned long *pvalue); -LOCAL void do_read(ab_card *pcard,unsigned long *pvalue); -LOCAL void do_write(ab_card *pcard,unsigned long value); -LOCAL abStatus bt_queue(unsigned short command,ab_card *pcard, - unsigned short *pmsg, unsigned short msg_len); -LOCAL int link_status(ab_link *plink); -LOCAL int ab_reboot_hook(int boot_type); -LOCAL void config_init(ab_link *plink); -LOCAL int ab_driver_init(); -LOCAL int link_init(ab_link *plink); -LOCAL void abScanTask(ab_link *plink); -LOCAL void abDoneTask(ab_link *plink); -LOCAL void read_ab_adapter(ab_link *plink, ab_adapter *padapter); -LOCAL void ab_reset_task(ab_link *plink); -LOCAL long ab_io_report(int level); - -/*Global variables */ -unsigned int ab_debug=0; - -LOCAL char *statusMessage[] = { - "Success","New Card","Card Conflict","No Card", - "Card not initialized","block transfer queued", - "Card Busy","Timeout","Adapter Down","Failure"}; -char **abStatusMessage = statusMessage; - -LOCAL char *numBitsMessage[] = { - "nbits_Not_defined"," 8_Bit","16_Bit","32_Bit"}; -char **abNumBitsMessage = numBitsMessage; -/*End Global variables*/ - -/*Beginning of DSET routines */ - -LOCAL long report(); -LOCAL long init(); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvAb={ - 2, - report, - init -}; - -LOCAL long report(int level) -{ - return(ab_io_report(level)); -} -LOCAL long init() -{ - - return(ab_driver_init()); -} - -LOCAL void *abCalloc(size_t nobj,size_t size) -{ - void *p; - - p=calloc(nobj,size); - if(p) return(p); - logMsg("drvAb: calloc failure\n",0,0,0,0,0,0); - taskSuspend(0); - return(NULL); -} -LOCAL ab_link *allocLink(unsigned short link) -{ - ab_link *plink; - - if(pab_links[link]) return(pab_links[link]); - plink = abCalloc(1,sizeof(ab_link)); - plink->ab_disable = TRUE; - plink->papadapter = abCalloc(MAX_AB_ADAPTERS,sizeof(ab_adapter *)); - plink->plink_status = abCalloc(1,sizeof(ab_link_status)); - plink->link = link; - config_init(plink); - pab_links[link] = plink; - return(plink); -} - -/* - * AB_INTR - * - * The Allen-Bradley protocol requires that an interrupt be received when - * a block transfer request is given to the scanner board through the dual - * ported memory and then another when the command is complete. - * dual-ported memory lock is controlled in a much different fashion than it is. - */ -LOCAL void ab_intr(int link) -{ - ab_link *plink; - ab_region *p6008; - dp_mbox *pmb; - - if(!pab_links) return; /*Called before init complete*/ - plink = pab_links[link]; - if(!plink) return; /*Called before init complete*/ - p6008 = plink->vme_addr; - if(!p6008) return; - pmb = &p6008->mail; - if((pmb->fl_lock&0x80)==0) {/*Should NEVER be True*/ - if (ab_debug != 0) - logMsg("drvAb: Interrupt but fl_lock not locked\n", 0,0,0,0,0,0); - } - if(p6008->osw & UNSOLICITED_BT){ - if (ab_debug != 0) - logMsg("link %x, unsolicited_block xfer\n",plink->link,0,0,0,0,0); - /* scanner depends on us to clear some bits */ - p6008->osw = 0; - } - plink->intr_cnt++; - if((pmb->command==AB_WRITE || pmb->command==AB_READ) - && (pmb->conf_stat != BT_ACCEPTED) && (pmb->conf_stat != BT_QUEUE_FULL)) { - semGive(plink->ab_data_sem); - } else { - semGive(plink->ab_cmd_sem); - } -} - -/*Routines for communication with scanner*/ -LOCAL int sc_lock(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - unsigned short lock_stat = 0; - int i; - - if(ab_debug>3)printf("sc_lock\n"); - semTake(plink->request_sem,WAIT_FOREVER); - /* try to to lock the dual port memory */ - for(i=0; ifl_lock)) == TRUE) break; - taskDelay(1); - } - if(lock_stat == FALSE) { - if(ab_debug) - printf("drvAb: link %x sc_lock failure\n", plink->link); - plink->sclock_to += 1; - pmb->fl_lock = 0; /*Unlock to attempt to recover. May not work*/ - semGive(plink->request_sem); - return (ERROR); - } - return(0); -} - -LOCAL int sc_waitcmd(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - unsigned short savecmd; - int status; - int ntry; - - if(ab_debug>3)printf("sc_waitcmd\n"); - savecmd = pmb->command; - pmb->conf_stat = 0x000f; - ntry = 0; - p6008->sc_intr = 1; /*Wake up scanner*/ - status = semTake(plink->ab_cmd_sem,sysClkRateGet()); - if(status!=OK) { - plink->sccmd_to++; - if(ab_debug) printf( - "drvAb: sc_waitcmd timeout link %hu command %4x\n", - plink->link,savecmd); - sc_unlock(plink); - return(ERROR); - } - if(pmb->command != savecmd){ - plink->sc_fail++; - if(ab_debug) printf( - "drvAb: bad cmd response. link %hu sent %4x received %4x\n", - plink->link,savecmd,pmb->command); - sc_unlock(plink); - return(ERROR); - } - return(0); -} - -LOCAL void sc_conferr(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - - if(ab_debug>3)printf("sc_conferr\n"); - plink->sc_fail++; - if(ab_debug) printf("drvAb: link %hu conf_stat error %4x\n", - plink->link,pmb->conf_stat); - sc_unlock(plink); - return; -} - -LOCAL void sc_unlock(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - - if(ab_debug>3)printf("sc_unlock\n"); - pmb->fl_lock = 0; - semGive(plink->request_sem); -} - -/*Routines to transfer data to/from mailbox*/ -/* Unsigned character transfer*/ -LOCAL void uctrans (unsigned char *from,unsigned char *to,unsigned short n) -{ - int i; - for (i=0;ilink; - unsigned short adapter = pcard->adapter; - unsigned short card = pcard->card; - unsigned short group,slot; - unsigned short rack_offset; - unsigned short *pimage; - unsigned long value; - - rack_offset = (adapter * MAX_GROUPS_PER_ADAPTER); - group = card/2; slot = card - group*2; - pimage = &(pab_links[link]->vme_addr->iit[rack_offset + group]); - if (pcard->nBits == abBit8) { - value = *pimage; - if(slot==1) value >>= 8; - value &= 0x00ff; - *pvalue = value; - }else if(pcard->nBits == abBit16){ - *pvalue = *pimage; - } else if (pcard->nBits == abBit32) { - value = *(pimage+1); - value <<= 16; - value += *pimage; - *pvalue = value; - } -} - -/* read the values from the hardware into the local word */ -LOCAL void do_read(ab_card *pcard,unsigned long *pvalue) -{ - unsigned short link = pcard->link; - unsigned short adapter = pcard->adapter; - unsigned short card = pcard->card; - unsigned short group,slot; - unsigned short rack_offset; - unsigned short *pimage; - unsigned long value; - - rack_offset = (adapter * MAX_GROUPS_PER_ADAPTER); - group = card/2; slot = card - group*2; - pimage = &(pab_links[link]->vme_addr->oit[rack_offset + group]); - if (pcard->nBits == abBit8) { - value = *pimage; - if(slot==1) value >>= 8; - value &= 0x00ff; - *pvalue = value; - }else if(pcard->nBits == abBit16){ - *pvalue = *pimage; - } else if (pcard->nBits == abBit32) { - value = *(pimage+1); - value <<= 16; - value += *pimage; - *pvalue = value; - } -} - -/* write the values to the hardware from the local word */ -LOCAL void do_write(ab_card *pcard,unsigned long value) -{ - unsigned short link = pcard->link; - unsigned short adapter = pcard->adapter; - unsigned short card = pcard->card; - unsigned short group,slot; - unsigned short rack_offset; - unsigned short *pimage; - - rack_offset = (adapter * MAX_GROUPS_PER_ADAPTER); - group = card/2; slot = card - group*2; - pimage = &(pab_links[link]->vme_addr->oit[rack_offset + group]); - if (pcard->nBits == abBit8) { - if(slot==0) { - *pimage = (*pimage & 0xff00) | ((unsigned short)value & 0x00ff); - } else { - value <<= 8; - *pimage = (*pimage & 0x00ff) | ((unsigned short)value & 0xff00); - } - }else if(pcard->nBits == abBit16){ - *pimage = (unsigned short)value; - } else if (pcard->nBits == abBit32) { - *pimage = (unsigned short)value; - *(pimage+1) = (unsigned short)(value >> 16); - } -} - -LOCAL abStatus bt_queue(unsigned short command,ab_card *pcard, - unsigned short *pmsg, unsigned short msg_len) -{ - ab_link *plink = pab_links[pcard->link]; - ab_adapter *padapter = plink->papadapter[pcard->adapter]; - btInfo *pbtInfo = pcard->pbtInfo; - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - unsigned short *pmb_msg = &pmb->msg[0]; - int status; - - if(!padapter->adapter_online) return(abAdapterDown); - pbtInfo->cmd = command; - pbtInfo->pmsg = pmsg; - pbtInfo->msg_len = msg_len; - status = sc_lock(plink); - if(status) return(abFailure); - pmb->command = command; - pmb->address = (padapter->adapter << 4) + pcard->card; - pmb->data_len = msg_len; - if(pbtInfo->cmd==AB_WRITE) ustrans(pmsg,pmb_msg,msg_len); - status = sc_waitcmd(plink); - if(status) return(abFailure); - status = pmb->conf_stat; - if(status != BT_ACCEPTED){ - sc_conferr(plink); - if (status == BT_QUEUE_FULL){ - printf("drvAb: BT_QUEUE_FULL link %hu\n",plink->link); - taskDelay(sysClkRateGet()/10); - } - return(abFailure); - } - pbtInfo->btStatus = abBtqueued; - sc_unlock(plink); - return(abBtqueued); -} - -/* - * LINK_STATUS - * - * Fetches the status of the adapters on the specified link - * The ab_adapter_status table is used to determine hardware communication - * errors and convey them to the database - */ -LOCAL int link_status(ab_link *plink) -{ - short i; - ab_adapter *padapter; - dp_mbox *pmb; - ab_link_status *plink_status = plink->plink_status; - int status; - int ntry; - int linkOK = TRUE; - - /* initialize the pointer to the dual ported memory */ - pmb = (dp_mbox *)(&plink->vme_addr->mail); - /* get the link status */ - for(ntry=0; ntrycommand = LINK_STATUS; - pmb->data_len = 0; - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - plink_status->list_len = pmb->data_len; - ustrans(pmb->msg,plink_status->status,32); - uctrans((unsigned char *)(pmb->msg+32),plink_status->list,64); - sc_unlock(plink); - break; - } - if(ntry>=maxCmdTrys) { - if(ab_debug)printf("abDrv: link_status failed link %hu\n",plink->link); - linkOK = FALSE; - } - /* check each adapter on this link */ - for (i = 0; i< AB_MAX_ADAPTERS; i++){ - padapter = plink->papadapter[i]; - - if(!padapter) continue; - /* good status */ - if (linkOK && plink_status->status[i*4] & 0x70){ - if (!padapter->adapter_online) { - printf("link %d adapter %d change bad to good\n", - plink->link,i); - padapter->adapter_status_change=TRUE; - } - padapter->adapter_online = TRUE; - }else { /* bad status */ - if (padapter->adapter_online){ - printf("link %d adapter %d change good to bad\n", - plink->link,i); - padapter->adapter_status_change=TRUE; - } - padapter->adapter_online = FALSE; - } - } - return(0); -} - -/* ab_reboot_hook - routine to call when IOC is rebooted with a control-x */ -LOCAL int ab_reboot_hook(int boot_type) -{ - short i; - ab_link *plink; - - /* Stop communication to the Allen-Bradley Scanner Cards */ - /* delete the scan task stops analog input communication */ - for (i=0; iab_disable = 1; - taskDelete(pab_links[i]->abScanId); - } - } - /* this seems to be necessary for the AB card to stop talking */ - printf("\nReboot: drvAb delay to clear interrupts off backplane\n"); - taskDelay(sysClkRateGet()*2); - return(0); -} - - -LOCAL void config_init(ab_link *plink) -{ - ab_config *pconfig = plink->pconfig; - int i; - ab_region *p6008; - - if(!pconfig) plink->pconfig = pconfig = abCalloc(1,sizeof(ab_config)); - p6008 = (ab_region *)AB_BASE_ADDR; - p6008 += plink->link; - pconfig->base_address = (void *)p6008; - pconfig->baud_rate = DEF_RATE; - pconfig->autoconfig = FALSE; - pconfig->int_vector = AB_VEC_BASE + plink->link; - pconfig->int_level = AB_INT_LEVEL; - pconfig->scan_list_len = 8; - for(i=0; i< AB_MAX_ADAPTERS; i++) pconfig->scan_list[i] = (i<<2); -} - -int abConfigNlinks(int nlinks) -{ - if(pab_links) { - printf("abConfigNlinks Illegal call. Must be first abDrv related call\n"); - return(-1); - } - max_ab_6008s = nlinks; - pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - return(0); -} - -int abConfigVme(int link, int base, int vector, int level) -{ - ab_link *plink; - ab_config *pconfig; - - if(link<0 || link>=max_ab_6008s) return(-1); - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - plink = pab_links[link]; - if(!plink) plink = allocLink(link); - pconfig = plink->pconfig; - pconfig->base_address = (void *)base; - pconfig->int_vector = vector; - pconfig->int_level = level; - return(0); -} - -int abConfigBaud(int link, int baud) -{ - ab_link *plink; - ab_config *pconfig; - - if(link<0 || link>=max_ab_6008s) return(-1); - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - plink = pab_links[link]; - if(!plink) plink = allocLink(link); - pconfig = plink->pconfig; - if(baud = 0) pconfig->baud_rate = DEF_RATE; - else pconfig->baud_rate = FAST_RATE; - return(0); -} - -int abConfigAuto(int link) -{ - ab_link *plink; - ab_config *pconfig; - - if(link<0 || link>=max_ab_6008s) return(-1); - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - plink = pab_links[link]; - if(!plink) plink = allocLink(link); - pconfig = plink->pconfig; - pconfig->autoconfig = TRUE; - return(0); -} - -int abConfigScanList(int link, int scan_list_len, char *scan_list) -{ - ab_link *plink; - ab_config *pconfig; - - if(link<0 || link>=max_ab_6008s) return(-1); - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - plink = pab_links[link]; - if(!plink) plink = allocLink(link); - pconfig = plink->pconfig; - pconfig->scan_list_len = scan_list_len; - memset(pconfig->scan_list,'\0',64); - memcpy(pconfig->scan_list,scan_list,scan_list_len); - return(0); -} - -int abConfigScanListAscii(int link, char *filename,int setRackSize) -{ - FILE *fp; - char *scan_list; - char buf[80]; - unsigned rack,group,size; - int nItemsRead,nCharsRead,scan_list_len; - - scan_list = abCalloc(64,sizeof(char)); - fp = fopen(filename,"r"); - scan_list_len = 0; - while(fgets(buf,80,fp)) { - if(buf[0] == '#') continue; - nItemsRead = sscanf(buf,"%u %u %n",&rack,&group,&nCharsRead); - if(nItemsRead!=2) { - printf("abConfigScanListAscii: Illegal line %d %s\n", - scan_list_len,buf); - fclose(fp); - return(0); - } - if(!setRackSize) { - size = 0x00; - } else if(strstr(&buf[nCharsRead],"1/4")) { - size = 0x00; - } else if(strstr(&buf[nCharsRead],"1/2")) { - size = 0x40; - } else if(strstr(&buf[nCharsRead],"3/4")) { - size = 0x80; - } else if(strstr(&buf[nCharsRead],"Full")) { - size = 0xc0; - } else { - printf("abConfigScanListAscii: Illegal line %d %s\n", - scan_list_len,buf); - fclose(fp); - return(0); - } - scan_list[scan_list_len] = size | (rack<<2) | group; - scan_list_len++; - } - fclose(fp); - return(abConfigScanList(link,scan_list_len,scan_list)); -} - -LOCAL int ab_driver_init() -{ - unsigned short cok; - unsigned short link; - ab_link *plink; - ab_region *p6008; - ab_config *pconfig; - int vxstatus; - long status; - int got_one; - char task_name[50]; - - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - /* check if any of the cards are there */ - got_one = 0; - for (link = 0; link < max_ab_6008s; link++,p6008++){ - plink = pab_links[link]; - if(plink) { - p6008 = plink->pconfig->base_address; - } else { - p6008 = (void *)AB_BASE_ADDR; - p6008 += link; - } - status = devRegisterAddress("drvAb",atVMEA24,(long)p6008, - sizeof(ab_region),(void **)&p6008); - if(status) { - errMessage(status,"drvAb"); - return(status); - } - if (vxMemProbe((char *)p6008,READ,1,(char *)&cok)==ERROR) { - continue; - } - got_one = 1; - if(!plink) plink = allocLink(link); - plink->vme_addr = p6008; /* set AB card address */ - pconfig = plink->pconfig; - if(!(plink->request_sem = semBCreate(SEM_Q_FIFO,SEM_EMPTY))){ - printf("AB_DRIVER_INIT: semBcreate failed\n"); - taskSuspend(0); - } - if(!(plink->ab_cmd_sem = semBCreate(SEM_Q_FIFO,SEM_EMPTY))){ - printf("AB_DRIVER_INIT: semBcreate failed\n"); - taskSuspend(0); - } - if(!(plink->ab_data_sem = semBCreate(SEM_Q_FIFO,SEM_EMPTY))){ - printf("AB_DRIVER_INIT: semBcreate failed\n"); - taskSuspend(0); - } - status = devConnectInterrupt(intVME,pconfig->int_vector, - ab_intr,(void *)(int)link); - if(status) { - errMessage(status,"drvAb"); - return(status); - } - status = devEnableInterruptLevel(intVME,pconfig->int_level); - if(status) { - errMessage(status,"drvAb"); - taskSuspend(0); - } - /* initialize the serial link */ - if(link_init(plink)) { - /*No use proceeding*/ - continue; - } - plink->initialized = TRUE; - sprintf(task_name,"%s%2.2d",ABSCAN_NAME,link); - vxstatus = taskSpawn(task_name,ABSCAN_PRI,ABSCAN_OPT, - ABSCAN_STACK,(FUNCPTR)abScanTask,(int)plink, - 0,0,0,0,0,0,0,0,0); - if(vxstatus < 0){ - printf("AB_DRIVER_INIT: failed taskSpawn\n"); - taskSuspend(0); - } - plink->abScanId = vxstatus; - taskwdInsert(plink->abScanId,NULL,NULL); - sprintf(task_name,"%s%2.2d",ABDONE_NAME,link); - vxstatus = taskSpawn(task_name,ABDONE_PRI,ABDONE_OPT, - ABDONE_STACK,(FUNCPTR)abDoneTask,(int)plink, - 0,0,0,0,0,0,0,0,0); - if(vxstatus < 0){ - printf("AB_DRIVER_INIT: failed taskSpawn\n"); - taskSuspend(0); - } - plink->abDoneId = vxstatus; - taskwdInsert(plink->abDoneId,NULL,NULL); - plink->ab_disable = FALSE; - } - /* put in hook for disabling communication for a reboot */ - if (got_one) rebootHookAdd(ab_reboot_hook); - return(0); -} - -/* - * link_init - * - * establish the communication link with the AB scanner - */ -LOCAL int link_init(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - ab_config *pconfig=plink->pconfig; - int status; - int ntry; - - /* the scanner comes up with the dual ported memory locked */ - pmb->fl_lock = 0; /* so unlock it */ - /*clear request semaphore*/ - semGive(plink->request_sem); - if(pmb->conf_stat != SCANNER_POWERUP){ - /* This link must already be initialized. We're done */ - if (ab_debug){ - printf("Link %x already initialized\n", plink->link); - } - return(0); - } - if(ab_debug) printf("drvAb: link %x, powerup...\n",plink->link); - /* on initialization the scanner puts its firmware revision info*/ - /* into the general data are of the dual-port. We save it here. */ - /* (The most current revision is Series A, Revision D.) */ - strcpy(plink->firmware_info,(char *)&pmb->msg[0]); - /* setup scanner */ - /* Wake up scanner for the first time*/ - p6008->sc_intr = 1; /*Wake up scanner*/ - taskDelay(1); /*Give it time to initialize*/ - for(ntry=0; ntrycommand = SET_UP; - pmb->data_len = 4; - pmb->msg[0] = (pconfig->baud_rate<<8) | 0; - pmb->msg[1] = (DEBUG<<8) | pconfig->int_level; - pmb->msg[2] = (pconfig->int_vector<<8) | AB_INT_ENABLE; - pmb->msg[3] = (AB_SYSFAIL_DISABLE<<8) | 0; - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - break; - } - if(ntry>=maxCmdTrys) { - printf("abDrv: SET_UP failed link %hu\n",plink->link); - return(ERROR); - } - sc_unlock(plink); - /* Once scanner has been placed in RUN_MODE, putting it back into - * PROGRAM_MODE will disable binary outputs until it is placed back in - * RUN_MODE. Some scanner commands, such as SCAN_LIST, can only be - * performed in PROGRAM_MODE. These commands should only be issued* - * immediately after initialization. - * Re-booting an IOC (without powering it down) is the presently - * the only way of getting it into PROGRAM_MODE - * without disabling binary outputs */ - - /* initialize scan list for each link present */ - /* A promised firmware change will allow us to RESET - the scanner over the vmeBus. For now, the only way - to get the scanner into prog-mode without having - the BO's glitch is with the vmeBus SYSRESET signal, - which occurs when the RESET switch on the VME chassis - is used. Until the f/w change is made, changing the - scanner from run mode to program mode (to modify the - scan list, for instance) will cause the BO's to turn - off until the scanner is returned to run mode. It's - not nice, but for now we'll have to assume that all - adapters are needed and put them all in the scan list. */ - /* set scan list*/ - if(pconfig->autoconfig) for(ntry=0; ntrycommand = AUTO_CONF; - pmb->data_len = 0; - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - break; - }else for(ntry=0; ntrycommand = SCAN_LIST; - pmb->data_len = pconfig->scan_list_len; - uctrans(pconfig->scan_list,(unsigned char *)pmb->msg, - pconfig->scan_list_len); - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - break; - } - if(ntry>=maxCmdTrys) { - printf("abDrv: AUTO_CONFIG or SCAN_LIST failed link %hu\n",plink->link); - return(ERROR); - } - sc_unlock(plink); - /* place the scanner into run mode */ - for(ntry=0; ntrycommand = SET_MODE; - pmb->msg[0] = (RUN_MODE<<8); - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - break; - } - if(ntry>=maxCmdTrys) { - printf("abDrv: SET_MODE failed link %hu\n",plink->link); - return(ERROR); - } - sc_unlock(plink); - return(0); -} - -/* - * abScanTask - * - * Scans the AB IO according to the AB configuration table. - * Entries are made in the AB configuration table when an IO - * interface is attempted from the database scan tasks. - * The sleep time assures that there is at least 1/10 second between the passes. - * The time through the scan loop seems to be minimal so there are no provisions - * for excluding the scan time from the sleep time. - */ -LOCAL void abScanTask(ab_link *plink) -{ - unsigned short adapter; - ab_adapter *padapter; - unsigned int pass = 0; - BOOL madeInitialCallback = FALSE; - unsigned long tickNow,tickBeg,tickDiff; - - tickBeg = tickGet(); - while(TRUE){ - /* run every 1/10 second */ - taskDelay(sysClkRateGet()/10); - if(plink->ab_disable) continue; - /* Every second perform a link check to see if any adapters */ - /* have changed state. (Don't want to queue up requests if*/ - /* they're off) */ - if((pass % 10) == 0){ - if (link_status(plink) != 0){ - if(ab_debug) printf("%x link_stat error\n",plink->link); - } - } - if(!madeInitialCallback && interruptAccept) - plink->initialCallback = TRUE; - pass++; - /*recompute intrSec and btSec about every 10 seconds*/ - if((pass %100) == 0) { - tickNow = tickGet(); - if(tickNow > tickBeg){/*skip overflows*/ - tickDiff = tickNow - tickBeg; - /*round to nearest counts/sec */ - plink->intrSec=((plink->intr_cnt*sysClkRateGet())+5)/tickDiff; - plink->btSec=((plink->bt_cnt*sysClkRateGet())+5)/tickDiff; - } - tickBeg = tickNow; - plink->intr_cnt = 0; - plink->bt_cnt = 0; - } - for (adapter = 0; adapter < AB_MAX_ADAPTERS; adapter++){ - padapter = plink->papadapter[adapter]; - if(!padapter) continue; - read_ab_adapter(plink,padapter); - padapter->adapter_status_change = FALSE; - } - if(plink->initialCallback) { - plink->initialCallback = FALSE; - madeInitialCallback = TRUE; - } - } -} - -LOCAL void read_ab_adapter(ab_link *plink, ab_adapter *padapter) -{ - unsigned short card; - unsigned long value; - ab_card *pcard; - scanInfo *pscanInfo; - btInfo *pbtInfo; - abStatus btStatus=0; - - /* each card */ - for (card = 0; card < AB_MAX_CARDS; card++){ - pcard = padapter->papcard[card]; - if (!pcard) continue; - if(!pcard->active) continue; - if(pcard->type==typeBt) { - pbtInfo = pcard->pbtInfo; - semTake(pcard->card_sem,WAIT_FOREVER); - if(pcard->active && pbtInfo->btStatus != abBtqueued) { - pcard->active = FALSE; - pcard->status = pbtInfo->btStatus; - if(pcard->callback) (*pcard->callback) ((void *)pcard); - } - semGive(pcard->card_sem); - continue; - } - if(pcard->type==typeBi || pcard->type==typeBo || pcard->type==typeBiBo){ - if(pcard->type==typeBi || pcard->type==typeBiBo) { - di_read(pcard,&value); - if ((value != pcard->diprev)||padapter->adapter_status_change){ - pcard->diprev = value; - if(pcard->callback) (*pcard->callback)((void *)pcard); - } - } - if(pcard->type==typeBo || pcard->type==typeBiBo) { - if(padapter->adapter_status_change) { - if(pcard->bocallback) (*pcard->bocallback)((void *)pcard); - } - } - if(plink->initialCallback) { - if(pcard->callback) (*pcard->callback)((void *)pcard); - if(pcard->bocallback) (*pcard->bocallback)((void *)pcard); - } - continue; - } - /*If we get here card is typeAi or typeAo*/ - pscanInfo = pcard->pscanInfo; - if(!pscanInfo) continue; - pbtInfo = pcard->pbtInfo; - if(!pbtInfo) continue; - if(padapter->adapter_status_change){ - if(!padapter->adapter_online) { - pcard->status = abNotInitialized; - if(pcard->callback) (*pcard->callback)((void *)pcard); - continue; - } - pscanInfo->state = stateInit; - } - if(!padapter->adapter_online) continue; - switch(pscanInfo->state) { - case stateInit: - if(pcard->status !=abNotInitialized) { - pcard->status = abNotInitialized; - if(pcard->callback) (*pcard->callback)((void *)pcard); - } - if(pcard->type==typeAo) { - btStatus = bt_queue(AB_READ,pcard,pscanInfo->pread_msg, - pscanInfo->read_msg_len); - }else { - btStatus = bt_queue(AB_WRITE,pcard,pscanInfo->pwrite_msg, - pscanInfo->write_msg_len); - } - if(btStatus==abBtqueued) { - pscanInfo->state_cnt = 0; - pscanInfo->state = stateInitBTwait; - pscanInfo->init_ctr++; - } else { - pscanInfo->bt_fail++; - pscanInfo->state_cnt++; - } - break; - case stateInitBTwait: - if(pbtInfo->btStatus==abBtqueued) { - pscanInfo->state_cnt++; - if(pscanInfo->state_cnt < 15) break; - } - if(pbtInfo->btStatus!=abSuccess) { - if(btStatus==abTimeout) pscanInfo->bt_to++; - else pscanInfo->bt_fail++; - pscanInfo->state_cnt = 0; - pscanInfo->state = stateInit; - break; - } - pscanInfo->state_cnt = 0; - pscanInfo->state = stateBT; - if(pcard->type==typeAi) { - pcard->needsUpdate = TRUE; - } else { - /*Give device support time to set output words*/ - pscanInfo->down_cnt = pscanInfo->update_rate; - } - /*break left out on purpose*/ -repeat_countdown: - case stateCountdown: - if(pcard->needsUpdate) { - pscanInfo->down_cnt = 0; - pcard->needsUpdate = FALSE; - } - if(pscanInfo->down_cnt>0) pscanInfo->down_cnt--; - if(pscanInfo->down_cnt>0) continue; - pscanInfo->state_cnt = 0; - pscanInfo->state = stateBT; - /*break left out on purpose*/ - case stateBT: - if(pcard->type==typeAi) { - btStatus = bt_queue(AB_READ,pcard,pscanInfo->pread_msg, - pscanInfo->read_msg_len); - }else { - btStatus = bt_queue(AB_WRITE,pcard,pscanInfo->pwrite_msg, - pscanInfo->write_msg_len); - } - if(btStatus!=abBtqueued) { - pscanInfo->state_cnt++; - /*After 15 trys reinitialize*/ - if(pscanInfo->state_cnt > 15) { - pcard->status = abFailure; - pscanInfo->bt_fail++; - pscanInfo->state_cnt = 0; - pscanInfo->state = stateInit; - } - break; - } - pscanInfo->state_cnt = 0; - pscanInfo->state = stateBTwait; - break; - case stateBTwait: - if(pbtInfo->btStatus==abBtqueued) { - pscanInfo->state_cnt++; - if(pscanInfo->state_cnt < 30) break; - } - if(pbtInfo->btStatus!=abSuccess) { - pcard->status = abFailure; - if(btStatus==abTimeout) pscanInfo->bt_to++; - else pscanInfo->bt_fail++; - pscanInfo->state_cnt = 0; - pscanInfo->state = stateInit; - break; - } - pcard->status = abSuccess; - pscanInfo->state_cnt = 0; - pscanInfo->down_cnt = pscanInfo->update_rate; - pscanInfo->state = stateCountdown; - if(pcard->callback) (*pcard->callback)((void *)pcard); - goto repeat_countdown; - } - } -} - -LOCAL void abDoneTask(ab_link *plink) -{ - unsigned short adapter; - unsigned short card; - ab_adapter *padapter; /* adapter data structure */ - ab_card *pcard; /* card data structure */ - btInfo *pbtInfo; - dp_mbox *pmb = &plink->vme_addr->mail; - unsigned short *pmb_msg = &pmb->msg[0]; - - while(TRUE) { - semTake(plink->ab_data_sem,WAIT_FOREVER); - /* Must check all data returned by hardware interface*/ - card = pmb->address & 0x0f; - adapter = (pmb->address & 0x70) >> 4; - if(card >= MAX_CARDS_PER_ADAPTER || adapter>=MAX_AB_ADAPTERS) { - if(ab_debug) - printf("drvAb: scanner returned bad address %4x\n", - pmb->address); - pmb->fl_lock = 0; - continue; - } - padapter = plink->papadapter[adapter]; - if(!padapter) { - if(ab_debug) - printf("abDrv:abDoneTask padapter=NULL adapter=%d\n", - adapter); - pmb->fl_lock = 0; - continue; - } - pcard = padapter->papcard[card]; - if(!pcard) { - if(ab_debug) - printf("abDrv: abDoneTask pcard=NULL card=%d adapter=%d\n", - card,adapter); - pmb->fl_lock = 0; - continue; - } - plink->bt_cnt++; - pbtInfo = pcard->pbtInfo; - /* block transfer failure */ - if (pmb->conf_stat != 0){ - if (pmb->conf_stat == BT_TIMEOUT) { - pbtInfo->btStatus = abTimeout; - }else{ - pbtInfo->btStatus = abFailure; - } - }else{ - /* successful */ - pbtInfo->btStatus = abSuccess; - /* was it the response to a read command */ - if (pbtInfo->cmd == AB_READ){ - ustrans(pmb_msg,pbtInfo->pmsg,pbtInfo->msg_len); - } - } - pmb->fl_lock = 0; - if(pcard->type==typeBt) { - semTake(pcard->card_sem,WAIT_FOREVER); - if(pcard->active) { - pcard->active = FALSE; - wdCancel(pbtInfo->wdId); - pcard->status = pbtInfo->btStatus; - if(pcard->callback) (*pcard->callback) ((void *)pcard); - } - semGive(pcard->card_sem); - } - } -} - -LOCAL void ab_reset_task(ab_link *plink) -{ - unsigned short link,adapter,card,ab_reset_wait; - ab_adapter *padapter; - ab_region *pab_region=0; - ab_card *pcard; - btInfo *pbtInfo; - - link = plink->link; - pab_region = plink->vme_addr; - plink->ab_disable = 1; - printf("Disabled AB Scanner Task\n"); - taskDelay(sysClkRateGet()*2); - /* Signal the Scanner to Reset */ - pab_region->sys_fail_set2 = 0xa0a0; - pab_region->sys_fail_set1 = 0x0080; - printf("Card %d Reset\n",link); - /*mark all block transfer cards for initialization*/ - for(adapter = 0; adapter < AB_MAX_ADAPTERS; adapter++){ - padapter = plink->papadapter[adapter]; - if(!padapter) continue; - for (card = 0; card < AB_MAX_CARDS; card++){ - pcard = padapter->papcard[card]; - if(!pcard) continue; - pbtInfo = pcard->pbtInfo; - if(pcard->type==typeAo || pcard->type==typeAi) - pcard->needsUpdate = TRUE; - } - } - ab_reset_wait = 0; - while((pab_region->mail.conf_stat != SCANNER_POWERUP) - && (ab_reset_wait < 600)){ - taskDelay(1); - ab_reset_wait++; - } - if (ab_reset_wait < 600) - printf("Link %d Power Up After %d Ticks\n",link,ab_reset_wait); - else - printf("Link %d Failed to Reinitialize After %d Ticks\n", - link,ab_reset_wait); - - link_init(plink); - /* enable the scanner */ - plink->ab_disable = 0; -} - -int ab_reset_link(int link) -{ - ab_link *plink; - - if(link>=max_ab_6008s) return(0); - plink = pab_links[link]; - if(!plink) return(0); - taskSpawn("ab_reset",38,0,8000,(FUNCPTR)ab_reset_task,(int)plink, - 0,0,0,0,0,0,0,0,0); - return(0); -} - -int ab_reset(void) -{ - int link; - - for(link=0; linkinitialized) { - printf("AB-6008SV link %hu not initialized\n",link); - continue; - } - printf("AB-6008SV link: %hu osw %4.4x vme: %p\n", - link,plink->vme_addr->osw,plink->vme_addr); - if(plink->firmware_info[0]) printf(" %s\n",plink->firmware_info); - printf(" Mailbox lock timeouts %hu\n",plink->sclock_to); - printf(" Command timeouts %hu\n", plink->sccmd_to); - printf(" Command Failure %hu\n", plink->sc_fail); - printf(" Interrupts per second %hu\n", plink->intrSec); - printf(" Block Transfers per second %hu\n", plink->btSec); - if(level>2) { - ab_link_status *plink_status = plink->plink_status; - - printf(" Adapter Status Words"); - for(i=0; i<32; i++) { - if((i%8)==0) printf("\n "); - printf("%4.4x ",plink_status->status[i]); - } - printf("\n scan list"); - for(i=0; ilist_len; i++) { - if((i%16)==0) printf("\n "); - printf("%2.2x ",plink_status->list[i]); - } - printf("\n"); - } - /* adapter information */ - for (adapter = 0; adapter < AB_MAX_ADAPTERS; adapter++){ - padapter = plink->papadapter[adapter]; - if (!padapter) continue; - if (padapter->adapter_online) - printf(" Adapter %hu ONLINE\n",adapter); - else - printf(" Adapter %hu OFFLINE\n",adapter); - - /* card information */ - for (card = 0; card < AB_MAX_CARDS; card++){ - pcard = padapter->papcard[card]; - if(!pcard) continue; - pscanInfo = pcard->pscanInfo; - switch (pcard->type){ - case (typeBi): - di_read(pcard,&divalue); - printf(" CARD %hu: BI %s %s 0x%x\n", - card,abNumBitsMessage[pcard->nBits], - activeMessage[pcard->active],divalue); - break; - case (typeBo): - do_read(pcard,&dovalue); - printf(" CARD %hu: BO %s %s 0x%x\n", - card,abNumBitsMessage[pcard->nBits], - activeMessage[pcard->active],dovalue); - break; - case (typeBiBo): - di_read(pcard,&divalue); - do_read(pcard,&dovalue); - printf(" CARD %hu: BIBO %s %s in 0x%x out 0x%x\n", - card,abNumBitsMessage[pcard->nBits], - activeMessage[pcard->active],divalue,dovalue); - break; - case (typeAi): - case (typeAo): - if(pcard->type==typeAi) - printf(" CARD %hu: AI ",card); - else - printf(" CARD %hu: AO ",card); - if(!pscanInfo || pscanInfo->state==stateInit) - printf(" NOT INITIALIZED "); - printf(" %s %s",activeMessage[pcard->active], - pcard->card_name); - /* error reporting */ - if(!pscanInfo) { - printf("\n"); - break; - } - if (pscanInfo->bt_to) - printf(" bt timeout: %hu",pscanInfo->bt_to); - if (pscanInfo->bt_fail) - printf(" bt fail: %hu",pscanInfo->bt_fail); - if (pscanInfo->init_ctr) - printf(" initialized %hu times",pscanInfo->init_ctr); - printf("\n"); - if (level > 0){ - if(pcard->type==typeAo || level>1) { - printf("\tWrite"); - for (i=0; iwrite_msg_len; i++) { - if((i%10)==0) printf("\n\t"); - printf("%4.4x ",pscanInfo->pwrite_msg[i]); - } - printf("\n"); - } - if(pcard->type==typeAi || level>1) { - printf("\tRead"); - for (i=0; iread_msg_len; i++) { - if((i%10)==0) printf("\n\t"); - printf("%4.4x ",pscanInfo->pread_msg[i]); - } - printf("\n"); - } - } - break; - case (typeBt): - printf(" CARD %hu: BT %s %s\n", card, - activeMessage[pcard->active],pcard->card_name); - break; - default: - continue; - } - } - } - } - return(0); - -} - -LOCAL abStatus registerCard( - unsigned short link,unsigned short adapter, unsigned short card, - cardType type, const char *card_name, void (*callback)(void *drvPvt), - void **pdrvPvt) -{ - ab_adapter *padapter; - ab_card *pcard = NULL; - ab_link *plink; - ab_card **ppcard = (ab_card **)pdrvPvt; - - - if(link>=max_ab_6008s) { - if(ab_debug>0) - printf("abDrv(registerCard) bad link %hu\n",link); - return(abNoCard); - } - if(adapter>=MAX_AB_ADAPTERS) { - if(ab_debug>0) - printf("abDrv(registerCard) bad adapter %hu\n",adapter); - return(abNoCard); - } - if(card>=MAX_CARDS_PER_ADAPTER) { - if(ab_debug>0) - printf("abDrv(registerCard) bad card %hu\n",card); - return(abNoCard); - } - if(!pab_links || !(plink = pab_links[link]) || !plink->initialized) { - if(ab_debug>0) - printf("abDrv(registerCard) link %hu not initialized\n",link); - return(abNoCard); - } - padapter = plink->papadapter[adapter]; - if(padapter) pcard = padapter->papcard[card]; - if(pcard) { - if(strcmp(pcard->card_name,card_name)!=0) return(abCardConflict); - if(pcard->type==type) { - *ppcard = pcard; - return(abSuccess); - } - if(type==typeBi || type==typeBo) { - if(pcard->type==typeBo || pcard->type==typeBi - || pcard->type==typeBiBo) { - if(!pcard->callback && type==typeBi ) - pcard->callback = callback; - if(!pcard->bocallback && type==typeBo ) - pcard->bocallback = callback; - pcard->type = typeBiBo; - *ppcard = pcard; - return(abSuccess); - } - } - return(abCardConflict); - } - /*New Card*/ - pcard = abCalloc(1,sizeof(ab_card)); - pcard->link = link; - pcard->adapter = adapter; - pcard->card = card; - pcard->type = type; - pcard->card_name = card_name; - if(!(pcard->card_sem = semBCreate(SEM_Q_FIFO,SEM_FULL))){ - printf("abDrv register card: semBcreate failed\n"); - taskSuspend(0); - } - if(type==typeBo) pcard->bocallback = callback; - else pcard->callback = callback; - if(type==typeAi || type ==typeAo || type == typeBt) { - pcard->pbtInfo = abCalloc(1,sizeof(btInfo)); - if(type == typeBt) { - if(!(pcard->pbtInfo->wdId = wdCreate()) ) { - printf("abDrv register card: wdCreate failed\n"); - taskSuspend(0); - } - } - } - *ppcard = pcard; - if(!padapter) { - padapter = abCalloc(1,sizeof(ab_adapter)); - padapter->papcard = abCalloc(MAX_CARDS_PER_ADAPTER,sizeof(ab_card *)); - if(!(padapter->adapter_sem = semBCreate(SEM_Q_FIFO,SEM_FULL))){ - printf("abDrv: abRegister: semBcreate failed\n"); - taskSuspend(0); - } - padapter->adapter = adapter; - } - padapter->papcard[card] = pcard; - if(!plink->papadapter[adapter]) plink->papadapter[adapter] = padapter; - link_status(plink); - return(abNewCard); -} - -LOCAL void getLocation(void *drvPvt,unsigned short *link, - unsigned short *adapter,unsigned short *card) -{ - ab_card *pcard = drvPvt; - - *link = pcard->link; - *adapter = pcard->adapter; - *card = pcard->card; - return; -} - -LOCAL abStatus setNbits(void *drvPvt, abNumBits nBits) -{ - ab_card *pcard = drvPvt; - - if(pcard->nBits == abBitNotdefined) { - pcard->nBits = nBits; - pcard->active = TRUE; - return(abSuccess); - } - if(pcard->nBits == nBits) return(abSuccess); - return(abFailure); -} - -LOCAL void setUserPvt(void *drvPvt,void *userPvt) -{ - ab_card *pcard = drvPvt; - - pcard->userPvt = userPvt; - return; -} - -LOCAL void *getUserPvt(void *drvPvt) -{ - ab_card *pcard = drvPvt; - - return(pcard->userPvt); -} - -LOCAL abStatus getStatus(void *drvPvt) -{ - ab_card *pcard = drvPvt; - - unsigned short link = pcard->link; - unsigned short adapter = pcard->adapter; - ab_adapter *padapter = pab_links[link]->papadapter[adapter]; - - if(!padapter->adapter_online) return(abAdapterDown); - return(pcard->status); -} - -LOCAL abStatus startScan(void *drvPvt, unsigned short update_rate, - unsigned short *pwrite_msg, unsigned short write_msg_len, - unsigned short *pread_msg, unsigned short read_msg_len) -{ - ab_card *pcard = drvPvt; - scanInfo *pscanInfo; - - pscanInfo = pcard->pscanInfo; - if(!pscanInfo) pcard->pscanInfo = pscanInfo = abCalloc(1,sizeof(scanInfo)); - pscanInfo->update_rate = update_rate; - pscanInfo->pwrite_msg = pwrite_msg; - pscanInfo->write_msg_len = write_msg_len; - pscanInfo->pread_msg = pread_msg; - pscanInfo->read_msg_len = read_msg_len; - pscanInfo->state = stateInit; - pcard->active = TRUE; - pcard->status = abNotInitialized; - return(abSuccess); -} - -LOCAL abStatus updateAo(void *drvPvt) -{ - ab_card *pcard = drvPvt; - - pcard->needsUpdate = TRUE; - return(getStatus(drvPvt)); -} - -LOCAL abStatus updateBo(void *drvPvt,unsigned long value,unsigned long mask) -{ - ab_card *pcard = drvPvt; - unsigned long imagevalue; - - semTake(pcard->card_sem,WAIT_FOREVER); - do_read(pcard,&imagevalue); - imagevalue = (imagevalue & ~mask) | (value & mask); - do_write(pcard,imagevalue); - semGive(pcard->card_sem); - if(pcard->bocallback) (*pcard->bocallback)((void *)pcard); - return(getStatus(drvPvt)); -} - -LOCAL abStatus readBo(void *drvPvt,unsigned long *pvalue,unsigned long mask) -{ - ab_card *pcard = drvPvt; - unsigned long value; - - do_read(pcard,&value); - *pvalue = value & mask; - return(getStatus(drvPvt)); -} - -LOCAL abStatus readBi(void *drvPvt,unsigned long *pvalue,unsigned long mask) -{ - ab_card *pcard = drvPvt; - unsigned long value; - - di_read(pcard,&value); - *pvalue = value & mask; - return(getStatus(drvPvt)); -} - -static void btTimeoutCallback(ab_card *pcard) -{ - pcard->pbtInfo->btStatus = abFailure; - if(ab_debug) logMsg("btTimeoutCallback link %d adapter %d card %d\n", - pcard->link,pcard->adapter,pcard->card,0,0,0); - return; -} - -LOCAL abStatus btReadWrite(unsigned short cmd, void *drvPvt, - unsigned short *pread_msg, unsigned short read_msg_len) -{ - ab_card *pcard = drvPvt; - int btStatus; - STATUS wdStatus; - - if(!pcard) return(abFailure); - semTake(pcard->card_sem,WAIT_FOREVER); - if(pcard->active) { - btStatus = abBusy; - } else { - pcard->active = TRUE; - btStatus=bt_queue(cmd,pcard,pread_msg,read_msg_len); - if(btStatus==abBtqueued) { - /* Set timeout for 1 second more than 68008 SV block */ - /* transfer timout, which is 4 seconds */ - wdStatus = wdStart(pcard->pbtInfo->wdId, - sysClkRateGet()*5, - (FUNCPTR)btTimeoutCallback,(int)pcard); - if(wdStatus==ERROR) { - printf("abDrv btReadWrite : wdStart failure\n"); - btStatus = abFailure; - } - } - if(btStatus!=abBtqueued) pcard->active = FALSE; - } - semGive(pcard->card_sem); - return(btStatus); -} - -LOCAL abStatus btRead(void *drvPvt, - unsigned short *pread_msg, unsigned short read_msg_len) -{ - return(btReadWrite(AB_READ,drvPvt,pread_msg,read_msg_len)); -} - -LOCAL abStatus btWrite(void *drvPvt, - unsigned short *pwrite_msg, unsigned short write_msg_len) -{ - return(btReadWrite(AB_WRITE,drvPvt,pwrite_msg,write_msg_len)); -} - -LOCAL abStatus adapterStatus(unsigned short link,unsigned short adapter) -{ - ab_adapter *padapter; - ab_link *plink; - - if(link>=max_ab_6008s) return(abFailure); - if(adapter>=MAX_AB_ADAPTERS) return(abFailure); - plink = pab_links[link]; - if(!plink || !plink->initialized) return(abFailure); - padapter = plink->papadapter[adapter]; - if(!padapter->adapter_online) return(abAdapterDown); - return(abSuccess); -} - -LOCAL abStatus cardStatus( - unsigned short link,unsigned short adapter,unsigned short card) -{ - ab_adapter *padapter; - ab_link *plink; - ab_card *pcard; - - if(link>=max_ab_6008s) return(abFailure); - if(adapter>=MAX_AB_ADAPTERS) return(abFailure); - if(card>=MAX_CARDS_PER_ADAPTER) return(abFailure); - plink = pab_links[link]; - if(!plink || !plink->initialized) return(abFailure); - padapter = plink->papadapter[adapter]; - if(!padapter->adapter_online) return(abAdapterDown); - pcard = padapter->papcard[card]; - if(!pcard) return(abNoCard); - if(!padapter->adapter_online) return(abAdapterDown); - return(pcard->status); -} - -LOCAL abDrv abDrvTable= { - registerCard,getLocation,setNbits,setUserPvt,getUserPvt, - getStatus,startScan,updateAo,updateBo,readBo,readBi,btRead,btWrite, - adapterStatus,cardStatus -}; -abDrv *pabDrv = &abDrvTable; - - -/*Time how long it takes to issue link_status */ -int ab_time_link_status(int link) -{ - ab_link *plink = pab_links[link]; - int startTicks; - int stopTicks; - int pass; - double tdiff; - - if(!plink) return(-1); - startTicks = tickGet(); - for (pass=0; pass<100; pass++) link_status(plink); - stopTicks = tickGet(); - tdiff = (stopTicks - startTicks)/60.0; - printf("pass/sec %f\n",(float)pass/tdiff); - return(0); -} diff --git a/src/drv/ansi/drvAb.h b/src/drv/ansi/drvAb.h deleted file mode 100644 index 6d96a904c..000000000 --- a/src/drv/ansi/drvAb.h +++ /dev/null @@ -1,93 +0,0 @@ -/* drvAb.h */ -/* header file for the Allen-Bradley Remote Serial IO - * This defines interface between driver and device support - * - * Author: Marty Kraimer - * Date: 03-06-95 - * - * 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 03-06-95 mrk Moved all driver specific code to drvAb.c - */ - -#ifndef INCdrvAbh -#define INCdrvAbh 1 -#include "dbScan.h" - - -/* interface types */ -typedef enum {typeNotAssigned,typeBi,typeBo,typeBiBo,typeAi,typeAo,typeBt} - cardType; -/* status values*/ -typedef enum{abSuccess,abNewCard,abCardConflict,abNoCard,abNotInitialized, - abBtqueued,abBusy,abTimeout,abAdapterDown,abFailure} abStatus; -extern char **abStatusMessage; - -typedef enum{abBitNotdefined,abBit8,abBit16,abBit32} abNumBits; -extern char **abNumBitsMessage; - -/*entry table for dev to drv routines*/ -typedef struct { - abStatus (*registerCard) - (unsigned short link,unsigned short adapter, unsigned short card, - cardType type, const char *card_name, - void (*callback)(void *drvPvt), - void **drvPvt); - void (*getLocation) - (void *drvPvt, - unsigned short *link, unsigned short *adapter,unsigned short *card); - abStatus (*setNbits)(void *drvPvt, abNumBits nbits); - void (*setUserPvt)(void *drvPvt, void *userPvt); - void *(*getUserPvt)(void *drvPvt); - abStatus (*getStatus)(void *drvPvt); - abStatus(*startScan) - (void *drvPvt, unsigned short update_rate, - unsigned short *pwrite_msg, unsigned short write_msg_len, - unsigned short *pread_msg, unsigned short read_msg_len); - abStatus(*updateAo)(void *drvPvt); - abStatus(*updateBo) (void *drvPvt,unsigned long value,unsigned long mask); - abStatus(*readBo) (void *drvPvt,unsigned long *value,unsigned long mask); - abStatus(*readBi) (void *drvPvt,unsigned long *value,unsigned long mask); - abStatus(*btRead)(void *drvPvt,unsigned short *pread_msg, - unsigned short read_msg_len); - abStatus(*btWrite)(void *drvPvt,unsigned short *pwrite_msg, - unsigned short write_msg_len); - abStatus (*adapterStatus) - (unsigned short link,unsigned short adapter); - abStatus (*cardStatus) - (unsigned short link,unsigned short adapter, unsigned short card); -}abDrv; - -extern abDrv *pabDrv; - -int ab_reset(void); -int ab_reset_link(int link); -int abConfigNlinks(int nlinks); -int abConfigVme(int link, int base, int vector, int level); -int abConfigBaud(int link, int baud); -int abConfigScanList(int link, int scan_list_len, char *scan_list); -int abConfigScanListAscii(int link, char *filename,int setRackSize); -int abConfigAuto(int link); - -#endif /*INCdrvAbh*/ diff --git a/src/drv/ansi/drvAt5Vxi.c b/src/drv/ansi/drvAt5Vxi.c deleted file mode 100644 index 14a0d29d6..000000000 --- a/src/drv/ansi/drvAt5Vxi.c +++ /dev/null @@ -1,1414 +0,0 @@ -/* base/src/drv $Id$ */ - -/* - * - * driver for at5 designed VXI modules - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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 021490 first release - * .02 joh 040490 took out init of binary outs as requested by AT5 - * .03 joh 040490 KLUDGED so DC is invarient of model number - * .04 joh 072590 fixed case where a missing SC module could - * be accessed before checking to prevent bus error - * .05 joh 102990 slightly improved sync to busy in init - * .06 joh 032191 added code to implement a new register - * interface from AT5 - * .07 joh 080291 disable ints during control X reboot - * .08 joh 080291 fixed ints on before handler installed problem - * introduced by .06 - * .09 joh 080291 synch source with sorce release control version - * .10 joh 080891 delinting - * .11 joh 090591 converted to v5 vxWorks - * .12 joh 120591 reorganized for use with new vxi support and removed - * KLUDGE introduced in .03 - * .13 joh 042492 removed support for (ifdefs for) the old - * style register map - * .14 joh 071792 added model name registration - * .15 joh 072992 print more raw values in io report - * .16 joh 081092 merged at5vxi_models.h into this source - * .17 joh 081992 function name change - * .18 joh 082792 converted to ansi C - * .19 joh 111392 removed shifts on analog IO - * .20 joh 071593 fixed comment - * .21 joh 081193 took out EPICS_V2 compile switches - * - * Notes: - * ------ - * .01 Dont use C bitfields to write the AT5VXI CSR - * directly because some bits have different meanings - * for read than for write (bitfields writes generate RMW - * instructions- performing reads with C bitfields - * from an IO module works fine however). - * - * To avoid this I write all bits in the CSR with - * each write. See the codes defined by at5vxi_init(). - */ - -/* - * Improvements: - * - * Dont allow them to connect an interrupt if another device is - * installed there ! Perhaps intConnectSafe() should be written? - */ - - - -/* - * Code Portions - * - * AT5VXI_INIT initialize all at5vxi cards - * AT5VXI_INIT_CARD initialize single at5vxi card - * AT5VXI_INT_SERVICE update card busy writes, notify IO scanner - * AT5VXI_ONE_SHOT setup AMD9513 STC with a one shot - * AT5VXI_ONE_SHOT_READ read back timing from an AMD 9513 STC - * AT5VXI_STAT print status for a single at5 vxi card - * AT5VXI_READ_TEST diagnostic - * AT5VXI_AI_DRIVER analog input driver - * AT5VXI_AO_DRIVER analog output driver - * AT5VXI_AO_READ analog output read back - * AT5VXI_BI_DRIVER binary input driver - * AT5VXI_BO_DRIVER binary output driver - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static char SccsId[] = "@(#)drvAt5Vxi.c 1.19\t8/27/93"; - -LOCAL void at5vxi_int_service( - int addr -); - -LOCAL void at5vxi_init_card( - unsigned addr, - void *pArg -); - -LOCAL int at5vxi_shutdown(void); - -LOCAL void at5vxi_shutdown_card( - unsigned la, - void *pArg -); - -LOCAL at5VxiStatus at5vxi_report_timing( - unsigned card, - unsigned channel -); - -LOCAL void at5vxi_stat( - unsigned card, - int level -); - -LOCAL at5VxiStatus at5vxi_init( - void -); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvAt5Vxi={ - 2, - NULL, /* VXI io report takes care of this */ - at5vxi_init}; - -#define EXT_TICKS 5.0e06 /* GTA std speed of SRC1 in Hz */ - -/* - * Set this flag if you wish for the driver to - * to disable the busy period and operate - * without periodic interrupts - * -#define CONTINUOUS_OPERATION - * - */ - -/* - * all AT5VXI cards will use this VME interrupt level - */ -#ifdef CONTINUOUS_OPERATION -# define AT5VXI_INT_LEVEL 0 -# define AT5VXI_INT_ENABLE FALSE -# define AT5VXI_BUSY_ENABLE FALSE -#else -# define AT5VXI_INT_LEVEL 5 -# define AT5VXI_INT_ENABLE TRUE -# define AT5VXI_BUSY_ENABLE TRUE -#endif - -#define abort(A) taskSuspend(0) - -/* - * bit fields allocated starting with the ms bit - */ -struct at5vxi_status{ - unsigned pad0:1; - unsigned modid_cmpl:1; - unsigned dev255:1; - unsigned busy:1; - unsigned pad1:2; - unsigned timer_bank:1; - unsigned ipend:1; - unsigned ienable:1; - unsigned ilevel:3; - unsigned ready:1; - unsigned passed:1; - unsigned sfinh:1; - unsigned sreset:1; -}; - - -#define PSTATUS(PCSR)\ -(&((struct vxi_csr *)PCSR)->dir.r.status) - -struct at5vxi_control{ - unsigned pad0:3; - unsigned busy_enable:1; - unsigned pad1:2; - unsigned timer_bank:1; - unsigned softint:1; - unsigned ienable:1; - unsigned ilevel:3; - unsigned pad2:2; - unsigned sfinh:1; - unsigned sreset:1; -}; - -/* - * Insert or extract a bit field using the standard - * masks and shifts defined below - */ -#ifdef __STDC__ -# define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S)) -# define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M)) -#else -# define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S)) -# define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M)) -#endif - -/* - * in the constants below _M is a right justified mask - * and _S is a shift required to right justify the field - */ -#define FD_INT_ENABLE_M (0x1) -#define FD_INT_ENABLE_S (7) -#define FD_BUSY_ENABLE_M (0x1) -#define FD_BUSY_ENABLE_S (12) -#define FD_BUSY_STATUS_M (0x1) -#define FD_BUSY_STATUS_S (12) -#define FD_INT_LEVEL_M (0x7) -#define FD_INT_LEVEL_S (4) -#define FD_TIMER_BANK_M (0x1) -#define FD_TIMER_BANK_S (9) - -#define BUSY(PCSR)\ -(((struct vxi_csr *)PCSR)->dir.r.status & INSERT(BUSY_STATUS,1)) - -/* - * Some constants for the CSR. - * - */ -#ifndef CONTINUOUS_OPERATION -# define INTDISABLE\ - ( \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_ENABLE, FALSE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) -#endif - -/* - * Used to initialize the control register. - * (enables interrupts) - */ -#define CSRINIT\ - ( \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_ENABLE, AT5VXI_INT_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) - -/* - * Use bank zero of the timing. - */ -#define BANK0\ - ( \ - INSERT(TIMER_BANK, 0) | \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) -/* - * Use bank one of the timing. - */ -#define BANK1\ - ( \ - INSERT(TIMER_BANK, 1) | \ - INSERT(BUSY_ENABLE, AT5VXI_BUSY_ENABLE) | \ - INSERT(INT_LEVEL, AT5VXI_INT_LEVEL) \ - ) - -/* - * Some constants for the CSR. - * set at initialization for better readability - */ -#define PCONTROL(PCSR)\ -(&((struct vxi_csr *)PCSR)->dir.w.control) - - - - -#define AT5VXI_TIMER_BANKS_PER_MODULE 2 -#define AT5VXI_CHANNELS_PER_TIMER_BANK 5 -#define AT5VXI_NTIMER_CHANNELS\ - (AT5VXI_TIMER_BANKS_PER_MODULE*AT5VXI_CHANNELS_PER_TIMER_BANK) - - -struct at5vxi_dd{ - vxi16_t bio[2]; - vxi16_t tdata; - vxi8_t pad; - vxi8_t tcmd; - vxi16_t ai[8]; - vxi16_t ao[16]; -}; - - -struct at5vxi_setup{ -# define UNITY 0 -# define TIMES2 1 - unsigned gainA:1; - unsigned gainB:1; - unsigned gainC:1; - unsigned gainD:1; -# define UNIPOLAR 0 -# define BIPOLAR 1 - unsigned modeA:1; - unsigned modeB:1; - unsigned modeC:1; - unsigned modeD:1; - unsigned ch2enbl:1; - unsigned ch2select:3; - unsigned ch1enbl:1; - unsigned ch1select:3; -}; - - -#define AT5VXI_BUSY_PERIOD 2 - -struct bo_val { - volatile int32_t val; - volatile int32_t mask; -}; - -struct ao_val { - volatile int16_t mdt; - volatile int16_t val; -}; - -struct time_val { - volatile unsigned preset; - volatile int16_t iedge0_delay; - volatile int16_t iedge1_delay; - volatile char mdt; - volatile char valid; -}; - -struct at5vxi_config{ - FAST_LOCK lock; /* mutual exclusion */ - struct bo_val bv; /* binary out values */ - struct ao_val av[16]; /* analog out values */ - struct time_val tv[10]; /* delayed pulse values */ - volatile char mdt; /* modified data tag */ - struct vxi_csr *pcsr; /* vxi device hdr ptr */ - struct at5vxi_dd *pdd; /* at5 device dep ptr */ - IOSCANPVT ioscanpvt; -}; - -LOCAL unsigned long at5vxiDriverID; - -#define AT5VXI_PCONFIG(CARD, PTR) \ -epvxiFetchPConfig(CARD, at5vxiDriverID, PTR) - -#define AT5VXI_CORRECT_MAKE(PCSR) (VXIMAKE(PCSR)==VXI_MAKE_LANSCE5) - -struct at5vxi_model{ - char *name; /* AT5 VXI module name */ - char *drawing; /* AT5 VXI assembly drawing number */ -}; - -#define AT5VXI_INDEX_FROM_MODEL(MODEL) ((unsigned)((MODEL)&0xff)) -#define AT5VXI_MODEL_FROM_INDEX(INDEX) ((unsigned)((INDEX)|0xf00)) - -/* - * NOTE: The macro AT5VXI_INDEX_FROM_MODEL(MODEL) defined above - * should return an index into the correct data given the - * VXI device's model code. - */ -struct at5vxi_model at5vxi_models[] = { - {"INTERFACE SIMULATOR", "112Y-280158"}, - {"I CONTROLLER", "112Y-280176"}, - {"CONTROL PREDISTORTER", "112Y-280172"}, - {"VECTOR DETECTOR", "112Y-280230"}, - {"VECTOR MODULATOR", "112Y-280177"}, - {"425MHz ENVELOPE DETECTOR", "112Y-280169"}, - {"425MHz DOWNCONVERTER", "112Y-280165"}, - {"POLAR DETECTOR", "112Y-280567"}, - {"UPCONVERTER", "112Y-280225"}, - {"MONITOR TRANSMITTER", "112Y-280187"}, - {"TIMING DISTRIBUTION", "112Y-280582"}, - {"LINE CONDITIONER", "112Y-280305"}, - {"BEAM FEEDFORWARD", "112Y-280564"}, - {"TIMING RECEIVER", "112Y-280243"}, - {"FAST PROTECTION", "112Y-280246"}, - {"ADAPTIVE FEEDFORWARD", "112Y-280563"}, - {"CABLE CONTROLLER", "112Y-280307"}, - {"Q CONTROLLER", "112Y-280180"}, - {"ENVELOPE DETECTOR", "112Y-280249"}, - {"DOWNCONVERTER", "112Y-280456"}, - {"COAX MONITOR TRANSMITTER", "112Y-280587"}, - {"CAVITY SIMULATOR", "112Y-280232"}, - {"CABLE CONTROLLER (2 CHANNEL)","112Y-280539"}, - {"BREADBOARD", "112Y-280358"}, - {"I/O INTERFACE", "112Y-280359"}, - {"DIAGNOSTIC - BPM", "112Y-280422-1"}, - {"FAST ENVELOPE DETECTOR", "112Y-280421"}, - {"DIAGNOSTIC - CM", "112Y-280422-2"}, - {"DIAGNOSTIC - MISC", "112Y-280422-3"}, - {"FAST VECTOR DETECTOR", "112Y-280651"}, - {"SINGLE-WIDE VECTOR DETECTOR", "112Y-280672"}, - {"FM / AM", "112Y-280xxx"} -}; - -#define AT5VXI_VALID_MODEL(MODEL) \ -(AT5VXI_INDEX_FROM_MODEL(MODEL)dir.w.control = INTDISABLE; -#endif -} - - - -/* - * AT5VXI_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL -void at5vxi_init_card( - unsigned addr, - void *pArg -) -{ - at5VxiStatus r0; - struct at5vxi_config *pc; - struct time_val *ptv; - unsigned chan; - int i; - int model; - - r0 = epvxiOpen( - addr, - at5vxiDriverID, - (unsigned long) sizeof(*pc), - at5vxi_stat); - if(r0){ - errPrintf( - r0, - __FILE__, - __LINE__, - "AT5VXI: device open failed %d\n", addr); - return; - } - - r0 = AT5VXI_PCONFIG(addr, pc); - if(r0){ - errMessage(r0, NULL); - epvxiClose(addr, at5vxiDriverID); - return; - } - - pc->pcsr = VXIBASE(addr); - pc->pdd = (struct at5vxi_dd *) &pc->pcsr->dir.r.dd; - - FASTLOCKINIT(&pc->lock); - - scanIoInit(&pc->ioscanpvt); - - - /* - * revert to power up control - * (temporarily disable the busy period) - */ - pc->pcsr->dir.w.control = 0; - - -#ifndef CONTINUOUS_OPERATION - /* - * wait 5 sec for the end of current busy cycle as required - * (busy period is temporarily disabled - * - */ - for(i=0; i<5 && BUSY(pc->pcsr); i++) - taskDelay(sysClkRateGet()); - if(BUSY(pc->pcsr)){ - epvxiClose(addr, at5vxiDriverID); - return; - } -#endif - -#if defined(INIT_BINARY_OUTS) - /* - * Set AD 664 default - */ - { - struct at5vxi_setup su; - - su.gainA = TIMES2; - su.gainB = TIMES2; - su.gainC = TIMES2; - su.gainD = TIMES2; - - su.modeA = BIPOLAR; - su.modeB = BIPOLAR; - su.modeC = BIPOLAR; - su.modeD = BIPOLAR; - - su.ch2enbl = FALSE; - su.ch1enbl = FALSE; - - (* (struct at5vxi_setup *) &pc->pdd->bio[1]) = su; - } -#endif - - /* - * Init AMD 9513 for - * - * binary division - * data ptr seq enbl - * 16 bit bus - * FOUT on - * FOUT divide by 16 - * FOUT source (F1) - * Time of day disabled - */ -# define MASTER_MODE ((uint16_t)0x2000) - *PCONTROL(pc->pcsr) = BANK0; - r0 = stc_init( &pc->pdd->tcmd, - &pc->pdd->tdata, - MASTER_MODE); - if(r0!=STC_SUCCESS){ - epvxiClose(addr, at5vxiDriverID); - return; - } - - *PCONTROL(pc->pcsr) = BANK1; - r0 = stc_init( - &pc->pdd->tcmd, - &pc->pdd->tdata, - MASTER_MODE); - if(r0!=STC_SUCCESS){ - epvxiClose(addr, at5vxiDriverID); - return; - } - - for(chan=0, ptv = pc->tv; chantv); chan++, ptv++){ - unsigned int_source; - - if(chan/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pc->pcsr) = BANK1; - } - else{ - *PCONTROL(pc->pcsr) = BANK0; - } - - /* - * casting below discards volatile - * (ok in this case) - */ - r0 = stc_one_shot_read( - (unsigned *)&ptv->preset, - (uint16_t *)&ptv->iedge0_delay, - (uint16_t *)&ptv->iedge1_delay, - &pc->pdd->tcmd, - &pc->pdd->tdata, - chan, - &int_source); - if(r0 == STC_SUCCESS && int_source == FALSE) - ptv->valid = TRUE; - else - ptv->valid = FALSE; - } - -# ifndef CONTINUOUS_OPERATION - r0 = intConnect( - INUM_TO_IVEC(addr), - at5vxi_int_service, - addr); - if(r0 == ERROR) - return; - - sysIntEnable(AT5VXI_INT_LEVEL); -# endif - - /* - * init the csr - * (see at5vxi_init() for field definitions) - * interrupts enabled if not compiled for continuous operation - */ - *PCONTROL(pc->pcsr) = CSRINIT; - - model = VXIMODEL(pc->pcsr); - if(AT5VXI_VALID_MODEL(model)){ - r0 = epvxiRegisterModelName( - VXIMAKE(pc->pcsr), - model, - at5vxi_models[AT5VXI_INDEX_FROM_MODEL(model)].name); - if(r0){ - errMessage(r0,NULL); - } - - r0 = epvxiRegisterMakeName(VXI_MAKE_LANSCE5, "LANL LANSCE-5"); - if(r0){ - errMessage(r0,NULL); - } - } - - return; -} - - -/* - * - * AT5VXI_INT_SERVICE - * - * update card busy writes and notify the IO interrupt scanner - */ -void at5vxi_int_service( - int addr -) -{ - struct at5vxi_config *pconfig; - at5VxiStatus r0; - - r0 = AT5VXI_PCONFIG(addr, pconfig); - if(r0){ - epicsPrintf("AT5VXI: int before init\n"); - return; - } - - /* - * wake up the I/O event scanner - */ - scanIoRequest(pconfig->ioscanpvt); - - /* - * Update outputs while it is safe to do so - */ - if(pconfig->mdt){ - struct at5vxi_dd *pdd; - struct vxi_csr *pcsr; - unsigned chan; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - for(chan=0; chantv); chan++){ - unsigned chip_chan; - - if(!pconfig->tv[chan].mdt) - continue; - - - if(chan/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - } - else{ - *PCONTROL(pcsr) = BANK0; - } - - chip_chan = chan% - AT5VXI_CHANNELS_PER_TIMER_BANK; - - r0 = stc_one_shot( - pconfig->tv[chan].preset, - pconfig->tv[chan].iedge0_delay, - pconfig->tv[chan].iedge1_delay, - &pdd->tcmd, - &pdd->tdata, - chip_chan, - FALSE); - if(r0 != STC_SUCCESS){ - epicsPrintf("AT5 VXI- AMD9513 load fail\n"); - } - else{ - pconfig->tv[chan].valid = TRUE; - } - - /* - * reenable interrupts - */ - *PCONTROL(pcsr) = CSRINIT; - - pconfig->tv[chan].mdt = FALSE; - } - - for(chan=0; chanav); chan++){ - if(!pconfig->av[chan].mdt) - continue; - pdd->ao[chan] = pconfig->av[chan].val; - pconfig->av[chan].mdt = FALSE; - } - - if(pconfig->bv.mask){ - uint32_t work; - - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | - pdd->bio[0]); - - /* alter specified bits */ - work = (work & ~pconfig->bv.mask) | - (pconfig->bv.val & pconfig->bv.mask); - - pdd->bio[0] = work; - pdd->bio[1] = work>>(NBBY*sizeof(uint16_t)); - - pconfig->bv.mask = 0; - } - - if(BUSY(pcsr)) - logMsg( "AT5 VXI INT- finished with card busy\n", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - - pconfig->mdt = FALSE; - } - -} - - - -/* - * - * AT5VXI_ONE_SHOT - * - * setup AMD 9513 STC for a repeated two edge timing signal - */ -at5VxiStatus at5vxi_one_shot( - unsigned preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - unsigned int_source, /* (FALSE)External/(TRUE)Internal source */ - void (*event_rtn)(void *pParam),/* subroutine to run on events */ - void *event_rtn_param /* parameter to pass to above routine */ -) -{ - at5VxiStatus status; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - status = AT5VXI_PCONFIG(card, pconfig); - if(status){ - return status; - } - - pcsr = pconfig->pcsr; - -/* AT5VXI does not support internal source for now -*/ if(int_source){ - status = S_dev_badRequest; - errMessage( - status, - "AT5VXI does not support internal trigger source"); - return status; - } - -/* AT5VXI does not support interrupts on timing channels for now -*/ if(event_rtn){ - status = S_dev_badRequest; - errMessage(status, "AT5VXI does not support interrupts on timing channels"); - return status; - } - - if(channel>=AT5VXI_NTIMER_CHANNELS) - return S_dev_badSignalNumber; - -/* dont overflow unsigned short in STC -*/ if(edge0_delay >= devCreateMask(NBBY*sizeof(uint16_t))/EXT_TICKS) - return S_dev_highValue; - if(edge1_delay >= devCreateMask(NBBY*sizeof(uint16_t))/EXT_TICKS) - return S_dev_highValue; - if(edge0_delay < 0.0) - return S_dev_lowValue; - if(edge1_delay < 0.0) - return S_dev_lowValue; - - FASTLOCK(&pconfig->lock); - -# ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - if(channel/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - }else{ - *PCONTROL(pcsr) = BANK0; - } - channel = channel%AT5VXI_CHANNELS_PER_TIMER_BANK; - - status = stc_one_shot( - preset, - (uint16_t) (edge0_delay * EXT_TICKS), - (uint16_t) (edge1_delay * EXT_TICKS), - &pdd->tcmd, - &pdd->tdata, - channel, - FALSE); - - /* - * not required for now but safe - * against future mods - */ - *PCONTROL(pcsr) = CSRINIT; - } -# else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->tv[channel].preset = preset; - pconfig->tv[channel].iedge0_delay = - (edge0_delay * EXT_TICKS); - pconfig->tv[channel].iedge1_delay = - (edge1_delay * EXT_TICKS); - pconfig->tv[channel].mdt = TRUE; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; - - status = STC_SUCCESS; -# endif - - FASTUNLOCK(&pconfig->lock); - - if(status!=STC_SUCCESS){ - return status; - } - - return VXI_SUCCESS; -} - - -/* - * - * AT5VXI_ONE_SHOT_READ - * - * read back two edge timing from an AMD 9513 STC - */ -at5VxiStatus at5vxi_one_shot_read( - unsigned *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - unsigned *int_source /* (FALSE)External/(TRUE)Internal src */ -) -{ -#ifdef CONTINUOUS_OPERATION - uint16_t iedge0; - uint16_t iedge1; -#endif - at5VxiStatus status; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - status = AT5VXI_PCONFIG(card, pconfig); - if(status) - return status; - - pcsr = pconfig->pcsr; - - if(channel>=AT5VXI_NTIMER_CHANNELS) - return S_dev_badSignalNumber; - - -# ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - FASTLOCK(&pconfig->lock); - - if(channel/AT5VXI_CHANNELS_PER_TIMER_BANK){ - *PCONTROL(pcsr) = BANK1; - }else{ - *PCONTROL(pcsr) = BANK0; - } - channel = channel%AT5VXI_CHANNELS_PER_TIMER_BANK; - status = stc_one_shot_read( - preset, - &iedge0, - &iedge1, - &pdd->tcmd, - &pdd->tdata, - channel, - int_source); - /* - * not required for noe but safe - * against future mods - */ - *PCONTROL(pcsr) = CSRINIT; - FASTUNLOCK(&pconfig->lock); - - if(status==STC_SUCCESS){ - /* - * AT5VXI does not support external - * source for now - */ - if(int_source) - return S_dev_badRequest; - - *edge0_delay = iedge0 / EXT_TICKS; - *edge1_delay = iedge1 / EXT_TICKS; - } - - - return status; - } -# else - if(!pconfig->tv[channel].valid) - return S_dev_badRequest; - - FASTLOCK(&pconfig->lock); - - *preset = pconfig->tv[channel].preset; - *edge0_delay = pconfig->tv[channel].iedge0_delay - /EXT_TICKS; - *edge1_delay = pconfig->tv[channel].iedge1_delay - /EXT_TICKS; - *int_source = FALSE; - - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -# endif -} - - - -/* - * - * AT5VXI_STAT - * - * print status for a single at5 vxi card - * - * - */ -void at5vxi_stat( - unsigned card, - int level -) -{ - struct vxi_csr *pcsr; - register struct at5vxi_dd *pdd; - struct at5vxi_status status; - unsigned channel; - at5VxiStatus r0; - struct at5vxi_config *pconfig; - - static char *busy_status[] = {"","busy"}; - static char *modid_status[] = {"modid-on",""}; - static char *ipend_status[] = {"","int-pending"}; - static char *ienable_status[] = {"int-disabled","int-enabled"}; - static char *ext_st_status[] = {"extended-self-testing",""}; - static char *st_status[] = {"self-testing",""}; - static char *sfinh_status[] = {"","sys-fail-inhibit"}; - static char *sreset_status[] = {"","sys-reset"}; - static char *addr_mode_status[] = {"SC","DC"}; - - if(level==0) - return; - - r0 = AT5VXI_PCONFIG(card, pconfig); - if(r0){ - errMessage(r0,NULL); - return; - } - - pcsr = VXIBASE(card); - pdd = pconfig->pdd; - - r0 = vxMemProbe( (char *)&pcsr->dir.r.status, - READ, - sizeof(status), - (char *)&status); - if(r0 != OK) - return; - - if(VXIMAKE(pcsr) != VXI_MAKE_LANSCE5) - return; - - if(AT5VXI_VALID_MODEL(VXIMODEL(pcsr))){ - printf( "\tDrawing: %s\n", - at5vxi_models[AT5VXI_INDEX_FROM_MODEL(VXIMODEL(pcsr))].drawing); - } - - printf( - "\tcard=%d address-mode=%s %s %s %s %s ilevel=%d %s %s %s %s\n", - card, - addr_mode_status[status.dev255], - busy_status[ status.busy ], - modid_status[ status.modid_cmpl ], - ipend_status[ status.ipend ], - ienable_status[ status.ienable ], - status.ilevel, - ext_st_status[ status.ready ], - st_status[ status.passed ], - sfinh_status[ status.sfinh ], - sreset_status[ status.sreset ]); - - if(pconfig){ - if(pconfig->mdt){ - printf("\toutput update is pending for interrupt\n"); - } - } - - if(level <= 1) - return; - - for(channel=0; channelai); channel++){ - printf( - "\tAI: channel %d value %x\n", - channel, - pdd->ai[channel]); - } - - for(channel=0; channelao); channel++){ - printf( - "\tAO: channel %d value %x\n", - channel, - pdd->ao[channel]); - } - - { - uint32_t work; - - work = ((uint32_t)pdd->bio[1]) << (sizeof(uint16_t)*NBBY); - work |= pdd->bio[0]; - printf("\tBIO: value %lx\n", (unsigned long) work); - } - - for(channel=0; channeltv); channel++){ - at5vxi_report_timing(card, channel); - } - - return; -} - - -/* - * - * - * AT5VXI_REPORT_TIMING - * - * diagnostic - */ -LOCAL -at5VxiStatus at5vxi_report_timing( - unsigned card, - unsigned channel -) -{ - unsigned preset; - double edge0_delay; - double edge1_delay; - unsigned int_source; - at5VxiStatus status; - char *clk_src[] = {"external-clk", "internal-clk"}; - - status = - at5vxi_one_shot_read( - &preset, - &edge0_delay, - &edge1_delay, - card, - channel, - &int_source); - if(status == VXI_SUCCESS) - printf( - "\tTI: channel %d preset %u delay %f width %f %s\n", - channel, - preset, - edge0_delay, - edge1_delay, - clk_src[int_source?1:0]); - - return status; -} - - -/* - * - * - * AT5VXI_AI_DRIVER - * - * analog input driver - */ -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -) -{ - at5VxiStatus s; - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ai)) - return S_dev_badSignalNumber; - - *prval = pdd->ai[chan]; - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_AO_DRIVER - * - * analog output driver - */ -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -) -{ - struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ao)) - return S_dev_badSignalNumber; - -#ifdef CONTINUOUS_OPERATION - pdd->ao[chan] = *prval; - *prbval = pdd->ao[chan]; -#else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->av[chan].val = *prval; - pconfig->av[chan].mdt = TRUE; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; - - *prbval = *prval; -#endif - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_AO_READ - * - * analog output read back - */ -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -) -{ - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s){ - return s; - } - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - if(chan >= NELEMENTS(pdd->ao)) - return S_dev_badSignalNumber; - - *pval = pdd->ao[chan]; - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_BI_DRIVER - * - * binary input driver - */ -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -) -{ - register uint32_t work; - register struct at5vxi_dd *pdd; - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - pdd = pconfig->pdd; - - FASTLOCK(&pconfig->lock); - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | pdd->bio[0]); - *prval = mask & work; - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -} - - -/* - * - * - * AT5VXI_BO_DRIVER - * - * binary output driver - */ -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -) -{ -#ifdef CONTINUOUS_OPERATION - register uint32_t work; -#endif - register struct vxi_csr *pcsr; - register struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s) - return s; - - pcsr = pconfig->pcsr; - - FASTLOCK(&pconfig->lock); - -#ifdef CONTINUOUS_OPERATION - { - struct at5vxi_dd *pdd; - - pdd = pconfig->pdd; - - work = ((pdd->bio[1]<<(NBBY*sizeof(uint16_t))) | pdd->bio[0]); - - /* alter specified bits */ - work = (work & ~mask) | (val & mask); - - pdd->bio[0] = work; - pdd->bio[1] = work>>(NBBY*sizeof(uint16_t)); - } -#else - *PCONTROL(pcsr) = INTDISABLE; - pconfig->bv.val = (pconfig->bv.val & ~mask) | (val & mask); - pconfig->bv.mask |= mask; - pconfig->mdt = TRUE; - *PCONTROL(pcsr) = CSRINIT; -#endif - - FASTUNLOCK(&pconfig->lock); - - return VXI_SUCCESS; -} - - -/* - * - * at5vxi_getioscanpvt() - * - * - */ -at5VxiStatus at5vxi_getioscanpvt( -unsigned card, -IOSCANPVT *scanpvt -) -{ - struct at5vxi_config *pconfig; - at5VxiStatus s; - - s = AT5VXI_PCONFIG(card, pconfig); - if(s == VXI_SUCCESS){ - *scanpvt = pconfig->ioscanpvt; - } - return s; -} - diff --git a/src/drv/ansi/drvAt5Vxi.h b/src/drv/ansi/drvAt5Vxi.h deleted file mode 100644 index ab3b5f546..000000000 --- a/src/drv/ansi/drvAt5Vxi.h +++ /dev/null @@ -1,94 +0,0 @@ -/* base/src/drv $Id$ */ - -/* - * - * driver for at5 designed VXI modules - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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: - * ----------------- - */ - -#include - -typedef long at5VxiStatus; - -at5VxiStatus at5vxi_one_shot( - unsigned preset, /* TRUE or COMPLEMENT logic */ - double edge0_delay, /* sec */ - double edge1_delay, /* set */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - unsigned int_source, /* (FALSE)External/(TRUE)Internal source */ - void (*event_rtn)(void *pParam), /* subroutine to run on events */ - void *event_rtn_param/* parameter to pass to above routine */ -); - -at5VxiStatus at5vxi_one_shot_read( - unsigned *preset, /* TRUE or COMPLEMENT logic */ - double *edge0_delay, /* sec */ - double *edge1_delay, /* sec */ - unsigned card, /* 0 through ... */ - unsigned channel, /* 0 through channels on a card */ - unsigned *int_source /* (FALSE)External/(TRUE)Internal src */ -); - -at5VxiStatus at5vxi_ai_driver( - unsigned card, - unsigned chan, - unsigned short *prval -); - -at5VxiStatus at5vxi_ao_driver( - unsigned card, - unsigned chan, - unsigned short *prval, - unsigned short *prbval -); - -at5VxiStatus at5vxi_ao_read( - unsigned card, - unsigned chan, - unsigned short *pval -); - -at5VxiStatus at5vxi_bi_driver( - unsigned card, - unsigned long mask, - unsigned long *prval -); - -at5VxiStatus at5vxi_bo_driver( - unsigned card, - unsigned long val, - unsigned long mask -); - -at5VxiStatus at5vxi_getioscanpvt( - unsigned card, - IOSCANPVT *scanpvt -); - diff --git a/src/drv/ansi/drvCaenV265.c b/src/drv/ansi/drvCaenV265.c deleted file mode 100644 index 0603576b2..000000000 --- a/src/drv/ansi/drvCaenV265.c +++ /dev/null @@ -1,808 +0,0 @@ -/* share/src/drv @(#)drvCaenV265.c 1.1 9/2/94 */ -/* drvCaenV265.c - Driver/Device Support Routines for CAEN V265 - * - * Author: Jeff Hill (johill@lanl.gov) - * Date: 8-11-94 - * - * 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 - * MIT Bates Lab - * - * Modification Log: - * ----------------- - */ - -/* - * ANSI C Includes - */ -#include -#include -#include -#include - -/* - * vxWorks includes - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * EPICS include - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * base address, base interrupt vector, - * number of cards, & interrupt level - */ -#define CAIN_V265_A24_BASE (0x000000) -#define CAIN_V265_INTVEC_BASE (0xA0) -#define CAIN_V265_MAX_CARD_COUNT (8) -#define CAIN_V265_INT_LEVEL (6) - - - - -/* - * all device registers declared - * ANSI C volatile so we dont need to - * use the -fvolatile flag (and dont - * limit the optimizer) - */ -typedef volatile int16_t devReg; - -struct caenV265 { - devReg csr; - devReg clear; - devReg DAC; - devReg gate; - const devReg data; - const devReg pad1[(0xf8-0x8)/2]; - const devReg fixed; - const devReg identifier; - const devReg version; -}; -#define CAENV265ID 0x0812 - -/* - * Insert or extract a bit field using the standard - * masks and shifts defined below - */ -#ifdef __STDC__ -#define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S)) -#define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M)) -#else /*__STDC__*/ -#define INSERT(FIELD,VALUE)\ - (((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S)) -#define EXTRACT(FIELD,VALUE)\ - ( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M)) -#endif /*__STDC__*/ - -/* - * in the constants below _M is a right justified mask - * and _S is a shift required to right justify the field - */ - -/* - * csr register - */ -#define FD_FULL_M (0x1) -#define FD_FULL_S (14) -#define FD_READY_M (0x1) -#define FD_READY_S (15) -#define FD_BUSY_FULL_M (0x3) -#define FD_BUSY_FULL_S (14) -#define FD_IVEC_M (0xff) -#define FD_IVEC_S (0) -#define FD_ILEVEL_M (0x7) -#define FD_ILEVEL_S (8) - -/* - * series/version register - */ -#define FD_SERIES_M (0xfff) -#define FD_SERIES_S (0) -#define FD_VERSION_M (0xf) -#define FD_VERSION_S (12) - -/* - * data register - */ -#define FD_CHANNEL_M (0x7) -#define FD_CHANNEL_S (13) -#define FD_RANGE_M (1) -#define FD_RANGE_S (12) -#define FD_DATA_M (0xfff) -#define FD_DATA_S (0) - -struct channel{ - int16_t signal; - char newData; -}; - -enum adc_range {adc_12, adc_15, NUMBER_OF_ADC_RANGES}; -#define NUMBER_OF_SIGNALS 8 -#define NUMBER_OF_FIFO_ENTRIES (16*NUMBER_OF_SIGNALS*NUMBER_OF_ADC_RANGES) -LOCAL struct caenV265Config{ - struct caenV265 *pCaenV265; /* pointer to the card */ - struct channel chan[NUMBER_OF_SIGNALS][NUMBER_OF_ADC_RANGES]; - IOSCANPVT scanpvt; - WDOG_ID wdid; -}caenV265Info[CAIN_V265_MAX_CARD_COUNT]; - -#ifdef __STDC__ -#define SHOW_OFFSET(STRUCT,FIELD) \ -printf( "%s.%s is at 0x%X\n", \ - #STRUCT, \ - #FIELD, \ - offsetof(struct STRUCT, FIELD)) -#endif - -LOCAL void caenV265ISR(unsigned card); -LOCAL int caenV265Shutdown(void); -LOCAL int caenV265IdTest(struct caenV265 *pCaenV265); -int caenV265Test(unsigned card); -LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config); -LOCAL int caenV265TestVal(unsigned card, unsigned dacVal); -LOCAL int caenV265IntEnable(unsigned card); - -/* - * device support entry table - */ -LOCAL long caenV265InitRecord(struct aiRecord *pai); -LOCAL long caenV265AiRead(struct aiRecord *pai); -LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after); -LOCAL long caenV265GetIoIntInfo(int cmd, struct aiRecord *pai, IOSCANPVT *ppvt); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -} devCaenV265 ={ - 6, - NULL, - NULL, - caenV265InitRecord, - caenV265GetIoIntInfo, - caenV265AiRead, - caenV265SpecialLinconv}; - -/* - * driver support entry table - */ -LOCAL long caenV265Init(void); -LOCAL long caenV265IOReport(int level); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvCaenV265 ={ - 2, - caenV265IOReport, - caenV265Init}; - - - -/* - * verify that register - * offsets match the doc. - */ -#ifdef DEBUG -void offsettest() -{ - SHOW_OFFSET(caenV265, version); - SHOW_OFFSET(caenV265, identifier); - SHOW_OFFSET(caenV265, fixed); - SHOW_OFFSET(caenV265, data); - SHOW_OFFSET(caenV265, gate); - SHOW_OFFSET(caenV265, DAC); - SHOW_OFFSET(caenV265, clear); - SHOW_OFFSET(caenV265, csr); - - return; -} -#endif - - -/* - * caenV265InitRecord() - */ -LOCAL long caenV265InitRecord(struct aiRecord *pai) -{ - struct vmeio *pvmeio; - - /* ai.inp must be an VME_IO */ - switch (pai->inp.type) { - case (VME_IO): - break; - default : - recGblRecordError(S_db_badField,(void *)pai, - "devAiXy566Se (init_record) Illegal INP field"); - return(S_db_badField); - } - - pvmeio = (struct vmeio *)&(pai->inp.value); - - /* - * check for bad signal or card number - */ - if ( pvmeio->signal >= NUMBER_OF_SIGNALS || - pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) { - - recGblRecordError( - S_db_badField, - (void *)pai, - "devCaenV265 bad card or signal number"); - return -1; - } - - if(!caenV265Info[pvmeio->card].pCaenV265){ - recGblRecordError( - S_db_badField, - (void *)pai, - "devCaenV265 card does not exist"); - return -1; - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M; - - return(0); -} - - -/* - * caenV265AiRead() - */ -LOCAL long caenV265AiRead(struct aiRecord *pai) -{ - int16_t value; - struct vmeio *pvmeio; - - pvmeio = (struct vmeio *)&(pai->inp.value); - - /* - * check for bad signal or card number - */ - if ( pvmeio->signal >= NUMBER_OF_SIGNALS || - pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) { - - recGblSetSevr(pai, READ_ALARM, INVALID_ALARM); - return -1; - } - - /* - * uninitialized data? - */ - if (!caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].newData) { - recGblSetSevr(pai, READ_ALARM, INVALID_ALARM); - return -1; - } - - value = caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].signal; - pai->rval = value; - - return 0; -} - - -/* - * caenV265SpecialLinconv() - */ -LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after) -{ - if(!after) { - return 0; - } - - /* set linear conversion slope*/ - pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M; - return 0; -} - - -/* - * caenV265GetIoIntInfo() - */ -LOCAL long caenV265GetIoIntInfo( -int cmd, -struct aiRecord *pai, -IOSCANPVT *ppvt) -{ - struct vmeio *pvmeio; - - pvmeio = (struct vmeio *)&(pai->inp.value); - - /* - * check for bad card number - */ - if ( pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) { - epicsPrintf ( - "%s.%d:devCaenV265 bad card number %d %s\n", - (int)__FILE__, - __LINE__, - pvmeio->card, - (int)pai->name); - recGblRecordError( - S_db_badField, - (void *)pai, - "devCaenV265 bad card number"); - return -1; - } - - *ppvt = caenV265Info[pvmeio->card].scanpvt; - - return 0; -} - - -/* - * caenV265Init() - */ -LOCAL long caenV265Init(void) -{ - unsigned card; - struct caenV265 *pCaenV265; - int status; - - status = rebootHookAdd(caenV265Shutdown); - if(status){ - errMessage(S_dev_internal,"reboot hook add failed"); - return ERROR; - } - - status = sysBusToLocalAdrs( - VME_AM_STD_SUP_DATA, - CAIN_V265_A24_BASE, - (char **)&pCaenV265); - if(status!=OK){ - errPrintf( - S_dev_badA24, - __FILE__, - __LINE__, - "caenV265Init"); - return ERROR; - } - - for(card=0; cardclear = 0; /* any rw op resets the device */ - pCaenV265->DAC = 0; /* set test-signal "offset" to zero */ - - /* - * attach ISR - */ - vec = CAIN_V265_INTVEC_BASE+card; - status = intConnect( - INUM_TO_IVEC(vec), - caenV265ISR, - card); - assert(status>=0); - - /* - * Enable interrupts - */ - caenV265IntEnable(card); - } - status = sysIntEnable(CAIN_V265_INT_LEVEL); - assert(status>=0); - - return OK; -} - - -/* - * caenV265ISR() - */ -LOCAL void caenV265ISR(unsigned card) -{ - struct caenV265Config *pCaenV256Config = &caenV265Info[card]; - struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265; - unsigned signal; - int16_t csr; - static unsigned ticks; - unsigned newTicks; - - /* - * If its full then its more efficient - * to read it out without checking - * in between each read - */ - csr = pCaenV265->csr; - if (EXTRACT(FULL,csr)) { - for( signal=0; - signalcsr; - } - - /* - * limit the EPICS scan rate - */ - newTicks = tickGet(); - if(newTicks == ticks){ - /* - * Disable Interrupts - */ - pCaenV265->csr = 0; - - /* - * start a watch dog after one tick - * so that we limit the int rate to - * the system tick rate. - */ - wdStart(pCaenV256Config->wdid, - 1, - caenV265IntEnable, - card); - - return; - } - else{ - ticks = newTicks; - } - - /* - * tell EPICS to scan on int - */ - scanIoRequest(caenV265Info[card].scanpvt); - - return; -} - - -/* - * caenV265IntEnable - */ -LOCAL int caenV265IntEnable(unsigned card) -{ - struct caenV265Config *pCaenV256Config = &caenV265Info[card]; - struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265; - unsigned vec; - int16_t newcsr; - - - vec = CAIN_V265_INTVEC_BASE+card; - newcsr = INSERT(IVEC, vec) | INSERT(ILEVEL, CAIN_V265_INT_LEVEL); - pCaenV265->csr = newcsr; - - return OK; -} - - -/* - * caenV265ReadData() - */ -LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config) -{ - struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265; - int16_t val = pCaenV265->data; - int16_t data = EXTRACT(DATA, val); - unsigned range = EXTRACT(RANGE, val); - unsigned signal = EXTRACT(CHANNEL, val); - - if(range>=NUMBER_OF_ADC_RANGES){ - epicsPrintf ("caenV265ReadData: bad range number\n"); - return; - } - if(signal>=NUMBER_OF_SIGNALS){ - epicsPrintf ("caenV265ReadData: bad signal number\n"); - return; - } - pCaenV256Config->chan[signal][range].signal=data; - pCaenV256Config->chan[signal][range].newData=TRUE; - - return; -} - - -/* - * caenV265IdTest() - */ -LOCAL int caenV265IdTest(struct caenV265 *pCaenV265) -{ - int status; - int16_t id; - - /* - * Is a card present - */ - status = vxMemProbe( - (char *)&pCaenV265->identifier, - READ, - sizeof(id), - (char *)&id); - if(status!=OK){ - return FALSE; - } - - /* - * Is the correct type of card present - */ - if(id!=CAENV265ID){ - errPrintf( - S_dev_wrongDevice, - __FILE__, - __LINE__, - "caenV265IdTest"); - return FALSE; - } - return TRUE; -} - - -/* - * caenV265Shutdown() - * turns off interrupts so that dont foul up the boot - */ -LOCAL int caenV265Shutdown(void) -{ - struct caenV265 *pCaenV265; - unsigned card; - - for(card=0; cardcsr=0; - } - } - return OK; -} - - -/* - * caenV265Test() - */ -int caenV265Test(unsigned card) -{ - unsigned dacVal; - struct caenV265Config cofigCpy; - unsigned range; - unsigned signal; - - - dacVal=0; - caenV265TestVal(card, dacVal); - while(dacValpCaenV265; - unsigned signal; - - if(!pCaenV265){ - return ERROR; - } - - if(!caenV265IdTest(pCaenV265)){ - return ERROR; - } - - /* - * clear the module - */ - pCaenV265->clear=0; - - /* - * generate a test signal - */ - pCaenV265->DAC=dacVal; - - /* - * generate a test gate - */ - for( signal=0; - signalgate=0; - taskDelay(1); - } - while(!caenV265Info[card].chan[signal][adc_12].newData){ - pCaenV265->gate=0; - taskDelay(1); - } - } - - /* - * turn off test signal - */ - pCaenV265->clear=0; - pCaenV265->DAC=0; - - return OK; -} - - -/* - * caenV265IOReport() - */ -LOCAL long caenV265IOReport(int level) -{ - struct caenV265 *pCaenV265; - unsigned card; - unsigned signal; - unsigned range; - char *pVersion[] = {"NIM","ECL"}; - char *pState[] = { - "FIFO empty", - "FIFO full", - "FIFO partially filled", - "FIFO full"}; - - for (card=0; cardversion)]); - printf("\tseries = %d\n", - EXTRACT(SERIES, pCaenV265->version)); - printf("\tstate = %s\n", - pState[EXTRACT(BUSY_FULL,pCaenV265->csr)]); - printf("\tint level = %d\n", - EXTRACT(ILEVEL,pCaenV265->csr)); - printf("\tint vec = 0x%02X\n", - EXTRACT(IVEC,pCaenV265->csr)); - printf( "\tbase addr= 0x%X on the %s\n", - (unsigned)caenV265Info[card].pCaenV265, - sysModel()); - - for( range=0; - range\n", - signal); - } - } - - } - } - return OK; -} diff --git a/src/drv/ansi/drvEpvxi.3 b/src/drv/ansi/drvEpvxi.3 deleted file mode 100644 index 1f2c40902..000000000 --- a/src/drv/ansi/drvEpvxi.3 +++ /dev/null @@ -1,766 +0,0 @@ -.TH epvxiMsgLib 1 "" "EPICS Reference Manual" -.ad b -.SH VERSION @(#)drvEpvxi.nr 1.9 8/13/93 -.SH NAME -epvxiMsgLib.c - the VXI message based device interface library -.SH SYNOPSIS -.nf - -epvxiCmd - deliver a command to a message based device -epvxiQuery - fetch a response from a message based device -epvxiCmdQuery - send a command and fetch a response -epvxiRead - read a string of bytes from a device -epvxiWrite - write a string of bytes to a device -epvxiSetTimeout - change the message based transfer timeout -epvxiSetTraceEnable - turn trace mode on or off - -int epvxiCmd (la, command) -int epvxiQuery (la, presponse) -int epvxiCmdQuery (la, command, presponse) -int epvxiRead (la, pbuffer, count, pactual_count, option) -int epvxiWrite (la, pbuffer, pcount, pactual_count, option) -int epvxiSetTimeout (la, timeout) -int epvxiSetTraceEnable(la, enable) - - -.fi -.SH DESCRIPTION -This library provides a vendor independent interface to VXI message -based devices. Device drivers which use this library may optionally -open devices accessed by this library using epvxiOpen() prior to use. -Opening a device prevents other drivers from using it. -.SH RETURNS -.nf -less than zero- operation failed -greater than zero- operation successful - -#define VXI_SUCCESS 0 /* successful completion */ -#define VXI_NO_DEVICE (-1) /* device does not exist */ -#define VXI_NOT_SLOT0 (-2) /* not a slot zero device */ -#define VXI_UKN_DEVICE (-3) /* device not supported */ -#define VXI_BAD_TRIGGER (-4) /* no such trigger */ -#define VXI_BAD_TRIG_IO (-5) /* no such trigger io */ -#define VXI_DEVICE_OPEN (-6) /* device already open */ -#define VXI_NOT_OWNER (-7) /* dev in use by another drv */ -#define VXI_NO_MEMORY (-8) /* failed to allocate memory */ -#define VXI_NOT_OPEN (-9) /* device not open */ -#define VXI_NOT_MSG_DEVICE (-10) /* must be a message based dev */ -#define VXI_MSG_DEVICE_TMO (-11) /* message based dev timed out */ -#define VXI_MSG_DEVICE_FAILURE (-12) /* message based dev failed */ -#define VXI_BAD_LA (-13) /* logical addr out of range */ -#define VXI_MULTIPLE_QUERIES (-14) /* serial protocol error */ -#define VXI_UNSUPPORTED_CMD (-15) /* serial protocol error */ -#define VXI_DIR_VIOLATION (-16) /* serial protocol error */ -#define VXI_DOR_VIOLATION (-17) /* serial protocol error */ -#define VXI_RR_VIOLATION (-18) /* serial protocol error */ -#define VXI_WR_VIOLATION (-19) /* serial protocol error */ -#define VXI_ERR_FETCH_FAIL (-20) /* ukn serial protocol error */ -#define VXI_SELF_TEST_FAILED (-21) /* self test failed */ - -.SH INCLUDES -epvxiLib.h -.fi - - -.TH epvxiCmd 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiCmd - deliver a command to a message based device -.SH SYNOPSIS -.CS -.nf -#include -int epvxiCmd (la, command) - unsigned la; /* logical address */ - unsigned long command; /* command */ -.fi -.CE -.SH DESCRIPTION -Delivers a command to a message based device. - -.SH RETURNS -See epvxiMsgLib(1) for a description of the return codes from this library. -.SH SEE ALSO -epvxiMsgLib(1), epvxiLib(1) - -.TH epvxiQuery 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiQuery - fetch a response from a message based device -.SH SYNOPSIS -.CS -.nf -#include -int epvxiQuery (la, presponse) - unsigned la; /* logical address */ - unsigned long *presponse; /* response pointer */ -.fi -.CE -.SH DESCRIPTION -Fetch a response from a message based device. - -.SH RETURNS -See epvxiMsgLib(1) for a description of the returns from this library. -.SH SEE ALSO -epvxiMsgLib(1), epvxiLib(1) - -.TH epvxiCmdQuery 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiCmdQuery - send a command and fetch a response from a message based device -.SH SYNOPSIS -.CS -.nf -#include -int epvxiCmdQuery (la, command, presponse) - unsigned la; /* logical address */ - unsigned long command; /* command */ - unsigned long *presponse; /* response pointer */ -.fi -.CE -.SH DESCRIPTION -Send a command and fetch a response from a message based device. - -.SH RETURNS -See epvxiMsgLib(1) for a description of the return codes from this library. -.SH SEE ALSO -epvxiMsgLib(1), epvxiLib(1) - -.TH epvxiRead 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiRead - read a string of bytes from a device -.SH SYNOPSIS -.CS -.nf -#include -int epvxiRead ( - unsigned la, /* logical address */ - char *pbuffer, /* pointer to supplied buffer */ - unsigned long count, /* number of bytes to read */ - unsigned long *pactual_count, /* number of bytes read */ - unsigned long option /* read options */ -) -.fi -.CE -.SH DESCRIPTION -Read a string of bytes from a message based device using the -byte transfer protocol. Copy bytes into the supplied buffer -until the end of string terminator is received from the device -or the end of the buffer is reached as determined by the supplied -count. Returns the number of bytes read in *pactual_count. -The options argument is a mask with each bit potentially -representing a different option. If you need to specify more -than one option then you must bit or together the option -constants which apply. Currently, no read options are supported. -The option argument should be set to epvxiReadOptNone. - -.nf -Option Bit Mask Purpose ---------------- ------- -epvxiReadOptNon no options -.fi - -.SH RETURNS -See epvxiMsgLib(1) for a description of the return codes from this library. -.SH SEE ALSO -epvxiMsgLib(1), epvxiLib(1) - - -.TH epvxiWrite 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiWrite - write a string of bytes to a device -.SH SYNOPSIS -.CS -.nf -#include -int epvxiWrite ( - unsigned la, /* logical address */ - char *pbuffer, /* pointer to supplied buffer */ - unsigned long count, /* number of bytes to write */ - unsigned long *pactual_count, /* number of bytes written */ - unsigned long option /* write options */ -) -.fi -.CE -.SH DESCRIPTION -Write a string of bytes to a message based device using the -byte transfer protocol. Copy count bytes from the supplied buffer -to the device. Returns the number of bytes written in *pactual_count. -The options argument is a mask with each bit potentially -representing a different option. If you need to specify more -than one option then you must bit or together the option -constants which apply. Or in the constant epvxiWriteOptPartialMsg -if the string sent is part of a larger message and it is -not the last segment of the larger message. - -.nf -Option Bit Mask Purpose ---------------- ------- -epvxiWriteOptNone no options -epvxiWriteOptPartialMsg message continues after this transfer -.fi - -.SH RETURNS -See epvxiMsgLib(1) for an description of the return codes from this library. -.SH SEE ALSO -epvxiMsgLib(1), epvxiLib(1) - - -.TH epvxiSetTimeout 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiSetTimeout - change the message based transfer timeout -.SH SYNOPSIS -.CS -.nf -#include -int epvxiSetTimeout (la, timeout) - unsigned la; /* logical address */ - unsigned long timeout; /* milli-seconds prior to timeout */ -.fi -.CE -.SH DESCRIPTION -Set the delay prior to timeout for each portion of a message based -VXI transfer. The default timeout is 10 seconds. - -.SH RETURNS -See epvxiMsgLib(1) for a description of the return codes from this library. -.SH SEE ALSO -epvxiMsgLib(1), epvxiLib(1) - - -.TH epvxiSetTraceEnable 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiSetTraceEnable - set trace mode on or off -.SH SYNOPSIS -.CS -.nf -#include -int epvxiSetTraceEnable(la, enable) - unsigned la; /* logical address */ - int enable; /* T=trace on, F=trace off */ -.fi -.CE -.SH DESCRIPTION -Set trace mode on or off. If "enable" is true then trace mode is enabled. -If "enable" is false then trace mode is turned off. Trace mode is enable -for each VXI message based device independently. - -.SH RETURNS -See epvxiMsgLib(1) for a description of the return codes from this library. -.SH SEE ALSO -epvxiMsgLib(1), epvxiLib(1) - - - -.TH epvxiLib 1 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiLib.c - the VXI driver support library -.SH SYNOPSIS -.nf - -epvxiLookupLA - find all devices matching a pattern -epvxiUniqueDriverID - return a non zero unique identification for a VXI driver -epvxiOpen - open a VXI device -epvxiClose - close a VXI device -epvxiPConfig - MACRO which returns a pointer to the drivers private structure -epvxiFetchPConfig - similar to epvxiPConfig but with status -epvxiRouteTriggerECL - route an ECL trigger to/from the front panel -epvxiRouteTriggerTTL - route an TTL trigger to/from the front panel -epvxiResman - perform VXI resource management and setup the MXI bus -epvxiDeviceList - list which drivers own which devices -epvxiCrateList - list all slot zero devices -epvxiExtenderList - list all extender devices and there windows -epvxiIOReport - list all VXI hardware in the system - - -int epvxiLookupLA(pmatch_structure, pcallback, pargument) -int epvxiUniqueDriverID() -int epvxiOpen(la, driverID, structure_size, pioReportFunction) -int epvxiClose(la, driverID) -( *) epvxiPConfig(la, driverID, ) -int epvxiFetchPConfig(la, driverID, pConfig) -int epvxiRouteTriggerECL (la, trigger, io) -int epvxiRouteTriggerTTL(la, trigger, io) -int epvxiResman() -int epvxiDeviceList() -int epvxiCrateList() -int epvxiExtenderList() -int epvxiIOReport(level) -.fi - -This is the structure used to specify search patterns for epvxiLookupLA(). -Set a bit in the flags member for each item that is to be a -constraint on the search. All other items are ignored during -the search. The call back routine will be called for all devices -which exactly match all items specified in the flags field - -.nf -#define VXI_DSP_make (1<<0) -#define VXI_DSP_model (1<<1) -#define VXI_DSP_class (1<<2) -#define VXI_DSP_slot (1<<3) -#define VXI_DSP_slot_zero_la (1<<4) -#define VXI_DSP_commander_la (1<<5) -#define VXI_DSP_extender_la (1<<6) /* id crates that have one */ - -typedef struct { - long flags; /* one bit enabling each field */ - unsigned short make; /* manufacture identification */ - unsigned short model; /* model code for the device */ - unsigned short class; /* VXI device class */ - unsigned char slot; /* slot where the device resides */ - unsigned char slot_zero_la; /* logical address of slot 0 device */ - unsigned char commander_la /* logical address of commander */ - unsigned char extender_la /* logical address of bus repeater */ -}epvxiDeviceSearchPattern; -.fi - -.SH DESCRIPTION -.nf -Low level support needed if you are writing a VXI driver: -* Determine the logical address of all devices in a particular slot -* Determine the logical address of all devices of a particular make or model -* Prevent two drivers from accessing the same card -* Prevent a driver from accessing a nonexistent card -* Return a pointer to the driver's private variables given a logical address -* Device independent front panel trigger routing on the slot zero device -.fi - -The message based device interface library epvxiMsgLib(1) is -an example of a VXI driver which utilizes this core VXI driver support. - -.SH INCLUDES -epvxiLib.h - -.SH RETURNS -.nf -less than zero- operation failed -greater than zero- operation successful - -#define VXI_SUCCESS 0 /* successful completion */ -#define VXI_NO_DEVICE (-1) /* device does not exist */ -#define VXI_NOT_SLOT0 (-2) /* not a slot zero device */ -#define VXI_UKN_DEVICE (-3) /* device not supported */ -#define VXI_BAD_TRIGGER (-4) /* no such trigger */ -#define VXI_BAD_TRIG_IO (-5) /* no such trigger io */ -#define VXI_DEVICE_OPEN (-6) /* device already open */ -#define VXI_NOT_OWNER (-7) /* dev in use by another drv */ -#define VXI_NO_MEMORY (-8) /* failed to allocate memory */ -#define VXI_NOT_OPEN (-9) /* device not open */ -#define VXI_NOT_MSG_DEVICE (-10) /* must be a message based dev */ -#define VXI_MSG_DEVICE_TMO (-11) /* message based dev timed out */ -#define VXI_MSG_DEVICE_FAILURE (-12) /* message based dev failed */ -#define VXI_BAD_LA (-13) /* logical addr out of range */ -#define VXI_MULTIPLE_QUERIES (-14) /* serial protocol error */ -#define VXI_UNSUPPORTED_CMD (-15) /* serial protocol error */ -#define VXI_DIR_VIOLATION (-16) /* serial protocol error */ -#define VXI_DOR_VIOLATION (-17) /* serial protocol error */ -#define VXI_RR_VIOLATION (-18) /* serial protocol error */ -#define VXI_WR_VIOLATION (-19) /* serial protocol error */ -#define VXI_ERR_FETCH_FAIL (-20) /* ukn serial protocol error */ -#define VXI_SELF_TEST_FAILED (-21) /* self test failed */ -#define VXI_TIMEOUT_TO_LARGE (-22) /* supplied timeout to long */ -#define VXI_PROTOCOL_ERROR (-23) /* protocol error */ - - - -.fi -.SH SEE ALSO -epvxiMsgLib(1) - -.TH epvxiLookupLA 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiLookupLA - find all of the devices matching a search pattern -.SH SYNOPSIS -.CS -.nf -#include -int epvxiLookupLA(pmatch_structure, pcallback, pargument) -epvxiDeviceSearchPattern *pmatch_structure; -void (*pcallback)(); -void *pargument; - -/* - * your call back - */ -void callback(la, pargument) -unsigned la; -void *pargument; -{ -} - -.fi -.CE -.SH DESCRIPTION - -Find all devices in the system matching the search pattern and call -the specified call back for each of them. The search pattern is specified -by filling fields in the structure epvxiDeviceSearchPattern and -setting the flags field of the same structure to match. For example: - -.nf -epvxiDeviceSearchPattern dsp; -dsp.make = VXI_MAKE_HP; -dsp.model = 0xffc; -dsp.flags = VXI_DSP_make | VXI_DSP_model; -epvxiLookupLA(&dsp, pcallback, pargument); -.fi - -A list of these constants can be found in epvxiLib.h and -device make codes can be found in epvxi.h - -This is the structure used to specify search patterns for epvxiLookupLA(). -Set a bit in the flags member for each item that is to be a -constraint on the search. All other items are ignored during -the search. The call back routine will be called for all devices -which exactly match all items specified in the flags field - -.nf -#define VXI_DSP_make (1<<0) -#define VXI_DSP_model (1<<1) -#define VXI_DSP_class (1<<2) -#define VXI_DSP_slot (1<<3) -#define VXI_DSP_slot_zero_la (1<<4) -#define VXI_DSP_commander_la (1<<5) - -typedef struct { - long flags; /* one bit enabling each field */ - unsigned short make; /* manufacture identification */ - unsigned short model; /* model code for the device */ - unsigned short class; /* VXI device class */ - unsigned char slot; /* slot where the device resides */ - unsigned char slot_zero_la; /* logical address of slot 0 device */ - unsigned char commander_la /* logical address of commander */ -}epvxiDeviceSearchPattern; -.fi - -.SH RETURNS -Returns a non zero unique constant to be used as a driver identification. - -.SH SEE ALSO -epvxiLib(1), - -.TH epvxiUniqueDriverID 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiUniqueDriverID - return a non zero unique identification for a VXI driver -.SH SYNOPSIS -.CS -.nf -#include -int epvxiUniqueDriverID () - -.fi -.CE -.SH DESCRIPTION - -Should be called once only -by each type of VXI driver to uniquely identify itself. The routines -in epvxiDrvLib.c use this constant to prevent a VXI device from being -accessed by the wrong driver. - -.SH RETURNS - -.SH SEE ALSO -epvxiLib(1), - -.TH epvxiOpen 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiOpen - open a VXI device for a VXI driver -.SH SYNOPSIS -.CS -.nf -#include -int epvxiOpen (la, epvxiDriverID, structureSize, pio_report_func) - unsigned la; - int epvxiDriverID; - unsigned long structureSize; - void (*pio_report_func)(); - -void pio_report_func(la, level) -unsigned la; -int level; -{ -} - -.fi -.CE -.SH DESCRIPTION - -Records this driver as the owner of the device at the specified logical -address la and verifies that the device has passed it's self test. -Allocates memory of size structureSize and saves a -pointer to this memory with the logical address for future use by the -driver with identification epvxiDriverID for its private configuration. -Installs call back routine pio_report_func as an io report function to -be called each time the user requests the status -of VXI devices. This routine is called with the logical address -and an integer specifying the detail level of the report -as the first and second arguments respectively. -The macro epvxiFetchPConfig returns a pointer to this block if the -specified device has been opened by the specified driver. - -.SH RETURNS - -.SH SEE ALSO -epvxiUniqueDriverID() -epvxiFetchPConfig() -epvxiLib(1), - -.TH epvxiClose 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiClose - close a VXI device for a VXI driver -.SH SYNOPSIS -.CS -.nf -#include -int epvxiClose (la, vxiDriverID) - unsigned la; - int vxiDriverID; -.fi -.CE -.SH DESCRIPTION - -Releases driver ownership of the device at the specified logical -address la. Deallocates memory in use for the driver's private -configuration. - -.SH RETURNS - -.SH SEE ALSO -epvxiLib(1), - - -.TH epvxiFetchPConfig 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiFetchPConfig - macro which loads a pointer to the drivers private structure -.SH SYNOPSIS -.CS -.nf -#include -int evxiFetchPConfig (la, vxiDriverID, pConfig) -unsigned la; -int vxiDriverID; -stuct XXXXXX *pConfig; - -.fi -.CE -.SH DESCRIPTION - -epvxiFetchPConfig() is a MACRO which loads a pointer to the devices -private configuration block (ie pConfig above). This macro -replaces the macro epvxiPConfig() which didnt return status. - -This routine performs two functions: -.nf -1) Loads a pointer to the device's configuration block. -2) Informs your driver if the specified device does not exist or has - been opened by another driver. -.fi - -.SH RETURNS -.SH SEE ALSO -epvxiLib(1), - - - - -.TH epvxiRouteTriggerECL 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiRouteTriggerECL - route an ECL trigger to/from the front panel -of a supported VXI device -.SH SYNOPSIS -.CS -.nf -#include -int epvxiRouteTriggerECL (la, trigger, io) - unsigned la; /* 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 */ - -.fi -.CE -.SH DESCRIPTION -Route a VXI backplane trigger to or from the front panel of a slot zero -device. -The bits in argument enable_map correspond to an enable for triggers -0-5 (1 enables the trigger and 0 disables the trigger). The bits -in argument io_map set the direction for triggers 0-5 (1 sources -the front panel and 0 sources the backplane). - -Most VXI slot zero devices have one trigger output and one trigger input -connector. The trigger input connector can drive multiple VXI backplane -triggers. The trigger output connector should be driven by only one of -the backplane triggers at a time. - -.SH RETURNS -.SH SEE ALSO -epvxiLib(1), - - -.TH epvxiRouteTriggerTTL 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiRouteTriggerTTL - route an TTL trigger to/from the front panel -of a supported VXI device -.SH SYNOPSIS -.CS -.nf -#include -int epvxiRouteTriggerTTL (la, trigger, io) - unsigned la; /* 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 */ - -.fi -.CE -.SH DESCRIPTION - -Route a VXI backplane trigger to or from the front panel of a slot zero -device. -The bits in argument enable_map correspond to an enable for triggers -0-5 (1 enables the trigger and 0 disables the trigger). The bits -in argument io_map set the direction for triggers 0-5 (1 sources -the front panel and 0 sources the backplane). - -Most VXI slot zero devices have one trigger output and one trigger input -connector. The trigger input connector can drive multiple VXI backplane -triggers. The trigger output connector should be driven by only one of -the backplane triggers at a time. - -.SH RETURNS -.SH SEE ALSO -epvxiLib(1), - - - - -.TH epvxiResman 2 "" "EPICS Reference Manual" -.ad b -.SH NAME -epvxiResman - perform VXI resource management and MXI bus setup -.SH SYNOPSIS -.CS -.nf -#include -int epvxiResman () - -.fi -.CE -.nf - MXI bus background information - -o A MXI bus extender facilitates bus communication between - a VME bus master and a VME bus slave that are installed - in different crates. MXI bus extenders can be joined - together in a hierarchy interconnected by the MXI bus. - -o A MXI bus extender's LA window determines the VXI LA range - over which local VME bus master initiated requests are - extended onto the MXI bus. - -o A MXI bus extender's LA window also determines the MXI - LA range over which MXI extended bus master requests - are allowed to be further extended into the local VXI bus. - -o MXI bus extenders are always SC devices. A MXI bus - extenders are always accessible from the MXI bus - invariant of the location of its LA window. - Conclusion: the LA of a MXI does not constrain the - location of its LA window. - -o Each MXI's LA window must be large enough to contain all - of the MXI bus extender LA windows beneath it in the - hierarchy. A MXI's LA window may not overlap the windows of - any other MXI'at the same level in the hierarchy. - -o SC devices within one crate must be within a block - which does not overlap the LA windows of other - MXI bus extenders at the same level in the - hierarchy. Likewise SC devices within one crate - must not overlap the LA windows of MXI bus - extenders at a lower level in the hierarchy. - - - EPICS VXI resource manager background information - -o The EPICS VXI resource manager will always successfully - allocate all DC devices in a DC MXI bus system if - the available LA address range is large enough and - if all devices other than the resource manager and - the MXIs are DC. - -o Otherwise if some of the devices in the system - (other than the MXIs and the resource manager) are - SC then the burden is placed on the project - engineer to guarantee that SC devices are located - such that nonoverlapping MXI LA windows can - be allocated by the resource manager. Additionally - the project engineer must locate the SC devices - so that there is sufficient space to allocate the LAs - of DC devices into nonoverlapping MXI LA windows. - If the project engineer locates SC devices - correctly the resource manager will always find the - corresponding window hierarchy that provides - access to all devices. If the project engineer - improperly locates SC devices the resource manager - will detect it and print a message. - -o The CPU running the EPICS VXI resource manager is at the - root of the MXI hierarchy. - -o The resource manager will never allocate a DC device - at a LA overlapping an interrupt vector already - allocated to another device (use "veclist()" to - determine what vectors are in use). - - - - Resource manager DC device allocation rules - -o When DC devices are allocated they will be placed between - existing SC devices (in the same extender) first. - Next they will be placed after existing DC devices - (in the same extender). If there isn't room above existing - DC devices then the resource manager will attempt to - allocate DC device beneath the existing SC devices. - If devices in other extenders (the limits of other windows) - bracket the upper and lower limits of an extender's - window there may not be enough space to allocate - all of the DC devices present in a crate. - If so, a warning message will be printed and the DC - device will not be allocated a valid LA. - -o If the only SC device in a crate is the MXI granting access - to the crate then the resource manager will be free to place - any DC devices found in a contiguous block where there is room. - The resource manager requires block allocation because the MXI - address window must contain only the DC device LA assignments - for the current crate. This contiguous block will be placed - at the highest open LA block available. If a contiguous block - of sufficient size is not found then none of the DC devices will - be allocated (assigned) valid LAs and a warning message - will be printed. This block will not be anchored in any way - to the SC LA of the extender that provides access to the - DC devices in the crate. - - -.fi diff --git a/src/drv/ansi/drvEpvxi.c b/src/drv/ansi/drvEpvxi.c deleted file mode 100644 index f8d90dadc..000000000 --- a/src/drv/ansi/drvEpvxi.c +++ /dev/null @@ -1,4567 +0,0 @@ -/* - * drvEpvxi.c - * - * base/src/drv $Id$ - * Routines for the VXI device support and resource management. - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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 02-14-90 formal release - * .02 joh 04-04-90 as requested KLUDGED dynamic address so they - * dont have to specify model number in DCT - * .03 joh 04-04-90 as requested KLUDGED dynamic address so they - * dont have to specify model number in DCT - * .04 joh 07-26-90 changed from ttl trig 7 to ecl trig 0 - * .05 joh 07-27-90 added support for multiple slot0 cards - * .06 joh 08-08-91 delinting - * .07 joh 09-05-91 converted to v5 vxWorks - * .08 joh 12-05-91 split vxi_driver.c into vxi_driver.c and - * vxi_resman.c - * .09 joh 01-29-91 added MXI support & removed KLUDGE - * .10 joh 07-06-92 added A24 & A32 address config - * .11 joh 07-07-92 added routine to return A24 or A32 base - * .12 joh 07-13-92 merged in model hash support written by - * Richard Baker (summer intern) - * .13 joh 07-21-92 Now stores extender info in a hierarchical - * linked list - * .14 joh 07-29-92 vxi record topology needed check for - * device present - * .15 joh 07-29-92 added sccs id - * .16 joh 08-19-92 make name registration - * .17 joh 08-21-92 cleaned up A24/A32 MXI setup - * .18 joh 08-26-92 dont return error if a make or model - * has already been registered - * .19 joh 09-03-92 Use the correct routine in NIVXI - * for CPU030 trigger routing - * .20 joh 09-30-92 split epvxiOpen() into epvxiOpen() and - * epvxiDeviceVerify() - * .21 joh 10-30-92 NI CPU030 trigger routing was failing - * due to no entry for the 030 in the resman - * tables - it cant see itself in A16. - * A work around was installed. - * .22 joh 05-24-93 Fixed over-zealous parameter checks in - * TTL trigger route - * .23 joh 06-03-93 Fixed incorrect MXI BP TTL trigger enable - * .24 joh 07-12-93 Record the task id when opening a device - * .25 joh 07-21-93 Improved DC device allocation in MXI - * environment - * .26 joh 11-10-93 Now configures multiple DC devices per slot. - * Blocked address devices are preallocated - * where possible. Independently addressed - * multiple devices per slot are allocated on - * demand. - * .27 joh 02-06-95 Force natural alignment of blocked address - * DC devices. - * - * RM unfinished items - * ------------------- - * 1. Assigning the cmdr/serv hierarchy from within a DC res man - * needs to be revisited - * 2. Should this module prevent two triggers from driving - * the same front panel connector at once? - * - * - * NOTES - * ----- - * - * - */ - -/* - * Code Portions - * - * local - * vxi_find_slot given a VXI modules addr find its slot - * vxi_init_ignore_list init list of interrupt handlers to ignore - * vxi_configure_hierarchies setup commander servant hierarchies - * vxi_self_test test for dev self test passed - * open_slot0_device open slot zero devices - * nicpu030_init NI CPU030 controller setup - * nivxi_cpu030_set_modid set modid on the NICPU030 - * nivxi_cpu030_clr_all_modid clear all modid lines on the NICPU030 - * set_reg_modid set modid on a reg based slot0 device - * clr_all_reg_modid clr all modid on a reg based slot0 dev - * vxi_find_sc_devices find all SC devices and open them - * vxi_find_dc_devices find all DC devices and open them - * vxi_count_dc_devices determine the number of DC devices in - * this extender - * vxi_init_ignore_list find addresses of default int handlers - * mxi_map mat the addresses on a MXI bus extender - * vxi_find_mxi_devices search for and open mxi bus repeaters - * map_mxi_inward map from a VXI crate towards the RM - * vxi_address_config setup A24 and A32 offsets - * open_vxi_device log VXI device info - * vxi_record_topology find slots and extenders for each device - * - * for use by IOC core - * epvxiResman entry for a VXI resource manager which - * also sets up the MXI bus - * epvxiIOReport call io device specific report routines - * for all registered devices and print - * information about device's configuration - * epvxiDeviceList print info useful when debugging drivers - * vxi_init backwards compatibility - * vxi_io_report backwards compatibility - * - * for use by vxi drivers - * epvxiLookupLA find LA given search pattern - * epvxiUniqueDriverID obtain a unique id each call - * epvxiOpen register a drivers use of a device - * epvxiClose disconnect from a device - * epvxiPConfig fetch a driver config block given a LA - * epvxiRouteTriggerECL route ECL trig to/from front panel - * epvxiRouteTriggerTTL route TTL trig to/from front panel - * - */ - -static char *sccsId = "$Id$\t$Date$"; - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsAssert.h" -#include "dbDefs.h" -#include "errlog.h" -#include "devLib.h" -#define SRCepvxiLib /* allocate externals here */ -#include "drvEpvxi.h" -#include "drvHp1404a.h" -#include "epicsDynLink.h" - -#define NICPU030 - -/* - * EPICS driver entry point table - */ -typedef long (*DRVSUPFUN) (); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvVxi={ - 2, - epvxiIOReport, - epvxiResman}; - - -/* - * so setting ECL triggers does not mess with the - * RM's address windows - */ -#define MXI_CONTROL_CONSTANT 0x4000 -#define INTX_INT_OUT_ENABLE 0x7f00 -#define INTX_INT_IN_ENABLE 0x7f7f - -#define abort(A) taskSuspend(0) - -#define VXIMSGINTLEVEL 1 - -#define BELL 7 - -#define UKN_LA (-1) -#define UKN_SLOT (-1) -#define UKN_CRATE (-1) - -#define DEFAULT_VXI_A24_BASE 0x90000 -#define DEFAULT_VXI_A24_SIZE 0x10000 -#define DEFAULT_VXI_A32_BASE 0x90000000 -#define DEFAULT_VXI_A32_SIZE 0x10000000 - -/* - * laPassLast and laPassFirst must be last/first respectively - * and have no purpose outside of being delimiters - */ -enum laPass { - laPassSC, - laPassAnchoredDC, - laPassFloatingDC, - laPassSetWindows}; - - -LOCAL char niCpu030Initialized; -LOCAL VXIE root_extender; -LOCAL ELLLIST crateList; - -LOCAL char *ignore_list[] = {"_excStub","_excIntStub"}; -LOCAL void *ignore_addr_list[NELEMENTS(ignore_list)]; -LOCAL unsigned last_la; -LOCAL unsigned first_la; - -struct vxi_csr *pDynDevice; - -#define SETMODID(PVXISZ, SLOT) \ -(*(PVXISZ)->set_modid)((PVXISZ), SLOT) - -#define CLRMODID(PVXISZ) \ -(*(PVXISZ)->clear_modid)(PVXISZ); - -LOCAL -SYMTAB *epvxiSymbolTable; -LOCAL -char epvxiSymbolTableDeviceIdString[] = "%03x:%03x"; -LOCAL -char epvxiSymbolTableMakeIdString[] = "%03x"; - -/* - * for the VXI symbol table - * just contains model names for now - */ -#define EPVXI_MODEL_NAME_SYMBOL 1 -#define EPVXI_MAKE_NAME_SYMBOL 2 -#define EPVXI_MAX_SYMBOLS_LOG2 8 -#define EPVXI_MAX_SYMBOLS (1<la_mapped){ - break; - } - vxi_find_dc_devices(pvxie); - break; - - - /* - * allocate DC devices - */ - case laPassAnchoredDC: - /* - * wait until laPassFloatingDC if - * nothing is mapped - */ - if(!pvxie->la_mapped){ - break; - } - vxi_find_dc_devices(pvxie); - break; - - default: - break; - } - - /* - * - * find any MXI bus repeaters - * - */ - vxi_find_mxi_devices( - pvxie, - pass); - - return VXI_SUCCESS; -} - - -/* - * - * vxi_unmap_mxi_devices() - * - * close any MXI devices which have open windows but - * have not been encountered by this execution - * of the resource manager. - * - * This makes the MXI/VXI configure correctly after - * a control x (soft) reboot. - */ -LOCAL void vxi_unmap_mxi_devices(void) -{ - struct vxi_csr *pmxi; - EPVXISTAT status; - int16_t id; - unsigned addr; - - for(addr=first_la; addr<=last_la; addr++){ - /* - * only configure devices not seen before - */ - if(epvxiLibDeviceList[addr]){ - continue; - } - - pmxi = VXIBASE(addr); - - status = devReadProbe (sizeof(id), pmxi, &id); - if (status) { - continue; - } - - if(!VXIMXI(pmxi)){ - continue; - } - - /* - * force all of these back to the hard reset state - */ - pmxi->dir.w.dd.mxi.la_window = 0; - pmxi->dir.w.dd.mxi.a16_window_low = 0; - pmxi->dir.w.dd.mxi.a16_window_high = 0; - pmxi->dir.w.dd.mxi.a24_window_low = 0; - pmxi->dir.w.dd.mxi.a24_window_high = 0; - pmxi->dir.w.dd.mxi.a32_window_low = 0; - pmxi->dir.w.dd.mxi.a32_window_high = 0; - } -} - - - -/* - * - * vxi_find_mxi_devices() - * - */ -LOCAL void vxi_find_mxi_devices( -VXIE *pvxie, -enum laPass pass -) -{ - struct vxi_csr *pmxi; - unsigned addr; - VXIDI *pvxidi; - VXIE *pnewvxie; - - for( addr=first_la; addr<=last_la; addr++){ - - pvxidi = epvxiLibDeviceList[addr]; - - /* - * only configure devices seen before - */ - if(!pvxidi){ - continue; - } - - /* - * skip MXI devices which are not - * in this extender - */ - if(pvxidi->pvxie != pvxie){ - continue; - } - - pmxi = VXIBASE(addr); - - pnewvxie = open_mxi_device( - addr, - pvxie, - ext_import_mxi_into_vxi); - if(!pnewvxie){ - continue; - } - - /* - * open the LA window outward over the entire LA range - */ - pmxi->dir.w.dd.mxi.control = - MXI_UPPER_LOWER_BOUNDS; - pmxi->dir.w.dd.mxi.la_window = - VXIADDRMASK | (VXIADDRMASK<la_mapped){ - pvxie->la_mapped = TRUE; - pvxie->la_low = min(pvxie->la_low, pnewvxie->la_low); - pvxie->la_high = max(pvxie->la_high, pnewvxie->la_high); - } - - /* - * disable the window until the last pass - */ - if(pass != laPassSetWindows){ - pmxi->dir.w.dd.mxi.la_window = - 0 | (0<la_mapped){ -# ifdef DEBUG - printf( "VXI resman: VXI to MXI(%x) %x-%x\n", - addr, - pnewvxie->la_low, - pnewvxie->la_high); -# endif - pmxi->dir.w.dd.mxi.la_window = - (pnewvxie->la_low<la_high+1); - - /* - * if INTX is installed gate the interrupts off of - * INTX - */ - if(MXIINTX(pmxi)){ - pmxi->dir.w.dd.mxi.INTX_interrupt = - INTX_INT_IN_ENABLE; - } - } - else{ - printf( "VXI resman: VXI to MXI LA=0x%X is empty\n", - addr); - pmxi->dir.w.dd.mxi.la_window = - 0 | (0<pvxieSelf){ - return pvxidi->pvxieSelf; - } - - pnewvxie = (VXIE *) calloc(1, sizeof(*pnewvxie)); - if(!pnewvxie){ - errMessage(S_epvxi_noMemory, "MXI device ignored"); - return NULL; - } - - pnewvxie->type = type; - pnewvxie->la = la; - pnewvxie->la_low = last_la; - pnewvxie->la_high = first_la; - pnewvxie->pParent = pvxie; - pnewvxie->pSZD = NULL; - - pvxidi->pvxieSelf = pnewvxie; - - /* - * make sure PARENT window includes the MXI - * bus extender - */ - pvxie->la_mapped = TRUE; - pvxie->la_low = min(pvxie->la_low, la); - pvxie->la_high = max(pvxie->la_high, la); - ellAdd(&pvxie->extenders, &pnewvxie->node); - - epvxiRegisterModelName( - VXIMAKE(pmxi), - VXIMODEL(pmxi), - "MXI bus extender"); - - return pnewvxie; -} - - -/* - * MAP_MXI_INWARD - * - * for each MXI found that we have not seen before - * open the la window inward for all devices - * - */ -LOCAL EPVXISTAT map_mxi_inward( -VXIE *pvxie, -enum laPass pass -) -{ - VXIDI *pvxidi; - struct vxi_csr *pmxi_new; - unsigned addr; - EPVXISTAT status; - VXIE *pnewvxie; - - /* - * open all new MXI devices now - * so that we dont confuse them with - * SC devices when a MXI's window is - * completely open. - * - * If we attempt to communicate with a - * MXI device while another MXI device - * at the same level has its window open - * all the way we see VME bus conflicts. - */ - for(addr=first_la; addr<=last_la; addr++){ - - pvxidi = epvxiLibDeviceList[addr]; - if(!pvxidi){ - /* - * if it has not been seen before we know - * its a MXI device - */ - status = open_vxi_device(pvxie, addr); - if(status==VXI_SUCCESS){ - open_mxi_device( - addr, - pvxie, - ext_export_vxi_onto_mxi); - } - } - } - - /* - * now step through and open up all MXI devices found - */ - for(addr=first_la; addr<=last_la; addr++){ - - pvxidi = epvxiLibDeviceList[addr]; - - if(!pvxidi){ - continue; - } - - pnewvxie = pvxidi->pvxieSelf; - - /* - * dont bother with - * devices that are - * not extenders - * here - */ - if(!pnewvxie){ - continue; - } - - /* - * if it is an extender dont - * configure it unless - * it is a child of the - * current parent - */ - if(pvxidi->pvxie != pvxie){ - continue; - } - - pmxi_new = VXIBASE(addr); - - /* - * open the address window inward for all device - */ - pmxi_new->dir.w.dd.mxi.control = - MXI_UPPER_LOWER_BOUNDS; - pmxi_new->dir.w.dd.mxi.la_window = - 1 | (1<la_mapped){ - pvxie->la_mapped = TRUE; - pvxie->la_low = min(pvxie->la_low, pnewvxie->la_low); - pvxie->la_high = max(pvxie->la_high, pnewvxie->la_high); - } - - /* - * temporarily close the windows so that we can discover - * iproperly located SC devices - */ - if(pass != laPassSetWindows){ - pmxi_new->dir.w.dd.mxi.la_window = - 0 | (0<la_mapped){ -# ifdef DEBUG - printf( "VXI resman: MXI to VXI LA=%x %x-%x\n", - addr, - pnewvxie->la_low, - pnewvxie->la_high); -# endif - pmxi_new->dir.w.dd.mxi.la_window = - pnewvxie->la_low | - ((pnewvxie->la_high+1)<dir.w.dd.mxi.INTX_interrupt = - INTX_INT_OUT_ENABLE; - } - } - else{ - - printf( "VXI resman: MXI to VXI LA=0x%X is empty\n", - addr); - pmxi_new->dir.w.dd.mxi.la_window = - 0 | (0<node.next; - if(pvxisz->la == pnewvxie->la || - pvxisz->pvxie == pnewvxie){ - ellDelete(&crateList, &pvxisz->node); - } - pvxisz = next; - } -# endif /*REMOVE_UNUSED_SLOT_ZERO_DEVICES*/ - } - } - return VXI_SUCCESS; -} - - -/* - * - * open_vxi_device - * - * - */ -LOCAL EPVXISTAT open_vxi_device( -VXIE *pvxie, -unsigned la -) -{ - struct vxi_csr *pdevice; - VXIDI *plac; - int16_t id; - EPVXISTAT status; - - /* - * just return if this device is known about - */ - if(epvxiLibDeviceList[la]){ - return VXI_SUCCESS; - } - - pdevice = VXIBASE(la); - - status = devReadProbe (sizeof(id), pdevice, &id); - if (status) { - return status; - } - - status = verify_valid_window(pvxie, la); - if(status){ - errMessage( - status, - "VXI resman: no access to SC device"); - errMessage( - status, - "VXI resman: without MXI LA window overlap."); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: SC device LA=0X%X", - la); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: extender LA=0X%X", - pvxie->la); - errMessage( - status, - "VXI resman: SC device ignored"); - return status; - } - - plac = (VXIDI *) calloc(1, sizeof(*plac)); - if(!plac){ - errMessage(S_epvxi_noMemory,"... continuing"); - return S_epvxi_noMemory; - } - - plac->make = VXIMAKE(pdevice); - plac->model = VXIMODEL(pdevice); - plac->class = VXICLASS(pdevice); - plac->pvxie = pvxie; - epvxiLibDeviceList[la] = plac; - - pvxie->la_low = min(pvxie->la_low, la); - pvxie->la_high = max(pvxie->la_high, la); - pvxie->la_mapped = TRUE; - - if(devInterruptInUseVME(la)){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "SC VXI device at allocated int vec=0x%X", - la); - epvxiSetDeviceOffline(la); - } - else{ - if(VXISLOT0MODELTEST(plac->model)){ - open_slot0_device (pvxie, la); - } - } - -# ifdef DEBUG - printf("Found LA=0X%X extender LA=0X%X\n", la, pvxie->la); -# endif - - return VXI_SUCCESS; -} - - -/* - * - * verify_valid_window() - * - * determine if this la is within one - * of the other extenders at the same level - * - */ -LOCAL EPVXISTAT verify_valid_window( -VXIE *pvxie, -unsigned la -) -{ - VXIE *pChild; - - /* - * If its the root extender we dont care - */ - if(!pvxie->pParent){ - return VXI_SUCCESS; - } - - for( pChild = (VXIE *) pvxie->pParent->extenders.node.next; - pChild; - pChild = (VXIE *) pChild->node.next){ - - /* - * of course its ok to be in the - * current extender - */ - if(pChild == pvxie){ - continue; - } - - /* - * its not ok to overlap other extenders - * window - */ - if(pChild->la_mapped){ - if(la >= pChild->la_low && - la <= pChild->la_high){ - - return S_epvxi_badConfig; - } - } - } - - /* - * traverse the hierarchy - */ - return verify_valid_window(pvxie->pParent, la); -} - - -/* - * - * - * VXI_FIND_SC_DEVICES - * - */ -LOCAL void vxi_find_sc_devices( -VXIE *pvxie -) -{ - unsigned addr; - - /* - * Locate the slots of all SC devices - */ - for(addr=first_la; addr<=last_la; addr++){ - - /* - * dont configure devices seen before - */ - if(epvxiLibDeviceList[addr]){ - continue; - } - - (void) open_vxi_device(pvxie, addr); - } -} - - -/* - * - * vxi_record_topology() - * - * Record topological information after all MXIs - * and slot zero cards have been located since - * MXIs can appear in the address space prior - * to their slot zero cards ( so their slots - * cant be found initially ). - * - */ -LOCAL void vxi_record_topology(void) -{ - VXIDI **pplac; - struct vxi_csr *pdevice; - VXISZ *pvxisz; - unsigned la; - unsigned slot; - EPVXISTAT status; - - for( la=first_la, pplac = &epvxiLibDeviceList[first_la]; - la<=last_la; - la++, pplac++){ - - if(!*pplac){ - continue; - } - - pdevice = VXIBASE(la); - status = vxi_find_slot(pdevice, &slot, &pvxisz); - if(status==VXI_SUCCESS){ - (*pplac)->slot = slot; - if ((*pplac)->pvxisz!=NULL && (*pplac)->pvxisz != pvxisz) { - epicsPrintf ("Warning, slot zero device changed LA=%u\n", la); - } - (*pplac)->pvxisz = pvxisz; - (*pplac)->extender_la = pvxisz->pvxie->la; - - if(VXISLOT0MODEL(pdevice)){ - if((*pplac)->slot!=0){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI slot 0 found in slot %d? LA=0x%X", - (*pplac)->slot, - la); - } - } - } - else{ - errPrintf( - status, - __FILE__, - __LINE__, - "LA=0X%X", - la); - (*pplac)->slot = UKN_SLOT; - (*pplac)->extender_la = UKN_LA; - } - } -} - - -/* - * - * - * VXI_FIND_DC_DEVICES - * - */ -LOCAL void vxi_find_dc_devices( -VXIE *pvxie -) -{ - unsigned maxInBlockedDC; /* max LA in a blocked addr DC device */ - int prealloc; - int16_t id; - EPVXISTAT status; - unsigned offset; - VXISZ *pvxisz; - unsigned nDC; - - /* - * dont move DC devices if SC device at address 0xff - */ - if(epvxiLibDeviceList[VXIDYNAMICADDR]){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI SC device recorded at dynamic address 0x%X", - VXIDYNAMICADDR); - errMessage( - S_epvxi_badConfig, - "VXI DC devices ignored"); - return; - } - - status = devReadProbe (sizeof(id), pDynDevice, &id); - if (status == S_dev_success) { - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI SC device at dynamic address 0x%X", - VXIDYNAMICADDR); - errMessage( - S_epvxi_badConfig, - "VXI DC devices ignored"); - return; - } - - /* - * find out how many DC devices are in the system - * and there worst case (blocked address) alignment - */ - status = vxi_count_dc_devices( - pvxie, - &nDC, - &maxInBlockedDC); - if (status) { - return; - } - - if(nDC < 1){ - return; - } - - /* - * if unanchored force them to all be in one - * contiguous block - */ - prealloc = FALSE; - if(!pvxie->la_mapped){ - - /* - * allocate with worst case (blocked address) alignment - */ - status = vxi_alloc_la( - pvxie, - nDC, - blocked_la_alignment (maxInBlockedDC), - &offset); - if(status){ - errMessage( - status, - "VXI resman: unanchored DC VXI device block doesnt fit"); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: %d DC VXI devices in extender LA=0X%X ignored", - nDC, - pvxie->la); - return; - } - prealloc = TRUE; - } - - /* - * find all DC devices - */ - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - /* - * We wish to selectively configure DC devices - * accessed through the current extender. - * - * If the slot zero card is the extender then - * the LAs of the extender and the slot zero will - * match. Otherwise the slotzero card was found - * by opening up the window in the extender - * and the slot zeros extender will be the - * current extender. - */ - if(pvxisz->pvxie == pvxie || pvxisz->la == pvxie->la){ - unsigned count; - - /* - * allocate largest blocked address devices first ... - * so that we dont end up with pads for alignment - * purposes - */ - count = 1 << blocked_la_alignment (maxInBlockedDC); - while (count) { - vxi_assign_dc_addresses( - pvxie, - prealloc, - &offset, - pvxisz, - count); - count = count >> 1; - } - CLRMODID(pvxisz); - } - pvxisz = (VXISZ *) pvxisz->node.next; - } -} - - -/* - * vxi_assign_dc_addresses() - */ -LOCAL void vxi_assign_dc_addresses( -VXIE *pvxie, -int prealloc, -unsigned *pOffset, -VXISZ *pvxisz, -unsigned minNumberDC -) -{ - unsigned slot; - unsigned status; - - for(slot=0;slotla); - return S_epvxi_noMemory; - } - } - - /* - * blocked addr devices must recv their - * addr assignements in unison - * at a natural alignement - */ - assert ( (offset&mask)==0 ); - pDynDevice->dir.w.addr = offset; - nextOffset = offset + mask + 1; - - while (count) { - status = open_vxi_device( - pvxie, - offset); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: DC dev assign to LA=0X%X failed", - offset); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: Slot Zero LA=0X%X", - pvxisz->la); - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: DC VXI device ignored"); - } - count--; - offset++; - } - - if(prealloc){ - *pOffset = nextOffset; - } - - return status; -} - - -/* - * - * - * VXI_COUNT_DC_DEVICES - * - */ -LOCAL EPVXISTAT vxi_count_dc_devices( -VXIE *pvxie, -unsigned *pCount, -unsigned *pMaxInBlockedDC /* max LA in a blocked addr DC device */ -) -{ - int16_t id; - EPVXISTAT status; - VXISZ *pvxisz; - int slot; - unsigned nDC; - unsigned maxInBlockedDC; - - /* - * dont count DC devices if SC device at address 0xff - */ - if(epvxiLibDeviceList[VXIDYNAMICADDR]){ - status = S_epvxi_badConfig; - errMessage(status, "SC device at DC address"); - return status; - } - - status = devReadProbe (sizeof(id), pDynDevice, &id); - if (status == S_dev_success) { - status = S_epvxi_badConfig; - errMessage(status, "SC device at DC address"); - return status; - } - - /* - * find all dynamic modules - */ - nDC=0; - maxInBlockedDC=0; - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - /* - * We wish to selectively configure DC devices - * accessed through the current extender. - * - * If the slot zero card is the extender then - * the LAs of the extender and the slot zero will - * match. Otherwise the slotzero card was found - * by opening up the window in the extender - * and the slot zeros extender will be the - * current extender. - * - * Counts multiple blocked addr device per slot here. - * Does not try to count multiple independently - * addressed devices per slot here. Space is - * allocated for these DC devices on demand due to - * difficulties counting them ahead of time. - */ - if(pvxisz->pvxie == pvxie || - pvxisz->la == pvxie->la){ - - for(slot=0; slotnode.next; - } - *pCount = nDC; - *pMaxInBlockedDC = maxInBlockedDC; - return VXI_SUCCESS; -} - - -/* - * - * blocked_la_alignment() - * - * Rule F.2.7 - * - * determine the required alignment for DC - * blocked address devices - * - */ -LOCAL unsigned blocked_la_alignment(unsigned blockedLACount) -{ - unsigned alignment; - - if (blockedLACount <= 1) { - return 0; - } - - alignment = 0; - blockedLACount = blockedLACount-1; - while (blockedLACount) { - alignment++; - blockedLACount = blockedLACount >> 1; - } - - return alignment; -} - - -/* - * - * blocked_la_count() - * - */ -LOCAL unsigned blocked_la_count(struct vxi_csr *pcsr) -{ - unsigned blockedAddrCount; - - /* - * Rule F.2.6 - */ - blockedAddrCount = VXINDCDEVICES(pcsr); - if(blockedAddrCount==0 || blockedAddrCount==0xff){ - blockedAddrCount = 1; - } - return blockedAddrCount; -} - - -/* - * open_slot0_device() - * - * open slot 0 device - */ -LOCAL void open_slot0_device( -VXIE *pvxie, -unsigned la -) -{ - struct vxi_csr *pcsr; - EPVXISTAT status; - VXISZ *pvxisz; - - /* - * only one slot zero device per extender - */ - if (pvxie->pSZD) { - if (la != pvxie->pSZD->la) { - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, -"Detected a 2nd slot 0 device in the same extender ???? LA=0x%X", - la); - } - return; - } - - /* - * dont open the same slot zero device twice - */ - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - if(pvxisz->la == la){ - return; - } - pvxisz = (VXISZ *) pvxisz->node.next; - } - - pcsr = VXIBASE(la); - - /* - * MXI's are device class extended - */ - if(VXICLASS(pcsr) != VXI_REGISTER_DEVICE){ - if(!VXIMXI(pcsr)){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, -"Only register based slot 0 devices currently supported LA=0x%X class=%d", - la, VXICLASS(pcsr)); - return; - } - } - - pvxisz = (VXISZ *) calloc(1, sizeof(*pvxisz)); - if(!pvxisz){ - errMessage( - S_epvxi_noMemory, - "continuing..."); - return; - } - pvxisz->reg = TRUE; - pvxisz->pcsr = pcsr; - pvxisz->set_modid = set_reg_modid; - pvxisz->clear_modid = clr_all_reg_modid; - pvxisz->report = report_one_device; - pvxisz->pvxie = pvxie; - pvxisz->la = la; - - ellAdd(&crateList, &pvxisz->node); - - /* - * force the slot zero device into a known state - */ - CLRMODID(pvxisz); - - if(!epvxiLibDeviceList[la]){ - status = open_vxi_device(pvxie, la); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "attempted slot zero device open la=0X%X", - la); - } - } - pvxie->pSZD = pvxisz; -} - - -/* - * - * NICPU030_INIT() - * check to see if this code is running on a - * national instruments cpu030 installed in - * slot zero. - * - */ -#ifdef NICPU030 -LOCAL EPVXISTAT nicpu030_init( -VXIE *pvxie -) -{ - int i; - EPVXISTAT status = S_epvxi_internal; - int16_t model; - SYM_TYPE type; - UINT8 la; - - /* - * If we are running this code on the NI 030 - * we are the resource manager and the NI 030 will - * be the first slot zero card found. - */ - if(niCpu030Initialized){ - return VXI_SUCCESS; - } - - for(i=0; ipSZD == NULL) { - pvxisz = (VXISZ *) calloc(1, sizeof(*pvxisz)); - if(!pvxisz){ - status = S_epvxi_noMemory; - errMessage(status, NULL); - return status; - } - - pvxisz->set_modid = nivxi_cpu030_set_modid; - pvxisz->clear_modid = nivxi_cpu030_clr_all_modid; - pvxisz->report = nivxi_cpu030_io_report; - pvxisz->la = la; - pvxisz->pvxie = pvxie; - pvxie->pSZD = pvxisz; - - ellAdd(&crateList, &pvxisz->node); - } - else { - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, -"Detected a 2nd slot 0 device in the same extender ???? LA=0x%X", - la); - } - } - return VXI_SUCCESS; -} -#endif - - - -/* - * - * vxi_alloc_la() - * - */ -LOCAL EPVXISTAT vxi_alloc_la( -VXIE *pvxie, -unsigned count, -unsigned alignment, /* number of zero ls bits in LA */ -unsigned *poffset -) -{ - EPVXISTAT status; - unsigned hla; - VXIDI *pvxidi; - unsigned base_la; - unsigned peak; - unsigned la; - unsigned mask = (1<la_mapped){ - - /* - * look inside the range thats mapped (or above) first - * (from the bottom up)) - */ - for(base_la=la=pvxie->la_low; la<=last_la; la++){ - - pvxidi = epvxiLibDeviceList[la]; - - /* - * If we are starting out with the alignement - * wrong then just continue - */ - if (peak==0) { - base_la = la; - if (base_la&mask) { - continue; - } - } - - /* - * skip all devices seen before - */ - if(pvxidi){ - /* - * LA window cant cross extender boundaries - * so just quit - */ - if(pvxidi->pvxie != pvxie){ - break; - } - peak = 0; - continue; - } - - if(vxi_la_occupied(la)){ - peak = 0; - continue; - } - - peak++; - - /* - * if count is not evenly divisable by - * (mask+1) then extend the block size - * out to natural alignment - */ - if (peak >= count && ((la+1)&mask)==0 ) { - assert ( (base_la&mask)==0 ); - *poffset = base_la; - return VXI_SUCCESS; - } - } - - hla = pvxie->la_low; - } - else{ - /* - * unachored DC device allocations go from high - * to low so that we avoid mc680xx reserved - * interrupt vectors - */ - hla = last_la; - } - - /* - * Now look from the top down - * - * stop before unsigned la=0 is decremented - * (shouldnt allocate the resource manager's LA anyways) - */ - peak=0; - la=hla; - base_la = la - (count-1); - for(; la>=max(VXI_RESMAN_LA+1,first_la); la--){ - - /* - * If we are starting out with the alignement - * wrong then just continue - */ - if (peak==0) { - base_la = la - (count-1); - if (base_la&mask) { - continue; - } - } - - pvxidi = epvxiLibDeviceList[la]; - - /* - * skip all devices seen before - */ - if(pvxidi){ - /* - * LA window cant cross extender boundaries - * (if something is mapped already) so just quit - */ - if(pvxie->la_mapped){ - if(pvxidi->pvxie != pvxie){ - break; - } - } - - peak= 0; - continue; - } - - if(vxi_la_occupied(la)){ - peak= 0; - continue; - } - - peak++; - - /* - * if count is not evenly divisable by - * (mask+1) then extend the block size - * out to natural alignment - */ - if (peak >= count && la == base_la) { - assert ( (base_la&mask)==0 ); - *poffset = base_la; - return VXI_SUCCESS; - } - } - - return S_epvxi_internal; -} - - -/* - * - * vxi_la_occupied() - * - */ -LOCAL EPVXISTAT vxi_la_occupied(unsigned la) -{ - struct vxi_csr *pcsr; - int16_t *pi16; - int16_t i16; - EPVXISTAT s; - - /* - * dont allocate the resource manager's LA - */ - if(la == VXI_RESMAN_LA){ - return TRUE; - } - - /* - * Check to see if this LA belongs to - * the NI 030 CPU (that does not show - * in A16 when it is a VME BM) - */ - if(niCpu030Initialized){ - if(la == (*pnivxi_func[(unsigned)e_GetMyLA])()){ - return TRUE; - } - } - - /* - * Probe the entire LA space - */ - pcsr = VXIBASE(la); - for( pi16 = (int16_t *) &pcsr->dir.r.make; - pi16 <= (int16_t *) &pcsr->dir.r.dd.reg.ddx2e; - pi16++){ - - s = devReadProbe (sizeof(i16), pi16, &i16); - if (s==S_dev_success) { - return TRUE; - } - } - - /* - * dont allow vxi int vec to overlap - * VME vectors in use - */ - if(devInterruptInUseVME(la)){ - return TRUE; - } - - return FALSE; -} - - - -/* - * - * VXI_FIND_SLOT - * given a VXI module's addr find its slot - * - */ -LOCAL EPVXISTAT vxi_find_slot( -struct vxi_csr *pcsr, -unsigned *pslot, -VXISZ **ppvxisz -) -{ - VXISZ *pvxisz; - EPVXISTAT status; - unsigned char slot; - - status = S_epvxi_slotNotFound; - - /* - * RULE C.2.7 - */ - if(VXIMODIDSTATUS(pcsr->dir.r.status)){ - errMessage(status, "device's MODID status is active & no MODID?"); - return status; - } - - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - - /* - * if it is a slot zero card - * then dont bother searching - */ - if(pvxisz->pcsr == pcsr){ - *pslot = 0; - *ppvxisz = pvxisz; - status = VXI_SUCCESS; - break; - } - - for(slot=0;slotdir.r.status)){ - *pslot = slot; - *ppvxisz = pvxisz; - status = VXI_SUCCESS; - break; - } - } - CLRMODID(pvxisz); - - if(status == VXI_SUCCESS) - break; - - pvxisz = (VXISZ *) pvxisz->node.next; - } - - return status; -} - - -/* - * - * VXI_DC_TEST - * determine if a VXI module in the static address range is dynamic - * - */ -#ifdef JUNKYARD -LOCAL EPVXISTAT vxi_dc_test( -unsigned current_addr -) -{ - register unsigned addr; - unsigned slot; - unsigned crate; - int16_t id; - EPVXISTAT status; - struct vxi_csr_w *pcr; - struct vxi_csr_r *psr; - - static unsigned open_addr; - unsigned dynamic; - - for(addr=first_la; addr<=last_la; addr++){ - - status = devReadProbe (sizeof(id), VXIBASE(addr), &id); - if (status) { - open_addr = addr; - break; - } - } - - psr = (struct vxi_csr_r *) VXIBASE(current_addr); - pcr = (struct vxi_csr_w *) psr; - - status = vxi_find_slot(psr, &slot, &crate); - if(status){ - errMessage(status,NULL); - return status; - } - - SETMODID(slot, crate); - pcr->addr = open_addr; - - psr = (struct vxi_csr_r *) VXIBASE(open_addr); - pcr = (struct vxi_csr_w *) psr; - - status = devReadProbe (sizeof(id), psr, &id); - if(status==S_dev_success){ - dynamic = TRUE; - pcr->addr = current_addr; - } - else - dynamic = FALSE; - - status = devReadProbe (sizeof(id), VXIBASE(current_addr), &id); - if (status) - return S_epvxi_internal; - - - return dynamic; -} -#endif - - -/* - * - * VXI_CONFIGURE_HIERARCHIES - * - */ -LOCAL void vxi_configure_hierarchies( -unsigned commander_la, -unsigned servant_area -) -{ - EPVXISTAT status; - struct vxi_csr *pcsr; - unsigned long response; - VXIDI **ppvxidi; - VXIDI *pvxidi; - unsigned sla; - unsigned last_sla; - unsigned area; - - last_sla = servant_area+commander_la; - - if(last_sla >= NELEMENTS(epvxiLibDeviceList)){ - errPrintf( - S_epvxi_internal, - __FILE__, - __LINE__, - "VXI resman: Clipping servant area (LA=0x%X)", - commander_la); - last_sla = NELEMENTS(epvxiLibDeviceList)-1; - } - - sla = commander_la+1; - ppvxidi = &epvxiLibDeviceList[sla]; - for( ; - sla<=last_sla; - sla += area+1, ppvxidi += area+1){ - - pvxidi = *ppvxidi; - area = 0; - - if(!pvxidi){ - continue; - } - - pvxidi->commander_la = commander_la; - - if(!pvxidi->st_passed){ - continue; - } - - pcsr = VXIBASE(sla); - - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - continue; - } - - if(commander_la != VXI_RESMAN_LA){ - status = epvxiCmdQuery( - commander_la, - (unsigned long)MBC_GRANT_DEVICE | sla, - &response); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: GD failed (LA=0x%X)", - sla); - } - else{ - printf( - "VXI resman: gd resp %lx\n", - response); - } - } - if(VXICMDR(pcsr)){ - status = epvxiCmdQuery( - sla, - (unsigned long)MBC_READ_SERVANT_AREA, - &response); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: RSA failed (LA=0x%X)", - sla); - } - else{ - area = response & MBR_READ_SERVANT_AREA_MASK; - - printf( "The servant area was %d (LA=0x%X)\n", - area, - sla); - - vxi_configure_hierarchies( - sla, - area); - } - } - } -} - - -/* - * - * VXI_BEGIN_NORMAL_OPERATION - * - */ -LOCAL void vxi_begin_normal_operation(void) -{ - EPVXISTAT status; - unsigned la; - VXIDI **ppvxidi; - VXIDI *pvxidi; - struct vxi_csr *pcsr; - - for (la=0, ppvxidi = epvxiLibDeviceList; - ppvxidi < epvxiLibDeviceList+NELEMENTS(epvxiLibDeviceList); - ppvxidi++, la++){ - - unsigned cmdr; - unsigned long cmd; - unsigned long resp; - - pvxidi = *ppvxidi; - - if(!pvxidi){ - continue; - } - - /* - * dont do this step for the top level slot zero device - */ - if (root_extender.pSZD) { - if (la == root_extender.pSZD->la) { - continue; - } - } - - pcsr = VXIBASE(la); - - if(!pvxidi->st_passed){ - continue; - } - - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - continue; - } - - cmdr = VXICMDR(pcsr); - - cmd = MBC_BEGIN_NORMAL_OPERATION; -/* - * this will send the begin nml op command to servants which - * have a commander - * - * more work needs to be done here if this situation occurs - * see below - */ - if(cmdr){ - cmd |= MBC_TOP_LEVEL_CMDR; - } - status = epvxiCmdQuery(la, cmd, &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "VXI resman: Device rejected BEGIN_NORMAL_OPERATION LA=0x%X (reason=%d)", - la, - status); - } - else if( - MBR_STATUS(resp)!=MBR_STATUS_SUCCESS || - MBR_BNO_STATE(resp)!=MBR_BNO_STATE_NO){ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "VXI resman: Device rejected BEGIN_NORMAL_OPERATION LA=0x%X (status=%x) (state=%x)", - la, - MBR_STATUS(resp), - MBR_BNO_STATE(resp)); - } - else{ - pvxidi->msg_dev_online = TRUE; - } - - /* - * Dont send begin normal operation cmd - * to servants who have a commander - */ -/* - * apparently this is not a good enough test - * for CMDR since some devices are rejecting this cmd - */ -#if 0 - if(cmdr){ - unsigned long sa=0; - - printf("Found a msg based cmdr\n"); - - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_SERVANT_AREA, - &sa); - if(status){ - errMessage( - status, - "vxi resman: rsa failed"); - } - else{ - sa = sa & MBR_READ_SERVANT_AREA_MASK; - printf( - "The servant area was %d\n", - sa); - la += sa; - } - } -#endif - } -} - - -/* - * - * VXI_SELF_TEST - * check self test bits and place in safe state if failed - * print message about failed devices - * - */ -LOCAL EPVXISTAT vxi_self_test(void) -{ - unsigned la; - uint16_t wd; - struct vxi_csr *pcsr; - VXIDI **ppvxidi; - - - for( la=0, ppvxidi = epvxiLibDeviceList; - ppvxidi < epvxiLibDeviceList+NELEMENTS(epvxiLibDeviceList); - ppvxidi++, la++){ - - if(!*ppvxidi){ - continue; - } - - pcsr = VXIBASE(la); - - wd = pcsr->dir.r.status; - - if(VXIPASSEDSTATUS(wd)){ - (*ppvxidi)->st_passed = TRUE; - } - else{ - errMessage( - S_epvxi_selfTestFailed, - "VXI resman: device self test failed"); - epvxiSetDeviceOffline(la); - } - } - - return VXI_SUCCESS; -} - - -/* - * - * - * epvxiSetDeviceOffline() - * - */ -LOCAL EPVXISTAT epvxiSetDeviceOffline( -unsigned la -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "WARNING: VXI device placed off line %c(LA=0x%X)", - BELL, - la); - - pcsr->dir.w.control = VXISAFECONTROL; - - return VXI_SUCCESS; -} - - -/* - * - * VXI_ADDRESS_CONFIG - * - */ -LOCAL void vxi_address_config(void) -{ - volatile char *pBase; - EPVXISTAT status; - - /* - * fetch the EPICS address ranges from the global - * symbol table if they are available - */ - status = symbol_value_fetch( - "_EPICS_VXI_A24_BASE", - &root_extender.A24_base, - sizeof(root_extender.A24_base)); - if(status){ - root_extender.A24_base = DEFAULT_VXI_A24_BASE; - } - status = symbol_value_fetch( - "_EPICS_VXI_A24_SIZE", - &root_extender.A24_size, - sizeof(root_extender.A24_size)); - if(status){ - root_extender.A24_size = DEFAULT_VXI_A24_SIZE; - } - status = symbol_value_fetch( - "_EPICS_VXI_A32_BASE", - &root_extender.A32_base, - sizeof(root_extender.A32_base)); - if(status){ - root_extender.A32_base = DEFAULT_VXI_A32_BASE; - } - status = symbol_value_fetch( - "_EPICS_VXI_A32_SIZE", - &root_extender.A32_size, - sizeof(root_extender.A32_size)); - if(status){ - root_extender.A32_size = DEFAULT_VXI_A32_SIZE; - } - - /* - * find A24 and A32 on this processor - */ - status = devRegisterAddress ("VXI Res Mgr", atVMEA24, - root_extender.A24_base, root_extender.A24_size, (volatile void **)&pBase); - if (status) { - root_extender.A24_ok = FALSE; - errMessage(status, "A24 VXI Base Addr problems"); - } - else { - root_extender.A24_base = (long) pBase; - root_extender.A24_ok = TRUE; - } - - status = devRegisterAddress ("VXI Res Mgr", atVMEA32, - root_extender.A32_base, root_extender.A32_size, (volatile void **)&pBase); - if (status) { - root_extender.A32_ok = FALSE; - errMessage (status, "A32 VXI Base Addr problems"); - } - else { - root_extender.A32_base = (long) pBase; - root_extender.A32_ok = TRUE; - } - - vxi_allocate_address_block(&root_extender); -} - - -/* - * - * VXI_ALLOCATE_ADDRESS_BLOCK - * - */ -LOCAL void vxi_allocate_address_block( -VXIE *pvxie -) -{ - unsigned la; - struct vxi_csr *pcsr; - VXIDI **ppvxidi; - VXIE *psubvxie; - unsigned long A24_base; - unsigned long A24_size; - unsigned long A32_base; - unsigned long A32_size; - - if(!pvxie->la_mapped){ - return; - } - - switch(pvxie->type){ - case ext_export_vxi_onto_mxi: - case ext_import_mxi_into_vxi: - pvxie->A24_base = MXIA24ALIGN(pvxie->A24_base); - pvxie->A32_base = MXIA32ALIGN(pvxie->A32_base); - pvxie->A24_size &= ~MXIA24MASK; - pvxie->A32_size &= ~MXIA32MASK; - break; - case ext_local_cpu: - default: - break; - } - - A24_base = pvxie->A24_base; - A24_size = pvxie->A24_size; - A32_base = pvxie->A32_base; - A32_size = pvxie->A32_size; - - psubvxie = (VXIE *) &pvxie->extenders.node; - while( (psubvxie = (VXIE *) ellNext((ELLNODE *)psubvxie)) ){ - - psubvxie->A24_base = A24_base; - psubvxie->A24_size = A24_size; - psubvxie->A32_base = A32_base; - psubvxie->A32_size = A32_size; - psubvxie->A24_ok = pvxie->A24_ok; - psubvxie->A32_ok = pvxie->A32_ok; - - vxi_allocate_address_block(psubvxie); - - if(psubvxie->A24_mapped){ - A24_base = psubvxie->A24_base + psubvxie->A24_size; - A24_size -= psubvxie->A24_size; - pvxie->A24_mapped = TRUE; - } - - if(psubvxie->A32_mapped){ - A32_base = psubvxie->A32_base + psubvxie->A32_size; - A32_size -= psubvxie->A32_size; - pvxie->A32_mapped = TRUE; - } - } - - for( la=pvxie->la_low, ppvxidi = &epvxiLibDeviceList[la]; - ppvxidi <= &epvxiLibDeviceList[pvxie->la_high]; - ppvxidi++, la++){ - - unsigned long m; - unsigned long size; - unsigned long mask; - - if(!*ppvxidi){ - continue; - } - - /* - * dont configure devices lower in the hierarchy - */ - if((*ppvxidi)->A24_mapped || (*ppvxidi)->A32_mapped){ - continue; - } - - pcsr = VXIBASE(la); - - m = VXIREQMEM(pcsr); - - switch(VXIADDRSPACE(pcsr)){ - case VXI_ADDR_EXT_A24: - if(!pvxie->A24_ok){ - break; - } - - /* - * perform any needed alignment - */ - size = VXIA24MEMSIZE(m); - if(size>A24_size){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI A24 device does not fit Request=%d Avail=%d LA=0X%X", - size, - A24_size, - la); - epvxiSetDeviceOffline(la); - break; - } - mask = size-1; - A24_base = ((A24_base)+mask)&(~mask); - pcsr->dir.w.offset = A24_base>>8; - pcsr->dir.w.control = VXIMEMENBLCONTROL; - (*ppvxidi)->pFatAddrBase = (void *) A24_base; - (*ppvxidi)->A24_mapped = TRUE; - pvxie->A24_mapped = TRUE; - A24_base += size; - A24_size -= size; - break; - - case VXI_ADDR_EXT_A32: - if(!pvxie->A32_ok){ - break; - } - - /* - * perform any needed alignment - */ - size = VXIA32MEMSIZE(m); - if(size>A32_size){ - errPrintf( - S_epvxi_badConfig, - __FILE__, - __LINE__, - "VXI A32 device does not fit Request=%d Avail=%d LA=0X%X", - size, - A32_size, - la); - epvxiSetDeviceOffline(la); - break; - } - mask = size-1; - A32_base = (A32_base+mask)&(~mask); - pcsr->dir.w.offset = A32_base>>16; - pcsr->dir.w.control = VXIMEMENBLCONTROL; - (*ppvxidi)->pFatAddrBase = (void *) A32_base; - (*ppvxidi)->A32_mapped = TRUE; - pvxie->A32_mapped = TRUE; - A32_base += size; - A32_size -= size; - break; - - default: - /* - * do nothing - */ - break; - } - } - - pcsr = VXIBASE(pvxie->la); - - if(pvxie->A24_mapped){ - pvxie->A24_size = pvxie->A24_size - A24_size; - pvxie->A24_size = MXIA24ALIGN(pvxie->A24_size); - } - - if(pvxie->A32_mapped){ - pvxie->A32_size = pvxie->A32_size - A32_size; - pvxie->A32_size = MXIA32ALIGN(pvxie->A32_size); - } - - switch(pvxie->type){ - case ext_export_vxi_onto_mxi: - if(pvxie->A24_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a24_window_high = - (pvxie->A24_base+pvxie->A24_size) - >> MXIA24MASKSIZE; - pcsr->dir.w.dd.mxi.a24_window_low = - pvxie->A24_base - >> MXIA24MASKSIZE; - } - if(pvxie->A32_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a32_window_high = - (pvxie->A32_base+pvxie->A32_size) - >> MXIA32MASKSIZE; - pcsr->dir.w.dd.mxi.a32_window_low = - pvxie->A32_base - >> MXIA32MASKSIZE; - } - break; - - case ext_import_mxi_into_vxi: - if(pvxie->A24_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a24_window_high = - pvxie->A24_base - >> MXIA24MASKSIZE; - pcsr->dir.w.dd.mxi.a24_window_low = - (pvxie->A24_base+pvxie->A24_size) - >> MXIA24MASKSIZE; - } - if(pvxie->A32_mapped){ - /* - * window enables only after the low - * byte is written - */ - pcsr->dir.w.dd.mxi.a32_window_high = - pvxie->A32_base - >> MXIA32MASKSIZE; - pcsr->dir.w.dd.mxi.a32_window_low = - (pvxie->A32_base+pvxie->A32_size) - >> MXIA32MASKSIZE; - } - break; - - case ext_local_cpu: - default: - break; - } -} - - -/* - * - * symbol_value_fetch - * - */ -LOCAL EPVXISTAT symbol_value_fetch( -char *pname, -void *pdest, -unsigned dest_size -) -{ - EPVXISTAT status; - SYM_TYPE type; - char *pvalue; - - status = symFindByNameEPICS( - sysSymTbl, - pname, - &pvalue, - &type); - if(status == OK){ - memcpy (pdest, pvalue, dest_size); - return VXI_SUCCESS; - } - else{ - return S_epvxi_internal; - } -} - - -/* - * - * VXI_INIT_IGNORE_LIST - * init list of interrupt handlers to ignore - * - */ -LOCAL EPVXISTAT vxi_init_ignore_list(void) -{ - int i; - SYM_TYPE type; - EPVXISTAT status; - - for(i=0; ireg)){ - errMessage( - S_epvxi_internal, - "bad crate for set_reg_modid"); - return; - } - VXI_SET_REG_MODID(pvxisz->pcsr, slot); -} - -/* - * - * CLR_ALL_REG_MODID - * - */ -LOCAL void clr_all_reg_modid( -VXISZ *pvxisz -) -{ - if(!(pvxisz->reg)){ - errMessage( - S_epvxi_internal, - "bad crate for clr_all_reg_modid"); - return; - } - VXI_CLR_ALL_REG_MODID(pvxisz->pcsr); -} - - - -/* - * - * NIVXI_CPU030_SET_MODID - * - */ -#ifdef NICPU030 -LOCAL void nivxi_cpu030_set_modid( -VXISZ *pvxisz, -unsigned slot -) -{ - EPVXISTAT status; - - if(niCpu030Initialized){ - status = (*pnivxi_func[(unsigned)e_SetMODID])(TRUE,1<slot, - pmxidi->class); - printf("\t"); - if(pmxidi->pvxieSelf){ - printf("extender, "); - } - if(pmxidi->msg_dev_online){ - printf("msg online, "); - } - printf("driver ID %ld, ", pmxidi->driverID); - if(taskIdVerify(pmxidi->taskID)>=0){ - printf( "opened by task %s, ", - taskName(pmxidi->taskID)); - } - printf("cmdr la=0x%X, ", pmxidi->commander_la); - printf("extdr la=0x%X, ", pmxidi->extender_la); - if (pmxidi->pvxisz) { - printf("slot-zero la=0x%X, ", pmxidi->pvxisz->la); - } - printf("make 0X%X, ", (unsigned) pmxidi->make); - printf("model 0x%X, ", pmxidi->model); - printf( "pio_report_func %x, ", - (unsigned) pmxidi->pio_report_func); - printf("\n"); - } - i++; - ppmxidi++; - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiCrateList() - * - */ -EPVXISTAT epvxiCrateList(void) -{ - VXISZ *pvxisz; - - printf("VXI crate list\n"); - pvxisz = (VXISZ *) crateList.node.next; - while(pvxisz){ - - printf("LA=0X%X", pvxisz->la); - printf( ", extender LA=0X%X", - pvxisz->pvxie->la); - if(pvxisz->reg){ - printf(", register device"); - } - if(pvxisz->msg){ - printf(", message device"); - } - printf("\n"); - pvxisz = (VXISZ *) pvxisz->node.next; - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiUniqueDriverID() - * - * return a non zero unique id for a VXI driver - */ -long epvxiUniqueDriverID(void) -{ - if(epvxiNextDriverIDdriverID == vxiDriverID){ - return S_epvxi_deviceOpen; - } - else if(pvxidi->driverID != NO_DRIVER_ATTACHED_ID){ - return S_epvxi_notOwner; - } - - if(driverConfigSize){ - pconfig = (void *)calloc(1,driverConfigSize); - if(!pconfig){ - return S_epvxi_noMemory; - } - pvxidi->pDriverConfig = pconfig; - } - else{ - pvxidi->pDriverConfig = NULL; - } - - pvxidi->pio_report_func = pio_report_func; - - pvxidi->taskID = taskIdSelf(); - pvxidi->driverID = vxiDriverID; - - return VXI_SUCCESS; -} - - -/* - * - * epvxiDeviceVerify() - * - * - */ -EPVXISTAT epvxiDeviceVerify(unsigned la) -{ - EPVXISTAT status; - VXICSR *pcsr; - VXIDI *pvxidi; - uint16_t device_status; - - if(la > NELEMENTS(epvxiLibDeviceList)){ - return S_epvxi_badLA; - } - - pvxidi = epvxiLibDeviceList[la]; - if(!pvxidi){ - return S_epvxi_uknDevice; - } - - /* - * verify that the device exists - * and check the self test in memory - * since this may run before - * the self tests are verified. - */ - pcsr = VXIBASE(la); - status = devReadProbe (sizeof(device_status), - &pcsr->dir.r.status, &device_status); - if(status){ - return S_epvxi_uknDevice; - } - if(!VXIPASSEDSTATUS(device_status)){ - return S_epvxi_selfTestFailed; - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiClose() - * - * 1) Unregister a driver's ownership of a device - * 2) Free driver's configuration block if one is allocated - */ -EPVXISTAT epvxiClose( -unsigned la, -int vxiDriverID -) -{ - VXIDI *pvxidi; - - if(la > NELEMENTS(epvxiLibDeviceList)){ - return S_epvxi_badLA; - } - - pvxidi = epvxiLibDeviceList[la]; - - if(pvxidi){ - if(pvxidi->driverID == vxiDriverID){ - pvxidi->driverID = NO_DRIVER_ATTACHED_ID; - if(pvxidi->pDriverConfig){ - free(pvxidi->pDriverConfig); - pvxidi->pDriverConfig = NULL; - } - return VXI_SUCCESS; - } - return S_epvxi_notOwner; - } - - return S_epvxi_notOwner; -} - -/* - * epvxiLookupLA() - */ -EPVXISTAT epvxiLookupLA( - epvxiDeviceSearchPattern *pdsp, - void (*pfunc)(unsigned, void *), - void *parg - ) -{ - VXIDI *plac; - unsigned i; - - for(i=first_la; i<=last_la; i++){ - long flags; - - flags = pdsp->flags; - plac = epvxiLibDeviceList[i]; - - /* - * skip devices not present - */ - if(!plac){ - continue; - } - - if(flags & VXI_DSP_make){ - if(plac->make != pdsp->make){ - continue; - } - } - - if(flags & VXI_DSP_model){ - if(plac->model != pdsp->model){ - continue; - } - } - - if(flags & VXI_DSP_class){ - if(plac->class != pdsp->class){ - continue; - } - } - - if(flags & VXI_DSP_slot){ - if(plac->slot != pdsp->slot){ - continue; - } - } - - if(flags & VXI_DSP_slot_zero_la){ - if (plac->pvxisz==NULL) { - continue; - } - if(plac->pvxisz->la != pdsp->slot_zero_la){ - continue; - } - } - - if(flags & VXI_DSP_commander_la){ - if(plac->commander_la != pdsp->commander_la){ - continue; - } - } - - if(flags & VXI_DSP_extender_la){ - if(plac->extender_la != pdsp->extender_la){ - continue; - } - } - - (*pfunc)(i, parg); - - } - - return VXI_SUCCESS; -} - - -/* - * epvxiRouteTriggerECL() - */ -EPVXISTAT epvxiRouteTriggerECL( -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 */ -) -{ - VXIDI *plac; - struct vxi_csr *pcsr; - char mask; - EPVXISTAT status; - int i; - - mask = (1<> 1, - io_map = io_map >> 1, - i++){ - - int (*pfunc)(); - int src; - int dest; - - if(!(enable_map&1)){ - continue; - } - - if(io_map&1){ - src = TRIG_LINE_FPOUT; - dest = TRIG_LINE_ECL_BASE + i; - } - else{ - src = TRIG_LINE_FPIN; - dest = TRIG_LINE_ECL_BASE + i; - } - - pfunc = pnivxi_func[(unsigned)e_MapTrigToTrig]; - status = (*pfunc)( - la, - src, - dest, - 0); - if(status < 0){ - status = S_epvxi_badTrigIO; - errPrintf( - status, - __FILE__, - __LINE__, - "NI CPU030 ECL trig map fail LA=0X%X", - la); - return status; - } - - } - return VXI_SUCCESS; - } - } - - plac = epvxiLibDeviceList[la]; - if(plac){ - if(!plac->st_passed){ - return S_epvxi_selfTestFailed; - } - } - else{ - return S_epvxi_noDevice; - } - - pcsr = VXIBASE(la); - - if(VXIMXI(pcsr)){ - int ctrl = MXI_CONTROL_CONSTANT; - - if(enable_map & (1<<0)){ - ctrl |= MXI_ECL0_ENABLE; - } - if(io_map & (1<<0)){ - ctrl |= MXI_ECL0_BP_TO_FP; - } - else{ - ctrl |= MXI_ECL0_FP_TO_BP; - } - - - if(enable_map & (1<<1)){ - ctrl |= MXI_ECL1_ENABLE; - } - if(io_map & (1<<1)){ - ctrl |= MXI_ECL1_BP_TO_FP; - } - else{ - ctrl |= MXI_ECL1_FP_TO_BP; - } - - pcsr->dir.w.dd.mxi.control = ctrl; - - return VXI_SUCCESS; - } - - /* - * HP MODEL E1404 trigger routing - */ - if(VXIMAKE(pcsr)==VXI_MAKE_HP){ - if( VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG || - VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG_SLOT0){ - return hpE1404RouteTriggerECL( - la, - enable_map, - io_map); - } - } - - status = S_epvxi_uknDevice; - errPrintf( - status, - __FILE__, - __LINE__, - "failed to map ECL trigger for (la=0x%X)", - la); - return status; -} - - -/* - * epvxiRouteTriggerTTL() - * - */ -EPVXISTAT epvxiRouteTriggerTTL( -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 */ -) -{ - VXIDI *plac; - struct vxi_csr *pcsr; - unsigned mask; - EPVXISTAT status; - int i; - - mask = (1<> 1, - io_map = io_map >> 1, - i++){ - - int (*pfunc)(); - int src; - int dest; - - if(!(enable_map&1)){ - continue; - } - - if(io_map&1){ - src = TRIG_LINE_FPOUT; - dest = TRIG_LINE_TTL_BASE + i; - } - else{ - src = TRIG_LINE_FPIN; - dest = TRIG_LINE_TTL_BASE + i; - } - - pfunc = pnivxi_func[(unsigned)e_MapTrigToTrig]; - status = (*pfunc)( - la, - src, - dest, - 0); - if(status < 0){ - status = S_epvxi_badTrigIO; - errPrintf( - status, - __FILE__, - __LINE__, - "NI030 TTL trig map fail LA=0X%X", - la); - return status; - } - - } - return VXI_SUCCESS; - } - } - - plac = epvxiLibDeviceList[la]; - if(plac){ - if(!plac->st_passed){ - return S_epvxi_selfTestFailed; - } - } - else{ - return S_epvxi_noDevice; - } - - - pcsr = VXIBASE(la); - - if(VXIMXI(pcsr)){ - int16_t tmp; - - tmp = ~io_map & enable_map; - tmp = (enable_map<<8) | tmp; - pcsr->dir.w.dd.mxi.trigger_config = tmp; - - return VXI_SUCCESS; - } - - /* - * HP MODEL E1404 trigger routing - */ - if(VXIMAKE(pcsr)==VXI_MAKE_HP){ - if( VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG || - VXIMODEL(pcsr)==VXI_HP_MODEL_E1404_REG_SLOT0){ - return hpE1404RouteTriggerTTL( - la, - enable_map, - io_map); - } - } - - status = S_epvxi_uknDevice; - errPrintf( - status, - __FILE__, - __LINE__, - "Failed to map TTL trigger for (LA=%x%X)", - la); - return status; -} - - -/* - * vxi_io_report() - */ -EPVXISTAT vxi_io_report( -unsigned level -) -{ - return epvxiIOReport(level); -} - - -/* - * - * epvxiIOReport - * - * call io report routines for all registered devices - * - */ -EPVXISTAT epvxiIOReport( -unsigned level -) -{ - unsigned la; - EPVXISTAT status; - unsigned base; - unsigned count; - - /* Get local address from VME address. */ - /* in case the resource manager has not been called */ - if(!epvxi_local_base){ - status = epvxiInitLocalBase (&base, &count); - if (status) { - errMessage(status, "A16 base map failed"); - return status; - } - } - - /* - * special support for the niCPU030 - * since it does not see itself - */ - nicpu030_init(&root_extender); - - for(la=first_la; la<=last_la; la++){ - - /* - * dont provide a report on the top level slot zero - * device - */ - if (root_extender.pSZD) { - if (la == root_extender.pSZD->la) { - (*root_extender.pSZD->report)(la, level); - continue; - } - } - - report_one_device (la, level); - } - - return VXI_SUCCESS; -} - - -/* - * - * report_one_device() - * - */ -LOCAL EPVXISTAT report_one_device( -unsigned la, -unsigned level -) -{ - VXIDI *plac; - VXISZ *pvxisz; - unsigned slot; - EPVXISTAT status; - int make; - int model; - struct vxi_csr *pcsr; - int16_t id; - - /* Get local address from VME address. */ - /* in case the resource manager has not been called */ - if(!epvxi_local_base){ - unsigned base, count; - status = epvxiInitLocalBase (&base, &count); - if (status) { - errMessage(status, "A16 base map failed"); - return status; - } - } - - pcsr = VXIBASE(la); - status = devReadProbe (sizeof(id), pcsr, &id); - if (status) { - return status; - } - - status = vxi_find_slot(pcsr, &slot, &pvxisz); - if(status){ - pvxisz = NULL; - slot = UKN_SLOT; - } - - - /* - * the logical address - */ - printf("VXI LA 0x%02X ", la); - - /* - * crate and slot - */ - if(pvxisz){ - printf( "slot zero LA=0X%02X slot %2d ", - pvxisz->la, - slot); - } - else{ - printf( "slot zero LA=?? slot=?? "); - } - - - /* - * make - */ - make = VXIMAKE(pcsr); - { - char buf[32]; - unsigned nactual; - - status = epuxiLookupMakeName( - make, - buf, - sizeof(buf)-1, - &nactual); - if(status==VXI_SUCCESS){ - buf[sizeof(buf)-1] = NULL; - printf("%s ", buf); - } - else{ - printf("make 0x%03X ", make); - } - } - - /* - * model - */ - model = VXIMODEL(pcsr); - { - char model_name[32]; - unsigned int nread; - - status = epuxiLookupModelName( - make, - model, - model_name, - sizeof(model_name)-1, - &nread); - if(status){ - printf( "model 0x%03X ", model); - } - else{ - model_name[sizeof(model_name)]=NULL; - printf( "%s ", model_name); - } - } - - printf("\n"); - - if(!VXIPASSEDSTATUS(pcsr->dir.r.status)){ - printf("\t---- Self Test Failed ----\n"); - return VXI_SUCCESS; - } - - /* - * call their io report routine if they supply one - */ - plac = epvxiLibDeviceList[la]; - if(plac){ - if(plac->pio_report_func){ - (*plac->pio_report_func)(la, level); - } - } - - if(level == 0){ - return VXI_SUCCESS; - } - - /* - * print out physical addresses of the cards - */ - printf("\tA16=0x%X ", (int) VXIBASE(la)); - if(VXIMEMENBL(pcsr)){ - long VMEmod = NULL; - char *VMEaddr = NULL; - char *pname = NULL; - char *pbase; - - switch(VXIADDRSPACE(pcsr)){ - case VXI_ADDR_EXT_A24: - VMEmod = VME_AM_STD_SUP_DATA; - VMEaddr = (char *) (pcsr->dir.w.offset<<8); - pname = "A24"; - break; - case VXI_ADDR_EXT_A32: - VMEmod = VME_AM_EXT_SUP_DATA; - VMEaddr = (char *) (pcsr->dir.w.offset<<16); - pname = "A32"; - break; - } - if(pname){ - if (PVXIDI(la)) { - pbase = PVXIDI(la)->pFatAddrBase; - } - else { - pbase = NULL; - } - printf( "%s=%p", pname, pbase); - } - } - printf("\n"); - - if(VXISLOT0MODEL(pcsr)){ - printf("\tSlot Zero Device\n"); - } - - printf( "\t%s device", - vxi_device_class_names[VXICLASS(pcsr)]); - switch(VXICLASS(pcsr)){ - case VXI_MEMORY_DEVICE: - break; - - case VXI_EXTENDED_DEVICE: - if(VXIMXI(pcsr)){ - mxi_io_report(pcsr, level); - } - break; - - case VXI_MESSAGE_DEVICE: - { - unsigned long resp; - - if(VXICMDR(pcsr)){ - printf(", cmdr"); - } - if(VXIFHS(pcsr)){ - printf(", fh"); - } - if(VXISHM(pcsr)){ - printf(", shm"); - } - if(VXIMBINT(pcsr)){ - printf(", interrupter"); - } - if(VXIVMEBM(pcsr)){ - printf(", VME bus master"); - } - if(VXISIGREG(pcsr)){ - printf(", has signal reg"); - } - printf("\n"); - /* - * all message based devices are required to - * implement this command query - */ - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_PROTOCOL, - &resp); - if(status==VXI_SUCCESS){ - printf("\tprotocols("); - if(MBR_REV_12(resp)){ - printf("Rev 1.2 device, "); - } - if(MBR_RP_LW(resp)){ - printf("long word serial, "); - } - if(MBR_RP_ELW(resp)){ - printf("extended long word serial, "); - } - if(MBR_RP_I(resp)){ - printf("VXI instr, "); - } - if(MBR_RP_I4(resp)){ - printf("488 instr, "); - } - if(MBR_RP_TRG(resp)){ - printf("sft trig, "); - } - if(MBR_RP_PH(resp)){ - printf("prog int hdlr, "); - } - if(MBR_RP_PI(resp)){ - printf("prog interrupter, "); - } - if(MBR_RP_EG(resp)){ - printf("event gen, "); - } - if(MBR_RP_RG(resp)){ - printf("resp gen, "); - } - printf(")"); - } - break; - } - case VXI_REGISTER_DEVICE: - break; - - } - printf("\n"); - - return VXI_SUCCESS; -} - - -/* - * - * mxi_io_report() - * - * - */ -LOCAL void mxi_io_report( -struct vxi_csr *pmxi, -unsigned level -) -{ - unsigned la; - unsigned ha; - unsigned a; - unsigned b; - char *msg; - - printf(", MXI sub class\n\t"); - - if(pmxi->dir.w.dd.mxi.control & MXI_UPPER_LOWER_BOUNDS){ - la = VXIADDRMASK & - pmxi->dir.w.dd.mxi.la_window; - ha = VXIADDRMASK & - (pmxi->dir.w.dd.mxi.la_window>>NVXIADDRBITS); - if(la 0 since la < ha - */ - ha--; - } - else if(la>ha){ - msg = "MXI LA's seen by this crate"; - /* - * la > 0 since la > ha - */ - la--; - } - else if(la == 0){ - msg = "LA window disabled"; - la = 0; - ha = 0; - } - else if(la >= 0x80){ - msg = "MXI LA's seen by this crate"; - la = 0; - ha = 0xff; - } - else{ - msg = "local VXI LA's seen by MXI"; - la = 0; - ha = 0xff; - } - - printf(", %s 0x%X-0x%X\n\t", - msg, - la, - ha); - - a = pmxi->dir.w.dd.mxi.a24_window_low; - b = pmxi->dir.w.dd.mxi.a24_window_high; - printf(", A24 window 0x%X-0x%X", - a, - b); - - a = pmxi->dir.w.dd.mxi.a32_window_low; - b = pmxi->dir.w.dd.mxi.a32_window_high; - printf(", A32 window 0x%X-0x%X", - a, - b); - } -# ifdef BASE_PLUS_SIZE_MXI_SUPPORT - else{ - la = VXIADDRMASK & - pmxi->dir.w.dd.mxi.la_window; - ha = la + (MXI_LA_WINDOW_SIZE_MASK & - (pmxi->dir.w.dd.mxi.la_window>>NVXIADDRBITS)); - - printf(", LA window 0x%X-0x%X", - la, - ha); - } -# endif -} - - -/* - * - * vxi_allocate_int_lines() - * - * - */ -LOCAL void vxi_allocate_int_lines(void) -{ - EPVXISTAT status; - struct vxi_csr *pcsr; - VXIDI **ppvxidi; - VXIDI *pvxidi; - unsigned la; - unsigned long resp; - unsigned long cmd; - unsigned line_count; - - for( la=0, ppvxidi = epvxiLibDeviceList; - ppvxidi < epvxiLibDeviceList+NELEMENTS(epvxiLibDeviceList); - ppvxidi++, la++){ - - pvxidi = *ppvxidi; - - if(!pvxidi){ - continue; - } - - pcsr = VXIBASE(la); - - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - continue; - } - - /* - * dont do this step for the top level slot zero device - */ - if (root_extender.pSZD) { - if (la == root_extender.pSZD->la) { - continue; - } - } - - /* - * find out if this is a programmable interrupter - */ - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_PROTOCOL, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected READ_PROTOCOL (LA=0x%X)", - la); - continue; - } - if(!MBR_RP_PI(resp)){ - continue; - } - - printf("Programming interrupter (LA=0x%X)\n", la); - - cmd = MBC_READ_INTERRUPTERS; - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected READ_INTERRUPTERS (LA=0x%X)", - la); - continue; - } - line_count = resp&MBR_READ_INTERRUPTERS_MASK; - while(line_count--){ - cmd = MBC_ASSIGN_INTERRUPTER_LINE | - ((line_count+1)<<4) | - VXIMSGINTLEVEL; - status = devEnableInterruptLevel (intVXI, VXIMSGINTLEVEL); - if(status){ - errPrintf (status, __FILE__, __LINE__, - "Unable to enable VXI msg int level"); - continue; - } - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected ASSIGN_INT(LA=0x%X)", - la); - continue; - } - if(MBR_STATUS(resp) != MBR_STATUS_SUCCESS){ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "ASSIGN_INT failed (LA=0x%X)", - la); - continue; - } - } - } -} - - - - -/* - * - * epvxiSymbolTableInit() - * (written by Richard Baker LANL summer intern) - * - */ -LOCAL EPVXISTAT epvxiSymbolTableInit(void) -{ - - epvxiSymbolTable = symTblCreate( - EPVXI_MAX_SYMBOLS_LOG2, - FALSE, - memSysPartId); - if(!epvxiSymbolTable){ - return S_epvxi_noMemory; - } - - return VXI_SUCCESS; -} - - -/* - * - * epuxiRegisterModelName() - * (written by Richard Baker LANL summer intern) - * - * - */ -EPVXISTAT epvxiRegisterModelName( -unsigned int make, -unsigned int model, -char *pmodel_name -) -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pcopy; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableDeviceIdString, make,model); - pcopy = (char *) malloc(strlen(pmodel_name)+1); - if(pcopy == NULL){ - return S_epvxi_noMemory; - } - - strcpy(pcopy, pmodel_name); - - status = symAdd( - epvxiSymbolTable, - name, - pcopy, - EPVXI_MODEL_NAME_SYMBOL, - NULL); - if(status < 0){ - char *pold_model_name; - SYM_TYPE type; - - free(pcopy); - status = symFindByNameAndTypeEPICS( - epvxiSymbolTable, - name, - &pold_model_name, - &type, - EPVXI_MODEL_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMemory; - } - else if(strcmp(pmodel_name, pold_model_name)){ - return S_epvxi_nameMismatch; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * epvxiRegisterMakeName() - * - * - */ -EPVXISTAT epvxiRegisterMakeName( -unsigned int make, -char *pmake_name -) -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pcopy; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableMakeIdString, make); - pcopy = (char *) malloc(strlen(pmake_name)+1); - if(pcopy == NULL){ - return S_epvxi_noMemory; - } - - strcpy(pcopy, pmake_name); - - status = symAdd( - epvxiSymbolTable, - name, - pcopy, - EPVXI_MAKE_NAME_SYMBOL, - NULL); - if(status<0){ - char *pold_make_name; - SYM_TYPE type; - - free(pcopy); - - status = symFindByNameAndTypeEPICS( - epvxiSymbolTable, - name, - &pold_make_name, - &type, - EPVXI_MAKE_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMemory; - } - else if(strcmp(pmake_name, pold_make_name)){ - return S_epvxi_nameMismatch; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * epuxiLookupMakeName() - * (written by Richard Baker LANL summer intern) - * - */ -EPVXISTAT epuxiLookupMakeName( -unsigned int make, /* VXI manuf. */ -char *pbuffer, /* model name return */ -unsigned int bufsize, /* size of supplied buf */ -unsigned int *preadcount) /* n bytes written */ -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pmake_name; - SYM_TYPE type; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableMakeIdString, make); - status = symFindByNameAndTypeEPICS( - epvxiSymbolTable, - name, - &pmake_name, - &type, - EPVXI_MAKE_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMatch; - } - if(type != EPVXI_MAKE_NAME_SYMBOL){ - abort(0); - } - *preadcount = min(strlen(pmake_name)+1, bufsize); - strncpy(pbuffer, pmake_name, bufsize); - - return VXI_SUCCESS; -} - - -/* - * - * epuxiLookupModelName() - * (written by Richard Baker LANL summer intern) - * - */ -EPVXISTAT epuxiLookupModelName( -unsigned int make, /* VXI manuf. */ -unsigned int model, /* VXI model code */ -char *pbuffer, /* model name return */ -unsigned int bufsize, /* size of supplied buf */ -unsigned int *preadcount) /* n bytes written */ -{ - char name[EPVXI_MAX_SYMBOL_LENGTH]; - char *pmodel_name; - SYM_TYPE type; - EPVXISTAT status; - - if(!epvxiSymbolTable){ /* initialize table at 1st call */ - status = epvxiSymbolTableInit(); - if(status){ - return status; - } - } - - sprintf(name, epvxiSymbolTableDeviceIdString, make, model); - status = symFindByNameAndTypeEPICS( - epvxiSymbolTable, - name, - &pmodel_name, - &type, - EPVXI_MODEL_NAME_SYMBOL, - ~0); - if(status<0){ - return S_epvxi_noMatch; - } - if(type != EPVXI_MODEL_NAME_SYMBOL){ - abort(0); - } - *preadcount = min(strlen(pmodel_name)+1, bufsize); - strncpy(pbuffer, pmodel_name, bufsize); - - return VXI_SUCCESS; -} - - -/* - * - * epvxiExtenderList() - * - * list any bus extenders - */ -EPVXISTAT epvxiExtenderList(void) -{ - epvxiExtenderPrint(&root_extender); - - return VXI_SUCCESS; -} - - - -/* - * - * epvxiExtenderPrint - * - * - */ -LOCAL void epvxiExtenderPrint(VXIE *pvxie) -{ - VXIE *psubvxie; - - - printf( "%s Extender LA=0x%02X\n", - ext_type_name[pvxie->type], - pvxie->la); - - if(pvxie->la_mapped){ - printf("\tLA window 0x%02X - 0x%02X\n", - pvxie->la_low, - pvxie->la_high); - } - - if(pvxie->A24_mapped){ - printf("\tA24 window base=0x%08lX size=0x%08lX\n", - pvxie->A24_base, - pvxie->A24_size); - } - - if(pvxie->A32_mapped){ - printf("\tA32 window base=0x%08lX size=0x%08lX\n", - pvxie->A32_base, - pvxie->A32_size); - } - - psubvxie = (VXIE *) &pvxie->extenders.node; - while( (psubvxie = (VXIE *) ellNext((ELLNODE *)psubvxie)) ){ - epvxiExtenderPrint(psubvxie); - } -} - - -/* - * - * register some common manufacturer names - * for consistency - * - */ -LOCAL void epvxiRegisterCommonMakeNames(void) -{ - int i; - EPVXISTAT status; - - for(i=0; i -#include -#include - -/* - * Structure used to specify search patterns for epvxiLookupLA() - * - * Set a bit in the flags member for each item that is to be a - * constraint on the search. All other items are ignored during - * the search. The callback routine will be called for all devices - * which exactly match all items specified in the flags field - */ -#define VXI_DSP_make (1<<0) -#define VXI_DSP_model (1<<1) -#define VXI_DSP_class (1<<2) -#define VXI_DSP_slot (1<<3) -#define VXI_DSP_slot_zero_la (1<<4) -#define VXI_DSP_commander_la (1<<5) -#define VXI_DSP_extender_la (1<<6) /* id crates that have one */ - -typedef struct { - long flags; /* one bit enabling each field */ - unsigned short make; /* manufacture identification */ - unsigned short model; /* model code for the device */ - unsigned short class; /* vxi device class */ - unsigned char slot; /* slot where the device resides */ - unsigned char slot_zero_la; /* logical address of slot 0 dev */ - unsigned char commander_la; /* logical address of commander */ - unsigned char extender_la; /* logical address of bus repeater */ -}epvxiDeviceSearchPattern; - -typedef long EPVXISTAT; - -/* - * functions from epvxiLib.c - */ -EPVXISTAT epvxiResman( - void -); - -EPVXISTAT epvxiIOReport( - unsigned level -); - -EPVXISTAT epvxiDeviceList( - void -); - -EPVXISTAT epvxiCrateList( - void -); - -EPVXISTAT epvxiExtenderList( - void -); - -EPVXISTAT epvxiUniqueDriverID( - void -); - -EPVXISTAT epvxiDeviceVerify( - unsigned la -); - -EPVXISTAT epvxiOpen( - unsigned la, - int vxiDriverID, - unsigned long driverConfigSize, - void (*pio_report_func)() -); - -EPVXISTAT epvxiClose( - unsigned la, - int vxiDriverID -); - -EPVXISTAT epvxiLookupLA( - epvxiDeviceSearchPattern - *pdsp, - void (*pfunc)(unsigned, void *), - void *parg -); - -EPVXISTAT epvxiRouteTriggerECL( - 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 */ -); - -EPVXISTAT epvxiRouteTriggerTTL( - 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 */ -); - -EPVXISTAT epvxiRegisterModelName( - unsigned int make, - unsigned int model, - char *pmodel_name -); - -EPVXISTAT epvxiRegisterMakeName( - unsigned int make, - char *pmake_name -); - -EPVXISTAT epuxiLookupModelName( - unsigned int make, /* VXI manuf. */ - unsigned int model, /* VXI model code */ - char *pbuffer, /* model name return */ - unsigned int bufsize, /* size of supplied buf */ - unsigned int *preadcount /* n bytes written */ -); - -EPVXISTAT epuxiLookupMakeName( - unsigned int make, /* VXI manuf. */ - char *pbuffer, /* model name return */ - unsigned int bufsize, /* size of supplied buf */ - unsigned int *preadcount /* n bytes written */ -); - -EPVXISTAT vxi_init( /* compatibility */ - void -); - -EPVXISTAT vxi_io_report( /* compatibility */ - unsigned level -); - -/* - * functions from epvxiMsgLib.c - */ -EPVXISTAT epvxiCmd( - unsigned la, - unsigned long cmd -); -EPVXISTAT epvxiQuery( - unsigned la, - unsigned long *presp -); -EPVXISTAT epvxiCmdQuery( - unsigned la, - unsigned long cmd, - unsigned long *presp -); -EPVXISTAT epvxiRead( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -); -#define epvxiReadOptNone 0 - -EPVXISTAT epvxiWrite( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pwrite_count, - unsigned long option -); -#define epvxiWriteOptNone 0 -#define epvxiWriteOptPartialMsg 1 /* message continues after this transfer */ - -EPVXISTAT epvxiSetTimeout( - unsigned la, - unsigned long timeout -); - -/* - * epvxiLib return codes (also used by epvxiMsgLib) - * - * These codes changed to the EPICS standrd format on 033193 - */ -#define VXI_SUCCESS 0 /* normal successful completion*/ -#define S_epvxi_noDevice (M_epvxi|1) /*device does not exist*/ -#define S_epvxi_notSlotZero (M_epvxi|2) /*not a slot zero devic*/ -#define S_epvxi_uknDevice (M_epvxi|3) /*device not supported*/ -#define S_epvxi_badTrigger (M_epvxi|4) /*specified trigger does not exist*/ -#define S_epvxi_badTrigIO (M_epvxi|5) /*specified trigger io does not exist*/ -#define S_epvxi_deviceOpen (M_epvxi|6) /*device already open*/ -#define S_epvxi_notOwner (M_epvxi|7) /*device in use by a different driver*/ -#define S_epvxi_noMemory (M_epvxi|8) /*memory allocation failed*/ -#define S_epvxi_notOpen (M_epvxi|9) /*device not open*/ -#define S_epvxi_notMsgDevice (M_epvxi|10) /*operation requires a message based device*/ -#define S_epvxi_deviceTMO (M_epvxi|11) /*message based dev timed out*/ -#define S_epvxi_msgDeviceFailure (M_epvxi|12) /*message based dev failed*/ -#define S_epvxi_badLA (M_epvxi|13) /*logical addr out of range*/ -#define S_epvxi_multipleQueries (M_epvxi|14) /*multiple queries serial protocol error*/ -#define S_epvxi_unsupportedCmd (M_epvxi|15) /*unsupported cmd serial protocol error*/ -#define S_epvxi_dirViolation (M_epvxi|16) /*DIR violation serial protocol error*/ -#define S_epvxi_dorViolation (M_epvxi|17) /*DOR violation serial protocol error*/ -#define S_epvxi_rrViolation (M_epvxi|18) /*RR violation serial protocol error*/ -#define S_epvxi_wrViolation (M_epvxi|19) /*WR violation serial protocol error*/ -#define S_epvxi_errFetchFailed (M_epvxi|20) /*unknown serial protocol error*/ -#define S_epvxi_selfTestFailed (M_epvxi|21) /*self test failed*/ -#define S_epvxi_timeoutToLarge (M_epvxi|22) /*specified timeout to long*/ -#define S_epvxi_protocolError (M_epvxi|23) /*protocol error*/ -#define S_epvxi_unreadData (M_epvxi|24) /*attempt to write when unread data from a previous command is present (RULE C.3.3)*/ -#define S_epvxi_nameMismatch (M_epvxi|25) /*make or model name already registered does not matchi supplied name*/ -#define S_epvxi_noMatch (M_epvxi|26) /*no name registered for the supplied make and or model*/ -#define S_epvxi_bufferFull (M_epvxi|27) /*read terminated with unread data remaining because the end of the supplied buffer was reached*/ -#define S_epvxi_noResman (M_epvxi|28) /*the VXI resource manager must run first*/ -#define S_epvxi_internal (M_epvxi|29) /*VXI internal failure*/ -#define S_epvxi_badConfig (M_epvxi|30) /*Incorrect system configuration*/ -#define S_epvxi_noCmdr (M_epvxi|31) /*No commander hardware support for message based comm - continuing*/ -#define S_epvxi_msgDeviceStatus (M_epvxi|32) /*VXI Message based device reporting error condition*/ -#define S_epvxi_slotNotFound (M_epvxi|33) /*VXI device's slot not found- MODID failure?*/ -#define S_epvxi_noMODID (M_epvxi|34) /*VXI device does not have MODID capability*/ - - -enum ext_type { ext_local_cpu, /* bus master constrained by module_types.h */ - ext_export_vxi_onto_mxi, /* VXI mapped into MXI addr space */ - ext_import_mxi_into_vxi /* MXI mapped into VXI addr space */ - /* - . - . - other bus extender types could be inserted here - . - . - */ - }; - -#ifndef SRCepvxiLib -extern -#endif -char *ext_type_name[] -#ifdef SRCepvxiLib - = { - "VXI hosted VME bus master", - "VXI mapped onto MXI addr space", - "MXI mapped into VXI addr space" - } -#endif -; - -typedef struct extender_device{ - ELLNODE node; - ELLLIST extenders; /* sub extenders */ - struct extender_device *pParent; - struct slot_zero_device *pSZD; - enum ext_type type; - int la; - int la_low; /* inclusive */ - int la_high; /* inclusive */ - unsigned long A24_base; - unsigned long A24_size; - unsigned long A32_base; - unsigned long A32_size; - unsigned la_mapped:1; /* device present */ - unsigned A24_mapped:1; - unsigned A32_mapped:1; - unsigned A24_ok:1; - unsigned A32_ok:1; -}VXIE; - -/* - * bits for the device type and a pointer - * to its configuration registers if - * available - */ -typedef struct slot_zero_device{ - ELLNODE node; - void (*set_modid)(struct slot_zero_device *pvxisz, unsigned slot); - void (*clear_modid)(struct slot_zero_device *pvxisz); - EPVXISTAT (*report)(unsigned la, unsigned level); - VXIE *pvxie; - struct vxi_csr *pcsr; - unsigned char la; - unsigned reg:1; - unsigned msg:1; -}VXISZ; - -typedef struct epvxiLibDeviceConfig{ - void (*pio_report_func)(); /* ptr to io report func */ - void *pDriverConfig; /* ptr to driver config */ - void *pMsgConfig; /* msg driver config area */ - void *pFatAddrBase; - VXIE *pvxie; /* extender info */ - VXIE *pvxieSelf; /* extender info for self */ - VXISZ *pvxisz; /* ptr to slot zero info */ - unsigned long driverID; /* unique driver id */ - int taskID; /* opened by this id */ - unsigned short make; - unsigned short model; - short slot; - short commander_la; - short extender_la; /* logical address of bus repeater */ - unsigned char class; - unsigned st_passed:1; /* self test passed */ - unsigned msg_dev_online:1; - unsigned A24_mapped:1; - unsigned A32_mapped:1; -}VXIDI; - -/* - * - * - * functions used from the nivxi library - * (to support runtime linking) - * - */ -enum nivxi_func_index { - e_SetMODID, - e_VXIinLR, - e_InitVXIlibrary, - e_vxiinit, - e_MapTrigToTrig, - e_GetMyLA, - e_EnableSignalInt, - e_SetSignalHandler, - e_RouteSignal - }; -#ifndef SRCepvxiLib -extern -#endif -char *nivxi_func_names[] -#ifdef SRCepvxiLib - = { - "_SetMODID", - "_VXIinLR", - "_InitVXIlibrary", - "_vxiinit", /* WARNING this is different than vxiInit */ - "_MapTrigToTrig", - "_GetMyLA", - "_EnableSignalInt", - "_SetSignalHandler", - "_RouteSignal" - } -#endif -; - -#ifdef SRCepvxiLib -int (*pnivxi_func[NELEMENTS(nivxi_func_names)])(); -#else -extern -int (*pnivxi_func[])(); -#endif - - -/* - * - * typical usage - * - * struct freds_driver_info pfdi; - * - * pfdi = epvxiPConfig(14, driverID, (struct freds_driver_info *)) - * - * RETURNS ptr to device config area or NULL - */ -#define PVXIDI(LA) (epvxiLibDeviceList[LA]) -#define epvxiPConfig(LA, ID, CAST) \ -( \ -PVXIDI(LA)? \ - PVXIDI(LA)->driverID==(ID)? \ - (CAST) PVXIDI(LA)->pDriverConfig \ - : \ - (CAST) NULL \ -: \ - (CAST) NULL \ -) - -/* - * epvxiFetchPConfig - * (improved version of the above returns status) - */ -#define epvxiFetchPConfig(LA, ID, PTR) \ -( \ -PVXIDI(LA)!=NULL? \ - (PVXIDI(LA)->driverID==(ID)? \ - (((PTR) = PVXIDI(LA)->pDriverConfig), VXI_SUCCESS) \ - : \ - S_epvxi_notOwner) \ -: \ - S_epvxi_noDevice \ -) - -/* - * A24 and A32 base addressing - */ -#define epvxiA24Base(LA) (PVXIDI(LA)->pFatAddrBase) -#define epvxiA32Base(LA) (PVXIDI(LA)->pFatAddrBase) - -#ifndef SRCepvxiLib -extern -#endif -VXIDI *epvxiLibDeviceList[NVXIADDR]; - -#define NO_DRIVER_ATTACHED_ID (0) -#define UNINITIALIZED_DRIVER_ID (0xffff) -#ifndef SRCepvxiLib -extern -#endif -unsigned long epvxiNextDriverID -#ifdef SRCepvxiLib -= (NO_DRIVER_ATTACHED_ID+1) -#endif -; - -/* - * set by the RM when it is done and VXI modules are present - */ -#ifndef SRCepvxiLib -extern -#endif -int epvxiResourceMangerOK; - -#ifndef SRCepvxiLib -extern -#endif -volatile void *epvxi_local_base; - -#define VXIBASE(LA) VXI_LA_TO_PA(LA, epvxi_local_base) - -#endif /* INCepvxiLibh */ diff --git a/src/drv/ansi/drvEpvxiMsg.c b/src/drv/ansi/drvEpvxiMsg.c deleted file mode 100644 index af7b7815a..000000000 --- a/src/drv/ansi/drvEpvxiMsg.c +++ /dev/null @@ -1,1535 +0,0 @@ -/* - * base/src/drv $Id$ - * driver for VXI message based devices - * - * Author: Jeff Hill - * Date: 042792 - * - * 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 042792 first release - * .02 joh 052292 Always append a NULL even if at the end of - * the buffer in vxi_read() - * .03 joh 060292 Added debug mode - * .04 joh 072992 added signal register for the HP1404 - * .05 joh 082592 added arg to epvxiRead() and epvxiWrite() - * .06 joh 072393 better test for nonexistent device during - * msg open - * - * Improvements - * ------------ - * .01 joh 051992 Some work on fast handshake exists in this file. - * If a card with fast handshake is found to exist - * then this code will be tested and uncommented. - * - */ - -static char *sccsId = "@(#)drvEpvxiMsg.c 1.15\t8/27/93"; - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include - -enum msgDeviceSyncType { - syncInt, - syncSignal, - syncPoll -}; - -typedef -struct epvxiMessageDeviceInfo{ - unsigned err:1; /* error pending */ - unsigned trace:1; /* debug trace on */ - unsigned long timeout; /* in ticks */ - enum msgDeviceSyncType syncType; - SEM_ID syncSem; - FAST_LOCK lck; -}VXIMDI; - -#define VXIMSGSYNCDELAY 1 - -#define DEFAULTMSGTMO (sysClkRateGet()*10) /* 10 sec */ -#define MAXIMUMTMO (0xffffff) - -/* - * set to a valid LA when the LA of the - * commander is located - */ -LOCAL -int msgCommanderLA = (-1); - - -#define abort(A) taskSuspend(0) - -#define epvxiPMsgConfig(LA)\ -((VXIMDI *)(epvxiLibDeviceList[LA]?epvxiLibDeviceList[LA]->pMsgConfig:0)) - -/* - * local functions - */ -LOCAL void set_la( - unsigned la, - void *pLA -); - -LOCAL void vxiMsgInt( - unsigned la -); - -LOCAL void signalHandler( - int16_t signal -); - -LOCAL EPVXISTAT epvxiReadSlowHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -); - -#ifdef FASTHANDSHAKE -LOCAL EPVXISTAT epvxiReadFastHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -); -#endif - -LOCAL EPVXISTAT vxiMsgClose( - unsigned la -); - -LOCAL EPVXISTAT vxiMsgOpen( - unsigned la -); - -LOCAL void vxiMsgSignalSetup( - void -); - -LOCAL void vxiCPU030MsgSignalSetup( - void -); - -LOCAL void vxiHP1404MsgSignalSetup( - void -); - -LOCAL EPVXISTAT vxiAttemptAsyncModeControl( - unsigned la, - unsigned long cmd -); - -LOCAL EPVXISTAT vxiMsgSync( - unsigned la, - unsigned resp_mask, - unsigned resp_state, - int override_err -); - -LOCAL EPVXISTAT fetch_protocol_error( - unsigned la -); - - -/* - * should be in a header - */ -EPVXISTAT vxi_msg_test( - unsigned la -); - -EPVXISTAT vxi_msg_print_id( - unsigned la -); - -EPVXISTAT vxi_msg_test_protocol_error( - unsigned la -); - - -/* - * - * vxi_msg_test() - * - */ -EPVXISTAT vxi_msg_test( - unsigned la -) -{ - char buf[512]; - unsigned long count; - EPVXISTAT status; - - status = epvxiWrite(la, "*IDN?", 5, &count, epvxiWriteOptNone); - if(status != VXI_SUCCESS){ - return status; - } - status = epvxiRead(la, buf, sizeof(buf)-1, &count, epvxiReadOptNone); - if(status != VXI_SUCCESS){ - return status; - } - - buf[count] = '\0'; - printf("%s %ld\n", buf,count); - - status = epvxiWrite(la, "*TST?", 5, &count, epvxiWriteOptNone); - if(status != VXI_SUCCESS){ - return status; - } - status = epvxiRead(la, buf, sizeof(buf)-1, &count, epvxiReadOptNone); - if(status != VXI_SUCCESS){ - return status; - } - - buf[count] = '\0'; - printf("%s %ld\n", buf, count); - - return VXI_SUCCESS; -} - - -/* - * - * vxi_msg_print_id - * - */ -EPVXISTAT vxi_msg_print_id( - unsigned la -) -{ - char buf[32]; - unsigned long count; - char *pcmd = "*IDN?"; - EPVXISTAT status; - - status = epvxiWrite(la, pcmd, strlen(pcmd), &count, epvxiWriteOptNone); - if(status != VXI_SUCCESS){ - return status; - } - status = epvxiRead(la, buf, sizeof(buf)-1, &count, epvxiReadOptNone); - if(status != VXI_SUCCESS){ - return status; - } - - buf[count] = '\0'; - printf(" %s ", buf); - - return VXI_SUCCESS; -} - - -/* - * - * vxi_msg_test_protocol_error - * - */ -EPVXISTAT vxi_msg_test_protocol_error( - unsigned la -) -{ - int i; - EPVXISTAT status; - - for(i=0;i<1000;i++){ - status = epvxiCmd(la, MBC_READ_PROTOCOL); - if(status){ - return status; - } - } - return VXI_SUCCESS; -} - - -/* - * epvxiCmd() - * - * deliver a command to a msg based device - * - */ -EPVXISTAT epvxiCmd( -unsigned la, -unsigned long cmd -) -{ - struct vxi_csr *pcsr; - VXIMDI *pvximdi; - EPVXISTAT status; - -# ifdef DEBUG - printf("cmd to be sent %4x (la=%d)\n", cmd, la); -# endif - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - - /* - * RULE C.3.3 - * A commander shall not send any command requiring a servant to - * place data in in its data registers until the commander has read - * (from the data registers) all data generated by previous commands - * (and the read ready bit is set to zero). - */ - status = vxiMsgSync( - la, - VXIWRITEREADYMASK|VXIREADREADYMASK, - VXIWRITEREADYMASK, - cmd == MBC_CLEAR); - if(status>=0){ - pcsr->dir.w.dd.msg.dlow = cmd; - } - else{ - /* - * RULE C.3.2 - */ - if(pcsr->dir.r.dd.msg.response&VXIREADREADYMASK){ - status = S_epvxi_unreadData; - } - } - - FASTUNLOCK(&pvximdi->lck); - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Cmd -> %lx\n", - la, - cmd); - } - - return status; -} - - - -/* - * epvxiQuery() - * - * query the response to a command - * - */ -EPVXISTAT epvxiQuery( -unsigned la, -unsigned long *presp -) -{ - struct vxi_csr *pcsr; - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - - status = vxiMsgSync( - la, - VXIREADREADYMASK, - VXIREADREADYMASK, - FALSE); - if(status==VXI_SUCCESS){ - *presp = pcsr->dir.r.dd.msg.dlow; - } - - FASTUNLOCK(&pvximdi->lck); - -# ifdef DEBUG - printf("resp returned %4x (la=%d)\n", *presp, la); -# endif - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Query -> %lx\n", - la, - *presp); - } - - return status; -} - - -/* - * epvxiCmdQuery() - */ -EPVXISTAT epvxiCmdQuery( -unsigned la, -unsigned long cmd, -unsigned long *presp -) -{ - EPVXISTAT status; - - status = epvxiCmd(la, cmd); - if(status){ - return status; - } - status = epvxiQuery(la, presp); - return status; -} - - -/* - * epvxiRead() - * - * Read a string using fast handshake mode - * or call a routine to do a slow handshake - * if that is all that is supported. - */ -EPVXISTAT epvxiRead( -unsigned la, -char *pbuf, -unsigned long count, -unsigned long *pread_count, -unsigned long option -) -{ - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - /* - * does the device support fast handshake - */ -# ifdef FASTHANDSHAKE - if(VXIFHS(pcsr)){ - status = epvxiReadFastHandshake( - la, - pbuf, - count, - pread_count, - option); - } - else{ -# endif - status = epvxiReadSlowHandshake( - la, - pbuf, - count, - pread_count, - option); -# ifdef FASTHANDSHAKE - } -# endif - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Read -> %*s\n", - la, - (int)count, - pbuf); - } - - return status; -} - - -#ifdef FASTHANDSHAKE -@@@@ needs to tell them if their buffer is full - and the EOM bit wasnt se @@@@ -/* - * epvxiReadFastHandshake() - * - * Read a string using fast handshake mode - * or call a routine to do a slow handshake - * if that is all that is supported. - * - * This function will be tested and installed - * if a card with fast handshake s found to exist - * - */ -LOCAL EPVXISTAT epvxiReadFastHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -) -{ - struct vxi_csr *pcsr; - VXIMDI *pvximdi; - short resp; - int fhm; - short cmd; - EPVXISTAT status; - int i; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - fhm = FALSE; - /* - * always leave room to write a NULL termination - */ - for(i=0; i<(count-1); i++){ - - while(TRUE){ - /* - * wait for fast handshake mode - */ - if(!fhm){ - status = vxiMsgSync( - la, - VXIFHSMMASK, - 0, - FALSE); - if(status){ - *pread_count = i; - goto exit; - } - fhm = TRUE; - } - - cmd = MBC_BR; - status = devReadProbe (sizeof(cmd), - &pcsr->dir.r.dd.msg.dlow, &cmd); - if(status == SUCCESS){ - break; - } - fhm = FALSE; - } - - while(TRUE){ - /* - * wait for fast handshake mode - */ - if(!fhm){ - status = vxiMsgSync( - la, - VXIFHSMMASK, - 0, - FALSE); - if(status){ - *pread_count = i; - goto exit; - } - fhm = TRUE; - } - status = devReadProbe (sizeof(resp), - &pcsr->dir.r.dd.msg.dlow, &resp); - if(status == SUCCESS){ - break; - } - fhm = FALSE; - } - - *pbuf = resp; - pbuf++; - if(resp & MBC_END){ - *pread_count = i+1; - break; - } - } - status = VXI_SUCCESS; -exit: - FASTUNLOCK(&pvximdi->lck); - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - *pbuf = NULL; - - return status; -} -#endif - - -/* - * epvxiReadSlowHandshake() - */ -LOCAL -EPVXISTAT epvxiReadSlowHandshake( - unsigned la, - char *pbuf, - unsigned long count, - unsigned long *pread_count, - unsigned long option -) -{ - VXIMDI *pvximdi; - struct vxi_csr *pcsr; - uint16_t resp; - EPVXISTAT status; - int function_status; - unsigned long i; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - /* - * always leave room to write a NULL termination - */ - if(count<1){ - return S_epvxi_bufferFull; - } - - FASTLOCK(&pvximdi->lck); - - /* - * always leave room to write a NULL termination - */ - function_status = S_epvxi_bufferFull; - for(i=0; i<(count-1); i++){ - - /* - * wait for handshake - * - * RULE C.3.3 specifies that there shouldnt be - * any unread data present at this point . - */ - status = vxiMsgSync( - la, - VXIWRITEREADYMASK|VXIDORMASK|VXIREADREADYMASK, - VXIWRITEREADYMASK|VXIDORMASK, - FALSE); - if(status){ - if(pcsr->dir.r.dd.msg.response&VXIREADREADYMASK){ - function_status = S_epvxi_unreadData; - } - else{ - function_status = status; - } - break; - } - - pcsr->dir.w.dd.msg.dlow = MBC_BR; - - /* - * wait for handshake - */ - status = vxiMsgSync( - la, - VXIREADREADYMASK, - VXIREADREADYMASK, - FALSE); - if(status){ - function_status = status; - break; - } - - resp = pcsr->dir.r.dd.msg.dlow; - - *pbuf = resp; - pbuf++; - if(resp & MBC_END){ - - /* - * so the read count will be correct below - */ - i++; - function_status = VXI_SUCCESS; - break; - } - } - FASTUNLOCK(&pvximdi->lck); - - *pread_count = i; - - /* - * append the NULL - */ - *pbuf = '\0'; - - if(function_status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - return function_status; -} - - -/* - * epvxiWrite() - * (set the end bit on the last byte sent) - */ -EPVXISTAT epvxiWrite( -unsigned la, -char *pbuf, -unsigned long count, -unsigned long *pwrite_count, -unsigned long option -) -{ - VXIMDI *pvximdi; - struct vxi_csr *pcsr; - unsigned long i; - uint16_t cmd; - uint16_t extra; - EPVXISTAT status; - uint8_t *pstr; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pvximdi->lck); - pstr = (uint8_t *) pbuf; - if(option&epvxiWriteOptPartialMsg){ - extra = 0u; - } - else{ - extra = MBC_END; - } - for(i=0u; idir.r.dd.msg.dlow = cmd; - pstr++; - } - *pwrite_count = i; - status = VXI_SUCCESS; -exit: - FASTUNLOCK(&pvximdi->lck); - - if(status == S_epvxi_protocolError){ - return fetch_protocol_error(la); - } - - if(pvximdi->trace){ - printf( "VXI Trace: (la=0X%X) Write -> %*s\n", - la, - (int)count, - pbuf); - } - - return status; -} - - -/* - * - * epvxiSetTimeout() - * - * change the message based transfer timeout - * (timeout is in milli sec) - * - */ -EPVXISTAT epvxiSetTimeout( -unsigned la, -unsigned long timeout -) -{ - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - /* - * order of operations significant here - */ - if(timeout > MAXIMUMTMO){ - return S_epvxi_timeoutToLarge; - } - - pvximdi->timeout = (timeout * sysClkRateGet())/1000; - - return VXI_SUCCESS; -} - - -/* - * - * epvxiSetTraceEnable() - * - * turn trace mode on or off - * - */ -EPVXISTAT epvxiSetTraceEnable(la, enable) -unsigned la; -int enable; -{ - VXIMDI *pvximdi; - EPVXISTAT status; - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pvximdi->trace = enable?TRUE:FALSE; - - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgClose() - * - * - */ -LOCAL -EPVXISTAT vxiMsgClose( -unsigned la -) -{ - EPVXISTAT status; - VXIMDI *pvximdi; - - pvximdi = epvxiPMsgConfig(la); - if(!pvximdi){ - return S_epvxi_notOpen; - } - - status = semDelete(pvximdi->syncSem); - if(status){ - errMessage( - S_epvxi_internal, - "vxiMsgClose(): bad sem id"); - } - FASTLOCKFREE(&pvximdi->lck); - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgOpen() - * - * - */ -LOCAL -EPVXISTAT vxiMsgOpen( - unsigned la -) -{ - EPVXISTAT status; - VXIDI *pvxidi; - VXIMDI *pvximdi; - unsigned long resp; - unsigned long read_proto_resp; - unsigned long cmd; - struct vxi_csr *pcsr; - int signalSync = FALSE; - int intSync = FALSE; - - - /* - * return quickly if we have been here before - */ - pvxidi = epvxiLibDeviceList[la]; - if(pvxidi){ - if(pvxidi->pMsgConfig){ - return VXI_SUCCESS; - } - } - - /* - * standard verification of unknown LA - */ - status = epvxiDeviceVerify(la); - if(status){ - return status; - } - - pcsr = VXIBASE(la); - if(VXICLASS(pcsr) != VXI_MESSAGE_DEVICE){ - return S_epvxi_notMsgDevice; - } - - pvximdi = (VXIMDI *) calloc(1, sizeof(*pvximdi)); - if(!pvximdi){ - return S_epvxi_noMemory; - } - - pvxidi->pMsgConfig = (void *) pvximdi; - - vxiMsgSignalSetup(); - - pvximdi->syncSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - if(!pvximdi->syncSem){ - return S_epvxi_noMemory; - } - - /* - * - * assume the worst for the transfers below - * - */ - pvximdi->timeout = DEFAULTMSGTMO; - pvximdi->syncType = syncPoll; - FASTLOCKINIT(&pvximdi->lck); - - /* - * if it is not an interrupter or a signal - * generator then we poll - */ - if(!VXIMBINT(pcsr) && !VXIVMEBM(pcsr)){ - return VXI_SUCCESS; - } - - /* - * if it is not a response generator then we poll - */ - status = epvxiCmdQuery( - la, - (unsigned long) MBC_READ_PROTOCOL, - &read_proto_resp); - if(status){ - /* - * All devices are required by the VXI standard - * to accept this command while in the - * configure state or in the normal operation - * state. Some dont. - * - */ - errPrintf( - status, - __FILE__, - __LINE__, - "Device rejected MBC_READ_PROTOCOL (la=0X%X)", - la); - return VXI_SUCCESS; - } - -return VXI_SUCCESS; - - if(!MBR_RP_RG(read_proto_resp)){ - return VXI_SUCCESS; - } - -printf("mb device has response gen\n"); - - /* - * try to setup interrupt synchronization first - * (this works even if we dont have a signal register) - */ - if(VXIMBINT(pcsr)){ - cmd = MBC_ASYNC_MODE_CONTROL | - MBC_AMC_RESP_ENABLE | - MBC_AMC_RESP_INT_ENABLE; - status = vxiAttemptAsyncModeControl(la, cmd); - if(status>=0){ - printf( "%s: mb device has int sync!\n", - __FILE__); - intSync = TRUE; - } - } - - /* - * hopefully a signal register is available if we get to here - */ - if(VXIVMEBM(pcsr) && !intSync && msgCommanderLA>=0){ - cmd = MBC_ASYNC_MODE_CONTROL | - MBC_AMC_RESP_ENABLE | - MBC_AMC_EVENT_ENABLE | - MBC_AMC_RESP_SIGNAL_ENABLE | - MBC_AMC_EVENT_SIGNAL_ENABLE; - status = vxiAttemptAsyncModeControl(la, cmd); - if(status>=0){ - printf( "%s: mb device has signal sync!\n", - __FILE__); - signalSync = TRUE; - } - } - - if(!intSync && !signalSync){ - errMessage( - S_epvxi_msgDeviceFailure, - "mb responder failed to configure"); - return VXI_SUCCESS; - } - - cmd = MBC_CONTROL_RESPONSE; - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errMessage( - status, - "Control response rejected by responder"); - vxiMsgClose(la); - return status; - } - if( MBR_STATUS(resp) != MBR_STATUS_SUCCESS || - (resp^cmd)&MBR_CR_CONFIRM_MASK){ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "Control Response Failed %x", - resp); - return VXI_SUCCESS; - } -printf("sent ctrl resp (la=%d) (cmd=%lx)\n", la, cmd); - -printf("synchronized msg based device is ready!\n"); - - if(intSync){ - pvximdi->syncType = syncInt; - } - if(signalSync){ - pvximdi->syncType = syncSignal; - } - - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgSignalSetup - * - * - */ -LOCAL -void vxiMsgSignalSetup( - void -) -{ - static char vxiMsgSignalInit; - - if(vxiMsgSignalInit){ - return; - } - - vxiMsgSignalInit = TRUE; - - vxiHP1404MsgSignalSetup(); - - if(msgCommanderLA<0){ - vxiCPU030MsgSignalSetup(); - } - - if(msgCommanderLA<0){ - errMessage( - S_epvxi_noCmdr, - NULL); - } -} - - -/* - * - * vxiCPU030MsgSignalSetup - * - * - */ -LOCAL void vxiCPU030MsgSignalSetup( - void -) -{ - int niMsgLA; - EPVXISTAT status; - - if( !pnivxi_func[(unsigned)e_EnableSignalInt] || - !pnivxi_func[(unsigned)e_SetSignalHandler] || - !pnivxi_func[(unsigned)e_RouteSignal] || - !pnivxi_func[(unsigned)e_GetMyLA]){ - return; - } - - niMsgLA = (*pnivxi_func[(unsigned)e_GetMyLA])(); - -# define ANY_DEVICE (-1) -# define MSG_RESP_ENABLE (0x3f) - status = (*pnivxi_func[(unsigned)e_RouteSignal])( - ANY_DEVICE, - ~0); /* enable every thing */ - if(status){ - return; - } - -# define UKN_DEVICE (-2) - status = (*pnivxi_func[(unsigned)e_SetSignalHandler])( - UKN_DEVICE, - signalHandler); - if(status){ - return; - } - - status = (*pnivxi_func[(unsigned)e_EnableSignalInt])(); - if(status){ - return; - } - - msgCommanderLA = niMsgLA; - - return; -} - - -/* - * - * vxiHP1404MsgSignalSetup - * - * - */ -LOCAL -void vxiHP1404MsgSignalSetup( - void -) -{ - epvxiDeviceSearchPattern dsp; - int hpMsgLA = -1; - int hpRegLA = -1; - EPVXISTAT status; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_HP_MODEL_E1404_MSG; - status = epvxiLookupLA(&dsp, set_la, (void *)&hpMsgLA); - if(status){ - return; - } - if(hpMsgLA<0){ - return; - } - dsp.flags = VXI_DSP_make | VXI_DSP_slot; - dsp.make = VXI_MAKE_HP; - dsp.slot = epvxiLibDeviceList[hpMsgLA]->slot; - status = epvxiLookupLA(&dsp, set_la, (void *)&hpRegLA); - if(status){ - return; - } - - if(hpRegLA<0){ - return; - } - - msgCommanderLA = hpMsgLA; - status = hpE1404SignalConnect(hpRegLA, signalHandler); - if(status){ - errMessage(status, NULL); - } - - return; -} - - -/* - * - * set_la - * - * - */ -LOCAL void set_la( -unsigned la, -void *pArg -) -{ - unsigned *pla = (unsigned *) pArg; - *pla = la; -} - - -/* - * - * vxiAttemptAsyncModeControl - * - * - */ -LOCAL EPVXISTAT vxiAttemptAsyncModeControl( - unsigned la, - unsigned long cmd -) -{ - EPVXISTAT status; - unsigned long resp; - unsigned long tmpcmd; - - if(msgCommanderLA<0 && cmd&MBC_AMC_RESP_SIGNAL_ENABLE){ - return S_epvxi_badConfig; - } - - /* - * this step tells the device what la to signal at - */ - if(cmd & MBC_AMC_RESP_SIGNAL_ENABLE){ - tmpcmd = MBC_IDENTIFY_COMMANDER | msgCommanderLA; - status = epvxiCmd( - la, - tmpcmd); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "IDENTIFY_COMMANDER rejected (la=0X%X)", - la); - return status; - } -printf("sent id cmdr (la=0X%X) (cmd=%lx)\n", la, tmpcmd); - } - - status = epvxiCmdQuery( - la, - cmd, - &resp); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "Async mode control rejected (la=0X%X)", - la); - return status; - } - if( MBR_STATUS(resp) != MBR_STATUS_SUCCESS || - (resp^cmd)&MBR_AMC_CONFIRM_MASK){ - status = S_epvxi_msgDeviceFailure; - errPrintf( - status, - __FILE__, - __LINE__, - "async mode ctrl failure (la=0X%X,cmd=%x,resp=%x)", - la, - cmd, - resp); - return status; - } -printf("sent asynch mode control (la=%d) (cmd=%lx)\n",la,cmd); - - - if(cmd & MBC_AMC_RESP_INT_ENABLE){ - intConnect( - INUM_TO_IVEC(la), - vxiMsgInt, - la); -printf("connected to interrupt (la=%d)\n", la); - } - - return VXI_SUCCESS; -} - - -/* - * - * vxiMsgSync() - * - * - */ -LOCAL EPVXISTAT vxiMsgSync( - unsigned la, - unsigned resp_mask, - unsigned resp_state, - int override_err -) -{ - VXIMDI *pvximdi; - struct vxi_csr *pcsr; - EPVXISTAT status; - long timeout; - unsigned short resp; - int pollcnt = 100; - - - while(!(pvximdi = epvxiPMsgConfig(la))){ - status = vxiMsgOpen(la); - if(status != VXI_SUCCESS){ - return status; - } - } - - pcsr = VXIBASE(la); - -# ifdef DEBUG - printf( "Syncing to resp mask %4x, request %4x (la=%d)\n", - resp_mask, - resp_state, - la); -# endif - - timeout = pvximdi->timeout; - do{ - int sync; - - resp = pcsr->dir.r.dd.msg.response; - - sync = !((resp^resp_state)&resp_mask); - - if(!(resp & VXIERRNOTMASK)){ - if(!override_err && !pvximdi->err){ - pvximdi->err = TRUE; - return S_epvxi_protocolError; - } - } - - if(sync){ - return VXI_SUCCESS; - } - - /* - * this improves VXI throughput at the - * expense of sucking CPU - */ - if(pollcnt>0){ - pollcnt--; - } - else{ - status = semTake( - pvximdi->syncSem, - VXIMSGSYNCDELAY); - if(status){ - timeout -= VXIMSGSYNCDELAY; - } - } - } - while(timeout>0); - - /* - * sync timed out if we got here - */ - status = S_epvxi_deviceTMO; - errPrintf( - status, - __FILE__, - __LINE__, - "msg dev timed out after %d sec", - (pvximdi->timeout-timeout) / sysClkRateGet()); - errPrintf( - status, - __FILE__, - __LINE__, - "resp mask %4x, request %4x, actual %4x", - resp_mask, - resp_state, - resp); - return status; -} - - -/* - * - * fetch_protocol_error - * - */ -LOCAL EPVXISTAT fetch_protocol_error( - unsigned la -) -{ - VXIMDI *pvximdi; - unsigned long error; - struct vxi_csr *pcsr; - unsigned short resp; - EPVXISTAT status; - - pvximdi = epvxiPMsgConfig(la); - if(!pvximdi){ - return S_epvxi_errFetchFailed; - } - - status = epvxiCmdQuery( - la, - (unsigned long)MBC_READ_PROTOCOL_ERROR, - &error); - if(status){ - errMessage(status, "serial protocol error fetch"); - return S_epvxi_errFetchFailed; - } - - pcsr = VXIBASE(la); - resp = pcsr->dir.r.dd.msg.response; - - if(resp & VXIERRNOTMASK){ - pvximdi->err = FALSE; - } - else{ - errPrintf( - S_epvxi_msgDeviceFailure, - __FILE__, - __LINE__, - "Device failed to clear its ERR bit (la=0X%X)", - la); - } - - switch(error){ - case MBE_MULTIPLE_QUERIES: - status = S_epvxi_multipleQueries; - break; - case MBE_UNSUPPORTED_CMD: - status = S_epvxi_unsupportedCmd; - break; - case MBE_DIR_VIOLATION: - status = S_epvxi_dirViolation; - break; - case MBE_DOR_VIOLATION: - status = S_epvxi_dorViolation; - break; - case MBE_RR_VIOLATION: - status = S_epvxi_rrViolation; - break; - case MBE_WR_VIOLATION: - status = S_epvxi_wrViolation; - break; - case MBE_NO_ERROR: - default: - status = S_epvxi_errFetchFailed; - break; - } - - errMessage(status, "serial protocol error"); - return status; -} - - -/* - * - * vxiMsgInt - * - * - */ -LOCAL -void vxiMsgInt( - unsigned la -) -{ - VXIMDI *pvximdi; - - /* - * verify that this device is open for business - */ - pvximdi = epvxiPMsgConfig(la); - if(pvximdi){ - - /* - * - * wakeup pending tasks - * - */ - semGive(pvximdi->syncSem); - } - else{ - logMsg ( - "%s: vxiMsgInt(): msg int to ukn or closed dev\n", - (int)__FILE__, - 0, - 0, - 0, - 0, - 0); - } -} - - - -/* - * signalHandler - */ -LOCAL -void signalHandler( -int16_t signal -) -{ - unsigned signal_la; - - signal_la = signal & VXIADDRMASK; - - if(MBE_EVENT_TEST(signal)){ - logMsg( "%s: VXI event was ignored %x\n", - (int)__FILE__, - signal, - 0, - 0, - 0, - 0); - } - else{ - vxiMsgInt(signal_la); - } -} diff --git a/src/drv/ansi/drvHp1404a.c b/src/drv/ansi/drvHp1404a.c deleted file mode 100644 index c3f04d271..000000000 --- a/src/drv/ansi/drvHp1404a.c +++ /dev/null @@ -1,414 +0,0 @@ -/* 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 -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include - -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, - void *pArg -); - -LOCAL int hpE1404ShutDown( - void -); - -LOCAL void hpE1404ShutDownLA( - unsigned la, - void *pArg -); - -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, - void *pArg -) -{ - struct vxi_csr *pcsr; - - pcsr = VXIBASE(la); - - pcsr->IRQ_enable = HP1404A_INT_DISABLE; -} - - -/* - * - * hpE1404InitLA() - * - */ -LOCAL -void hpE1404InitLA( - unsigned la, - void *pArg -) -{ - 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 -) -{ - - - - -} diff --git a/src/drv/ansi/drvHp1404a.h b/src/drv/ansi/drvHp1404a.h deleted file mode 100644 index f6f6d2bfb..000000000 --- a/src/drv/ansi/drvHp1404a.h +++ /dev/null @@ -1,74 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * drvHp1404a.h - * - * HP E1404A VXI bus slot zero translator - * device dependent routines header file - * - * share/src/drv/@(#)drvHp1404a.h 1.1 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: - * ----------------- - * - * - * - */ - -typedef long hpE1404Stat; - -hpE1404Stat hpE1404Init(void); - -hpE1404Stat hpE1404SignalConnect( - unsigned la, - void (*pSignalCallback)(int16_t signal) -); - -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 */ -); - -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 */ -); - -#define VXI_HP_MODEL_E1404_REG_SLOT0 0x10 -#define VXI_HP_MODEL_E1404_REG 0x110 -#define VXI_HP_MODEL_E1404_MSG 0x111 - - diff --git a/src/drv/ansi/drvHpe1368a.c b/src/drv/ansi/drvHpe1368a.c deleted file mode 100644 index b51f7c2de..000000000 --- a/src/drv/ansi/drvHpe1368a.c +++ /dev/null @@ -1,361 +0,0 @@ -/* drvHpe1368a.c*/ -/* base/src/drv $Id$ */ - -/* - * hpe1368a_driver.c - * - * driver for hpe1368a and hpe1369a microwave switch VXI modules - * - * Author: Jeff Hill - * Date: 052192 - * - * 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 071792 joh Added model name registration - * .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID - * .03 082692 mrk Added support for new I/O event scanning and DRVET - * .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals - * - */ - -static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93"; - -#include -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include - - -#define HPE1368A_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), hpe1368aDriverId, (PC)) - -#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08) -#define ModuleStatus(PCSR) ((PCSR)->dir.r.status) - -#define ALL_SWITCHES_OPEN 0 - -struct hpe1368a_config{ - FAST_LOCK lock; /* mutual exclusion */ - uint16_t pending; /* switch position pending int */ - uint16_t shadow; /* shadow of actual switch pos */ - int busy; /* relays active */ - IOSCANPVT ioscanpvt; -}; - -#define HPE1368A_INT_LEVEL 1 - -LOCAL int hpe1368aDriverId; - -LOCAL void hpe1368a_int_service(unsigned la); -LOCAL void hpe1368a_init_card(unsigned la, void *pArg); -LOCAL void hpe1368a_stat(unsigned la, int level); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvHpe1368a={ - 2, - NULL, /*VXI io report takes care of this */ - hpe1368a_init}; - - -/* - * hpe1368a_init - * - * initialize all hpe1368a cards - * - */ -hpe1368aStat hpe1368a_init(void) -{ - hpe1368aStat r0; - - /* - * do nothing on crates without VXI - */ - if(!epvxiResourceMangerOK){ - return VXI_SUCCESS; - } - - hpe1368aDriverId = epvxiUniqueDriverID(); - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_HP; - dsp.model = VXI_MODEL_HPE1368A; - r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL); - if(r0){ - errMessage(r0, NULL); - return r0; - } - } - - return VXI_SUCCESS; -} - - - -/* - * HPE1368A_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL void hpe1368a_init_card(unsigned la, void *pArg) -{ - hpe1368aStat r0; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - int model; - - r0 = epvxiOpen( - la, - hpe1368aDriverId, - (unsigned long) sizeof(*pc), - hpe1368a_stat); - if(r0){ - errMessage(r0,NULL); - return; - } - - r0 = HPE1368A_PCONFIG(la, pc); - if(r0){ - errMessage(r0, NULL); - return; - } - - pcsr = VXIBASE(la); - - /* - * we must reset the device to a known state since - * we cant read back the current state - */ - pc->pending = ALL_SWITCHES_OPEN; - pc->shadow = ALL_SWITCHES_OPEN; - ChannelEnable(pcsr) = ALL_SWITCHES_OPEN; - - FASTLOCKINIT(&pc->lock); - scanIoInit(&pc->ioscanpvt); - - r0 = intConnect( - INUM_TO_IVEC(la), - hpe1368a_int_service, - la); - if(r0 == ERROR){ - errMessage(S_dev_vecInstlFail, NULL); - return; - } - - sysIntEnable(HPE1368A_INT_LEVEL); - - model = VXIMODEL(pcsr); - r0 = epvxiRegisterModelName( - VXIMAKE(pcsr), - model, - "E 1368A Microwave Switch\n"); - if(r0){ - errMessage(r0, NULL); - } - r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard"); - if(r0){ - errMessage(r0,NULL); - } -} - - -/* - * - * hpe1368a_int_service() - * - * - * This device interrupts once the - * switches have settled - * - */ -LOCAL void -hpe1368a_int_service(unsigned la) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la,pc); - if(s){ - return; - } - - /* - * operation completed so we can update - * the shadow value - */ - pc->shadow = pc->pending; - pc->busy = FALSE; - - /* - * tell them that the switches have settled - */ - scanIoRequest(pc->ioscanpvt); -} - - -/* - * HPE1368A_STAT - * - * initialize single at5vxi card - * - */ -LOCAL void hpe1368a_stat( -unsigned la, -int level -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return; - } - pcsr = VXIBASE(la); - - if(level>0){ - printf("\tSwitch states %x\n", pc->shadow); - printf("\tModule status %x\n", pcsr->dir.r.status); - if(pc->busy){ - printf("\tModule is busy.\n"); - } - } -} - - -/* - * hpe1368a_getioscanpvt() - */ -hpe1368aStat hpe1368a_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - *scanpvt = pc->ioscanpvt; - return VXI_SUCCESS; -} - - -/* - * HPE1368A_BO_DRIVER - */ -hpe1368aStat hpe1368a_bo_driver( -unsigned la, -unsigned val, -unsigned mask -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - struct vxi_csr *pcsr; - unsigned int work; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - pcsr = VXIBASE(la); - - FASTLOCK(&pc->lock); - - work = pc->pending; - - /* alter specified bits */ - work = (work & ~mask) | (val & mask); - - pc->pending = work; - - ChannelEnable(pcsr) = work; - - FASTUNLOCK(&pc->lock); - - return VXI_SUCCESS; -} - - - -/* - * - * HPE1368A_BI_DRIVER - * - * - * - */ -hpe1368aStat hpe1368a_bi_driver( -unsigned la, -unsigned mask, -unsigned *pval -) -{ - hpe1368aStat s; - struct hpe1368a_config *pc; - - s = HPE1368A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - FASTLOCK(&pc->lock); - - *pval = pc->shadow & mask; - - FASTUNLOCK(&pc->lock); - - return VXI_SUCCESS; -} diff --git a/src/drv/ansi/drvHpe1368a.h b/src/drv/ansi/drvHpe1368a.h deleted file mode 100644 index 6e7688555..000000000 --- a/src/drv/ansi/drvHpe1368a.h +++ /dev/null @@ -1,60 +0,0 @@ -/* drvHpe1368a.h*/ -/* base/src/drv $Id$ */ - -/* - * hpe1368a_driver.h - * - * driver for hpe1368a and hpe1369a microwave switch VXI modules - * - * Author: Jeff Hill - * Date: 052192 - * - * 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: - * ----------------- - * - */ - -#define VXI_MODEL_HPE1368A (0xf28) - -typedef long hpe1368aStat; - -hpe1368aStat hpe1368a_init(void); - -hpe1368aStat hpe1368a_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -); - -hpe1368aStat hpe1368a_bo_driver( -unsigned la, -unsigned val, -unsigned mask -); - -hpe1368aStat hpe1368a_bi_driver( -unsigned la, -unsigned mask, -unsigned *pval -); - diff --git a/src/drv/ansi/drvHpe1445a.c b/src/drv/ansi/drvHpe1445a.c deleted file mode 100644 index 58ec441e9..000000000 --- a/src/drv/ansi/drvHpe1445a.c +++ /dev/null @@ -1,1188 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * driver for hpe1445a arbitrary function generator VXI modules - * - * Author: Jeff Hill - * Date: 082492 - * - * 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 021192 joh Fixed hpe1445aUnloadWaveformLocked() ANSI C - * function prototype missmatch. Changed - * unsigned short to unsigned. - * - * - */ - -static char *sccsId = "@(#)drvHpe1445a.c 1.5\t8/27/93"; - -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include -#include - -/* - * comment out this line if you prefer - * to use backplane ttl trigger 0 - */ -#define FRONT_PANEL_TRIGGER - -#define VXI_MODEL_HPE1445A (418) - -LOCAL int hpe1445aDriverId; - -#define HPE1445A_MAX_POINTS 0x40000 -#define HPE1445A_MIN_POINTS 4 - -#define HPE1445_DATA_PORT_OFFSET (0x26) - -struct hpe1445aConfig { - FAST_LOCK lck; - char device_active; - double dacPeakAmplitude; - double dacOffset; - char buf[256]; -}; - -#define HPE1445A_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), hpe1445aDriverId, (PC)) - -typedef long hpe1445aStat; - -/* - * - * For External Use - * - */ -hpe1445aStat hpe1445aInit(void); -hpe1445aStat hpe1445aSetupDAC(unsigned la, double dacPeakAmplitude, double dacOffset); -hpe1445aStat hpe1445aSetupFreq(unsigned la, char *pFreqString); -void hpe1445aIoReport(unsigned la, int level); -hpe1445aStat hpe1445aLoadWaveform(unsigned la, char *pWaveformName, - double *pdata, unsigned long npoints); -hpe1445aStat hpe1445aUnloadWaveform(unsigned la, char *pWaveformName); -hpe1445aStat hpe1445aActivateWaveform(unsigned la, char *pWaveformName); -hpe1445aStat hpe1445aTest(unsigned la); -hpe1445aStat hpe1445aWriteWithLineno(unsigned la, char *pmsg, unsigned lineno); -void hpe1445aLogErrorsWithLineno(unsigned la, int lineno); - - -/* - * - * For Driver Internal Use - * - */ -LOCAL void hpe1445aInitCard(unsigned la, void *pArg); -LOCAL hpe1445aStat hpe1445aReset(unsigned la); -LOCAL hpe1445aStat logEntireError(unsigned la, int lineno); -LOCAL hpe1445aStat hpe1445aActivateWaveformLocked(unsigned la, char *pWaveformName, - struct hpe1445aConfig *pc); -LOCAL hpe1445aStat hpe1445aSetupFunction(unsigned la); -LOCAL hpe1445aStat hpe1445aSetupOutput(unsigned la); -LOCAL hpe1445aStat hpe1445aArm(unsigned la); -LOCAL hpe1445aStat hpe1445aUnloadWaveformLocked(unsigned la, char *pWaveformName); -LOCAL hpe1445aStat hpe1445aLoadWaveformLocked(unsigned la, - struct hpe1445aConfig *pc, - char *pWaveformName, double *pdata, - unsigned long npoints); - - -#define logErrors(LA) hpe1445aLogErrorsWithLineno(LA, __LINE__) -#define hpe1445aWrite(LA, PMSG) hpe1445aWriteWithLineno(LA, PMSG, __LINE__) - -#define HPE1445A_MAX_NAME_LENGTH 12 -#define SEGMENT_NAME_PREFIX "e_" -#define SEQUENCE_NAME_PREFIX "e__" -#define PREFIX_MAX_NAME_LENGTH 3 -#define MAX_NAME_LENGTH (HPE1445A_MAX_NAME_LENGTH-PREFIX_MAX_NAME_LENGTH) - -#define TEST_FILE_NAME "hpe1445a.dat" - - -/* - * - * hpe1445aTest() - * - * - */ -hpe1445aStat hpe1445aTest(unsigned la) -{ - hpe1445aStat s; - FILE *pf; - char *pfn = TEST_FILE_NAME; - double *pwaveform; - int nsamples; - int i; - - pf = fopen(pfn, "r"); - if(!pf){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "file access problems %s", - pfn); - fclose(pf); - return s; - } - s = fscanf(pf, "%d", &nsamples); - if(s!=1){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "no element count in the file %s", - pfn); - fclose(pf); - return s; - } - - pwaveform = (double *) calloc(nsamples, sizeof(double)); - if(!pwaveform){ - s = S_dev_noMemory; - errPrintf( - s, - __FILE__, - __LINE__, - "specified sample count to large %s", - pfn); - fclose(pf); - return s; - } - - for(i=0; ibuf, - sizeof(pc->buf), - &read_count, - 0); - if(s!=S_epvxi_bufferFull && s!=VXI_SUCCESS){ - errPrintf( - s, - __FILE__, - lineno, - "error fetch problem at LA=0X%X", - la); - return s; - } - nreads++; - /* - * return of zero indicates no errors - * this will always be a very short message - */ - if(nreads==1){ - int val; - int n; - - n = sscanf(pc->buf,"%d",&val); - if(n==1){ - if(val==0){ - return S_epvxi_internal; - } - } - } - errPrintf( - S_epvxi_msgDeviceStatus, - __FILE__, - lineno, - "LA=0X%X: Error => %s", - la, - pc->buf); - - if(s==VXI_SUCCESS){ - break; - } - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aReset() - * - * - */ -LOCAL -hpe1445aStat hpe1445aReset(unsigned la) -{ - hpe1445aStat s; - - s = hpe1445aWrite(la, "*RST"); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list1:ssequence:delete:all"); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list1:segment:delete:all"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupFreq() - * - * - */ -hpe1445aStat hpe1445aSetupFreq(unsigned la, char *pFreqString) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return s; - } - - /* - * - * Set the sample rate - * - */ - sprintf(pc->buf, "source:frequency:fixed %s", pFreqString); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupFunction() - * - * - */ -LOCAL -hpe1445aStat hpe1445aSetupFunction(unsigned la) -{ - hpe1445aStat s; - - /* - * - * set the function to arbitrary waveform - * - */ - s = hpe1445aWrite(la, "source:function:shape user"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aSetupOutput() - * - * - */ -LOCAL -hpe1445aStat hpe1445aSetupOutput(unsigned la) -{ - hpe1445aStat s; - - - /* - * set the output impedance - * (50 Ohm coax assumed) - * - */ - s = hpe1445aWrite(la, "output:impedance 50 Ohm"); - if(s){ - return s; - } - - /* - * - * disable output low pass filter - * (freq would need to be set if it were turned on) - * - */ - s = hpe1445aWrite(la, "output:filter:lpass:state off"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * hpe1445aArm() - * - */ -hpe1445aStat hpe1445aArm(unsigned la) -{ - hpe1445aStat s; - - /* - * - * initiate waveform output off the external trigger input - * - */ -#ifdef FRONT_PANEL_TRIGGER - s = hpe1445aWrite(la, "arm:start:layer2:source external"); -#else - s = hpe1445aWrite(la, "arm:start:layer2:source ttltrg0"); -#endif - if(s){ - return s; - } - - /* - * - * initiate waveform output on the rising edge - * - */ - s = hpe1445aWrite(la, "arm:start:layer2:slope positive"); - if(s){ - return s; - } - - /* - * - * output the waveform once only after receiving - * a trigger - * - */ - s = hpe1445aWrite(la, "arm:start:layer1:count 1"); - if(s){ - return s; - } - - /* - * - * output the waveform after each trigger edge - * forever - * - */ - s = hpe1445aWrite(la, "arm:start:layer2:count infinity"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * - * hpe1445aSetupDAC - * - * - * - */ -hpe1445aStat hpe1445aSetupDAC( -unsigned la, -double dacPeakAmplitude, -double dacOffset) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la,pc); - if(s){ - errMessage(s,NULL); - return s; - } - - sprintf(pc->buf, - "source:voltage:level:immediate:amplitude %f V", - dacPeakAmplitude); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - pc->dacPeakAmplitude = dacPeakAmplitude; - - sprintf(pc->buf, - "source:voltage:level:immediate:offset %f V", - dacOffset); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - pc->dacOffset = dacOffset; - - logErrors(la); - - return VXI_SUCCESS; -} - - - -/* - * - * hpe1445aActivateWaveform() - * - * - * - */ -hpe1445aStat hpe1445aActivateWaveform( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s,NULL); - return s; - } - - FASTLOCK(&pc->lck); - - s = hpe1445aActivateWaveformLocked(la, pWaveformName, pc); - - FASTUNLOCK(&pc->lck); - - return s; -} - - -/* - * - * hpe1445aActivateWaveformLocked() - * - * - * - */ -LOCAL hpe1445aStat -hpe1445aActivateWaveformLocked( -unsigned la, -char *pWaveformName, -struct hpe1445aConfig *pc -) -{ - int s; - - if(pc->device_active){ - s = hpe1445aWrite(la, "abort"); - if(s){ - return s; - } - pc->device_active = FALSE; - } - - /* - * - * select active sequence - * - */ - sprintf( pc->buf, - "source:function:user %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * - * initiate the trigger system - * - */ - s = hpe1445aWrite(la, "initiate:immediate"); - if(s){ - return s; - } - pc->device_active = TRUE; - - logErrors(la); - - return VXI_SUCCESS; -} - - - -/* - * - * hpe1445aUnloadWaveform() - * - * - * - */ -hpe1445aStat hpe1445aUnloadWaveform( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - FASTLOCK(&pc->lck); - - s = hpe1445aUnloadWaveformLocked(la, pWaveformName); - - FASTUNLOCK(&pc->lck); - - logErrors(la); - - return s; -} - - -/* - * - * hpe1445aUnloadWaveformLocked() - * - * - * - */ -LOCAL hpe1445aStat hpe1445aUnloadWaveformLocked( -unsigned la, -char *pWaveformName -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - sprintf( - pc->buf, - "source:list:ssequence:select %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list:ssequence:delete:selected"); - if(s){ - return s; - } - - sprintf( - pc->buf, - "source:list:segment:select %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - s = hpe1445aWrite(la, "source:list:segment:delete:selected"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - - -/* - * hpe1445aLoadWaveform() - */ -hpe1445aStat -hpe1445aLoadWaveform( -unsigned la, -char *pWaveformName, -double *pdata, -unsigned long npoints -) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - - if(strlen(pWaveformName)>MAX_NAME_LENGTH){ - s = S_dev_highValue; - errMessage(s, "waveform element name to long"); - return s; - } - - if(npointslck); - - s = hpe1445aLoadWaveformLocked(la, pc, pWaveformName, pdata, npoints); - - FASTUNLOCK(&pc->lck); - - return s; -} - - -/* - * - * hpe1445aLoadWaveformLocked() - * - * - */ -LOCAL hpe1445aStat hpe1445aLoadWaveformLocked( -unsigned la, -struct hpe1445aConfig *pc, -char *pWaveformName, -double *pdata, -unsigned long npoints -) -{ - unsigned long read_count; - hpe1445aStat s; - - s = hpe1445aWrite(la, "source:list:segment:free?"); - if(s){ - return s; - } - s = epvxiRead( - la, - pc->buf, - sizeof(pc->buf), - &read_count, - 0); - if(s){ - errMessage(s, "\"source:list:segment:free?\" query failed"); - return s; - } - - { - int nfree; - int nused; - - s = sscanf(pc->buf, "%d,%d", &nfree, &nused); - if(s!=2){ - s = S_dev_internal; - errMessage(s, "bad \"source:list:segment:free?\" resp"); - return s; - } - if(nfree < npoints){ - s = S_dev_internal; - errPrintf( - s, - __FILE__, - __LINE__, - "%d waveform elements available", - nfree); - errPrintf( - s, - __FILE__, - __LINE__, - "%d element waveform rejected", - npoints); - return s; - } - } - - - /* - * - * select the segment for subsequent - * commands - * - */ - sprintf( - pc->buf, - "source:list:segment:select %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - sprintf(pc->buf, "source:list:segment:define %lu", npoints); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - sprintf( pc->buf, - "source:arbitrary:download VXI,%s%s,%lu", - SEGMENT_NAME_PREFIX, - pWaveformName, - npoints); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * wait for the device to finish with the download - * command prior to the backplane download - */ - s = hpe1445aWrite(la, "*OPC?"); - if(s){ - return s; - } - s = epvxiRead( - la, - pc->buf, - sizeof(pc->buf), - &read_count, - 0); - if(s){ - errMessage(s,"\"*OPC?\" query failed"); - return s; - } - - { - double truncationOffset; - double dacPeakAmplitude; - double dacOffset; - double *pwf; - uint16_t *pdata_port; - - pdata_port = (unsigned short *) epvxiA24Base(la); - pdata_port += (HPE1445_DATA_PORT_OFFSET/sizeof(*pdata_port)); - dacPeakAmplitude = pc->dacPeakAmplitude; - dacOffset = pc->dacOffset; - truncationOffset = dacPeakAmplitude/(4095*2); - for(pwf=pdata; pwf < &pdata[npoints]; pwf++){ - short idata; - double fdata; - - /* - * extra step here preserves precision - */ - fdata = (*pwf-dacOffset)*4095; - fdata = fdata/dacPeakAmplitude; - /* - * This offset causes round up to occur and - * not truncation - */ - fdata += truncationOffset; - idata = (short) fdata; - idata = idata << 3; - - if(pwf == &pdata[npoints-4]){ -# define LAST_POINT 1 - idata |= LAST_POINT; - } - - /* - * load the waveform element into the 1445 - */ - *pdata_port = idata; - } - } - - s = hpe1445aWrite(la, "source:arbitrary:download:complete"); - if(s){ - return s; - } - - /* - * - * install this segment into the sequence - * - */ - sprintf( pc->buf, - "source:list:ssequence:select %s%s", - SEQUENCE_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - - /* - * set the number of segments in this sequence - */ - s = hpe1445aWrite(la, "source:list:ssequence:define 1"); - if(s){ - return s; - } - sprintf(pc->buf, - "source:list:ssequence:sequence %s%s", - SEGMENT_NAME_PREFIX, - pWaveformName); - s = hpe1445aWrite(la, pc->buf); - if(s){ - return s; - } - s = hpe1445aWrite(la, "source:list:ssequence:dwell:count 1"); - if(s){ - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aWriteWithLineno() - * - */ -hpe1445aStat hpe1445aWriteWithLineno( - unsigned la, - char *pmsg, - unsigned lineno -) -{ - unsigned long nactual; - hpe1445aStat s; - - s = epvxiWrite( - la, - pmsg, - strlen(pmsg), - &nactual, - 0); - if(s){ - errPrintf( - s, - __FILE__, - lineno, - "LA=0X%02X MSG=%s", - la, - pmsg); - return s; - } - - return VXI_SUCCESS; -} - - -/* - * - * hpe1445aIoReport() - * - * - */ -void hpe1445aIoReport(unsigned la, int level) -{ - hpe1445aStat s; - struct hpe1445aConfig *pc; - char *pStateName[] = {"in",""}; - - s = HPE1445A_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - - if(level>0){ - printf("\tdevice %sactive, DAC peak = %f V, DAC offset = %f V\n", - pStateName[(unsigned)pc->device_active], - pc->dacPeakAmplitude, - pc->dacOffset); - } -} diff --git a/src/drv/ansi/drvIpMv162.c b/src/drv/ansi/drvIpMv162.c deleted file mode 100644 index d625a429c..000000000 --- a/src/drv/ansi/drvIpMv162.c +++ /dev/null @@ -1,341 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - drvIpMv162.c - -Description: - IPAC Carrier Driver for the IndustryPack carriers on the Motorola - MVME162 CPU board, provides the interface between IPAC driver and the - hardware. - -Author: - Andrew Johnson -Created: - 6 July 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include "drvIpac.h" -#include "ipic.h" - - -/* Characteristics of the card */ - -#define SLOTS 4 -#define IO_SPACES 2 /* Address spaces in A16 */ -#define IPAC_IRQS 2 /* Interrupts per module */ -#define IPIC_BASE 0xfffbc000 - - -/* Base Addresses of IO and ID spaces */ - -#define REGS_A 0xfff58000 -#define PROM_A 0xfff58080 -#define REGS_B 0xfff58100 -#define PROM_B 0xfff58180 -#define REGS_C 0xfff58200 -#define PROM_C 0xfff58280 -#define REGS_D 0xfff58300 -#define PROM_D 0xfff58380 -#define REGS_AB 0xfff58400 -#define REGS_CD 0xfff58500 - - -/* IPIC chip */ - -ipic_t *ipic = (ipic_t *) IPIC_BASE; - - -/* IP Recovery Timers */ - -LOCAL const uchar_t recoveryTime[] = { - IPIC_GEN_RT_0, - IPIC_GEN_RT_2, - IPIC_GEN_RT_2, - IPIC_GEN_RT_4, - IPIC_GEN_RT_4, - IPIC_GEN_RT_8, - IPIC_GEN_RT_8, - IPIC_GEN_RT_8, - IPIC_GEN_RT_8 -}; - - -/* Carrier Base Address structure, only one instance can exist! */ - -LOCAL long mBase[IPAC_ADDR_SPACES][SLOTS] = { - PROM_A, PROM_B, PROM_C, PROM_D, - REGS_A, REGS_B, REGS_C, REGS_D, - REGS_AB, NULL, REGS_CD, NULL, - NULL, NULL, NULL, NULL -}; - - -/******************************************************************************* - -Routine: - initialise - -Purpose: - Initialises the MVME162 IPIC chip with settings given in cardParams - -Description: - - -Parameters: - - -Examples: - "A:m=0x80000000,1024 l=4;B:l=2,2;C:m=0x80100000,64" - -Returns: - 0 = OK, - S_IPAC_tooMany = Carrier already registered - S_IPAC_badDriver = IPIC chip not found - S_IPAC_badAddress = Parameter string error, or address not reachable - -*/ - -LOCAL int initialise ( - char *cardParams, - void **pprivate -) { - static int initialised = FALSE; - ushort_t slot; - int count, p1, p2, next; - char dummy, cmd; - - if (initialised) { - return S_IPAC_tooMany; - } - - if (vxMemProbe((void *)&ipic->chipId, READ, 1, &dummy) || - ipic->chipId != IPIC_CHIP_ID) { - return S_IPAC_badDriver; - } - - /* Initialise the IPIC chip */ - for (slot = 0; slot < SLOTS; slot++) { - ipic->intCtrl[slot][0] = IPIC_INT_ICLR; - ipic->intCtrl[slot][1] = IPIC_INT_ICLR; - ipic->genCtrl[slot] = IPIC_GEN_WIDTH_16 | IPIC_GEN_RT_0; - } - - /* Parse the parameter string */ - slot = 0; - while ((cmd = *cardParams++) != '\0') { - switch (cmd) { - case 'A': - case 'B': - case 'C': - case 'D': - slot = cmd - 'A'; - break; - - case 'm': - p1 = p2 = 0; - count = sscanf(cardParams, "=%p,%d%n", - (void **) &p1, &p2, &next); - if (count != 2 || - p1 < (long) sysMemTop() || - p1 & 0xffff != 0 || - p2 < 64 || p2 > 16384 || - p1 + (p2*1024) > 0xfff00000) { - return S_IPAC_badAddress; - } - - ipic->memBase[slot] = p1 >> 16; - ipic->memSize[slot] = (p2 / 64) - 1; - ipic->genCtrl[slot] |= IPIC_GEN_MEN; - mBase[ipac_addrMem][slot] = p1; - cardParams += next; - break; - - case 'l': - p1 = p2 = 0; - count = sscanf(cardParams, "=%d%n,%d%n", &p1, &next, &p2, &next); - if (count < 1 || count > 2 || - p1 < 0 || p1 > 7 || - p2 < 0 || p2 > 7) { - return S_IPAC_badAddress; - } - - ipic->intCtrl[slot][0] = (p1 & IPIC_INT_LEVEL) | - (ipic->intCtrl[slot][0] & ~IPIC_INT_LEVEL); - ipic->intCtrl[slot][1] = (p2 & IPIC_INT_LEVEL) | - (ipic->intCtrl[slot][1] & ~IPIC_INT_LEVEL); - cardParams += next; - break; - - case 'r': - p1 = 0; - count = sscanf(cardParams, "=%d%n", &p1, &next); - if (count != 1 || - p1 < 0 || p1 > 8) { - return S_IPAC_badAddress; - } - - ipic->genCtrl[slot] = (ipic->genCtrl[slot] & ~IPIC_GEN_RT) | - recoveryTime[p1]; - cardParams += next; - break; - - case 'w': - p1 = 0; - count = sscanf(cardParams, "=%d%n", &p1, &next); - if (count != 1) { - return S_IPAC_badAddress; - } - - switch (p1) { - case 8: - ipic->genCtrl[slot] = IPIC_GEN_WIDTH_8 | - (ipic->genCtrl[slot] & ~IPIC_GEN_WIDTH); - break; - case 16: - ipic->genCtrl[slot] = IPIC_GEN_WIDTH_16 | - (ipic->genCtrl[slot] & ~IPIC_GEN_WIDTH); - break; - case 32: - if (slot & 1) { - /* Illegal for odd-numbered slots */ - return S_IPAC_badAddress; - } - ipic->genCtrl[slot] = IPIC_GEN_WIDTH_32 | - (ipic->genCtrl[slot] & ~IPIC_GEN_WIDTH); - ipic->genCtrl[slot+1] &= ~(IPIC_GEN_WIDTH | - IPIC_GEN_MEN); - break; - default: - return S_IPAC_badAddress; - } - } - } - - initialised = TRUE; - return OK; -} - - -/******************************************************************************* - -Routine: - baseAddr - -Purpose: - Returns the base address for the requested slot & address space - -Description: - This routine only has to do a table lookup in the mBase array. - Note that no parameter checking is required - the IPAC driver which - calls this routine handles that. - -Returns: - The requested address, or NULL if the slot has no memory in the - requested address space. - -*/ - -LOCAL void *baseAddr ( - void *private, - ushort_t slot, - ipac_addr_t space -) { - return (void *) mBase[space][slot]; -} - - -/******************************************************************************* - -Routine: - irqCmd - -Purpose: - Handles interrupter commands and status requests - -Description: - The IPIC chip allows a lot of control over the IP interrupters, thus - all commands perform the requested action. - -Returns: - ipac_irqGetLevel returns the current interrupt level, - ipac_irqPoll returns >0 if interrupt line active else 0, - other calls return 0 = OK. - -*/ - -LOCAL int irqCmd ( - void *private, - ushort_t slot, - ushort_t irqNumber, - ipac_irqCmd_t cmd -) { - switch (cmd) { - case ipac_irqLevel0: - case ipac_irqLevel1: - case ipac_irqLevel2: - case ipac_irqLevel3: - case ipac_irqLevel4: - case ipac_irqLevel5: - case ipac_irqLevel6: - case ipac_irqLevel7: - ipic->intCtrl[slot][irqNumber] = (cmd & IPIC_INT_LEVEL) | - (ipic->intCtrl[slot][irqNumber] & ~IPIC_INT_LEVEL); - return OK; - - case ipac_irqGetLevel: - return ipic->intCtrl[slot][irqNumber] & IPIC_INT_LEVEL; - - case ipac_irqEnable: - ipic->intCtrl[slot][irqNumber] |= IPIC_INT_IEN; - return OK; - - case ipac_irqDisable: - ipic->intCtrl[slot][irqNumber] &= ~IPIC_INT_IEN; - return OK; - - case ipac_irqPoll: - return ipic->intCtrl[slot][irqNumber] & IPIC_INT_INT; - - case ipac_irqSetEdge: - ipic->intCtrl[slot][irqNumber] |= IPIC_INT_EDGE; - return OK; - - case ipac_irqSetLevel: - ipic->intCtrl[slot][irqNumber] &= ~IPIC_INT_EDGE; - return OK; - - case ipac_irqClear: - ipic->intCtrl[slot][irqNumber] |= IPIC_INT_ICLR; - return OK; - - default: - return S_IPAC_notImplemented; - } -} - -/******************************************************************************/ - - -/* IPAC Carrier Table */ - -ipac_carrier_t ipmv162 = { - "Motorola MVME162", - SLOTS, - initialise, - NULL, - baseAddr, - irqCmd -}; - diff --git a/src/drv/ansi/drvIpac.c b/src/drv/ansi/drvIpac.c deleted file mode 100644 index e98a5c850..000000000 --- a/src/drv/ansi/drvIpac.c +++ /dev/null @@ -1,520 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - drvIpac.c - -Description: - IPAC Driver, provides a standard interface between IPAC Module - drivers and the IPAC Carrier drivers. - -Author: - Andrew Johnson -Created: - 3 July 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#ifndef NO_EPICS -# include -#endif - -#include -#include -#include -#include -#include "drvIpac.h" - - -#define IPAC_MAX_CARRIERS 21 - - -/* Private carrier data structures */ -struct carrierInfo { - ipac_carrier_t *driver; - void *cPrivate; -}; - -LOCAL struct { - ushort_t number; - struct carrierInfo *info[IPAC_MAX_CARRIERS]; -} carriers = { - 0 -}; - - -/* Null carrier stuff */ - -LOCAL ipac_carrier_t nullCarrier = { - "Null carrier (place holder)", - 0, /* No slots */ - NULL, NULL, NULL, NULL -}; - -LOCAL struct carrierInfo nullInfo = { - &nullCarrier, - NULL -}; - - -#ifndef NO_EPICS - -/* EPICS Driver Support Entry Table */ - -struct drvet drvIpac = { - 3, - (DRVSUPFUN) ipacReport, - (DRVSUPFUN) ipacInitialise, - NULL -}; - - -#endif - - -/******************************************************************************* - -Routine: - ipacAddCarrier - -Purpose: - Used to register a carrier board & carrier driver with the IPAC driver. - -Description: - Usually called from the vxWorks (EPICS) startup script. Some types of - carrier may need additional initilisation before or after registering, - but the card parameter string should be sufficient for most carriers. - Note that only the carrier initialise routine is called at this stage. - The order in which carriers are registered with this routine specifies - the carrier number which they will be allocated, starting from zero. - - Checks that the carrier descriptor table looks sensible, then calls the - initialise routine with the given card parameters, and saves the carrier - private pointer and carrier table address. The card number allows the - same descriptor to be used for all carriers of the same type. - - It may be necessary to remove a carrier temporarily from a system in - some circumstances without wanting to have to change the carrier number - allocated to higher numbered carriers. To allow this, it is legal to - call this routine with a NULL (zero) carrier table address, which - switches in the null carrier table instead. - -Returns: - 0 = OK, - S_IPAC_tooMany = Carrier Info Table full, - S_IPAC_badTable = Carrier Table invalid. - -Example: - ipacAddCarrier(&vipc310, "0x6000"); - -*/ - -int ipacAddCarrier ( - ipac_carrier_t *pcarrierTable, - char *cardParams -) { - void *cPrivate; - int status; - - if (carriers.number >= IPAC_MAX_CARRIERS) { - return S_IPAC_tooMany; - } - - if (pcarrierTable == NULL) { - carriers.info[carriers.number] = &nullInfo; - carriers.number++; - return OK; - } - - if (pcarrierTable->numberSlots == 0 || - pcarrierTable->initialise == NULL || - pcarrierTable->baseAddr == NULL || - pcarrierTable->irqCmd == NULL) { - return S_IPAC_badTable; - } - - status = pcarrierTable->initialise(cardParams, &cPrivate); - if (status) { - return status; - } - - carriers.info[carriers.number] = malloc(sizeof (struct carrierInfo)); - carriers.info[carriers.number]->driver = pcarrierTable; - carriers.info[carriers.number]->cPrivate = cPrivate; - carriers.number++; - - return OK; -} - - -/******************************************************************************* - -Routine: - ipmCheck - -Function: - Check on presence of an IPAC module at the given carrier & slot number. - -Description: - Does a quick check to make sure the carrier and slot numbers are legal, - probes the IDprom space to ensure an IPAC is installed, and checks that - the IDprom starts with the "IPAC" identifier. - -Returns: - 0 = OK, - S_IPAC_badAddress = Bad carrier or slot number, - S_IPAC_noModule = No module installed, - S_IPAC_noIpacId = "IPAC" identifier not found - -*/ - -int ipmCheck ( - ushort_t carrier, - ushort_t slot -) { - ipac_idProm_t *id; - char dummy; - - if (carrier >= carriers.number || - slot >= carriers.info[carrier]->driver->numberSlots) { - return S_IPAC_badAddress; - } - - id = (ipac_idProm_t *) ipmBaseAddr(carrier, slot, ipac_addrID); - if (id == NULL) { - return S_IPAC_badDriver; - } - - if (vxMemProbe((void *)&id->asciiI, READ, 1, &dummy)) { - return S_IPAC_noModule; - } - - if (id->asciiI != 'I' || - id->asciiP != 'P' || - id->asciiA != 'A' || - id->asciiC != 'C') { - return S_IPAC_noIpacId; /* Not an IPAC */ - } - - return OK; -} - - -/******************************************************************************* - -Routine: - checkCRC - -Function: - Calculate the CRC of the IDprom at the given address. - -Description: - Generates an industry standard CRC of the ID Prom data as described - in the GreenSpring Industry Pack specification. The CRC byte in the - Prom (at address 0x17) is set to zero for the purpose of calculating - the CRC. - -Returns: - The low 8 bits of the calculated CRC value. - -*/ - -LOCAL int checkCRC ( - uchar_t *data, - ushort_t length -) { - uint_t i, crc = 0xffff; - uchar_t mask; - - for (i = 1; i < 2*length; i += 2) { - mask = 0x80; - while (mask) { - if ((data[i] & mask) && (i != 0x17)) { - crc ^= 0x8000; - } - crc += crc; - if (crc > 0xffff) { - crc = (crc & 0xffff) ^ 0x1021; - } - mask >>= 1; - } - } - - return (~crc) & 0xff; -} - - -/******************************************************************************* - -Routine: - ipmValidate - -Function: - Validate a particular IPAC module type at the given carrier & slot number. - -Description: - Uses ipmCheck to ensure the carrier and slot numbers are legal, probe the - IDprom and check that the IDprom looks like an IPAC module. Calculates - the CRC for the ID Prom, and compares the manufacturer and model ID values - in the Prom to the ones given. - -Returns: - 0 = OK, - S_IPAC_badAddress = Bad carrier or slot number, - S_IPAC_noModule = No module installed, - S_IPAC_noIpacId = "IPAC" identifier not found - S_IPAC_badCRC = CRC Check failed, - S_IPAC_badModule = Manufacturer or model IDs wrong - -*/ - -int ipmValidate ( - ushort_t carrier, - ushort_t slot, - uchar_t manufacturerId, - uchar_t modelId -) { - ipac_idProm_t *id; - int status; - - status = ipmCheck(carrier, slot); - if (status) { - return status; - } - - id = (ipac_idProm_t *) ipmBaseAddr(carrier, slot, ipac_addrID); - if (checkCRC((uchar_t *) id, id->bytesUsed) != id->CRC) { - return S_IPAC_badCRC; - } - - if (id->manufacturerId != manufacturerId || - id->modelId != modelId) { - return S_IPAC_badModule; - } - - return OK; -} - - -/******************************************************************************* - -Routine: - ipmReport - -Function: - returns printable string giving status of module at given carrier/slot. - -Description: - Generates a report string describing the given IPAC slot. If a module - is installed, it includes the manufacturer and model ID numbers. If - the report function is supported by the carrier driver this report - string is appended. - -Returns: - Pointer to static, printable string. - -Sample Output: - "C0 S1 : 0xB1/0x01 - M0 L4,5" - -*/ - -char *ipmReport ( - ushort_t carrier, - ushort_t slot -) { - static char report[80]; - int status; - - sprintf(report, "C%hd S%hd : ", carrier, slot); - - status = ipmCheck(carrier, slot); - if (status == S_IPAC_badAddress) { - strcat(report, "No such carrier/slot"); - return report; - } - - if (status == S_IPAC_noModule) { - strcat(report, "No Module"); - } else { - ipac_idProm_t *id; - char module[16]; - - id = (ipac_idProm_t *) ipmBaseAddr(carrier, slot, ipac_addrID); - sprintf(module, "0x%02hX/0x%02hX", (short) id->manufacturerId, - (short) id->modelId); - strcat(report, module); - } - - if (carriers.info[carrier]->driver->report != NULL) { - strcat(report, " - "); - strcat(report, carriers.info[carrier]->driver->report( - carriers.info[carrier]->cPrivate, slot)); - } - - return report; -} - - -/******************************************************************************* - -Routine: - ipmBaseAddr - -Function: - Returns a pointer to the selected IP address space - -Description: - Checks its input parameters, then calls the carrier driver. This will - return a pointer to the location of the address space indicated by the - space parameter. All IP modules must provide an ID prom to indicate - the module type (space = ipac_addrID). Most modules need register I/O - locations, which are in the I/O space (space = ipac_addrIO). Some - types of module also provide memory (space = ipac_addrMem), but if - this is not required the carrier may allow it to be disabled, in which - case the driver should return a NULL for this address space. Some - carriers provide a 32-bit wide I/O space for Dual-slot IP modules; - carriers which do not should return NULL for this space. - -Returns: - Base CPU address of IP address space, or NULL pointer. - -*/ - -void *ipmBaseAddr ( - ushort_t carrier, - ushort_t slot, - ipac_addr_t space -) { - if (carrier >= carriers.number || - slot >= carriers.info[carrier]->driver->numberSlots) { - return NULL; - } - return carriers.info[carrier]->driver->baseAddr( - carriers.info[carrier]->cPrivate, slot, space); -} - - -/******************************************************************************* - -Routine: - ipmIrqCmd - -Function: - Send command to slot interrupt controller. - -Description: - Checks input parameters, then passes the interrupt command request to - the carrier driver routine. The driver is only required to support - the command ipac_irqEnable; for other commands it may return the status - code S_IPAC_notImplemented and do nothing. - -Returns: - 0 = OK, - S_IPAC_badAddress = illegal carrier, slot or irqNumber, - S_IPAC_notImplemented = Driver does not support that command, - other, depending on command. - -*/ - -int ipmIrqCmd ( - ushort_t carrier, - ushort_t slot, - ushort_t irqNumber, - ipac_irqCmd_t cmd -) { - if (irqNumber > 1 || - carrier >= carriers.number || - slot >= carriers.info[carrier]->driver->numberSlots) { - return S_IPAC_badAddress; - } - - return carriers.info[carrier]->driver->irqCmd( - carriers.info[carrier]->cPrivate, slot, irqNumber, cmd); -} - - -/******************************************************************************* - -Routine: - ipacReport - -Function: - Report status of all known IPAC carriers - -Description: - Prints information on each known carrier board and slot according to the - specified interest level. Level 0 lists carriers only, with the number - of slots it supports. Level 1 gives each slot, manufacturer & model ID - of the installed module (if any), and the carrier driver report for that - slot. Level 2 adds the address of each memory space for the slot. - -Returns: - OK. - -*/ - -int ipacReport ( - int interest -) { - ushort_t carrier, slot; - - for (carrier=0; carrier < carriers.number; carrier++) { - printf(" IP Carrier %2d: %s, %d slots\n", carrier, - carriers.info[carrier]->driver->carrierType, - carriers.info[carrier]->driver->numberSlots); - - if (interest > 0) { - long memBase, io32Base; - - for (slot=0; slot < carriers.info[carrier]->driver->numberSlots; - slot++) { - printf(" %s\n", ipmReport(carrier, slot)); - - if (interest > 1) { - printf(" ID = 0x%lx, I/O = 0x%lx", - (long) ipmBaseAddr(carrier, slot, ipac_addrID), - (long) ipmBaseAddr(carrier, slot, ipac_addrIO)); - io32Base = (long) ipmBaseAddr(carrier, slot, ipac_addrIO32); - if (io32Base != NULL) { - printf(", I/O32 = 0x%lx", io32Base); - } - memBase = (long) ipmBaseAddr(carrier, slot, ipac_addrMem); - if (memBase != NULL) { - printf(", Mem = 0x%lx", memBase); - } - printf("\n"); - } - } - } - } - return OK; -} - - -/******************************************************************************* - -Routine: - ipacInitialise - -Function: - Initialise the IPAC driver - -Description: - Null routine. - -Returns: - OK. - -*/ - -int ipacInitialise ( - int after -) { - return OK; -} - diff --git a/src/drv/ansi/drvIpac.h b/src/drv/ansi/drvIpac.h deleted file mode 100644 index eb9679dcf..000000000 --- a/src/drv/ansi/drvIpac.h +++ /dev/null @@ -1,176 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - drvIpac.h - -Description: - IPAC Driver header file, defines the software interfaces: - 1. Upwards to the IPAC Module driver - 2. Downwards to the IPAC Carrier driver - -Author: - Andrew Johnson -Created: - 1 July 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#ifndef INCdrvIpacH -#define INCdrvIpacH - -#include -#include "ipModules.h" - -#ifndef NO_EPICS -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Error numbers */ - -#ifndef OK -#define OK 0 -#endif - -#ifndef M_ipac -#define M_ipac (600 << 16) -#endif - -#define S_IPAC_badTable (M_ipac| 1) /*IPAC Carrier Table invalid*/ -#define S_IPAC_tooMany (M_ipac| 2) /*Too many IPAC carriers, table full*/ -#define S_IPAC_badAddress (M_ipac| 3) /*Bad IPAC carrier or slot number*/ -#define S_IPAC_badDriver (M_ipac| 4) /*Bad value from IPAC carrier driver*/ -#define S_IPAC_noModule (M_ipac| 5) /*No IP module installed*/ -#define S_IPAC_noIpacId (M_ipac| 6) /*IPAC identifier not found*/ -#define S_IPAC_badCRC (M_ipac| 7) /*IPAC CRC Check failed*/ -#define S_IPAC_badModule (M_ipac| 8) /*IPAC Manufacturer or model ID wrong*/ -#define S_IPAC_notImplemented (M_ipac| 9) /*IPAC Driver command not available*/ - - -/* Structure of the IPAC ID Prom, located in the pack ID space. */ - -typedef struct { - uchar_t pad00; - uchar_t asciiI; - uchar_t pad02; - uchar_t asciiP; - uchar_t pad04; - uchar_t asciiA; - uchar_t pad06; - uchar_t asciiC; - uchar_t pad08; - uchar_t manufacturerId; - uchar_t pad0a; - uchar_t modelId; - uchar_t pad0c; - uchar_t revision; - uchar_t pad0e; - uchar_t reserved; - uchar_t pad10; - uchar_t driverIdLow; - uchar_t pad12; - uchar_t driverIdHigh; - uchar_t pad14; - uchar_t bytesUsed; - uchar_t pad16; - uchar_t CRC; - uchar_t pad18; - uchar_t packSpecific[0x3f-0x18]; -} ipac_idProm_t; - - -/* These are the types of address space implemented in the IP - specification. Some IP modules only use the ID and IO spaces. */ - -#define IPAC_ADDR_SPACES 4 - -typedef enum { - ipac_addrID = 0, /* ID Prom space */ - ipac_addrIO = 1, /* Registers etc */ - ipac_addrIO32 = 2, /* Registers for 32-bit dual-slot */ - ipac_addrMem = 3 /* Memory space */ -} ipac_addr_t; - - -/* The following are the possible commands to the carrier driver to - handle interrupts from the IP modules. Some carriers will only be - able to implement a subset of these commands. Note that irqEnable - should call the vxWorks sysBusEnable routine if this is needed to - pass the carrier interrupts through to the CPU. */ - -typedef enum { - ipac_irqLevel0 = 0, /* Disables interrupts */ - ipac_irqLevel1 = 1, /* Lowest priority */ - ipac_irqLevel2 = 2, - ipac_irqLevel3 = 3, - ipac_irqLevel4 = 4, - ipac_irqLevel5 = 5, - ipac_irqLevel6 = 6, /* Highest priority */ - ipac_irqLevel7 = 7, /* Non-maskable, don't use */ - ipac_irqGetLevel, /* Returns level set (or hard-coded) */ - ipac_irqEnable, /* Required to use interrupts */ - ipac_irqDisable, /* Not necessarily supported */ - ipac_irqPoll, /* Returns interrupt state */ - ipac_irqSetEdge, /* Sets edge-triggered interrupts */ - ipac_irqSetLevel, /* Sets level-triggered (default) */ - ipac_irqClear /* Only needed if using edge-triggered */ -} ipac_irqCmd_t; - - -/* This is a table which each IPAC carrier driver provides to allow - it to be queried by the IPAC driver. One table is required for - each type of carrier. The cPrivate pointer is returned by the - carrier driver initialise routine, and passed to all of the other - routines as a means of identification of the carrier board. */ - -typedef struct { - char *carrierType; - /* String containing carrier board type */ - ushort_t numberSlots; - /* Number of IPAC devices this carrier can hold */ - int (*initialise)(char *cardParams, void **cPrivate); - /* Initialise carrier and return *cPrivate */ - char *(*report)(void *cPrivate, ushort_t slot); - /* Return string with giving status of this slot */ - void *(*baseAddr)(void *cPrivate, ushort_t slot, ipac_addr_t space); - /* Return base addresses for this slot */ - int (*irqCmd)(void *cPrivate, ushort_t slot, - ushort_t irqNumber, ipac_irqCmd_t cmd); - /* interrupt manipulation */ -} ipac_carrier_t; - - -/* Functions for startup and interactive use */ - -extern int ipacAddCarrier(ipac_carrier_t *pcarrier, char *cardParams); -extern int ipacReport(int interest); -extern int ipacInitialise(int after); - - -/* Functions for use in IPAC module drivers */ - -extern int ipmCheck(ushort_t carrier, ushort_t slot); -extern int ipmValidate(ushort_t carrier, ushort_t slot, - uchar_t manufacturerId, uchar_t modelId); -extern char *ipmReport(ushort_t carrier, ushort_t slot); -extern void *ipmBaseAddr(ushort_t carrier, ushort_t slot, ipac_addr_t space); -extern int ipmIrqCmd(ushort_t carrier, ushort_t slot, - ushort_t irqNumber, ipac_irqCmd_t cmd); - - -#ifdef __cplusplus -} -#endif - -#endif /* INCipacH */ - diff --git a/src/drv/ansi/drvKscV215.c b/src/drv/ansi/drvKscV215.c deleted file mode 100644 index 6939edb67..000000000 --- a/src/drv/ansi/drvKscV215.c +++ /dev/null @@ -1,486 +0,0 @@ -/* drvKscV215.c*/ -/* base/src/drv $Id$ */ -/* - * KscV215_driver.c - * - * driver for KscV215 VXI module - * - * Author: Jeff Hill - * Date: 052192 - * - * 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 071792 joh Added model name registration - * .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID - * .03 082692 mrk Added support for new I/O event scanning and DRVET - * .04 012893 joh include file name change - * .05 080493 mgb Removed V5/V4 and EPICS_V2 conditionals - * - */ - - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include -#include -#include -#include -#include - -#include - - -#define MAXTRIES 100 - -#define KSCV215_PCONFIG(LA, PC) \ -epvxiFetchPConfig((LA), KscV215DriverId, PC) - -#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08) -#define ModuleStatus(PCSR) ((PCSR)->dir.r.status) - -#define ALL_SWITCHES_OPEN 0 - -struct KscV215_config{ - FAST_LOCK lock; /* mutual exclusion */ - IOSCANPVT ioscanpvt; -}; - -#define KSCV215_INT_LEVEL 1 -#define KscV215Handshake (0x0040) -#define KscV215csrInit (0x9000) - -LOCAL int KscV215DriverId; - - -struct KscV215_A24{ - volatile uint16_t diag; - volatile uint16_t isr; - volatile uint16_t pad1[7]; - volatile uint16_t channels[64]; /* odd access causes a bus error ? */ - volatile uint16_t controlMemoryAddr; - volatile uint16_t pad2; - volatile uint16_t controlMemoryDataWrite; - volatile uint16_t pad3; - volatile uint16_t controlMemoryDataRead; - volatile uint16_t pad4; - volatile uint16_t lastChannel; - volatile uint16_t pad5; - volatile uint16_t singleScan; - volatile uint16_t pad6; - volatile uint16_t stopScan; - volatile uint16_t pad7; - volatile uint16_t clearControlMemoryAddr; - volatile uint16_t pad8; - volatile uint16_t enableContinuousScanning; - volatile uint16_t pad9; - volatile uint16_t disableContinuousScanning; - volatile uint16_t pad10; - volatile uint16_t enableDoneInt; - volatile uint16_t pad11; - volatile uint16_t disbaleDoneInt; - volatile uint16_t pad12; - volatile uint16_t clearDoneInt; - volatile uint16_t pad13; - volatile uint16_t testDoneInt; - volatile uint16_t pad14; -}; - -#ifdef INTERRUPTS -LOCAL void KscV215_int_service(unsigned la); -#endif -LOCAL void KscV215_init_card(unsigned la, void *pArg); - -LOCAL void KscV215_stat( -unsigned la, -int level -); - -LOCAL kscV215Stat KscV215WriteSync( -struct KscV215_A24 *pA24, -volatile uint16_t *preg, -uint16_t val -); - - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvKscV215={ - 2, - NULL, /* VXI report takes care of this */ - KscV215Init}; - -/* - * KscV215_init - * - * initialize all KscV215 cards - * - */ -kscV215Stat KscV215Init(void) -{ - kscV215Stat r0; - - /* - * do nothing on crates without VXI - */ - if(!epvxiResourceMangerOK){ - return VXI_SUCCESS; - } - - KscV215DriverId = epvxiUniqueDriverID(); - - { - epvxiDeviceSearchPattern dsp; - - dsp.flags = VXI_DSP_make | VXI_DSP_model; - dsp.make = VXI_MAKE_KSC; - dsp.model = VXI_MODEL_KSCV215; - r0 = epvxiLookupLA(&dsp, KscV215_init_card, (void *)NULL); - if(r0){ - return r0; - } - } - - return VXI_SUCCESS; -} - - - -/* - * KSCV215_INIT_CARD - * - * initialize single at5vxi card - * - */ -LOCAL void KscV215_init_card(unsigned la, void *pArg) -{ - kscV215Stat status; - int i; - struct KscV215_config *pc; - struct KscV215_A24 *pA24; - struct vxi_csr *pcsr; - int model; - - status = epvxiOpen( - la, - KscV215DriverId, - (unsigned long) sizeof(*pc), - KscV215_stat); - if(status){ - errPrintf( - status, - __FILE__, - __LINE__, - "AT5VXI: device open failed %d\n", - la); - - return; - } - - status = KSCV215_PCONFIG(la, pc); - if(status){ - errMessage(status,NULL); - epvxiClose(la, KscV215DriverId); - return; - } - - pA24 = epvxiA24Base(la); - pcsr = VXIBASE(la); - - pcsr->dir.w.control = KscV215csrInit; - - status = KscV215WriteSync(pA24, &pA24->controlMemoryAddr, 0U); - if(status){ - epvxiClose(la, KscV215DriverId); - errMessage(status, "KscV215 init failed\n"); - return; - } - for(i=0; i<(NELEMENTS(pA24->channels)/2); i++){ - status = KscV215WriteSync( - pA24, - &pA24->controlMemoryDataWrite, - 0U); - if(status){ - epvxiClose(la, KscV215DriverId); - errMessage(status, "KscV215 init failed\n"); - return; - } - } - - /* - * turn on continuous scan mode - */ - status = KscV215WriteSync( - pA24, - &pA24->enableContinuousScanning, - 0U); - if(status){ - epvxiClose(la, KscV215DriverId); - errMessage(status, "KscV215 init failed- device left open\n"); - return; - } - - FASTLOCKINIT(&pc->lock); - scanIoInit(&pc->ioscanpvt); - -#ifdef INTERRUPTS - status = intConnect( - (unsigned char) INUM_TO_IVEC(la), - KscV215_int_service, - (void *) la); - if(status == ERROR){ - epvxiClose(la, KscV215DriverId); - errMessage(S_dev_vecInstlFail, - "KscV215 init failed- device left open"); - return; - } - sysIntEnable(KSCV215_INT_LEVEL); -#endif - - status = epvxiRegisterMakeName(VXI_MAKE_KSC, "Kinetic Systems"); - if(status){ - errMessage(status, NULL); - } - - model = VXIMODEL(pcsr); - status = epvxiRegisterModelName( - VXIMAKE(pcsr), - model, - "V215 16 bit 32 channel ADC\n"); - if(status){ - errMessage(status, NULL); - } - -} - - -/* - * - * KscV215WriteSync - * - * - */ -LOCAL kscV215Stat KscV215WriteSync( -struct KscV215_A24 *pA24, -volatile uint16_t *preg, -uint16_t val -) -{ - kscV215Stat status; - int i; - - for(i=0; idiag & KscV215Handshake){ - return VXI_SUCCESS; - } - taskDelay(1); - } - - status = S_dev_deviceTMO; - errMessage(status, NULL); - return status; -} - - -/* - * - * KscV215_int_service() - * - * - * This device interrupts once the - * switches have settled - * - */ -#ifdef INTERRUPTS -LOCAL void KscV215_int_service(unsigned la) -{ - kscV215Stat s; - struct KscV215_config *pc; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - logMsg( "Int to ukn device %s line=%d\n", - __FILE__, - __LINE__, - NULL, - NULL, - NULL, - NULL); - return; - } - - /* - * tell them that the switches have settled - */ - scanIoRequest(pc->ioscanpvt); -} -#endif - - -/* - * KSCV215_STAT - * - * initialize single at5vxi card - * - */ -LOCAL void KscV215_stat( -unsigned la, -int level -) -{ - kscV215Stat s; - struct KscV215_config *pc; - struct vxi_csr *pcsr; - struct KscV215_A24 *pA24; - int i; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return; - } - pcsr = VXIBASE(la); - - pA24 = (struct KscV215_A24 *) epvxiA24Base(la); - - if(level>0){ - printf ("KSC V215 32 CHANNEL 16 BIT ADC.\n"); - } - if (level > 1) { - for (i = 0; i < 32; i++) - printf ("Channel %d Value %d\n", - i, - pA24->channels[i*2]); - } - if (level > 2) { - printf ("\nGain Setting (Control Memory Data Register\n"); - pA24->controlMemoryAddr = 0; - for (i = 0; i < 32; i++) { - switch (pA24->controlMemoryAddr) { - case 0: - printf ("+- 10V"); - break; - case 1: - printf ("+- 5V"); - break; - case 3: - printf ("+- 2.5V"); - break; - case 5: - printf ("+- 1.25V"); - break; - case 6: - printf ("+- 625mV"); - break; - default: - printf ("Unknown Gain Setting."); - } - } - printf ("\n"); - } - - - -} - - - -/* - * - * - * AT5VXI_AI_DRIVER - * - * analog input driver - */ -kscV215Stat KscV215_ai_driver( -unsigned la, -unsigned chan, -unsigned short *prval -) -{ - struct KscV215_config *pc; - struct vxi_csr *pcsr; - struct KscV215_A24 *pA24; - long tmp; - int i; - kscV215Stat s; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - return s; - } - pcsr = VXIBASE(la); - - pA24 = epvxiA24Base(la); - - if(chan >= NELEMENTS(pA24->channels)/2){ - return S_dev_badSignalNumber; - } - - for(i=0; ichannels[chan<<1]; - if(pA24->diag & KscV215Handshake){ - tmp = tmp + 0xffff; - tmp = tmp >> 4; - tmp &= 0xfff; - *prval = tmp; - return VXI_SUCCESS; - } - taskDelay(1); - } - - s = S_dev_deviceTMO; - return s; -} - - -/* - * KscV215_getioscanpvt() - */ -kscV215Stat KscV215_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -) -{ - kscV215Stat s; - struct KscV215_config *pc; - - s = KSCV215_PCONFIG(la, pc); - if(s){ - errMessage(s, NULL); - return s; - } - *scanpvt = pc->ioscanpvt; - return VXI_SUCCESS; -} diff --git a/src/drv/ansi/drvKscV215.h b/src/drv/ansi/drvKscV215.h deleted file mode 100644 index 34eaf2c27..000000000 --- a/src/drv/ansi/drvKscV215.h +++ /dev/null @@ -1,56 +0,0 @@ -/* drvKscV215.c*/ -/* base/src/drv $Id$ */ -/* - * KscV215_driver.c - * - * driver for KscV215 VXI module - * - * Author: Jeff Hill - * Date: 052192 - * - * 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: - * ----------------- - * - */ - -#define VXI_MODEL_KSCV215 (0x215) - -typedef long kscV215Stat; - -kscV215Stat KscV215Init(void); - -kscV215Stat KscV215_ai_driver( -unsigned la, -unsigned chan, -unsigned short *prval -); - -kscV215Stat KscV215_getioscanpvt( -unsigned la, -IOSCANPVT *scanpvt -); - - - - diff --git a/src/drv/ansi/drvMz8310.c b/src/drv/ansi/drvMz8310.c deleted file mode 100644 index 5acd5fca0..000000000 --- a/src/drv/ansi/drvMz8310.c +++ /dev/null @@ -1,628 +0,0 @@ - -/* drvMz8310.c */ -/* base/src/drv $Id$ */ -/* - * Routines specific to the MZ8310. Low level routines for the AMD STC in - * stc_driver.c - * Author: Jeff Hill - * Date: Feb 1989 - * - * 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 History - * joh 02-20-89 Init Release - * joh 04-28-89 Added read back - * joh 11-17-89 added readback to io report - * joh 12-10-89 DB defaults the internal/external clock - * parameter to 0 or external clock. This was the opposite - * of what this driver expected. Fix was made here. - * joh 07-06-90 print channel number with channel value in IO report - * joh 02-25-91 made ext/int clk IO report more readable - * joh 09-05-91 converted to v5 vxWorks - * bg 09-15-91 added sysBustoLocalAdrs() for addressing - * bg 03-10-92 added the argument, level, to mz310_io_report(). - * bg 04-27-92 added rebootHookAdd and mz8310_reset so ioc will - * not hang on ctl X reboot. - * joh 04-28-92 added arguments to MACROS which had hidden - * parameters - * bg 06-25-92 combined drvMz8310.c and mz8310_driver.c - * bg 06-26-92 Added level to mz8310_io_report. - * joh 08-05-92 callable interface now conforms with epics standard - * mgb 08-04-93 Removed V5/V4 and EPICS_V2 conditionals - * joh 08-24-93 Include drvStc.h and ANSI C upgrade - * joh 09-29-93 removed superfluous error message - */ - -/* drvMz8310.c - Driver Support Routines for Mz8310 */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include -#include -#include - -#include - -#define MZ8310CHIPSIZE 0x20 -#define MZ8310SIZE 0x00000100 -#define MZ8310BASE(CARD) (shortaddr+tm_addrs[MZ8310]+(CARD)*MZ8310SIZE) - -#define MZ8310DATA 0 -#define MZ8310CMD 3 -#define MZ8310CHANONCHIP 5 -#define MZ8310CHIPCOUNT 2 -#define MZ8310CHANCNT (MZ8310CHANONCHIP*MZ8310CHIPCOUNT) - -/* - NOTE: The mizar draftsman has labeled the chip at the - highest address as one and the chip at the lowest address - 2 so I am reversing the chip number below. -*/ -#define CHIP_REVERSE(CHIP) (MZ8310CHIPCOUNT-1-(CHIP)) -#define CHIP_ADDR(CARD,CHIP) (MZ8310BASE(CARD)+\ - (CHIP_REVERSE(CHIP)*MZ8310CHIPSIZE)) - -#define MZ8310_CMD_ADDR(CARD,CHIP)\ -((volatile uint8_t *) CHIP_ADDR(CARD,CHIP) + MZ8310CMD) -#define MZ8310_DATA_ADDR(CARD,CHIP)\ -((volatile uint16_t *) CHIP_ADDR(CARD,CHIP) + MZ8310DATA) -#if 0 -#define MZ8310VECBASE(CARD,CHIP)\ -((volatile uint8_t *) CHIP_ADDR(CARD,CHIP) + 0x41) -#endif - -#define MZ8310VECSIZE (0x20) -#define MZ8310INTCNT 4 -#define MZ8310FIRSTINTCHAN 0 -#define MZ8310INTVEC(CARD,CHAN)\ -(MZ8310_INT_VEC_BASE + (CARD*MZ8310INTCNT) + mz8310_strap[CHAN].vec_num) - -#define MZ8310_INTERUPTABLE(CHAN) (mz8310_strap[CHAN].vec_addr) - -# define INT_TICKS 4.0e06 /* speed of F1 in Hz */ -# define EXT_TICKS 5.0e06 /* GTA std speed of SRC1 in Hz */ - - -struct mz8310_int_conf{ - void (*user_service)(void *user_param); - void *user_param; - unsigned int cnt; -}; - -struct mz8310_conf{ - char init; - FAST_LOCK lock; - struct mz8310_int_conf icf[MZ8310CHANCNT]; -}; - -struct mz8310_strap_info{ - unsigned char irq; /* the level at which the chan gen ints */ - unsigned char vec_num; /* really a vec offset-see MZ8310INTVEC */ - unsigned char vec_addr;/* offset from card base address */ -}; - -static volatile char *shortaddr; - -LOCAL struct mz8310_conf *mzconf; -LOCAL unsigned int mz8310_card_count; - -/* - only 4 unique interrupts per card but any channel can potentially - generate an interrupt depending on board strapping. - - NOTE: existence of vec addr tells the driver that that channel is - strapped for interrupts since the card can't be polled for this info. - - In the MIZAR 8310 Documentation: - - Designation vector reg offset - IRQA 0x41 - IRQB 0x61 - IRQC 0x81 - IRQD 0xa1 -*/ - -LOCAL struct mz8310_strap_info mz8310_strap[MZ8310CHANCNT] = -{ - { NULL, NULL, NULL }, /* channel 0 */ - { NULL, NULL, NULL }, /* channel 1 */ - { NULL, NULL, NULL }, /* channel 2 */ - { NULL, NULL, NULL }, /* channel 3 */ - { NULL, NULL, NULL }, /* channel 4 */ - { NULL, NULL, NULL }, /* channel 5 */ - { 1, 0, 0x41 }, /* channel 6 */ - { 3, 1, 0x61 }, /* channel 7 */ - { 5, 2, 0x81 }, /* channel 8 */ - { 6, 3, 0xa1 } /* channel 9 */ -}; - -/* forward reference. */ -LOCAL int mz8310_reset(void); -LOCAL mz8310Stat mz8310_io_report_card(unsigned card, unsigned level); -LOCAL mz8310Stat mz8310_init_card(unsigned card); -LOCAL mz8310Stat mz8310_setup_int(unsigned card, unsigned channel); -LOCAL mz8310Stat mz8310_io_report(unsigned level); -LOCAL mz8310Stat mz8310_init(void); -LOCAL mz8310Stat mz8310_read_test(unsigned card, unsigned channel); -LOCAL void mz8310_int_service(struct mz8310_int_conf *icf); - -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvMz8310={ - 2, - mz8310_io_report, - mz8310_init}; - - -/* - * mz8310_io_report() - */ -LOCAL mz8310Stat mz8310_io_report(unsigned level) -{ - unsigned card; - - for(card=0; card= MZ8310CHANONCHIP * MZ8310CHIPCOUNT) - return S_dev_badSignalNumber; - - if(card>=mz8310_card_count) - return S_dev_badA16; - - if(!mzconf) - return S_dev_noDevice; - - FASTLOCK(&mzconf[card].lock); - - status = - stc_one_shot_read( - preset, - &iedge0, - &iedge1, - MZ8310_CMD_ADDR(card,chip), - MZ8310_DATA_ADDR(card,chip), - channel % MZ8310CHANONCHIP, - int_source); - if(status==STC_SUCCESS){ - ticks = *int_source ? INT_TICKS : EXT_TICKS; - *edge0_delay = iedge0 / ticks; - *edge1_delay = iedge1 / ticks; - } - - FASTUNLOCK(&mzconf[card].lock); - - return status; -} - - -/* - * mz8310_read_test() - */ -LOCAL mz8310Stat mz8310_read_test(unsigned card, unsigned channel) -{ - unsigned preset; - double edge0_delay; - double edge1_delay; - unsigned int_source; - mz8310Stat status; - static char *pclktype[] = {"external-clk", "internal-clk"}; - static char *ppresettype[] = {"preset-FALSE", "preset-TRUE "}; - - status = - mz8310_one_shot_read( - &preset, - &edge0_delay, - &edge1_delay, - card, - channel, - &int_source); - if(status==MZ8310_SUCCESS){ - printf( "\tChannel %u %s delay=%f width=%f %s\n", - channel, - ppresettype[preset&1], - edge0_delay, - edge1_delay, - pclktype[int_source&1]); - if(mzconf[card].icf[channel].cnt) - printf("\tChannel %u Interrupt count=%u\n", - channel, - mzconf[card].icf[channel].cnt); - } - - return status; -} - - -/* - * mz8310_one_shot() - */ -mz8310Stat mz8310_one_shot( -unsigned preset, /* TRUE or COMPLEMENT logic */ -double edge0_delay, /* sec */ -double edge1_delay, /* sec */ -unsigned card, /* 0 through ... */ -unsigned channel, /* 0 through channels on a card */ -unsigned int_source, /* (FALSE)External/ (TRUE)Internal source */ -void (*event_rtn)(void *pParam), /* subroutine to run on events */ -void *event_rtn_param /* parameter to pass to above routine */ -) -{ - int chip = channel/MZ8310CHANONCHIP; - double ticks = int_source?INT_TICKS:EXT_TICKS; - mz8310Stat status; - - if(channel >= MZ8310CHANONCHIP * MZ8310CHIPCOUNT) - return S_dev_badSignalNumber; - - if(card>=mz8310_card_count) - return S_dev_badA16; - - if(!mzconf) - return S_dev_noDevice; - - /* dont overflow unsigned short in STC */ - if(edge0_delay >= 0xffff/ticks) - return S_dev_highValue; - if(edge1_delay >= 0xffff/ticks) - return S_dev_highValue; - if(edge0_delay < 0.0) - return S_dev_lowValue; - if(edge1_delay < 0.0) - return S_dev_lowValue; - - FASTLOCK(&mzconf[card].lock); - - /* Enable calling of user routine */ - if(MZ8310_INTERUPTABLE(channel)){ - mzconf[card].icf[channel].user_service = event_rtn; - mzconf[card].icf[channel].user_param = event_rtn_param; - } - - status = - stc_one_shot( - preset, - (unsigned short) (edge0_delay * ticks), - (unsigned short) (edge1_delay * ticks), - MZ8310_CMD_ADDR(card,chip), - MZ8310_DATA_ADDR(card,chip), - channel % MZ8310CHANONCHIP, - int_source); - - FASTUNLOCK(&mzconf[card].lock); - - return status; - -} - - - -/* - * mz8310_int_service() - */ -LOCAL void mz8310_int_service(struct mz8310_int_conf *icf) -{ - icf->cnt++; - - if(icf->user_service) - (*icf->user_service)(icf->user_param); - - return; -} - -/* - * The following are provided for mz8310 access from the shell - */ - - -/* - * mz8310_cmd() - */ -int mz8310_cmd( -unsigned value, -unsigned card, -unsigned chip -) -{ - volatile unsigned char *cmd = MZ8310_CMD_ADDR(card,chip); - - *cmd = value; - - return *cmd; -} - - -/* - * mz8310_rdata() - */ -int mz8310_rdata(int card, int chip) -{ - volatile unsigned short *data = MZ8310_DATA_ADDR(card,chip); - - return *data; -} - - -/* - * mz8310_wdata() - */ -int mz8310_wdata( -unsigned value, -unsigned card, -unsigned chip -) -{ - volatile uint16_t *data = MZ8310_DATA_ADDR(card,chip); - - *data = value; - - return value; -} - - - -/* - * mz8310_reset - */ -LOCAL int mz8310_reset(void) -{ - short card,channel,chip; - - for (card = 0; card < mz8310_card_count; card++){ - FASTLOCK(&mzconf[card].lock); - for ( channel = 0; channel < tm_num_channels[MZ8310]; channel++){ - if (mzconf[card].icf[channel].cnt){ - chip = channel/MZ8310CHANONCHIP; - - stc_one_shot( - 0, - 10, - 0, - MZ8310_CMD_ADDR(card,chip), - MZ8310_DATA_ADDR(card,chip), - channel % MZ8310CHANONCHIP, - 0); - } - } - FASTUNLOCK(&mzconf[card].lock); - } - - return OK; -} - - - diff --git a/src/drv/ansi/drvMz8310.h b/src/drv/ansi/drvMz8310.h deleted file mode 100644 index f4023bbe6..000000000 --- a/src/drv/ansi/drvMz8310.h +++ /dev/null @@ -1,74 +0,0 @@ -/* drvMz8310.c */ -/* base/src/drv $Id$ */ -/* - * Routines specific to the MZ8310. Low level routines for the AMD STC in - * stc_driver.c - * Author: Jeff Hill - * Date: Feb 1989 - * - * 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 History - */ - - - - -#define MZ8310_SUCCESS 0 - -typedef long mz8310Stat; - -mz8310Stat mz8310_one_shot_read( -unsigned *preset, /* TRUE or COMPLEMENT logic */ -double *edge0_delay, /* sec */ -double *edge1_delay, /* sec */ -unsigned card, /* 0 through ... */ -unsigned channel, /* 0 through channels on a card */ -unsigned *int_source /* (FALSE)External/(TRUE)Internal src */ -); - -mz8310Stat mz8310_one_shot( -unsigned preset, /* TRUE or COMPLEMENT logic */ -double edge0_delay, /* sec */ -double edge1_delay, /* set */ -unsigned card, /* 0 through ... */ -unsigned channel, /* 0 through channels on a card */ -unsigned int_source, /* (FALSE)External/ (TRUE)Internal source */ -void (*event_rtn)(void *pParam), /* subroutine to run on events */ -void *event_rtn_param /* parameter to pass to above routine */ -); - -int mz8310_cmd( -unsigned value, -unsigned card, -unsigned chip -); - -int mz8310_rdata(int card, int chip); - -int mz8310_wdata( -unsigned value, -unsigned card, -unsigned chip -); - - diff --git a/src/drv/ansi/drvStc.c b/src/drv/ansi/drvStc.c deleted file mode 100644 index 45b779cde..000000000 --- a/src/drv/ansi/drvStc.c +++ /dev/null @@ -1,316 +0,0 @@ -/* drvStc.c */ -/* base/src/drv $Id$ */ -/* - * The following are specific driver routines for the AMD STC - * - * NOTE: if multiple threads use these routines at once you must provide locking - * so command/data sequences are gauranteed. See mz8310_driver.c for examples. - * - * - * Author: Jeff Hill - * Date: Feb 89 - * - * 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: - * ----------------- - * - * joh 022089 Init Release - * joh 042889 Added read back - * joh 111789 Fixed reset goes to byte mode bug - * joh 121090 Fixed confusion about the polarity of internal/external - * clock between DB and the drivers. - * joh 110791 Prevent the stc from generating tc prior to the trigger - * in delayed pulse mode by forcing edge 0 delays of zero to be - * a delay of one instead. - * joh 010491 force all edge 0 delays less than two to two - * joh 082493 ANSI C and EPICS return codes - */ - -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include -#include -#include -#include - - - -/* - * stc_io_report() - */ -stcStat stc_io_report( -volatile uint8_t *pcmd, -volatile uint16_t *pdata -) -{ - uint8_t cmd; - uint16_t data; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - - /* - * addd AMD STC status here - */ - - return STC_SUCCESS; -} - - - -/* - * stc_init() - */ -stcStat stc_init( -volatile uint8_t *pcmd, -volatile uint16_t *pdata, -unsigned master_mode -) -{ - uint8_t cmd; - uint16_t data; - unsigned channel; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - - /* - * go to 16 bit mode in order to test the master mode register - */ - STC_BUS16; - if(master_mode != STC_MASTER_MODE){ - - /* - * start in a known state - */ - STC_RESET; - - /* - * required since the reset puts it in byte mode - */ - STC_BUS16; - STC_SET_MASTER_MODE(master_mode); - for(channel=0; channel=CHANONCHIP) - return S_dev_badSignalNumber; - - STC_CTR_READ(mode, edge0, edge1); - - /* - * Only return values if the counter is in the proper mode - * see stc_one_shot() for info on conversions and functions selected - * by these bit fields - */ - if(mode == 0xc16a){ - *int_source = FALSE; - *preset = TRUE; - *edge0_count = ~edge0; - *edge1_count = ~edge1+1; - } - else if(mode == 0xc162){ - *int_source = FALSE; - *preset = FALSE; - *edge0_count = edge0-1; - *edge1_count = edge1; - } - else if(mode == 0xcb6a){ - *int_source = TRUE; - *preset = TRUE; - *edge0_count = ~edge0; - *edge1_count = ~edge1+1; - } - else if(mode == 0xcb62){ - *int_source = TRUE; - *preset = FALSE; - *edge0_count = edge0-1; - *edge1_count = edge1; - } - else - return S_dev_internal; - - return STC_SUCCESS; -} - - - -/* - * stc_one_shot() - */ -stcStat stc_one_shot( -unsigned preset, -unsigned edge0_count, -unsigned edge1_count, -volatile uint8_t *pcmd, -volatile uint16_t *pdata, -unsigned channel, -unsigned int_source -) -{ - uint8_t cmd; - uint16_t data; - - if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK) - return S_dev_noDevice; - if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK) - return S_dev_noDevice; - if(channel>=CHANONCHIP) - return S_dev_badSignalNumber; - - /* - * joh 110791 - * Prevent the stc from generating tc prior to the trigger - * in delayed pulse mode by forcing edge 0 delays of zero to be - * a delay of one instead. - * - * 010492 - * Strange extra edges occur when the delay is 0 or 1 - * and the counter is reinitialized to a width of - * zero so I have disabled a delay of one also - * - * These extra edges occur when TC is set - */ - - if(edge0_count < 2) - edge0_count = 2; - - STC_DISARM; - - /* - * active positive going edge (gate input) - * count on the rising edge of source - * ctr source: (F1- internal) (SRC1- external) - * mode L - Hardware triggered delayed pulse one-shot - * binary count - * count down (count up if preset is TRUE) - * TC toggled output - * - * see chapter 7 of the Am9513 STC tech man concerning count + 1 - * - */ - - /* - * NOTE: I must be able to read back the state of the preset later - * so I encode this information in the count down/up bit. - * count up on TRUE preset - * count down on FALSE preset - * - * see stc_one_shot_read() above - */ - if(int_source){ - if(preset) - STC_CTR_INIT(0xcb6a, ~edge0_count, ~edge1_count+1) - else - STC_CTR_INIT(0xcb62, edge0_count+1, edge1_count); - }else{ - if(preset) - STC_CTR_INIT(0xc16a, ~edge0_count, ~edge1_count+1) - else - STC_CTR_INIT(0xc162, edge0_count+1, edge1_count); - } - - STC_LOAD; - /* - *see chapter 7 of the Am9513 STC tech man concerning this step - */ - - STC_STEP; - - STC_SET_TC(preset); - - /* - * Only arm counter if the pulse has a finite duration - */ - if(edge1_count != 0){ - STC_ARM; - } - - return STC_SUCCESS; -} - -/* - * stcWriteData() - */ -void stcWriteData(volatile uint16_t *pdata, uint16_t data) -{ - *pdata = data; -} - -/* - * stcReadData() - */ -uint16_t stcReadData(volatile uint16_t *pdata) -{ - uint16_t data; - data = *pdata; - return data; -} - -/* - * stcWriteCmd() - */ -void stcWriteCmd(volatile uint8_t *pcmd, uint8_t cmd) -{ - *pcmd = cmd; -} - diff --git a/src/drv/ansi/drvStc.h b/src/drv/ansi/drvStc.h deleted file mode 100644 index a0cccacef..000000000 --- a/src/drv/ansi/drvStc.h +++ /dev/null @@ -1,116 +0,0 @@ -/* drvStc.h */ -/* base/src/drv $Id$ */ -/* - * The following are specific driver routines for the AMD STC - * - * NOTE: if multiple threads use these routines at once you must provide locking - * so command/data sequences are gauranteed. See mz8310_driver.c for examples. - * - * - * Author: Jeff Hill - * Date: Feb 89 - * - * 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: - * ----------------- - * - * joh 022089 Init Release - * joh 082493 ANSI C and EPICS return codes - */ - -/* - * AMD STC constants - */ -#define CHANONCHIP 5U -#define CHIPCHAN (channel%CHANONCHIP) -#define CHIPNUM (channel/CHANONCHIP) - -#define STC_RESET stcWriteCmd(pcmd,0xffU); -#define STC_BUS16 stcWriteCmd(pcmd,0xefU); -#define STC_BUS16 stcWriteCmd(pcmd,0xefU); -#define STC_SET_MASTER_MODE(D) {stcWriteCmd(pcmd,0x17U); \ - stcWriteData(pdata,(D));} -#define STC_MASTER_MODE (stcWriteCmd(pcmd,0x17U), stcReadData(pdata)) - -#define STC_CTR_INIT(MODE,LOAD,HOLD)\ -{stcWriteCmd(pcmd,CHIPCHAN+1); stcWriteData(pdata,(MODE)); \ -stcWriteData(pdata,(LOAD)); stcWriteData(pdata,(HOLD));} - -#define STC_CTR_READ(MODE,LOAD,HOLD)\ -{stcWriteCmd(pcmd,CHIPCHAN+1); (MODE) = stcReadData(pdata); \ -(LOAD) = stcReadData(pdata); (HOLD) = stcReadData(pdata);} - -#define STC_SET_TC(D) stcWriteCmd(pcmd, \ - 0xe0U | ((D)?8:0)|(CHIPCHAN+1U) ) - -#define STC_LOAD stcWriteCmd(pcmd, 0x40U | 1<<(CHIPCHAN)) -#define STC_STEP stcWriteCmd(pcmd, 0xf0U | (CHIPCHAN+1U)) -#define STC_ARM stcWriteCmd(pcmd, 0x20U | 1< -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -#define T810_INT_VEC_BASE 0x60 -#define T810_MAGIC_NUMBER 81001 - - -#ifndef NO_EPICS -#include - -/* EPICS Driver Support Entry Table */ - -struct drvet drvTip810 = { - 3, - (DRVSUPFUN) t810Report, - (DRVSUPFUN) t810Initialise, - NULL -}; - -#endif /* NO_EPICS */ - - -typedef void callback_t(void *pprivate, long parameter); - -typedef struct callbackTable_s { - struct callbackTable_s *pnext; /* linked list ... */ - void *pprivate; /* reference for callback routine */ - callback_t *pcallback; /* registered routine */ -} callbackTable_t; - - -typedef struct t810Dev_s { - struct t810Dev_s *pnext; /* To next device. Must be first member */ - int magicNumber; /* device pointer confirmation */ - char *pbusName; /* Bus identification */ - ushort_t card; /* Industry Pack address */ - ushort_t slot; /* " " " */ - uint_t busRate; /* bit rate of bus in Kbits/sec */ - pca82c200_t *pchip; /* controller registers */ - uchar_t *pintVec; /* interrupt vector register */ - SEM_ID txSem; /* Transmit buffer protection */ - uint_t txCount; /* messages transmitted */ - uint_t rxCount; /* messages received */ - uint_t overCount; /* overrun - lost messages */ - uint_t unusedCount; /* messages without callback */ - ushort_t unusedId; /* last ID received without a callback */ - uint_t errorCount; /* Times entered Error state */ - uint_t busOffCount; /* Times entered Bus Off state */ - SEM_ID readSem; /* canRead task Mutex */ - canMessage_t *preadBuffer; /* canRead destination buffer */ - SEM_ID rxSem; /* canRead message arrival signal */ - callbackTable_t *pmsgHandler[CAN_IDENTIFIERS]; /* message callbacks */ - callbackTable_t *psigHandler; /* error signal callbacks */ -} t810Dev_t; - - -t810Dev_t *pt810First = NULL; - - -/******************************************************************************* - -Routine: - t810Report - -Purpose: - Report status of all t810 devices - -Description: - Prints a list of all the t810 devices created, their IP carrier & - slot numbers and the bus name string. For interest > 0 it gives - some message statistics, and for interest > 1 also lists all CAN - IDs for which a callback has been registered. - -Returns: - OK, or - S_t810_badDevice if device list corrupted. - -*/ - -int t810Report ( - int interest -) { - t810Dev_t *pdevice = pt810First; - ushort_t id, printed; - uchar_t status; - - while (pdevice != NULL) { - if (pdevice->magicNumber != T810_MAGIC_NUMBER) { - printf("t810 device list is corrupt\n"); - return S_t810_badDevice; - } - - printf(" '%s' : IP Carrier %hd Slot %hd, Bus rate %d Kbits/sec\n", - pdevice->pbusName, pdevice->card, pdevice->slot, - pdevice->busRate); - - switch (interest) { - case 1: - printf("\tMessages Sent : %5d\n", pdevice->txCount); - printf("\tMessages Received : %5d\n", pdevice->rxCount); - printf("\tMessage Overruns : %5d\n", pdevice->overCount); - printf("\tDiscarded Messages : %5d\n", pdevice->unusedCount); - if (pdevice->unusedCount > 0) { - printf("\tLast Discarded ID : %#5x\n", pdevice->unusedId); - } - printf("\tError Interrupts : %5d\n", pdevice->errorCount); - printf("\tBus Off Events : %5d\n", pdevice->busOffCount); - break; - - case 2: - printed = 0; - printf("\tCallbacks registered: "); - for (id=0; id < CAN_IDENTIFIERS; id++) { - if (pdevice->pmsgHandler[id] != NULL) { - if (printed % 10 == 0) { - printf("\n\t "); - } - printf("0x%-3hx ", id); - printed++; - } - } - if (printed == 0) { - printf("None."); - } - printf("\n\tcanRead Status : %s\n", - pdevice->preadBuffer ? "Active" : "Idle"); - break; - - case 3: - printf(" pca82c200 Chip Status:\n"); - status = pdevice->pchip->status; - - printf("\tBus Status : %s\n", - status & PCA_SR_BS ? "Bus-Off" : "Bus-On"); - printf("\tError Status : %s\n", - status & PCA_SR_ES ? "Error" : "Ok"); - printf("\tData Overrun : %s\n", - status & PCA_SR_DO ? "Overrun" : "Ok"); - printf("\tReceive Status : %s\n", - status & PCA_SR_RS ? "Receiving" : "Idle"); - printf("\tReceive Buffer Status : %s\n", - status & PCA_SR_RBS ? "Full" : "Empty"); - printf("\tTransmit Status : %s\n", - status & PCA_SR_TS ? "Transmitting" : "Idle"); - printf("\tTransmission Complete : %s\n", - status & PCA_SR_TCS ? "Complete" : "Incomplete"); - printf("\tTransmit Buffer Access : %s\n", - status & PCA_SR_TBS ? "Released" : "Locked"); - break; - } - pdevice = pdevice->pnext; - } - return OK; -} - - -/******************************************************************************* - -Routine: - t810Create - -Purpose: - Register a new TIP810 device - -Description: - Checks that the given name and card/slot numbers are unique, then - creates a new device table, initialises it and adds it to the end - of the linked list. - -Returns: - - -Example: - t810Create "CAN1", 0, 0, 500 - -*/ - -int t810Create ( - char *pbusName, /* Unique Identifier for this device */ - ushort_t card, /* Ipac Driver card .. */ - ushort_t slot, /* .. and slot number */ - uint_t busRate /* in Kbits/sec */ -) { - static const struct { - uint_t rate; - uchar_t busTiming0; - uchar_t busTiming1; - } rateTable[] = { - 5, PCA_BTR0_5K, PCA_BTR1_5K, - 10, PCA_BTR0_10K, PCA_BTR1_10K, - 20, PCA_BTR0_20K, PCA_BTR1_20K, - 50, PCA_BTR0_50K, PCA_BTR1_50K, - 100, PCA_BTR0_100K, PCA_BTR1_100K, - 125, PCA_BTR0_125K, PCA_BTR1_125K, - 250, PCA_BTR0_250K, PCA_BTR1_250K, - 500, PCA_BTR0_500K, PCA_BTR1_500K, - 1000, PCA_BTR0_1M0, PCA_BTR1_1M0, - 1600, PCA_BTR0_1M6, PCA_BTR1_1M6, - -125, PCA_KVASER_125K, PCA_BTR1_KVASER, - -250, PCA_KVASER_250K, PCA_BTR1_KVASER, - -500, PCA_KVASER_500K, PCA_BTR1_KVASER, - -1000,PCA_KVASER_1M0, PCA_BTR1_KVASER, - 0 - }; - t810Dev_t *pdevice, *plist = (t810Dev_t *) &pt810First; - int status, rateIndex, id; - - status = ipmValidate(card, slot, IP_MANUFACTURER_TEWS, - IP_MODEL_TEWS_TIP810); - if (status) { - return status; - } - /* Slot contains a real TIP810 module */ - - if (busRate == 0) { - return S_t810_badBusRate; - } - for (rateIndex = 0; rateTable[rateIndex].rate != busRate; rateIndex++) { - if (rateTable[rateIndex].rate == 0) { - return S_t810_badBusRate; - } - } - /* Bus rate is legal and we now know the right chip settings */ - - while (plist->pnext != NULL) { - plist = plist->pnext; - if (strcmp(plist->pbusName, pbusName) == 0 || - (plist->card == card && - plist->slot == slot)) { - return S_t810_duplicateDevice; - } - } - /* plist now points to the last item in the list */ - - pdevice = malloc(sizeof (t810Dev_t)); - if (pdevice == NULL) { - return errno; - } - /* pdevice is our new device table */ - - pdevice->pnext = NULL; - pdevice->magicNumber = T810_MAGIC_NUMBER; - pdevice->pbusName = pbusName; - pdevice->card = card; - pdevice->slot = slot; - pdevice->busRate = busRate; - pdevice->pchip = (pca82c200_t *) ipmBaseAddr(card, slot, ipac_addrIO); - pdevice->pintVec = 0x41 + (uchar_t *) pdevice->pchip; - pdevice->preadBuffer = NULL; - pdevice->psigHandler = NULL; - - for (id=0; idpmsgHandler[id] = NULL; - } - - pdevice->txSem = semBCreate(SEM_Q_PRIORITY, SEM_FULL); - pdevice->rxSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pdevice->readSem = semMCreate(SEM_Q_PRIORITY | - SEM_INVERSION_SAFE | - SEM_DELETE_SAFE); - if (pdevice->txSem == NULL || - pdevice->rxSem == NULL || - pdevice->readSem == NULL) { - free(pdevice); /* Ought to free those semaphores, but... */ - return errno; - } - - plist->pnext = pdevice; - /* device table interface stuff filled in and added to list */ - - pdevice->pchip->control = PCA_CR_RR; /* Reset state */ - pdevice->pchip->acceptanceCode = 0; - pdevice->pchip->acceptanceMask = 0xff; - pdevice->pchip->busTiming0 = rateTable[rateIndex].busTiming0; - pdevice->pchip->busTiming1 = rateTable[rateIndex].busTiming1; - pdevice->pchip->outputControl = PCA_OCR_OCM_NORMAL | - PCA_OCR_OCT0_PUSHPULL | - PCA_OCR_OCT1_PUSHPULL; - /* chip now initialised, but held in the Reset state */ - - return OK; -} - - -/******************************************************************************* - -Routine: - t810Shutdown - -Purpose: - Reboot hook routine - -Description: - Stops interrupts and resets the CAN controller chip. - -Returns: - void - -*/ - -int t810Shutdown ( - int startType -) { - t810Dev_t *pdevice = pt810First; - - while (pdevice != NULL) { - if (pdevice->magicNumber != T810_MAGIC_NUMBER) { - /* Whoops! */ - return S_t810_badDevice; - } - - pdevice->pchip->control = PCA_CR_RR; /* Reset, interrupts off */ - pdevice = pdevice->pnext; - } - return OK; -} - - -/******************************************************************************* - -Routine: - getRxMessage - -Purpose: - Copy a received message from chip to memory - -Description: - Reads a message from the chip receive buffer into the message buffer - and flags to chip to release the buffer for further input. - -Returns: - void - -*/ - -LOCAL void getRxMessage ( - pca82c200_t *pchip, - canMessage_t *pmessage -) { - uchar_t desc0, desc1, i; - - desc0 = pchip->rxBuffer.descriptor0; - desc1 = pchip->rxBuffer.descriptor1; - - pmessage->identifier = (desc0 << PCA_MSG_ID0_RSHIFT) | - ((desc1 & PCA_MSG_ID1_MASK) >> PCA_MSG_ID1_LSHIFT); - pmessage->length = desc1 & PCA_MSG_DLC_MASK; - - if (desc1 & PCA_MSG_RTR) { - pmessage->rtr = RTR; - } else { - pmessage->rtr = SEND; - for (i=0; ilength; i++) { - pmessage->data[i] = pchip->rxBuffer.data[i]; - } - } - - pchip->command = PCA_CMR_RRB; /* Finished with chip buffer */ -} - - -/******************************************************************************* - -Routine: - putTxMessage - -Purpose: - Copy a message from memory to the chip - -Description: - Copies a message from the message buffer into the chip receive buffer - and flags to chip to transmit the message. - -Returns: - void - -*/ - -LOCAL void putTxMessage ( - pca82c200_t *pchip, - canMessage_t *pmessage -) { - uchar_t desc0, desc1, i; - - desc0 = pmessage->identifier >> PCA_MSG_ID0_RSHIFT; - desc1 = (pmessage->identifier << PCA_MSG_ID1_LSHIFT) & PCA_MSG_ID1_MASK; - desc1 |= pmessage->length & PCA_MSG_DLC_MASK; - - if (pmessage->rtr == SEND) { - for (i=0; ilength; i++) { - pchip->txBuffer.data[i] = pmessage->data[i]; - } - } else { - desc1 |= PCA_MSG_RTR; - } - - pchip->txBuffer.descriptor0 = desc0; - pchip->txBuffer.descriptor1 = desc1; - - pchip->command = PCA_CMR_TR; -} - - -/******************************************************************************* - -Routine: - doCallbacks - -Purpose: - calls all routines in the given list - -Description: - - -Returns: - void - -*/ - -LOCAL void doCallbacks ( - callbackTable_t *phandler, - long parameter -) { - while (phandler != NULL) { - (*phandler->pcallback)(phandler->pprivate, parameter); - phandler = phandler->pnext; - } -} - - -/******************************************************************************* - -Routine: - t810ISR - -Purpose: - Interrupt Service Routine - -Description: - - -Returns: - void - -*/ - -LOCAL void t810ISR ( - t810Dev_t *pdevice -) { - uchar_t intSource = pdevice->pchip->interrupt; - - if (intSource & PCA_IR_WUI) { /* Wake-up Interrupt */ - logMsg("Wake-up Interrupt from CANbus '%s'\n", - (int) pdevice->pbusName, 0, 0, 0, 0, 0); - } - - if (intSource & PCA_IR_TI) { /* Transmit Interrupt */ - pdevice->txCount++; - semGive(pdevice->txSem); - } - - if (intSource & PCA_IR_RI) { /* Receive Interrupt */ - canMessage_t message; - callbackTable_t *phandler; - - /* Take a local copy of the message */ - getRxMessage(pdevice->pchip, &message); - pdevice->rxCount++; - - /* Look up the message ID and do the message callbacks */ - phandler = pdevice->pmsgHandler[message.identifier]; - if (phandler == NULL) { - pdevice->unusedId = message.identifier; - pdevice->unusedCount++; - } else { - doCallbacks(phandler, (long) &message); - } - - /* If canRead is waiting for this ID, give it the message and kick it */ - if (pdevice->preadBuffer != NULL && - pdevice->preadBuffer->identifier == message.identifier) { - memcpy(pdevice->preadBuffer, &message, sizeof(canMessage_t)); - pdevice->preadBuffer = NULL; - semGive(pdevice->rxSem); - } - } - - if (intSource & PCA_IR_OI) { /* Overrun Interrupt */ - pdevice->overCount++; - pdevice->pchip->command = PCA_CMR_COS; - } - - if (intSource & PCA_IR_EI) { /* Error Interrupt */ - callbackTable_t *phandler = pdevice->psigHandler; - ushort_t status; - - switch (pdevice->pchip->status & (PCA_SR_ES | PCA_SR_BS)) { - case PCA_SR_ES: - status = CAN_BUS_ERROR; - pdevice->errorCount++; - break; - case PCA_SR_BS: - case PCA_SR_BS | PCA_SR_ES: - status = CAN_BUS_OFF; - pdevice->busOffCount++; - pdevice->pchip->control &= ~PCA_CR_RR; /* Clear Reset state */ - break; - default: - status = CAN_BUS_OK; - break; - } - - doCallbacks(phandler, status); - } -} - - -/******************************************************************************* - -Routine: - t810Initialise - -Purpose: - Initialise driver and all registered hardware - -Description: - Under EPICS this routine is called by iocInit, which must occur - after all canCreate calls in the startup script. It completes the - initialisation of the CAN controller chip and interrupt vector - registers for all known TIP810 devices and starts the chip - running. A reboot hook is used to make sure all interrupts are - turned off if the OS is shut down. - -Returns: - - -*/ - -int t810Initialise ( - void -) { - uchar_t intVec = T810_INT_VEC_BASE, intLevel; - t810Dev_t *pdevice = pt810First; - int status = OK; - - rebootHookAdd(t810Shutdown); - - while (pdevice != NULL) { - pdevice->txCount = 0; - pdevice->rxCount = 0; - pdevice->overCount = 0; - pdevice->unusedCount = 0; - pdevice->errorCount = 0; - pdevice->busOffCount = 0; - - if (intConnect(INUM_TO_IVEC(intVec), t810ISR, (int) pdevice)) { - status = errno; - } - *(pdevice->pintVec) = intVec++; - - intLevel = ipmIrqCmd(pdevice->card, pdevice->slot, 0, ipac_irqGetLevel); - sysIntEnable(intLevel); - - pdevice->pchip->control = PCA_CR_OIE | - PCA_CR_EIE | - PCA_CR_TIE | - PCA_CR_RIE; - - pdevice = pdevice->pnext; - } - return status; -} - - -/******************************************************************************* - -Routine: - canOpen - -Purpose: - Return device pointer for given CAN bus name - -Description: - Searches through the linked list of known t810 devices for one - which matches the name given, and returns the device pointer - associated with the relevant device table. - -Returns: - OK, or S_can_noDevice if no match found. - -Example: - void *can1; - status = canOpen("CAN1", &can1); - -*/ - -int canOpen ( - char *pbusName, - void **ppdevice -) { - t810Dev_t *pdevice = pt810First; - - while (pdevice != NULL) { - if (strcmp(pdevice->pbusName, pbusName) == 0) { - *ppdevice = pdevice; - return OK; - } - pdevice = pdevice->pnext; - } - return S_can_noDevice; -} - - -/******************************************************************************* - -Routine: - strdupn - -Purpose: - duplicate n characters of a string and return pointer to new substring - -Description: - Copies n characters from the input string to a newly malloc'ed memory - buffer, and adds a trailing '\0', then returns the new string pointer. - -Returns: - char *newString, or NULL if malloc failed. - -*/ - -LOCAL char* strdupn ( - const char *ct, - size_t n -) { - char *duplicate; - - duplicate = malloc(n+1); - if (duplicate == NULL) { - return NULL; - } - - memcpy(duplicate, ct, n); - duplicate[n] = '\0'; - - return duplicate; -} - - -/******************************************************************************* - -Routine: - canIoParse - -Purpose: - Parse a CAN address string into a canIo_t structure - -Description: - - -Returns: - OK, or - S_can_badAddress for illegal input strings, - S_can_noDevice for an unregistered bus name. - -Example: - canIoParse("CAN1/20:0126.4 0xfff", &myIo); - -*/ - -int canIoParse ( - char *canString, - canIo_t *pcanIo -) { - char separator; - char *name; - - pcanIo->canBusID = NULL; - - if (canString == NULL || - pcanIo == NULL) { - return S_can_badAddress; - } - - /* Get rid of leading whitespace and non-alphanumeric chars */ - while (!isalnum(*canString)) { - if (*canString++ == '\0') { - return S_can_badAddress; - } - } - - /* First part of string is the bus name */ - name = canString; - - /* find the end of the busName */ - canString = strpbrk(canString, "/:"); - if (canString == NULL || - *canString == '\0') { - return S_can_badAddress; - } - - /* now we're at character after the end of the busName */ - pcanIo->busName = strdupn(name, canString - name); - if (pcanIo->busName == NULL) { - return errno; - } - separator = *canString++; - - /* Handle / if present, convert from ms to ticks */ - if (separator == '/') { - pcanIo->timeout = strtol(canString, &canString, 0) * sysClkRateGet(); - pcanIo->timeout = ((pcanIo->timeout + 500) / 1000); - separator = *canString++; - } else { - pcanIo->timeout = WAIT_FOREVER; - } - - /* String must contain : */ - if (separator != ':') { - return S_can_badAddress; - } - pcanIo->identifier = strtoul(canString, &canString, 0); - - /* Handle . if present */ - separator = *canString++; - if (separator == '.') { - pcanIo->offset = strtoul(canString, &canString, 0); - if (pcanIo->offset >= CAN_DATA_SIZE) { - return S_can_badAddress; - } - separator = *canString++; - } else { - pcanIo->offset = 0; - } - - /* Final parameter is separated by whitespace */ - if (separator != ' ' && - separator != '\t') { - return S_can_badAddress; - } - pcanIo->parameter = strtol(canString, &canString, 0); - - /* Ok, finally look up the bus name */ - return canOpen(pcanIo->busName, &pcanIo->canBusID); -} - - -/******************************************************************************* - -Routine: - canWrite - -Purpose: - writes a CAN message to the bus - -Description: - - -Returns: - - -Example: - - -*/ - -int canWrite ( - void *canBusID, - canMessage_t *pmessage, - int timeout -) { - t810Dev_t *pdevice = (t810Dev_t *) canBusID; - int status; - - if (pdevice->magicNumber != T810_MAGIC_NUMBER) { - return S_t810_badDevice; - } - - if (pmessage->identifier >= CAN_IDENTIFIERS || - pmessage->length > CAN_DATA_SIZE || - (pmessage->rtr != SEND && pmessage->rtr != RTR)) { - return S_can_badMessage; - } - - status = semTake(pdevice->txSem, timeout); - if (status) { - return errno; - } - - if (pdevice->pchip->status & PCA_SR_TBS) { - putTxMessage(pdevice->pchip, pmessage); - return OK; - } else { - semGive(pdevice->txSem); - return S_t810_transmitterBusy; - } -} - - -/******************************************************************************* - -Routine: - canMessage - -Purpose: - Register CAN message callback - -Description: - Adds a new callback routine for the given CAN message ID on the - given device. There can be any number of callbacks for the same ID, - and all are called in turn when a message with this ID is - received. As a result, the callback routine must not change the - message at all - it is only permitted to examine it. The callback - is called from vxWorks Interrupt Context, thus there are several - restrictions in what the routine can perform (see vxWorks User - Guide for details of these). The callback routine should be - declared of type canMsgCallback_t - void callback(void *pprivate, can_Message_t *pmessage); - The pprivate value supplied to canMessage is passed to the callback - routine with each message to allow it to identify its context. - -Returns: - OK, - S_can_badMessage for bad identifier or NULL callback routine, - S_can_badDevice for bad device pointer. - -Example: - - -*/ - -int canMessage ( - void *canBusID, - ushort_t identifier, - canMsgCallback_t *pcallback, - void *pprivate -) { - t810Dev_t *pdevice = (t810Dev_t *) canBusID; - callbackTable_t *phandler, *plist; - - if (pdevice->magicNumber != T810_MAGIC_NUMBER) { - return S_t810_badDevice; - } - - if (identifier >= CAN_IDENTIFIERS || - pcallback == NULL) { - return S_can_badMessage; - } - - phandler = malloc(sizeof (callbackTable_t)); - if (phandler == NULL) { - return errno; - } - - phandler->pnext = NULL; - phandler->pprivate = pprivate; - phandler->pcallback = (callback_t *) pcallback; - - plist = (callbackTable_t *) (&pdevice->pmsgHandler[identifier]); - while (plist->pnext != NULL) { - plist = plist->pnext; - } - /* plist now points to the last handler in the list */ - - plist->pnext = phandler; - return OK; -} - - -/******************************************************************************* - -Routine: - canSignal - -Purpose: - Register CAN error signal callback - -Description: - Adds a new callback routine for the CAN error reports. There can be - any number of error callbacks, and all are called in turn when the - controller chip reports an error or bus Off The callback is called - from vxWorks Interrupt Context, thus there are restrictions in what - the routine can perform (see vxWorks User Guide for details of - these). The callback routine should be declared a canSigCallback_t - void callback(void *pprivate, ushort_t status); - The pprivate value supplied to canSignal is passed to the callback - routine with the error status to allow it to identify its context. - Status values will be one of - CAN_BUS_OK, - CAN_BUS_ERROR or - CAN_BUS_OFF. - If the chip goes to the Bus Off state, the driver will attempt to - restart it. - -Returns: - OK, - S_can_badDevice for bad device pointer. - -Example: - - -*/ - -int canSignal ( - void *canBusID, - canSigCallback_t *pcallback, - void *pprivate -) { - t810Dev_t *pdevice = (t810Dev_t *) canBusID; - callbackTable_t *phandler, *plist; - - if (pdevice->magicNumber != T810_MAGIC_NUMBER) { - return S_t810_badDevice; - } - - phandler = malloc(sizeof (callbackTable_t)); - if (phandler == NULL) { - return errno; - } - - phandler->pnext = NULL; - phandler->pprivate = pprivate; - phandler->pcallback = (callback_t *) pcallback; - - plist = (callbackTable_t *) (&pdevice->psigHandler); - while (plist->pnext != NULL) { - plist = plist->pnext; - } - /* plist now points to the last handler in the list */ - - plist->pnext = phandler; - return OK; -} - - -/******************************************************************************* - -Routine: - canRead - -Purpose: - read incoming CAN message, any ID number - -Description: - The simplest way to implement this is have canRead take a message - ID in the buffer, send an RTR and look for the returned value of - this message. This is in keeping with the CAN philosophy and makes - it useful for simple software interfaces. More complex ones ought - to use the canMessage callback functions. - -Returns: - OK, or - S_t810_badDevice for bad bus ID, - S_can_badMessage for bad message Identifier or length, - vxWorks errno for semTake failures (timeout etc). - -Example: - canMessage_t myBuffer = { - 139, // Can ID - 0, // RTR - 4 // Length - }; - int status = canRead(canID, &myBuffer, WAIT_FOREVER); - -*/ - -int canRead ( - void *canBusID, - canMessage_t *pmessage, - int timeout -) { - t810Dev_t *pdevice = (t810Dev_t *) canBusID; - int status; - - if (pdevice->magicNumber != T810_MAGIC_NUMBER) { - return S_t810_badDevice; - } - - if (pmessage->identifier >= CAN_IDENTIFIERS || - pmessage->length > CAN_DATA_SIZE) { - return S_can_badMessage; - } - - /* This semaphore is so only one task canRead simultaneously */ - status = semTake(pdevice->readSem, timeout); - if (status) { - return errno; - } - - pdevice->preadBuffer = pmessage; - - /* All set for the reply, now send the request */ - pmessage->rtr = RTR; - - status = canWrite(canBusID, pmessage, timeout); - if (status == OK) { - /* Wait for the message to be recieved */ - status = semTake(pdevice->rxSem, timeout); - if (status) { - status = errno; - } - } - if (status) { - /* Problem (timeout) sending the RTR or receiving the reply */ - pdevice->preadBuffer = NULL; - semTake(pdevice->rxSem, NO_WAIT); /* Must leave this EMPTY */ - } - semGive(pdevice->readSem); - return status; -} - - -/******************************************************************************* - -Routine: - canTest - -Purpose: - Test routine, sends a single message to the named bus. - -Description: - - -Returns: - - -Example: - - -*/ - -int canTest ( - char *pbusName, - ushort_t identifier, - ushort_t rtr, - uchar_t length, - char *data -) { - void *canBusID; - canMessage_t message; - int status = canOpen(pbusName, &canBusID); - - if (status) { - printf("Error %d opening CAN bus '%s'\n", status, pbusName); - return ERROR; - } - - message.identifier = identifier; - message.rtr = rtr ? RTR : SEND; - message.length = length; - - if (rtr == 0) { - memcpy(&message.data[0], data, length); - } - - status = canWrite(canBusID, &message, 0); - if (status) { - printf("Error %d writing message\n", status); - return ERROR; - } - return OK; -} diff --git a/src/drv/ansi/drvTip810.h b/src/drv/ansi/drvTip810.h deleted file mode 100644 index 43cae8e4f..000000000 --- a/src/drv/ansi/drvTip810.h +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - drvTip810.h - -Description: - Header file for TEWS TIP810 CAN Bus driver. - -Author: - Andrew Johnson -Created: - 20 July 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#ifndef INCdrvTip810H -#define INCdrvTip810H - -#include -#include "canBus.h" - - -/* Error Numbers */ - -#ifndef M_t810 -#define M_t810 (810<<16) -#endif - -#define S_t810_duplicateDevice (M_t810| 1) /*duplicate t810 device definition*/ -#define S_t810_badBusRate (M_t810| 2) /*CANbus bit rate not supported*/ -#define S_t810_badDevice (M_t810| 3) /*device pointer is not for t810*/ -#define S_t810_transmitterBusy (M_t810| 4) /*transmit buffer unexpectedly busy*/ - - -extern int t810Report(int page); -extern int t810Create(char *busName, ushort_t card, ushort_t slot, - uint_t busRate); -extern int t810Shutdown(int starttype); -extern int t810Initialise(void); - -#endif /* INCdrvTip810H */ - diff --git a/src/drv/ansi/drvVipc310.c b/src/drv/ansi/drvVipc310.c deleted file mode 100644 index b393033b0..000000000 --- a/src/drv/ansi/drvVipc310.c +++ /dev/null @@ -1,262 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - drvVipc310.c - -Description: - IPAC Carrier Driver for the GreenSpring VIPC310 Dual IndustryPack - Carrier VME board, provides the interface between IPAC driver and the - hardware. This carrier is 3U high, and thus cannot support 32-bit - accesses to dual-slot IP modules. - -Author: - Andrew Johnson -Created: - 5 July 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - -#include -#include -#include -#include -#include -#include "drvIpac.h" - - -/* Characteristics of the card */ - -#define SLOTS 2 -#define IO_SPACES 2 /* Address spaces in A16 */ -#define IPAC_IRQS 2 /* Interrupts per module */ - - -/* Offsets from base address in VME A16 */ - -#define REGS_A 0x0000 -#define PROM_A 0x0080 -#define REGS_B 0x0100 -#define PROM_B 0x0180 - - -/* VME Interrupt levels */ - -#define IRQ_A0 4 -#define IRQ_A1 5 -#define IRQ_B0 2 -#define IRQ_B1 1 - - -/* Carrier Private structure type, one instance per board */ - -typedef void* private_t[IPAC_ADDR_SPACES][SLOTS]; - - -/******************************************************************************* - -Routine: - initialise - -Purpose: - Creates new private table for VIPC310 at addresses given by cardParams - -Description: - Checks the parameter string for the address of the card I/O space and - optional size of the memory space for the modules. If both the I/O and - memory base addresses can be reached from the CPU, a private table is - created for this board. The private table is a 2-D array of pointers - to the base addresses of the various accessible parts of the IP module. - -Parameters: - The parameter string should comprise a hex number (the 0x or 0X at the - start is optional) optionally followed by a comma and a decimal integer. - The first number is the I/O base address of the card in the VME A16 - address space (the factory default is 0x6000). If present the second - number gives the memory space in Kbytes allocated to each IP module. - The memory base address of the VIPC310 card is set using the same jumpers - as the I/O base address and is always 256 times the I/O base address, - but in the VME A24 address space. The factory default fot the memory - base address is thus 0x600000. If the memory size parameter is omitted - or set to zero then neither IP module provides any memory space. Legal - memory size values are 0, 64, 128, 256, 512, 1024 or 2048. The memory - size interacts with the memory base address such that it is possible to - set the existance of memory in either slot independently with suitable - adjustment of the base address. - -Examples: - "0x6000" - This indicates that the carrier has its I/O base set to 0x6000, and - neither slot uses any memory space. - "1000,512" - Here the I/O base is set to 0x1000, and there is 512 Kbytes of - memory on each module, with the IP module A memory at 0x100000 - and module B at 0x180000. - "0xfe00, 128" - The I/O base is at 0xfe00, and hence the carrier memory base is - 0xfe0000. However because the memory size is set to give each module - 128 Kbytes of memory space, module A cannot be selected (128 K = - 0x020000, so the module is decoded at 0xfc0000 but can't be accessed - because this is below the memory base). - -Returns: - 0 = OK, - S_IPAC_badAddress = Parameter string error, or address not reachable - -*/ - -LOCAL int initialise ( - char *cardParams, - void **pprivate -) { - int params, status1 = OK, status2 = OK, mSize = 0; - long ioBase, mOrig, mBase; - ushort_t space, slot; - private_t *private; - static const int offset[IO_SPACES][SLOTS] = { - PROM_A, PROM_B, - REGS_A, REGS_B - }; - - if (cardParams == NULL || - strlen(cardParams) == 0) { - ioBase = 0x6000; - } else { - params = sscanf(cardParams, "%p,%i", (void **) &ioBase, &mSize); - if (params < 1 || params > 2 || - ioBase > 0xfe00 || ioBase & 0x01ff || - mSize < 0 || mSize > 2048 || mSize & 63) { - return S_IPAC_badAddress; - } - } - - mBase = ioBase << 8; /* Fixed by VIPC310 card */ - - status1 = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, - (char *) ioBase, (char **) &ioBase); - if (mSize > 0) { - status2 = sysBusToLocalAdrs(VME_AM_STD_SUP_DATA, - (char *) mBase, (char **) &mBase); - } - if (status1 || status2) { - return S_IPAC_badAddress; - } - - mSize = mSize << 10; /* Convert size from K to Bytes */ - mOrig = mBase & ~(mSize * SLOTS - 1); - - private = malloc(sizeof (private_t)); - for (space = 0; space < IO_SPACES; space++) { - for (slot = 0; slot < SLOTS; slot++) { - (*private)[space][slot] = (void *) (ioBase + offset[space][slot]); - } - } - - (*private)[ipac_addrIO32][0] = NULL; - (*private)[ipac_addrIO32][1] = NULL; - - if (mOrig == mBase) { - (*private)[ipac_addrMem][0] = (void *) mBase; - (*private)[ipac_addrMem][1] = (void *) (mBase + mSize); - } else { - (*private)[ipac_addrMem][0] = NULL; - (*private)[ipac_addrMem][1] = (void *) mBase; - } - - *pprivate = private; - return OK; -} - - -/******************************************************************************* - -Routine: - baseAddr - -Purpose: - Returns the base address for the requested slot & address space - -Description: - Because we did all that hard work in the initialise routine, this - routine only has to do a table lookup in the private array. - Note that no parameter checking is required - the IPAC driver which - calls this routine handles that. - -Returns: - The requested address, or NULL if the module has no memory. - -*/ - -LOCAL void *baseAddr ( - void *private, - ushort_t slot, - ipac_addr_t space -) { - return (*(private_t *) private)[space][slot]; -} - - -/******************************************************************************* - -Routine: - irqCmd - -Purpose: - Handles interrupter commands and status requests - -Description: - The GreenSpring board is limited to fixed interrupt levels, and has - no control over interrupts. The only commands thus supported are - a request of the interrupt level associated with a particular slot - and interrupt number, or to enable interrupts by making sure the - VMEbus interrupter is listening on the necessary level. - -Returns: - ipac_irqGetLevel returns the interrupt level (1, 2, 4 or 5), - ipac_irqEnable returns 0 = OK, - other calls return S_IPAC_notImplemented. - -*/ - -LOCAL int irqCmd ( - void *private, - ushort_t slot, - ushort_t irqNumber, - ipac_irqCmd_t cmd -) { - static const int irqLevel[SLOTS][IPAC_IRQS] = { - IRQ_A0, IRQ_A1, - IRQ_B0, IRQ_B1 - }; - - switch (cmd) { - case ipac_irqGetLevel: - return irqLevel[slot][irqNumber]; - - case ipac_irqEnable: - sysIntEnable(irqLevel[slot][irqNumber]); - return OK; - - default: - return S_IPAC_notImplemented; - } -} - -/******************************************************************************/ - - -/* IPAC Carrier Table */ - -ipac_carrier_t vipc310 = { - "GreenSpring VIPC310", - SLOTS, - initialise, - NULL, - baseAddr, - irqCmd -}; - diff --git a/src/drv/ansi/drvVipc610.c b/src/drv/ansi/drvVipc610.c deleted file mode 100644 index e4e7a45f0..000000000 --- a/src/drv/ansi/drvVipc610.c +++ /dev/null @@ -1,275 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - drvVipc610.c - -Description: - IPAC Carrier Driver for the GreenSpring VIPC610-01 Quad IndustryPack - Carrier VME board, provides the interface between IPAC driver and the - hardware. This carrier is 6U high, but cannot support 32-bit accesses - to dual-slot IP modules. Note the -01 option fixes the IRQ levels to - be equivalent to two VIPC310 carriers. - -Author: - Andrew Johnson -Created: - 19 July 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - -#include -#include -#include -#include -#include -#include "drvIpac.h" - - -/* Characteristics of the card */ - -#define SLOTS 4 -#define IO_SPACES 2 /* Address spaces in A16 */ -#define IPAC_IRQS 2 /* Interrupts per module */ - - -/* Offsets from base address in VME A16 */ - -#define REGS_A 0x0000 -#define PROM_A 0x0080 -#define REGS_B 0x0100 -#define PROM_B 0x0180 -#define REGS_C 0x0200 -#define PROM_C 0x0280 -#define REGS_D 0x0300 -#define PROM_D 0x0380 - - -/* VME Interrupt levels for -01 option */ - -#define IRQ_A0 4 -#define IRQ_A1 5 -#define IRQ_B0 2 -#define IRQ_B1 1 -#define IRQ_C0 4 -#define IRQ_C1 5 -#define IRQ_D0 2 -#define IRQ_D1 1 - - -/* Carrier Private structure type, one instance per board */ - -typedef void* private_t[IPAC_ADDR_SPACES][SLOTS]; - - -/******************************************************************************* - -Routine: - initialise - -Purpose: - Creates new private table for VIPC610 at addresses given by cardParams - -Description: - Checks the parameter string for the address of the card I/O space and - optional size of the memory space for the modules. If both the I/O and - memory base addresses can be reached from the CPU, a private table is - created for this board. The private table is a 2-D array of pointers - to the base addresses of the various accessible parts of the IP module. - -Parameters: - The parameter string should comprise a hex number (the 0x or 0X at the - start is optional) optionally followed by a comma and a decimal integer. - The first number is the I/O base address of the card in the VME A16 - address space (the factory default is 0x6000). If present the second - number gives the memory space in Kbytes allocated to each IP module. - The memory base address of the VIPC610 card is set using the same jumpers - as the I/O base address and is always 256 times the I/O base address, - but in the VME A24 address space. The factory default for the memory - base address is thus 0x600000. If the memory size parameter is omitted - or set to zero then none of the IP modules on the carrier provide any - memory space. Legal memory size values are 0, 64?, 128, 256, 512, 1024 - or 2048. The memory size interacts with the memory base address such - that it is possible to exclude memory from the lower slots while still - providing access to memory in the later slots by adjusting the base - address suitably. - -Examples: - "0x6000" - This indicates that the carrier board has its I/O base set to - 0x6000, and none of the slots provide memory space. - "1000,128" - Here the I/O base is set to 0x1000, and there is 128Kbytes of - memory on each module, with the IP module A memory at 0x100000, - module B at 0x120000, module C at 0x140000 and D at 0x160000. - "7000,1024" - The I/O base is at 0x7000, and hence the carrier memory base is - 0x700000. However because the memory size is set to 1024 Kbytes, - modules A, B and C cannot be selected (1024 K = 0x100000, so they - are decoded at 0x400000, 0x500000 and 0x600000 but can't be accessed - because these are below the base address). - -Returns: - 0 = OK, - S_IPAC_badAddress = Parameter string error, or address not reachable - -*/ - -LOCAL int initialise ( - char *cardParams, - void **pprivate -) { - int params, status1 = OK, status2 = OK, mSize = 0; - ulong_t ioBase, mOrig, mBase, addr; - ushort_t space, slot; - private_t *private; - static const int offset[IO_SPACES][SLOTS] = { - PROM_A, PROM_B, PROM_C, PROM_D, - REGS_A, REGS_B, REGS_C, REGS_D - }; - - if (cardParams == NULL || - strlen(cardParams) == 0) { - ioBase = 0x6000; - } else { - params = sscanf(cardParams, "%p,%i", (void **) &ioBase, &mSize); - if (params < 1 || params > 2 || - ioBase > 0xfc00 || ioBase & 0x01ff || - mSize < 0 || mSize > 2048 || mSize & 63) { - return S_IPAC_badAddress; - } - } - - mBase = ioBase << 8; /* Fixed by the VIPC610 card */ - ioBase = ioBase & 0xfc00; /* Clear A09 */ - - status1 = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, - (char *) ioBase, (char **) &ioBase); - if (mSize > 0) { - status2 = sysBusToLocalAdrs(VME_AM_STD_SUP_DATA, - (char *) mBase, (char **) &mBase); - } - if (status1 || status2) { - return S_IPAC_badAddress; - } - - mSize = mSize << 10; /* Convert size from K to Bytes */ - mOrig = mBase & ~(mSize * SLOTS - 1); - - private = malloc(sizeof (private_t)); - for (space = 0; space < IO_SPACES; space++) { - for (slot = 0; slot < SLOTS; slot++) { - (*private)[space][slot] = (void *) (ioBase + offset[space][slot]); - } - } - - for (slot = 0; slot < SLOTS; slot++) { - (*private)[ipac_addrIO32][slot] = NULL; - addr = mOrig + (mSize * slot); - if (addr < mBase) { - (*private)[ipac_addrMem][slot] = NULL; - } else { - (*private)[ipac_addrMem][slot] = (void *) addr; - } - } - - *pprivate = private; - - return OK; -} - - -/******************************************************************************* - -Routine: - baseAddr - -Purpose: - Returns the base address for the requested slot & address space - -Description: - Because we did all that hard work in the initialise routine, this - routine only has to do a table lookup in the private array. - Note that no parameter checking is required - the IPAC driver which - calls this routine handles that. - -Returns: - The requested address, or NULL if the module has no memory. - -*/ - -LOCAL void *baseAddr ( - void *private, - ushort_t slot, - ipac_addr_t space -) { - return (*(private_t *) private)[space][slot]; -} - - -/******************************************************************************* - -Routine: - irqCmd - -Purpose: - Handles interrupter commands and status requests - -Description: - The GreenSpring board is limited to fixed interrupt levels, and has - no control over interrupts. The only commands thus supported are - a request of the interrupt level associated with a particular slot - and interrupt number, or to enable interrupts by making sure the - VMEbus interrupter is listening on the necessary level. - -Returns: - ipac_irqGetLevel returns the interrupt level (1, 2, 4 or 5), - ipac_irqEnable returns 0 = OK, - other calls return S_IPAC_notImplemented. - -*/ - -LOCAL int irqCmd ( - void *private, - ushort_t slot, - ushort_t irqNumber, - ipac_irqCmd_t cmd -) { - static const int irqLevel[SLOTS][IPAC_IRQS] = { - IRQ_A0, IRQ_A1, - IRQ_B0, IRQ_B1, - IRQ_C0, IRQ_C1, - IRQ_D0, IRQ_D1 - }; - - switch (cmd) { - case ipac_irqGetLevel: - return irqLevel[slot][irqNumber]; - - case ipac_irqEnable: - sysIntEnable(irqLevel[slot][irqNumber]); - return OK; - - default: - return S_IPAC_notImplemented; - } -} - -/******************************************************************************/ - - -/* IPAC Carrier Table */ - -ipac_carrier_t vipc610 = { - "GreenSpring VIPC610-01", - SLOTS, - initialise, - NULL, - baseAddr, - irqCmd -}; - diff --git a/src/drv/ansi/drvVmic2534.c b/src/drv/ansi/drvVmic2534.c deleted file mode 100644 index 001ea7eff..000000000 --- a/src/drv/ansi/drvVmic2534.c +++ /dev/null @@ -1,690 +0,0 @@ -/* drvVmi2534.c */ -/* share/src/drv @(#)drvVmic2534.c 1.1 003/22/94 */ - -#ifndef lint -static char rcsid[] = - "@(#) /babar/CVSROOT/epics/base/src/drv/old/drvVmi2534.c,v 1.1 1996/01/09 19:54:35 lewis Exp(LBL)"; -#endif - -/* - * routines used to test and interface with V.M.I.C. VMIVME-2534 - * digital i/o module - * - * Author: Bill Brown - * Date: 03/22/94 - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1994, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (DE-AC03-76SF00) at Lawrence Berkeley Laboratory. - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * Control System Group - * Advanced Light Source - * Lawrence Berkeley Laboratory - * - * Co-developed with - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * NOTES: - * This code is/was cloned from "drvXy240.c" of EPICS R3.11 - * - * Data direction is dynamically assigned at ioInit() time. - * The definition of the first bit(s) in a given byte will - * determine the data direction of all bits within that byte. - * - * Modification Log: - * - * - @(#) drvVmi2534.c,v - @(#) Revision 1.1 1996/01/09 19:54:35 lewis - @(#) Add PAL record. Remove APS eg/er records. - @(#) Add 4 STAR drivers, LBL 2534, and preliminaries for LBL/SLAC 9210/9325 drivers. - @(#) - * Revision 1.1.1.1 1995/07/25 21:49:57 lewis - * Baseline import R3.12 w/LBL drivers and mods. - * - * Revision 1.5 1994/09/28 09:05:51 wbrown - * at beginning of init function, ctrl reg is set to match - * SYS_RESET* condition. - * - * Revision 1.4 94/09/27 09:44:31 wbrown - * changed order of "writes to '2534 hardware during initialization - * to prevent undesired output transistions when calculating - * "output correction factor." - * - * Revision 1.3 94/08/19 15:16:14 wbrown - * added debug #ifdef, printf statements - * fixed initialization of record definition structure - * - * Revision 1.2 94/07/20 09:25:26 wbrown - * modified to dynamically assign data direction at - * record init time. - * - * Revision 1.1 94/05/27 09:57:51 wbrown - * Initial revision - * - * - */ - -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "errlog.h" -#include "module_types.h" -#include "task_params.h" -#include "drvSup.h" -#include "dbDefs.h" -#include "dbScan.h" -#include "taskwd.h" - -#define VMIC_2534_ADDR0 (bi_addrs[VMIC_2534_BI]) -#define VMIC_2534_MAX_CARDS (bi_num_cards[VMIC_2534_BI]) -#define VMIC_2534_MAX_CHANS (bi_num_channels[VMIC_2534_BI]) - -/* control-status register - bit definiitions */ - -#define BYTE_0_OUT_ENA 1<<0 -#define BYTE_1_OUT_ENA 1<<1 -#define BYTE_2_OUT_ENA 1<<2 -#define BYTE_3_OUT_ENA 1<<3 - -#define FAIL_LED_OFF 1<<5 -#define TM1_ENABLE 1<<7 -#define TM2_ENABLE 1<<6 - -/* Refer to VMIVME-2534 manual for hardware options */ -/* These boards are available in two configurations; */ -/* "POSITIVE-TRUE Option" - writing a "1" to the output register */ -/* "TURNS ON the output driver, ie pulls the output LOW */ -/* "NEGATIVE-TRUE Option" - writing a "1" to the output register */ -/* "TURNS OFF" the output driver, allowing the load to pull */ -/* the output HIGH. */ - -/* The initialization routine recognizes which type of board is */ -/* installed and generates a mask which is used by the device- */ -/* driver to cause BOTH board types to appear to have the */ -/* POSITIVE-TRUE Option installed. */ - -#define FAIL_FLAG 1<<5 - /* Test Mode */ -#define TM2 1<<6 /* TM2 - "1" = disable test buffers */ -#define TM1 1<<7 /* TM1 - "1" = enable output drivers */ - -#define masks( K ) ((1<pioData ) - & ( vmic2534Rec[ i ].inputMask ); - - if ( (temp ^ vmic2534Rec[ i ].savedInputs) || firstScan ) - { - scanIoRequest( vmic2534Rec[ i ].ioscanpvt ); - vmic2534Rec[ i ].savedInputs = temp; - } - } - } - - if ( firstScan ) - firstScan = FALSE; - - taskDelay( vxTicksPerSecond/30 ); - } - } - - -/* - * DIO DRIVER INIT - * - */ - -vmic2534Init( ) - { - u_long dummy; - register short i; - VMIC_2534 *theHardware; - int tid; - int status; - int atLeastOnePresent = FALSE; - - /* - * allow for runtime reconfiguration of the addr map - */ - - vmic2534Rec = (VMIC_2534_REC *)calloc( - VMIC_2534_MAX_CARDS, sizeof( VMIC_2534_REC ) ); - if ( !vmic2534Rec ) - { - logMsg("Attempt to calloc \"VMIC_2534_REC\" failed\n"); - return( ERROR ); - } - status = sysBusToLocalAdrs( VME_AM_SUP_SHORT_IO, (VMIC_2534_ADDR0), - &theHardware ); - if ( status != OK ) - { - logMsg("%s: Unable to map VMIC_2534 base addr\n", __FILE__); - return( ERROR ); - } - - for ( i = 0; i < VMIC_2534_MAX_CARDS; i++, theHardware++ ) - { - if ( (vxMemProbe( theHardware, READ, 2 ,&dummy )) != OK ) - { - vmic2534Rec[i].vmicDevice = NULL; - continue; - } - else - /* initialize hardware */ - { - /* Outputs/Inputs are undetermined at this time */ - /* Disable output drivers in case of no SYS_RESET* */ - theHardware->ctlStatReg = 0; - - /* determine "sense" of output and save correction factor */ - theHardware->pioData = 0; - vmic2534Rec[i].outputCorrector = theHardware->pioData; - - /* clear input & output masks, (malloc'ed mem may != 0) */ - vmic2534Rec[i].inputMask = 0; - vmic2534Rec[i].outputMask = 0; - - /* insure that outputs are initially "OFF", i.e. HIGH */ - theHardware->pioData = vmic2534Rec[i].outputCorrector; - theHardware->ctlStatReg = TM1 | TM2 | FAIL_LED_OFF; - - /* - * record structure initalization - */ - - vmic2534Rec[ i ].vmicDevice = theHardware; - atLeastOnePresent = TRUE; - scanIoInit( &(vmic2534Rec[ i ].ioscanpvt) ); - } - } - - if ( atLeastOnePresent) - { - if ( (tid = taskNameToId( VMIC_2534_NAME )) != ERROR ) - { - taskwdRemove( tid ); - taskDelete( tid ); - } - - if ( (status = taskSpawn( - VMIC_2534_NAME, VMIC_2534_PRI, VMIC_2534_OPT, - VMIC_2534_STACK, vmic2534IOScan )) == ERROR ) - logMsg("Unable to spawn \"vmic2534IOScan( )\" task\n"); - else - taskwdInsert( status, NULL, NULL ); - } - return( OK ); - } - -/* - * Set data direction control for specified data bits - * Note: - * Data direction is controlled on a "per-byte" basis. - * The first bit defined within a byte sets the direction for the entire - * byte. Any attempt to define conflicting bits after the direction - * for a byte is set will return an error (-1) response.) - * Permmissable values for "direction" are: - * direction == 0 indicates input - * direction != 0 indicates output - * - */ -vmic2534_setIOBitDirection( short card, u_int mask, u_int direction ) - { - int status = 0; - u_long work, j; - - static u_long maskTbl[ ] = - { 0x000000ff, - 0x0000ff00, - 0x00ff0000, - 0xff000000 - }; - - if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) ) - status = -1 ; - else - { - if ( direction == 0) - { - /* INPUT */ -#ifdef DEBUG_2534 - printf("Mask = %08x, outPutMask =%08x\n", - mask, vmic2534Rec[ card ].outputMask); -#endif DEBUG_2534 - if ( ((u_long)mask & vmic2534Rec[ card ].outputMask) == 0 ) - { - for ( j = 0; j < 4; j++ ) - { - - if ( ( (u_long)mask & maskTbl[ j ] ) != 0 ) - { - vmic2534Rec[ card ].inputMask |= maskTbl[ j ]; -#ifdef DEBUG_2534 - printf("inputMask = %08x\n", - vmic2534Rec[ card ].inputMask); -#endif DEBUG_2534 - vmic2534Rec[ card ].vmicDevice->ctlStatReg - &= (u_char) ~(1 << j); - } - } - } - else - { - status = -1; - } - } - else - { - /* OUTPUT */ -#ifdef DEBUG_2534 - printf("Mask = %08x, inputMask =%08x\n", - mask, vmic2534Rec[ card ].inputMask); -#endif DEBUG_2534 - if ( ((u_long)mask & vmic2534Rec[ card ].inputMask) == 0 ) - { - for ( j = 0; j < 4; j++ ) - { - if ( ( (u_long)mask & maskTbl[ j ] ) != 0 ) - { - vmic2534Rec[ card ].outputMask |= maskTbl[ j ]; -#ifdef DEBUG_2534 - printf("outputMask = %08x\n", - vmic2534Rec[ card ].outputMask); -#endif DEBUG_2534 - vmic2534Rec[ card ].vmicDevice->ctlStatReg - |= (u_char)(1 << j); - } - } - } - else - { - status = -1; - } - } - } - return( status ); - } - -vmic2534_getioscanpvt( short card, IOSCANPVT *scanpvt ) - { - if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) ) - return( -1 ); - *scanpvt = vmic2534Rec[ card ].ioscanpvt; - return( 0 ); - } - - -/* - * VMEVMIC_BI_DRIVER - * - * interface binary inputs - */ - -vmic2534_bi_driver( register short card, - u_int mask, - register u_int * prval ) - { - if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) ) - return( -1 ); - - *prval = (u_int)( (vmic2534Rec[ card ].vmicDevice->pioData) - & (vmic2534Rec[ card ].inputMask) ) - & mask; - return( 0 ); - } - - -/* - * vmic2534_bo_read - * - * (read) interface to binary outputs - * - */ - -vmic2534_bo_read( register short card, - u_int mask, - register u_int * prval ) - { - if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) ) - return( -1 ); - - *prval = (u_int)(~( ( (vmic2534Rec[ card ].vmicDevice->pioData) - & (vmic2534Rec[ card ].outputMask) ) - ^ vmic2534Rec[card].outputCorrector) ) & mask; - return( 0 ); - } - - -/* - * vmic2534_bo_driver - * - * (write) interface to binary outputs - */ - -vmic2534_bo_driver( register short card, - register u_int val, - u_int mask ) - { - u_long work; - - if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) ) - return( ERROR ); - -#ifndef DEBUGTHIS - - - vmic2534Rec[ card ].vmicDevice->pioData = - ( ( ( ~(vmic2534Rec[ card ].vmicDevice->pioData) & (u_long)~mask) - | (u_long)(val & mask) ) ^ vmic2534Rec[card].outputCorrector ) - & vmic2534Rec[ card ].outputMask; -#else - printf("Data = 0x%x, mask = 0x%x, corrector = 0x%x\n", - val, mask, vmic2534Rec[card].outputCorrector); - - work = vmic2534Rec[ card ].vmicDevice->pioData; - printf("Current raw i/o data = 0x%x, output mask = 0x%x\n", - work, vmic2534Rec[ card ].outputMask); - work = ~work; - printf("Corrected output data = 0x%x\n", work); - work &= ( (u_long)~mask ); - printf("Masked data = 0x%x\n", work); - work |= ( (u_long)(val & mask) ); - printf("New output data = 0x%x\n", work); - work ^= vmic2534Rec[card].outputCorrector; - printf("Polarity-corrected output data = 0x%x\n", work); - work &= vmic2534Rec[ card ].outputMask; - printf("Output data masked to output bits only = 0x%x\n", work); - vmic2534Rec[ card ].vmicDevice->pioData = work; - printf("*\n"); -#undef DEBUGTHIS -#endif DEBUGTHIS - return( OK ); - } - - -/* - * vmiv2534Out - * - * test routine for vm1c2534 output - */ - -vmiv2534Out( short card, - u_long val ) - { - /* check for valid card nr */ - if ( card >= VMIC_2534_MAX_CARDS ) - { - logMsg("card # out of range/n"); - return( -1 ); - } - - /* check for card actually installed */ - if ( !(vmic2534Rec[ card ].vmicDevice) ) - { - logMsg("card #%d not found\n", card); - return( -2 ); - } - - /* set the physical output */ - vmic2534Rec[ card ].vmicDevice->pioData - = vmic2534Rec[ card ].outputCorrector ^ val; - return( OK ); - } - - -/* - * vmic2534Write - * - * command line interface to test bo driver - */ - -vmic2534Write( short card, - u_int val ) - { - return( vmic2534_bo_driver( card, val, 0xffff ) ); - } - - - -long -vmic2534_io_report( short level ) - { - int card; - - for ( card = 0; card < VMIC_2534_MAX_CARDS; card++ ) - { - if ( vmic2534Rec[ card ].vmicDevice ) - { - printf("B*: vmic2534:\tcard%d\n", card); - if( level >= 1 ) - { - vmic2534_bi_io_report( card ); - vmic2534_bo_io_report( card ); - } - } - } - } - -void -vmic2534_bi_io_report( int card ) - { - short int num_chans,j,k,l,m,status; - int ival,jval,kval,lval,mval; - unsigned int *prval; - - num_chans = VMIC_2534_MAX_CHANS; - - if( !vmic2534Rec[card].vmicDevice ) - return; - - printf("\tVMEVMI-2534 BINARY IN CHANNELS:\n"); - for( j=0, k=1, l=2, m=3; - j < num_chans, k < num_chans, l< num_chans, m < num_chans; - j+=IOR_MAX_COLS, k+= IOR_MAX_COLS, l+= IOR_MAX_COLS, - m += IOR_MAX_COLS ) - { - if( j < num_chans ) - { - vmic2534_bi_driver( card, masks( j ), &jval ); - if ( jval != 0 ) - jval = 1; - printf("\tChan %d = %x\t ", j, jval); - } - - if( k < num_chans ) - { - vmic2534_bi_driver( card, masks( k ), &kval ); - if ( kval != 0) - kval = 1; - printf("Chan %d = %x\t ", k, kval); - } - - if( l < num_chans ) - { - vmic2534_bi_driver( card, masks( l ), &lval ); - if ( lval != 0 ) - lval = 1; - printf("Chan %d = %x \t", l, lval); - } - if( m < num_chans) - { - vmic2534_bi_driver( card, masks( m ), &mval ); - if ( mval != 0 ) - mval = 1; - printf("Chan %d = %x \n", m, mval); - } - } - } - - -void -vmic2534_bo_io_report( int card ) - { - short int num_chans,j,k,l,m,status; - int ival,jval,kval,lval,mval; - unsigned int *prval; - - num_chans = VMIC_2534_MAX_CHANS; - - if( !vmic2534Rec[card].vmicDevice ) - return; - - printf("\tVMEVMI-2534 BINARY OUT CHANNELS:\n"); - for( j=0, k=1, l=2, m=3; - j < num_chans, k < num_chans, l< num_chans, m < num_chans; - j+=IOR_MAX_COLS, k+= IOR_MAX_COLS, l+= IOR_MAX_COLS, - m += IOR_MAX_COLS ) - { - if( j < num_chans ) - { - vmic2534_bo_read( card, masks( j ), &jval ); - if ( jval != 0 ) - jval = 1; - printf("\tChan %d = %x\t ", j, jval); - } - - if( k < num_chans ) - { - vmic2534_bo_read( card, masks( k ), &kval ); - if ( kval != 0) - kval = 1; - printf("Chan %d = %x\t ", k, kval); - } - - if( l < num_chans ) - { - vmic2534_bo_read( card, masks( l ), &lval ); - if ( lval != 0 ) - lval = 1; - printf("Chan %d = %x \t", l, lval); - } - if( m < num_chans) - { - vmic2534_bo_read( card, masks( m ), &mval ); - if ( mval != 0 ) - mval = 1; - printf("Chan %d = %x \n", m, mval); - } - } - } diff --git a/src/drv/ansi/epvxi.h b/src/drv/ansi/epvxi.h deleted file mode 100644 index cda7dddb1..000000000 --- a/src/drv/ansi/epvxi.h +++ /dev/null @@ -1,532 +0,0 @@ -/* $Id$ - * - * VXI standard defines - * - * Author: Jeff Hill - * Date: 11-89 - * - * 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 021490 changed NVXIADDR to 32 before formal release - * .02 joh 120591 reorganized to support nivxi - * .03 joh 010892 added message based device registers and - * commands - * .04 joh 013091 moved some of the slot 0 stuff here - * .05 joh 070692 added KSC manufacturer id - * .06 joh 070692 added address space defines - * .07 joh 081992 added csr typedef - * .08 joh 071593 typedef for device registers - * .09 joh 051995 fixed incorrect MBC_TOP_LEVEL_CMDR def - * - */ - -#ifndef INCepvxih -#define INCepvxih - -#include - -/* - * offset from the bottom of VME short addr of - * VXI logical address space - */ -#define VXIBASEADDR 0xc000 - -typedef volatile uint16_t vxi16_t; -typedef volatile uint8_t vxi8_t; - -/* - * set NVXIADDR to less than 0x100 since other VME modules - * currently live in VXI address space - */ -#define NVXIADDR (0x100) -#define NVXISLOTS 13 -#define VXIDYNAMICADDR (0xff) -#define NVXIADDRBITS 8 -#define VXIADDRMASK ((1<>VXIDEVBITS)&VXIADDRMASK ) - -struct vxi_msg_dev_w{ - vxi16_t signal; - vxi16_t dextended; - vxi16_t dhigh; - vxi16_t dlow; -}; - -struct vxi_mxi_dev_w{ - vxi16_t modid; - vxi16_t la_window; - vxi8_t a16_window_high; - vxi8_t a16_window_low; - vxi8_t a24_window_high; - vxi8_t a24_window_low; - vxi8_t a32_window_high; - vxi8_t a32_window_low; - vxi16_t INTX_interrupt; - vxi16_t INTX_trigger; - vxi16_t dd7; - vxi16_t INTX_utility; - vxi16_t dd9; - vxi16_t dd10; - vxi16_t subclass; - vxi16_t control; - vxi16_t lock; - vxi16_t irq; - vxi16_t trigger_drive; - vxi16_t trigger_mode; - vxi16_t interrupt; - vxi16_t status_id; - vxi16_t trigger_config; - vxi16_t trigger_sync_ack; - vxi16_t trigger_async_ack; - vxi16_t irq_ack; -}; - -struct vxi_reg_dev_w{ - vxi16_t ddx08; - vxi16_t ddxoa; - vxi16_t ddx0c; - vxi16_t ddx0e; - vxi16_t ddx10; - vxi16_t ddx12; - vxi16_t ddx14; - vxi16_t ddx16; - vxi16_t ddx18; - vxi16_t ddx1a; - vxi16_t ddx1c; - vxi16_t ddx1e; - vxi16_t ddx20; - vxi16_t ddx22; - vxi16_t ddx24; - vxi16_t ddx26; - vxi16_t ddx28; - vxi16_t ddx2a; - vxi16_t ddx2c; - vxi16_t ddx2e; -}; - -struct vxi_reg_slot0_dev_w{ - vxi16_t modid; - vxi16_t ddxoa; - vxi16_t ddx0c; - vxi16_t ddx0e; - vxi16_t ddx10; - vxi16_t ddx12; - vxi16_t ddx14; - vxi16_t ddx16; - vxi16_t ddx18; - vxi16_t ddx1a; - vxi16_t ddx1c; - vxi16_t ddx1e; - vxi16_t ddx20; - vxi16_t ddx22; - vxi16_t ddx24; - vxi16_t ddx26; - vxi16_t ddx28; - vxi16_t ddx2a; - vxi16_t ddx2c; - vxi16_t ddx2e; -}; - -struct vxi_csr_w{ - vxi16_t addr; - vxi16_t pad0; - vxi16_t control; - vxi16_t offset; - union { - struct vxi_msg_dev_w msg; - struct vxi_mxi_dev_w mxi; - struct vxi_reg_dev_w reg; - struct vxi_reg_slot0_dev_w reg_s0; - }dd; -}; - -struct vxi_msg_dev_r{ - vxi16_t protocol; - vxi16_t response; - vxi16_t dhigh; - vxi16_t dlow; -}; - -struct vxi_mxi_dev_r{ - vxi16_t modid; - vxi16_t la_window; - vxi16_t a16_window; - vxi16_t a24_window; - vxi16_t a32_window; - vxi16_t dd5; - vxi16_t dd6; - vxi16_t dd7; - vxi16_t dd8; - vxi16_t dd9; - vxi16_t dd10; - vxi16_t subclass; - vxi16_t status; - vxi16_t lock; - vxi16_t irq; - vxi16_t read_la; - vxi16_t trigger_mode; - vxi16_t interrupt; - vxi16_t status_id; - vxi16_t trigger_config; - vxi16_t trigger_sync_ack; - vxi16_t trigger_async_ack; - vxi16_t irq_ack; -}; - -struct vxi_reg_dev_r{ - vxi16_t ddx08; - vxi16_t ddxoa; - vxi16_t ddx0c; - vxi16_t ddx0e; - vxi16_t ddx10; - vxi16_t ddx12; - vxi16_t ddx14; - vxi16_t ddx16; - vxi16_t ddx18; - vxi16_t ddx1a; - vxi16_t ddx1c; - vxi16_t ddx1e; - vxi16_t ddx20; - vxi16_t ddx22; - vxi16_t ddx24; - vxi16_t ddx26; - vxi16_t ddx28; - vxi16_t ddx2a; - vxi16_t ddx2c; - vxi16_t ddx2e; -}; - -struct vxi_reg_slot0_dev_r{ - vxi16_t modid; - vxi16_t ddxoa; - vxi16_t ddx0c; - vxi16_t ddx0e; - vxi16_t ddx10; - vxi16_t ddx12; - vxi16_t ddx14; - vxi16_t ddx16; - vxi16_t ddx18; - vxi16_t ddx1a; - vxi16_t ddx1c; - vxi16_t ddx1e; - vxi16_t ddx20; - vxi16_t ddx22; - vxi16_t ddx24; - vxi16_t ddx26; - vxi16_t ddx28; - vxi16_t ddx2a; - vxi16_t ddx2c; - vxi16_t ddx2e; -}; - -struct vxi_csr_r{ - vxi16_t make; - vxi16_t model; - vxi16_t status; - vxi16_t offset; - union { - struct vxi_msg_dev_r msg; - struct vxi_mxi_dev_r mxi; - struct vxi_reg_dev_r reg; - struct vxi_reg_slot0_dev_r reg_s0; - }dd; -}; - - -struct vxi_csr{ - union { - struct vxi_csr_w w; - struct vxi_csr_r r; - }dir; -}; - -typedef struct vxi_csr VXICSR; - -#define CSRRMEM(PSR,MEMBER) ( ((VXICSR *)(PSR))->MEMBER ) - -/* - * Reserved device types - */ -#define VXIMODELMASK(WD) ( (WD)&0xfff ) -#define VXIMODEL(PSR) ( (unsigned) VXIMODELMASK(CSRRMEM(PSR,dir.r.model)) ) -#define VXIMAKE(PSR) ( (unsigned) 0xfff&CSRRMEM(PSR,dir.r.make) ) -#define VXISLOT0MODELTEST(WD) ((WD)<0x100) -#define VXISLOT0MODEL(PCSR) (VXISLOT0MODELTEST(VXIMODEL(PCSR))) - -/* - * vxi device classes - */ -#define VXI_MEMORY_DEVICE 0 -#define VXI_EXTENDED_DEVICE 1 -#define VXI_MESSAGE_DEVICE 2 -#define VXI_REGISTER_DEVICE 3 -#define VXICLASS(PSR) ((unsigned)(0xc000&CSRRMEM(PSR,dir.r.make))>>14) -#define VXISUBCLASS(PSR) ((unsigned)CSRRMEM(PSR,dir.r.dd.mxi.subclass) ) -#define VXIMXI(PSR)\ -(VXICLASS(PSR)==VXI_EXTENDED_DEVICE ? VXISUBCLASS(PSR)==VXI_MXI_DEVICE : 0) -#define VXI_MXI_DEVICE 0xfffc -#define MXI_BASE_DEVICE 0xf -#define MXI_INTX_DEVICE 0xe -#define MXI_EXTENDED_TYPE(PSR) ((((unsigned)CSRRMEM(PSR,dir.r.status))>>10)&0xf) -#define MXIINTX(PSR) (MXI_EXTENDED_TYPE(PSR) == MXI_INTX_DEVICE) -#ifndef SRCepvxiLib -extern -#endif -char *vxi_device_class_names[] -#ifdef SRCepvxiLib - = { - "memory", - "extended", - "message", - "register"} -#endif -; - -/* - * A32/A24 address space - */ -#define VXIADDRSPACE(PSR) ( (unsigned long) 3&(CSRRMEM(PSR,dir.r.make)>>12) ) -#define VXIREQMEM(PSR) ( (unsigned long) 0xf&(CSRRMEM(PSR,dir.r.model)>>12) ) -#define VXIA24MEMSIZE(M) ( (long) 1<<(23-(M)) ) -#define VXIA32MEMSIZE(M) ( (long) 1<<(31-(M)) ) -#define VXI_ADDR_EXT_A24 0 -#define VXI_ADDR_EXT_A32 1 -#define VXI_ADDR_EXT_NONE 3 - -/* - * - * VXI vendor codes - * - */ -#define VXI_MAKE_HP 0xfff /* Hewlett Packard */ -#define VXI_MAKE_RD 0xffb /* Racal Dana */ -#define VXI_MAKE_NI 0xff6 /* National Instruments */ -#define VXI_MAKE_LANSCE5 0xfa0 /* Los Alamos Natl Lab LANSCE-5 */ -#define VXI_MAKE_KSC 0xf29 /* Kinetic Systems */ -struct vxi_vendor_info{ - uint16_t make; - char *pvendor_name; -}; - -/* - * In decreasing order of vendor id - */ -#ifndef SRCepvxiLib - extern -#endif -struct vxi_vendor_info vxi_vi[] -#ifdef SRCepvxiLib -= { - {VXI_MAKE_HP, "Hewlett-Packard"}, - {VXI_MAKE_RD, "Racal-Dana"}, - {VXI_MAKE_NI, "National Instruments"}, - {VXI_MAKE_LANSCE5, "LANL LANSCE-5"}, - {VXI_MAKE_KSC, "Kinetic Systems"}, -} -#endif -; - - -/* - * MXI commands - * (for the MXI control register) - */ -#define MXI_UPPER_LOWER_BOUNDS 0x4000 -#define MXI_LA_WINDOW_SIZE_MASK 0x3 -#define MXIA24MASK (0xffff) -#define MXIA24MASKSIZE 16 -#define MXIA32MASK (0xffffff) -#define MXIA32MASKSIZE 24 -#define MXIA24ALIGN(A) (((unsigned long)(A)+MXIA24MASK)&~MXIA24MASK) -#define MXIA32ALIGN(A) (((unsigned long)(A)+MXIA32MASK)&~MXIA32MASK) - -/* - * applies to all vxi devices - */ -#define VXIMEMENBLMASK (0x8000) -#define VXIMEMENBL(PSR) (VXIMEMENBLMASK&CSRRMEM(PSR,dir.r.status)) -#define VXINDCDEVICESMASK (0xff) -#define VXINDCDEVICES(PSR) (VXINDCDEVICESMASK&CSRRMEM(PSR,dir.r.offset)) - -/* - * Register based slot zero - */ -#define VXIMODIDSTATUS(WD) ((WD)&0x4000?FALSE:TRUE) -#define VXIPASS 3 -#define VXIPASSEDSTATUS(WD) (((WD)>>2)&VXIPASS) - - -/* - * RULE C.4.4 - * - * The resource manager shall write all ones to the - * device dependent bits when writing to the control register - * - */ -#define VXISAFECONTROL 0x7fff /* sys fail inhibit, reset, no mem enbl */ -#define VXIMEMENBLCONTROL 0xfffc /* mem enbl, no sys fail inhibit, no reset */ - -#define VXI_SET_REG_MODID(PCSR, SLOT) \ -( ((VXICSR *)(PCSR))->dir.w.dd.reg_s0.modid = \ - 0x2000|1<<(SLOT) ) -#define VXI_CLR_ALL_REG_MODID(PCSR) \ -( ((VXICSR *)(PCSR))->dir.w.dd.reg_s0.modid = 0 ) - -/* - * vxi msg based functions - */ -#define VXIWRITEREADYMASK (0x0200) -#define VXIREADREADYMASK (0x0400) -#define VXIDIRMASK (0x1000) -#define VXIDORMASK (0x2000) -#define VXIFHSMMASK (0x0100) -#define VXIERRNOTMASK (0x0800) - -#define VXICMDRMASK (0x8000) -#define VXICMDR(PSR) (!(VXICMDRMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol))) -#define VXIFHSMASK (0x0800) -#define VXIFHS(PSR) (!(VXIFHSMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol))) -#define VXISHMMASK (0x0400) -#define VXISHM(PSR) (!(VXISHMMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol))) -#define VXIMBINTMASK (0x1000) -#define VXIMBINT(PSR) (VXIMBINTMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol)) -#define VXIVMEBMMASK (0x2000) -#define VXIVMEBM(PSR) (!(VXIVMEBMMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol))) -#define VXISIGREGMASK (0x4000) -#define VXISIGREG(PSR) (!(VXISIGREGMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol))) - -/* - * serial protocol errors - */ -#define MBE_NO_ERROR (0xff) -#define MBE_MULTIPLE_QUERIES (0xfd) -#define MBE_UNSUPPORTED_CMD (0xfc) -#define MBE_DIR_VIOLATION (0xfb) -#define MBE_DOR_VIOLATION (0xfa) -#define MBE_RR_VIOLATION (0xf9) -#define MBE_WR_VIOLATION (0xf8) - -/* - * vxi message based commands - */ -#define MBC_BEGIN_NORMAL_OPERATION 0xfcff -#define MBC_TOP_LEVEL_CMDR 0x0100 -#define MBC_READ_SERVANT_AREA 0xceff -#define MBC_BA 0xbc00 -#define MBC_BR 0xdeff -#define MBC_END 0x0100 -#define MBC_READ_PROTOCOL 0xdfff -#define MBC_ASSIGN_INTERRUPTER_LINE 0xaa00 -#define MBC_READ_INTERRUPTERS 0xcaff -#define MBC_READ_PROTOCOL_ERROR 0xcdff -#define MBC_GRANT_DEVICE 0xbf00 -#define MBC_IDENTIFY_COMMANDER 0xbe00 -#define MBC_CLEAR 0xffff - -/* - * async mode control commands - */ -#define MBC_ASYNC_MODE_CONTROL 0xa800 - -#define MBC_AMC_RESP_ENABLE 0x0000 -#define MBC_AMC_RESP_DISABLE 0x0008 -#define MBC_AMC_EVENT_ENABLE 0x0000 -#define MBC_AMC_EVENT_DISABLE 0x0004 - -#define MBC_AMC_RESP_INT_ENABLE 0x0000 -#define MBC_AMC_RESP_SIGNAL_ENABLE 0x0002 -#define MBC_AMC_EVENT_INT_ENABLE 0x0000 -#define MBC_AMC_EVENT_SIGNAL_ENABLE 0x0001 - -/* - * control resp command - * (enable all) - */ -#define MBC_CONTROL_RESPONSE 0x8fc0 - -/* - * msg based responses - */ -#define MBR_STATUS(RESP) (((RESP)>>12) & 0xf) -#define MBR_STATUS_SUCCESS 0xf -#define MBR_READ_SERVANT_AREA_MASK 0x00ff -#define MBR_CR_CONFIRM_MASK 0x007f - -/* - * read interrupters response - */ -#define MBR_READ_INTERRUPTERS_MASK 0x7 - -/* - * async mode control resp - */ -#define MBR_AMC_CONFIRM_MASK 0xf - -/* - * begin normal operation message based responses - */ -#define MBR_BNO_STATE(RESP) (((RESP)>>8) & 0xf) -#define MBR_BNO_STATE_NO 0xf - -/* - * read protocol message based responses - */ -#define MBR_RP_LW(RESP) (!((RESP)&0x1)) -#define MBR_RP_ELW(RESP) (!((RESP)&0x2)) -#define MBR_RP_I(RESP) (!((RESP)&0x4)) -#define MBR_RP_I4(RESP) (!((RESP)&0x8)) -#define MBR_RP_TRG(RESP) (!((RESP)&0x10)) -#define MBR_RP_PH(RESP) (!((RESP)&0x20)) -#define MBR_RP_PI(RESP) (!((RESP)&0x40)) -#define MBR_RP_EG(RESP) (!((RESP)&0x100)) -#define MBR_RP_RG(RESP) (!((RESP)&0x200)) -#define MBR_REV_12(RESP) (!((RESP)&0x8000)) - -/* - * protocol events - * vxi spec E.4 - */ -#define MBE_EVENT_TEST(EVENT) ((EVENT)&0x1000) - -/* - * vxi trigger constants - */ -#define VXI_N_TTL_TRIGGERS 8 -#define VXI_N_ECL_TRIGGERS 6 -#define MXI_ECL0_ENABLE 0x0800 -#define MXI_ECL0_FP_TO_BP 0x0400 -#define MXI_ECL0_BP_TO_FP 0 -#define MXI_ECL1_ENABLE 0x2000 -#define MXI_ECL1_FP_TO_BP 0x1000 -#define MXI_ECL1_BP_TO_FP 0 - -#endif /* INCvxih */ diff --git a/src/drv/ansi/ipModules.h b/src/drv/ansi/ipModules.h deleted file mode 100644 index 37128f24d..000000000 --- a/src/drv/ansi/ipModules.h +++ /dev/null @@ -1,33 +0,0 @@ - -#ifndef INCipModulesH -#define INCipModulesH - - -#define IP_MANUFACTURER_GREENSPRING 0xf0 - -#define IP_MODEL_GS_PRECISION_ADC 0x15 -#define IP_MODEL_GS_PRECISION_ADC_N "ADC" - -#define IP_MODEL_GS_QUAD_SERIAL 0x37 -#define IP_MODEL_GS_QUAD_SERIAL_N "Quad_Serial" - -#define IP_MODEL_GS_OCTAL_SERIAL 0x22 -#define IP_MODEL_GS_OCTAL_SERIAL_N "Octal_Serial" - -#define IP_MODEL_GS_SERIAL 0x10 -#define IP_MODEL_GS_SERIAL_N "Serial" - -#define IP_MODEL_GS_QUADRATURE 0x41 -#define IP_MODEL_GS_QUADRATURE_N "Quadrature" - -#define IP_MODEL_GS_488 0x14 -#define IP_MODEL_GS_488_N "ip488" - - -#define IP_MANUFACTURER_TEWS 0xb3 - -#define IP_MODEL_TEWS_TIP810 0x01 - - -#endif /* INCipModulesH */ - diff --git a/src/drv/ansi/ipic.h b/src/drv/ansi/ipic.h deleted file mode 100644 index a7025d911..000000000 --- a/src/drv/ansi/ipic.h +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - ipic.h - -Description: - IndustryPack Interface Controller ASIC header file, giving the register - layout and programming model for the IPIC chip used on the MVME162. - -Author: - Andrew Johnson -Created: - 6 July 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#ifndef INCipicH -#define INCipicH - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Chip Registers */ - -#define IPIC_CHIP_ID 0x23 -#define IPIC_CHIP_REVISION 0x00 - - -/* Interrupt Control Register bits */ - -#define IPIC_INT_LEVEL 0x07 -#define IPIC_INT_ICLR 0x08 -#define IPIC_INT_IEN 0x10 -#define IPIC_INT_INT 0x20 -#define IPIC_INT_EDGE 0x40 -#define IPIC_INT_PLTY 0x80 - - -/* General Control Registers bits */ - -#define IPIC_GEN_MEN 0x01 -#define IPIC_GEN_WIDTH 0x0c -#define IPIC_GEN_WIDTH_8 0x04 -#define IPIC_GEN_WIDTH_16 0x08 -#define IPIC_GEN_WIDTH_32 0x00 -#define IPIC_GEN_RT 0x30 -#define IPIC_GEN_RT_0 0x00 -#define IPIC_GEN_RT_2 0x10 -#define IPIC_GEN_RT_4 0x20 -#define IPIC_GEN_RT_8 0x30 -#define IPIC_GEN_ERR 0x80 - - -/* IP Reset register bits */ - -#define IPIC_IP_RESET 0x01 - - -/* Chip Structure */ - -typedef struct { - uchar_t chipId; - uchar_t chipRevision; - uchar_t reserved1[2]; - ushort_t memBase[4]; - uchar_t memSize[4]; - uchar_t intCtrl[4][2]; - uchar_t genCtrl[4]; - uchar_t reserved2[3]; - uchar_t ipReset; -} ipic_t; - - -#ifdef __cplusplus -} -#endif - -#endif /* INCipicH */ - diff --git a/src/drv/ansi/pca82c200.h b/src/drv/ansi/pca82c200.h deleted file mode 100644 index dd6b00aca..000000000 --- a/src/drv/ansi/pca82c200.h +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - -Project: - Gemini/UKIRT CAN Bus Driver for EPICS - -File: - pca82c200.h - -Description: - Philips Stand-alone CAN-controller chip header file, giving the register - layout and programming model for the chip used on the TIP810 IP module. - -Author: - Andrew Johnson -Created: - 19 July 1995 - -(c) 1995 Royal Greenwich Observatory - -*******************************************************************************/ - - -#ifndef INCpca82c200H -#define INCpca82c200H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/***** Control Segment Bit Patterns *****/ - -/* Control Register */ - -#define PCA_CR_TM 0x80 /* Test Mode */ -#define PCA_CR_S 0x40 /* Synch */ -#define PCA_CR_OIE 0x10 /* Overrun Interrupt Enable */ -#define PCA_CR_EIE 0x08 /* Error Interrupt Enable */ -#define PCA_CR_TIE 0x04 /* Transmit Interrupt Enable */ -#define PCA_CR_RIE 0x02 /* Receive Interrupt Enable */ -#define PCA_CR_RR 0x01 /* Reset Request */ - - -/* Command Register */ - -#define PCA_CMR_GTS 0x10 /* Goto Sleep */ -#define PCA_CMR_COS 0x08 /* Clear Overrun Status */ -#define PCA_CMR_RRB 0x04 /* Release Receive Buffer */ -#define PCA_CMR_AT 0x02 /* Abort Transmission */ -#define PCA_CMR_TR 0x01 /* Transmission Request */ - - -/* Status Register */ - -#define PCA_SR_BS 0x80 /* Bus Status */ -#define PCA_SR_ES 0x40 /* Error Status */ -#define PCA_SR_TS 0x20 /* Transmit Status */ -#define PCA_SR_RS 0x10 /* Receive Status */ -#define PCA_SR_TCS 0x08 /* Transmission Complete Status */ -#define PCA_SR_TBS 0x04 /* Transmit Buffer Status */ -#define PCA_SR_DO 0x02 /* Data Overrun */ -#define PCA_SR_RBS 0x01 /* Receive Buffer Status */ - - -/* Interrupt Register */ - -#define PCA_IR_WUI 0x10 /* Wake-Up Interrupt */ -#define PCA_IR_OI 0x08 /* Overrun Interrupt */ -#define PCA_IR_EI 0x04 /* Error Interrupt */ -#define PCA_IR_TI 0x02 /* Transmit Interrupt */ -#define PCA_IR_RI 0x01 /* Receive Interrupt */ - - -/* Bus Timing Register 0 */ - -#define PCA_BTR0_1M6 0x00 /* 1.6 Mbits/sec, 20 m */ -#define PCA_BTR0_1M0 0x00 /* 1.0 Mbits/sec, 40 m */ -#define PCA_BTR0_500K 0x00 /* 500 Kbits/sec, 130 m */ -#define PCA_BTR0_250K 0x01 /* 250 Kbits/sec, 270 m */ -#define PCA_BTR0_125K 0x03 /* 125 Kbits/sec, 530 m */ -#define PCA_BTR0_100K 0x43 /* 100 Kbits/sec, 620 m */ -#define PCA_BTR0_50K 0x47 /* 50 Kbits/sec, 1.3 km */ -#define PCA_BTR0_20K 0x53 /* 20 Kbits/sec, 3.3 km */ -#define PCA_BTR0_10K 0x67 /* 10 Kbits/sec, 6.7 km */ -#define PCA_BTR0_5K 0x7f /* 5 Kbits/sec, 10 km */ - -#define PCA_KVASER_1M0 0x00 /* 1.0 Mbits/sec, 40 m -- Kvaser standard */ -#define PCA_KVASER_500K 0x01 /* 500 Kbits/sec, 130 m -- Kvaser standard */ -#define PCA_KVASER_250K 0x03 /* 250 Kbits/sec, 270 m -- Kvaser standard */ -#define PCA_KVASER_125K 0x07 /* 125 Kbits/sec, 530 m -- Kvaser standard */ - - -/* Bus Timing Register 1 */ - -#define PCA_BTR1_1M6 0x11 /* 1.6 Mbits/sec, 20 m */ -#define PCA_BTR1_1M0 0x14 /* 1.0 Mbits/sec, 40 m */ -#define PCA_BTR1_500K 0x1c /* 500 Kbits/sec, 130 m */ -#define PCA_BTR1_250K 0x1c /* 250 Kbits/sec, 270 m */ -#define PCA_BTR1_125K 0x1c /* 125 Kbits/sec, 530 m */ -#define PCA_BTR1_100K 0x2f /* 100 Kbits/sec, 620 m */ -#define PCA_BTR1_50K 0x2f /* 50 Kbits/sec, 1.3 km */ -#define PCA_BTR1_20K 0x2f /* 20 Kbits/sec, 3.3 km */ -#define PCA_BTR1_10K 0x2f /* 10 Kbits/sec, 6.7 km */ -#define PCA_BTR1_5K 0x7f /* 5 Kbits/sec, 10 km */ - -#define PCA_BTR1_KVASER 0x23 /* All speeds -- Kvaser standard */ - -/* Output Control Register */ - -#define PCA_OCR_OCM_NORMAL 0x02 -#define PCA_OCR_OCM_CLOCK 0x03 -#define PCA_OCR_OCM_BIPHASE 0x00 -#define PCA_OCR_OCM_TEST 0x01 - -#define PCA_OCR_OCT1_FLOAT 0x00 -#define PCA_OCR_OCT1_PULLDOWN 0x40 -#define PCA_OCR_OCT1_PULLUP 0x80 -#define PCA_OCR_OCT1_PUSHPULL 0xc0 - -#define PCA_OCR_OCT0_FLOAT 0x00 -#define PCA_OCR_OCT0_PULLDOWN 0x08 -#define PCA_OCR_OCT0_PULLUP 0x10 -#define PCA_OCR_OCT0_PUSHPULL 0x18 - -#define PCA_OCR_OCP1_INVERT 0x20 -#define PCA_OCR_OCP0_INVERT 0x04 - - -/* Message Buffers */ - -#define PCA_MSG_ID0_RSHIFT 3 -#define PCA_MSG_ID1_LSHIFT 5 -#define PCA_MSG_ID1_MASK 0xe0 -#define PCA_MSG_RTR 0x10 -#define PCA_MSG_DLC_MASK 0x0f - - -/***** Chip Structure *****/ - -/* Message Buffers */ - -typedef struct { - uchar_t pad0; - uchar_t descriptor0; - uchar_t pad1; - uchar_t descriptor1; - ushort_t data[8]; -} msgBuffer_t; - - -/* Chip Registers */ - -typedef volatile struct { - uchar_t pad00; - uchar_t control; - uchar_t pad01; - uchar_t command; - uchar_t pad02; - uchar_t status; - uchar_t pad03; - uchar_t interrupt; - uchar_t pad04; - uchar_t acceptanceCode; - uchar_t pad05; - uchar_t acceptanceMask; - uchar_t pad06; - uchar_t busTiming0; - uchar_t pad07; - uchar_t busTiming1; - uchar_t pad08; - uchar_t outputControl; - uchar_t pad09; - uchar_t test; - msgBuffer_t txBuffer; - msgBuffer_t rxBuffer; - uchar_t pad31; - uchar_t clockDivider; -} pca82c200_t; - - -#ifdef __cplusplus -} -#endif - -#endif /* INCpca82c200H */ -