Skip to content

Commit 3d577bf

Browse files
committed
Convert to ring mode (instead of chain mode)
1 parent 2ee46e1 commit 3d577bf

File tree

18 files changed

+992
-1078
lines changed

18 files changed

+992
-1078
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ ieee802_3_miim = "0.8"
2929
cortex-m = "0.7"
3030
log = { version = "0.4", optional = true }
3131
defmt = { version = "0.3", optional = true }
32+
siphasher = "*"
3233

3334
[dependencies.smoltcp]
3435
version = "0.8.2"

examples/arp.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ use cortex_m_rt::{entry, exception};
1616

1717
use cortex_m::interrupt::Mutex;
1818
use stm32_eth::{
19+
dma::{RxDescriptor, TxDescriptor},
1920
mac::{phy::BarePhy, Phy},
2021
stm32::{interrupt, CorePeripherals, Peripherals, SYST},
21-
Parts,
22+
Parts, MTU,
2223
};
2324

2425
pub mod common;
2526

26-
use stm32_eth::dma::{RxRingEntry, TxError, TxRingEntry};
27+
use stm32_eth::dma::{RxDescriptorRing, TxDescriptorRing, TxError};
2728

2829
const PHY_ADDR: u8 = 0;
2930

@@ -43,22 +44,20 @@ fn main() -> ! {
4344

4445
let (eth_pins, mdio, mdc, _) = common::setup_pins(gpio);
4546

46-
let mut rx_ring: [RxRingEntry; 2] = Default::default();
47-
let mut tx_ring: [TxRingEntry; 2] = Default::default();
47+
let mut rx_descriptors: [RxDescriptor; 2] = Default::default();
48+
let mut rx_buffers: [[u8; MTU]; 2] = [[0u8; MTU]; 2];
49+
let rx_ring = RxDescriptorRing::new(&mut rx_descriptors, &mut rx_buffers);
50+
51+
let mut tx_descriptors: [TxDescriptor; 2] = Default::default();
52+
let mut tx_buffers: [[u8; MTU]; 2] = [[0u8; MTU]; 2];
53+
let tx_ring = TxDescriptorRing::new(&mut tx_descriptors, &mut tx_buffers);
4854

4955
let Parts {
5056
mut dma,
5157
mac,
5258
#[cfg(feature = "ptp")]
5359
ptp: _,
54-
} = stm32_eth::new(
55-
ethernet,
56-
&mut rx_ring[..],
57-
&mut tx_ring[..],
58-
clocks,
59-
eth_pins,
60-
)
61-
.unwrap();
60+
} = stm32_eth::new(ethernet, rx_ring, tx_ring, clocks, eth_pins).unwrap();
6261
dma.enable_interrupt();
6362

6463
let mut last_link_up = false;
@@ -109,14 +108,32 @@ fn main() -> ! {
109108
buf[38..42].copy_from_slice(&TARGET_IP);
110109
});
111110

111+
loop {
112+
use core::hash::{Hash, Hasher};
113+
114+
if let Ok(rx_packet) = dma.recv_next(None) {
115+
let mut hasher = siphasher::sip::SipHasher::new();
116+
rx_packet.hash(&mut hasher);
117+
118+
defmt::info!(
119+
"Received {} bytes. Hash: {:016X}",
120+
rx_packet.len(),
121+
hasher.finish()
122+
);
123+
break;
124+
}
125+
}
126+
112127
match r {
113128
Ok(()) => {
114129
defmt::info!("ARP sent");
115130
}
116-
Err(TxError::WouldBlock) => defmt::info!("ARP failed"),
131+
Err(TxError::WouldBlock) => {
132+
defmt::panic!("ARP failed. {}", dma.tx_state())
133+
}
117134
}
118135
} else {
119-
defmt::info!("Down");
136+
// defmt::info!("Down");
120137
}
121138

122139
cortex_m::interrupt::free(|cs| {

examples/rtic-echo.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ mod app {
2929
use systick_monotonic::Systick;
3030

3131
use stm32_eth::{
32-
dma::{EthernetDMA, RxRingEntry, TxRingEntry},
32+
dma::{EthernetDMA, RxDescriptor, RxDescriptorRing, TxDescriptor, TxDescriptorRing},
3333
mac::Speed,
3434
Parts,
3535
};
@@ -61,8 +61,10 @@ mod app {
6161
}
6262

6363
#[init(local = [
64-
rx_ring: [RxRingEntry; 2] = [RxRingEntry::new(),RxRingEntry::new()],
65-
tx_ring: [TxRingEntry; 2] = [TxRingEntry::new(),TxRingEntry::new()],
64+
rx_desc: [RxDescriptor; 2] = [RxDescriptor::new(); 2],
65+
tx_desc: [TxDescriptor; 2] = [TxDescriptor::new(); 2],
66+
rx_buffers: [[u8; 1522]; 2] = [[0u8; stm32_eth::MTU]; 2],
67+
tx_buffers: [[u8; 1522]; 2] = [[0u8; stm32_eth::MTU]; 2],
6668
storage: NetworkStorage = NetworkStorage::new(),
6769
dma: core::mem::MaybeUninit<EthernetDMA<'static, 'static>> = core::mem::MaybeUninit::uninit(),
6870
])]
@@ -71,8 +73,8 @@ mod app {
7173
let core = cx.core;
7274
let p = cx.device;
7375

74-
let rx_ring = cx.local.rx_ring;
75-
let tx_ring = cx.local.tx_ring;
76+
let rx_ring = RxDescriptorRing::new(cx.local.rx_desc, cx.local.rx_buffers);
77+
let tx_ring = TxDescriptorRing::new(cx.local.tx_desc, cx.local.tx_buffers);
7678

7779
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
7880
let mono = Systick::new(core.SYST, clocks.hclk().raw());

examples/rtic-timestamp.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ mod app {
4343
use systick_monotonic::Systick;
4444

4545
use stm32_eth::{
46-
dma::{EthernetDMA, PacketId, RxRingEntry, TxRingEntry},
46+
dma::{
47+
EthernetDMA, PacketId, RxDescriptor, RxDescriptorRing, TxDescriptor, TxDescriptorRing,
48+
},
4749
mac::Speed,
4850
ptp::{EthernetPTP, Timestamp},
4951
Parts,
@@ -64,16 +66,18 @@ mod app {
6466
type Monotonic = Systick<1000>;
6567

6668
#[init(local = [
67-
rx_ring: [RxRingEntry; 2] = [RxRingEntry::new(),RxRingEntry::new()],
68-
tx_ring: [TxRingEntry; 2] = [TxRingEntry::new(),TxRingEntry::new()],
69+
rx_desc: [RxDescriptor; 2] = [RxDescriptor::new(); 2],
70+
tx_desc: [TxDescriptor; 2] = [TxDescriptor::new(); 2],
71+
rx_buffers: [[u8; 1522]; 2] = [[0u8; stm32_eth::MTU]; 2],
72+
tx_buffers: [[u8; 1522]; 2] = [[0u8; stm32_eth::MTU]; 2],
6973
])]
7074
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
7175
defmt::info!("Pre-init");
7276
let core = cx.core;
7377
let p = cx.device;
7478

75-
let rx_ring = cx.local.rx_ring;
76-
let tx_ring = cx.local.tx_ring;
79+
let rx_ring = RxDescriptorRing::new(cx.local.rx_desc, cx.local.rx_buffers);
80+
let tx_ring = TxDescriptorRing::new(cx.local.tx_desc, cx.local.tx_buffers);
7781

7882
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
7983
let mono = Systick::new(core.SYST, clocks.hclk().raw());

src/dma/desc.rs

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/dma/mod.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,40 @@ mod smoltcp_phy;
1111
#[cfg(feature = "smoltcp-phy")]
1212
pub use smoltcp_phy::*;
1313

14-
pub(crate) mod desc;
15-
16-
pub(crate) mod ring;
14+
pub(crate) mod raw_descriptor;
1715

1816
mod rx;
19-
use rx::RxRing;
20-
pub use rx::{RxError, RxPacket, RxRingEntry};
17+
pub use rx::{RxDescriptor, RxDescriptorRing, RxError, RxPacket};
2118

2219
mod tx;
23-
use tx::TxRing;
24-
pub use tx::{TxError, TxRingEntry};
20+
pub use tx::{TxDescriptor, TxDescriptorRing, TxError};
2521

2622
#[cfg(feature = "ptp")]
2723
use crate::ptp::Timestamp;
2824

2925
mod packet_id;
3026
pub use packet_id::PacketId;
3127

28+
use rx::RxRing;
29+
use tx::{RunningState, TxRing};
30+
31+
use self::raw_descriptor::DESC_SIZE;
32+
33+
const _RXDESC_SIZE: usize = core::mem::size_of::<RxDescriptor>();
34+
const _TXDESC_SIZE: usize = core::mem::size_of::<TxDescriptor>();
35+
36+
/// Assert that our descriptors have the same size.
37+
///
38+
/// This is necessary as we only have a single Descriptor Skip Length
39+
/// value which applies to both TX and RX descriptors.
40+
const _ASSERT_DESCRIPTOR_SIZES: () = assert!(_RXDESC_SIZE == _TXDESC_SIZE);
41+
42+
const DESC_WORD_SKIP: u8 = (core::mem::size_of::<RxDescriptor>() / 4 - DESC_SIZE) as u8;
43+
44+
/// The maximum transmission unit of this Ethernet peripheral.
45+
///
3246
/// From the datasheet: *VLAN Frame maxsize = 1522*
33-
pub(crate) const MTU: usize = 1522;
47+
pub const MTU: usize = 1522;
3448

3549
/// An error that can occur when retrieving a timestamp from an
3650
/// RX or TX descriptor handled by the DMA.
@@ -60,8 +74,8 @@ impl<'rx, 'tx> EthernetDMA<'rx, 'tx> {
6074
/// usually not accessible.
6175
pub(crate) fn new(
6276
eth_dma: ETHERNET_DMA,
63-
rx_buffer: &'rx mut [RxRingEntry],
64-
tx_buffer: &'tx mut [TxRingEntry],
77+
rx_buffer: RxDescriptorRing<'rx>,
78+
tx_buffer: TxDescriptorRing<'tx>,
6579
) -> Self {
6680
// reset DMA bus mode register
6781
eth_dma.dmabmr.modify(|_, w| w.sr().set_bit());
@@ -120,6 +134,9 @@ impl<'rx, 'tx> EthernetDMA<'rx, 'tx> {
120134
}
121135
});
122136

137+
// Configure word skip length.
138+
eth_dma.dmabmr.modify(|_, w| w.dsl().bits(DESC_WORD_SKIP));
139+
123140
let mut dma = EthernetDMA {
124141
eth_dma,
125142
rx_ring: RxRing::new(rx_buffer),
@@ -179,6 +196,11 @@ impl<'rx, 'tx> EthernetDMA<'rx, 'tx> {
179196
self.rx_ring.running_state(&self.eth_dma).is_running()
180197
}
181198

199+
///
200+
pub fn tx_state(&self) -> RunningState {
201+
self.tx_ring.running_state(&self.eth_dma)
202+
}
203+
182204
pub(crate) fn recv_next_impl<'rx_borrow>(
183205
eth_dma: &ETHERNET_DMA,
184206
rx_ring: &'rx_borrow mut RxRing,

src/dma/packet_id.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The main use is obtaining timestamps for frames using [`EthernetDMA::get_timesta
1010
"
1111
)]
1212
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
13-
#[derive(Debug, PartialEq, Clone)]
13+
#[derive(Debug, PartialEq, Clone, Copy)]
1414
pub struct PacketId(pub u32);
1515

1616
impl PacketId {

0 commit comments

Comments
 (0)