spi: Fix Rx/Tx buffer logic & simplify

* tx/rx: Rename wrap_addr to start_addr for clarity
* Fix RX logic, when advancing the tail pointer, not retrieving the stored RX buffer start address but the default value instead
* Fix TX logic, when advancing the head pointer for next transmission, not retrieving the stored TX buffer end address but the default value instead
* Rename SPI-related const's to match the datasheet: RERXDATA→RRXDATA, WEGPDATA→WGPDATA
* Remove useless const's for SRAM default addresses for TX buffer
* Simplify code
This commit is contained in:
Harry Ho 2021-04-27 15:02:31 +08:00
parent 6d17703e6b
commit 40a53cc0d6
4 changed files with 28 additions and 30 deletions

View File

@ -96,7 +96,7 @@ impl <SPI: Transfer<u8>,
pub fn init_rxbuf(&mut self) -> Result<(), Error> { pub fn init_rxbuf(&mut self) -> Result<(), Error> {
// Set ERXST pointer // Set ERXST pointer
self.spi_port.write_reg_16b(spi::addrs::ERXST, self.rx_buf.get_wrap_addr())?; self.spi_port.write_reg_16b(spi::addrs::ERXST, self.rx_buf.get_start_addr())?;
// Set ERXTAIL pointer // Set ERXTAIL pointer
self.spi_port.write_reg_16b(spi::addrs::ERXTAIL, self.rx_buf.get_tail_addr())?; self.spi_port.write_reg_16b(spi::addrs::ERXTAIL, self.rx_buf.get_tail_addr())?;
// Set MAMXFL to maximum number of bytes in each accepted packet // Set MAMXFL to maximum number of bytes in each accepted packet
@ -180,8 +180,11 @@ impl <SPI: Transfer<u8>,
self.spi_port.read_rxdat(&mut frame_buf, rx_packet.get_frame_length())?; self.spi_port.read_rxdat(&mut frame_buf, rx_packet.get_frame_length())?;
rx_packet.copy_frame_from(&frame_buf[1..]); rx_packet.copy_frame_from(&frame_buf[1..]);
// Set ERXTAIL pointer to (next_addr - 2) // Set ERXTAIL pointer to (next_addr - 2)
if self.rx_buf.get_next_addr() > rx::ERXST_DEFAULT { // * Assume head, tail, next and wrap addresses are word-aligned (even)
// - If next_addr is at least (start_addr+2), then set tail pointer to the word right before next_addr
if self.rx_buf.get_next_addr() > self.rx_buf.get_start_addr() {
self.spi_port.write_reg_16b(spi::addrs::ERXTAIL, self.rx_buf.get_next_addr() - 2)?; self.spi_port.write_reg_16b(spi::addrs::ERXTAIL, self.rx_buf.get_next_addr() - 2)?;
// - Otherwise, next_addr will wrap, so set tail pointer to the last word address of RX buffer
} else { } else {
self.spi_port.write_reg_16b(spi::addrs::ERXTAIL, rx::RX_MAX_ADDRESS - 1)?; self.spi_port.write_reg_16b(spi::addrs::ERXTAIL, rx::RX_MAX_ADDRESS - 1)?;
} }
@ -216,8 +219,9 @@ impl <SPI: Transfer<u8>,
// TODO: Read ETXSTAT to understand Ethernet transmission status // TODO: Read ETXSTAT to understand Ethernet transmission status
// (See: Register 9-2, ENC424J600 Data Sheet) // (See: Register 9-2, ENC424J600 Data Sheet)
// Update TX buffer start address // Update TX buffer start address
// * Assume TX buffer consumes the entire general-purpose SRAM block
self.tx_buf.set_next_addr((self.tx_buf.get_next_addr() + packet.get_frame_length() as u16) % self.tx_buf.set_next_addr((self.tx_buf.get_next_addr() + packet.get_frame_length() as u16) %
tx::GPBUFEN_DEFAULT); self.rx_buf.get_start_addr() - self.tx_buf.get_start_addr());
Ok(()) Ok(())
} }
} }

View File

@ -11,7 +11,7 @@ pub const RSV_LENGTH: usize = 6;
/// Struct for RX Buffer on the hardware /// Struct for RX Buffer on the hardware
/// TODO: Should be a singleton /// TODO: Should be a singleton
pub struct RxBuffer { pub struct RxBuffer {
wrap_addr: u16, start_addr: u16,
next_addr: u16, next_addr: u16,
tail_addr: u16 tail_addr: u16
} }
@ -19,23 +19,23 @@ pub struct RxBuffer {
impl RxBuffer { impl RxBuffer {
pub fn new() -> Self { pub fn new() -> Self {
RxBuffer { RxBuffer {
wrap_addr: ERXST_DEFAULT, start_addr: ERXST_DEFAULT,
next_addr: ERXST_DEFAULT, next_addr: ERXST_DEFAULT,
tail_addr: ERXTAIL_DEFAULT tail_addr: ERXTAIL_DEFAULT
} }
} }
pub fn set_wrap_addr(&mut self, addr: u16) { pub fn set_start_addr(&mut self, addr: u16) {
self.wrap_addr = addr; self.start_addr = addr;
} }
pub fn get_wrap_addr(& self) -> u16{ pub fn get_start_addr(& self) -> u16{
self.wrap_addr self.start_addr
} }
pub fn set_next_addr(&mut self, addr: u16) { pub fn set_next_addr(&mut self, addr: u16) {
self.next_addr = addr; self.next_addr = addr;
} }
pub fn get_next_addr(& self) -> u16{ pub fn get_next_addr(& self) -> u16 {
self.next_addr self.next_addr
} }

View File

@ -18,8 +18,8 @@ pub mod opcodes {
/// SPI Opcodes /// SPI Opcodes
pub const RCRU: u8 = 0b0010_0000; pub const RCRU: u8 = 0b0010_0000;
pub const WCRU: u8 = 0b0010_0010; pub const WCRU: u8 = 0b0010_0010;
pub const RERXDATA: u8 = 0b0010_1100; // 8-bit opcode followed by data pub const RRXDATA: u8 = 0b0010_1100; // 8-bit opcode followed by data
pub const WEGPDATA: u8 = 0b0010_1010; // 8-bit opcode followed by data pub const WGPDATA: u8 = 0b0010_1010; // 8-bit opcode followed by data
} }
pub mod addrs { pub mod addrs {
@ -94,16 +94,14 @@ impl <SPI: Transfer<u8>,
// Currently requires manual slicing (buf[1..]) for the data read back // Currently requires manual slicing (buf[1..]) for the data read back
pub fn read_rxdat<'a>(&mut self, buf: &'a mut [u8], data_length: usize) pub fn read_rxdat<'a>(&mut self, buf: &'a mut [u8], data_length: usize)
-> Result<(), Error> { -> Result<(), Error> {
let r_valid = self.r_n(buf, opcodes::RERXDATA, data_length)?; self.r_n(buf, opcodes::RRXDATA, data_length)
Ok(r_valid)
} }
// Currenly requires actual data to be stored in buf[1..] instead of buf[0..] // Currently requires actual data to be stored in buf[1..] instead of buf[0..]
// TODO: Maybe better naming? // TODO: Maybe better naming?
pub fn write_txdat<'a>(&mut self, buf: &'a mut [u8], data_length: usize) pub fn write_txdat<'a>(&mut self, buf: &'a mut [u8], data_length: usize)
-> Result<(), Error> { -> Result<(), Error> {
let w_valid = self.w_n(buf, opcodes::WEGPDATA, data_length)?; self.w_n(buf, opcodes::WGPDATA, data_length)
Ok(w_valid)
} }
pub fn write_reg_8b(&mut self, addr: u8, data: u8) -> Result<(), Error> { pub fn write_reg_8b(&mut self, addr: u8, data: u8) -> Result<(), Error> {

View File

@ -1,13 +1,9 @@
use crate::RAW_FRAME_LENGTH_MAX; use crate::RAW_FRAME_LENGTH_MAX;
/// SRAM Addresses
pub const GPBUFST_DEFAULT: u16 = 0x0000; // Start of General-Purpose SRAM Buffer
pub const GPBUFEN_DEFAULT: u16 = 0x5340; // End of General-Purpose SRAM Buffer == ERXST default
/// Struct for TX Buffer on the hardware /// Struct for TX Buffer on the hardware
/// TODO: Should be a singleton /// TODO: Should be a singleton
pub struct TxBuffer { pub struct TxBuffer {
wrap_addr: u16, start_addr: u16,
// The following two fields are controlled by firmware // The following two fields are controlled by firmware
next_addr: u16, next_addr: u16,
tail_addr: u16 tail_addr: u16
@ -16,23 +12,23 @@ pub struct TxBuffer {
impl TxBuffer { impl TxBuffer {
pub fn new() -> Self { pub fn new() -> Self {
TxBuffer { TxBuffer {
wrap_addr: GPBUFST_DEFAULT, start_addr: 0x0000,
next_addr: GPBUFST_DEFAULT + 1, next_addr: 0x0001,
tail_addr: GPBUFST_DEFAULT tail_addr: 0x0000
} }
} }
pub fn set_wrap_addr(&mut self, addr: u16) { pub fn set_start_addr(&mut self, addr: u16) {
self.wrap_addr = addr; self.start_addr = addr;
} }
pub fn get_wrap_addr(& self) -> u16{ pub fn get_start_addr(& self) -> u16{
self.wrap_addr self.start_addr
} }
pub fn set_next_addr(&mut self, addr: u16) { pub fn set_next_addr(&mut self, addr: u16) {
self.next_addr = addr; self.next_addr = addr;
} }
pub fn get_next_addr(& self) -> u16{ pub fn get_next_addr(& self) -> u16 {
self.next_addr self.next_addr
} }