//C sample for PCI-AI12-16(A) //This sample polls all channels for data and prints the data to the screen //for the non-FIFO version of the card //For the FIFO version, the card interrupts on FIFO half full and the data //is read out of the FIFO and displayed on screen. #include #include #include #include #include #include #include #include #include #ifdef __cplusplus // if it's a C++ program, ISRs take on ... argument #define __CPPARGS ... #else // ortherwise nothing #define __CPPARGS #endif unsigned int IRQ = 5; int speed = 0; int flag = 0; int newflag = 0; unsigned IRQBASE; unsigned short irqdata[2048]; void interrupt far (*oldisr[16])(__CPPARGS); //global to store old handler pointer void sendEOI(void) { //send non-specific to master AND slave PIC outportb(0x20, 0x20); outportb(0xA0, 0x20); } void interrupt far ISR(__CPPARGS); unsigned char initirq(char IRQnumber,void interrupt (*ISR)()) { unsigned char intmask, oldmask; if (IRQnumber <=7) { oldmask = inportb(0x21); oldisr[IRQnumber] = getvect(IRQnumber + 8); setvect(IRQnumber + 8,ISR); intmask = oldmask & (~(1 << IRQnumber)); outportb(0x21,intmask); } else { oldmask = inportb(0xA1); oldisr[IRQnumber] = getvect(IRQnumber + 0x70 - 8); setvect(IRQnumber - 8 + 0x70, ISR); intmask = oldmask & (~(1 << (IRQnumber - 8))); outportb(0xA1, intmask); } return(oldmask); } void restoreirq(char IRQnumber) { unsigned char intmask; if (IRQnumber <=7 ){ intmask = inportb(0x21); intmask |= (1 << IRQnumber); setvect(IRQnumber + 8, oldisr[IRQnumber]); outportb(0x21, intmask); } else { intmask = inportb(0xA1); intmask |= (1 << (IRQnumber - 8)); setvect(IRQnumber - 8 + 0x70, oldisr[IRQnumber]); outportb(0xA1, intmask); } } void RESETFIFOS(unsigned int BASE) { int i; outportb(BASE+4, 0x48);//0x40 resets channel fifo, 0x08 resets data fifo inportb(BASE+6); for (i=0;i<1024;i++) inport(BASE+0); } void SETCHANNEL(unsigned int BASE) { outport(BASE+2,0x0000); outport(BASE+2,0x1010); outport(BASE+2,0x2020); outport(BASE+2,0x3030); outport(BASE+2,0x4040); outport(BASE+2,0x5050); outport(BASE+2,0x6060); outport(BASE+2,0x7070); outport(BASE+2,0x8080); outport(BASE+2,0x9090); outport(BASE+2,0xA0A0); outport(BASE+2,0xB0B0); outport(BASE+2,0xC0C0); outport(BASE+2,0xD0D0); outport(BASE+2,0xE0E0); outport(BASE+2,0xF0F0); inport(BASE + 2); } void STARTCONVERSION(unsigned int BASE) { outportb(BASE+0, 0);//write anything to base+0 to start conversion } int RETRIEVEANALOGCONVERSION(unsigned int BASE) { int data=0; data = inport(BASE+0)&0x0fff;//mask upper nibble return data; } unsigned int WAITFOREOC(unsigned int BASE) { unsigned int timeout=65535; while(((inportb(BASE+4) & 0x80) != 0x80) && timeout--); return timeout; //0==error } void ENABLECOUNTERS(unsigned int BASE) { outportb(BASE+4, 0x05); //set counter/irq enable bits, starts conversions } void DISABLECOUNTERS(unsigned int BASE) { outportb(BASE+4, 0); //set counter disable bit, stop conversions } unsigned AskForBaseAddress(unsigned int OldOne) { char msg[7]; int NewOne = 0, Success = 0, Dummy; int AddrInputPosX, AddrInputPosY; puts("Please enter the Base Address for your card (in hex)"); printf("or press ENTER for %X.\n>", OldOne); AddrInputPosX = wherex(); AddrInputPosY = wherey(); do { gotoxy(AddrInputPosX, AddrInputPosY); clreol(); msg[0] = 5; msg[1] = 0; cgets(msg); sscanf(msg + 2, "%x", &NewOne); Success = 1; Dummy = NewOne; if (msg[1] == 0) { gotoxy(AddrInputPosX, AddrInputPosY); printf("%X", OldOne); Success = 1; Dummy = OldOne; } } while(!Success); return (Dummy); } /* end of AskForBaseAddress */ void CtrMode(unsigned int addr, char cntr, char mode) { int ctrl; ctrl = (cntr << 6) | 0x30 | (mode << 1); outportb(addr+3,ctrl); } void CtrLoad(unsigned int addr ,int c,int val) { outportb(addr+c,val & 0x00FF); outportb(addr+c,(val>>8) & 0x00FF); } void interrupt setflag() { int i; if (flag){ flag=99; DISABLECOUNTERS(IRQBASE); }else{ for(i = 0; i < 1024; i++) irqdata[i] = inport(IRQBASE + 0); flag = 1; } sendEOI(); } void Fifo(unsigned int BASE) { unsigned int chan; short data = 0; int x; unsigned long a=0; int y=0; char msg[256]; IRQBASE = BASE; clrscr(); puts("FIFO Sample"); printf("BASE:%04X IRQ:%2x\n",BASE,IRQ); puts("Press any key to exit."); RESETFIFOS(BASE);//clear channel and data fifos SETCHANNEL(BASE); // set up point list sendEOI(); initirq(IRQ,setflag); sendEOI(); CtrMode(BASE+8,1,2); CtrLoad(BASE+8,1,0x2); CtrMode(BASE+8,2,2); CtrLoad(BASE+8,2,0xff); ENABLECOUNTERS(BASE);//set INT on fifo half full bit, enable counters to start conversions while(!kbhit() && flag != 99) { if(flag){ for(x = 0; x < 1024; x++){ gotoxy(1,y+8); y++; y%=16; data=irqdata[x] & 0xFFF; data= (data << 4) >> 4; printf("Channel:%2u Volts: % 3.3f Sample number: %6lu",irqdata[x]>>12,data*20.0/4095.0,a); a++; } flag = 0; }// end if }//end while if (flag==99) puts("DATA RATE TOO FAST FOR DISPLAY!"); DISABLECOUNTERS(BASE); restoreirq(IRQ); getch(); } void NoFifo(unsigned int BASE) { unsigned int chan; int data=0; float display=0; unsigned int timeout; clrscr(); puts("Non-FIFO Sample"); puts("This sample will not work correctly if the FIFOs are installed."); gotoxy(1,19); puts("Press any key to exit."); DISABLECOUNTERS(BASE); while (!kbhit()) { delay(250); gotoxy(1,9); for (chan = 0; chan < 16; chan++) { timeout = 65535; outport(BASE+2,chan<<4);//set channel/range delay(1); outportb(BASE+0,0);//start conversion timeout = WAITFOREOC(BASE); //WAITFOREOC returns zero if it times out if (timeout == 0) printf("A/D timeout "); else clreol(); data = RETRIEVEANALOGCONVERSION(BASE+0); //read counts delay(1); data = (data<<4)>>4; //sign extend bipolar display = ((double)data * 20.0)/4096.0;//convert to volts printf("Channel: %2hu\t Counts: %4x\t Volts: % 2.3f\n", chan,data,display); }//end for loop }//end while loop getch(); } void main() { unsigned int BASE=0xFCA0; char card; clrscr(); puts("PCI-AI12-16(A) Sample\n"); puts("--This program will read data from all channels on the A/D card."); puts("--The FIFO sample generates an interrupt on FIFO half full and "); puts("displays the data on screen."); puts("--The non-FIFO sample continuously polls all channels and displays "); puts("the data."); puts("--The card is configured by software for ñ10V."); BASE=AskForBaseAddress(BASE); puts("\nPress 'a' for the PCI-AI12-16A or ENTER for the PCI-AI12-16."); card=getche(); if(toupper(card)=='A'){ puts("\nEnter the IRQ number (hex)."); scanf("%x",&IRQ); Fifo(BASE); } else NoFifo(BASE); } //end main