diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-05-22 15:42:14 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-05-22 15:42:14 +0200 |
| commit | 55c3ba2a5fb2ffddca187c0b04ad353433508426 (patch) | |
| tree | dfc047da0329ffe947844d4c1c2c5ddf031c6c7e | |
| parent | 13524080d337d0b767c6c3e7df18af02919c1155 (diff) | |
nrf/saadc: do not use dyn
| -rw-r--r-- | embassy-nrf/src/saadc.rs | 93 |
1 files changed, 47 insertions, 46 deletions
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index 03f21d829..edb8aa21f 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs | |||
| @@ -32,7 +32,7 @@ pub enum Error {} | |||
| 32 | /// One-shot saadc. Continuous sample mode TODO. | 32 | /// One-shot saadc. Continuous sample mode TODO. |
| 33 | pub struct OneShot<'d> { | 33 | pub struct OneShot<'d> { |
| 34 | irq: interrupt::SAADC, | 34 | irq: interrupt::SAADC, |
| 35 | phantom: PhantomData<(&'d mut peripherals::SAADC)>, | 35 | phantom: PhantomData<&'d mut peripherals::SAADC>, |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | /// Used to configure the SAADC peripheral. | 38 | /// Used to configure the SAADC peripheral. |
| @@ -117,6 +117,49 @@ impl<'d> OneShot<'d> { | |||
| 117 | fn regs(&self) -> &saadc::RegisterBlock { | 117 | fn regs(&self) -> &saadc::RegisterBlock { |
| 118 | unsafe { &*SAADC::ptr() } | 118 | unsafe { &*SAADC::ptr() } |
| 119 | } | 119 | } |
| 120 | |||
| 121 | async fn sample_inner(&mut self, pin: PositiveChannel) -> i16 { | ||
| 122 | let r = self.regs(); | ||
| 123 | |||
| 124 | // Set positive channel | ||
| 125 | r.ch[0].pselp.write(|w| w.pselp().variant(pin)); | ||
| 126 | |||
| 127 | // Set up the DMA | ||
| 128 | let mut val: i16 = 0; | ||
| 129 | r.result | ||
| 130 | .ptr | ||
| 131 | .write(|w| unsafe { w.ptr().bits(((&mut val) as *mut _) as u32) }); | ||
| 132 | r.result.maxcnt.write(|w| unsafe { w.maxcnt().bits(1) }); | ||
| 133 | |||
| 134 | // Reset and enable the end event | ||
| 135 | r.events_end.reset(); | ||
| 136 | r.intenset.write(|w| w.end().set()); | ||
| 137 | |||
| 138 | // Don't reorder the ADC start event before the previous writes. Hopefully self | ||
| 139 | // wouldn't happen anyway. | ||
| 140 | compiler_fence(Ordering::SeqCst); | ||
| 141 | |||
| 142 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | ||
| 143 | r.tasks_sample.write(|w| unsafe { w.bits(1) }); | ||
| 144 | |||
| 145 | // Wait for 'end' event. | ||
| 146 | poll_fn(|cx| { | ||
| 147 | let r = self.regs(); | ||
| 148 | |||
| 149 | if r.events_end.read().bits() != 0 { | ||
| 150 | r.events_end.reset(); | ||
| 151 | return Poll::Ready(()); | ||
| 152 | } | ||
| 153 | |||
| 154 | wake_on_interrupt(&mut self.irq, cx.waker()); | ||
| 155 | |||
| 156 | Poll::Pending | ||
| 157 | }) | ||
| 158 | .await; | ||
| 159 | |||
| 160 | // The DMA wrote the sampled value to `val`. | ||
| 161 | val | ||
| 162 | } | ||
| 120 | } | 163 | } |
| 121 | 164 | ||
| 122 | impl<'d> Drop for OneShot<'d> { | 165 | impl<'d> Drop for OneShot<'d> { |
| @@ -131,57 +174,15 @@ pub trait Sample { | |||
| 131 | where | 174 | where |
| 132 | Self: 'a; | 175 | Self: 'a; |
| 133 | 176 | ||
| 134 | fn sample<'a>(&'a mut self, pin: &mut dyn PositivePin) -> Self::SampleFuture<'a>; | 177 | fn sample<'a, T: PositivePin>(&'a mut self, pin: &mut T) -> Self::SampleFuture<'a>; |
| 135 | } | 178 | } |
| 136 | 179 | ||
| 137 | impl<'d> Sample for OneShot<'d> { | 180 | impl<'d> Sample for OneShot<'d> { |
| 138 | #[rustfmt::skip] | 181 | #[rustfmt::skip] |
| 139 | type SampleFuture<'a> where Self: 'a = impl Future<Output = i16> + 'a; | 182 | type SampleFuture<'a> where Self: 'a = impl Future<Output = i16> + 'a; |
| 140 | 183 | ||
| 141 | fn sample<'a>(&'a mut self, pin: &mut dyn PositivePin) -> Self::SampleFuture<'a> { | 184 | fn sample<'a, T: PositivePin>(&'a mut self, pin: &mut T) -> Self::SampleFuture<'a> { |
| 142 | let channel = pin.channel(); | 185 | self.sample_inner(pin.channel()) |
| 143 | async move { | ||
| 144 | let r = self.regs(); | ||
| 145 | |||
| 146 | // Set positive channel | ||
| 147 | r.ch[0].pselp.write(|w| w.pselp().variant(channel)); | ||
| 148 | |||
| 149 | // Set up the DMA | ||
| 150 | let mut val: i16 = 0; | ||
| 151 | r.result | ||
| 152 | .ptr | ||
| 153 | .write(|w| unsafe { w.ptr().bits(((&mut val) as *mut _) as u32) }); | ||
| 154 | r.result.maxcnt.write(|w| unsafe { w.maxcnt().bits(1) }); | ||
| 155 | |||
| 156 | // Reset and enable the end event | ||
| 157 | r.events_end.reset(); | ||
| 158 | r.intenset.write(|w| w.end().set()); | ||
| 159 | |||
| 160 | // Don't reorder the ADC start event before the previous writes. Hopefully self | ||
| 161 | // wouldn't happen anyway. | ||
| 162 | compiler_fence(Ordering::SeqCst); | ||
| 163 | |||
| 164 | r.tasks_start.write(|w| unsafe { w.bits(1) }); | ||
| 165 | r.tasks_sample.write(|w| unsafe { w.bits(1) }); | ||
| 166 | |||
| 167 | // Wait for 'end' event. | ||
| 168 | poll_fn(|cx| { | ||
| 169 | let r = self.regs(); | ||
| 170 | |||
| 171 | if r.events_end.read().bits() != 0 { | ||
| 172 | r.events_end.reset(); | ||
| 173 | return Poll::Ready(()); | ||
| 174 | } | ||
| 175 | |||
| 176 | wake_on_interrupt(&mut self.irq, cx.waker()); | ||
| 177 | |||
| 178 | Poll::Pending | ||
| 179 | }) | ||
| 180 | .await; | ||
| 181 | |||
| 182 | // The DMA wrote the sampled value to `val`. | ||
| 183 | val | ||
| 184 | } | ||
| 185 | } | 186 | } |
| 186 | } | 187 | } |
| 187 | 188 | ||
