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}