Better autodoc, firmware project local w/ copyjob

master
kaqu 2 years ago
parent e56f154623
commit d1272adbbb
  1. 193
      firmware/main.c
  2. 174
      firmware/main.c.original
  3. 15
      neopixelar.py
  4. 31
      neopixelengine.py
  5. 84187
      npe.vcd
  6. 38
      prepare_firmware.py

@ -0,0 +1,193 @@
// This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
// This file is Copyright (c) 2014-2019 Florent Kermarrec <florent@enjoy-digital.fr>
// This file is Copyright (c) 2015 Yann Sionneau <ys@m-labs.hk>
// This file is Copyright (c) 2015 whitequark <whitequark@whitequark.org>
// This file is Copyright (c) 2019 Ambroz Bizjak <ambrop7@gmail.com>
// This file is Copyright (c) 2019 Caleb Jamison <cbjamo@gmail.com>
// This file is Copyright (c) 2018 Dolu1990 <charles.papon.90@gmail.com>
// This file is Copyright (c) 2018 Felix Held <felix-github@felixheld.de>
// This file is Copyright (c) 2019 Gabriel L. Somlo <gsomlo@gmail.com>
// This file is Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.fr>
// This file is Copyright (c) 2018 Sergiusz Bazanski <q3k@q3k.org>
// This file is Copyright (c) 2016 Tim 'mithro' Ansell <mithro@mithis.com>
// This file is Copyright (c) 2020 Franck Jullien <franck.jullien@gmail.com>
// This file is Copyright (c) 2020 Antmicro <www.antmicro.com>
// License: BSD
#include <stdio.h>
#include <stdlib.h>
#include <console.h>
#include <string.h>
#include <uart.h>
#include <system.h>
#include <id.h>
#include <irq.h>
#include <crc.h>
#include "boot.h"
#include "readline.h"
#include "helpers.h"
#include "command.h"
#include <generated/csr.h>
#include <generated/soc.h>
#include <generated/mem.h>
#include <generated/git.h>
#include <spiflash.h>
#include <liblitedram/sdram.h>
#include <libliteeth/udp.h>
#include <libliteeth/mdio.h>
#include <liblitespi/spiflash.h>
#include <liblitesdcard/sdcard.h>
static void boot_sequence(void)
{
if(serialboot()) {
#ifdef FLASH_BOOT_ADDRESS
flashboot();
#endif
#ifdef ROM_BOOT_ADDRESS
romboot();
#endif
#if defined(CSR_SPISDCARD_BASE) || defined(CSR_SDCORE_BASE)
sdcardboot();
#endif
#ifdef CSR_ETHMAC_BASE
#ifdef CSR_ETHPHY_MODE_DETECTION_MODE_ADDR
eth_mode();
#endif
netboot();
#endif
printf("No boot medium found\n");
}
}
int main(int i, char **c)
{
char buffer[CMD_LINE_BUFFER_SIZE];
char *params[MAX_PARAM];
char *command;
struct command_struct *cmd;
int nb_params;
int sdr_ok;
//npe_b24Data2Load_write(uint32_t)
//npe_b8LoadOffset_write(uint8_t v)
//npe_b8Len_write(uint8_t v)
//npe_bEnable_write(uint8_t v)
for(int i=0;i<27;i+=3)
{
npe_b8LoadOffset_write(i); // @Offset 0
npe_b24Data2Load_write(0x040000); // G
npe_b8LoadOffset_write(i+1); // @Offset 0
npe_b24Data2Load_write(0x000400); // R
npe_b8LoadOffset_write(i+2); // @Offset 0
npe_b24Data2Load_write(0x000004); // B
if(!i) // Only on init. ...
npe_b8Len_write(27); // Length
npe_bEnable_write(1); // Enable!
}
#ifdef CONFIG_CPU_HAS_INTERRUPT
irq_setmask(0);
irq_setie(1);
#endif
uart_init();
printf("\n");
printf("\e[1m __ _ __ _ __\e[0m\n");
printf("\e[1m / / (_) /____ | |/_/\e[0m\n");
printf("\e[1m / /__/ / __/ -_)> <\e[0m\n");
printf("\e[1m /____/_/\\__/\\__/_/|_|\e[0m\n");
printf("\e[1m Build your hardware, easily!\e[0m\n");
printf("\n");
printf(" (c) Copyright 2012-2020 Enjoy-Digital\n");
printf(" (c) Copyright 2007-2015 M-Labs\n");
printf(" --- Copyleft 2020 KQ ---------\n");
printf("\n");
printf(" BIOS built on "__DATE__" "__TIME__"\n");
crcbios();
printf("\n");
printf(" Migen git sha1: "MIGEN_GIT_SHA1"\n");
printf(" LiteX git sha1: "LITEX_GIT_SHA1"\n");
printf("\n");
printf("--=============== \e[1mSoC\e[0m ==================--\n");
printf("\e[1mCPU\e[0m:\t\t%s @ %dMHz\n",
CONFIG_CPU_HUMAN_NAME,
CONFIG_CLOCK_FREQUENCY/1000000);
printf("\e[1mBUS\e[0m:\t\t%s %d-bit @ %dGiB\n",
CONFIG_BUS_STANDARD,
CONFIG_BUS_DATA_WIDTH,
(1 << (CONFIG_BUS_ADDRESS_WIDTH - 30)));
printf("\e[1mCSR\e[0m:\t\t%d-bit data\n",
CONFIG_CSR_DATA_WIDTH);
printf("\e[1mROM\e[0m:\t\t%dKiB\n", ROM_SIZE/1024);
printf("\e[1mSRAM\e[0m:\t\t%dKiB\n", SRAM_SIZE/1024);
#ifdef CONFIG_L2_SIZE
printf("\e[1mL2\e[0m:\t\t%dKiB\n", CONFIG_L2_SIZE/1024);
#endif
#ifdef MAIN_RAM_SIZE
#ifdef CSR_SDRAM_BASE
printf("\e[1mSDRAM\e[0m:\t\t%dKiB %d-bit @ %dMbps/pin\n",
MAIN_RAM_SIZE/1024,
sdrdatabits(),
sdrfreq()/1000000);
#else
printf("\e[1mMAIN-RAM\e[0m:\t%dKiB \n", MAIN_RAM_SIZE/1024);
#endif
#endif
printf("\n");
sdr_ok = 1;
#if defined(CSR_ETHMAC_BASE) || defined(CSR_SDRAM_BASE)
printf("--========== \e[1mInitialization\e[0m ============--\n");
#ifdef CSR_ETHMAC_BASE
eth_init();
#endif
#ifdef CSR_SDRAM_BASE
sdr_ok = sdrinit();
#else
#ifdef MAIN_RAM_TEST
sdr_ok = memtest();
#endif
#endif
if (sdr_ok !=1)
printf("Memory initialization failed\n");
printf("\n");
#endif
#ifdef CSR_SPIFLASH_MMAP_BASE
spiflash_init();
#endif
if(sdr_ok) {
printf("--============== \e[1mBoot\e[0m ==================--\n");
boot_sequence();
printf("\n");
}
printf("--============= \e[1mConsole\e[0m ================--\n");
#if !defined(TERM_MINI) && !defined(TERM_NO_HIST)
hist_init();
#endif
printf("\n%s", PROMPT);
while(1) {
readline(buffer, CMD_LINE_BUFFER_SIZE);
if (buffer[0] != 0) {
printf("\n");
nb_params = get_param(buffer, &command, params);
cmd = command_dispatcher(command, nb_params, params);
if (!cmd)
printf("Command not found");
}
printf("\n%s", PROMPT);
}
return 0;
}

@ -0,0 +1,174 @@
// This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
// This file is Copyright (c) 2014-2019 Florent Kermarrec <florent@enjoy-digital.fr>
// This file is Copyright (c) 2015 Yann Sionneau <ys@m-labs.hk>
// This file is Copyright (c) 2015 whitequark <whitequark@whitequark.org>
// This file is Copyright (c) 2019 Ambroz Bizjak <ambrop7@gmail.com>
// This file is Copyright (c) 2019 Caleb Jamison <cbjamo@gmail.com>
// This file is Copyright (c) 2018 Dolu1990 <charles.papon.90@gmail.com>
// This file is Copyright (c) 2018 Felix Held <felix-github@felixheld.de>
// This file is Copyright (c) 2019 Gabriel L. Somlo <gsomlo@gmail.com>
// This file is Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.fr>
// This file is Copyright (c) 2018 Sergiusz Bazanski <q3k@q3k.org>
// This file is Copyright (c) 2016 Tim 'mithro' Ansell <mithro@mithis.com>
// This file is Copyright (c) 2020 Franck Jullien <franck.jullien@gmail.com>
// This file is Copyright (c) 2020 Antmicro <www.antmicro.com>
// License: BSD
#include <stdio.h>
#include <stdlib.h>
#include <console.h>
#include <string.h>
#include <uart.h>
#include <system.h>
#include <id.h>
#include <irq.h>
#include <crc.h>
#include "boot.h"
#include "readline.h"
#include "helpers.h"
#include "command.h"
#include <generated/csr.h>
#include <generated/soc.h>
#include <generated/mem.h>
#include <generated/git.h>
#include <spiflash.h>
#include <liblitedram/sdram.h>
#include <libliteeth/udp.h>
#include <libliteeth/mdio.h>
#include <liblitespi/spiflash.h>
#include <liblitesdcard/sdcard.h>
static void boot_sequence(void)
{
if(serialboot()) {
#ifdef FLASH_BOOT_ADDRESS
flashboot();
#endif
#ifdef ROM_BOOT_ADDRESS
romboot();
#endif
#if defined(CSR_SPISDCARD_BASE) || defined(CSR_SDCORE_BASE)
sdcardboot();
#endif
#ifdef CSR_ETHMAC_BASE
#ifdef CSR_ETHPHY_MODE_DETECTION_MODE_ADDR
eth_mode();
#endif
netboot();
#endif
printf("No boot medium found\n");
}
}
int main(int i, char **c)
{
char buffer[CMD_LINE_BUFFER_SIZE];
char *params[MAX_PARAM];
char *command;
struct command_struct *cmd;
int nb_params;
int sdr_ok;
#ifdef CONFIG_CPU_HAS_INTERRUPT
irq_setmask(0);
irq_setie(1);
#endif
uart_init();
printf("\n");
printf("\e[1m __ _ __ _ __\e[0m\n");
printf("\e[1m / / (_) /____ | |/_/\e[0m\n");
printf("\e[1m / /__/ / __/ -_)> <\e[0m\n");
printf("\e[1m /____/_/\\__/\\__/_/|_|\e[0m\n");
printf("\e[1m Build your hardware, easily!\e[0m\n");
printf("\n");
printf(" (c) Copyright 2012-2020 Enjoy-Digital\n");
printf(" (c) Copyright 2007-2015 M-Labs\n");
printf("\n");
printf(" BIOS built on "__DATE__" "__TIME__"\n");
crcbios();
printf("\n");
printf(" Migen git sha1: "MIGEN_GIT_SHA1"\n");
printf(" LiteX git sha1: "LITEX_GIT_SHA1"\n");
printf("\n");
printf("--=============== \e[1mSoC\e[0m ==================--\n");
printf("\e[1mCPU\e[0m:\t\t%s @ %dMHz\n",
CONFIG_CPU_HUMAN_NAME,
CONFIG_CLOCK_FREQUENCY/1000000);
printf("\e[1mBUS\e[0m:\t\t%s %d-bit @ %dGiB\n",
CONFIG_BUS_STANDARD,
CONFIG_BUS_DATA_WIDTH,
(1 << (CONFIG_BUS_ADDRESS_WIDTH - 30)));
printf("\e[1mCSR\e[0m:\t\t%d-bit data\n",
CONFIG_CSR_DATA_WIDTH);
printf("\e[1mROM\e[0m:\t\t%dKiB\n", ROM_SIZE/1024);
printf("\e[1mSRAM\e[0m:\t\t%dKiB\n", SRAM_SIZE/1024);
#ifdef CONFIG_L2_SIZE
printf("\e[1mL2\e[0m:\t\t%dKiB\n", CONFIG_L2_SIZE/1024);
#endif
#ifdef MAIN_RAM_SIZE
#ifdef CSR_SDRAM_BASE
printf("\e[1mSDRAM\e[0m:\t\t%dKiB %d-bit @ %dMbps/pin\n",
MAIN_RAM_SIZE/1024,
sdrdatabits(),
sdrfreq()/1000000);
#else
printf("\e[1mMAIN-RAM\e[0m:\t%dKiB \n", MAIN_RAM_SIZE/1024);
#endif
#endif
printf("\n");
sdr_ok = 1;
#if defined(CSR_ETHMAC_BASE) || defined(CSR_SDRAM_BASE)
printf("--========== \e[1mInitialization\e[0m ============--\n");
#ifdef CSR_ETHMAC_BASE
eth_init();
#endif
#ifdef CSR_SDRAM_BASE
sdr_ok = sdrinit();
#else
#ifdef MAIN_RAM_TEST
sdr_ok = memtest();
#endif
#endif
if (sdr_ok !=1)
printf("Memory initialization failed\n");
printf("\n");
#endif
#ifdef CSR_SPIFLASH_MMAP_BASE
spiflash_init();
#endif
if(sdr_ok) {
printf("--============== \e[1mBoot\e[0m ==================--\n");
boot_sequence();
printf("\n");
}
printf("--============= \e[1mConsole\e[0m ================--\n");
#if !defined(TERM_MINI) && !defined(TERM_NO_HIST)
hist_init();
#endif
printf("\n%s", PROMPT);
while(1) {
readline(buffer, CMD_LINE_BUFFER_SIZE);
if (buffer[0] != 0) {
printf("\n");
nb_params = get_param(buffer, &command, params);
cmd = command_dispatcher(command, nb_params, params);
if (!cmd)
printf("Command not found");
}
printf("\n%s", PROMPT);
}
return 0;
}

@ -22,10 +22,11 @@
# to generate
# - 'python3 neopixelar.py --load' to download to FPGA
# - 'ping 192.168.1.50' to verify ethernet connection - via LEFT(!) RJ45 port
# - 'wishbone-tool --ethernet-host 192.168.1.50 --server terminal --csr-csv build/csr.csv'
# - '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
#
# ~/fpga/litex/litex/litex/soc/doc/module.py for autodoc functionality ...
#
import os
import argparse
import sys
@ -59,6 +60,8 @@ import litex.soc.doc as lxsocdoc
from neopixelengine import NeoPixelEngine
from 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 = [
@ -332,7 +335,7 @@ class BaseSoC(SoCCore):
platform.add_extension(_gpios) # General LED outputs
self.submodules.npe = NeoPixelEngine()
self.submodules.npe = NeoPixelEngine(27)
self.add_csr("npe")
for i in range(42,56): # Do output on J4
self.comb += platform.request("gpio", i).eq(self.npe.bDataPin) # Output data pin
@ -371,8 +374,8 @@ def main():
use_internal_osc = args.use_internal_osc,
sdram_rate = args.sdram_rate,
**soc_core_argdict(args))
builder = Builder(soc, **builder_argdict(args))
builder.build(**trellis_argdict(args), run=args.build)
builder = Builder(soc, **builder_argdict(args))
builder.build(**trellis_argdict(args), run=args.build) # Written here to (local) build tree
if args.doc:
print("Generating documentation for sphinx ...")
@ -384,4 +387,6 @@ def main():
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".svf"))
if __name__ == "__main__":
copyjob() # Create backup if nec. & move our firmware to the correct location
main()
# Maybe revoke backup action here ...

@ -35,18 +35,28 @@ class NeoPixelEngine(Module, AutoCSR):
:return bDataPin bool: NeoPixel 'Din' pin output
"""
def __init__(self):
def __init__(self, n_LEDs=3):
# On Colorlight-5A-75B/Lattice ECP5-25 (@i7/4th gen.):
# 256 NeoPixel LEDs will use 95% of TRELLIS_SLICES & REQUIRE ether_net & ether_bone being DISABLED! Calc. time >2h
# 192 NeoPixel LEDs w/ ethernet/etherbone will use 95% of TRELLIS_SLICES & take approx. 2:20h to calculate
# 27 NeoPixels LEDs w/ ethernet/etherbone used for any tests will require 73% of TRELLIS_SLICES & take less than 0:10h to calculate
n_LEDs = 27
# 27 NeoPixels LEDs w/ ethernet/etherbone used for any tests will require 73% of TRELLIS_SLICES & take less than 0:10h to calculate
self.b24GRBArray = Array(Signal(24) for word24 in range(n_LEDs)) # Local 24-bit data Array
# Inputs
self.b24Data2Load = CSRStorage(24, reset_less=True, description="Load value (GRB)")
self.b8LoadOffset = CSRStorage(8, reset_less=True, description="Offset to store (GRB) value")
self.b8Len = CSRStorage(8, reset_less=True, description="No. of active (GRB) entries")
self.bEnable = CSRStorage(8, reset_less=True, description="Enable free run signal (start & abort)")
self.b24Data2Load = CSRStorage(24, reset_less=True, description="""
Load value (24-Bit G/R/B).
Use *b8LoadOffset* first to indicate array location where to store this value.
""")
self.b8LoadOffset = CSRStorage(8, reset_less=True, description="""
Offset into storage array for 24-bit G/R/B values.
Prepare this one first, then indicate value to store via *b24Data2Load*.
""")
self.b8Len = CSRStorage(8, reset_less=True, description="""
No. of active (GRB) entries.
Indicate actual # of elements used (may be less than max!)
""")
self.bEnable = CSRStorage(8, reset_less=True, description="""
Enable free run (signal start & abort)
""")
# Local data
self.b8Offset = Signal(8) # Array rover
@ -144,9 +154,8 @@ class NeoPixelEngine(Module, AutoCSR):
)
)
def npe_testbench(npe):
print("----- npe testbench -----")
print("----- npe testbench -----")
yield npe.b8LoadOffset.storage.eq(3)
yield
yield npe.b24Data2Load.storage.eq(0x100000)
@ -163,7 +172,7 @@ def npe_testbench(npe):
yield
#
for i in range(10000): # Send the whole data & restart ...
print(i,": ", sep="", end="")
print(i,": ", sep="", end="")
print((yield npe.bDataPin)) # Actual pin to move
yield
if i == 5000:
@ -171,5 +180,5 @@ def npe_testbench(npe):
yield
if __name__ == "__main__":
npe = NeoPixelEngine()
npe = NeoPixelEngine(n_LEDs=3)
run_simulation(npe, npe_testbench(npe), vcd_name="npe.vcd")

84187
npe.vcd

File diff suppressed because it is too large Load Diff

@ -0,0 +1,38 @@
#!/usr/bin/env python3
#
# prepare_firmware.py
#
# Utility to temporarily move project local resources to LiteX path
# (w/ backing up of original data)
#
# History:
# --------
# 25.10.20/KQ Initial version
#
import os
import shutil
def copyjob():
#for ev in os.environ:
# print(ev, " = ", os.environ[ev])
# $PWD path to working directory
# $HOME path to home directory of current user
localpath = os.environ["PWD"] + "/firmware/"
path2firmware = os.environ["HOME"] + "/fpga/litex/litex/litex/soc/software/bios/"
originalfilename = "main.c"
backupfilename = "main.c.bak"
backupfilename2 = "main.c.original"
if os.path.isfile(path2firmware + backupfilename): # Check for existing backup
print("Backup already exists")
else: # Ok, no backup. Let's create one in-place & one to our local project directory ...
print("Preparing backup first ...")
shutil.copy2(path2firmware + originalfilename, path2firmware + backupfilename)
shutil.copy2(path2firmware + originalfilename, localpath + backupfilename2)
print("Backups in-place & to local project path finished.")
print("Copying project firmware to target path ...")
shutil.copy2(localpath + originalfilename, path2firmware + originalfilename)
if __name__ == "__main__":
copyjob()
Loading…
Cancel
Save