aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Alsér <[email protected]>2022-07-06 02:35:46 +0200
committerHenrik Alsér <[email protected]>2022-07-06 02:35:46 +0200
commit264b32d71baf471d0d36a34cc48aa10d429bed04 (patch)
tree80545647cfbbc6be6b97be2ac83ebb85a254e8d3
parent5fef527764f1b694a9213050f4a187339dcc049b (diff)
Add blocking shared bus for i2c and SPI
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/i2c.rs69
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/mod.rs3
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/spi.rs69
-rw-r--r--embassy-embedded-hal/src/shared_bus/mod.rs6
4 files changed, 145 insertions, 2 deletions
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
new file mode 100644
index 000000000..2a6ea6dc8
--- /dev/null
+++ b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
@@ -0,0 +1,69 @@
1//! Blocking shared I2C bus
2use core::cell::RefCell;
3use core::fmt::Debug;
4use core::future::Future;
5
6use embedded_hal_1::i2c;
7
8#[derive(Copy, Clone, Eq, PartialEq, Debug)]
9pub enum I2cBusDeviceError<BUS> {
10 I2c(BUS),
11}
12
13impl<BUS> i2c::Error for I2cBusDeviceError<BUS>
14where
15 BUS: i2c::Error + Debug,
16{
17 fn kind(&self) -> i2c::ErrorKind {
18 match self {
19 Self::I2c(e) => e.kind(),
20 }
21 }
22}
23
24pub struct I2cBusDevice<'a, BUS> {
25 bus: &'a RefCell<BUS>,
26}
27
28impl<'a, BUS> I2cBusDevice<'a, BUS> {
29 pub fn new(bus: &'a RefCell<BUS>) -> Self {
30 Self { bus }
31 }
32}
33
34impl<'a, BUS> i2c::ErrorType for I2cBusDevice<'a, BUS>
35where
36 BUS: i2c::ErrorType,
37{
38 type Error = I2cBusDeviceError<BUS::Error>;
39}
40
41impl<M, BUS> i2c::I2c for I2cBusDevice<'_, BUS>
42where
43 BUS: i2c::I2c,
44{
45 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
46 let mut bus = self.bus.borrow_mut();
47 bus.read(address, buffer).map_err(I2cBusDeviceError::I2c)?;
48 Ok(())
49 }
50
51 fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
52 let mut bus = self.bus.borrow_mut();
53 bus.write(address, bytes).map_err(I2cBusDeviceError::I2c)?;
54 Ok(())
55 }
56
57 fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Self::Error> {
58 let mut bus = self.bus.borrow_mut();
59 bus.write_read(address, wr_buffer, rd_buffer)
60 .map_err(I2cBusDeviceError::I2c)?;
61 Ok(())
62 }
63
64 fn transaction<'a>(&mut self, address: u8, operations: &mut [i2c::Operation<'a>]) -> Result<(), Self::Error> {
65 let _ = address;
66 let _ = operations;
67 todo!()
68 }
69}
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/mod.rs b/embassy-embedded-hal/src/shared_bus/blocking/mod.rs
new file mode 100644
index 000000000..c2063ed2e
--- /dev/null
+++ b/embassy-embedded-hal/src/shared_bus/blocking/mod.rs
@@ -0,0 +1,3 @@
1//! Blocking shared bus implementations for embedded-hal
2pub mod i2c;
3pub mod spi;
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
new file mode 100644
index 000000000..0d01a590b
--- /dev/null
+++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
@@ -0,0 +1,69 @@
1//! Blocking shared SPI bus
2use core::cell::RefCell;
3use core::fmt::Debug;
4
5use embedded_hal_1::digital::blocking::OutputPin;
6use embedded_hal_1::spi;
7use embedded_hal_1::spi::blocking::SpiDevice;
8
9#[derive(Copy, Clone, Eq, PartialEq, Debug)]
10pub enum SpiBusDeviceError<BUS, CS> {
11 Spi(BUS),
12 Cs(CS),
13}
14
15impl<BUS, CS> spi::Error for SpiBusDeviceError<BUS, CS>
16where
17 BUS: spi::Error + Debug,
18 CS: Debug,
19{
20 fn kind(&self) -> spi::ErrorKind {
21 match self {
22 Self::Spi(e) => e.kind(),
23 Self::Cs(_) => spi::ErrorKind::Other,
24 }
25 }
26}
27
28pub struct SpiBusDevice<'a, BUS, CS> {
29 bus: &'a RefCell<BUS>,
30 cs: CS,
31}
32
33impl<'a, BUS, CS> SpiBusDevice<'a, BUS, CS> {
34 pub fn new(bus: &'a RefCell<BUS>, cs: CS) -> Self {
35 Self { bus, cs }
36 }
37}
38
39impl<'a, BUS, CS> spi::ErrorType for SpiBusDevice<'a, BUS, CS>
40where
41 BUS: spi::ErrorType,
42 CS: OutputPin,
43{
44 type Error = SpiBusDeviceError<BUS::Error, CS::Error>;
45}
46
47impl<BUS, CS> spi::SpiDevice for SpiBusDevice<'_, BUS, CS>
48where
49 BUS: spi::SpiBusFlush,
50 CS: OutputPin,
51{
52 type Bus = BUS;
53 fn transaction<R>(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>) -> Result<R, Self::Error> {
54 let mut bus = self.bus.borrow_mut();
55 self.cs.set_low().map_err(SpiDeviceWithCsError::Cs)?;
56
57 let f_res = f(&mut bus);
58
59 // On failure, it's important to still flush and deassert CS.
60 let flush_res = bus.flush();
61 let cs_res = self.cs.set_high();
62
63 let f_res = f_res.map_err(SpiDeviceWithCsError::Spi)?;
64 flush_res.map_err(SpiDeviceWithCsError::Spi)?;
65 cs_res.map_err(SpiDeviceWithCsError::Cs)?;
66
67 Ok(f_res)
68 }
69}
diff --git a/embassy-embedded-hal/src/shared_bus/mod.rs b/embassy-embedded-hal/src/shared_bus/mod.rs
index bd4fd2c31..cd748cac8 100644
--- a/embassy-embedded-hal/src/shared_bus/mod.rs
+++ b/embassy-embedded-hal/src/shared_bus/mod.rs
@@ -1,4 +1,6 @@
1//! Shared bus implementations for embedded-hal-async 1//! Shared bus implementations
2 2pub mod blocking;
3/// Shared i2c bus implementation for embedded-hal-async
3pub mod i2c; 4pub mod i2c;
5/// Shared SPI bus implementation for embedded-hal-async
4pub mod spi; 6pub mod spi;