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