|
| 1 | +import os |
| 2 | +import argparse |
| 3 | +import subprocess |
| 4 | + |
| 5 | + |
| 6 | +from amaranth.build import * |
| 7 | +from amaranth.vendor import LatticeMachXO2Platform |
| 8 | +from .resources import * |
| 9 | + |
| 10 | + |
| 11 | +__all__ = ["StepMXO2Platform"] |
| 12 | + |
| 13 | + |
| 14 | +class StepMXO2Platform(LatticeMachXO2Platform): |
| 15 | + package = "MG132" |
| 16 | + speed = "4" |
| 17 | + default_clk = "clk12" |
| 18 | + device = "LCMXO2-4000HC" |
| 19 | + resources = [ |
| 20 | + Resource("clk12", 0, Pins("C1", dir="i"), Attrs(IO_TYPE="LVCMOS33"), |
| 21 | + Clock(12e6)), |
| 22 | + |
| 23 | + UARTResource(0, rx="A3", tx="A2", attrs=Attrs(IO_TYPE="LVCMOS33"), |
| 24 | + role="dce"), |
| 25 | + |
| 26 | + *LEDResources(pins="N13 M12 P12 M11 P11 N10 N9 P9", |
| 27 | + invert=True, attrs=Attrs(IO_TYPE="LVCMOS33")), |
| 28 | + |
| 29 | + RGBLEDResource(0, r="M2", g="N2", b="P2", |
| 30 | + invert=True, attrs=Attrs(IO_TYPE="LVCMOS33")), |
| 31 | + RGBLEDResource(1, r="M3", g="N3", b="P4", |
| 32 | + invert=True, attrs=Attrs(IO_TYPE="LVCMOS33")), |
| 33 | + |
| 34 | + *ButtonResources(pins="L14 M13 M14 N14", invert=True, |
| 35 | + attrs=Attrs(IO_TYPE="LVCMOS33")), |
| 36 | + |
| 37 | + *SwitchResources(pins="M7 M8 M9 M10", |
| 38 | + attrs=Attrs(IO_TYPE="LVCMOS33")), |
| 39 | + |
| 40 | + Display7SegResource(0, |
| 41 | + a="A10", b="C11", c="F2", d="E1", e="E2", f="A9", g="B9", dp="F1", |
| 42 | + attrs=Attrs(IO_TYPE="LVCMOS33") |
| 43 | + ), |
| 44 | + Display7SegResource(1, |
| 45 | + a="C12", b="B14", c="J1", d="H1", e="H2", f="B12", g="A11", |
| 46 | + dp="K1", attrs=Attrs(IO_TYPE="LVCMOS33") |
| 47 | + ), |
| 48 | + Resource("display_7seg_ctrl", 0, |
| 49 | + Subsignal("en", Pins("C9 A12", invert=True, dir="o")), |
| 50 | + Attrs(IO_TYPE="LVCMOS33") |
| 51 | + ) |
| 52 | + ] |
| 53 | + connectors = [ |
| 54 | + # Special pins for MachXO2 hard IP. |
| 55 | + # I2C: 2- SCL, 3- SDA |
| 56 | + # SPI: 25- CS_N, 24- CLK, 22- COPI, 23- CIPO |
| 57 | + Connector("gpio", 0, |
| 58 | + # Left side of the board |
| 59 | + # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
| 60 | + " - C8 B8 E3 F3 G3 H3 I2 I3 K2 K3 L3 N5 P6 N6 P7 N7 P8 N8 -" |
| 61 | + # Right side of the board |
| 62 | + # 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
| 63 | + " - P13 N4 M4 P3 J12 K13 K14 K12 J14 J13 H12 G14 G13 F14 F13 G12 F12 E12 -" |
| 64 | + ), |
| 65 | + ] |
| 66 | + |
| 67 | + # This board doesn't have an integrated programmer; the board's MCU |
| 68 | + # implements a mass-storage device. You copy the JED file to it. |
| 69 | + |
| 70 | + # Workaround a STEP-MXO2-LPC parsing bug in the bootloader, as it doesn't |
| 71 | + # like JED files processed by ddtcmd. Copy the original JED file unchanged |
| 72 | + # to {{name}}-lpc.jed. Prefer this file. |
| 73 | + @property |
| 74 | + def command_templates(self): |
| 75 | + templates = super().command_templates |
| 76 | + cp_template = r"""{%- if syntax == "sh" -%} |
| 77 | + cp {{name}}_impl/{{name}}_impl.jed {{name}}-lpc.jed |
| 78 | + {%- else -%} |
| 79 | + copy {{name}}_impl\{{name}}_impl.jed {{name}}-lpc.jed |
| 80 | + {%- endif -%} |
| 81 | + """ |
| 82 | + |
| 83 | + if self.family == "machxo2": |
| 84 | + if self.toolchain == "Diamond": |
| 85 | + return templates + [cp_template] |
| 86 | + if self.toolchain == "Trellis": |
| 87 | + return self.templates |
| 88 | + assert False |
| 89 | + assert False |
| 90 | + |
| 91 | + |
| 92 | +if __name__ == "__main__": |
| 93 | + from .test.blinky import * |
| 94 | + |
| 95 | + parser = argparse.ArgumentParser() |
| 96 | + parser.add_argument('toolchain', nargs="?", choices=["Trellis", "Diamond"], default="Diamond") |
| 97 | + args = parser.parse_args() |
| 98 | + |
| 99 | + StepMXO2Platform(toolchain=args.toolchain).build(Blinky(), do_program=False) |
0 commit comments