Skip to content

Commit 8236fba

Browse files
committed
examples: set up MPU for all examples
It seems that (part of) the problem in #105 could, in fact, be caching. To prevent the examples from doing the same, we can set up the MPU to make all RAM regions non-cacheable.
1 parent 13e2991 commit 8236fba

11 files changed

Lines changed: 89 additions & 18 deletions

File tree

examples/arp.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,17 @@ fn main() -> ! {
3535
let p = Peripherals::take().unwrap();
3636
let mut cp = CorePeripherals::take().unwrap();
3737

38-
let (clocks, gpio, ethernet) = common::setup_peripherals(p);
38+
let mut rx_ring: [RxRingEntry; 2] = Default::default();
39+
let mut tx_ring: [TxRingEntry; 2] = Default::default();
40+
41+
let (clocks, gpio, ethernet) = common::setup_peripherals(p, cp.MPU, &rx_ring, &tx_ring);
3942

4043
setup_systick(&mut cp.SYST);
4144

4245
defmt::info!("Enabling ethernet...");
4346

4447
let (eth_pins, mdio, mdc, _) = common::setup_pins(gpio);
4548

46-
let mut rx_ring: [RxRingEntry; 2] = Default::default();
47-
let mut tx_ring: [TxRingEntry; 2] = Default::default();
48-
4949
let Parts {
5050
mut dma,
5151
mac,

examples/async-rtic-timestamp.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ mod app {
8181
let rx_ring = cx.local.rx_ring;
8282
let tx_ring = cx.local.tx_ring;
8383

84-
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
84+
let (clocks, gpio, ethernet) =
85+
crate::common::setup_peripherals(p, cx.core.MPU, rx_ring, tx_ring);
8586

8687
defmt::info!("Setting up pins");
8788
let (pins, mdio, mdc, pps) = crate::common::setup_pins(gpio);

examples/common.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use defmt_rtt as _;
1010
use panic_probe as _;
1111

1212
use stm32_eth::{
13+
dma::{RxRingEntry, TxRingEntry},
1314
hal::{gpio::GpioExt, rcc::Clocks},
15+
stm32::MPU,
1416
PartsIn,
1517
};
1618

@@ -25,12 +27,72 @@ use stm32_eth::hal::rcc::RccExt;
2527
#[allow(unused)]
2628
fn main() {}
2729

30+
/// Mark RAM as non-cachable. Also validate that the RX ring
31+
/// and TX ring are within them.
32+
fn mpu_mark_noncachable(mpu: MPU, rx_ring: &[RxRingEntry], tx_ring: &[TxRingEntry]) {
33+
let start = 0x20000000u32;
34+
let len = 32u32 * 1024;
35+
let range = start as usize..(start as usize + len as usize);
36+
37+
let rx_start = rx_ring.as_ptr();
38+
let rx_first_addr = rx_start.addr();
39+
let rx_last_addr = unsafe { rx_start.add(rx_ring.len() + 1) }.addr() - 1;
40+
assert!(
41+
range.contains(&rx_first_addr),
42+
"RX ring starts before non-cacheable region"
43+
);
44+
45+
assert!(
46+
range.contains(&rx_last_addr),
47+
"RX ring ends after non-cacheable region"
48+
);
49+
50+
let tx_start = tx_ring.as_ptr();
51+
let tx_first_addr = tx_start.addr();
52+
let tx_last_addr = unsafe { rx_start.add(tx_ring.len() + 1) }.addr() - 1;
53+
assert!(
54+
range.contains(&tx_first_addr),
55+
"TX ring starts before non-cacheable region"
56+
);
57+
58+
assert!(
59+
range.contains(&tx_last_addr),
60+
"TX ring ends after non-cacheable region"
61+
);
62+
63+
let size_field = len.trailing_zeros() - 1;
64+
65+
unsafe {
66+
mpu.ctrl.write(0);
67+
let region = 0;
68+
mpu.rnr.write(region);
69+
mpu.rbar.write(start | 1 << 4 | region);
70+
71+
mpu.rasr.write(
72+
(1 << 28)
73+
| (0b011 << 24)
74+
| (0b0001 << 19)
75+
| (0 << 17)
76+
| (0 << 16)
77+
| (size_field << 1)
78+
| (1 << 0),
79+
)
80+
}
81+
}
82+
2883
/// Setup the clocks and return clocks and a GPIO struct that
2984
/// can be used to set up all of the pins.
3085
///
3186
/// This configures HCLK to be at least 25 MHz, which is the minimum required
3287
/// for ethernet operation to be valid.
33-
pub fn setup_peripherals(p: stm32_eth::stm32::Peripherals) -> (Clocks, Gpio, PartsIn) {
88+
pub fn setup_peripherals(
89+
p: stm32_eth::stm32::Peripherals,
90+
mpu: MPU,
91+
rx_ring: &[RxRingEntry],
92+
tx_ring: &[TxRingEntry],
93+
) -> (Clocks, Gpio, PartsIn) {
94+
mpu_mark_noncachable(mpu, rx_ring, tx_ring);
95+
3496
let ethernet = PartsIn {
3597
dma: p.ETHERNET_DMA,
3698
mac: p.ETHERNET_MAC,

examples/ip.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,17 @@ fn main() -> ! {
3838
let p = Peripherals::take().unwrap();
3939
let mut cp = CorePeripherals::take().unwrap();
4040

41-
let (clocks, gpio, ethernet) = common::setup_peripherals(p);
41+
let mut rx_ring: [RxRingEntry; 2] = Default::default();
42+
let mut tx_ring: [TxRingEntry; 2] = Default::default();
43+
44+
let (clocks, gpio, ethernet) = common::setup_peripherals(p, cp.MPU, &rx_ring, &tx_ring);
4245

4346
setup_systick(&mut cp.SYST);
4447

4548
defmt::info!("Enabling ethernet...");
4649

4750
let (eth_pins, _mdio, _mdc, _) = common::setup_pins(gpio);
4851

49-
let mut rx_ring: [RxRingEntry; 2] = Default::default();
50-
let mut tx_ring: [TxRingEntry; 2] = Default::default();
5152
let Parts {
5253
mut dma,
5354
mac: _,

examples/pktgen.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,16 @@ fn main() -> ! {
3535
let p = Peripherals::take().unwrap();
3636
let mut cp = CorePeripherals::take().unwrap();
3737

38-
let (clocks, gpio, ethernet) = common::setup_peripherals(p);
38+
let mut rx_ring: [RxRingEntry; 2] = Default::default();
39+
let mut tx_ring: [TxRingEntry; 2] = Default::default();
40+
41+
let (clocks, gpio, ethernet) = common::setup_peripherals(p, cp.MPU, &rx_ring, &tx_ring);
3942

4043
setup_systick(&mut cp.SYST);
4144

4245
defmt::info!("Enabling ethernet...");
4346
let (eth_pins, mdio, mdc, _) = common::setup_pins(gpio);
4447

45-
let mut rx_ring: [RxRingEntry; 2] = Default::default();
46-
let mut tx_ring: [TxRingEntry; 2] = Default::default();
4748
let Parts {
4849
mut dma,
4950
mac,

examples/rtic-echo.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ mod app {
7272
let rx_ring = cx.local.rx_ring;
7373
let tx_ring = cx.local.tx_ring;
7474

75-
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
75+
let (clocks, gpio, ethernet) =
76+
crate::common::setup_peripherals(p, core.MPU, rx_ring, tx_ring);
7677
let mono = Systick::new(core.SYST, clocks.hclk().raw());
7778

7879
let (rx_storage, tx_storage, socket_storage) = (

examples/rtic-timestamp.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ mod app {
7777
let rx_ring = cx.local.rx_ring;
7878
let tx_ring = cx.local.tx_ring;
7979

80-
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
80+
let (clocks, gpio, ethernet) =
81+
crate::common::setup_peripherals(p, core.MPU, rx_ring, tx_ring);
8182
let mono = Systick::new(core.SYST, clocks.hclk().raw());
8283

8384
defmt::info!("Setting up pins");

examples/smoltcp-timesync/client.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ mod app {
112112
let tx_payload_storage = cx.local.tx_payload_storage;
113113
let sockets = cx.local.sockets;
114114

115-
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
115+
let (clocks, gpio, ethernet) =
116+
crate::common::setup_peripherals(p, core.MPU, rx_ring, tx_ring);
116117
let mono = Systick::new(core.SYST, clocks.hclk().raw());
117118

118119
defmt::info!("Setting up pins");

examples/smoltcp-timesync/server.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ mod app {
8181
let tx_payload_storage = cx.local.tx_payload_storage;
8282
let sockets = cx.local.sockets;
8383

84-
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
84+
let (clocks, gpio, ethernet) =
85+
crate::common::setup_peripherals(p, core.MPU, rx_ring, tx_ring);
8586
let mono = Systick::new(core.SYST, clocks.hclk().raw());
8687

8788
defmt::info!("Setting up pins");

examples/timesync/client.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ mod app {
123123
let rx_ring = cx.local.rx_ring;
124124
let tx_ring = cx.local.tx_ring;
125125

126-
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
126+
let (clocks, gpio, ethernet) =
127+
crate::common::setup_peripherals(p, core.MPU, rx_ring, tx_ring);
127128
let mono = Systick::new(core.SYST, clocks.hclk().raw());
128129

129130
defmt::info!("Setting up pins");

0 commit comments

Comments
 (0)