From f3fba80a713b632bee7190db8105065864518028 Mon Sep 17 00:00:00 2001 From: Nic0w Date: Mon, 26 Apr 2021 22:05:37 +0200 Subject: [PATCH] Implement embedded_hal::serial traits for the UART. --- rp2040-hal/src/lib.rs | 1 + rp2040-hal/src/serial.rs | 50 ++++++++++++++++++++++++++++++++++++++++ rp2040-hal/src/uart.rs | 16 +++++++++---- 3 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 rp2040-hal/src/serial.rs diff --git a/rp2040-hal/src/lib.rs b/rp2040-hal/src/lib.rs index e8d96e2..00be8ba 100644 --- a/rp2040-hal/src/lib.rs +++ b/rp2040-hal/src/lib.rs @@ -23,4 +23,5 @@ pub mod ssi; pub mod timer; pub mod uart; pub mod usb; +pub mod serial; pub mod watchdog; diff --git a/rp2040-hal/src/serial.rs b/rp2040-hal/src/serial.rs new file mode 100644 index 0000000..c7a3a2e --- /dev/null +++ b/rp2040-hal/src/serial.rs @@ -0,0 +1,50 @@ +//! Implementation for the embedded_hal::serial traits for the UART. +// See [embedded-hal](https://docs.rs/embedded-hal/0.2.4/embedded_hal/serial/index.html) for more details + +use core::convert::Infallible; + +use crate::uart::{ + UARTPeripheral, + UARTDevice, + Enabled +}; + +use embedded_hal::serial::{ + Read, + Write +}; + +use nb::Error::WouldBlock; + +impl Read for UARTPeripheral { + type Error = Infallible; + + fn read(&mut self) -> nb::Result { + + let byte: &mut [u8] = &mut [0; 1]; + + if let Err(_) = self.read_raw(byte) { + Err(WouldBlock) + } + else { + Ok(byte[0]) + } + } +} + +impl Write for UARTPeripheral { + type Error = Infallible; + + fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { + if let Err(_) = self.write_raw(&[word]) { + Err(WouldBlock) + } + else { + Ok(()) + } + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.transmit_flushed() + } +} diff --git a/rp2040-hal/src/uart.rs b/rp2040-hal/src/uart.rs index a51c4d2..8860c4f 100644 --- a/rp2040-hal/src/uart.rs +++ b/rp2040-hal/src/uart.rs @@ -203,6 +203,14 @@ impl UARTPeripheral { self.transition(Disabled) } + pub(crate) fn transmit_flushed(&self) -> nb::Result<(), Infallible> { + + if self.device.uartfr.read().txfe().bit_is_set() { + Ok(()) + } + else { Err(WouldBlock) } + } + fn uart_is_writable(&self) -> bool { self.device.uartfr.read().txff().bit_is_clear() } @@ -216,7 +224,7 @@ impl UARTPeripheral { /// - 0 bytes were written, a WouldBlock Error is returned /// - some bytes were written, it is deemed to be a success /// Upon success, the number of written bytes is returned. - pub fn write<'d>(&self, data: &'d [u8]) -> nb::Result<&'d [u8], Infallible> { + pub fn write_raw <'d>(&self, data: &'d [u8]) -> nb::Result<&'d [u8], Infallible> { let mut bytes_written = 0; @@ -246,7 +254,7 @@ impl UARTPeripheral { /// - 0 bytes were read, a WouldBlock Error is returned /// - some bytes were read, it is deemed to be a success /// Upon success, the number of read bytes is returned. - pub fn read<'b>(&self, buffer: &'b mut [u8]) -> nb::Result<&'b mut [u8], Infallible> { + pub fn read_raw<'b>(&self, buffer: &'b mut [u8]) -> nb::Result<&'b mut [u8], Infallible> { let mut bytes_read = 0; @@ -277,7 +285,7 @@ impl UARTPeripheral { let mut temp = data; while !temp.is_empty() { - temp = match self.write(temp) { + temp = match self.write_raw(temp) { Ok(remaining) => remaining, Err(WouldBlock) => continue, Err(_) => unreachable!() @@ -291,7 +299,7 @@ impl UARTPeripheral { let mut offset = 0; while offset != buffer.len() { - offset += match self.read(&mut buffer[offset..]) { + offset += match self.read_raw(&mut buffer[offset..]) { Ok(remaining) => { remaining.len() }, Err(WouldBlock) => continue, Err(_) => unreachable!()