diff --git a/CHANGELOG.md b/CHANGELOG.md index cbcdb9a0..a2c72af7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Pwm channels now constants [#432] - Add channel events, make Event use bitflags (simplify interrupt handling) [#425] - reexport `digital::v2::PinState` again [#428] -- reexport `digital::v2::PinState` again - Timer impls with time based on `fugit` moved to `fugit` module, added `Pwm` and `fugit-timer` impls [#423] ### Fixed @@ -29,6 +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 - 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] diff --git a/Cargo.toml b/Cargo.toml index 571d6b96..88a5a8b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ embedded-dma = "0.2.0" bare-metal = { version = "1" } cast = { default-features = false, version = "0.3.0" } void = { default-features = false, version = "1.0.2" } -embedded-hal = { features = ["unproven"], version = "0.2.6" } +embedded-hal = { features = ["unproven"], version = "0.2.7" } display-interface = { version = "0.4.1", optional = true } fugit = "0.3.3" fugit-timer = "0.1.3" @@ -52,7 +52,7 @@ version = "0.3" default-features = false [dependencies.embedded-hal-one] -version = "=1.0.0-alpha.6" +version = "1.0.0-alpha.7" package = "embedded-hal" [dependencies.stm32_i2s_v12x] diff --git a/src/fmpi2c/hal_1.rs b/src/fmpi2c/hal_1.rs index 9a7237a5..9567ca2b 100644 --- a/src/fmpi2c/hal_1.rs +++ b/src/fmpi2c/hal_1.rs @@ -1,148 +1,67 @@ +use embedded_hal_one::i2c::ErrorType; + +impl ErrorType for super::FMPI2c { + type Error = super::Error; +} + mod blocking { - use super::super::{fmpi2c1, Error, FMPI2c}; + use super::super::{fmpi2c1, FMPI2c}; use core::ops::Deref; - use embedded_hal_one::i2c::blocking::{Read, Write, WriteRead}; + use embedded_hal_one::i2c::blocking::Operation; - impl WriteRead for FMPI2c + impl embedded_hal_one::i2c::blocking::I2c for FMPI2c where I2C: Deref, { - type Error = Error; - - fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> { - // Set up current slave address for writing and disable autoending - self.i2c.cr2.modify(|_, w| { - w.sadd() - .bits(u16::from(addr) << 1) - .nbytes() - .bits(bytes.len() as u8) - .rd_wrn() - .clear_bit() - .autoend() - .clear_bit() - }); - - // Send a START condition - self.i2c.cr2.modify(|_, w| w.start().set_bit()); - - // Wait until the transmit buffer is empty and there hasn't been any error condition - while { - let isr = self.i2c.isr.read(); - self.check_and_clear_error_flags(&isr) - .map_err(Error::nack_addr)?; - isr.txis().bit_is_clear() && isr.tc().bit_is_clear() - } {} - - // Send out all individual bytes - for c in bytes { - self.send_byte(*c)?; - } - - // Wait until data was sent - while { - let isr = self.i2c.isr.read(); - self.check_and_clear_error_flags(&isr) - .map_err(Error::nack_data)?; - isr.tc().bit_is_clear() - } {} - - // Set up current address for reading - self.i2c.cr2.modify(|_, w| { - w.sadd() - .bits(u16::from(addr) << 1) - .nbytes() - .bits(buffer.len() as u8) - .rd_wrn() - .set_bit() - }); - - // Send another START condition - self.i2c.cr2.modify(|_, w| w.start().set_bit()); - - // Send the autoend after setting the start to get a restart - self.i2c.cr2.modify(|_, w| w.autoend().set_bit()); - - // Now read in all bytes - for c in buffer.iter_mut() { - *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(()) + fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { + self.read(addr, buffer) } - } - impl Read for FMPI2c - where - I2C: Deref, - { - type Error = Error; - - fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> { - // Set up current address for reading - self.i2c.cr2.modify(|_, w| { - w.sadd() - .bits(u16::from(addr) << 1) - .nbytes() - .bits(buffer.len() as u8) - .rd_wrn() - .set_bit() - }); - - // Send a START condition - self.i2c.cr2.modify(|_, w| w.start().set_bit()); - - // Send the autoend after setting the start to get a restart - self.i2c.cr2.modify(|_, w| w.autoend().set_bit()); - - // Now read in all bytes - for c in buffer.iter_mut() { - *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(()) + fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { + self.write(addr, bytes) } - } - impl Write for FMPI2c - where - I2C: Deref, - { - type Error = Error; - - fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { - // Set up current slave address for writing and enable autoending - self.i2c.cr2.modify(|_, w| { - w.sadd() - .bits(u16::from(addr) << 1) - .nbytes() - .bits(bytes.len() as u8) - .rd_wrn() - .clear_bit() - .autoend() - .set_bit() - }); + fn write_iter(&mut self, _addr: u8, _bytes: B) -> Result<(), Self::Error> + where + B: IntoIterator, + { + todo!() + } - // Send a START condition - self.i2c.cr2.modify(|_, w| w.start().set_bit()); + fn write_read( + &mut self, + addr: u8, + bytes: &[u8], + buffer: &mut [u8], + ) -> Result<(), Self::Error> { + self.write_read(addr, bytes, buffer) + } - // Send out all individual bytes - for c in bytes { - self.send_byte(*c)?; - } + fn write_iter_read( + &mut self, + _addr: u8, + _bytes: B, + _buffer: &mut [u8], + ) -> Result<(), Self::Error> + where + B: IntoIterator, + { + todo!() + } - // 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)?; + fn transaction<'a>( + &mut self, + _addr: u8, + _operations: &mut [Operation<'a>], + ) -> Result<(), Self::Error> { + todo!() + } - Ok(()) + fn transaction_iter<'a, O>(&mut self, _addr: u8, _operations: O) -> Result<(), Self::Error> + where + O: IntoIterator>, + { + todo!() } } } diff --git a/src/fugit/hal_1.rs b/src/fugit/hal_1.rs new file mode 100644 index 00000000..cd9f6df7 --- /dev/null +++ b/src/fugit/hal_1.rs @@ -0,0 +1,17 @@ +use super::{Delay, Error, Instance}; + +use embedded_hal_one::delay::blocking::DelayUs; + +use fugit::ExtU32; + +impl DelayUs for Delay { + type Error = Error; + + fn delay_us(&mut self, us: u32) -> Result<(), Self::Error> { + self.delay(us.micros()) + } + + fn delay_ms(&mut self, ms: u32) -> Result<(), Self::Error> { + self.delay(ms.millis()) + } +} diff --git a/src/fugit/mod.rs b/src/fugit/mod.rs index 318a9d7a..75bb8298 100644 --- a/src/fugit/mod.rs +++ b/src/fugit/mod.rs @@ -25,6 +25,7 @@ pub mod pwm; pub use pwm::*; mod hal_02; +mod hal_1; /// Timer wrapper pub struct Timer { diff --git a/src/gpio/hal_1.rs b/src/gpio/hal_1.rs index 91a06155..0998d3a3 100644 --- a/src/gpio/hal_1.rs +++ b/src/gpio/hal_1.rs @@ -5,10 +5,11 @@ use super::{ PushPull, }; -use embedded_hal_one::digital::blocking::{ - InputPin, IoPin, OutputPin, StatefulOutputPin, ToggleableOutputPin, -}; pub use embedded_hal_one::digital::PinState; +use embedded_hal_one::digital::{ + blocking::{InputPin, IoPin, OutputPin, StatefulOutputPin, ToggleableOutputPin}, + ErrorType, +}; fn into_state(state: PinState) -> super::PinState { match state { @@ -18,10 +19,11 @@ fn into_state(state: PinState) -> super::PinState { } // Implementations for `Pin` - -impl OutputPin for Pin, P, N> { +impl ErrorType for Pin { type Error = Infallible; +} +impl OutputPin for Pin, P, N> { #[inline(always)] fn set_high(&mut self) -> Result<(), Self::Error> { self.set_high(); @@ -48,8 +50,6 @@ impl StatefulOutputPin for Pin, P } impl ToggleableOutputPin for Pin, P, N> { - type Error = Infallible; - #[inline(always)] fn toggle(&mut self) -> Result<(), Self::Error> { self.toggle(); @@ -58,8 +58,6 @@ impl ToggleableOutputPin for Pin, } impl InputPin for Pin, P, N> { - type Error = Infallible; - #[inline(always)] fn is_high(&self) -> Result { Ok(self.is_high()) @@ -72,8 +70,6 @@ impl InputPin for Pin, P, N> { } impl InputPin for Pin, P, N> { - type Error = Infallible; - #[inline(always)] fn is_high(&self) -> Result { Ok(self.is_high()) @@ -197,10 +193,11 @@ impl IoPin, P, N>> } // Implementations for `ErasedPin` - -impl OutputPin for ErasedPin> { +impl ErrorType for ErasedPin { type Error = core::convert::Infallible; +} +impl OutputPin for ErasedPin> { #[inline(always)] fn set_high(&mut self) -> Result<(), Self::Error> { self.set_high(); @@ -227,8 +224,6 @@ impl StatefulOutputPin for ErasedPin> { } impl ToggleableOutputPin for ErasedPin> { - type Error = Infallible; - #[inline(always)] fn toggle(&mut self) -> Result<(), Self::Error> { self.toggle(); @@ -237,8 +232,6 @@ impl ToggleableOutputPin for ErasedPin> { } impl InputPin for ErasedPin> { - type Error = core::convert::Infallible; - #[inline(always)] fn is_high(&self) -> Result { Ok(self.is_high()) @@ -251,8 +244,6 @@ impl InputPin for ErasedPin> { } impl InputPin for ErasedPin> { - type Error = core::convert::Infallible; - #[inline(always)] fn is_high(&self) -> Result { Ok(self.is_high()) @@ -265,10 +256,11 @@ impl InputPin for ErasedPin> { } // Implementations for `PartiallyErasedPin` - -impl OutputPin for PartiallyErasedPin, P> { +impl ErrorType for PartiallyErasedPin { type Error = Infallible; +} +impl OutputPin for PartiallyErasedPin, P> { #[inline(always)] fn set_high(&mut self) -> Result<(), Self::Error> { self.set_high(); @@ -295,8 +287,6 @@ impl StatefulOutputPin for PartiallyErasedPin, } impl ToggleableOutputPin for PartiallyErasedPin, P> { - type Error = Infallible; - #[inline(always)] fn toggle(&mut self) -> Result<(), Self::Error> { self.toggle(); @@ -305,8 +295,6 @@ impl ToggleableOutputPin for PartiallyErasedPin InputPin for PartiallyErasedPin, P> { - type Error = Infallible; - #[inline(always)] fn is_high(&self) -> Result { Ok(self.is_high()) @@ -319,8 +307,6 @@ impl InputPin for PartiallyErasedPin, P> { } impl InputPin for PartiallyErasedPin, P> { - type Error = Infallible; - #[inline(always)] fn is_high(&self) -> Result { Ok(self.is_high()) diff --git a/src/i2c/hal_1.rs b/src/i2c/hal_1.rs index 9d95f81b..30ea3260 100644 --- a/src/i2c/hal_1.rs +++ b/src/i2c/hal_1.rs @@ -1,4 +1,4 @@ -use embedded_hal_one::i2c::{Error, ErrorKind, NoAcknowledgeSource}; +use embedded_hal_one::i2c::{Error, ErrorKind, ErrorType, NoAcknowledgeSource}; impl Error for super::Error { fn kind(&self) -> ErrorKind { @@ -14,15 +14,29 @@ impl Error for super::Error { } } +impl ErrorType for super::I2c { + type Error = super::Error; +} + mod blocking { - use super::super::{Error, I2c, Instance}; - use embedded_hal_one::i2c::blocking::{Read, Write, WriteIter, WriteIterRead, WriteRead}; + use super::super::{I2c, Instance}; + use embedded_hal_one::i2c::blocking::Operation; + + impl embedded_hal_one::i2c::blocking::I2c for I2c { + fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { + self.read(addr, buffer) + } + + fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { + self.write(addr, bytes) + } - impl WriteRead for I2c - where - I2C: Instance, - { - type Error = Error; + fn write_iter(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error> + where + B: IntoIterator, + { + self.write_iter(addr, bytes) + } fn write_read( &mut self, @@ -32,13 +46,6 @@ mod blocking { ) -> Result<(), Self::Error> { self.write_read(addr, bytes, buffer) } - } - - impl WriteIterRead for I2c - where - I2C: Instance, - { - type Error = Error; fn write_iter_read( &mut self, @@ -51,41 +58,20 @@ mod blocking { { self.write_iter_read(addr, bytes, buffer) } - } - - impl Write for I2c - where - I2C: Instance, - { - type Error = Error; - fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { - self.write(addr, bytes) + fn transaction<'a>( + &mut self, + _addr: u8, + _operations: &mut [Operation<'a>], + ) -> Result<(), Self::Error> { + todo!() } - } - impl WriteIter for I2c - where - I2C: Instance, - { - type Error = Error; - - fn write_iter(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error> + fn transaction_iter<'a, O>(&mut self, _addr: u8, _operations: O) -> Result<(), Self::Error> where - B: IntoIterator, + O: IntoIterator>, { - self.write_iter(addr, bytes) - } - } - - impl Read for I2c - where - I2C: Instance, - { - type Error = Error; - - fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { - self.read(addr, buffer) + todo!() } } } diff --git a/src/pwm.rs b/src/pwm.rs index 25b4b8ae..fa1749f0 100644 --- a/src/pwm.rs +++ b/src/pwm.rs @@ -2,7 +2,7 @@ use crate::{ time::{Hertz, U32Ext}, timer::{compute_arr_presc, Channel, Instance, Ocm, Timer, WithPwm}, }; -use core::{convert::Infallible, marker::PhantomData}; +use core::marker::PhantomData; pub trait Pins { const C1: bool = false; @@ -146,27 +146,6 @@ impl embedded_hal::PwmPin for PwmChannel { } } -impl embedded_hal_one::pwm::blocking::PwmPin for PwmChannel { - type Error = Infallible; - type Duty = u16; - - fn disable(&mut self) -> Result<(), Self::Error> { - Ok(self.disable()) - } - fn enable(&mut self) -> Result<(), Self::Error> { - Ok(self.enable()) - } - fn get_duty(&self) -> Result { - Ok(self.get_duty()) - } - fn get_max_duty(&self) -> Result { - Ok(self.get_max_duty()) - } - fn set_duty(&mut self, duty: Self::Duty) -> Result<(), Self::Error> { - Ok(self.set_duty(duty)) - } -} - impl Timer { pub fn pwm(mut self, _pins: PINS, freq: T) -> Pwm where diff --git a/src/qei.rs b/src/qei.rs index 6ad27262..8328a061 100644 --- a/src/qei.rs +++ b/src/qei.rs @@ -59,23 +59,6 @@ impl embedded_hal::Qei for Qei { } } -impl embedded_hal_one::qei::blocking::Qei for Qei { - type Error = core::convert::Infallible; - type Count = TIM::Width; - - fn count(&self) -> Result { - Ok(self.tim.read_count() as Self::Count) - } - - fn direction(&self) -> Result { - Ok(if self.tim.read_direction() { - embedded_hal_one::qei::Direction::Upcounting - } else { - embedded_hal_one::qei::Direction::Downcounting - }) - } -} - pub trait Instance: crate::Sealed + rcc::Enable + rcc::Reset + General { fn setup_qei(&mut self); diff --git a/src/serial/hal_1.rs b/src/serial/hal_1.rs index 3510c425..1f698b46 100644 --- a/src/serial/hal_1.rs +++ b/src/serial/hal_1.rs @@ -1,4 +1,4 @@ -use embedded_hal_one::serial::{Error, ErrorKind}; +use embedded_hal_one::serial::{Error, ErrorKind, ErrorType}; impl Error for super::Error { fn kind(&self) -> ErrorKind { @@ -11,25 +11,36 @@ impl Error for super::Error { } } +impl ErrorType for super::Serial { + type Error = super::Error; +} + +impl ErrorType for super::Rx { + type Error = super::Error; +} + +impl ErrorType for super::Tx { + type Error = super::Error; +} + mod nb { use super::super::{Error, Instance, Rx, Serial, Tx}; - use embedded_hal_one::serial::nb::{Read, Write}; + use embedded_hal_one::serial::{ + nb::{Read, Write}, + ErrorType, + }; - impl Read for Serial + impl Read for Serial where USART: Instance, - Rx: Read, + Rx: Read + ErrorType, { - type Error = Error; - fn read(&mut self) -> nb::Result { self.rx.read() } } impl Read for Rx { - type Error = Error; - fn read(&mut self) -> nb::Result { // Delegate to the Read implementation, then truncate to 8 bits Rx::::new().read().map(|word16| word16 as u8) @@ -42,8 +53,6 @@ mod nb { /// 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 { - type Error = Error; - fn read(&mut self) -> nb::Result { // NOTE(unsafe) atomic read with no side effects let sr = unsafe { (*USART::ptr()).sr.read() }; @@ -74,13 +83,11 @@ mod nb { } } - impl Write for Serial + impl Write for Serial where USART: Instance, - Tx: Write, + Tx: Write + ErrorType, { - type Error = Error; - fn flush(&mut self) -> nb::Result<(), Self::Error> { self.tx.flush() } @@ -91,8 +98,6 @@ mod nb { } impl Write for Tx { - type Error = Error; - fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { // Delegate to u16 version Tx::::new().write(u16::from(word)) @@ -110,8 +115,6 @@ mod nb { /// 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 { - type Error = Error; - fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> { // NOTE(unsafe) atomic read with no side effects let sr = unsafe { (*USART::ptr()).sr.read() }; @@ -139,12 +142,10 @@ mod nb { } mod blocking { - use super::super::{Error, Instance, Serial, Tx}; + use super::super::{Instance, Serial, Tx}; use embedded_hal_one::serial::{self, blocking::Write}; impl Write for Tx { - type Error = Error; - fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { for &b in bytes { loop { @@ -170,8 +171,6 @@ mod blocking { } impl Write for Serial { - type Error = Error; - fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { self.tx.write(bytes) } @@ -182,8 +181,6 @@ mod blocking { } impl Write for Tx { - type Error = Error; - fn write(&mut self, buffer: &[u16]) -> Result<(), Self::Error> { for &b in buffer { loop { @@ -209,8 +206,6 @@ mod blocking { } impl Write for Serial { - type Error = Error; - fn write(&mut self, bytes: &[u16]) -> Result<(), Self::Error> { self.tx.write(bytes) } diff --git a/src/spi/hal_1.rs b/src/spi/hal_1.rs index 24c4a807..c6d2f686 100644 --- a/src/spi/hal_1.rs +++ b/src/spi/hal_1.rs @@ -1,4 +1,4 @@ -pub use embedded_hal_one::spi::{Error, ErrorKind, Mode, Phase, Polarity}; +pub use embedded_hal_one::spi::{Error, ErrorKind, ErrorType, Mode, Phase, Polarity}; impl From for super::Polarity { fn from(p: Polarity) -> Self { @@ -37,6 +37,10 @@ impl Error for super::Error { } } +impl ErrorType for super::Spi { + type Error = super::Error; +} + mod nb { use super::super::{Error, Instance, Spi, TransferModeBidi, TransferModeNormal}; use embedded_hal_one::spi::nb::FullDuplex; @@ -45,8 +49,6 @@ mod nb { where SPI: Instance, { - type Error = Error; - fn read(&mut self) -> nb::Result { self.check_read() } @@ -60,8 +62,6 @@ mod nb { where SPI: Instance, { - type Error = Error; - fn read(&mut self) -> nb::Result { self.spi.cr1.modify(|_, w| w.bidioe().clear_bit()); self.check_read() @@ -86,8 +86,6 @@ mod blocking { Self: FullDuplex, SPI: Instance, { - type Error = Error; - fn transfer_inplace(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { for word in words.iter_mut() { nb::block!(self.write(*word))?; @@ -103,8 +101,6 @@ mod blocking { Self: FullDuplex, SPI: Instance, { - type Error = Error; - fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { for word in words { nb::block!(>::write(self, *word))?; @@ -120,8 +116,6 @@ mod blocking { Self: FullDuplex, SPI: Instance, { - type Error = Error; - fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { for word in words { nb::block!(>::write(self, *word))?; @@ -136,8 +130,6 @@ mod blocking { Self: FullDuplex, SPI: Instance, { - type Error = Error; - fn write_iter(&mut self, words: WI) -> Result<(), Self::Error> where WI: IntoIterator, @@ -156,8 +148,6 @@ mod blocking { Self: FullDuplex, SPI: Instance, { - type Error = Error; - fn write_iter(&mut self, words: WI) -> Result<(), Self::Error> where WI: IntoIterator, @@ -170,12 +160,10 @@ mod blocking { } } - impl Transactional for Spi + impl Transactional for Spi where Self: Write + TransferInplace, { - type Error = Error; - fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Error> { for op in operations { match op {