new-sonar/firmware/src/eth.rs
David Lenfesty 26389576d5 fw: first attempt at writing a packet
Unsure if this is working, not sure if I have the tools to even know if
it does.

I could spend the time to actually write the packet by hand, or I could
probably spend ~2x the time and get smoltcp up.

Either way, the HW is validated, I am bringing up a link, I can talk to
LiteEth, so past here is driver stuff
2023-03-05 12:58:18 -07:00

85 lines
2.5 KiB
Rust

//! Quick and hacky ethernet thing to test
const LITEETH_BASE: u32 = 0x0200_0000;
const ETHMAC_SRAM_WRITER_EV_PENDING: u32 = LITEETH_BASE + 0x810;
const ETHMAC_SRAM_WRITER_EV_ENABLE: u32 = LITEETH_BASE + 0x814;
const ETHMAC_SRAM_READER_EV_PENDING: u32 = LITEETH_BASE + 0x830;
const ETHMAC_SRAM_READER_EV_ENABLE: u32 = LITEETH_BASE + 0x834;
// OMFG, READER is TX, WRITER is RX
const ETHMAC_SRAM_READER_SLOT: u32 = LITEETH_BASE + 0x824;
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);
}
}
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);
// If this isn't true, we screwed.
return value == 0x12345678;
}
pub 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);
// Disable all events
write_u32_reg(ETHMAC_SRAM_WRITER_EV_ENABLE, 0);
write_u32_reg(ETHMAC_SRAM_READER_EV_ENABLE, 0);
}
// a8:a1:59:32:a7:a5
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() {
// Preamble/start delimiter/crc are all handled for us by the MAC
let frame: [u8; 18] = [
// TODO endianness of MAC addresses?
0xA8, 0xA1, 0x59, 0x32, 0xA7, 0xA5, // Destination MAC (ares)
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, // Source MAC (fake)
0x08, 0x00, // Ethertype frame
0xDE, 0xAD, 0xBE, 0xEF, // Data!
];
// buffer_depth = 2048
// it goes, base, RX slot 0, RX slot ..., Tx slot 0, tx slot ...,
const TX_SLOT_LOC: u32 = LITEETH_BASE + 1 * 2048;
let tx_slot: &mut [u8] = unsafe {
core::slice::from_raw_parts_mut(TX_SLOT_LOC as *mut u8, 2048)
};
// Copy our frame into the slot buffer
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);
// Wait to be ready
while read_u32_reg(ETHMAC_SRAM_READER_READY) == 0 {}
// Write!
write_u32_reg(ETHMAC_SRAM_READER_START, 1);
}