stm32f7xx_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> fmt::Debug for ErasedPin<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
25impl<MODE> PinExt for ErasedPin<MODE> {
26 type Mode = MODE;
27
28 #[inline(always)]
29 fn pin_id(&self) -> u8 {
30 self.pin_port & 0x0f
31 }
32 #[inline(always)]
33 fn port_id(&self) -> u8 {
34 self.pin_port >> 4
35 }
36}
37
38impl<MODE> ErasedPin<MODE> {
39 pub(crate) fn new(port: u8, pin: u8) -> Self {
40 Self {
41 pin_port: port << 4 | pin,
42 _mode: PhantomData,
43 }
44 }
45
46 #[inline]
47 fn block(&self) -> &crate::pac::gpioa::RegisterBlock {
48 const GPIO_REGISTER_OFFSET: usize = 0x0400;
58
59 let offset = GPIO_REGISTER_OFFSET * self.port_id() as usize;
60 let block_ptr =
61 (crate::pac::GPIOA::ptr() as usize + offset) as *const crate::pac::gpioa::RegisterBlock;
62
63 unsafe { &*block_ptr }
64 }
65}
66
67impl<MODE> ErasedPin<Output<MODE>> {
68 #[inline(always)]
69 pub fn set_high(&mut self) {
70 unsafe { self.block().bsrr.write(|w| w.bits(1 << self.pin_id())) };
72 }
73
74 #[inline(always)]
75 pub fn set_low(&mut self) {
76 unsafe {
78 self.block()
79 .bsrr
80 .write(|w| w.bits(1 << (self.pin_id() + 16)))
81 };
82 }
83
84 #[inline(always)]
85 pub fn get_state(&self) -> PinState {
86 if self.is_set_low() {
87 PinState::Low
88 } else {
89 PinState::High
90 }
91 }
92
93 #[inline(always)]
94 pub fn set_state(&mut self, state: PinState) {
95 match state {
96 PinState::Low => self.set_low(),
97 PinState::High => self.set_high(),
98 }
99 }
100
101 #[inline(always)]
102 pub fn is_set_high(&self) -> bool {
103 !self.is_set_low()
104 }
105
106 #[inline(always)]
107 pub fn is_set_low(&self) -> bool {
108 self.block().odr.read().bits() & (1 << self.pin_id()) == 0
109 }
110
111 #[inline(always)]
112 pub fn toggle(&mut self) {
113 if self.is_set_low() {
114 self.set_high()
115 } else {
116 self.set_low()
117 }
118 }
119}
120
121impl ErasedPin<Output<OpenDrain>> {
122 #[inline(always)]
123 pub fn is_high(&self) -> bool {
124 !self.is_low()
125 }
126
127 #[inline(always)]
128 pub fn is_low(&self) -> bool {
129 self.block().idr.read().bits() & (1 << self.pin_id()) == 0
130 }
131}
132
133impl<MODE> ErasedPin<Input<MODE>> {
134 #[inline(always)]
135 pub fn is_high(&self) -> bool {
136 !self.is_low()
137 }
138
139 #[inline(always)]
140 pub fn is_low(&self) -> bool {
141 self.block().idr.read().bits() & (1 << self.pin_id()) == 0
142 }
143}