humpback-dds/nmigen/humpback.py

194 lines
4.2 KiB
Python

# Strongly inspired by the migen build of humpback
# Using STM32 Nucleo-H743ZI2 board
# Note to self: Pin assignment differs from Nucleo-H743ZI
import os
import subprocess
from nmigen.build import *
from nmigen.vendor.lattice_ice40 import *
from nmigen_boards.resources import *
from resources import *
__all__ = ["HumpbackPlatform"]
class HumpbackPlatform(LatticeICE40Platform):
device = "iCE40HX8K" # Using ICE40HX8K-CT256
package = "CT256"
default_clk = "clk25"
resources = [
# Define clock
Resource("clk25", 0, Pins("K9", dir="i"),
Clock(25e6), Attrs(GLOBAL=True, IO_STANDARD="SB_LVCMOS")
),
# Define user LED
Resource("user_led", 0, Pins("H3", dir="o"),
Attrs(IO_STANDARD="SB_LVCMOS")
),
# Define UART interfaces
UARTResource(0,
rx="T11", tx="M13", rts="M15", cts="T10",
attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1)
),
# UART1 interface: Read note for UART interface above
# UART1 interface is broken due to pin rearrangement introduced for Nucleo-H743ZI2
# Uncomment if fixed, or found an alternative (e.g. bit banging UART)
# *UARTResource(1,
# tx="M11", rx="T13", rts="A6", cts="B16",
# attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1)
# ),
# Define SPI interfaces
# Note: Use "role=device" to make humpback a SPI slave
# The ~CS pin is a global pin, but not being configured global.
SPIResource(0,
cs="R2", clk="C8", mosi="N5", miso="T2",
attrs=Attrs(IO_STANDARD="SB_LVCMOS")
),
# Define I2C interface
# Use "role=device" to make humpback a I2C slave
I2CResource(0,
sda="T16", scl="M12",
attrs=Attrs(IO_STANDARD="SB_LVCMOS", PULLUP=1)
),
]
# Using the dict approach in (o)migen
# Note: Numbering is required in nMigen, so some probably meaningful strings/integers are inserted
connectors = [
# EEM0 Connection Interface
Connector("eem", 0, {
"d0_cc_n": "H1",
"d0_cc_p": "J3",
"d1_n" : "B1",
"d1_p" : "F5",
"d2_n" : "C2",
"d2_p" : "C1",
"d3_n" : "D2",
"d3_p" : "F4",
"d4_n" : "D1",
"d4_p" : "G5",
"d5_n" : "E3",
"d5_p" : "G4",
"d6_n" : "E2",
"d6_p" : "H5",
"d7_n" : "F3",
"d7_p" : "G3",
}),
# EEM1 Connection Interface
Connector("eem", 1,
"d0_cc_n": "L3",
"d0_cc_p": "L6",
"d1_n": "F1",
"d1_p": "H6",
"d2_n": "G2",
"d2_p": "H4",
"d3_n": "H2",
"d3_p": "J4",
"d4_n": "J1",
"d4_p": "J2",
"d5_n": "K3",
"d5_p": "K1",
"d6_n": "L1",
"d6_p": "L4",
"d7_n": "M1",
"d7_p": "K4",
}),
# EEM2 Connection Interface
Connector("eem", 2,
"d0_cc_n": "G1",
"d0_cc_p": "J5",
"d1_n": "M2",
"d1_p": "K5",
"d2_n": "N2",
"d2_p": "L7",
"d3_n": "M3",
"d3_p": "M6",
"d4_n": "N3",
"d4_p": "L5",
"d5_n": "M4",
"d5_p": "P1",
"d6_n": "M5",
"d6_p": "P2",
"d7_n": "N4",
"d7_p": "R1",
}),
# STM32 Connection Pins
Connector("stm32", "GPIO", {
"PA0": "A2",
"PA1": "P14",
"PA2": "B8",
"PA3": "L13",
"PA7": "N12",
"PA8": "M9",
"PA9": "P10",
"PA10": "R10",
"PA15": "B14",
"PB0": "A1",
"PB1": "G12",
"PB2": "B6",
"PB6": "A7",
"PB10": "C3",
"PB11": "F7",
"PB12": "B13",
"PB13": "B12",
"PB15": "A11",
"PC0": "L14",
"PC1": "M14",
"PC2": "A9",
"PC3": "M16",
"PC4": "N16",
"PC5": "P16",
"PC6": "B10",
"PC7": "B15",
"PC8": "H16",
"PC9": "J10",
"PC10": "J16",
"PC11": "J15",
"PC12": "K12",
"PD0": "T9",
"PD1": "N9",
"PD2": "K13",
"PD7": "L12",
"PD11": "E5",
"PD12": "D5",
"PD13": "C5",
"PF7": "L9",
"PF8": "L10",
"PF9": "P9",
"PF14": "B9",
"PG0": "M7",
"PG1": "P8",
"PG2": "K14",
"PG3": "K15",
}),
]
# tool chain setup, using default ICE40 HX8K evaluation code
def toolchain_program(self, products, name):
iceprog = os.environ.get("ICEPROG", "iceprog")
with products.extract("{}.bin".format(name)) as bitstream_filename:
subprocess.check_call([iceprog, "-S", bitstream_filename])
if __name__ == "__main__":
from nmigen_boards.test.blinky import *
HumpbackPlatform().build(Blinky(), do_program=False)