diff options
| author | Mathias <[email protected]> | 2022-09-09 10:36:27 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-09-26 20:34:55 +0200 |
| commit | f2239d34cc26bb147d136d312b8b6af1020d4e0f (patch) | |
| tree | 26a271e379520926e4acb2f14ebf4f4fc103b880 | |
| parent | ee76831f93e792757bf43136be712c343c4d5336 (diff) | |
Add bufferedUart, including a split version for only Rx or Tx
| -rw-r--r-- | embassy-rp/src/uart/buffered.rs | 369 | ||||
| -rw-r--r-- | embassy-rp/src/uart/mod.rs | 2 |
2 files changed, 310 insertions, 61 deletions
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index c31af8018..3eb96e3d5 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs | |||
| @@ -9,31 +9,70 @@ use futures::future::poll_fn; | |||
| 9 | 9 | ||
| 10 | use super::*; | 10 | use super::*; |
| 11 | 11 | ||
| 12 | pub struct State<'d, T: Instance>(StateStorage<StateInner<'d, T>>); | 12 | pub struct State<'d, T: Instance>(StateStorage<FullStateInner<'d, T>>); |
| 13 | impl<'d, T: Instance> State<'d, T> { | 13 | impl<'d, T: Instance> State<'d, T> { |
| 14 | pub fn new() -> Self { | 14 | pub const fn new() -> Self { |
| 15 | Self(StateStorage::new()) | 15 | Self(StateStorage::new()) |
| 16 | } | 16 | } |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | struct StateInner<'d, T: Instance> { | 19 | pub struct RxState<'d, T: Instance>(StateStorage<RxStateInner<'d, T>>); |
| 20 | impl<'d, T: Instance> RxState<'d, T> { | ||
| 21 | pub const fn new() -> Self { | ||
| 22 | Self(StateStorage::new()) | ||
| 23 | } | ||
| 24 | } | ||
| 25 | |||
| 26 | pub struct TxState<'d, T: Instance>(StateStorage<TxStateInner<'d, T>>); | ||
| 27 | impl<'d, T: Instance> TxState<'d, T> { | ||
| 28 | pub const fn new() -> Self { | ||
| 29 | Self(StateStorage::new()) | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | struct RxStateInner<'d, T: Instance> { | ||
| 34 | phantom: PhantomData<&'d mut T>, | ||
| 35 | |||
| 36 | waker: WakerRegistration, | ||
| 37 | buf: RingBuffer<'d>, | ||
| 38 | } | ||
| 39 | |||
| 40 | struct TxStateInner<'d, T: Instance> { | ||
| 20 | phantom: PhantomData<&'d mut T>, | 41 | phantom: PhantomData<&'d mut T>, |
| 21 | 42 | ||
| 22 | rx_waker: WakerRegistration, | 43 | waker: WakerRegistration, |
| 23 | rx: RingBuffer<'d>, | 44 | buf: RingBuffer<'d>, |
| 45 | } | ||
| 24 | 46 | ||
| 25 | tx_waker: WakerRegistration, | 47 | struct FullStateInner<'d, T: Instance> { |
| 26 | tx: RingBuffer<'d>, | 48 | rx: RxStateInner<'d, T>, |
| 49 | tx: TxStateInner<'d, T>, | ||
| 27 | } | 50 | } |
| 28 | 51 | ||
| 29 | unsafe impl<'d, T: Instance> Send for StateInner<'d, T> {} | 52 | unsafe impl<'d, T: Instance> Send for RxStateInner<'d, T> {} |
| 30 | unsafe impl<'d, T: Instance> Sync for StateInner<'d, T> {} | 53 | unsafe impl<'d, T: Instance> Sync for RxStateInner<'d, T> {} |
| 54 | |||
| 55 | unsafe impl<'d, T: Instance> Send for TxStateInner<'d, T> {} | ||
| 56 | unsafe impl<'d, T: Instance> Sync for TxStateInner<'d, T> {} | ||
| 57 | |||
| 58 | unsafe impl<'d, T: Instance> Send for FullStateInner<'d, T> {} | ||
| 59 | unsafe impl<'d, T: Instance> Sync for FullStateInner<'d, T> {} | ||
| 31 | 60 | ||
| 32 | pub struct BufferedUart<'d, T: Instance> { | 61 | pub struct BufferedUart<'d, T: Instance> { |
| 33 | inner: PeripheralMutex<'d, StateInner<'d, T>>, | 62 | inner: PeripheralMutex<'d, FullStateInner<'d, T>>, |
| 63 | } | ||
| 64 | |||
| 65 | pub struct RxBufferedUart<'d, T: Instance> { | ||
| 66 | inner: PeripheralMutex<'d, RxStateInner<'d, T>>, | ||
| 67 | } | ||
| 68 | |||
| 69 | pub struct TxBufferedUart<'d, T: Instance> { | ||
| 70 | inner: PeripheralMutex<'d, TxStateInner<'d, T>>, | ||
| 34 | } | 71 | } |
| 35 | 72 | ||
| 36 | impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {} | 73 | impl<'d, T: Instance> Unpin for BufferedUart<'d, T> {} |
| 74 | impl<'d, T: Instance> Unpin for RxBufferedUart<'d, T> {} | ||
| 75 | impl<'d, T: Instance> Unpin for TxBufferedUart<'d, T> {} | ||
| 37 | 76 | ||
| 38 | impl<'d, T: Instance> BufferedUart<'d, T> { | 77 | impl<'d, T: Instance> BufferedUart<'d, T> { |
| 39 | pub fn new<M: Mode>( | 78 | pub fn new<M: Mode>( |
| @@ -55,66 +94,158 @@ impl<'d, T: Instance> BufferedUart<'d, T> { | |||
| 55 | } | 94 | } |
| 56 | 95 | ||
| 57 | Self { | 96 | Self { |
| 58 | inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner { | 97 | inner: PeripheralMutex::new(irq, &mut state.0, move || FullStateInner { |
| 98 | tx: TxStateInner { | ||
| 99 | phantom: PhantomData, | ||
| 100 | waker: WakerRegistration::new(), | ||
| 101 | buf: RingBuffer::new(tx_buffer), | ||
| 102 | }, | ||
| 103 | rx: RxStateInner { | ||
| 104 | phantom: PhantomData, | ||
| 105 | waker: WakerRegistration::new(), | ||
| 106 | buf: RingBuffer::new(rx_buffer), | ||
| 107 | }, | ||
| 108 | }), | ||
| 109 | } | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | impl<'d, T: Instance> RxBufferedUart<'d, T> { | ||
| 114 | pub fn new<M: Mode>( | ||
| 115 | state: &'d mut RxState<'d, T>, | ||
| 116 | _uart: UartRx<'d, T, M>, | ||
| 117 | irq: impl Peripheral<P = T::Interrupt> + 'd, | ||
| 118 | rx_buffer: &'d mut [u8], | ||
| 119 | ) -> RxBufferedUart<'d, T> { | ||
| 120 | into_ref!(irq); | ||
| 121 | |||
| 122 | let r = T::regs(); | ||
| 123 | unsafe { | ||
| 124 | r.uartimsc().modify(|w| { | ||
| 125 | // TODO: Should and more or fewer interrupts be enabled? | ||
| 126 | w.set_rxim(true); | ||
| 127 | w.set_rtim(true); | ||
| 128 | }); | ||
| 129 | } | ||
| 130 | |||
| 131 | Self { | ||
| 132 | inner: PeripheralMutex::new(irq, &mut state.0, move || RxStateInner { | ||
| 133 | phantom: PhantomData, | ||
| 134 | |||
| 135 | buf: RingBuffer::new(rx_buffer), | ||
| 136 | waker: WakerRegistration::new(), | ||
| 137 | }), | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | impl<'d, T: Instance> TxBufferedUart<'d, T> { | ||
| 143 | pub fn new<M: Mode>( | ||
| 144 | state: &'d mut TxState<'d, T>, | ||
| 145 | _uart: UartTx<'d, T, M>, | ||
| 146 | irq: impl Peripheral<P = T::Interrupt> + 'd, | ||
| 147 | tx_buffer: &'d mut [u8], | ||
| 148 | ) -> TxBufferedUart<'d, T> { | ||
| 149 | into_ref!(irq); | ||
| 150 | |||
| 151 | let r = T::regs(); | ||
| 152 | unsafe { | ||
| 153 | r.uartimsc().modify(|w| { | ||
| 154 | // TODO: Should and more or fewer interrupts be enabled? | ||
| 155 | w.set_rxim(true); | ||
| 156 | w.set_rtim(true); | ||
| 157 | }); | ||
| 158 | } | ||
| 159 | |||
| 160 | Self { | ||
| 161 | inner: PeripheralMutex::new(irq, &mut state.0, move || TxStateInner { | ||
| 59 | phantom: PhantomData, | 162 | phantom: PhantomData, |
| 60 | tx: RingBuffer::new(tx_buffer), | ||
| 61 | tx_waker: WakerRegistration::new(), | ||
| 62 | 163 | ||
| 63 | rx: RingBuffer::new(rx_buffer), | 164 | buf: RingBuffer::new(tx_buffer), |
| 64 | rx_waker: WakerRegistration::new(), | 165 | waker: WakerRegistration::new(), |
| 65 | }), | 166 | }), |
| 66 | } | 167 | } |
| 67 | } | 168 | } |
| 68 | } | 169 | } |
| 69 | 170 | ||
| 70 | impl<'d, T: Instance> StateInner<'d, T> | 171 | impl<'d, T: Instance> PeripheralState for FullStateInner<'d, T> |
| 71 | where | 172 | where |
| 72 | Self: 'd, | 173 | Self: 'd, |
| 73 | { | 174 | { |
| 74 | fn on_rx(&mut self) { | 175 | type Interrupt = T::Interrupt; |
| 176 | fn on_interrupt(&mut self) { | ||
| 177 | self.rx.on_interrupt(); | ||
| 178 | self.tx.on_interrupt(); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | impl<'d, T: Instance> PeripheralState for RxStateInner<'d, T> | ||
| 183 | where | ||
| 184 | Self: 'd, | ||
| 185 | { | ||
| 186 | type Interrupt = T::Interrupt; | ||
| 187 | fn on_interrupt(&mut self) { | ||
| 75 | let r = T::regs(); | 188 | let r = T::regs(); |
| 76 | unsafe { | 189 | unsafe { |
| 77 | let ris = r.uartris().read(); | 190 | let ris = r.uartmis().read(); |
| 78 | // Clear interrupt flags | 191 | // Clear interrupt flags |
| 79 | r.uarticr().write(|w| { | 192 | r.uarticr().modify(|w| { |
| 80 | w.set_rxic(true); | 193 | w.set_rxic(true); |
| 81 | w.set_rtic(true); | 194 | w.set_rtic(true); |
| 82 | }); | 195 | }); |
| 83 | 196 | ||
| 84 | if ris.rxris() { | 197 | if ris.rxmis() { |
| 85 | if ris.peris() { | 198 | if ris.pemis() { |
| 86 | warn!("Parity error"); | 199 | warn!("Parity error"); |
| 200 | r.uarticr().modify(|w| { | ||
| 201 | w.set_peic(true); | ||
| 202 | }); | ||
| 87 | } | 203 | } |
| 88 | if ris.feris() { | 204 | if ris.femis() { |
| 89 | warn!("Framing error"); | 205 | warn!("Framing error"); |
| 206 | r.uarticr().modify(|w| { | ||
| 207 | w.set_feic(true); | ||
| 208 | }); | ||
| 90 | } | 209 | } |
| 91 | if ris.beris() { | 210 | if ris.bemis() { |
| 92 | warn!("Break error"); | 211 | warn!("Break error"); |
| 212 | r.uarticr().modify(|w| { | ||
| 213 | w.set_beic(true); | ||
| 214 | }); | ||
| 93 | } | 215 | } |
| 94 | if ris.oeris() { | 216 | if ris.oemis() { |
| 95 | warn!("Overrun error"); | 217 | warn!("Overrun error"); |
| 218 | r.uarticr().modify(|w| { | ||
| 219 | w.set_oeic(true); | ||
| 220 | }); | ||
| 96 | } | 221 | } |
| 97 | 222 | ||
| 98 | let buf = self.rx.push_buf(); | 223 | let buf = self.buf.push_buf(); |
| 99 | if !buf.is_empty() { | 224 | if !buf.is_empty() { |
| 100 | buf[0] = r.uartdr().read().data(); | 225 | buf[0] = r.uartdr().read().data(); |
| 101 | self.rx.push(1); | 226 | self.buf.push(1); |
| 102 | } else { | 227 | } else { |
| 103 | warn!("RX buffer full, discard received byte"); | 228 | warn!("RX buffer full, discard received byte"); |
| 104 | } | 229 | } |
| 105 | 230 | ||
| 106 | if self.rx.is_full() { | 231 | if self.buf.is_full() { |
| 107 | self.rx_waker.wake(); | 232 | self.waker.wake(); |
| 108 | } | 233 | } |
| 109 | } | 234 | } |
| 110 | 235 | ||
| 111 | if ris.rtris() { | 236 | if ris.rtmis() { |
| 112 | self.rx_waker.wake(); | 237 | self.waker.wake(); |
| 113 | }; | 238 | }; |
| 114 | } | 239 | } |
| 115 | } | 240 | } |
| 241 | } | ||
| 116 | 242 | ||
| 117 | fn on_tx(&mut self) { | 243 | impl<'d, T: Instance> PeripheralState for TxStateInner<'d, T> |
| 244 | where | ||
| 245 | Self: 'd, | ||
| 246 | { | ||
| 247 | type Interrupt = T::Interrupt; | ||
| 248 | fn on_interrupt(&mut self) { | ||
| 118 | let r = T::regs(); | 249 | let r = T::regs(); |
| 119 | unsafe { | 250 | unsafe { |
| 120 | let ris = r.uartris().read(); | 251 | let ris = r.uartris().read(); |
| @@ -124,14 +255,14 @@ where | |||
| 124 | }); | 255 | }); |
| 125 | 256 | ||
| 126 | if ris.txris() { | 257 | if ris.txris() { |
| 127 | let buf = self.tx.pop_buf(); | 258 | let buf = self.buf.pop_buf(); |
| 128 | if !buf.is_empty() { | 259 | if !buf.is_empty() { |
| 129 | r.uartimsc().modify(|w| { | 260 | r.uartimsc().modify(|w| { |
| 130 | w.set_txim(true); | 261 | w.set_txim(true); |
| 131 | }); | 262 | }); |
| 132 | r.uartdr().write(|w| w.set_data(buf[0].into())); | 263 | r.uartdr().write(|w| w.set_data(buf[0].into())); |
| 133 | self.tx.pop(1); | 264 | self.buf.pop(1); |
| 134 | self.tx_waker.wake(); | 265 | self.waker.wake(); |
| 135 | } else { | 266 | } else { |
| 136 | // Disable interrupt until we have something to transmit again | 267 | // Disable interrupt until we have something to transmit again |
| 137 | r.uartimsc().modify(|w| { | 268 | r.uartimsc().modify(|w| { |
| @@ -143,17 +274,6 @@ where | |||
| 143 | } | 274 | } |
| 144 | } | 275 | } |
| 145 | 276 | ||
| 146 | impl<'d, T: Instance> PeripheralState for StateInner<'d, T> | ||
| 147 | where | ||
| 148 | Self: 'd, | ||
| 149 | { | ||
| 150 | type Interrupt = T::Interrupt; | ||
| 151 | fn on_interrupt(&mut self) { | ||
| 152 | self.on_rx(); | ||
| 153 | self.on_tx(); | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | impl embedded_io::Error for Error { | 277 | impl embedded_io::Error for Error { |
| 158 | fn kind(&self) -> embedded_io::ErrorKind { | 278 | fn kind(&self) -> embedded_io::ErrorKind { |
| 159 | embedded_io::ErrorKind::Other | 279 | embedded_io::ErrorKind::Other |
| @@ -164,8 +284,54 @@ impl<'d, T: Instance> embedded_io::Io for BufferedUart<'d, T> { | |||
| 164 | type Error = Error; | 284 | type Error = Error; |
| 165 | } | 285 | } |
| 166 | 286 | ||
| 287 | impl<'d, T: Instance> embedded_io::Io for RxBufferedUart<'d, T> { | ||
| 288 | type Error = Error; | ||
| 289 | } | ||
| 290 | |||
| 291 | impl<'d, T: Instance> embedded_io::Io for TxBufferedUart<'d, T> { | ||
| 292 | type Error = Error; | ||
| 293 | } | ||
| 294 | |||
| 167 | impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> { | 295 | impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> { |
| 168 | type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> | 296 | type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> |
| 297 | where | ||
| 298 | Self: 'a; | ||
| 299 | |||
| 300 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { | ||
| 301 | poll_fn(move |cx| { | ||
| 302 | let mut do_pend = false; | ||
| 303 | let res = self.inner.with(|state| { | ||
| 304 | compiler_fence(Ordering::SeqCst); | ||
| 305 | |||
| 306 | // We have data ready in buffer? Return it. | ||
| 307 | let data = state.rx.buf.pop_buf(); | ||
| 308 | if !data.is_empty() { | ||
| 309 | let len = data.len().min(buf.len()); | ||
| 310 | buf[..len].copy_from_slice(&data[..len]); | ||
| 311 | |||
| 312 | if state.rx.buf.is_full() { | ||
| 313 | do_pend = true; | ||
| 314 | } | ||
| 315 | state.rx.buf.pop(len); | ||
| 316 | |||
| 317 | return Poll::Ready(Ok(len)); | ||
| 318 | } | ||
| 319 | |||
| 320 | state.rx.waker.register(cx.waker()); | ||
| 321 | Poll::Pending | ||
| 322 | }); | ||
| 323 | |||
| 324 | if do_pend { | ||
| 325 | self.inner.pend(); | ||
| 326 | } | ||
| 327 | |||
| 328 | res | ||
| 329 | }) | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | impl<'d, T: Instance + 'd> embedded_io::asynch::Read for RxBufferedUart<'d, T> { | ||
| 334 | type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> | ||
| 169 | where | 335 | where |
| 170 | Self: 'a; | 336 | Self: 'a; |
| 171 | 337 | ||
| @@ -176,20 +342,20 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> { | |||
| 176 | compiler_fence(Ordering::SeqCst); | 342 | compiler_fence(Ordering::SeqCst); |
| 177 | 343 | ||
| 178 | // We have data ready in buffer? Return it. | 344 | // We have data ready in buffer? Return it. |
| 179 | let data = state.rx.pop_buf(); | 345 | let data = state.buf.pop_buf(); |
| 180 | if !data.is_empty() { | 346 | if !data.is_empty() { |
| 181 | let len = data.len().min(buf.len()); | 347 | let len = data.len().min(buf.len()); |
| 182 | buf[..len].copy_from_slice(&data[..len]); | 348 | buf[..len].copy_from_slice(&data[..len]); |
| 183 | 349 | ||
| 184 | if state.rx.is_full() { | 350 | if state.buf.is_full() { |
| 185 | do_pend = true; | 351 | do_pend = true; |
| 186 | } | 352 | } |
| 187 | state.rx.pop(len); | 353 | state.buf.pop(len); |
| 188 | 354 | ||
| 189 | return Poll::Ready(Ok(len)); | 355 | return Poll::Ready(Ok(len)); |
| 190 | } | 356 | } |
| 191 | 357 | ||
| 192 | state.rx_waker.register(cx.waker()); | 358 | state.waker.register(cx.waker()); |
| 193 | Poll::Pending | 359 | Poll::Pending |
| 194 | }); | 360 | }); |
| 195 | 361 | ||
| @@ -213,7 +379,44 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T> | |||
| 213 | compiler_fence(Ordering::SeqCst); | 379 | compiler_fence(Ordering::SeqCst); |
| 214 | 380 | ||
| 215 | // We have data ready in buffer? Return it. | 381 | // We have data ready in buffer? Return it. |
| 216 | let buf = state.rx.pop_buf(); | 382 | let buf = state.rx.buf.pop_buf(); |
| 383 | if !buf.is_empty() { | ||
| 384 | let buf: &[u8] = buf; | ||
| 385 | // Safety: buffer lives as long as uart | ||
| 386 | let buf: &[u8] = unsafe { core::mem::transmute(buf) }; | ||
| 387 | return Poll::Ready(Ok(buf)); | ||
| 388 | } | ||
| 389 | |||
| 390 | state.rx.waker.register(cx.waker()); | ||
| 391 | Poll::<Result<&[u8], Self::Error>>::Pending | ||
| 392 | }) | ||
| 393 | }) | ||
| 394 | } | ||
| 395 | |||
| 396 | fn consume(&mut self, amt: usize) { | ||
| 397 | let signal = self.inner.with(|state| { | ||
| 398 | let full = state.rx.buf.is_full(); | ||
| 399 | state.rx.buf.pop(amt); | ||
| 400 | full | ||
| 401 | }); | ||
| 402 | if signal { | ||
| 403 | self.inner.pend(); | ||
| 404 | } | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for RxBufferedUart<'d, T> { | ||
| 409 | type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> | ||
| 410 | where | ||
| 411 | Self: 'a; | ||
| 412 | |||
| 413 | fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> { | ||
| 414 | poll_fn(move |cx| { | ||
| 415 | self.inner.with(|state| { | ||
| 416 | compiler_fence(Ordering::SeqCst); | ||
| 417 | |||
| 418 | // We have data ready in buffer? Return it. | ||
| 419 | let buf = state.buf.pop_buf(); | ||
| 217 | if !buf.is_empty() { | 420 | if !buf.is_empty() { |
| 218 | let buf: &[u8] = buf; | 421 | let buf: &[u8] = buf; |
| 219 | // Safety: buffer lives as long as uart | 422 | // Safety: buffer lives as long as uart |
| @@ -221,7 +424,7 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T> | |||
| 221 | return Poll::Ready(Ok(buf)); | 424 | return Poll::Ready(Ok(buf)); |
| 222 | } | 425 | } |
| 223 | 426 | ||
| 224 | state.rx_waker.register(cx.waker()); | 427 | state.waker.register(cx.waker()); |
| 225 | Poll::<Result<&[u8], Self::Error>>::Pending | 428 | Poll::<Result<&[u8], Self::Error>>::Pending |
| 226 | }) | 429 | }) |
| 227 | }) | 430 | }) |
| @@ -229,8 +432,8 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T> | |||
| 229 | 432 | ||
| 230 | fn consume(&mut self, amt: usize) { | 433 | fn consume(&mut self, amt: usize) { |
| 231 | let signal = self.inner.with(|state| { | 434 | let signal = self.inner.with(|state| { |
| 232 | let full = state.rx.is_full(); | 435 | let full = state.buf.is_full(); |
| 233 | state.rx.pop(amt); | 436 | state.buf.pop(amt); |
| 234 | full | 437 | full |
| 235 | }); | 438 | }); |
| 236 | if signal { | 439 | if signal { |
| @@ -247,16 +450,62 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> { | |||
| 247 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | 450 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { |
| 248 | poll_fn(move |cx| { | 451 | poll_fn(move |cx| { |
| 249 | let (poll, empty) = self.inner.with(|state| { | 452 | let (poll, empty) = self.inner.with(|state| { |
| 250 | let empty = state.tx.is_empty(); | 453 | let empty = state.tx.buf.is_empty(); |
| 251 | let tx_buf = state.tx.push_buf(); | 454 | let tx_buf = state.tx.buf.push_buf(); |
| 455 | if tx_buf.is_empty() { | ||
| 456 | state.tx.waker.register(cx.waker()); | ||
| 457 | return (Poll::Pending, empty); | ||
| 458 | } | ||
| 459 | |||
| 460 | let n = core::cmp::min(tx_buf.len(), buf.len()); | ||
| 461 | tx_buf[..n].copy_from_slice(&buf[..n]); | ||
| 462 | state.tx.buf.push(n); | ||
| 463 | |||
| 464 | (Poll::Ready(Ok(n)), empty) | ||
| 465 | }); | ||
| 466 | if empty { | ||
| 467 | self.inner.pend(); | ||
| 468 | } | ||
| 469 | poll | ||
| 470 | }) | ||
| 471 | } | ||
| 472 | |||
| 473 | type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> | ||
| 474 | where | ||
| 475 | Self: 'a; | ||
| 476 | |||
| 477 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | ||
| 478 | poll_fn(move |cx| { | ||
| 479 | self.inner.with(|state| { | ||
| 480 | if !state.tx.buf.is_empty() { | ||
| 481 | state.tx.waker.register(cx.waker()); | ||
| 482 | return Poll::Pending; | ||
| 483 | } | ||
| 484 | |||
| 485 | Poll::Ready(Ok(())) | ||
| 486 | }) | ||
| 487 | }) | ||
| 488 | } | ||
| 489 | } | ||
| 490 | |||
| 491 | impl<'d, T: Instance + 'd> embedded_io::asynch::Write for TxBufferedUart<'d, T> { | ||
| 492 | type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> | ||
| 493 | where | ||
| 494 | Self: 'a; | ||
| 495 | |||
| 496 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | ||
| 497 | poll_fn(move |cx| { | ||
| 498 | let (poll, empty) = self.inner.with(|state| { | ||
| 499 | let empty = state.buf.is_empty(); | ||
| 500 | let tx_buf = state.buf.push_buf(); | ||
| 252 | if tx_buf.is_empty() { | 501 | if tx_buf.is_empty() { |
| 253 | state.tx_waker.register(cx.waker()); | 502 | state.waker.register(cx.waker()); |
| 254 | return (Poll::Pending, empty); | 503 | return (Poll::Pending, empty); |
| 255 | } | 504 | } |
| 256 | 505 | ||
| 257 | let n = core::cmp::min(tx_buf.len(), buf.len()); | 506 | let n = core::cmp::min(tx_buf.len(), buf.len()); |
| 258 | tx_buf[..n].copy_from_slice(&buf[..n]); | 507 | tx_buf[..n].copy_from_slice(&buf[..n]); |
| 259 | state.tx.push(n); | 508 | state.buf.push(n); |
| 260 | 509 | ||
| 261 | (Poll::Ready(Ok(n)), empty) | 510 | (Poll::Ready(Ok(n)), empty) |
| 262 | }); | 511 | }); |
| @@ -274,8 +523,8 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> { | |||
| 274 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | 523 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { |
| 275 | poll_fn(move |cx| { | 524 | poll_fn(move |cx| { |
| 276 | self.inner.with(|state| { | 525 | self.inner.with(|state| { |
| 277 | if !state.tx.is_empty() { | 526 | if !state.buf.is_empty() { |
| 278 | state.tx_waker.register(cx.waker()); | 527 | state.waker.register(cx.waker()); |
| 279 | return Poll::Pending; | 528 | return Poll::Pending; |
| 280 | } | 529 | } |
| 281 | 530 | ||
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index 3b71d87be..67e24b605 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs | |||
| @@ -343,7 +343,7 @@ impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { | |||
| 343 | w.set_stp2(config.stop_bits == StopBits::STOP2); | 343 | w.set_stp2(config.stop_bits == StopBits::STOP2); |
| 344 | w.set_pen(pen); | 344 | w.set_pen(pen); |
| 345 | w.set_eps(eps); | 345 | w.set_eps(eps); |
| 346 | w.set_fen(true); | 346 | w.set_fen(false); |
| 347 | }); | 347 | }); |
| 348 | 348 | ||
| 349 | r.uartcr().write(|w| { | 349 | r.uartcr().write(|w| { |
