diff --git a/embassy-embedded-hal/src/lib.rs b/embassy-embedded-hal/src/lib.rs index 3aad838b..8872b3d6 100644 --- a/embassy-embedded-hal/src/lib.rs +++ b/embassy-embedded-hal/src/lib.rs @@ -26,6 +26,18 @@ pub trait SetConfig { /// The configuration type used by this driver. type Config; + /// The error type that can occur if `set_config` fails. + type ConfigError; + /// Set the configuration of the driver. - fn set_config(&mut self, config: &Self::Config); + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError>; +} + +/// Get the configuration of a peripheral driver. +pub trait GetConfig { + /// The configuration type used by this driver. + type Config; + + /// Get the configuration of the driver. + fn get_config(&self) -> Self::Config; } diff --git a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs index 87e8a430..1053d384 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs @@ -125,14 +125,14 @@ where { async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), I2cDeviceError> { let mut bus = self.bus.lock().await; - bus.set_config(&self.config); + bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?; bus.read(address, buffer).await.map_err(I2cDeviceError::I2c)?; Ok(()) } async fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), I2cDeviceError> { let mut bus = self.bus.lock().await; - bus.set_config(&self.config); + bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?; bus.write(address, bytes).await.map_err(I2cDeviceError::I2c)?; Ok(()) } @@ -144,7 +144,7 @@ where rd_buffer: &mut [u8], ) -> Result<(), I2cDeviceError> { let mut bus = self.bus.lock().await; - bus.set_config(&self.config); + bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?; bus.write_read(address, wr_buffer, rd_buffer) .await .map_err(I2cDeviceError::I2c)?; @@ -153,7 +153,7 @@ where async fn transaction(&mut self, address: u8, operations: &mut [i2c::Operation<'_>]) -> Result<(), Self::Error> { let mut bus = self.bus.lock().await; - bus.set_config(&self.config); + bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?; bus.transaction(address, operations) .await .map_err(I2cDeviceError::I2c)?; diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs index 03039218..b2a9f1e3 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs @@ -130,7 +130,7 @@ where { async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> { let mut bus = self.bus.lock().await; - bus.set_config(&self.config); + bus.set_config(&self.config).map_err(|_| SpiDeviceError::Config)?; self.cs.set_low().map_err(SpiDeviceError::Cs)?; let op_res: Result<(), BUS::Error> = try { diff --git a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs index af73df05..233c9e1f 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs @@ -148,7 +148,7 @@ where fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { self.bus.lock(|bus| { let mut bus = bus.borrow_mut(); - bus.set_config(&self.config); + bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?; bus.read(address, buffer).map_err(I2cDeviceError::I2c) }) } @@ -156,7 +156,7 @@ where fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { self.bus.lock(|bus| { let mut bus = bus.borrow_mut(); - bus.set_config(&self.config); + bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?; bus.write(address, bytes).map_err(I2cDeviceError::I2c) }) } @@ -164,7 +164,7 @@ where fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Self::Error> { self.bus.lock(|bus| { let mut bus = bus.borrow_mut(); - bus.set_config(&self.config); + bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?; bus.write_read(address, wr_buffer, rd_buffer) .map_err(I2cDeviceError::I2c) }) diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs index 6d03d626..feb0f5b7 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs @@ -163,7 +163,7 @@ where fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> { self.bus.lock(|bus| { let mut bus = bus.borrow_mut(); - bus.set_config(&self.config); + bus.set_config(&self.config).map_err(|_| SpiDeviceError::Config)?; self.cs.set_low().map_err(SpiDeviceError::Cs)?; let op_res = operations.iter_mut().try_for_each(|op| match op { diff --git a/embassy-embedded-hal/src/shared_bus/mod.rs b/embassy-embedded-hal/src/shared_bus/mod.rs index 79a90bd5..b0159ac0 100644 --- a/embassy-embedded-hal/src/shared_bus/mod.rs +++ b/embassy-embedded-hal/src/shared_bus/mod.rs @@ -14,6 +14,8 @@ pub mod blocking; pub enum I2cDeviceError { /// An operation on the inner I2C bus failed. I2c(BUS), + /// Configuration of the inner I2C bus failed. + Config, } impl i2c::Error for I2cDeviceError @@ -23,6 +25,7 @@ where fn kind(&self) -> i2c::ErrorKind { match self { Self::I2c(e) => e.kind(), + Self::Config => i2c::ErrorKind::Other, } } } @@ -38,6 +41,8 @@ pub enum SpiDeviceError { Cs(CS), /// DelayUs operations are not supported when the `time` Cargo feature is not enabled. DelayUsNotSupported, + /// The SPI bus could not be configured. + Config, } impl spi::Error for SpiDeviceError @@ -50,6 +55,7 @@ where Self::Spi(e) => e.kind(), Self::Cs(_) => spi::ErrorKind::Other, Self::DelayUsNotSupported => spi::ErrorKind::Other, + Self::Config => spi::ErrorKind::Other, } } } diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index 4828af43..caf681d9 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -176,7 +176,7 @@ impl<'d, T: Instance> Spim<'d, T> { let mut spim = Self { _p: spim }; // Apply runtime peripheral configuration - Self::set_config(&mut spim, &config); + Self::set_config(&mut spim, &config).unwrap(); // Disable all events interrupts r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); @@ -566,7 +566,8 @@ mod eha { impl<'d, T: Instance> SetConfig for Spim<'d, T> { type Config = Config; - fn set_config(&mut self, config: &Self::Config) { + type ConfigError = (); + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { let r = T::regs(); // Configure mode. let mode = config.mode; @@ -604,5 +605,7 @@ impl<'d, T: Instance> SetConfig for Spim<'d, T> { // Set over-read character let orc = config.orc; r.orc.write(|w| unsafe { w.orc().bits(orc) }); + + Ok(()) } } diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index e695ba6b..e202c6c2 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs @@ -172,7 +172,7 @@ impl<'d, T: Instance> Spis<'d, T> { let mut spis = Self { _p: spis }; // Apply runtime peripheral configuration - Self::set_config(&mut spis, &config); + Self::set_config(&mut spis, &config).unwrap(); // Disable all events interrupts. r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); @@ -467,7 +467,8 @@ macro_rules! impl_spis { impl<'d, T: Instance> SetConfig for Spis<'d, T> { type Config = Config; - fn set_config(&mut self, config: &Self::Config) { + type ConfigError = (); + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { let r = T::regs(); // Configure mode. let mode = config.mode; @@ -509,5 +510,7 @@ impl<'d, T: Instance> SetConfig for Spis<'d, T> { // Configure auto-acquire on 'transfer end' event. let auto_acquire = config.auto_acquire; r.shorts.write(|w| w.end_acquire().bit(auto_acquire)); + + Ok(()) } } diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index fe38fb10..919bb4ab 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs @@ -170,7 +170,7 @@ impl<'d, T: Instance> Twim<'d, T> { let mut twim = Self { _p: twim }; // Apply runtime peripheral configuration - Self::set_config(&mut twim, &config); + Self::set_config(&mut twim, &config).unwrap(); // Disable all events interrupts r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); @@ -890,9 +890,12 @@ mod eha { impl<'d, T: Instance> SetConfig for Twim<'d, T> { type Config = Config; - fn set_config(&mut self, config: &Self::Config) { + type ConfigError = (); + fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { let r = T::regs(); r.frequency .write(|w| unsafe { w.frequency().bits(config.frequency as u32) }); + + Ok(()) } } diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index 46c440b8..a59ce841 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs @@ -597,7 +597,8 @@ mod eha { impl<'d, T: Instance, M: Mode> SetConfig for Spi<'d, T, M> { type Config = Config; - fn set_config(&mut self, config: &Self::Config) { + type ConfigError = (); + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { let p = self.inner.regs(); let (presc, postdiv) = calc_prescs(config.frequency); p.cpsr().write(|w| w.set_cpsdvsr(presc)); @@ -607,5 +608,7 @@ impl<'d, T: Instance, M: Mode> SetConfig for Spi<'d, T, M> { w.set_sph(config.phase == Phase::CaptureOnSecondTransition); w.set_scr(postdiv); }); + + Ok(()) } } diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 2c349e55..76db0a76 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -91,6 +91,7 @@ fn main() { struct SplitFeature { feature_name: String, pin_name_with_c: String, + #[cfg(feature = "_split-pins-enabled")] pin_name_without_c: String, } diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index f32dd0f0..0d2bfc06 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs @@ -518,7 +518,8 @@ impl Timings { impl<'d, T: Instance> SetConfig for I2c<'d, T> { type Config = Hertz; - fn set_config(&mut self, config: &Self::Config) { + type ConfigError = (); + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { let timings = Timings::new(T::frequency(), *config); T::regs().cr2().modify(|reg| { reg.set_freq(timings.freq); @@ -531,5 +532,7 @@ impl<'d, T: Instance> SetConfig for I2c<'d, T> { T::regs().trise().modify(|reg| { reg.set_trise(timings.trise); }); + + Ok(()) } } diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 36f70e32..543d8f1b 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs @@ -1075,7 +1075,8 @@ mod eha { impl<'d, T: Instance> SetConfig for I2c<'d, T> { type Config = Hertz; - fn set_config(&mut self, config: &Self::Config) { + type ConfigError = (); + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { let timings = Timings::new(T::frequency(), *config); T::regs().timingr().write(|reg| { reg.set_presc(timings.prescale); @@ -1084,5 +1085,7 @@ impl<'d, T: Instance> SetConfig for I2c<'d, T> { reg.set_sdadel(timings.sdadel); reg.set_scldel(timings.scldel); }); + + Ok(()) } } diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 2741b790..5eecb637 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs @@ -982,8 +982,9 @@ impl<'d, T: Instance, C: Channel, W: word::Word> SubBlock<'d, T, C, W> { ch.cr2().modify(|w| w.set_mute(value)); } + #[allow(dead_code)] /// Reconfigures it with the supplied config. - pub fn reconfigure(&mut self, _config: Config) {} + fn reconfigure(&mut self, _config: Config) {} pub fn get_current_config(&self) -> Config { Config::default() @@ -1056,7 +1057,10 @@ foreach_peripheral!( impl<'d, T: Instance> SetConfig for Sai<'d, T> { type Config = Config; - fn set_config(&mut self, _config: &Self::Config) { + type ConfigError = (); + fn set_config(&mut self, _config: &Self::Config) -> Result<(), ()> { // self.reconfigure(*config); + + Ok(()) } } diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index f40bce78..14333ba2 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs @@ -323,7 +323,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { } /// Reconfigures it with the supplied config. - pub fn set_config(&mut self, config: Config) { + fn set_config(&mut self, config: Config) { let cpha = config.raw_phase(); let cpol = config.raw_polarity(); @@ -1061,7 +1061,10 @@ foreach_peripheral!( impl<'d, T: Instance, Tx, Rx> SetConfig for Spi<'d, T, Tx, Rx> { type Config = Config; - fn set_config(&mut self, config: &Self::Config) { + type ConfigError = (); + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { self.set_config(*config); + + Ok(()) } } diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index e2d6e42a..445ca0ed 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -116,25 +116,28 @@ pub struct BufferedUartRx<'d, T: BasicInstance> { impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> { type Config = Config; + type ConfigError = (); - fn set_config(&mut self, config: &Self::Config) { - unwrap!(self.set_config(config)) + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { + self.set_config(config).map_err(|_| ()) } } impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> { type Config = Config; + type ConfigError = (); - fn set_config(&mut self, config: &Self::Config) { - unwrap!(self.set_config(config)) + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { + self.set_config(config).map_err(|_| ()) } } impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> { type Config = Config; + type ConfigError = (); - fn set_config(&mut self, config: &Self::Config) { - unwrap!(self.set_config(config)) + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { + self.set_config(config).map_err(|_| ()) } } @@ -253,7 +256,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { (self.tx, self.rx) } - pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } } @@ -333,7 +336,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { } } - pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } } @@ -407,7 +410,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { } } - pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } } diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 9835f1ac..2eb2e4e8 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -181,10 +181,11 @@ pub struct Uart<'d, T: BasicInstance, TxDma = NoDma, RxDma = NoDma> { impl<'d, T: BasicInstance, TxDma, RxDma> SetConfig for Uart<'d, T, TxDma, RxDma> { type Config = Config; + type ConfigError = (); - fn set_config(&mut self, config: &Self::Config) { - unwrap!(self.tx.set_config(config)); - unwrap!(self.rx.set_config(config)); + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { + self.tx.set_config(config).map_err(|_| ())?; + self.rx.set_config(config).map_err(|_| ()) } } @@ -195,9 +196,10 @@ pub struct UartTx<'d, T: BasicInstance, TxDma = NoDma> { impl<'d, T: BasicInstance, TxDma> SetConfig for UartTx<'d, T, TxDma> { type Config = Config; + type ConfigError = (); - fn set_config(&mut self, config: &Self::Config) { - unwrap!(self.set_config(config)); + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { + self.set_config(config).map_err(|_| ()) } } @@ -211,9 +213,10 @@ pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { impl<'d, T: BasicInstance, RxDma> SetConfig for UartRx<'d, T, RxDma> { type Config = Config; + type ConfigError = (); - fn set_config(&mut self, config: &Self::Config) { - unwrap!(self.set_config(config)); + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { + self.set_config(config).map_err(|_| ()) } } @@ -273,7 +276,7 @@ impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { }) } - pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } @@ -374,7 +377,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { }) } - pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { reconfigure::(config) } @@ -803,10 +806,6 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { }) } - pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { - reconfigure::(config) - } - pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> where TxDma: crate::usart::TxDma, diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index 347aae7c..535d1b1f 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs @@ -18,9 +18,10 @@ pub struct RingBufferedUartRx<'d, T: BasicInstance, RxDma: super::RxDma> { impl<'d, T: BasicInstance, RxDma: super::RxDma> SetConfig for RingBufferedUartRx<'d, T, RxDma> { type Config = Config; + type ConfigError = (); - fn set_config(&mut self, config: &Self::Config) { - unwrap!(self.set_config(config)); + fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { + self.set_config(config).map_err(|_| ()) } } @@ -63,7 +64,7 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma> RingBufferedUartRx<'d, T, RxD Err(err) } - pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { + fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { self.teardown_uart(); reconfigure::(config) }