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:
parent
6d17703e6b
commit
40a53cc0d6
10
src/lib.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
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
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
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…
Reference in New Issue