diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-01-25 16:19:46 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-01-25 16:19:46 +0000 |
| commit | cd36e3f7332d08865e670ca5b515d1c6efa1bf85 (patch) | |
| tree | 138f01bc3f400bdf907712b8fd489adf4d2e432a | |
| parent | a950266a7501c5534ebd7c477d42d29ac25cf472 (diff) | |
| parent | 3fc54236ea18a5ade403fe4a2c85906dbcf727b4 (diff) | |
Merge #589
589: stm32/i2c: allow empty writes r=Dirbaio a=darkwater
The Senseair Sunrise CO2 sensor expects a wake-up packet in the form of (START, address, STOP), which looks like a `write(addr, &[])`, but this assertion prevents sending that.
I'm not sure why the assertion is there. Sending empty packets works fine in my limited testing, at least.
Co-authored-by: Sam Lakerveld <[email protected]>
| -rw-r--r-- | embassy-stm32/src/dma/mod.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v2.rs | 30 |
2 files changed, 26 insertions, 8 deletions
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index b7067a9c4..3b22faca7 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs | |||
| @@ -130,7 +130,7 @@ mod transfers { | |||
| 130 | reg_addr: *mut W, | 130 | reg_addr: *mut W, |
| 131 | buf: &'a mut [W], | 131 | buf: &'a mut [W], |
| 132 | ) -> impl Future<Output = ()> + 'a { | 132 | ) -> impl Future<Output = ()> + 'a { |
| 133 | assert!(buf.len() <= 0xFFFF); | 133 | assert!(buf.len() > 0 && buf.len() <= 0xFFFF); |
| 134 | unborrow!(channel); | 134 | unborrow!(channel); |
| 135 | 135 | ||
| 136 | unsafe { channel.start_read::<W>(request, reg_addr, buf) }; | 136 | unsafe { channel.start_read::<W>(request, reg_addr, buf) }; |
| @@ -145,7 +145,7 @@ mod transfers { | |||
| 145 | buf: &'a [W], | 145 | buf: &'a [W], |
| 146 | reg_addr: *mut W, | 146 | reg_addr: *mut W, |
| 147 | ) -> impl Future<Output = ()> + 'a { | 147 | ) -> impl Future<Output = ()> + 'a { |
| 148 | assert!(buf.len() <= 0xFFFF); | 148 | assert!(buf.len() > 0 && buf.len() <= 0xFFFF); |
| 149 | unborrow!(channel); | 149 | unborrow!(channel); |
| 150 | 150 | ||
| 151 | unsafe { channel.start_write::<W>(request, buf, reg_addr) }; | 151 | unsafe { channel.start_write::<W>(request, buf, reg_addr) }; |
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index af04dc061..5b0e5fce2 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -139,7 +139,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | unsafe fn master_read(address: u8, length: usize, stop: Stop, reload: bool, restart: bool) { | 141 | unsafe fn master_read(address: u8, length: usize, stop: Stop, reload: bool, restart: bool) { |
| 142 | assert!(length < 256 && length > 0); | 142 | assert!(length < 256); |
| 143 | 143 | ||
| 144 | if !restart { | 144 | if !restart { |
| 145 | // Wait for any previous address sequence to end | 145 | // Wait for any previous address sequence to end |
| @@ -170,7 +170,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | unsafe fn master_write(address: u8, length: usize, stop: Stop, reload: bool) { | 172 | unsafe fn master_write(address: u8, length: usize, stop: Stop, reload: bool) { |
| 173 | assert!(length < 256 && length > 0); | 173 | assert!(length < 256); |
| 174 | 174 | ||
| 175 | // Wait for any previous address sequence to end | 175 | // Wait for any previous address sequence to end |
| 176 | // automatically. This could be up to 50% of a bus | 176 | // automatically. This could be up to 50% of a bus |
| @@ -577,7 +577,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 577 | where | 577 | where |
| 578 | TXDMA: crate::i2c::TxDma<T>, | 578 | TXDMA: crate::i2c::TxDma<T>, |
| 579 | { | 579 | { |
| 580 | self.write_dma_internal(address, bytes, true, true).await | 580 | if bytes.is_empty() { |
| 581 | self.write_internal(address, bytes, true) | ||
| 582 | } else { | ||
| 583 | self.write_dma_internal(address, bytes, true, true).await | ||
| 584 | } | ||
| 581 | } | 585 | } |
| 582 | 586 | ||
| 583 | pub async fn write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> | 587 | pub async fn write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error> |
| @@ -606,7 +610,11 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 606 | where | 610 | where |
| 607 | RXDMA: crate::i2c::RxDma<T>, | 611 | RXDMA: crate::i2c::RxDma<T>, |
| 608 | { | 612 | { |
| 609 | self.read_dma_internal(address, buffer, false).await | 613 | if buffer.is_empty() { |
| 614 | self.read_internal(address, buffer, false) | ||
| 615 | } else { | ||
| 616 | self.read_dma_internal(address, buffer, false).await | ||
| 617 | } | ||
| 610 | } | 618 | } |
| 611 | 619 | ||
| 612 | pub async fn write_read( | 620 | pub async fn write_read( |
| @@ -619,8 +627,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 619 | TXDMA: super::TxDma<T>, | 627 | TXDMA: super::TxDma<T>, |
| 620 | RXDMA: super::RxDma<T>, | 628 | RXDMA: super::RxDma<T>, |
| 621 | { | 629 | { |
| 622 | self.write_dma_internal(address, bytes, true, true).await?; | 630 | if bytes.is_empty() { |
| 623 | self.read_dma_internal(address, buffer, true).await?; | 631 | self.write_internal(address, bytes, false)?; |
| 632 | } else { | ||
| 633 | self.write_dma_internal(address, bytes, true, true).await?; | ||
| 634 | } | ||
| 635 | |||
| 636 | if buffer.is_empty() { | ||
| 637 | self.read_internal(address, buffer, true)?; | ||
| 638 | } else { | ||
| 639 | self.read_dma_internal(address, buffer, true).await?; | ||
| 640 | } | ||
| 641 | |||
| 624 | Ok(()) | 642 | Ok(()) |
| 625 | } | 643 | } |
| 626 | 644 | ||
