fw: more progress for ethernet, unable to read data

This commit is contained in:
David Lenfesty 2023-04-15 22:43:52 -06:00
parent 3b2af908c7
commit 9b49f1184e
7 changed files with 134 additions and 19 deletions

View File

@ -2,6 +2,9 @@
rustflags = [ rustflags = [
"-C", "link-arg=-Tmemory.x", "-C", "link-arg=-Tmemory.x",
"-C", "link-arg=-Tlink.x", "-C", "link-arg=-Tlink.x",
# defmt
"-C", "link-arg=-Tdefmt.x",
] ]
[build] [build]

85
firmware/Cargo.lock generated
View File

@ -56,6 +56,38 @@ version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" 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]] [[package]]
name = "embedded-hal" name = "embedded-hal"
version = "0.2.7" version = "0.2.7"
@ -70,6 +102,7 @@ dependencies = [
name = "fw" name = "fw"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"defmt",
"embedded-hal", "embedded-hal",
"panic-halt", "panic-halt",
"riscv-rt", "riscv-rt",
@ -92,6 +125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
dependencies = [ dependencies = [
"atomic-polyfill", "atomic-polyfill",
"defmt",
"hash32", "hash32",
"rustc_version", "rustc_version",
"spin", "spin",
@ -147,6 +181,30 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" 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]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.50" version = "1.0.50"
@ -262,6 +320,7 @@ dependencies = [
"bitflags", "bitflags",
"byteorder", "byteorder",
"cfg-if", "cfg-if",
"defmt",
"heapless", "heapless",
"managed", "managed",
] ]
@ -292,12 +351,38 @@ dependencies = [
"unicode-ident", "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]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.6" version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]] [[package]]
name = "void" name = "void"
version = "1.0.2" version = "1.0.2"

View File

@ -9,11 +9,12 @@ edition = "2021"
riscv-rt = "0.11.0" riscv-rt = "0.11.0"
panic-halt = "0.2.0" panic-halt = "0.2.0"
embedded-hal = "0.2.7" embedded-hal = "0.2.7"
defmt = {version = "0.3.4", features = ["encoding-raw"] }
[dependencies.smoltcp] [dependencies.smoltcp]
version = "0.9.1" version = "0.9.1"
default-features = false default-features = false
features = ["medium-ethernet", "socket-icmp", "proto-ipv4"] features = ["medium-ethernet", "proto-ipv4", "socket-icmp", "defmt"]
[profile.release] [profile.release]
debug = true debug = true

View File

@ -1,4 +1,4 @@
#!/usr/bin/sh #!/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 riscv64-unknown-elf-objcopy -S -O binary target/riscv32i-unknown-none-elf/release/fw fw.bin

View File

@ -38,9 +38,13 @@ const ETHMAC_SRAM_READER_EV_ENABLE: u32 = 0x834;
const NUM_RX_SLOTS: u32 = 2; const NUM_RX_SLOTS: u32 = 2;
const NUM_TX_SLOTS: u32 = 2; const NUM_TX_SLOTS: u32 = 2;
const MTU: usize = 1530; const MTU: usize = 1530;
const SLOT_LEN: u32 = 2048;
use crate::{busy_wait, read_reg, write_reg}; use crate::{busy_wait, read_reg, write_reg};
use crate::uart::AmlibUart;
use core::fmt::Write;
pub struct LiteEthDevice { pub struct LiteEthDevice {
base_addr: u32, base_addr: u32,
} }
@ -67,9 +71,7 @@ impl LiteEthDevice {
write_reg(base_addr + CTRL_RESET, 0u32); write_reg(base_addr + CTRL_RESET, 0u32);
busy_wait(200); busy_wait(200);
// Set up RX slot 0 // Clear RX event to mark the slot as available
write_reg(base_addr + ETHMAC_SRAM_WRITER_SLOT, 0);
// Clear to mark the slot as available
write_reg(base_addr + ETHMAC_SRAM_WRITER_EV_PENDING, 1u32); write_reg(base_addr + ETHMAC_SRAM_WRITER_EV_PENDING, 1u32);
// Clear TX event (unsure if necessary) // Clear TX event (unsure if necessary)
@ -104,8 +106,8 @@ impl smoltcp::phy::Device for LiteEthDevice {
// Check if available, if so , return a RxToken + a TxToken to slot 1 // Check if available, if so , return a RxToken + a TxToken to slot 1
unsafe { unsafe {
// No data is available
if read_reg::<u32>(self.base_addr + ETHMAC_SRAM_WRITER_EV_STATUS) == 0 { if read_reg::<u32>(self.base_addr + ETHMAC_SRAM_WRITER_EV_STATUS) == 0 {
// No data is available in writer slot 0
return None; 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, // We have data, and TX slot 1 is ready for something to be potentially transmitted,
// so we can return valid tokens // so we can return valid tokens
//writeln!(self.uart, "RX tkn").unwrap();
defmt::trace!("RX Token given");
Some(( Some((
LiteEthRxToken { LiteEthRxToken {
base_addr: self.base_addr, base_addr: self.base_addr,
@ -138,6 +142,7 @@ impl smoltcp::phy::Device for LiteEthDevice {
} }
} }
//writeln!(self.uart, "TX tkn").unwrap();
Some(LiteEthTxToken { Some(LiteEthTxToken {
base_addr: self.base_addr, base_addr: self.base_addr,
slot: 0, slot: 0,
@ -151,6 +156,8 @@ impl smoltcp::phy::Device for LiteEthDevice {
caps.max_transmission_unit = MTU; caps.max_transmission_unit = MTU;
caps.max_burst_size = Some(MTU); caps.max_burst_size = Some(MTU);
caps.checksum.udp = Checksum::None;
caps caps
} }
} }
@ -160,8 +167,9 @@ impl smoltcp::phy::TxToken for LiteEthTxToken {
where where
F: FnOnce(&mut [u8]) -> R, F: FnOnce(&mut [u8]) -> R,
{ {
let tx_slot_base: u32 = self.base_addr + NUM_RX_SLOTS * 2048; // TODO 0x800 is ETHMAC offset, need to encode it somehow properly
let tx_slot_addr = tx_slot_base + (self.slot as u32) * 2048; 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] = let tx_slot: &mut [u8] =
unsafe { core::slice::from_raw_parts_mut(tx_slot_addr as *mut u8, MTU) }; 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 where
F: FnOnce(&mut [u8]) -> R, F: FnOnce(&mut [u8]) -> R,
{ {
let len = unsafe { // Read the slot number
// Select slot 0 let slot = unsafe {
write_reg(self.base_addr + ETHMAC_SRAM_WRITER_SLOT, 0u32); read_reg::<u32>(self.base_addr + ETHMAC_SRAM_WRITER_SLOT)
};
// Read the available length // Read the available length
read_reg::<u32>(self.base_addr + ETHMAC_SRAM_READER_LENGTH) let len = unsafe {
read_reg::<u32>(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] = let rx_slot: &mut [u8] =
unsafe { core::slice::from_raw_parts_mut(rx_slot_addr as *mut u8, len as usize) }; 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::<u8>(base + j)});
}
}
// Read data from buffer // Read data from buffer
let res = f(rx_slot); let res = f(rx_slot);

View File

@ -1,6 +1,9 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
// TODO remove
#![allow(unused)]
extern crate panic_halt; extern crate panic_halt;
use core::fmt::Write; use core::fmt::Write;
@ -23,8 +26,9 @@ mod eth;
mod i2c; mod i2c;
mod mcp4726; mod mcp4726;
mod uart; 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 // use `main` as the entry point of this application
// `main` is not allowed to return // `main` is not allowed to return
@ -46,7 +50,7 @@ fn main() -> ! {
use smoltcp::wire::{EthernetAddress, HardwareAddress}; use smoltcp::wire::{EthernetAddress, HardwareAddress};
let mut config = smoltcp::iface::Config::default(); 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); let mut iface = smoltcp::iface::Interface::new(config, &mut device);
// Set address // Set address
@ -70,7 +74,7 @@ fn main() -> ! {
let mut last_blink: u32 = 0; let mut last_blink: u32 = 0;
let mut toggle = false; let mut toggle = false;
writeln!(uart, "boot").unwrap(); defmt::info!("Done setup");
loop { loop {
let now = millis(); let now = millis();
@ -80,9 +84,8 @@ fn main() -> ! {
write_led(if toggle { 1 } else { 0 }); write_led(if toggle { 1 } else { 0 });
} }
// TODO timestamp
if iface.poll(Instant::from_millis(now), &mut device, &mut socket_set) { if iface.poll(Instant::from_millis(now), &mut device, &mut socket_set) {
writeln!(uart, "iface did something").unwrap(); //writeln!(uart, "iface did something");
} }
} }
} }

View File

@ -20,6 +20,8 @@ pub enum Error {
RxEmpty, RxEmpty,
} }
// Hacky derive, shouldn't exist but it's fine :tm:
#[derive(Copy, Clone)]
pub struct AmlibUart { pub struct AmlibUart {
base_addr: u32, base_addr: u32,
} }