### AtomicDevice Example Usage Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/i2c/struct.AtomicDevice_search= Demonstrates how to use AtomicDevice to share a single I2C bus instance between multiple sensor devices. It utilizes AtomicCell to wrap the I2C bus and then creates AtomicDevice instances for each sensor. ```rust use embedded_hal_bus::i2c; use embedded_hal_bus::util::AtomicCell; let i2c = hal.i2c(); let i2c_cell = AtomicCell::new(i2c); let mut temperature_sensor = TemperatureSensor::new( i2c::AtomicDevice::new(&i2c_cell), 0x20, ); let mut pressure_sensor = PressureSensor::new( i2c::AtomicDevice::new(&i2c_cell), 0x42, ); ``` -------------------------------- ### RefCellDevice Struct Definition and Usage Example (Rust) Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/i2c/struct.RefCellDevice_search=std%3A%3Avec Defines the RefCellDevice struct for single-thread I2C bus sharing using RefCell. Includes an example demonstrating how to instantiate and use RefCellDevice for multiple sensors on the same bus. ```rust pub struct RefCellDevice<'a, T> { /* private fields */ } use embedded_hal_bus::i2c; use core::cell::RefCell; let i2c = hal.i2c(); let i2c_ref_cell = RefCell::new(i2c); let mut temperature_sensor = TemperatureSensor::new( i2c::RefCellDevice::new(&i2c_ref_cell), 0x20, ); let mut pressure_sensor = PressureSensor::new( i2c::RefCellDevice::new(&i2c_ref_cell), 0x42, ); ``` -------------------------------- ### TryFrom and TryInto Trait Implementations Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.ExclusiveDevice Documentation for the blanket implementations of `TryFrom` for `T` and `TryInto` for `T`, including error types. ```APIDOC ## impl TryFrom for T ### Description This block describes the blanket implementation of the `TryFrom` trait. It allows a type `T` to be attempted to be converted from type `U`, provided that `U` implements `Into`. The conversion might fail. ### Method Blanket Implementation ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) - **Result>::Error>** (Result) - A `Result` containing either the successfully converted value of type `T` or an error. ### Response Example N/A ## impl TryInto for T ### Description This block details the blanket implementation of the `TryInto` trait. It allows a type `T` to be attempted to be converted into type `U`, provided that `U` implements `TryFrom`. The conversion might fail. ### Method Blanket Implementation ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) - **Result>::Error>** (Result) - A `Result` containing either the successfully converted value of type `U` or an error. ### Response Example N/A ``` -------------------------------- ### Auto Trait Implementations Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.AtomicDevice_search=std%3A%3Avec Information on auto trait implementations for AtomicDevice, including Send and Sync. ```APIDOC ## Auto Trait Implementations ### `impl<'a, BUS, CS, D> Freeze for AtomicDevice<'a, BUS, CS, D>` ### `impl<'a, BUS, CS, D> !RefUnwindSafe for AtomicDevice<'a, BUS, CS, D>` ### `impl<'a, BUS, CS, D> Send for AtomicDevice<'a, BUS, CS, D>` ### `impl<'a, BUS, CS, D> Sync for AtomicDevice<'a, BUS, CS, D>` ### `impl<'a, BUS, CS, D> Unpin for AtomicDevice<'a, BUS, CS, D>` ``` -------------------------------- ### AtomicDevice Struct Definition and Usage Example (Rust) Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/i2c/struct.AtomicDevice Defines the AtomicDevice struct for atomic-based shared I2C bus access and provides an example of its usage with multiple sensors on the same bus. This requires the 'portable-atomic' feature or 'target_has_atomic=8'. ```rust pub struct AtomicDevice<'a, T> { /* private fields */ } use embedded_hal_bus::i2c; use embedded_hal_bus::util::AtomicCell; // Assuming hal and TemperatureSensor/PressureSensor are defined elsewhere // let i2c = hal.i2c(); // let i2c_cell = AtomicCell::new(i2c); // let mut temperature_sensor = TemperatureSensor::new( // i2c::AtomicDevice::new(&i2c_cell), // 0x20, // ); // let mut pressure_sensor = PressureSensor::new( // i2c::AtomicDevice::new(&i2c_cell), // 0x42, // ); ``` -------------------------------- ### From and Into Trait Implementations Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.ExclusiveDevice Documentation for the blanket implementations of `From` for `T` and `Into` for `T` where `U` implements `From`. ```APIDOC ## impl From for T ### Description This block describes the blanket implementation of the `From` trait. It allows a type `T` to be converted from itself, returning the argument unchanged. ### Method Blanket Implementation ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) - **T** (T) - The original value is returned unchanged. ### Response Example N/A ## impl Into for T ### Description This block details the blanket implementation of the `Into` trait. It allows a type `T` to be converted into type `U`, provided that `U` implements `From`. The conversion is performed by calling `U::from(self)`. ### Method Blanket Implementation ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) - **U** (U) - The converted value of type `U`. ### Response Example N/A ``` -------------------------------- ### RefCellDevice Struct Definition and Usage Example (Rust) Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/i2c/struct.RefCellDevice_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Defines the RefCellDevice struct and provides an example of its usage for sharing an I2C bus among multiple devices like temperature and pressure sensors. This implementation is suitable for single-threaded environments due to its reliance on RefCell. ```rust pub struct RefCellDevice<'a, T> { /* private fields */ } ``` ```rust use embedded_hal_bus::i2c; use core::cell::RefCell; let i2c = hal.i2c(); let i2c_ref_cell = RefCell::new(i2c); let mut temperature_sensor = TemperatureSensor::new( i2c::RefCellDevice::new(&i2c_ref_cell), 0x20, ); let mut pressure_sensor = PressureSensor::new( i2c::RefCellDevice::new(&i2c_ref_cell), 0x42, ); ``` -------------------------------- ### RefCellDevice Struct Definition and Usage Example (Rust) Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/i2c/struct.RefCellDevice Defines the RefCellDevice struct and demonstrates its usage for sharing an I2C bus among multiple devices within a single thread. It highlights the use of RefCell for shared mutable access and provides an example of initializing multiple sensor instances. ```rust pub struct RefCellDevice<'a, T> { /* private fields */ } // Example Usage: use embedded_hal_bus::i2c; use core::cell::RefCell; // Assuming 'hal' is an existing I2c peripheral and TemperatureSensor/PressureSensor are defined elsewhere // let i2c = hal.i2c(); // let i2c_ref_cell = RefCell::new(i2c); // let mut temperature_sensor = TemperatureSensor::new( // i2c::RefCellDevice::new(&i2c_ref_cell), // 0x20, // ); // let mut pressure_sensor = PressureSensor::new( // i2c::RefCellDevice::new(&i2c_ref_cell), // 0x42, // ); ``` -------------------------------- ### AtomicDevice Blanket Implementations Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.AtomicDevice_search=u32+-%3E+bool Details the blanket implementations for AtomicDevice<'a, BUS, CS, D>. ```APIDOC ## Blanket Implementations for AtomicDevice<'a, BUS, CS, D> This section details the blanket implementations available for the `AtomicDevice` struct. ### `impl<'a, BUS, CS, D> !UnwindSafe for AtomicDevice<'a, BUS, CS, D>` This indicates that `AtomicDevice` does not implement the `UnwindSafe` trait. ### `impl Any for T where T: 'static + ?Sized` This is a blanket implementation of the `Any` trait for any type `T` that is `'static` and not dynamically sized. #### `fn type_id(&self) -> TypeId` Gets the `TypeId` of `self`. ### `impl Borrow for T where T: ?Sized` This is a blanket implementation of the `Borrow` trait for any type `T`. #### `fn borrow(&self) -> &T` Immutably borrows from an owned value. ### `impl BorrowMut for T where T: ?Sized` This is a blanket implementation of the `BorrowMut` trait for any type `T`. #### `fn borrow_mut(&mut self) -> &mut T` Mutably borrows from an owned value. ### `impl From for T` This is a blanket implementation of the `From` trait for any type `T`. #### `fn from(t: T) -> T` Returns the argument unchanged. ### `impl Into for T where U: From` This is a blanket implementation of the `Into` trait for any type `T` where `U` implements `From`. #### `fn into(self) -> U` Calls `U::from(self)`. That is, this conversion is whatever the implementation of `From for U` chooses to do. ### `impl TryFrom for T where U: Into` This is a blanket implementation of the `TryFrom` trait for any type `T` where `U` implements `Into`. #### `type Error = Infallible` The type returned in the event of a conversion error. #### `fn try_from(value: U) -> Result>::Error>` Performs the conversion. ### `impl TryInto for T where U: TryFrom` This is a blanket implementation of the `TryInto` trait for any type `T` where `U` implements `TryFrom`. #### `type Error = >::Error` The type returned in the event of a conversion error. #### `fn try_into(self) -> Result>::Error>` Performs the conversion. ``` -------------------------------- ### SPI RefCellDevice Creation and Usage (Rust) Source: https://docs.rs/embedded-hal-bus/latest/src/embedded_hal_bus/spi/refcell.rs_search= Demonstrates the creation and usage of RefCellDevice for shared SPI bus access within a single thread. It includes methods for creating a device with delay support and a variant without delay support, highlighting the implications of omitting delays. ```rust use core::cell::RefCell; use embedded_hal::delay::DelayNs; use embedded_hal::digital::OutputPin; use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice}; use super::DeviceError; use crate::spi::shared::transaction; /// `RefCell`-based shared bus [`SpiDevice`] implementation. /// /// This allows for sharing an [`SpiBus`], obtaining multiple [`SpiDevice`] instances, /// each with its own `CS` pin. /// /// Sharing is implemented with a `RefCell`. This means it has low overhead, but `RefCellDevice` instances are not `Send`, /// so it only allows sharing within a single thread (interrupt priority level). If you need to share a bus across several /// threads, use [`CriticalSectionDevice`](super::CriticalSectionDevice) instead. pub struct RefCellDevice<'a, BUS, CS, D> { bus: &'a RefCell, cs: CS, delay: D, } impl<'a, BUS, CS, D> RefCellDevice<'a, BUS, CS, D> { /// Create a new [`RefCellDevice`]. /// /// This sets the `cs` pin high, and returns an error if that fails. It is recommended /// to set the pin high the moment it's configured as an output, to avoid glitches. #[inline] pub fn new(bus: &'a RefCell, mut cs: CS, delay: D) -> Result where CS: OutputPin, { cs.set_high()?; Ok(Self { bus, cs, delay }) } } impl<'a, BUS, CS> RefCellDevice<'a, BUS, CS, super::NoDelay> { /// Create a new [`RefCellDevice`] without support for in-transaction delays. /// /// This sets the `cs` pin high, and returns an error if that fails. It is recommended /// to set the pin high the moment it's configured as an output, to avoid glitches. /// /// **Warning**: The returned instance *technically* doesn't comply with the `SpiDevice` /// contract, which mandates delay support. It is relatively rare for drivers to use /// in-transaction delays, so you might still want to use this method because it's more practical. /// /// Note that a future version of the driver might start using delays, causing your /// code to panic. This wouldn't be considered a breaking change from the driver side, because /// drivers are allowed to assume `SpiDevice` implementations comply with the contract. /// If you feel this risk outweighs the convenience of having `cargo` automatically upgrade /// the driver crate, you might want to pin the driver's version. /// /// # Panics /// /// The returned device will panic if you try to execute a transaction /// that contains any operations of type [`Operation::DelayNs`]. #[inline] pub fn new_no_delay(bus: &'a RefCell, mut cs: CS) -> Result where CS: OutputPin, { cs.set_high()?; Ok(Self { bus, cs, delay: super::NoDelay, }) } } impl ErrorType for RefCellDevice<'_, BUS, CS, D> where BUS: ErrorType, CS: OutputPin, { type Error = DeviceError; } impl SpiDevice for RefCellDevice<'_, BUS, CS, D> where BUS: SpiBus, CS: OutputPin, D: DelayNs, { #[inline] fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error> { let bus = &mut *self.bus.borrow_mut(); transaction(operations, bus, &mut self.delay, &mut self.cs) } } ``` -------------------------------- ### Implement Clone for DeviceError Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/enum.DeviceError_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E This implementation allows DeviceError instances to be cloned. This is useful when error information needs to be duplicated, for example, when propagating errors across different parts of an application. It requires the underlying BUS and CS types to also implement the Clone trait. ```rust impl Clone for DeviceError fn clone(&self) -> DeviceError ``` -------------------------------- ### Example Usage of RefCellDevice for Multiple Sensors Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/i2c/struct.RefCellDevice_search=u32+-%3E+bool Illustrates how to use RefCellDevice to provide access to multiple I2C devices (temperature and pressure sensors) from a single I2C bus instance. This is achieved by wrapping the I2C bus in a RefCell and creating separate RefCellDevice instances for each sensor. ```rust use embedded_hal_bus::i2c; use core::cell::RefCell; let i2c = hal.i2c(); let i2c_ref_cell = RefCell::new(i2c); let mut temperature_sensor = TemperatureSensor::new( i2c::RefCellDevice::new(&i2c_ref_cell), 0x20, ); let mut pressure_sensor = PressureSensor::new( i2c::RefCellDevice::new(&i2c_ref_cell), 0x42, ); ``` -------------------------------- ### RcDevice::new Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/i2c/struct.RcDevice Constructor for RcDevice. Creates a new RcDevice instance. ```APIDOC ## `RcDevice::new` ### Description Creates a new `RcDevice`. This function does not increment the reference count for the bus: you will need to call `Rc::clone(&bus)` if you only have a `&Rc>`. ### Method `pub fn new(bus: Rc>) -> Self` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) `RcDevice`: A new instance of RcDevice. #### Response Example None ``` -------------------------------- ### Any Trait Implementation Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.ExclusiveDevice Documentation for the blanket implementation of the `Any` trait for any type `T` that is `'static + ?Sized`. ```APIDOC ## impl Any for T ### Description This block describes the blanket implementation of the `Any` trait. This trait is implemented for any type `T` that satisfies the `'static + ?Sized` bounds, allowing for runtime type identification. ### Method Blanket Implementation ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) - **TypeId** (TypeId) - The unique identifier for the type of `self`. ### Response Example ```json { "type_id": "example_type_id" } ``` ``` -------------------------------- ### MutexDevice Constructor without Delay Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.MutexDevice_search= Creates a new MutexDevice instance without support for in-transaction delays. This is useful when delays are not needed, but be aware that it technically doesn't fully comply with the SpiDevice contract. Using this might lead to panics if the driver later starts using delays. ```rust pub fn new_no_delay(bus: &'a Mutex, cs: CS) -> Result where CS: OutputPin ``` -------------------------------- ### Blanket Implementations Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.ExclusiveDevice_search= This section details the blanket implementations available within the rs_embedded-hal-bus project, including implementations for Any, Borrow, BorrowMut, From, Into, TryFrom, and TryInto. ```APIDOC ## Blanket Implementations This section details the blanket implementations available within the rs_embedded-hal-bus project. ### `impl Any for T` #### `fn type_id(&self) -> TypeId` Gets the `TypeId` of `self`. ### `impl Borrow for T` #### `fn borrow(&self) -> &T` Immutably borrows from an owned value. ### `impl BorrowMut for T` #### `fn borrow_mut(&mut self) -> &mut T` Mutably borrows from an owned value. ### `impl From for T` #### `fn from(t: T) -> T` Returns the argument unchanged. ### `impl Into for T` #### `fn into(self) -> U` Calls `U::from(self)`. That is, this conversion is whatever the implementation of `From for U` chooses to do. ### `impl TryFrom for T` #### `type Error = Infallible` The type returned in the event of a conversion error. #### `fn try_from(value: U) -> Result>::Error>` Performs the conversion. ### `impl TryInto for T` #### `type Error = >::Error` The type returned in the event of a conversion error. #### `fn try_into(self) -> Result>::Error>` Performs the conversion. ``` -------------------------------- ### Create CriticalSectionDevice without Delay Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.CriticalSectionDevice_search=std%3A%3Avec Creates a new `CriticalSectionDevice` instance without support for in-transaction delays. This is useful when delays are not required, but note that the returned instance technically doesn't fully comply with the `SpiDevice` contract. Using this might lead to panics if drivers later start using delays. ```rust pub fn new_no_delay( bus: &'a Mutex>, cs: CS, ) -> Result where CS: OutputPin ``` -------------------------------- ### Implement SpiDevice Transaction for AtomicDevice (Rust) Source: https://docs.rs/embedded-hal-bus/latest/src/embedded_hal_bus/spi/atomic.rs Implements the SpiDevice trait's transaction method for AtomicDevice. This method handles SPI bus operations, including atomic locking of the bus, executing the transaction, and managing delays. It ensures that the bus is not busy before starting and releases it afterward. Dependencies include SpiBus, OutputPin, and DelayNs traits. ```rust impl SpiDevice for AtomicDevice<'_, BUS, CS, D> where BUS: SpiBus, CS: OutputPin, D: DelayNs, { #[inline] fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error> { self.bus .busy .compare_exchange( false, true, core::sync::atomic::Ordering::SeqCst, core::sync::atomic::Ordering::SeqCst, ) .map_err(|_| AtomicError::Busy)?; let bus = unsafe { &mut *self.bus.bus.get() }; let result = transaction(operations, bus, &mut self.delay, &mut self.cs); self.bus .busy .store(false, core::sync::atomic::Ordering::SeqCst); result.map_err(AtomicError::Other) } } ``` -------------------------------- ### Create ExclusiveDevice with Delay Support (Rust) Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.ExclusiveDevice_search=std%3A%3Avec Constructs a new ExclusiveDevice instance, requiring a bus, a chip select (CS) pin, and a delay provider. It initializes the CS pin to high and returns an error if this operation fails. ```rust pub fn new(bus: BUS, cs: CS, delay: D) -> Result where CS: OutputPin, ``` -------------------------------- ### NoDelay Struct Documentation Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.NoDelay Documentation for the NoDelay struct, which provides a dummy DelayNs implementation that panics on use. ```APIDOC ## Struct NoDelay ### Summary ```rust pub struct NoDelay; ``` ### Description Dummy `DelayNs` implementation that panics on use. ### Trait Implementations #### `impl Clone for NoDelay` - `fn clone(&self) -> NoDelay`: Returns a duplicate of the value. - `fn clone_from(&mut self, source: &Self)`: Performs copy-assignment from `source`. #### `impl Debug for NoDelay` - `fn fmt(&self, f: &mut Formatter<'_>) -> Result`: Formats the value using the given formatter. #### `impl DelayNs for NoDelay` (Synchronous) - `fn delay_ns(&mut self, _ns: u32)`: Pauses execution for at minimum `ns` nanoseconds. - `fn delay_us(&mut self, us: u32)`: Pauses execution for at minimum `us` microseconds. - `fn delay_ms(&mut self, ms: u32)`: Pauses execution for at minimum `ms` milliseconds. #### `impl DelayNs for NoDelay` (Asynchronous - requires `async` feature) - `async fn delay_ns(&mut self, _ns: u32)`: Pauses execution for at minimum `ns` nanoseconds. - `async fn delay_us(&mut self, us: u32)`: Pauses execution for at minimum `us` microseconds. - `async fn delay_ms(&mut self, ms: u32)`: Pauses execution for at minimum `ms` milliseconds. #### `impl PartialEq for NoDelay` - `fn eq(&self, other: &NoDelay) -> bool`: Tests for `self` and `other` values to be equal. - `fn ne(&self, other: &Rhs) -> bool`: Tests for `!=`. #### `impl Copy for NoDelay` #### `impl Eq for NoDelay` #### `impl StructuralPartialEq for NoDelay` ``` -------------------------------- ### AtomicDevice Implementations Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.AtomicDevice Details regarding the Unpin and !UnwindSafe implementations for AtomicDevice. ```APIDOC ## AtomicDevice Implementations ### `impl<'a, BUS, CS, D> Unpin for AtomicDevice<'a, BUS, CS, D>` This implementation indicates that `AtomicDevice` is `Unpin` if its generic parameters `CS` and `D` are also `Unpin`. ### `impl<'a, BUS, CS, D> !UnwindSafe for AtomicDevice<'a, BUS, CS, D>` This indicates that `AtomicDevice` is not `UnwindSafe`. ``` -------------------------------- ### AtomicDevice::new Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.AtomicDevice_search=std%3A%3Avec Constructor for creating a new AtomicDevice with delay support. ```APIDOC ## `impl<'a, BUS, CS, D> AtomicDevice<'a, BUS, CS, D>` ### `pub fn new( bus: &'a AtomicCell, cs: CS, delay: D, ) -> Result` #### Description Create a new `AtomicDevice`. This sets the `cs` pin high, and returns an error if that fails. It is recommended to set the pin high the moment it’s configured as an output, to avoid glitches. #### Type Parameters - `BUS`: The type of the SPI bus. - `CS`: The type of the Chip Select output pin. - `D`: The type of the delay provider. #### Parameters - `bus`: A reference to an `AtomicCell` containing the SPI bus. - `cs`: The Chip Select output pin. - `delay`: The delay provider. #### Returns A `Result` containing the new `AtomicDevice` on success, or a `CS::Error` on failure. ``` -------------------------------- ### CriticalSectionDevice Constructors Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.CriticalSectionDevice_search= Constructors for creating `CriticalSectionDevice` instances. ```APIDOC ## impl<'a, BUS, CS, D> CriticalSectionDevice<'a, BUS, CS, D> ### pub fn new( bus: &'a Mutex>, cs: CS, delay: D, ) -> Result #### Description Create a new `CriticalSectionDevice`. This sets the `cs` pin high, and returns an error if that fails. It is recommended to set the pin high the moment it’s configured as an output, to avoid glitches. #### Parameters * **bus** (`&'a Mutex>`) - A reference to a mutex-protected `RefCell` containing the SPI bus. * **cs** (`CS`) - The chip select pin. * **delay** (`D`) - A delay implementation. #### Returns * `Result` - A new `CriticalSectionDevice` instance or an error if the CS pin cannot be set high. ### pub fn new_no_delay( bus: &'a Mutex>, cs: CS, ) -> Result #### Description Create a new `CriticalSectionDevice` without support for in-transaction delays. This sets the `cs` pin high, and returns an error if that fails. It is recommended to set the pin high the moment it’s configured as an output, to avoid glitches. **Warning**: The returned instance _technically_ doesn’t comply with the `SpiDevice` contract, which mandates delay support. It is relatively rare for drivers to use in-transaction delays, so you might still want to use this method because it’s more practical. Note that a future version of the driver might start using delays, causing your code to panic. This wouldn’t be considered a breaking change from the driver side, because drivers are allowed to assume `SpiDevice` implementations comply with the contract. If you feel this risk outweighs the convenience of having `cargo` automatically upgrade the driver crate, you might want to pin the driver’s version. #### Parameters * **bus** (`&'a Mutex>`) - A reference to a mutex-protected `RefCell` containing the SPI bus. * **cs** (`CS`) - The chip select pin. #### Returns * `Result` - A new `CriticalSectionDevice` instance or an error if the CS pin cannot be set high. #### Panics The returned device will panic if you try to execute a transaction that contains any operations of type `Operation::DelayNs`. ``` -------------------------------- ### RcDevice::new Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.RcDevice Creates a new RcDevice instance, initializing the chip select pin and returning a Result. ```APIDOC ## POST /RcDevice::new ### Description Creates a new `RcDevice`. This sets the `cs` pin high, and returns an error if that fails. It is recommended to have already set that pin high the moment it has been configured as an output, to avoid glitches. This function does not increment the reference count: you will need to call `Rc::clone(&bus)` if you only have a `&Rc>`. Available on **crate feature`alloc`** only. ### Method `POST` (Conceptual - this is a constructor, not a typical HTTP endpoint) ### Endpoint `/RcDevice::new` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **bus** (`Rc>`) - Required - An `Rc>` representing the shared SPI bus. * **cs** (`Cs`) - Required - The chip select pin. * **delay** (`Delay`) - Required - A delay implementation. ### Request Example ```json { "bus": "Rc>", "cs": "GpioPinType", "delay": "DelayImplementation" } ``` ### Response #### Success Response (200) * **RcDevice** - A new instance of `RcDevice`. * **Cs::Error** - An error if setting the CS pin high fails. #### Response Example ```json { "result": "Ok(RcDevice)" } ``` ``` -------------------------------- ### Implement TryFrom for Type Conversion Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.MutexDevice Demonstrates the implementation of the TryFrom trait for custom type conversions. This is crucial for safely converting between different types, especially in embedded systems where memory and performance are critical. It returns a Result to handle potential conversion errors. ```rust impl TryFrom for T where U: TryFrom, { type Error = >::Error; fn try_from(value: U) -> Result { // Implementation details for conversion unimplemented!() } } ``` -------------------------------- ### ExclusiveDevice Creation Source: https://docs.rs/embedded-hal-bus/latest/src/embedded_hal_bus/spi/exclusive.rs_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates how to create a new ExclusiveDevice, ensuring exclusive access to the SPI bus. It includes methods for both devices with and without delay support. ```APIDOC ## ExclusiveDevice Creation ### Description This section details the creation of an `ExclusiveDevice`, which is used when only one SPI device is present on the bus, thus not requiring sharing mechanisms. Two constructor methods are provided: `new` for devices with delay support and `new_no_delay` for devices where in-transaction delays are not needed or supported. ### Method `ExclusiveDevice::new` and `ExclusiveDevice::new_no_delay` ### Parameters #### `ExclusiveDevice::new` - **bus** (BUS) - The underlying SPI bus object. - **cs** (CS) - The chip select pin for the SPI device. - **delay** (D) - A type implementing `embedded_hal::delay::DelayNs` for in-transaction delays. #### `ExclusiveDevice::new_no_delay` - **bus** (BUS) - The underlying SPI bus object. - **cs** (CS) - The chip select pin for the SPI device. ### Request Example ```rust // Example using ExclusiveDevice::new let spi_bus = ...; // Your SpiBus implementation let cs_pin = ...; // Your OutputPin implementation for chip select let delay_provider = ...; // Your DelayNs implementation let mut exclusive_device = ExclusiveDevice::new(spi_bus, cs_pin, delay_provider)?; // Example using ExclusiveDevice::new_no_delay let spi_bus_no_delay = ...; // Your SpiBus implementation let cs_pin_no_delay = ...; // Your OutputPin implementation for chip select let mut exclusive_device_no_delay = ExclusiveDevice::new_no_delay(spi_bus_no_delay, cs_pin_no_delay)?; ``` ### Response #### Success Response (200) - **Self** (ExclusiveDevice) - A new instance of `ExclusiveDevice`. #### Error Response - **CS::Error** - An error occurred while setting the chip select pin high. ### Notes - `ExclusiveDevice::new` requires a `CS` type that implements `OutputPin` and a `D` type that implements `DelayNs`. - `ExclusiveDevice::new_no_delay` is a convenience constructor that uses `super::NoDelay`. It comes with a warning that using it might lead to panics if `Operation::DelayNs` is encountered in a transaction, as the `SpiDevice` contract mandates delay support. ``` -------------------------------- ### Create CriticalSectionDevice with Delay Support Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.CriticalSectionDevice_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Constructs a new `CriticalSectionDevice` instance, enabling support for in-transaction delays. It initializes the CS pin to high and returns an error if this operation fails. This is the recommended approach for full `SpiDevice` contract compliance. ```rust pub fn new( bus: &'a Mutex>, cs: CS, delay: D, ) -> Result ``` -------------------------------- ### TryFrom Trait Implementation Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.ExclusiveDevice_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Provides a fallible conversion from one type to another, returning a `Result` to indicate success or failure. ```APIDOC ## impl TryFrom for T ### Description Provides a fallible conversion from one type to another, returning a `Result` to indicate success or failure. ### Method `try_from` ### Endpoint N/A (Trait Implementation) ### Parameters - **value** (U) - The value to attempt conversion from. ### Request Body None ### Response #### Success Response (Ok) - **T** (T) - The successfully converted value. #### Error Response (Err) - **Error** (>::Error) - The error type indicating conversion failure. ### Response Example ```json { "try_from": { "Ok": "converted_value" } } ``` ```json { "try_from": { "Err": "conversion_error" } } ``` ``` -------------------------------- ### AtomicDevice::new constructor Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.AtomicDevice Creates a new AtomicDevice instance. This function initializes the chip select (CS) pin to high and returns an error if this operation fails. It's recommended to set the CS pin high immediately upon configuration. ```rust pub fn new( bus: &'a AtomicCell, cs: CS, delay: D, ) -> Result where CS: OutputPin, ``` -------------------------------- ### SPI Device Implementations Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/index_search= This section details the different implementations of the SpiDevice trait provided by the embedded-hal-bus crate for managing shared access to an SPI bus. ```APIDOC ## SPI Device Implementations This section details the different implementations of the SpiDevice trait provided by the embedded-hal-bus crate for managing shared access to an SPI bus. ### Structs * **AtomicDevice** * Description: Atomics-based shared bus `SpiDevice` implementation. Requires `portable-atomic` or `target_has_atomic=8`. * Method: N/A (Struct definition) * Endpoint: N/A * **CriticalSectionDevice** * Description: `critical-section`-based shared bus `SpiDevice` implementation. * Method: N/A (Struct definition) * Endpoint: N/A * **ExclusiveDevice** * Description: `SpiDevice` implementation with exclusive access to the bus (not shared). * Method: N/A (Struct definition) * Endpoint: N/A * **MutexDevice** * Description: `std` `Mutex`-based shared bus `SpiDevice` implementation. Requires `std`. * Method: N/A (Struct definition) * Endpoint: N/A * **RcDevice** * Description: Implementation of `SpiDevice` around a bus shared with `Rc>`. This is the reference-counting equivalent of `RefCellDevice`, requiring allocation. Requires `std` or `alloc`. * Method: N/A (Struct definition) * Endpoint: N/A * **RefCellDevice** * Description: `RefCell`-based shared bus `SpiDevice` implementation. * Method: N/A (Struct definition) * Endpoint: N/A ### Enums * **AtomicError** * Description: Wrapper type for errors returned by `AtomicDevice`. Requires `portable-atomic` or `target_has_atomic=8`. * Method: N/A (Enum definition) * Endpoint: N/A * **DeviceError** * Description: Error type for `ExclusiveDevice` operations. * Method: N/A (Enum definition) * Endpoint: N/A ### Dummy Implementation * **NoDelay** * Description: Dummy `DelayNs` implementation that panics on use. * Method: N/A (Struct definition) * Endpoint: N/A ``` -------------------------------- ### Crate Root and Module Declarations (Rust) Source: https://docs.rs/embedded-hal-bus/latest/src/embedded_hal_bus/lib.rs_search= This snippet shows the main lib.rs file for the embedded-hal-bus crate. It includes documentation attributes, feature flag configurations (like `no_std` and `docsrs`), and declares the main modules: `i2c`, `spi`, and `util`. It also conditionally imports the `defmt` crate. ```rust #![doc = include_str!("../README.md")] #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(docsrs, feature(doc_cfg))] // needed to prevent defmt macros from breaking, since they emit code that does `defmt::blahblah`. #[cfg(feature = "defmt-03")] use defmt_03 as defmt; pub mod i2c; pub mod spi; pub mod util; ``` -------------------------------- ### Create AtomicDevice with Delay Support Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.AtomicDevice_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Constructs a new AtomicDevice instance that supports in-transaction delays. This function initializes the CS pin to high and returns an error if this operation fails. It requires the BUS to be an AtomicCell, and CS and D to implement OutputPin and DelayNs respectively. ```rust pub fn new( bus: &'a AtomicCell, cs: CS, delay: D, ) -> Result ``` -------------------------------- ### AtomicDevice Overview Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.AtomicDevice_search=std%3A%3Avec An overview of the AtomicDevice struct, its purpose, and how it enables shared SPI bus access. ```APIDOC ## Struct AtomicDevice `embedded_hal_bus::spi` ### Description Atomics-based shared bus `SpiDevice` implementation. This allows for sharing an `SpiBus`, obtaining multiple `SpiDevice` instances, each with its own `CS` pin. Sharing is implemented with a `AtomicDevice`, which consists of an `UnsafeCell` and an `AtomicBool` “locked” flag. This means it has low overhead, like `RefCellDevice`. Aditionally, it is `Send`, which allows sharing a single bus across multiple threads (interrupt priority level), like `CriticalSectionDevice`, while not using critical sections and therefore impacting real-time performance less. The downside is using a simple `AtomicBool` for locking doesn’t prevent two threads from trying to lock it at once. For example, the main thread can be doing a SPI transaction, and an interrupt fires and tries to do another. In this case, a `Busy` error is returned that must be handled somehow, usually dropping the data or trying again later. Note that retrying in a loop on `Busy` errors usually leads to deadlocks. In the above example, it’ll prevent the interrupt handler from returning, which will starve the main thread and prevent it from releasing the lock. If this is an issue for your use case, you most likely should use `CriticalSectionDevice` instead. This primitive is particularly well-suited for applications that have external arbitration rules that prevent `Busy` errors in the first place, such as the RTIC framework. ### Available On `crate feature 'portable-atomic'` or `target_has_atomic=8` only. ``` -------------------------------- ### TryFrom Trait Implementation Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/struct.ExclusiveDevice_search=u32+-%3E+bool Provides the `try_from` method for attempting a conversion that may fail. ```APIDOC ## impl TryFrom for T ### Description Blanket implementation of the `TryFrom` trait for attempting to convert a type `U` into a type `T`, where `U` implements `Into`. ### Method `try_from(value: U) -> Result>::Error>` ### Endpoint N/A (Trait Implementation) ### Parameters N/A ### Request Body N/A ### Response N/A ### Success Response (200) N/A ### Response Example N/A ``` -------------------------------- ### SPI Device Implementations Source: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/index_search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E This section details various implementations of the `SpiDevice` trait for managing shared access to an SPI bus. These include atomic, critical-section, exclusive, mutex-based, and reference-counted approaches. ```APIDOC ## SPI Device Implementations ### Description This section details various implementations of the `SpiDevice` trait for managing shared access to an SPI bus. These include atomic, critical-section, exclusive, mutex-based, and reference-counted approaches. ### Structs * **AtomicDevice** * Description: Atomics-based shared bus `SpiDevice` implementation. Requires `portable-atomic` or `target_has_atomic=8`. * Method: N/A (Struct definition) * Endpoint: N/A * **CriticalSectionDevice** * Description: `critical-section`-based shared bus `SpiDevice` implementation. * Method: N/A (Struct definition) * Endpoint: N/A * **ExclusiveDevice** * Description: `SpiDevice` implementation with exclusive access to the bus (not shared). * Method: N/A (Struct definition) * Endpoint: N/A * **MutexDevice** * Description: `std` `Mutex`-based shared bus `SpiDevice` implementation. Requires `std`. * Method: N/A (Struct definition) * Endpoint: N/A * **RcDevice** * Description: Implementation of `SpiDevice` around a bus shared with `Rc>`. Requires allocation. Requires `std` or `alloc`. * Method: N/A (Struct definition) * Endpoint: N/A * **RefCellDevice** * Description: `RefCell`-based shared bus `SpiDevice` implementation. * Method: N/A (Struct definition) * Endpoint: N/A ### Enums * **AtomicError** * Description: Wrapper type for errors returned by `AtomicDevice`. Requires `portable-atomic` or `target_has_atomic=8`. * Method: N/A (Enum definition) * Endpoint: N/A * **DeviceError** * Description: Error type for `ExclusiveDevice` operations. * Method: N/A (Enum definition) * Endpoint: N/A ### Other Implementations * **NoDelay** * Description: Dummy `DelayNs` implementation that panics on use. * Method: N/A (Struct definition) * Endpoint: N/A ```