diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-08-18 18:36:27 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-08-18 18:36:27 +0000 |
| commit | aefa5275a2ab2cac6caef599e7adb76ce1beeddd (patch) | |
| tree | 0f83ec1b3eacfba6e3208d1ac446bf00c8b02d4c | |
| parent | 3572da29c80283db5a5f082d9dc9173739566b3c (diff) | |
| parent | 0f74f870b00942a3020a32d44470edf80870676c (diff) | |
Merge #910
910: (embassy-rp): Implement remaining logic for blocking UART r=lulf a=MathiasKoch
async read/write is still `todo!()`, awaiting DMA implementation.
Co-authored-by: Mathias <[email protected]>
| -rw-r--r-- | embassy-rp/Cargo.toml | 2 | ||||
| -rw-r--r-- | embassy-rp/src/dma.rs | 6 | ||||
| -rw-r--r-- | embassy-rp/src/uart.rs | 401 | ||||
| -rw-r--r-- | examples/rp/src/bin/uart.rs | 6 |
4 files changed, 374 insertions, 41 deletions
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index aaf4ede13..af7c8ee6e 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml | |||
| @@ -36,6 +36,8 @@ embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } | |||
| 36 | atomic-polyfill = "1.0.1" | 36 | atomic-polyfill = "1.0.1" |
| 37 | defmt = { version = "0.3", optional = true } | 37 | defmt = { version = "0.3", optional = true } |
| 38 | log = { version = "0.4.14", optional = true } | 38 | log = { version = "0.4.14", optional = true } |
| 39 | nb = "1.0.0" | ||
| 40 | cfg-if = "1.0.0" | ||
| 39 | cortex-m-rt = ">=0.6.15,<0.8" | 41 | cortex-m-rt = ">=0.6.15,<0.8" |
| 40 | cortex-m = "0.7.6" | 42 | cortex-m = "0.7.6" |
| 41 | critical-section = "1.1" | 43 | critical-section = "1.1" |
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs index 235e92d7c..42c4fd13e 100644 --- a/embassy-rp/src/dma.rs +++ b/embassy-rp/src/dma.rs | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | use core::sync::atomic::{compiler_fence, Ordering}; | 1 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 2 | 2 | ||
| 3 | use embassy_hal_common::impl_peripheral; | ||
| 4 | |||
| 3 | use crate::pac::dma::vals; | 5 | use crate::pac::dma::vals; |
| 4 | use crate::{pac, peripherals}; | 6 | use crate::{pac, peripherals}; |
| 5 | 7 | ||
| @@ -35,6 +37,10 @@ impl<T: Channel> Dma<T> { | |||
| 35 | } | 37 | } |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 40 | pub struct NoDma; | ||
| 41 | |||
| 42 | impl_peripheral!(NoDma); | ||
| 43 | |||
| 38 | mod sealed { | 44 | mod sealed { |
| 39 | use super::*; | 45 | use super::*; |
| 40 | 46 | ||
diff --git a/embassy-rp/src/uart.rs b/embassy-rp/src/uart.rs index b19f043f8..6c5ab3515 100644 --- a/embassy-rp/src/uart.rs +++ b/embassy-rp/src/uart.rs | |||
| @@ -1,42 +1,199 @@ | |||
| 1 | use core::marker::PhantomData; | ||
| 2 | |||
| 1 | use embassy_hal_common::{into_ref, PeripheralRef}; | 3 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 2 | use gpio::Pin; | ||
| 3 | 4 | ||
| 4 | use crate::{gpio, pac, peripherals, Peripheral}; | 5 | use crate::gpio::sealed::Pin; |
| 6 | use crate::gpio::AnyPin; | ||
| 7 | use crate::{pac, peripherals, Peripheral}; | ||
| 8 | |||
| 9 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
| 10 | pub enum DataBits { | ||
| 11 | DataBits5, | ||
| 12 | DataBits6, | ||
| 13 | DataBits7, | ||
| 14 | DataBits8, | ||
| 15 | } | ||
| 16 | |||
| 17 | impl DataBits { | ||
| 18 | fn bits(&self) -> u8 { | ||
| 19 | match self { | ||
| 20 | Self::DataBits5 => 0b00, | ||
| 21 | Self::DataBits6 => 0b01, | ||
| 22 | Self::DataBits7 => 0b10, | ||
| 23 | Self::DataBits8 => 0b11, | ||
| 24 | } | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
| 29 | pub enum Parity { | ||
| 30 | ParityNone, | ||
| 31 | ParityEven, | ||
| 32 | ParityOdd, | ||
| 33 | } | ||
| 34 | |||
| 35 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
| 36 | pub enum StopBits { | ||
| 37 | #[doc = "1 stop bit"] | ||
| 38 | STOP1, | ||
| 39 | #[doc = "2 stop bits"] | ||
| 40 | STOP2, | ||
| 41 | } | ||
| 5 | 42 | ||
| 6 | #[non_exhaustive] | 43 | #[non_exhaustive] |
| 44 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
| 7 | pub struct Config { | 45 | pub struct Config { |
| 8 | pub baudrate: u32, | 46 | pub baudrate: u32, |
| 9 | pub data_bits: u8, | 47 | pub data_bits: DataBits, |
| 10 | pub stop_bits: u8, | 48 | pub stop_bits: StopBits, |
| 49 | pub parity: Parity, | ||
| 11 | } | 50 | } |
| 12 | 51 | ||
| 13 | impl Default for Config { | 52 | impl Default for Config { |
| 14 | fn default() -> Self { | 53 | fn default() -> Self { |
| 15 | Self { | 54 | Self { |
| 16 | baudrate: 115200, | 55 | baudrate: 115200, |
| 17 | data_bits: 8, | 56 | data_bits: DataBits::DataBits8, |
| 18 | stop_bits: 1, | 57 | stop_bits: StopBits::STOP1, |
| 58 | parity: Parity::ParityNone, | ||
| 19 | } | 59 | } |
| 20 | } | 60 | } |
| 21 | } | 61 | } |
| 22 | 62 | ||
| 63 | /// Serial error | ||
| 64 | #[derive(Debug, Eq, PartialEq, Copy, Clone)] | ||
| 65 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 66 | #[non_exhaustive] | ||
| 67 | pub enum Error { | ||
| 68 | /// Triggered when the FIFO (or shift-register) is overflowed. | ||
| 69 | Overrun, | ||
| 70 | /// Triggered when a break is received | ||
| 71 | Break, | ||
| 72 | /// Triggered when there is a parity mismatch between what's received and | ||
| 73 | /// our settings. | ||
| 74 | Parity, | ||
| 75 | /// Triggered when the received character didn't have a valid stop bit. | ||
| 76 | Framing, | ||
| 77 | } | ||
| 78 | |||
| 23 | pub struct Uart<'d, T: Instance> { | 79 | pub struct Uart<'d, T: Instance> { |
| 24 | inner: PeripheralRef<'d, T>, | 80 | tx: UartTx<'d, T>, |
| 81 | rx: UartRx<'d, T>, | ||
| 82 | } | ||
| 83 | |||
| 84 | pub struct UartTx<'d, T: Instance> { | ||
| 85 | phantom: PhantomData<&'d mut T>, | ||
| 86 | } | ||
| 87 | |||
| 88 | pub struct UartRx<'d, T: Instance> { | ||
| 89 | phantom: PhantomData<&'d mut T>, | ||
| 90 | } | ||
| 91 | |||
| 92 | impl<'d, T: Instance> UartTx<'d, T> { | ||
| 93 | fn new() -> Self { | ||
| 94 | Self { phantom: PhantomData } | ||
| 95 | } | ||
| 96 | |||
| 97 | pub async fn write(&mut self, _buffer: &[u8]) -> Result<(), Error> { | ||
| 98 | todo!() | ||
| 99 | } | ||
| 100 | |||
| 101 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { | ||
| 102 | let r = T::regs(); | ||
| 103 | unsafe { | ||
| 104 | for &b in buffer { | ||
| 105 | while r.uartfr().read().txff() {} | ||
| 106 | r.uartdr().write(|w| w.set_data(b)); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | Ok(()) | ||
| 110 | } | ||
| 111 | |||
| 112 | pub fn blocking_flush(&mut self) -> Result<(), Error> { | ||
| 113 | let r = T::regs(); | ||
| 114 | unsafe { while r.uartfr().read().txff() {} } | ||
| 115 | Ok(()) | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | impl<'d, T: Instance> UartRx<'d, T> { | ||
| 120 | fn new() -> Self { | ||
| 121 | Self { phantom: PhantomData } | ||
| 122 | } | ||
| 123 | |||
| 124 | pub async fn read(&mut self, _buffer: &mut [u8]) -> Result<(), Error> { | ||
| 125 | todo!(); | ||
| 126 | } | ||
| 127 | |||
| 128 | pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | ||
| 129 | let r = T::regs(); | ||
| 130 | unsafe { | ||
| 131 | for b in buffer { | ||
| 132 | *b = loop { | ||
| 133 | let dr = r.uartdr().read(); | ||
| 134 | |||
| 135 | if dr.oe() { | ||
| 136 | return Err(Error::Overrun); | ||
| 137 | } else if dr.be() { | ||
| 138 | return Err(Error::Break); | ||
| 139 | } else if dr.pe() { | ||
| 140 | return Err(Error::Parity); | ||
| 141 | } else if dr.fe() { | ||
| 142 | return Err(Error::Framing); | ||
| 143 | } else if dr.fe() { | ||
| 144 | break dr.data(); | ||
| 145 | } | ||
| 146 | }; | ||
| 147 | } | ||
| 148 | } | ||
| 149 | Ok(()) | ||
| 150 | } | ||
| 25 | } | 151 | } |
| 26 | 152 | ||
| 27 | impl<'d, T: Instance> Uart<'d, T> { | 153 | impl<'d, T: Instance> Uart<'d, T> { |
| 154 | /// Create a new UART without hardware flow control | ||
| 28 | pub fn new( | 155 | pub fn new( |
| 29 | inner: impl Peripheral<P = T> + 'd, | 156 | uart: impl Peripheral<P = T> + 'd, |
| 157 | tx: impl Peripheral<P = impl TxPin<T>> + 'd, | ||
| 158 | rx: impl Peripheral<P = impl RxPin<T>> + 'd, | ||
| 159 | config: Config, | ||
| 160 | ) -> Self { | ||
| 161 | into_ref!(tx, rx); | ||
| 162 | Self::new_inner(uart, rx.map_into(), tx.map_into(), None, None, config) | ||
| 163 | } | ||
| 164 | |||
| 165 | /// Create a new UART with hardware flow control (RTS/CTS) | ||
| 166 | pub fn new_with_rtscts( | ||
| 167 | uart: impl Peripheral<P = T> + 'd, | ||
| 30 | tx: impl Peripheral<P = impl TxPin<T>> + 'd, | 168 | tx: impl Peripheral<P = impl TxPin<T>> + 'd, |
| 31 | rx: impl Peripheral<P = impl RxPin<T>> + 'd, | 169 | rx: impl Peripheral<P = impl RxPin<T>> + 'd, |
| 32 | cts: impl Peripheral<P = impl CtsPin<T>> + 'd, | 170 | cts: impl Peripheral<P = impl CtsPin<T>> + 'd, |
| 33 | rts: impl Peripheral<P = impl RtsPin<T>> + 'd, | 171 | rts: impl Peripheral<P = impl RtsPin<T>> + 'd, |
| 34 | config: Config, | 172 | config: Config, |
| 35 | ) -> Self { | 173 | ) -> Self { |
| 36 | into_ref!(inner, tx, rx, cts, rts); | 174 | into_ref!(tx, rx, cts, rts); |
| 175 | Self::new_inner( | ||
| 176 | uart, | ||
| 177 | rx.map_into(), | ||
| 178 | tx.map_into(), | ||
| 179 | Some(cts.map_into()), | ||
| 180 | Some(rts.map_into()), | ||
| 181 | config, | ||
| 182 | ) | ||
| 183 | } | ||
| 184 | |||
| 185 | fn new_inner( | ||
| 186 | _uart: impl Peripheral<P = T> + 'd, | ||
| 187 | tx: PeripheralRef<'d, AnyPin>, | ||
| 188 | rx: PeripheralRef<'d, AnyPin>, | ||
| 189 | cts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 190 | rts: Option<PeripheralRef<'d, AnyPin>>, | ||
| 191 | config: Config, | ||
| 192 | ) -> Self { | ||
| 193 | into_ref!(_uart); | ||
| 37 | 194 | ||
| 38 | unsafe { | 195 | unsafe { |
| 39 | let p = inner.regs(); | 196 | let r = T::regs(); |
| 40 | 197 | ||
| 41 | let clk_base = crate::clocks::clk_peri_freq(); | 198 | let clk_base = crate::clocks::clk_peri_freq(); |
| 42 | 199 | ||
| @@ -53,49 +210,217 @@ impl<'d, T: Instance> Uart<'d, T> { | |||
| 53 | } | 210 | } |
| 54 | 211 | ||
| 55 | // Load PL011's baud divisor registers | 212 | // Load PL011's baud divisor registers |
| 56 | p.uartibrd().write_value(pac::uart::regs::Uartibrd(baud_ibrd)); | 213 | r.uartibrd().write_value(pac::uart::regs::Uartibrd(baud_ibrd)); |
| 57 | p.uartfbrd().write_value(pac::uart::regs::Uartfbrd(baud_fbrd)); | 214 | r.uartfbrd().write_value(pac::uart::regs::Uartfbrd(baud_fbrd)); |
| 58 | 215 | ||
| 59 | p.uartlcr_h().write(|w| { | 216 | let (pen, eps) = match config.parity { |
| 60 | w.set_wlen(config.data_bits - 5); | 217 | Parity::ParityNone => (false, false), |
| 61 | w.set_stp2(config.stop_bits == 2); | 218 | Parity::ParityEven => (true, true), |
| 62 | w.set_pen(false); | 219 | Parity::ParityOdd => (true, false), |
| 63 | w.set_eps(false); | 220 | }; |
| 221 | |||
| 222 | r.uartlcr_h().write(|w| { | ||
| 223 | w.set_wlen(config.data_bits.bits()); | ||
| 224 | w.set_stp2(config.stop_bits == StopBits::STOP2); | ||
| 225 | w.set_pen(pen); | ||
| 226 | w.set_eps(eps); | ||
| 64 | w.set_fen(true); | 227 | w.set_fen(true); |
| 65 | }); | 228 | }); |
| 66 | 229 | ||
| 67 | p.uartcr().write(|w| { | 230 | r.uartcr().write(|w| { |
| 68 | w.set_uarten(true); | 231 | w.set_uarten(true); |
| 69 | w.set_rxe(true); | 232 | w.set_rxe(true); |
| 70 | w.set_txe(true); | 233 | w.set_txe(true); |
| 234 | w.set_ctsen(cts.is_some()); | ||
| 235 | w.set_rtsen(rts.is_some()); | ||
| 71 | }); | 236 | }); |
| 72 | 237 | ||
| 73 | tx.io().ctrl().write(|w| w.set_funcsel(2)); | 238 | tx.io().ctrl().write(|w| w.set_funcsel(2)); |
| 74 | rx.io().ctrl().write(|w| w.set_funcsel(2)); | 239 | rx.io().ctrl().write(|w| w.set_funcsel(2)); |
| 75 | cts.io().ctrl().write(|w| w.set_funcsel(2)); | 240 | if let Some(pin) = &cts { |
| 76 | rts.io().ctrl().write(|w| w.set_funcsel(2)); | 241 | pin.io().ctrl().write(|w| w.set_funcsel(2)); |
| 242 | } | ||
| 243 | if let Some(pin) = &rts { | ||
| 244 | pin.io().ctrl().write(|w| w.set_funcsel(2)); | ||
| 245 | } | ||
| 246 | } | ||
| 247 | |||
| 248 | Self { | ||
| 249 | tx: UartTx::new(), | ||
| 250 | rx: UartRx::new(), | ||
| 77 | } | 251 | } |
| 78 | Self { inner } | ||
| 79 | } | 252 | } |
| 80 | 253 | ||
| 81 | pub fn send(&mut self, data: &[u8]) { | 254 | pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 82 | unsafe { | 255 | self.tx.write(buffer).await |
| 83 | let p = self.inner.regs(); | 256 | } |
| 257 | |||
| 258 | pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { | ||
| 259 | self.tx.blocking_write(buffer) | ||
| 260 | } | ||
| 84 | 261 | ||
| 85 | for &byte in data { | 262 | pub fn blocking_flush(&mut self) -> Result<(), Error> { |
| 86 | if !p.uartfr().read().txff() { | 263 | self.tx.blocking_flush() |
| 87 | p.uartdr().write(|w| w.set_data(byte)); | 264 | } |
| 265 | |||
| 266 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | ||
| 267 | self.rx.read(buffer).await | ||
| 268 | } | ||
| 269 | |||
| 270 | pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | ||
| 271 | self.rx.blocking_read(buffer) | ||
| 272 | } | ||
| 273 | |||
| 274 | /// Split the Uart into a transmitter and receiver, which is | ||
| 275 | /// particuarly useful when having two tasks correlating to | ||
| 276 | /// transmitting and receiving. | ||
| 277 | pub fn split(self) -> (UartTx<'d, T>, UartRx<'d, T>) { | ||
| 278 | (self.tx, self.rx) | ||
| 279 | } | ||
| 280 | } | ||
| 281 | |||
| 282 | mod eh02 { | ||
| 283 | use super::*; | ||
| 284 | |||
| 285 | impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for UartRx<'d, T> { | ||
| 286 | type Error = Error; | ||
| 287 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { | ||
| 288 | let r = T::regs(); | ||
| 289 | unsafe { | ||
| 290 | let dr = r.uartdr().read(); | ||
| 291 | |||
| 292 | if dr.oe() { | ||
| 293 | Err(nb::Error::Other(Error::Overrun)) | ||
| 294 | } else if dr.be() { | ||
| 295 | Err(nb::Error::Other(Error::Break)) | ||
| 296 | } else if dr.pe() { | ||
| 297 | Err(nb::Error::Other(Error::Parity)) | ||
| 298 | } else if dr.fe() { | ||
| 299 | Err(nb::Error::Other(Error::Framing)) | ||
| 300 | } else if dr.fe() { | ||
| 301 | Ok(dr.data()) | ||
| 302 | } else { | ||
| 303 | Err(nb::Error::WouldBlock) | ||
| 88 | } | 304 | } |
| 89 | } | 305 | } |
| 90 | } | 306 | } |
| 91 | } | 307 | } |
| 308 | |||
| 309 | impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T> { | ||
| 310 | type Error = Error; | ||
| 311 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { | ||
| 312 | self.blocking_write(buffer) | ||
| 313 | } | ||
| 314 | fn bflush(&mut self) -> Result<(), Self::Error> { | ||
| 315 | self.blocking_flush() | ||
| 316 | } | ||
| 317 | } | ||
| 318 | |||
| 319 | impl<'d, T: Instance> embedded_hal_02::serial::Read<u8> for Uart<'d, T> { | ||
| 320 | type Error = Error; | ||
| 321 | fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { | ||
| 322 | embedded_hal_02::serial::Read::read(&mut self.rx) | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T> { | ||
| 327 | type Error = Error; | ||
| 328 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { | ||
| 329 | self.blocking_write(buffer) | ||
| 330 | } | ||
| 331 | fn bflush(&mut self) -> Result<(), Self::Error> { | ||
| 332 | self.blocking_flush() | ||
| 333 | } | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | #[cfg(feature = "unstable-traits")] | ||
| 338 | mod eh1 { | ||
| 339 | use super::*; | ||
| 340 | |||
| 341 | impl embedded_hal_1::serial::Error for Error { | ||
| 342 | fn kind(&self) -> embedded_hal_1::serial::ErrorKind { | ||
| 343 | match *self { | ||
| 344 | Self::Framing => embedded_hal_1::serial::ErrorKind::FrameFormat, | ||
| 345 | Self::Break => embedded_hal_1::serial::ErrorKind::Other, | ||
| 346 | Self::Overrun => embedded_hal_1::serial::ErrorKind::Overrun, | ||
| 347 | Self::Parity => embedded_hal_1::serial::ErrorKind::Parity, | ||
| 348 | } | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 352 | impl<'d, T: Instance> embedded_hal_1::serial::ErrorType for Uart<'d, T> { | ||
| 353 | type Error = Error; | ||
| 354 | } | ||
| 355 | |||
| 356 | impl<'d, T: Instance> embedded_hal_1::serial::ErrorType for UartTx<'d, T> { | ||
| 357 | type Error = Error; | ||
| 358 | } | ||
| 359 | |||
| 360 | impl<'d, T: Instance> embedded_hal_1::serial::ErrorType for UartRx<'d, T> { | ||
| 361 | type Error = Error; | ||
| 362 | } | ||
| 363 | } | ||
| 364 | |||
| 365 | cfg_if::cfg_if! { | ||
| 366 | if #[cfg(all(feature = "unstable-traits", feature = "nightly", feature = "_todo_embedded_hal_serial"))] { | ||
| 367 | use core::future::Future; | ||
| 368 | |||
| 369 | impl<'d, T: Instance> embedded_hal_async::serial::Write for UartTx<'d, T> | ||
| 370 | { | ||
| 371 | type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; | ||
| 372 | |||
| 373 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | ||
| 374 | self.write(buf) | ||
| 375 | } | ||
| 376 | |||
| 377 | type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; | ||
| 378 | |||
| 379 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | ||
| 380 | async move { Ok(()) } | ||
| 381 | } | ||
| 382 | } | ||
| 383 | |||
| 384 | impl<'d, T: Instance> embedded_hal_async::serial::Read for UartRx<'d, T> | ||
| 385 | { | ||
| 386 | type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; | ||
| 387 | |||
| 388 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { | ||
| 389 | self.read(buf) | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | impl<'d, T: Instance> embedded_hal_async::serial::Write for Uart<'d, T> | ||
| 394 | { | ||
| 395 | type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; | ||
| 396 | |||
| 397 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | ||
| 398 | self.write(buf) | ||
| 399 | } | ||
| 400 | |||
| 401 | type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; | ||
| 402 | |||
| 403 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | ||
| 404 | async move { Ok(()) } | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | impl<'d, T: Instance> embedded_hal_async::serial::Read for Uart<'d, T> | ||
| 409 | { | ||
| 410 | type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a; | ||
| 411 | |||
| 412 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { | ||
| 413 | self.read(buf) | ||
| 414 | } | ||
| 415 | } | ||
| 416 | } | ||
| 92 | } | 417 | } |
| 93 | 418 | ||
| 94 | mod sealed { | 419 | mod sealed { |
| 95 | use super::*; | 420 | use super::*; |
| 96 | 421 | ||
| 97 | pub trait Instance { | 422 | pub trait Instance { |
| 98 | fn regs(&self) -> pac::uart::Uart; | 423 | fn regs() -> pac::uart::Uart; |
| 99 | } | 424 | } |
| 100 | pub trait TxPin<T: Instance> {} | 425 | pub trait TxPin<T: Instance> {} |
| 101 | pub trait RxPin<T: Instance> {} | 426 | pub trait RxPin<T: Instance> {} |
| @@ -106,23 +431,23 @@ mod sealed { | |||
| 106 | pub trait Instance: sealed::Instance {} | 431 | pub trait Instance: sealed::Instance {} |
| 107 | 432 | ||
| 108 | macro_rules! impl_instance { | 433 | macro_rules! impl_instance { |
| 109 | ($type:ident, $irq:ident) => { | 434 | ($inst:ident, $irq:ident) => { |
| 110 | impl sealed::Instance for peripherals::$type { | 435 | impl sealed::Instance for peripherals::$inst { |
| 111 | fn regs(&self) -> pac::uart::Uart { | 436 | fn regs() -> pac::uart::Uart { |
| 112 | pac::$type | 437 | pac::$inst |
| 113 | } | 438 | } |
| 114 | } | 439 | } |
| 115 | impl Instance for peripherals::$type {} | 440 | impl Instance for peripherals::$inst {} |
| 116 | }; | 441 | }; |
| 117 | } | 442 | } |
| 118 | 443 | ||
| 119 | impl_instance!(UART0, UART0); | 444 | impl_instance!(UART0, UART0); |
| 120 | impl_instance!(UART1, UART1); | 445 | impl_instance!(UART1, UART1); |
| 121 | 446 | ||
| 122 | pub trait TxPin<T: Instance>: sealed::TxPin<T> + Pin {} | 447 | pub trait TxPin<T: Instance>: sealed::TxPin<T> + crate::gpio::Pin {} |
| 123 | pub trait RxPin<T: Instance>: sealed::RxPin<T> + Pin {} | 448 | pub trait RxPin<T: Instance>: sealed::RxPin<T> + crate::gpio::Pin {} |
| 124 | pub trait CtsPin<T: Instance>: sealed::CtsPin<T> + Pin {} | 449 | pub trait CtsPin<T: Instance>: sealed::CtsPin<T> + crate::gpio::Pin {} |
| 125 | pub trait RtsPin<T: Instance>: sealed::RtsPin<T> + Pin {} | 450 | pub trait RtsPin<T: Instance>: sealed::RtsPin<T> + crate::gpio::Pin {} |
| 126 | 451 | ||
| 127 | macro_rules! impl_pin { | 452 | macro_rules! impl_pin { |
| 128 | ($pin:ident, $instance:ident, $function:ident) => { | 453 | ($pin:ident, $instance:ident, $function:ident) => { |
diff --git a/examples/rp/src/bin/uart.rs b/examples/rp/src/bin/uart.rs index 5fdc3ff77..c63b31cae 100644 --- a/examples/rp/src/bin/uart.rs +++ b/examples/rp/src/bin/uart.rs | |||
| @@ -10,11 +10,11 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 10 | async fn main(_spawner: Spawner) { | 10 | async fn main(_spawner: Spawner) { |
| 11 | let p = embassy_rp::init(Default::default()); | 11 | let p = embassy_rp::init(Default::default()); |
| 12 | let config = uart::Config::default(); | 12 | let config = uart::Config::default(); |
| 13 | let mut uart = uart::Uart::new(p.UART0, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, config); | 13 | let mut uart = uart::Uart::new_with_rtscts(p.UART0, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, config); |
| 14 | uart.send("Hello World!\r\n".as_bytes()); | 14 | uart.blocking_write("Hello World!\r\n".as_bytes()).unwrap(); |
| 15 | 15 | ||
| 16 | loop { | 16 | loop { |
| 17 | uart.send("hello there!\r\n".as_bytes()); | 17 | uart.blocking_write("hello there!\r\n".as_bytes()).unwrap(); |
| 18 | cortex_m::asm::delay(1_000_000); | 18 | cortex_m::asm::delay(1_000_000); |
| 19 | } | 19 | } |
| 20 | } | 20 | } |
