diff --git a/embassy-embedded-hal/src/lib.rs b/embassy-embedded-hal/src/lib.rs index aae71992..688d0b48 100644 --- a/embassy-embedded-hal/src/lib.rs +++ b/embassy-embedded-hal/src/lib.rs @@ -5,6 +5,7 @@ pub mod adapter; pub mod shared_bus; -pub trait SetConfig { - fn set_config(&mut self, config: &C); +pub trait SetConfig { + type Config; + fn set_config(&mut self, config: &Self::Config); } diff --git a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs index e8dd0f24..0c8338c7 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs @@ -101,28 +101,71 @@ where } } -pub struct I2cBusDeviceWithConfig<'a, M: RawMutex, BUS, C> { - bus: &'a Mutex>, - config: C, +impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::Write for I2cBusDevice<'_, M, BUS> +where + M: RawMutex, + BUS: embedded_hal_02::blocking::i2c::Write, +{ + type Error = I2cBusDeviceError; + + fn write<'w>(&mut self, addr: u8, bytes: &'w [u8]) -> Result<(), Self::Error> { + self.bus + .lock(|bus| bus.borrow_mut().write(addr, bytes).map_err(I2cBusDeviceError::I2c)) + } } -impl<'a, M: RawMutex, BUS, C> I2cBusDeviceWithConfig<'a, M, BUS, C> { - pub fn new(bus: &'a Mutex>, config: C) -> Self { +impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::Read for I2cBusDevice<'_, M, BUS> +where + M: RawMutex, + BUS: embedded_hal_02::blocking::i2c::Read, +{ + type Error = I2cBusDeviceError; + + fn read<'w>(&mut self, addr: u8, bytes: &'w mut [u8]) -> Result<(), Self::Error> { + self.bus + .lock(|bus| bus.borrow_mut().read(addr, bytes).map_err(I2cBusDeviceError::I2c)) + } +} + +impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::WriteRead for I2cBusDevice<'_, M, BUS> +where + M: RawMutex, + BUS: embedded_hal_02::blocking::i2c::WriteRead, +{ + type Error = I2cBusDeviceError; + + fn write_read<'w>(&mut self, addr: u8, bytes: &'w [u8], buffer: &'w mut [u8]) -> Result<(), Self::Error> { + self.bus.lock(|bus| { + bus.borrow_mut() + .write_read(addr, bytes, buffer) + .map_err(I2cBusDeviceError::I2c) + }) + } +} + +pub struct I2cBusDeviceWithConfig<'a, M: RawMutex, BUS: SetConfig> { + bus: &'a Mutex>, + config: BUS::Config, +} + +impl<'a, M: RawMutex, BUS: SetConfig> I2cBusDeviceWithConfig<'a, M, BUS> { + pub fn new(bus: &'a Mutex>, config: BUS::Config) -> Self { Self { bus, config } } } -impl<'a, M: RawMutex, BUS, C> ErrorType for I2cBusDeviceWithConfig<'a, M, BUS, C> +impl<'a, M, BUS> ErrorType for I2cBusDeviceWithConfig<'a, M, BUS> where - BUS: ErrorType, + M: RawMutex, + BUS: ErrorType + SetConfig, { type Error = I2cBusDeviceError; } -impl I2c for I2cBusDeviceWithConfig<'_, M, BUS, C> +impl I2c for I2cBusDeviceWithConfig<'_, M, BUS> where M: RawMutex, - BUS: I2c + SetConfig, + BUS: I2c + SetConfig, { fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { self.bus.lock(|bus| { @@ -183,45 +226,3 @@ where todo!() } } - -impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::Write for I2cBusDevice<'_, M, BUS> -where - M: RawMutex, - BUS: embedded_hal_02::blocking::i2c::Write, -{ - type Error = I2cBusDeviceError; - - fn write<'w>(&mut self, addr: u8, bytes: &'w [u8]) -> Result<(), Self::Error> { - self.bus - .lock(|bus| bus.borrow_mut().write(addr, bytes).map_err(I2cBusDeviceError::I2c)) - } -} - -impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::Read for I2cBusDevice<'_, M, BUS> -where - M: RawMutex, - BUS: embedded_hal_02::blocking::i2c::Read, -{ - type Error = I2cBusDeviceError; - - fn read<'w>(&mut self, addr: u8, bytes: &'w mut [u8]) -> Result<(), Self::Error> { - self.bus - .lock(|bus| bus.borrow_mut().read(addr, bytes).map_err(I2cBusDeviceError::I2c)) - } -} - -impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::WriteRead for I2cBusDevice<'_, M, BUS> -where - M: RawMutex, - BUS: embedded_hal_02::blocking::i2c::WriteRead, -{ - type Error = I2cBusDeviceError; - - fn write_read<'w>(&mut self, addr: u8, bytes: &'w [u8], buffer: &'w mut [u8]) -> Result<(), Self::Error> { - self.bus.lock(|bus| { - bus.borrow_mut() - .write_read(addr, bytes, buffer) - .map_err(I2cBusDeviceError::I2c) - }) - } -} diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs index 2bcf47cf..456da885 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs @@ -76,54 +76,6 @@ where } } -pub struct SpiBusDeviceWithConfig<'a, M: RawMutex, BUS, CS, C> { - bus: &'a Mutex>, - cs: CS, - config: C, -} - -impl<'a, M: RawMutex, BUS, CS, C> SpiBusDeviceWithConfig<'a, M, BUS, CS, C> { - pub fn new(bus: &'a Mutex>, cs: CS, config: C) -> Self { - Self { bus, cs, config } - } -} - -impl<'a, M: RawMutex, BUS, CS, C> spi::ErrorType for SpiBusDeviceWithConfig<'a, M, BUS, CS, C> -where - BUS: spi::ErrorType, - CS: OutputPin, -{ - type Error = SpiBusDeviceError; -} - -impl SpiDevice for SpiBusDeviceWithConfig<'_, M, BUS, CS, C> -where - M: RawMutex, - BUS: SpiBusFlush + SetConfig, - CS: OutputPin, -{ - type Bus = BUS; - - fn transaction(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result) -> Result { - self.bus.lock(|bus| { - let mut bus = bus.borrow_mut(); - bus.set_config(&self.config); - self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; - - let f_res = f(&mut bus); - - // On failure, it's important to still flush and deassert CS. - let flush_res = bus.flush(); - let cs_res = self.cs.set_high(); - - let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; - flush_res.map_err(SpiBusDeviceError::Spi)?; - cs_res.map_err(SpiBusDeviceError::Cs)?; - Ok(f_res) - }) - } -} - impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Transfer for SpiBusDevice<'_, M, BUS, CS> where M: RawMutex, @@ -164,3 +116,52 @@ where }) } } + +pub struct SpiBusDeviceWithConfig<'a, M: RawMutex, BUS: SetConfig, CS> { + bus: &'a Mutex>, + cs: CS, + config: BUS::Config, +} + +impl<'a, M: RawMutex, BUS: SetConfig, CS> SpiBusDeviceWithConfig<'a, M, BUS, CS> { + pub fn new(bus: &'a Mutex>, cs: CS, config: BUS::Config) -> Self { + Self { bus, cs, config } + } +} + +impl<'a, M, BUS, CS> spi::ErrorType for SpiBusDeviceWithConfig<'a, M, BUS, CS> +where + M: RawMutex, + BUS: spi::ErrorType + SetConfig, + CS: OutputPin, +{ + type Error = SpiBusDeviceError; +} + +impl SpiDevice for SpiBusDeviceWithConfig<'_, M, BUS, CS> +where + M: RawMutex, + BUS: SpiBusFlush + SetConfig, + CS: OutputPin, +{ + type Bus = BUS; + + fn transaction(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result) -> Result { + self.bus.lock(|bus| { + let mut bus = bus.borrow_mut(); + bus.set_config(&self.config); + self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; + + let f_res = f(&mut bus); + + // On failure, it's important to still flush and deassert CS. + let flush_res = bus.flush(); + let cs_res = self.cs.set_high(); + + let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; + flush_res.map_err(SpiBusDeviceError::Spi)?; + cs_res.map_err(SpiBusDeviceError::Cs)?; + Ok(f_res) + }) + } +} diff --git a/embassy-embedded-hal/src/shared_bus/i2c.rs b/embassy-embedded-hal/src/shared_bus/i2c.rs index 0e964773..18f14453 100644 --- a/embassy-embedded-hal/src/shared_bus/i2c.rs +++ b/embassy-embedded-hal/src/shared_bus/i2c.rs @@ -119,28 +119,30 @@ where } } -pub struct I2cBusDeviceWithConfig<'a, M: RawMutex, BUS, C> { +pub struct I2cBusDeviceWithConfig<'a, M: RawMutex, BUS: SetConfig> { bus: &'a Mutex, - config: C, + config: BUS::Config, } -impl<'a, M: RawMutex, BUS, C> I2cBusDeviceWithConfig<'a, M, BUS, C> { - pub fn new(bus: &'a Mutex, config: C) -> Self { +impl<'a, M: RawMutex, BUS: SetConfig> I2cBusDeviceWithConfig<'a, M, BUS> { + pub fn new(bus: &'a Mutex, config: BUS::Config) -> Self { Self { bus, config } } } -impl<'a, M: RawMutex, BUS, C> i2c::ErrorType for I2cBusDeviceWithConfig<'a, M, BUS, C> +impl<'a, M, BUS> i2c::ErrorType for I2cBusDeviceWithConfig<'a, M, BUS> where BUS: i2c::ErrorType, + M: RawMutex, + BUS: SetConfig, { type Error = I2cBusDeviceError; } -impl i2c::I2c for I2cBusDeviceWithConfig<'_, M, BUS, C> +impl i2c::I2c for I2cBusDeviceWithConfig<'_, M, BUS> where M: RawMutex + 'static, - BUS: i2c::I2c + SetConfig + 'static, + BUS: i2c::I2c + SetConfig + 'static, { type ReadFuture<'a> = impl Future> + 'a where Self: 'a; diff --git a/embassy-embedded-hal/src/shared_bus/spi.rs b/embassy-embedded-hal/src/shared_bus/spi.rs index 04378c33..8e3762e6 100644 --- a/embassy-embedded-hal/src/shared_bus/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/spi.rs @@ -112,30 +112,31 @@ where } } -pub struct SpiBusDeviceWithConfig<'a, M: RawMutex, BUS, CS, C> { +pub struct SpiBusDeviceWithConfig<'a, M: RawMutex, BUS: SetConfig, CS> { bus: &'a Mutex, cs: CS, - config: C, + config: BUS::Config, } -impl<'a, M: RawMutex, BUS, CS, C> SpiBusDeviceWithConfig<'a, M, BUS, CS, C> { - pub fn new(bus: &'a Mutex, cs: CS, config: C) -> Self { +impl<'a, M: RawMutex, BUS: SetConfig, CS> SpiBusDeviceWithConfig<'a, M, BUS, CS> { + pub fn new(bus: &'a Mutex, cs: CS, config: BUS::Config) -> Self { Self { bus, cs, config } } } -impl<'a, M: RawMutex, BUS, CS, C> spi::ErrorType for SpiBusDeviceWithConfig<'a, M, BUS, CS, C> +impl<'a, M, BUS, CS> spi::ErrorType for SpiBusDeviceWithConfig<'a, M, BUS, CS> where - BUS: spi::ErrorType, + BUS: spi::ErrorType + SetConfig, CS: OutputPin, + M: RawMutex, { type Error = SpiBusDeviceError; } -impl spi::SpiDevice for SpiBusDeviceWithConfig<'_, M, BUS, CS, C> +impl spi::SpiDevice for SpiBusDeviceWithConfig<'_, M, BUS, CS> where M: RawMutex + 'static, - BUS: spi::SpiBusFlush + SetConfig + 'static, + BUS: spi::SpiBusFlush + SetConfig + 'static, CS: OutputPin, { type Bus = BUS; diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index 882bf4b4..d34d9a0c 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -523,8 +523,9 @@ cfg_if::cfg_if! { } } -impl<'d, T: Instance> SetConfig for Spim<'d, T> { - fn set_config(&mut self, config: &Config) { +impl<'d, T: Instance> SetConfig for Spim<'d, T> { + type Config = Config; + fn set_config(&mut self, config: &Self::Config) { let r = T::regs(); // Configure mode. let mode = config.mode; diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 8189d3e7..2088691b 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -880,8 +880,9 @@ cfg_if::cfg_if! { } } -impl<'d, T: Instance> SetConfig for Twim<'d, T> { - fn set_config(&mut self, config: &Config) { +impl<'d, T: Instance> SetConfig for Twim<'d, T> { + type Config = Config; + fn set_config(&mut self, config: &Self::Config) { let r = T::regs(); r.frequency .write(|w| unsafe { w.frequency().bits(config.frequency as u32) }); diff --git a/examples/nrf/src/bin/shared_bus.rs b/examples/nrf/src/bin/shared_bus.rs deleted file mode 100644 index 23d16f79..00000000 --- a/examples/nrf/src/bin/shared_bus.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![no_std] -#![no_main] -#![feature(type_alias_impl_trait)] - -use embassy::executor::Spawner; -use embassy::time::{Duration, Timer}; -use embassy_nrf::gpio::{Level, Output, OutputDrive}; -use embassy_nrf::Peripherals; -use {defmt_rtt as _, panic_probe as _}; - -#[embassy::main] -async fn main(_spawner: Spawner, p: Peripherals) { - let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); - - loop { - led.set_high(); - Timer::after(Duration::from_millis(300)).await; - led.set_low(); - Timer::after(Duration::from_millis(300)).await; - } -}