Ben Bass avatar Ben Bass committed bce2b77

0.7 final - doc updates etc

Comments (0)

Files changed (6)

 
 0.7
  * support multiple attached devices
- * new API - separation between driver and device
+ * API changes:
+   - separation between driver and device. Generally, now use Device() /
+     BitBangDevice() rather than Driver / BitBangDriver(), though older code
+     _should_ still work via some shims (though with Deprecation warnings).
+   - first parameter in Device() and BitBangDevice() is a device ID - the serial
+     number string of the target device.
+   - open() is generally no longer required on Devices. This is to more closely
+     model the file() API.
 0.6
  * same source now works on both Python2.6+ and Python3.
 0.5
 
  - Supports Python 2 and Python 3
  - Supports parallel and serial devices
+ - Support for multiple devices
  - Cross-platform
- - Support for multiple devices
 
 :Limitations:
 
 Usage
 -----
 
-The primary interface is the ``Driver`` class in the pylibftdi package; this
+The primary interface is the ``Device`` class in the pylibftdi package; this
 gives serial access on relevant FTDI devices (e.g. the UM232R), providing a
 file-like interface (read, write).  Baudrate is controlled with the ``baudrate``
 property.
 
-If a Driver instance is created with ``mode='t'`` (text mode) then read() and
+If a Device instance is created with ``mode='t'`` (text mode) then read() and
 write() can use the given ``encoding`` (defaulting to latin-1). This doesn't
 make a lot of difference on Python 2 (and can be omitted), but allows easier
 integration with passing unicode strings between devices in Python 3.
 
+Multiple devices are supported by passing the desired device serial number (as
+a string) in the ``device_id`` parameter - this is the first parameter in both
+Device() and BitBangDevice() constructors.
+
 Examples
 ~~~~~~~~
 
 ::
 
-    >>> from pylibftdi import Driver
+    >>> from pylibftdi import Device
     >>>
-    >>> with Driver(mode='t') as drv:
-    >>>     drv.baudrate = 115200
-    >>>     drv.write('Hello World')
+    >>> with Device(mode='t') as dev:
+    ...     dev.baudrate = 115200
+    ...     dev.write('Hello World')
 
-The pylibftdi.BitBang wrapper provides access to the parallel IO mode of
+The pylibftdi.BitBangDevice wrapper provides access to the parallel IO mode of
 operation through the ``port`` and ``direction`` properties.  These provide an
 8 bit IO port including all the relevant bit operations to make things simple.
 
 ::
 
-    >>> from pylibftdi import BitBang
+    >>> from pylibftdi import BitBangDevice
     >>>
-    >>> with BitBang() as bb:
-    >>>     bb.direction = 0x0F  # four LSB are output(1), four MSB are input(0)
-    >>>     bb.port |= 2         # set bit 1
-    >>>     bb.port &= 0xFE      # clear bit 0
+    >>> with BitBangDevice('FTE00P4L') as bb:
+    ...     bb.direction = 0x0F  # four LSB are output(1), four MSB are input(0)
+    ...     bb.port |= 2         # set bit 1
+    ...     bb.port &= 0xFE      # clear bit 0
 
 There is support for a number of external devices and protocols, specifically
 for interfacing with HD44780 LCDs using the 4-bit interface.
     def write_data(self, x):
         self._write_raw(1, x)
 
-def display(string):
-    "Display the given string on an attached LCD"
-    with BitBangDevice() as bb:
+def display(string, device_id=None):
+    """
+    Display the given string on an attached LCD
+    an optional `device_id` can be given.
+    """
+    with BitBangDevice(device_id) as bb:
 
         # These LCDs are quite slow - and the actual baudrate
         # is 16x this in bitbang mode...

pylibftdi/__init__.py

 FtdiError = _base.FtdiError
 Bus = util.Bus
 Driver = driver.Driver
+Device = driver.Device
 BitBangDevice = bitbang.BitBangDevice
 
 ALL_OUTPUTS = bitbang.ALL_OUTPUTS
 
 # LEGACY SUPPORT
 
-#__ALL__.append('BitBangDriver')
-#Driver = driver.Device
-#BitBangDriver = bitbang.BitBangDevice
+class BitBangDriver(bitbang.BitBangDevice):
+    def __init__(self, direction=ALL_OUTPUTS):
+        import warnings
+        warnings.warn('change BitBangDriver reference to BitBangDevice',
+                      DeprecationWarning)
+        return BitBangDevice.__init__(self, direction=direction, lazy_open=True)

pylibftdi/bitbang.py

 
 """
 
-from pylibftdi.driver import Device
+from pylibftdi.driver import Device, FtdiError
 
 ALL_OUTPUTS = 0xFF
 ALL_INPUTS = 0x00
      direction: 8 bit input(0)/output(1) direction control.
      port: 8 bit IO port, as defined by direction.
     """
-    def __init__(self, direction = ALL_OUTPUTS,
+    def __init__(self,
                  device_id = None,
+                 direction = ALL_OUTPUTS,
                  lazy_open = False):
         # initialise the super-class, but don't open yet. We really want
         # two-part initialisation here - set up all the instance variables

pylibftdi/driver.py

 """
 
 import functools
+import warnings
+
 # be disciplined so pyflakes can check us...
 from ctypes import (CDLL, byref, c_int, c_char_p, c_void_p, cast,
                     create_string_buffer, Structure, pointer, POINTER)
             self.fdll = fdll
         self._need_init = False
 
+    ## Legacy support - prior to version 0.7, Device and Driver
+    ## were unified (and named 'Driver'). This provides basic
+    ## backwards compatiblity support.
+    LEGACY_ATTRIBUTES = ['open', 'close', 'ftdi_fn', 'baudrate',
+                         'read', 'write', 'get_error_string',
+                         '__enter__', '__exit__']
+    @property
+    def legacy_device(self):
+        warnings.warn("using Device() methods on Driver(); see CHANGES.txt",
+                DeprecationWarning)
+        if not hasattr(self, '_legacy_device'):
+            self._legacy_device = Device(lazy_open=True)
+        return self._legacy_device
+
+    def __getattr__(self, key):
+        if key in Driver.LEGACY_ATTRIBUTES:
+            return getattr(self.legacy_device, key)
+        else:
+            return object.__getattr__(self, key)
+    def __setattr__(self, key, value):
+        if key in Driver.LEGACY_ATTRIBUTES:
+            return setattr(self.legacy_device, key, value)
+        else:
+            self.__dict__[key] = value
+    def __delattr__(self, key):
+        if key in Driver.LEGACY_ATTRIBUTES:
+            delattr(self.legacy_device, key)
+        else:
+            del self.__dict__[key]
+
     def list_devices(self):
         """
         return a list of triples (manufacturer, description, serial#)
             self.fdll.ftdi_deinit(byref(ctx))
         return devices
 
+
 class Device(object):
     """
     Device([device_id[, mode [, encoding [, lazy_open]]]) -> Device instance
     def close(self):
         "close our connection, free resources"
         if self.opened:
+            self.fdll.ftdi_usb_close(byref(self.ctx))
             self.fdll.ftdi_deinit(byref(self.ctx))
             del self.ctx
         self.opened = False
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.