Skip to content

Commit 26388b6

Browse files
committed
Initial H7 support
1 parent d311ce5 commit 26388b6

File tree

18 files changed

+1450
-296
lines changed

18 files changed

+1450
-296
lines changed

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ stm32f7xx-hal = { version = "0.7.0", optional = true }
2525
stm32f4xx-hal = { version = "0.14", optional = true }
2626
stm32f4 = { version = "0.15", optional = true }
2727
stm32f1xx-hal = { version = "0.10", optional = true }
28+
stm32h7xx-hal = { version = "0.13", optional = true }
2829
ieee802_3_miim = "0.8"
2930
cortex-m = "0.7"
3031
log = { version = "0.4", optional = true }
3132
defmt = { version = "0.3", optional = true }
3233
siphasher = "*"
34+
paste = { version = "1.0", optional = true }
3335

3436
[dependencies.smoltcp]
3537
version = "0.8.2"
@@ -41,6 +43,12 @@ default = [ "defmt", "ptp" ]
4143
device-selected = []
4244
fence = []
4345
ptp = [ ]
46+
f-series = [ ]
47+
48+
stm32f1xx-hal = [ "dep:stm32f1xx-hal", "f-series" ]
49+
stm32f4xx-hal = [ "dep:stm32f4xx-hal", "f-series" ]
50+
stm32f7xx-hal = [ "dep:stm32f7xx-hal", "f-series" ]
51+
stm32h7xx-hal = [ "dep:stm32h7xx-hal", "paste" ]
4452

4553
stm32f107 = ["stm32f1xx-hal/stm32f107", "device-selected"]
4654

@@ -63,6 +71,8 @@ stm32f777 = ["stm32f7xx-hal/stm32f777", "device-selected", "fence"]
6371
stm32f778 = ["stm32f7xx-hal/stm32f778", "device-selected", "fence"]
6472
stm32f779 = ["stm32f7xx-hal/stm32f779", "device-selected", "fence"]
6573

74+
stm32h735 = ["stm32h7xx-hal/stm32h735", "device-selected", "fence"]
75+
6676
smoltcp-phy = ["smoltcp"]
6777

6878
[dev-dependencies]

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: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ use cortex_m_rt::{entry, exception};
1717
use cortex_m::interrupt::Mutex;
1818
use stm32_eth::{
1919
dma::{RxDescriptor, TxDescriptor},
20-
mac::{phy::BarePhy, Phy},
2120
stm32::{interrupt, CorePeripherals, Peripherals, SYST},
2221
Parts, MTU,
2322
};
2423

24+
#[cfg(feature = "f-series")]
25+
use stm32_eth::mac::{phy::BarePhy, Phy};
26+
2527
pub mod common;
2628

2729
use stm32_eth::dma::{RxDescriptorRing, TxDescriptorRing, TxError};
@@ -31,6 +33,17 @@ const PHY_ADDR: u8 = 0;
3133
static TIME: Mutex<RefCell<usize>> = Mutex::new(RefCell::new(0));
3234
static ETH_PENDING: Mutex<RefCell<bool>> = Mutex::new(RefCell::new(false));
3335

36+
/// On H7s, the ethernet DMA does not have access to the normal ram
37+
/// so we must explicitly put them in SRAM.
38+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth")]
39+
static mut TX_DESCRIPTORS: [TxDescriptor; 4] = [TxDescriptor::new(); 4];
40+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth")]
41+
static mut TX_BUFFERS: [[u8; MTU + 2]; 4] = [[0u8; MTU + 2]; 4];
42+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth2")]
43+
static mut RX_DESCRIPTORS: [RxDescriptor; 4] = [RxDescriptor::new(); 4];
44+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth2")]
45+
static mut RX_BUFFERS: [[u8; MTU + 2]; 4] = [[0u8; MTU + 2]; 4];
46+
3447
#[entry]
3548
fn main() -> ! {
3649
let p = Peripherals::take().unwrap();
@@ -44,13 +57,8 @@ fn main() -> ! {
4457

4558
let (eth_pins, mdio, mdc, _) = common::setup_pins(gpio);
4659

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);
60+
let rx_ring = RxDescriptorRing::new(unsafe { &mut RX_DESCRIPTORS }, unsafe { &mut RX_BUFFERS });
61+
let tx_ring = TxDescriptorRing::new(unsafe { &mut TX_DESCRIPTORS }, unsafe { &mut TX_BUFFERS });
5462

5563
let Parts {
5664
mut dma,
@@ -62,11 +70,16 @@ fn main() -> ! {
6270

6371
let mut last_link_up = false;
6472

65-
let mut bare_phy = BarePhy::new(mac.with_mii(mdio, mdc), PHY_ADDR, Default::default());
73+
#[cfg(feature = "f-series")]
74+
let mut bare_phy = BarePhy::new(_mac.with_mii(mdio, mdc), PHY_ADDR, Default::default());
6675

6776
loop {
77+
#[cfg(feature = "f-series")]
6878
let link_up = bare_phy.phy_link_up();
6979

80+
#[cfg(feature = "stm32h7xx-hal")]
81+
let link_up = true;
82+
7083
if link_up != last_link_up {
7184
if link_up {
7285
defmt::info!("Ethernet: link detected");
@@ -129,7 +142,7 @@ fn main() -> ! {
129142
defmt::info!("ARP sent");
130143
}
131144
Err(TxError::WouldBlock) => {
132-
defmt::panic!("ARP failed. {}", dma.tx_state())
145+
defmt::info!("ARP failed. {}", dma.tx_state())
133146
}
134147
}
135148
} else {

examples/common.rs

Lines changed: 113 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44
//!
55
//! Note that this module isn't an example by itself.
66
7-
use stm32_eth::{
8-
hal::{gpio::GpioExt, rcc::Clocks},
9-
PartsIn,
10-
};
7+
use stm32_eth::{hal::gpio::GpioExt, PartsIn};
8+
9+
#[cfg(feature = "f-series")]
10+
use stm32_eth::hal::rcc::Clocks;
11+
12+
#[cfg(feature = "stm32h7xx-hal")]
13+
use stm32_eth::hal::rcc::CoreClocks as Clocks;
1114

1215
pub use pins::{setup_pins, Gpio};
1316

@@ -23,6 +26,9 @@ pub fn setup_peripherals(p: stm32_eth::stm32::Peripherals) -> (Clocks, Gpio, Par
2326
let ethernet = PartsIn {
2427
dma: p.ETHERNET_DMA,
2528
mac: p.ETHERNET_MAC,
29+
#[cfg(feature = "stm32h7xx-hal")]
30+
mtl: p.ETHERNET_MTL,
31+
#[cfg(feature = "f-series")]
2632
mmc: p.ETHERNET_MMC,
2733
#[cfg(feature = "ptp")]
2834
ptp: p.ETHERNET_PTP,
@@ -99,6 +105,40 @@ pub fn setup_peripherals(p: stm32_eth::stm32::Peripherals) -> (Clocks, Gpio, Par
99105

100106
(clocks, gpio, ethernet)
101107
}
108+
109+
#[cfg(feature = "stm32h7xx-hal")]
110+
{
111+
use stm32_eth::hal::pwr::PwrExt;
112+
113+
let rcc = p.RCC.constrain();
114+
let pwr = p.PWR.constrain();
115+
116+
let syscfg = p.SYSCFG;
117+
118+
let pwrcfg = pwr.vos0(&syscfg).freeze();
119+
120+
let rcc = rcc.hclk(240.MHz());
121+
122+
let rcc = if cfg!(hse = "bypass") {
123+
rcc.bypass_hse().use_hse(8.MHz())
124+
} else if cfg!(hse = "oscillator") {
125+
rcc.use_hse(8.MHz())
126+
} else {
127+
rcc
128+
};
129+
130+
let ccdr = rcc.freeze(pwrcfg, &syscfg);
131+
let clocks = ccdr.clocks;
132+
133+
let gpio = Gpio {
134+
gpioa: p.GPIOA.split(ccdr.peripheral.GPIOA),
135+
gpiob: p.GPIOB.split(ccdr.peripheral.GPIOB),
136+
gpioc: p.GPIOC.split(ccdr.peripheral.GPIOC),
137+
gpiog: p.GPIOG.split(ccdr.peripheral.GPIOG),
138+
};
139+
140+
(clocks, gpio, ethernet)
141+
}
102142
}
103143

104144
pub use pins::*;
@@ -280,6 +320,75 @@ mod pins {
280320
}
281321
}
282322

323+
#[cfg(feature = "stm32h7xx-hal")]
324+
mod pins {
325+
use stm32_eth::{
326+
hal::gpio::{Input, PushPull, *},
327+
EthPins,
328+
};
329+
330+
pub struct Gpio {
331+
pub gpioa: gpioa::Parts,
332+
pub gpiob: gpiob::Parts,
333+
pub gpioc: gpioc::Parts,
334+
pub gpiog: gpiog::Parts,
335+
}
336+
337+
pub type RefClk = PA1<Input>;
338+
pub type Crs = PA7<Input>;
339+
pub type TxEn = PG11<Input>;
340+
pub type TxD0 = PG13<Input>;
341+
pub type TxD1 = PB13<Input>;
342+
pub type RxD0 = PC4<Input>;
343+
pub type RxD1 = PC5<Input>;
344+
345+
pub type Pps = PB5<Output<PushPull>>;
346+
347+
pub type Mdio = ();
348+
pub type Mdc = ();
349+
350+
pub fn setup_pins(
351+
gpio: Gpio,
352+
) -> (
353+
EthPins<RefClk, Crs, TxEn, TxD0, TxD1, RxD0, RxD1>,
354+
Mdio,
355+
Mdc,
356+
Pps,
357+
) {
358+
let Gpio {
359+
gpioa,
360+
gpiob,
361+
gpioc,
362+
gpiog,
363+
} = gpio;
364+
365+
let ref_clk = gpioa.pa1.into_input();
366+
let crs = gpioa.pa7.into_input();
367+
let rx_d0 = gpioc.pc4.into_input();
368+
let rx_d1 = gpioc.pc5.into_input();
369+
let tx_en = gpiog.pg11.into_input();
370+
let tx_d0 = gpiog.pg13.into_input();
371+
let tx_d1 = gpiob.pb13.into_input();
372+
373+
let mdc = ();
374+
let mdio = ();
375+
376+
let pps = gpiob.pb5.into_push_pull_output();
377+
378+
let pins = EthPins {
379+
ref_clk,
380+
crs,
381+
tx_en,
382+
tx_d0,
383+
tx_d1,
384+
rx_d0,
385+
rx_d1,
386+
};
387+
388+
(pins, mdio, mdc, pps)
389+
}
390+
}
391+
283392
use ieee802_3_miim::{
284393
phy::{
285394
lan87xxa::{LAN8720A, LAN8742A},

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)