Commits

Ben Bass committed aac8f24

add bit_server, configurable PID/VID

Comments (0)

Files changed (2)

examples/bit_server.py

+"""
+bit_server.py - remote HTTP interface to bit-bangged FTDI port
+This runs as a web server, connect to port 8008
+
+Change HTTP_PORT for different port number or supply alternate as args[1]
+
+Requires:
+ - pylibftdi
+"""
+
+from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+from cStringIO import StringIO
+from SocketServer import ThreadingMixIn
+import sys
+from pylibftdi import BitBangDevice
+
+HTTP_PORT = 8008
+
+
+class ThreadingServer(ThreadingMixIn, HTTPServer):
+    pass
+
+
+def get_page():
+    port = switch.port
+    page = """
+<!DOCTYPE html>
+<html>
+<head>
+ <title>%s - pylibftdi</title>
+</head>
+<body>
+<div>
+""" % port
+    for i in range(8):
+        bit = 7-i
+        is_on = port & (1 << bit)
+        color = '#00FF00' if is_on else '#FF0000'
+        page += """
+<fieldset style="background-color: %s; display: inline-block; margin:0px; padding: 8px;">
+<form action="" method="post" >
+<input type="checkbox" onchange="document.querySelector('[name=bit%d]').value=this.value; document.forms[%d].submit()" %s />
+<input type="hidden" name="bit%d" />
+</form>
+</fieldset>
+""" % (color, bit, i, 'checked="checked"' if is_on else '', bit)
+    page += """
+</div>
+DATA=%s
+</body>
+</html>
+""" % port
+    return page
+
+class ReqHandler(BaseHTTPRequestHandler):
+    def do_GET(self):
+        f = self.send_head()
+        if f:
+            self.wfile.write(f.read())
+            f.close()
+
+    def do_POST(self):
+        length = self.headers.getheader('content-length')
+        nbytes = int(length)
+        query = self.rfile.read(nbytes)
+        # this is lazy and fragile - assumes only a single
+        # query parameter XXX
+        if query.startswith('bit'):
+            bit = int(query[3])
+            value = 1 if query.rsplit('=', 1)[-1] == 'on' else 0
+            if value:
+                switch.port |= (1 << bit)
+            else:
+                switch.port &= 255^(1 << bit)
+
+        f = self.send_head()
+        if f:
+            self.wfile.write(f.read())
+            f.close()
+
+    def send_head(self):
+        f = StringIO()
+        f.write(get_page())
+        length = f.tell()
+        f.seek(0)
+        self.send_response(200)
+        self.send_header("Content-type", "text/html")
+        self.send_header("Content-Length", str(length))
+        self.end_headers()
+        return f
+
+def runserver(port = HTTP_PORT):
+    serveraddr = ('', port)
+    srvr = ThreadingServer(serveraddr, ReqHandler)
+    srvr.serve_forever()
+
+if __name__ == '__main__':
+    import threading, time, webbrowser
+    switch = BitBangDevice()
+
+    try:
+        HTTP_PORT = int(sys.argv[1])
+    except TypeError:
+        print "Usage: FtdiWebServer [portnumber]"
+    except IndexError:
+        pass
+
+    t = threading.Thread(target = runserver, args = (HTTP_PORT,))
+    t.setDaemon(True)
+    t.start()
+    time.sleep(0.5)
+    retry = 10
+    while retry:
+        try:
+            webbrowser.open('http://localhost:%d'%HTTP_PORT)
+        except EnvironmentError:
+            time.sleep(1)
+            retry -= 1
+        else:
+            break
+
+    # wait for Ctrl-C
+    try:
+        while 1: time.sleep(1)
+    except KeyboardInterrupt:
+        pass

pylibftdi/driver.py

 FLUSH_INPUT = 2
 FLUSH_OUTPUT = 3
 
+USB_VID = 0x0403
+USB_PID = 0x6001
+
 class Driver(object):
     """
     This is where it all happens...
         try:
             res = self.fdll.ftdi_usb_find_all(byref(ctx),
                                               byref(dev_list_ptr),
-                                              0x0403, 0x6001)
+                                              USB_VID, USB_PID)
             if res < 0:
                 raise FtdiError(self.fdll.ftdi_get_error_string(byref(ctx)))
             elif res > 0:
         # they were, but we can't use self.close as that assumes things
         # have already been setup.
         # FTDI vendor/product ids required here.
-        open_args = [byref(self.ctx), 0x0403, 0x6001]
+        open_args = [byref(self.ctx), USB_VID, USB_PID]
         if self.device_id is None:
             res = self.fdll.ftdi_usb_open(*tuple(open_args))
         else: