summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <dirbaio@dirbaio.net>2022-06-07 14:52:45 +0200
committerDario Nieuwenhuis <dirbaio@dirbaio.net>2022-06-07 14:52:45 +0200
commit2be36122c7986a31da8c33a39d6c2878bf6f5919 (patch)
tree6dc2f4bb547c2b11f6becaaeb9740c663888952a
parentc212f30be0f680ea5ba5950371062e19678454b6 (diff)
downloadembassy-2be36122c7986a31da8c33a39d6c2878bf6f5919.zip
nrf/twim: allow zero length transfers.
-rw-r--r--embassy-nrf/src/twim.rs24
1 files changed, 14 insertions, 10 deletions
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index bb943c2c..510266c9 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -60,8 +60,6 @@ impl Default for Config {
pub enum Error {
TxBufferTooLong,
RxBufferTooLong,
- TxBufferZeroLength,
- RxBufferZeroLength,
Transmit,
Receive,
DMABufferNotInDataMemory,
@@ -159,9 +157,6 @@ impl<'d, T: Instance> Twim<'d, T> {
unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> {
slice_in_ram_or(buffer, Error::DMABufferNotInDataMemory)?;
- if buffer.len() == 0 {
- return Err(Error::TxBufferZeroLength);
- }
if buffer.len() > EASY_DMA_SIZE {
return Err(Error::TxBufferTooLong);
}
@@ -193,9 +188,6 @@ impl<'d, T: Instance> Twim<'d, T> {
// NOTE: RAM slice check is not necessary, as a mutable
// slice can only be built from data located in RAM.
- if buffer.len() == 0 {
- return Err(Error::RxBufferZeroLength);
- }
if buffer.len() > EASY_DMA_SIZE {
return Err(Error::RxBufferTooLong);
}
@@ -357,6 +349,10 @@ impl<'d, T: Instance> Twim<'d, T> {
// Start write operation.
r.shorts.write(|w| w.lasttx_stop().enabled());
r.tasks_starttx.write(|w| unsafe { w.bits(1) });
+ if buffer.len() == 0 {
+ // With a zero-length buffer, LASTTX doesn't fire (because there's no last byte!), so do the STOP ourselves.
+ r.tasks_stop.write(|w| unsafe { w.bits(1) });
+ }
Ok(())
}
@@ -384,6 +380,10 @@ impl<'d, T: Instance> Twim<'d, T> {
// Start read operation.
r.shorts.write(|w| w.lastrx_stop().enabled());
r.tasks_startrx.write(|w| unsafe { w.bits(1) });
+ if buffer.len() == 0 {
+ // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STOP ourselves.
+ r.tasks_stop.write(|w| unsafe { w.bits(1) });
+ }
Ok(())
}
@@ -424,6 +424,12 @@ impl<'d, T: Instance> Twim<'d, T> {
w
});
r.tasks_starttx.write(|w| unsafe { w.bits(1) });
+ if wr_buffer.len() == 0 && rd_buffer.len() == 0 {
+ // With a zero-length buffer, LASTRX/LASTTX doesn't fire (because there's no last byte!), so do the STOP ourselves.
+ // TODO handle when only one of the buffers is zero length
+ r.tasks_stop.write(|w| unsafe { w.bits(1) });
+ }
+
Ok(())
}
@@ -800,8 +806,6 @@ mod eh1 {
match *self {
Self::TxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other,
- Self::TxBufferZeroLength => embedded_hal_1::i2c::ErrorKind::Other,
- Self::RxBufferZeroLength => embedded_hal_1::i2c::ErrorKind::Other,
Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other,
Self::Receive => embedded_hal_1::i2c::ErrorKind::Other,
Self::DMABufferNotInDataMemory => embedded_hal_1::i2c::ErrorKind::Other,