VisionEgg.DaqLPT

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