Merge #845
845: Add blocking shared bus for i2c and SPI r=Dirbaio a=kalkyl Blocking versions of the shared buses Co-authored-by: Henrik Alsér <henrik.alser@me.com> Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
		
							
								
								
									
										84
									
								
								embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| //! Blocking shared I2C bus | ||||
| use core::cell::RefCell; | ||||
|  | ||||
| use embassy::blocking_mutex::raw::RawMutex; | ||||
| use embassy::blocking_mutex::Mutex; | ||||
| use embedded_hal_1::i2c::blocking::{I2c, Operation}; | ||||
| use embedded_hal_1::i2c::ErrorType; | ||||
|  | ||||
| use crate::shared_bus::i2c::I2cBusDeviceError; | ||||
|  | ||||
| pub struct I2cBusDevice<'a, M: RawMutex, BUS> { | ||||
|     bus: &'a Mutex<M, RefCell<BUS>>, | ||||
| } | ||||
|  | ||||
| impl<'a, M: RawMutex, BUS> I2cBusDevice<'a, M, BUS> { | ||||
|     pub fn new(bus: &'a Mutex<M, RefCell<BUS>>) -> Self { | ||||
|         Self { bus } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a, M: RawMutex, BUS> ErrorType for I2cBusDevice<'a, M, BUS> | ||||
| where | ||||
|     BUS: ErrorType, | ||||
| { | ||||
|     type Error = I2cBusDeviceError<BUS::Error>; | ||||
| } | ||||
|  | ||||
| impl<M, BUS> I2c for I2cBusDevice<'_, M, BUS> | ||||
| where | ||||
|     M: RawMutex, | ||||
|     BUS: I2c, | ||||
| { | ||||
|     fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { | ||||
|         self.bus | ||||
|             .lock(|bus| bus.borrow_mut().read(address, buffer).map_err(I2cBusDeviceError::I2c)) | ||||
|     } | ||||
|  | ||||
|     fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> { | ||||
|         self.bus | ||||
|             .lock(|bus| bus.borrow_mut().write(address, bytes).map_err(I2cBusDeviceError::I2c)) | ||||
|     } | ||||
|  | ||||
|     fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Self::Error> { | ||||
|         self.bus.lock(|bus| { | ||||
|             bus.borrow_mut() | ||||
|                 .write_read(address, wr_buffer, rd_buffer) | ||||
|                 .map_err(I2cBusDeviceError::I2c) | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     fn transaction<'a>(&mut self, address: u8, operations: &mut [Operation<'a>]) -> Result<(), Self::Error> { | ||||
|         let _ = address; | ||||
|         let _ = operations; | ||||
|         todo!() | ||||
|     } | ||||
|  | ||||
|     fn write_iter<B: IntoIterator<Item = u8>>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error> { | ||||
|         let _ = addr; | ||||
|         let _ = bytes; | ||||
|         todo!() | ||||
|     } | ||||
|  | ||||
|     fn write_iter_read<B: IntoIterator<Item = u8>>( | ||||
|         &mut self, | ||||
|         addr: u8, | ||||
|         bytes: B, | ||||
|         buffer: &mut [u8], | ||||
|     ) -> Result<(), Self::Error> { | ||||
|         let _ = addr; | ||||
|         let _ = bytes; | ||||
|         let _ = buffer; | ||||
|         todo!() | ||||
|     } | ||||
|  | ||||
|     fn transaction_iter<'a, O: IntoIterator<Item = Operation<'a>>>( | ||||
|         &mut self, | ||||
|         address: u8, | ||||
|         operations: O, | ||||
|     ) -> Result<(), Self::Error> { | ||||
|         let _ = address; | ||||
|         let _ = operations; | ||||
|         todo!() | ||||
|     } | ||||
| } | ||||
							
								
								
									
										3
									
								
								embassy-embedded-hal/src/shared_bus/blocking/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								embassy-embedded-hal/src/shared_bus/blocking/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| //! Blocking shared bus implementations for embedded-hal | ||||
| pub mod i2c; | ||||
| pub mod spi; | ||||
							
								
								
									
										57
									
								
								embassy-embedded-hal/src/shared_bus/blocking/spi.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								embassy-embedded-hal/src/shared_bus/blocking/spi.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| //! Blocking shared SPI bus | ||||
| use core::cell::RefCell; | ||||
|  | ||||
| use embassy::blocking_mutex::raw::RawMutex; | ||||
| use embassy::blocking_mutex::Mutex; | ||||
| use embedded_hal_1::digital::blocking::OutputPin; | ||||
| use embedded_hal_1::spi; | ||||
| use embedded_hal_1::spi::blocking::{SpiBusFlush, SpiDevice}; | ||||
|  | ||||
| use crate::shared_bus::spi::SpiBusDeviceError; | ||||
|  | ||||
| pub struct SpiBusDevice<'a, M: RawMutex, BUS, CS> { | ||||
|     bus: &'a Mutex<M, RefCell<BUS>>, | ||||
|     cs: CS, | ||||
| } | ||||
|  | ||||
| impl<'a, M: RawMutex, BUS, CS> SpiBusDevice<'a, M, BUS, CS> { | ||||
|     pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, cs: CS) -> Self { | ||||
|         Self { bus, cs } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a, M: RawMutex, BUS, CS> spi::ErrorType for SpiBusDevice<'a, M, BUS, CS> | ||||
| where | ||||
|     BUS: spi::ErrorType, | ||||
|     CS: OutputPin, | ||||
| { | ||||
|     type Error = SpiBusDeviceError<BUS::Error, CS::Error>; | ||||
| } | ||||
|  | ||||
| impl<BUS, M, CS> SpiDevice for SpiBusDevice<'_, M, BUS, CS> | ||||
| where | ||||
|     M: RawMutex, | ||||
|     BUS: SpiBusFlush, | ||||
|     CS: OutputPin, | ||||
| { | ||||
|     type Bus = BUS; | ||||
|  | ||||
|     fn transaction<R>(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>) -> Result<R, Self::Error> { | ||||
|         self.bus.lock(|bus| { | ||||
|             let mut bus = bus.borrow_mut(); | ||||
|             self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; | ||||
|  | ||||
|             let f_res = f(&mut bus); | ||||
|  | ||||
|             // On failure, it's important to still flush and deassert CS. | ||||
|             let flush_res = bus.flush(); | ||||
|             let cs_res = self.cs.set_high(); | ||||
|  | ||||
|             let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; | ||||
|             flush_res.map_err(SpiBusDeviceError::Spi)?; | ||||
|             cs_res.map_err(SpiBusDeviceError::Cs)?; | ||||
|  | ||||
|             Ok(f_res) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| @@ -1,4 +1,6 @@ | ||||
| //! Shared bus implementations for embedded-hal-async | ||||
|  | ||||
| //! Shared bus implementations | ||||
| pub mod blocking; | ||||
| /// Shared i2c bus implementation for embedded-hal-async | ||||
| pub mod i2c; | ||||
| /// Shared SPI bus implementation for embedded-hal-async | ||||
| pub mod spi; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user