aboutsummaryrefslogtreecommitdiff
path: root/embassy-embedded-hal/src/shared_bus
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-embedded-hal/src/shared_bus')
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/i2c.rs85
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/spi.rs48
-rw-r--r--embassy-embedded-hal/src/shared_bus/i2c.rs78
-rw-r--r--embassy-embedded-hal/src/shared_bus/spi.rs61
4 files changed, 272 insertions, 0 deletions
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
index bfbcb6c2e..12c2a1f4b 100644
--- a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
+++ b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
@@ -24,6 +24,7 @@ use embedded_hal_1::i2c::blocking::{I2c, Operation};
24use embedded_hal_1::i2c::ErrorType; 24use embedded_hal_1::i2c::ErrorType;
25 25
26use crate::shared_bus::i2c::I2cBusDeviceError; 26use crate::shared_bus::i2c::I2cBusDeviceError;
27use crate::SetConfig;
27 28
28pub struct I2cBusDevice<'a, M: RawMutex, BUS> { 29pub struct I2cBusDevice<'a, M: RawMutex, BUS> {
29 bus: &'a Mutex<M, RefCell<BUS>>, 30 bus: &'a Mutex<M, RefCell<BUS>>,
@@ -100,6 +101,89 @@ where
100 } 101 }
101} 102}
102 103
104<<<<<<< HEAD
105pub struct I2cBusDeviceWithConfig<'a, M: RawMutex, BUS, C> {
106 bus: &'a Mutex<M, RefCell<BUS>>,
107 config: C,
108}
109
110impl<'a, M: RawMutex, BUS, C> I2cBusDeviceWithConfig<'a, M, BUS, C> {
111 pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, config: C) -> Self {
112 Self { bus, config }
113 }
114}
115
116impl<'a, M: RawMutex, BUS, C> ErrorType for I2cBusDeviceWithConfig<'a, M, BUS, C>
117where
118 BUS: ErrorType,
119{
120 type Error = I2cBusDeviceError<BUS::Error>;
121}
122
123impl<M, BUS, C> I2c for I2cBusDeviceWithConfig<'_, M, BUS, C>
124where
125 M: RawMutex,
126 BUS: I2c + SetConfig<C>,
127{
128 fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
129 self.bus.lock(|bus| {
130 let mut bus = bus.borrow_mut();
131 bus.set_config(&self.config);
132 bus.read(address, buffer).map_err(I2cBusDeviceError::I2c)
133 })
134 }
135
136 fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
137 self.bus.lock(|bus| {
138 let mut bus = bus.borrow_mut();
139 bus.set_config(&self.config);
140 bus.write(address, bytes).map_err(I2cBusDeviceError::I2c)
141 })
142 }
143
144 fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Self::Error> {
145 self.bus.lock(|bus| {
146 let mut bus = bus.borrow_mut();
147 bus.set_config(&self.config);
148 bus.write_read(address, wr_buffer, rd_buffer)
149 .map_err(I2cBusDeviceError::I2c)
150 })
151 }
152
153 fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> {
154 let _ = address;
155 let _ = operations;
156 todo!()
157 }
158
159 fn write_iter<B: IntoIterator<Item = u8>>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error> {
160 let _ = addr;
161 let _ = bytes;
162 todo!()
163 }
164
165 fn write_iter_read<B: IntoIterator<Item = u8>>(
166 &mut self,
167 addr: u8,
168 bytes: B,
169 buffer: &mut [u8],
170 ) -> Result<(), Self::Error> {
171 let _ = addr;
172 let _ = bytes;
173 let _ = buffer;
174 todo!()
175 }
176
177 fn transaction_iter<'a, O: IntoIterator<Item = Operation<'a>>>(
178 &mut self,
179 address: u8,
180 operations: O,
181 ) -> Result<(), Self::Error> {
182 let _ = address;
183 let _ = operations;
184 todo!()
185 }
186=======
103impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::Write for I2cBusDevice<'_, M, BUS> 187impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::Write for I2cBusDevice<'_, M, BUS>
104where 188where
105 M: RawMutex, 189 M: RawMutex,
@@ -140,4 +224,5 @@ where
140 .map_err(I2cBusDeviceError::I2c) 224 .map_err(I2cBusDeviceError::I2c)
141 }) 225 })
142 } 226 }
227>>>>>>> master
143} 228}
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
index 81cf97457..b31efd64b 100644
--- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
+++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
@@ -27,6 +27,7 @@ use embedded_hal_1::spi;
27use embedded_hal_1::spi::blocking::{SpiBusFlush, SpiDevice}; 27use embedded_hal_1::spi::blocking::{SpiBusFlush, SpiDevice};
28 28
29use crate::shared_bus::spi::SpiBusDeviceError; 29use crate::shared_bus::spi::SpiBusDeviceError;
30use crate::SetConfig;
30 31
31pub struct SpiBusDevice<'a, M: RawMutex, BUS, CS> { 32pub struct SpiBusDevice<'a, M: RawMutex, BUS, CS> {
32 bus: &'a Mutex<M, RefCell<BUS>>, 33 bus: &'a Mutex<M, RefCell<BUS>>,
@@ -75,6 +76,52 @@ where
75 } 76 }
76} 77}
77 78
79<<<<<<< HEAD
80pub struct SpiBusDeviceWithConfig<'a, M: RawMutex, BUS, CS, C> {
81 bus: &'a Mutex<M, RefCell<BUS>>,
82 cs: CS,
83 config: C,
84}
85
86impl<'a, M: RawMutex, BUS, CS, C> SpiBusDeviceWithConfig<'a, M, BUS, CS, C> {
87 pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, cs: CS, config: C) -> Self {
88 Self { bus, cs, config }
89 }
90}
91
92impl<'a, M: RawMutex, BUS, CS, C> spi::ErrorType for SpiBusDeviceWithConfig<'a, M, BUS, CS, C>
93where
94 BUS: spi::ErrorType,
95 CS: OutputPin,
96{
97 type Error = SpiBusDeviceError<BUS::Error, CS::Error>;
98}
99
100impl<BUS, M, CS, C> SpiDevice for SpiBusDeviceWithConfig<'_, M, BUS, CS, C>
101where
102 M: RawMutex,
103 BUS: SpiBusFlush + SetConfig<C>,
104 CS: OutputPin,
105{
106 type Bus = BUS;
107
108 fn transaction<R>(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>) -> Result<R, Self::Error> {
109 self.bus.lock(|bus| {
110 let mut bus = bus.borrow_mut();
111 bus.set_config(&self.config);
112 self.cs.set_low().map_err(SpiBusDeviceError::Cs)?;
113
114 let f_res = f(&mut bus);
115
116 // On failure, it's important to still flush and deassert CS.
117 let flush_res = bus.flush();
118 let cs_res = self.cs.set_high();
119
120 let f_res = f_res.map_err(SpiBusDeviceError::Spi)?;
121 flush_res.map_err(SpiBusDeviceError::Spi)?;
122 cs_res.map_err(SpiBusDeviceError::Cs)?;
123
124=======
78impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Transfer<u8> for SpiBusDevice<'_, M, BUS, CS> 125impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Transfer<u8> for SpiBusDevice<'_, M, BUS, CS>
79where 126where
80 M: RawMutex, 127 M: RawMutex,
@@ -111,6 +158,7 @@ where
111 let cs_res = self.cs.set_high(); 158 let cs_res = self.cs.set_high();
112 let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; 159 let f_res = f_res.map_err(SpiBusDeviceError::Spi)?;
113 cs_res.map_err(SpiBusDeviceError::Cs)?; 160 cs_res.map_err(SpiBusDeviceError::Cs)?;
161>>>>>>> master
114 Ok(f_res) 162 Ok(f_res)
115 }) 163 })
116 } 164 }
diff --git a/embassy-embedded-hal/src/shared_bus/i2c.rs b/embassy-embedded-hal/src/shared_bus/i2c.rs
index e8131288a..0e964773c 100644
--- a/embassy-embedded-hal/src/shared_bus/i2c.rs
+++ b/embassy-embedded-hal/src/shared_bus/i2c.rs
@@ -29,6 +29,8 @@ use embassy::blocking_mutex::raw::RawMutex;
29use embassy::mutex::Mutex; 29use embassy::mutex::Mutex;
30use embedded_hal_async::i2c; 30use embedded_hal_async::i2c;
31 31
32use crate::SetConfig;
33
32#[derive(Copy, Clone, Eq, PartialEq, Debug)] 34#[derive(Copy, Clone, Eq, PartialEq, Debug)]
33pub enum I2cBusDeviceError<BUS> { 35pub enum I2cBusDeviceError<BUS> {
34 I2c(BUS), 36 I2c(BUS),
@@ -116,3 +118,79 @@ where
116 async move { todo!() } 118 async move { todo!() }
117 } 119 }
118} 120}
121
122pub struct I2cBusDeviceWithConfig<'a, M: RawMutex, BUS, C> {
123 bus: &'a Mutex<M, BUS>,
124 config: C,
125}
126
127impl<'a, M: RawMutex, BUS, C> I2cBusDeviceWithConfig<'a, M, BUS, C> {
128 pub fn new(bus: &'a Mutex<M, BUS>, config: C) -> Self {
129 Self { bus, config }
130 }
131}
132
133impl<'a, M: RawMutex, BUS, C> i2c::ErrorType for I2cBusDeviceWithConfig<'a, M, BUS, C>
134where
135 BUS: i2c::ErrorType,
136{
137 type Error = I2cBusDeviceError<BUS::Error>;
138}
139
140impl<M, BUS, C> i2c::I2c for I2cBusDeviceWithConfig<'_, M, BUS, C>
141where
142 M: RawMutex + 'static,
143 BUS: i2c::I2c + SetConfig<C> + 'static,
144{
145 type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
146
147 fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
148 async move {
149 let mut bus = self.bus.lock().await;
150 bus.set_config(&self.config);
151 bus.read(address, buffer).await.map_err(I2cBusDeviceError::I2c)?;
152 Ok(())
153 }
154 }
155
156 type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
157
158 fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Self::WriteFuture<'a> {
159 async move {
160 let mut bus = self.bus.lock().await;
161 bus.set_config(&self.config);
162 bus.write(address, bytes).await.map_err(I2cBusDeviceError::I2c)?;
163 Ok(())
164 }
165 }
166
167 type WriteReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a;
168
169 fn write_read<'a>(
170 &'a mut self,
171 address: u8,
172 wr_buffer: &'a [u8],
173 rd_buffer: &'a mut [u8],
174 ) -> Self::WriteReadFuture<'a> {
175 async move {
176 let mut bus = self.bus.lock().await;
177 bus.set_config(&self.config);
178 bus.write_read(address, wr_buffer, rd_buffer)
179 .await
180 .map_err(I2cBusDeviceError::I2c)?;
181 Ok(())
182 }
183 }
184
185 type TransactionFuture<'a, 'b> = impl Future<Output = Result<(), Self::Error>> + 'a where Self: 'a, 'b: 'a;
186
187 fn transaction<'a, 'b>(
188 &'a mut self,
189 address: u8,
190 operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
191 ) -> Self::TransactionFuture<'a, 'b> {
192 let _ = address;
193 let _ = operations;
194 async move { todo!() }
195 }
196}
diff --git a/embassy-embedded-hal/src/shared_bus/spi.rs b/embassy-embedded-hal/src/shared_bus/spi.rs
index fd4b6d565..04378c330 100644
--- a/embassy-embedded-hal/src/shared_bus/spi.rs
+++ b/embassy-embedded-hal/src/shared_bus/spi.rs
@@ -34,6 +34,8 @@ use embedded_hal_1::digital::blocking::OutputPin;
34use embedded_hal_1::spi::ErrorType; 34use embedded_hal_1::spi::ErrorType;
35use embedded_hal_async::spi; 35use embedded_hal_async::spi;
36 36
37use crate::SetConfig;
38
37#[derive(Copy, Clone, Eq, PartialEq, Debug)] 39#[derive(Copy, Clone, Eq, PartialEq, Debug)]
38pub enum SpiBusDeviceError<BUS, CS> { 40pub enum SpiBusDeviceError<BUS, CS> {
39 Spi(BUS), 41 Spi(BUS),
@@ -109,3 +111,62 @@ where
109 } 111 }
110 } 112 }
111} 113}
114
115pub struct SpiBusDeviceWithConfig<'a, M: RawMutex, BUS, CS, C> {
116 bus: &'a Mutex<M, BUS>,
117 cs: CS,
118 config: C,
119}
120
121impl<'a, M: RawMutex, BUS, CS, C> SpiBusDeviceWithConfig<'a, M, BUS, CS, C> {
122 pub fn new(bus: &'a Mutex<M, BUS>, cs: CS, config: C) -> Self {
123 Self { bus, cs, config }
124 }
125}
126
127impl<'a, M: RawMutex, BUS, CS, C> spi::ErrorType for SpiBusDeviceWithConfig<'a, M, BUS, CS, C>
128where
129 BUS: spi::ErrorType,
130 CS: OutputPin,
131{
132 type Error = SpiBusDeviceError<BUS::Error, CS::Error>;
133}
134
135impl<M, BUS, CS, C> spi::SpiDevice for SpiBusDeviceWithConfig<'_, M, BUS, CS, C>
136where
137 M: RawMutex + 'static,
138 BUS: spi::SpiBusFlush + SetConfig<C> + 'static,
139 CS: OutputPin,
140{
141 type Bus = BUS;
142
143 type TransactionFuture<'a, R, F, Fut> = impl Future<Output = Result<R, Self::Error>> + 'a
144 where
145 Self: 'a, R: 'a, F: FnOnce(*mut Self::Bus) -> Fut + 'a,
146 Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>> + 'a;
147
148 fn transaction<'a, R, F, Fut>(&'a mut self, f: F) -> Self::TransactionFuture<'a, R, F, Fut>
149 where
150 R: 'a,
151 F: FnOnce(*mut Self::Bus) -> Fut + 'a,
152 Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>> + 'a,
153 {
154 async move {
155 let mut bus = self.bus.lock().await;
156 bus.set_config(&self.config);
157 self.cs.set_low().map_err(SpiBusDeviceError::Cs)?;
158
159 let f_res = f(&mut *bus).await;
160
161 // On failure, it's important to still flush and deassert CS.
162 let flush_res = bus.flush().await;
163 let cs_res = self.cs.set_high();
164
165 let f_res = f_res.map_err(SpiBusDeviceError::Spi)?;
166 flush_res.map_err(SpiBusDeviceError::Spi)?;
167 cs_res.map_err(SpiBusDeviceError::Cs)?;
168
169 Ok(f_res)
170 }
171 }
172}