Commits

Ben Bass committed 927fe8f

multi-interface device support

Comments (0)

Files changed (5)

     <various output stuff>
     $ cd pylibftdi
     $ python -m unittest discover
-    ...............
+    ................
     ----------------------------------------------------------------------
-    Ran 15 tests in 0.025s
+    Ran 16 tests in 0.025s
 
     OK
     $
 
+How do I use multi-port devices?
+--------------------------------
+
+Use the ``interface`` parameter to the Device (or BitBangDevice) class.
+The value should be one of the following values:
+
+    =================== =============
+    ``interface`` value Meaning
+    ------------------- -------------
+    0                   Any interface
+    1                   INTERFACE A
+    2                   INTERFACE B
+    3                   INTERFACE C
+    4                   INTERFACE D
+    =================== =============
+
+You should be able to open multiple ``Device``\s with different
+``interface`` settings, though I haven't got multi-interface devices
+to test against at the moment, so can't yet confirm this.

pylibftdi/bitbang.py

                  device_id=None,
                  direction=ALL_OUTPUTS,
                  lazy_open=False,
-                 sync=True):
+                 sync=True,
+                 bitbang_mode=BITMODE_BITBANG,
+                 interface=None):
         # 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
         # of our own variables.
         super(BitBangDevice, self).__init__(device_id=device_id,
                                             mode='b',
-                                            lazy_open=True)
+                                            lazy_open=True,
+                                            interface=interface)
         self.direction = direction
         self.sync = sync
+        self.bitbang_mode = bitbang_mode
         self._last_set_dir = None
         self._latch = 0
         if not lazy_open:
             raise FtdiError("invalid direction bitmask")
         self._direction = dir
         if not self.closed:
-            self.ftdi_fn.ftdi_set_bitmode(dir, BITMODE_BITBANG)
+            self.ftdi_fn.ftdi_set_bitmode(dir, self.bitbang_mode)
             self._last_set_dir = dir
 
     # port property - 8 bit read/write value
         """
         if self.sync:
             pin_byte = c_ubyte()
-            res = self.fdll.ftdi_read_pins(self.ctx, byref(pin_byte))
+            res = self.ftdi_fn.ftdi_read_pins(byref(pin_byte))
             if res != 0:
                 raise FtdiError("Could not read device pins")
             result = pin_byte.value

pylibftdi/driver.py

     """
     def __init__(self, device_id=None, mode="b",
                  encoding="latin1", lazy_open=False,
-                 buffer_size=0):
+                 buffer_size=0, interface=None):
         self._opened = False
         self.driver = Driver()
         self.fdll = self.driver.fdll
         # buffer_size (if not 0) chunks the reads and writes
         # to allow interruption
         self.buffer_size = buffer_size
+        # interface can be set for devices which have multiple interface
+        # ports (e.g. FT4232, FT2232)
+        self.interface = interface
         # lazy_open tells us not to open immediately.
         if not lazy_open:
             self.open()
             del self.ctx
             raise FtdiError(msg)
 
+        if self.interface is not None:
+            self.fdll.ftdi_set_interface(byref(self.ctx), self.interface)
+
         # Try to open the device.  If this fails, reset things to how
         # they were, but we can't use self.close as that assumes things
         # have already been setup.

tests/test_common.py

         fn()
         self.assertIn(methodname, CallLog.get())
 
+    def assertNotCalls(self, fn, methodname):
+        CallLog.reset()
+        fn()
+        self.assertNotIn(methodname, CallLog.get())
+
     def assertCallsExact(self, fn, call_list):
         CallLog.reset()
         fn()

tests/test_driver.py

         self.assertCalls(lambda: Device(), 'ftdi_usb_open')
         # and given a device_id, it should do a open_desc
         self.assertCalls(lambda: Device('bogus'), 'ftdi_usb_open_desc')
+        # check that opening a specific interface does that
+
+    def testOpenInterface(self):
+        self.assertCalls(lambda: Device(interface=1), 'ftdi_set_interface')
+        # check that opening a specific interface does that
+        self.assertNotCalls(lambda: Device(), 'ftdi_set_interface')
 
     def testReadWrite(self):
         with Device() as dev:
         self.assertEqual(d.readline(), 'Bye')
 
 
-
 if __name__ == "__main__":
     unittest.main()