stm32l4xx_hal/gpio/
erased.rs1use super::*;
2
3pub type EPin<MODE> = ErasedPin<MODE>;
4
5pub struct ErasedPin<MODE> {
9 pin_port: u8,
11 _mode: PhantomData<MODE>,
12}
13
14impl<MODE> PinExt for ErasedPin<MODE> {
15 type Mode = MODE;
16
17 #[inline(always)]
18 fn pin_id(&self) -> u8 {
19 self.pin_port & 0x0f
20 }
21 #[inline(always)]
22 fn port_id(&self) -> u8 {
23 self.pin_port >> 4
24 }
25}
26
27impl<MODE> ErasedPin<MODE> {
28 pub(crate) fn new(port: u8, pin: u8) -> Self {
29 Self {
30 pin_port: port << 4 | pin,
31 _mode: PhantomData,
32 }
33 }
34
35 #[inline]
36 fn block(&self) -> &crate::pac::gpioa::RegisterBlock {
37 const GPIO_REGISTER_OFFSET: usize = 0x0400;
47
48 let offset = GPIO_REGISTER_OFFSET * self.port_id() as usize;
49 let block_ptr =
50 (crate::pac::GPIOA::ptr() as usize + offset) as *const crate::pac::gpioa::RegisterBlock;
51
52 unsafe { &*block_ptr }
53 }
54}
55
56impl<MODE> ErasedPin<Output<MODE>> {
57 #[inline(always)]
58 pub fn set_high(&mut self) {
59 unsafe { self.block().bsrr.write(|w| w.bits(1 << self.pin_id())) };
61 }
62
63 #[inline(always)]
64 pub fn set_low(&mut self) {
65 unsafe {
67 self.block()
68 .bsrr
69 .write(|w| w.bits(1 << (self.pin_id() + 16)))
70 };
71 }
72
73 #[inline(always)]
74 pub fn get_state(&self) -> PinState {
75 if self.is_set_low() {
76 PinState::Low
77 } else {
78 PinState::High
79 }
80 }
81
82 #[inline(always)]
83 pub fn set_state(&mut self, state: PinState) {
84 match state {
85 PinState::Low => self.set_low(),
86 PinState::High => self.set_high(),
87 }
88 }
89
90 #[inline(always)]
91 pub fn is_set_high(&self) -> bool {
92 !self.is_set_low()
93 }
94
95 #[inline(always)]
96 pub fn is_set_low(&self) -> bool {
97 self.block().odr.read().bits() & (1 << self.pin_id()) == 0
98 }
99
100 #[inline(always)]
101 pub fn toggle(&mut self) {
102 if self.is_set_low() {
103 self.set_high()
104 } else {
105 self.set_low()
106 }
107 }
108}
109
110impl<MODE> OutputPin for ErasedPin<Output<MODE>> {
111 type Error = core::convert::Infallible;
112
113 #[inline(always)]
114 fn set_high(&mut self) -> Result<(), Self::Error> {
115 self.set_high();
116 Ok(())
117 }
118
119 #[inline(always)]
120 fn set_low(&mut self) -> Result<(), Self::Error> {
121 self.set_low();
122 Ok(())
123 }
124}
125
126impl<MODE> StatefulOutputPin for ErasedPin<Output<MODE>> {
127 #[inline(always)]
128 fn is_set_high(&self) -> Result<bool, Self::Error> {
129 Ok(self.is_set_high())
130 }
131
132 #[inline(always)]
133 fn is_set_low(&self) -> Result<bool, Self::Error> {
134 Ok(self.is_set_low())
135 }
136}
137
138impl<MODE> ToggleableOutputPin for ErasedPin<Output<MODE>> {
139 type Error = Infallible;
140
141 #[inline(always)]
142 fn toggle(&mut self) -> Result<(), Self::Error> {
143 self.toggle();
144 Ok(())
145 }
146}
147
148impl ErasedPin<Output<OpenDrain>> {
149 #[inline(always)]
150 pub fn is_high(&self) -> bool {
151 !self.is_low()
152 }
153
154 #[inline(always)]
155 pub fn is_low(&self) -> bool {
156 self.block().idr.read().bits() & (1 << self.pin_id()) == 0
157 }
158}
159
160impl InputPin for ErasedPin<Output<OpenDrain>> {
161 type Error = core::convert::Infallible;
162
163 #[inline(always)]
164 fn is_high(&self) -> Result<bool, Self::Error> {
165 Ok(self.is_high())
166 }
167
168 #[inline(always)]
169 fn is_low(&self) -> Result<bool, Self::Error> {
170 Ok(self.is_low())
171 }
172}
173
174impl<MODE> ErasedPin<Input<MODE>> {
175 #[inline(always)]
176 pub fn is_high(&self) -> bool {
177 !self.is_low()
178 }
179
180 #[inline(always)]
181 pub fn is_low(&self) -> bool {
182 self.block().idr.read().bits() & (1 << self.pin_id()) == 0
183 }
184}
185
186impl<MODE> InputPin for ErasedPin<Input<MODE>> {
187 type Error = core::convert::Infallible;
188
189 #[inline(always)]
190 fn is_high(&self) -> Result<bool, Self::Error> {
191 Ok(self.is_high())
192 }
193
194 #[inline(always)]
195 fn is_low(&self) -> Result<bool, Self::Error> {
196 Ok(self.is_low())
197 }
198}