cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 2 | # parallel port access using the ppdev driver |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 3 | |
alexperry | 9c6d6f1 | 2004-10-04 18:13:39 +0000 | [diff] [blame] | 4 | import sys |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 5 | import struct |
| 6 | import fcntl |
| 7 | import os |
| 8 | |
| 9 | #---- |
| 10 | # Generated by h2py 0.1.1 from <linux/ppdev.h>, |
| 11 | # then cleaned up a bit by Michael P. Ashton and then a gain by chris ;-) |
alexperry | 9c6d6f1 | 2004-10-04 18:13:39 +0000 | [diff] [blame] | 12 | # Changes for Python2.2 support (c) September 2004 Alex.Perry@qm.com |
| 13 | |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 14 | |
| 15 | def sizeof(type): return struct.calcsize(type) |
cliechti | 9cc9353 | 2005-01-15 21:16:33 +0000 | [diff] [blame] | 16 | def _IOC(dir, type, nr, size): return int((dir << _IOC_DIRSHIFT ) | (type << _IOC_TYPESHIFT ) |\ |
| 17 | (nr << _IOC_NRSHIFT ) | (size << _IOC_SIZESHIFT)) |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 18 | def _IO(type, nr): return _IOC(_IOC_NONE, type, nr, 0) |
| 19 | def _IOR(type,nr,size): return _IOC(_IOC_READ, type, nr, sizeof(size)) |
| 20 | def _IOW(type,nr,size): return _IOC(_IOC_WRITE, type, nr, sizeof(size)) |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 21 | |
| 22 | _IOC_SIZEBITS = 14 |
alexperry | 5499022 | 2004-04-16 19:17:04 +0000 | [diff] [blame] | 23 | _IOC_SIZEMASK = (1L << _IOC_SIZEBITS ) - 1 |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 24 | _IOC_NRSHIFT = 0 |
| 25 | _IOC_NRBITS = 8 |
| 26 | _IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS |
| 27 | _IOC_TYPEBITS = 8 |
| 28 | _IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS |
| 29 | IOCSIZE_MASK = _IOC_SIZEMASK << _IOC_SIZESHIFT |
| 30 | IOCSIZE_SHIFT = _IOC_SIZESHIFT |
alexperry | 9c6d6f1 | 2004-10-04 18:13:39 +0000 | [diff] [blame] | 31 | |
| 32 | # Python 2.2 uses a signed int for the ioctl() call, so ... |
| 33 | if ( sys.version_info[0] < 3 ) or ( sys.version_info[1] < 3 ): |
| 34 | _IOC_WRITE = 1L |
| 35 | _IOC_READ = -2L |
| 36 | _IOC_INOUT = -1L |
| 37 | else: |
| 38 | _IOC_WRITE = 1L |
| 39 | _IOC_READ = 2L |
| 40 | _IOC_INOUT = 3L |
| 41 | |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 42 | _IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS |
alexperry | 9c6d6f1 | 2004-10-04 18:13:39 +0000 | [diff] [blame] | 43 | IOC_INOUT = _IOC_INOUT << _IOC_DIRSHIFT |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 44 | IOC_IN = _IOC_WRITE << _IOC_DIRSHIFT |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 45 | IOC_OUT = _IOC_READ << _IOC_DIRSHIFT |
| 46 | |
| 47 | _IOC_NONE = 0 |
| 48 | PP_IOCTL = ord('p') |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 49 | PPCLAIM = _IO(PP_IOCTL, 0x8b) |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 50 | PPCLRIRQ = _IOR(PP_IOCTL, 0x93, 'i') |
| 51 | |
| 52 | PPDATADIR = _IOW(PP_IOCTL, 0x90, 'i') |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 53 | PPEXCL = _IO(PP_IOCTL, 0x8f) |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 54 | PPFCONTROL = _IOW(PP_IOCTL, 0x8e, 'BB') |
| 55 | PPGETFLAGS = _IOR(PP_IOCTL, 0x9a, 'i') |
| 56 | PPGETMODE = _IOR(PP_IOCTL, 0x98, 'i') |
| 57 | PPGETMODES = _IOR(PP_IOCTL, 0x97, 'I') |
| 58 | PPGETPHASE = _IOR(PP_IOCTL, 0x99, 'i') |
| 59 | PPGETTIME = _IOR(PP_IOCTL, 0x95, 'll') |
| 60 | PPNEGOT = _IOW(PP_IOCTL, 0x91, 'i') |
| 61 | PPRCONTROL = _IOR(PP_IOCTL, 0x83, 'B') |
| 62 | PPRDATA = _IOR(PP_IOCTL, 0x85, 'B') |
| 63 | #'OBSOLETE__IOR' undefined in 'PPRECONTROL' |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 64 | PPRELEASE = _IO(PP_IOCTL, 0x8c) |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 65 | #'OBSOLETE__IOR' undefined in 'PPRFIFO' |
| 66 | PPRSTATUS = _IOR(PP_IOCTL, 0x81, 'B') |
| 67 | PPSETFLAGS = _IOW(PP_IOCTL, 0x9b, 'i') |
| 68 | PPSETMODE = _IOW(PP_IOCTL, 0x80, 'i') |
| 69 | PPSETPHASE = _IOW(PP_IOCTL, 0x94, 'i') |
| 70 | PPSETTIME = _IOW(PP_IOCTL, 0x96, 'll') |
| 71 | PPWCONTROL = _IOW(PP_IOCTL, 0x84, 'B') |
| 72 | PPWCTLONIRQ = _IOW(PP_IOCTL, 0x92, 'B') |
| 73 | PPWDATA = _IOW(PP_IOCTL, 0x86, 'B') |
| 74 | #'OBSOLETE__IOW' undefined in 'PPWECONTROL' |
| 75 | #'OBSOLETE__IOW' undefined in 'PPWFIFO' |
| 76 | #'OBSOLETE__IOW' undefined in 'PPWSTATUS' |
| 77 | PPYIELD = _IO(PP_IOCTL, 0x8d) |
| 78 | PP_FASTREAD = 1 << 3 |
| 79 | PP_FASTWRITE = 1 << 2 |
| 80 | PP_W91284PIC = 1 << 4 |
| 81 | PP_FLAGMASK = PP_FASTWRITE | PP_FASTREAD | PP_W91284PIC |
| 82 | PP_MAJOR = 99 |
| 83 | _ASMI386_IOCTL_H= None |
| 84 | _IOC_DIRBITS = 2 |
| 85 | _IOC_DIRMASK = (1 << _IOC_DIRBITS) - 1 |
| 86 | _IOC_NRMASK = (1 << _IOC_NRBITS) - 1 |
| 87 | _IOC_TYPEMASK = (1 << _IOC_TYPEBITS ) - 1 |
| 88 | |
| 89 | def _IOC_DIR(nr): return (nr >> _IOC_DIRSHIFT) & _IOC_DIRMASK |
| 90 | def _IOC_NR(nr): return (nr >> _IOC_NRSHIFT) & _IOC_NRMASK |
| 91 | def _IOC_SIZE(nr): return (nr >> _IOC_SIZESHIFT) & _IOC_SIZEMASK |
| 92 | def _IOC_TYPE(nr): return (nr >> _IOC_TYPESHIFT) & _IOC_TYPEMASK |
| 93 | def _IOWR(type, nr, size): return _IOC(_IOC_READ | _IOC_WRITE, type, nr , sizeof(size)) |
| 94 | |
| 95 | __ELF__ = 1 |
| 96 | __i386 = 1 |
| 97 | __i386__ = 1 |
| 98 | __linux = 1 |
| 99 | __linux__ = 1 |
| 100 | __unix = 1 |
| 101 | __unix__ = 1 |
| 102 | i386 = 1 |
| 103 | linux = 1 |
| 104 | unix = 1 |
| 105 | |
| 106 | #-------- Constants from <linux/parport.h> |
| 107 | |
| 108 | PARPORT_CONTROL_STROBE = 0x1 |
| 109 | PARPORT_CONTROL_AUTOFD = 0x2 |
| 110 | PARPORT_CONTROL_INIT = 0x4 |
| 111 | PARPORT_CONTROL_SELECT = 0x8 |
| 112 | PARPORT_STATUS_ERROR = 8 |
| 113 | PARPORT_STATUS_SELECT = 0x10 |
| 114 | PARPORT_STATUS_PAPEROUT = 0x20 |
| 115 | PARPORT_STATUS_ACK = 0x40 |
| 116 | PARPORT_STATUS_BUSY = 0x80 |
| 117 | |
| 118 | IEEE1284_MODE_NIBBLE = 0 |
| 119 | IEEE1284_MODE_BYTE = 1 |
| 120 | IEEE1284_MODE_COMPAT = 1<<8 |
| 121 | IEEE1284_MODE_BECP = 1<<9 |
| 122 | IEEE1284_MODE_ECP = 1<<4 |
| 123 | IEEE1284_MODE_ECPRLE = IEEE1284_MODE_ECP | (1<<5) |
| 124 | IEEE1284_MODE_ECPSWE = 1<<10 |
| 125 | IEEE1284_MODE_EPP = 1<<6 |
| 126 | IEEE1284_MODE_EPPSL = 1<<11 |
| 127 | IEEE1284_MODE_EPPSWE = 1<<12 |
| 128 | IEEE1284_DEVICEID = 1<<2 |
| 129 | IEEE1284_EXT_LINK = 1<<14 |
| 130 | |
| 131 | IEEE1284_ADDR = 1<<13 |
| 132 | IEEE1284_DATA = 0 |
| 133 | |
| 134 | PARPORT_EPP_FAST = 1 |
| 135 | PARPORT_W91284PIC = 2 |
| 136 | #---- |
| 137 | |
| 138 | class Parallel: |
| 139 | """Class for controlling the pins on a parallel port |
| 140 | |
| 141 | This class provides bit-level access to the pins on a PC parallel |
| 142 | port. It is primarily designed for programs which must control |
| 143 | special circuitry - most often non-IEEE-1284-compliant devices |
| 144 | other than printers - using 'bit-banging' techniques. |
| 145 | |
| 146 | The current implementation makes ioctl() calls to the Linux ppdev |
| 147 | driver, using the Python fcntl library. It might be rewritten in |
| 148 | C for extra speed. This particular implementation is written for |
| 149 | Linux; all of the upper-level calls can be ported to Windows as |
| 150 | well. |
| 151 | |
| 152 | On Linux, the ppdev device driver, from the Linux 2.4 parallel |
| 153 | port subsystem, is used to control the parallel port hardware. |
| 154 | This driver must be made available from a kernel compile. The |
| 155 | option is called "Support user-space parallel-port drivers". When |
| 156 | using the module, be sure to unload the lp module first: usually |
| 157 | the lp module claims exclusive access to the parallel port, and if |
| 158 | it is loaded, this class will fail to open the parallel port file, |
| 159 | and throw an exception. |
| 160 | |
| 161 | The primary source of information about the Linux 2.4 parallel |
| 162 | port subsystem is Tim Waugh's documentation, the source for which |
| 163 | is available in the kernel tree. This document (called, |
| 164 | appropriately enough, "The Linux 2.4 Parallel Port Subsystem"), |
| 165 | thoroughly describes the parallel port drivers and how to use |
| 166 | them. |
| 167 | |
| 168 | This class provides a method for each of the ioctls supported by |
| 169 | the ppdev module. The ioctl methods are named, in uppercase, the |
| 170 | same as the ioctls they invoke. The documentation for these |
| 171 | methods was taken directly from the documentation for their |
| 172 | corresponding ioctl, and modified only where necessary. |
| 173 | |
| 174 | Unless you have special reason to use the Linux ioctls, you should |
| 175 | use instead the upper-level functions, which are named in |
| 176 | lowerCase fashion and should be portable between Linux and |
| 177 | Windows. This way, any code you write for this class will (or |
| 178 | should) also work with the Windows version of this class. |
| 179 | |
| 180 | """ |
| 181 | def __init__(self, port = 0): |
| 182 | if type(port) == type(""): |
| 183 | self.device = port |
| 184 | else: |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 185 | self.device = "/dev/parport%d" % port |
cliechti | 8e778b1 | 2008-06-20 23:11:57 +0000 | [diff] [blame] | 186 | self._fd = None |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 187 | self._fd = os.open(self.device, os.O_RDWR) |
cliechti | 8e778b1 | 2008-06-20 23:11:57 +0000 | [diff] [blame] | 188 | try: |
| 189 | self.PPEXCL() |
| 190 | self.PPCLAIM() |
| 191 | self.setDataDir(1) |
| 192 | self.setData(0) |
| 193 | except IOError: |
| 194 | os.close(self._fd) |
| 195 | self._fd = None |
| 196 | raise |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 197 | |
| 198 | def __del__(self): |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 199 | if self._fd is not None: |
cliechti | 8e778b1 | 2008-06-20 23:11:57 +0000 | [diff] [blame] | 200 | self.PPRELEASE() |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 201 | os.close(self._fd) |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 202 | |
| 203 | def timevalToFloat(self, timeval): |
| 204 | t=struct.unpack('ll', timeval) |
| 205 | return t[0] + (t[1]/1000000.0) |
| 206 | |
| 207 | def floatToTimeval(self, time): |
| 208 | sec = int(time) |
| 209 | usec = int(time*1000000.0) |
| 210 | return struct.pack('ll', sec, usec) |
| 211 | |
| 212 | def PPCLAIM(self): |
| 213 | """ |
| 214 | Claims access to the port. As a user-land device driver |
| 215 | writer, you will need to do this before you are able to |
| 216 | actually change the state of the parallel port in any |
| 217 | way. Note that some operations only affect the ppdev driver |
| 218 | and not the port, such as PPSETMODE; they can be performed |
| 219 | while access to the port is not claimed. |
| 220 | """ |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 221 | fcntl.ioctl(self._fd, PPCLAIM) |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 222 | |
| 223 | def PPEXCL(self): |
| 224 | """ |
| 225 | Instructs the kernel driver to forbid any sharing of the port |
| 226 | with other drivers, i.e. it requests exclusivity. The PPEXCL |
| 227 | command is only valid when the port is not already claimed for |
| 228 | use, and it may mean that the next PPCLAIM ioctl will fail: |
| 229 | some other driver may already have registered itself on that |
| 230 | port. |
| 231 | |
| 232 | Most device drivers don't need exclusive access to the |
| 233 | port. It's only provided in case it is really needed, for |
| 234 | example for devices where access to the port is required for |
| 235 | extensive periods of time (many seconds). |
| 236 | |
| 237 | Note that the PPEXCL ioctl doesn't actually claim the port |
| 238 | there and then---action is deferred until the PPCLAIM ioctl is |
| 239 | performed. |
| 240 | """ |
cliechti | 7d2b78a | 2002-08-07 22:39:54 +0000 | [diff] [blame] | 241 | fcntl.ioctl(self._fd, PPEXCL) |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 242 | |
| 243 | def PPRELEASE(self): |
| 244 | """ |
| 245 | Releases the port. Releasing the port undoes the effect of |
| 246 | claiming the port. It allows other device drivers to talk to |
| 247 | their devices (assuming that there are any). |
| 248 | """ |
| 249 | fcntl.ioctl(self._fd, PPRELEASE) |
| 250 | |
| 251 | def PPYIELD(self): |
| 252 | """ |
| 253 | Yields the port to another driver. This ioctl is a kind of |
| 254 | short-hand for releasing the port and immediately reclaiming |
| 255 | it. It gives other drivers a chance to talk to their devices, |
| 256 | but afterwards claims the port back. An example of using this |
| 257 | would be in a user-land printer driver: once a few characters |
| 258 | have been written we could give the port to another device |
| 259 | driver for a while, but if we still have characters to send to |
| 260 | the printer we would want the port back as soon as possible. |
| 261 | |
| 262 | It is important not to claim the parallel port for too long, |
| 263 | as other device drivers will have no time to service their |
| 264 | devices. If your device does not allow for parallel port |
| 265 | sharing at all, it is better to claim the parallel port |
| 266 | exclusively (see PPEXCL). |
| 267 | """ |
| 268 | fcntl.ioctl(self._fd, PPYIELD) |
| 269 | |
| 270 | def PPNEGOT(self, mode): |
| 271 | """ |
| 272 | Performs IEEE 1284 negotiation into a particular |
| 273 | mode. Briefly, negotiation is the method by which the host and |
| 274 | the peripheral decide on a protocol to use when transferring |
| 275 | data. |
| 276 | |
| 277 | An IEEE 1284 compliant device will start out in compatibility |
| 278 | mode, and then the host can negotiate to another mode (such as |
| 279 | ECP). |
| 280 | |
| 281 | The 'mode' parameter should be one of the following constants |
| 282 | from PPDEV: |
| 283 | |
| 284 | - IEEE1284_MODE_COMPAT |
| 285 | - IEEE1284_MODE_NIBBLE |
| 286 | - IEEE1284_MODE_BYTE |
| 287 | - IEEE1284_MODE_EPP |
| 288 | - IEEE1284_MODE_ECP |
| 289 | |
| 290 | The PPNEGOT ioctl actually does two things: it performs the |
| 291 | on-the-wire negotiation, and it sets the behaviour of |
| 292 | subsequent read/write calls so that they use that mode (but |
| 293 | see PPSETMODE). |
| 294 | """ |
| 295 | fcntl.ioctl(self._fd, PPNEGOT, struct.pack('i', mode)) |
| 296 | |
| 297 | def PPSETMODE(self, mode): |
| 298 | """ |
| 299 | Sets which IEEE 1284 protocol to use for the read and write |
| 300 | calls. |
| 301 | |
| 302 | The 'mode' parameter should be one of the following constants |
| 303 | from PPDEV: |
| 304 | |
| 305 | - IEEE1284_MODE_COMPAT |
| 306 | - IEEE1284_MODE_NIBBLE |
| 307 | - IEEE1284_MODE_BYTE |
| 308 | - IEEE1284_MODE_EPP |
| 309 | - IEEE1284_MODE_ECP |
| 310 | """ |
| 311 | fcntl.ioctl(self._fd, PPSETMODE, struct.pack('i', mode)) |
| 312 | |
| 313 | def PPGETMODE(self): |
| 314 | """ |
| 315 | Retrieves the IEEE 1284 mode being used for read and |
| 316 | write. The return value is one of the following constants |
| 317 | from PPDEV: |
| 318 | |
| 319 | - IEEE1284_MODE_COMPAT |
| 320 | - IEEE1284_MODE_NIBBLE |
| 321 | - IEEE1284_MODE_BYTE |
| 322 | - IEEE1284_MODE_EPP |
| 323 | - IEEE1284_MODE_ECP |
| 324 | """ |
| 325 | ret = struct.pack('i', 0) |
| 326 | ret = fcntl.ioctl(self._fd, PPGETMODE, ret) |
| 327 | return struct.unpack('i', ret)[0] |
| 328 | |
| 329 | def PPGETTIME(self): |
| 330 | """ |
| 331 | Retrieves the time-out value. The read and write calls will |
| 332 | time out if the peripheral doesn't respond quickly enough. The |
| 333 | PPGETTIME ioctl retrieves the length of time that the |
| 334 | peripheral is allowed to have before giving up. |
| 335 | |
| 336 | Returns the timeout value in seconds as a floating-point value. |
| 337 | """ |
| 338 | ret = struct.pack('ll', 0, 0) |
| 339 | ret = fcntl.ioctl(self._fd, PPGETTIME, ret) |
| 340 | return timevalToFloat(ret) |
| 341 | |
| 342 | def PPSETTIME(self, time): |
| 343 | """ |
| 344 | Sets the time-out (see PPGETTIME for more information). |
| 345 | 'time' is the new time-out in seconds; floating-point values |
| 346 | are acceptable. |
| 347 | """ |
| 348 | fcntl.ioctl(self._fd, PPSETTIME, floatToTimeval(time)) |
| 349 | |
| 350 | def PPGETMODES(self): |
| 351 | """ |
| 352 | Retrieves the capabilities of the hardware (i.e. the modes |
| 353 | field of the parport structure). |
| 354 | """ |
| 355 | raise NotImplementedError |
| 356 | |
| 357 | def PPSETFLAGS(self): |
| 358 | """ |
| 359 | Sets flags on the ppdev device which can affect future I/O |
| 360 | operations. Available flags are: |
| 361 | |
| 362 | - PP_FASTWRITE |
| 363 | - PP_FASTREAD |
| 364 | - PP_W91284PIC |
| 365 | """ |
| 366 | raise NotImplementedError |
| 367 | |
| 368 | def PPWCONTROL(self, lines): |
| 369 | """ |
| 370 | Sets the control lines. The 'lines' parameter is a bitwise OR |
| 371 | of the following constants from PPDEV: |
| 372 | |
| 373 | - PARPORT_CONTROL_STROBE |
| 374 | - PARPORT_CONTROL_AUTOFD |
| 375 | - PARPORT_CONTROL_INIT |
| 376 | - PARPORT_CONTROL_SELECT |
| 377 | """ |
| 378 | fcntl.ioctl(self._fd, PPWCONTROL, struct.pack('B', lines)) |
| 379 | |
| 380 | def PPRCONTROL(self): |
| 381 | """ |
| 382 | Returns the last value written to the control register, in the |
| 383 | form of an integer, for which each bit corresponds to a control |
| 384 | line (although some are unused). |
| 385 | |
| 386 | This doesn't actually touch the hardware; the last value |
| 387 | written is remembered in software. This is because some |
| 388 | parallel port hardware does not offer read access to the |
| 389 | control register. |
| 390 | |
| 391 | The control lines bits are defined by the following constants |
| 392 | from PPDEV: |
| 393 | |
| 394 | - PARPORT_CONTROL_STROBE |
| 395 | - PARPORT_CONTROL_AUTOFD |
| 396 | - PARPORT_CONTROL_SELECT |
| 397 | - PARPORT_CONTROL_INIT |
| 398 | """ |
| 399 | ret = struct.pack('B',0) |
| 400 | ret = fcntl.ioctl(self._fd, PPRCONTROL, ret) |
| 401 | return struct.unpack('B', ret)[0] |
| 402 | |
| 403 | def PPFCONTROL(self, mask, val): |
| 404 | """ |
| 405 | Frobs the control lines. Since a common operation is to change |
| 406 | one of the control signals while leaving the others alone, it |
| 407 | would be quite inefficient for the user-land driver to have to |
| 408 | use PPRCONTROL, make the change, and then use PPWCONTROL. Of |
| 409 | course, each driver could remember what state the control |
| 410 | lines are supposed to be in (they are never changed by |
| 411 | anything else), but in order to provide PPRCONTROL, ppdev must |
| 412 | remember the state of the control lines anyway. |
| 413 | |
| 414 | The PPFCONTROL ioctl is for "frobbing" control lines, and is |
| 415 | like PPWCONTROL but acts on a restricted set of control |
| 416 | lines. The ioctl parameter is a pointer to a struct |
| 417 | ppdev_frob_struct: |
| 418 | |
| 419 | struct ppdev_frob_struct { |
| 420 | unsigned char mask; |
| 421 | unsigned char val; |
| 422 | }; |
| 423 | |
| 424 | The mask and val fields are bitwise ORs of control line names |
| 425 | (such as in PPWCONTROL). The operation performed by PPFCONTROL |
| 426 | is: |
| 427 | |
| 428 | new_ctr = (old_ctr & ~mask) | val |
| 429 | |
| 430 | In other words, the signals named in mask are set to the |
| 431 | values in val. |
| 432 | """ |
| 433 | fcntl.ioctl(self._fd, PPFCONTROL, struct.pack('BB', mask, val)) |
| 434 | |
| 435 | def PPRSTATUS(self): |
| 436 | """ |
| 437 | Returns an unsigned char containing bits set for each status |
| 438 | line that is set (for instance, PARPORT_STATUS_BUSY). The |
| 439 | ioctl parameter should be a pointer to an unsigned char. |
| 440 | """ |
| 441 | ret = struct.pack('B',0) |
| 442 | ret = fcntl.ioctl(self._fd, PPRSTATUS, ret) |
| 443 | return struct.unpack('B', ret)[0] |
| 444 | |
| 445 | def PPDATADIR(self, out): |
| 446 | """ |
| 447 | Controls the data line drivers. Normally the computer's |
| 448 | parallel port will drive the data lines, but for byte-wide |
| 449 | transfers from the peripheral to the host it is useful to turn |
| 450 | off those drivers and let the peripheral drive the |
| 451 | signals. (If the drivers on the computer's parallel port are |
| 452 | left on when this happens, the port might be damaged.) |
| 453 | This is only needed in conjunction with PPWDATA or PPRDATA. |
| 454 | |
| 455 | The 'out' parameter indicates the desired port direction. If |
| 456 | 'out' is true or non-zero, the drivers are turned on (forward |
| 457 | direction); otherwise, the drivers are turned off (reverse |
| 458 | direction). |
| 459 | """ |
| 460 | if out: |
| 461 | msg=struct.pack('i',0) |
| 462 | else: |
| 463 | msg=struct.pack('i',1) |
| 464 | fcntl.ioctl(self._fd, PPDATADIR, msg) |
| 465 | |
| 466 | def PPWDATA(self, byte): |
| 467 | """ |
| 468 | Sets the data lines (if in forward mode). The ioctl parameter |
| 469 | is a pointer to an unsigned char. |
| 470 | """ |
| 471 | fcntl.ioctl(self._fd, PPWDATA,struct.pack('B',byte)) |
| 472 | |
| 473 | def PPRDATA(self): |
| 474 | """ |
| 475 | Reads the data lines (if in reverse mode). The ioctl parameter |
| 476 | is a pointer to an unsigned char. |
| 477 | """ |
| 478 | ret=struct.pack('B',0) |
| 479 | ret=fcntl.ioctl(self._fd, PPRDATA,ret) |
| 480 | return struct.unpack('B',ret)[0] |
| 481 | |
| 482 | def PPCLRIRQ(self): |
| 483 | """ |
| 484 | Returns the current interrupt count, and clears it. The ppdev |
| 485 | driver keeps a count of interrupts as they are triggered. |
| 486 | """ |
| 487 | ret=struct.pack('i',0) |
| 488 | ret=fcntl.ioctl(self._fd, PPCLRIRQ,ret) |
| 489 | return struct.unpack('i',ret)[0] |
| 490 | |
| 491 | def PPWCTLONIRQ(self, lines): |
| 492 | """ |
| 493 | Set a trigger response. Afterwards when an interrupt is |
| 494 | triggered, the interrupt handler will set the control lines as |
| 495 | requested. The ioctl parameter is a pointer to an unsigned |
| 496 | char, which is interpreted in the same way as for PPWCONTROL. |
| 497 | |
| 498 | The reason for this ioctl is simply speed. Without this ioctl, |
| 499 | responding to an interrupt would start in the interrupt |
| 500 | handler, switch context to the user-land driver via poll or |
| 501 | select, and then switch context back to the kernel in order to |
| 502 | handle PPWCONTROL. Doing the whole lot in the interrupt |
| 503 | handler is a lot faster. |
| 504 | """ |
| 505 | fcntl.ioctl(self._fd, PPWCTLONIRQ,struct.pack('B',lines)) |
| 506 | |
| 507 | #data lines |
| 508 | ## def data(self): |
| 509 | ## """Returns the states of the data bus line drivers (pins 2-9)""" |
| 510 | ## return self._data |
| 511 | |
| 512 | def setDataDir(self,out): |
| 513 | """Activates or deactivates the data bus line drivers (pins 2-9)""" |
| 514 | self._dataDir = out |
| 515 | self.PPDATADIR(out) |
| 516 | |
| 517 | def dataDir(self): |
| 518 | """Returns true if the data bus line drivers are on (pins 2-9)""" |
| 519 | return self._dataDir |
| 520 | |
| 521 | #control lines |
| 522 | ## def strobe(self): |
| 523 | ## """Returns the state of the nStrobe output (pin 1)""" |
| 524 | ## return (self.PPRCONTROL()&PARPORT_CONTROL_STROBE)==0 |
| 525 | |
| 526 | def setDataStrobe(self, level): |
| 527 | """Sets the state of the nStrobe output (pin 1)""" |
| 528 | if level: |
| 529 | self.PPFCONTROL(PARPORT_CONTROL_STROBE, 0) |
| 530 | else: |
| 531 | self.PPFCONTROL(PARPORT_CONTROL_STROBE, PARPORT_CONTROL_STROBE) |
| 532 | |
| 533 | ## def autoFd(self): |
| 534 | ## """Returns the state of the nAutoFd output (pin 14)""" |
| 535 | ## return (self.PPRCONTROL()&PARPORT_CONTROL_AUTOFD)==0 |
| 536 | |
| 537 | def setAutoFeed(self, level): |
| 538 | """Sets the state of the nAutoFd output (pin 14)""" |
| 539 | if level: |
| 540 | self.PPFCONTROL(PARPORT_CONTROL_AUTOFD, 0) |
| 541 | else: |
| 542 | self.PPFCONTROL(PARPORT_CONTROL_AUTOFD, PARPORT_CONTROL_AUTOFD) |
| 543 | |
| 544 | ## def init(self): |
| 545 | ## """Returns the state of the nInit output (pin 16)""" |
| 546 | ## return (self.PPRCONTROL()&PARPORT_CONTROL_INIT)!=0 |
| 547 | |
| 548 | def setInitOut(self, level): |
| 549 | """Sets the state of the nInit output (pin 16)""" |
| 550 | if level: |
| 551 | self.PPFCONTROL(PARPORT_CONTROL_INIT, PARPORT_CONTROL_INIT) |
| 552 | else: |
| 553 | self.PPFCONTROL(PARPORT_CONTROL_INIT, 0) |
| 554 | |
| 555 | ## def selectIn(self): |
| 556 | ## """Returns the state of the nSelectIn output (pin 17)""" |
| 557 | ## return (self.PPRCONTROL()&PARPORT_CONTROL_SELECT)==0 |
| 558 | |
| 559 | def setSelect(self,level): |
| 560 | """Sets the state of the nSelectIn output (pin 17)""" |
| 561 | if level: |
| 562 | self.PPFCONTROL(PARPORT_CONTROL_SELECT, 0) |
| 563 | else: |
| 564 | self.PPFCONTROL(PARPORT_CONTROL_SELECT, PARPORT_CONTROL_SELECT) |
| 565 | |
| 566 | def setData(self,d): |
| 567 | """Sets the states of the data bus line drivers (pins 2-9)""" |
| 568 | self._data=d |
| 569 | return self.PPWDATA(d) |
cliechti | b58a321 | 2009-07-22 00:30:47 +0000 | [diff] [blame^] | 570 | |
| 571 | def getData(self): |
| 572 | """Gets the states of the data bus line (pin 2-9)""" |
| 573 | return self.PPRDATA() |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 574 | |
cliechti | b58a321 | 2009-07-22 00:30:47 +0000 | [diff] [blame^] | 575 | # status lines |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 576 | def getInError(self): |
| 577 | """Returns the level on the nFault pin (15)""" |
| 578 | return (self.PPRSTATUS() & PARPORT_STATUS_ERROR) != 0 |
| 579 | |
cliechti | e7d23fe | 2003-05-26 19:42:23 +0000 | [diff] [blame] | 580 | def getInSelected(self): |
cliechti | 619e456 | 2002-07-31 00:53:06 +0000 | [diff] [blame] | 581 | """Returns the level on the Select pin (13)""" |
| 582 | return (self.PPRSTATUS() & PARPORT_STATUS_SELECT) != 0 |
| 583 | |
| 584 | def getInPaperOut(self): |
| 585 | """Returns the level on the paperOut pin (12)""" |
| 586 | return (self.PPRSTATUS() & PARPORT_STATUS_PAPEROUT) != 0 |
| 587 | |
| 588 | def getInAcknowledge(self): |
| 589 | """Returns the level on the nAck pin (10)""" |
| 590 | return (self.PPRSTATUS() & PARPORT_STATUS_ACK) != 0 |
| 591 | |
| 592 | def getInBusy(self): |
| 593 | """Returns the level on the Busy pin (11)""" |
| 594 | return (self.PPRSTATUS() & PARPORT_STATUS_BUSY) == 0 |
| 595 | |