Addition of USB ACM for ECP5

This commit is contained in:
Dave Marples 2020-04-14 13:53:46 +01:00
parent a12faae0fb
commit 389e8aa13a
6 changed files with 104 additions and 16 deletions

View File

@ -172,6 +172,13 @@ _io_v7_0 = [ # Documented by @miek
Subsignal("tx_data", Pins("T14 R12 R13 R14")),
IOStandard("LVCMOS33")
),
("usb", 0,
Subsignal("d_p", Pins("M8")),
Subsignal("d_n", Pins("R2")),
Subsignal("pullup", Pins("P4")),
IOStandard("LVCMOS33")
),
]
# from https://github.com/miek/chubby75/blob/5a-75b-v7_pinout/5a-75b/hardware_V6.1.md

View File

@ -84,6 +84,13 @@ _io = [
Subsignal("n", Pins("C10")),
IOStandard("LVCMOS33")
),
("usb", 0,
Subsignal("d_p", Pins("D15")),
Subsignal("d_n", Pins("E15")),
Subsignal("pullup", Pins("B12 C12")),
IOStandard("LVCMOS33")
),
]
# Platform -----------------------------------------------------------------------------------------

View File

@ -0,0 +1,26 @@
USB
===
USB support has been integrated for the V7.0 this board. Supporting other
versions should be trivial and just need pinning changes. To build with
usb support just do;
./colourlight_5a_75b.py --uart-name=usb_cdc
To install onto the board;
./colourlight_5a_75b.py --load
The USB Serial connection will appear as /dev/ttyACMx, or equivalent on your OS.
Pinning for V7.0;
* Replace U23 with a SN74CBT3245APWR, or remove U23 and place jumper wires.
(You're basically making the ports Bi-directional).
* Place a 15K resistor between J4 pin 2 and J4 pin 4.
* Place a 15K resistor between J4 pin 3 and J4 pin 4.
* Place a 1.5K resistor between J4 pin 1 and J4 pin 3.
* Connect USB DP (Green) to J4 pin 3, USB DN (White) to J4 pin 2.

View File

@ -0,0 +1,11 @@
USB
===
USB support has been integrated and tested for V3.0.3 this board. Revisions
higher than this should be supported. The USB connection is on US2.
To build with usb support just do;
./ulx3s.py --uart-name=usb_cdc
The USB Serial connection will appear as /dev/ttyACMx, or equivalent on your OS.

View File

@ -48,7 +48,7 @@ from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq, with_rst=True):
def __init__(self, platform, sys_clk_freq, with_usb_pll=False, with_rst=True):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys_ps = ClockDomain()
@ -67,22 +67,34 @@ class _CRG(Module):
pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.
self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll.locked | ~rst_n)
# USB PLL
if with_usb_pll:
self.submodules.usb_pll = usb_pll = ECP5PLL()
usb_pll.register_clkin(clk25, 25e6)
self.clock_domains.cd_usb_12 = ClockDomain()
self.clock_domains.cd_usb_48 = ClockDomain()
usb_pll.create_clkout(self.cd_usb_12, 12e6, margin=0)
usb_pll.create_clkout(self.cd_usb_48, 48e6, margin=0)
#self.comb += self.cd_usb_48.clk.eq(self.cd_sys.clk)
# SDRAM clock
self.specials += DDROutput(1, 0, platform.request("sdram_clock"), ClockSignal("sys_ps"))
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, revision, with_ethernet=False, with_etherbone=False, **kwargs):
def __init__(self, revision, with_ethernet=False, with_etherbone=False, sys_clk_freq=60e6, **kwargs):
platform = colorlight_5a_75b.Platform(revision=revision)
sys_clk_freq = int(125e6) if with_etherbone else int(60e6)
if (with_etherbone):
sys_clk_freq = int(125e6)
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs)
# CRG --------------------------------------------------------------------------------------
with_rst = kwargs["uart_name"] not in ["serial", "bridge"] # serial_rx shared with user_btn_n.
self.submodules.crg = _CRG(platform, sys_clk_freq, with_rst=with_rst)
with_usb_pll = kwargs.get("uart_name", None) == "usb_cdc"
self.submodules.crg = _CRG(platform, sys_clk_freq, with_usb_pll=with_usb_pll,with_rst=with_rst)
# SDR SDRAM --------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
@ -115,21 +127,33 @@ class BaseSoC(SoCCore):
# Load ---------------------------------------------------------------------------------------------
def load():
def load(iface="ftdi"):
import os
f = open("openocd.cfg", "w")
f.write(
"""
interface ftdi
if (iface == "ftdi"):
f.write(
"""adapter driver ftdi
ftdi_vid_pid 0x0403 0x6011
ftdi_channel 0
ftdi_layout_init 0x0098 0x008b
reset_config none
adapter_khz 25000
adapter speed 25000
jtag newtap ecp5 tap -irlen 8 -expected-id 0x41111043
""")
elif (iface=="jlink"):
f.write("""adapter driver jlink
transport select jtag
reset_config none
telnet_port 4444
adapter speed 10000
jtag newtap lfe5u25 tap -irlen 8 -irmask 0xFF -ircapture 0x5 -expected-id 0x41111043
""")
else:
print("Unrecognised jtag interface")
exit()
f.close()
os.system("openocd -f openocd.cfg -c \"transport select jtag; init; svf soc_basesoc_colorlight_5a_75b/gateware/top.svf; exit\"")
os.system("openocd -f openocd.cfg -c \"transport select jtag; init; svf -tap lfe5u25.tap -quiet -progress soc_basesoc_colorlight_5a_75b/gateware/top.svf; exit\"")
exit()
# Build --------------------------------------------------------------------------------------------
@ -144,15 +168,20 @@ def main():
parser.add_argument("--with-etherbone", action="store_true", help="enable Etherbone support")
parser.add_argument("--eth-phy", default=0, type=int, help="Ethernet PHY 0 or 1 (default=0)")
parser.add_argument("--load", action="store_true", help="load bitstream")
parser.add_argument("--iface", default="ftdi", help="loading jtag interface")
parser.add_argument("--sys-clk-freq", default=60e6,
help="system clock frequency (default=60MHz)")
args = parser.parse_args()
if args.load:
load()
load(iface=args.iface)
assert not (args.with_ethernet and args.with_etherbone)
soc = BaseSoC(revision=args.revision,
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
sys_clk_freq = args.sys_clk_freq,
**soc_core_argdict(args))
builder = Builder(soc, **builder_argdict(args))
builder.build(**trellis_argdict(args))

View File

@ -27,7 +27,7 @@ from litedram.phy import GENSDRPHY
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq):
def __init__(self, platform, sys_clk_freq, with_usb_pll=False):
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True)
@ -42,10 +42,17 @@ class _CRG(Module):
self.submodules.pll = pll = ECP5PLL()
self.comb += pll.reset.eq(rst)
pll.register_clkin(clk25, 25e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
pll.create_clkout(self.cd_sys, sys_clk_freq, margin=0)
pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=90)
self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll.locked | rst)
# USB PLL
if with_usb_pll:
self.clock_domains.cd_usb_12 = ClockDomain()
self.clock_domains.cd_usb_48 = ClockDomain()
pll.create_clkout(self.cd_usb_12, 12e6, margin=0)
self.comb += self.cd_usb_48.clk.eq(self.cd_sys.clk)
# SDRAM clock
self.specials += DDROutput(1, 0, platform.request("sdram_clock"), ClockSignal("sys_ps"))
@ -64,7 +71,8 @@ class BaseSoC(SoCCore):
SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
with_usb_pll = kwargs.get("uart_name", None) == "usb_cdc"
self.submodules.crg = _CRG(platform, sys_clk_freq, with_usb_pll)
# SDR SDRAM --------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
@ -87,8 +95,8 @@ def main():
help="gateware toolchain to use, trellis (default) or diamond")
parser.add_argument("--device", dest="device", default="LFE5U-45F",
help="FPGA device, ULX3S can be populated with LFE5U-45F (default) or LFE5U-85F")
parser.add_argument("--sys-clk-freq", default=50e6,
help="system clock frequency (default=50MHz)")
parser.add_argument("--sys-clk-freq", default=48e6,
help="system clock frequency (default=48MHz)")
parser.add_argument("--sdram-module", default="MT48LC16M16",
help="SDRAM module: MT48LC16M16, AS4C32M16 or AS4C16M16 (default=MT48LC16M16)")
builder_args(parser)