Neopixelar/neopixelar.py

470 lines
23 KiB
Python
Raw Normal View History

2020-09-19 09:28:09 +00:00
#!/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...
2020-09-19 09:28:09 +00:00
#
# History:
# --------
2020-10-17 16:50:33 +00:00
# 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 ...)
2020-11-20 11:38:24 +00:00
# 20.11.20/KQ Input provided: U28 -> J1 (1, 2, 3, [4=GND], 5, 6, 7), J2 (1, 2, [4=GND])
2020-11-22 11:36:57 +00:00
# (U15 -> J7 ([4=GND], 5, 7), J8 (1, 2, 3, [4=GND], 5, 6, 7))
2021-01-02 11:46:28 +00:00
# 02.01.21/KQ DMA DRAM access integration started
2020-09-19 09:28:09 +00:00
#
# 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'
2020-09-19 09:28:09 +00:00
# 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'
2020-09-19 09:28:09 +00:00
# You should see the LiteX BIOS and be able to interact with it
2020-10-02 17:34:19 +00:00
# - 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
2020-10-02 17:34:19 +00:00
# --load-name build/colorlight_5a_75b/software/<filename>
2020-10-10 17:06:08 +00:00
# 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
2020-09-19 09:28:09 +00:00
#
import os
import argparse
import sys
from migen import *
from migen.genlib.misc import WaitTimer
2020-09-19 09:28:09 +00:00
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.build.io import DDROutput
from litex_boards.platforms import colorlight_5a_75b
2020-09-19 09:28:09 +00:00
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
2020-09-19 09:28:09 +00:00
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
2020-09-22 16:00:46 +00:00
from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage, CSRField
2020-09-19 09:28:09 +00:00
from litedram.modules import M12L16161A, M12L64322A
from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
from litex.build.generic_platform import *
import litex.soc.doc as lxsocdoc
2021-01-02 11:46:28 +00:00
# KQ's helper modules ...
from modules.systime import SysTime
from modules.dramtransfer import DRAMTransfer
2020-09-19 09:28:09 +00:00
from neopixelengine import NeoPixelEngine
from helpers.prepare_firmware import copyjob
2020-09-19 09:28:09 +00:00
# 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
2020-11-20 11:38:24 +00:00
("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
2020-09-19 09:28:09 +00:00
# GND
2020-11-20 11:38:24 +00:00
("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
2020-09-19 09:28:09 +00:00
("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
2020-11-20 11:38:24 +00:00
("gpio", 14, Pins("j2:0"), IOStandard("LVCMOS33")), # Input now
("gpio", 15, Pins("j2:1"), IOStandard("LVCMOS33")), # Input now
2020-09-19 09:28:09 +00:00
("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
2020-11-20 11:38:24 +00:00
("gpio", 87, Pins("j7:4"), IOStandard("LVCMOS33")), # Input now
2020-09-19 09:28:09 +00:00
("gpio", 88, Pins("j7:5"), IOStandard("LVCMOS33")),
2020-11-20 11:38:24 +00:00
("gpio", 89, Pins("j7:6"), IOStandard("LVCMOS33")), # Input now
2020-09-19 09:28:09 +00:00
("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
2020-11-20 11:38:24 +00:00
("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
2020-09-19 09:28:09 +00:00
# GND
2020-11-20 11:38:24 +00:00
("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
2020-09-19 09:28:09 +00:00
("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")
2020-09-19 09:28:09 +00:00
# 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 ---------------------------------------------------------------------
2020-09-19 09:28:09 +00:00
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,
)
2020-11-20 11:38:24 +00:00
# Add platform specific I/O
platform.add_extension(_gpios) # General LED outputs
2021-01-02 11:46:28 +00:00
# For U28 3.3V(!) inputs: (also see separate picture)
2020-11-21 17:39:36 +00:00
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)
'''
2021-01-02 11:46:28 +00:00
# For U15 (not used currently)
2020-11-20 11:38:24 +00:00
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))
2020-11-21 17:39:36 +00:00
'''
2021-01-02 11:46:28 +00:00
# OR it all together: Every input lights LED ...
2020-11-21 17:39:36 +00:00
self.led_logic1 = led_logic1 = Signal(1)
2020-11-20 11:38:24 +00:00
self.comb += led_logic1.eq(J1_1 | J1_2 | J1_3 | J1_5 | J1_6 | J1_7 | J2_1 | J2_2)
2021-01-02 11:46:28 +00:00
#led_logic2 = Signal(1) # Not used currently
2020-11-21 17:39:36 +00:00
#self.comb += led_logic2.eq(J8_1 | J8_2 | J8_3 | J8_5 | J8_6 | J8_7 | J7_5 | J7_7)
2020-09-19 09:28:09 +00:00
# Base counter (used for clocking)
counter = Signal(32) # 32-Bit counter
self.sync += counter.eq(counter + 1)
# USERLED blink (on-board LED)
2020-10-17 16:50:33 +00:00
# only w/ uart-name=crossover option:
2020-10-18 10:05:25 +00:00
if kwargs["uart_name"] not in ["serial", "bridge"]:
2021-01-02 11:46:28 +00:00
self.comb += platform.request("user_led_n").eq(~(counter[23] | led_logic1)) #| led_logic2) # ~2Hz | inputs
2020-09-19 09:28:09 +00:00
2021-01-02 11:46:28 +00:00
# System time (count)
self.submodules.systime = systime = SysTime(comparecount=0x0000EA90)
self.add_csr("systime")
2020-10-18 10:05:25 +00:00
# Adjust no. for your actual project ...
max_TABLES = 3 # 1..16
max_LEDS_per_chain = 27 # 1..256
2020-09-29 22:44:27 +00:00
self.submodules.npe = NeoPixelEngine(n_TABLES=max_TABLES, n_LEDs=max_LEDS_per_chain)
self.add_csr("npe")
2020-10-18 10:05:25 +00:00
for i in range(42,56+2): # Example: Do output on J4 (14) & J5 (2)
2020-09-29 22:44:27 +00:00
self.comb += platform.request("gpio", i).eq(self.npe.bDataPin[i-42]) # Output data pin
2020-09-19 09:28:09 +00:00
# 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.")
2020-09-19 09:28:09 +00:00
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")
2020-09-19 09:28:09 +00:00
args = parser.parse_args()
2020-10-02 17:34:19 +00:00
#assert not (args.with_ethernet and args.with_etherbone)
2020-09-19 09:28:09 +00:00
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),
2020-09-19 09:28:09 +00:00
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 ------------------------------------------------------------------------
2020-10-23 17:09:05 +00:00
flashbase = 0xc0000000
flashoffset = 0x100000 # Used to be zero (default)
soc.mem_map["spiflash"] = flashbase # Length: 0x01000000 ('til 0xc1000000 - 1)
# Boot at +1MB
2020-10-22 14:36:58 +00:00
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)
2020-10-22 14:36:58 +00:00
builder = Builder(soc, **builder_argdict(args))
2020-10-23 17:09:05 +00:00
# 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
2020-09-19 09:28:09 +00:00
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
2020-09-19 09:28:09 +00:00
if args.flash: # Convert Bit File to Jtag Write Flash command
name = os.path.join(builder.gateware_dir, soc.build_name)
2020-09-26 15:57:23 +00:00
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
2020-09-19 09:28:09 +00:00
if __name__ == "__main__":
copyjob() # Create backup if nec. & move our firmware to the correct location
2020-09-19 09:28:09 +00:00
main()
# Maybe revoke backup action here ...