From 7eb0c08e11dee4d42e2fbe3208eb093e7295d64c Mon Sep 17 00:00:00 2001 From: Zhouqi Jiang Date: Wed, 10 Jan 2024 09:53:08 +0800 Subject: [PATCH] lib: update embedded-hal into 1.0.0 Signed-off-by: Zhouqi Jiang --- Cargo.toml | 3 +- src/gpio.rs | 31 +++++---------- src/gpiohs.rs | 22 ++++------- src/lib.rs | 7 ---- src/serial.rs | 103 ++++++++++++++++++++++++++------------------------ src/spi.rs | 27 +++++++++---- src/stdout.rs | 23 +++-------- 7 files changed, 98 insertions(+), 118 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0ae1b42..098ecf7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,8 @@ edition = "2021" targets = ["riscv64gc-unknown-none-elf"] [dependencies] -embedded-hal = { version = "0.2.7", features = ["unproven"] } +embedded-hal = "1.0.0" +embedded-io = "0.6.1" nb = "1" k210-pac = "0.2.0" bitflags = "1.3" diff --git a/src/gpio.rs b/src/gpio.rs index 61d74c5..3eff05d 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -1,11 +1,11 @@ //! General Purpose Input/Output (GPIO) -use crate::bit_utils::{u32_bit_is_clear, u32_bit_is_set, u32_set_bit, u32_toggle_bit}; +use crate::bit_utils::{u32_bit_is_clear, u32_bit_is_set, u32_set_bit}; use crate::fpioa::{IoPin, Mode, Pull}; use crate::pac; use crate::sysctl::{self, APB0}; use core::marker::PhantomData; -use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin}; +use embedded_hal::digital::{ErrorType, InputPin, OutputPin, StatefulOutputPin}; /// Extension trait to split a GPIO peripheral into independent pins pub trait GpioExt { @@ -186,17 +186,20 @@ impl Gpio { } } -impl InputPin for Gpio> { +impl ErrorType for Gpio { + // All GPIO operations are infallible. type Error = core::convert::Infallible; +} - fn is_high(&self) -> Result { +impl InputPin for Gpio> { + fn is_high(&mut self) -> Result { Ok(unsafe { let p = &(*pac::GPIO::ptr()).data_input as *const _ as *const _; u32_bit_is_set(p, GPIO::INDEX as usize) }) } - fn is_low(&self) -> Result { + fn is_low(&mut self) -> Result { Ok(unsafe { let p = &(*pac::GPIO::ptr()).data_input as *const _ as *const _; u32_bit_is_clear(p, GPIO::INDEX as usize) @@ -205,8 +208,6 @@ impl InputPin for Gpio> { } impl OutputPin for Gpio { - type Error = core::convert::Infallible; - fn set_high(&mut self) -> Result<(), Self::Error> { unsafe { let p = &(*pac::GPIO::ptr()).data_output as *const _ as *mut _; @@ -225,29 +226,17 @@ impl OutputPin for Gpio { } impl StatefulOutputPin for Gpio { - fn is_set_high(&self) -> Result { + fn is_set_high(&mut self) -> Result { Ok(unsafe { let p = &(*pac::GPIO::ptr()).data_output as *const _ as *const _; u32_bit_is_set(p, GPIO::INDEX as usize) }) } - fn is_set_low(&self) -> Result { + fn is_set_low(&mut self) -> Result { Ok(unsafe { let p = &(*pac::GPIO::ptr()).data_output as *const _ as *const _; u32_bit_is_clear(p, GPIO::INDEX as usize) }) } } - -impl ToggleableOutputPin for Gpio { - type Error = core::convert::Infallible; - - fn toggle(&mut self) -> Result<(), Self::Error> { - unsafe { - let p = &(*pac::GPIO::ptr()).data_output as *const _ as *mut _; - u32_toggle_bit(p, GPIO::INDEX as usize); - } - Ok(()) - } -} diff --git a/src/gpiohs.rs b/src/gpiohs.rs index dccfd16..aeba868 100644 --- a/src/gpiohs.rs +++ b/src/gpiohs.rs @@ -1,9 +1,9 @@ //! High-speed GPIO peripheral (GPIOHS) -use crate::bit_utils::{u32_bit_is_clear, u32_bit_is_set, u32_set_bit, u32_toggle_bit}; +use crate::bit_utils::{u32_bit_is_clear, u32_bit_is_set, u32_set_bit}; use crate::pac::GPIOHS; use core::marker::PhantomData; -use embedded_hal::digital::v2::{InputPin, OutputPin}; +use embedded_hal::digital::{ErrorType, InputPin, OutputPin}; // todo: verify @@ -114,17 +114,20 @@ impl Gpiohs0 { } } -impl InputPin for Gpiohs0> { +impl ErrorType for Gpiohs0 { + // All GPIO operations are infallible. type Error = core::convert::Infallible; +} - fn is_high(&self) -> Result { +impl InputPin for Gpiohs0> { + fn is_high(&mut self) -> Result { Ok(unsafe { let p = &(*GPIOHS::ptr()).input_val as *const _ as *const _; u32_bit_is_set(p, 0) }) } - fn is_low(&self) -> Result { + fn is_low(&mut self) -> Result { Ok(unsafe { let p = &(*GPIOHS::ptr()).input_val as *const _ as *const _; u32_bit_is_clear(p, 0) @@ -133,8 +136,6 @@ impl InputPin for Gpiohs0> { } impl OutputPin for Gpiohs0> { - type Error = core::convert::Infallible; - fn set_high(&mut self) -> Result<(), Self::Error> { unsafe { let p = &(*GPIOHS::ptr()).output_val as *const _ as *mut _; @@ -211,13 +212,6 @@ trait GpiohsAccess { } } - fn toggle_pin(index: usize) { - unsafe { - let p = &mut Self::peripheral().output_val as *mut _ as *mut _; - u32_toggle_bit(p, index); - } - } - fn set_pullup_en(index: usize, bit: bool) { unsafe { let p = &mut Self::peripheral().pullup_en as *mut _ as *mut _; diff --git a/src/lib.rs b/src/lib.rs index 221e202..1c7de8a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,7 +35,6 @@ pub mod prelude { pub use crate::stdout::Write as _k210_hal_stdout_Write; pub use crate::sysctl::SysctlExt as _k210_hal_sysctl_SysctlExt; pub use crate::time::U32Ext as _k210_hal_time_U32Ext; - pub use embedded_hal::prelude::*; } mod bit_utils { @@ -49,12 +48,6 @@ mod bit_utils { } } - #[inline(always)] - pub(crate) unsafe fn u32_toggle_bit(p: *mut u32, index: usize) { - let mask = 1 << index; - *p ^= mask; - } - #[inline(always)] pub(crate) unsafe fn u32_bit_is_set(r: *const u32, index: usize) -> bool { (*r & 1 << index) != 0 diff --git a/src/serial.rs b/src/serial.rs index 97aee33..62fa0c0 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -9,8 +9,6 @@ use core::convert::Infallible; use core::mem; -use embedded_hal::serial; - use crate::clock::Clocks; use crate::pac::{uart1, UART1, UART2, UART3, UARTHS}; use crate::time::Bps; @@ -98,44 +96,48 @@ impl Serial { } } -impl serial::Read for Rx { - type Error = Infallible; - - fn read(&mut self) -> nb::Result { - let rxdata = self.uart.rxdata.read(); +impl embedded_io::ErrorType for Rx { + type Error = core::convert::Infallible; +} - if rxdata.empty().bit_is_set() { - Err(nb::Error::WouldBlock) - } else { - Ok(rxdata.data().bits() as u8) +impl embedded_io::Read for Rx { + fn read(&mut self, buf: &mut [u8]) -> Result { + while self.uart.rxdata.read().empty().bit_is_set() { + // Block until rxdata available. + core::hint::spin_loop() + } + let len = buf.len(); + for slot in buf { + *slot = self.uart.rxdata.read().data().bits(); } + Ok(len) } } -impl serial::Write for Tx { - type Error = Infallible; - - fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> { - let txdata = self.uart.txdata.read(); +impl embedded_io::ErrorType for Tx { + type Error = core::convert::Infallible; +} - if txdata.full().bit_is_set() { - Err(nb::Error::WouldBlock) - } else { +impl embedded_io::Write for Tx { + fn write(&mut self, bytes: &[u8]) -> Result { + while self.uart.txdata.read().full().bit_is_set() { + // Block until txdata available. + core::hint::spin_loop() + } + for byte in bytes { unsafe { - (*UARTHS::ptr()).txdata.write(|w| w.data().bits(byte)); + self.uart.txdata.write(|w| w.data().bits(*byte)); } - Ok(()) } + Ok(bytes.len()) } - fn flush(&mut self) -> nb::Result<(), Infallible> { - let txdata = self.uart.txdata.read(); - - if txdata.full().bit_is_set() { - Err(nb::Error::WouldBlock) - } else { - Ok(()) + fn flush(&mut self) -> Result<(), Infallible> { + while self.uart.txdata.read().full().bit_is_set() { + // Block until flush complete. If you don't want a block, use embedded_io_async traits instead. + core::hint::spin_loop() } + Ok(()) } } @@ -207,40 +209,43 @@ impl Serial { } } -impl serial::Read for Rx { - type Error = Infallible; - - fn read(&mut self) -> nb::Result { - let lsr = self.uart.lsr.read(); +impl embedded_io::ErrorType for Rx { + type Error = core::convert::Infallible; +} - if (lsr.bits() & (1 << 0)) == 0 { +impl embedded_io::Read for Rx { + fn read(&mut self, buf: &mut [u8]) -> Result { + while (self.uart.lsr.read().bits() & (1 << 0)) == 0 { // Data Ready bit - Err(nb::Error::WouldBlock) - } else { - let rbr = self.uart.rbr_dll_thr.read(); - Ok((rbr.bits() & 0xff) as u8) + core::hint::spin_loop() + } + let len = buf.len(); + for slot in buf { + *slot = (self.uart.rbr_dll_thr.read().bits() & 0xff) as u8; } + Ok(len) } } -impl serial::Write for Tx { - type Error = Infallible; - - fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> { - let lsr = self.uart.lsr.read(); +impl embedded_io::ErrorType for Tx { + type Error = core::convert::Infallible; +} - if (lsr.bits() & (1 << 5)) != 0 { +impl embedded_io::Write for Tx { + fn write(&mut self, bytes: &[u8]) -> Result { + while (self.uart.lsr.read().bits() & (1 << 5)) != 0 { // Transmit Holding Register Empty bit - Err(nb::Error::WouldBlock) - } else { + core::hint::spin_loop(); + } + for byte in bytes { unsafe { - self.uart.rbr_dll_thr.write(|w| w.bits(byte.into())); + self.uart.rbr_dll_thr.write(|w| w.bits(*byte as u32)); } - Ok(()) } + Ok(bytes.len()) } - fn flush(&mut self) -> nb::Result<(), Infallible> { + fn flush(&mut self) -> Result<(), Infallible> { // TODO Ok(()) } diff --git a/src/spi.rs b/src/spi.rs index 2435ac6..fc5a717 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -3,7 +3,6 @@ use crate::clock::Clocks; use crate::pac::SPI0; use crate::sysctl::{self, APB0}; -use core::convert::Infallible; pub use embedded_hal::spi::{Mode, Phase, Polarity}; /// @@ -64,21 +63,33 @@ impl Spi { } } -impl embedded_hal::spi::FullDuplex for Spi { - /// An enumeration of SPI errors - type Error = Infallible; +impl embedded_hal::spi::ErrorType for Spi { + type Error = core::convert::Infallible; +} +impl embedded_hal::spi::SpiBus for Spi { /// Reads the word stored in the shift register /// /// **NOTE** A word must be sent to the slave before attempting to call this /// method. - fn read(&mut self) -> nb::Result { + fn read(&mut self, _words: &mut [u8]) -> Result<(), Self::Error> { + todo!() + } + + fn write(&mut self, _words: &[u8]) -> Result<(), Self::Error> { todo!() } - /// Sends a word to the slave - fn send(&mut self, word: u8) -> nb::Result<(), Self::Error> { - todo!("{}", word) + fn transfer(&mut self, _read: &mut [u8], _write: &[u8]) -> Result<(), Self::Error> { + todo!() + } + + fn transfer_in_place(&mut self, _words: &mut [u8]) -> Result<(), Self::Error> { + todo!() + } + + fn flush(&mut self) -> Result<(), Self::Error> { + todo!() } } diff --git a/src/stdout.rs b/src/stdout.rs index 3e0c7e6..616e87a 100644 --- a/src/stdout.rs +++ b/src/stdout.rs @@ -1,6 +1,5 @@ //! Stdout pub use core::fmt::Write; -use nb::block; /// Stdout implements the core::fmt::Write trait for hal::serial::Write /// implementations. @@ -8,24 +7,12 @@ pub struct Stdout<'p, T>(pub &'p mut T); impl<'p, T> Write for Stdout<'p, T> where - T: embedded_hal::serial::Write, + T: embedded_io::Write, { fn write_str(&mut self, s: &str) -> core::fmt::Result { - for byte in s.as_bytes() { - if *byte == b'\n' { - let res = block!(self.0.write(b'\r')); - - if res.is_err() { - return Err(core::fmt::Error); - } - } - - let res = block!(self.0.write(*byte)); - - if res.is_err() { - return Err(core::fmt::Error); - } - } - Ok(()) + self.0 + .write(s.as_bytes()) + .map_err(|_| core::fmt::Error) + .map(|_| ()) } }