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 <dark@dark.red>
This commit is contained in:
		
						commit
						cd36e3f733
					
				@ -130,7 +130,7 @@ mod transfers {
 | 
				
			|||||||
        reg_addr: *mut W,
 | 
					        reg_addr: *mut W,
 | 
				
			||||||
        buf: &'a mut [W],
 | 
					        buf: &'a mut [W],
 | 
				
			||||||
    ) -> impl Future<Output = ()> + 'a {
 | 
					    ) -> impl Future<Output = ()> + 'a {
 | 
				
			||||||
        assert!(buf.len() <= 0xFFFF);
 | 
					        assert!(buf.len() > 0 && buf.len() <= 0xFFFF);
 | 
				
			||||||
        unborrow!(channel);
 | 
					        unborrow!(channel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe { channel.start_read::<W>(request, reg_addr, buf) };
 | 
					        unsafe { channel.start_read::<W>(request, reg_addr, buf) };
 | 
				
			||||||
@ -145,7 +145,7 @@ mod transfers {
 | 
				
			|||||||
        buf: &'a [W],
 | 
					        buf: &'a [W],
 | 
				
			||||||
        reg_addr: *mut W,
 | 
					        reg_addr: *mut W,
 | 
				
			||||||
    ) -> impl Future<Output = ()> + 'a {
 | 
					    ) -> impl Future<Output = ()> + 'a {
 | 
				
			||||||
        assert!(buf.len() <= 0xFFFF);
 | 
					        assert!(buf.len() > 0 && buf.len() <= 0xFFFF);
 | 
				
			||||||
        unborrow!(channel);
 | 
					        unborrow!(channel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe { channel.start_write::<W>(request, buf, reg_addr) };
 | 
					        unsafe { channel.start_write::<W>(request, buf, reg_addr) };
 | 
				
			||||||
 | 
				
			|||||||
@ -139,7 +139,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe fn master_read(address: u8, length: usize, stop: Stop, reload: bool, restart: bool) {
 | 
					    unsafe fn master_read(address: u8, length: usize, stop: Stop, reload: bool, restart: bool) {
 | 
				
			||||||
        assert!(length < 256 && length > 0);
 | 
					        assert!(length < 256);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if !restart {
 | 
					        if !restart {
 | 
				
			||||||
            // Wait for any previous address sequence to end
 | 
					            // Wait for any previous address sequence to end
 | 
				
			||||||
@ -170,7 +170,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe fn master_write(address: u8, length: usize, stop: Stop, reload: bool) {
 | 
					    unsafe fn master_write(address: u8, length: usize, stop: Stop, reload: bool) {
 | 
				
			||||||
        assert!(length < 256 && length > 0);
 | 
					        assert!(length < 256);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Wait for any previous address sequence to end
 | 
					        // Wait for any previous address sequence to end
 | 
				
			||||||
        // automatically. This could be up to 50% of a bus
 | 
					        // 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> {
 | 
				
			|||||||
    where
 | 
					    where
 | 
				
			||||||
        TXDMA: crate::i2c::TxDma<T>,
 | 
					        TXDMA: crate::i2c::TxDma<T>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        self.write_dma_internal(address, bytes, true, true).await
 | 
					        if bytes.is_empty() {
 | 
				
			||||||
 | 
					            self.write_internal(address, bytes, true)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            self.write_dma_internal(address, bytes, true, true).await
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn write_vectored(&mut self, address: u8, bytes: &[&[u8]]) -> Result<(), Error>
 | 
					    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> {
 | 
				
			|||||||
    where
 | 
					    where
 | 
				
			||||||
        RXDMA: crate::i2c::RxDma<T>,
 | 
					        RXDMA: crate::i2c::RxDma<T>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        self.read_dma_internal(address, buffer, false).await
 | 
					        if buffer.is_empty() {
 | 
				
			||||||
 | 
					            self.read_internal(address, buffer, false)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            self.read_dma_internal(address, buffer, false).await
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn write_read(
 | 
					    pub async fn write_read(
 | 
				
			||||||
@ -619,8 +627,18 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
        TXDMA: super::TxDma<T>,
 | 
					        TXDMA: super::TxDma<T>,
 | 
				
			||||||
        RXDMA: super::RxDma<T>,
 | 
					        RXDMA: super::RxDma<T>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        self.write_dma_internal(address, bytes, true, true).await?;
 | 
					        if bytes.is_empty() {
 | 
				
			||||||
        self.read_dma_internal(address, buffer, true).await?;
 | 
					            self.write_internal(address, bytes, false)?;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            self.write_dma_internal(address, bytes, true, true).await?;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if buffer.is_empty() {
 | 
				
			||||||
 | 
					            self.read_internal(address, buffer, true)?;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            self.read_dma_internal(address, buffer, true).await?;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user