diff options
| author | Til Blechschmidt <[email protected]> | 2022-03-02 22:45:38 +0100 |
|---|---|---|
| committer | Til Blechschmidt <[email protected]> | 2022-03-02 22:45:38 +0100 |
| commit | 3f2d9cfe0a643b1f1afcaef0fcb2cbbf305fd83d (patch) | |
| tree | 4af9d59399a6674eca331fcc9450e84f5a9fa1d0 /embassy-nrf | |
| parent | 2c402ecf1695974ae5474f828f062d06b2392295 (diff) | |
Change TWIM methods to copy slice if required and add non-copying variants
Diffstat (limited to 'embassy-nrf')
| -rw-r--r-- | embassy-nrf/src/twim.rs | 127 |
1 files changed, 86 insertions, 41 deletions
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index ed2844f79..675029a88 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -287,7 +287,12 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 287 | }) | 287 | }) |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | fn setup_write(&mut self, address: u8, buffer: &[u8], inten: bool) -> Result<(), Error> { | 290 | fn setup_write_from_ram( |
| 291 | &mut self, | ||
| 292 | address: u8, | ||
| 293 | buffer: &[u8], | ||
| 294 | inten: bool, | ||
| 295 | ) -> Result<(), Error> { | ||
| 291 | let r = T::regs(); | 296 | let r = T::regs(); |
| 292 | 297 | ||
| 293 | compiler_fence(SeqCst); | 298 | compiler_fence(SeqCst); |
| @@ -342,7 +347,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 342 | Ok(()) | 347 | Ok(()) |
| 343 | } | 348 | } |
| 344 | 349 | ||
| 345 | fn setup_write_read( | 350 | fn setup_write_read_from_ram( |
| 346 | &mut self, | 351 | &mut self, |
| 347 | address: u8, | 352 | address: u8, |
| 348 | wr_buffer: &[u8], | 353 | wr_buffer: &[u8], |
| @@ -382,6 +387,43 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 382 | Ok(()) | 387 | Ok(()) |
| 383 | } | 388 | } |
| 384 | 389 | ||
| 390 | fn setup_write_read( | ||
| 391 | &mut self, | ||
| 392 | address: u8, | ||
| 393 | wr_buffer: &[u8], | ||
| 394 | rd_buffer: &mut [u8], | ||
| 395 | inten: bool, | ||
| 396 | ) -> Result<(), Error> { | ||
| 397 | match self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, inten) { | ||
| 398 | Ok(_) => Ok(()), | ||
| 399 | Err(Error::DMABufferNotInDataMemory) => { | ||
| 400 | trace!("Copying TWIM tx buffer into RAM for DMA"); | ||
| 401 | let mut tx_buf = [0u8; FORCE_COPY_BUFFER_SIZE]; | ||
| 402 | tx_buf[..wr_buffer.len()].copy_from_slice(wr_buffer); | ||
| 403 | self.setup_write_read_from_ram( | ||
| 404 | address, | ||
| 405 | &tx_buf[..wr_buffer.len()], | ||
| 406 | rd_buffer, | ||
| 407 | inten, | ||
| 408 | ) | ||
| 409 | } | ||
| 410 | Err(error) => Err(error), | ||
| 411 | } | ||
| 412 | } | ||
| 413 | |||
| 414 | fn setup_write(&mut self, address: u8, wr_buffer: &[u8], inten: bool) -> Result<(), Error> { | ||
| 415 | match self.setup_write_from_ram(address, wr_buffer, inten) { | ||
| 416 | Ok(_) => Ok(()), | ||
| 417 | Err(Error::DMABufferNotInDataMemory) => { | ||
| 418 | trace!("Copying TWIM tx buffer into RAM for DMA"); | ||
| 419 | let mut tx_buf = [0u8; FORCE_COPY_BUFFER_SIZE]; | ||
| 420 | tx_buf[..wr_buffer.len()].copy_from_slice(wr_buffer); | ||
| 421 | self.setup_write_from_ram(address, &tx_buf[..wr_buffer.len()], inten) | ||
| 422 | } | ||
| 423 | Err(error) => Err(error), | ||
| 424 | } | ||
| 425 | } | ||
| 426 | |||
| 385 | /// Write to an I2C slave. | 427 | /// Write to an I2C slave. |
| 386 | /// | 428 | /// |
| 387 | /// The buffer must have a length of at most 255 bytes on the nRF52832 | 429 | /// The buffer must have a length of at most 255 bytes on the nRF52832 |
| @@ -395,6 +437,15 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 395 | Ok(()) | 437 | Ok(()) |
| 396 | } | 438 | } |
| 397 | 439 | ||
| 440 | pub fn blocking_write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { | ||
| 441 | self.setup_write_from_ram(address, buffer, false)?; | ||
| 442 | self.blocking_wait(); | ||
| 443 | compiler_fence(SeqCst); | ||
| 444 | self.check_errorsrc()?; | ||
| 445 | self.check_tx(buffer.len())?; | ||
| 446 | Ok(()) | ||
| 447 | } | ||
| 448 | |||
| 398 | /// Read from an I2C slave. | 449 | /// Read from an I2C slave. |
| 399 | /// | 450 | /// |
| 400 | /// The buffer must have a length of at most 255 bytes on the nRF52832 | 451 | /// The buffer must have a length of at most 255 bytes on the nRF52832 |
| @@ -428,45 +479,19 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 428 | Ok(()) | 479 | Ok(()) |
| 429 | } | 480 | } |
| 430 | 481 | ||
| 431 | /// Copy data into RAM and write to an I2C slave. | 482 | pub fn blocking_write_read_from_ram( |
| 432 | /// | ||
| 433 | /// The write buffer must have a length of at most 255 bytes on the nRF52832 | ||
| 434 | /// and at most 1024 bytes on the nRF52840. | ||
| 435 | pub fn blocking_copy_write(&mut self, address: u8, wr_buffer: &[u8]) -> Result<(), Error> { | ||
| 436 | if wr_buffer.len() > FORCE_COPY_BUFFER_SIZE { | ||
| 437 | return Err(Error::TxBufferTooLong); | ||
| 438 | } | ||
| 439 | |||
| 440 | // Copy to RAM | ||
| 441 | let wr_ram_buffer = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()]; | ||
| 442 | wr_ram_buffer.copy_from_slice(wr_buffer); | ||
| 443 | |||
| 444 | self.blocking_write(address, wr_ram_buffer) | ||
| 445 | } | ||
| 446 | |||
| 447 | /// Copy data into RAM and write to an I2C slave, then read data from the slave without | ||
| 448 | /// triggering a stop condition between the two. | ||
| 449 | /// | ||
| 450 | /// The write buffer must have a length of at most 255 bytes on the nRF52832 | ||
| 451 | /// and at most 1024 bytes on the nRF52840. | ||
| 452 | /// | ||
| 453 | /// The read buffer must have a length of at most 255 bytes on the nRF52832 | ||
| 454 | /// and at most 65535 bytes on the nRF52840. | ||
| 455 | pub fn blocking_copy_write_read( | ||
| 456 | &mut self, | 483 | &mut self, |
| 457 | address: u8, | 484 | address: u8, |
| 458 | wr_buffer: &[u8], | 485 | wr_buffer: &[u8], |
| 459 | rd_buffer: &mut [u8], | 486 | rd_buffer: &mut [u8], |
| 460 | ) -> Result<(), Error> { | 487 | ) -> Result<(), Error> { |
| 461 | if wr_buffer.len() > FORCE_COPY_BUFFER_SIZE { | 488 | self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, false)?; |
| 462 | return Err(Error::TxBufferTooLong); | 489 | self.blocking_wait(); |
| 463 | } | 490 | compiler_fence(SeqCst); |
| 464 | 491 | self.check_errorsrc()?; | |
| 465 | // Copy to RAM | 492 | self.check_tx(wr_buffer.len())?; |
| 466 | let wr_ram_buffer = &mut [0; FORCE_COPY_BUFFER_SIZE][..wr_buffer.len()]; | 493 | self.check_rx(rd_buffer.len())?; |
| 467 | wr_ram_buffer.copy_from_slice(wr_buffer); | 494 | Ok(()) |
| 468 | |||
| 469 | self.blocking_write_read(address, wr_ram_buffer, rd_buffer) | ||
| 470 | } | 495 | } |
| 471 | 496 | ||
| 472 | pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { | 497 | pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error> { |
| @@ -487,6 +512,15 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 487 | Ok(()) | 512 | Ok(()) |
| 488 | } | 513 | } |
| 489 | 514 | ||
| 515 | pub async fn write_from_ram(&mut self, address: u8, buffer: &[u8]) -> Result<(), Error> { | ||
| 516 | self.setup_write_from_ram(address, buffer, true)?; | ||
| 517 | self.async_wait().await; | ||
| 518 | compiler_fence(SeqCst); | ||
| 519 | self.check_errorsrc()?; | ||
| 520 | self.check_tx(buffer.len())?; | ||
| 521 | Ok(()) | ||
| 522 | } | ||
| 523 | |||
| 490 | pub async fn write_read( | 524 | pub async fn write_read( |
| 491 | &mut self, | 525 | &mut self, |
| 492 | address: u8, | 526 | address: u8, |
| @@ -501,6 +535,21 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 501 | self.check_rx(rd_buffer.len())?; | 535 | self.check_rx(rd_buffer.len())?; |
| 502 | Ok(()) | 536 | Ok(()) |
| 503 | } | 537 | } |
| 538 | |||
| 539 | pub async fn write_read_from_ram( | ||
| 540 | &mut self, | ||
| 541 | address: u8, | ||
| 542 | wr_buffer: &[u8], | ||
| 543 | rd_buffer: &mut [u8], | ||
| 544 | ) -> Result<(), Error> { | ||
| 545 | self.setup_write_read_from_ram(address, wr_buffer, rd_buffer, true)?; | ||
| 546 | self.async_wait().await; | ||
| 547 | compiler_fence(SeqCst); | ||
| 548 | self.check_errorsrc()?; | ||
| 549 | self.check_tx(wr_buffer.len())?; | ||
| 550 | self.check_rx(rd_buffer.len())?; | ||
| 551 | Ok(()) | ||
| 552 | } | ||
| 504 | } | 553 | } |
| 505 | 554 | ||
| 506 | impl<'a, T: Instance> Drop for Twim<'a, T> { | 555 | impl<'a, T: Instance> Drop for Twim<'a, T> { |
| @@ -601,11 +650,7 @@ mod eh02 { | |||
| 601 | bytes: &'w [u8], | 650 | bytes: &'w [u8], |
| 602 | buffer: &'w mut [u8], | 651 | buffer: &'w mut [u8], |
| 603 | ) -> Result<(), Error> { | 652 | ) -> Result<(), Error> { |
| 604 | if slice_in_ram(bytes) { | 653 | self.blocking_write_read(addr, bytes, buffer) |
| 605 | self.blocking_write_read(addr, bytes, buffer) | ||
| 606 | } else { | ||
| 607 | self.blocking_copy_write_read(addr, bytes, buffer) | ||
| 608 | } | ||
| 609 | } | 654 | } |
| 610 | } | 655 | } |
| 611 | } | 656 | } |
