diff options
| author | Marc <[email protected]> | 2025-05-02 12:17:35 +0200 |
|---|---|---|
| committer | Marc <[email protected]> | 2025-05-02 12:17:35 +0200 |
| commit | 2fd803f7c336dd6aa042c34e11e213e6e4eb13ad (patch) | |
| tree | 6e28c11ed9b77d5b08df968b906e3b5518fa1d11 | |
| parent | 9ab6100577eab3a23ac0c47fd74dc7a696d94837 (diff) | |
Removed instance from uart types
| -rw-r--r-- | embassy-rp/src/uart/buffered.rs | 306 | ||||
| -rw-r--r-- | embassy-rp/src/uart/mod.rs | 291 |
2 files changed, 324 insertions, 273 deletions
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index da18138b5..44b6ee469 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs | |||
| @@ -34,28 +34,31 @@ impl State { | |||
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | /// Buffered UART driver. | 36 | /// Buffered UART driver. |
| 37 | pub struct BufferedUart<'d, T: Instance> { | 37 | pub struct BufferedUart { |
| 38 | pub(crate) rx: BufferedUartRx<'d, T>, | 38 | pub(super) rx: BufferedUartRx, |
| 39 | pub(crate) tx: BufferedUartTx<'d, T>, | 39 | pub(super) tx: BufferedUartTx, |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | /// Buffered UART RX handle. | 42 | /// Buffered UART RX handle. |
| 43 | pub struct BufferedUartRx<'d, T: Instance> { | 43 | pub struct BufferedUartRx { |
| 44 | pub(crate) phantom: PhantomData<&'d mut T>, | 44 | pub(super) info: &'static Info, |
| 45 | pub(super) state: &'static State, | ||
| 46 | // pub(crate) phantom: PhantomData<&'d mut T>, | ||
| 45 | } | 47 | } |
| 46 | 48 | ||
| 47 | /// Buffered UART TX handle. | 49 | /// Buffered UART TX handle. |
| 48 | pub struct BufferedUartTx<'d, T: Instance> { | 50 | pub struct BufferedUartTx { |
| 49 | pub(crate) phantom: PhantomData<&'d mut T>, | 51 | pub(super) info: &'static Info, |
| 52 | pub(super) state: &'static State, | ||
| 53 | // pub(crate) phantom: PhantomData<&'d mut T>, | ||
| 50 | } | 54 | } |
| 51 | 55 | ||
| 52 | pub(crate) fn init_buffers<'d, T: Instance + 'd>( | 56 | pub(super) fn init_buffers<'d>( |
| 53 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 57 | info: &Info, |
| 58 | state: &State, | ||
| 54 | tx_buffer: Option<&'d mut [u8]>, | 59 | tx_buffer: Option<&'d mut [u8]>, |
| 55 | rx_buffer: Option<&'d mut [u8]>, | 60 | rx_buffer: Option<&'d mut [u8]>, |
| 56 | ) { | 61 | ) { |
| 57 | let state = T::buffered_state(); | ||
| 58 | |||
| 59 | if let Some(tx_buffer) = tx_buffer { | 62 | if let Some(tx_buffer) = tx_buffer { |
| 60 | let len = tx_buffer.len(); | 63 | let len = tx_buffer.len(); |
| 61 | unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | 64 | unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; |
| @@ -76,61 +79,73 @@ pub(crate) fn init_buffers<'d, T: Instance + 'd>( | |||
| 76 | // This means we can leave the interrupt enabled the whole time as long as | 79 | // This means we can leave the interrupt enabled the whole time as long as |
| 77 | // we clear it after it happens. The downside is that the we manually have | 80 | // we clear it after it happens. The downside is that the we manually have |
| 78 | // to pend the ISR when we want data transmission to start. | 81 | // to pend the ISR when we want data transmission to start. |
| 79 | let regs = T::regs(); | 82 | info.regs.uartimsc().write(|w| { |
| 80 | regs.uartimsc().write(|w| { | ||
| 81 | w.set_rxim(true); | 83 | w.set_rxim(true); |
| 82 | w.set_rtim(true); | 84 | w.set_rtim(true); |
| 83 | w.set_txim(true); | 85 | w.set_txim(true); |
| 84 | }); | 86 | }); |
| 85 | 87 | ||
| 86 | T::Interrupt::unpend(); | 88 | info.interrupt.unpend(); |
| 87 | unsafe { T::Interrupt::enable() }; | 89 | unsafe { info.interrupt.enable() }; |
| 88 | } | 90 | } |
| 89 | 91 | ||
| 90 | impl<'d, T: Instance> BufferedUart<'d, T> { | 92 | impl BufferedUart { |
| 91 | /// Create a buffered UART instance. | 93 | /// Create a buffered UART instance. |
| 92 | pub fn new( | 94 | pub fn new<'d, T: Instance>( |
| 93 | _uart: Peri<'d, T>, | 95 | _uart: Peri<'d, T>, |
| 94 | tx: Peri<'d, impl TxPin<T>>, | 96 | tx: Peri<'d, impl TxPin<T>>, |
| 95 | rx: Peri<'d, impl RxPin<T>>, | 97 | rx: Peri<'d, impl RxPin<T>>, |
| 96 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 98 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| 97 | tx_buffer: &'d mut [u8], | 99 | tx_buffer: &'d mut [u8], |
| 98 | rx_buffer: &'d mut [u8], | 100 | rx_buffer: &'d mut [u8], |
| 99 | config: Config, | 101 | config: Config, |
| 100 | ) -> Self { | 102 | ) -> Self { |
| 101 | super::Uart::<'d, T, Async>::init(Some(tx.into()), Some(rx.into()), None, None, config); | 103 | super::Uart::<'d, Async>::init(T::info(), Some(tx.into()), Some(rx.into()), None, None, config); |
| 102 | init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); | 104 | init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), Some(rx_buffer)); |
| 103 | 105 | ||
| 104 | Self { | 106 | Self { |
| 105 | rx: BufferedUartRx { phantom: PhantomData }, | 107 | rx: BufferedUartRx { |
| 106 | tx: BufferedUartTx { phantom: PhantomData }, | 108 | info: T::info(), |
| 109 | state: T::buffered_state(), | ||
| 110 | }, | ||
| 111 | tx: BufferedUartTx { | ||
| 112 | info: T::info(), | ||
| 113 | state: T::buffered_state(), | ||
| 114 | }, | ||
| 107 | } | 115 | } |
| 108 | } | 116 | } |
| 109 | 117 | ||
| 110 | /// Create a buffered UART instance with flow control. | 118 | /// Create a buffered UART instance with flow control. |
| 111 | pub fn new_with_rtscts( | 119 | pub fn new_with_rtscts<'d, T: Instance>( |
| 112 | _uart: Peri<'d, T>, | 120 | _uart: Peri<'d, T>, |
| 113 | tx: Peri<'d, impl TxPin<T>>, | 121 | tx: Peri<'d, impl TxPin<T>>, |
| 114 | rx: Peri<'d, impl RxPin<T>>, | 122 | rx: Peri<'d, impl RxPin<T>>, |
| 115 | rts: Peri<'d, impl RtsPin<T>>, | 123 | rts: Peri<'d, impl RtsPin<T>>, |
| 116 | cts: Peri<'d, impl CtsPin<T>>, | 124 | cts: Peri<'d, impl CtsPin<T>>, |
| 117 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 125 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| 118 | tx_buffer: &'d mut [u8], | 126 | tx_buffer: &'d mut [u8], |
| 119 | rx_buffer: &'d mut [u8], | 127 | rx_buffer: &'d mut [u8], |
| 120 | config: Config, | 128 | config: Config, |
| 121 | ) -> Self { | 129 | ) -> Self { |
| 122 | super::Uart::<'d, T, Async>::init( | 130 | super::Uart::<'d, Async>::init( |
| 131 | T::info(), | ||
| 123 | Some(tx.into()), | 132 | Some(tx.into()), |
| 124 | Some(rx.into()), | 133 | Some(rx.into()), |
| 125 | Some(rts.into()), | 134 | Some(rts.into()), |
| 126 | Some(cts.into()), | 135 | Some(cts.into()), |
| 127 | config, | 136 | config, |
| 128 | ); | 137 | ); |
| 129 | init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); | 138 | init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), Some(rx_buffer)); |
| 130 | 139 | ||
| 131 | Self { | 140 | Self { |
| 132 | rx: BufferedUartRx { phantom: PhantomData }, | 141 | rx: BufferedUartRx { |
| 133 | tx: BufferedUartTx { phantom: PhantomData }, | 142 | info: T::info(), |
| 143 | state: T::buffered_state(), | ||
| 144 | }, | ||
| 145 | tx: BufferedUartTx { | ||
| 146 | info: T::info(), | ||
| 147 | state: T::buffered_state(), | ||
| 148 | }, | ||
| 134 | } | 149 | } |
| 135 | } | 150 | } |
| 136 | 151 | ||
| @@ -160,68 +175,75 @@ impl<'d, T: Instance> BufferedUart<'d, T> { | |||
| 160 | } | 175 | } |
| 161 | 176 | ||
| 162 | /// sets baudrate on runtime | 177 | /// sets baudrate on runtime |
| 163 | pub fn set_baudrate(&mut self, baudrate: u32) { | 178 | pub fn set_baudrate<'d>(&mut self, baudrate: u32) { |
| 164 | super::Uart::<'d, T, Async>::set_baudrate_inner(baudrate); | 179 | super::Uart::<'d, Async>::set_baudrate_inner(self.rx.info, baudrate); |
| 165 | } | 180 | } |
| 166 | 181 | ||
| 167 | /// Split into separate RX and TX handles. | 182 | /// Split into separate RX and TX handles. |
| 168 | pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) { | 183 | pub fn split(self) -> (BufferedUartTx, BufferedUartRx) { |
| 169 | (self.tx, self.rx) | 184 | (self.tx, self.rx) |
| 170 | } | 185 | } |
| 171 | 186 | ||
| 172 | /// Split the Uart into a transmitter and receiver by mutable reference, | 187 | /// Split the Uart into a transmitter and receiver by mutable reference, |
| 173 | /// which is particularly useful when having two tasks correlating to | 188 | /// which is particularly useful when having two tasks correlating to |
| 174 | /// transmitting and receiving. | 189 | /// transmitting and receiving. |
| 175 | pub fn split_ref(&mut self) -> (&mut BufferedUartTx<'d, T>, &mut BufferedUartRx<'d, T>) { | 190 | pub fn split_ref(&mut self) -> (&mut BufferedUartTx, &mut BufferedUartRx) { |
| 176 | (&mut self.tx, &mut self.rx) | 191 | (&mut self.tx, &mut self.rx) |
| 177 | } | 192 | } |
| 178 | } | 193 | } |
| 179 | 194 | ||
| 180 | impl<'d, T: Instance> BufferedUartRx<'d, T> { | 195 | impl BufferedUartRx { |
| 181 | /// Create a new buffered UART RX. | 196 | /// Create a new buffered UART RX. |
| 182 | pub fn new( | 197 | pub fn new<'d, T: Instance>( |
| 183 | _uart: Peri<'d, T>, | 198 | _uart: Peri<'d, T>, |
| 184 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 199 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| 185 | rx: Peri<'d, impl RxPin<T>>, | 200 | rx: Peri<'d, impl RxPin<T>>, |
| 186 | rx_buffer: &'d mut [u8], | 201 | rx_buffer: &'d mut [u8], |
| 187 | config: Config, | 202 | config: Config, |
| 188 | ) -> Self { | 203 | ) -> Self { |
| 189 | super::Uart::<'d, T, Async>::init(None, Some(rx.into()), None, None, config); | 204 | super::Uart::<'d, Async>::init(T::info(), None, Some(rx.into()), None, None, config); |
| 190 | init_buffers::<T>(irq, None, Some(rx_buffer)); | 205 | init_buffers(T::info(), T::buffered_state(), None, Some(rx_buffer)); |
| 191 | 206 | ||
| 192 | Self { phantom: PhantomData } | 207 | Self { |
| 208 | info: T::info(), | ||
| 209 | state: T::buffered_state(), | ||
| 210 | } | ||
| 193 | } | 211 | } |
| 194 | 212 | ||
| 195 | /// Create a new buffered UART RX with flow control. | 213 | /// Create a new buffered UART RX with flow control. |
| 196 | pub fn new_with_rts( | 214 | pub fn new_with_rts<'d, T: Instance>( |
| 197 | _uart: Peri<'d, T>, | 215 | _uart: Peri<'d, T>, |
| 198 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 216 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| 199 | rx: Peri<'d, impl RxPin<T>>, | 217 | rx: Peri<'d, impl RxPin<T>>, |
| 200 | rts: Peri<'d, impl RtsPin<T>>, | 218 | rts: Peri<'d, impl RtsPin<T>>, |
| 201 | rx_buffer: &'d mut [u8], | 219 | rx_buffer: &'d mut [u8], |
| 202 | config: Config, | 220 | config: Config, |
| 203 | ) -> Self { | 221 | ) -> Self { |
| 204 | super::Uart::<'d, T, Async>::init(None, Some(rx.into()), Some(rts.into()), None, config); | 222 | super::Uart::<'d, Async>::init(T::info(), None, Some(rx.into()), Some(rts.into()), None, config); |
| 205 | init_buffers::<T>(irq, None, Some(rx_buffer)); | 223 | init_buffers(T::info(), T::buffered_state(), None, Some(rx_buffer)); |
| 206 | 224 | ||
| 207 | Self { phantom: PhantomData } | 225 | Self { |
| 226 | info: T::info(), | ||
| 227 | state: T::buffered_state(), | ||
| 228 | } | ||
| 208 | } | 229 | } |
| 209 | 230 | ||
| 210 | fn read<'a>(buf: &'a mut [u8]) -> impl Future<Output = Result<usize, Error>> + 'a | 231 | fn read<'a>( |
| 211 | where | 232 | info: &'static Info, |
| 212 | T: 'd, | 233 | state: &'static State, |
| 213 | { | 234 | buf: &'a mut [u8], |
| 235 | ) -> impl Future<Output = Result<usize, Error>> + 'a { | ||
| 214 | poll_fn(move |cx| { | 236 | poll_fn(move |cx| { |
| 215 | if let Poll::Ready(r) = Self::try_read(buf) { | 237 | if let Poll::Ready(r) = Self::try_read(info, state, buf) { |
| 216 | return Poll::Ready(r); | 238 | return Poll::Ready(r); |
| 217 | } | 239 | } |
| 218 | T::buffered_state().rx_waker.register(cx.waker()); | 240 | state.rx_waker.register(cx.waker()); |
| 219 | Poll::Pending | 241 | Poll::Pending |
| 220 | }) | 242 | }) |
| 221 | } | 243 | } |
| 222 | 244 | ||
| 223 | fn get_rx_error() -> Option<Error> { | 245 | fn get_rx_error(state: &State) -> Option<Error> { |
| 224 | let errs = T::buffered_state().rx_error.swap(0, Ordering::Relaxed); | 246 | let errs = state.rx_error.swap(0, Ordering::Relaxed); |
| 225 | if errs & RXE_OVERRUN != 0 { | 247 | if errs & RXE_OVERRUN != 0 { |
| 226 | Some(Error::Overrun) | 248 | Some(Error::Overrun) |
| 227 | } else if errs & RXE_BREAK != 0 { | 249 | } else if errs & RXE_BREAK != 0 { |
| @@ -235,15 +257,11 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { | |||
| 235 | } | 257 | } |
| 236 | } | 258 | } |
| 237 | 259 | ||
| 238 | fn try_read(buf: &mut [u8]) -> Poll<Result<usize, Error>> | 260 | fn try_read(info: &Info, state: &State, buf: &mut [u8]) -> Poll<Result<usize, Error>> { |
| 239 | where | ||
| 240 | T: 'd, | ||
| 241 | { | ||
| 242 | if buf.is_empty() { | 261 | if buf.is_empty() { |
| 243 | return Poll::Ready(Ok(0)); | 262 | return Poll::Ready(Ok(0)); |
| 244 | } | 263 | } |
| 245 | 264 | ||
| 246 | let state = T::buffered_state(); | ||
| 247 | let mut rx_reader = unsafe { state.rx_buf.reader() }; | 265 | let mut rx_reader = unsafe { state.rx_buf.reader() }; |
| 248 | let n = rx_reader.pop(|data| { | 266 | let n = rx_reader.pop(|data| { |
| 249 | let n = data.len().min(buf.len()); | 267 | let n = data.len().min(buf.len()); |
| @@ -252,7 +270,7 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { | |||
| 252 | }); | 270 | }); |
| 253 | 271 | ||
| 254 | let result = if n == 0 { | 272 | let result = if n == 0 { |
| 255 | match Self::get_rx_error() { | 273 | match Self::get_rx_error(state) { |
| 256 | None => return Poll::Pending, | 274 | None => return Poll::Pending, |
| 257 | Some(e) => Err(e), | 275 | Some(e) => Err(e), |
| 258 | } | 276 | } |
| @@ -262,8 +280,7 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { | |||
| 262 | 280 | ||
| 263 | // (Re-)Enable the interrupt to receive more data in case it was | 281 | // (Re-)Enable the interrupt to receive more data in case it was |
| 264 | // disabled because the buffer was full or errors were detected. | 282 | // disabled because the buffer was full or errors were detected. |
| 265 | let regs = T::regs(); | 283 | info.regs.uartimsc().write_set(|w| { |
| 266 | regs.uartimsc().write_set(|w| { | ||
| 267 | w.set_rxim(true); | 284 | w.set_rxim(true); |
| 268 | w.set_rtim(true); | 285 | w.set_rtim(true); |
| 269 | }); | 286 | }); |
| @@ -274,23 +291,19 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { | |||
| 274 | /// Read from UART RX buffer blocking execution until done. | 291 | /// Read from UART RX buffer blocking execution until done. |
| 275 | pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 292 | pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { |
| 276 | loop { | 293 | loop { |
| 277 | match Self::try_read(buf) { | 294 | match Self::try_read(self.info, self.state, buf) { |
| 278 | Poll::Ready(res) => return res, | 295 | Poll::Ready(res) => return res, |
| 279 | Poll::Pending => continue, | 296 | Poll::Pending => continue, |
| 280 | } | 297 | } |
| 281 | } | 298 | } |
| 282 | } | 299 | } |
| 283 | 300 | ||
| 284 | fn fill_buf<'a>() -> impl Future<Output = Result<&'a [u8], Error>> | 301 | fn fill_buf<'a>(state: &'static State) -> impl Future<Output = Result<&'a [u8], Error>> { |
| 285 | where | ||
| 286 | T: 'd, | ||
| 287 | { | ||
| 288 | poll_fn(move |cx| { | 302 | poll_fn(move |cx| { |
| 289 | let state = T::buffered_state(); | ||
| 290 | let mut rx_reader = unsafe { state.rx_buf.reader() }; | 303 | let mut rx_reader = unsafe { state.rx_buf.reader() }; |
| 291 | let (p, n) = rx_reader.pop_buf(); | 304 | let (p, n) = rx_reader.pop_buf(); |
| 292 | let result = if n == 0 { | 305 | let result = if n == 0 { |
| 293 | match Self::get_rx_error() { | 306 | match Self::get_rx_error(state) { |
| 294 | None => { | 307 | None => { |
| 295 | state.rx_waker.register(cx.waker()); | 308 | state.rx_waker.register(cx.waker()); |
| 296 | return Poll::Pending; | 309 | return Poll::Pending; |
| @@ -306,64 +319,70 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> { | |||
| 306 | }) | 319 | }) |
| 307 | } | 320 | } |
| 308 | 321 | ||
| 309 | fn consume(amt: usize) { | 322 | fn consume(info: &Info, state: &State, amt: usize) { |
| 310 | let state = T::buffered_state(); | ||
| 311 | let mut rx_reader = unsafe { state.rx_buf.reader() }; | 323 | let mut rx_reader = unsafe { state.rx_buf.reader() }; |
| 312 | rx_reader.pop_done(amt); | 324 | rx_reader.pop_done(amt); |
| 313 | 325 | ||
| 314 | // (Re-)Enable the interrupt to receive more data in case it was | 326 | // (Re-)Enable the interrupt to receive more data in case it was |
| 315 | // disabled because the buffer was full or errors were detected. | 327 | // disabled because the buffer was full or errors were detected. |
| 316 | let regs = T::regs(); | 328 | info.regs.uartimsc().write_set(|w| { |
| 317 | regs.uartimsc().write_set(|w| { | ||
| 318 | w.set_rxim(true); | 329 | w.set_rxim(true); |
| 319 | w.set_rtim(true); | 330 | w.set_rtim(true); |
| 320 | }); | 331 | }); |
| 321 | } | 332 | } |
| 322 | 333 | ||
| 323 | /// we are ready to read if there is data in the buffer | 334 | /// we are ready to read if there is data in the buffer |
| 324 | fn read_ready() -> Result<bool, Error> { | 335 | fn read_ready(state: &State) -> Result<bool, Error> { |
| 325 | let state = T::buffered_state(); | ||
| 326 | Ok(!state.rx_buf.is_empty()) | 336 | Ok(!state.rx_buf.is_empty()) |
| 327 | } | 337 | } |
| 328 | } | 338 | } |
| 329 | 339 | ||
| 330 | impl<'d, T: Instance> BufferedUartTx<'d, T> { | 340 | impl BufferedUartTx { |
| 331 | /// Create a new buffered UART TX. | 341 | /// Create a new buffered UART TX. |
| 332 | pub fn new( | 342 | pub fn new<'d, T: Instance>( |
| 333 | _uart: Peri<'d, T>, | 343 | _uart: Peri<'d, T>, |
| 334 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 344 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| 335 | tx: Peri<'d, impl TxPin<T>>, | 345 | tx: Peri<'d, impl TxPin<T>>, |
| 336 | tx_buffer: &'d mut [u8], | 346 | tx_buffer: &'d mut [u8], |
| 337 | config: Config, | 347 | config: Config, |
| 338 | ) -> Self { | 348 | ) -> Self { |
| 339 | super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, None, config); | 349 | super::Uart::<'d, Async>::init(T::info(), Some(tx.into()), None, None, None, config); |
| 340 | init_buffers::<T>(irq, Some(tx_buffer), None); | 350 | init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), None); |
| 341 | 351 | ||
| 342 | Self { phantom: PhantomData } | 352 | Self { |
| 353 | info: T::info(), | ||
| 354 | state: T::buffered_state(), | ||
| 355 | } | ||
| 343 | } | 356 | } |
| 344 | 357 | ||
| 345 | /// Create a new buffered UART TX with flow control. | 358 | /// Create a new buffered UART TX with flow control. |
| 346 | pub fn new_with_cts( | 359 | pub fn new_with_cts<'d, T: Instance>( |
| 347 | _uart: Peri<'d, T>, | 360 | _uart: Peri<'d, T>, |
| 348 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 361 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| 349 | tx: Peri<'d, impl TxPin<T>>, | 362 | tx: Peri<'d, impl TxPin<T>>, |
| 350 | cts: Peri<'d, impl CtsPin<T>>, | 363 | cts: Peri<'d, impl CtsPin<T>>, |
| 351 | tx_buffer: &'d mut [u8], | 364 | tx_buffer: &'d mut [u8], |
| 352 | config: Config, | 365 | config: Config, |
| 353 | ) -> Self { | 366 | ) -> Self { |
| 354 | super::Uart::<'d, T, Async>::init(Some(tx.into()), None, None, Some(cts.into()), config); | 367 | super::Uart::<'d, Async>::init(T::info(), Some(tx.into()), None, None, Some(cts.into()), config); |
| 355 | init_buffers::<T>(irq, Some(tx_buffer), None); | 368 | init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), None); |
| 356 | 369 | ||
| 357 | Self { phantom: PhantomData } | 370 | Self { |
| 371 | info: T::info(), | ||
| 372 | state: T::buffered_state(), | ||
| 373 | } | ||
| 358 | } | 374 | } |
| 359 | 375 | ||
| 360 | fn write(buf: &[u8]) -> impl Future<Output = Result<usize, Error>> + '_ { | 376 | fn write<'d>( |
| 377 | info: &'static Info, | ||
| 378 | state: &'static State, | ||
| 379 | buf: &'d [u8], | ||
| 380 | ) -> impl Future<Output = Result<usize, Error>> + 'd { | ||
| 361 | poll_fn(move |cx| { | 381 | poll_fn(move |cx| { |
| 362 | if buf.is_empty() { | 382 | if buf.is_empty() { |
| 363 | return Poll::Ready(Ok(0)); | 383 | return Poll::Ready(Ok(0)); |
| 364 | } | 384 | } |
| 365 | 385 | ||
| 366 | let state = T::buffered_state(); | ||
| 367 | let mut tx_writer = unsafe { state.tx_buf.writer() }; | 386 | let mut tx_writer = unsafe { state.tx_buf.writer() }; |
| 368 | let n = tx_writer.push(|data| { | 387 | let n = tx_writer.push(|data| { |
| 369 | let n = data.len().min(buf.len()); | 388 | let n = data.len().min(buf.len()); |
| @@ -379,14 +398,13 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 379 | // FIFO and the number of bytes drops below a threshold. When the | 398 | // FIFO and the number of bytes drops below a threshold. When the |
| 380 | // FIFO was empty we have to manually pend the interrupt to shovel | 399 | // FIFO was empty we have to manually pend the interrupt to shovel |
| 381 | // TX data from the buffer into the FIFO. | 400 | // TX data from the buffer into the FIFO. |
| 382 | T::Interrupt::pend(); | 401 | info.interrupt.pend(); |
| 383 | Poll::Ready(Ok(n)) | 402 | Poll::Ready(Ok(n)) |
| 384 | }) | 403 | }) |
| 385 | } | 404 | } |
| 386 | 405 | ||
| 387 | fn flush() -> impl Future<Output = Result<(), Error>> { | 406 | fn flush(state: &'static State) -> impl Future<Output = Result<(), Error>> { |
| 388 | poll_fn(move |cx| { | 407 | poll_fn(move |cx| { |
| 389 | let state = T::buffered_state(); | ||
| 390 | if !state.tx_buf.is_empty() { | 408 | if !state.tx_buf.is_empty() { |
| 391 | state.tx_waker.register(cx.waker()); | 409 | state.tx_waker.register(cx.waker()); |
| 392 | return Poll::Pending; | 410 | return Poll::Pending; |
| @@ -403,8 +421,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 403 | } | 421 | } |
| 404 | 422 | ||
| 405 | loop { | 423 | loop { |
| 406 | let state = T::buffered_state(); | 424 | let mut tx_writer = unsafe { self.state.tx_buf.writer() }; |
| 407 | let mut tx_writer = unsafe { state.tx_buf.writer() }; | ||
| 408 | let n = tx_writer.push(|data| { | 425 | let n = tx_writer.push(|data| { |
| 409 | let n = data.len().min(buf.len()); | 426 | let n = data.len().min(buf.len()); |
| 410 | data[..n].copy_from_slice(&buf[..n]); | 427 | data[..n].copy_from_slice(&buf[..n]); |
| @@ -416,7 +433,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 416 | // FIFO and the number of bytes drops below a threshold. When the | 433 | // FIFO and the number of bytes drops below a threshold. When the |
| 417 | // FIFO was empty we have to manually pend the interrupt to shovel | 434 | // FIFO was empty we have to manually pend the interrupt to shovel |
| 418 | // TX data from the buffer into the FIFO. | 435 | // TX data from the buffer into the FIFO. |
| 419 | T::Interrupt::pend(); | 436 | self.info.interrupt.pend(); |
| 420 | return Ok(n); | 437 | return Ok(n); |
| 421 | } | 438 | } |
| 422 | } | 439 | } |
| @@ -425,8 +442,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 425 | /// Flush UART TX blocking execution until done. | 442 | /// Flush UART TX blocking execution until done. |
| 426 | pub fn blocking_flush(&mut self) -> Result<(), Error> { | 443 | pub fn blocking_flush(&mut self) -> Result<(), Error> { |
| 427 | loop { | 444 | loop { |
| 428 | let state = T::buffered_state(); | 445 | if self.state.tx_buf.is_empty() { |
| 429 | if state.tx_buf.is_empty() { | ||
| 430 | return Ok(()); | 446 | return Ok(()); |
| 431 | } | 447 | } |
| 432 | } | 448 | } |
| @@ -434,7 +450,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 434 | 450 | ||
| 435 | /// Check if UART is busy. | 451 | /// Check if UART is busy. |
| 436 | pub fn busy(&self) -> bool { | 452 | pub fn busy(&self) -> bool { |
| 437 | T::regs().uartfr().read().busy() | 453 | self.info.regs.uartfr().read().busy() |
| 438 | } | 454 | } |
| 439 | 455 | ||
| 440 | /// Assert a break condition after waiting for the transmit buffers to empty, | 456 | /// Assert a break condition after waiting for the transmit buffers to empty, |
| @@ -445,7 +461,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 445 | /// This method may block for a long amount of time since it has to wait | 461 | /// This method may block for a long amount of time since it has to wait |
| 446 | /// for the transmit fifo to empty, which may take a while on slow links. | 462 | /// for the transmit fifo to empty, which may take a while on slow links. |
| 447 | pub async fn send_break(&mut self, bits: u32) { | 463 | pub async fn send_break(&mut self, bits: u32) { |
| 448 | let regs = T::regs(); | 464 | let regs = self.info.regs; |
| 449 | let bits = bits.max({ | 465 | let bits = bits.max({ |
| 450 | let lcr = regs.uartlcr_h().read(); | 466 | let lcr = regs.uartlcr_h().read(); |
| 451 | let width = lcr.wlen() as u32 + 5; | 467 | let width = lcr.wlen() as u32 + 5; |
| @@ -458,7 +474,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 458 | let div_clk = clk_peri_freq() as u64 * 64; | 474 | let div_clk = clk_peri_freq() as u64 * 64; |
| 459 | let wait_usecs = (1_000_000 * bits as u64 * divx64 * 16 + div_clk - 1) / div_clk; | 475 | let wait_usecs = (1_000_000 * bits as u64 * divx64 * 16 + div_clk - 1) / div_clk; |
| 460 | 476 | ||
| 461 | Self::flush().await.unwrap(); | 477 | Self::flush(self.state).await.unwrap(); |
| 462 | while self.busy() {} | 478 | while self.busy() {} |
| 463 | regs.uartlcr_h().write_set(|w| w.set_brk(true)); | 479 | regs.uartlcr_h().write_set(|w| w.set_brk(true)); |
| 464 | Timer::after_micros(wait_usecs).await; | 480 | Timer::after_micros(wait_usecs).await; |
| @@ -466,28 +482,26 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> { | |||
| 466 | } | 482 | } |
| 467 | } | 483 | } |
| 468 | 484 | ||
| 469 | impl<'d, T: Instance> Drop for BufferedUartRx<'d, T> { | 485 | impl Drop for BufferedUartRx { |
| 470 | fn drop(&mut self) { | 486 | fn drop(&mut self) { |
| 471 | let state = T::buffered_state(); | 487 | unsafe { self.state.rx_buf.deinit() } |
| 472 | unsafe { state.rx_buf.deinit() } | ||
| 473 | 488 | ||
| 474 | // TX is inactive if the buffer is not available. | 489 | // TX is inactive if the buffer is not available. |
| 475 | // We can now unregister the interrupt handler | 490 | // We can now unregister the interrupt handler |
| 476 | if !state.tx_buf.is_available() { | 491 | if !self.state.tx_buf.is_available() { |
| 477 | T::Interrupt::disable(); | 492 | self.info.interrupt.disable(); |
| 478 | } | 493 | } |
| 479 | } | 494 | } |
| 480 | } | 495 | } |
| 481 | 496 | ||
| 482 | impl<'d, T: Instance> Drop for BufferedUartTx<'d, T> { | 497 | impl Drop for BufferedUartTx { |
| 483 | fn drop(&mut self) { | 498 | fn drop(&mut self) { |
| 484 | let state = T::buffered_state(); | 499 | unsafe { self.state.tx_buf.deinit() } |
| 485 | unsafe { state.tx_buf.deinit() } | ||
| 486 | 500 | ||
| 487 | // RX is inactive if the buffer is not available. | 501 | // RX is inactive if the buffer is not available. |
| 488 | // We can now unregister the interrupt handler | 502 | // We can now unregister the interrupt handler |
| 489 | if !state.rx_buf.is_available() { | 503 | if !self.state.rx_buf.is_available() { |
| 490 | T::Interrupt::disable(); | 504 | self.info.interrupt.disable(); |
| 491 | } | 505 | } |
| 492 | } | 506 | } |
| 493 | } | 507 | } |
| @@ -499,7 +513,7 @@ pub struct BufferedInterruptHandler<T: Instance> { | |||
| 499 | 513 | ||
| 500 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterruptHandler<T> { | 514 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterruptHandler<T> { |
| 501 | unsafe fn on_interrupt() { | 515 | unsafe fn on_interrupt() { |
| 502 | let r = T::regs(); | 516 | let r = T::info().regs; |
| 503 | if r.uartdmacr().read().rxdmae() { | 517 | if r.uartdmacr().read().rxdmae() { |
| 504 | return; | 518 | return; |
| 505 | } | 519 | } |
| @@ -603,95 +617,95 @@ impl embedded_io::Error for Error { | |||
| 603 | } | 617 | } |
| 604 | } | 618 | } |
| 605 | 619 | ||
| 606 | impl<'d, T: Instance> embedded_io_async::ErrorType for BufferedUart<'d, T> { | 620 | impl embedded_io_async::ErrorType for BufferedUart { |
| 607 | type Error = Error; | 621 | type Error = Error; |
| 608 | } | 622 | } |
| 609 | 623 | ||
| 610 | impl<'d, T: Instance> embedded_io_async::ErrorType for BufferedUartRx<'d, T> { | 624 | impl embedded_io_async::ErrorType for BufferedUartRx { |
| 611 | type Error = Error; | 625 | type Error = Error; |
| 612 | } | 626 | } |
| 613 | 627 | ||
| 614 | impl<'d, T: Instance> embedded_io_async::ErrorType for BufferedUartTx<'d, T> { | 628 | impl embedded_io_async::ErrorType for BufferedUartTx { |
| 615 | type Error = Error; | 629 | type Error = Error; |
| 616 | } | 630 | } |
| 617 | 631 | ||
| 618 | impl<'d, T: Instance + 'd> embedded_io_async::Read for BufferedUart<'d, T> { | 632 | impl embedded_io_async::Read for BufferedUart { |
| 619 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | 633 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
| 620 | BufferedUartRx::<'d, T>::read(buf).await | 634 | BufferedUartRx::read(self.rx.info, self.rx.state, buf).await |
| 621 | } | 635 | } |
| 622 | } | 636 | } |
| 623 | 637 | ||
| 624 | impl<'d, T: Instance + 'd> embedded_io_async::Read for BufferedUartRx<'d, T> { | 638 | impl embedded_io_async::Read for BufferedUartRx { |
| 625 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | 639 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
| 626 | Self::read(buf).await | 640 | Self::read(self.info, self.state, buf).await |
| 627 | } | 641 | } |
| 628 | } | 642 | } |
| 629 | 643 | ||
| 630 | impl<'d, T: Instance + 'd> embedded_io_async::ReadReady for BufferedUart<'d, T> { | 644 | impl embedded_io_async::ReadReady for BufferedUart { |
| 631 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | 645 | fn read_ready(&mut self) -> Result<bool, Self::Error> { |
| 632 | BufferedUartRx::<'d, T>::read_ready() | 646 | BufferedUartRx::read_ready(self.rx.state) |
| 633 | } | 647 | } |
| 634 | } | 648 | } |
| 635 | 649 | ||
| 636 | impl<'d, T: Instance + 'd> embedded_io_async::ReadReady for BufferedUartRx<'d, T> { | 650 | impl embedded_io_async::ReadReady for BufferedUartRx { |
| 637 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | 651 | fn read_ready(&mut self) -> Result<bool, Self::Error> { |
| 638 | Self::read_ready() | 652 | Self::read_ready(self.state) |
| 639 | } | 653 | } |
| 640 | } | 654 | } |
| 641 | 655 | ||
| 642 | impl<'d, T: Instance + 'd> embedded_io_async::BufRead for BufferedUart<'d, T> { | 656 | impl embedded_io_async::BufRead for BufferedUart { |
| 643 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | 657 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { |
| 644 | BufferedUartRx::<'d, T>::fill_buf().await | 658 | BufferedUartRx::fill_buf(self.rx.state).await |
| 645 | } | 659 | } |
| 646 | 660 | ||
| 647 | fn consume(&mut self, amt: usize) { | 661 | fn consume(&mut self, amt: usize) { |
| 648 | BufferedUartRx::<'d, T>::consume(amt) | 662 | BufferedUartRx::consume(self.rx.info, self.rx.state, amt) |
| 649 | } | 663 | } |
| 650 | } | 664 | } |
| 651 | 665 | ||
| 652 | impl<'d, T: Instance + 'd> embedded_io_async::BufRead for BufferedUartRx<'d, T> { | 666 | impl embedded_io_async::BufRead for BufferedUartRx { |
| 653 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | 667 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { |
| 654 | Self::fill_buf().await | 668 | Self::fill_buf(self.state).await |
| 655 | } | 669 | } |
| 656 | 670 | ||
| 657 | fn consume(&mut self, amt: usize) { | 671 | fn consume(&mut self, amt: usize) { |
| 658 | Self::consume(amt) | 672 | Self::consume(self.info, self.state, amt) |
| 659 | } | 673 | } |
| 660 | } | 674 | } |
| 661 | 675 | ||
| 662 | impl<'d, T: Instance + 'd> embedded_io_async::Write for BufferedUart<'d, T> { | 676 | impl embedded_io_async::Write for BufferedUart { |
| 663 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 677 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 664 | BufferedUartTx::<'d, T>::write(buf).await | 678 | BufferedUartTx::write(self.tx.info, self.tx.state, buf).await |
| 665 | } | 679 | } |
| 666 | 680 | ||
| 667 | async fn flush(&mut self) -> Result<(), Self::Error> { | 681 | async fn flush(&mut self) -> Result<(), Self::Error> { |
| 668 | BufferedUartTx::<'d, T>::flush().await | 682 | BufferedUartTx::flush(self.tx.state).await |
| 669 | } | 683 | } |
| 670 | } | 684 | } |
| 671 | 685 | ||
| 672 | impl<'d, T: Instance + 'd> embedded_io_async::Write for BufferedUartTx<'d, T> { | 686 | impl embedded_io_async::Write for BufferedUartTx { |
| 673 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 687 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 674 | Self::write(buf).await | 688 | Self::write(self.info, self.state, buf).await |
| 675 | } | 689 | } |
| 676 | 690 | ||
| 677 | async fn flush(&mut self) -> Result<(), Self::Error> { | 691 | async fn flush(&mut self) -> Result<(), Self::Error> { |
| 678 | Self::flush().await | 692 | Self::flush(self.state).await |
| 679 | } | 693 | } |
| 680 | } | 694 | } |
| 681 | 695 | ||
| 682 | impl<'d, T: Instance + 'd> embedded_io::Read for BufferedUart<'d, T> { | 696 | impl embedded_io::Read for BufferedUart { |
| 683 | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | 697 | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
| 684 | self.rx.blocking_read(buf) | 698 | self.rx.blocking_read(buf) |
| 685 | } | 699 | } |
| 686 | } | 700 | } |
| 687 | 701 | ||
| 688 | impl<'d, T: Instance + 'd> embedded_io::Read for BufferedUartRx<'d, T> { | 702 | impl embedded_io::Read for BufferedUartRx { |
| 689 | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | 703 | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
| 690 | self.blocking_read(buf) | 704 | self.blocking_read(buf) |
| 691 | } | 705 | } |
| 692 | } | 706 | } |
| 693 | 707 | ||
| 694 | impl<'d, T: Instance + 'd> embedded_io::Write for BufferedUart<'d, T> { | 708 | impl embedded_io::Write for BufferedUart { |
| 695 | fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 709 | fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 696 | self.tx.blocking_write(buf) | 710 | self.tx.blocking_write(buf) |
| 697 | } | 711 | } |
| @@ -701,7 +715,7 @@ impl<'d, T: Instance + 'd> embedded_io::Write for BufferedUart<'d, T> { | |||
| 701 | } | 715 | } |
| 702 | } | 716 | } |
| 703 | 717 | ||
| 704 | impl<'d, T: Instance + 'd> embedded_io::Write for BufferedUartTx<'d, T> { | 718 | impl embedded_io::Write for BufferedUartTx { |
| 705 | fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 719 | fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 706 | self.blocking_write(buf) | 720 | self.blocking_write(buf) |
| 707 | } | 721 | } |
| @@ -711,11 +725,11 @@ impl<'d, T: Instance + 'd> embedded_io::Write for BufferedUartTx<'d, T> { | |||
| 711 | } | 725 | } |
| 712 | } | 726 | } |
| 713 | 727 | ||
| 714 | impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d, T> { | 728 | impl embedded_hal_02::serial::Read<u8> for BufferedUartRx { |
| 715 | type Error = Error; | 729 | type Error = Error; |
| 716 | 730 | ||
| 717 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { | 731 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { |
| 718 | let r = T::regs(); | 732 | let r = self.info.regs; |
| 719 | if r.uartfr().read().rxfe() { | 733 | if r.uartfr().read().rxfe() { |
| 720 | return Err(nb::Error::WouldBlock); | 734 | return Err(nb::Error::WouldBlock); |
| 721 | } | 735 | } |
| @@ -736,7 +750,7 @@ impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d, T | |||
| 736 | } | 750 | } |
| 737 | } | 751 | } |
| 738 | 752 | ||
| 739 | impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d, T> { | 753 | impl embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx { |
| 740 | type Error = Error; | 754 | type Error = Error; |
| 741 | 755 | ||
| 742 | fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> { | 756 | fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> { |
| @@ -755,7 +769,7 @@ impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedU | |||
| 755 | } | 769 | } |
| 756 | } | 770 | } |
| 757 | 771 | ||
| 758 | impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d, T> { | 772 | impl embedded_hal_02::serial::Read<u8> for BufferedUart { |
| 759 | type Error = Error; | 773 | type Error = Error; |
| 760 | 774 | ||
| 761 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { | 775 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { |
| @@ -763,7 +777,7 @@ impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d, T> | |||
| 763 | } | 777 | } |
| 764 | } | 778 | } |
| 765 | 779 | ||
| 766 | impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d, T> { | 780 | impl embedded_hal_02::blocking::serial::Write<u8> for BufferedUart { |
| 767 | type Error = Error; | 781 | type Error = Error; |
| 768 | 782 | ||
| 769 | fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> { | 783 | fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> { |
| @@ -782,25 +796,25 @@ impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for BufferedU | |||
| 782 | } | 796 | } |
| 783 | } | 797 | } |
| 784 | 798 | ||
| 785 | impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUartRx<'d, T> { | 799 | impl embedded_hal_nb::serial::ErrorType for BufferedUartRx { |
| 786 | type Error = Error; | 800 | type Error = Error; |
| 787 | } | 801 | } |
| 788 | 802 | ||
| 789 | impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUartTx<'d, T> { | 803 | impl embedded_hal_nb::serial::ErrorType for BufferedUartTx { |
| 790 | type Error = Error; | 804 | type Error = Error; |
| 791 | } | 805 | } |
| 792 | 806 | ||
| 793 | impl<'d, T: Instance> embedded_hal_nb::serial::ErrorType for BufferedUart<'d, T> { | 807 | impl embedded_hal_nb::serial::ErrorType for BufferedUart { |
| 794 | type Error = Error; | 808 | type Error = Error; |
| 795 | } | 809 | } |
| 796 | 810 | ||
| 797 | impl<'d, T: Instance> embedded_hal_nb::serial::Read for BufferedUartRx<'d, T> { | 811 | impl embedded_hal_nb::serial::Read for BufferedUartRx { |
| 798 | fn read(&mut self) -> nb::Result<u8, Self::Error> { | 812 | fn read(&mut self) -> nb::Result<u8, Self::Error> { |
| 799 | embedded_hal_02::serial::Read::read(self) | 813 | embedded_hal_02::serial::Read::read(self) |
| 800 | } | 814 | } |
| 801 | } | 815 | } |
| 802 | 816 | ||
| 803 | impl<'d, T: Instance> embedded_hal_nb::serial::Write for BufferedUartTx<'d, T> { | 817 | impl embedded_hal_nb::serial::Write for BufferedUartTx { |
| 804 | fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { | 818 | fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { |
| 805 | self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other) | 819 | self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other) |
| 806 | } | 820 | } |
| @@ -810,13 +824,13 @@ impl<'d, T: Instance> embedded_hal_nb::serial::Write for BufferedUartTx<'d, T> { | |||
| 810 | } | 824 | } |
| 811 | } | 825 | } |
| 812 | 826 | ||
| 813 | impl<'d, T: Instance> embedded_hal_nb::serial::Read for BufferedUart<'d, T> { | 827 | impl embedded_hal_nb::serial::Read for BufferedUart { |
| 814 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { | 828 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { |
| 815 | embedded_hal_02::serial::Read::read(&mut self.rx) | 829 | embedded_hal_02::serial::Read::read(&mut self.rx) |
| 816 | } | 830 | } |
| 817 | } | 831 | } |
| 818 | 832 | ||
| 819 | impl<'d, T: Instance> embedded_hal_nb::serial::Write for BufferedUart<'d, T> { | 833 | impl embedded_hal_nb::serial::Write for BufferedUart { |
| 820 | fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { | 834 | fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { |
| 821 | self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other) | 835 | self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other) |
| 822 | } | 836 | } |
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index 7ce074a3f..d36884109 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs | |||
| @@ -13,7 +13,8 @@ use pac::uart::regs::Uartris; | |||
| 13 | use crate::clocks::clk_peri_freq; | 13 | use crate::clocks::clk_peri_freq; |
| 14 | use crate::dma::{AnyChannel, Channel}; | 14 | use crate::dma::{AnyChannel, Channel}; |
| 15 | use crate::gpio::{AnyPin, SealedPin}; | 15 | use crate::gpio::{AnyPin, SealedPin}; |
| 16 | use crate::interrupt::typelevel::{Binding, Interrupt}; | 16 | use crate::interrupt::typelevel::{Binding, Interrupt as _}; |
| 17 | use crate::interrupt::{Interrupt, InterruptExt}; | ||
| 17 | use crate::pac::io::vals::{Inover, Outover}; | 18 | use crate::pac::io::vals::{Inover, Outover}; |
| 18 | use crate::{interrupt, pac, peripherals, RegExt}; | 19 | use crate::{interrupt, pac, peripherals, RegExt}; |
| 19 | 20 | ||
| @@ -135,37 +136,41 @@ pub struct DmaState { | |||
| 135 | } | 136 | } |
| 136 | 137 | ||
| 137 | /// UART driver. | 138 | /// UART driver. |
| 138 | pub struct Uart<'d, T: Instance, M: Mode> { | 139 | pub struct Uart<'d, M: Mode> { |
| 139 | tx: UartTx<'d, T, M>, | 140 | tx: UartTx<'d, M>, |
| 140 | rx: UartRx<'d, T, M>, | 141 | rx: UartRx<'d, M>, |
| 141 | } | 142 | } |
| 142 | 143 | ||
| 143 | /// UART TX driver. | 144 | /// UART TX driver. |
| 144 | pub struct UartTx<'d, T: Instance, M: Mode> { | 145 | pub struct UartTx<'d, M: Mode> { |
| 146 | info: &'static Info, | ||
| 145 | tx_dma: Option<Peri<'d, AnyChannel>>, | 147 | tx_dma: Option<Peri<'d, AnyChannel>>, |
| 146 | phantom: PhantomData<(&'d mut T, M)>, | 148 | phantom: PhantomData<M>, |
| 147 | } | 149 | } |
| 148 | 150 | ||
| 149 | /// UART RX driver. | 151 | /// UART RX driver. |
| 150 | pub struct UartRx<'d, T: Instance, M: Mode> { | 152 | pub struct UartRx<'d, M: Mode> { |
| 153 | info: &'static Info, | ||
| 154 | dma_state: &'static DmaState, | ||
| 151 | rx_dma: Option<Peri<'d, AnyChannel>>, | 155 | rx_dma: Option<Peri<'d, AnyChannel>>, |
| 152 | phantom: PhantomData<(&'d mut T, M)>, | 156 | phantom: PhantomData<M>, |
| 153 | } | 157 | } |
| 154 | 158 | ||
| 155 | impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { | 159 | impl<'d, M: Mode> UartTx<'d, M> { |
| 156 | /// Create a new DMA-enabled UART which can only send data | 160 | /// Create a new DMA-enabled UART which can only send data |
| 157 | pub fn new( | 161 | pub fn new<T: Instance>( |
| 158 | _uart: Peri<'d, T>, | 162 | _uart: Peri<'d, T>, |
| 159 | tx: Peri<'d, impl TxPin<T>>, | 163 | tx: Peri<'d, impl TxPin<T>>, |
| 160 | tx_dma: Peri<'d, impl Channel>, | 164 | tx_dma: Peri<'d, impl Channel>, |
| 161 | config: Config, | 165 | config: Config, |
| 162 | ) -> Self { | 166 | ) -> Self { |
| 163 | Uart::<T, M>::init(Some(tx.into()), None, None, None, config); | 167 | Uart::<M>::init(T::info(), Some(tx.into()), None, None, None, config); |
| 164 | Self::new_inner(Some(tx_dma.into())) | 168 | Self::new_inner::<T>(Some(tx_dma.into())) |
| 165 | } | 169 | } |
| 166 | 170 | ||
| 167 | fn new_inner(tx_dma: Option<Peri<'d, AnyChannel>>) -> Self { | 171 | fn new_inner<T: Instance>(tx_dma: Option<Peri<'d, AnyChannel>>) -> Self { |
| 168 | Self { | 172 | Self { |
| 173 | info: T::info(), | ||
| 169 | tx_dma, | 174 | tx_dma, |
| 170 | phantom: PhantomData, | 175 | phantom: PhantomData, |
| 171 | } | 176 | } |
| @@ -173,7 +178,7 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { | |||
| 173 | 178 | ||
| 174 | /// Transmit the provided buffer blocking execution until done. | 179 | /// Transmit the provided buffer blocking execution until done. |
| 175 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 180 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 176 | let r = T::regs(); | 181 | let r = self.info.regs; |
| 177 | for &b in buffer { | 182 | for &b in buffer { |
| 178 | while r.uartfr().read().txff() {} | 183 | while r.uartfr().read().txff() {} |
| 179 | r.uartdr().write(|w| w.set_data(b)); | 184 | r.uartdr().write(|w| w.set_data(b)); |
| @@ -183,14 +188,13 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { | |||
| 183 | 188 | ||
| 184 | /// Flush UART TX blocking execution until done. | 189 | /// Flush UART TX blocking execution until done. |
| 185 | pub fn blocking_flush(&mut self) -> Result<(), Error> { | 190 | pub fn blocking_flush(&mut self) -> Result<(), Error> { |
| 186 | let r = T::regs(); | 191 | while !self.info.regs.uartfr().read().txfe() {} |
| 187 | while !r.uartfr().read().txfe() {} | ||
| 188 | Ok(()) | 192 | Ok(()) |
| 189 | } | 193 | } |
| 190 | 194 | ||
| 191 | /// Check if UART is busy transmitting. | 195 | /// Check if UART is busy transmitting. |
| 192 | pub fn busy(&self) -> bool { | 196 | pub fn busy(&self) -> bool { |
| 193 | T::regs().uartfr().read().busy() | 197 | self.info.regs.uartfr().read().busy() |
| 194 | } | 198 | } |
| 195 | 199 | ||
| 196 | /// Assert a break condition after waiting for the transmit buffers to empty, | 200 | /// Assert a break condition after waiting for the transmit buffers to empty, |
| @@ -201,7 +205,7 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { | |||
| 201 | /// This method may block for a long amount of time since it has to wait | 205 | /// This method may block for a long amount of time since it has to wait |
| 202 | /// for the transmit fifo to empty, which may take a while on slow links. | 206 | /// for the transmit fifo to empty, which may take a while on slow links. |
| 203 | pub async fn send_break(&mut self, bits: u32) { | 207 | pub async fn send_break(&mut self, bits: u32) { |
| 204 | let regs = T::regs(); | 208 | let regs = self.info.regs; |
| 205 | let bits = bits.max({ | 209 | let bits = bits.max({ |
| 206 | let lcr = regs.uartlcr_h().read(); | 210 | let lcr = regs.uartlcr_h().read(); |
| 207 | let width = lcr.wlen() as u32 + 5; | 211 | let width = lcr.wlen() as u32 + 5; |
| @@ -222,65 +226,75 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { | |||
| 222 | } | 226 | } |
| 223 | } | 227 | } |
| 224 | 228 | ||
| 225 | impl<'d, T: Instance> UartTx<'d, T, Blocking> { | 229 | impl<'d> UartTx<'d, Blocking> { |
| 226 | /// Create a new UART TX instance for blocking mode operations. | 230 | /// Create a new UART TX instance for blocking mode operations. |
| 227 | pub fn new_blocking(_uart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self { | 231 | pub fn new_blocking<T: Instance>(_uart: Peri<'d, T>, tx: Peri<'d, impl TxPin<T>>, config: Config) -> Self { |
| 228 | Uart::<T, Blocking>::init(Some(tx.into()), None, None, None, config); | 232 | Uart::<Blocking>::init(T::info(), Some(tx.into()), None, None, None, config); |
| 229 | Self::new_inner(None) | 233 | Self::new_inner::<T>(None) |
| 230 | } | 234 | } |
| 231 | 235 | ||
| 232 | /// Convert this uart TX instance into a buffered uart using the provided | 236 | /// Convert this uart TX instance into a buffered uart using the provided |
| 233 | /// irq and transmit buffer. | 237 | /// irq and transmit buffer. |
| 234 | pub fn into_buffered( | 238 | pub fn into_buffered<T: Instance>( |
| 235 | self, | 239 | self, |
| 236 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 240 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| 237 | tx_buffer: &'d mut [u8], | 241 | tx_buffer: &'d mut [u8], |
| 238 | ) -> BufferedUartTx<'d, T> { | 242 | ) -> BufferedUartTx { |
| 239 | buffered::init_buffers::<T>(irq, Some(tx_buffer), None); | 243 | buffered::init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), None); |
| 240 | 244 | ||
| 241 | BufferedUartTx { phantom: PhantomData } | 245 | BufferedUartTx { |
| 246 | info: T::info(), | ||
| 247 | state: T::buffered_state(), | ||
| 248 | } | ||
| 242 | } | 249 | } |
| 243 | } | 250 | } |
| 244 | 251 | ||
| 245 | impl<'d, T: Instance> UartTx<'d, T, Async> { | 252 | impl<'d> UartTx<'d, Async> { |
| 246 | /// Write to UART TX from the provided buffer using DMA. | 253 | /// Write to UART TX from the provided buffer using DMA. |
| 247 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 254 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 248 | let ch = self.tx_dma.as_mut().unwrap().reborrow(); | 255 | let ch = self.tx_dma.as_mut().unwrap().reborrow(); |
| 249 | let transfer = unsafe { | 256 | let transfer = unsafe { |
| 250 | T::regs().uartdmacr().write_set(|reg| { | 257 | self.info.regs.uartdmacr().write_set(|reg| { |
| 251 | reg.set_txdmae(true); | 258 | reg.set_txdmae(true); |
| 252 | }); | 259 | }); |
| 253 | // If we don't assign future to a variable, the data register pointer | 260 | // If we don't assign future to a variable, the data register pointer |
| 254 | // is held across an await and makes the future non-Send. | 261 | // is held across an await and makes the future non-Send. |
| 255 | crate::dma::write(ch, buffer, T::regs().uartdr().as_ptr() as *mut _, T::TX_DREQ.into()) | 262 | crate::dma::write( |
| 263 | ch, | ||
| 264 | buffer, | ||
| 265 | self.info.regs.uartdr().as_ptr() as *mut _, | ||
| 266 | self.info.tx_dreq.into(), | ||
| 267 | ) | ||
| 256 | }; | 268 | }; |
| 257 | transfer.await; | 269 | transfer.await; |
| 258 | Ok(()) | 270 | Ok(()) |
| 259 | } | 271 | } |
| 260 | } | 272 | } |
| 261 | 273 | ||
| 262 | impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { | 274 | impl<'d, M: Mode> UartRx<'d, M> { |
| 263 | /// Create a new DMA-enabled UART which can only receive data | 275 | /// Create a new DMA-enabled UART which can only receive data |
| 264 | pub fn new( | 276 | pub fn new<T: Instance>( |
| 265 | _uart: Peri<'d, T>, | 277 | _uart: Peri<'d, T>, |
| 266 | rx: Peri<'d, impl RxPin<T>>, | 278 | rx: Peri<'d, impl RxPin<T>>, |
| 267 | _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, | 279 | _irq: impl Binding<T::Interrupt, InterruptHandler<T>>, |
| 268 | rx_dma: Peri<'d, impl Channel>, | 280 | rx_dma: Peri<'d, impl Channel>, |
| 269 | config: Config, | 281 | config: Config, |
| 270 | ) -> Self { | 282 | ) -> Self { |
| 271 | Uart::<T, M>::init(None, Some(rx.into()), None, None, config); | 283 | Uart::<M>::init(T::info(), None, Some(rx.into()), None, None, config); |
| 272 | Self::new_inner(true, Some(rx_dma.into())) | 284 | Self::new_inner::<T>(true, Some(rx_dma.into())) |
| 273 | } | 285 | } |
| 274 | 286 | ||
| 275 | fn new_inner(has_irq: bool, rx_dma: Option<Peri<'d, AnyChannel>>) -> Self { | 287 | fn new_inner<T: Instance>(has_irq: bool, rx_dma: Option<Peri<'d, AnyChannel>>) -> Self { |
| 276 | debug_assert_eq!(has_irq, rx_dma.is_some()); | 288 | debug_assert_eq!(has_irq, rx_dma.is_some()); |
| 277 | if has_irq { | 289 | if has_irq { |
| 278 | // disable all error interrupts initially | 290 | // disable all error interrupts initially |
| 279 | T::regs().uartimsc().write(|w| w.0 = 0); | 291 | T::info().regs.uartimsc().write(|w| w.0 = 0); |
| 280 | T::Interrupt::unpend(); | 292 | T::Interrupt::unpend(); |
| 281 | unsafe { T::Interrupt::enable() }; | 293 | unsafe { T::Interrupt::enable() }; |
| 282 | } | 294 | } |
| 283 | Self { | 295 | Self { |
| 296 | info: T::info(), | ||
| 297 | dma_state: T::dma_state(), | ||
| 284 | rx_dma, | 298 | rx_dma, |
| 285 | phantom: PhantomData, | 299 | phantom: PhantomData, |
| 286 | } | 300 | } |
| @@ -299,7 +313,7 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { | |||
| 299 | /// encountered. in both cases, `len` is the number of *good* bytes copied into | 313 | /// encountered. in both cases, `len` is the number of *good* bytes copied into |
| 300 | /// `buffer`. | 314 | /// `buffer`. |
| 301 | fn drain_fifo(&mut self, buffer: &mut [u8]) -> Result<usize, (usize, Error)> { | 315 | fn drain_fifo(&mut self, buffer: &mut [u8]) -> Result<usize, (usize, Error)> { |
| 302 | let r = T::regs(); | 316 | let r = self.info.regs; |
| 303 | for (i, b) in buffer.iter_mut().enumerate() { | 317 | for (i, b) in buffer.iter_mut().enumerate() { |
| 304 | if r.uartfr().read().rxfe() { | 318 | if r.uartfr().read().rxfe() { |
| 305 | return Ok(i); | 319 | return Ok(i); |
| @@ -323,12 +337,12 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { | |||
| 323 | } | 337 | } |
| 324 | } | 338 | } |
| 325 | 339 | ||
| 326 | impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> { | 340 | impl<'d, M: Mode> Drop for UartRx<'d, M> { |
| 327 | fn drop(&mut self) { | 341 | fn drop(&mut self) { |
| 328 | if self.rx_dma.is_some() { | 342 | if self.rx_dma.is_some() { |
| 329 | T::Interrupt::disable(); | 343 | self.info.interrupt.disable(); |
| 330 | // clear dma flags. irq handlers use these to disambiguate among themselves. | 344 | // clear dma flags. irq handlers use these to disambiguate among themselves. |
| 331 | T::regs().uartdmacr().write_clear(|reg| { | 345 | self.info.regs.uartdmacr().write_clear(|reg| { |
| 332 | reg.set_rxdmae(true); | 346 | reg.set_rxdmae(true); |
| 333 | reg.set_txdmae(true); | 347 | reg.set_txdmae(true); |
| 334 | reg.set_dmaonerr(true); | 348 | reg.set_dmaonerr(true); |
| @@ -337,23 +351,26 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> { | |||
| 337 | } | 351 | } |
| 338 | } | 352 | } |
| 339 | 353 | ||
| 340 | impl<'d, T: Instance> UartRx<'d, T, Blocking> { | 354 | impl<'d> UartRx<'d, Blocking> { |
| 341 | /// Create a new UART RX instance for blocking mode operations. | 355 | /// Create a new UART RX instance for blocking mode operations. |
| 342 | pub fn new_blocking(_uart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self { | 356 | pub fn new_blocking<T: Instance>(_uart: Peri<'d, T>, rx: Peri<'d, impl RxPin<T>>, config: Config) -> Self { |
| 343 | Uart::<T, Blocking>::init(None, Some(rx.into()), None, None, config); | 357 | Uart::<Blocking>::init(T::info(), None, Some(rx.into()), None, None, config); |
| 344 | Self::new_inner(false, None) | 358 | Self::new_inner::<T>(false, None) |
| 345 | } | 359 | } |
| 346 | 360 | ||
| 347 | /// Convert this uart RX instance into a buffered uart using the provided | 361 | /// Convert this uart RX instance into a buffered uart using the provided |
| 348 | /// irq and receive buffer. | 362 | /// irq and receive buffer. |
| 349 | pub fn into_buffered( | 363 | pub fn into_buffered<T: Instance>( |
| 350 | self, | 364 | self, |
| 351 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 365 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| 352 | rx_buffer: &'d mut [u8], | 366 | rx_buffer: &'d mut [u8], |
| 353 | ) -> BufferedUartRx<'d, T> { | 367 | ) -> BufferedUartRx { |
| 354 | buffered::init_buffers::<T>(irq, None, Some(rx_buffer)); | 368 | buffered::init_buffers(T::info(), T::buffered_state(), None, Some(rx_buffer)); |
| 355 | 369 | ||
| 356 | BufferedUartRx { phantom: PhantomData } | 370 | BufferedUartRx { |
| 371 | info: T::info(), | ||
| 372 | state: T::buffered_state(), | ||
| 373 | } | ||
| 357 | } | 374 | } |
| 358 | } | 375 | } |
| 359 | 376 | ||
| @@ -364,7 +381,7 @@ pub struct InterruptHandler<T: Instance> { | |||
| 364 | 381 | ||
| 365 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { | 382 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { |
| 366 | unsafe fn on_interrupt() { | 383 | unsafe fn on_interrupt() { |
| 367 | let uart = T::regs(); | 384 | let uart = T::info().regs; |
| 368 | if !uart.uartdmacr().read().rxdmae() { | 385 | if !uart.uartdmacr().read().rxdmae() { |
| 369 | return; | 386 | return; |
| 370 | } | 387 | } |
| @@ -380,13 +397,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 380 | } | 397 | } |
| 381 | } | 398 | } |
| 382 | 399 | ||
| 383 | impl<'d, T: Instance> UartRx<'d, T, Async> { | 400 | impl<'d> UartRx<'d, Async> { |
| 384 | /// Read from UART RX into the provided buffer. | 401 | /// Read from UART RX into the provided buffer. |
| 385 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | 402 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { |
| 386 | // clear error flags before we drain the fifo. errors that have accumulated | 403 | // clear error flags before we drain the fifo. errors that have accumulated |
| 387 | // in the flags will also be present in the fifo. | 404 | // in the flags will also be present in the fifo. |
| 388 | T::dma_state().rx_errs.store(0, Ordering::Relaxed); | 405 | self.dma_state.rx_errs.store(0, Ordering::Relaxed); |
| 389 | T::regs().uarticr().write(|w| { | 406 | self.info.regs.uarticr().write(|w| { |
| 390 | w.set_oeic(true); | 407 | w.set_oeic(true); |
| 391 | w.set_beic(true); | 408 | w.set_beic(true); |
| 392 | w.set_peic(true); | 409 | w.set_peic(true); |
| @@ -408,28 +425,33 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { | |||
| 408 | // interrupt flags will have been raised, and those will be picked up immediately | 425 | // interrupt flags will have been raised, and those will be picked up immediately |
| 409 | // by the interrupt handler. | 426 | // by the interrupt handler. |
| 410 | let ch = self.rx_dma.as_mut().unwrap().reborrow(); | 427 | let ch = self.rx_dma.as_mut().unwrap().reborrow(); |
| 411 | T::regs().uartimsc().write_set(|w| { | 428 | self.info.regs.uartimsc().write_set(|w| { |
| 412 | w.set_oeim(true); | 429 | w.set_oeim(true); |
| 413 | w.set_beim(true); | 430 | w.set_beim(true); |
| 414 | w.set_peim(true); | 431 | w.set_peim(true); |
| 415 | w.set_feim(true); | 432 | w.set_feim(true); |
| 416 | }); | 433 | }); |
| 417 | T::regs().uartdmacr().write_set(|reg| { | 434 | self.info.regs.uartdmacr().write_set(|reg| { |
| 418 | reg.set_rxdmae(true); | 435 | reg.set_rxdmae(true); |
| 419 | reg.set_dmaonerr(true); | 436 | reg.set_dmaonerr(true); |
| 420 | }); | 437 | }); |
| 421 | let transfer = unsafe { | 438 | let transfer = unsafe { |
| 422 | // If we don't assign future to a variable, the data register pointer | 439 | // If we don't assign future to a variable, the data register pointer |
| 423 | // is held across an await and makes the future non-Send. | 440 | // is held across an await and makes the future non-Send. |
| 424 | crate::dma::read(ch, T::regs().uartdr().as_ptr() as *const _, buffer, T::RX_DREQ.into()) | 441 | crate::dma::read( |
| 442 | ch, | ||
| 443 | self.info.regs.uartdr().as_ptr() as *const _, | ||
| 444 | buffer, | ||
| 445 | self.info.rx_dreq.into(), | ||
| 446 | ) | ||
| 425 | }; | 447 | }; |
| 426 | 448 | ||
| 427 | // wait for either the transfer to complete or an error to happen. | 449 | // wait for either the transfer to complete or an error to happen. |
| 428 | let transfer_result = select( | 450 | let transfer_result = select( |
| 429 | transfer, | 451 | transfer, |
| 430 | poll_fn(|cx| { | 452 | poll_fn(|cx| { |
| 431 | T::dma_state().rx_err_waker.register(cx.waker()); | 453 | self.dma_state.rx_err_waker.register(cx.waker()); |
| 432 | match T::dma_state().rx_errs.swap(0, Ordering::Relaxed) { | 454 | match self.dma_state.rx_errs.swap(0, Ordering::Relaxed) { |
| 433 | 0 => Poll::Pending, | 455 | 0 => Poll::Pending, |
| 434 | e => Poll::Ready(Uartris(e as u32)), | 456 | e => Poll::Ready(Uartris(e as u32)), |
| 435 | } | 457 | } |
| @@ -441,7 +463,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { | |||
| 441 | Either::First(()) => { | 463 | Either::First(()) => { |
| 442 | // We're here because the DMA finished, BUT if an error occurred on the LAST | 464 | // We're here because the DMA finished, BUT if an error occurred on the LAST |
| 443 | // byte, then we may still need to grab the error state! | 465 | // byte, then we may still need to grab the error state! |
| 444 | Uartris(T::dma_state().rx_errs.swap(0, Ordering::Relaxed) as u32) | 466 | Uartris(self.dma_state.rx_errs.swap(0, Ordering::Relaxed) as u32) |
| 445 | } | 467 | } |
| 446 | Either::Second(e) => { | 468 | Either::Second(e) => { |
| 447 | // We're here because we errored, which means this is the error that | 469 | // We're here because we errored, which means this is the error that |
| @@ -521,8 +543,8 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { | |||
| 521 | ) -> Result<usize, ReadToBreakError> { | 543 | ) -> Result<usize, ReadToBreakError> { |
| 522 | // clear error flags before we drain the fifo. errors that have accumulated | 544 | // clear error flags before we drain the fifo. errors that have accumulated |
| 523 | // in the flags will also be present in the fifo. | 545 | // in the flags will also be present in the fifo. |
| 524 | T::dma_state().rx_errs.store(0, Ordering::Relaxed); | 546 | self.dma_state.rx_errs.store(0, Ordering::Relaxed); |
| 525 | T::regs().uarticr().write(|w| { | 547 | self.info.regs.uarticr().write(|w| { |
| 526 | w.set_oeic(true); | 548 | w.set_oeic(true); |
| 527 | w.set_beic(true); | 549 | w.set_beic(true); |
| 528 | w.set_peic(true); | 550 | w.set_peic(true); |
| @@ -555,13 +577,13 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { | |||
| 555 | // interrupt flags will have been raised, and those will be picked up immediately | 577 | // interrupt flags will have been raised, and those will be picked up immediately |
| 556 | // by the interrupt handler. | 578 | // by the interrupt handler. |
| 557 | let ch = self.rx_dma.as_mut().unwrap(); | 579 | let ch = self.rx_dma.as_mut().unwrap(); |
| 558 | T::regs().uartimsc().write_set(|w| { | 580 | self.info.regs.uartimsc().write_set(|w| { |
| 559 | w.set_oeim(true); | 581 | w.set_oeim(true); |
| 560 | w.set_beim(true); | 582 | w.set_beim(true); |
| 561 | w.set_peim(true); | 583 | w.set_peim(true); |
| 562 | w.set_feim(true); | 584 | w.set_feim(true); |
| 563 | }); | 585 | }); |
| 564 | T::regs().uartdmacr().write_set(|reg| { | 586 | self.info.regs.uartdmacr().write_set(|reg| { |
| 565 | reg.set_rxdmae(true); | 587 | reg.set_rxdmae(true); |
| 566 | reg.set_dmaonerr(true); | 588 | reg.set_dmaonerr(true); |
| 567 | }); | 589 | }); |
| @@ -572,9 +594,9 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { | |||
| 572 | // is held across an await and makes the future non-Send. | 594 | // is held across an await and makes the future non-Send. |
| 573 | crate::dma::read( | 595 | crate::dma::read( |
| 574 | ch.reborrow(), | 596 | ch.reborrow(), |
| 575 | T::regs().uartdr().as_ptr() as *const _, | 597 | self.info.regs.uartdr().as_ptr() as *const _, |
| 576 | sbuffer, | 598 | sbuffer, |
| 577 | T::RX_DREQ.into(), | 599 | self.info.rx_dreq.into(), |
| 578 | ) | 600 | ) |
| 579 | }; | 601 | }; |
| 580 | 602 | ||
| @@ -582,8 +604,8 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { | |||
| 582 | let transfer_result = select( | 604 | let transfer_result = select( |
| 583 | transfer, | 605 | transfer, |
| 584 | poll_fn(|cx| { | 606 | poll_fn(|cx| { |
| 585 | T::dma_state().rx_err_waker.register(cx.waker()); | 607 | self.dma_state.rx_err_waker.register(cx.waker()); |
| 586 | match T::dma_state().rx_errs.swap(0, Ordering::Relaxed) { | 608 | match self.dma_state.rx_errs.swap(0, Ordering::Relaxed) { |
| 587 | 0 => Poll::Pending, | 609 | 0 => Poll::Pending, |
| 588 | e => Poll::Ready(Uartris(e as u32)), | 610 | e => Poll::Ready(Uartris(e as u32)), |
| 589 | } | 611 | } |
| @@ -596,7 +618,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { | |||
| 596 | Either::First(()) => { | 618 | Either::First(()) => { |
| 597 | // We're here because the DMA finished, BUT if an error occurred on the LAST | 619 | // We're here because the DMA finished, BUT if an error occurred on the LAST |
| 598 | // byte, then we may still need to grab the error state! | 620 | // byte, then we may still need to grab the error state! |
| 599 | Uartris(T::dma_state().rx_errs.swap(0, Ordering::Relaxed) as u32) | 621 | Uartris(self.dma_state.rx_errs.swap(0, Ordering::Relaxed) as u32) |
| 600 | } | 622 | } |
| 601 | Either::Second(e) => { | 623 | Either::Second(e) => { |
| 602 | // We're here because we errored, which means this is the error that | 624 | // We're here because we errored, which means this is the error that |
| @@ -635,7 +657,7 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { | |||
| 635 | continue; | 657 | continue; |
| 636 | } | 658 | } |
| 637 | 659 | ||
| 638 | let regs = T::regs(); | 660 | let regs = self.info.regs; |
| 639 | let all_full = next_addr == eval; | 661 | let all_full = next_addr == eval; |
| 640 | 662 | ||
| 641 | // NOTE: This is off label usage of RSR! See the issue below for | 663 | // NOTE: This is off label usage of RSR! See the issue below for |
| @@ -685,9 +707,9 @@ impl<'d, T: Instance> UartRx<'d, T, Async> { | |||
| 685 | } | 707 | } |
| 686 | } | 708 | } |
| 687 | 709 | ||
| 688 | impl<'d, T: Instance> Uart<'d, T, Blocking> { | 710 | impl<'d> Uart<'d, Blocking> { |
| 689 | /// Create a new UART without hardware flow control | 711 | /// Create a new UART without hardware flow control |
| 690 | pub fn new_blocking( | 712 | pub fn new_blocking<T: Instance>( |
| 691 | uart: Peri<'d, T>, | 713 | uart: Peri<'d, T>, |
| 692 | tx: Peri<'d, impl TxPin<T>>, | 714 | tx: Peri<'d, impl TxPin<T>>, |
| 693 | rx: Peri<'d, impl RxPin<T>>, | 715 | rx: Peri<'d, impl RxPin<T>>, |
| @@ -697,7 +719,7 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> { | |||
| 697 | } | 719 | } |
| 698 | 720 | ||
| 699 | /// Create a new UART with hardware flow control (RTS/CTS) | 721 | /// Create a new UART with hardware flow control (RTS/CTS) |
| 700 | pub fn new_with_rtscts_blocking( | 722 | pub fn new_with_rtscts_blocking<T: Instance>( |
| 701 | uart: Peri<'d, T>, | 723 | uart: Peri<'d, T>, |
| 702 | tx: Peri<'d, impl TxPin<T>>, | 724 | tx: Peri<'d, impl TxPin<T>>, |
| 703 | rx: Peri<'d, impl RxPin<T>>, | 725 | rx: Peri<'d, impl RxPin<T>>, |
| @@ -720,24 +742,30 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> { | |||
| 720 | 742 | ||
| 721 | /// Convert this uart instance into a buffered uart using the provided | 743 | /// Convert this uart instance into a buffered uart using the provided |
| 722 | /// irq, transmit and receive buffers. | 744 | /// irq, transmit and receive buffers. |
| 723 | pub fn into_buffered( | 745 | pub fn into_buffered<T: Instance>( |
| 724 | self, | 746 | self, |
| 725 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 747 | _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| 726 | tx_buffer: &'d mut [u8], | 748 | tx_buffer: &'d mut [u8], |
| 727 | rx_buffer: &'d mut [u8], | 749 | rx_buffer: &'d mut [u8], |
| 728 | ) -> BufferedUart<'d, T> { | 750 | ) -> BufferedUart { |
| 729 | buffered::init_buffers::<T>(irq, Some(tx_buffer), Some(rx_buffer)); | 751 | buffered::init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), Some(rx_buffer)); |
| 730 | 752 | ||
| 731 | BufferedUart { | 753 | BufferedUart { |
| 732 | rx: BufferedUartRx { phantom: PhantomData }, | 754 | rx: BufferedUartRx { |
| 733 | tx: BufferedUartTx { phantom: PhantomData }, | 755 | info: T::info(), |
| 756 | state: T::buffered_state(), | ||
| 757 | }, | ||
| 758 | tx: BufferedUartTx { | ||
| 759 | info: T::info(), | ||
| 760 | state: T::buffered_state(), | ||
| 761 | }, | ||
| 734 | } | 762 | } |
| 735 | } | 763 | } |
| 736 | } | 764 | } |
| 737 | 765 | ||
| 738 | impl<'d, T: Instance> Uart<'d, T, Async> { | 766 | impl<'d> Uart<'d, Async> { |
| 739 | /// Create a new DMA enabled UART without hardware flow control | 767 | /// Create a new DMA enabled UART without hardware flow control |
| 740 | pub fn new( | 768 | pub fn new<T: Instance>( |
| 741 | uart: Peri<'d, T>, | 769 | uart: Peri<'d, T>, |
| 742 | tx: Peri<'d, impl TxPin<T>>, | 770 | tx: Peri<'d, impl TxPin<T>>, |
| 743 | rx: Peri<'d, impl RxPin<T>>, | 771 | rx: Peri<'d, impl RxPin<T>>, |
| @@ -760,7 +788,7 @@ impl<'d, T: Instance> Uart<'d, T, Async> { | |||
| 760 | } | 788 | } |
| 761 | 789 | ||
| 762 | /// Create a new DMA enabled UART with hardware flow control (RTS/CTS) | 790 | /// Create a new DMA enabled UART with hardware flow control (RTS/CTS) |
| 763 | pub fn new_with_rtscts( | 791 | pub fn new_with_rtscts<T: Instance>( |
| 764 | uart: Peri<'d, T>, | 792 | uart: Peri<'d, T>, |
| 765 | tx: Peri<'d, impl TxPin<T>>, | 793 | tx: Peri<'d, impl TxPin<T>>, |
| 766 | rx: Peri<'d, impl RxPin<T>>, | 794 | rx: Peri<'d, impl RxPin<T>>, |
| @@ -785,8 +813,8 @@ impl<'d, T: Instance> Uart<'d, T, Async> { | |||
| 785 | } | 813 | } |
| 786 | } | 814 | } |
| 787 | 815 | ||
| 788 | impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { | 816 | impl<'d, M: Mode> Uart<'d, M> { |
| 789 | fn new_inner( | 817 | fn new_inner<T: Instance>( |
| 790 | _uart: Peri<'d, T>, | 818 | _uart: Peri<'d, T>, |
| 791 | mut tx: Peri<'d, AnyPin>, | 819 | mut tx: Peri<'d, AnyPin>, |
| 792 | mut rx: Peri<'d, AnyPin>, | 820 | mut rx: Peri<'d, AnyPin>, |
| @@ -798,6 +826,7 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { | |||
| 798 | config: Config, | 826 | config: Config, |
| 799 | ) -> Self { | 827 | ) -> Self { |
| 800 | Self::init( | 828 | Self::init( |
| 829 | T::info(), | ||
| 801 | Some(tx.reborrow()), | 830 | Some(tx.reborrow()), |
| 802 | Some(rx.reborrow()), | 831 | Some(rx.reborrow()), |
| 803 | rts.as_mut().map(|x| x.reborrow()), | 832 | rts.as_mut().map(|x| x.reborrow()), |
| @@ -806,19 +835,20 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { | |||
| 806 | ); | 835 | ); |
| 807 | 836 | ||
| 808 | Self { | 837 | Self { |
| 809 | tx: UartTx::new_inner(tx_dma), | 838 | tx: UartTx::new_inner::<T>(tx_dma), |
| 810 | rx: UartRx::new_inner(has_irq, rx_dma), | 839 | rx: UartRx::new_inner::<T>(has_irq, rx_dma), |
| 811 | } | 840 | } |
| 812 | } | 841 | } |
| 813 | 842 | ||
| 814 | fn init( | 843 | fn init( |
| 844 | info: &Info, | ||
| 815 | tx: Option<Peri<'_, AnyPin>>, | 845 | tx: Option<Peri<'_, AnyPin>>, |
| 816 | rx: Option<Peri<'_, AnyPin>>, | 846 | rx: Option<Peri<'_, AnyPin>>, |
| 817 | rts: Option<Peri<'_, AnyPin>>, | 847 | rts: Option<Peri<'_, AnyPin>>, |
| 818 | cts: Option<Peri<'_, AnyPin>>, | 848 | cts: Option<Peri<'_, AnyPin>>, |
| 819 | config: Config, | 849 | config: Config, |
| 820 | ) { | 850 | ) { |
| 821 | let r = T::regs(); | 851 | let r = info.regs; |
| 822 | if let Some(pin) = &tx { | 852 | if let Some(pin) = &tx { |
| 823 | let funcsel = { | 853 | let funcsel = { |
| 824 | let pin_number = ((pin.gpio().as_ptr() as u32) & 0x1FF) / 8; | 854 | let pin_number = ((pin.gpio().as_ptr() as u32) & 0x1FF) / 8; |
| @@ -896,7 +926,7 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { | |||
| 896 | }); | 926 | }); |
| 897 | } | 927 | } |
| 898 | 928 | ||
| 899 | Self::set_baudrate_inner(config.baudrate); | 929 | Self::set_baudrate_inner(info, config.baudrate); |
| 900 | 930 | ||
| 901 | let (pen, eps) = match config.parity { | 931 | let (pen, eps) = match config.parity { |
| 902 | Parity::ParityNone => (false, false), | 932 | Parity::ParityNone => (false, false), |
| @@ -926,8 +956,8 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { | |||
| 926 | }); | 956 | }); |
| 927 | } | 957 | } |
| 928 | 958 | ||
| 929 | fn lcr_modify<R>(f: impl FnOnce(&mut crate::pac::uart::regs::UartlcrH) -> R) -> R { | 959 | fn lcr_modify<R>(info: &Info, f: impl FnOnce(&mut crate::pac::uart::regs::UartlcrH) -> R) -> R { |
| 930 | let r = T::regs(); | 960 | let r = info.regs; |
| 931 | 961 | ||
| 932 | // Notes from PL011 reference manual: | 962 | // Notes from PL011 reference manual: |
| 933 | // | 963 | // |
| @@ -978,11 +1008,11 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { | |||
| 978 | 1008 | ||
| 979 | /// sets baudrate on runtime | 1009 | /// sets baudrate on runtime |
| 980 | pub fn set_baudrate(&mut self, baudrate: u32) { | 1010 | pub fn set_baudrate(&mut self, baudrate: u32) { |
| 981 | Self::set_baudrate_inner(baudrate); | 1011 | Self::set_baudrate_inner(self.tx.info, baudrate); |
| 982 | } | 1012 | } |
| 983 | 1013 | ||
| 984 | fn set_baudrate_inner(baudrate: u32) { | 1014 | fn set_baudrate_inner(info: &Info, baudrate: u32) { |
| 985 | let r = T::regs(); | 1015 | let r = info.regs; |
| 986 | 1016 | ||
| 987 | let clk_base = crate::clocks::clk_peri_freq(); | 1017 | let clk_base = crate::clocks::clk_peri_freq(); |
| 988 | 1018 | ||
| @@ -1002,11 +1032,11 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { | |||
| 1002 | r.uartibrd().write_value(pac::uart::regs::Uartibrd(baud_ibrd)); | 1032 | r.uartibrd().write_value(pac::uart::regs::Uartibrd(baud_ibrd)); |
| 1003 | r.uartfbrd().write_value(pac::uart::regs::Uartfbrd(baud_fbrd)); | 1033 | r.uartfbrd().write_value(pac::uart::regs::Uartfbrd(baud_fbrd)); |
| 1004 | 1034 | ||
| 1005 | Self::lcr_modify(|_| {}); | 1035 | Self::lcr_modify(info, |_| {}); |
| 1006 | } | 1036 | } |
| 1007 | } | 1037 | } |
| 1008 | 1038 | ||
| 1009 | impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { | 1039 | impl<'d, M: Mode> Uart<'d, M> { |
| 1010 | /// Transmit the provided buffer blocking execution until done. | 1040 | /// Transmit the provided buffer blocking execution until done. |
| 1011 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 1041 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 1012 | self.tx.blocking_write(buffer) | 1042 | self.tx.blocking_write(buffer) |
| @@ -1034,19 +1064,19 @@ impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { | |||
| 1034 | 1064 | ||
| 1035 | /// Split the Uart into a transmitter and receiver, which is particularly | 1065 | /// Split the Uart into a transmitter and receiver, which is particularly |
| 1036 | /// useful when having two tasks correlating to transmitting and receiving. | 1066 | /// useful when having two tasks correlating to transmitting and receiving. |
| 1037 | pub fn split(self) -> (UartTx<'d, T, M>, UartRx<'d, T, M>) { | 1067 | pub fn split(self) -> (UartTx<'d, M>, UartRx<'d, M>) { |
| 1038 | (self.tx, self.rx) | 1068 | (self.tx, self.rx) |
| 1039 | } | 1069 | } |
| 1040 | 1070 | ||
| 1041 | /// Split the Uart into a transmitter and receiver by mutable reference, | 1071 | /// Split the Uart into a transmitter and receiver by mutable reference, |
| 1042 | /// which is particularly useful when having two tasks correlating to | 1072 | /// which is particularly useful when having two tasks correlating to |
| 1043 | /// transmitting and receiving. | 1073 | /// transmitting and receiving. |
| 1044 | pub fn split_ref(&mut self) -> (&mut UartTx<'d, T, M>, &mut UartRx<'d, T, M>) { | 1074 | pub fn split_ref(&mut self) -> (&mut UartTx<'d, M>, &mut UartRx<'d, M>) { |
| 1045 | (&mut self.tx, &mut self.rx) | 1075 | (&mut self.tx, &mut self.rx) |
| 1046 | } | 1076 | } |
| 1047 | } | 1077 | } |
| 1048 | 1078 | ||
| 1049 | impl<'d, T: Instance> Uart<'d, T, Async> { | 1079 | impl<'d> Uart<'d, Async> { |
| 1050 | /// Write to UART TX from the provided buffer. | 1080 | /// Write to UART TX from the provided buffer. |
| 1051 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 1081 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 1052 | self.tx.write(buffer).await | 1082 | self.tx.write(buffer).await |
| @@ -1076,10 +1106,10 @@ impl<'d, T: Instance> Uart<'d, T, Async> { | |||
| 1076 | } | 1106 | } |
| 1077 | } | 1107 | } |
| 1078 | 1108 | ||
| 1079 | impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, M> { | 1109 | impl<'d, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, M> { |
| 1080 | type Error = Error; | 1110 | type Error = Error; |
| 1081 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { | 1111 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { |
| 1082 | let r = T::regs(); | 1112 | let r = self.info.regs; |
| 1083 | if r.uartfr().read().rxfe() { | 1113 | if r.uartfr().read().rxfe() { |
| 1084 | return Err(nb::Error::WouldBlock); | 1114 | return Err(nb::Error::WouldBlock); |
| 1085 | } | 1115 | } |
| @@ -1100,11 +1130,11 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, | |||
| 1100 | } | 1130 | } |
| 1101 | } | 1131 | } |
| 1102 | 1132 | ||
| 1103 | impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for UartTx<'d, T, M> { | 1133 | impl<'d, M: Mode> embedded_hal_02::serial::Write<u8> for UartTx<'d, M> { |
| 1104 | type Error = Error; | 1134 | type Error = Error; |
| 1105 | 1135 | ||
| 1106 | fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> { | 1136 | fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> { |
| 1107 | let r = T::regs(); | 1137 | let r = self.info.regs; |
| 1108 | if r.uartfr().read().txff() { | 1138 | if r.uartfr().read().txff() { |
| 1109 | return Err(nb::Error::WouldBlock); | 1139 | return Err(nb::Error::WouldBlock); |
| 1110 | } | 1140 | } |
| @@ -1114,7 +1144,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for UartTx<'d, | |||
| 1114 | } | 1144 | } |
| 1115 | 1145 | ||
| 1116 | fn flush(&mut self) -> Result<(), nb::Error<Self::Error>> { | 1146 | fn flush(&mut self) -> Result<(), nb::Error<Self::Error>> { |
| 1117 | let r = T::regs(); | 1147 | let r = self.info.regs; |
| 1118 | if !r.uartfr().read().txfe() { | 1148 | if !r.uartfr().read().txfe() { |
| 1119 | return Err(nb::Error::WouldBlock); | 1149 | return Err(nb::Error::WouldBlock); |
| 1120 | } | 1150 | } |
| @@ -1122,7 +1152,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for UartTx<'d, | |||
| 1122 | } | 1152 | } |
| 1123 | } | 1153 | } |
| 1124 | 1154 | ||
| 1125 | impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T, M> { | 1155 | impl<'d, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, M> { |
| 1126 | type Error = Error; | 1156 | type Error = Error; |
| 1127 | 1157 | ||
| 1128 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { | 1158 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { |
| @@ -1134,7 +1164,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for | |||
| 1134 | } | 1164 | } |
| 1135 | } | 1165 | } |
| 1136 | 1166 | ||
| 1137 | impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for Uart<'d, T, M> { | 1167 | impl<'d, M: Mode> embedded_hal_02::serial::Read<u8> for Uart<'d, M> { |
| 1138 | type Error = Error; | 1168 | type Error = Error; |
| 1139 | 1169 | ||
| 1140 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { | 1170 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { |
| @@ -1142,7 +1172,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Read<u8> for Uart<'d, T, | |||
| 1142 | } | 1172 | } |
| 1143 | } | 1173 | } |
| 1144 | 1174 | ||
| 1145 | impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for Uart<'d, T, M> { | 1175 | impl<'d, M: Mode> embedded_hal_02::serial::Write<u8> for Uart<'d, M> { |
| 1146 | type Error = Error; | 1176 | type Error = Error; |
| 1147 | 1177 | ||
| 1148 | fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> { | 1178 | fn write(&mut self, word: u8) -> Result<(), nb::Error<Self::Error>> { |
| @@ -1154,7 +1184,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::serial::Write<u8> for Uart<'d, T | |||
| 1154 | } | 1184 | } |
| 1155 | } | 1185 | } |
| 1156 | 1186 | ||
| 1157 | impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T, M> { | 1187 | impl<'d, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, M> { |
| 1158 | type Error = Error; | 1188 | type Error = Error; |
| 1159 | 1189 | ||
| 1160 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { | 1190 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { |
| @@ -1177,21 +1207,21 @@ impl embedded_hal_nb::serial::Error for Error { | |||
| 1177 | } | 1207 | } |
| 1178 | } | 1208 | } |
| 1179 | 1209 | ||
| 1180 | impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for UartRx<'d, T, M> { | 1210 | impl<'d, M: Mode> embedded_hal_nb::serial::ErrorType for UartRx<'d, M> { |
| 1181 | type Error = Error; | 1211 | type Error = Error; |
| 1182 | } | 1212 | } |
| 1183 | 1213 | ||
| 1184 | impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for UartTx<'d, T, M> { | 1214 | impl<'d, M: Mode> embedded_hal_nb::serial::ErrorType for UartTx<'d, M> { |
| 1185 | type Error = Error; | 1215 | type Error = Error; |
| 1186 | } | 1216 | } |
| 1187 | 1217 | ||
| 1188 | impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::ErrorType for Uart<'d, T, M> { | 1218 | impl<'d, M: Mode> embedded_hal_nb::serial::ErrorType for Uart<'d, M> { |
| 1189 | type Error = Error; | 1219 | type Error = Error; |
| 1190 | } | 1220 | } |
| 1191 | 1221 | ||
| 1192 | impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, T, M> { | 1222 | impl<'d, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, M> { |
| 1193 | fn read(&mut self) -> nb::Result<u8, Self::Error> { | 1223 | fn read(&mut self) -> nb::Result<u8, Self::Error> { |
| 1194 | let r = T::regs(); | 1224 | let r = self.info.regs; |
| 1195 | if r.uartfr().read().rxfe() { | 1225 | if r.uartfr().read().rxfe() { |
| 1196 | return Err(nb::Error::WouldBlock); | 1226 | return Err(nb::Error::WouldBlock); |
| 1197 | } | 1227 | } |
| @@ -1212,7 +1242,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, T, M | |||
| 1212 | } | 1242 | } |
| 1213 | } | 1243 | } |
| 1214 | 1244 | ||
| 1215 | impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, T, M> { | 1245 | impl<'d, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, M> { |
| 1216 | fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { | 1246 | fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { |
| 1217 | self.blocking_write(&[char]).map_err(nb::Error::Other) | 1247 | self.blocking_write(&[char]).map_err(nb::Error::Other) |
| 1218 | } | 1248 | } |
| @@ -1222,11 +1252,11 @@ impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, T, | |||
| 1222 | } | 1252 | } |
| 1223 | } | 1253 | } |
| 1224 | 1254 | ||
| 1225 | impl<'d, T: Instance> embedded_io::ErrorType for UartTx<'d, T, Blocking> { | 1255 | impl<'d> embedded_io::ErrorType for UartTx<'d, Blocking> { |
| 1226 | type Error = Error; | 1256 | type Error = Error; |
| 1227 | } | 1257 | } |
| 1228 | 1258 | ||
| 1229 | impl<'d, T: Instance> embedded_io::Write for UartTx<'d, T, Blocking> { | 1259 | impl<'d> embedded_io::Write for UartTx<'d, Blocking> { |
| 1230 | fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 1260 | fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 1231 | self.blocking_write(buf).map(|_| buf.len()) | 1261 | self.blocking_write(buf).map(|_| buf.len()) |
| 1232 | } | 1262 | } |
| @@ -1236,13 +1266,13 @@ impl<'d, T: Instance> embedded_io::Write for UartTx<'d, T, Blocking> { | |||
| 1236 | } | 1266 | } |
| 1237 | } | 1267 | } |
| 1238 | 1268 | ||
| 1239 | impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Read for Uart<'d, T, M> { | 1269 | impl<'d, M: Mode> embedded_hal_nb::serial::Read for Uart<'d, M> { |
| 1240 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { | 1270 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { |
| 1241 | embedded_hal_02::serial::Read::read(&mut self.rx) | 1271 | embedded_hal_02::serial::Read::read(&mut self.rx) |
| 1242 | } | 1272 | } |
| 1243 | } | 1273 | } |
| 1244 | 1274 | ||
| 1245 | impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, T, M> { | 1275 | impl<'d, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, M> { |
| 1246 | fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { | 1276 | fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { |
| 1247 | self.blocking_write(&[char]).map_err(nb::Error::Other) | 1277 | self.blocking_write(&[char]).map_err(nb::Error::Other) |
| 1248 | } | 1278 | } |
| @@ -1252,11 +1282,11 @@ impl<'d, T: Instance, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, T, M> | |||
| 1252 | } | 1282 | } |
| 1253 | } | 1283 | } |
| 1254 | 1284 | ||
| 1255 | impl<'d, T: Instance> embedded_io::ErrorType for Uart<'d, T, Blocking> { | 1285 | impl<'d> embedded_io::ErrorType for Uart<'d, Blocking> { |
| 1256 | type Error = Error; | 1286 | type Error = Error; |
| 1257 | } | 1287 | } |
| 1258 | 1288 | ||
| 1259 | impl<'d, T: Instance> embedded_io::Write for Uart<'d, T, Blocking> { | 1289 | impl<'d> embedded_io::Write for Uart<'d, Blocking> { |
| 1260 | fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 1290 | fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 1261 | self.blocking_write(buf).map(|_| buf.len()) | 1291 | self.blocking_write(buf).map(|_| buf.len()) |
| 1262 | } | 1292 | } |
| @@ -1266,13 +1296,17 @@ impl<'d, T: Instance> embedded_io::Write for Uart<'d, T, Blocking> { | |||
| 1266 | } | 1296 | } |
| 1267 | } | 1297 | } |
| 1268 | 1298 | ||
| 1299 | struct Info { | ||
| 1300 | regs: pac::uart::Uart, | ||
| 1301 | tx_dreq: pac::dma::vals::TreqSel, | ||
| 1302 | rx_dreq: pac::dma::vals::TreqSel, | ||
| 1303 | interrupt: Interrupt, | ||
| 1304 | } | ||
| 1305 | |||
| 1269 | trait SealedMode {} | 1306 | trait SealedMode {} |
| 1270 | 1307 | ||
| 1271 | trait SealedInstance { | 1308 | trait SealedInstance { |
| 1272 | const TX_DREQ: pac::dma::vals::TreqSel; | 1309 | fn info() -> &'static Info; |
| 1273 | const RX_DREQ: pac::dma::vals::TreqSel; | ||
| 1274 | |||
| 1275 | fn regs() -> pac::uart::Uart; | ||
| 1276 | 1310 | ||
| 1277 | fn buffered_state() -> &'static buffered::State; | 1311 | fn buffered_state() -> &'static buffered::State; |
| 1278 | 1312 | ||
| @@ -1308,11 +1342,14 @@ pub trait Instance: SealedInstance + PeripheralType { | |||
| 1308 | macro_rules! impl_instance { | 1342 | macro_rules! impl_instance { |
| 1309 | ($inst:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => { | 1343 | ($inst:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => { |
| 1310 | impl SealedInstance for peripherals::$inst { | 1344 | impl SealedInstance for peripherals::$inst { |
| 1311 | const TX_DREQ: pac::dma::vals::TreqSel = $tx_dreq; | 1345 | fn info() -> &'static Info { |
| 1312 | const RX_DREQ: pac::dma::vals::TreqSel = $rx_dreq; | 1346 | static INFO: Info = Info { |
| 1313 | 1347 | regs: pac::$inst, | |
| 1314 | fn regs() -> pac::uart::Uart { | 1348 | tx_dreq: $tx_dreq, |
| 1315 | pac::$inst | 1349 | rx_dreq: $rx_dreq, |
| 1350 | interrupt: crate::interrupt::typelevel::$irq::IRQ, | ||
| 1351 | }; | ||
| 1352 | &INFO | ||
| 1316 | } | 1353 | } |
| 1317 | 1354 | ||
| 1318 | fn buffered_state() -> &'static buffered::State { | 1355 | fn buffered_state() -> &'static buffered::State { |
