/* partest.c for testing the Parallel Port. * E. g. "partest 888 255" puts the value 255 to the port 888 (e. g. lp0, lpt1) * and prints if the port can be bidirectional and prints the status register * Byte. * * This Program won't work on the sparc, where there's no concept of I/O space * Tested with 2.2 on the x86 * * important: this program won't work without the compiler-option -O or -02 ... * and this program can only be run by a superuser (or another user after * "chown root.root partest; chmod 4755 partest"). * * It takes approx. 1,5us for one Parallel Port I/O (with an onboard Parallel Port). The first version used a 150 Ohm resistor from a data pin to ground and another resistor to a status pin but some parallel port do have status pins with a high level that is read (via data port) as low. This second version uses a 1000 uF capacitator between a data pin and ground and works correct with every tested parallel port. All tested parallel ports (CMOS and TTL versions), e. g. the one on the mainboard Tyan Tiger MPX, are bidirectional. Rolf Freitag Lizenz: GPL */ #include #include // or asm/io.h; for inb, ioperm, iopl ... #include // strtol #include // getuid() #include // EPERM #include // and int main (int argc, char *argv[]) { int base; // Parallel Port Base. A wrong value can cause serious damage! int value; unsigned char b = 0, b0, b1; if (3 != argc) { printf ("Usage: %s \n", argv[0]); exit (-1); } base = strtol (argv[1], (char **)NULL, 0); value = strtol (argv[2], (char **)NULL, 0); if (geteuid () != 0) { printf ("\a\n\nError: $EUID==%d!=0 (you are not a superuser).\n\n", getuid ()); exit (-EPERM); } iopl (3); // unlimited I/O access permission, nessesary above the 0x3ff limit e. g. at 0x9800=38912 outb (0x04, base + 2); // write mode, interrupt disable, all controll pins high outb (0xb7, base + 1); // try to set the status pins high outb (0x00, base); // write 0x00 usleep (1000000); // wait one second outb (0x24, base + 2); // read mode b = inb (base); b0 = b; // store first byte printf ("Wrote 0x00 data for one second, read 0x%x.\n", b); // if (b0) // printf ("The port is not bidirectional (or damaged or something (maybe internall pullups) pulls up).\n"); outb (0x04, base + 2); // write mode outb (0xff, base); // write 0xff outb (0x24, base + 2); // read mode usleep (1); // wait one microsecond b = inb (base); b1 = b; printf ("Wrote 0xff data for one mikrosecond, read 0x%x.\n", b); if (b1 != 0xff) // port seems ok and something pulled down at second reading { printf ("The parallel at 0x%x is bidirektional (could read 0x%x from the data port\n", base, b1); printf ("after writing 0xff)!\n"); } else { printf ("The parallel port at 0x%x can be bidirektional. Check with (minimum) one data\n", base); printf ("pin connected to ground with a 1000 uF capacitator (elko) or 220 Ohm (or less)\n"); printf ("resistor. If done so, the parallel port is NOT bidirektional.\n"); } b = inb (base + 1); printf ("status register: %i = 0x%x\n", b, b); outb (0x04, base + 2); // write mode outb (value, base); iopl (0); // no I/O permission return 0; };