Remove SpiBusDevice and SpiBusController (#978)

* Remove SpiBusDevice and SpiBusController

* Update examples
This commit is contained in:
Dániel Buga 2023-11-28 09:55:55 +01:00 committed by GitHub
parent a54588d45b
commit 4a0af66884
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 128 additions and 202 deletions

View File

@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed
- Removed the `mcu-boot` feature from `esp32c3-hal` (#938)
- Removed SpiBusController and SpiBusDevice in favour of embedded-hal-bus and embassy-embedded-hal implementataions. (#978)
### Breaking
- Direct boot support has been removed (#903).

View File

@ -34,18 +34,18 @@
//! - Use the [`SpiBus`](embedded_hal_1::spi::SpiBus) trait (requires the "eh1"
//! feature) and its associated functions to initiate transactions with
//! simultaneous reads and writes, or
// TODO async moved to embedded-hal-bus:
//! - Use the `ExclusiveDevice` struct from `embedded-hal-bus` or
//! `embedded-hal-async` (recommended).
//! - Use the `ExclusiveDevice` struct from [`embedded-hal-bus`] or `SpiDevice`
//! from [`embassy-embedded-hal`].
//!
//!
//! ## Shared SPI access
//!
//! If you have multiple devices on the same SPI bus that each have their own CS
//! line, you may want to have a look at the [`ehal1::SpiBusController`] and
//! [`ehal1::SpiBusDevice`] implemented here. These give exclusive access to the
//! underlying SPI bus by means of a Mutex. This ensures that device
//! transactions do not interfere with each other.
//! line, you may want to have a look at the implementations provided by
//! [`embedded-hal-bus`] and [`embassy-embedded-hal`].
//!
//! [`embedded-hal-bus`]: https://docs.rs/embedded-hal-bus/latest/embedded_hal_bus/spi/index.html
//! [`embassy-embedded-hal`]: https://docs.embassy.dev/embassy-embedded-hal/git/default/shared_bus/index.html
use core::marker::PhantomData;
@ -1629,7 +1629,7 @@ pub use ehal1::*;
mod ehal1 {
use core::cell::RefCell;
use embedded_hal_1::spi::{self, ErrorType, Operation, SpiBus, SpiDevice};
use embedded_hal_1::spi::{self, ErrorType, Operation, SpiBus};
use embedded_hal_nb::spi::FullDuplex;
use super::*;
@ -1725,102 +1725,6 @@ mod ehal1 {
self.spi.flush()
}
}
/// SPI bus controller.
///
/// Has exclusive access to an SPI bus, which is managed via a `Mutex`. Used
/// as basis for the [`SpiBusDevice`] implementation. Note that the
/// wrapped [`RefCell`] is used solely to achieve interior mutability.
pub struct SpiBusController<'d, I: Instance, M: IsFullDuplex> {
lock: critical_section::Mutex<RefCell<Spi<'d, I, M>>>,
}
impl<'d, I: Instance, M: IsFullDuplex> SpiBusController<'d, I, M> {
/// Create a new controller from an SPI bus instance.
///
/// Takes ownership of the SPI bus in the process. Afterwards, the SPI
/// bus can only be accessed via instances of [`SpiBusDevice`].
pub fn from_spi(bus: Spi<'d, I, M>) -> Self {
SpiBusController {
lock: critical_section::Mutex::new(RefCell::new(bus)),
}
}
pub fn add_device<'a, CS: OutputPin>(&'a self, cs: CS) -> SpiBusDevice<'a, 'd, I, CS, M> {
SpiBusDevice::new(self, cs)
}
}
impl<'d, I: Instance, M: IsFullDuplex> ErrorType for SpiBusController<'d, I, M> {
type Error = spi::ErrorKind;
}
/// An SPI device on a shared SPI bus.
///
/// Provides device specific access on a shared SPI bus. Enables attaching
/// multiple SPI devices to the same bus, each with its own CS line, and
/// performing safe transfers on them.
pub struct SpiBusDevice<'a, 'd, I, CS, M>
where
I: Instance,
CS: OutputPin,
M: IsFullDuplex,
{
bus: &'a SpiBusController<'d, I, M>,
cs: CS,
}
impl<'a, 'd, I, CS, M> SpiBusDevice<'a, 'd, I, CS, M>
where
I: Instance,
CS: OutputPin,
M: IsFullDuplex,
{
pub fn new(bus: &'a SpiBusController<'d, I, M>, mut cs: CS) -> Self {
cs.set_to_push_pull_output().set_output_high(true);
SpiBusDevice { bus, cs }
}
}
impl<'a, 'd, I, CS, M> ErrorType for SpiBusDevice<'a, 'd, I, CS, M>
where
I: Instance,
CS: OutputPin,
M: IsFullDuplex,
{
type Error = spi::ErrorKind;
}
impl<'a, 'd, I, CS, M> SpiDevice<u8> for SpiBusDevice<'a, 'd, I, CS, M>
where
I: Instance,
CS: OutputPin,
M: IsFullDuplex,
{
fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
critical_section::with(|cs| {
let mut bus = self.bus.lock.borrow_ref_mut(cs);
self.cs.connect_peripheral_to_output(bus.spi.cs_signal());
let op_res = operations.iter_mut().try_for_each(|op| match op {
Operation::Read(buf) => SpiBus::read(&mut (*bus), buf),
Operation::Write(buf) => SpiBus::write(&mut (*bus), buf),
Operation::Transfer(read, write) => bus.transfer(read, write),
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
Operation::DelayUs(_delay) => unimplemented!(),
});
// On failure, it's important to still flush and de-assert CS.
let flush_res = bus.flush();
self.cs.disconnect_peripheral_from_output();
op_res.map_err(|_| spi::ErrorKind::Other)?;
flush_res.map_err(|_| spi::ErrorKind::Other)?;
Ok(())
})
}
}
}
pub trait InstanceDma<TX, RX>: Instance

View File

@ -38,6 +38,7 @@ embedded-graphics = "0.8.1"
embedded-hal-1 = { version = "=1.0.0-rc.1", package = "embedded-hal" }
embedded-hal-async = "=1.0.0-rc.1"
embedded-io-async = "0.6.0"
embedded-hal-bus = "0.1.0-rc.1"
esp-alloc = "0.3.0"
esp-backtrace = { version = "0.9.0", features = ["esp32", "panic-handler", "exception-handler", "print-uart"] }
esp-hal-smartled = { version = "0.6.0", features = ["esp32"], path = "../esp-hal-smartled" }

View File

@ -18,16 +18,16 @@
#![no_std]
#![no_main]
use core::cell::RefCell;
use embedded_hal_1::spi::SpiDevice;
use embedded_hal_bus::spi::RefCellDevice;
use esp32_hal::{
clock::ClockControl,
gpio::{self, IO},
peripherals::Peripherals,
prelude::*,
spi::{
master::{Spi, SpiBusController},
SpiMode,
},
spi::{master::Spi, SpiMode},
Delay,
};
use esp_backtrace as _;
@ -44,17 +44,19 @@ fn main() -> ! {
let miso = io.pins.gpio25;
let mosi = io.pins.gpio23;
let spi_controller = SpiBusController::from_spi(
Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
),
let spi_bus = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
);
let mut spi_device_1 = spi_controller.add_device(io.pins.gpio12);
let mut spi_device_2 = spi_controller.add_device(io.pins.gpio13);
let mut spi_device_3 = spi_controller.add_device(io.pins.gpio14);
let spi_bus = RefCell::new(spi_bus);
let mut spi_device_1 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio12.into_push_pull_output());
let mut spi_device_2 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio13.into_push_pull_output());
let mut spi_device_3 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio14.into_push_pull_output());
let mut delay = Delay::new(&clocks);
println!("=== SPI example with embedded-hal-1 traits ===");

View File

@ -35,6 +35,7 @@ embedded-graphics = "0.8.1"
embedded-hal-1 = { version = "=1.0.0-rc.1", package = "embedded-hal" }
embedded-hal-async = "=1.0.0-rc.1"
embedded-io-async = "0.6.0"
embedded-hal-bus = "0.1.0-rc.1"
esp-backtrace = { version = "0.9.0", features = ["esp32c2", "panic-handler", "exception-handler", "print-uart"] }
esp-println = { version = "0.7.0", features = ["esp32c2"] }
heapless = "0.7.16"

View File

@ -18,16 +18,16 @@
#![no_std]
#![no_main]
use core::cell::RefCell;
use embedded_hal_1::spi::SpiDevice;
use embedded_hal_bus::spi::RefCellDevice;
use esp32c2_hal::{
clock::ClockControl,
gpio::{self, IO},
peripherals::Peripherals,
prelude::*,
spi::{
master::{Spi, SpiBusController},
SpiMode,
},
spi::{master::Spi, SpiMode},
Delay,
};
use esp_backtrace as _;
@ -44,17 +44,19 @@ fn main() -> ! {
let miso = io.pins.gpio2;
let mosi = io.pins.gpio7;
let spi_controller = SpiBusController::from_spi(
Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
),
let spi_bus = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
);
let mut spi_device_1 = spi_controller.add_device(io.pins.gpio3);
let mut spi_device_2 = spi_controller.add_device(io.pins.gpio4);
let mut spi_device_3 = spi_controller.add_device(io.pins.gpio5);
let spi_bus = RefCell::new(spi_bus);
let mut spi_device_1 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio3.into_push_pull_output());
let mut spi_device_2 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio4.into_push_pull_output());
let mut spi_device_3 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio5.into_push_pull_output());
let mut delay = Delay::new(&clocks);
println!("=== SPI example with embedded-hal-1 traits ===");

View File

@ -40,6 +40,7 @@ embedded-hal = { version = "0.2.7", features = ["unproven"] }
embedded-hal-1 = { version = "=1.0.0-rc.1", package = "embedded-hal" }
embedded-hal-async = "=1.0.0-rc.1"
embedded-io-async = "0.6.0"
embedded-hal-bus = "0.1.0-rc.1"
esp-backtrace = { version = "0.9.0", features = ["esp32c3", "panic-handler", "exception-handler", "print-uart"] }
esp-hal-smartled = { version = "0.6.0", features = ["esp32c3"], path = "../esp-hal-smartled" }
esp-println = { version = "0.7.0", features = ["esp32c3"] }

View File

@ -18,16 +18,16 @@
#![no_std]
#![no_main]
use core::cell::RefCell;
use embedded_hal_1::spi::SpiDevice;
use embedded_hal_bus::spi::RefCellDevice;
use esp32c3_hal::{
clock::ClockControl,
gpio::{self, IO},
peripherals::Peripherals,
prelude::*,
spi::{
master::{Spi, SpiBusController},
SpiMode,
},
spi::{master::Spi, SpiMode},
Delay,
};
use esp_backtrace as _;
@ -44,17 +44,19 @@ fn main() -> ! {
let miso = io.pins.gpio2;
let mosi = io.pins.gpio7;
let spi_controller = SpiBusController::from_spi(
Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
),
let spi_bus = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
);
let mut spi_device_1 = spi_controller.add_device(io.pins.gpio3);
let mut spi_device_2 = spi_controller.add_device(io.pins.gpio4);
let mut spi_device_3 = spi_controller.add_device(io.pins.gpio5);
let spi_bus = RefCell::new(spi_bus);
let mut spi_device_1 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio3.into_push_pull_output());
let mut spi_device_2 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio4.into_push_pull_output());
let mut spi_device_3 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio5.into_push_pull_output());
let mut delay = Delay::new(&clocks);
println!("=== SPI example with embedded-hal-1 traits ===");

View File

@ -39,6 +39,7 @@ embedded-hal-1 = { version = "=1.0.0-rc.1", package = "embedded-hal" }
embedded-hal-async = "=1.0.0-rc.1"
embedded-can = "0.4.1"
embedded-io-async = "0.6.0"
embedded-hal-bus = "0.1.0-rc.1"
esp-backtrace = { version = "0.9.0", features = ["esp32c6", "panic-handler", "exception-handler", "print-uart"] }
esp-hal-smartled = { version = "0.6.0", features = ["esp32c6"], path = "../esp-hal-smartled" }
esp-println = { version = "0.7.0", features = ["esp32c6"] }

View File

@ -18,16 +18,16 @@
#![no_std]
#![no_main]
use core::cell::RefCell;
use embedded_hal_1::spi::SpiDevice;
use embedded_hal_bus::spi::RefCellDevice;
use esp32c6_hal::{
clock::ClockControl,
gpio::{self, IO},
peripherals::Peripherals,
prelude::*,
spi::{
master::{Spi, SpiBusController},
SpiMode,
},
spi::{master::Spi, SpiMode},
Delay,
};
use esp_backtrace as _;
@ -44,17 +44,19 @@ fn main() -> ! {
let miso = io.pins.gpio2;
let mosi = io.pins.gpio7;
let spi_controller = SpiBusController::from_spi(
Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
),
let spi_bus = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
);
let mut spi_device_1 = spi_controller.add_device(io.pins.gpio3);
let mut spi_device_2 = spi_controller.add_device(io.pins.gpio4);
let mut spi_device_3 = spi_controller.add_device(io.pins.gpio5);
let spi_bus = RefCell::new(spi_bus);
let mut spi_device_1 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio3.into_push_pull_output());
let mut spi_device_2 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio4.into_push_pull_output());
let mut spi_device_3 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio5.into_push_pull_output());
let mut delay = Delay::new(&clocks);
println!("=== SPI example with embedded-hal-1 traits ===");

View File

@ -39,6 +39,7 @@ embedded-hal-1 = { version = "=1.0.0-rc.1", package = "embedded-hal" }
embedded-hal-async = "=1.0.0-rc.1"
embedded-can = "0.4.1"
embedded-io-async = "0.6.0"
embedded-hal-bus = "0.1.0-rc.1"
esp-backtrace = { version = "0.9.0", features = ["esp32h2", "panic-handler", "exception-handler", "print-uart"] }
esp-hal-smartled = { version = "0.6.0", features = ["esp32h2"], path = "../esp-hal-smartled" }
esp-println = { version = "0.7.0", features = ["esp32h2"] }

View File

@ -18,16 +18,16 @@
#![no_std]
#![no_main]
use core::cell::RefCell;
use embedded_hal_1::spi::SpiDevice;
use embedded_hal_bus::spi::RefCellDevice;
use esp32h2_hal::{
clock::ClockControl,
gpio::{self, IO},
peripherals::Peripherals,
prelude::*,
spi::{
master::{Spi, SpiBusController},
SpiMode,
},
spi::{master::Spi, SpiMode},
Delay,
};
use esp_backtrace as _;
@ -44,17 +44,19 @@ fn main() -> ! {
let miso = io.pins.gpio2;
let mosi = io.pins.gpio3;
let spi_controller = SpiBusController::from_spi(
Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
),
let spi_bus = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
);
let mut spi_device_1 = spi_controller.add_device(io.pins.gpio11);
let mut spi_device_2 = spi_controller.add_device(io.pins.gpio12);
let mut spi_device_3 = spi_controller.add_device(io.pins.gpio25);
let spi_bus = RefCell::new(spi_bus);
let mut spi_device_1 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio11.into_push_pull_output());
let mut spi_device_2 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio12.into_push_pull_output());
let mut spi_device_3 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio25.into_push_pull_output());
let mut delay = Delay::new(&clocks);
println!("=== SPI example with embedded-hal-1 traits ===");

View File

@ -39,6 +39,7 @@ embedded-graphics = "0.8.1"
embedded-hal-1 = { version = "=1.0.0-rc.1", package = "embedded-hal" }
embedded-hal-async = "=1.0.0-rc.1"
embedded-io-async = "0.6.0"
embedded-hal-bus = "0.1.0-rc.1"
esp-alloc = "0.3.0"
esp-backtrace = { version = "0.9.0", features = ["esp32s2", "panic-handler", "print-uart", "exception-handler"] }
esp-hal-smartled = { version = "0.6.0", features = ["esp32s2"], path = "../esp-hal-smartled" }

View File

@ -18,16 +18,16 @@
#![no_std]
#![no_main]
use core::cell::RefCell;
use embedded_hal_1::spi::SpiDevice;
use embedded_hal_bus::spi::RefCellDevice;
use esp32s2_hal::{
clock::ClockControl,
gpio::{self, IO},
peripherals::Peripherals,
prelude::*,
spi::{
master::{Spi, SpiBusController},
SpiMode,
},
spi::{master::Spi, SpiMode},
Delay,
};
use esp_backtrace as _;
@ -44,17 +44,19 @@ fn main() -> ! {
let miso = io.pins.gpio37;
let mosi = io.pins.gpio35;
let spi_controller = SpiBusController::from_spi(
Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
),
let spi_bus = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
);
let mut spi_device_1 = spi_controller.add_device(io.pins.gpio1);
let mut spi_device_2 = spi_controller.add_device(io.pins.gpio2);
let mut spi_device_3 = spi_controller.add_device(io.pins.gpio3);
let spi_bus = RefCell::new(spi_bus);
let mut spi_device_1 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio1.into_push_pull_output());
let mut spi_device_2 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio2.into_push_pull_output());
let mut spi_device_3 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio3.into_push_pull_output());
let mut delay = Delay::new(&clocks);
println!("=== SPI example with embedded-hal-1 traits ===");

View File

@ -41,6 +41,7 @@ embedded-hal-1 = { version = "=1.0.0-rc.1", package = "embedded-hal" }
embedded-hal-async = "=1.0.0-rc.1"
embedded-can = "0.4.1"
embedded-io-async = "0.6.0"
embedded-hal-bus = "0.1.0-rc.1"
esp-alloc = "0.3.0"
esp-backtrace = { version = "0.9.0", features = ["esp32s3", "panic-handler", "exception-handler", "print-uart"] }
esp-hal-smartled = { version = "0.6.0", features = ["esp32s3"], path = "../esp-hal-smartled" }

View File

@ -18,16 +18,16 @@
#![no_std]
#![no_main]
use core::cell::RefCell;
use embedded_hal_1::spi::SpiDevice;
use embedded_hal_bus::spi::RefCellDevice;
use esp32s3_hal::{
clock::ClockControl,
gpio::{self, IO},
peripherals::Peripherals,
prelude::*,
spi::{
master::{Spi, SpiBusController},
SpiMode,
},
spi::{master::Spi, SpiMode},
Delay,
};
use esp_backtrace as _;
@ -44,17 +44,19 @@ fn main() -> ! {
let miso = io.pins.gpio11;
let mosi = io.pins.gpio13;
let spi_controller = SpiBusController::from_spi(
Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
),
let spi_bus = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(
Some(sclk),
Some(mosi),
Some(miso),
gpio::NO_PIN,
);
let mut spi_device_1 = spi_controller.add_device(io.pins.gpio4);
let mut spi_device_2 = spi_controller.add_device(io.pins.gpio5);
let mut spi_device_3 = spi_controller.add_device(io.pins.gpio6);
let spi_bus = RefCell::new(spi_bus);
let mut spi_device_1 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio4.into_push_pull_output());
let mut spi_device_2 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio5.into_push_pull_output());
let mut spi_device_3 =
RefCellDevice::new_no_delay(&spi_bus, io.pins.gpio6.into_push_pull_output());
let mut delay = Delay::new(&clocks);
println!("=== SPI example with embedded-hal-1 traits ===");