/* demo 10: INT_CHAN_1, interrupt demo */ /* step 1 : apply a init_HIGH & active_LOW signal to PC3 of port-5 */ /* (note: The PC7 of port_5 is used to enable the interrupt*/ /* operation, if PC7=GND --> PC3_interrupt is enable */ /* if PC7=VCC --> PC3_interrupt is disable) */ /* ----------------------- ---------------------------------------- */ /* step 2 : run demo10.exe */ /* --------------------------------------------------------------- */ #include "PIO.H" #define A1_8259 0x20 #define A2_8259 0xA0 #define EOI 0x20 WORD init_high(); WORD wBase,wIrq; WORD pio_d48_c0(char cConfig, char cLow, char cHigh); WORD pio_d48_c1(char cConfig, char cLow, char cHigh); WORD pio_d48_c2(char cConfig, char cLow, char cHigh); static void interrupt irq_service(); int COUNT,irqmask,now_int_state; int main() { int i,j; WORD wBoards,wRetVal; WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice,t1,t2,t3,t4,t5; char c; DWORD dwVal; /* step 1: find address-mapping of PIO/PISO cards */ clrscr(); wRetVal=PIO_DriverInit(&wBoards,0x80,0x01,0x30); /* for PIO-D48 */ printf("\nThrer are %d PIO_D48 Cards in this PC",wBoards); if (wBoards==0) exit(0); printf("\n----------------- The Configuration Space -------------------------"); for(i=0; i "); ShowPioPiso(wSubVendor,wSubDevice,wSubAux); } /* select card_0 */ PIO_GetConfigAddressSpace(0,&wBase,&wIrq,&t1,&t2,&t3,&t4,&t5); /* step 2: enable all D/I/O port */ outportb(wBase,1); /* enable D/I/O */ init_high(); /* interrupt initialize, INIT_CHAN_1 is HIGH now */ COUNT=0; printf("\n*** show the count of Low_pulse **\n"); for (;;) { printf("\nLow Pulse Count=%d (initial is HIGH, active is LOW)",COUNT); if (kbhit()!=0) {getch(); break;} } outportb(wBase+5,0); /* disable all interrupt */ PIO_DriverClose(); } /* -------------------------------------------------------------------- */ /* Use INT_CHAN_1 as external interrupt signal */ WORD 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 */ outportb(A1_8259+1,irqmask & (0xff ^ (1 << wIrq))); irqmask=inportb(A2_8259+1); outportb(A2_8259+1,irqmask & (0xff ^ (1 << (wIrq-8)))); setvect(wIrq-8+0x70, irq_service); } /* select PC3 & !PC7 of port_5 as interrupt signal */ outportb(wBase+0xf0,0x04); /* CTRL_D5=0,CTRL_D4=0 --> */ /* INT_CHAN_1=PC3&!PC7 -> */ /* PC7 can enable/disable PC3 */ /* Note: In this demo, assume the PC3 is init_HIGH & active_LOW */ /* the PC7 is used to enable/disable PC3 --> */ /* PC7=VCC --> PC3-interrupt is disable */ /* PC7=GND --> PC3-interrupt is enable */ /* ------------------------------------------------------------ */ /* now the PC3 of port-5 is HIGH */ /* --> INV1 must select the inverted PC3 */ /* --> INT_CHAN_1=!PC3=init_LOW, active_HIGH */ outportb(wBase+0x2a,0); /* select the inverted PC3 */ /* INT_CHAN_1=!PC3 */ now_int_state=1; /* now PC3 is high */ outportb(wBase+5,2); /* enable INT_CHAN_1 interrupt */ for (;;) /* wait PC3&!PC7=HIGH */ { if ((inportb(wBase+7)&2)!=0) break; printf("\nWait PC3&!PC7=HIGH"); } enable(); } /* -------------------------------------------------------------------- */ void interrupt irq_service() { if (now_int_state==1) /* now PC3 is changed to LOW */ { /* --> INT_CHAN_1=!PC3=HIGH now */ COUNT++; /* find a LOW_pulse (PC3) */ if((inportb(wBase+7)&2)==0) /* the PC3 is still fixed in LOW */ { /* --> need to generate a high_pulse */ outportb(wBase+0x2a,2); /* INV1 select the non-inverted input */ /* INT_CHAN_1=PC3=LOW --> */ /* INT_CHAN_1 generate a high_pulse */ now_int_state=0; /* now PC3=LOW */ } else now_int_state=1; /* now PC3=HIGH */ /* (no need to generate high_pulse ) */ } else /* now PC3 is changed to HIGH */ { /* --> INT_CHAN_1=PC3=HIGH now */ /* find a HIGH_pulse (PC3) */ if((inportb(wBase+7)&2)==2) /* the PC3 is still fixed in LOW */ { /* --> need to generate a high_pulse */ outportb(wBase+0x2a,0); /* INV1 select the inverted input */ /* INT_CHAN_1=!PC3=LOW --> */ /* INT_CHAN_1 generate a high_pulse */ now_int_state=1; /* now PC3=HIGH */ } else now_int_state=0; /* now PC3=HIGH */ /* (no need to generate high_pulse ) */ } if (wIrq>=8) outportb(A2_8259,0x20); outportb(A1_8259,0x20); } /* -------------------------------------------------------------------- */ WORD pio_d48_c0(char cConfig, char cLow, char cHigh) /* COUNTER_0 */ { outportb(wBase+0xec,cConfig); outportb(wBase+0xe0,cLow); outportb(wBase+0xe0,cHigh); return(NoError); } WORD pio_d48_c1(char cConfig, char cLow, char cHigh) /* COUNTER_1 */ { outportb(wBase+0xec,cConfig); outportb(wBase+0xe4,cLow); outportb(wBase+0xe4,cHigh); return(NoError); } WORD pio_d48_c2(char cConfig, char cLow, char cHigh) /* COUNTER_2 */ { outportb(wBase+0xec,cConfig); outportb(wBase+0xe8,cLow); outportb(wBase+0xe8,cHigh); return(NoError); }