Compare commits
3 Commits
26389576d5
...
f846cc1fab
Author | SHA1 | Date | |
---|---|---|---|
f846cc1fab | |||
ea32a00b68 | |||
4e7c9984d7 |
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"rust-analyzer.cargo.target": "riscv32i-unknown-none-elf",
|
||||
"rust-analyzer.check.allTargets": false
|
||||
}
|
1
firmware/Cargo.lock
generated
1
firmware/Cargo.lock
generated
@ -37,6 +37,7 @@ dependencies = [
|
||||
name = "fw"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"embedded-hal",
|
||||
"panic-halt",
|
||||
"riscv-rt",
|
||||
]
|
||||
|
@ -8,3 +8,4 @@ edition = "2021"
|
||||
[dependencies]
|
||||
riscv-rt = "0.11.0"
|
||||
panic-halt = "0.2.0"
|
||||
embedded-hal = "0.2.7"
|
||||
|
@ -13,35 +13,23 @@ const ETHMAC_SRAM_READER_LENGTH: u32 = LITEETH_BASE + 0x828;
|
||||
const ETHMAC_SRAM_READER_START: u32 = LITEETH_BASE + 0x818;
|
||||
const ETHMAC_SRAM_READER_READY: u32 = LITEETH_BASE + 0x81c;
|
||||
|
||||
fn write_u32_reg(addr: u32, value: u32) {
|
||||
use core::ptr::write;
|
||||
unsafe {
|
||||
write(addr as *mut u32, value);
|
||||
}
|
||||
}
|
||||
use crate::{write_reg, read_reg};
|
||||
|
||||
fn read_u32_reg(addr: u32) -> u32 {
|
||||
use core::ptr::read;
|
||||
unsafe {
|
||||
return read(addr as *mut u32);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_wishbone_correct() -> bool {
|
||||
let value = read_u32_reg(LITEETH_BASE + 4);
|
||||
pub unsafe fn is_wishbone_correct() -> bool {
|
||||
let value: u32 = read_reg(LITEETH_BASE + 4);
|
||||
|
||||
// If this isn't true, we screwed.
|
||||
return value == 0x12345678;
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
pub unsafe fn init() {
|
||||
// Clear any potential pending events
|
||||
write_u32_reg(ETHMAC_SRAM_WRITER_EV_PENDING, 1);
|
||||
write_u32_reg(ETHMAC_SRAM_READER_EV_PENDING, 1);
|
||||
write_reg(ETHMAC_SRAM_WRITER_EV_PENDING, 1u32);
|
||||
write_reg(ETHMAC_SRAM_READER_EV_PENDING, 1u32);
|
||||
|
||||
// Disable all events
|
||||
write_u32_reg(ETHMAC_SRAM_WRITER_EV_ENABLE, 0);
|
||||
write_u32_reg(ETHMAC_SRAM_READER_EV_ENABLE, 0);
|
||||
write_reg(ETHMAC_SRAM_WRITER_EV_ENABLE, 0u32);
|
||||
write_reg(ETHMAC_SRAM_READER_EV_ENABLE, 0u32);
|
||||
}
|
||||
|
||||
// a8:a1:59:32:a7:a5
|
||||
@ -49,7 +37,7 @@ const ares_mac: [u8; 6] = [0xA8, 0xA1, 0x59, 0x32, 0xA7, 0xA5];
|
||||
const fake_mac: [u8; 6] = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05];
|
||||
|
||||
/// Just make an ethernet frame and yeet it
|
||||
pub fn tranmsit() {
|
||||
pub unsafe fn tranmsit() {
|
||||
// Preamble/start delimiter/crc are all handled for us by the MAC
|
||||
let frame: [u8; 18] = [
|
||||
// TODO endianness of MAC addresses?
|
||||
@ -71,14 +59,12 @@ pub fn tranmsit() {
|
||||
tx_slot[..18].copy_from_slice(&frame);
|
||||
|
||||
// Set slot and packet length
|
||||
write_u32_reg(ETHMAC_SRAM_READER_SLOT, 0);
|
||||
write_u32_reg(ETHMAC_SRAM_READER_LENGTH, 18);
|
||||
write_reg(ETHMAC_SRAM_READER_SLOT, 0u32);
|
||||
write_reg(ETHMAC_SRAM_READER_LENGTH, 18u32);
|
||||
|
||||
// Wait to be ready
|
||||
while read_u32_reg(ETHMAC_SRAM_READER_READY) == 0 {}
|
||||
while read_reg::<u32>(ETHMAC_SRAM_READER_READY) == 0 {}
|
||||
|
||||
// Write!
|
||||
write_u32_reg(ETHMAC_SRAM_READER_START, 1);
|
||||
|
||||
|
||||
write_reg(ETHMAC_SRAM_READER_START, 1u32);
|
||||
}
|
||||
|
@ -3,33 +3,39 @@
|
||||
|
||||
extern crate panic_halt;
|
||||
|
||||
use core::{arch::asm, ptr::write};
|
||||
use core::{arch::asm, ptr::{write, read}};
|
||||
|
||||
use embedded_hal::prelude::_embedded_hal_blocking_i2c_Write;
|
||||
use riscv_rt::entry;
|
||||
|
||||
mod eth;
|
||||
mod i2c;
|
||||
|
||||
// use `main` as the entry point of this application
|
||||
// `main` is not allowed to return
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
eth::init();
|
||||
//unsafe { eth::init(); }
|
||||
|
||||
let blink_period = if eth::is_wishbone_correct() {
|
||||
10_000_000
|
||||
} else {
|
||||
500_000
|
||||
};
|
||||
//let blink_period = unsafe {
|
||||
// if eth::is_wishbone_correct() {
|
||||
// 10_000_000
|
||||
// } else {
|
||||
// 500_000
|
||||
// }
|
||||
//};
|
||||
let blink_period = 10_000_000u32;
|
||||
|
||||
let mut i2c = i2c::AmlibI2c::new(0x01003000);
|
||||
let data = [0u8, 2u8];
|
||||
i2c.write(0xAA, &data).unwrap();
|
||||
|
||||
// do something here
|
||||
loop {
|
||||
unsafe {
|
||||
//eth::tranmsit();
|
||||
write_led(0);
|
||||
busy_wait(blink_period);
|
||||
write_led(1);
|
||||
busy_wait(blink_period);
|
||||
}
|
||||
//eth::tranmsit();
|
||||
write_led(0);
|
||||
busy_wait(blink_period);
|
||||
write_led(1);
|
||||
busy_wait(blink_period);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +48,13 @@ fn busy_wait(num_nops: u32) {
|
||||
}
|
||||
|
||||
fn write_led(val: u32) {
|
||||
unsafe {
|
||||
write(0x01002000 as *mut u32, val);
|
||||
}
|
||||
unsafe { write_reg(0x0100200, val); }
|
||||
}
|
||||
|
||||
unsafe fn write_reg<T>(addr: u32, value: T) {
|
||||
write(addr as *mut T, value);
|
||||
}
|
||||
|
||||
unsafe fn read_reg<T>(addr: u32) -> T {
|
||||
return read(addr as *mut T);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ class I2C(Elaboratable):
|
||||
|
||||
# Set up CSR bus
|
||||
addr_width = ceil(log2(64)) # Support up to 64 registers just because
|
||||
data_width = 32 # 32 bit bus
|
||||
data_width = 8 # 32 bit bus
|
||||
self._csr_mux = Multiplexer(addr_width=addr_width, data_width=data_width)
|
||||
# TODO export the addresses of these somehow
|
||||
self._csr_mux.add(self.CR)
|
||||
|
@ -4,6 +4,9 @@ from amaranth import *
|
||||
from amaranth.sim import *
|
||||
from amaranth_boards import colorlight_i9
|
||||
from amaranth_soc.wishbone import *
|
||||
from amaranth_soc import csr
|
||||
from amaranth_soc.csr.wishbone import WishboneCSRBridge
|
||||
from amaranth.lib.io import pin_layout
|
||||
|
||||
from minerva.core import Minerva
|
||||
|
||||
@ -38,6 +41,18 @@ def load_firmware_for_mem() -> List[int]:
|
||||
|
||||
return out
|
||||
|
||||
class I2CPads:
|
||||
"""Small structure to avoid using record. Unsure what the proper solution is"""
|
||||
class Pad:
|
||||
def __init__(self):
|
||||
self.o = Signal()
|
||||
self.i = Signal()
|
||||
self.oe = Signal()
|
||||
|
||||
def __init__(self):
|
||||
self.scl = self.Pad()
|
||||
self.sda = self.Pad()
|
||||
|
||||
class Core(Elaboratable):
|
||||
def __init__(self, clk25, led_signal, eth_interface):
|
||||
self.count = Signal(64)
|
||||
@ -124,12 +139,36 @@ class Core(Elaboratable):
|
||||
start, _stop, _step = self.decoder.add(self.led)
|
||||
print(f"LED added at 0x{start:08x}")
|
||||
|
||||
m.submodules.uart = uart.UART(10e6)
|
||||
# TODO how to set addr_width?
|
||||
# Create CSR bus and connect it to Wishbone
|
||||
self.csr = csr.Decoder(addr_width=10, data_width=8)
|
||||
m.submodules.csr = self.csr
|
||||
print(f"CSR bus added at 0x{start:08x}")
|
||||
|
||||
# I2C (connected to DAC for VCO and ADC?)
|
||||
Signal()
|
||||
if platform is not None:
|
||||
i2c_pads = platform.request("i2c")
|
||||
else:
|
||||
# TODO this is hacky crap
|
||||
i2c_pads = I2CPads()
|
||||
with m.If(i2c_pads.scl.oe):
|
||||
m.d.comb += i2c_pads.scl.i.eq(0)
|
||||
with m.Else():
|
||||
m.d.comb += i2c_pads.scl.i.eq(1)
|
||||
self.i2c = i2c.I2C(50e6, 100e3, i2c_pads)
|
||||
m.submodules.i2c = self.i2c
|
||||
self.csr.add(self.i2c.bus)
|
||||
|
||||
self.csr_bridge = WishboneCSRBridge(self.csr.bus, data_width=32, name="CSR")
|
||||
m.submodules.csr_bridge = self.csr_bridge
|
||||
# TODO shouldn't have to hard-specify this address
|
||||
start, _stop, _step = self.decoder.add(self.csr_bridge.wb_bus, addr=0x01003000)
|
||||
|
||||
# Ethernet
|
||||
self.eth = LiteEth(self.eth_interface)
|
||||
m.submodules.eth = self.eth
|
||||
start, _stop, _step = self.decoder.add(self.eth, addr=0x02000000)
|
||||
#start, _stop, _step = self.decoder.add(self.eth, addr=0x02000000)
|
||||
print(f"LiteETH added at 0x{start:08x}")
|
||||
|
||||
# Connect arbiter to decoder
|
||||
@ -167,7 +206,7 @@ def run_sim():
|
||||
sim = Simulator(dut)
|
||||
|
||||
def proc():
|
||||
for i in range(1000):
|
||||
for i in range(10000):
|
||||
yield Tick()
|
||||
|
||||
sim.add_clock(1e-6)
|
||||
@ -205,5 +244,6 @@ if __name__ == "__main__":
|
||||
unittest.main(module=mod, argv=[sys.argv[0]])
|
||||
|
||||
if args.sim:
|
||||
print("Running simulation...")
|
||||
run_sim()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user