diff --git a/Cargo.toml b/Cargo.toml
index 25cf58bf..77c9dd02 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -40,6 +40,10 @@ version = "0.2"
package = "embedded-hal"
version = "1.0.0"
+[dependencies.eio06]
+package = "embedded-io"
+version = "0.6.1"
+
[dependencies.rand_core]
version = "0.5"
default-features = false
diff --git a/src/common/lpuart.rs b/src/common/lpuart.rs
index 337029a2..3dffe030 100644
--- a/src/common/lpuart.rs
+++ b/src/common/lpuart.rs
@@ -349,6 +349,35 @@ impl
Lpuart
{
ral::modify_reg!(ral::lpuart, self.lpuart, BAUD, RDMAE: 0);
}
}
+
+ /// Attempts to write a single byte to the bus.
+ ///
+ /// Returns `false` if the fifo was already full.
+ pub fn try_write(&mut self, byte: u8) -> bool {
+ ral::modify_reg!(ral::lpuart, self.lpuart, FIFO, TXOF: TXOF_1);
+ self.write_byte(byte);
+ ral::read_reg!(ral::lpuart, self.lpuart, FIFO, TXOF == TXOF_0)
+ }
+
+ /// Attempts to read a single byte from the bus.
+ ///
+ /// Returns:
+ /// - `Ok(Some(u8))` if data was read
+ /// - `Ok(None)` if the fifo was empty
+ /// - `Err(..)` if a read error happened
+ pub fn try_read(&mut self) -> Result, ReadFlags> {
+ let data = self.read_data();
+ if data.flags().contains(ReadFlags::RXEMPT) {
+ Ok(None)
+ } else if data
+ .flags()
+ .intersects(ReadFlags::PARITY_ERROR | ReadFlags::FRAME_ERROR | ReadFlags::NOISY)
+ {
+ Err(data.flags())
+ } else {
+ Ok(Some(data.into()))
+ }
+ }
}
fn flush_fifo(lpuart: &Instance, direction: Direction) {
@@ -930,6 +959,88 @@ impl eh02::blocking::serial::Write for Lpuart {
}
}
+impl eio06::Error for ReadFlags {
+ fn kind(&self) -> eio06::ErrorKind {
+ eio06::ErrorKind::Other
+ }
+}
+
+impl
eio06::ErrorType for Lpuart
{
+ type Error = ReadFlags;
+}
+
+impl
eio06::WriteReady for Lpuart
{
+ fn write_ready(&mut self) -> Result {
+ Ok(self.status().contains(Status::TRANSMIT_EMPTY))
+ }
+}
+
+impl eio06::ReadReady for Lpuart
{
+ fn read_ready(&mut self) -> Result {
+ Ok(self.status().contains(Status::RECEIVE_FULL))
+ }
+}
+
+impl eio06::Write for Lpuart
{
+ fn write(&mut self, buf: &[u8]) -> Result {
+ let mut num_written = 0;
+ for word in buf {
+ if num_written == 0 {
+ // For the first word, continue trying until we send.
+ // This function is supposed to block until at least one word is
+ // sent.
+ while !self.try_write(*word) {}
+ } else {
+ // If we already sent at least one word, return once
+ // the buffer is full
+ if !self.try_write(*word) {
+ break;
+ }
+ }
+ num_written += 1;
+ }
+
+ Ok(num_written)
+ }
+
+ fn flush(&mut self) -> Result<(), Self::Error> {
+ while !self.status().contains(Status::TRANSMIT_COMPLETE) {}
+
+ Ok(())
+ }
+}
+
+impl eio06::Read for Lpuart
{
+ fn read(&mut self, buf: &mut [u8]) -> Result {
+ let mut num_read = 0;
+ for word in buf {
+ let data = if num_read == 0 {
+ // For the first word, continue querying until we receive something.
+ // This function is supposed to block until at least one word is
+ // received.
+ loop {
+ if let Some(data) = self.try_read()? {
+ break data;
+ }
+ }
+ } else {
+ // If we already read at least one word, return once
+ // the buffer is empty
+ if let Some(data) = self.try_read()? {
+ data
+ } else {
+ break;
+ }
+ };
+
+ *word = data;
+ num_read += 1;
+ }
+
+ Ok(num_read)
+ }
+}
+
#[cfg(test)]
mod tests {
use super::{Baud, ReadData, ReadFlags, Status};