aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-03-27 04:01:48 +0100
committerDario Nieuwenhuis <[email protected]>2021-03-29 00:58:58 +0200
commit90f599bc2fdc9ff94002970d9c147e02e6961acf (patch)
tree3a15b2bca6ea9588546c2c4775a0f3d680f139d6
parent2bd9323f28537da035692e48820ce8687e627c9e (diff)
nrf/gpiote: update output channel to new API
-rw-r--r--embassy-nrf/src/gpio.rs2
-rw-r--r--embassy-nrf/src/gpiote.rs89
2 files changed, 34 insertions, 57 deletions
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index bda5aceff..a6d2fc071 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -117,7 +117,7 @@ pub enum OutputDrive {
117 117
118/// GPIO output driver. 118/// GPIO output driver.
119pub struct Output<'d, T: Pin> { 119pub struct Output<'d, T: Pin> {
120 pin: T, 120 pub(crate) pin: T,
121 phantom: PhantomData<&'d mut T>, 121 phantom: PhantomData<&'d mut T>,
122} 122}
123 123
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 95e49324d..32f085a60 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -15,7 +15,7 @@ use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
15use futures::future::poll_fn; 15use futures::future::poll_fn;
16 16
17use crate::gpio::sealed::Pin as _; 17use crate::gpio::sealed::Pin as _;
18use crate::gpio::{AnyPin, Input, Pin as GpioPin, Port, Pull}; 18use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin, Port, Pull};
19use crate::pac; 19use crate::pac;
20use crate::pac::generic::Reg; 20use crate::pac::generic::Reg;
21use crate::pac::gpiote::_TASKS_OUT; 21use crate::pac::gpiote::_TASKS_OUT;
@@ -204,37 +204,35 @@ impl<'d, C: Channel, T: GpioPin> InputPin for InputChannel<'d, C, T> {
204 } 204 }
205} 205}
206 206
207/* 207pub struct OutputChannel<'d, C: Channel, T: GpioPin> {
208pub struct OutputChannel<C: ChannelID, T> {
209 ch: C, 208 ch: C,
210 pin: GpioPin<Output<T>>, 209 pin: Output<'d, T>,
211} 210}
212 211
213impl<C: ChannelID, T> Drop for OutputChannel<C, T> { 212impl<'d, C: Channel, T: GpioPin> Drop for OutputChannel<'d, C, T> {
214 fn drop(&mut self) { 213 fn drop(&mut self) {
215 let g = unsafe { &*GPIOTE::ptr() }; 214 let g = unsafe { &*pac::GPIOTE::ptr() };
216 let index = self.ch.number(); 215 let num = self.ch.number() as usize;
217 g.config[index].write(|w| w.mode().disabled()); 216 g.config[num].write(|w| w.mode().disabled());
218 g.intenclr.write(|w| unsafe { w.bits(1 << index) }); 217 g.intenclr.write(|w| unsafe { w.bits(1 << num) });
219 } 218 }
220} 219}
221 220
222impl<C: ChannelID, T> OutputChannel<C, T> { 221impl<'d, C: Channel, T: GpioPin> OutputChannel<'d, C, T> {
223 pub fn new( 222 pub fn new(
224 _gpiote: Gpiote, 223 _init: Initialized,
225 ch: C, 224 ch: C,
226 pin: GpioPin<Output<T>>, 225 pin: Output<'d, T>,
227 level: Level,
228 polarity: OutputChannelPolarity, 226 polarity: OutputChannelPolarity,
229 ) -> Self { 227 ) -> Self {
230 let g = unsafe { &*GPIOTE::ptr() }; 228 let g = unsafe { &*pac::GPIOTE::ptr() };
231 let index = ch.number(); 229 let num = ch.number() as usize;
232 230
233 g.config[index].write(|w| { 231 g.config[num].write(|w| {
234 w.mode().task(); 232 w.mode().task();
235 match level { 233 match pin.is_set_high().unwrap() {
236 Level::High => w.outinit().high(), 234 true => w.outinit().high(),
237 Level::Low => w.outinit().low(), 235 false => w.outinit().low(),
238 }; 236 };
239 match polarity { 237 match polarity {
240 OutputChannelPolarity::Set => w.polarity().lo_to_hi(), 238 OutputChannelPolarity::Set => w.polarity().lo_to_hi(),
@@ -242,77 +240,56 @@ impl<C: ChannelID, T> OutputChannel<C, T> {
242 OutputChannelPolarity::Toggle => w.polarity().toggle(), 240 OutputChannelPolarity::Toggle => w.polarity().toggle(),
243 }; 241 };
244 #[cfg(any(feature = "52833", feature = "52840"))] 242 #[cfg(any(feature = "52833", feature = "52840"))]
245 w.port().bit(match pin.port() { 243 w.port().bit(match pin.pin.port() {
246 Port::Port0 => false, 244 Port::Port0 => false,
247 Port::Port1 => true, 245 Port::Port1 => true,
248 }); 246 });
249 unsafe { w.psel().bits(pin.pin()) } 247 unsafe { w.psel().bits(pin.pin.pin()) }
250 }); 248 });
251 249
252 // Enable interrupt
253 g.intenset.write(|w| unsafe { w.bits(1 << index) });
254
255 OutputChannel { ch, pin } 250 OutputChannel { ch, pin }
256 } 251 }
257 252
258 pub fn free(self) -> (C, GpioPin<Output<T>>) {
259 let m = ManuallyDrop::new(self);
260 let ch = unsafe { ptr::read(&m.ch) };
261 let pin = unsafe { ptr::read(&m.pin) };
262 (ch, pin)
263 }
264
265 /// Triggers `task out` (as configured with task_out_polarity, defaults to Toggle). 253 /// Triggers `task out` (as configured with task_out_polarity, defaults to Toggle).
266 pub fn out(&self) { 254 pub fn out(&self) {
267 let g = unsafe { &*GPIOTE::ptr() }; 255 let g = unsafe { &*pac::GPIOTE::ptr() };
268 let index = self.ch.number(); 256 g.tasks_out[self.ch.number() as usize].write(|w| unsafe { w.bits(1) });
269
270 g.tasks_out[index].write(|w| unsafe { w.bits(1) });
271 } 257 }
258
272 /// Triggers `task set` (set associated pin high). 259 /// Triggers `task set` (set associated pin high).
273 #[cfg(not(feature = "51"))] 260 #[cfg(not(feature = "51"))]
274 pub fn set(&self) { 261 pub fn set(&self) {
275 let g = unsafe { &*GPIOTE::ptr() }; 262 let g = unsafe { &*pac::GPIOTE::ptr() };
276 let index = self.ch.number(); 263 g.tasks_set[self.ch.number() as usize].write(|w| unsafe { w.bits(1) });
277
278 g.tasks_set[index].write(|w| unsafe { w.bits(1) });
279 } 264 }
265
280 /// Triggers `task clear` (set associated pin low). 266 /// Triggers `task clear` (set associated pin low).
281 #[cfg(not(feature = "51"))] 267 #[cfg(not(feature = "51"))]
282 pub fn clear(&self) { 268 pub fn clear(&self) {
283 let g = unsafe { &*GPIOTE::ptr() }; 269 let g = unsafe { &*pac::GPIOTE::ptr() };
284 let index = self.ch.number(); 270 g.tasks_clr[self.ch.number() as usize].write(|w| unsafe { w.bits(1) });
285
286 g.tasks_clr[index].write(|w| unsafe { w.bits(1) });
287 } 271 }
288 272
289 /// Returns reference to task_out endpoint for PPI. 273 /// Returns reference to task_out endpoint for PPI.
290 pub fn task_out(&self) -> &Reg<u32, _TASKS_OUT> { 274 pub fn task_out(&self) -> &Reg<u32, _TASKS_OUT> {
291 let g = unsafe { &*GPIOTE::ptr() }; 275 let g = unsafe { &*pac::GPIOTE::ptr() };
292 let index = self.ch.number(); 276 &g.tasks_out[self.ch.number() as usize]
293
294 &g.tasks_out[index]
295 } 277 }
296 278
297 /// Returns reference to task_clr endpoint for PPI. 279 /// Returns reference to task_clr endpoint for PPI.
298 #[cfg(not(feature = "51"))] 280 #[cfg(not(feature = "51"))]
299 pub fn task_clr(&self) -> &Reg<u32, _TASKS_CLR> { 281 pub fn task_clr(&self) -> &Reg<u32, _TASKS_CLR> {
300 let g = unsafe { &*GPIOTE::ptr() }; 282 let g = unsafe { &*pac::GPIOTE::ptr() };
301 let index = self.ch.number(); 283 &g.tasks_clr[self.ch.number() as usize]
302
303 &g.tasks_clr[index]
304 } 284 }
305 285
306 /// Returns reference to task_set endpoint for PPI. 286 /// Returns reference to task_set endpoint for PPI.
307 #[cfg(not(feature = "51"))] 287 #[cfg(not(feature = "51"))]
308 pub fn task_set(&self) -> &Reg<u32, _TASKS_SET> { 288 pub fn task_set(&self) -> &Reg<u32, _TASKS_SET> {
309 let g = unsafe { &*GPIOTE::ptr() }; 289 let g = unsafe { &*pac::GPIOTE::ptr() };
310 let index = self.ch.number(); 290 &g.tasks_set[self.ch.number() as usize]
311
312 &g.tasks_set[index]
313 } 291 }
314} 292}
315 */
316 293
317/// GPIO input driver with support 294/// GPIO input driver with support
318pub struct PortInput<'d, T: GpioPin> { 295pub struct PortInput<'d, T: GpioPin> {