From cb959628506e61cae2d7be05276bba8f42138cfb Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 14 Apr 2020 16:14:18 +0200 Subject: [PATCH] targets/ulx3s and colorlight_5a_75b: cleanup USB ACM addition and only keep USB ACM changes. - remove update in loading/flashing: we need to thinks how to integrate this. - remove specific README: documentation is moved to the files, link to more complete project can be added if maintained externally, as done for the iCEBreaker for example. - revert default freq on ULX3S to 50MHz and instantiate a second PLL as done on the colorlight. --- litex_boards/targets/README.colorlight_5a_75b | 26 --- litex_boards/targets/README.ulx3s | 11 -- litex_boards/targets/bit_to_flash.py | 149 ------------------ litex_boards/targets/colorlight_5a_75b.py | 55 +++---- litex_boards/targets/ulx3s.py | 12 +- 5 files changed, 25 insertions(+), 228 deletions(-) delete mode 100644 litex_boards/targets/README.colorlight_5a_75b delete mode 100644 litex_boards/targets/README.ulx3s delete mode 100755 litex_boards/targets/bit_to_flash.py diff --git a/litex_boards/targets/README.colorlight_5a_75b b/litex_boards/targets/README.colorlight_5a_75b deleted file mode 100644 index 8663810..0000000 --- a/litex_boards/targets/README.colorlight_5a_75b +++ /dev/null @@ -1,26 +0,0 @@ -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. diff --git a/litex_boards/targets/README.ulx3s b/litex_boards/targets/README.ulx3s deleted file mode 100644 index d565499..0000000 --- a/litex_boards/targets/README.ulx3s +++ /dev/null @@ -1,11 +0,0 @@ -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. - diff --git a/litex_boards/targets/bit_to_flash.py b/litex_boards/targets/bit_to_flash.py deleted file mode 100755 index aeba5e6..0000000 --- a/litex_boards/targets/bit_to_flash.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import textwrap - -# Very basic bitstream to SVF converter, tested with the ULX3S WiFi interface - -flash_page_size = 256 -erase_block_size = 64*1024 - - -def bitreverse(x): - y = 0 - for i in range(8): - if (x >> (7 - i)) & 1 == 1: - y |= (1 << i) - return y - -with open(sys.argv[1], 'rb') as bitf: - bs = bitf.read() - # Autodetect IDCODE from bitstream - idcode_cmd = bytes([0xE2, 0x00, 0x00, 0x00]) - idcode = None - for i in range(len(bs) - 4): - if bs[i:i+4] == idcode_cmd: - idcode = bs[i+4] << 24 - idcode |= bs[i+5] << 16 - idcode |= bs[i+6] << 8 - idcode |= bs[i+7] - break - if idcode is None: - print("Failed to find IDCODE in bitstream, check bitstream is valid") - sys.exit(1) - bitf.seek(0) - - address = 0 - last_page = -1 - - with open(sys.argv[2], 'w') as svf: - print(""" -STATE RESET; -HDR 0; -HIR 0; -TDR 0; -TIR 0; -ENDDR DRPAUSE; -ENDIR IRPAUSE; -STATE IDLE; - """, file=svf) - print(""" -SIR 8 TDI (E0); -SDR 32 TDI (00000000) - TDO ({:08X}) - MASK (FFFFFFFF); - """.format(idcode), file=svf) - print(""" -SIR 8 TDI (1C); -SDR 510 TDI (3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - -// Enter Programming mode -SIR 8 TDI (C6); -SDR 8 TDI (00); -RUNTEST IDLE 2 TCK 1.00E-02 SEC; - -// Erase -SIR 8 TDI (0E); -SDR 8 TDI (01); -RUNTEST IDLE 2 TCK 2.0E-1 SEC; - -// Read STATUS -SIR 8 TDI (3C); -SDR 32 TDI (00000000) - TDO (00000000) - MASK (0000B000); - -// Exit Programming mode -SIR 8 TDI (26); -RUNTEST IDLE 2 TCK 1.00E-02 SEC; - -// BYPASS -SIR 8 TDI (FF); -STATE IDLE; -RUNTEST 32 TCK; -RUNTEST 2.00E-2 SEC; - -// Enter SPI mode - -SIR 8 TDI (3A); -SDR 16 TDI (68FE); -STATE IDLE; -RUNTEST 32 TCK; -RUNTEST 2.00E-2 SEC; - -// SPI IO -SDR 8 TDI (D5); - -RUNTEST 2.00E-0 SEC; - -// CONFIRM FLASH ID -SDR 32 TDI (000000F9) - TDO (68FFFFFF) - MASK (FF000000); - -SDR 8 TDI(60); -SDR 16 TDI(0080); -RUNTEST 1.00E-0 SEC; - - - """, file=svf) - while True: - if((address // 0x10000) != last_page): - last_page = (address // 0x10000) - print("""SDR 8 TDI (60); - """, file=svf) - address_flipped = [bitreverse(x) for x in [0xd8,int(address // 0x10000),0x00,0x00]] - hex_address= ["{:02X}".format(x) for x in reversed(address_flipped)] - print("\n".join(textwrap.wrap("SDR {} TDI ({});".format(8*len(hex_address), "".join(hex_address)), 100)), file=svf) - print("""RUNTEST 3.00 SEC; - """, file=svf) - - chunk = bitf.read(flash_page_size) - if not chunk: - break - # Convert chunk to bit-reversed hex - br_chunk = [bitreverse(x) for x in bytes([0x02, int(address / 0x10000 % 0x100),int(address / 0x100 % 0x100),int(address % 0x100)]) + chunk] - address += len(chunk) - hex_chunk = ["{:02X}".format(x) for x in reversed(br_chunk)] - print(""" -SDR 8 TDI (60); - """, file=svf) - print("\n".join(textwrap.wrap("SDR {} TDI ({});".format(8*len(br_chunk), "".join(hex_chunk)), 100)), file=svf) - print(""" -RUNTEST 2.50E-2 SEC; - """, file=svf) - - print(""" -// BYPASS -SIR 8 TDI (FF); - -//REFRESH -SIR 8 TDI(79); -SDR 24 TDI(000000); - -STATE IDLE; -RUNTEST 32 TCK; -RUNTEST 2.00E-2 SEC; -STATE RESET; - """, file=svf) diff --git a/litex_boards/targets/colorlight_5a_75b.py b/litex_boards/targets/colorlight_5a_75b.py index cafe99d..a33ec42 100755 --- a/litex_boards/targets/colorlight_5a_75b.py +++ b/litex_boards/targets/colorlight_5a_75b.py @@ -20,6 +20,16 @@ # wishbone-tool --ethernet-host 192.168.1.50 --server terminal --csr-csv csr.csv # You should see the LiteX BIOS and be able to interact with it. # +# 3) SoC with USB-ACM UART (on V7.0): +# - Replace U23 with a SN74CBT3245APWR or remove U23 and place jumper wires to make 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. +# ./colorlight_5a_75b.py --revision=7.0 --uart-name=usb_cdcc +# ./colorlight_5a_75b.py --load +# You should see the LiteX BIOS and be able to interact with it. +# # Disclaimer: SoC 2) is still a Proof of Concept with large timings violations on the IP/UDP and # Etherbone stack that need to be optimized. It was initially just used to validate the reversed # pinout but happens to work on hardware... @@ -75,7 +85,6 @@ class _CRG(Module): 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")) @@ -127,44 +136,23 @@ class BaseSoC(SoCCore): # Load --------------------------------------------------------------------------------------------- -def openocd_run_svf(filename, iface="ftdi"): +def load(): import os f = open("openocd.cfg", "w") - if (iface == "ftdi"): - f.write( -"""adapter driver ftdi + f.write( +""" +interface ftdi ftdi_vid_pid 0x0403 0x6011 ftdi_channel 0 ftdi_layout_init 0x0098 0x008b reset_config none -adapter speed 25000 +adapter_khz 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 -d0 -f openocd.cfg -c \"transport select jtag; init; svf -tap lfe5u25.tap {} -quiet -progress; exit\"".format(filename)) - os.system("rm openocd.cfg") + os.system("openocd -f openocd.cfg -c \"transport select jtag; init; svf soc_basesoc_colorlight_5a_75b/gateware/top.svf; exit\"") exit() -def load(iface="ftdi"): - openocd_run_svf("soc_basesoc_colorlight_5a_75b/gateware/top.svf",iface=iface) - -def flash(iface="ftdi"): - import os - os.system("./bit_to_flash.py soc_basesoc_colorlight_5a_75b/gateware/top.bit soc_basesoc_colorlight_5a_75b/gateware/top.svf.flash") - openocd_run_svf("soc_basesoc_colorlight_5a_75b/gateware/top.svf.flash",iface=iface) - # Build -------------------------------------------------------------------------------------------- def main(): @@ -177,18 +165,11 @@ 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("--flash", action="store_true", help="flash 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)") - + parser.add_argument("--sys-clk-freq", default=60e6, help="system clock frequency (default=60MHz)") args = parser.parse_args() if args.load: - load(iface=args.iface) - - if args.flash: - flash(iface=args.iface) + load() assert not (args.with_ethernet and args.with_etherbone) soc = BaseSoC(revision=args.revision, diff --git a/litex_boards/targets/ulx3s.py b/litex_boards/targets/ulx3s.py index eec7670..1f3e338 100755 --- a/litex_boards/targets/ulx3s.py +++ b/litex_boards/targets/ulx3s.py @@ -42,16 +42,18 @@ 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, margin=0) + pll.create_clkout(self.cd_sys, sys_clk_freq) 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.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() - pll.create_clkout(self.cd_usb_12, 12e6, margin=0) - self.comb += self.cd_usb_48.clk.eq(self.cd_sys.clk) + usb_pll.create_clkout(self.cd_usb_12, 12e6, margin=0) + usb_pll.create_clkout(self.cd_usb_48, 48e6, margin=0) # SDRAM clock self.specials += DDROutput(1, 0, platform.request("sdram_clock"), ClockSignal("sys_ps")) @@ -95,8 +97,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=48e6, - help="system clock frequency (default=48MHz)") + parser.add_argument("--sys-clk-freq", default=50e6, + help="system clock frequency (default=50MHz)") parser.add_argument("--sdram-module", default="MT48LC16M16", help="SDRAM module: MT48LC16M16, AS4C32M16 or AS4C16M16 (default=MT48LC16M16)") builder_args(parser)