diff options
Diffstat (limited to 'embassy-rp/src/uart/mod.rs')
| -rw-r--r-- | embassy-rp/src/uart/mod.rs | 300 |
1 files changed, 171 insertions, 129 deletions
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 { |
