Skip to content

Commit b0131e7

Browse files
Merge pull request #68 from stm32-rs/ptp-pps
Ptp pps
2 parents 2354f43 + a3a9c1e commit b0131e7

File tree

12 files changed

+143
-15
lines changed

12 files changed

+143
-15
lines changed

.github/workflows/build.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ jobs:
132132
features: ""
133133
- example: rtic-echo
134134
features: smoltcp-phy
135+
- example: rtic-timestamp
136+
features: ""
135137
mcu:
136138
- stm32f107
137139
- stm32f429
@@ -143,19 +145,23 @@ jobs:
143145
pins:
144146
- nucleo
145147
- default
148+
pps:
149+
- default
150+
- alternate
151+
146152
steps:
147153
- name: Checkout
148154
uses: actions/checkout@v3
149155

150-
- name: Install Rust ${{ matrix.toolchain }} with target (${{ matrix.target }}) and pins ${{ matrix.pins }}
156+
- name: Install Rust ${{ matrix.toolchain }} with target (${{ matrix.target }})
151157
run: |
152158
rustup set profile minimal
153159
rustup override set ${{ matrix.toolchain }}
154160
rustup target add ${{ matrix.target }}
155161
156-
- name: Build example ${{ matrix.example.example }} for ${{ matrix.mcu }}
162+
- name: Build example ${{ matrix.example.example }} for ${{ matrix.mcu }}, eth pins ${{ matrix.pins }}, pps pin ${{ matrix.pps }}
157163
run: |
158-
STM32_ETH_EXAMPLE_PINS=${{ matrix.pins }} cargo build --release --target=${{ matrix.target }} --example ${{ matrix.example.example}} --features ${{ matrix.mcu }},${{ matrix.example.features }}
164+
STM32_ETH_EXAMPLE_PPS=${{ matrix.pps }} STM32_ETH_EXAMPLE_PINS=${{ matrix.pins }} cargo build --release --target=${{ matrix.target }} --example ${{ matrix.example.example}} --features ${{ matrix.mcu }},${{ matrix.example.features }}
159165
160166
# Refs: https://github.com/rust-lang/crater/blob/9ab6f9697c901c4a44025cf0a39b73ad5b37d198/.github/workflows/bors.yml#L125-L149
161167
#

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,14 @@ The examples should run and compile on any MCU that has an 802.3 compatible PHY
9898

9999
The examples use `defmt` and `defmt_rtt` for logging, and `panic_probe` over `defmt_rtt` for printing panic backtraces.
100100

101-
##### Alternative pin configuration & HSE
101+
##### Alternative pin configuration, HSE & PPS
102102

103103
If the board you're developing for has a High Speed External oscillator connected to the correct pins, the HSE configuration can be activated by setting the `STM32_ETH_EXAMPLE_HSE` environment variable to one of `oscillator` or `bypass` when compiling.
104104

105105
If the board you're developing for uses the nucleo pinout (PG11 and PG13 instead of PB11 and PB12), the pin configuration can be changed by setting the `STM32_ETH_EXAMPLE_PINS` environment variable to `nucleo` when compiling.
106106

107+
If you wish to use the alternative PPS output pin (PG8 instead of PB5) for the `rtic-timestamp` example, the pin configuration can be changed by setting the `STM32_ETH_EXAMPLE_PPS_PIN` environment variable to `alternate` when compiling.
108+
107109
### Building examples
108110
To build an example, run the following command:
109111
```bash

build.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ fn main() {
2424
}
2525
}
2626

27+
let pps_pin = std::env::var("STM32_ETH_EXAMPLE_PPS_PIN");
28+
29+
if let Ok(pps_pin) = pps_pin {
30+
if pps_pin == "alternate" {
31+
println!("cargo:rustc-cfg=pps=\"alternate\"")
32+
} else if pps_pin != "default" {
33+
panic!("Invalid STM32_ETH_EXAMPLE_PPS_PIN value. Allowed values: alternate, default");
34+
}
35+
}
36+
37+
println!("cargo:rerun-if-env-changed=STM32_ETH_EXAMPLE_PPS_PIN");
2738
println!("cargo:rerun-if-env-changed=STM32_ETH_EXAMPLE_HSE");
2839
println!("cargo:rerun-if-env-changed=STM32_ETH_EXAMPLE_PINS");
2940
}

examples/arp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fn main() -> ! {
4141

4242
defmt::info!("Enabling ethernet...");
4343

44-
let (eth_pins, mdio, mdc) = common::setup_pins(gpio);
44+
let (eth_pins, mdio, mdc, _) = common::setup_pins(gpio);
4545

4646
let mut rx_ring: [RxRingEntry; 2] = Default::default();
4747
let mut tx_ring: [TxRingEntry; 2] = Default::default();

examples/common.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,19 @@ mod pins {
133133
pub type Mdio = PA2<Alternate<11>>;
134134
pub type Mdc = PC1<Alternate<11>>;
135135

136+
#[cfg(not(pps = "alternate"))]
137+
pub type Pps = PB5<Output<PushPull>>;
138+
139+
#[cfg(pps = "alternate")]
140+
pub type Pps = PG8<Output<PushPull>>;
141+
136142
pub fn setup_pins(
137143
gpio: Gpio,
138144
) -> (
139145
EthPins<RefClk, Crs, TxEn, TxD0, TxD1, RxD0, RxD1>,
140146
Mdio,
141147
Mdc,
148+
Pps,
142149
) {
143150
#[allow(unused_variables)]
144151
let Gpio {
@@ -183,6 +190,11 @@ mod pins {
183190
gpioc.pc1.into_alternate().set_speed(Speed::VeryHigh),
184191
);
185192

193+
#[cfg(not(pps = "alternate"))]
194+
let pps = gpiob.pb5.into_push_pull_output();
195+
#[cfg(pps = "alternate")]
196+
let pps = gpiog.pg8.into_push_pull_output();
197+
186198
(
187199
EthPins {
188200
ref_clk,
@@ -195,6 +207,7 @@ mod pins {
195207
},
196208
mdio,
197209
mdc,
210+
pps,
198211
)
199212
}
200213
}
@@ -223,12 +236,15 @@ mod pins {
223236
pub type Mdio = PA2<Alternate<PushPull>>;
224237
pub type Mdc = PC1<Alternate<PushPull>>;
225238

239+
pub type Pps = PB5<Output<PushPull>>;
240+
226241
pub fn setup_pins(
227242
gpio: Gpio,
228243
) -> (
229244
EthPins<RefClk, Crs, TxEn, TxD0, TxD1, RxD0, RxD1>,
230245
Mdio,
231246
Mdc,
247+
Pps,
232248
) {
233249
let Gpio {
234250
mut gpioa,
@@ -248,6 +264,8 @@ mod pins {
248264
let tx_d0 = gpiob.pb12.into_alternate_push_pull(&mut gpiob.crh);
249265
let tx_d1 = gpiob.pb13.into_alternate_push_pull(&mut gpiob.crh);
250266

267+
let pps = gpiob.pb5.into_push_pull_output(&mut gpiob.crl);
268+
251269
let pins = EthPins {
252270
ref_clk,
253271
crs,
@@ -258,7 +276,7 @@ mod pins {
258276
rx_d1,
259277
};
260278

261-
(pins, mdio, mdc)
279+
(pins, mdio, mdc, pps)
262280
}
263281
}
264282

examples/ip.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn main() -> ! {
4343

4444
defmt::info!("Enabling ethernet...");
4545

46-
let (eth_pins, _mdio, _mdc) = common::setup_pins(gpio);
46+
let (eth_pins, _mdio, _mdc, _) = common::setup_pins(gpio);
4747

4848
let mut rx_ring: [RxRingEntry; 2] = Default::default();
4949
let mut tx_ring: [TxRingEntry; 2] = Default::default();

examples/pktgen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fn main() -> ! {
4040
setup_systick(&mut cp.SYST);
4141

4242
defmt::info!("Enabling ethernet...");
43-
let (eth_pins, mdio, mdc) = common::setup_pins(gpio);
43+
let (eth_pins, mdio, mdc, _) = common::setup_pins(gpio);
4444

4545
let mut rx_ring: [RxRingEntry; 2] = Default::default();
4646
let mut tx_ring: [TxRingEntry; 2] = Default::default();

examples/rtic-echo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ mod app {
7878
let mono = Systick::new(core.SYST, clocks.hclk().raw());
7979

8080
defmt::info!("Setting up pins");
81-
let (pins, mdio, mdc) = crate::common::setup_pins(gpio);
81+
let (pins, mdio, mdc, _) = crate::common::setup_pins(gpio);
8282

8383
defmt::info!("Configuring ethernet");
8484

examples/rtic-timestamp.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,15 @@ mod app {
7979
let mono = Systick::new(core.SYST, clocks.hclk().raw());
8080

8181
defmt::info!("Setting up pins");
82-
let (pins, mdio, mdc) = crate::common::setup_pins(gpio);
82+
let (pins, mdio, mdc, pps) = crate::common::setup_pins(gpio);
8383

8484
defmt::info!("Configuring ethernet");
8585

86-
let Parts { dma, mac, ptp } =
86+
let Parts { dma, mac, mut ptp } =
8787
stm32_eth::new_with_mii(ethernet, rx_ring, tx_ring, clocks, pins, mdio, mdc).unwrap();
8888

89+
ptp.enable_pps(pps);
90+
8991
defmt::info!("Enabling interrupts");
9092
dma.enable_interrupt();
9193

src/ptp/mod.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ pub use timestamp::Timestamp;
1010
mod subseconds;
1111
pub use subseconds::{Subseconds, NANOS_PER_SECOND, SUBSECONDS_PER_SECOND, SUBSECONDS_TO_SECONDS};
1212

13+
mod pps_pin;
14+
pub use pps_pin::PPSPin;
15+
1316
/// Access to the IEEE 1508v2 PTP peripheral present on the ethernet peripheral.
1417
///
1518
/// On STM32FXXX's, the PTP peripheral has/uses the following important parts:
@@ -191,6 +194,14 @@ impl EthernetPTP {
191194
}
192195
}
193196
}
197+
198+
/// Enable the PPS output on the provided pin.
199+
pub fn enable_pps<P>(&mut self, pin: P) -> P::Output
200+
where
201+
P: PPSPin,
202+
{
203+
pin.enable()
204+
}
194205
}
195206

196207
/// Setting and configuring target time interrupts on the STM32F107 does not
@@ -230,6 +241,22 @@ impl EthernetPTP {
230241
}
231242
is_tsint
232243
}
244+
245+
/// Configure the PPS output frequency.
246+
///
247+
/// The PPS output frequency becomes `2 ^ pps_freq`. `pps_freq` is
248+
/// clamped to `[0..31]`.
249+
pub fn set_pps_freq(&mut self, pps_freq: u8) {
250+
let pps_freq = pps_freq.max(31);
251+
252+
// SAFETY: we atomically write to the PTPPPSCR register, which is
253+
// not read or written to anywhere else. The SVD files are incorrectly
254+
// saying that the bits in this register are read-only.
255+
unsafe {
256+
let ptpppscr = self.eth_ptp.ptpppscr.as_ptr() as *mut u32;
257+
core::ptr::write_volatile(ptpppscr, pps_freq as u32);
258+
}
259+
}
233260
}
234261

235262
#[cfg(all(test, not(target_os = "none")))]

0 commit comments

Comments
 (0)