Package VisionEgg :: Module DaqLPT
[frames] | no frames]

Source Code for Module VisionEgg.DaqLPT

  1  # The Vision Egg: DaqLPT 
  2  # 
  3  # Copyright (C) 2001-2003 Andrew Straw. 
  4  # Copyright (C) 2005 Hubertus Becker 
  5  # Author: Andrew Straw <astraw@users.sourceforge.net> 
  6  # URL: <http://www.visionegg.org/> 
  7  # 
  8  # Distributed under the terms of the GNU Lesser General Public License 
  9  # (LGPL). See LICENSE.TXT that came with this file. 
 10   
 11  """ 
 12  Data acquisition and triggering over the parallel port. 
 13   
 14  This module was programmed using information from "Interfacing the 
 15  Standard Parallel Port" by Craig Peacock, 
 16  http://www.senet.com.au/~cpeacock. 
 17   
 18  You may also be interested in http://www.lvr.com/files/ibmlpt.txt. 
 19   
 20  This module only uses the Standard Parallel Port (SPP) protocol, not 
 21  ECP or EPP.  You may have to set your computer's BIOS accordingly. 
 22   
 23  You may need to be root or otherwise have permission to access the 
 24  parallel port. 
 25   
 26  Example usage: 
 27   
 28  >>> from VisionEgg.DaqLPT import raw_lpt_module 
 29  >>> address = 0x378 
 30  >>> out_value = 0 
 31  >>> raw_lpt_module.out( address, out_value ) 
 32  >>> in_value = raw_lpt_module.inp( address+1 ) 
 33   
 34  """ 
 35   
 36  #################################################################### 
 37  # 
 38  #        Import all the necessary packages 
 39  # 
 40  #################################################################### 
 41   
 42  import VisionEgg 
 43  import VisionEgg.Core 
 44  import VisionEgg.FlowControl 
 45  import VisionEgg.Daq 
 46  import VisionEgg.ParameterTypes as ve_types 
 47  import sys 
 48   
 49  # See the raw LPT module for your platform for direct LPT access 
 50  # without VisionEgg DAQ overhead.  In particular, the inp and out 
 51  # functions are useful. 
 52   
 53  if sys.platform == 'win32': 
 54      try: 
 55          # Dincer Aydin's module http://www.geocities.com/dinceraydin 
 56          import winioport as raw_lpt_module 
 57      except ImportError: 
 58          # Andrew Straw's module http://www.its.caltech.edu/~astraw/coding.html 
 59          import dlportio as raw_lpt_module 
 60  elif sys.platform.startswith('linux'): 
 61      import VisionEgg._raw_lpt_linux as raw_lpt_module 
 62  elif sys.platform.startswith('irix'): 
 63  ### IRIX implementation not done, but possible 
 64      raise NotImplementedError("VisionEgg.DaqLPT not implemented on IRIX") 
 65  ##    import VisionEgg._raw_plp_irix 
 66  ##    raw_lpt_module = VisionEgg._raw_plp_irix 
 67  else: 
 68      raise RuntimeError("VisionEgg.DaqLPT not supported on this platform") 
 69   
 70  __version__ = VisionEgg.release_name 
 71   
72 -class LPTInput(VisionEgg.Daq.Input):
73 - def get_data(self):
74 """Get status bits 0-7 of the LPT port. 75 76 The status bits were not meant for high speed digital input. 77 Nevertheless, for sampling one or two digital inputs at slow 78 rates, they work fine. 79 80 Bits 4 and 5 (pins 13 and 12, respectively) should be first 81 choice to sample a digital voltage. The other bits have some 82 oddities. Bits 0 and 1 are designated reserved. Others are 83 "active low"; they show a logic 0 when +5v is applied. 84 85 bit3 = value & 0x08 86 bit4 = value & 0x10 87 bit5 = value & 0x20 88 bit6 = value & 0x40 89 """ 90 return raw_lpt_module.inp(self.channel.device.base_address+1)
91
92 -class LPTOutput(VisionEgg.Daq.Output):
93 - def put_data(self,data):
94 """Set output bits 0-7 (pins 2-9) on the LPT port.""" 95 raw_lpt_module.out(self.channel.device.base_address,data)
96 - def __del__(self):
97 """Set output bits low when closing.""" 98 raw_lpt_module.out(self.channel.device.base_address,0)
99
100 -class LPTChannel(VisionEgg.Daq.Channel):
101 """A data acquisition channel using the parallel port."""
102 - def __init__(self,**kw):
103 if not 'raw_lpt_module' in globals().keys(): 104 raise RuntimeError("LPT output not supported on this platform.") 105 VisionEgg.Daq.Channel.__init__(self,**kw) 106 signal_type = self.constant_parameters.signal_type 107 if not isinstance(signal_type,VisionEgg.Daq.Digital): 108 raise ValueError("Channel must be digital.") 109 daq_mode = self.constant_parameters.daq_mode 110 if not isinstance(daq_mode,VisionEgg.Daq.Immediate): 111 raise ValueError("Channel must be immediate mode.") 112 functionality = self.constant_parameters.functionality 113 if not isinstance(functionality,LPTInput): 114 if not isinstance(functionality,LPTOutput): 115 raise ValueError("Channel functionality must be instance of LPTInput or LPTOutput.")
116
117 -class LPTDevice(VisionEgg.Daq.Device):
118 """A single parallel port. (Line PrinTer port.) 119 120 Typically, LPT1 has a base address of 0x0378, and LPT2 has a base 121 address of 0x0278.""" 122
123 - def __init__(self,base_address=0x378,**kw):
124 if not 'raw_lpt_module' in globals().keys(): 125 raise RuntimeError("LPT output not supported on this platform.") 126 VisionEgg.Daq.Device.__init__(self,**kw) 127 for channel in self.channels: 128 if not isinstance(channel,LPTChannel): 129 raise ValueError("LPTDevice only has LPTChannels.") 130 self.base_address = base_address
131
132 - def add_channel(self,channel):
133 if not isinstance(channel,LPTChannel): 134 raise ValueError("LPTDevice only has LPTChannels.") 135 VisionEgg.Daq.Device.add_channel(self,channel)
136
137 -class LPTTriggerOutController(VisionEgg.FlowControl.Controller):
138 """Use 8 bits of digital output for triggering and frame timing verification. 139 140 Bit 0 (pin 2) goes high when the go loop begins and low when the 141 loop ends. Bits 1-7 (pins 3-9) count the frame_number (modulo 142 2^7) in binary. Looking at any one of these pins therefore 143 provides verification that your stimulus is not skipping 144 frames.""" 145
146 - def __init__(self,lpt_device=None):
147 if not 'raw_lpt_module' in globals().keys(): 148 raise RuntimeError("LPT output not supported on this platform.") 149 VisionEgg.FlowControl.Controller.__init__(self, 150 return_type=ve_types.NoneType, 151 eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME) 152 # Initialize DAQ stuff: 153 self.trigger_out_channel = LPTChannel(signal_type = VisionEgg.Daq.Digital(), 154 daq_mode = VisionEgg.Daq.Immediate(), 155 functionality = LPTOutput()) 156 if lpt_device is None: 157 self.device = LPTDevice() 158 else: 159 if not isinstance(lpt_device,LPTDevice): 160 raise ValueError("lpt_device must be instance of LPTDevice.") 161 self.device = lpt_device 162 self.device.add_channel(self.trigger_out_channel) 163 164 self.total_frames = 0
165 - def during_go_eval(self):
166 self.total_frames = (self.total_frames + 1) % (2**7) 167 value = self.total_frames*2 + 1 168 self.trigger_out_channel.constant_parameters.functionality.put_data(value)
169 - def between_go_eval(self):
170 self.total_frames = (self.total_frames + 1) % (2**7) 171 value = self.total_frames*2 + 0 172 self.trigger_out_channel.constant_parameters.functionality.put_data(value)
173
174 -class LPTTriggerInController(VisionEgg.FlowControl.Controller):
175 - def __init__(self,lpt_device=None,pin=13):
176 if not 'raw_lpt_module' in globals().keys(): 177 raise RuntimeError("LPT input not supported on this platform.") 178 VisionEgg.FlowControl.Controller.__init__(self, 179 return_type=ve_types.Integer, 180 eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME) 181 # Initialize DAQ stuff: 182 self.trigger_in_channel = LPTChannel(signal_type = VisionEgg.Daq.Digital(), 183 daq_mode = VisionEgg.Daq.Immediate(), 184 functionality = LPTInput()) 185 if lpt_device is None: 186 self.device = LPTDevice() 187 else: 188 if not isinstance(lpt_device,LPTDevice): 189 raise ValueError("lpt_device must be instance of LPTDevice.") 190 self.device = lpt_device 191 self.device.add_channel(self.trigger_in_channel) 192 if pin==15: 193 bit = 3 194 elif pin==13: 195 bit = 4 196 elif pin==12: 197 bit = 5 198 elif pin==10: 199 bit = 6 200 elif pin==11: 201 bit = 7 202 else: 203 raise ValueError("Only pins 10, 11, 12, 13 and 15 supported at this time.") 204 self.mask = 2**bit
205 - def during_go_eval(self):
206 return 1
207 - def between_go_eval(self):
208 value = self.trigger_in_channel.constant_parameters.functionality.get_data() 209 return (value & self.mask)
210