From f5d27d3ac8c39c61449130fb674869e2716cf5c1 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Tue, 6 Jul 2021 07:23:29 +0300 Subject: [PATCH] use embedded-hal 1.0 with ehal1 feature --- CHANGELOG.md | 2 + Cargo.toml | 5 ++ src/adc.rs | 8 +++- src/delay/mod.rs | 73 ++++++++++++++++++++++++++++- src/delay/syst.rs | 2 +- src/delay/timer.rs | 2 +- src/dwt.rs | 26 ++++++++++- src/gpio.rs | 5 +- src/i2c.rs | 2 +- src/lib.rs | 12 +++++ src/prelude.rs | 47 ++++++++++++------- src/pwm.rs | 59 +++++++++++++++++++++++- src/qei.rs | 32 +++++++++++-- src/serial.rs | 111 +++++++++++++++++++++++++++++++++++++++++---- src/spi.rs | 37 +++++++++++++-- src/timer.rs | 36 ++++++++++++--- src/watchdog.rs | 31 +++++++++++-- 17 files changed, 438 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c1925b7..7126b345 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed +- Use both `0.2.x` and `1.0` `embedded-hal` crates. + With `ehal1` option enabled traits of `1.0` version are used. - Add `Spi::new` and deprecate `Spi:spix`, deprecate `Serial::usartx`, remove deprecated `I2c::i2cx` - Deprecate `free` in favour of `release` - Clean features in `serial`, `spi`, `i2c`, `timer` diff --git a/Cargo.toml b/Cargo.toml index 6e672e44..9f4cde34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,11 @@ display-interface = { version = "0.4.0", optional = true } version = "0.2.0" optional = true +[dependencies.ehal1] +package = "embedded-hal" +git = "https://github.com/rust-embedded/embedded-hal" +optional = true + [dev-dependencies] panic-semihosting = "0.5.3" cortex-m-semihosting = "0.3.3" diff --git a/src/adc.rs b/src/adc.rs index 514a9d84..676631b1 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -9,10 +9,10 @@ */ use crate::dma::traits::PeriAddress; +use crate::hal_nb::adc::{Channel, OneShot}; use crate::rcc::{Enable, Reset}; use crate::{gpio::*, pac, signature::VrefCal, signature::VDDA_CALIB}; use core::fmt; -use embedded_hal::adc::{Channel, OneShot}; /// Vref internal signal, used for calibration pub struct Vref; @@ -28,7 +28,10 @@ macro_rules! adc_pins { $( impl Channel for $pin { type ID = u8; + #[cfg(not(feature = "ehal1"))] fn channel() -> u8 { $chan } + #[cfg(feature = "ehal1")] + fn channel(&self) -> u8 { $chan } } )+ }; @@ -909,7 +912,10 @@ macro_rules! adc { } }); + #[cfg(not(feature = "ehal1"))] let channel = CHANNEL::channel(); + #[cfg(feature = "ehal1")] + let channel = _channel.channel(); //Set the channel in the right sequence field match sequence { diff --git a/src/delay/mod.rs b/src/delay/mod.rs index c3152aed..5577dcf9 100644 --- a/src/delay/mod.rs +++ b/src/delay/mod.rs @@ -1,5 +1,7 @@ //! Delays +use crate::hal::blocking::delay::{DelayMs, DelayUs}; + mod syst; use cortex_m::peripheral::SYST; @@ -7,9 +9,76 @@ use cortex_m::peripheral::SYST; use crate::rcc::Clocks; /// Timer as a delay provider (SysTick by default) -pub struct Delay { - tim: T, +pub struct Delay { + tim: TIM, clocks: Clocks, } mod timer; + +mod infallible { + pub trait DelayMs { + fn delay_ms(&mut self, ms: UXX); + } + + pub trait DelayUs { + fn delay_us(&mut self, us: UXX); + } +} + +impl Delay { + pub fn delay_ms(&mut self, ms: T) + where + Self: infallible::DelayMs, + { + >::delay_ms(self, ms) + } + pub fn delay_us(&mut self, us: T) + where + Self: infallible::DelayUs, + { + >::delay_us(self, us) + } +} + +#[cfg(not(feature = "ehal1"))] +impl DelayMs for Delay +where + Self: infallible::DelayMs, +{ + fn delay_ms(&mut self, ms: UXX) { + >::delay_ms(self, ms); + } +} +#[cfg(feature = "ehal1")] +impl DelayMs for Delay +where + Self: infallible::DelayMs, +{ + type Error = core::convert::Infallible; + fn delay_ms(&mut self, ms: UXX) -> Result<(), Self::Error> { + >::delay_ms(self, ms); + Ok(()) + } +} + +#[cfg(not(feature = "ehal1"))] +impl DelayUs for Delay +where + Self: infallible::DelayUs, +{ + fn delay_us(&mut self, us: UXX) { + >::delay_us(self, us); + } +} +#[cfg(feature = "ehal1")] +impl DelayUs for Delay +where + Self: infallible::DelayUs, +{ + type Error = core::convert::Infallible; + fn delay_us(&mut self, us: UXX) -> Result<(), Self::Error> { + >::delay_us(self, us); + Ok(()) + } +} diff --git a/src/delay/syst.rs b/src/delay/syst.rs index 008a5ce2..ef906752 100644 --- a/src/delay/syst.rs +++ b/src/delay/syst.rs @@ -4,8 +4,8 @@ use cast::u32; use cortex_m::peripheral::syst::SystClkSource; use cortex_m::peripheral::SYST; +use super::infallible::{DelayMs, DelayUs}; use crate::rcc::Clocks; -use embedded_hal::blocking::delay::{DelayMs, DelayUs}; use super::Delay; diff --git a/src/delay/timer.rs b/src/delay/timer.rs index 9261775c..f0e0fef7 100644 --- a/src/delay/timer.rs +++ b/src/delay/timer.rs @@ -5,8 +5,8 @@ use core::cmp::max; +use super::infallible::{DelayMs, DelayUs}; use cast::{u16, u32}; -use embedded_hal::blocking::delay::{DelayMs, DelayUs}; use crate::{ pac::{self, RCC}, diff --git a/src/dwt.rs b/src/dwt.rs index b650ecac..b1edc74e 100644 --- a/src/dwt.rs +++ b/src/dwt.rs @@ -1,9 +1,9 @@ //! Debug and trace and stuff +use crate::hal::blocking::delay::{DelayMs, DelayUs}; use crate::rcc::Clocks; use crate::time::Hertz; use cortex_m::peripheral::{DCB, DWT}; -use embedded_hal::blocking::delay::{DelayMs, DelayUs}; pub trait DwtExt { fn constrain(self, dcb: DCB, clocks: Clocks) -> Dwt; @@ -100,6 +100,7 @@ impl Delay { } // Implement DelayUs/DelayMs for various integer types +#[cfg(not(feature = "ehal1"))] impl> DelayUs for Delay { fn delay_us(&mut self, us: T) { // Convert us to ticks @@ -108,6 +109,18 @@ impl> DelayUs for Delay { Delay::delay_ticks(start, ticks); } } +#[cfg(feature = "ehal1")] +impl> DelayUs for Delay { + type Error = core::convert::Infallible; + fn delay_us(&mut self, us: T) -> Result<(), Self::Error> { + // Convert us to ticks + let start = DWT::get_cycle_count(); + let ticks = (us.into() * self.clock.0 as u64) / 1_000_000; + Delay::delay_ticks(start, ticks); + Ok(()) + } +} +#[cfg(not(feature = "ehal1"))] impl> DelayMs for Delay { fn delay_ms(&mut self, ms: T) { // Convert ms to ticks @@ -116,6 +129,17 @@ impl> DelayMs for Delay { Delay::delay_ticks(start, ticks); } } +#[cfg(feature = "ehal1")] +impl> DelayMs for Delay { + type Error = core::convert::Infallible; + fn delay_ms(&mut self, ms: T) -> Result<(), Self::Error> { + // Convert ms to ticks + let start = DWT::get_cycle_count(); + let ticks = (ms.into() * self.clock.0 as u64) / 1_000; + Delay::delay_ticks(start, ticks); + Ok(()) + } +} /// Very simple stopwatch which reads from DWT Cycle Counter to record timing. /// diff --git a/src/gpio.rs b/src/gpio.rs index 61a09f1c..24cfecc3 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -3,7 +3,10 @@ use core::convert::Infallible; use core::marker::PhantomData; -use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin}; +#[cfg(feature = "ehal1")] +use crate::hal::blocking::digital::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin}; +#[cfg(not(feature = "ehal1"))] +use crate::hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin}; use crate::pac::EXTI; use crate::syscfg::SysCfg; diff --git a/src/i2c.rs b/src/i2c.rs index ef13fbd9..d042ed8d 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -1,5 +1,5 @@ +use crate::hal::blocking::i2c::{Read, Write, WriteRead}; use core::ops::Deref; -use embedded_hal::blocking::i2c::{Read, Write, WriteRead}; use crate::pac::i2c1; use crate::rcc::{Enable, Reset}; diff --git a/src/lib.rs b/src/lib.rs index a60ef1c5..2aac4dbb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,8 +23,20 @@ compile_error!( stm32f479" ); +#[cfg(feature = "ehal1")] +pub use ehal1 as hal; +#[cfg(not(feature = "ehal1"))] pub use embedded_hal as hal; +#[cfg(not(feature = "ehal1"))] +use crate::hal as hal_blocking; +#[cfg(not(feature = "ehal1"))] +use crate::hal as hal_nb; +#[cfg(feature = "ehal1")] +use crate::hal::blocking as hal_blocking; +#[cfg(feature = "ehal1")] +use crate::hal::nb as hal_nb; + pub use nb; pub use nb::block; diff --git a/src/prelude.rs b/src/prelude.rs index 0034f453..aea5c130 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -36,27 +36,42 @@ //! ``` //! use stm32f4xx_hal::prelude::*; //! ``` -pub use embedded_hal::adc::OneShot as _embedded_hal_adc_OneShot; -pub use embedded_hal::blocking::delay::DelayMs as _embedded_hal_blocking_delay_DelayMs; -pub use embedded_hal::blocking::delay::DelayUs as _embedded_hal_blocking_delay_DelayUs; -pub use embedded_hal::blocking::i2c::{ +pub use crate::hal::blocking::delay::DelayMs as _embedded_hal_blocking_delay_DelayMs; +pub use crate::hal::blocking::delay::DelayUs as _embedded_hal_blocking_delay_DelayUs; +pub use crate::hal::blocking::i2c::{ Read as _embedded_hal_blocking_i2c_Read, Write as _embedded_hal_blocking_i2c_Write, WriteRead as _embedded_hal_blocking_i2c_WriteRead, }; -pub use embedded_hal::blocking::serial::Write as _embedded_hal_blocking_serial_Write; -pub use embedded_hal::blocking::spi::{ +#[cfg(feature = "ehal1")] +pub use crate::hal::blocking::pwm::Pwm as _embedded_hal_blocking_pwm_Pwm; +#[cfg(feature = "ehal1")] +pub use crate::hal::blocking::qei::Qei as _embedded_hal_blocking_qei_Qei; +pub use crate::hal::blocking::serial::Write as _embedded_hal_blocking_serial_Write; +pub use crate::hal::blocking::spi::{ Transfer as _embedded_hal_blocking_spi_Transfer, Write as _embedded_hal_blocking_spi_Write, }; -pub use embedded_hal::serial::Read as _embedded_hal_serial_Read; -pub use embedded_hal::serial::Write as _embedded_hal_serial_Write; -pub use embedded_hal::spi::FullDuplex as _embedded_hal_spi_FullDuplex; -pub use embedded_hal::timer::CountDown as _embedded_hal_timer_CountDown; -pub use embedded_hal::watchdog::Watchdog as _embedded_hal_watchdog_Watchdog; -pub use embedded_hal::watchdog::WatchdogDisable as _embedded_hal_watchdog_WatchdogDisable; -pub use embedded_hal::watchdog::WatchdogEnable as _embedded_hal_watchdog_WatchdogEnable; -pub use embedded_hal::Capture as _embedded_hal_Capture; -pub use embedded_hal::Pwm as _embedded_hal_Pwm; -pub use embedded_hal::Qei as _embedded_hal_Qei; +#[cfg(feature = "ehal1")] +pub use crate::hal::blocking::watchdog::Disable as _embedded_hal_blocking_watchdog_Disable; +#[cfg(feature = "ehal1")] +pub use crate::hal::blocking::watchdog::Enable as _embedded_hal_blocking_watchdog_Enable; +#[cfg(feature = "ehal1")] +pub use crate::hal::nb::capture::Capture as _embedded_hal_nb_capture_Capture; +#[cfg(not(feature = "ehal1"))] +pub use crate::hal::watchdog::WatchdogDisable as _embedded_hal_blocking_watchdog_Disable; +#[cfg(not(feature = "ehal1"))] +pub use crate::hal::watchdog::WatchdogEnable as _embedded_hal_blocking_watchdog_Enable; +#[cfg(not(feature = "ehal1"))] +pub use crate::hal::Capture as _embedded_hal_nb_capture_Capture; +#[cfg(not(feature = "ehal1"))] +pub use crate::hal::Pwm as _embedded_hal_blocking_pwm_Pwm; +#[cfg(not(feature = "ehal1"))] +pub use crate::hal::Qei as _embedded_hal_blocking_qei_Qei; +pub use crate::hal_blocking::watchdog::Watchdog as _embedded_hal_blocking_watchdog_Watchdog; +pub use crate::hal_nb::adc::OneShot as _embedded_hal_nb_adc_OneShot; +pub use crate::hal_nb::serial::Read as _embedded_hal_nb_serial_Read; +pub use crate::hal_nb::serial::Write as _embedded_hal_nb_serial_Write; +pub use crate::hal_nb::spi::FullDuplex as _embedded_hal_nb_spi_FullDuplex; +pub use crate::hal_nb::timer::CountDown as _embedded_hal_nb_timer_CountDown; #[cfg(all(feature = "device-selected", feature = "dac"))] pub use crate::dac::DacExt as _stm32f4xx_hal_dac_DacExt; diff --git a/src/pwm.rs b/src/pwm.rs index 04d6f49e..4dcc7077 100644 --- a/src/pwm.rs +++ b/src/pwm.rs @@ -1,5 +1,5 @@ use crate::{ - bb, hal as pwm, + bb, pac::RCC, rcc::{Clocks, Enable, Reset}, time::Hertz, @@ -7,6 +7,11 @@ use crate::{ use cast::{u16, u32}; use core::{marker::PhantomData, mem::MaybeUninit}; +#[cfg(not(feature = "ehal1"))] +use crate::hal as pwm; +#[cfg(feature = "ehal1")] +use crate::hal::blocking::pwm; + use crate::pac::{TIM1, TIM11, TIM5, TIM9}; #[cfg(any( @@ -173,6 +178,7 @@ macro_rules! pwm_pin { } } + #[cfg(not(feature = "ehal1"))] impl pwm::PwmPin for PwmChannels<$TIMX, $C> { type Duty = u16; fn disable(&mut self) { @@ -191,6 +197,31 @@ macro_rules! pwm_pin { self.set_duty(duty) } } + + #[cfg(feature = "ehal1")] + impl pwm::PwmPin for PwmChannels<$TIMX, $C> { + type Error = core::convert::Infallible; + type Duty = u16; + + fn disable(&mut self) -> Result<(), Self::Error> { + self.disable(); + Ok(()) + } + fn enable(&mut self) -> Result<(), Self::Error> { + self.enable(); + Ok(()) + } + 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> { + self.set_duty(duty); + Ok(()) + } + } }; } @@ -425,6 +456,7 @@ macro_rules! pwm_pin_tim5 { } } + #[cfg(not(feature = "ehal1"))] impl pwm::PwmPin for PwmChannels<$TIMX, $C> { type Duty = u16; fn disable(&mut self) { @@ -443,6 +475,31 @@ macro_rules! pwm_pin_tim5 { self.set_duty(duty) } } + + #[cfg(feature = "ehal1")] + impl pwm::PwmPin for PwmChannels<$TIMX, $C> { + type Error = core::convert::Infallible; + type Duty = u16; + + fn disable(&mut self) -> Result<(), Self::Error> { + self.disable(); + Ok(()) + } + fn enable(&mut self) -> Result<(), Self::Error> { + self.enable(); + Ok(()) + } + 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> { + self.set_duty(duty); + Ok(()) + } + } }; } diff --git a/src/qei.rs b/src/qei.rs index 01642f4c..f15dd4df 100644 --- a/src/qei.rs +++ b/src/qei.rs @@ -1,10 +1,14 @@ //! # Quadrature Encoder Interface use crate::{ - hal::{self, Direction}, pac::RCC, rcc::{Enable, Reset}, }; +#[cfg(not(feature = "ehal1"))] +use crate::hal as qei; +#[cfg(feature = "ehal1")] +use crate::hal::blocking::qei; + pub trait Pins {} use crate::timer::PinC1; use crate::timer::PinC2; @@ -41,21 +45,39 @@ impl Qei { } } -impl hal::Qei for Qei { +#[cfg(not(feature = "ehal1"))] +impl qei::Qei for Qei { type Count = TIM::Count; fn count(&self) -> Self::Count { self.tim.read_count() as Self::Count } - fn direction(&self) -> Direction { + fn direction(&self) -> qei::Direction { if self.tim.read_direction() { - hal::Direction::Upcounting + qei::Direction::Upcounting } else { - hal::Direction::Downcounting + qei::Direction::Downcounting } } } +#[cfg(feature = "ehal1")] +impl qei::Qei for Qei { + type Error = core::convert::Infallible; + type Count = TIM::Count; + + fn count(&self) -> Result { + Ok(self.tim.read_count() as Self::Count) + } + + fn direction(&self) -> Result { + Ok(if self.tim.read_direction() { + qei::Direction::Upcounting + } else { + qei::Direction::Downcounting + }) + } +} mod sealed { pub trait Sealed {} diff --git a/src/serial.rs b/src/serial.rs index 4177fead..9fe09f6c 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -19,10 +19,9 @@ use core::fmt; use core::marker::PhantomData; +use crate::hal::blocking; +use crate::hal_nb::serial; use crate::rcc::Enable; -use embedded_hal::blocking; -use embedded_hal::prelude::*; -use embedded_hal::serial; use nb::block; #[cfg(feature = "gpiod")] @@ -1038,10 +1037,11 @@ where { type Error = Error; + #[cfg(not(feature = "ehal1"))] fn bwrite_all(&mut self, buffer: &[u16]) -> Result<(), Self::Error> { for &b in buffer { loop { - match self.write(b) { + match serial::Write::write(self, b) { Err(nb::Error::WouldBlock) => continue, Err(nb::Error::Other(err)) => return Err(err), Ok(()) => break, @@ -1051,9 +1051,35 @@ where Ok(()) } + #[cfg(feature = "ehal1")] + fn write(&mut self, buffer: &[u16]) -> Result<(), Self::Error> { + for &b in buffer { + loop { + match serial::Write::write(self, b) { + Err(nb::Error::WouldBlock) => continue, + Err(nb::Error::Other(err)) => return Err(err), + Ok(()) => break, + } + } + } + Ok(()) + } + + #[cfg(not(feature = "ehal1"))] fn bflush(&mut self) -> Result<(), Self::Error> { loop { - match >::flush(self) { + match serial::Write::flush(self) { + Ok(()) => return Ok(()), + Err(nb::Error::WouldBlock) => continue, + Err(nb::Error::Other(err)) => return Err(err), + } + } + } + + #[cfg(feature = "ehal1")] + fn flush(&mut self) -> Result<(), Self::Error> { + loop { + match serial::Write::flush(self) { Ok(()) => return Ok(()), Err(nb::Error::WouldBlock) => continue, Err(nb::Error::Other(err)) => return Err(err), @@ -1068,10 +1094,25 @@ where { type Error = Error; + #[cfg(not(feature = "ehal1"))] fn bwrite_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { for &b in bytes { loop { - match self.write(b) { + match serial::Write::write(self, b) { + Err(nb::Error::WouldBlock) => continue, + Err(nb::Error::Other(err)) => return Err(err), + Ok(()) => break, + } + } + } + Ok(()) + } + + #[cfg(feature = "ehal1")] + fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { + for &b in bytes { + loop { + match serial::Write::write(self, b) { Err(nb::Error::WouldBlock) => continue, Err(nb::Error::Other(err)) => return Err(err), Ok(()) => break, @@ -1081,9 +1122,21 @@ where Ok(()) } + #[cfg(not(feature = "ehal1"))] fn bflush(&mut self) -> Result<(), Self::Error> { loop { - match >::flush(self) { + match serial::Write::flush(self) { + Ok(()) => return Ok(()), + Err(nb::Error::WouldBlock) => continue, + Err(nb::Error::Other(err)) => return Err(err), + } + } + } + + #[cfg(feature = "ehal1")] + fn flush(&mut self) -> Result<(), Self::Error> { + loop { + match serial::Write::flush(self) { Ok(()) => return Ok(()), Err(nb::Error::WouldBlock) => continue, Err(nb::Error::Other(err)) => return Err(err), @@ -1098,6 +1151,7 @@ where { type Error = Error; + #[cfg(not(feature = "ehal1"))] fn bwrite_all(&mut self, bytes: &[u16]) -> Result<(), Self::Error> { let mut tx: Tx = Tx { _usart: PhantomData, @@ -1106,6 +1160,16 @@ where tx.bwrite_all(bytes) } + #[cfg(feature = "ehal1")] + fn write(&mut self, bytes: &[u16]) -> Result<(), Self::Error> { + let mut tx: Tx = Tx { + _usart: PhantomData, + _word: PhantomData, + }; + tx.write(bytes) + } + + #[cfg(not(feature = "ehal1"))] fn bflush(&mut self) -> Result<(), Self::Error> { let mut tx: Tx = Tx { _usart: PhantomData, @@ -1113,6 +1177,15 @@ where }; tx.bflush() } + + #[cfg(feature = "ehal1")] + fn flush(&mut self) -> Result<(), Self::Error> { + let mut tx: Tx = Tx { + _usart: PhantomData, + _word: PhantomData, + }; + tx.flush() + } } impl blocking::serial::Write for Serial @@ -1121,6 +1194,7 @@ where { type Error = Error; + #[cfg(not(feature = "ehal1"))] fn bwrite_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { let mut tx: Tx = Tx { _usart: PhantomData, @@ -1129,6 +1203,16 @@ where tx.bwrite_all(bytes) } + #[cfg(feature = "ehal1")] + fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { + let mut tx: Tx = Tx { + _usart: PhantomData, + _word: PhantomData, + }; + tx.write(bytes) + } + + #[cfg(not(feature = "ehal1"))] fn bflush(&mut self) -> Result<(), Self::Error> { let mut tx: Tx = Tx { _usart: PhantomData, @@ -1136,6 +1220,15 @@ where }; tx.bflush() } + + #[cfg(feature = "ehal1")] + fn flush(&mut self) -> Result<(), Self::Error> { + let mut tx: Tx = Tx { + _usart: PhantomData, + _word: PhantomData, + }; + tx.flush() + } } impl Serial @@ -1328,7 +1421,7 @@ where { fn write_str(&mut self, s: &str) -> fmt::Result { s.bytes() - .try_for_each(|c| block!(self.write(c))) + .try_for_each(|c| block!(serial::Write::write(self, c))) .map_err(|_| fmt::Error) } } @@ -1339,7 +1432,7 @@ where { fn write_str(&mut self, s: &str) -> fmt::Result { s.bytes() - .try_for_each(|c| block!(self.write(c))) + .try_for_each(|c| block!(serial::Write::write(self, c))) .map_err(|_| fmt::Error) } } diff --git a/src/spi.rs b/src/spi.rs index c59282b0..9d5d7768 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -1,8 +1,8 @@ use core::ops::Deref; use core::ptr; -use embedded_hal::spi; -pub use embedded_hal::spi::{Mode, Phase, Polarity}; +use crate::hal_nb::spi; +pub use crate::hal_nb::spi::{Mode, Phase, Polarity}; #[allow(unused)] #[cfg(feature = "gpiod")] @@ -549,6 +549,7 @@ where }) } + #[cfg(not(feature = "ehal1"))] fn send(&mut self, byte: u8) -> nb::Result<(), Error> { let sr = self.spi.sr.read(); @@ -575,14 +576,42 @@ where nb::Error::WouldBlock }) } + + #[cfg(feature = "ehal1")] + fn write(&mut self, byte: u8) -> nb::Result<(), Error> { + let sr = self.spi.sr.read(); + + Err(if sr.ovr().bit_is_set() { + // Read from the DR to clear the OVR bit + let _ = self.spi.dr.read(); + nb::Error::Other(Error::Overrun) + } else if sr.modf().bit_is_set() { + // Write to CR1 to clear MODF + self.spi.cr1.modify(|_r, w| w); + nb::Error::Other(Error::ModeFault) + } else if sr.crcerr().bit_is_set() { + // Clear the CRCERR bit + self.spi.sr.modify(|_r, w| { + w.crcerr().clear_bit(); + w + }); + nb::Error::Other(Error::Crc) + } else if sr.txe().bit_is_set() { + // NOTE(write_volatile) see note above + unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut u8, byte) } + return Ok(()); + } else { + nb::Error::WouldBlock + }) + } } -impl embedded_hal::blocking::spi::transfer::Default for Spi where +impl crate::hal::blocking::spi::transfer::Default for Spi where SPI: Deref { } -impl embedded_hal::blocking::spi::write::Default for Spi where +impl crate::hal::blocking::spi::write::Default for Spi where SPI: Deref { } diff --git a/src/timer.rs b/src/timer.rs index a8f9f2cf..2dda754c 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -3,11 +3,10 @@ //! Pins can be used for PWM output in both push-pull mode (`Alternate`) and open-drain mode //! (`AlternateOD`). +use crate::hal_nb::timer::{Cancel, CountDown, Periodic}; use cast::{u16, u32}; use cortex_m::peripheral::syst::SystClkSource; use cortex_m::peripheral::{DCB, DWT, SYST}; -use embedded_hal::timer::{Cancel, CountDown, Periodic}; -use void::Void; use crate::pac::RCC; @@ -40,7 +39,10 @@ impl Timer { { syst.set_clock_source(SystClkSource::Core); let mut timer = Timer { tim: syst, clocks }; + #[cfg(not(feature = "ehal1"))] timer.start(timeout); + #[cfg(feature = "ehal1")] + timer.start(timeout).unwrap(); timer } @@ -59,10 +61,21 @@ impl Timer { } } +#[cfg(not(feature = "ehal1"))] +type CDStartResult = (); +#[cfg(feature = "ehal1")] +type CDStartResult = Result<(), Error>; +#[cfg(not(feature = "ehal1"))] +type CDWaitResult = nb::Result<(), void::Void>; +#[cfg(feature = "ehal1")] +type CDWaitResult = nb::Result<(), Error>; + impl CountDown for Timer { + #[cfg(feature = "ehal1")] + type Error = Error; type Time = Hertz; - fn start(&mut self, timeout: T) + fn start(&mut self, timeout: T) -> CDStartResult where T: Into, { @@ -73,9 +86,11 @@ impl CountDown for Timer { self.tim.set_reload(rvr); self.tim.clear_current(); self.tim.enable_counter(); + #[cfg(feature = "ehal1")] + Ok(()) } - fn wait(&mut self) -> nb::Result<(), Void> { + fn wait(&mut self) -> CDWaitResult { if self.tim.has_wrapped() { Ok(()) } else { @@ -85,6 +100,7 @@ impl CountDown for Timer { } impl Cancel for Timer { + #[cfg(not(feature = "ehal1"))] type Error = Error; fn cancel(&mut self) -> Result<(), Self::Error> { @@ -171,7 +187,10 @@ macro_rules! hal { clocks, tim, }; + #[cfg(not(feature = "ehal1"))] timer.start(timeout); + #[cfg(feature = "ehal1")] + timer.start(timeout).unwrap(); timer } @@ -221,9 +240,11 @@ macro_rules! hal { } impl CountDown for Timer<$TIM> { + #[cfg(feature = "ehal1")] + type Error = Error; type Time = Hertz; - fn start(&mut self, timeout: T) + fn start(&mut self, timeout: T) -> CDStartResult where T: Into, { @@ -249,9 +270,11 @@ macro_rules! hal { // start counter self.tim.cr1.modify(|_, w| w.cen().set_bit()); + #[cfg(feature = "ehal1")] + Ok(()) } - fn wait(&mut self) -> nb::Result<(), Void> { + fn wait(&mut self) -> CDWaitResult { if self.tim.sr.read().uif().bit_is_clear() { Err(nb::Error::WouldBlock) } else { @@ -263,6 +286,7 @@ macro_rules! hal { impl Cancel for Timer<$TIM> { + #[cfg(not(feature = "ehal1"))] type Error = Error; fn cancel(&mut self) -> Result<(), Self::Error> { diff --git a/src/watchdog.rs b/src/watchdog.rs index 904a8cb4..c11ec8d8 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -1,11 +1,12 @@ //! Watchdog peripherals use crate::{ - hal::watchdog::{Watchdog, WatchdogEnable}, pac::{DBGMCU, IWDG}, time::MilliSeconds, }; +use crate::hal_blocking::watchdog; + /// Wraps the Independent Watchdog (IWDG) peripheral pub struct IndependentWatchdog { iwdg: IWDG, @@ -87,7 +88,8 @@ impl IndependentWatchdog { } } -impl WatchdogEnable for IndependentWatchdog { +#[cfg(not(feature = "ehal1"))] +impl watchdog::WatchdogEnable for IndependentWatchdog { type Time = MilliSeconds; fn start>(&mut self, period: T) { @@ -97,8 +99,31 @@ impl WatchdogEnable for IndependentWatchdog { } } -impl Watchdog for IndependentWatchdog { +#[cfg(feature = "ehal1")] +impl watchdog::Enable for IndependentWatchdog { + type Error = core::convert::Infallible; + type Time = MilliSeconds; + type Target = IndependentWatchdog; + + fn start>(self, period: T) -> Result { + self.setup(period.into().0); + + self.iwdg.kr.write(|w| unsafe { w.key().bits(KR_START) }); + Ok(self) + } +} + +#[cfg(not(feature = "ehal1"))] +impl watchdog::Watchdog for IndependentWatchdog { fn feed(&mut self) { self.iwdg.kr.write(|w| unsafe { w.key().bits(KR_RELOAD) }); } } +#[cfg(feature = "ehal1")] +impl watchdog::Watchdog for IndependentWatchdog { + type Error = core::convert::Infallible; + fn feed(&mut self) -> Result<(), Self::Error> { + self.iwdg.kr.write(|w| unsafe { w.key().bits(KR_RELOAD) }); + Ok(()) + } +}