#include #include #include #include unsigned int BASE=0x300; unsigned int IRQPIN=5; //INSW - input string of words void insw(unsigned short Port, void far *Buf, int Count) { _ES = FP_SEG(Buf); /* Segment of Buf */ _DI = FP_OFF(Buf); /* Offset of Buf */ _CX = Count; /* Number to read */ _DX = Port; /* Port */ asm REP INSW; } char far *VM = (char far *)MK_FP(0xB800, 0); const char HexDigit[16] = "0123456789ABCDEF"; char *WordToPChar(unsigned short Data) { static char Lit[5]; Lit[4] = 0; Lit[3] = HexDigit[Data & 0xF]; Lit[2] = HexDigit[(Data >> 4) & 0xF]; Lit[1] = HexDigit[(Data >> 8) & 0xF]; Lit[0] = HexDigit[(Data >> 12) & 0xF]; return Lit; } void PrintWord(int XR, int Y, unsigned short Data) { char far *Tar = VM + (Y * 80 + XR) * 2; *Tar = HexDigit[Data & 0xF]; Data >>= 4; Tar -= 2; *Tar = HexDigit[Data & 0xF]; Data >>= 4; Tar -= 2; *Tar = HexDigit[Data & 0xF]; Data >>= 4; Tar -= 2; *Tar = HexDigit[Data & 0xF]; } void PrintNybble(int X, int Y, unsigned char Data) { char far *Tar = VM + (Y * 80 + X) * 2; *Tar = HexDigit[Data & 0xF]; } void PrintChar(int X, int Y, char Data) { char far *Tar = VM + (Y * 80 + X) * 2; *Tar = Data; } unsigned AskForBaseAddress(unsigned int OldOne) { char msg[8]; unsigned int NewOne = 0, Success = 0, Dummy; int AddrInputPosX, AddrInputPosY; puts("\n\nPlease enter the Base Address (100-FFFF) 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); if (NewOne >= 0x100) { Success = 1; Dummy = NewOne; } else if (msg[1] == 0) { gotoxy(AddrInputPosX, AddrInputPosY); printf("%X", OldOne); Success = 1; Dummy = OldOne; } } while(!Success); return (Dummy); } /* end of AskForBaseAddress */ unsigned AskForIRQ(unsigned int OldOne) { char msg[8]; unsigned int NewOne = 0, Success = 0, Dummy; int AddrInputPosX, AddrInputPosY; puts("\n\nPlease enter the IRQ (2-F) for your card (in hex)"); printf("or press ENTER for %X.\n>", OldOne); AddrInputPosX = wherex(); AddrInputPosY = wherey(); do { gotoxy(AddrInputPosX, AddrInputPosY); clreol(); msg[0] = 3; msg[1] = 0; cgets(msg); sscanf(msg + 2, "%x", &NewOne); if ( (NewOne >= 0x2) && (NewOne <= 0xF) ) { Success = 1; Dummy = NewOne; } else if (msg[1] == 0) { gotoxy(AddrInputPosX, AddrInputPosY); printf("%X", OldOne); Success = 1; Dummy = OldOne; } } while(!Success); return (Dummy); } /* end of AskForIRQ */ //8254 functions void CtrMode(unsigned char Ctr, unsigned char Mode) { unsigned char Ctrl = (Ctr << 6) | 0x30 | (Mode << 1); outportb(BASE+0x08+3, Ctrl); } void CtrLoad(unsigned char Ctr, unsigned short Data) { outportb(BASE+0x08+Ctr, Data & 0xFF); outportb(BASE+0x08+Ctr, Data >> 8); } //IRQ array and functions //In C++, ISRs take (...) arguments #ifdef __cplusplus #define __CPPARGS ... #else #define __CPPARGS #endif void interrupt far (*oldisr[16])(__CPPARGS); //global to store old handler pointer void SendEOI(void) { outportb(0xA0, 0x20); outportb(0x20, 0x20); } unsigned char initirq(char IRQnumber,void interrupt (*ISR)(__CPPARGS)) { 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); } } //104-AIO1616W config variables and utility functions unsigned char ADRange, dacArange, dacBrange; void init(void) { unsigned char jumpers; outportb(BASE + 0x1B,0xFF); delay(1); jumpers = inportb(BASE+0x12);//jumper configuration readback ADRange = jumpers & 0x07;//d0,d1,d2 are 16ch, 5V, Bip dacBrange = (jumpers>>3) & 0x01;//d4,d3 are 5V for daca,b dacArange = (jumpers>>4) & 0x01; outportb(BASE+0x13, 0x04); //Enable FIFO half full IRQs outportb(BASE+0x07, 0x00); //Set oversample to +0 CtrMode(1, 2); CtrMode(2, 2); CtrLoad(1, 0x0002); //Ctr 1 & 2 divisor of 50h with 10MHz clock gives 125kHz tick CtrLoad(2, 0x0028); outport(BASE + 0x02, 0x0000); //Clear gains 0-7 outport(BASE + 0x04, 0x0000); //Clear gains 8-F outportb(BASE + 0x06, 0x10); //Set channel scan from 0 to 1 } #define STARTTIMEDCONVERSIONS StartTimedConversions() void StartTimedConversions(void) { outportb(BASE+0x1B, 0x01); //Clear FIFO outportb(BASE+0x11, 0x01); //Select Ctr as ADC trigger, one channel per output pulse } #define STOPTIMEDCONVERSIONS outportb(BASE+0x11, 0x00) //Bytes in half FIFO #define FIFOHALF 1024 //Bytes in quarter FIFO = samples in half FIFO #define FIFOQUAR (FIFOHALF / 2) unsigned short Buf[FIFOQUAR]; unsigned long IRQCount; void interrupt far newisr(__CPPARGS) { insw(BASE + 0x0, Buf, FIFOQUAR); ++IRQCount; PrintChar(13, 6, IRQCount); SendEOI(); inportb(BASE+ 0x13); //Clear FIFO half full IRQs } void main(void) { unsigned long OIRQCount = 0; IRQCount = 0; directvideo = 1; clrscr(); BASE = AskForBaseAddress(BASE); IRQPIN = AskForIRQ(IRQPIN); clrscr(); cputs("104-AIO16 Family High-Speed Sample\r\n"); cputs("This sample acquires from A/D channels 0 and 1 at 125kHz per channel.\r\n"); cputs("Data is displayed in the idle time between acquisition.\r\n\r\n"); init(); cprintf("A/D: %s %s\r\n\r\n", (ADRange & 0x01)? ((ADRange & 0x04)?"ñ5V":"ñ10V") : ((ADRange & 0x04)?"0-10V":"0-10V(Low Res)") //0-10V(Low Res) is , //in theory 0-20V, (ADRange & 0x02)?"16ch":"8ch" //but the amps cap //at 10V ); cputs("Taking data: \r\n\r\n"); gotoxy(11, 9); cputs("Ch 0 Ch 1"); gotoxy(11, 10); cputs(".... ...."); gotoxy(1, 12); cputs("Press any key to exit.\r\n"); initirq(IRQPIN, newisr); STARTTIMEDCONVERSIONS; while(-1) { if ( IRQCount != OIRQCount ) { OIRQCount = IRQCount; PrintWord(13, 9, Buf[0]); PrintWord(23, 9, Buf[1]); } if ( kbhit() ) { getch(); break; } } restoreirq(IRQPIN); STOPTIMEDCONVERSIONS; }