/* demo 7 : INT_CHAN_2, 16-bit down-counter (using interrupt) */ /* step 1 : apply a init_HIGH & active_LOW signal to PC0 of port-2 */ /* step 2 : run demo7.exe */ /* --------------------------------------------------------------- */ #include "PIO.H" #define A1_8259 0x20 #define A2_8259 0xA0 #define EOI 0x20 WORD init_low(); 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_low(); /* interrupt initialize, INT_CHAN_2 now is initial LOW */ COUNT=0; printf("\n*** show the count of Low_pulse **\n"); for (;;) { printf("\nInterrupt Count=%d (one interrupt=5 low_pulse)",COUNT); if (kbhit()!=0) {getch(); break;} } outportb(wBase+5,0); /* disable all interrupt */ PIO_DriverClose(); } /* -------------------------------------------------------------------- */ /* Use INT_CHAN_2 as external interrupt signal */ WORD init_low() { DWORD dwVal; disable(); 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); } outportb(wBase+5,0); /* disable all interrupt */ /* select PC0 of port_2 as init_HIGH & active_LOW sinal */ outportb(wBase+0xf0,0); /* CTRL_D1=0 -> init_HIGH, active_LOW */ /* NOTE : The 8254 need the extra starting two event_clock to initialize */ /* So the counter value before the starting two clock is error */ pio_d48_c0(0x30,3,0); /* COUNTER0,mode-0 down count 3+2=5 */ /* Note: now the COUT0 is LOW */ /* --> INV2 must select the non-inverted COUT0 */ /* --> INT_CHAN_2=COUT0=init_LOW, active_HIGH */ outportb(wBase+0x2a,4); /* select the non-inverted COUT0 */ /* INT_CHAN_2=COUT0=LOW now */ now_int_state=0; /* now COUT0 is LOW */ outportb(wBase+5,4); /* enable INT_CHAN_2 interrupt */ for (;;) /* wait COUT0=LOW */ { if ((inportb(wBase+7)&4)==0) break; } enable(); } /* -------------------------------------------------------------------- */ void interrupt irq_service() { if (now_int_state==0) /* now COUT0 is changed to HIGH */ { /* --> INT_CHAN_2=COUT0=HIGH now */ COUNT++; /* find a HIGH_pulse (COUT0) */ pio_d48_c0(0x30,3,0); /* COUNTER0,mode-0 down count 3+2=5 */ /* now INT_CHAN_2=COUT0=LOW now --> */ /* INT_CHAN_2 generate a HIGH_pulse */ now_int_state=0; /* now COUT0=LOW */ } 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); }