Skip to content

Commit 64a44b1

Browse files
committed
Tentative PTP support on H7 as well :D
1 parent 489e80d commit 64a44b1

File tree

8 files changed

+230
-94
lines changed

8 files changed

+230
-94
lines changed

examples/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub fn setup_peripherals(p: stm32_eth::stm32::Peripherals) -> (Clocks, Gpio, Par
3030
mtl: p.ETHERNET_MTL,
3131
#[cfg(feature = "f-series")]
3232
mmc: p.ETHERNET_MMC,
33-
#[cfg(feature = "ptp")]
33+
#[cfg(all(feature = "ptp", feature = "f-series"))]
3434
ptp: p.ETHERNET_PTP,
3535
};
3636

examples/rtic-timestamp.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ mod app {
4848
},
4949
mac::Speed,
5050
ptp::{EthernetPTP, Timestamp},
51-
Parts,
51+
Parts, MTU,
5252
};
5353

5454
#[local]
@@ -65,19 +65,27 @@ mod app {
6565
#[monotonic(binds = SysTick, default = true)]
6666
type Monotonic = Systick<1000>;
6767

68-
#[init(local = [
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],
73-
])]
68+
/// On H7s, the ethernet DMA does not have access to the normal ram
69+
/// so we must explicitly put them in SRAM.
70+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth")]
71+
static mut TX_DESCRIPTORS: [TxDescriptor; 4] = [TxDescriptor::new(); 4];
72+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth")]
73+
static mut TX_BUFFERS: [[u8; MTU + 2]; 4] = [[0u8; MTU + 2]; 4];
74+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth2")]
75+
static mut RX_DESCRIPTORS: [RxDescriptor; 4] = [RxDescriptor::new(); 4];
76+
#[cfg_attr(feature = "stm32h7xx-hal", link_section = ".sram1.eth2")]
77+
static mut RX_BUFFERS: [[u8; MTU + 2]; 4] = [[0u8; MTU + 2]; 4];
78+
79+
#[init]
7480
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
7581
defmt::info!("Pre-init");
7682
let core = cx.core;
7783
let p = cx.device;
7884

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);
85+
let rx_ring =
86+
RxDescriptorRing::new(unsafe { &mut RX_DESCRIPTORS }, unsafe { &mut RX_BUFFERS });
87+
let tx_ring =
88+
TxDescriptorRing::new(unsafe { &mut TX_DESCRIPTORS }, unsafe { &mut TX_BUFFERS });
8189

8290
let (clocks, gpio, ethernet) = crate::common::setup_peripherals(p);
8391
let mono = Systick::new(core.SYST, clocks.hclk().raw());
@@ -88,13 +96,15 @@ mod app {
8896
defmt::info!("Configuring ethernet");
8997

9098
let Parts { dma, mac, mut ptp } =
91-
stm32_eth::new_with_mii(ethernet, rx_ring, tx_ring, clocks, pins, mdio, mdc).unwrap();
99+
stm32_eth::new(ethernet, rx_ring, tx_ring, clocks, pins).unwrap();
92100

101+
#[cfg(not(feature = "stm32h7xx-hal"))]
93102
ptp.enable_pps(pps);
94103

95104
defmt::info!("Enabling interrupts");
96105
dma.enable_interrupt();
97106

107+
#[cfg(not(feature = "stm32h7xx-hal"))]
98108
match EthernetPhy::from_miim(mac, 0) {
99109
Ok(mut phy) => {
100110
defmt::info!(
@@ -151,14 +161,15 @@ mod app {
151161
// incorrect, but works well enough in low-activity systems (such as this example).
152162
let now = (cx.shared.ptp, cx.shared.scheduled_time).lock(|ptp, sched_time| {
153163
let now = ptp.get_time();
154-
#[cfg(not(feature = "stm32f107"))]
164+
#[cfg(not(any(feature = "stm32f107", feature = "stm32h7xx-hal")))]
155165
{
156166
let in_half_sec = now
157167
+ Timestamp::new(
158168
false,
159169
0,
160170
stm32_eth::ptp::Subseconds::new_from_nanos(500_000_000).unwrap(),
161171
);
172+
162173
ptp.configure_target_time_interrupt(in_half_sec);
163174
}
164175
*sched_time = Some(now);
@@ -201,7 +212,7 @@ mod app {
201212
.lock(|dma, tx_id, ptp, _sched_time| {
202213
dma.interrupt_handler();
203214

204-
#[cfg(not(feature = "stm32f107"))]
215+
#[cfg(not(any(feature = "stm32f107", feature = "stm32h7xx-hal")))]
205216
{
206217
if ptp.interrupt_handler() {
207218
if let Some(sched_time) = _sched_time.take() {

src/dma/rx/h_desc.rs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -216,25 +216,7 @@ impl RxDescriptor {
216216
impl RxDescriptor {
217217
/// Get PTP timestamps if available
218218
pub(super) fn read_timestamp(&self) -> Option<Timestamp> {
219-
#[cfg(not(feature = "stm32f1xx-hal"))]
220-
let is_valid = {
221-
/// RX timestamp
222-
const RXDESC_0_TIMESTAMP_VALID: u32 = 1 << 7;
223-
self.inner_raw.read(0) & RXDESC_0_TIMESTAMP_VALID == RXDESC_0_TIMESTAMP_VALID
224-
};
225-
226-
#[cfg(feature = "stm32f1xx-hal")]
227-
// There is no "timestamp valid" indicator bit
228-
// on STM32F1XX
229-
let is_valid = true;
230-
231-
let timestamp = Timestamp::from_descriptor(&self.inner_raw);
232-
233-
if is_valid && self.is_last() {
234-
timestamp
235-
} else {
236-
None
237-
}
219+
todo!();
238220
}
239221

240222
fn attach_timestamp(&mut self) {

src/dma/tx/h_desc.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ impl TxDescriptor {
144144
}
145145
}
146146

147+
fn is_last(&self) -> bool {
148+
(self.inner_raw.read(3) & TXDESC_3_LD) == TXDESC_3_LD
149+
}
150+
147151
// Placeholder for API parity with f-series descriptor.
148152
pub(super) fn setup(&mut self, _: &[u8]) {}
149153

@@ -216,12 +220,11 @@ impl TxDescriptor {
216220
#[cfg(feature = "ptp")]
217221
impl TxDescriptor {
218222
fn read_timestamp(&mut self) -> Option<Timestamp> {
219-
let tdes0 = self.inner_raw.read(0);
220-
221-
let contains_timestamp = (tdes0 & TXDESC_0_TIMESTAMP_STATUS) == TXDESC_0_TIMESTAMP_STATUS;
223+
let contains_timestamp = (self.inner_raw.read(3) & TXDESC_3_TTSS) == TXDESC_3_TTSS;
222224

223-
if !self.is_owned() && contains_timestamp && Self::is_last(tdes0) {
224-
Timestamp::from_descriptor(&self.inner_raw)
225+
if !self.is_owned() && contains_timestamp && self.is_last() {
226+
let (low, high) = (self.inner_raw.read(0), self.inner_raw.read(1));
227+
Some(Timestamp::from_parts(high, low))
225228
} else {
226229
None
227230
}

src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,12 @@ where
125125

126126
// Configure the ethernet PTP
127127
#[cfg(feature = "ptp")]
128-
let ptp = EthernetPTP::new(parts.ptp.into(), clocks, &dma);
128+
let ptp = EthernetPTP::new(
129+
#[cfg(feature = "f-series")]
130+
parts.ptp.into(),
131+
clocks,
132+
&dma,
133+
);
129134

130135
// Configure the ethernet MAC
131136
let mac = EthernetMAC::new(mac_parts, clocks, Speed::FullDuplexBase100Tx, &dma)?;

src/mac/mod.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,19 +287,18 @@ impl EthernetMAC {
287287
EthernetMACWithMii::new(self, mdio, mdc)
288288
}
289289

290-
#[cfg(feature = "ptp")]
290+
#[cfg(all(feature = "ptp", feature = "f-series"))]
291291
pub(crate) fn mask_timestamp_trigger_interrupt() {
292292
// SAFETY: MACIMR only receives atomic writes.
293293
let mac = &unsafe { &*ETHERNET_MAC::ptr() };
294294
mac.macimr.write(|w| w.tstim().set_bit());
295295
}
296296

297297
// NOTE(allow): only used on F4 and F7
298-
#[cfg(feature = "ptp")]
299-
#[allow(dead_code)]
298+
#[cfg(all(feature = "ptp", feature = "f-series"))]
300299
pub(crate) fn unmask_timestamp_trigger_interrupt() {
301300
// SAFETY: MACIMR only receives atomic writes.
302-
let macimr = &unsafe { &*ETHERNET_MAC::ptr() }.macimr;
303-
macimr.write(|w| w.tstim().clear_bit());
301+
let mac = &unsafe { &*ETHERNET_MAC::ptr() };
302+
mac.macimr.write(|w| w.tstim().clear_bit());
304303
}
305304
}

0 commit comments

Comments
 (0)