aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkalkyl <[email protected]>2022-11-14 11:22:14 +0100
committerkalkyl <[email protected]>2022-11-14 11:22:14 +0100
commit43c1afb6a6b31a60f43b2faf8ca93bf5129e4d68 (patch)
treeb085efe956c9d01a95e589dff445587aea20cdc3
parenteba42cb5f4c4dc1be54c27729325e982d85fc8b0 (diff)
Return number of bytes written, add address match getter
-rw-r--r--embassy-nrf/src/twis.rs141
-rw-r--r--examples/nrf/src/bin/twis.rs2
2 files changed, 77 insertions, 66 deletions
diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs
index 8c9cb54ea..769522877 100644
--- a/embassy-nrf/src/twis.rs
+++ b/embassy-nrf/src/twis.rs
@@ -24,8 +24,8 @@ use crate::{gpio, pac, Peripheral};
24 24
25#[non_exhaustive] 25#[non_exhaustive]
26pub struct Config { 26pub struct Config {
27 pub addr0: u8, 27 pub address0: u8,
28 pub addr1: Option<u8>, 28 pub address1: Option<u8>,
29 pub orc: u8, 29 pub orc: u8,
30 pub sda_high_drive: bool, 30 pub sda_high_drive: bool,
31 pub sda_pullup: bool, 31 pub sda_pullup: bool,
@@ -36,8 +36,8 @@ pub struct Config {
36impl Default for Config { 36impl Default for Config {
37 fn default() -> Self { 37 fn default() -> Self {
38 Self { 38 Self {
39 addr0: 0x55, 39 address0: 0x55,
40 addr1: None, 40 address1: None,
41 orc: 0x00, 41 orc: 0x00,
42 scl_high_drive: false, 42 scl_high_drive: false,
43 sda_pullup: false, 43 sda_pullup: false,
@@ -134,10 +134,10 @@ impl<'d, T: Instance> Twis<'d, T> {
134 r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); 134 r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) });
135 135
136 // Set address 136 // Set address
137 r.address[0].write(|w| unsafe { w.address().bits(config.addr0) }); 137 r.address[0].write(|w| unsafe { w.address().bits(config.address0) });
138 r.config.modify(|_r, w| w.address0().enabled()); 138 r.config.modify(|_r, w| w.address0().enabled());
139 if let Some(addr1) = config.addr1 { 139 if let Some(address1) = config.address1 {
140 r.address[1].write(|w| unsafe { w.address().bits(addr1) }); 140 r.address[1].write(|w| unsafe { w.address().bits(address1) });
141 r.config.modify(|_r, w| w.address1().enabled()); 141 r.config.modify(|_r, w| w.address1().enabled());
142 } 142 }
143 143
@@ -242,7 +242,13 @@ impl<'d, T: Instance> Twis<'d, T> {
242 .write(|w| w.overflow().bit(true).overread().bit(true).dnack().bit(true)); 242 .write(|w| w.overflow().bit(true).overread().bit(true).dnack().bit(true));
243 } 243 }
244 244
245 /// Wait for stop or error 245 /// Returns matched address for latest command.
246 pub fn address_match(&self) -> u8 {
247 let r = T::regs();
248 r.address[r.match_.read().bits() as usize].read().address().bits()
249 }
250
251 /// Wait for read, write, stop or error
246 fn blocking_listen_wait(&mut self) -> Result<Status, Error> { 252 fn blocking_listen_wait(&mut self) -> Result<Status, Error> {
247 let r = T::regs(); 253 let r = T::regs();
248 loop { 254 loop {
@@ -267,7 +273,7 @@ impl<'d, T: Instance> Twis<'d, T> {
267 } 273 }
268 } 274 }
269 275
270 /// Wait for stop or error 276 /// Wait for stop, repeated start or error
271 fn blocking_listen_wait_end(&mut self, status: Status) -> Result<Command, Error> { 277 fn blocking_listen_wait_end(&mut self, status: Status) -> Result<Command, Error> {
272 let r = T::regs(); 278 let r = T::regs();
273 loop { 279 loop {
@@ -294,7 +300,7 @@ impl<'d, T: Instance> Twis<'d, T> {
294 } 300 }
295 301
296 /// Wait for stop or error 302 /// Wait for stop or error
297 fn blocking_wait(&mut self) -> Result<(), Error> { 303 fn blocking_wait(&mut self) -> Result<usize, Error> {
298 let r = T::regs(); 304 let r = T::regs();
299 loop { 305 loop {
300 // stop if an error occured 306 // stop if an error occured
@@ -311,12 +317,42 @@ impl<'d, T: Instance> Twis<'d, T> {
311 } 317 }
312 } else if r.events_stopped.read().bits() != 0 { 318 } else if r.events_stopped.read().bits() != 0 {
313 r.events_stopped.reset(); 319 r.events_stopped.reset();
314 return Ok(()); 320 let n = r.txd.amount.read().bits() as usize;
321 return Ok(n);
315 } 322 }
316 } 323 }
317 } 324 }
318 325
319 /// Wait for stop or error 326 /// Wait for stop or error with timeout
327 #[cfg(feature = "time")]
328 fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<usize, Error> {
329 let r = T::regs();
330 let deadline = Instant::now() + timeout;
331 loop {
332 // stop if an error occured
333 if r.events_error.read().bits() != 0 {
334 r.events_error.reset();
335 r.tasks_stop.write(|w| unsafe { w.bits(1) });
336 let errorsrc = r.errorsrc.read();
337 if errorsrc.overread().is_detected() {
338 return Err(Error::OverRead);
339 } else if errorsrc.dnack().is_received() {
340 return Err(Error::DataNack);
341 } else {
342 return Err(Error::Bus);
343 }
344 } else if r.events_stopped.read().bits() != 0 {
345 r.events_stopped.reset();
346 let n = r.txd.amount.read().bits() as usize;
347 return Ok(n);
348 } else if Instant::now() > deadline {
349 r.tasks_stop.write(|w| unsafe { w.bits(1) });
350 return Err(Error::Timeout);
351 }
352 }
353 }
354
355 /// Wait for read, write, stop or error with timeout
320 #[cfg(feature = "time")] 356 #[cfg(feature = "time")]
321 fn blocking_listen_wait_timeout(&mut self, timeout: Duration) -> Result<Status, Error> { 357 fn blocking_listen_wait_timeout(&mut self, timeout: Duration) -> Result<Status, Error> {
322 let r = T::regs(); 358 let r = T::regs();
@@ -347,7 +383,7 @@ impl<'d, T: Instance> Twis<'d, T> {
347 } 383 }
348 } 384 }
349 385
350 /// Wait for stop or error 386 /// Wait for stop, repeated start or error with timeout
351 #[cfg(feature = "time")] 387 #[cfg(feature = "time")]
352 fn blocking_listen_wait_end_timeout(&mut self, status: Status, timeout: Duration) -> Result<Command, Error> { 388 fn blocking_listen_wait_end_timeout(&mut self, status: Status, timeout: Duration) -> Result<Command, Error> {
353 let r = T::regs(); 389 let r = T::regs();
@@ -379,35 +415,7 @@ impl<'d, T: Instance> Twis<'d, T> {
379 } 415 }
380 416
381 /// Wait for stop or error 417 /// Wait for stop or error
382 #[cfg(feature = "time")] 418 fn async_wait(&mut self) -> impl Future<Output = Result<usize, Error>> {
383 fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<(), Error> {
384 let r = T::regs();
385 let deadline = Instant::now() + timeout;
386 loop {
387 // stop if an error occured
388 if r.events_error.read().bits() != 0 {
389 r.events_error.reset();
390 r.tasks_stop.write(|w| unsafe { w.bits(1) });
391 let errorsrc = r.errorsrc.read();
392 if errorsrc.overread().is_detected() {
393 return Err(Error::OverRead);
394 } else if errorsrc.dnack().is_received() {
395 return Err(Error::DataNack);
396 } else {
397 return Err(Error::Bus);
398 }
399 } else if r.events_stopped.read().bits() != 0 {
400 r.events_stopped.reset();
401 return Ok(());
402 } else if Instant::now() > deadline {
403 r.tasks_stop.write(|w| unsafe { w.bits(1) });
404 return Err(Error::Timeout);
405 }
406 }
407 }
408
409 /// Wait for stop or error
410 fn async_wait(&mut self) -> impl Future<Output = Result<(), Error>> {
411 poll_fn(move |cx| { 419 poll_fn(move |cx| {
412 let r = T::regs(); 420 let r = T::regs();
413 let s = T::state(); 421 let s = T::state();
@@ -428,7 +436,8 @@ impl<'d, T: Instance> Twis<'d, T> {
428 } 436 }
429 } else if r.events_stopped.read().bits() != 0 { 437 } else if r.events_stopped.read().bits() != 0 {
430 r.events_stopped.reset(); 438 r.events_stopped.reset();
431 return Poll::Ready(Ok(())); 439 let n = r.txd.amount.read().bits() as usize;
440 return Poll::Ready(Ok(n));
432 } 441 }
433 442
434 Poll::Pending 443 Poll::Pending
@@ -462,7 +471,7 @@ impl<'d, T: Instance> Twis<'d, T> {
462 }) 471 })
463 } 472 }
464 473
465 /// Wait for stop or error 474 /// Wait for stop, repeated start or error
466 fn async_listen_wait_end(&mut self, status: Status) -> impl Future<Output = Result<Command, Error>> { 475 fn async_listen_wait_end(&mut self, status: Status) -> impl Future<Output = Result<Command, Error>> {
467 poll_fn(move |cx| { 476 poll_fn(move |cx| {
468 let r = T::regs(); 477 let r = T::regs();
@@ -595,25 +604,23 @@ impl<'d, T: Instance> Twis<'d, T> {
595 } 604 }
596 605
597 /// Write to an I2C master. 606 /// Write to an I2C master.
598 /// 607 /// Returns the number of bytes written.
599 /// The buffer must have a length of at most 255 bytes on the nRF52832 608 /// The buffer must have a length of at most 255 bytes on the nRF52832
600 /// and at most 65535 bytes on the nRF52840. 609 /// and at most 65535 bytes on the nRF52840.
601 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { 610 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<usize, Error> {
602 self.setup_write(buffer, false)?; 611 self.setup_write(buffer, false)?;
603 self.blocking_wait()?; 612 self.blocking_wait()
604 Ok(())
605 } 613 }
606 614
607 /// Same as [`blocking_write`](Twis::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. 615 /// Same as [`blocking_write`](Twis::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
608 pub fn blocking_write_from_ram(&mut self, buffer: &[u8]) -> Result<(), Error> { 616 pub fn blocking_write_from_ram(&mut self, buffer: &[u8]) -> Result<usize, Error> {
609 self.setup_write_from_ram(buffer, false)?; 617 self.setup_write_from_ram(buffer, false)?;
610 self.blocking_wait()?; 618 self.blocking_wait()
611 Ok(())
612 } 619 }
613 620
614 // =========================================== 621 // ===========================================
615 622
616 /// Listen for commands from an I2C master. 623 /// Listen for commands from an I2C master with timeout.
617 /// 624 ///
618 /// The buffer must have a length of at most 255 bytes on the nRF52832 625 /// The buffer must have a length of at most 255 bytes on the nRF52832
619 /// and at most 65535 bytes on the nRF52840. 626 /// and at most 65535 bytes on the nRF52840.
@@ -630,25 +637,27 @@ impl<'d, T: Instance> Twis<'d, T> {
630 } 637 }
631 638
632 /// Write to an I2C master with timeout. 639 /// Write to an I2C master with timeout.
633 /// 640 /// Returns the number of bytes written.
634 /// See [`blocking_write`]. 641 /// See [`blocking_write`].
635 #[cfg(feature = "time")] 642 #[cfg(feature = "time")]
636 pub fn blocking_write_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<(), Error> { 643 pub fn blocking_write_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<usize, Error> {
637 self.setup_write(buffer, false)?; 644 self.setup_write(buffer, false)?;
638 self.blocking_wait_timeout(timeout)?; 645 self.blocking_wait_timeout(timeout)
639 Ok(())
640 } 646 }
641 647
642 /// Same as [`blocking_write`](Twis::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. 648 /// Same as [`blocking_write`](Twis::blocking_write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
643 #[cfg(feature = "time")] 649 #[cfg(feature = "time")]
644 pub fn blocking_write_from_ram_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<(), Error> { 650 pub fn blocking_write_from_ram_timeout(&mut self, buffer: &[u8], timeout: Duration) -> Result<usize, Error> {
645 self.setup_write_from_ram(buffer, false)?; 651 self.setup_write_from_ram(buffer, false)?;
646 self.blocking_wait_timeout(timeout)?; 652 self.blocking_wait_timeout(timeout)
647 Ok(())
648 } 653 }
649 654
650 // =========================================== 655 // ===========================================
651 656
657 /// Listen asynchronously for commands from an I2C master.
658 ///
659 /// The buffer must have a length of at most 255 bytes on the nRF52832
660 /// and at most 65535 bytes on the nRF52840.
652 pub async fn listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> { 661 pub async fn listen(&mut self, buffer: &mut [u8]) -> Result<Command, Error> {
653 self.setup_listen(buffer, true)?; 662 self.setup_listen(buffer, true)?;
654 let status = self.async_listen_wait().await?; 663 let status = self.async_listen_wait().await?;
@@ -660,17 +669,19 @@ impl<'d, T: Instance> Twis<'d, T> {
660 Ok(Command::Read) 669 Ok(Command::Read)
661 } 670 }
662 671
663 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 672 /// Async write to an I2C master.
673 /// Returns the number of bytes written.
674 /// The buffer must have a length of at most 255 bytes on the nRF52832
675 /// and at most 65535 bytes on the nRF52840.
676 pub async fn write(&mut self, buffer: &[u8]) -> Result<usize, Error> {
664 self.setup_write(buffer, true)?; 677 self.setup_write(buffer, true)?;
665 self.async_wait().await?; 678 self.async_wait().await
666 Ok(())
667 } 679 }
668 680
669 /// Same as [`write`](Twis::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more. 681 /// Same as [`write`](Twis::write) but will fail instead of copying data into RAM. Consult the module level documentation to learn more.
670 pub async fn write_from_ram(&mut self, buffer: &[u8]) -> Result<(), Error> { 682 pub async fn write_from_ram(&mut self, buffer: &[u8]) -> Result<usize, Error> {
671 self.setup_write_from_ram(buffer, true)?; 683 self.setup_write_from_ram(buffer, true)?;
672 self.async_wait().await?; 684 self.async_wait().await
673 Ok(())
674 } 685 }
675} 686}
676 687
diff --git a/examples/nrf/src/bin/twis.rs b/examples/nrf/src/bin/twis.rs
index f85173c08..a34bb2711 100644
--- a/examples/nrf/src/bin/twis.rs
+++ b/examples/nrf/src/bin/twis.rs
@@ -17,7 +17,7 @@ async fn main(_spawner: Spawner) {
17 let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); 17 let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
18 let mut config = twis::Config::default(); 18 let mut config = twis::Config::default();
19 // Set i2c address 19 // Set i2c address
20 config.addr0 = 0x55; 20 config.address0 = 0x55;
21 let mut i2c = Twis::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); 21 let mut i2c = Twis::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
22 22
23 info!("Listening..."); 23 info!("Listening...");