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> {
|
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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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
|
/// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/spi.rs
12
src/spi.rs
|
@ -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> {
|
||||||
|
|
22
src/tx.rs
22
src/tx.rs
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue