diff --git a/firmware/.cargo/config b/firmware/.cargo/config index 5ca804d..9b23ddb 100644 --- a/firmware/.cargo/config +++ b/firmware/.cargo/config @@ -2,6 +2,9 @@ rustflags = [ "-C", "link-arg=-Tmemory.x", "-C", "link-arg=-Tlink.x", + + # defmt + "-C", "link-arg=-Tdefmt.x", ] [build] diff --git a/firmware/Cargo.lock b/firmware/Cargo.lock index 547b46e..b18dc33 100644 --- a/firmware/Cargo.lock +++ b/firmware/Cargo.lock @@ -56,6 +56,38 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" +[[package]] +name = "defmt" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956673bd3cb347512bf988d1e8d89ac9a82b64f6eec54d3c01c3529dac019882" +dependencies = [ + "bitflags", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82610855c67a4dc36299cc6bfcf140f329e4f013582531c7ba7d32512ddabc47" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "defmt-parser" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e15e994575e38332cf4a2dc9dc745ff6a65695d37a41e00efadd57fcd42c1ba4" +dependencies = [ + "thiserror", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -70,6 +102,7 @@ dependencies = [ name = "fw" version = "0.1.0" dependencies = [ + "defmt", "embedded-hal", "panic-halt", "riscv-rt", @@ -92,6 +125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" dependencies = [ "atomic-polyfill", + "defmt", "hash32", "rustc_version", "spin", @@ -147,6 +181,30 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.50" @@ -262,6 +320,7 @@ dependencies = [ "bitflags", "byteorder", "cfg-if", + "defmt", "heapless", "managed", ] @@ -292,12 +351,38 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-ident" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "void" version = "1.0.2" diff --git a/firmware/Cargo.toml b/firmware/Cargo.toml index 039e5b2..b86a921 100644 --- a/firmware/Cargo.toml +++ b/firmware/Cargo.toml @@ -9,11 +9,12 @@ edition = "2021" riscv-rt = "0.11.0" panic-halt = "0.2.0" embedded-hal = "0.2.7" +defmt = {version = "0.3.4", features = ["encoding-raw"] } [dependencies.smoltcp] version = "0.9.1" default-features = false -features = ["medium-ethernet", "socket-icmp", "proto-ipv4"] +features = ["medium-ethernet", "proto-ipv4", "socket-icmp", "defmt"] [profile.release] debug = true diff --git a/firmware/build_and_strip.sh b/firmware/build_and_strip.sh index 4e17ac0..1c6fb70 100755 --- a/firmware/build_and_strip.sh +++ b/firmware/build_and_strip.sh @@ -1,4 +1,4 @@ #!/usr/bin/sh -cargo build --release +DEFMT_LOG=trace cargo build --release riscv64-unknown-elf-objcopy -S -O binary target/riscv32i-unknown-none-elf/release/fw fw.bin diff --git a/firmware/src/eth.rs b/firmware/src/eth.rs index a4ceca1..bddadac 100644 --- a/firmware/src/eth.rs +++ b/firmware/src/eth.rs @@ -38,9 +38,13 @@ const ETHMAC_SRAM_READER_EV_ENABLE: u32 = 0x834; const NUM_RX_SLOTS: u32 = 2; const NUM_TX_SLOTS: u32 = 2; const MTU: usize = 1530; +const SLOT_LEN: u32 = 2048; use crate::{busy_wait, read_reg, write_reg}; +use crate::uart::AmlibUart; +use core::fmt::Write; + pub struct LiteEthDevice { base_addr: u32, } @@ -67,9 +71,7 @@ impl LiteEthDevice { write_reg(base_addr + CTRL_RESET, 0u32); busy_wait(200); - // Set up RX slot 0 - write_reg(base_addr + ETHMAC_SRAM_WRITER_SLOT, 0); - // Clear to mark the slot as available + // Clear RX event to mark the slot as available write_reg(base_addr + ETHMAC_SRAM_WRITER_EV_PENDING, 1u32); // Clear TX event (unsure if necessary) @@ -80,7 +82,7 @@ impl LiteEthDevice { write_reg(base_addr + ETHMAC_SRAM_WRITER_EV_ENABLE, 0u32); // Return a new device - Some(Self { base_addr }) + Some(Self { base_addr}) } /// Checks that wishbone memory access is correct for the given base address @@ -104,8 +106,8 @@ impl smoltcp::phy::Device for LiteEthDevice { // Check if available, if so , return a RxToken + a TxToken to slot 1 unsafe { + // No data is available if read_reg::(self.base_addr + ETHMAC_SRAM_WRITER_EV_STATUS) == 0 { - // No data is available in writer slot 0 return None; } @@ -117,6 +119,8 @@ impl smoltcp::phy::Device for LiteEthDevice { // We have data, and TX slot 1 is ready for something to be potentially transmitted, // so we can return valid tokens + //writeln!(self.uart, "RX tkn").unwrap(); + defmt::trace!("RX Token given"); Some(( LiteEthRxToken { base_addr: self.base_addr, @@ -138,6 +142,7 @@ impl smoltcp::phy::Device for LiteEthDevice { } } + //writeln!(self.uart, "TX tkn").unwrap(); Some(LiteEthTxToken { base_addr: self.base_addr, slot: 0, @@ -151,6 +156,8 @@ impl smoltcp::phy::Device for LiteEthDevice { caps.max_transmission_unit = MTU; caps.max_burst_size = Some(MTU); + caps.checksum.udp = Checksum::None; + caps } } @@ -160,8 +167,9 @@ impl smoltcp::phy::TxToken for LiteEthTxToken { where F: FnOnce(&mut [u8]) -> R, { - let tx_slot_base: u32 = self.base_addr + NUM_RX_SLOTS * 2048; - let tx_slot_addr = tx_slot_base + (self.slot as u32) * 2048; + // TODO 0x800 is ETHMAC offset, need to encode it somehow properly + let tx_slot_base: u32 = self.base_addr + 0x800 + NUM_RX_SLOTS * SLOT_LEN; + let tx_slot_addr = tx_slot_base + (self.slot as u32) * SLOT_LEN; let tx_slot: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(tx_slot_addr as *mut u8, MTU) }; @@ -187,17 +195,30 @@ impl smoltcp::phy::RxToken for LiteEthRxToken { where F: FnOnce(&mut [u8]) -> R, { + // Read the slot number + let slot = unsafe { + read_reg::(self.base_addr + ETHMAC_SRAM_WRITER_SLOT) + }; + // Read the available length let len = unsafe { - // Select slot 0 - write_reg(self.base_addr + ETHMAC_SRAM_WRITER_SLOT, 0u32); - // Read the available length - read_reg::(self.base_addr + ETHMAC_SRAM_READER_LENGTH) + read_reg::(self.base_addr + ETHMAC_SRAM_WRITER_LENGTH) }; - let rx_slot_addr: u32 = self.base_addr + 2048; + // TODO 0x800 is ETHMAC offset, need to encode it somehow properly + let rx_slot_base: u32 = self.base_addr + 0x800 + SLOT_LEN; + let rx_slot_addr: u32 = rx_slot_base + slot * SLOT_LEN; let rx_slot: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(rx_slot_addr as *mut u8, len as usize) }; + defmt::trace!("RX packet data. slot: {}, len: {}, addr: 0x{:08x}", slot, len, rx_slot_addr); + for i in 0..16 { + let base = self.base_addr + i * 0x400; + defmt::trace!("Data at offset: 0x{:08x}", base); + for j in 0..32 { + defmt::trace!("byte {}: 0x{:x}", j, unsafe {read_reg::(base + j)}); + } + } + // Read data from buffer let res = f(rx_slot); diff --git a/firmware/src/main.rs b/firmware/src/main.rs index ece2532..3fd521a 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -1,6 +1,9 @@ #![no_std] #![no_main] +// TODO remove +#![allow(unused)] + extern crate panic_halt; use core::fmt::Write; @@ -23,8 +26,9 @@ mod eth; mod i2c; mod mcp4726; mod uart; +mod logging; -const mac: [u8; 6] = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]; +const MAC: [u8; 6] = [0xA0, 0xBB, 0xCC, 0xDD, 0xEE, 0xF0]; // use `main` as the entry point of this application // `main` is not allowed to return @@ -46,7 +50,7 @@ fn main() -> ! { use smoltcp::wire::{EthernetAddress, HardwareAddress}; let mut config = smoltcp::iface::Config::default(); - config.hardware_addr = Some(HardwareAddress::Ethernet(EthernetAddress::from_bytes(&mac))); + config.hardware_addr = Some(HardwareAddress::Ethernet(EthernetAddress::from_bytes(&MAC))); let mut iface = smoltcp::iface::Interface::new(config, &mut device); // Set address @@ -70,7 +74,7 @@ fn main() -> ! { let mut last_blink: u32 = 0; let mut toggle = false; - writeln!(uart, "boot").unwrap(); + defmt::info!("Done setup"); loop { let now = millis(); @@ -80,9 +84,8 @@ fn main() -> ! { write_led(if toggle { 1 } else { 0 }); } - // TODO timestamp if iface.poll(Instant::from_millis(now), &mut device, &mut socket_set) { - writeln!(uart, "iface did something").unwrap(); + //writeln!(uart, "iface did something"); } } } diff --git a/firmware/src/uart.rs b/firmware/src/uart.rs index 4c9542a..4abb7b1 100644 --- a/firmware/src/uart.rs +++ b/firmware/src/uart.rs @@ -20,6 +20,8 @@ pub enum Error { RxEmpty, } +// Hacky derive, shouldn't exist but it's fine :tm: +#[derive(Copy, Clone)] pub struct AmlibUart { base_addr: u32, }