A Neopixel solution for Colorlight boards ...
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

481 lines
23 KiB

#!/usr/bin/env python3
#
# neopixelar.py
#
# This file has been derived from LiteX-Boards/colorlight_5b_75x.py
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
#
# Disclaimer: 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...
#
# History:
# --------
# 14.09.20/KQ Initial version, some output ports activated (user_led, J4) for testing
# 15.09.20/KQ Own logic exported to external module (neopixelprotocol.py - now neopixelengine.py)
# 19.09.20/KQ Project renamed 'NeoPixelar' (swedish plural for NeoPixel ...)
# 20.11.20/KQ Input provided: U28 -> J1 (1, 2, 3, [4=GND], 5, 6, 7), J2 (1, 2, [4=GND])
# (U15 -> J7 ([4=GND], 5, 7), J8 (1, 2, 3, [4=GND], 5, 6, 7))
# 02.01.21/KQ DMA DRAM access integration started
#
# Build/Use ----------------------------------------------------------------------------------------
# - 'python3 neopixelar.py --build --revision=7.0 --uart-name=crossover --with-etherbone --ip-address=192.168.1.20 --csr-csv=build/csr.csv'
# to generate
# - 'python3 neopixelar.py --load' to download to FPGA
# - 'ping 192.168.1.20' to verify ethernet connection - via LEFT(!) RJ45 port
# - 'wishbone-tool --ethernet-host 192.168.1.20 --server terminal --csr-csv build/csr.csv'
# You should see the LiteX BIOS and be able to interact with it
# - To load a file to RAM (@0x40000000 len=0x400000) use:
# wishbone-tool --ethernet-host 192.168.1.20 --server load-file --csr-csv build/csr.csv
# --load-address 0x40000000
# --load-name build/colorlight_5a_75b/software/<filename>
# To disassemble raw file:
# ../fpga/litex/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-objdump
# -D -b binary ./build/colorlight_5a_75b/software/bios/bios.bin -m riscv
#
import os
import argparse
import sys
from migen import *
from migen.genlib.misc import WaitTimer
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.build.io import DDROutput
from litex_boards.platforms import colorlight_5a_75b
from litex.build.lattice.trellis import trellis_args, trellis_argdict
from litex.soc.cores.clock import *
from litex.soc.cores.spi_flash import ECP5SPIFlash
from litex.soc.cores.gpio import GPIOOut
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage, CSRField
from litex.soc.interconnect.stream import SyncFIFO
from litedram.modules import M12L16161A, M12L64322A
from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY
from litedram.frontend.dma import LiteDRAMDMAReader, LiteDRAMDMAWriter
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
from litex.build.generic_platform import *
import litex.soc.doc as lxsocdoc
# KQ's helper modules ...
from libmodules.systime import SysTime
from libmodules.dramtransfer import DRAMTransfer
from neopixelengine import NeoPixelEngine
from helpers.prepare_firmware import copyjob
# Explicit IO naming, taken from board colorlight 5a 75b board defs. (rev. 7.0)
# from https://github.com/q3k/chubby75/blob/master/5a-75b/hardware_V7.0.md
#_connectors_v7_0 = [
# ("j1", "F3 F1 G3 - G2 H3 H5 F15 L2 K1 J5 K2 B16 J14 F12 -"),
# ("j2", "J4 K3 G1 - K4 C2 E3 F15 L2 K1 J5 K2 B16 J14 F12 -"),
# ("j3", "H4 K5 P1 - R1 L5 F2 F15 L2 K1 J5 K2 B16 J14 F12 -"),
# ("j4", "P4 R2 M8 - M9 T6 R6 F15 L2 K1 J5 K2 B16 J14 F12 -"),
# ("j5", "M11 N11 P12 - K15 N12 L16 F15 L2 K1 J5 K2 B16 J14 F12 -"),
# ("j6", "K16 J15 J16 - J12 H15 G16 F15 L2 K1 J5 K2 B16 J14 F12 -"),
# ("j7", "H13 J13 H12 - G14 H14 G15 F15 L2 K1 J5 K2 B16 J14 F12 -"),
# ("j8", "A15 F16 A14 - E13 B14 A13 F15 L2 K1 J5 K2 B16 J14 F12 -"),
#]
_gpios = [
# Attn. Jx/pin descriptions are 1-based, but zero based defs. used!
# J1
("gpio", 0, Pins("j1:0"), IOStandard("LVCMOS33")), # Input now
("gpio", 1, Pins("j1:1"), IOStandard("LVCMOS33")), # Input now
("gpio", 2, Pins("j1:2"), IOStandard("LVCMOS33")), # Input now
# GND
("gpio", 3, Pins("j1:4"), IOStandard("LVCMOS33")), # Input now
("gpio", 4, Pins("j1:5"), IOStandard("LVCMOS33")), # Input now
("gpio", 5, Pins("j1:6"), IOStandard("LVCMOS33")), # Input now
("gpio", 6, Pins("j1:7"), IOStandard("LVCMOS33")),
("gpio", 7, Pins("j1:8"), IOStandard("LVCMOS33")),
("gpio", 8, Pins("j1:9"), IOStandard("LVCMOS33")),
("gpio", 9, Pins("j1:10"), IOStandard("LVCMOS33")),
("gpio", 10, Pins("j1:11"), IOStandard("LVCMOS33")),
("gpio", 11, Pins("j1:12"), IOStandard("LVCMOS33")),
("gpio", 12, Pins("j1:13"), IOStandard("LVCMOS33")),
("gpio", 13, Pins("j1:14"), IOStandard("LVCMOS33")),
# GND
# J2
("gpio", 14, Pins("j2:0"), IOStandard("LVCMOS33")), # Input now
("gpio", 15, Pins("j2:1"), IOStandard("LVCMOS33")), # Input now
("gpio", 16, Pins("j2:2"), IOStandard("LVCMOS33")),
# GND
("gpio", 17, Pins("j2:4"), IOStandard("LVCMOS33")),
("gpio", 18, Pins("j2:5"), IOStandard("LVCMOS33")),
("gpio", 19, Pins("j2:6"), IOStandard("LVCMOS33")),
("gpio", 20, Pins("j2:7"), IOStandard("LVCMOS33")),
("gpio", 21, Pins("j2:8"), IOStandard("LVCMOS33")),
("gpio", 22, Pins("j2:9"), IOStandard("LVCMOS33")),
("gpio", 23, Pins("j2:10"), IOStandard("LVCMOS33")),
("gpio", 24, Pins("j2:11"), IOStandard("LVCMOS33")),
("gpio", 25, Pins("j2:12"), IOStandard("LVCMOS33")),
("gpio", 26, Pins("j2:13"), IOStandard("LVCMOS33")),
("gpio", 27, Pins("j2:14"), IOStandard("LVCMOS33")),
# GND
# J3
("gpio", 28, Pins("j3:0"), IOStandard("LVCMOS33")),
("gpio", 29, Pins("j3:1"), IOStandard("LVCMOS33")),
("gpio", 30, Pins("j3:2"), IOStandard("LVCMOS33")),
# GND
("gpio", 31, Pins("j3:4"), IOStandard("LVCMOS33")),
("gpio", 32, Pins("j3:5"), IOStandard("LVCMOS33")),
("gpio", 33, Pins("j3:6"), IOStandard("LVCMOS33")),
("gpio", 34, Pins("j3:7"), IOStandard("LVCMOS33")),
("gpio", 35, Pins("j3:8"), IOStandard("LVCMOS33")),
("gpio", 36, Pins("j3:9"), IOStandard("LVCMOS33")),
("gpio", 37, Pins("j3:10"), IOStandard("LVCMOS33")),
("gpio", 38, Pins("j3:11"), IOStandard("LVCMOS33")),
("gpio", 39, Pins("j3:12"), IOStandard("LVCMOS33")),
("gpio", 40, Pins("j3:13"), IOStandard("LVCMOS33")),
("gpio", 41, Pins("j3:14"), IOStandard("LVCMOS33")),
# GND
# J4
("gpio", 42, Pins("j4:0"), IOStandard("LVCMOS33")), # j4 pin 1
("gpio", 43, Pins("j4:1"), IOStandard("LVCMOS33")), # j4 pin 2
("gpio", 44, Pins("j4:2"), IOStandard("LVCMOS33")), # j4 pin 3
# j4 pin 4, GND
("gpio", 45, Pins("j4:4"), IOStandard("LVCMOS33")), # j4 pin 5
("gpio", 46, Pins("j4:5"), IOStandard("LVCMOS33")), # j4 pin 6
("gpio", 47, Pins("j4:6"), IOStandard("LVCMOS33")), # j4 pin 7
("gpio", 48, Pins("j4:7"), IOStandard("LVCMOS33")), # j4 pin 8
("gpio", 49, Pins("j4:8"), IOStandard("LVCMOS33")), # j4 pin 9
("gpio", 50, Pins("j4:9"), IOStandard("LVCMOS33")), # j4 pin 10
("gpio", 51, Pins("j4:10"), IOStandard("LVCMOS33")), # j4 pin 11
("gpio", 52, Pins("j4:11"), IOStandard("LVCMOS33")), # j4 pin 12
("gpio", 53, Pins("j4:12"), IOStandard("LVCMOS33")), # j4 pin 13
("gpio", 54, Pins("j4:13"), IOStandard("LVCMOS33")), # j4 pin 14
("gpio", 55, Pins("j4:14"), IOStandard("LVCMOS33")), # j4 pin 15
# j4 pin 16, GND
# J5
("gpio", 56, Pins("j5:0"), IOStandard("LVCMOS33")),
("gpio", 57, Pins("j5:1"), IOStandard("LVCMOS33")),
("gpio", 58, Pins("j5:2"), IOStandard("LVCMOS33")),
# GND
("gpio", 59, Pins("j5:4"), IOStandard("LVCMOS33")),
("gpio", 60, Pins("j5:5"), IOStandard("LVCMOS33")),
("gpio", 61, Pins("j5:6"), IOStandard("LVCMOS33")),
("gpio", 62, Pins("j5:7"), IOStandard("LVCMOS33")),
("gpio", 63, Pins("j5:8"), IOStandard("LVCMOS33")),
("gpio", 64, Pins("j5:9"), IOStandard("LVCMOS33")),
("gpio", 65, Pins("j5:10"), IOStandard("LVCMOS33")),
("gpio", 66, Pins("j5:11"), IOStandard("LVCMOS33")),
("gpio", 67, Pins("j5:12"), IOStandard("LVCMOS33")),
("gpio", 68, Pins("j5:13"), IOStandard("LVCMOS33")),
("gpio", 69, Pins("j5:14"), IOStandard("LVCMOS33")),
# GND
# J6
("gpio", 70, Pins("j6:0"), IOStandard("LVCMOS33")),
("gpio", 71, Pins("j6:1"), IOStandard("LVCMOS33")),
("gpio", 72, Pins("j6:2"), IOStandard("LVCMOS33")),
# GND
("gpio", 73, Pins("j6:4"), IOStandard("LVCMOS33")),
("gpio", 74, Pins("j6:5"), IOStandard("LVCMOS33")),
("gpio", 75, Pins("j6:6"), IOStandard("LVCMOS33")),
("gpio", 76, Pins("j6:7"), IOStandard("LVCMOS33")),
("gpio", 77, Pins("j6:8"), IOStandard("LVCMOS33")),
("gpio", 78, Pins("j6:9"), IOStandard("LVCMOS33")),
("gpio", 79, Pins("j6:10"), IOStandard("LVCMOS33")),
("gpio", 80, Pins("j6:11"), IOStandard("LVCMOS33")),
("gpio", 81, Pins("j6:12"), IOStandard("LVCMOS33")),
("gpio", 82, Pins("j6:13"), IOStandard("LVCMOS33")),
("gpio", 83, Pins("j6:14"), IOStandard("LVCMOS33")),
# GND
# J7
("gpio", 84, Pins("j7:0"), IOStandard("LVCMOS33")),
("gpio", 85, Pins("j7:1"), IOStandard("LVCMOS33")),
("gpio", 86, Pins("j7:2"), IOStandard("LVCMOS33")),
# GND
("gpio", 87, Pins("j7:4"), IOStandard("LVCMOS33")), # Input now
("gpio", 88, Pins("j7:5"), IOStandard("LVCMOS33")),
("gpio", 89, Pins("j7:6"), IOStandard("LVCMOS33")), # Input now
("gpio", 90, Pins("j7:7"), IOStandard("LVCMOS33")),
("gpio", 91, Pins("j7:8"), IOStandard("LVCMOS33")),
("gpio", 92, Pins("j7:9"), IOStandard("LVCMOS33")),
("gpio", 93, Pins("j7:10"), IOStandard("LVCMOS33")),
("gpio", 94, Pins("j7:11"), IOStandard("LVCMOS33")),
("gpio", 95, Pins("j7:12"), IOStandard("LVCMOS33")),
("gpio", 96, Pins("j7:13"), IOStandard("LVCMOS33")),
("gpio", 97, Pins("j7:14"), IOStandard("LVCMOS33")),
# GND
# J8
("gpio", 98, Pins("j8:0"), IOStandard("LVCMOS33")), # Input now
("gpio", 99, Pins("j8:1"), IOStandard("LVCMOS33")), # Input now
("gpio", 100, Pins("j8:2"), IOStandard("LVCMOS33")), # Input now
# GND
("gpio", 101, Pins("j8:4"), IOStandard("LVCMOS33")), # Input now
("gpio", 102, Pins("j8:5"), IOStandard("LVCMOS33")), # Input now
("gpio", 103, Pins("j8:6"), IOStandard("LVCMOS33")), # Input now
("gpio", 104, Pins("j8:7"), IOStandard("LVCMOS33")),
("gpio", 105, Pins("j8:8"), IOStandard("LVCMOS33")),
("gpio", 106, Pins("j8:9"), IOStandard("LVCMOS33")),
("gpio", 107, Pins("j8:10"), IOStandard("LVCMOS33")),
("gpio", 108, Pins("j8:11"), IOStandard("LVCMOS33")),
("gpio", 109, Pins("j8:12"), IOStandard("LVCMOS33")),
("gpio", 110, Pins("j8:13"), IOStandard("LVCMOS33")),
("gpio", 111, Pins("j8:14"), IOStandard("LVCMOS33")),
# GND
]
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_rst=True, sdram_rate="1:1"):
self.clock_domains.cd_sys = ClockDomain()
if sdram_rate == "1:2":
self.clock_domains.cd_sys2x = ClockDomain()
self.clock_domains.cd_sys2x_ps = ClockDomain(reset_less=True)
else:
self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True)
# # #
# Clk / Rst
if not use_internal_osc:
clk = platform.request("clk25")
clk_freq = 25e6
else:
clk = Signal()
div = 5
self.specials += Instance("OSCG",
p_DIV = div,
o_OSC = clk)
clk_freq = 310e6/div
rst_n = 1 if not with_rst else platform.request("user_btn_n", 0)
# PLL
self.submodules.pll = pll = ECP5PLL()
self.comb += pll.reset.eq(~rst_n)
pll.register_clkin(clk, clk_freq)
pll.create_clkout(self.cd_sys, sys_clk_freq)
if sdram_rate == "1:2":
pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq)
pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.
else:
pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.
# USB PLL
if with_usb_pll:
self.submodules.usb_pll = usb_pll = ECP5PLL()
self.comb += usb_pll.reset.eq(~rst_n)
usb_pll.register_clkin(clk, clk_freq)
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)
# SDRAM clock
sdram_clk = ClockSignal("sys2x_ps" if sdram_rate == "1:2" else "sys_ps")
self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, board, revision, with_ethernet=False, with_etherbone=False, eth_phy=0, ip_address=None, mac_address=None, sys_clk_freq=60e6, use_internal_osc=False, sdram_rate="1:1", **kwargs):
platform = colorlight_5a_75b.Platform(revision="7.0")
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, int(sys_clk_freq),
ident = "LiteX SoC on Colorlight " + board.upper(),
ident_version = True,
**kwargs)
# CRG --------------------------------------------------------------------------------------
with_rst = kwargs["uart_name"] not in ["serial", "bridge"] # serial_rx shared with user_btn_n.
with_usb_pll = kwargs.get("uart_name", None) == "usb_acm"
self.submodules.crg = _CRG(platform, sys_clk_freq, use_internal_osc=use_internal_osc, with_usb_pll=with_usb_pll,with_rst=with_rst, sdram_rate=sdram_rate)
# SDR SDRAM --------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
sdrphy_cls = HalfRateGENSDRPHY if sdram_rate == "1:2" else GENSDRPHY
self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
if board == "5a-75e" and revision == "6.0":
sdram_cls = M12L64322A
sdram_size = 0x80000000
else:
sdram_cls = M12L16161A
sdram_size = 0x40000000
self.add_sdram("sdram",
phy = self.sdrphy,
module = sdram_cls(sys_clk_freq, sdram_rate),
origin = self.mem_map["main_ram"],
size = kwargs.get("max_sdram_size", sdram_size),
l2_cache_size = kwargs.get("l2_size", 8192),
l2_cache_min_data_width = kwargs.get("min_l2_data_width", 128),
l2_cache_reverse = True
)
# Ethernet / Etherbone ---------------------------------------------------------------------
if with_ethernet or with_etherbone:
self.submodules.ethphy = LiteEthPHYRGMII(
clock_pads = self.platform.request("eth_clocks", eth_phy),
pads = self.platform.request("eth", eth_phy))
self.add_csr("ethphy")
if with_ethernet:
self.add_ethernet(phy=self.ethphy)
if with_etherbone:
self.add_etherbone(
phy=self.ethphy,
ip_address = ip_address,
mac_address = mac_address,
)
# Add platform specific I/O
platform.add_extension(_gpios) # General LED outputs
# For U28 3.3V(!) inputs: (also see separate picture)
self.J1_1 = J1_1 = platform.request("gpio", 0) # Pins for logical evaluation
self.J1_2 = J1_2 = platform.request("gpio", 1)
self.J1_3 = J1_3 = platform.request("gpio", 2)
self.J1_5 = J1_5 = platform.request("gpio", 3)
self.J1_6 = J1_6 = platform.request("gpio", 4)
self.J1_7 = J1_7 = platform.request("gpio", 5)
self.J2_1 = J2_1 = platform.request("gpio", 14)
self.J2_2 = J2_2 = platform.request("gpio", 15)
'''
# For U15 (not used currently)
J7_5 = Signal(1)
self.comb += J7_5.eq(platform.request("gpio", 87))
J7_7 = Signal(1)
self.comb += J7_7.eq(platform.request("gpio", 89))
J8_1 = Signal(1)
self.comb += J8_1.eq(platform.request("gpio", 98))
J8_2 = Signal(1)
self.comb += J8_2.eq(platform.request("gpio", 99))
J8_3 = Signal(1)
self.comb += J8_3.eq(platform.request("gpio", 100))
J8_5 = Signal(1)
self.comb += J8_5.eq(platform.request("gpio", 101))
J8_6 = Signal(1)
self.comb += J8_6.eq(platform.request("gpio", 102))
J8_7 = Signal(1)
self.comb += J8_7.eq(platform.request("gpio", 103))
'''
# OR it all together: Every input lights LED ...
self.led_logic1 = led_logic1 = Signal(1)
self.comb += led_logic1.eq(J1_1 | J1_2 | J1_3 | J1_5 | J1_6 | J1_7 | J2_1 | J2_2)
#led_logic2 = Signal(1) # Not used currently
#self.comb += led_logic2.eq(J8_1 | J8_2 | J8_3 | J8_5 | J8_6 | J8_7 | J7_5 | J7_7)
# Base counter (used for clocking)
counter = Signal(32) # 32-Bit counter
self.sync += counter.eq(counter + 1)
# USERLED blink (on-board LED)
# only w/ uart-name=crossover option:
if kwargs["uart_name"] not in ["serial", "bridge"]:
self.comb += platform.request("user_led_n").eq(~(counter[23] | led_logic1)) #| led_logic2) # ~2Hz | inputs
# System time (count)
self.submodules.systime = systime = SysTime(comparecount=0x0000EA90)
self.add_csr("systime")
# DRAM test
MAXWORDS = 512 #32 # Transfer length x 32-bit, FIFO depth
self.submodules.mm2s = mm2s = LiteDRAMDMAReader(self.sdram.crossbar.get_port(), fifo_depth=MAXWORDS, fifo_buffered=True)
mm2s.add_csr()
self.add_csr("mm2s")
self.submodules.sync_fifo = sync_fifo = SyncFIFO([("data", 32)], MAXWORDS, True)
self.comb += mm2s.source.connect(sync_fifo.sink) # Connect DMA-Reader.source -> FIFO.sink
self.submodules.dramtransfer = dramtransfer = DRAMTransfer(maxwords=MAXWORDS, dma_reader=mm2s, sync_fifo=sync_fifo)
self.add_csr("dramtransfer")
# Adjust no. for your actual project ...
max_TABLES = 64 #2 # 1..64
max_LEDS_per_chain = MAXWORDS # 1..512
self.submodules.npe = NeoPixelEngine(n_TABLES=max_TABLES, n_LEDs=max_LEDS_per_chain, dramtransfer=dramtransfer)
self.add_csr("npe")
for i in range(42,56+2): # Example: Do output on J4 (14) & J5 (2)
self.comb += platform.request("gpio", i).eq(self.npe.bDataPin[i-42]) # Output data pin
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on Colorlight 5A-75X")
builder_args(parser)
soc_core_args(parser)
trellis_args(parser)
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream")
parser.add_argument("--board", default="5a-75b", help="Board type: 5a-75b (default) & don't change!")
parser.add_argument("--revision", default="7.0", type=str, help="Board revision 7.0 (default) & don't change!")
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
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("--ip-address", default="192.168.1.50", help="Ethernet IP address of the board.")
parser.add_argument("--mac-address", default="0x726b895bc2e2", help="Ethernet MAC address of the board.")
parser.add_argument("--sys-clk-freq", default=60e6, type=float, help="System clock frequency (default=60MHz)")
parser.add_argument("--use-internal-osc", action="store_true", help="Use internal oscillator")
parser.add_argument("--sdram-rate", default="1:1", help="SDRAM Rate 1:1 Full Rate (default), 1:2 Half Rate")
parser.add_argument("--csr_csv", default="build/csr.csv", help="CSR list location")
parser.add_argument("--doc", action="store_true", help="Create doc files for sphinx generator")
parser.add_argument("--flash", action="store_true", help="Load bitstream to flash")
args = parser.parse_args()
#assert not (args.with_ethernet and args.with_etherbone)
soc = BaseSoC(board=args.board, revision=args.revision,
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
eth_phy = args.eth_phy,
ip_address = args.ip_address,
mac_address = int(args.mac_address, 0),
sys_clk_freq = args.sys_clk_freq,
use_internal_osc = args.use_internal_osc,
sdram_rate = args.sdram_rate,
**soc_core_argdict(args))
# 32MBit SPIFlash ------------------------------------------------------------------------
flashbase = 0xc0000000
flashoffset = 0x100000 # Used to be zero (default)
soc.mem_map["spiflash"] = flashbase # Length: 0x01000000 ('til 0xc1000000 - 1)
# Boot at +1MB
soc.add_constant("FLASH_BOOT_ADDRESS", soc.mem_map["spiflash"] + 1024*1024) # 0xc0100000
soc.add_spi_flash(name="spiflash", mode="1x", dummy_cycles=8, clk_freq=5e6)
builder = Builder(soc, **builder_argdict(args))
# Now override boot address (used to be zero/default)
args.ecppack_bootaddr = flashbase + flashoffset # 0xC0100000
builder.build(**trellis_argdict(args), run=args.build) # Written here to (local) build tree
if args.doc:
print("Generating documentation for sphinx ...")
lxsocdoc.generate_docs(soc, "build/documentation/", project_name="neopixelar", author="KQ")
print("Generate via: 'sphinx-build -b html build/documentation build/documentation/html'")
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".svf"))
return
if args.flash: # Convert Bit File to Jtag Write Flash command
name = os.path.join(builder.gateware_dir, soc.build_name)
print(f"Executing ./bit_to_flash.py {name}.bit {name}.svf.flash")
from helpers.bit_to_flash import convertBitToFlashFile
convertBitToFlashFile(name + ".bit", name + ".svf.flash", address=0)
from helpers.load_to_flash import load2flash
load2flash(name + ".svf.flash")
return
if __name__ == "__main__":
copyjob() # Create backup if nec. & move our firmware to the correct location
main()
# Maybe revoke backup action here ...