diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 68801a7..46acc60 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -5,21 +5,30 @@ extern crate panic_halt; 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(); loop { //eth::tranmsit(); diff --git a/gateware/i2c.py b/gateware/i2c.py index f6f5fe9..0bd876a 100644 --- a/gateware/i2c.py +++ b/gateware/i2c.py @@ -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) diff --git a/gateware/main.py b/gateware/main.py index 0fe0381..d2da4ce 100644 --- a/gateware/main.py +++ b/gateware/main.py @@ -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()