diff options
| author | Ulf Lilleengen <[email protected]> | 2023-12-19 11:26:08 +0100 |
|---|---|---|
| committer | Ulf Lilleengen <[email protected]> | 2023-12-19 11:26:08 +0100 |
| commit | 486b67e89522d7e36f6b1078ff8018d64447b39e (patch) | |
| tree | c21c2012318dee216026d8b4457082a23ad6eb62 /embassy-rp/src | |
| parent | e45e3e76b564b0589a24c1ca56599640238fd672 (diff) | |
docs: document spi, rtc and rest of uart for embassy-rp
Diffstat (limited to 'embassy-rp/src')
| -rw-r--r-- | embassy-rp/src/pwm.rs | 5 | ||||
| -rw-r--r-- | embassy-rp/src/rtc/mod.rs | 1 | ||||
| -rw-r--r-- | embassy-rp/src/spi.rs | 31 | ||||
| -rw-r--r-- | embassy-rp/src/uart/mod.rs | 48 |
4 files changed, 83 insertions, 2 deletions
diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index 516b8254b..5b96557a3 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs | |||
| @@ -61,9 +61,13 @@ impl Default for Config { | |||
| 61 | } | 61 | } |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | /// PWM input mode. | ||
| 64 | pub enum InputMode { | 65 | pub enum InputMode { |
| 66 | /// Level mode. | ||
| 65 | Level, | 67 | Level, |
| 68 | /// Rising edge mode. | ||
| 66 | RisingEdge, | 69 | RisingEdge, |
| 70 | /// Falling edge mode. | ||
| 67 | FallingEdge, | 71 | FallingEdge, |
| 68 | } | 72 | } |
| 69 | 73 | ||
| @@ -77,6 +81,7 @@ impl From<InputMode> for Divmode { | |||
| 77 | } | 81 | } |
| 78 | } | 82 | } |
| 79 | 83 | ||
| 84 | /// PWM driver. | ||
| 80 | pub struct Pwm<'d, T: Channel> { | 85 | pub struct Pwm<'d, T: Channel> { |
| 81 | inner: PeripheralRef<'d, T>, | 86 | inner: PeripheralRef<'d, T>, |
| 82 | pin_a: Option<PeripheralRef<'d, AnyPin>>, | 87 | pin_a: Option<PeripheralRef<'d, AnyPin>>, |
diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs index 60ca8627b..c3df3ee57 100644 --- a/embassy-rp/src/rtc/mod.rs +++ b/embassy-rp/src/rtc/mod.rs | |||
| @@ -194,6 +194,7 @@ mod sealed { | |||
| 194 | } | 194 | } |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | /// RTC peripheral instance. | ||
| 197 | pub trait Instance: sealed::Instance {} | 198 | pub trait Instance: sealed::Instance {} |
| 198 | 199 | ||
| 199 | impl sealed::Instance for crate::peripherals::RTC { | 200 | impl sealed::Instance for crate::peripherals::RTC { |
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index 6ba985a65..a2a22ffe5 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs | |||
| @@ -11,6 +11,7 @@ use crate::gpio::sealed::Pin as _; | |||
| 11 | use crate::gpio::{AnyPin, Pin as GpioPin}; | 11 | use crate::gpio::{AnyPin, Pin as GpioPin}; |
| 12 | use crate::{pac, peripherals, Peripheral}; | 12 | use crate::{pac, peripherals, Peripheral}; |
| 13 | 13 | ||
| 14 | /// SPI errors. | ||
| 14 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 15 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 15 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 16 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 16 | #[non_exhaustive] | 17 | #[non_exhaustive] |
| @@ -18,11 +19,15 @@ pub enum Error { | |||
| 18 | // No errors for now | 19 | // No errors for now |
| 19 | } | 20 | } |
| 20 | 21 | ||
| 22 | /// SPI configuration. | ||
| 21 | #[non_exhaustive] | 23 | #[non_exhaustive] |
| 22 | #[derive(Clone)] | 24 | #[derive(Clone)] |
| 23 | pub struct Config { | 25 | pub struct Config { |
| 26 | /// Frequency. | ||
| 24 | pub frequency: u32, | 27 | pub frequency: u32, |
| 28 | /// Phase. | ||
| 25 | pub phase: Phase, | 29 | pub phase: Phase, |
| 30 | /// Polarity. | ||
| 26 | pub polarity: Polarity, | 31 | pub polarity: Polarity, |
| 27 | } | 32 | } |
| 28 | 33 | ||
| @@ -36,6 +41,7 @@ impl Default for Config { | |||
| 36 | } | 41 | } |
| 37 | } | 42 | } |
| 38 | 43 | ||
| 44 | /// SPI driver. | ||
| 39 | pub struct Spi<'d, T: Instance, M: Mode> { | 45 | pub struct Spi<'d, T: Instance, M: Mode> { |
| 40 | inner: PeripheralRef<'d, T>, | 46 | inner: PeripheralRef<'d, T>, |
| 41 | tx_dma: Option<PeripheralRef<'d, AnyChannel>>, | 47 | tx_dma: Option<PeripheralRef<'d, AnyChannel>>, |
| @@ -119,6 +125,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 119 | } | 125 | } |
| 120 | } | 126 | } |
| 121 | 127 | ||
| 128 | /// Write data to SPI blocking execution until done. | ||
| 122 | pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> { | 129 | pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> { |
| 123 | let p = self.inner.regs(); | 130 | let p = self.inner.regs(); |
| 124 | for &b in data { | 131 | for &b in data { |
| @@ -131,6 +138,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 131 | Ok(()) | 138 | Ok(()) |
| 132 | } | 139 | } |
| 133 | 140 | ||
| 141 | /// Transfer data in place to SPI blocking execution until done. | ||
| 134 | pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Error> { | 142 | pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Error> { |
| 135 | let p = self.inner.regs(); | 143 | let p = self.inner.regs(); |
| 136 | for b in data { | 144 | for b in data { |
| @@ -143,6 +151,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 143 | Ok(()) | 151 | Ok(()) |
| 144 | } | 152 | } |
| 145 | 153 | ||
| 154 | /// Read data from SPI blocking execution until done. | ||
| 146 | pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<(), Error> { | 155 | pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<(), Error> { |
| 147 | let p = self.inner.regs(); | 156 | let p = self.inner.regs(); |
| 148 | for b in data { | 157 | for b in data { |
| @@ -155,6 +164,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 155 | Ok(()) | 164 | Ok(()) |
| 156 | } | 165 | } |
| 157 | 166 | ||
| 167 | /// Transfer data to SPI blocking execution until done. | ||
| 158 | pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> { | 168 | pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> { |
| 159 | let p = self.inner.regs(); | 169 | let p = self.inner.regs(); |
| 160 | let len = read.len().max(write.len()); | 170 | let len = read.len().max(write.len()); |
| @@ -172,12 +182,14 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 172 | Ok(()) | 182 | Ok(()) |
| 173 | } | 183 | } |
| 174 | 184 | ||
| 185 | /// Block execution until SPI is done. | ||
| 175 | pub fn flush(&mut self) -> Result<(), Error> { | 186 | pub fn flush(&mut self) -> Result<(), Error> { |
| 176 | let p = self.inner.regs(); | 187 | let p = self.inner.regs(); |
| 177 | while p.sr().read().bsy() {} | 188 | while p.sr().read().bsy() {} |
| 178 | Ok(()) | 189 | Ok(()) |
| 179 | } | 190 | } |
| 180 | 191 | ||
| 192 | /// Set SPI frequency. | ||
| 181 | pub fn set_frequency(&mut self, freq: u32) { | 193 | pub fn set_frequency(&mut self, freq: u32) { |
| 182 | let (presc, postdiv) = calc_prescs(freq); | 194 | let (presc, postdiv) = calc_prescs(freq); |
| 183 | let p = self.inner.regs(); | 195 | let p = self.inner.regs(); |
| @@ -196,6 +208,7 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 196 | } | 208 | } |
| 197 | 209 | ||
| 198 | impl<'d, T: Instance> Spi<'d, T, Blocking> { | 210 | impl<'d, T: Instance> Spi<'d, T, Blocking> { |
| 211 | /// Create an SPI driver in blocking mode. | ||
| 199 | pub fn new_blocking( | 212 | pub fn new_blocking( |
| 200 | inner: impl Peripheral<P = T> + 'd, | 213 | inner: impl Peripheral<P = T> + 'd, |
| 201 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, | 214 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, |
| @@ -216,6 +229,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { | |||
| 216 | ) | 229 | ) |
| 217 | } | 230 | } |
| 218 | 231 | ||
| 232 | /// Create an SPI driver in blocking mode supporting writes only. | ||
| 219 | pub fn new_blocking_txonly( | 233 | pub fn new_blocking_txonly( |
| 220 | inner: impl Peripheral<P = T> + 'd, | 234 | inner: impl Peripheral<P = T> + 'd, |
| 221 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, | 235 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, |
| @@ -235,6 +249,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { | |||
| 235 | ) | 249 | ) |
| 236 | } | 250 | } |
| 237 | 251 | ||
| 252 | /// Create an SPI driver in blocking mode supporting reads only. | ||
| 238 | pub fn new_blocking_rxonly( | 253 | pub fn new_blocking_rxonly( |
| 239 | inner: impl Peripheral<P = T> + 'd, | 254 | inner: impl Peripheral<P = T> + 'd, |
| 240 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, | 255 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, |
| @@ -256,6 +271,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { | |||
| 256 | } | 271 | } |
| 257 | 272 | ||
| 258 | impl<'d, T: Instance> Spi<'d, T, Async> { | 273 | impl<'d, T: Instance> Spi<'d, T, Async> { |
| 274 | /// Create an SPI driver in async mode supporting DMA operations. | ||
| 259 | pub fn new( | 275 | pub fn new( |
| 260 | inner: impl Peripheral<P = T> + 'd, | 276 | inner: impl Peripheral<P = T> + 'd, |
| 261 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, | 277 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, |
| @@ -278,6 +294,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 278 | ) | 294 | ) |
| 279 | } | 295 | } |
| 280 | 296 | ||
| 297 | /// Create an SPI driver in async mode supporting DMA write operations only. | ||
| 281 | pub fn new_txonly( | 298 | pub fn new_txonly( |
| 282 | inner: impl Peripheral<P = T> + 'd, | 299 | inner: impl Peripheral<P = T> + 'd, |
| 283 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, | 300 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, |
| @@ -298,6 +315,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 298 | ) | 315 | ) |
| 299 | } | 316 | } |
| 300 | 317 | ||
| 318 | /// Create an SPI driver in async mode supporting DMA read operations only. | ||
| 301 | pub fn new_rxonly( | 319 | pub fn new_rxonly( |
| 302 | inner: impl Peripheral<P = T> + 'd, | 320 | inner: impl Peripheral<P = T> + 'd, |
| 303 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, | 321 | clk: impl Peripheral<P = impl ClkPin<T> + 'd> + 'd, |
| @@ -318,6 +336,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 318 | ) | 336 | ) |
| 319 | } | 337 | } |
| 320 | 338 | ||
| 339 | /// Write data to SPI using DMA. | ||
| 321 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 340 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 322 | let tx_ch = self.tx_dma.as_mut().unwrap(); | 341 | let tx_ch = self.tx_dma.as_mut().unwrap(); |
| 323 | let tx_transfer = unsafe { | 342 | let tx_transfer = unsafe { |
| @@ -340,6 +359,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 340 | Ok(()) | 359 | Ok(()) |
| 341 | } | 360 | } |
| 342 | 361 | ||
| 362 | /// Read data from SPI using DMA. | ||
| 343 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | 363 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { |
| 344 | // Start RX first. Transfer starts when TX starts, if RX | 364 | // Start RX first. Transfer starts when TX starts, if RX |
| 345 | // is not started yet we might lose bytes. | 365 | // is not started yet we might lose bytes. |
| @@ -365,10 +385,12 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 365 | Ok(()) | 385 | Ok(()) |
| 366 | } | 386 | } |
| 367 | 387 | ||
| 388 | /// Transfer data to SPI using DMA. | ||
| 368 | pub async fn transfer(&mut self, rx_buffer: &mut [u8], tx_buffer: &[u8]) -> Result<(), Error> { | 389 | pub async fn transfer(&mut self, rx_buffer: &mut [u8], tx_buffer: &[u8]) -> Result<(), Error> { |
| 369 | self.transfer_inner(rx_buffer, tx_buffer).await | 390 | self.transfer_inner(rx_buffer, tx_buffer).await |
| 370 | } | 391 | } |
| 371 | 392 | ||
| 393 | /// Transfer data in place to SPI using DMA. | ||
| 372 | pub async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> { | 394 | pub async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Error> { |
| 373 | self.transfer_inner(words, words).await | 395 | self.transfer_inner(words, words).await |
| 374 | } | 396 | } |
| @@ -434,7 +456,10 @@ mod sealed { | |||
| 434 | } | 456 | } |
| 435 | } | 457 | } |
| 436 | 458 | ||
| 459 | /// Mode. | ||
| 437 | pub trait Mode: sealed::Mode {} | 460 | pub trait Mode: sealed::Mode {} |
| 461 | |||
| 462 | /// SPI instance trait. | ||
| 438 | pub trait Instance: sealed::Instance {} | 463 | pub trait Instance: sealed::Instance {} |
| 439 | 464 | ||
| 440 | macro_rules! impl_instance { | 465 | macro_rules! impl_instance { |
| @@ -454,9 +479,13 @@ macro_rules! impl_instance { | |||
| 454 | impl_instance!(SPI0, Spi0, 16, 17); | 479 | impl_instance!(SPI0, Spi0, 16, 17); |
| 455 | impl_instance!(SPI1, Spi1, 18, 19); | 480 | impl_instance!(SPI1, Spi1, 18, 19); |
| 456 | 481 | ||
| 482 | /// CLK pin. | ||
| 457 | pub trait ClkPin<T: Instance>: GpioPin {} | 483 | pub trait ClkPin<T: Instance>: GpioPin {} |
| 484 | /// CS pin. | ||
| 458 | pub trait CsPin<T: Instance>: GpioPin {} | 485 | pub trait CsPin<T: Instance>: GpioPin {} |
| 486 | /// MOSI pin. | ||
| 459 | pub trait MosiPin<T: Instance>: GpioPin {} | 487 | pub trait MosiPin<T: Instance>: GpioPin {} |
| 488 | /// MISO pin. | ||
| 460 | pub trait MisoPin<T: Instance>: GpioPin {} | 489 | pub trait MisoPin<T: Instance>: GpioPin {} |
| 461 | 490 | ||
| 462 | macro_rules! impl_pin { | 491 | macro_rules! impl_pin { |
| @@ -503,7 +532,9 @@ macro_rules! impl_mode { | |||
| 503 | }; | 532 | }; |
| 504 | } | 533 | } |
| 505 | 534 | ||
| 535 | /// Blocking mode. | ||
| 506 | pub struct Blocking; | 536 | pub struct Blocking; |
| 537 | /// Async mode. | ||
| 507 | pub struct Async; | 538 | pub struct Async; |
| 508 | 539 | ||
| 509 | impl_mode!(Blocking); | 540 | impl_mode!(Blocking); |
diff --git a/embassy-rp/src/uart/mod.rs b/embassy-rp/src/uart/mod.rs index 26f21193a..32be7661d 100644 --- a/embassy-rp/src/uart/mod.rs +++ b/embassy-rp/src/uart/mod.rs | |||
| @@ -20,11 +20,16 @@ use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; | |||
| 20 | mod buffered; | 20 | mod buffered; |
| 21 | pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; | 21 | pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx}; |
| 22 | 22 | ||
| 23 | /// Word length. | ||
| 23 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | 24 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] |
| 24 | pub enum DataBits { | 25 | pub enum DataBits { |
| 26 | /// 5 bits. | ||
| 25 | DataBits5, | 27 | DataBits5, |
| 28 | /// 6 bits. | ||
| 26 | DataBits6, | 29 | DataBits6, |
| 30 | /// 7 bits. | ||
| 27 | DataBits7, | 31 | DataBits7, |
| 32 | /// 8 bits. | ||
| 28 | DataBits8, | 33 | DataBits8, |
| 29 | } | 34 | } |
| 30 | 35 | ||
| @@ -39,13 +44,18 @@ impl DataBits { | |||
| 39 | } | 44 | } |
| 40 | } | 45 | } |
| 41 | 46 | ||
| 47 | /// Parity bit. | ||
| 42 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | 48 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] |
| 43 | pub enum Parity { | 49 | pub enum Parity { |
| 50 | /// No parity. | ||
| 44 | ParityNone, | 51 | ParityNone, |
| 52 | /// Even parity. | ||
| 45 | ParityEven, | 53 | ParityEven, |
| 54 | /// Odd parity. | ||
| 46 | ParityOdd, | 55 | ParityOdd, |
| 47 | } | 56 | } |
| 48 | 57 | ||
| 58 | /// Stop bits. | ||
| 49 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | 59 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] |
| 50 | pub enum StopBits { | 60 | pub enum StopBits { |
| 51 | #[doc = "1 stop bit"] | 61 | #[doc = "1 stop bit"] |
| @@ -54,20 +64,25 @@ pub enum StopBits { | |||
| 54 | STOP2, | 64 | STOP2, |
| 55 | } | 65 | } |
| 56 | 66 | ||
| 67 | /// UART config. | ||
| 57 | #[non_exhaustive] | 68 | #[non_exhaustive] |
| 58 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | 69 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] |
| 59 | pub struct Config { | 70 | pub struct Config { |
| 71 | /// Baud rate. | ||
| 60 | pub baudrate: u32, | 72 | pub baudrate: u32, |
| 73 | /// Word length. | ||
| 61 | pub data_bits: DataBits, | 74 | pub data_bits: DataBits, |
| 75 | /// Stop bits. | ||
| 62 | pub stop_bits: StopBits, | 76 | pub stop_bits: StopBits, |
| 77 | /// Parity bit. | ||
| 63 | pub parity: Parity, | 78 | pub parity: Parity, |
| 64 | /// Invert the tx pin output | 79 | /// Invert the tx pin output |
| 65 | pub invert_tx: bool, | 80 | pub invert_tx: bool, |
| 66 | /// Invert the rx pin input | 81 | /// Invert the rx pin input |
| 67 | pub invert_rx: bool, | 82 | pub invert_rx: bool, |
| 68 | // Invert the rts pin | 83 | /// Invert the rts pin |
| 69 | pub invert_rts: bool, | 84 | pub invert_rts: bool, |
| 70 | // Invert the cts pin | 85 | /// Invert the cts pin |
| 71 | pub invert_cts: bool, | 86 | pub invert_cts: bool, |
| 72 | } | 87 | } |
| 73 | 88 | ||
| @@ -102,21 +117,25 @@ pub enum Error { | |||
| 102 | Framing, | 117 | Framing, |
| 103 | } | 118 | } |
| 104 | 119 | ||
| 120 | /// Internal DMA state of UART RX. | ||
| 105 | pub struct DmaState { | 121 | pub struct DmaState { |
| 106 | rx_err_waker: AtomicWaker, | 122 | rx_err_waker: AtomicWaker, |
| 107 | rx_errs: AtomicU16, | 123 | rx_errs: AtomicU16, |
| 108 | } | 124 | } |
| 109 | 125 | ||
| 126 | /// UART driver. | ||
| 110 | pub struct Uart<'d, T: Instance, M: Mode> { | 127 | pub struct Uart<'d, T: Instance, M: Mode> { |
| 111 | tx: UartTx<'d, T, M>, | 128 | tx: UartTx<'d, T, M>, |
| 112 | rx: UartRx<'d, T, M>, | 129 | rx: UartRx<'d, T, M>, |
| 113 | } | 130 | } |
| 114 | 131 | ||
| 132 | /// UART TX driver. | ||
| 115 | pub struct UartTx<'d, T: Instance, M: Mode> { | 133 | pub struct UartTx<'d, T: Instance, M: Mode> { |
| 116 | tx_dma: Option<PeripheralRef<'d, AnyChannel>>, | 134 | tx_dma: Option<PeripheralRef<'d, AnyChannel>>, |
| 117 | phantom: PhantomData<(&'d mut T, M)>, | 135 | phantom: PhantomData<(&'d mut T, M)>, |
| 118 | } | 136 | } |
| 119 | 137 | ||
| 138 | /// UART RX driver. | ||
| 120 | pub struct UartRx<'d, T: Instance, M: Mode> { | 139 | pub struct UartRx<'d, T: Instance, M: Mode> { |
| 121 | rx_dma: Option<PeripheralRef<'d, AnyChannel>>, | 140 | rx_dma: Option<PeripheralRef<'d, AnyChannel>>, |
| 122 | phantom: PhantomData<(&'d mut T, M)>, | 141 | phantom: PhantomData<(&'d mut T, M)>, |
| @@ -142,6 +161,7 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { | |||
| 142 | } | 161 | } |
| 143 | } | 162 | } |
| 144 | 163 | ||
| 164 | /// Transmit the provided buffer blocking execution until done. | ||
| 145 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 165 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 146 | let r = T::regs(); | 166 | let r = T::regs(); |
| 147 | for &b in buffer { | 167 | for &b in buffer { |
| @@ -151,12 +171,14 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { | |||
| 151 | Ok(()) | 171 | Ok(()) |
| 152 | } | 172 | } |
| 153 | 173 | ||
| 174 | /// Flush UART TX blocking execution until done. | ||
| 154 | pub fn blocking_flush(&mut self) -> Result<(), Error> { | 175 | pub fn blocking_flush(&mut self) -> Result<(), Error> { |
| 155 | let r = T::regs(); | 176 | let r = T::regs(); |
| 156 | while !r.uartfr().read().txfe() {} | 177 | while !r.uartfr().read().txfe() {} |
| 157 | Ok(()) | 178 | Ok(()) |
| 158 | } | 179 | } |
| 159 | 180 | ||
| 181 | /// Check if UART is busy transmitting. | ||
| 160 | pub fn busy(&self) -> bool { | 182 | pub fn busy(&self) -> bool { |
| 161 | T::regs().uartfr().read().busy() | 183 | T::regs().uartfr().read().busy() |
| 162 | } | 184 | } |
| @@ -191,6 +213,8 @@ impl<'d, T: Instance, M: Mode> UartTx<'d, T, M> { | |||
| 191 | } | 213 | } |
| 192 | 214 | ||
| 193 | impl<'d, T: Instance> UartTx<'d, T, Blocking> { | 215 | impl<'d, T: Instance> UartTx<'d, T, Blocking> { |
| 216 | /// Convert this uart TX instance into a buffered uart using the provided | ||
| 217 | /// irq and transmit buffer. | ||
| 194 | pub fn into_buffered( | 218 | pub fn into_buffered( |
| 195 | self, | 219 | self, |
| 196 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 220 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| @@ -203,6 +227,7 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> { | |||
| 203 | } | 227 | } |
| 204 | 228 | ||
| 205 | impl<'d, T: Instance> UartTx<'d, T, Async> { | 229 | impl<'d, T: Instance> UartTx<'d, T, Async> { |
| 230 | /// Write to UART TX from the provided buffer using DMA. | ||
| 206 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 231 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 207 | let ch = self.tx_dma.as_mut().unwrap(); | 232 | let ch = self.tx_dma.as_mut().unwrap(); |
| 208 | let transfer = unsafe { | 233 | let transfer = unsafe { |
| @@ -246,6 +271,7 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> { | |||
| 246 | } | 271 | } |
| 247 | } | 272 | } |
| 248 | 273 | ||
| 274 | /// Read from UART RX blocking execution until done. | ||
| 249 | pub fn blocking_read(&mut self, mut buffer: &mut [u8]) -> Result<(), Error> { | 275 | pub fn blocking_read(&mut self, mut buffer: &mut [u8]) -> Result<(), Error> { |
| 250 | while buffer.len() > 0 { | 276 | while buffer.len() > 0 { |
| 251 | let received = self.drain_fifo(buffer)?; | 277 | let received = self.drain_fifo(buffer)?; |
| @@ -294,6 +320,7 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> { | |||
| 294 | } | 320 | } |
| 295 | 321 | ||
| 296 | impl<'d, T: Instance> UartRx<'d, T, Blocking> { | 322 | impl<'d, T: Instance> UartRx<'d, T, Blocking> { |
| 323 | /// Create a new UART RX instance for blocking mode operations. | ||
| 297 | pub fn new_blocking( | 324 | pub fn new_blocking( |
| 298 | _uart: impl Peripheral<P = T> + 'd, | 325 | _uart: impl Peripheral<P = T> + 'd, |
| 299 | rx: impl Peripheral<P = impl RxPin<T>> + 'd, | 326 | rx: impl Peripheral<P = impl RxPin<T>> + 'd, |
| @@ -304,6 +331,8 @@ impl<'d, T: Instance> UartRx<'d, T, Blocking> { | |||
| 304 | Self::new_inner(false, None) | 331 | Self::new_inner(false, None) |
| 305 | } | 332 | } |
| 306 | 333 | ||
| 334 | /// Convert this uart RX instance into a buffered uart using the provided | ||
| 335 | /// irq and receive buffer. | ||
| 307 | pub fn into_buffered( | 336 | pub fn into_buffered( |
| 308 | self, | 337 | self, |
| 309 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 338 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| @@ -315,6 +344,7 @@ impl<'d, T: Instance> UartRx<'d, T, Blocking> { | |||
| 315 | } | 344 | } |
| 316 | } | 345 | } |
| 317 | 346 | ||
| 347 | /// Interrupt handler. | ||
| 318 | pub struct InterruptHandler<T: Instance> { | 348 | pub struct InterruptHandler<T: Instance> { |
| 319 | _uart: PhantomData<T>, | 349 | _uart: PhantomData<T>, |
| 320 | } | 350 | } |
| @@ -338,6 +368,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 338 | } | 368 | } |
| 339 | 369 | ||
| 340 | impl<'d, T: Instance> UartRx<'d, T, Async> { | 370 | impl<'d, T: Instance> UartRx<'d, T, Async> { |
| 371 | /// Read from UART RX into the provided buffer. | ||
| 341 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | 372 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { |
| 342 | // clear error flags before we drain the fifo. errors that have accumulated | 373 | // clear error flags before we drain the fifo. errors that have accumulated |
| 343 | // in the flags will also be present in the fifo. | 374 | // in the flags will also be present in the fifo. |
| @@ -458,6 +489,8 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> { | |||
| 458 | ) | 489 | ) |
| 459 | } | 490 | } |
| 460 | 491 | ||
| 492 | /// Convert this uart instance into a buffered uart using the provided | ||
| 493 | /// irq, transmit and receive buffers. | ||
| 461 | pub fn into_buffered( | 494 | pub fn into_buffered( |
| 462 | self, | 495 | self, |
| 463 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, | 496 | irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>, |
| @@ -667,22 +700,27 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> { | |||
| 667 | } | 700 | } |
| 668 | 701 | ||
| 669 | impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { | 702 | impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { |
| 703 | /// Transmit the provided buffer blocking execution until done. | ||
| 670 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 704 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 671 | self.tx.blocking_write(buffer) | 705 | self.tx.blocking_write(buffer) |
| 672 | } | 706 | } |
| 673 | 707 | ||
| 708 | /// Flush UART TX blocking execution until done. | ||
| 674 | pub fn blocking_flush(&mut self) -> Result<(), Error> { | 709 | pub fn blocking_flush(&mut self) -> Result<(), Error> { |
| 675 | self.tx.blocking_flush() | 710 | self.tx.blocking_flush() |
| 676 | } | 711 | } |
| 677 | 712 | ||
| 713 | /// Read from UART RX blocking execution until done. | ||
| 678 | pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | 714 | pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { |
| 679 | self.rx.blocking_read(buffer) | 715 | self.rx.blocking_read(buffer) |
| 680 | } | 716 | } |
| 681 | 717 | ||
| 718 | /// Check if UART is busy transmitting. | ||
| 682 | pub fn busy(&self) -> bool { | 719 | pub fn busy(&self) -> bool { |
| 683 | self.tx.busy() | 720 | self.tx.busy() |
| 684 | } | 721 | } |
| 685 | 722 | ||
| 723 | /// Wait until TX is empty and send break condition. | ||
| 686 | pub async fn send_break(&mut self, bits: u32) { | 724 | pub async fn send_break(&mut self, bits: u32) { |
| 687 | self.tx.send_break(bits).await | 725 | self.tx.send_break(bits).await |
| 688 | } | 726 | } |
| @@ -695,10 +733,12 @@ impl<'d, T: Instance, M: Mode> Uart<'d, T, M> { | |||
| 695 | } | 733 | } |
| 696 | 734 | ||
| 697 | impl<'d, T: Instance> Uart<'d, T, Async> { | 735 | impl<'d, T: Instance> Uart<'d, T, Async> { |
| 736 | /// Write to UART TX from the provided buffer. | ||
| 698 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { | 737 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 699 | self.tx.write(buffer).await | 738 | self.tx.write(buffer).await |
| 700 | } | 739 | } |
| 701 | 740 | ||
| 741 | /// Read from UART RX into the provided buffer. | ||
| 702 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | 742 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { |
| 703 | self.rx.read(buffer).await | 743 | self.rx.read(buffer).await |
| 704 | } | 744 | } |
| @@ -889,6 +929,7 @@ mod sealed { | |||
| 889 | pub trait RtsPin<T: Instance> {} | 929 | pub trait RtsPin<T: Instance> {} |
| 890 | } | 930 | } |
| 891 | 931 | ||
| 932 | /// UART mode. | ||
| 892 | pub trait Mode: sealed::Mode {} | 933 | pub trait Mode: sealed::Mode {} |
| 893 | 934 | ||
| 894 | macro_rules! impl_mode { | 935 | macro_rules! impl_mode { |
| @@ -898,12 +939,15 @@ macro_rules! impl_mode { | |||
| 898 | }; | 939 | }; |
| 899 | } | 940 | } |
| 900 | 941 | ||
| 942 | /// Blocking mode. | ||
| 901 | pub struct Blocking; | 943 | pub struct Blocking; |
| 944 | /// Async mode. | ||
| 902 | pub struct Async; | 945 | pub struct Async; |
| 903 | 946 | ||
| 904 | impl_mode!(Blocking); | 947 | impl_mode!(Blocking); |
| 905 | impl_mode!(Async); | 948 | impl_mode!(Async); |
| 906 | 949 | ||
| 950 | /// UART instance trait. | ||
| 907 | pub trait Instance: sealed::Instance {} | 951 | pub trait Instance: sealed::Instance {} |
| 908 | 952 | ||
| 909 | macro_rules! impl_instance { | 953 | macro_rules! impl_instance { |
