Browse Source

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
master
Harry Ho 2 months ago
parent
commit
40a53cc0d6
  1. 10
      src/lib.rs
  2. 14
      src/rx.rs
  3. 12
      src/spi.rs
  4. 22
      src/tx.rs

10
src/lib.rs

@ -96,7 +96,7 @@ impl <SPI: Transfer<u8>,
pub fn init_rxbuf(&mut self) -> Result<(), Error> {
// 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
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
@ -180,8 +180,11 @@ impl <SPI: Transfer<u8>,
self.spi_port.read_rxdat(&mut frame_buf, rx_packet.get_frame_length())?;
rx_packet.copy_frame_from(&frame_buf[1..]);
// 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)?;
// - Otherwise, next_addr will wrap, so set tail pointer to the last word address of RX buffer
} else {
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
// (See: Register 9-2, ENC424J600 Data Sheet)
// 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) %
tx::GPBUFEN_DEFAULT);
self.rx_buf.get_start_addr() - self.tx_buf.get_start_addr());
Ok(())
}
}

14
src/rx.rs

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

12
src/spi.rs

@ -18,8 +18,8 @@ pub mod opcodes {
/// SPI Opcodes
pub const RCRU: u8 = 0b0010_0000;
pub const WCRU: u8 = 0b0010_0010;
pub const RERXDATA: u8 = 0b0010_1100; // 8-bit opcode followed by data
pub const WEGPDATA: u8 = 0b0010_1010; // 8-bit opcode followed by data
pub const RRXDATA: u8 = 0b0010_1100; // 8-bit opcode followed by data
pub const WGPDATA: u8 = 0b0010_1010; // 8-bit opcode followed by data
}
pub mod addrs {
@ -94,16 +94,14 @@ impl <SPI: Transfer<u8>,
// 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)
-> Result<(), Error> {
let r_valid = self.r_n(buf, opcodes::RERXDATA, data_length)?;
Ok(r_valid)
self.r_n(buf, opcodes::RRXDATA, data_length)
}
// 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?
pub fn write_txdat<'a>(&mut self, buf: &'a mut [u8], data_length: usize)
-> Result<(), Error> {
let w_valid = self.w_n(buf, opcodes::WEGPDATA, data_length)?;
Ok(w_valid)
self.w_n(buf, opcodes::WGPDATA, data_length)
}
pub fn write_reg_8b(&mut self, addr: u8, data: u8) -> Result<(), Error> {

22
src/tx.rs

@ -1,13 +1,9 @@
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
/// TODO: Should be a singleton
pub struct TxBuffer {
wrap_addr: u16,
start_addr: u16,
// The following two fields are controlled by firmware
next_addr: u16,
tail_addr: u16
@ -16,23 +12,23 @@ pub struct TxBuffer {
impl TxBuffer {
pub fn new() -> Self {
TxBuffer {
wrap_addr: GPBUFST_DEFAULT,
next_addr: GPBUFST_DEFAULT + 1,
tail_addr: GPBUFST_DEFAULT
start_addr: 0x0000,
next_addr: 0x0001,
tail_addr: 0x0000
}
}
pub fn set_wrap_addr(&mut self, addr: u16) {
self.wrap_addr = addr;
pub fn set_start_addr(&mut self, addr: u16) {
self.start_addr = addr;
}
pub fn get_wrap_addr(& self) -> u16{
self.wrap_addr
pub fn get_start_addr(& self) -> u16{
self.start_addr
}
pub fn set_next_addr(&mut self, addr: u16) {
self.next_addr = addr;
}
pub fn get_next_addr(& self) -> u16{
pub fn get_next_addr(& self) -> u16 {
self.next_addr
}

Loading…
Cancel
Save