From e22d41b3c3deaeb5beb66933804cfb8daf05a9a0 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Thu, 11 Jan 2024 01:08:39 +0300 Subject: [PATCH] io --- Cargo.toml | 3 + src/serial.rs | 1 + src/serial/hal_1.rs | 199 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 src/serial/hal_1.rs diff --git a/Cargo.toml b/Cargo.toml index 5225fea12..94fec83c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,6 +64,9 @@ version = "1.0" [dependencies.embedded-hal-nb] version = "1.0" +[dependencies.embedded-io] +version = "0.6.1" + [dependencies.stm32_i2s_v12x] version = "0.5.0" optional = true diff --git a/src/serial.rs b/src/serial.rs index 6a92d8d99..72a523047 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -17,6 +17,7 @@ use core::marker::PhantomData; mod hal_02; +mod hal_1; pub(crate) mod uart_impls; pub use uart_impls::Instance; diff --git a/src/serial/hal_1.rs b/src/serial/hal_1.rs new file mode 100644 index 000000000..1f62c5209 --- /dev/null +++ b/src/serial/hal_1.rs @@ -0,0 +1,199 @@ +mod nb { + use core::ops::Deref; + + use super::super::{Error, Instance, RegisterBlockImpl, Rx, Serial, Tx}; + use embedded_hal_nb::serial::{ErrorKind, Read, Write}; + + impl embedded_hal_nb::serial::Error for Error { + fn kind(&self) -> ErrorKind { + match self { + Error::Overrun => ErrorKind::Overrun, + Error::FrameFormat => ErrorKind::FrameFormat, + Error::Parity => ErrorKind::Parity, + Error::Noise => ErrorKind::Noise, + Error::Other => ErrorKind::Other, + } + } + } + + impl embedded_hal_nb::serial::ErrorType for Serial { + type Error = Error; + } + impl embedded_hal_nb::serial::ErrorType for Rx { + type Error = Error; + } + impl embedded_hal_nb::serial::ErrorType for Tx { + type Error = Error; + } + + impl Read for Serial + where + Rx: Read, + { + fn read(&mut self) -> nb::Result { + self.rx.read() + } + } + + impl Read for Rx + where + ::RegisterBlock: RegisterBlockImpl, + { + fn read(&mut self) -> nb::Result { + unsafe { (*USART::ptr()).read_u8() } + } + } + + /// Reads 9-bit words from the UART/USART + /// + /// If the UART/USART was configured with `WordLength::DataBits9`, the returned value will contain + /// 9 received data bits and all other bits set to zero. Otherwise, the returned value will contain + /// 8 received data bits and all other bits set to zero. + impl Read for Rx + where + ::RegisterBlock: RegisterBlockImpl, + { + fn read(&mut self) -> nb::Result { + unsafe { (*USART::ptr()).read_u16() } + } + } + + impl Write for Serial + where + Tx: Write, + { + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.tx.flush() + } + + fn write(&mut self, byte: WORD) -> nb::Result<(), Self::Error> { + self.tx.write(byte) + } + } + + impl Write for Tx + where + ::RegisterBlock: RegisterBlockImpl, + USART: Deref::RegisterBlock>, + { + fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { + self.usart.write_u8(word) + } + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.usart.flush() + } + } + + /// Writes 9-bit words to the UART/USART + /// + /// If the UART/USART was configured with `WordLength::DataBits9`, the 9 least significant bits will + /// be transmitted and the other 7 bits will be ignored. Otherwise, the 8 least significant bits + /// will be transmitted and the other 8 bits will be ignored. + impl Write for Tx + where + ::RegisterBlock: RegisterBlockImpl, + USART: Deref::RegisterBlock>, + { + fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> { + self.usart.write_u16(word) + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.usart.flush() + } + } +} + +mod io { + use core::ops::Deref; + + use super::super::{Error, Instance, RegisterBlockImpl, Rx, Serial, Tx}; + use embedded_io::Write; + + impl embedded_io::Error for Error { + // TODO: fix error conversion + fn kind(&self) -> embedded_io::ErrorKind { + embedded_io::ErrorKind::Other + } + } + + impl embedded_io::ErrorType for Serial { + type Error = Error; + } + + impl embedded_io::ErrorType for Tx { + type Error = Error; + } + + impl embedded_io::ErrorType for Rx { + type Error = Error; + } + + impl Write for Tx + where + ::RegisterBlock: RegisterBlockImpl, + USART: Deref::RegisterBlock>, + { + /* + fn write(&mut self, bytes: &[u8]) -> Result { + let mut iter = bytes.iter(); + let Some(first) = iter.next() else { + return Ok(0); + }; + // block for first byte + self.usart.write_u8(*first)?; + let mut i = 1; + + // write more bytes if it's possible + for byte in iter { + match self.usart.write_u8(*byte) { + Ok(_) => { + i += 1; + } + Err(nb::Error::WouldBlock) => { + return Ok(i); + } + Err(nb::Error::Other(e)) => { + return Err(e); + } + } + } + Ok(i) + }*/ + fn write(&mut self, bytes: &[u8]) -> Result { + let mut i = 0; + for byte in bytes.iter() { + match self.usart.write_u8(*byte) { + Ok(_) => { + i += 1; + } + Err(nb::Error::WouldBlock) => { + return Ok(i); + } + Err(nb::Error::Other(e)) => { + return Err(e); + } + } + } + Ok(i) + } + + fn flush(&mut self) -> Result<(), Self::Error> { + self.usart.bflush()?; + Ok(()) + } + } + + impl Write for Serial + where + Tx: Write, + { + fn write(&mut self, bytes: &[u8]) -> Result { + self.tx.write(bytes) + } + + fn flush(&mut self) -> Result<(), Self::Error> { + self.tx.flush() + } + } +}