aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-01-13 20:00:33 +0100
committerDario Nieuwenhuis <[email protected]>2022-01-13 23:56:39 +0100
commita287fef687b47edc57e17131e3d663cd860ad471 (patch)
treef2d3b0b55d568eaee70f1714c485b3b0e77ecb18
parent7086642ce43de7c2fe476da94ec53ed6282087ec (diff)
nrf/spim: expose all functionality as inherent methods.
-rw-r--r--embassy-nrf/src/spim.rs65
-rw-r--r--examples/nrf/src/bin/spim.rs9
2 files changed, 47 insertions, 27 deletions
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index 8159cefe8..e767bc703 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -133,9 +133,7 @@ impl<'d, T: Instance> Spim<'d, T> {
133 133
134 // Set over-read character 134 // Set over-read character
135 let orc = config.orc; 135 let orc = config.orc;
136 r.orc.write(|w| 136 r.orc.write(|w| unsafe { w.orc().bits(orc) });
137 // The ORC field is 8 bits long, so any u8 is a valid value to write.
138 unsafe { w.orc().bits(orc) });
139 137
140 // Disable all events interrupts 138 // Disable all events interrupts
141 r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); 139 r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) });
@@ -159,14 +157,11 @@ impl<'d, T: Instance> Spim<'d, T> {
159 } 157 }
160 } 158 }
161 159
162 fn start_transfer(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> { 160 fn prepare(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
163 slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?; 161 slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?;
164 // NOTE: RAM slice check for rx is not necessary, as a mutable 162 // NOTE: RAM slice check for rx is not necessary, as a mutable
165 // slice can only be built from data located in RAM. 163 // slice can only be built from data located in RAM.
166 164
167 // Conservative compiler fence to prevent optimizations that do not
168 // take in to account actions by DMA. The fence has been placed here,
169 // before any DMA action has started.
170 compiler_fence(Ordering::SeqCst); 165 compiler_fence(Ordering::SeqCst);
171 166
172 let r = T::regs(); 167 let r = T::regs();
@@ -191,22 +186,19 @@ impl<'d, T: Instance> Spim<'d, T> {
191 Ok(()) 186 Ok(())
192 } 187 }
193 188
194 fn blocking_transfer(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> { 189 fn blocking_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
195 self.start_transfer(rx, tx)?; 190 self.prepare(rx, tx)?;
196 191
197 // Wait for 'end' event. 192 // Wait for 'end' event.
198 while T::regs().events_end.read().bits() == 0 {} 193 while T::regs().events_end.read().bits() == 0 {}
199 194
200 // Conservative compiler fence to prevent optimizations that do not
201 // take in to account actions by DMA. The fence has been placed here,
202 // after all possible DMA actions have completed.
203 compiler_fence(Ordering::SeqCst); 195 compiler_fence(Ordering::SeqCst);
204 196
205 Ok(()) 197 Ok(())
206 } 198 }
207 199
208 async fn async_transfer(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> { 200 async fn async_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
209 self.start_transfer(rx, tx)?; 201 self.prepare(rx, tx)?;
210 202
211 // Wait for 'end' event. 203 // Wait for 'end' event.
212 poll_fn(|cx| { 204 poll_fn(|cx| {
@@ -219,13 +211,42 @@ impl<'d, T: Instance> Spim<'d, T> {
219 }) 211 })
220 .await; 212 .await;
221 213
222 // Conservative compiler fence to prevent optimizations that do not
223 // take in to account actions by DMA. The fence has been placed here,
224 // after all possible DMA actions have completed.
225 compiler_fence(Ordering::SeqCst); 214 compiler_fence(Ordering::SeqCst);
226 215
227 Ok(()) 216 Ok(())
228 } 217 }
218
219 pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<(), Error> {
220 self.blocking_inner(data, &[])
221 }
222
223 pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> {
224 self.blocking_inner(read, write)
225 }
226
227 pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Error> {
228 self.blocking_inner(data, data)
229 }
230
231 pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> {
232 self.blocking_inner(&mut [], data)
233 }
234
235 pub async fn read(&mut self, data: &mut [u8]) -> Result<(), Error> {
236 self.async_inner(data, &[]).await
237 }
238
239 pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> {
240 self.async_inner(read, write).await
241 }
242
243 pub async fn transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Error> {
244 self.async_inner(data, data).await
245 }
246
247 pub async fn write(&mut self, data: &[u8]) -> Result<(), Error> {
248 self.async_inner(&mut [], data).await
249 }
229} 250}
230 251
231impl<'d, T: Instance> Drop for Spim<'d, T> { 252impl<'d, T: Instance> Drop for Spim<'d, T> {
@@ -257,7 +278,7 @@ impl<'d, T: Instance> Read<u8> for Spim<'d, T> {
257 = impl Future<Output = Result<(), Self::Error>> + 'a; 278 = impl Future<Output = Result<(), Self::Error>> + 'a;
258 279
259 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> { 280 fn read<'a>(&'a mut self, data: &'a mut [u8]) -> Self::ReadFuture<'a> {
260 self.read_write(data, &[]) 281 self.read(data)
261 } 282 }
262} 283}
263 284
@@ -268,7 +289,7 @@ impl<'d, T: Instance> Write<u8> for Spim<'d, T> {
268 = impl Future<Output = Result<(), Self::Error>> + 'a; 289 = impl Future<Output = Result<(), Self::Error>> + 'a;
269 290
270 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> { 291 fn write<'a>(&'a mut self, data: &'a [u8]) -> Self::WriteFuture<'a> {
271 self.read_write(&mut [], data) 292 self.write(data)
272 } 293 }
273} 294}
274 295
@@ -279,14 +300,14 @@ impl<'d, T: Instance> FullDuplex<u8> for Spim<'d, T> {
279 = impl Future<Output = Result<(), Self::Error>> + 'a; 300 = impl Future<Output = Result<(), Self::Error>> + 'a;
280 301
281 fn read_write<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::WriteReadFuture<'a> { 302 fn read_write<'a>(&'a mut self, rx: &'a mut [u8], tx: &'a [u8]) -> Self::WriteReadFuture<'a> {
282 self.async_transfer(rx, tx) 303 self.transfer(rx, tx)
283 } 304 }
284} 305}
285 306
286impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spim<'d, T> { 307impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spim<'d, T> {
287 type Error = Error; 308 type Error = Error;
288 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { 309 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
289 self.blocking_transfer(words, words)?; 310 self.blocking_transfer_in_place(words)?;
290 Ok(words) 311 Ok(words)
291 } 312 }
292} 313}
@@ -295,7 +316,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spim<'d, T> {
295 type Error = Error; 316 type Error = Error;
296 317
297 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 318 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
298 self.blocking_transfer(&mut [], words) 319 self.blocking_write(words)
299 } 320 }
300} 321}
301 322
diff --git a/examples/nrf/src/bin/spim.rs b/examples/nrf/src/bin/spim.rs
index fc31d140a..cda3baa26 100644
--- a/examples/nrf/src/bin/spim.rs
+++ b/examples/nrf/src/bin/spim.rs
@@ -9,7 +9,6 @@ use embassy::executor::Spawner;
9use embassy_nrf::gpio::{Level, Output, OutputDrive}; 9use embassy_nrf::gpio::{Level, Output, OutputDrive};
10use embassy_nrf::Peripherals; 10use embassy_nrf::Peripherals;
11use embassy_nrf::{interrupt, spim}; 11use embassy_nrf::{interrupt, spim};
12use embassy_traits::spi::FullDuplex;
13use example_common::*; 12use example_common::*;
14 13
15#[embassy::main] 14#[embassy::main]
@@ -31,7 +30,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
31 ncs.set_low(); 30 ncs.set_low();
32 cortex_m::asm::delay(5); 31 cortex_m::asm::delay(5);
33 let tx = [0xFF]; 32 let tx = [0xFF];
34 unwrap!(spim.read_write(&mut [], &tx).await); 33 unwrap!(spim.transfer(&mut [], &tx).await);
35 cortex_m::asm::delay(10); 34 cortex_m::asm::delay(10);
36 ncs.set_high(); 35 ncs.set_high();
37 36
@@ -44,7 +43,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
44 ncs.set_low(); 43 ncs.set_low();
45 cortex_m::asm::delay(5000); 44 cortex_m::asm::delay(5000);
46 let tx = [0b000_11101, 0]; 45 let tx = [0b000_11101, 0];
47 unwrap!(spim.read_write(&mut rx, &tx).await); 46 unwrap!(spim.transfer(&mut rx, &tx).await);
48 cortex_m::asm::delay(5000); 47 cortex_m::asm::delay(5000);
49 ncs.set_high(); 48 ncs.set_high();
50 info!("estat: {=[?]}", rx); 49 info!("estat: {=[?]}", rx);
@@ -54,7 +53,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
54 ncs.set_low(); 53 ncs.set_low();
55 cortex_m::asm::delay(5); 54 cortex_m::asm::delay(5);
56 let tx = [0b100_11111, 0b11]; 55 let tx = [0b100_11111, 0b11];
57 unwrap!(spim.read_write(&mut rx, &tx).await); 56 unwrap!(spim.transfer(&mut rx, &tx).await);
58 cortex_m::asm::delay(10); 57 cortex_m::asm::delay(10);
59 ncs.set_high(); 58 ncs.set_high();
60 59
@@ -63,7 +62,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
63 ncs.set_low(); 62 ncs.set_low();
64 cortex_m::asm::delay(5); 63 cortex_m::asm::delay(5);
65 let tx = [0b000_10010, 0]; 64 let tx = [0b000_10010, 0];
66 unwrap!(spim.read_write(&mut rx, &tx).await); 65 unwrap!(spim.transfer(&mut rx, &tx).await);
67 cortex_m::asm::delay(10); 66 cortex_m::asm::delay(10);
68 ncs.set_high(); 67 ncs.set_high();
69 68