diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-06-07 12:54:09 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-06-07 12:54:09 +0000 |
| commit | bf09017032ea456043c6dddad4f9b6a2a24079b6 (patch) | |
| tree | 6dc2f4bb547c2b11f6becaaeb9740c663888952a | |
| parent | c212f30be0f680ea5ba5950371062e19678454b6 (diff) | |
| parent | 2be36122c7986a31da8c33a39d6c2878bf6f5919 (diff) | |
Merge #796
796: nrf/twim: allow zero length transfers. r=Dirbaio a=Dirbaio
bors r+
Co-authored-by: Dario Nieuwenhuis <[email protected]>
| -rw-r--r-- | embassy-nrf/src/twim.rs | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index bb943c2c7..510266c9a 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -60,8 +60,6 @@ impl Default for Config { | |||
| 60 | pub enum Error { | 60 | pub enum Error { |
| 61 | TxBufferTooLong, | 61 | TxBufferTooLong, |
| 62 | RxBufferTooLong, | 62 | RxBufferTooLong, |
| 63 | TxBufferZeroLength, | ||
| 64 | RxBufferZeroLength, | ||
| 65 | Transmit, | 63 | Transmit, |
| 66 | Receive, | 64 | Receive, |
| 67 | DMABufferNotInDataMemory, | 65 | DMABufferNotInDataMemory, |
| @@ -159,9 +157,6 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 159 | unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { | 157 | unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> { |
| 160 | slice_in_ram_or(buffer, Error::DMABufferNotInDataMemory)?; | 158 | slice_in_ram_or(buffer, Error::DMABufferNotInDataMemory)?; |
| 161 | 159 | ||
| 162 | if buffer.len() == 0 { | ||
| 163 | return Err(Error::TxBufferZeroLength); | ||
| 164 | } | ||
| 165 | if buffer.len() > EASY_DMA_SIZE { | 160 | if buffer.len() > EASY_DMA_SIZE { |
| 166 | return Err(Error::TxBufferTooLong); | 161 | return Err(Error::TxBufferTooLong); |
| 167 | } | 162 | } |
| @@ -193,9 +188,6 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 193 | // NOTE: RAM slice check is not necessary, as a mutable | 188 | // NOTE: RAM slice check is not necessary, as a mutable |
| 194 | // slice can only be built from data located in RAM. | 189 | // slice can only be built from data located in RAM. |
| 195 | 190 | ||
| 196 | if buffer.len() == 0 { | ||
| 197 | return Err(Error::RxBufferZeroLength); | ||
| 198 | } | ||
| 199 | if buffer.len() > EASY_DMA_SIZE { | 191 | if buffer.len() > EASY_DMA_SIZE { |
| 200 | return Err(Error::RxBufferTooLong); | 192 | return Err(Error::RxBufferTooLong); |
| 201 | } | 193 | } |
| @@ -357,6 +349,10 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 357 | // Start write operation. | 349 | // Start write operation. |
| 358 | r.shorts.write(|w| w.lasttx_stop().enabled()); | 350 | r.shorts.write(|w| w.lasttx_stop().enabled()); |
| 359 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 351 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); |
| 352 | if buffer.len() == 0 { | ||
| 353 | // With a zero-length buffer, LASTTX doesn't fire (because there's no last byte!), so do the STOP ourselves. | ||
| 354 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | ||
| 355 | } | ||
| 360 | Ok(()) | 356 | Ok(()) |
| 361 | } | 357 | } |
| 362 | 358 | ||
| @@ -384,6 +380,10 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 384 | // Start read operation. | 380 | // Start read operation. |
| 385 | r.shorts.write(|w| w.lastrx_stop().enabled()); | 381 | r.shorts.write(|w| w.lastrx_stop().enabled()); |
| 386 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 382 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); |
| 383 | if buffer.len() == 0 { | ||
| 384 | // With a zero-length buffer, LASTRX doesn't fire (because there's no last byte!), so do the STOP ourselves. | ||
| 385 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | ||
| 386 | } | ||
| 387 | Ok(()) | 387 | Ok(()) |
| 388 | } | 388 | } |
| 389 | 389 | ||
| @@ -424,6 +424,12 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 424 | w | 424 | w |
| 425 | }); | 425 | }); |
| 426 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 426 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); |
| 427 | if wr_buffer.len() == 0 && rd_buffer.len() == 0 { | ||
| 428 | // With a zero-length buffer, LASTRX/LASTTX doesn't fire (because there's no last byte!), so do the STOP ourselves. | ||
| 429 | // TODO handle when only one of the buffers is zero length | ||
| 430 | r.tasks_stop.write(|w| unsafe { w.bits(1) }); | ||
| 431 | } | ||
| 432 | |||
| 427 | Ok(()) | 433 | Ok(()) |
| 428 | } | 434 | } |
| 429 | 435 | ||
| @@ -800,8 +806,6 @@ mod eh1 { | |||
| 800 | match *self { | 806 | match *self { |
| 801 | Self::TxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other, | 807 | Self::TxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other, |
| 802 | Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other, | 808 | Self::RxBufferTooLong => embedded_hal_1::i2c::ErrorKind::Other, |
| 803 | Self::TxBufferZeroLength => embedded_hal_1::i2c::ErrorKind::Other, | ||
| 804 | Self::RxBufferZeroLength => embedded_hal_1::i2c::ErrorKind::Other, | ||
| 805 | Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other, | 809 | Self::Transmit => embedded_hal_1::i2c::ErrorKind::Other, |
| 806 | Self::Receive => embedded_hal_1::i2c::ErrorKind::Other, | 810 | Self::Receive => embedded_hal_1::i2c::ErrorKind::Other, |
| 807 | Self::DMABufferNotInDataMemory => embedded_hal_1::i2c::ErrorKind::Other, | 811 | Self::DMABufferNotInDataMemory => embedded_hal_1::i2c::ErrorKind::Other, |
