diff --git a/litex/boards/platforms/tinyfpga_bx.py b/litex/boards/platforms/tinyfpga_bx.py new file mode 100644 index 000000000..0c022817a --- /dev/null +++ b/litex/boards/platforms/tinyfpga_bx.py @@ -0,0 +1,61 @@ +from litex.build.generic_platform import * +from litex.build.lattice import LatticePlatform +from litex.build.lattice.programmer import TinyProgProgrammer + +_io = [ + ("user_led", 0, Pins("B3"), IOStandard("LVCMOS33")), + + ("usb", 0, + Subsignal("d_p", Pins("B4")), + Subsignal("d_n", Pins("A4")), + Subsignal("pullup", Pins("A3")), + IOStandard("LVCMOS33") + ), + + ("spiflash", 0, + Subsignal("cs_n", Pins("F7"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("G7"), IOStandard("LVCMOS33")), + Subsignal("mosi", Pins("G6"), IOStandard("LVCMOS33")), + Subsignal("miso", Pins("H7"), IOStandard("LVCMOS33")), + Subsignal("wp", Pins("H4"), IOStandard("LVCMOS33")), + Subsignal("hold", Pins("J8"), IOStandard("LVCMOS33")) + ), + + ("spiflash4x", 0, + Subsignal("cs_n", Pins("F7"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("G7"), IOStandard("LVCMOS33")), + Subsignal("dq", Pins("G6 H7 H4 J8"), IOStandard("LVCMOS33")) + ), + + ("clk16", 0, Pins("B2"), IOStandard("LVCMOS33")) +] + +_connectors = [ + # A2-H2, Pins 1-13 + # H9-A6, Pins 14-24 + # G1-J2, Pins 25-31 + ("GPIO", "A2 A1 B1 C2 C1 D2 D1 E2 E1 G2 H1 J1 H2 H9 D9 D8 C9 A9 B8 A8 B7 A7 B6 A6"), + ("EXTRA", "G1 J3 J4 G9 J9 E8 J2") +] + + +# Default peripherals +serial = [ + ("serial", 0, + Subsignal("tx", Pins("GPIO:0")), + Subsignal("rx", Pins("GPIO:1")), + IOStandard("LVCMOS33") + ) +] + + +class Platform(LatticePlatform): + default_clk_name = "clk16" + default_clk_period = 62.5 + + def __init__(self): + LatticePlatform.__init__(self, "ice40-lp8k-cm81", _io, _connectors, + toolchain="icestorm") + + def create_programmer(self): + return TinyProgProgrammer() diff --git a/litex/build/lattice/programmer.py b/litex/build/lattice/programmer.py index e9e5791b4..6b066cf28 100644 --- a/litex/build/lattice/programmer.py +++ b/litex/build/lattice/programmer.py @@ -56,3 +56,31 @@ class TinyFpgaBProgrammer(GenericProgrammer): # is active, and the user image need not be reprogrammed. def boot(self): subprocess.call(["tinyfpgab", "-b"]) + + +# Different bootloader protocol requires different application. In the basic +# case, command-line arguments are the same. Note that this programmer can +# also be used with TinyFPGA B2 if you have updated its bootloader. +class TinyProgProgrammer(GenericProgrammer): + needs_bitreverse = False + + # You probably want to pass address="None" for this programmer + # unless you know what you're doing. + def flash(self, address, bitstream_file, user_data=False): + if address is None: + if not user_data: + # tinyprog looks at spi flash metadata to figure out where to + # program your bitstream. + subprocess.call(["tinyprog", "-p", bitstream_file]) + else: + # Ditto with user data. + subprocess.call(["tinyprog", "-u", bitstream_file]) + else: + # Provide override so user can program wherever they wish. + subprocess.call(["tinyprog", "-a", str(address), "-p", + bitstream_file]) + + # Force user image to boot if a user reset tinyfpga, the bootloader + # is active, and the user image need not be reprogrammed. + def boot(self): + subprocess.call(["tinyprog", "-b"])