diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-03-27 04:01:48 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-03-29 00:58:58 +0200 |
| commit | 90f599bc2fdc9ff94002970d9c147e02e6961acf (patch) | |
| tree | 3a15b2bca6ea9588546c2c4775a0f3d680f139d6 | |
| parent | 2bd9323f28537da035692e48820ce8687e627c9e (diff) | |
nrf/gpiote: update output channel to new API
| -rw-r--r-- | embassy-nrf/src/gpio.rs | 2 | ||||
| -rw-r--r-- | embassy-nrf/src/gpiote.rs | 89 |
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. |
| 119 | pub struct Output<'d, T: Pin> { | 119 | pub 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}; | |||
| 15 | use futures::future::poll_fn; | 15 | use futures::future::poll_fn; |
| 16 | 16 | ||
| 17 | use crate::gpio::sealed::Pin as _; | 17 | use crate::gpio::sealed::Pin as _; |
| 18 | use crate::gpio::{AnyPin, Input, Pin as GpioPin, Port, Pull}; | 18 | use crate::gpio::{AnyPin, Input, Output, Pin as GpioPin, Port, Pull}; |
| 19 | use crate::pac; | 19 | use crate::pac; |
| 20 | use crate::pac::generic::Reg; | 20 | use crate::pac::generic::Reg; |
| 21 | use crate::pac::gpiote::_TASKS_OUT; | 21 | use 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 | /* | 207 | pub struct OutputChannel<'d, C: Channel, T: GpioPin> { |
| 208 | pub 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 | ||
| 213 | impl<C: ChannelID, T> Drop for OutputChannel<C, T> { | 212 | impl<'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 | ||
| 222 | impl<C: ChannelID, T> OutputChannel<C, T> { | 221 | impl<'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 |
| 318 | pub struct PortInput<'d, T: GpioPin> { | 295 | pub struct PortInput<'d, T: GpioPin> { |
