1use crate::{Error, PinMode, Polarity, Register, Stmpe1600};
2use core::marker::PhantomData;
3use embedded_hal::blocking::i2c::{Read, Write};
4use embedded_hal::digital::v2::{InputPin, OutputPin};
5
6pub mod modes {
7 pub struct Input;
8 pub struct Output;
9 pub struct Interrupt;
10}
11use modes::*;
12
13pub struct Pin<'a, I2C, MODE> {
63 driver: &'a Stmpe1600<I2C>,
64 pin: u8,
65 _phantom: PhantomData<MODE>,
66}
67
68impl<'a, E, I2C, MODE> Pin<'a, I2C, MODE>
69where
70 I2C: Read<Error = E> + Write<Error = E>,
71{
72 pub(crate) fn new(driver: &'a Stmpe1600<I2C>, pin: u8) -> Pin<'a, I2C, MODE> {
73 Pin {
74 driver,
75 pin,
76 _phantom: PhantomData,
77 }
78 }
79
80 pub fn polarity_inversion(&mut self) -> Result<Polarity, Error<E>> {
82 let mut dev = self.driver.device.borrow_mut();
83 let gppir = dev.read_reg(Register::GPPIR)?;
84 if gppir & (1 << self.pin) == (1 << self.pin) {
85 Ok(Polarity::High)
86 } else {
87 Ok(Polarity::Low)
88 }
89 }
90
91 pub fn set_polarity_inversion(&mut self, polarity: Polarity) -> Result<(), Error<E>> {
93 let mut dev = self.driver.device.borrow_mut();
94 let mut gppir = dev.read_reg(Register::GPPIR)?;
95 match polarity {
96 Polarity::Low => gppir &= !(1 << self.pin),
97 Polarity::High => gppir |= 1 << self.pin,
98 }
99 dev.write_reg(Register::GPPIR, gppir)?;
100 Ok(())
101 }
102}
103
104impl<'a, E, I2C> Pin<'a, I2C, Input>
105where
106 I2C: Read<Error = E> + Write<Error = E>,
107{
108 pub fn into_output_pin(self) -> Result<Pin<'a, I2C, Output>, Error<E>> {
110 let mut dev = self.driver.device.borrow_mut();
111 let mut gpdr = dev.read_reg(Register::GPDR)?;
112 gpdr |= 1 << self.pin;
113 dev.write_reg(Register::GPDR, gpdr)?;
114
115 self.driver.pins.borrow_mut()[self.pin as usize] = PinMode::Output;
116 Ok(Pin::new(self.driver, self.pin))
117 }
118
119 pub fn into_interrupt_pin(self) -> Result<Pin<'a, I2C, Interrupt>, Error<E>> {
121 let mut dev = self.driver.device.borrow_mut();
122 let mut iegpior = dev.read_reg(Register::IEGPIOR)?;
123 iegpior |= 1 << self.pin;
124 dev.write_reg(Register::IEGPIOR, iegpior)?;
125
126 self.driver.pins.borrow_mut()[self.pin as usize] = PinMode::Interrupt;
127 Ok(Pin::new(self.driver, self.pin))
128 }
129}
130
131impl<'a, E, I2C> InputPin for Pin<'a, I2C, Input>
132where
133 I2C: Read<Error = E> + Write<Error = E>,
134{
135 type Error = Error<E>;
136
137 fn is_low(&self) -> Result<bool, Self::Error> {
138 let mask = self.driver.device.borrow_mut().read_reg(Register::GPMR)?;
139 Ok(mask & (1 << self.pin) == 0)
140 }
141
142 fn is_high(&self) -> Result<bool, Self::Error> {
143 let mask = self.driver.device.borrow_mut().read_reg(Register::GPMR)?;
144 Ok(mask & (1 << self.pin) == 1 << self.pin)
145 }
146}
147
148impl<'a, E, I2C> Pin<'a, I2C, Output>
149where
150 I2C: Read<Error = E> + Write<Error = E>,
151{
152 pub fn into_input_pin(self) -> Result<Pin<'a, I2C, Input>, Error<E>> {
154 let mut dev = self.driver.device.borrow_mut();
155 let mut gpdr = dev.read_reg(Register::GPDR)?;
156 gpdr &= !(1 << self.pin);
157 dev.write_reg(Register::GPDR, gpdr)?;
158
159 self.driver.pins.borrow_mut()[self.pin as usize] = PinMode::Input;
160 Ok(Pin::new(self.driver, self.pin))
161 }
162
163 pub fn into_interrupt_pin(self) -> Result<Pin<'a, I2C, Interrupt>, Error<E>> {
165 let mut dev = self.driver.device.borrow_mut();
166 let mut gpdr = dev.read_reg(Register::GPDR)?;
167 gpdr &= !(1 << self.pin);
168 dev.write_reg(Register::GPDR, gpdr)?;
169 let mut iegpior = dev.read_reg(Register::IEGPIOR)?;
170 iegpior |= 1 << self.pin;
171 dev.write_reg(Register::IEGPIOR, iegpior)?;
172
173 self.driver.pins.borrow_mut()[self.pin as usize] = PinMode::Interrupt;
174 Ok(Pin::new(self.driver, self.pin))
175 }
176}
177
178impl<'a, E, I2C> OutputPin for Pin<'a, I2C, Output>
179where
180 I2C: Read<Error = E> + Write<Error = E>,
181{
182 type Error = Error<E>;
183
184 fn set_low(&mut self) -> Result<(), Self::Error> {
185 let mask = self.driver.device.borrow_mut().read_reg(Register::GPSR)?;
186 self.driver
187 .device
188 .borrow_mut()
189 .write_reg(Register::GPSR, mask & !(1 << self.pin))
190 }
191
192 fn set_high(&mut self) -> Result<(), Self::Error> {
193 let mask = self.driver.device.borrow_mut().read_reg(Register::GPSR)?;
194 self.driver
195 .device
196 .borrow_mut()
197 .write_reg(Register::GPSR, mask | (1 << self.pin))
198 }
199}
200
201impl<'a, E, I2C> Pin<'a, I2C, Interrupt>
202where
203 I2C: Read<Error = E> + Write<Error = E>,
204{
205 pub fn into_input_pin(self) -> Result<Pin<'a, I2C, Input>, Error<E>> {
207 let mut dev = self.driver.device.borrow_mut();
208 let mut iegpior = dev.read_reg(Register::IEGPIOR)?;
209 iegpior &= !(1 << self.pin);
210 dev.write_reg(Register::IEGPIOR, iegpior)?;
211
212 self.driver.pins.borrow_mut()[self.pin as usize] = PinMode::Input;
213 Ok(Pin::new(self.driver, self.pin))
214 }
215
216 pub fn into_output_pin(self) -> Result<Pin<'a, I2C, Output>, Error<E>> {
218 let mut dev = self.driver.device.borrow_mut();
219 let mut gpdr = dev.read_reg(Register::GPDR)?;
220 gpdr |= 1 << self.pin;
221 dev.write_reg(Register::GPDR, gpdr)?;
222 let mut iegpior = dev.read_reg(Register::IEGPIOR)?;
223 iegpior &= !(1 << self.pin);
224 dev.write_reg(Register::IEGPIOR, iegpior)?;
225
226 self.driver.pins.borrow_mut()[self.pin as usize] = PinMode::Output;
227 Ok(Pin::new(self.driver, self.pin))
228 }
229}
230
231impl<'a, E, I2C> InputPin for Pin<'a, I2C, Interrupt>
232where
233 I2C: Read<Error = E> + Write<Error = E>,
234{
235 type Error = Error<E>;
236
237 fn is_low(&self) -> Result<bool, Self::Error> {
238 let mask = self.driver.device.borrow_mut().read_reg(Register::GPMR)?;
239 Ok(mask & (1 << self.pin) == 0)
240 }
241
242 fn is_high(&self) -> Result<bool, Self::Error> {
243 let mask = self.driver.device.borrow_mut().read_reg(Register::GPMR)?;
244 Ok(mask & (1 << self.pin) == 1 << self.pin)
245 }
246}