#include "Gpib.h" int isr1,isr2; /*********************************************************************** * * * gpib_write(buf,addr) writes the data string in buf on the bus * * and makes the device with address addr a listener * * * * It returns the number of bytes written, excluding the trailing \n. * * Check GPIB_ERR for errors. * * * ***********************************************************************/ gpib_write(buf,addr) unsigned char *buf,addr; { int count; count=0; cmd_write(UNT); /* unaddress all devices */ cmd_write(UNL); cmd_write(MLA+addr); /* address device as listener */ cmd_write(MTA+MA); /* address TLC as talker */ gpib_wait_for(COUT); /* wait until ready */ GpibReg[AUXMR]=GTS; /* and go to standby */ buf--; while(*++buf){ /* write until,but excluding, */ data_write(*buf); /* the null byte */ count++; } data_write(EOSC); /* EOSC ends the string */ gpib_wait_for(DOUT); /* wait until ready and */ GpibReg[AUXMR] = TCA; /* take control again */ cmd_write(UNT); /* unaddress all devices */ cmd_write(UNL); return(count); } /*********************************************************************** * * * gpib_read(buf,buflen) reads a data string from the device with * * address addr and stores it at the location pointed to by buf. * * At most, buflen bytes are stored. The string is ended with a * * null byte. If buflen bytes have been stored, the last one is * * overwritten by the trailing null byte, otherwise the null byte * * is appended to the string. * * * * It returns 0 if successful. * * It returns -1 if the buffer was too small to hold all received data. * * * * But check GPIB_ERR for errors. * * * ***********************************************************************/ gpib_read(buf,buflen,addr) unsigned char *buf,addr; int buflen; { int k,ret; ret=0; cmd_write(MTA+addr); /* address the device as talker */ cmd_write(MLA+MA); /* address the TLC as listener */ gpib_wait_for(COUT); /* wait until ready */ GpibReg[AUXMR]=GTS; /* and goto standby */ buf--; k=0; do{ if(gpib_wait_for(DIN)) { GPIB_ERR|=2; break;} if(buflen-->0) *++buf=GpibReg[DIR]; } while(!ISR.endrx); *buf='\0'; /* don't care if other listeners */ /* did not receive the last byte */ GpibReg[AUXMR] = TCA; /* take control again */ cmd_write(UNT); cmd_write(UNL); if(buflen<0) ret= -1; return(ret); } /*********************************************************************** * * * data_write(c) sends the character c over the gpib bus. * * * * It returns -1 on timeout, and 0 otherwise. * * But check GPIB_ERR for errors. * * * ***********************************************************************/ data_write(c) unsigned char c; { int k; k=0; if(gpib_wait_for(DOUT)) return(-1); /* wait until ready */ GpibReg[CDOR] = c; /* and send byte */ gpib_get_isr(1); /* read status register ISR1 */ if(ISR.err) GPIB_ERR|=1; /* record transmission errors */ return(0); } /*********************************************************************** * * * cmd_write(c) sends a bus command over the gpib bus. * * * * It returns -1 on timeout, and 0 otherwise. * * But check GPIB_ERR for errors. * * * ***********************************************************************/ cmd_write(c) unsigned char c; { int k; k=0; if(gpib_wait_for(COUT)) return(-1); /* wait until ready */ GpibReg[CDOR] = c; /* and send command */ gpib_get_isr(1); if(ISR.err) GPIB_ERR|=1; /* record transmission errors */ return(0); } /*********************************************************************** * * * gpib_wait_for(c) checks a certain condition in ISR1 or ISR2. * * It first looks at the previously recorded value. of the * * relevant register, ie ISR1 for c=DIN or c=DOUT, and ISR2 for * * c=COUT. If the condition is met in the recorded value the * * the corresponding bit is set to zero and the corresponding * * condition is cleared. Note this happens only in memory, the * * TLC register is not read again. The function then returns 0. * * * * If the condition is not met in the recorded data the TLC * * register is read again and again, until either the condition * * met or a timeout situation occurs. If the condition was met * * the function returns 0 and clears the relevant bit and condition. * * The assumptionis that after the gpib_wait_for function has * * returned an action will occur that changes the relevant bit * * in the TLC status register. At the same time, a previous * * action may have prepared the TLC. CO in ISR1 after gpib_ifc() * * is an point in case. * * On timeout bit two of GPIB_ERR is set and the function returns -1. * * * * This behaviour allows the user to additionally check for * * other conditions not addressed by the function, and at the same * * time retain all information. Remember that the status registers * * cleared on reading. * * * ***********************************************************************/ gpib_wait_for(c) BYTE c; { int k=0; twiddle(0x10000); switch(c){ case DIN: /* waiting for data in */ if(ISR.din){ /* if already there, */ ISR.R1 -= DI; /* clear condition, */ ISR.din = 0; return(0); /* and return 0 */ } else{ /* if not */ while(k++ < TIMOUT){ /* try until timeout */ gpib_get_isr(1); /* read ISR1 */ if(ISR.din){ /* if data have arrived */ ISR.R1 -= DI; /* clear that bit */ ISR.din = 0; /* and that condition */ return(0); /* and return 0 */ } else twiddle(0x10000); /* twiddle thumbs */ } GPIB_ERR|=2; /* we have a timeout */ return(-1); /* report error */ } break; case DOUT: /* wait until ready for data output */ if(ISR.dout){ /* if so , */ ISR.R1 -= DO; /* clear condition, */ ISR.dout = 0; return(0); /* and return 0 */ } else{ /* if not */ while(k++ < TIMOUT){ /* try until timeout */ gpib_get_isr(1); /* read ISR1 */ if(ISR.dout){ /* if ready */ ISR.R1 -= DO; /* clear that bit */ ISR.dout = 0; /* and that condition */ return(0); /* and return 0 */ } else twiddle(0x10000); /* twiddle thumbs */ } GPIB_ERR|=2; /* we have a timeout */ return(-1); /* report error */ } break; case COUT: /* wait until ready for new command */ if(ISR.cout){ /* if already there, */ ISR.R2 -= CO; /* clear condition, */ ISR.cout= 0; return(0); /* and return 0 */ } else{ /* if not */ while(k++ < TIMOUT){ /* try until timeout */ gpib_get_isr(2); /* read ISR2 */ if(ISR.cout){ /* if ready */ ISR.R2 -= CO; /* clear that bit */ ISR.cout= 0; /* and that condition */ return(0); /* and return 0 */ } else twiddle(0x10000); /* twiddle thumbs */ } GPIB_ERR|=2; /* we have a timeout */ return(-1); /* report error */ } break; default: break; } return(-1); } /************************************************************* * * * gpib_get_isr(n) * * read TLC status register n and set a few flags concerning * * data and command transfer to the gpib bus. * * * **************************************************************/ gpib_get_isr(n) BYTE n; { switch(n){ case 1: ISR.R1 = GpibReg[ISR1]; ISR.din = (ISR.R1 & DI) ? 1:0; ISR.dout = (ISR.R1 & DO) ? 1:0; ISR.err = (ISR.R1 & ERR) ? 1:0; ISR.endrx = (ISR.R1 & ENDRX) ? 1:0; break; case 2: ISR.R2 = GpibReg[ISR2]; ISR.cout = (ISR.R2 & CO) ? 1:0; break; default: break; } return(0); } /************************************************************* * * * gpib_init() * * Initialize GPIB-1014 * * * **************************************************************/ gpib_init() { #define GpibAM 0x29 #define GpibSize 1000 int status; char errstring[80]; if((status=RD13_VmeMap(GpibBase,GpibAM,GpibSize,&GpibReg))!=0) printf("Error %x GPIB VME Map",status); GPIB_ERR=0; /* clear the error container */ GpibReg[CFG2] = 0; GpibReg[CFG2] = SLMR; GpibReg[CFG2] = CLMR; GpibReg[AUXMR] = CRST; GpibReg[IMR1] = 0; GpibReg[IMR2] = 0; /* programmed data I/O, ie no DMA activity */ gpib_get_isr(1); /* clear the status registers */ gpib_get_isr(1); /* ISR1, ISR2 by reading them */ GpibReg[ADMR] = MODE1 + TRM; GpibReg[ADR] = MA + SEL0; GpibReg[ADR] = DT1+DL1+SEL1; GpibReg[AUXMR] = ICR + 8; GpibReg[CFG2] = SC; /* be the active controller */ GpibReg[EOSR] = EOSC; /* end-of-string character */ GpibReg[AUXMR] = IEPON; /* bring TLC online */ gpib_ifc(); /* wakeup call for the devices on the bus */ gpib_get_isr(1); /* record the value of the two */ gpib_get_isr(2); /* status registers ISR1,ISR2 */ return(0); } /************************************************************* * * * gpib_isrclr() * * It clears the two ISR registers by simply reading them * * * **************************************************************/ gpib_isrclr() { return((int)(GpibReg[ISR1]+GpibReg[ISR2])); } /************************************************************* * * * gpib_ifc() * * Interface clear, and becoming active CIC * * * **************************************************************/ gpib_ifc() { GpibReg[ AUXMR] = SIFC; sleep(2); GpibReg[ AUXMR] = CIFC; return(0); } /************************************************************* * * * gpib_ren() * * Select remote or local programming mode * * * **************************************************************/ gpib_ren(sre) int sre; { if (sre) GpibReg[AUXMR] = SREN; else GpibReg[AUXMR] = CREN; return(0); } /************************************************************* * * * reg_test() * * Find out if the GPIB registers are set * * * **************************************************************/ reg_test() { GpibReg[CFG2]=SLMR; sleep(10); GpibReg[CFG2]=CLMR; printf("G[dir]=%d\n",(int)GpibReg[DIR]); printf("G[isr1]=%d\n",(int)GpibReg[ISR1]); printf("G[isr2]=%d\n",(int)GpibReg[ISR2]); printf("G[spsr]=%d\n",(int)GpibReg[SPSR]); printf("G[adsr]=%d\n",(int)GpibReg[ADSR]); printf("G[cptr]=%d\n",(int)GpibReg[CPTR]); /* printf("G[gcr]=%d\n",(int)GpibReg[GCR]); */ printf("G[ccr0]=%d\n",(int)GpibReg[CCR0]); printf("G[ccr1]=%d\n",(int)GpibReg[CCR1]); printf("G[csr0]=%d\n",(int)GpibReg[CSR0]); printf("G[csr1]=%d\n",(int)GpibReg[CSR1]); /* printf("G[niv1]=%d\n",(int)GpibReg[NIV1]); */ /* printf("G[eiv1]=%d\n",(int)GpibReg[EIV1]); */ return 0; } test_5() { printf("\n TEST 5\n"); GpibReg[CFG2]=10; GpibReg[CFG2]=8; GpibReg[AUXMR]=2; GpibReg[ADMR]=0x80; GpibReg[AUXMR]=2; printf("G[adsr]=%d\n",(int)GpibReg[ADSR]); printf("G[isr1]=%d\n",(int)GpibReg[ISR1]); GpibReg[CDOR]=0x51; printf("G[cptr]=%d\n",(int)GpibReg[CPTR]); printf("G[isr1]=%d\n",(int)GpibReg[ISR1]); printf("G[isr1]=%d\n",(int)GpibReg[ISR1]); GpibReg[AUXMR]=2; GpibReg[ADMR]=0; GpibReg[AUXMR]=0; printf("G[adsr]=%d\n",(int)GpibReg[ADSR]); printf("\n"); return(0); } print_reg() { printf("dir =%X ",(int)GpibReg[DIR]); /* printf("spsr=%X adsr=%X\n",(int)GpibReg[SPSR],(int)GpibReg[ADSR]);*/ printf("cptr =%X ",(int)GpibReg[CPTR]); /* printf("adr0=%X adr1=%X\n\n",(int)GpibReg[ADR0],(int)GpibReg[ADR1]);*/ printf("isr1=%d isr2=%d DIN=%d DOUT=%d COUT=%d ERR=%d ENDRX=%d\n", (int)ISR.R1,(int)ISR.R2,(int)ISR.din,(int)ISR.dout,(int)ISR.cout, (int)ISR.err,(int)ISR.endrx); printf("\n"); return(0); } twiddle(K) int K; { int k,count; count=0; for(k=0;k