diff options
| author | Henrik Alsér <[email protected]> | 2022-07-09 00:00:55 +0200 |
|---|---|---|
| committer | Henrik Alsér <[email protected]> | 2022-07-09 00:00:55 +0200 |
| commit | d637510b44ec8e58581f3e22f8398b53145503dc (patch) | |
| tree | b1a062c6b032947323248c6945fee87110bfc10d /embassy-embedded-hal/src/shared_bus/blocking/spi.rs | |
| parent | 15384d27bb181bf48e580ca4a1c4fd848ecb1720 (diff) | |
Associated type
Diffstat (limited to 'embassy-embedded-hal/src/shared_bus/blocking/spi.rs')
| -rw-r--r-- | embassy-embedded-hal/src/shared_bus/blocking/spi.rs | 89 |
1 files changed, 45 insertions, 44 deletions
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs index 2bcf47cff..456da8859 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs | |||
| @@ -76,66 +76,39 @@ where | |||
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | pub struct SpiBusDeviceWithConfig<'a, M: RawMutex, BUS, CS, C> { | 79 | impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Transfer<u8> for SpiBusDevice<'_, M, BUS, CS> |
| 80 | bus: &'a Mutex<M, RefCell<BUS>>, | ||
| 81 | cs: CS, | ||
| 82 | config: C, | ||
| 83 | } | ||
| 84 | |||
| 85 | impl<'a, M: RawMutex, BUS, CS, C> SpiBusDeviceWithConfig<'a, M, BUS, CS, C> { | ||
| 86 | pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, cs: CS, config: C) -> Self { | ||
| 87 | Self { bus, cs, config } | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | impl<'a, M: RawMutex, BUS, CS, C> spi::ErrorType for SpiBusDeviceWithConfig<'a, M, BUS, CS, C> | ||
| 92 | where | ||
| 93 | BUS: spi::ErrorType, | ||
| 94 | CS: OutputPin, | ||
| 95 | { | ||
| 96 | type Error = SpiBusDeviceError<BUS::Error, CS::Error>; | ||
| 97 | } | ||
| 98 | |||
| 99 | impl<BUS, M, CS, C> SpiDevice for SpiBusDeviceWithConfig<'_, M, BUS, CS, C> | ||
| 100 | where | 80 | where |
| 101 | M: RawMutex, | 81 | M: RawMutex, |
| 102 | BUS: SpiBusFlush + SetConfig<C>, | 82 | BUS: embedded_hal_02::blocking::spi::Transfer<u8, Error = BusErr>, |
| 103 | CS: OutputPin, | 83 | CS: OutputPin<Error = CsErr>, |
| 104 | { | 84 | { |
| 105 | type Bus = BUS; | 85 | type Error = SpiBusDeviceError<BusErr, CsErr>; |
| 106 | 86 | fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { | |
| 107 | fn transaction<R>(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>) -> Result<R, Self::Error> { | ||
| 108 | self.bus.lock(|bus| { | 87 | self.bus.lock(|bus| { |
| 109 | let mut bus = bus.borrow_mut(); | 88 | let mut bus = bus.borrow_mut(); |
| 110 | bus.set_config(&self.config); | ||
| 111 | self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; | 89 | self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; |
| 112 | 90 | let f_res = bus.transfer(words); | |
| 113 | let f_res = f(&mut bus); | ||
| 114 | |||
| 115 | // On failure, it's important to still flush and deassert CS. | ||
| 116 | let flush_res = bus.flush(); | ||
| 117 | let cs_res = self.cs.set_high(); | 91 | let cs_res = self.cs.set_high(); |
| 118 | |||
| 119 | let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; | 92 | let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; |
| 120 | flush_res.map_err(SpiBusDeviceError::Spi)?; | ||
| 121 | cs_res.map_err(SpiBusDeviceError::Cs)?; | 93 | cs_res.map_err(SpiBusDeviceError::Cs)?; |
| 122 | Ok(f_res) | 94 | Ok(f_res) |
| 123 | }) | 95 | }) |
| 124 | } | 96 | } |
| 125 | } | 97 | } |
| 126 | 98 | ||
| 127 | impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Transfer<u8> for SpiBusDevice<'_, M, BUS, CS> | 99 | impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Write<u8> for SpiBusDevice<'_, M, BUS, CS> |
| 128 | where | 100 | where |
| 129 | M: RawMutex, | 101 | M: RawMutex, |
| 130 | BUS: embedded_hal_02::blocking::spi::Transfer<u8, Error = BusErr>, | 102 | BUS: embedded_hal_02::blocking::spi::Write<u8, Error = BusErr>, |
| 131 | CS: OutputPin<Error = CsErr>, | 103 | CS: OutputPin<Error = CsErr>, |
| 132 | { | 104 | { |
| 133 | type Error = SpiBusDeviceError<BusErr, CsErr>; | 105 | type Error = SpiBusDeviceError<BusErr, CsErr>; |
| 134 | fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { | 106 | |
| 107 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { | ||
| 135 | self.bus.lock(|bus| { | 108 | self.bus.lock(|bus| { |
| 136 | let mut bus = bus.borrow_mut(); | 109 | let mut bus = bus.borrow_mut(); |
| 137 | self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; | 110 | self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; |
| 138 | let f_res = bus.transfer(words); | 111 | let f_res = bus.write(words); |
| 139 | let cs_res = self.cs.set_high(); | 112 | let cs_res = self.cs.set_high(); |
| 140 | let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; | 113 | let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; |
| 141 | cs_res.map_err(SpiBusDeviceError::Cs)?; | 114 | cs_res.map_err(SpiBusDeviceError::Cs)?; |
| @@ -144,21 +117,49 @@ where | |||
| 144 | } | 117 | } |
| 145 | } | 118 | } |
| 146 | 119 | ||
| 147 | impl<'d, M, BUS, CS, BusErr, CsErr> embedded_hal_02::blocking::spi::Write<u8> for SpiBusDevice<'_, M, BUS, CS> | 120 | pub struct SpiBusDeviceWithConfig<'a, M: RawMutex, BUS: SetConfig, CS> { |
| 121 | bus: &'a Mutex<M, RefCell<BUS>>, | ||
| 122 | cs: CS, | ||
| 123 | config: BUS::Config, | ||
| 124 | } | ||
| 125 | |||
| 126 | impl<'a, M: RawMutex, BUS: SetConfig, CS> SpiBusDeviceWithConfig<'a, M, BUS, CS> { | ||
| 127 | pub fn new(bus: &'a Mutex<M, RefCell<BUS>>, cs: CS, config: BUS::Config) -> Self { | ||
| 128 | Self { bus, cs, config } | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | impl<'a, M, BUS, CS> spi::ErrorType for SpiBusDeviceWithConfig<'a, M, BUS, CS> | ||
| 148 | where | 133 | where |
| 149 | M: RawMutex, | 134 | M: RawMutex, |
| 150 | BUS: embedded_hal_02::blocking::spi::Write<u8, Error = BusErr>, | 135 | BUS: spi::ErrorType + SetConfig, |
| 151 | CS: OutputPin<Error = CsErr>, | 136 | CS: OutputPin, |
| 152 | { | 137 | { |
| 153 | type Error = SpiBusDeviceError<BusErr, CsErr>; | 138 | type Error = SpiBusDeviceError<BUS::Error, CS::Error>; |
| 139 | } | ||
| 154 | 140 | ||
| 155 | fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { | 141 | impl<BUS, M, CS> SpiDevice for SpiBusDeviceWithConfig<'_, M, BUS, CS> |
| 142 | where | ||
| 143 | M: RawMutex, | ||
| 144 | BUS: SpiBusFlush + SetConfig, | ||
| 145 | CS: OutputPin, | ||
| 146 | { | ||
| 147 | type Bus = BUS; | ||
| 148 | |||
| 149 | fn transaction<R>(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>) -> Result<R, Self::Error> { | ||
| 156 | self.bus.lock(|bus| { | 150 | self.bus.lock(|bus| { |
| 157 | let mut bus = bus.borrow_mut(); | 151 | let mut bus = bus.borrow_mut(); |
| 152 | bus.set_config(&self.config); | ||
| 158 | self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; | 153 | self.cs.set_low().map_err(SpiBusDeviceError::Cs)?; |
| 159 | let f_res = bus.write(words); | 154 | |
| 155 | let f_res = f(&mut bus); | ||
| 156 | |||
| 157 | // On failure, it's important to still flush and deassert CS. | ||
| 158 | let flush_res = bus.flush(); | ||
| 160 | let cs_res = self.cs.set_high(); | 159 | let cs_res = self.cs.set_high(); |
| 160 | |||
| 161 | let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; | 161 | let f_res = f_res.map_err(SpiBusDeviceError::Spi)?; |
| 162 | flush_res.map_err(SpiBusDeviceError::Spi)?; | ||
| 162 | cs_res.map_err(SpiBusDeviceError::Cs)?; | 163 | cs_res.map_err(SpiBusDeviceError::Cs)?; |
| 163 | Ok(f_res) | 164 | Ok(f_res) |
| 164 | }) | 165 | }) |
