# Description -------------------------------------------------------------------------------------------------------------- # A parallel port class and functions to read and write data. # Name: printer_port_io.py # Author: W. Hetherington ( add your name if you contribute) # Created: 2009/04/28 # Copyright: (c) 2009 # License: No restrictions #--------------------------------------------------------------------------------------------------------------------------- import ctypes from numpy import * from pylab import * from time import * # ------------------------------------------------------------------------------------ # Basic I/O routines - These can be used in the Python shell. def In(addr) : return ctypes.windll.inpout32.Inp32(addr) # Read byte from io address addr def Out(addr, byte) : ctypes.windll.inpout32.Out32(addr, byte) # Send byte to io address addr # ------------------------------------------------------------------------------------ # Test rountines for the basic I/O routines - These can be used in the Python shell. def TestOut() : reset = 15 start_conversion = reset - 4 base = 0x378 data_spp = base data_epp = base + 4 control = base + 2 ecr = base + 0x402 ecr_byte_set_epp_mode = 128 #129 + 16 # Byte sent to the ecr to set the ECP to EPP mode ecr_byte_set_bispp_mode = 32 Out(ecr, ecr_byte_set_bispp_mode) # set ECP to bi-directional SPP mode Out(control, reset) # Set select, reset, autolf and strobe high for byte in range(8) : print byte Out(data_spp, byte) #Out(control, strobe) # Take the strobe (write) low #Out(control, strobe_autolf) # Take the autolf (data strobe) low #Out(control, reset) # Set select, reset, autolf and strobe high #Out(control, reset) # Set select, reset, autolf and strobe high q = raw_input("?") def TestIn() : reset = 15 start_conversion = reset - 4 base = 0x378 data_spp = base data_epp = base + 4 control = base + 2 ecr = base + 0x402 ecr_byte_set_epp_mode = 128 #129 + 16 # Byte sent to the ecr to set the ECP to EPP mode ecr_byte_set_bispp_mode = 32 Out(ecr, ecr_byte_set_bispp_mode) # set ECP to bi-directional SPP mode Out(control, reset) # Set select, reset, autolf and strobe high for i in range(8) : print i, In(data_spp) #Out(control, strobe) # Take the strobe (write) low #Out(control, strobe_autolf) # Take the autolf (data strobe) low #Out(control, reset) # Set select, reset, autolf and strobe high #Out(control, reset) # Set select, reset, autolf and strobe high q = raw_input("?") # ------------------------------------------------------------------------------------ # Parallel Port class - use bi-directional SPP mode only class Port : def __init__(self): base = 0x378 self.status = base + 1 self.control = base + 2 self.data_spp = base # Data port for SPP mode self.data_epp = base + 4 # Data port for EPP mode self.ecr = base + 0x402 #ECP extended control register in system default ECP mode self.ecr_byte_set_epp_mode = 128 # Byte sent to the ecr to set the ECP to EPP mode self.ecr_byte_set_bispp_mode = 32 # Byte sent to the ecr to set the ECP to bi-directional SPP mode self.control_byte_reset = 15 # Default or inactive state of the control register outputs. self.control_byte_write = 1 # bit 0 - not used self.control_byte_strobe = 2 # bit 1 - not used self.control_byte_start_conversion = self.control_byte_reset - 4 # This is pin 16 on the db25 connector and begins an AD conversion. self.status_byte_wait = 128 # This is pin 11 on the db25 connector and is the externally-generated eoc signal. def SetEPPMode(self) : Out(self.ecr, self.ecr_byte_set_epp_mode) # set ECP to EPP mode Out(self.control, self.control_byte_reset) # Set select, reset, autolf and strobe high def SetSPPMode(self) : Out(self.ecr, self.ecr_byte_set_bispp_mode) Out(self.control, self.control_byte_reset) # Set select, reset, autolf and strobe high def write(self, byte) : Out(self.data, byte) def read(self) : return In(self.data_spp) def eoc_read(self) : Out(self.control, self.control_byte_start_conversion) # Take the start conversion bit low. while In(self.status) < self.status_byte_wait : # This input bit is inverted by the printer port hardware! continue a = In(self.data_spp) Out(self.control, self.control_byte_reset) # Set select, reset, autolf and strobe high return a def eoc_read_block_fast(self, points) : a = zeros(points, dtype=int16) # Use a 16 bit integer since converting to floating point takes time. for i in range(points) : Out(self.control, self.control_byte_start_conversion) # Take the start conversion bit low. #while In(self.status) < self.status_byte_wait : # Do not bother checking the eoc since the conversion time is only 500 ns. # continue a[i] = In(self.data_spp) Out(self.control, self.control_byte_reset) # Set select, reset, autolf and strobe high return a def convert_eoc_endless(self) : while 1 : Out(self.control, self.control_byte_start_conversion) for i in range(200) : a = i*i Out(self.control, self.control_byte_reset) # Set select, reset, autolf and strobe high for i in range(100) : a = i*i return a # ------------------------------------------------------------------------------------ # Routines to test the Port class functions def TestWrite(p) : #p = Port() p.write(1) a = raw_input('?') p.write(2) a = raw_input('?') p.write(128) a = raw_input('?') def TestRead(p) : #p = Port() print p.read() a = raw_input('?') print p.read() a = raw_input('?') print p.read() a = raw_input('?') def TestRapidRead(p) : #p = Port() a = zeros(1000) # Create a 1000 element array of zeros begin = time() for i in range(1000) : a[i] = p.read() print time() - begin def TestEocRead(p) : #p = Port() print p.eoc_read() a = raw_input('?') print p.eoc_read() a = raw_input('?') print p.eoc_read() a = raw_input('?') def TestEocReadContinuously(p) : #p = Port() while 1 : print p.eoc_read() def TestEocReadBlockFast(p, points): begin = time() a = p.eoc_read_block_fast(points) print time() - begin #print a plot(a) show() q = raw_input('Enter a file name to save this data or just press enter to exit :') q.strip() if q : f = file(q, 'w') for b in a : f.write(str(b)+'\n') f.close() def TestConvertEocEndless(p): #p = Port() print p.convert_eoc_endless() #----------------------------------------------------------------------------------- # Execute this code only if this module is run as a Python program. if __name__ == '__main__' : #TestIn() #TestOut() p = Port() #p.SetEPPMode() p.SetSPPMode() #TestWrite(p) #TestRead(p) #TestRapidRead(p) #TestEocRead(p) #TestConvertEocEndless(p) #TestEocReadContinuously(p) TestEocReadBlockFast(p, 1000) #TestProgrammedRead(p)