net-enc28j60: reset rx logic when buffer corrupts.
This commit is contained in:
parent
3ebb93e47d
commit
73942f50cb
@ -106,19 +106,7 @@ where
|
|||||||
// disable CLKOUT output
|
// disable CLKOUT output
|
||||||
self.write_control_register(bank3::Register::ECOCON, 0);
|
self.write_control_register(bank3::Register::ECOCON, 0);
|
||||||
|
|
||||||
// RX start
|
self.init_rx();
|
||||||
// "It is recommended that the ERXST Pointer be programmed with an even address"
|
|
||||||
self.write_control_register(bank0::Register::ERXSTL, RXST.low());
|
|
||||||
self.write_control_register(bank0::Register::ERXSTH, RXST.high());
|
|
||||||
|
|
||||||
// RX read pointer
|
|
||||||
// NOTE Errata #14 so we are using an *odd* address here instead of ERXST
|
|
||||||
self.write_control_register(bank0::Register::ERXRDPTL, RXND.low());
|
|
||||||
self.write_control_register(bank0::Register::ERXRDPTH, RXND.high());
|
|
||||||
|
|
||||||
// RX end
|
|
||||||
self.write_control_register(bank0::Register::ERXNDL, RXND.low());
|
|
||||||
self.write_control_register(bank0::Register::ERXNDH, RXND.high());
|
|
||||||
|
|
||||||
// TX start
|
// TX start
|
||||||
// "It is recommended that an even address be used for ETXST"
|
// "It is recommended that an even address be used for ETXST"
|
||||||
@ -172,12 +160,37 @@ where
|
|||||||
// Set the per packet control byte; we'll always use the value 0
|
// Set the per packet control byte; we'll always use the value 0
|
||||||
self.write_buffer_memory(Some(TXST), &mut [0]);
|
self.write_buffer_memory(Some(TXST), &mut [0]);
|
||||||
|
|
||||||
|
// Enable reception
|
||||||
|
self.bit_field_set(common::Register::ECON1, common::ECON1::mask().rxen());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_rx(&mut self) {
|
||||||
|
// RX start
|
||||||
|
// "It is recommended that the ERXST Pointer be programmed with an even address"
|
||||||
|
self.write_control_register(bank0::Register::ERXSTL, RXST.low());
|
||||||
|
self.write_control_register(bank0::Register::ERXSTH, RXST.high());
|
||||||
|
|
||||||
|
// RX read pointer
|
||||||
|
// NOTE Errata #14 so we are using an *odd* address here instead of ERXST
|
||||||
|
self.write_control_register(bank0::Register::ERXRDPTL, RXND.low());
|
||||||
|
self.write_control_register(bank0::Register::ERXRDPTH, RXND.high());
|
||||||
|
|
||||||
|
// RX end
|
||||||
|
self.write_control_register(bank0::Register::ERXNDL, RXND.low());
|
||||||
|
self.write_control_register(bank0::Register::ERXNDH, RXND.high());
|
||||||
|
|
||||||
// decrease the packet count to 0
|
// decrease the packet count to 0
|
||||||
while self.read_control_register(bank1::Register::EPKTCNT) != 0 {
|
while self.read_control_register(bank1::Register::EPKTCNT) != 0 {
|
||||||
self.bit_field_set(common::Register::ECON2, common::ECON2::mask().pktdec());
|
self.bit_field_set(common::Register::ECON2, common::ECON2::mask().pktdec());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable reception
|
self.next_packet = RXST;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset_rx(&mut self) {
|
||||||
|
self.bit_field_set(common::Register::ECON1, common::ECON1::mask().rxrst());
|
||||||
|
self.bit_field_clear(common::Register::ECON1, common::ECON1::mask().rxrst());
|
||||||
|
self.init_rx();
|
||||||
self.bit_field_set(common::Register::ECON1, common::ECON1::mask().rxen());
|
self.bit_field_set(common::Register::ECON1, common::ECON1::mask().rxen());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,18 +211,17 @@ where
|
|||||||
|
|
||||||
// next packet pointer
|
// next packet pointer
|
||||||
let next_packet = u16::from_parts(temp_buf[0], temp_buf[1]);
|
let next_packet = u16::from_parts(temp_buf[0], temp_buf[1]);
|
||||||
if next_packet > RXND {
|
|
||||||
panic!("CorruptRxBuffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
// status vector
|
// status vector
|
||||||
let status = header::RxStatus(u32::from_le_bytes(temp_buf[2..].try_into().unwrap()));
|
let status = header::RxStatus(u32::from_le_bytes(temp_buf[2..].try_into().unwrap()));
|
||||||
let len = status.byte_count() as u16 - CRC_SZ;
|
let len_with_crc = status.byte_count() as u16;
|
||||||
|
|
||||||
if len > RXND {
|
if len_with_crc < CRC_SZ || len_with_crc > 1600 || next_packet > RXND {
|
||||||
panic!("CorruptRxBuffer 2");
|
warn!("RX buffer corrupted, resetting RX logic to recover...");
|
||||||
|
self.reset_rx();
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let len = len_with_crc - CRC_SZ;
|
||||||
self.read_buffer_memory(None, &mut buf[..len as usize]);
|
self.read_buffer_memory(None, &mut buf[..len as usize]);
|
||||||
|
|
||||||
// update ERXRDPT
|
// update ERXRDPT
|
||||||
|
Loading…
Reference in New Issue
Block a user