Skip to content

Commit 5ca5755

Browse files
committed
Examples
1 parent b4342ee commit 5ca5755

File tree

5 files changed

+232
-25
lines changed

5 files changed

+232
-25
lines changed

build.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
fn main() {
2-
#[cfg(feature = "stm32f1xx-hal")]
32
println!("cargo:rustc-link-search=memory.x");
43

54
let hse = std::env::var("STM32_ETH_EXAMPLE_HSE");

examples/arp.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use stm32_eth::{
2323

2424
pub mod common;
2525

26-
use stm32_eth::dma::{RxRingEntry, TxError, TxRingEntry};
26+
use stm32_eth::dma::TxError;
2727

2828
const PHY_ADDR: u8 = 0;
2929

@@ -43,22 +43,14 @@ fn main() -> ! {
4343

4444
let (eth_pins, mdio, mdc, _) = common::setup_pins(gpio);
4545

46-
let mut rx_ring: [RxRingEntry; 2] = Default::default();
47-
let mut tx_ring: [TxRingEntry; 2] = Default::default();
46+
let (tx_ring, rx_ring) = crate::common::setup_rings();
4847

4948
let Parts {
5049
mut dma,
5150
mac,
5251
#[cfg(feature = "ptp")]
5352
ptp: _,
54-
} = stm32_eth::new(
55-
ethernet,
56-
&mut rx_ring[..],
57-
&mut tx_ring[..],
58-
clocks,
59-
eth_pins,
60-
)
61-
.unwrap();
53+
} = stm32_eth::new(ethernet, rx_ring, tx_ring, clocks, eth_pins).unwrap();
6254
dma.enable_interrupt();
6355

6456
let mut last_link_up = false;
@@ -109,6 +101,8 @@ fn main() -> ! {
109101
buf[38..42].copy_from_slice(&TARGET_IP);
110102
});
111103

104+
stm32_eth::eth_interrupt_handler();
105+
112106
match r {
113107
Ok(()) => {
114108
defmt::info!("ARP sent");

examples/common.rs

Lines changed: 165 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,23 @@
55
//!
66
//! Note that this module isn't an example by itself.
77
8+
use core::mem::MaybeUninit;
9+
810
use defmt_rtt as _;
911
use panic_probe as _;
1012

1113
use stm32_eth::{
12-
hal::{gpio::GpioExt, rcc::Clocks},
14+
dma::{RxDescriptor, RxDescriptorRing, TxDescriptor, TxDescriptorRing, MTU},
15+
hal::gpio::GpioExt,
1316
PartsIn,
1417
};
1518

19+
#[cfg(feature = "f-series")]
20+
use stm32_eth::hal::rcc::Clocks;
21+
22+
#[cfg(feature = "stm32h7xx-hal")]
23+
use stm32_eth::hal::rcc::CoreClocks as Clocks;
24+
1625
pub use pins::{setup_pins, Gpio};
1726

1827
use fugit::RateExtU32;
@@ -24,6 +33,33 @@ use stm32_eth::hal::rcc::RccExt;
2433
#[allow(unused)]
2534
fn main() {}
2635

36+
const NUM_DESCRIPTORS: usize = 4;
37+
38+
// On H7s, the ethernet DMA does not have access to the normal ram
39+
// so we must explicitly put them in SRAM.
40+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth")]
41+
static mut TX_DESCRIPTORS: MaybeUninit<[TxDescriptor; NUM_DESCRIPTORS]> = MaybeUninit::uninit();
42+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth")]
43+
static mut TX_BUFFERS: MaybeUninit<[[u8; MTU + 2]; NUM_DESCRIPTORS]> = MaybeUninit::uninit();
44+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth")]
45+
static mut RX_DESCRIPTORS: MaybeUninit<[RxDescriptor; NUM_DESCRIPTORS]> = MaybeUninit::uninit();
46+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth")]
47+
static mut RX_BUFFERS: MaybeUninit<[[u8; MTU + 2]; NUM_DESCRIPTORS]> = MaybeUninit::uninit();
48+
49+
/// Set up the buffers to be used
50+
pub fn setup_rings() -> (TxDescriptorRing<'static>, RxDescriptorRing<'static>) {
51+
let tx_desc = unsafe { TX_DESCRIPTORS.write([TxDescriptor::new(); NUM_DESCRIPTORS]) };
52+
let tx_buf = unsafe { TX_BUFFERS.write([[0u8; MTU + 2]; NUM_DESCRIPTORS]) };
53+
54+
let rx_desc = unsafe { RX_DESCRIPTORS.write([RxDescriptor::new(); NUM_DESCRIPTORS]) };
55+
let rx_buf = unsafe { RX_BUFFERS.write([[0u8; MTU + 2]; NUM_DESCRIPTORS]) };
56+
57+
(
58+
TxDescriptorRing::new(tx_desc, tx_buf),
59+
RxDescriptorRing::new(rx_desc, rx_buf),
60+
)
61+
}
62+
2763
/// Setup the clocks and return clocks and a GPIO struct that
2864
/// can be used to set up all of the pins.
2965
///
@@ -33,8 +69,11 @@ pub fn setup_peripherals(p: stm32_eth::stm32::Peripherals) -> (Clocks, Gpio, Par
3369
let ethernet = PartsIn {
3470
dma: p.ETHERNET_DMA,
3571
mac: p.ETHERNET_MAC,
72+
#[cfg(feature = "stm32h7xx-hal")]
73+
mtl: p.ETHERNET_MTL,
74+
#[cfg(feature = "f-series")]
3675
mmc: p.ETHERNET_MMC,
37-
#[cfg(feature = "ptp")]
76+
#[cfg(all(feature = "ptp", feature = "f-series"))]
3877
ptp: p.ETHERNET_PTP,
3978
};
4079

@@ -109,6 +148,40 @@ pub fn setup_peripherals(p: stm32_eth::stm32::Peripherals) -> (Clocks, Gpio, Par
109148

110149
(clocks, gpio, ethernet)
111150
}
151+
152+
#[cfg(feature = "stm32h7xx-hal")]
153+
{
154+
use stm32_eth::hal::pwr::PwrExt;
155+
156+
let rcc = p.RCC.constrain();
157+
let pwr = p.PWR.constrain();
158+
159+
let syscfg = p.SYSCFG;
160+
161+
let pwrcfg = pwr.vos1().freeze();
162+
163+
let rcc = rcc.hclk(200.MHz()).sys_ck(200.MHz());
164+
165+
let rcc = if cfg!(hse = "bypass") {
166+
rcc.bypass_hse().use_hse(8.MHz())
167+
} else if cfg!(hse = "oscillator") {
168+
rcc.use_hse(8.MHz())
169+
} else {
170+
rcc
171+
};
172+
173+
let ccdr = rcc.freeze(pwrcfg, &syscfg);
174+
let clocks = ccdr.clocks;
175+
176+
let gpio = Gpio {
177+
gpioa: p.GPIOA.split(ccdr.peripheral.GPIOA),
178+
gpiob: p.GPIOB.split(ccdr.peripheral.GPIOB),
179+
gpioc: p.GPIOC.split(ccdr.peripheral.GPIOC),
180+
gpiog: p.GPIOG.split(ccdr.peripheral.GPIOG),
181+
};
182+
183+
(clocks, gpio, ethernet)
184+
}
112185
}
113186

114187
pub use pins::*;
@@ -290,6 +363,96 @@ mod pins {
290363
}
291364
}
292365

366+
#[cfg(feature = "stm32h7xx-hal")]
367+
mod pins {
368+
use stm32_eth::{
369+
hal::gpio::{Input, PushPull, *},
370+
EthPins,
371+
};
372+
373+
pub struct Gpio {
374+
pub gpioa: gpioa::Parts,
375+
pub gpiob: gpiob::Parts,
376+
pub gpioc: gpioc::Parts,
377+
pub gpiog: gpiog::Parts,
378+
}
379+
380+
pub type RefClk = PA1<Input>;
381+
pub type Crs = PA7<Input>;
382+
383+
#[cfg(pins = "nucleo")]
384+
pub type TxEn = PG11<Input>;
385+
#[cfg(pins = "nucleo")]
386+
pub type TxD0 = PG13<Input>;
387+
388+
#[cfg(not(pins = "nucleo"))]
389+
pub type TxEn = PB11<Input>;
390+
#[cfg(not(pins = "nucleo"))]
391+
pub type TxD0 = PB12<Input>;
392+
393+
pub type TxD1 = PB13<Input>;
394+
pub type RxD0 = PC4<Input>;
395+
pub type RxD1 = PC5<Input>;
396+
397+
#[cfg(not(pps = "alternate"))]
398+
pub type Pps = PB5<Output<PushPull>>;
399+
#[cfg(pps = "alternate")]
400+
pub type Pps = PG5<Output<PushPull>>;
401+
402+
pub type Mdio = PA2<Alternate<11>>;
403+
pub type Mdc = PC1<Alternate<11>>;
404+
405+
pub fn setup_pins(
406+
gpio: Gpio,
407+
) -> (
408+
EthPins<RefClk, Crs, TxEn, TxD0, TxD1, RxD0, RxD1>,
409+
Mdio,
410+
Mdc,
411+
Pps,
412+
) {
413+
#[allow(unused_variables)]
414+
let Gpio {
415+
gpioa,
416+
gpiob,
417+
gpioc,
418+
gpiog,
419+
} = gpio;
420+
421+
let ref_clk = gpioa.pa1.into_input();
422+
let crs = gpioa.pa7.into_input();
423+
let rx_d0 = gpioc.pc4.into_input();
424+
let rx_d1 = gpioc.pc5.into_input();
425+
let tx_d1 = gpiob.pb13.into_input();
426+
427+
#[cfg(not(pins = "nucleo"))]
428+
let (tx_en, tx_d0) = { (gpiob.pb11.into_input(), gpiob.pb12.into_input()) };
429+
430+
#[cfg(pins = "nucleo")]
431+
let (tx_en, tx_d0) = { (gpiog.pg11.into_input(), gpiog.pg13.into_input()) };
432+
433+
let mdio = gpioa.pa2.into_alternate();
434+
let mdc = gpioc.pc1.into_alternate();
435+
436+
#[cfg(not(pps = "alternate"))]
437+
let pps = gpiob.pb5.into_push_pull_output();
438+
439+
#[cfg(pps = "alternate")]
440+
let pps = gpiog.pg5.into_push_pull_output();
441+
442+
let pins = EthPins {
443+
ref_clk,
444+
crs,
445+
tx_en,
446+
tx_d0,
447+
tx_d1,
448+
rx_d0,
449+
rx_d1,
450+
};
451+
452+
(pins, mdio, mdc, pps)
453+
}
454+
}
455+
293456
use ieee802_3_miim::{
294457
phy::{
295458
lan87xxa::{LAN8720A, LAN8742A},

examples/rtic-echo.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@ mod app {
2626
use ieee802_3_miim::{phy::PhySpeed, Phy};
2727
use systick_monotonic::Systick;
2828

29-
use stm32_eth::{
30-
dma::{EthernetDMA, RxRingEntry, TxRingEntry},
31-
mac::Speed,
32-
Parts,
33-
};
29+
use stm32_eth::{dma::EthernetDMA, mac::Speed, Parts};
3430

3531
use smoltcp::{
3632
iface::{self, Interface, SocketHandle, SocketSet, SocketStorage},
@@ -58,8 +54,6 @@ mod app {
5854
}
5955

6056
#[init(local = [
61-
rx_ring: [RxRingEntry; 2] = [RxRingEntry::new(), RxRingEntry::new()],
62-
tx_ring: [TxRingEntry; 2] = [TxRingEntry::new(), TxRingEntry::new()],
6357
rx_storage: [u8; 512] = [0u8; 512],
6458
tx_storage: [u8; 512] = [0u8; 512],
6559
socket_storage: [SocketStorage<'static>; 1] = [SocketStorage::EMPTY; 1],
@@ -69,8 +63,7 @@ mod app {
6963
let core = cx.core;
7064
let p = cx.device;
7165

72-
let rx_ring = cx.local.rx_ring;
73-
let tx_ring = cx.local.tx_ring;
66+
let (tx_ring, rx_ring) = crate::common::setup_rings();
7467

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

memory.x

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,63 @@
11
MEMORY
22
{
3-
FLASH : ORIGIN = 0x08000000, LENGTH = 128k
4-
RAM : ORIGIN = 0x20000000, LENGTH = 32K
3+
/* FLASH and RAM are mandatory memory regions */
4+
5+
/* STM32H742xI/743xI/753xI */
6+
/* STM32H745xI/747xI/755xI/757xI */
7+
/* STM32H7A3xI/7B3xI */
8+
FLASH : ORIGIN = 0x08000000, LENGTH = 1M
9+
10+
/* STM32H742xG/743xG */
11+
/* STM32H745xG/STM32H747xG */
12+
/* STM32H7A3xG */
13+
/* FLASH : ORIGIN = 0x08000000, LENGTH = 512K */
14+
/* FLASH1 : ORIGIN = 0x08100000, LENGTH = 512K */
15+
16+
/* STM32H750xB */
17+
/* STM32H7B0 */
18+
/* FLASH : ORIGIN = 0x08000000, LENGTH = 128K */
19+
20+
/* DTCM */
21+
RAM : ORIGIN = 0x20000000, LENGTH = 128K
22+
23+
/* AXISRAM */
24+
AXISRAM : ORIGIN = 0x24000000, LENGTH = 512K
25+
26+
/* SRAM */
27+
SRAM1 : ORIGIN = 0x30000000, LENGTH = 128K
28+
SRAM2 : ORIGIN = 0x30020000, LENGTH = 128K
29+
/* SRAM3 : ORIGIN = 0x30040000, LENGTH = 32K */
30+
SRAM4 : ORIGIN = 0x38000000, LENGTH = 64K
31+
32+
/* Backup SRAM */
33+
BSRAM : ORIGIN = 0x38800000, LENGTH = 4K
34+
35+
/* Instruction TCM */
36+
ITCM : ORIGIN = 0x00000000, LENGTH = 64K
537
}
38+
39+
/* The location of the stack can be overridden using the
40+
`_stack_start` symbol. Place the stack at the end of RAM */
41+
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
42+
43+
/* The location of the .text section can be overridden using the
44+
`_stext` symbol. By default it will place after .vector_table */
45+
/* _stext = ORIGIN(FLASH) + 0x40c; */
46+
47+
/* These sections are used for some of the examples */
48+
SECTIONS {
49+
.axisram (NOLOAD) : ALIGN(8) {
50+
*(.axisram .axisram.*);
51+
. = ALIGN(8);
52+
} > AXISRAM
53+
/* The SRAM1 and SRAM2 section are commonly used as the stack and heap for the
54+
CM4 core in dualcore versions and should thus not be used in examples*/
55+
.sram4 (NOLOAD) : ALIGN(4) {
56+
*(.sram4 .sram4.*);
57+
. = ALIGN(4);
58+
} > SRAM4
59+
.sram1 (NOLOAD) : ALIGN(4) {
60+
*(.sram1 .sram1.*);
61+
. = ALIGN(4);
62+
} > SRAM1
63+
};

0 commit comments

Comments
 (0)