### # Author : E J Jonkers # company : DataCT # date created : 05-02-24 # date modified : # ### import sys import struct import fcntl import os IOCPARM_MASK = 0x1fff #/* parameter length, at most 13 bits */ #IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) #IOCBASECMD(x) ((x) & ~(IOCPARM_MASK << 16)) #IOCGROUP(x) (((x) >> 8) & 0xff) PAGE_SHIFT = 12 #/* LOG2(PAGE_SIZE) */ PAGE_SIZE = (1 << PAGE_SHIFT) #/* bytes/page */ IOCPARM_MAX = PAGE_SIZE #/* max size of ioctl, mult. of PAGE_SIZE */ IOC_VOID = 0x20000000 #/* no parameters */ IOC_OUT = 0x40000000 #/* copy out parameters */ IOC_IN = 0x80000000 #/* copy in parameters */ IOC_INOUT = (IOC_IN|IOC_OUT) IOC_DIRMASK = 0xe0000000 #/* mask for IN/OUT/VOID */ def sizeof(type): return struct.calcsize(type) def _IOC(inout, group, num, len): return int(inout | ((len & IOCPARM_MASK) << 16 ) |\ ((group) << 8 ) | (num)) def _IO(g,n): return _IOC(IOC_VOID, (g), (n), 0) def _IOR(g,n,t): return _IOC(IOC_OUT, (g), (n), sizeof(t)) def _IOW(g,n,t): return _IOC(IOC_IN, (g), (n), sizeof(t)) def _IOWR(g,n,t): return _IOC(IOC_INOUT, (g), (n), sizeof(t)) PP_IOCTL = ord('P') PPIGDATA = _IOR(PP_IOCTL, 10, 'B') PPIGSTATUS = _IOR(PP_IOCTL, 11, 'B') PPIGCTRL = _IOR(PP_IOCTL, 12, 'B') PPIGEPPD = _IOR(PP_IOCTL, 13, 'B') PPIGECR = _IOR(PP_IOCTL, 14, 'B') PPIGFIFO = _IOR(PP_IOCTL, 15, 'B') PPISDATA = _IOW(PP_IOCTL, 16, 'B') PPISSTATUS = _IOW(PP_IOCTL, 17, 'B') PPISCTRL = _IOW(PP_IOCTL, 18, 'B') PPISEPPD = _IOW(PP_IOCTL, 19, 'B') PPISECR = _IOW(PP_IOCTL, 20, 'B') PPISFIFO = _IOW(PP_IOCTL, 21, 'B') PPIGEPPA = _IOR(PP_IOCTL, 22, 'B') PPISEPPA = _IOR(PP_IOCTL, 23, 'B') 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 class Parallel: def __init__(self, port = 0): if type(port) == type(""): self.device = port else: self.device = "/dev/ppi%d" % port self._fd = os.open(self.device, os.O_RDWR) def __del__(self): # self.PPRELEASE() if self._fd is not None: os.close(self._fd) def PPFCONTROL(self, mask, val): old_ctr = self.PPRCONTROL() new_ctr = (old_ctr & ~mask) | val fcntl.ioctl(self._fd, PPISCTRL,struct.pack('B',new_ctr)) def PPRCONTROL(self): ret = struct.pack('B',0) ret = fcntl.ioctl(self._fd, PPIGCTRL, ret) return struct.unpack('B', ret)[0] 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, PPISDATA, struct.pack('B',byte)) 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 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, PPIGSTATUS, ret) return struct.unpack('B', ret)[0] #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