diff --git a/CHANGELOG.md b/CHANGELOG.md index a2c72af7..c7337d1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - Missing `DelayMs` / `DelayUs` impls for fugit::Delay -- Support of embedded-hal 1.0.0-alpha.7 +- Support of embedded-hal 1.0.0-alpha.7 [#443] - Aliases for peripheral wrappers [#434] - `WithPwm` trait implemented for timers with channels (internals) [#425] - `Pwm` struct with `split` method and implementation of embedded-hal::Pwm (similar to f1xx-hal) [#425] @@ -51,6 +51,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). [#438]: https://github.com/stm32-rs/stm32f4xx-hal/pull/438 [#439]: https://github.com/stm32-rs/stm32f4xx-hal/pull/439 [#440]: https://github.com/stm32-rs/stm32f4xx-hal/pull/440 +[#443]: https://github.com/stm32-rs/stm32f4xx-hal/pull/443 ### Changed diff --git a/src/fmpi2c.rs b/src/fmpi2c.rs index 3a8b9044..1e7166db 100644 --- a/src/fmpi2c.rs +++ b/src/fmpi2c.rs @@ -1,6 +1,6 @@ use core::ops::Deref; -use crate::i2c::{Error, Pins}; +use crate::i2c::{Error, NoAcknowledgeSource, Pins}; use crate::pac::{fmpi2c1, FMPI2C1, RCC}; use crate::rcc::{Enable, Reset}; use crate::time::{Hertz, U32Ext}; @@ -168,12 +168,19 @@ where self.i2c .icr .write(|w| w.stopcf().set_bit().nackcf().set_bit()); - return Err(Error::NACK); + return Err(Error::NoAcknowledge(NoAcknowledgeSource::Unknown)); } Ok(()) } + fn end_transaction(&self) -> Result<(), Error> { + // Check and clear flags if they somehow ended up set + self.check_and_clear_error_flags(&self.i2c.isr.read()) + .map_err(Error::nack_data)?; + Ok(()) + } + fn send_byte(&self, byte: u8) -> Result<(), Error> { // Wait until we're ready for sending while { @@ -186,9 +193,7 @@ where // Push out a byte of data self.i2c.txdr.write(|w| unsafe { w.bits(u32::from(byte)) }); - self.check_and_clear_error_flags(&self.i2c.isr.read()) - .map_err(Error::nack_data)?; - Ok(()) + self.end_transaction() } fn recv_byte(&self) -> Result { @@ -225,11 +230,7 @@ where *c = self.recv_byte()?; } - // Check and clear flags if they somehow ended up set - self.check_and_clear_error_flags(&self.i2c.isr.read()) - .map_err(Error::nack_data)?; - - Ok(()) + self.end_transaction() } pub fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { @@ -253,11 +254,7 @@ where self.send_byte(*c)?; } - // Check and clear flags if they somehow ended up set - self.check_and_clear_error_flags(&self.i2c.isr.read()) - .map_err(Error::nack_data)?; - - Ok(()) + self.end_transaction() } pub fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> { @@ -318,10 +315,6 @@ where *c = self.recv_byte()?; } - // Check and clear flags if they somehow ended up set - self.check_and_clear_error_flags(&self.i2c.isr.read()) - .map_err(Error::nack_data)?; - - Ok(()) + self.end_transaction() } } diff --git a/src/i2c.rs b/src/i2c.rs index f1cde145..525e2016 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -99,31 +99,34 @@ where } } +pub use embedded_hal_one::i2c::NoAcknowledgeSource; + #[derive(Debug, Eq, PartialEq, Copy, Clone)] #[non_exhaustive] pub enum Error { - OVERRUN, - NACK, - NACK_ADDR, - NACK_DATA, - TIMEOUT, - // Note: The BUS error type is not currently returned, but is maintained for backwards - // compatibility. - BUS, - CRC, - ARBITRATION, + Overrun, + NoAcknowledge(NoAcknowledgeSource), + Timeout, + // Note: The Bus error type is not currently returned, but is maintained for compatibility. + Bus, + Crc, + ArbitrationLoss, } impl Error { pub(crate) fn nack_addr(self) -> Self { match self { - Error::NACK => Error::NACK_ADDR, + Error::NoAcknowledge(NoAcknowledgeSource::Unknown) => { + Error::NoAcknowledge(NoAcknowledgeSource::Address) + } e => e, } } pub(crate) fn nack_data(self) -> Self { match self { - Error::NACK => Error::NACK_DATA, + Error::NoAcknowledge(NoAcknowledgeSource::Unknown) => { + Error::NoAcknowledge(NoAcknowledgeSource::Data) + } e => e, } } @@ -243,27 +246,27 @@ impl I2c { if sr1.timeout().bit_is_set() { self.i2c.sr1.modify(|_, w| w.timeout().clear_bit()); - return Err(Error::TIMEOUT); + return Err(Error::Timeout); } if sr1.pecerr().bit_is_set() { self.i2c.sr1.modify(|_, w| w.pecerr().clear_bit()); - return Err(Error::CRC); + return Err(Error::Crc); } if sr1.ovr().bit_is_set() { self.i2c.sr1.modify(|_, w| w.ovr().clear_bit()); - return Err(Error::OVERRUN); + return Err(Error::Overrun); } if sr1.af().bit_is_set() { self.i2c.sr1.modify(|_, w| w.af().clear_bit()); - return Err(Error::NACK); + return Err(Error::NoAcknowledge(NoAcknowledgeSource::Unknown)); } if sr1.arlo().bit_is_set() { self.i2c.sr1.modify(|_, w| w.arlo().clear_bit()); - return Err(Error::ARBITRATION); + return Err(Error::ArbitrationLoss); } // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and @@ -414,7 +417,7 @@ impl I2c { // Fallthrough is success Ok(()) } else { - Err(Error::OVERRUN) + Err(Error::Overrun) } } @@ -449,9 +452,7 @@ impl I2c { pub fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> { self.write_bytes(addr, bytes.iter().cloned())?; - self.read(addr, buffer)?; - - Ok(()) + self.read(addr, buffer) } pub fn write_iter_read(&mut self, addr: u8, bytes: B, buffer: &mut [u8]) -> Result<(), Error> @@ -459,8 +460,6 @@ impl I2c { B: IntoIterator, { self.write_bytes(addr, bytes.into_iter())?; - self.read(addr, buffer)?; - - Ok(()) + self.read(addr, buffer) } } diff --git a/src/i2c/hal_1.rs b/src/i2c/hal_1.rs index 30ea3260..0e0eedc1 100644 --- a/src/i2c/hal_1.rs +++ b/src/i2c/hal_1.rs @@ -1,15 +1,13 @@ -use embedded_hal_one::i2c::{Error, ErrorKind, ErrorType, NoAcknowledgeSource}; +use embedded_hal_one::i2c::{Error, ErrorKind, ErrorType}; impl Error for super::Error { fn kind(&self) -> ErrorKind { - match self { - Self::OVERRUN => ErrorKind::Overrun, - Self::BUS => ErrorKind::Bus, - Self::ARBITRATION => ErrorKind::ArbitrationLoss, - Self::NACK_ADDR => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Address), - Self::NACK_DATA => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Data), - Self::NACK => ErrorKind::NoAcknowledge(NoAcknowledgeSource::Unknown), - Self::CRC | Self::TIMEOUT => ErrorKind::Other, + match *self { + Self::Overrun => ErrorKind::Overrun, + Self::Bus => ErrorKind::Bus, + Self::ArbitrationLoss => ErrorKind::ArbitrationLoss, + Self::NoAcknowledge(nack) => ErrorKind::NoAcknowledge(nack), + Self::Crc | Self::Timeout => ErrorKind::Other, } } }