Commits

Ben Bass committed de3cd8f

add initial test framework, flush methods, open by desc

Comments (0)

Files changed (4)

pylibftdi/__init__.py

 rather than a problem with the libftdi library.
 """
 
-__VERSION__ = "0.7"
+__VERSION__ = "0.8"
 __AUTHOR__ = "Ben Bass"
 
 
 ALL_INPUTS = bitbang.ALL_INPUTS
 BB_OUTPUT = bitbang.BB_OUTPUT
 BB_INPUT = bitbang.BB_INPUT
-
+FLUSH_BOTH = driver.FLUSH_BOTH
+FLUSH_INPUT = driver.FLUSH_INPUT
+FLUSH_OUTPUT = driver.FLUSH_OUTPUT
 
 # LEGACY SUPPORT
 

pylibftdi/driver.py

 # ftdi_deinit() pair to manage the driver resources. It's very nice
 # how layered the libftdi code is, with access to each layer.
 
+# These constants determine what type of flush operation to perform
+FLUSH_BOTH = 1
+FLUSH_INPUT = 2
+FLUSH_OUTPUT = 3
+
 class Driver(object):
     """
     This is where it all happens...
         if self.device_id is None:
             res = self.fdll.ftdi_usb_open(*tuple(open_args))
         else:
+            # attempt to match device_id to serial number
             open_args.extend([0, c_char_p(self.device_id.encode('latin1'))])
             res = self.fdll.ftdi_usb_open_desc(*tuple(open_args))
+            if res != 0:
+                # swap last two parameters and try again
+                #  - attempt to match device_id to description
+                open_args[-2:] = open_args[-1:-3:-1]
+                res = self.fdll.ftdi_usb_open_desc(*tuple(open_args))
 
         if res != 0:
             msg = self.get_error_string()
             raise FtdiError(self.get_error_string())
         return written
 
+    def flush(self, flush_what=FLUSH_BOTH):
+        """
+        Instruct the FTDI device to flush its FIFO buffers
+
+        By default both the input and output buffers will be
+        flushed, but the caller can selectively chose to only
+        flush the input or output buffers using `flush_what`:
+          FLUSH_BOTH - (default)
+          FLUSH_INPUT - (just the rx buffer)
+          FLUSH_OUTPUT - (just the tx buffer)
+        """
+        if flush_what == FLUSH_BOTH:
+            fn = self.fdll.ftdi_usb_purge_buffers
+        elif flush_what == FLUSH_INPUT:
+            fn = self.fdll.ftdi_usb_purge_rx_buffer
+        elif flush_what == FLUSH_OUTPUT:
+            fn = self.fdll.ftdi_usb_purge_tx_buffer
+        else:
+            raise ValueError("Invalid value passed to %s.flush()" %
+                    self.__class__.__name__)
+        res = fn(byref(self.ctx))
+        if res != 0:
+            raise FtdiError(self.get_error_string())
+
+    def flush_input(self):
+        """
+        flush the device input buffer
+        """
+        self.flush(FLUSH_INPUT)
+
+    def flush_output(self):
+        """
+        flush the device output buffer
+        """
+        self.flush(FLUSH_OUTPUT)
 
     def get_error_string(self):
         "return error string from libftdi driver"
         return self.fdll.ftdi_get_error_string(byref(self.ctx))
 
-
     @property
     def ftdi_fn(self):
         """

pylibftdi/test_driver.py

+
+
+import pylibftdi.driver
+
+fn_log = []
+class SimpleMock(object):
+    def __init__(self, name="<base>"):
+        self.__name = name
+
+    def __getattr__(self, key):
+        return self.__dict__.get(key, SimpleMock(key))
+
+    def __setattr__(self, key, value):
+        return self.__dict__.setdefault(key, value)
+
+    def __call__(self, *o, **k):
+        fn_log.append(self.__name)
+        print("%s(*%s, **%s)" % (self.__name, o, k))
+        return 0
+
+class Driver(object):
+    def __init__(self, *o, **k):
+        self.fdll = SimpleMock()
+
+def assertCalls(fn, methodname):
+    del fn_log[:]
+    fn()
+    assert methodname in fn_log
+
+pylibftdi.driver.Driver = Driver
+
+from pylibftdi import Device
+
+with Device() as dev:
+    assertCalls(lambda : dev.write('xxx'), 'ftdi_write_data')
+    assertCalls(lambda : dev.read(10), 'ftdi_read_data')
+    assertCalls(dev.flush_input, 'ftdi_usb_purge_rx_buffer')
+    assertCalls(dev.flush_output, 'ftdi_usb_purge_tx_buffer')
+    assertCalls(dev.flush, 'ftdi_usb_purge_buffers')
+
+
 
 setup(
     name="pylibftdi",
-    version="0.7",
+    version="0.8",
     description="Pythonic interface to FTDI devices using libftdi",
     long_description=open('README.txt').read(),
     author="Ben Bass",
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.