From cb97d0786250259c1794dfb0ce86c6337b70af07 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 25 Nov 2024 16:43:06 +0100 Subject: [PATCH 1/3] removed eh02 dependencies, sh*tcode, not yet tested properly,copy-pasted --- esp-lp-hal/Cargo.toml | 9 +-- esp-lp-hal/README.md | 2 +- esp-lp-hal/examples/blinky.rs | 4 +- esp-lp-hal/examples/i2c.rs | 3 +- esp-lp-hal/examples/uart.rs | 3 +- esp-lp-hal/src/delay.rs | 24 ------ esp-lp-hal/src/gpio.rs | 42 ----------- esp-lp-hal/src/i2c.rs | 134 +++++++++++++++++++++++++++++----- esp-lp-hal/src/uart.rs | 22 ------ 9 files changed, 124 insertions(+), 119 deletions(-) diff --git a/esp-lp-hal/Cargo.toml b/esp-lp-hal/Cargo.toml index b8397a792e5..9ea3c5e4908 100644 --- a/esp-lp-hal/Cargo.toml +++ b/esp-lp-hal/Cargo.toml @@ -28,7 +28,6 @@ test = false cfg-if = "1.0.0" document-features = "0.2.10" embedded-hal = { version = "1.0.0", optional = true } -embedded-hal-02 = { version = "0.2.7", optional = true, features = ["unproven"], package = "embedded-hal" } embedded-hal-nb = { version = "1.0.0", optional = true } embedded-io = { version = "0.6.1", optional = true } esp32c6-lp = { version = "0.3.0", features = ["critical-section"], optional = true } @@ -63,8 +62,6 @@ esp32s2 = ["dep:esp32s2-ulp", "procmacros/is-ulp-core"] esp32s3 = ["dep:esp32s3-ulp", "procmacros/is-ulp-core"] #! ### Trait Implementation Feature Flags -## Implement the traits defined in the `0.2.x` release of `embedded-hal`. -embedded-hal-02 = ["dep:embedded-hal-02"] ## Implement the traits defined in the `1.0.0` releases of `embedded-hal` and ## `embedded-hal-nb` for the relevant peripherals. embedded-hal = ["dep:embedded-hal", "dep:embedded-hal-nb"] @@ -73,15 +70,15 @@ embedded-io = ["dep:embedded-io"] [[example]] name = "blinky" -required-features = ["embedded-hal-02"] +required-features = [] [[example]] name = "i2c" -required-features = ["embedded-hal-02", "esp32c6"] +required-features = ["esp32c6"] [[example]] name = "uart" -required-features = ["embedded-hal-02", "esp32c6"] +required-features = ["esp32c6"] [lints.rust] unexpected_cfgs = "allow" diff --git a/esp-lp-hal/README.md b/esp-lp-hal/README.md index e3057e34d76..820be8aac9a 100644 --- a/esp-lp-hal/README.md +++ b/esp-lp-hal/README.md @@ -12,7 +12,7 @@ Implements a number of blocking and, where applicable, async traits from the var For help getting started with this HAL, please refer to [The Rust on ESP Book] and the [documentation]. -[embedded-hal]: https://github.com/rust-embedded/embedded-hal +[embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/ [the rust on esp book]: https://docs.esp-rs.org/book/ ## [Documentation] diff --git a/esp-lp-hal/examples/blinky.rs b/esp-lp-hal/examples/blinky.rs index e4334ed6fbd..dfd12d10947 100644 --- a/esp-lp-hal/examples/blinky.rs +++ b/esp-lp-hal/examples/blinky.rs @@ -7,12 +7,10 @@ //! //! Make sure the LP RAM is cleared before loading the code. -//% FEATURES: embedded-hal-02 - #![no_std] #![no_main] -use embedded_hal_02::{blocking::delay::DelayMs, digital::v2::OutputPin}; +use embedded_hal::{delay::DelayNs, digital::OutputPin}; use esp_lp_hal::{delay::Delay, gpio::Output, prelude::*}; use panic_halt as _; diff --git a/esp-lp-hal/examples/i2c.rs b/esp-lp-hal/examples/i2c.rs index 25cf1f8a80e..8f429ba213a 100644 --- a/esp-lp-hal/examples/i2c.rs +++ b/esp-lp-hal/examples/i2c.rs @@ -8,12 +8,11 @@ //! - SCL => GPIO7 //% CHIPS: esp32c6 -//% FEATURES: embedded-hal-02 #![no_std] #![no_main] -use embedded_hal_02::blocking::i2c::WriteRead; +use embedded_hal::i2c::I2c; use esp_lp_hal::{i2c::LpI2c, prelude::*}; use panic_halt as _; diff --git a/esp-lp-hal/examples/uart.rs b/esp-lp-hal/examples/uart.rs index 293250ef28a..bce4da8817b 100644 --- a/esp-lp-hal/examples/uart.rs +++ b/esp-lp-hal/examples/uart.rs @@ -6,14 +6,13 @@ //! logs from LP_UART. Make sure the LP RAM is cleared before loading the code. //% CHIPS: esp32c6 -//% FEATURES: embedded-hal-02 #![no_std] #![no_main] use core::fmt::Write; -use embedded_hal_02::blocking::delay::DelayMs; +use embedded_hal::delay::DelayNs; use esp_lp_hal::{delay::Delay, prelude::*, uart::LpUart}; use panic_halt as _; diff --git a/esp-lp-hal/src/delay.rs b/esp-lp-hal/src/delay.rs index cdfbe07c808..2a0e9460895 100644 --- a/esp-lp-hal/src/delay.rs +++ b/esp-lp-hal/src/delay.rs @@ -74,30 +74,6 @@ fn cycles() -> u64 { cycles as u64 } -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::blocking::delay::DelayUs for Delay { - #[inline(always)] - fn delay_us(&mut self, us: u64) { - self.delay_micros(us as u32); - } -} - -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::blocking::delay::DelayUs for Delay { - #[inline(always)] - fn delay_us(&mut self, us: u32) { - self.delay_micros(us); - } -} - -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::blocking::delay::DelayMs for Delay { - #[inline(always)] - fn delay_ms(&mut self, ms: u32) { - self.delay_millis(ms); - } -} - #[cfg(feature = "embedded-hal")] impl embedded_hal::delay::DelayNs for Delay { #[inline(always)] diff --git a/esp-lp-hal/src/gpio.rs b/esp-lp-hal/src/gpio.rs index e50c418199a..ca87a57c5ad 100644 --- a/esp-lp-hal/src/gpio.rs +++ b/esp-lp-hal/src/gpio.rs @@ -86,48 +86,6 @@ pub unsafe fn conjure_input() -> Option> { } } -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::digital::v2::InputPin for Input { - type Error = core::convert::Infallible; - - fn is_high(&self) -> Result { - Ok(self.input_state()) - } - - fn is_low(&self) -> Result { - Ok(!self.is_high()?) - } -} - -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::digital::v2::OutputPin for Output { - type Error = core::convert::Infallible; - - fn set_low(&mut self) -> Result<(), Self::Error> { - self.set_output(false); - Ok(()) - } - - fn set_high(&mut self) -> Result<(), Self::Error> { - self.set_output(true); - Ok(()) - } -} - -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::digital::v2::StatefulOutputPin for Output { - fn is_set_high(&self) -> Result { - Ok(self.output_state()) - } - - fn is_set_low(&self) -> Result { - Ok(!self.is_set_high()?) - } -} - -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::digital::v2::toggleable::Default for Output {} - #[cfg(feature = "embedded-hal")] impl embedded_hal::digital::ErrorType for Input { type Error = core::convert::Infallible; diff --git a/esp-lp-hal/src/i2c.rs b/esp-lp-hal/src/i2c.rs index ec455bd2a0d..3c5d728139a 100644 --- a/esp-lp-hal/src/i2c.rs +++ b/esp-lp-hal/src/i2c.rs @@ -35,6 +35,20 @@ pub enum Error { InvalidResponse, } +#[cfg(feature = "embedded-hal")] +impl embedded_hal::i2c::Error for Error { + fn kind(&self) -> embedded_hal::i2c::ErrorKind { + use embedded_hal::i2c::{ErrorKind, NoAcknowledgeSource}; + + match self { + Self::ExceedingFifo => ErrorKind::Overrun, + Self::ArbitrationLost => ErrorKind::ArbitrationLoss, + Self::AckCheckFailed => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Unknown), + _ => ErrorKind::Other, + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum OperationType { Write = 0, @@ -56,6 +70,55 @@ enum Opcode { End = 4, } +/// LP_I2C operation. +/// +/// Several operations can be combined as part of a transaction. +pub enum Operation<'a> { + /// Write data from the provided buffer. + Write(&'a [u8]), + + /// Read data into the provided buffer. + Read(&'a mut [u8]), +} + +impl<'a, 'b> From<&'a mut embedded_hal::i2c::Operation<'b>> for Operation<'a> { + fn from(value: &'a mut embedded_hal::i2c::Operation<'b>) -> Self { + match value { + embedded_hal::i2c::Operation::Write(buffer) => Operation::Write(buffer), + embedded_hal::i2c::Operation::Read(buffer) => Operation::Read(buffer), + } + } +} + +impl<'a, 'b> From<&'a mut Operation<'b>> for Operation<'a> { + fn from(value: &'a mut Operation<'b>) -> Self { + match value { + Operation::Write(buffer) => Operation::Write(buffer), + Operation::Read(buffer) => Operation::Read(buffer), + } + } +} + +impl Operation<'_> { + fn is_write(&self) -> bool { + matches!(self, Operation::Write(_)) + } + + fn kind(&self) -> OperationType { + match self { + Operation::Write(_) => OperationType::Write, + Operation::Read(_) => OperationType::Read, + } + } + + fn is_empty(&self) -> bool { + match self { + Operation::Write(buffer) => buffer.is_empty(), + Operation::Read(buffer) => buffer.is_empty(), + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum Command { Start, @@ -467,36 +530,73 @@ impl LpI2c { Ok(()) } -} -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::blocking::i2c::Read for LpI2c { - type Error = Error; + fn transaction_impl<'a>( + &mut self, + address: u8, + operations: impl Iterator>, + ) -> Result<(), Error> { + let mut last_op: Option = None; + // filter out 0 length read operations + let mut op_iter = operations + .filter(|op| op.is_write() || !op.is_empty()) + .peekable(); + + while let Some(op) = op_iter.next() { + let next_op = op_iter.peek().map(|v| v.kind()); + let kind = op.kind(); + match op { + Operation::Write(buffer) => { + // execute a write operation: + // - issue START/RSTART if op is different from previous + // - issue STOP if op is the last one + self.master_write(address, buffer)?; + } + Operation::Read(buffer) => { + // execute a read operation: + // - issue START/RSTART if op is different from previous + // - issue STOP if op is the last one + // - will_continue is true if there is another read operation next + self.master_read(address, buffer)?; + } + } - fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { - self.master_read(address, buffer) + last_op = Some(kind); + } + + Ok(()) } } -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::blocking::i2c::Write for LpI2c { +#[cfg(feature = "embedded-hal")] +impl embedded_hal::i2c::ErrorType for LpI2c { type Error = Error; +} - fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { - self.master_write(addr, bytes) +#[cfg(feature = "embedded-hal")] +impl embedded_hal::i2c::I2c for LpI2c { + fn transaction( + &mut self, + address: u8, + operations: &mut [embedded_hal::i2c::Operation<'_>], + ) -> Result<(), Self::Error> { + self.transaction_impl(address, operations.iter_mut().map(Operation::from)) } -} -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::blocking::i2c::WriteRead for LpI2c { - type Error = Error; + fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { + self.master_read(address, read) + } + + fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> { + self.master_write(addr, write) + } fn write_read( &mut self, address: u8, - bytes: &[u8], - buffer: &mut [u8], + write: &[u8], + read: &mut [u8], ) -> Result<(), Self::Error> { - self.master_write_read(address, bytes, buffer) + self.master_write_read(address, write, read) } } diff --git a/esp-lp-hal/src/uart.rs b/esp-lp-hal/src/uart.rs index dc8664267fb..db09f0be2a7 100644 --- a/esp-lp-hal/src/uart.rs +++ b/esp-lp-hal/src/uart.rs @@ -231,28 +231,6 @@ impl core::fmt::Write for LpUart { } } -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::serial::Read for LpUart { - type Error = Error; - - fn read(&mut self) -> nb::Result { - self.read_byte() - } -} - -#[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::serial::Write for LpUart { - type Error = Error; - - fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { - self.write_byte(word) - } - - fn flush(&mut self) -> nb::Result<(), Self::Error> { - self.flush_tx() - } -} - #[cfg(feature = "embedded-hal")] impl embedded_hal_nb::serial::ErrorType for LpUart { type Error = Error; From 08d102d741099721026bc25836908d6d0193a214 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 25 Nov 2024 17:41:03 +0100 Subject: [PATCH 2/3] changelog entry --- esp-lp-hal/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/esp-lp-hal/CHANGELOG.md b/esp-lp-hal/CHANGELOG.md index 05ec2a29987..c1a0c6418c6 100644 --- a/esp-lp-hal/CHANGELOG.md +++ b/esp-lp-hal/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed ### Removed +- Remove embedded-hal 0.2.x impls and dependency from esp-lp-hal package (#2609) ## 0.1.0 - 2024-07-15 From afedbfcb5f15775329f0827732c01fd440a5c0b7 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Tue, 26 Nov 2024 18:35:28 +0100 Subject: [PATCH 3/3] Don't implement eh1 traits --- esp-lp-hal/examples/i2c.rs | 1 - esp-lp-hal/src/i2c.rs | 151 +++---------------------------------- 2 files changed, 9 insertions(+), 143 deletions(-) diff --git a/esp-lp-hal/examples/i2c.rs b/esp-lp-hal/examples/i2c.rs index 8f429ba213a..65e854d8bd5 100644 --- a/esp-lp-hal/examples/i2c.rs +++ b/esp-lp-hal/examples/i2c.rs @@ -12,7 +12,6 @@ #![no_std] #![no_main] -use embedded_hal::i2c::I2c; use esp_lp_hal::{i2c::LpI2c, prelude::*}; use panic_halt as _; diff --git a/esp-lp-hal/src/i2c.rs b/esp-lp-hal/src/i2c.rs index 3c5d728139a..c4a6029dada 100644 --- a/esp-lp-hal/src/i2c.rs +++ b/esp-lp-hal/src/i2c.rs @@ -35,20 +35,6 @@ pub enum Error { InvalidResponse, } -#[cfg(feature = "embedded-hal")] -impl embedded_hal::i2c::Error for Error { - fn kind(&self) -> embedded_hal::i2c::ErrorKind { - use embedded_hal::i2c::{ErrorKind, NoAcknowledgeSource}; - - match self { - Self::ExceedingFifo => ErrorKind::Overrun, - Self::ArbitrationLost => ErrorKind::ArbitrationLoss, - Self::AckCheckFailed => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Unknown), - _ => ErrorKind::Other, - } - } -} - #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum OperationType { Write = 0, @@ -70,55 +56,6 @@ enum Opcode { End = 4, } -/// LP_I2C operation. -/// -/// Several operations can be combined as part of a transaction. -pub enum Operation<'a> { - /// Write data from the provided buffer. - Write(&'a [u8]), - - /// Read data into the provided buffer. - Read(&'a mut [u8]), -} - -impl<'a, 'b> From<&'a mut embedded_hal::i2c::Operation<'b>> for Operation<'a> { - fn from(value: &'a mut embedded_hal::i2c::Operation<'b>) -> Self { - match value { - embedded_hal::i2c::Operation::Write(buffer) => Operation::Write(buffer), - embedded_hal::i2c::Operation::Read(buffer) => Operation::Read(buffer), - } - } -} - -impl<'a, 'b> From<&'a mut Operation<'b>> for Operation<'a> { - fn from(value: &'a mut Operation<'b>) -> Self { - match value { - Operation::Write(buffer) => Operation::Write(buffer), - Operation::Read(buffer) => Operation::Read(buffer), - } - } -} - -impl Operation<'_> { - fn is_write(&self) -> bool { - matches!(self, Operation::Write(_)) - } - - fn kind(&self) -> OperationType { - match self { - Operation::Write(_) => OperationType::Write, - Operation::Read(_) => OperationType::Read, - } - } - - fn is_empty(&self) -> bool { - match self { - Operation::Write(buffer) => buffer.is_empty(), - Operation::Read(buffer) => buffer.is_empty(), - } - } -} - #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum Command { Start, @@ -250,7 +187,8 @@ pub struct LpI2c { } impl LpI2c { - fn master_write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { + /// Writes bytes to slave with address `addr` + pub fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { let mut cmd_iterator = CommandRegister::COMD0; // If SCL is busy, reset the Master FSM @@ -335,7 +273,8 @@ impl LpI2c { Ok(()) } - fn master_read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> { + /// Reads enough bytes from slave with `addr` to fill `buffer` + pub fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> { // Check size constraints if buffer.len() > 254 { return Err(Error::ExceedingFifo); @@ -433,17 +372,14 @@ impl LpI2c { Ok(()) } - fn master_write_read( - &mut self, - addr: u8, - bytes: &[u8], - buffer: &mut [u8], - ) -> Result<(), Error> { + /// Writes bytes to slave with address `addr` and then reads enough bytes + /// to fill `buffer` *in a single transaction* + pub fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> { // It would be possible to combine the write and read in one transaction, but // filling the tx fifo with the current code is somewhat slow even in release // mode which can cause issues. - self.master_write(addr, bytes)?; - self.master_read(addr, buffer)?; + self.write(addr, bytes)?; + self.read(addr, buffer)?; Ok(()) } @@ -530,73 +466,4 @@ impl LpI2c { Ok(()) } - - fn transaction_impl<'a>( - &mut self, - address: u8, - operations: impl Iterator>, - ) -> Result<(), Error> { - let mut last_op: Option = None; - // filter out 0 length read operations - let mut op_iter = operations - .filter(|op| op.is_write() || !op.is_empty()) - .peekable(); - - while let Some(op) = op_iter.next() { - let next_op = op_iter.peek().map(|v| v.kind()); - let kind = op.kind(); - match op { - Operation::Write(buffer) => { - // execute a write operation: - // - issue START/RSTART if op is different from previous - // - issue STOP if op is the last one - self.master_write(address, buffer)?; - } - Operation::Read(buffer) => { - // execute a read operation: - // - issue START/RSTART if op is different from previous - // - issue STOP if op is the last one - // - will_continue is true if there is another read operation next - self.master_read(address, buffer)?; - } - } - - last_op = Some(kind); - } - - Ok(()) - } -} - -#[cfg(feature = "embedded-hal")] -impl embedded_hal::i2c::ErrorType for LpI2c { - type Error = Error; -} - -#[cfg(feature = "embedded-hal")] -impl embedded_hal::i2c::I2c for LpI2c { - fn transaction( - &mut self, - address: u8, - operations: &mut [embedded_hal::i2c::Operation<'_>], - ) -> Result<(), Self::Error> { - self.transaction_impl(address, operations.iter_mut().map(Operation::from)) - } - - fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { - self.master_read(address, read) - } - - fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> { - self.master_write(addr, write) - } - - fn write_read( - &mut self, - address: u8, - write: &[u8], - read: &mut [u8], - ) -> Result<(), Self::Error> { - self.master_write_read(address, write, read) - } }