stm32f4xx_hal/gpio/
erased.rs1use super::*;
2
3pub use AnyPin as ErasedPin;
4
5pub struct AnyPin<MODE> {
9 pin_port: u8,
11 _mode: PhantomData<MODE>,
12}
13
14impl<MODE> fmt::Debug for AnyPin<MODE> {
15 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
16 formatter.write_fmt(format_args!(
17 "P({}{})<{}>",
18 self.port_id(),
19 self.pin_id(),
20 crate::stripped_type_name::<MODE>()
21 ))
22 }
23}
24
25#[cfg(feature = "defmt")]
26impl<MODE> defmt::Format for AnyPin<MODE> {
27 fn format(&self, f: defmt::Formatter) {
28 defmt::write!(
29 f,
30 "P({}{})<{}>",
31 self.port_id(),
32 self.pin_id(),
33 crate::stripped_type_name::<MODE>()
34 );
35 }
36}
37
38impl<MODE> PinExt for AnyPin<MODE> {
39 type Mode = MODE;
40
41 #[inline(always)]
42 fn pin_id(&self) -> u8 {
43 self.pin_port & 0x0f
44 }
45 #[inline(always)]
46 fn port_id(&self) -> u8 {
47 self.pin_port >> 4
48 }
49}
50
51impl<MODE> AnyPin<MODE> {
52 pub(crate) fn from_pin_port(pin_port: u8) -> Self {
53 Self {
54 pin_port,
55 _mode: PhantomData,
56 }
57 }
58 pub(crate) fn into_pin_port(self) -> u8 {
59 self.pin_port
60 }
61 pub(crate) fn new(port: u8, pin: u8) -> Self {
62 Self {
63 pin_port: port << 4 | pin,
64 _mode: PhantomData,
65 }
66 }
67
68 pub fn restore<const P: char, const N: u8>(self) -> Pin<P, N, MODE> {
70 assert_eq!(self.port_id(), P as u8 - b'A');
71 assert_eq!(self.pin_id(), N);
72 Pin::new()
73 }
74
75 #[inline]
76 pub(crate) fn block(&self) -> &crate::pac::gpioa::RegisterBlock {
77 const GPIO_REGISTER_OFFSET: usize = 0x0400;
87
88 let offset = GPIO_REGISTER_OFFSET * self.port_id() as usize;
89 let block_ptr =
90 (crate::pac::GPIOA::ptr() as usize + offset) as *const crate::pac::gpioa::RegisterBlock;
91
92 unsafe { &*block_ptr }
93 }
94}
95
96impl<MODE> AnyPin<Output<MODE>> {
97 #[inline(always)]
99 pub fn set_high(&mut self) {
100 self.block().bsrr().write(|w| w.bs(self.pin_id()).set_bit());
101 }
102
103 #[inline(always)]
105 pub fn set_low(&mut self) {
106 self.block().bsrr().write(|w| w.br(self.pin_id()).set_bit());
107 }
108
109 #[inline(always)]
111 pub fn get_state(&self) -> PinState {
112 if self.is_set_low() {
113 PinState::Low
114 } else {
115 PinState::High
116 }
117 }
118
119 #[inline(always)]
121 pub fn set_state(&mut self, state: PinState) {
122 match state {
123 PinState::Low => self.set_low(),
124 PinState::High => self.set_high(),
125 }
126 }
127
128 #[inline(always)]
130 pub fn is_set_high(&self) -> bool {
131 !self.is_set_low()
132 }
133
134 #[inline(always)]
136 pub fn is_set_low(&self) -> bool {
137 self.block().odr().read().odr(self.pin_id()).bit_is_clear()
138 }
139
140 #[inline(always)]
142 pub fn toggle(&mut self) {
143 if self.is_set_low() {
144 self.set_high()
145 } else {
146 self.set_low()
147 }
148 }
149}
150
151impl<MODE> AnyPin<MODE>
152where
153 MODE: marker::Readable,
154{
155 #[inline(always)]
157 pub fn is_high(&self) -> bool {
158 !self.is_low()
159 }
160
161 #[inline(always)]
163 pub fn is_low(&self) -> bool {
164 self.block().idr().read().idr(self.pin_id()).bit_is_clear()
165 }
166}