diff options
| author | Henrik Alsér <[email protected]> | 2022-11-05 01:12:25 +0100 |
|---|---|---|
| committer | Henrik Alsér <[email protected]> | 2022-11-05 01:12:25 +0100 |
| commit | 7da18e194a8a9fef207803b96b16e7b7bc787ca7 (patch) | |
| tree | ad023aae5b9abd7f465714da79d931771b271c49 | |
| parent | a3e8a6bc3a706bc59b9d017699eaab93c1ba60d3 (diff) | |
Add status checks
| -rw-r--r-- | embassy-nrf/src/spis.rs | 69 | ||||
| -rw-r--r-- | examples/nrf/src/bin/spis.rs | 4 |
2 files changed, 44 insertions, 29 deletions
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index ab7986b89..71106b7df 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs | |||
| @@ -126,7 +126,7 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 126 | 126 | ||
| 127 | let r = T::regs(); | 127 | let r = T::regs(); |
| 128 | 128 | ||
| 129 | // Configure pins | 129 | // Configure pins. |
| 130 | sck.conf().write(|w| w.input().connect().drive().h0h1()); | 130 | sck.conf().write(|w| w.input().connect().drive().h0h1()); |
| 131 | cs.conf().write(|w| w.input().connect().drive().h0h1()); | 131 | cs.conf().write(|w| w.input().connect().drive().h0h1()); |
| 132 | if let Some(mosi) = &mosi { | 132 | if let Some(mosi) = &mosi { |
| @@ -151,10 +151,6 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 151 | } | 151 | } |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | if config.auto_acquire { | ||
| 155 | r.shorts.write(|w| w.end_acquire().bit(true)); | ||
| 156 | } | ||
| 157 | |||
| 158 | // Select pins. | 154 | // Select pins. |
| 159 | r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) }); | 155 | r.psel.sck.write(|w| unsafe { w.bits(sck.psel_bits()) }); |
| 160 | r.psel.csn.write(|w| unsafe { w.bits(cs.psel_bits()) }); | 156 | r.psel.csn.write(|w| unsafe { w.bits(cs.psel_bits()) }); |
| @@ -193,15 +189,20 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 193 | w | 189 | w |
| 194 | }); | 190 | }); |
| 195 | 191 | ||
| 196 | // Set over-read character | 192 | // Set over-read character. |
| 197 | let orc = config.orc; | 193 | let orc = config.orc; |
| 198 | r.orc.write(|w| unsafe { w.orc().bits(orc) }); | 194 | r.orc.write(|w| unsafe { w.orc().bits(orc) }); |
| 199 | 195 | ||
| 200 | // Set default character | 196 | // Set default character. |
| 201 | let def = config.def; | 197 | let def = config.def; |
| 202 | r.def.write(|w| unsafe { w.def().bits(def) }); | 198 | r.def.write(|w| unsafe { w.def().bits(def) }); |
| 203 | 199 | ||
| 204 | // Disable all events interrupts | 200 | // Configure auto-acquire on 'transfer end' event. |
| 201 | if config.auto_acquire { | ||
| 202 | r.shorts.write(|w| w.end_acquire().bit(true)); | ||
| 203 | } | ||
| 204 | |||
| 205 | // Disable all events interrupts. | ||
| 205 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); | 206 | r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); |
| 206 | 207 | ||
| 207 | irq.set_handler(Self::on_interrupt); | 208 | irq.set_handler(Self::on_interrupt); |
| @@ -245,11 +246,11 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 245 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); | 246 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); |
| 246 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 247 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); |
| 247 | 248 | ||
| 248 | // Reset and enable the end event | 249 | // Reset and enable the end event. |
| 249 | r.events_end.reset(); | 250 | r.events_end.reset(); |
| 250 | r.intenset.write(|w| w.end().set()); | 251 | r.intenset.write(|w| w.end().set()); |
| 251 | 252 | ||
| 252 | // Release the semaphore | 253 | // Release the semaphore. |
| 253 | r.tasks_release.write(|w| unsafe { w.bits(1) }); | 254 | r.tasks_release.write(|w| unsafe { w.bits(1) }); |
| 254 | 255 | ||
| 255 | Ok(()) | 256 | Ok(()) |
| @@ -287,12 +288,15 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 287 | let r = T::regs(); | 288 | let r = T::regs(); |
| 288 | let s = T::state(); | 289 | let s = T::state(); |
| 289 | 290 | ||
| 291 | // Clear status register. | ||
| 292 | r.status.write(|w| w.overflow().clear().overread().clear()); | ||
| 293 | |||
| 290 | if r.semstat.read().bits() != 1 { | 294 | if r.semstat.read().bits() != 1 { |
| 291 | // Reset and enable the acquire event | 295 | // Reset and enable the acquire event. |
| 292 | r.events_acquired.reset(); | 296 | r.events_acquired.reset(); |
| 293 | r.intenset.write(|w| w.acquired().set()); | 297 | r.intenset.write(|w| w.acquired().set()); |
| 294 | 298 | ||
| 295 | // Requests acquiring the SPIS semaphore | 299 | // Request acquiring the SPIS semaphore. |
| 296 | r.tasks_acquire.write(|w| unsafe { w.bits(1) }); | 300 | r.tasks_acquire.write(|w| unsafe { w.bits(1) }); |
| 297 | 301 | ||
| 298 | // Wait for 'acquire' event. | 302 | // Wait for 'acquire' event. |
| @@ -341,81 +345,92 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 341 | } | 345 | } |
| 342 | 346 | ||
| 343 | /// Reads data from the SPI bus without sending anything. Blocks until the buffer has been filled. | 347 | /// Reads data from the SPI bus without sending anything. Blocks until the buffer has been filled. |
| 344 | /// Returns number of bytes read | 348 | /// Returns number of bytes read. |
| 345 | pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<usize, Error> { | 349 | pub fn blocking_read(&mut self, data: &mut [u8]) -> Result<usize, Error> { |
| 346 | self.blocking_inner(data, &[]).map(|n| n.0) | 350 | self.blocking_inner(data, &[]).map(|n| n.0) |
| 347 | } | 351 | } |
| 348 | 352 | ||
| 349 | /// Simultaneously sends and receives data. Blocks until the transmission is completed. | 353 | /// Simultaneously sends and receives data. Blocks until the transmission is completed. |
| 350 | /// If necessary, the write buffer will be copied into RAM (see struct description for detail). | 354 | /// If necessary, the write buffer will be copied into RAM (see struct description for detail). |
| 351 | /// Returns number of bytes transferred `(n_rx, n_tx)` | 355 | /// Returns number of bytes transferred `(n_rx, n_tx)`. |
| 352 | pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(usize, usize), Error> { | 356 | pub fn blocking_transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(usize, usize), Error> { |
| 353 | self.blocking_inner(read, write) | 357 | self.blocking_inner(read, write) |
| 354 | } | 358 | } |
| 355 | 359 | ||
| 356 | /// Same as [`blocking_transfer`](Spis::blocking_transfer) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | 360 | /// Same as [`blocking_transfer`](Spis::blocking_transfer) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. |
| 357 | /// Returns number of bytes transferred `(n_rx, n_tx)` | 361 | /// Returns number of bytes transferred `(n_rx, n_tx)`. |
| 358 | pub fn blocking_transfer_from_ram(&mut self, read: &mut [u8], write: &[u8]) -> Result<(usize, usize), Error> { | 362 | pub fn blocking_transfer_from_ram(&mut self, read: &mut [u8], write: &[u8]) -> Result<(usize, usize), Error> { |
| 359 | self.blocking_inner(read, write) | 363 | self.blocking_inner(read, write) |
| 360 | } | 364 | } |
| 361 | 365 | ||
| 362 | /// Simultaneously sends and receives data. | 366 | /// Simultaneously sends and receives data. |
| 363 | /// Places the received data into the same buffer and blocks until the transmission is completed. | 367 | /// Places the received data into the same buffer and blocks until the transmission is completed. |
| 364 | /// Returns number of bytes transferred | 368 | /// Returns number of bytes transferred. |
| 365 | pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<usize, Error> { | 369 | pub fn blocking_transfer_in_place(&mut self, data: &mut [u8]) -> Result<usize, Error> { |
| 366 | self.blocking_inner_from_ram(data, data).map(|n| n.0) | 370 | self.blocking_inner_from_ram(data, data).map(|n| n.0) |
| 367 | } | 371 | } |
| 368 | 372 | ||
| 369 | /// Sends data, discarding any received data. Blocks until the transmission is completed. | 373 | /// Sends data, discarding any received data. Blocks until the transmission is completed. |
| 370 | /// If necessary, the write buffer will be copied into RAM (see struct description for detail). | 374 | /// If necessary, the write buffer will be copied into RAM (see struct description for detail). |
| 371 | /// Returns number of bytes written | 375 | /// Returns number of bytes written. |
| 372 | pub fn blocking_write(&mut self, data: &[u8]) -> Result<usize, Error> { | 376 | pub fn blocking_write(&mut self, data: &[u8]) -> Result<usize, Error> { |
| 373 | self.blocking_inner(&mut [], data).map(|n| n.1) | 377 | self.blocking_inner(&mut [], data).map(|n| n.1) |
| 374 | } | 378 | } |
| 375 | 379 | ||
| 376 | /// Same as [`blocking_write`](Spis::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | 380 | /// Same as [`blocking_write`](Spis::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. |
| 377 | /// Returns number of bytes written | 381 | /// Returns number of bytes written. |
| 378 | pub fn blocking_write_from_ram(&mut self, data: &[u8]) -> Result<usize, Error> { | 382 | pub fn blocking_write_from_ram(&mut self, data: &[u8]) -> Result<usize, Error> { |
| 379 | self.blocking_inner(&mut [], data).map(|n| n.1) | 383 | self.blocking_inner(&mut [], data).map(|n| n.1) |
| 380 | } | 384 | } |
| 381 | 385 | ||
| 382 | /// Reads data from the SPI bus without sending anything. | 386 | /// Reads data from the SPI bus without sending anything. |
| 383 | /// Returns number of bytes read | 387 | /// Returns number of bytes read. |
| 384 | pub async fn read(&mut self, data: &mut [u8]) -> Result<usize, Error> { | 388 | pub async fn read(&mut self, data: &mut [u8]) -> Result<usize, Error> { |
| 385 | self.async_inner(data, &[]).await.map(|n| n.0) | 389 | self.async_inner(data, &[]).await.map(|n| n.0) |
| 386 | } | 390 | } |
| 387 | 391 | ||
| 388 | /// Simultaneously sends and receives data. | 392 | /// Simultaneously sends and receives data. |
| 389 | /// If necessary, the write buffer will be copied into RAM (see struct description for detail). | 393 | /// If necessary, the write buffer will be copied into RAM (see struct description for detail). |
| 390 | /// Returns number of bytes transferred `(n_rx, n_tx)` | 394 | /// Returns number of bytes transferred `(n_rx, n_tx)`. |
| 391 | pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(usize, usize), Error> { | 395 | pub async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(usize, usize), Error> { |
| 392 | self.async_inner(read, write).await | 396 | self.async_inner(read, write).await |
| 393 | } | 397 | } |
| 394 | 398 | ||
| 395 | /// Same as [`transfer`](Spis::transfer) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | 399 | /// Same as [`transfer`](Spis::transfer) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. |
| 396 | /// Returns number of bytes transferred `(n_rx, n_tx)` | 400 | /// Returns number of bytes transferred `(n_rx, n_tx)`. |
| 397 | pub async fn transfer_from_ram(&mut self, read: &mut [u8], write: &[u8]) -> Result<(usize, usize), Error> { | 401 | pub async fn transfer_from_ram(&mut self, read: &mut [u8], write: &[u8]) -> Result<(usize, usize), Error> { |
| 398 | self.async_inner_from_ram(read, write).await | 402 | self.async_inner_from_ram(read, write).await |
| 399 | } | 403 | } |
| 400 | 404 | ||
| 401 | /// Simultaneously sends and receives data. Places the received data into the same buffer. | 405 | /// Simultaneously sends and receives data. Places the received data into the same buffer. |
| 402 | /// Returns number of bytes transferred | 406 | /// Returns number of bytes transferred. |
| 403 | pub async fn transfer_in_place(&mut self, data: &mut [u8]) -> Result<usize, Error> { | 407 | pub async fn transfer_in_place(&mut self, data: &mut [u8]) -> Result<usize, Error> { |
| 404 | self.async_inner_from_ram(data, data).await.map(|n| n.0) | 408 | self.async_inner_from_ram(data, data).await.map(|n| n.0) |
| 405 | } | 409 | } |
| 406 | 410 | ||
| 407 | /// Sends data, discarding any received data. | 411 | /// Sends data, discarding any received data. |
| 408 | /// If necessary, the write buffer will be copied into RAM (see struct description for detail). | 412 | /// If necessary, the write buffer will be copied into RAM (see struct description for detail). |
| 409 | /// Returns number of bytes written | 413 | /// Returns number of bytes written. |
| 410 | pub async fn write(&mut self, data: &[u8]) -> Result<usize, Error> { | 414 | pub async fn write(&mut self, data: &[u8]) -> Result<usize, Error> { |
| 411 | self.async_inner(&mut [], data).await.map(|n| n.1) | 415 | self.async_inner(&mut [], data).await.map(|n| n.1) |
| 412 | } | 416 | } |
| 413 | 417 | ||
| 414 | /// Same as [`write`](Spis::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. | 418 | /// Same as [`write`](Spis::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. |
| 415 | /// Returns number of bytes written | 419 | /// Returns number of bytes written. |
| 416 | pub async fn write_from_ram(&mut self, data: &[u8]) -> Result<usize, Error> { | 420 | pub async fn write_from_ram(&mut self, data: &[u8]) -> Result<usize, Error> { |
| 417 | self.async_inner_from_ram(&mut [], data).await.map(|n| n.1) | 421 | self.async_inner_from_ram(&mut [], data).await.map(|n| n.1) |
| 418 | } | 422 | } |
| 423 | |||
| 424 | /// Checks if last transaction overread. | ||
| 425 | pub fn is_overread(&mut self) -> bool { | ||
| 426 | T::regs().status.read().overread().is_present() | ||
| 427 | } | ||
| 428 | |||
| 429 | /// Checks if last transaction overflowed. | ||
| 430 | pub fn is_overflow(&mut self) -> bool { | ||
| 431 | T::regs().status.read().overflow().is_present() | ||
| 432 | } | ||
| 433 | |||
| 419 | } | 434 | } |
| 420 | 435 | ||
| 421 | impl<'d, T: Instance> Drop for Spis<'d, T> { | 436 | impl<'d, T: Instance> Drop for Spis<'d, T> { |
| @@ -516,15 +531,15 @@ impl<'d, T: Instance> SetConfig for Spis<'d, T> { | |||
| 516 | w | 531 | w |
| 517 | }); | 532 | }); |
| 518 | 533 | ||
| 519 | // Set over-read character | 534 | // Set over-read character. |
| 520 | let orc = config.orc; | 535 | let orc = config.orc; |
| 521 | r.orc.write(|w| unsafe { w.orc().bits(orc) }); | 536 | r.orc.write(|w| unsafe { w.orc().bits(orc) }); |
| 522 | 537 | ||
| 523 | // Set default character | 538 | // Set default character. |
| 524 | let def = config.def; | 539 | let def = config.def; |
| 525 | r.def.write(|w| unsafe { w.def().bits(def) }); | 540 | r.def.write(|w| unsafe { w.def().bits(def) }); |
| 526 | 541 | ||
| 527 | // Set auto acquire | 542 | // Configure auto-acquire on 'transfer end' event. |
| 528 | let auto_acquire = config.auto_acquire; | 543 | let auto_acquire = config.auto_acquire; |
| 529 | r.shorts.write(|w| w.end_acquire().bit(auto_acquire)); | 544 | r.shorts.write(|w| w.end_acquire().bit(auto_acquire)); |
| 530 | } | 545 | } |
diff --git a/examples/nrf/src/bin/spis.rs b/examples/nrf/src/bin/spis.rs index 181e08404..0fce23d31 100644 --- a/examples/nrf/src/bin/spis.rs +++ b/examples/nrf/src/bin/spis.rs | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | use defmt::info; | 5 | use defmt::info; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_nrf::interrupt; | 7 | use embassy_nrf::interrupt; |
| 8 | use embassy_nrf::spis::{self, Config}; | 8 | use embassy_nrf::spis::{Spis, Config}; |
| 9 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 10 | 10 | ||
| 11 | #[embassy_executor::main] | 11 | #[embassy_executor::main] |
| @@ -14,7 +14,7 @@ async fn main(_spawner: Spawner) { | |||
| 14 | info!("Running!"); | 14 | info!("Running!"); |
| 15 | 15 | ||
| 16 | let irq = interrupt::take!(SPIM2_SPIS2_SPI2); | 16 | let irq = interrupt::take!(SPIM2_SPIS2_SPI2); |
| 17 | let mut spis = spis::Spis::new(p.SPI2, irq, p.P0_31, p.P0_29, p.P0_28, p.P0_30, Config::default()); | 17 | let mut spis = Spis::new(p.SPI2, irq, p.P0_31, p.P0_29, p.P0_28, p.P0_30, Config::default()); |
| 18 | 18 | ||
| 19 | loop { | 19 | loop { |
| 20 | let mut buf = [0_u8; 64]; | 20 | let mut buf = [0_u8; 64]; |
