/***************************************************************************** * SAMPLE3.C : COUNTER/TIMER * * * * This program will set counter 0 to output 10,000 Hz, counter 1 * * to output 1000 Hz, and will set counter 2 to output 100 Hz. * * * *****************************************************************************/ #include #include #include #include #include #include #include "kbinp.h" #ifndef FALSE #define FALSE 0 #define TRUE !FALSE #endif #define uint unsigned int #define DEFAULT_ADDRESS 0x340 #define COUNTER_OFFSET 0x0C #define COUNTER_0 0 #define COUNTER_1 1 #define COUNTER_2 2 #define MODE_0 0 #define MODE_1 1 #define MODE_2 2 #define MODE_3 3 #define MODE_4 4 #define MODE_5 5 #define DIVIDE_BY_10 10 #define DIVIDE_BY_100 100 #define DIVIDE_BY_1000 1000 void CtrMode( uint, char, char); void CtrLoad( uint, int, int); uint CtrRead( uint, uint); uint AskForBaseAddress( unsigned int); void IOPermission(unsigned abase) { if(ioperm(abase,16,1)<0) { fprintf(stderr, "NO IO PERMISSION\n"); } } int main() { uint base; system("clear"); puts("Sample 3\n"); puts("This sample loads all three counters and continuously displays\n"); puts("the values that are currently in them.\n"); base= AskForBaseAddress( DEFAULT_ADDRESS); IOPermission(base); // Turn off interrupt request generation and set the A/DC trigger // to software only. inb( base ); // read the status reg., clr IRQ // set to software start conversion, disabled irqs, read of base+3 to start // conversions, enable internal clock, counter 1, and counter 2 outb(0xDF, base); CtrMode( base+COUNTER_OFFSET, COUNTER_0, MODE_3); CtrMode( base+COUNTER_OFFSET, COUNTER_1, MODE_3); CtrMode( base+COUNTER_OFFSET, COUNTER_2, MODE_3); CtrLoad( base+COUNTER_OFFSET, COUNTER_0, DIVIDE_BY_100); CtrLoad( base+COUNTER_OFFSET, COUNTER_1, DIVIDE_BY_1000); CtrLoad( base+COUNTER_OFFSET, COUNTER_2, DIVIDE_BY_10); system("clear"); system("tput cup 1 15"); puts("Press ENTER to exit...\n"); do { system("tput cup 2 4"); puts( "decrementing between 1000 and 0"); printf( "counter 0 = %4hu\n", CtrRead( base+COUNTER_OFFSET, COUNTER_1)); system("tput cup 4 4"); puts( "decrementing between 100 and 0"); printf( "counter 1 = %4hu\n", CtrRead( base+COUNTER_OFFSET, COUNTER_0)); system("tput cup 6 4"); puts( "decrementing between 10 and 0"); printf( "counter 2 = %4hu\n", CtrRead( base+COUNTER_OFFSET, COUNTER_2)); } while(kbhit()==0); system("tput cup 9 0"); return 0; } void CtrMode(uint addr, char cntr, char mode) { int ctrl; ctrl = (cntr << 6) | 0x30 | (mode << 1); outb(ctrl, addr+3); } void CtrLoad(uint addr ,int c,int val) { outb(val & 0x00FF,addr+c); outb((val>>8) & 0x00FF,addr+c); } uint CtrRead(uint addr , uint c) { outb(c<<6,addr+3); return inb(addr+c) + (inb(addr+c) << 8); } unsigned AskForBaseAddress(unsigned int OldOne) { char msg[3]; unsigned int newone; unsigned int temp = 0; int index = 0; int letter; puts("Please enter the Base Address for your card (in hex)"); printf("or press ENTER for %X.\n>", OldOne); while(temp==0) { newone=0; index=0; while((letter = getchar())!='\n') msg[index++] = letter; sscanf(msg, "%X", &newone); if(newone==0){ temp=OldOne; } else if((newone>=0x100)&&(newone<=0x3f0)){ temp=newone; } else { printf("\nEnter the Base Address or press ENTER for %x\n", OldOne); for(index=0; index<=3; index++) msg[index]=0; } } return(temp); } /* end of AskForBaseAddress */