This is useful for un-usual boot sequences where the binaries are not
loaded directly by the BIOS but externally (over a bridge for example).
Example of use:
$litex_sim
$litex_bare_metal_demo --build-path=build/sim
$litex_sim --ram-init=demo.bin
Press Esc during the LiteX boot.
litex> help
LiteX BIOS, available commands:
flush_cpu_dcache - Flush CPU data cache
crc - Compute CRC32 of a part of the address space
ident - Identifier of the system
help - Print this help
serialboot - Boot from Serial (SFL)
romboot - Boot from ROM
reboot - Reboot
boot - Boot from Memory
mem_speed - Test memory speed
mem_test - Test memory access
mem_copy - Copy address space
mem_write - Write address space
mem_read - Read address space
mem_list - List available memory regions
litex>
litex> mem_list
Available memory regions:
ROM 0x00000000 0x8000
SRAM 0x01000000 0x2000
MAIN_RAM 0x40000000 0x10000000
CSR 0x82000000 0x10000
litex>
litex> boot 0x40000000
Executing booted program at 0x40000000
--============= Liftoff! ===============--
LiteX minimal demo app built Feb 24 2021 11:30:05
Available commands:
help - Show this command
reboot - Reboot CPU
donut - Spinning Donut demo
litex-demo-app>
The CrossoverUART was in fact a particular UART connected to a second UART. Being able
to have access to multiple UARTs over a Bridge can be useful for several purposes, ex:
SoC0 --> UART0 + JTAGBone + litex_term bridge --bridge-name=UART0
SoC1 --> UART1 +--> SoC --> UARTBone --> LiteX-Server + litex_term bridge --bridge-name=UART1
SoC2 --> UART2 + EtherBone + litex_term bridge --bridge-name=UART2
LedChaser without PWM:
self.submodules.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
self.add_csr("leds")
Add PWM to it (with default values: 50% duty cycle):
self.leds.add_pwm()
Add PWM with custom default values (25% duty cycle here):
self.leds.add_pwm(default_width=128, default_period=1024)
Then adjust brightness dynamically from the BIOS or your software:
$cat csr.csv:
csr_register,leds_out,0x82003000,1,rw
csr_register,leds_pwm_enable,0x82003004,1,rw
csr_register,leds_pwm_width,0x82003008,1,rw
csr_register,leds_pwm_period,0x8200300c,1,rw
Set PWM to 0%:
$mem_write 0x82003008 0
Set PWM to 25%:
$mem_write 0x82003008 256
Set PWM to 50%:
$mem_write 0x82003008 512
Set PWM to 75%:
$mem_write 0x82003008 768
Set PWM to 100%:
$mem_write 0x82003008 1024
You can also only use default values and disable CSR is dynamic configuration is not
required (with_csr=False) or adjust PWM period if want to use a specific PWM period
in your system.
When the system/bus clock frequency is an exact power-of-2 multiple of
the desired sdcard frequency, we can drive the latter at the "maximum"
speed via the "perfect" divider. That sometimes turns out too fast, so
in order to be conservative, we double the divider, thus halving the
resulting sdclock.
This allows the Linux driver in single-block mode (cmd17-only) to
operate solidly, without running into timeouts from LiteSDCard FSMs.
FIXME: multi-block (cmd18) transfers still time out, so revisit this
after some additional debugging.
Use irqs dict and "rise", "fall" strings instead of Enums:
Ex: pads=Signal(8), irqs={} : 8-bit Input, No IRQ.
pads=Signal(8), irqs={0: "rise", 7: "fall"}: 8-bit Input, rising IRQ on 0, falling IRQ on 1.
Also simplify the logic.