Commits

Ben Bass committed 70d5028

fix synchronous bitbang reading; add pin_read example

  • Participants
  • Parent commits fed55e4

Comments (0)

Files changed (4)

 # built documents.
 #
 # The short X.Y version.
-version = '0.8.1'
+version = '0.9'
 # The full version, including alpha/beta/rc tags.
-release = '0.8.1'
+release = '0.9.pre'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

pylibftdi/bitbang.py

 """
 
 from pylibftdi.driver import Device, FtdiError
+from ctypes import c_ubyte, byref
 
 ALL_OUTPUTS = 0xFF
 ALL_INPUTS = 0x00
     """
     simple subclass to support bit-bang mode
 
-    Only uses async mode at the moment.
+    Internally uses async mode at the moment, but provides a 'sync'
+    flag (defaulting to True) which controls the behaviour of port
+    reading and writing - if set, the FIFOs are ignored (read) or
+    cleared (write) so operations will appear synchronous
 
     Adds two read/write properties to the base class:
      direction: 8 bit input(0)/output(1) direction control.
     def __init__(self,
                  device_id=None,
                  direction=ALL_OUTPUTS,
-                 lazy_open=False):
+                 lazy_open=False,
+                 sync=True):
         # initialise the super-class, but don't open yet. We really want
         # two-part initialisation here - set up all the instance variables
         # here in the super class, then open it after having set more
                                             mode='b',
                                             lazy_open=True)
         self.direction = direction
+        self.sync = sync
         self._last_set_dir = None
         self._latch = 0
         if not lazy_open:
         lines is persisted in this object for the purposes of reading,
         so read-modify-write operations (e.g. drv.port+=1) are valid.
         """
-        # the coercion to bytearray here is to make this work
-        # transparently between Python2 and Python3 - equivalent
-        # of ord() for Python2, a time-wasting do-nothing on Python3
-        result = bytearray(super(BitBangDevice, self).read(1))[0]
+        if self.sync:
+            pin_byte = c_ubyte()
+            res = self.fdll.ftdi_read_pins(self.ctx, byref(pin_byte))
+            if res != 0:
+                raise FtdiError("Could not read device pins")
+            result = pin_byte.value
+        else:
+            # the coercion to bytearray here is to make this work
+            # transparently between Python2 and Python3 - equivalent
+            # of ord() for Python2, a time-wasting do-nothing on Python3
+            result = bytearray(super(BitBangDevice, self).read(1))[0]
+
         # replace the 'output' bits with current value of _latch -
         # the last written value. This makes read-modify-write
         # operations (e.g. 'drv.port |= 0x10') work as expected
     @port.setter
     def port(self, value):
         self._latch = value
+        if self.sync:
+            self.flush_output()
         return super(BitBangDevice, self).write(chr(value))

pylibftdi/examples/list_devices.py

+"""
+Report connected FTDI devices. This may be useful in obtaining
+serial numbers to use as the device_id parameter of the Device()
+constructor to communicate with a specific device when more than
+one is present.
+
+example usage:
+
+    $ python pylibftdi/examples/list_devices.py
+    FTDI:UB232R:FTAS1UN5
+    FTDI:UM232R USB <-> Serial:FTE4FFVQ
+
+To open a device specifically to communicate with the second of
+these devices, the following would be used:
+
+    >>> from pylibftdi import Device
+    >>> dev = Device(device_id="FTE4FFVQ")
+    >>>
+
+Copyright (c) 2011 Ben Bass <benbass@codedstructure.net>
+All rights reserved.
+"""
 
 from pylibftdi import Driver
 
 
-def get_devices():
+def get_ftdi_device_list():
+    """
+    return a list of lines, each a colon-separated
+    vendor:product:serial summary of detected devices
+    """
     dev_list = []
     for device in Driver().list_devices():
-        dev_list.append("%s:%s:%s" % (tuple(x.decode('latin1') for x in device)))
-
+        # list_devices returns bytes rather than strings
+        device = map(lambda x: x.decode('latin1'), device)
+        # device must always be this triple
+        vendor, product, serial = device
+        dev_list.append("%s:%s:%s" % (vendor, product, serial))
+    return dev_list
 
 if __name__ == '__main__':
-    print('\n'.join(get_devices()))
+    for device in get_ftdi_device_list():
+        print(device)

pylibftdi/examples/pin_read.py

+
+from pylibftdi import BitBangDevice, ALL_INPUTS
+import time
+import sys
+
+d = BitBangDevice(direction=ALL_INPUTS)
+
+while True:
+    time.sleep(0.01)
+    value = d.port
+    sys.stdout.write("\b" * 32)
+    for n in range(8):
+        sys.stdout.write("1 " if value & (1 << (7 - n)) else "0 ")
+    sys.stdout.write("  (%d/0x%02X)" % (value, value))
+    sys.stdout.flush()