stm32_eth/ptp/pps_pin.rs
1/// Pins that can be used as PPS output
2///
3/// SAFETY: only pins that are capable of being a PPS output according
4/// to the datasheets of respective parts may implement this trait.
5pub unsafe trait PPSPin {
6 /// The output type of this pin, in which it acts as a PPS output.
7 type Output;
8
9 /// Enable the PPS output.
10 fn enable(self) -> Self::Output;
11}
12
13#[allow(unused_macros)]
14macro_rules! impl_pps_pin {
15 ($([$name:ty, $output:ty]),*) => {
16 $(
17 unsafe impl super::PPSPin for $name {
18 type Output = $output;
19
20 fn enable(self) -> Self::Output {
21 self.into_alternate()
22 }
23 }
24 )*
25 };
26}
27
28#[cfg(feature = "stm32f4xx-hal")]
29mod impl_pps_pin {
30 use crate::hal::gpio::{Alternate, Output, PushPull, PB5, PG8};
31
32 impl_pps_pin!([PG8<Output<PushPull>>, PG8<Alternate<11>>], [PB5<Output<PushPull>>, PB5<Alternate<11>>]);
33}
34
35#[cfg(feature = "stm32f7xx-hal")]
36mod impl_pps_pin {
37 use crate::hal::gpio::{Alternate, Output, PushPull, PB5, PG8};
38
39 impl_pps_pin!([PG8<Output<PushPull>>, PG8<Alternate<11>>], [PB5<Output<PushPull>>, PB5<Alternate<11>>]);
40}
41
42#[cfg(feature = "stm32f1xx-hal")]
43mod impl_pps_pin {
44 use crate::hal::gpio::{Alternate, Output, PushPull, PB5};
45
46 unsafe impl super::PPSPin for PB5<Output<PushPull>> {
47 type Output = PB5<Alternate<PushPull>>;
48
49 fn enable(self) -> Self::Output {
50 // Within this critical section, modifying the `CRL` register can
51 // only be unsound if this critical section preempts other code
52 // that is modifying the same register
53 cortex_m::interrupt::free(|_| {
54 // SAFETY: this is sound as long as the API of the HAL and structure of the CRL
55 // struct does not change. In case the size of the `CRL` struct is changed, compilation
56 // will fail as `mem::transmute` can only convert between types of the same size.
57 //
58 // This guards us from unsound behaviour introduced by point releases of the f1 hal
59 let cr: &mut _ = &mut unsafe { core::mem::transmute(()) };
60 // The speed can only be changed on output pins
61 self.into_alternate_push_pull(cr)
62 })
63 }
64 }
65}