From d637510b44ec8e58581f3e22f8398b53145503dc Mon Sep 17 00:00:00 2001 From: Henrik Alsér Date: Sat, 9 Jul 2022 00:00:55 +0200 Subject: Associated type --- embassy-embedded-hal/src/lib.rs | 5 +- .../src/shared_bus/blocking/i2c.rs | 101 +++++++++++---------- .../src/shared_bus/blocking/spi.rs | 89 +++++++++--------- embassy-embedded-hal/src/shared_bus/i2c.rs | 16 ++-- embassy-embedded-hal/src/shared_bus/spi.rs | 17 ++-- 5 files changed, 117 insertions(+), 111 deletions(-) (limited to 'embassy-embedded-hal') diff --git a/embassy-embedded-hal/src/lib.rs b/embassy-embedded-hal/src/lib.rs index aae719925..688d0b48d 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 e8dd0f248..0c8338c73 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> { +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) + }) + } +} + +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> 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 2bcf47cff..456da8859 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs @@ -76,66 +76,39 @@ 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> +impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Transfer for SpiBusDevice<'_, M, BUS, CS> where M: RawMutex, - BUS: SpiBusFlush + SetConfig, - CS: OutputPin, + BUS: embedded_hal_02::blocking::spi::Transfer, + CS: OutputPin, { - type Bus = BUS; - - fn transaction(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result) -> Result { + type Error = SpiBusDeviceError; + fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { 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 f_res = bus.transfer(words); 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> +impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Write for SpiBusDevice<'_, M, BUS, CS> where M: RawMutex, - BUS: embedded_hal_02::blocking::spi::Transfer, + BUS: embedded_hal_02::blocking::spi::Write, CS: OutputPin, { type Error = SpiBusDeviceError; - fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { + + fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { self.bus.lock(|bus| { let mut bus = bus.borrow_mut(); self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; - let f_res = bus.transfer(words); + let f_res = bus.write(words); let cs_res = self.cs.set_high(); let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; cs_res.map_err(SpiBusDeviceError::Cs)?; @@ -144,21 +117,49 @@ where } } -impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Write for SpiBusDevice<'_, M, BUS, CS> +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: embedded_hal_02::blocking::spi::Write, - CS: OutputPin, + BUS: spi::ErrorType + SetConfig, + CS: OutputPin, { - type Error = SpiBusDeviceError; + type Error = SpiBusDeviceError; +} - fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { +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 = bus.write(words); + + 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 0e964773c..18f144531 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 04378c330..8e3762e68 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; -- cgit