Adding support for programming with FPGALink
authorTim 'mithro' Ansell <mithro@mithis.com>
Thu, 2 Jul 2015 14:44:39 +0000 (16:44 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Thu, 2 Jul 2015 14:44:39 +0000 (16:44 +0200)
Steps for getting it set up.

 * Get libfpgalink dependencies
   sudo apt-get install \
      build-essential libreadline-dev libusb-1.0-0-dev python-yaml

 * Build libfpgalink
   wget -qO- http://tiny.cc/msbil | tar zxf -
   cd makestuff; ./scripts/msget.sh makestuff/common
   cd libs; ../scripts/msget.sh libfpgalink
   cd libfpgalink; make deps

 * Convert libfpgalink to python3
   wget -O - http://www.swaton.ukfsn.org/bin/2to3.tar.gz | tar zxf -
   cd examples/python
   cp fpgalink2.py fpgalink3.py
   ../../2to3/2to3 fpgalink3.py | patch fpgalink3.py

 * Set your path's correctly.

   export LD_LIBRARY_PATH=$(pwd)/libfpgalink/lin.x64/rel:$LD_LIBRARY_PATH
   export PYTHON_PATH=$(pwd)/libfpgalink/examples/python:$PYTHON_PATH

mibuild/fpgalink_programmer.py [new file with mode: 0644]
mibuild/xilinx/programmer.py

diff --git a/mibuild/fpgalink_programmer.py b/mibuild/fpgalink_programmer.py
new file mode 100644 (file)
index 0000000..12fcba3
--- /dev/null
@@ -0,0 +1,95 @@
+
+import os
+
+from mibuild.generic_programmer import GenericProgrammer
+from mibuild.xilinx.programmer import _create_xsvf
+
+import fpgalink3
+fpgalink3.flInitialise(0)
+
+
+class FPGALink(GenericProgrammer):
+    """Using the fpgalink library from makestuff
+
+    You will need fpgalink library installed from
+    https://github.com/makestuff/libfpgalink
+    """
+
+    needs_bitreverse = False
+
+    def __init__(self, initial_vidpid=None, pin_cfg="D0D2D3D4",
+                 fpgalink_vidpid="1D50:602B:0002", flash_proxy_basename=None):
+        """
+        Parameters
+        ----------
+        initial_vidpid : string
+            The USB vendor and product id of the device before fpgalink
+            firmware is loaded onto the device.
+
+            Format is vid:pid as 4 digit hex numbers.
+
+        pin_cfg : string
+            FPGALink pin configuration string describing how the JTAG interface
+            is hooked up to the programmer.
+
+        fpgalink_vidpid : string
+            The USB vendor, product and device id of the device after the
+            fpgalink firmware is loaded onto the device.
+
+            Format is vid:pid:did as 4 digit hex numbers.
+            Defaults to 1D50:602B:0002 which is the makestuff FPGALink device.
+        """
+        GenericProgrammer.__init__(self, flash_proxy_basename)
+        self.initial_vidpid = initial_vidpid
+        self.fpgalink_vidpid = fpgalink_vidpid
+        self.pin_cfg = pin_cfg
+
+    def open_device(self):
+        ivp = self.initial_vidpid
+        vp = self.fpgalink_vidpid
+
+        print("Attempting to open connection to FPGALink device", vp, "...")
+        try:
+            handle = fpgalink3.flOpen(self.fpgalink_vidpid)
+        except fpgalink3.FLException as ex:
+            if not ivp:
+                raise FLException(
+                    "Could not open FPGALink device at {0} and"
+                    " no initial VID:PID was supplied".format(vp))
+
+            print("Loading firmware into %s..." % ivp)
+            fpgalink3.flLoadStandardFirmware(ivp, vp)
+
+            print("Awaiting renumeration...")
+            if not fpgalink3.flAwaitDevice(vp, 600):
+                raise fpgalink3.FLException(
+                    "FPGALink device did not renumerate properly"
+                    " as {0}".format(vp))
+
+            print("Attempting to open connection to FPGALink device", vp,
+                  "again...")
+            handle = fpgalink3.flOpen(vp)
+
+        # Only Nero capable hardware support doing programming.
+        assert fpgalink3.flIsNeroCapable(handle)
+        return handle
+
+    def load_bitstream(self, bitstream_file):
+        n = 27
+
+        xsvf_file = os.path.splitext(bitstream_file)[0]+'.xsvf'
+        print("\nGenerating xsvf formatted bitstream")
+        print("="*n)
+        _create_xsvf(bitstream_file, xsvf_file)
+        print("\n"+"="*n+"\n")
+
+        print("Programming %s to device." % xsvf_file)
+        print("="*n)
+        handle = self.open_device()
+        fpgalink3.flProgram(handle, 'J:'+self.pin_cfg, progFile=xsvf_file)
+        print("Programming successful!")
+        print("="*n+"\n")
+        fpgalink3.flClose(handle)
+
+    def flash(self, address, data_file):
+        raise NotImplementedError("Not supported yet.")
index 36667a936085c1b1bfce6d53ae26da807c14a5de..7c76cf2f375167009394642130055fc276def44c 100644 (file)
@@ -70,11 +70,22 @@ class FpgaProg(GenericProgrammer):
 
 
 def _run_impact(cmds):
-    with subprocess.Popen("impact -batch", stdin=subprocess.PIPE) as process:
+    with subprocess.Popen("impact -batch", stdin=subprocess.PIPE, shell=True) as process:
         process.stdin.write(cmds.encode("ASCII"))
         process.communicate()
 
 
+def _create_xsvf(bitstream_file, xsvf_file):
+    _run_impact("""
+setPreference -pref KeepSVF:True
+setMode -bs
+setCable -port xsvf -file {xsvf}
+addDevice -p 1 -file {bitstream}
+program -p 1
+quit
+""".format(bitstream=bitstream_file, xsvf=xsvf_file))
+
+
 class iMPACT(GenericProgrammer):
     needs_bitreverse = False