Addition of USB ACM for ECP5
This commit is contained in:
parent
a12faae0fb
commit
389e8aa13a
|
@ -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
|
||||
|
|
|
@ -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 -----------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue