/* * Simple general purpose I/O port control program for Linux * Written and copyright by Tomi Engdahl 2005 * (e-mail: tomi.engdahl@hut.fi) * * * Supported port identifiers * LPT1DATA * LPT1STATUS * LPT1HANDSHAKE * JOYSTICK * * * Supported commands * * PRINT DEC Read data, gives output as decimal number * PRINT HEX Read data, gives output as hexadecimal number * PRINT BIN Read data, gives output as binary number * PRINTBITS bits Reads the specified bits in the specified order (0..7) * * WRITE Writes register value to port * READ Reads value from specified port to register * * SETVALUE value Sets the given value to register * AND value Performs AND with given value and register * OR value Performs OR with given value and register * XOR value Performs XOR with given value and register * SETBITS bits Sets given bits to 1 in register * RESETBITS bits Sets given bits to 0 in register * TOGGLEBITS bits Toggles specified bit values * * value can be gives as decimal number or heaxadecimal starting with 0x * bits is a list of bit position identifiers from 0 to 7 * */ #include #include #include #include #define MAX_ARGUMENT_LEN 8 /* * String compare routine, gives 1 when strings match, 0 otherwise */ int stringMatch(char * str1, char * str2) { if (strcmp(str1,str2) == 0) { return 1; } return 0; } /* * Routine to convert port */ int PortIDtoAddress(char * portID) { if (stringMatch(portID, "LPT1DATA")) { return 0x0378; } if (stringMatch(portID, "LPT1STATUS")) { return (0x0379 + 1); } if (stringMatch(portID, "LPT1HANDSHAKE")) { return (0x0378 + 2); } if (stringMatch(portID, "JOYSTICK")) { return 0x0201; } fprintf(stderr, "Error: Invalid port name %s\n", portID), exit(1); return 0; } int ReadPort(char * portID) { int iobase; iobase = PortIDtoAddress(portID); if (iobase==0) fprintf(stderr, "Error: Invalid port address %s\n", portID), exit(1); if (ioperm(iobase,1,1)) { fprintf(stderr, "Error: Couldn't get the port at %x\n", iobase), exit(1); } else { return inb(iobase); } return 0; } int WritePort(char * portID, int value) { int base; base = PortIDtoAddress(portID); if (base==0) fprintf(stderr, "Error: Invalid port address\n", base), exit(1); if (ioperm(base,1,1)) { fprintf(stderr, "Error: Couldn't get the port at %x\n", base), exit(1); } else { outb(value, base); } return 0; } void bin_prnt_byte(int x) { int n; for(n=0; n<8; n++) { if((x & 0x80) !=0) { printf("1"); } else { printf("0"); } x = x<<1; } } int printBits(int value,char *specifier) { int index=0; int mask=0; while ((index < MAX_ARGUMENT_LEN) && (specifier[index]!=0)) { switch (specifier[index]) { case '0': if ((value & 1) != 0) printf("1"); else printf("0"); break; case '1': if ((value & 2) != 0) printf("1"); else printf("0"); break; case '2': if ((value & 4) != 0) printf("1"); else printf("0"); break; case '3': if ((value & 8) != 0) printf("1"); else printf("0"); break; case '4': if ((value & 16) != 0) printf("1"); else printf("0"); break; case '5': if ((value & 32) != 0) printf("1"); else printf("0"); break; case '6': if ((value & 64) != 0) printf("1"); else printf("0"); break; case '7': if ((value & 128) != 0) printf("1"); else printf("0"); break; default: fprintf(stderr, "Error: Wrong bit position specifier.\n"), exit(1); break; } index++; } printf("\n"); return 0; } /* * Converts bit string like 0123456789 */ int bitsToMask(char * specifier) { int index=0; int mask=0; while ((index < MAX_ARGUMENT_LEN) && (specifier[index]!=0)) { switch (specifier[index]) { case '0': mask = mask | 1; break; case '1': mask = mask | 2; break; case '2': mask = mask | 4; break; case '3': mask = mask | 8; break; case '4': mask = mask | 16; break; case '5': mask = mask | 32; break; case '6': mask = mask | 64; break; case '7': mask = mask | 128; break; default: fprintf(stderr, "Error: Wrong bit position specifier.\n"), exit(1); break; } index++; } return mask; } int processCommand(char * command, char * argument, int * argcount, char * portId, int * portData) { int mask; *argcount=1; // defualt takes on argument if (stringMatch(command,"read")) { *argcount=0; // this command did no use any arguments *portData=ReadPort(portId); } else if (stringMatch(command,"write")) { *argcount=0; // this command did no use any arguments WritePort(portId, *portData); } else if (stringMatch(command,"print")) { if (stringMatch(argument,"dec")) { printf("%i\n",*portData); } else if (stringMatch(argument,"hex")) { printf("%x\n",*portData); } else if (stringMatch(argument,"bin")) { bin_prnt_byte(*portData); printf("\n"); } else { fprintf(stderr, "Error: Wrong PRINT argument.\n"), exit(1); } } else if (stringMatch(command,"printbits")) { printBits(*portData,argument); } else if (stringMatch(command,"setvalue")) { *portData=atoi(argument); } else if (stringMatch(command,"and")) { mask=atoi(argument); *portData = (*portData) & mask; } else if (stringMatch(command,"or")) { mask=atoi(argument); *portData = (*portData) | mask; } else if (stringMatch(command,"xor")) { mask=atoi(argument); *portData = (*portData) ^ mask; } else if (stringMatch(command,"setbits") || stringMatch(command,"setbit")) { mask=bitsToMask(argument); *portData = (*portData) | mask; } else if (stringMatch(command,"resetbits") || stringMatch(command,"resetbit")) { mask=bitsToMask(argument) ^ 0xFF; *portData = (*portData) & mask; } else if (stringMatch(command,"togglebits") || stringMatch(command,"togglebit")) { mask=bitsToMask(argument); *portData = (*portData) ^ mask; } return 0; } int main(int argc, char **argv) { int value; int argIndex; int acount; int portData; char * portId; if (argc<2) fprintf(stderr, "Error: Wrong number of arguments.\n"), exit(1); portId=argv[1]; portData=0; argIndex=2; // start from first argument after port definition while (argIndex < argc) { if ((argIndex+1) < argc) { processCommand(argv[argIndex],argv[argIndex+1],&acount,portId,&portData); } else { processCommand(argv[argIndex],argv[argIndex+1],&acount,portId,&portData); } argIndex=argIndex+acount+1; } return 0; }