#include #include #include "camlib.h" /*============================================================== ; (C) Alexander Kyrpotin, Novosibirsk, BINP. -- 12.04.1996 - ; - 15.04.1996 - 30.11.1998 - 16.04.1999 - 22.01.2001 ---------- ; Subroutines for K0607 through PPI-AT-2 (january 1995 version) ;===============================================================*/ /* PPI AT-2, K0607 */ #define ccstat 0x250 /* Base address. Change only here */ int const cccmd=ccstat+2; int const ccdata=ccstat+4; int const ccpipe=ccstat+6; #define ccncr0 0x2000 /* Crate #0 address. */ #define ccncr1 0x2200 /* Crate #1 address. */ int const ccread=0x1000; /* Read bit. */ /*===============================================================*/ // Single NAF static variables: int ncr = 0; // Current crate number. int ncrt = ccncr0; int inhc = 0, inh01[] = {0,0}; // I-bit in crates (0 or 040). int laststat=0, lastf=0; int *ptrq, *ptrx; // Block NAF static variables: int ccnob = 2; // Bytes per NAF (= 1,2,3). int ccqbl = 0; // = 0 - ignore q; =1 - stop if q=0. int ccntr = 0; // Number of NAF's (= CAMAC cycles). int ccnc = 0; // Crate number. int ccmode= 2; // Mode: (1,2,3) - ignore q, (4,5,6) - while q. int actntr= 0; // Number of performed NAF's. int nbcrt = ccncr0; int blnaf, blhigh; /*===============================================================*/ /* Change crate number to "ncrate" [default=0] */ void crate (int ncrate) {int w=inh01[(ncrate&=1)]; inh01[ncr] = inhc; ncr=ncrate; ncrt=(ncrate)?ccncr1:ccncr0; inhc = w;} /* int caml () = Purmakov's LAM request register */ int caml (void) { outport (cccmd, ncrt+0x1001); inport (ccpipe); return (inport(ccdata)>>8)&0377;} // int camcl (int moda); - C,Z,I - control. // (moda & 1) == 1 - execute Z-cycle. // (moda & 2) == 2 - execute C-cycle. // (moda & 8) == 8 - set I. I:=1. // (moda &16) ==16 - clear I. I:=0. // return: I or -1 if crate off line. int camcl (int moda) {int csr; if (moda & 8) inhc = 040; if (moda &16) inhc = 0; csr = inhc; if (moda & 1) csr |= 01000; if (moda & 2) csr |= 00400; outport (cccmd, ncrt); outport (ccpipe, csr); inport (ccpipe); csr = inport (ccpipe); if (inport(ccstat) & 0x1000) return -1; return csr&010000;} /* 1-st local internal subroutine */ void ccprepare (int n, int f, int a, int *q, int *x) { int naf = ((n&037)<<4)|(a&017)|ncrt; lastf = f; if (!(f&030)) naf |= ccread; outport (cccmd, ncrt); outport (ccpipe, (f&037)|inhc); outport (cccmd, naf); ptrq = q; ptrx = x; *q=1; *x=1;} /* 2-nd local internal subroutine */ int storeqx (void) { laststat = inport (ccstat); if (lastf&030==0) {laststat&=0x1c00; if(laststat&0x1000)laststat|=0x100;}; if (laststat&0x100) laststat |= 0xc00; if (laststat&0x400) *ptrq=0; if (laststat&0x800) *ptrx=0; return (laststat&0x100);} /* Write to CAMAC 16-bits word */ int camw (int n, int f, int a, int data, int *q, int *x) { ccprepare (n, f, a, q, x); outport (ccpipe, data); return storeqx();} int camo (int n, int f, int a, int *data, int *q, int *x) { ccprepare (n, f, a, q, x); outport (ccpipe, *data); return storeqx();} /* Read from CAMAC 16-bits word */ int cami (int n, int f, int a, int *data, int *q, int *x) { ccprepare (n, f, a, q, x); inport (ccpipe); *data = inport (ccdata); return storeqx();} /* Write to CAMAC long 24-bits word */ int camo24 (int n, int f, int a, long *data, int *q, int *x) { union li {long l; int i[2]; int k;} li; li.l=*data; outport (cccmd, ncrt+2); outport (ccpipe, li.i[1]); ccprepare (n, f, a, q, x); outport (ccpipe, li.k); return storeqx();} /* Read from CAMAC long 24-bits word */ int cami24 (int n, int f, int a, long *data, int *q, int *x) { union pli {long *l; int *i;} ptr; ptr.l=data; ccprepare (n, f, a, q, x); inport (ccpipe); *ptr.i++ = inport (ccdata); laststat = inport (ccstat); outport (cccmd, ncrt+0x1002); inport (ccpipe); *ptr.i = (inport (ccdata))&0377; if (laststat&0x1000) laststat |= 0xc00; if (laststat&0x400) *q=0; if (laststat&0x800) *x=0; return (laststat&0x1000);} /* Prepare to block NAF */ int dmaset ( int nc, // Crate number; int nob, // Bytes per NAF (= 1, 2 or 3); int qbl, // q-mode: =0 - ignore q, =1 - while q; unsigned ntr){ // Number of NAF's = CAMAC cycles. if ((nob<1)||(nob>3)) return 5; ccnc=nc&1; nbcrt=(ccnc)?ccncr1:ccncr0; ccnob = nob; ccqbl = (qbl)?1:0; ccmode = ccqbl*3+nob; ccntr = ntr; actntr = 0; return 0;} /* 3-rd local internal subroutine */ void blprepare (int n, int f, int a) { blnaf = ((n&037)<<4)|(a&017)|nbcrt; blhigh = nbcrt+2; lastf = f; if (!(f&030)) {blnaf |= ccread; blhigh |= ccread;}; outport (cccmd, nbcrt); outport (ccpipe, (f&037)|inhc);} /* Write array to CAMAC */ /* Return: {camOk, camNoBus, camErAcl, camDmaHung, camNoXQ} = {0,1,4}*/ int dmao (int n, int f, int a, void *buf) { union vb {int w; char b;} v; union wb {int *w; char *b;} ptr; ptr.w=buf; v.w=0; blprepare (n, f, a); if (ccmode==2) {outport (cccmd, blnaf); for (actntr=0; actntr!=ccntr; actntr++) outport (ccpipe, *ptr.w++);} else {for (actntr=0; actntr!=ccntr; actntr++) { switch (ccnob) { case 1: outport (cccmd, blnaf); v.b=*ptr.b++; outport (ccpipe, v.w); break; case 2: outport (cccmd, blnaf); outport (ccpipe, *ptr.w++); break; case 3: outport (cccmd, blhigh); v.b=*ptr.b++; outport (ccdata, v.b); outport (cccmd, blnaf); outport (ccpipe, *ptr.w++);}; if (ccqbl) {if (inport (ccstat) & 0xd00) break;};};}; laststat = inport (ccstat); if (laststat&0x100) return 1; // No BUS. if (laststat&0x0c00) return 4; // No Q or X; return 0;} /* Read array from CAMAC */ /* Return: {camOk, camNoBus, camErAcl, camDmaHung, camNoXQ} = {0,1,4} */ int dmai (int n, int f, int a, void *buf) { union vb {int w; char b;} v; union wb {int *w; char *b;} ptr; ptr.w=buf; blprepare (n, f, a); if (ccmode==2) {outport (cccmd, blnaf); inport (ccpipe); for (actntr=1; actntr!=ccntr; actntr++) *ptr.w++=inport (ccpipe); *ptr.w = inport (ccdata);} else { for (actntr=0; actntr!=ccntr; actntr++) { switch (ccnob) { case 1: outport (cccmd, blnaf); inport (ccpipe); v.w=inport (ccdata); *ptr.b++=v.b; break; case 2: outport (cccmd, blnaf); inport (ccpipe); *ptr.w++=inport (ccdata); break; case 3: outport (cccmd, blnaf); inport (ccpipe); outport (cccmd, blhigh); *ptr.w++=inport (ccpipe); v.w=inport (ccdata); *ptr.b++=v.b;}; if (ccqbl) {if (inport (ccstat) & 0x1c00) break;};};}; laststat = inport (ccstat); if (laststat&0x01000) return 1; // No BUS. if (laststat&0x0c00) return 4; // No Q or X; return 0;} /* Number of succsessfully performed CAMAC-cycles */ unsigned camcyc () {return actntr;}