aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-01-25 16:19:46 +0000
committerGitHub <[email protected]>2022-01-25 16:19:46 +0000
commitcd36e3f7332d08865e670ca5b515d1c6efa1bf85 (patch)
tree138f01bc3f400bdf907712b8fd489adf4d2e432a
parenta950266a7501c5534ebd7c477d42d29ac25cf472 (diff)
parent3fc54236ea18a5ade403fe4a2c85906dbcf727b4 (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.rs4
-rw-r--r--embassy-stm32/src/i2c/v2.rs30
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