ep_pin_toggle/
lib.rs

1//! An [`EmbeddedProfiler`] implementation that toggles the given pin.
2//!
3//! This profiler is geared towards systems that have very limited resources and
4//! just want to profile a function via an oscilloscope or logic analyzer. The
5//! analyzer takes any GPIO that implements the
6//! [`OutputPin`](embedded_hal::digital::v2::OutputPin) trait
7//!
8//! ## Example Usage
9//!
10//!```no_run
11//! # struct MyPin;
12//! # type MyPinError = ();
13//! # impl embedded_hal::digital::v2::OutputPin for MyPin { type Error = ();
14//! # fn set_low(&mut self) -> Result<(), Self::Error> { Ok(()) }
15//! # fn set_high(&mut self) -> Result<(), Self::Error> { Ok(()) } }
16//! # let pin = MyPin;
17//! let ep_pin_toggle = cortex_m::singleton!(: ep_pin_toggle::EPPinToggle<MyPinError, MyPin> =
18//!     ep_pin_toggle::EPPinToggle::new(pin)).unwrap();
19//! unsafe {
20//!     embedded_profiling::set_profiler(ep_pin_toggle).unwrap();
21//! }
22//! // (...)
23//! embedded_profiling::profile("print_profile", || println!("Hello, world"));
24//! ```
25//!
26//! ## Features
27//!
28//! ### `proc-macros`
29//!
30//! enables the `proc-macros` feature in [`embedded-profiling`](embedded_profiling). Enables
31//! the [`embedded_profiling::profile_function`] procedural macro.
32//!
33//! [`embedded_profiling::profile_function`]: https://docs.rs/embedded-profiling/latest/embedded_profiling/attr.profile_function.html
34#![cfg_attr(not(test), no_std)]
35
36use core::cell::RefCell;
37use embedded_hal::digital::v2::OutputPin;
38use embedded_profiling::{EPInstant, EmbeddedProfiler};
39
40/// Implements [`EmbeddedProfiler`] by toggling the given pin.
41pub struct EPPinToggle<E, P>
42where
43    P: OutputPin<Error = E>,
44{
45    pin: RefCell<P>,
46}
47
48impl<E, P> EPPinToggle<E, P>
49where
50    P: OutputPin<Error = E>,
51{
52    /// Creates a new [`EPPinToggle`] with the given `pin`.
53    #[must_use]
54    pub const fn new(pin: P) -> Self {
55        Self {
56            pin: RefCell::new(pin),
57        }
58    }
59
60    /// Consumes [`EPPinToggle`], returning the `pin`.
61    pub fn free(self) -> P {
62        self.pin.into_inner()
63    }
64}
65
66impl<E, P> EmbeddedProfiler for EPPinToggle<E, P>
67where
68    P: OutputPin<Error = E>,
69{
70    fn read_clock(&self) -> EPInstant {
71        EPInstant::from_ticks(0)
72    }
73
74    fn at_start(&self) {
75        self.pin.borrow_mut().set_high().ok();
76    }
77
78    fn at_end(&self) {
79        self.pin.borrow_mut().set_low().ok();
80    }
81}