|
74 | 74 | pub type I2cFutureDma<C, I> =
|
75 | 75 | I2cFuture<C, crate::pac::Interrupt, crate::dmac::Channel<I, crate::dmac::ReadyFuture>>;
|
76 | 76 |
|
| 77 | +impl<C, N, S, D> I2cFuture<C, N, D> |
| 78 | +where |
| 79 | + C: AnyConfig<Sercom = S>, |
| 80 | + S: Sercom, |
| 81 | + N: InterruptNumber, |
| 82 | +{ |
| 83 | + async fn wait_flags(&mut self, flags_to_wait: Flags) { |
| 84 | + core::future::poll_fn(|cx| { |
| 85 | + // Scope maybe_pending so we don't forget to re-poll the register later down. |
| 86 | + { |
| 87 | + let maybe_pending = self.i2c.config.as_ref().registers.read_flags(); |
| 88 | + if flags_to_wait.intersects(maybe_pending) { |
| 89 | + return Poll::Ready(()); |
| 90 | + } |
| 91 | + } |
| 92 | + |
| 93 | + self.i2c.disable_interrupts(Flags::all()); |
| 94 | + // By convention, I2C uses the sercom's RX waker. |
| 95 | + S::rx_waker().register(cx.waker()); |
| 96 | + self.i2c.enable_interrupts(flags_to_wait); |
| 97 | + let maybe_pending = self.i2c.config.as_ref().registers.read_flags(); |
| 98 | + |
| 99 | + if !flags_to_wait.intersects(maybe_pending) { |
| 100 | + Poll::Pending |
| 101 | + } else { |
| 102 | + Poll::Ready(()) |
| 103 | + } |
| 104 | + }) |
| 105 | + .await; |
| 106 | + } |
| 107 | +} |
| 108 | + |
77 | 109 | impl<C, N, S> I2cFuture<C, N, NoneT>
|
78 | 110 | where
|
79 | 111 | C: AnyConfig<Sercom = S>,
|
@@ -167,31 +199,6 @@ where
|
167 | 199 | self.wait_flags(Flags::SB | Flags::ERROR).await;
|
168 | 200 | self.i2c.config.as_mut().registers.read_one()
|
169 | 201 | }
|
170 |
| - |
171 |
| - async fn wait_flags(&mut self, flags_to_wait: Flags) { |
172 |
| - core::future::poll_fn(|cx| { |
173 |
| - // Scope maybe_pending so we don't forget to re-poll the register later down. |
174 |
| - { |
175 |
| - let maybe_pending = self.i2c.config.as_ref().registers.read_flags(); |
176 |
| - if flags_to_wait.intersects(maybe_pending) { |
177 |
| - return Poll::Ready(()); |
178 |
| - } |
179 |
| - } |
180 |
| - |
181 |
| - self.i2c.disable_interrupts(Flags::all()); |
182 |
| - // By convention, I2C uses the sercom's RX waker. |
183 |
| - S::rx_waker().register(cx.waker()); |
184 |
| - self.i2c.enable_interrupts(flags_to_wait); |
185 |
| - let maybe_pending = self.i2c.config.as_ref().registers.read_flags(); |
186 |
| - |
187 |
| - if !flags_to_wait.intersects(maybe_pending) { |
188 |
| - Poll::Pending |
189 |
| - } else { |
190 |
| - Poll::Ready(()) |
191 |
| - } |
192 |
| - }) |
193 |
| - .await; |
194 |
| - } |
195 | 202 | }
|
196 | 203 |
|
197 | 204 | // impl<C, N, D> Drop for I2cFuture<C, N, D>
|
@@ -416,6 +423,7 @@ mod dma {
|
416 | 423 | read_buf: &mut [u8],
|
417 | 424 | ) -> Result<(), i2c::Error> {
|
418 | 425 | self.write(addr, write_buf).await?;
|
| 426 | + // TODO may need some sort of delay here?? |
419 | 427 | self.read(addr, read_buf).await?;
|
420 | 428 | Ok(())
|
421 | 429 | }
|
|
0 commit comments