--- pyparallel-0.2.orig/setup.py +++ pyparallel-0.2/setup.py @@ -15,6 +15,5 @@ url="http://pyserial.sourceforge.net/", packages=['parallel'], license="Python", - long_description="Python Parallel Port Extension for Win32, Linux, BSD", - package_data = data_files + long_description="Python Parallel Port Extension for Win32, Linux, BSD" ) --- pyparallel-0.2.orig/README.txt +++ pyparallel-0.2/README.txt @@ -51,8 +51,8 @@ Examples -------- Please look in the CVS Repository. There is an example directory where you -can find a simple terminal and more. -http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/pyserial/pyparallel/examples/ +can find a n example module piloting an LCD display through the parallel port. +http://pyserial.svn.sourceforge.net/viewvc/pyserial/trunk/pyparallel/examples/ References ---------- --- pyparallel-0.2.orig/parallel/parallelutil.py +++ pyparallel-0.2/parallel/parallelutil.py @@ -0,0 +1,124 @@ +class BitaccessMeta(type): + """meta class that adds bit access properties to a + parallel port implementation""" + + def __new__(self, classname, bases, classdict): + klass = type.__new__(self, classname, bases, classdict) + # status lines + klass.paperOut = property(klass.getInPaperOut, None, "Read the PaperOut signal") + # control lines + klass.dataStrobe = property(None, klass.setDataStrobe, "Set the DataStrobe signal") + # XXX ... other bits + # data bits + for bit in range(8): + mask = (1<> shift) & mask + def setter(self, b, shift=shift, mask=mask): + self.setData((self.getData() & ~(mask<>4) & 0xf), (x & 0xf))) + # test setting + p._data = 0 + (p.D4_D7, p.D0_D3) = (((x>>4) & 0xf), (x & 0xf)) + self.failUnlessEqual(p._data, x) + + def testStatusbits(self): + """bit by bit status lines""" + # read the property: + self.p._dummy = 0 + self.failUnlessEqual(self.p.paperOut, 0) + + self.p._dummy = 1 + self.failUnlessEqual(self.p.paperOut, 1) + + # read only, must not be writable: + self.failUnlessRaises(AttributeError, setattr, self.p, 'paperOut', 1) + + def testControlbits(self): + """bit by bit control lines""" + self.p.dataStrobe = 0 + self.failUnlessEqual(self.p._last, ('setDataStrobe', 0)) + self.p.dataStrobe = 1 + self.failUnlessEqual(self.p._last, ('setDataStrobe', 1)) + + # write only, must not be writable: + self.failUnlessRaises(AttributeError, getattr, self.p, 'dataStrobe') + + sys.argv.append('-v') + # When this module is executed from the command-line, it runs all its tests + unittest.main() + --- pyparallel-0.2.orig/parallel/parallelwin32.py +++ pyparallel-0.2/parallel/parallelwin32.py @@ -1,130 +1,139 @@ -#pyparallel driver for win32 -#see __init__.py -# -#(C) 2002 Chris Liechti -# this is distributed under a free software license, see license.txt -# -# thanks to Dincer Aydin dinceraydin@altavista.net for his work on the -# winioport module: www.geocities.com/dinceraydin/ the graphic below is -# borrowed form him ;-) - - -# LPT1 = 0x0378 or 0x03BC -# LPT2 = 0x0278 or 0x0378 -# LPT3 = 0x0278 -# -# Data Register (base + 0) ........ outputs -# -# 7 6 5 4 3 2 1 0 -# . . . . . . . * D0 ........... (pin 2), 1=High, 0=Low (true) -# . . . . . . * . D1 ........... (pin 3), 1=High, 0=Low (true) -# . . . . . * . . D2 ........... (pin 4), 1=High, 0=Low (true) -# . . . . * . . . D3 ........... (pin 5), 1=High, 0=Low (true) -# . . . * . . . . D4 ........... (pin 6), 1=High, 0=Low (true) -# . . * . . . . . D5 ........... (pin 7), 1=High, 0=Low (true) -# . * . . . . . . D6 ........... (pin 8), 1=High, 0=Low (true) -# * . . . . . . . D7 ........... (pin 9), 1=High, 0=Low (true) -# -# Status Register (base + 1) ...... inputs -# -# 7 6 5 4 3 2 1 0 -# . . . . . * * * Undefined -# . . . . * . . . Error ........ (pin 15), high=1, low=0 (true) -# . . . * . . . . Selected ..... (pin 13), high=1, low=0 (true) -# . . * . . . . . No paper ..... (pin 12), high=1, low=0 (true) -# . * . . . . . . Ack .......... (pin 10), high=1, low=0 (true) -# * . . . . . . . Busy ......... (pin 11), high=0, low=1 (inverted) -# -# ctrl Register (base + 2) ..... outputs -# -# 7 6 5 4 3 2 1 0 -# . . . . . . . * Strobe ....... (pin 1), 1=low, 0=high (inverted) -# . . . . . . * . Auto Feed .... (pin 14), 1=low, 0=high (inverted) -# . . . . . * . . Initialize ... (pin 16), 1=high,0=low (true) -# . . . . * . . . Select ....... (pin 17), 1=low, 0=high (inverted) -# * * * * . . . . Unused - -LPT1 = 0 -LPT2 = 1 - -LPT1_base = 0x0378 -LPT2_base = 0x0278 - -import ctypes -import os -#need to patch PATH so that the DLL can be found and loaded -os.environ['PATH'] = os.environ['PATH'] + ';' + os.path.abspath(os.path.dirname(__file__)) -#fake module, names of the functions are the same as in the old _pyparallel -#python extension in earlier versions of this modules -_pyparallel = ctypes.windll.simpleio -#need to initialize giveio on WinNT based systems -_pyparallel.init() - - -class Parallel: - def __init__(self, port = LPT1): - if port == LPT1: - self.dataRegAdr = LPT1_base - elif port == LPT2: - self.dataRegAdr = LPT2_base - else: - raise ValueError("No such port available - expecting a number") - self.statusRegAdr = self.dataRegAdr + 1 - self.ctrlRegAdr = self.dataRegAdr + 2 - self.ctrlReg = _pyparallel.inp(self.ctrlRegAdr) - - def setData(self, value): - _pyparallel.outp(self.dataRegAdr, value) - - # control register output functions - def setDataStrobe(self, level): - """data strobe bit""" - if level: - self.ctrlReg = self.ctrlReg & ~0x01 - else: - self.ctrlReg = self.ctrlReg | 0x01 - _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg) - - def setAutoFeed(self, level): - """auto feed bit""" - if level: - self.ctrlReg = self.ctrlReg & ~0x02 - else: - self.ctrlReg = self.ctrlReg | 0x02 - _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg) - - def setInitOut(self, level): - """initialize bit""" - if level: - self.ctrlReg = self.ctrlReg | 0x04 - else: - self.ctrlReg = self.ctrlReg & ~0x04 - _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg) - - def setSelect(self, level): - """select bit""" - if level: - self.ctrlReg = self.ctrlReg & ~0x08 - else: - self.ctrlReg = self.ctrlReg | 0x08 - _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg) - - def getInError(self): - """Error pin""" - return _pyparallel.inp(self.statusRegAdr) & 0x08 and 1 - - def getInSelected(self): - """select pin""" - return _pyparallel.inp(self.statusRegAdr) & 0x10 and 1 - - def getInPaperOut(self): - """paper out pin""" - return _pyparallel.inp(self.statusRegAdr) & 0x20 and 1 - - def getInAcknowledge(self): - """Acknowledge pin""" - return _pyparallel.inp(self.statusRegAdr) & 0x40 and 1 - - def getInBusy(self): - """input from busy pin""" - return not (_pyparallel.inp(self.statusRegAdr) & 0x80) +#pyparallel driver for win32 +#see __init__.py +# +#(C) 2002 Chris Liechti +# this is distributed under a free software license, see license.txt +# +# thanks to Dincer Aydin dinceraydin@altavista.net for his work on the +# winioport module: www.geocities.com/dinceraydin/ the graphic below is +# borrowed form him ;-) + + +# LPT1 = 0x0378 or 0x03BC +# LPT2 = 0x0278 or 0x0378 +# LPT3 = 0x0278 +# +# Data Register (base + 0) ........ outputs +# +# 7 6 5 4 3 2 1 0 +# . . . . . . . * D0 ........... (pin 2), 1=High, 0=Low (true) +# . . . . . . * . D1 ........... (pin 3), 1=High, 0=Low (true) +# . . . . . * . . D2 ........... (pin 4), 1=High, 0=Low (true) +# . . . . * . . . D3 ........... (pin 5), 1=High, 0=Low (true) +# . . . * . . . . D4 ........... (pin 6), 1=High, 0=Low (true) +# . . * . . . . . D5 ........... (pin 7), 1=High, 0=Low (true) +# . * . . . . . . D6 ........... (pin 8), 1=High, 0=Low (true) +# * . . . . . . . D7 ........... (pin 9), 1=High, 0=Low (true) +# +# Status Register (base + 1) ...... inputs +# +# 7 6 5 4 3 2 1 0 +# . . . . . * * * Undefined +# . . . . * . . . Error ........ (pin 15), high=1, low=0 (true) +# . . . * . . . . Selected ..... (pin 13), high=1, low=0 (true) +# . . * . . . . . No paper ..... (pin 12), high=1, low=0 (true) +# . * . . . . . . Ack .......... (pin 10), high=1, low=0 (true) +# * . . . . . . . Busy ......... (pin 11), high=0, low=1 (inverted) +# +# ctrl Register (base + 2) ..... outputs +# +# 7 6 5 4 3 2 1 0 +# . . . . . . . * Strobe ....... (pin 1), 1=low, 0=high (inverted) +# . . . . . . * . Auto Feed .... (pin 14), 1=low, 0=high (inverted) +# . . . . . * . . Initialize ... (pin 16), 1=high,0=low (true) +# . . . . * . . . Select ....... (pin 17), 1=low, 0=high (inverted) +# * * * * . . . . Unused + +LPT1 = 0 +LPT2 = 1 + +LPT1_base = 0x0378 +LPT2_base = 0x0278 + +import ctypes +import os +#need to patch PATH so that the DLL can be found and loaded +os.environ['PATH'] = os.environ['PATH'] + ';' + os.path.abspath(os.path.dirname(__file__)) +#fake module, names of the functions are the same as in the old _pyparallel +#python extension in earlier versions of this modules +_pyparallel = ctypes.windll.simpleio +#need to initialize giveio on WinNT based systems +if _pyparallel.init(): + raise IOError('Could not access the giveio driver which is required on NT based systems.') + + +class Parallel: + def __init__(self, port = LPT1): + if port == LPT1: + self.dataRegAdr = LPT1_base + elif port == LPT2: + self.dataRegAdr = LPT2_base + else: + raise ValueError("No such port available - expecting a number") + self.statusRegAdr = self.dataRegAdr + 1 + self.ctrlRegAdr = self.dataRegAdr + 2 + self.ctrlReg = _pyparallel.inp(self.ctrlRegAdr) + + def setData(self, value): + _pyparallel.outp(self.dataRegAdr, value) + + def setDataDir( self, level): + """set for port as input, clear for output""" + if level: + self.ctrlReg |= 0x20 + else: + self.ctrlReg &= ~0x20 + _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg) + + # control register output functions + def setDataStrobe(self, level): + """data strobe bit""" + if level: + self.ctrlReg = self.ctrlReg & ~0x01 + else: + self.ctrlReg = self.ctrlReg | 0x01 + _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg) + + def setAutoFeed(self, level): + """auto feed bit""" + if level: + self.ctrlReg = self.ctrlReg & ~0x02 + else: + self.ctrlReg = self.ctrlReg | 0x02 + _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg) + + def setInitOut(self, level): + """initialize bit""" + if level: + self.ctrlReg = self.ctrlReg | 0x04 + else: + self.ctrlReg = self.ctrlReg & ~0x04 + _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg) + + def setSelect(self, level): + """select bit""" + if level: + self.ctrlReg = self.ctrlReg & ~0x08 + else: + self.ctrlReg = self.ctrlReg | 0x08 + _pyparallel.outp(self.ctrlRegAdr, self.ctrlReg) + + def getInError(self): + """Error pin""" + return _pyparallel.inp(self.statusRegAdr) & 0x08 and 1 + + def getInSelected(self): + """select pin""" + return _pyparallel.inp(self.statusRegAdr) & 0x10 and 1 + + def getInPaperOut(self): + """paper out pin""" + return _pyparallel.inp(self.statusRegAdr) & 0x20 and 1 + + def getInAcknowledge(self): + """Acknowledge pin""" + return _pyparallel.inp(self.statusRegAdr) & 0x40 and 1 + + def getInBusy(self): + """input from busy pin""" + return not (_pyparallel.inp(self.statusRegAdr) & 0x80) --- pyparallel-0.2.orig/parallel/parallelppdev.py +++ pyparallel-0.2/parallel/parallelppdev.py @@ -1,585 +1,595 @@ -#!/usr/bin/env python -# parallel port access using the ppdev driver - -import sys -import struct -import fcntl -import os - -#---- -# Generated by h2py 0.1.1 from , -# then cleaned up a bit by Michael P. Ashton and then a gain by chris ;-) -# Changes for Python2.2 support (c) September 2004 Alex.Perry@qm.com - - -def sizeof(type): return struct.calcsize(type) -def _IOC(dir, type, nr, size): return int((dir << _IOC_DIRSHIFT ) | (type << _IOC_TYPESHIFT ) |\ - (nr << _IOC_NRSHIFT ) | (size << _IOC_SIZESHIFT)) -def _IO(type, nr): return _IOC(_IOC_NONE, type, nr, 0) -def _IOR(type,nr,size): return _IOC(_IOC_READ, type, nr, sizeof(size)) -def _IOW(type,nr,size): return _IOC(_IOC_WRITE, type, nr, sizeof(size)) - -_IOC_SIZEBITS = 14 -_IOC_SIZEMASK = (1L << _IOC_SIZEBITS ) - 1 -_IOC_NRSHIFT = 0 -_IOC_NRBITS = 8 -_IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS -_IOC_TYPEBITS = 8 -_IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS -IOCSIZE_MASK = _IOC_SIZEMASK << _IOC_SIZESHIFT -IOCSIZE_SHIFT = _IOC_SIZESHIFT - -# Python 2.2 uses a signed int for the ioctl() call, so ... -if ( sys.version_info[0] < 3 ) or ( sys.version_info[1] < 3 ): - _IOC_WRITE = 1L - _IOC_READ = -2L - _IOC_INOUT = -1L -else: - _IOC_WRITE = 1L - _IOC_READ = 2L - _IOC_INOUT = 3L - -_IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS -IOC_INOUT = _IOC_INOUT << _IOC_DIRSHIFT -IOC_IN = _IOC_WRITE << _IOC_DIRSHIFT -IOC_OUT = _IOC_READ << _IOC_DIRSHIFT - -_IOC_NONE = 0 -PP_IOCTL = ord('p') -PPCLAIM = _IO(PP_IOCTL, 0x8b) -PPCLRIRQ = _IOR(PP_IOCTL, 0x93, 'i') - -PPDATADIR = _IOW(PP_IOCTL, 0x90, 'i') -PPEXCL = _IO(PP_IOCTL, 0x8f) -PPFCONTROL = _IOW(PP_IOCTL, 0x8e, 'BB') -PPGETFLAGS = _IOR(PP_IOCTL, 0x9a, 'i') -PPGETMODE = _IOR(PP_IOCTL, 0x98, 'i') -PPGETMODES = _IOR(PP_IOCTL, 0x97, 'I') -PPGETPHASE = _IOR(PP_IOCTL, 0x99, 'i') -PPGETTIME = _IOR(PP_IOCTL, 0x95, 'll') -PPNEGOT = _IOW(PP_IOCTL, 0x91, 'i') -PPRCONTROL = _IOR(PP_IOCTL, 0x83, 'B') -PPRDATA = _IOR(PP_IOCTL, 0x85, 'B') -#'OBSOLETE__IOR' undefined in 'PPRECONTROL' -PPRELEASE = _IO(PP_IOCTL, 0x8c) -#'OBSOLETE__IOR' undefined in 'PPRFIFO' -PPRSTATUS = _IOR(PP_IOCTL, 0x81, 'B') -PPSETFLAGS = _IOW(PP_IOCTL, 0x9b, 'i') -PPSETMODE = _IOW(PP_IOCTL, 0x80, 'i') -PPSETPHASE = _IOW(PP_IOCTL, 0x94, 'i') -PPSETTIME = _IOW(PP_IOCTL, 0x96, 'll') -PPWCONTROL = _IOW(PP_IOCTL, 0x84, 'B') -PPWCTLONIRQ = _IOW(PP_IOCTL, 0x92, 'B') -PPWDATA = _IOW(PP_IOCTL, 0x86, 'B') -#'OBSOLETE__IOW' undefined in 'PPWECONTROL' -#'OBSOLETE__IOW' undefined in 'PPWFIFO' -#'OBSOLETE__IOW' undefined in 'PPWSTATUS' -PPYIELD = _IO(PP_IOCTL, 0x8d) -PP_FASTREAD = 1 << 3 -PP_FASTWRITE = 1 << 2 -PP_W91284PIC = 1 << 4 -PP_FLAGMASK = PP_FASTWRITE | PP_FASTREAD | PP_W91284PIC -PP_MAJOR = 99 -_ASMI386_IOCTL_H= None -_IOC_DIRBITS = 2 -_IOC_DIRMASK = (1 << _IOC_DIRBITS) - 1 -_IOC_NRMASK = (1 << _IOC_NRBITS) - 1 -_IOC_TYPEMASK = (1 << _IOC_TYPEBITS ) - 1 - -def _IOC_DIR(nr): return (nr >> _IOC_DIRSHIFT) & _IOC_DIRMASK -def _IOC_NR(nr): return (nr >> _IOC_NRSHIFT) & _IOC_NRMASK -def _IOC_SIZE(nr): return (nr >> _IOC_SIZESHIFT) & _IOC_SIZEMASK -def _IOC_TYPE(nr): return (nr >> _IOC_TYPESHIFT) & _IOC_TYPEMASK -def _IOWR(type, nr, size): return _IOC(_IOC_READ | _IOC_WRITE, type, nr , sizeof(size)) - -__ELF__ = 1 -__i386 = 1 -__i386__ = 1 -__linux = 1 -__linux__ = 1 -__unix = 1 -__unix__ = 1 -i386 = 1 -linux = 1 -unix = 1 - -#-------- Constants from - -PARPORT_CONTROL_STROBE = 0x1 -PARPORT_CONTROL_AUTOFD = 0x2 -PARPORT_CONTROL_INIT = 0x4 -PARPORT_CONTROL_SELECT = 0x8 -PARPORT_STATUS_ERROR = 8 -PARPORT_STATUS_SELECT = 0x10 -PARPORT_STATUS_PAPEROUT = 0x20 -PARPORT_STATUS_ACK = 0x40 -PARPORT_STATUS_BUSY = 0x80 - -IEEE1284_MODE_NIBBLE = 0 -IEEE1284_MODE_BYTE = 1 -IEEE1284_MODE_COMPAT = 1<<8 -IEEE1284_MODE_BECP = 1<<9 -IEEE1284_MODE_ECP = 1<<4 -IEEE1284_MODE_ECPRLE = IEEE1284_MODE_ECP | (1<<5) -IEEE1284_MODE_ECPSWE = 1<<10 -IEEE1284_MODE_EPP = 1<<6 -IEEE1284_MODE_EPPSL = 1<<11 -IEEE1284_MODE_EPPSWE = 1<<12 -IEEE1284_DEVICEID = 1<<2 -IEEE1284_EXT_LINK = 1<<14 - -IEEE1284_ADDR = 1<<13 -IEEE1284_DATA = 0 - -PARPORT_EPP_FAST = 1 -PARPORT_W91284PIC = 2 -#---- - -class Parallel: - """Class for controlling the pins on a parallel port - - This class provides bit-level access to the pins on a PC parallel - port. It is primarily designed for programs which must control - special circuitry - most often non-IEEE-1284-compliant devices - other than printers - using 'bit-banging' techniques. - - The current implementation makes ioctl() calls to the Linux ppdev - driver, using the Python fcntl library. It might be rewritten in - C for extra speed. This particular implementation is written for - Linux; all of the upper-level calls can be ported to Windows as - well. - - On Linux, the ppdev device driver, from the Linux 2.4 parallel - port subsystem, is used to control the parallel port hardware. - This driver must be made available from a kernel compile. The - option is called "Support user-space parallel-port drivers". When - using the module, be sure to unload the lp module first: usually - the lp module claims exclusive access to the parallel port, and if - it is loaded, this class will fail to open the parallel port file, - and throw an exception. - - The primary source of information about the Linux 2.4 parallel - port subsystem is Tim Waugh's documentation, the source for which - is available in the kernel tree. This document (called, - appropriately enough, "The Linux 2.4 Parallel Port Subsystem"), - thoroughly describes the parallel port drivers and how to use - them. - - This class provides a method for each of the ioctls supported by - the ppdev module. The ioctl methods are named, in uppercase, the - same as the ioctls they invoke. The documentation for these - methods was taken directly from the documentation for their - corresponding ioctl, and modified only where necessary. - - Unless you have special reason to use the Linux ioctls, you should - use instead the upper-level functions, which are named in - lowerCase fashion and should be portable between Linux and - Windows. This way, any code you write for this class will (or - should) also work with the Windows version of this class. - - """ - def __init__(self, port = 0): - if type(port) == type(""): - self.device = port - else: - self.device = "/dev/parport%d" % port - self._fd = os.open(self.device, os.O_RDWR) - self.PPEXCL() - self.PPCLAIM() - self.setDataDir(1) - self.setData(0) - - def __del__(self): - self.PPRELEASE() - if self._fd is not None: - os.close(self._fd) - - def timevalToFloat(self, timeval): - t=struct.unpack('ll', timeval) - return t[0] + (t[1]/1000000.0) - - def floatToTimeval(self, time): - sec = int(time) - usec = int(time*1000000.0) - return struct.pack('ll', sec, usec) - - def PPCLAIM(self): - """ - Claims access to the port. As a user-land device driver - writer, you will need to do this before you are able to - actually change the state of the parallel port in any - way. Note that some operations only affect the ppdev driver - and not the port, such as PPSETMODE; they can be performed - while access to the port is not claimed. - """ - fcntl.ioctl(self._fd, PPCLAIM) - - def PPEXCL(self): - """ - Instructs the kernel driver to forbid any sharing of the port - with other drivers, i.e. it requests exclusivity. The PPEXCL - command is only valid when the port is not already claimed for - use, and it may mean that the next PPCLAIM ioctl will fail: - some other driver may already have registered itself on that - port. - - Most device drivers don't need exclusive access to the - port. It's only provided in case it is really needed, for - example for devices where access to the port is required for - extensive periods of time (many seconds). - - Note that the PPEXCL ioctl doesn't actually claim the port - there and then---action is deferred until the PPCLAIM ioctl is - performed. - """ - fcntl.ioctl(self._fd, PPEXCL) - - def PPRELEASE(self): - """ - Releases the port. Releasing the port undoes the effect of - claiming the port. It allows other device drivers to talk to - their devices (assuming that there are any). - """ - fcntl.ioctl(self._fd, PPRELEASE) - - def PPYIELD(self): - """ - Yields the port to another driver. This ioctl is a kind of - short-hand for releasing the port and immediately reclaiming - it. It gives other drivers a chance to talk to their devices, - but afterwards claims the port back. An example of using this - would be in a user-land printer driver: once a few characters - have been written we could give the port to another device - driver for a while, but if we still have characters to send to - the printer we would want the port back as soon as possible. - - It is important not to claim the parallel port for too long, - as other device drivers will have no time to service their - devices. If your device does not allow for parallel port - sharing at all, it is better to claim the parallel port - exclusively (see PPEXCL). - """ - fcntl.ioctl(self._fd, PPYIELD) - - def PPNEGOT(self, mode): - """ - Performs IEEE 1284 negotiation into a particular - mode. Briefly, negotiation is the method by which the host and - the peripheral decide on a protocol to use when transferring - data. - - An IEEE 1284 compliant device will start out in compatibility - mode, and then the host can negotiate to another mode (such as - ECP). - - The 'mode' parameter should be one of the following constants - from PPDEV: - - - IEEE1284_MODE_COMPAT - - IEEE1284_MODE_NIBBLE - - IEEE1284_MODE_BYTE - - IEEE1284_MODE_EPP - - IEEE1284_MODE_ECP - - The PPNEGOT ioctl actually does two things: it performs the - on-the-wire negotiation, and it sets the behaviour of - subsequent read/write calls so that they use that mode (but - see PPSETMODE). - """ - fcntl.ioctl(self._fd, PPNEGOT, struct.pack('i', mode)) - - def PPSETMODE(self, mode): - """ - Sets which IEEE 1284 protocol to use for the read and write - calls. - - The 'mode' parameter should be one of the following constants - from PPDEV: - - - IEEE1284_MODE_COMPAT - - IEEE1284_MODE_NIBBLE - - IEEE1284_MODE_BYTE - - IEEE1284_MODE_EPP - - IEEE1284_MODE_ECP - """ - fcntl.ioctl(self._fd, PPSETMODE, struct.pack('i', mode)) - - def PPGETMODE(self): - """ - Retrieves the IEEE 1284 mode being used for read and - write. The return value is one of the following constants - from PPDEV: - - - IEEE1284_MODE_COMPAT - - IEEE1284_MODE_NIBBLE - - IEEE1284_MODE_BYTE - - IEEE1284_MODE_EPP - - IEEE1284_MODE_ECP - """ - ret = struct.pack('i', 0) - ret = fcntl.ioctl(self._fd, PPGETMODE, ret) - return struct.unpack('i', ret)[0] - - def PPGETTIME(self): - """ - Retrieves the time-out value. The read and write calls will - time out if the peripheral doesn't respond quickly enough. The - PPGETTIME ioctl retrieves the length of time that the - peripheral is allowed to have before giving up. - - Returns the timeout value in seconds as a floating-point value. - """ - ret = struct.pack('ll', 0, 0) - ret = fcntl.ioctl(self._fd, PPGETTIME, ret) - return timevalToFloat(ret) - - def PPSETTIME(self, time): - """ - Sets the time-out (see PPGETTIME for more information). - 'time' is the new time-out in seconds; floating-point values - are acceptable. - """ - fcntl.ioctl(self._fd, PPSETTIME, floatToTimeval(time)) - - def PPGETMODES(self): - """ - Retrieves the capabilities of the hardware (i.e. the modes - field of the parport structure). - """ - raise NotImplementedError - - def PPSETFLAGS(self): - """ - Sets flags on the ppdev device which can affect future I/O - operations. Available flags are: - - - PP_FASTWRITE - - PP_FASTREAD - - PP_W91284PIC - """ - raise NotImplementedError - - def PPWCONTROL(self, lines): - """ - Sets the control lines. The 'lines' parameter is a bitwise OR - of the following constants from PPDEV: - - - PARPORT_CONTROL_STROBE - - PARPORT_CONTROL_AUTOFD - - PARPORT_CONTROL_INIT - - PARPORT_CONTROL_SELECT - """ - fcntl.ioctl(self._fd, PPWCONTROL, struct.pack('B', lines)) - - def PPRCONTROL(self): - """ - Returns the last value written to the control register, in the - form of an integer, for which each bit corresponds to a control - line (although some are unused). - - This doesn't actually touch the hardware; the last value - written is remembered in software. This is because some - parallel port hardware does not offer read access to the - control register. - - The control lines bits are defined by the following constants - from PPDEV: - - - PARPORT_CONTROL_STROBE - - PARPORT_CONTROL_AUTOFD - - PARPORT_CONTROL_SELECT - - PARPORT_CONTROL_INIT - """ - ret = struct.pack('B',0) - ret = fcntl.ioctl(self._fd, PPRCONTROL, ret) - return struct.unpack('B', ret)[0] - - def PPFCONTROL(self, mask, val): - """ - Frobs the control lines. Since a common operation is to change - one of the control signals while leaving the others alone, it - would be quite inefficient for the user-land driver to have to - use PPRCONTROL, make the change, and then use PPWCONTROL. Of - course, each driver could remember what state the control - lines are supposed to be in (they are never changed by - anything else), but in order to provide PPRCONTROL, ppdev must - remember the state of the control lines anyway. - - The PPFCONTROL ioctl is for "frobbing" control lines, and is - like PPWCONTROL but acts on a restricted set of control - lines. The ioctl parameter is a pointer to a struct - ppdev_frob_struct: - - struct ppdev_frob_struct { - unsigned char mask; - unsigned char val; - }; - - The mask and val fields are bitwise ORs of control line names - (such as in PPWCONTROL). The operation performed by PPFCONTROL - is: - - new_ctr = (old_ctr & ~mask) | val - - In other words, the signals named in mask are set to the - values in val. - """ - fcntl.ioctl(self._fd, PPFCONTROL, struct.pack('BB', mask, val)) - - def PPRSTATUS(self): - """ - Returns an unsigned char containing bits set for each status - line that is set (for instance, PARPORT_STATUS_BUSY). The - ioctl parameter should be a pointer to an unsigned char. - """ - ret = struct.pack('B',0) - ret = fcntl.ioctl(self._fd, PPRSTATUS, ret) - return struct.unpack('B', ret)[0] - - def PPDATADIR(self, out): - """ - Controls the data line drivers. Normally the computer's - parallel port will drive the data lines, but for byte-wide - transfers from the peripheral to the host it is useful to turn - off those drivers and let the peripheral drive the - signals. (If the drivers on the computer's parallel port are - left on when this happens, the port might be damaged.) - This is only needed in conjunction with PPWDATA or PPRDATA. - - The 'out' parameter indicates the desired port direction. If - 'out' is true or non-zero, the drivers are turned on (forward - direction); otherwise, the drivers are turned off (reverse - direction). - """ - if out: - msg=struct.pack('i',0) - else: - msg=struct.pack('i',1) - fcntl.ioctl(self._fd, PPDATADIR, msg) - - def PPWDATA(self, byte): - """ - Sets the data lines (if in forward mode). The ioctl parameter - is a pointer to an unsigned char. - """ - fcntl.ioctl(self._fd, PPWDATA,struct.pack('B',byte)) - - def PPRDATA(self): - """ - Reads the data lines (if in reverse mode). The ioctl parameter - is a pointer to an unsigned char. - """ - ret=struct.pack('B',0) - ret=fcntl.ioctl(self._fd, PPRDATA,ret) - return struct.unpack('B',ret)[0] - - def PPCLRIRQ(self): - """ - Returns the current interrupt count, and clears it. The ppdev - driver keeps a count of interrupts as they are triggered. - """ - ret=struct.pack('i',0) - ret=fcntl.ioctl(self._fd, PPCLRIRQ,ret) - return struct.unpack('i',ret)[0] - - def PPWCTLONIRQ(self, lines): - """ - Set a trigger response. Afterwards when an interrupt is - triggered, the interrupt handler will set the control lines as - requested. The ioctl parameter is a pointer to an unsigned - char, which is interpreted in the same way as for PPWCONTROL. - - The reason for this ioctl is simply speed. Without this ioctl, - responding to an interrupt would start in the interrupt - handler, switch context to the user-land driver via poll or - select, and then switch context back to the kernel in order to - handle PPWCONTROL. Doing the whole lot in the interrupt - handler is a lot faster. - """ - fcntl.ioctl(self._fd, PPWCTLONIRQ,struct.pack('B',lines)) - - #data lines -## def data(self): -## """Returns the states of the data bus line drivers (pins 2-9)""" -## return self._data - - def setDataDir(self,out): - """Activates or deactivates the data bus line drivers (pins 2-9)""" - self._dataDir = out - self.PPDATADIR(out) - - def dataDir(self): - """Returns true if the data bus line drivers are on (pins 2-9)""" - return self._dataDir - - #control lines -## def strobe(self): -## """Returns the state of the nStrobe output (pin 1)""" -## return (self.PPRCONTROL()&PARPORT_CONTROL_STROBE)==0 - - def setDataStrobe(self, level): - """Sets the state of the nStrobe output (pin 1)""" - if level: - self.PPFCONTROL(PARPORT_CONTROL_STROBE, 0) - else: - self.PPFCONTROL(PARPORT_CONTROL_STROBE, PARPORT_CONTROL_STROBE) - -## def autoFd(self): -## """Returns the state of the nAutoFd output (pin 14)""" -## return (self.PPRCONTROL()&PARPORT_CONTROL_AUTOFD)==0 - - def setAutoFeed(self, level): - """Sets the state of the nAutoFd output (pin 14)""" - if level: - self.PPFCONTROL(PARPORT_CONTROL_AUTOFD, 0) - else: - self.PPFCONTROL(PARPORT_CONTROL_AUTOFD, PARPORT_CONTROL_AUTOFD) - -## def init(self): -## """Returns the state of the nInit output (pin 16)""" -## return (self.PPRCONTROL()&PARPORT_CONTROL_INIT)!=0 - - def setInitOut(self, level): - """Sets the state of the nInit output (pin 16)""" - if level: - self.PPFCONTROL(PARPORT_CONTROL_INIT, PARPORT_CONTROL_INIT) - else: - self.PPFCONTROL(PARPORT_CONTROL_INIT, 0) - -## def selectIn(self): -## """Returns the state of the nSelectIn output (pin 17)""" -## return (self.PPRCONTROL()&PARPORT_CONTROL_SELECT)==0 - - def setSelect(self,level): - """Sets the state of the nSelectIn output (pin 17)""" - if level: - self.PPFCONTROL(PARPORT_CONTROL_SELECT, 0) - else: - self.PPFCONTROL(PARPORT_CONTROL_SELECT, PARPORT_CONTROL_SELECT) - - def setData(self,d): - """Sets the states of the data bus line drivers (pins 2-9)""" - self._data=d - return self.PPWDATA(d) - - #status lines - def getInError(self): - """Returns the level on the nFault pin (15)""" - return (self.PPRSTATUS() & PARPORT_STATUS_ERROR) != 0 - - def getInSelected(self): - """Returns the level on the Select pin (13)""" - return (self.PPRSTATUS() & PARPORT_STATUS_SELECT) != 0 - - def getInPaperOut(self): - """Returns the level on the paperOut pin (12)""" - return (self.PPRSTATUS() & PARPORT_STATUS_PAPEROUT) != 0 - - def getInAcknowledge(self): - """Returns the level on the nAck pin (10)""" - return (self.PPRSTATUS() & PARPORT_STATUS_ACK) != 0 - - def getInBusy(self): - """Returns the level on the Busy pin (11)""" - return (self.PPRSTATUS() & PARPORT_STATUS_BUSY) == 0 - +#!/usr/bin/env python +# parallel port access using the ppdev driver + +import sys +import struct +import fcntl +import os + +#---- +# Generated by h2py 0.1.1 from , +# then cleaned up a bit by Michael P. Ashton and then a gain by chris ;-) +# Changes for Python2.2 support (c) September 2004 Alex.Perry@qm.com + + +def sizeof(type): return struct.calcsize(type) +def _IOC(dir, type, nr, size): return int((dir << _IOC_DIRSHIFT ) | (type << _IOC_TYPESHIFT ) |\ + (nr << _IOC_NRSHIFT ) | (size << _IOC_SIZESHIFT)) +def _IO(type, nr): return _IOC(_IOC_NONE, type, nr, 0) +def _IOR(type,nr,size): return _IOC(_IOC_READ, type, nr, sizeof(size)) +def _IOW(type,nr,size): return _IOC(_IOC_WRITE, type, nr, sizeof(size)) + +_IOC_SIZEBITS = 14 +_IOC_SIZEMASK = (1 << _IOC_SIZEBITS ) - 1 +_IOC_NRSHIFT = 0 +_IOC_NRBITS = 8 +_IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS +_IOC_TYPEBITS = 8 +_IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS +IOCSIZE_MASK = _IOC_SIZEMASK << _IOC_SIZESHIFT +IOCSIZE_SHIFT = _IOC_SIZESHIFT + +# Python 2.2 uses a signed int for the ioctl() call, so ... +if ( sys.version_info[0] < 3 ) or ( sys.version_info[1] < 3 ): + _IOC_WRITE = 1 + _IOC_READ = -2 + _IOC_INOUT = -1 +else: + _IOC_WRITE = 1 + _IOC_READ = 2 + _IOC_INOUT = 3 + +_IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS +IOC_INOUT = _IOC_INOUT << _IOC_DIRSHIFT +IOC_IN = _IOC_WRITE << _IOC_DIRSHIFT +IOC_OUT = _IOC_READ << _IOC_DIRSHIFT + +_IOC_NONE = 0 +PP_IOCTL = ord('p') +PPCLAIM = _IO(PP_IOCTL, 0x8b) +PPCLRIRQ = _IOR(PP_IOCTL, 0x93, 'i') + +PPDATADIR = _IOW(PP_IOCTL, 0x90, 'i') +PPEXCL = _IO(PP_IOCTL, 0x8f) +PPFCONTROL = _IOW(PP_IOCTL, 0x8e, 'BB') +PPGETFLAGS = _IOR(PP_IOCTL, 0x9a, 'i') +PPGETMODE = _IOR(PP_IOCTL, 0x98, 'i') +PPGETMODES = _IOR(PP_IOCTL, 0x97, 'I') +PPGETPHASE = _IOR(PP_IOCTL, 0x99, 'i') +PPGETTIME = _IOR(PP_IOCTL, 0x95, 'll') +PPNEGOT = _IOW(PP_IOCTL, 0x91, 'i') +PPRCONTROL = _IOR(PP_IOCTL, 0x83, 'B') +PPRDATA = _IOR(PP_IOCTL, 0x85, 'B') +#'OBSOLETE__IOR' undefined in 'PPRECONTROL' +PPRELEASE = _IO(PP_IOCTL, 0x8c) +#'OBSOLETE__IOR' undefined in 'PPRFIFO' +PPRSTATUS = _IOR(PP_IOCTL, 0x81, 'B') +PPSETFLAGS = _IOW(PP_IOCTL, 0x9b, 'i') +PPSETMODE = _IOW(PP_IOCTL, 0x80, 'i') +PPSETPHASE = _IOW(PP_IOCTL, 0x94, 'i') +PPSETTIME = _IOW(PP_IOCTL, 0x96, 'll') +PPWCONTROL = _IOW(PP_IOCTL, 0x84, 'B') +PPWCTLONIRQ = _IOW(PP_IOCTL, 0x92, 'B') +PPWDATA = _IOW(PP_IOCTL, 0x86, 'B') +#'OBSOLETE__IOW' undefined in 'PPWECONTROL' +#'OBSOLETE__IOW' undefined in 'PPWFIFO' +#'OBSOLETE__IOW' undefined in 'PPWSTATUS' +PPYIELD = _IO(PP_IOCTL, 0x8d) +PP_FASTREAD = 1 << 3 +PP_FASTWRITE = 1 << 2 +PP_W91284PIC = 1 << 4 +PP_FLAGMASK = PP_FASTWRITE | PP_FASTREAD | PP_W91284PIC +PP_MAJOR = 99 +_ASMI386_IOCTL_H= None +_IOC_DIRBITS = 2 +_IOC_DIRMASK = (1 << _IOC_DIRBITS) - 1 +_IOC_NRMASK = (1 << _IOC_NRBITS) - 1 +_IOC_TYPEMASK = (1 << _IOC_TYPEBITS ) - 1 + +def _IOC_DIR(nr): return (nr >> _IOC_DIRSHIFT) & _IOC_DIRMASK +def _IOC_NR(nr): return (nr >> _IOC_NRSHIFT) & _IOC_NRMASK +def _IOC_SIZE(nr): return (nr >> _IOC_SIZESHIFT) & _IOC_SIZEMASK +def _IOC_TYPE(nr): return (nr >> _IOC_TYPESHIFT) & _IOC_TYPEMASK +def _IOWR(type, nr, size): return _IOC(_IOC_READ | _IOC_WRITE, type, nr , sizeof(size)) + +__ELF__ = 1 +__i386 = 1 +__i386__ = 1 +__linux = 1 +__linux__ = 1 +__unix = 1 +__unix__ = 1 +i386 = 1 +linux = 1 +unix = 1 + +#-------- Constants from + +PARPORT_CONTROL_STROBE = 0x1 +PARPORT_CONTROL_AUTOFD = 0x2 +PARPORT_CONTROL_INIT = 0x4 +PARPORT_CONTROL_SELECT = 0x8 +PARPORT_STATUS_ERROR = 8 +PARPORT_STATUS_SELECT = 0x10 +PARPORT_STATUS_PAPEROUT = 0x20 +PARPORT_STATUS_ACK = 0x40 +PARPORT_STATUS_BUSY = 0x80 + +IEEE1284_MODE_NIBBLE = 0 +IEEE1284_MODE_BYTE = 1 +IEEE1284_MODE_COMPAT = 1<<8 +IEEE1284_MODE_BECP = 1<<9 +IEEE1284_MODE_ECP = 1<<4 +IEEE1284_MODE_ECPRLE = IEEE1284_MODE_ECP | (1<<5) +IEEE1284_MODE_ECPSWE = 1<<10 +IEEE1284_MODE_EPP = 1<<6 +IEEE1284_MODE_EPPSL = 1<<11 +IEEE1284_MODE_EPPSWE = 1<<12 +IEEE1284_DEVICEID = 1<<2 +IEEE1284_EXT_LINK = 1<<14 + +IEEE1284_ADDR = 1<<13 +IEEE1284_DATA = 0 + +PARPORT_EPP_FAST = 1 +PARPORT_W91284PIC = 2 +#---- + +class Parallel: + """Class for controlling the pins on a parallel port + + This class provides bit-level access to the pins on a PC parallel + port. It is primarily designed for programs which must control + special circuitry - most often non-IEEE-1284-compliant devices + other than printers - using 'bit-banging' techniques. + + The current implementation makes ioctl() calls to the Linux ppdev + driver, using the Python fcntl library. It might be rewritten in + C for extra speed. This particular implementation is written for + Linux; all of the upper-level calls can be ported to Windows as + well. + + On Linux, the ppdev device driver, from the Linux 2.4 parallel + port subsystem, is used to control the parallel port hardware. + This driver must be made available from a kernel compile. The + option is called "Support user-space parallel-port drivers". When + using the module, be sure to unload the lp module first: usually + the lp module claims exclusive access to the parallel port, and if + it is loaded, this class will fail to open the parallel port file, + and throw an exception. + + The primary source of information about the Linux 2.4 parallel + port subsystem is Tim Waugh's documentation, the source for which + is available in the kernel tree. This document (called, + appropriately enough, "The Linux 2.4 Parallel Port Subsystem"), + thoroughly describes the parallel port drivers and how to use + them. + + This class provides a method for each of the ioctls supported by + the ppdev module. The ioctl methods are named, in uppercase, the + same as the ioctls they invoke. The documentation for these + methods was taken directly from the documentation for their + corresponding ioctl, and modified only where necessary. + + Unless you have special reason to use the Linux ioctls, you should + use instead the upper-level functions, which are named in + lowerCase fashion and should be portable between Linux and + Windows. This way, any code you write for this class will (or + should) also work with the Windows version of this class. + + """ + def __init__(self, port = 0): + if type(port) == type(""): + self.device = port + else: + self.device = "/dev/parport%d" % port + self._fd = None + self._fd = os.open(self.device, os.O_RDWR) + try: + self.PPEXCL() + self.PPCLAIM() + self.setDataDir(1) + self.setData(0) + except IOError: + os.close(self._fd) + self._fd = None + raise + + def __del__(self): + if self._fd is not None: + self.PPRELEASE() + os.close(self._fd) + + def timevalToFloat(self, timeval): + t=struct.unpack('ll', timeval) + return t[0] + (t[1]/1000000.0) + + def floatToTimeval(self, time): + sec = int(time) + usec = int(time*1000000.0) + return struct.pack('ll', sec, usec) + + def PPCLAIM(self): + """ + Claims access to the port. As a user-land device driver + writer, you will need to do this before you are able to + actually change the state of the parallel port in any + way. Note that some operations only affect the ppdev driver + and not the port, such as PPSETMODE; they can be performed + while access to the port is not claimed. + """ + fcntl.ioctl(self._fd, PPCLAIM) + + def PPEXCL(self): + """ + Instructs the kernel driver to forbid any sharing of the port + with other drivers, i.e. it requests exclusivity. The PPEXCL + command is only valid when the port is not already claimed for + use, and it may mean that the next PPCLAIM ioctl will fail: + some other driver may already have registered itself on that + port. + + Most device drivers don't need exclusive access to the + port. It's only provided in case it is really needed, for + example for devices where access to the port is required for + extensive periods of time (many seconds). + + Note that the PPEXCL ioctl doesn't actually claim the port + there and then---action is deferred until the PPCLAIM ioctl is + performed. + """ + fcntl.ioctl(self._fd, PPEXCL) + + def PPRELEASE(self): + """ + Releases the port. Releasing the port undoes the effect of + claiming the port. It allows other device drivers to talk to + their devices (assuming that there are any). + """ + fcntl.ioctl(self._fd, PPRELEASE) + + def PPYIELD(self): + """ + Yields the port to another driver. This ioctl is a kind of + short-hand for releasing the port and immediately reclaiming + it. It gives other drivers a chance to talk to their devices, + but afterwards claims the port back. An example of using this + would be in a user-land printer driver: once a few characters + have been written we could give the port to another device + driver for a while, but if we still have characters to send to + the printer we would want the port back as soon as possible. + + It is important not to claim the parallel port for too long, + as other device drivers will have no time to service their + devices. If your device does not allow for parallel port + sharing at all, it is better to claim the parallel port + exclusively (see PPEXCL). + """ + fcntl.ioctl(self._fd, PPYIELD) + + def PPNEGOT(self, mode): + """ + Performs IEEE 1284 negotiation into a particular + mode. Briefly, negotiation is the method by which the host and + the peripheral decide on a protocol to use when transferring + data. + + An IEEE 1284 compliant device will start out in compatibility + mode, and then the host can negotiate to another mode (such as + ECP). + + The 'mode' parameter should be one of the following constants + from PPDEV: + + - IEEE1284_MODE_COMPAT + - IEEE1284_MODE_NIBBLE + - IEEE1284_MODE_BYTE + - IEEE1284_MODE_EPP + - IEEE1284_MODE_ECP + + The PPNEGOT ioctl actually does two things: it performs the + on-the-wire negotiation, and it sets the behaviour of + subsequent read/write calls so that they use that mode (but + see PPSETMODE). + """ + fcntl.ioctl(self._fd, PPNEGOT, struct.pack('i', mode)) + + def PPSETMODE(self, mode): + """ + Sets which IEEE 1284 protocol to use for the read and write + calls. + + The 'mode' parameter should be one of the following constants + from PPDEV: + + - IEEE1284_MODE_COMPAT + - IEEE1284_MODE_NIBBLE + - IEEE1284_MODE_BYTE + - IEEE1284_MODE_EPP + - IEEE1284_MODE_ECP + """ + fcntl.ioctl(self._fd, PPSETMODE, struct.pack('i', mode)) + + def PPGETMODE(self): + """ + Retrieves the IEEE 1284 mode being used for read and + write. The return value is one of the following constants + from PPDEV: + + - IEEE1284_MODE_COMPAT + - IEEE1284_MODE_NIBBLE + - IEEE1284_MODE_BYTE + - IEEE1284_MODE_EPP + - IEEE1284_MODE_ECP + """ + ret = struct.pack('i', 0) + ret = fcntl.ioctl(self._fd, PPGETMODE, ret) + return struct.unpack('i', ret)[0] + + def PPGETTIME(self): + """ + Retrieves the time-out value. The read and write calls will + time out if the peripheral doesn't respond quickly enough. The + PPGETTIME ioctl retrieves the length of time that the + peripheral is allowed to have before giving up. + + Returns the timeout value in seconds as a floating-point value. + """ + ret = struct.pack('ll', 0, 0) + ret = fcntl.ioctl(self._fd, PPGETTIME, ret) + return timevalToFloat(ret) + + def PPSETTIME(self, time): + """ + Sets the time-out (see PPGETTIME for more information). + 'time' is the new time-out in seconds; floating-point values + are acceptable. + """ + fcntl.ioctl(self._fd, PPSETTIME, floatToTimeval(time)) + + def PPGETMODES(self): + """ + Retrieves the capabilities of the hardware (i.e. the modes + field of the parport structure). + """ + raise NotImplementedError + + def PPSETFLAGS(self): + """ + Sets flags on the ppdev device which can affect future I/O + operations. Available flags are: + + - PP_FASTWRITE + - PP_FASTREAD + - PP_W91284PIC + """ + raise NotImplementedError + + def PPWCONTROL(self, lines): + """ + Sets the control lines. The 'lines' parameter is a bitwise OR + of the following constants from PPDEV: + + - PARPORT_CONTROL_STROBE + - PARPORT_CONTROL_AUTOFD + - PARPORT_CONTROL_INIT + - PARPORT_CONTROL_SELECT + """ + fcntl.ioctl(self._fd, PPWCONTROL, struct.pack('B', lines)) + + def PPRCONTROL(self): + """ + Returns the last value written to the control register, in the + form of an integer, for which each bit corresponds to a control + line (although some are unused). + + This doesn't actually touch the hardware; the last value + written is remembered in software. This is because some + parallel port hardware does not offer read access to the + control register. + + The control lines bits are defined by the following constants + from PPDEV: + + - PARPORT_CONTROL_STROBE + - PARPORT_CONTROL_AUTOFD + - PARPORT_CONTROL_SELECT + - PARPORT_CONTROL_INIT + """ + ret = struct.pack('B',0) + ret = fcntl.ioctl(self._fd, PPRCONTROL, ret) + return struct.unpack('B', ret)[0] + + def PPFCONTROL(self, mask, val): + """ + Frobs the control lines. Since a common operation is to change + one of the control signals while leaving the others alone, it + would be quite inefficient for the user-land driver to have to + use PPRCONTROL, make the change, and then use PPWCONTROL. Of + course, each driver could remember what state the control + lines are supposed to be in (they are never changed by + anything else), but in order to provide PPRCONTROL, ppdev must + remember the state of the control lines anyway. + + The PPFCONTROL ioctl is for "frobbing" control lines, and is + like PPWCONTROL but acts on a restricted set of control + lines. The ioctl parameter is a pointer to a struct + ppdev_frob_struct: + + struct ppdev_frob_struct { + unsigned char mask; + unsigned char val; + }; + + The mask and val fields are bitwise ORs of control line names + (such as in PPWCONTROL). The operation performed by PPFCONTROL + is: + + new_ctr = (old_ctr & ~mask) | val + + In other words, the signals named in mask are set to the + values in val. + """ + fcntl.ioctl(self._fd, PPFCONTROL, struct.pack('BB', mask, val)) + + def PPRSTATUS(self): + """ + Returns an unsigned char containing bits set for each status + line that is set (for instance, PARPORT_STATUS_BUSY). The + ioctl parameter should be a pointer to an unsigned char. + """ + ret = struct.pack('B',0) + ret = fcntl.ioctl(self._fd, PPRSTATUS, ret) + return struct.unpack('B', ret)[0] + + def PPDATADIR(self, out): + """ + Controls the data line drivers. Normally the computer's + parallel port will drive the data lines, but for byte-wide + transfers from the peripheral to the host it is useful to turn + off those drivers and let the peripheral drive the + signals. (If the drivers on the computer's parallel port are + left on when this happens, the port might be damaged.) + This is only needed in conjunction with PPWDATA or PPRDATA. + + The 'out' parameter indicates the desired port direction. If + 'out' is true or non-zero, the drivers are turned on (forward + direction); otherwise, the drivers are turned off (reverse + direction). + """ + if out: + msg=struct.pack('i',0) + else: + msg=struct.pack('i',1) + fcntl.ioctl(self._fd, PPDATADIR, msg) + + def PPWDATA(self, byte): + """ + Sets the data lines (if in forward mode). The ioctl parameter + is a pointer to an unsigned char. + """ + fcntl.ioctl(self._fd, PPWDATA,struct.pack('B',byte)) + + def PPRDATA(self): + """ + Reads the data lines (if in reverse mode). The ioctl parameter + is a pointer to an unsigned char. + """ + ret=struct.pack('B',0) + ret=fcntl.ioctl(self._fd, PPRDATA,ret) + return struct.unpack('B',ret)[0] + + def PPCLRIRQ(self): + """ + Returns the current interrupt count, and clears it. The ppdev + driver keeps a count of interrupts as they are triggered. + """ + ret=struct.pack('i',0) + ret=fcntl.ioctl(self._fd, PPCLRIRQ,ret) + return struct.unpack('i',ret)[0] + + def PPWCTLONIRQ(self, lines): + """ + Set a trigger response. Afterwards when an interrupt is + triggered, the interrupt handler will set the control lines as + requested. The ioctl parameter is a pointer to an unsigned + char, which is interpreted in the same way as for PPWCONTROL. + + The reason for this ioctl is simply speed. Without this ioctl, + responding to an interrupt would start in the interrupt + handler, switch context to the user-land driver via poll or + select, and then switch context back to the kernel in order to + handle PPWCONTROL. Doing the whole lot in the interrupt + handler is a lot faster. + """ + fcntl.ioctl(self._fd, PPWCTLONIRQ,struct.pack('B',lines)) + + #data lines +## def data(self): +## """Returns the states of the data bus line drivers (pins 2-9)""" +## return self._data + + def setDataDir(self,out): + """Activates or deactivates the data bus line drivers (pins 2-9)""" + self._dataDir = out + self.PPDATADIR(out) + + def dataDir(self): + """Returns true if the data bus line drivers are on (pins 2-9)""" + return self._dataDir + + #control lines +## def strobe(self): +## """Returns the state of the nStrobe output (pin 1)""" +## return (self.PPRCONTROL()&PARPORT_CONTROL_STROBE)==0 + + def setDataStrobe(self, level): + """Sets the state of the nStrobe output (pin 1)""" + if level: + self.PPFCONTROL(PARPORT_CONTROL_STROBE, 0) + else: + self.PPFCONTROL(PARPORT_CONTROL_STROBE, PARPORT_CONTROL_STROBE) + +## def autoFd(self): +## """Returns the state of the nAutoFd output (pin 14)""" +## return (self.PPRCONTROL()&PARPORT_CONTROL_AUTOFD)==0 + + def setAutoFeed(self, level): + """Sets the state of the nAutoFd output (pin 14)""" + if level: + self.PPFCONTROL(PARPORT_CONTROL_AUTOFD, 0) + else: + self.PPFCONTROL(PARPORT_CONTROL_AUTOFD, PARPORT_CONTROL_AUTOFD) + +## def init(self): +## """Returns the state of the nInit output (pin 16)""" +## return (self.PPRCONTROL()&PARPORT_CONTROL_INIT)!=0 + + def setInitOut(self, level): + """Sets the state of the nInit output (pin 16)""" + if level: + self.PPFCONTROL(PARPORT_CONTROL_INIT, PARPORT_CONTROL_INIT) + else: + self.PPFCONTROL(PARPORT_CONTROL_INIT, 0) + +## def selectIn(self): +## """Returns the state of the nSelectIn output (pin 17)""" +## return (self.PPRCONTROL()&PARPORT_CONTROL_SELECT)==0 + + def setSelect(self,level): + """Sets the state of the nSelectIn output (pin 17)""" + if level: + self.PPFCONTROL(PARPORT_CONTROL_SELECT, 0) + else: + self.PPFCONTROL(PARPORT_CONTROL_SELECT, PARPORT_CONTROL_SELECT) + + def setData(self,d): + """Sets the states of the data bus line drivers (pins 2-9)""" + self._data=d + return self.PPWDATA(d) + + def getData(self): + """Gets the states of the data bus line (pin 2-9)""" + return self.PPRDATA() + + # status lines + def getInError(self): + """Returns the level on the nFault pin (15)""" + return (self.PPRSTATUS() & PARPORT_STATUS_ERROR) != 0 + + def getInSelected(self): + """Returns the level on the Select pin (13)""" + return (self.PPRSTATUS() & PARPORT_STATUS_SELECT) != 0 + + def getInPaperOut(self): + """Returns the level on the paperOut pin (12)""" + return (self.PPRSTATUS() & PARPORT_STATUS_PAPEROUT) != 0 + + def getInAcknowledge(self): + """Returns the level on the nAck pin (10)""" + return (self.PPRSTATUS() & PARPORT_STATUS_ACK) != 0 + + def getInBusy(self): + """Returns the level on the Busy pin (11)""" + return (self.PPRSTATUS() & PARPORT_STATUS_BUSY) == 0 + --- pyparallel-0.2.orig/parallel/__init__.py +++ pyparallel-0.2/parallel/__init__.py @@ -1,22 +1,22 @@ -#!/usr/bin/env python -#portable parallel port access with python -#this is a wrapper module for different platform implementations -# -# (C)2001-2002 Chris Liechti -# this is distributed under a free software license, see license.txt - -import sys, os, string -VERSION = string.split("$Revision: 1.4 $")[1] #extract CVS version - -#chose an implementation, depending on os -if os.name == 'nt': - from parallelwin32 import * -elif os.name == 'posix': - if sys.platform == 'linux2': - from parallelppdev import * #linux, kernel 2.4 - else: - from parallelioctl import * #IOCTLs -elif os.name == 'java': - from paralleljava import * -else: - raise "Sorry no implementation for your platform available." +#!/usr/bin/env python +#portable parallel port access with python +#this is a wrapper module for different platform implementations +# +# (C)2001-2002 Chris Liechti +# this is distributed under a free software license, see license.txt + +import sys, os, string +VERSION = "0.3" + +#chose an implementation, depending on os +if os.name == 'nt': + from parallelwin32 import * +elif os.name == 'posix': + if sys.platform == 'linux2': + from parallelppdev import * #linux, kernel 2.4 + else: + from parallelioctl import * #IOCTLs +elif os.name == 'java': + from paralleljava import * +else: + raise NotImplementedError, "Sorry no implementation for your platform available." --- pyparallel-0.2.orig/debian/changelog +++ pyparallel-0.2/debian/changelog @@ -0,0 +1,63 @@ +pyparallel (0.2-7build1) precise; urgency=low + + * Rebuild to drop python2.6 dependencies. + + -- Matthias Klose Sat, 31 Dec 2011 02:08:09 +0000 + +pyparallel (0.2-7) unstable; urgency=low + + * Build using dh_python2. Closes: #616977. + * Update to revision r379. Closes: #586893. + * Don't use string exceptions. Closes: #585312. + + -- Matthias Klose Fri, 22 Apr 2011 11:14:53 +0200 + +pyparallel (0.2-6) unstable; urgency=low + + * Update watch file. Closes: #450347. + * Fix pointer to examples in README.txt. Closes: #449381. + + -- Matthias Klose Tue, 24 Jun 2008 19:32:32 +0200 + +pyparallel (0.2-5) unstable; urgency=low + + * Build-depend on python-central (>= 0.4.17). Indirectly depends on + the first python2.3 including the Makefile. Closes: #373202. + + -- Matthias Klose Fri, 16 Jun 2006 18:53:41 +0000 + +pyparallel (0.2-4) unstable; urgency=low + + * Do not provide the versioned packages. + + -- Matthias Klose Fri, 9 Jun 2006 08:42:56 +0000 + +pyparallel (0.2-3) unstable; urgency=low + + * Convert to python-central. + + -- Matthias Klose Tue, 6 Jun 2006 22:37:57 +0000 + +pyparallel (0.2-1ubuntu1) breezy; urgency=low + + * Resynchronise with Debian. + + -- Andrew Mitchell Fri, 13 May 2005 10:17:35 +1200 + +pyparallel (0.1-1ubuntu1) hoary; urgency=low + + * Build for python2.4. + + -- Matthias Klose Sun, 19 Dec 2004 18:58:32 +0000 + +pyparallel (0.2-1) unstable; urgency=low + + * New upstream version. + + -- Matthias Klose Tue, 1 Feb 2005 11:45:47 +0100 + +pyparallel (0.1-1) unstable; urgency=low + + * Initial release. + + -- Matthias Klose Sun, 29 Aug 2004 15:10:57 +0200 --- pyparallel-0.2.orig/debian/rules +++ pyparallel-0.2/debian/rules @@ -0,0 +1,76 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +PYTHON := /usr/bin/python +PYVER := $(shell $(PYTHON) -c 'import sys; print sys.version[:3]') +PYVERS := $(shell pyversions -vs) + +build: build-stamp + +build-stamp: + dh_testdir + set -e; \ + for v in $(PYVERS); do \ + python setup.py build; \ + done + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + rm -rf build + -find . -name '*.py[co]' | xargs rm -f + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + set -e; \ + for v in $(PYVERS); do \ + python setup.py install \ + --root=$(CURDIR)/debian/python-parallel; \ + done + +# Build architecture-independent files here. +binary-indep: build install + dh_testdir + dh_testroot + dh_installchangelogs CHANGES.txt + dh_installdocs README.txt +# dh_installexamples examples/* + dh_installman + : # Replace all '#!' calls to python with $(PYTHON) + : # and make them executable + for i in `find debian -mindepth 3 -type f`; do \ + sed '1s,#!.*python[^ ]*\(.*\),#! $(PYTHON)\1,' \ + $$i > $$i.temp; \ + if cmp --quiet $$i $$i.temp; then \ + rm -f $$i.temp; \ + else \ + mv -f $$i.temp $$i; \ + chmod 755 $$i; \ + echo "fixed interpreter: $$i"; \ + fi; \ + done + dh_python2 + dh_compress -X.py + dh_fixperms + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +# Build architecture-dependent files here. +binary-arch: build install +# We have nothing to do by default. + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure --- pyparallel-0.2.orig/debian/control +++ pyparallel-0.2/debian/control @@ -0,0 +1,18 @@ +Source: pyparallel +Section: python +XS-Python-Version: all +Priority: optional +Maintainer: Matthias Klose +Build-Depends: debhelper (>= 5) +Build-Depends-Indep: python-all-dev (>= 2.6.6-14) +Standards-Version: 3.9.1 + +Package: python-parallel +Architecture: all +Depends: ${python:Depends} +XB-Python-Version: ${python:Versions} +Description: pyparallel - module encapsulating access for the parallel port + This module capsulates the access for the parallel port. It provides + backends for standard Python running on Windows, Linux, BSD (possibly + any POSIX compilant system). The module named "parallel" automaticaly + selects the appropriate backend. --- pyparallel-0.2.orig/debian/copyright +++ pyparallel-0.2/debian/copyright @@ -0,0 +1,69 @@ +This package was debianized by Matthias Klose on +Sat, 24 Apr 2004 00:15:15 +0200. + +It was downloaded from http://pyserial.sf.net/ + +Upstream Author: Chris Liechti + +Copyright: + +Copyright (c) 2001 Chris Liechti ; +All Rights Reserved. + +This is the Python license. In short, you can use this product in +commercial and non-commercial applications, modify it, redistribute it. +A notification to the author when you use and/or modify it is welcome. + + +TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING THIS SOFTWARE +=================================================================== + +LICENSE AGREEMENT +----------------- + +1. This LICENSE AGREEMENT is between the copyright holder of this +product, and the Individual or Organization ("Licensee") accessing +and otherwise using this product in source or binary form and its +associated documentation. + +2. Subject to the terms and conditions of this License Agreement, +the copyright holder hereby grants Licensee a nonexclusive, +royalty-free, world-wide license to reproduce, analyze, test, +perform and/or display publicly, prepare derivative works, distribute, +and otherwise use this product alone or in any derivative version, +provided, however, that copyright holders License Agreement and +copyright holders notice of copyright are retained in this product +alone or in any derivative version prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates this product or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to this product. + +4. The copyright holder is making this product available to Licensee on +an "AS IS" basis. THE COPYRIGHT HOLDER MAKES NO REPRESENTATIONS OR +WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, +THE COPYRIGHT HOLDER MAKES NO AND DISCLAIMS ANY REPRESENTATION OR +WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR +THAT THE USE OF THIS PRODUCT WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. + +5. THE COPYRIGHT HOLDER SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER +USERS OF THIS PRODUCT FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL +DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE +USING THIS PRODUCT, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE +POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between the +copyright holder and Licensee. This License Agreement does not grant +permission to use trademarks or trade names from the copyright holder +in a trademark sense to endorse or promote products or services of +Licensee, or any third party. + +8. By copying, installing or otherwise using this product, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. --- pyparallel-0.2.orig/debian/watch +++ pyparallel-0.2/debian/watch @@ -0,0 +1,2 @@ +version=3 +http://sf.net/pyserial/pyparallel-([\d\.]*).zip --- pyparallel-0.2.orig/debian/compat +++ pyparallel-0.2/debian/compat @@ -0,0 +1 @@ +5