Remote/wishbone access to 1st NeoPixel (24-bit)

master
kaqu 2 years ago
parent a7beeab8a4
commit 925e68b824
  1. 10
      .vscode/launch.json
  2. 42
      neopixelar.py
  3. 8
      neopixelengine.py
  4. 84531
      npe.vcd
  5. 38
      remotetest.py

@ -9,7 +9,15 @@
"type": "python",
"request": "launch",
"program": "${file}",
"args": ["--build", "--revision=7.0", "--uart-name=crossover", "--with-etherbone", "--csr-csv=build/csr.csv", "--doc"],
"args": ["--build",
"--revision=7.0",
"--uart-name=crossover",
"--with-etherbone",
"--ip-address=192.168.1.20",
"--csr-csv=build/csr.csv", // Only this one for remotetest.py!
"--doc"
],
//"args": ["--build"],
//"pythonArgs": ["--build", "--uart-name=crossover"],
"console": "integratedTerminal"
}

@ -6,6 +6,10 @@
# 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:
# --------
@ -21,24 +25,24 @@
# - 'wishbone-tool --ethernet-host 192.168.1.50 --server terminal --csr-csv build/csr.csv'
# You should see the LiteX BIOS and be able to interact with it
#
# 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...
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, colorlight_5a_75e
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 *
@ -268,16 +272,8 @@ class _CRG(Module):
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, board, revision, with_ethernet=False, with_etherbone=False, eth_phy=0, sys_clk_freq=60e6, use_internal_osc=False, sdram_rate="1:1", **kwargs):
board = board.lower()
assert board in ["5a-75b", "5a-75e"]
if board == "5a-75b":
platform = colorlight_5a_75b.Platform(revision=revision)
elif board == "5a-75e":
platform = colorlight_5a_75e.Platform(revision=revision)
if board == "5a-75e" and revision == "6.0" and (with_etherbone or with_ethernet):
assert use_internal_osc, "You cannot use the 25MHz clock as system clock since it is provided by the Ethernet PHY and will stop during PHY reset."
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),
@ -319,7 +315,11 @@ class BaseSoC(SoCCore):
if with_ethernet:
self.add_ethernet(phy=self.ethphy)
if with_etherbone:
self.add_etherbone(phy=self.ethphy)
self.add_etherbone(
phy=self.ethphy,
ip_address = ip_address,
mac_address = mac_address,
)
# Base counter (used for clocking)
counter = Signal(32) # 32-Bit counter
@ -332,8 +332,14 @@ class BaseSoC(SoCCore):
self.submodules.npe = NeoPixelEngine()
self.add_csr("npe")
sw_gpio = Signal(24)
self.submodules.npe_data = GPIOOut(sw_gpio)
self.comb += self.npe.b24GRBArray[0].eq(sw_gpio) # 1st LED G(reen) Bit4
self.add_csr("npe_data")
# Inputs 1st
self.comb += self.npe.b24GRBArray[0].eq(0x330000) # 1st: G
#self.comb += self.npe.b24GRBArray[0].eq(0x330000) # 1st: G
self.comb += self.npe.b24GRBArray[1].eq(0x004400) # 2nd: R
self.comb += self.npe.b24GRBArray[2].eq(0x000055) # 3rd: B
self.comb += self.npe.b24GRBArray[3].eq(0x330000) # 1st: G
@ -387,6 +393,8 @@ def main():
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")
@ -399,6 +407,8 @@ def main():
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,

@ -15,9 +15,12 @@
#
from migen import *
from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
class NeoPixelEngine(Module):
class NeoPixelEngine(Module, AutoCSR):
def __init__(self):
self.output = CSRStorage(32,reset_less=True,write_from_dev=True)
self.bStart = Signal() # External input: Start pulse
self.b8Len = Signal(8) # External input: No. of 24-bit data to transfer (unsigned)
self.b24GRBArray = Array(Signal(24) for word24 in range(255)) # External input: 24-bit data Array
@ -30,7 +33,8 @@ class NeoPixelEngine(Module):
self.bDataPin = Signal() # Output: To be wired to data pin ...
###
self.comb += self.output.re.eq(0x12345678) # Assign a defined value to memory
fsm = FSM(reset_state="IDLE") # FSM starts idling ...
self.submodules += fsm

84531
npe.vcd

File diff suppressed because it is too large Load Diff

@ -0,0 +1,38 @@
#!/usr/bin/env python3
#
# remotetest.py
# Test remote access to NeoPixelar
#
# History:
# --------
# 20.09.20/KQ Initial version
#
import argparse
import time
from litex import RemoteClient
def test(csr_csv):
wb = RemoteClient(csr_csv=csr_csv) # Access wishbone bus
wb.open() # to remote client
print("NeoPixel #0 on & off test: ")
for i in range(10):
print(".",end="")
wb.regs.npe_data_out.write(0x100000)
time.sleep(0.5)
wb.regs.npe_data_out.write(0)
time.sleep(0.5)
wb.close() # Close wishbone access
print(" Done.")
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on Colorlight 5A-75X Testbench")
parser.add_argument("--csr-csv", default="build/csr.csv", help="CSR list location")
args = parser.parse_args()
test(args.csr_csv)
if __name__ == "__main__":
main()
Loading…
Cancel
Save