Merge pull request #597 from antmicro/jboc/litex-buildenv-add-adapter-fix
[litex.git] / litex / build / lattice / programmer.py
index 6b066cf2804caa33488a52f06ce80bd96c8df8a8..96204e189c67f783f6f11a3cdc26e2c342953e66 100644 (file)
@@ -1,9 +1,14 @@
+# This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
+# This file is Copyright (c) 2017-2018 William D. Jones <thor0505@comcast.net>
+# License: BSD
+
 import os
 import subprocess
 
 from litex.build.generic_programmer import GenericProgrammer
 from litex.build import tools
 
+# LatticeProgrammer --------------------------------------------------------------------------------
 
 class LatticeProgrammer(GenericProgrammer):
     needs_bitreverse = False
@@ -11,16 +16,42 @@ class LatticeProgrammer(GenericProgrammer):
     def __init__(self, xcf_template):
         self.xcf_template = xcf_template
 
-    def load_bitstream(self, bitstream_file, toolchain_path=''):
+    def load_bitstream(self, bitstream_file):
         xcf_file = bitstream_file.replace(".bit", ".xcf")
         xcf_content = self.xcf_template.format(bitstream_file=bitstream_file)
         tools.write_to_file(xcf_file, xcf_content)
-        if toolchain_path:
-            pgrcmd = os.path.join(toolchain_path, 'bin/lin64/pgrcmd')
-        else:
-            pgrcmr = 'pgrcmr'
-        subprocess.call([pgrcmd, "-infile", xcf_file])
+        subprocess.call(["pgrcmd", "-infile", xcf_file])
+
+# OpenOCDJTAGProgrammer --------------------------------------------------------------------------------
 
+class OpenOCDJTAGProgrammer(GenericProgrammer):
+    def __init__(self, config, flash_proxy_basename=None):
+        GenericProgrammer.__init__(self, flash_proxy_basename)
+        self.config = config
+
+    def load_bitstream(self, bitstream_file):
+        config   = self.find_config()
+        svf_file = bitstream_file.replace(".bit", ".svf")
+        subprocess.call(["openocd", "-f", config, "-c", "transport select jtag; init; svf quiet progress \"{}\"; exit".format(svf_file)])
+
+    def flash(self, address, data, verify=True):
+        config      = self.find_config()
+        flash_proxy = self.find_flash_proxy()
+        script = "; ".join([
+            "transport select jtag",
+            "target create ecp5.spi0.proxy testee -chain-position ecp5.tap",
+            "flash bank spi0 jtagspi 0 0 0 0 ecp5.spi0.proxy 0x32",
+            "init",
+            "svf quiet progress \"{}\"".format(flash_proxy),
+            "reset halt",
+            "flash probe spi0",
+            "flash write_image erase \"{0}\" 0x{1:x}".format(data, address),
+            "flash verify_bank spi0 \"{0}\" 0x{1:x}" if verify else "".format(data, address),
+            "exit"
+        ])
+        subprocess.call(["openocd", "-f", config, "-c", script])
+
+# IceStormProgrammer -------------------------------------------------------------------------------
 
 class IceStormProgrammer(GenericProgrammer):
     needs_bitreverse = False
@@ -31,6 +62,7 @@ class IceStormProgrammer(GenericProgrammer):
     def load_bitstream(self, bitstream_file):
         subprocess.call(["iceprog", "-S", bitstream_file])
 
+# IceBurnProgrammer --------------------------------------------------------------------------------
 
 class IceBurnProgrammer(GenericProgrammer):
     def __init__(self, iceburn_path):
@@ -42,6 +74,7 @@ class IceBurnProgrammer(GenericProgrammer):
     def load_bitstream(self, bitstream_file):
         subprocess.call([self.iceburn, "-evw", bitstream_file])
 
+# TinyFpgaBProgrammer ------------------------------------------------------------------------------
 
 class TinyFpgaBProgrammer(GenericProgrammer):
     needs_bitreverse = False
@@ -57,6 +90,7 @@ class TinyFpgaBProgrammer(GenericProgrammer):
     def boot(self):
         subprocess.call(["tinyfpgab", "-b"])
 
+# TinyProgProgrammer -------------------------------------------------------------------------------
 
 # Different bootloader protocol requires different application. In the basic
 # case, command-line arguments are the same. Note that this programmer can
@@ -84,3 +118,23 @@ class TinyProgProgrammer(GenericProgrammer):
     # is active, and the user image need not be reprogrammed.
     def boot(self):
         subprocess.call(["tinyprog", "-b"])
+
+# MyStormProgrammer --------------------------------------------------------------------------------
+
+class MyStormProgrammer(GenericProgrammer):
+    def __init__(self, serial_port):
+        self.serial_port = serial_port
+
+    def load_bitstream(self, bitstream_file):
+        import serial
+        with serial.Serial(self.serial_port) as port:
+            with open(bitstream_file, "rb") as f:
+                port.write(f.read())
+
+# UJProg -------------------------------------------------------------------------------------------
+
+class UJProg(GenericProgrammer):
+    needs_bitreverse = False
+
+    def load_bitstream(self, bitstream_file):
+        subprocess.call(["ujprog", bitstream_file])