build/lattice: cleanup/simplify (no functional changes)
[litex.git] / litex / build / lattice / programmer.py
1 # This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
2 # This file is Copyright (c) 2017-2018 William D. Jones <thor0505@comcast.net>
3 # License: BSD
4
5 import os
6 import subprocess
7
8 from litex.build.generic_programmer import GenericProgrammer
9 from litex.build import tools
10
11 # LatticeProgrammer --------------------------------------------------------------------------------
12
13 class LatticeProgrammer(GenericProgrammer):
14 needs_bitreverse = False
15
16 def __init__(self, xcf_template):
17 self.xcf_template = xcf_template
18
19 def load_bitstream(self, bitstream_file):
20 xcf_file = bitstream_file.replace(".bit", ".xcf")
21 xcf_content = self.xcf_template.format(bitstream_file=bitstream_file)
22 tools.write_to_file(xcf_file, xcf_content)
23 subprocess.call(["pgrcmd", "-infile", xcf_file])
24
25 # IceStormProgrammer -------------------------------------------------------------------------------
26
27 class IceStormProgrammer(GenericProgrammer):
28 needs_bitreverse = False
29
30 def flash(self, address, bitstream_file):
31 subprocess.call(["iceprog", "-o", str(address), bitstream_file])
32
33 def load_bitstream(self, bitstream_file):
34 subprocess.call(["iceprog", "-S", bitstream_file])
35
36 # IceBurnProgrammer --------------------------------------------------------------------------------
37
38 class IceBurnProgrammer(GenericProgrammer):
39 def __init__(self, iceburn_path):
40 GenericProgrammer.__init__(self)
41 self.iceburn = iceburn_path
42
43 needs_bitreverse = False
44
45 def load_bitstream(self, bitstream_file):
46 subprocess.call([self.iceburn, "-evw", bitstream_file])
47
48 # TinyFpgaBProgrammer ------------------------------------------------------------------------------
49
50 class TinyFpgaBProgrammer(GenericProgrammer):
51 needs_bitreverse = False
52
53 # The default flash address you probably want is 0x30000; the image at
54 # address 0 is for the bootloader.
55 def flash(self, address, bitstream_file):
56 subprocess.call(["tinyfpgab", "-a", str(address), "-p",
57 bitstream_file])
58
59 # Force user image to boot if a user reset tinyfpga, the bootloader
60 # is active, and the user image need not be reprogrammed.
61 def boot(self):
62 subprocess.call(["tinyfpgab", "-b"])
63
64 # TinyProgProgrammer -------------------------------------------------------------------------------
65
66 # Different bootloader protocol requires different application. In the basic
67 # case, command-line arguments are the same. Note that this programmer can
68 # also be used with TinyFPGA B2 if you have updated its bootloader.
69 class TinyProgProgrammer(GenericProgrammer):
70 needs_bitreverse = False
71
72 # You probably want to pass address="None" for this programmer
73 # unless you know what you're doing.
74 def flash(self, address, bitstream_file, user_data=False):
75 if address is None:
76 if not user_data:
77 # tinyprog looks at spi flash metadata to figure out where to
78 # program your bitstream.
79 subprocess.call(["tinyprog", "-p", bitstream_file])
80 else:
81 # Ditto with user data.
82 subprocess.call(["tinyprog", "-u", bitstream_file])
83 else:
84 # Provide override so user can program wherever they wish.
85 subprocess.call(["tinyprog", "-a", str(address), "-p",
86 bitstream_file])
87
88 # Force user image to boot if a user reset tinyfpga, the bootloader
89 # is active, and the user image need not be reprogrammed.
90 def boot(self):
91 subprocess.call(["tinyprog", "-b"])
92
93 # MyStormProgrammer --------------------------------------------------------------------------------
94
95 class MyStormProgrammer(GenericProgrammer):
96 def __init__(self, serial_port):
97 self.serial_port = serial_port
98
99 def load_bitstream(self, bitstream_file):
100 import serial
101 with serial.Serial(self.serial_port) as port:
102 with open(bitstream_file, "rb") as f:
103 port.write(f.read())