/* DEMO6 : INT_CHAN_0 & INT_CHAN_1 timer interrupt demo */ /* wave generater (without calibration) */ /* (It is designed to be a machine independent) */ /* step1 : Run DEMO6.EXE */ /* -------------------------------------------------------------- */ #include "PIO.H" #define A1_8259 0x20 #define A2_8259 0xA0 #define EOI 0x20 static void interrupt irq_service(); void pio_da16_c0(char cConfig, char cLow, char cHigh); void pio_da16_c1(char cConfig, char cLow, char cHigh); void pio_da16_c2(char cConfig, char cLow, char cHigh); void pio_da16_da(char cChannel_no,int iVal); void init_high(); WORD wBase,wIrq; int irqmask,now_int_state,new_int_state,int_c; int INT0_L,INT0_H,INT1_L,INT1_H,invert; int v1,v2,v3,v4,h1,h2,h3,h4; float pi=3.141592654; float d1,d2; int main() { int i,j; WORD wBoards,wRetVal,t1,t2,t3,t4,t5,t6; WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice; clrscr(); /* step1 : find address-mapping of PIO/PISO cards */ wRetVal=PIO_DriverInit(&wBoards,0x80,0x04,0x00);/*for PIO-DA16/8/4*/ printf("\n(1) Threr are %d PIO-DA16/8/4 Cards in this PC",wBoards); if ( wBoards==0 ) exit(0); printf("\n\n-------------- The Configuration Space --------------"); for(i=0;i "); ShowPioPiso(wSubVendor,wSubDevice,wSubAux); } PIO_GetConfigAddressSpace(0,&wBase,&wIrq,&t1,&t2,&t3,&t4,&t5); /* select card_0 */ /* step2 : enable all D/I/O port */ outportb(wBase,0x11); /* /RESET -> 1 */ printf("\n\n(2) DEMO6 Interrupt test"); init_high(); /* interrupt initialize, INT_CHAN_0/1 is high now */ printf("\nChannel 0 : +/-10V, 200Hz sin wave"); printf("\nChannel 1 : 0-20mA, 100Hz sin wave"); for (;;) { if (kbhit()!=0) break; } outportb(wBase+5,0); /* disable all interrupt */ PIO_DriverClose(); } /* Use INT_CHAN_0 & INT_CHAN_1 as external interrupt signal */ void init_high() { DWORD dwVal; disable(); outportb(wBase+5,0); /* disable all interrupt */ if (wIrq<8) { irqmask=inportb(A1_8259+1); outportb(A1_8259+1,irqmask & (0xff ^ (1 << wIrq))); setvect(wIrq+8, irq_service); } else { irqmask=inportb(A1_8259+1); outportb(A1_8259+1,irqmask & 0xfb); /* IRQ2 */ irqmask=inportb(A2_8259+1); outportb(A2_8259+1,irqmask & (0xff ^ (1 << (wIrq-8)))); setvect(wIrq-8+0x70, irq_service); } /* CLK source = 4 MHz */ pio_da16_c0(0x36,0xc8,0x00); /* COUNTER0, mode3, div 200 */ /* program Cout0 20kHz */ pio_da16_c1(0x76,0xc8,0x00); /* COUNTER1, mode3, div 200 */ pio_da16_c2(0xb6,0x02,0x00); /* COUNTER2, mode3, div 2 */ /* program Cout2 10kHz */ /* note : the 8254 need extra 2-clock for initialization */ for (;;) { if ((inportb(wBase+7)&3)==3) break; /* wait Cout0/2 = high */ } /* note : Cout0/2 = high, INV0/1 must select the inverted Cout0/2 */ /* --> INT_CHAN_0 = !Cout0 = init_low, active_high */ /* --> INT_CHAN_1 = !Cout2 = init_low, active_high */ outportb(wBase+0x2a,0); now_int_state=3; /* now Cout0 & Cout2 is high */ outportb(wBase+5,3); /* enable INT_CHAN_0/1 interrupt */ enable(); } /* -------------------------------------------------------------- */ /* Note : 1.The hold_time of INT_CHAN_0 & INT_CHAN_1 must long */ /* enoug. */ /* 2.The ISR must read the interrupt status again to */ /* identify the active interrupt source. */ /* 3.The INT_CHAN_0 & INT_CHAN_1 can be active at the same */ /* time. */ /* -------------------------------------------------------------- */ void interrupt irq_service() { new_int_state=inportb(wBase+7)&0x03; int_c=new_int_state^now_int_state; if ((int_c&0x01)==1) /* INT_CHAN_0 is active */ { if ((new_int_state&1)==0) /* INT0 change to low now */ { d1=3.6*INT0_L; v1=(sin(d1*pi/180.0)+1)*8191.5; pio_da16_da(0,v1); /* channel_0 */ INT0_L++; if (INT0_L==100) INT0_L=0; } else { INT0_H++; /* INT0 change to high now */ } invert=invert^1; /* generate high_pulse */ } if ((int_c&0x02)==2) /* INT_CHAN_1 is active */ { if ((new_int_state&2)==0) /* INT1 change to low now */ { d2=3.6*INT1_L; v2=(sin(d2*pi/180.0)+1)*4096+8191; pio_da16_da(1,v2); /* channel_1 */ INT1_L++; if (INT1_L==100) INT1_L=0; } else /* INT1 change to high now */ { INT1_H++; } invert=invert^2; /* generate high_pulse */ } now_int_state=new_int_state; /* updata interrupt status */ outportb(wBase+0x2a,invert); /* generate high_pulse */ if (wIrq>=8) outportb(A2_8259,0x20); outportb(A1_8259,0x20); } /* -------------------------------------------------------------- */ void pio_da16_c0(char cConfig, char cLow, char cHigh) /* COUNTER0 */ { outportb(wBase+0xcc,cConfig); outportb(wBase+0xc0,cLow); outportb(wBase+0xc0,cHigh); } void pio_da16_c1(char cConfig, char cLow, char cHigh) /* COUNTER1 */ { outportb(wBase+0xcc,cConfig); outportb(wBase+0xc4,cLow); outportb(wBase+0xc4,cHigh); } void pio_da16_c2(char cConfig, char cLow, char cHigh) /* COUNTER2 */ { outportb(wBase+0xcc,cConfig); outportb(wBase+0xc8,cLow); outportb(wBase+0xc8,cHigh); } void pio_da16_da(char cChannel_no,int iVal) { iVal=iVal+(cChannel_no%4)*0x4000; /* cChannel_no : 0 - 15 */ outportb(wBase+0xf0,iVal); /* iVal : 0x0000 - 0x3fff */ outportb(wBase+0xf4,(iVal>>8)); outportb(wBase+0xe0+4*(cChannel_no/4),0xff); }