Commits

Ben Bass committed 5793439

make the pin_read script useful - add mask/match etc

Comments (0)

Files changed (2)

pylibftdi/examples/pin_read.py

+#!/usr/bin/env python
 """
 Display values on input pins of a BitBangDevice.
 
-TODO: add configurable delay, display differences in bold
-(make command line options compatible with 'watch')
+TODO:
+ * ANSI colours / display differences in bold
+
+example - beep on pin 1 going high:
+    $ pylibftdi/examples/pin_read.py -n 0.01 -m 1 -k 1 && echo -e "\a"
 
 Copyright (c) 2011-2012 Ben Bass <benbass@codedstructure.net>
 All rights reserved.
 """
 
-from pylibftdi import BitBangDevice, ALL_INPUTS
+import itertools
 import time
 import sys
+from pylibftdi import BitBangDevice, ALL_INPUTS
 
-d = BitBangDevice(direction=ALL_INPUTS)
 
-while True:
-    time.sleep(0.01)
-    value = d.port
+def get_value():
+    """
+    get the value of the pins
+    """
+    if not getattr(get_value, "dev", None):
+        get_value.dev = BitBangDevice(direction=ALL_INPUTS)
+    dev = getattr(get_value, "dev")
+    return dev.port
+
+
+def display_value(value):
+    """
+    display the given value
+    """
     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()
+
+
+def display_loop(interval=1, count=0, match=None, mask=0xFF):
+    """
+    display and compare the value
+
+    @param interval - polling interval in seconds
+    @param count - number of polls to do, or infinite if 0
+    @param match - value to look for to exit early
+    @param mask - mask of read value before comparing to match
+    @return bool - 'ok'. either a match was made or none was requested
+    """
+    if not count:
+        count_iter = itertools.count()
+    else:
+        count_iter = range(count)
+
+    try:
+        for _ in count_iter:
+            value = get_value()
+            display_value(value)
+            if match is not None and (value & mask == match):
+                return True
+            time.sleep(interval)
+        return False
+    except KeyboardInterrupt:
+        pass
+    finally:
+        sys.stdout.write('\n')
+
+    if match is not None:
+        # we quit early while looking for a match
+        return False
+    else:
+        # no match to do; no problem.
+        return True
+
+
+def main(args=None):
+    import optparse
+    parser = optparse.OptionParser()
+    parser.add_option("-n", "--interval", dest="interval",
+                      default=1, type=float,
+                      help="refresh interval, default 1 second")
+    parser.add_option("-c", "--count", dest="count",
+        default=0, type=int,
+        help="number of cycles to run for (0 = no limit - the default)")
+    parser.add_option("-m", "--match", dest="match",
+        help="value to match against (e.g. 0x1F, 7, etc)")
+    parser.add_option("-k", "--mask", dest="mask",
+        help="mask to match with (e.g. 0x07, 2, etc) - default 0xFF")
+    opts, args = parser.parse_args(args)
+
+    if opts.interval < 0.001:
+        parser.error("interval must be >= 0.001")
+    if opts.count < 0:
+        parser.error("count must be >= 0")
+    mask = match = None
+    if opts.mask:
+        if not opts.match:
+            parser.error("Must specify --match with mask")
+        try:
+            mask = int(opts.mask, 0)
+        except ValueError:
+            parser.error("Could not interpret given mask")
+    else:
+        mask = 0xFF
+    if opts.match:
+        try:
+            match = int(opts.match, 0)
+        except ValueError:
+            parser.error("Could not interpret given mask")
+    ok = display_loop(opts.interval, opts.count, match, mask)
+    sys.exit(0 if ok else 1)
+
+
+if __name__ == '__main__':
+    main()

pylibftdi/tests/test_bitbang.py

             self.assertCalls(lambda: _(port_test), 'ftdi_write_data')
             self.assertEqual(dev._latch, port_test)
             self.assertEqual(dev.port, port_test)
-        # XXX: this is incomplete.
+        # TODO: this is incomplete.
         # could check for various directions and how that impacts
         # port read / write, as well as r/m/w operations.