home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / zines / phrack2 / p50_11.txt < prev    next >
Encoding:
Text File  |  2003-06-11  |  10.3 KB  |  243 lines

  1.                                 .oO Phrack 50 Oo.
  2.  
  3.                             Volume Seven, Issue Fifty
  4.  
  5.                                     11 of 16
  6.  
  7.  
  8.              H A R D W A R E   I N T E R F A C I N G   F O R   T H E
  9.                    L I N U X   O P E R A T I N G   S Y S T E M
  10.  
  11.                      By The Professor <professr@hackerz.org>
  12.  
  13.   Computer control of real world devices has been an out of reach fantasy for
  14. most people.  In the past, it has rarely been seen outside the R&D labs of
  15. hardware design companies, universities, and a few dedicated hobbyist's
  16. basements.  It takes not only a skilled programmer, but also a person that can
  17. design and build small circuits.
  18.  
  19.   In this article, I will show you how to use a standard IBM/PC parallel
  20. printer port to control devices, such as bells, relays, and lights.  I will
  21. also show you how to take input from devices such as DTMF decoder IC's, analog
  22. to digital converters, and switches.
  23.  
  24.   To access the I/O port, the compiled program must be either executed by root
  25. or be suid root.  This could be a potential system security hazard so be
  26. warned.  In order to grant permissions to the port, one must use the function
  27. ioperm().
  28.  
  29. Syntax (also see the man page):
  30.  
  31. #include <unistd.h>
  32. ioperm(BASE_ADDRESS,NUM,PERMISSION_BIT);
  33.  
  34. The first parameter is the port number to set permissions of.
  35. The second parameter is the number of consecutive ports to set permissions of.
  36.  (i.e. if num==3, BASE_ADDRESS, BASE_ADDRESS+1, and BASE_ADDRESS+2 are set).
  37. The third parameter is 1 to give the program permissions or 0 to remove them.
  38.  
  39. Sending and receiving data via the port is done with the commands, inb() and
  40. outb().
  41.  
  42. Syntax:
  43.  
  44. #include <asm/io.h>
  45. value=inb(address); (address can be BASE_ADDRESS+1 or BASE_ADDRESS+2)
  46. outb(value,BASE_ADDRESS);
  47.  
  48.  
  49.                                  O U T P U T
  50.  
  51. Making individual output data lines of a parallel printer port "turn on" is as
  52. simple as selecting them with a corresponding binary value.  Pin 2 (D0) is the
  53. least significant bit and pin 9 (D7) is the most significant bit.  If you
  54. wanted bits 0, 2, 3, 4, and 6 to "turn on" or go high (+5v) while leaving 1,
  55. 5, and 7 low (ground) you would first convert the binary value to decimal and
  56. then send that value to the port.  (actually, there is no reason why you can't
  57. just send the binary value to the port)
  58.  
  59. D7 D6 D5 D4 D3 D2 D1 D0
  60.  0  1  0  1  1  1  0  1   ==  1011101  ==  93
  61.  
  62. outb(93,BASE_ADDRESS);
  63.  
  64. If you want all lines low or "off", you send a 0.
  65. If you want them all high or "on", you send 255.
  66.  
  67.   Controlling the status of the individual bits of the I/O port is a simple
  68. way of controlling solid state relays, optocouplers, LED's and so on.  You
  69. could very easily and very safely control a high wattage lighting system in
  70. this manner. (assuming you are using solid state relays with back EMF
  71. protection). This could/would be good for closet cultivators experimenting
  72. with the horticulture of cannabis sativa or any other plant.  Have you ever
  73. wanted things such as lights and irrigation systems to come on or turn off at
  74. certain times? That's what your crontab file is for!  The possibilities are
  75. endless.
  76.  
  77.  
  78.                                   I N P U T
  79.  
  80.   Standard IBM/PC parallel printer ports have nine control lines capable of
  81. inputting real world data.  Each printer port has three address locations.  The
  82. base address is used to transmit data.  The next address can input five data
  83. bits, using pins 11, 10, 12, 13, and 15 (referred to as BASE_ADDRESS+1 I7
  84. through I3), and the third port address can input or output a nibble of
  85. information using pins 17, 16, 14, and 1 (referred to as BASE_ADDRESS+2 I3
  86. through I0).  The third port address pins must be set HIGH so we can read from
  87. BASE_ADDRESS+2.  I'll show you how in the example.
  88.  
  89.   The inputs are all active LOW, meaning your device must short them to ground
  90. to create a signal (switch, analog to digital converter, DTMF decoder, etc).
  91. This is not a problem, as most devices already do this.  The ones that don't,
  92. just use an inverter.
  93.  
  94.   The simplest method of inputting eight data bits is to read the high nibble
  95. from the (BASE_ADDRESS+1) and the low nibble from the (BASE_ADDRESS+2). These
  96. two nibbles can be logically ORed together to form a data byte.  Some of the
  97. data bits are hard-wired on the printer card for active HIGH operation.  To
  98. get around this, I use four sections of a 7404 hex inverter to re-invert the
  99. inverted data lines.
  100.  
  101. I7 I6 I5 I4 I3 I2 I1 I0      BASE_ADDRESS+1 INPUT LINES
  102. 11 10 12 13 15 -- -- --      PIN NUMBER (-- = NOT USED)
  103.  
  104. I7 I6 I5 I4 I3 I2 I1 I0      BASE_ADDRESS+2 INPUT LINES
  105. -- -- -- -- 17 16 14  1      PIN NUMBER (-- = NOT USED)
  106.  
  107.   Notice both I3's of both ports are used.   Pin 15 (ERROR) is the 9th input
  108. of a standard IBM/PC parallel printer port.   No offense to this pin, but it's
  109. a pain in the ass to use and I only use it when I *have* to.  Through
  110. software, I disregard it.
  111.  
  112. Check out this example:
  113.  
  114. /* next line sets all open collector output pins HIGH
  115.    so we can read from BASE_ADDRESS+2)  */
  116. outb(inb(BASE_ADDRESS+2) || 15 , BASE_ADDRESS+2);
  117. High_Nibble = inb(BASE_ADDRESS+1);
  118. Low_Nibble = inb(BASE_ADDRESS+2);
  119. High_Nibble = High_Nibble & 0xF0;   /*   0xF0 = 11110000   */
  120. Low_Nibble = Low_Nibble & 0x0F;     /*   0x0F = 00001111   */
  121. Data_Byte = High_Nibble | Low_Nibble;
  122.  
  123.   Pretty simple, eh?  This means you can use I7 through I4 in BASE_ADDRESS+1
  124. and I3 through I0 in BASE_ADDRESS+2 to give you 8 bits of data input.
  125.  
  126.   All of the data lines must use a pull up resistor.  This includes the
  127. hard-wired active HIGH pins *after* the 7404 inverter.  This lets any device
  128. produce both a high and low logic signal.   Pull up resistors simply pull all
  129. the data lines high so software sees all 0's unless you short a pin to ground.
  130. (Remember these are all active LOW inputs -ground means 1)
  131.  
  132.   Pins 14, 17, 1, and 11 are all hard-wired for active HIGH operation.  These
  133. are the pins that are signaled through the 7404 inverter IC (which makes them
  134. just like the rest of the pins for ease of use).
  135.  
  136. NOTES:
  137.  
  138. *** When compiling programs using these routines, use the -O2 optimize flag,
  139. or else you'll have some headaches.
  140.  
  141. Port 888 is the 1st parallel printer port (LPT1)
  142.  
  143.   I am not responsible for your mistakes.  If you plug 120vAC directly into
  144. your parallel port, I guarantee you'll destroy your computer.  Use optically
  145. isolated solid state relays to switch high current.
  146.  
  147.   For any more info regarding I/O port programming, schematics to some fun
  148. projects, or to send a complaint, e-mail professr@hackerz.org
  149.  
  150.   If you don't like my code, keep in mind that I design hardware for a living.
  151. I am not a programmer, nor have I ever claimed to be one.   My programs are
  152. elegant on occasion, but mostly just get the job done without actually doing
  153. it the best way.
  154.  
  155. If you want schematics showing how to hook up the 7404 to the port, mail me.
  156.  
  157.   I have some interesting things there regarding circuit design.  One of my
  158. favorites is a software package called "PADS"  Personal Automated Design
  159. Software.   It is a CAD package for schematics and PCBoard Design.   The copy
  160. on my web page is a public domain demo.  This demo is fully functional in
  161. every way.  It only limits you to something like 20 IC's, 300 tie points, etc.
  162. I usually do not go over these limits.
  163.  
  164. Maybe this article will replace the IO-Port [mini] How-To 'cause that is only
  165. about 24 lines of text.
  166.  
  167.                                E X A M P L E S
  168.                                     A N D
  169.                                 D I A G R A M
  170.  
  171.             /*  simple program to send data via parallel port  */
  172.  
  173. #include <unistd.h>
  174. #include <asm/io.h>
  175. #define BASE_ADDRESS 888    /* 1st Parallel Port */ 
  176.  
  177. main() {
  178. int port_data=0;
  179. int Data_Byte=255;
  180. ioperm(BASE_ADDRESS,3,1);    /* set permission on port */
  181.     outb(Data_Byte,BASE_ADDRESS); 
  182.     printf("Sent 255 to port %d to turn all pins HIGH\n",BASE_ADDRESS);
  183. ioperm(BASE_ADDRESS,3,0);    /* take away port permission */
  184. return(0);
  185. }
  186.          /*  end of simple program to send data via parallel port  */
  187. /****************************************************************************/
  188.        /*  simple program to take in 8 bit input via parallel port  */
  189.  
  190. #include <unistd.h>
  191. #include <asm/io.h>
  192. #define BASE_ADDRESS 888    /* 1st Parallel Port */ 
  193.  
  194. main() {
  195. int port_data=0;
  196. int High_Nibble, Low_Nibble, Data_Byte;
  197. ioperm(BASE_ADDRESS,3,1);    /* set permission on port */
  198.     outb(inb(BASE_ADDRESS+2) || 15 , BASE_ADDRESS+2); 
  199.     High_Nibble = inb(BASE_ADDRESS+1);
  200.     Low_Nibble = inb(BASE_ADDRESS+2);
  201.     High_Nibble = High_Nibble & 0xF0;   /*   0xF0 = 11110000   */
  202.     Low_Nibble = Low_Nibble & 0x0F;     /*   0x0F = 00001111   */
  203.     Data_Byte = High_Nibble | Low_Nibble;
  204.     printf("LN=%d HN=%d DB=%d\n",Low_Nibble,High_Nibble,Data_Byte);
  205. ioperm(BASE_ADDRESS,3,0);    /* take away port permission */
  206. return(0);
  207. }
  208.     /*  end of simple program to take in 8 bit input via parallel port  */
  209. /****************************************************************************/
  210.                     I                          I  I  I  I
  211.                     0                          6  7  5  4
  212.  
  213.                                                      P
  214.                                                      A
  215.                     _                                P
  216.                     S                                E  S
  217.                     T                                R  E
  218.                     R                          _  B  |  L
  219.                     O                          A  U  E  E
  220.                     B  D  D  D  D  D  D  D  D  C  S  N  C
  221.                     E  0  1  2  3  4  5  6  7  K  Y  D  T
  222.                     _____________________________________
  223.                 1  (o  o  o  o  o  o  o  o  o  o  o  o  o)  13
  224.                 14  \ o  o  o  o  o  o  o  o  o  o  o  o/  25
  225.                      `---------------------------------'
  226.                       _        _  |      PINS 18       |
  227.                       A  E  I  S  |<----THROUGH 25---->|
  228.                       U  R  N  E  |       GROUND       |
  229.                       T  R  I  L
  230.                       O  O  T  |
  231.                       |  R     I
  232.                       F        N
  233.                       E        P
  234.                       E        U
  235.                       D  *     T        ** ERROR LINE IS NOT USED AS I3
  236.                          *                  (DISREGARDED VIA SOFTWARE)
  237.                       I  I  I  I
  238.                       1  3  2  3
  239.  
  240. /******************** End of my little text file / how-to *******************/
  241.  
  242. EOF
  243.