Merge pull request #1729 from mattico/i2c-async-timeout
stm32: add async timeout functions to I2c and TimeoutI2c
This commit is contained in:
		
						commit
						0d8a9b1e7a
					
				@ -22,11 +22,93 @@ fn timeout_fn(timeout: Duration) -> impl Fn() -> Result<(), Error> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a, 'd, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
 | 
					impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
 | 
				
			||||||
    pub fn new(i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, timeout: Duration) -> Self {
 | 
					    pub fn new(i2c: &'a mut I2c<'d, T, TXDMA, RXDMA>, timeout: Duration) -> Self {
 | 
				
			||||||
        Self { i2c, timeout }
 | 
					        Self { i2c, timeout }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // =========================
 | 
				
			||||||
 | 
					    //  Async public API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(i2c_v2)]
 | 
				
			||||||
 | 
					    pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        TXDMA: crate::i2c::TxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.write_timeout(address, write, self.timeout).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(i2c_v2)]
 | 
				
			||||||
 | 
					    pub async fn write_timeout(&mut self, address: u8, write: &[u8], timeout: Duration) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        TXDMA: crate::i2c::TxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.i2c.write_timeout(address, write, timeout_fn(timeout)).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(i2c_v2)]
 | 
				
			||||||
 | 
					    pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        TXDMA: crate::i2c::TxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.write_vectored_timeout(address, write, self.timeout).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(i2c_v2)]
 | 
				
			||||||
 | 
					    pub async fn write_vectored_timeout(&mut self, address: u8, write: &[&[u8]], timeout: Duration) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        TXDMA: crate::i2c::TxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.i2c
 | 
				
			||||||
 | 
					            .write_vectored_timeout(address, write, timeout_fn(timeout))
 | 
				
			||||||
 | 
					            .await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(i2c_v2)]
 | 
				
			||||||
 | 
					    pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        RXDMA: crate::i2c::RxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.read_timeout(address, buffer, self.timeout).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(i2c_v2)]
 | 
				
			||||||
 | 
					    pub async fn read_timeout(&mut self, address: u8, buffer: &mut [u8], timeout: Duration) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        RXDMA: crate::i2c::RxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.i2c.read_timeout(address, buffer, timeout_fn(timeout)).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(i2c_v2)]
 | 
				
			||||||
 | 
					    pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        TXDMA: super::TxDma<T>,
 | 
				
			||||||
 | 
					        RXDMA: super::RxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.write_read_timeout(address, write, read, self.timeout).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[cfg(i2c_v2)]
 | 
				
			||||||
 | 
					    pub async fn write_read_timeout(
 | 
				
			||||||
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        address: u8,
 | 
				
			||||||
 | 
					        write: &[u8],
 | 
				
			||||||
 | 
					        read: &mut [u8],
 | 
				
			||||||
 | 
					        timeout: Duration,
 | 
				
			||||||
 | 
					    ) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        TXDMA: super::TxDma<T>,
 | 
				
			||||||
 | 
					        RXDMA: super::RxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.i2c
 | 
				
			||||||
 | 
					            .write_read_timeout(address, write, read, timeout_fn(timeout))
 | 
				
			||||||
 | 
					            .await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // =========================
 | 
				
			||||||
 | 
					    //  Blocking public API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Blocking read with a custom timeout
 | 
					    /// Blocking read with a custom timeout
 | 
				
			||||||
    pub fn blocking_read_timeout(&mut self, addr: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> {
 | 
					    pub fn blocking_read_timeout(&mut self, addr: u8, read: &mut [u8], timeout: Duration) -> Result<(), Error> {
 | 
				
			||||||
        self.i2c.blocking_read_timeout(addr, read, timeout_fn(timeout))
 | 
					        self.i2c.blocking_read_timeout(addr, read, timeout_fn(timeout))
 | 
				
			||||||
@ -65,7 +147,9 @@ impl<'a, 'd, T: Instance, TXDMA, RXDMA> TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
 | 
					impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read
 | 
				
			||||||
 | 
					    for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    type Error = Error;
 | 
					    type Error = Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> {
 | 
					    fn read(&mut self, addr: u8, read: &mut [u8]) -> Result<(), Self::Error> {
 | 
				
			||||||
@ -73,7 +157,9 @@ impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Read for
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
 | 
					impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write
 | 
				
			||||||
 | 
					    for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    type Error = Error;
 | 
					    type Error = Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> {
 | 
					    fn write(&mut self, addr: u8, write: &[u8]) -> Result<(), Self::Error> {
 | 
				
			||||||
@ -81,7 +167,7 @@ impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::Write fo
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead
 | 
					impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRead
 | 
				
			||||||
    for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
 | 
					    for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    type Error = Error;
 | 
					    type Error = Error;
 | 
				
			||||||
@ -95,11 +181,11 @@ impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_02::blocking::i2c::WriteRea
 | 
				
			|||||||
mod eh1 {
 | 
					mod eh1 {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
 | 
					    impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::ErrorType for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
 | 
				
			||||||
        type Error = Error;
 | 
					        type Error = Error;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    impl<'a, 'd, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::I2c for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
 | 
					    impl<'a, 'd: 'a, T: Instance, TXDMA, RXDMA> embedded_hal_1::i2c::I2c for TimeoutI2c<'a, 'd, T, TXDMA, RXDMA> {
 | 
				
			||||||
        fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
 | 
					        fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
 | 
				
			||||||
            self.blocking_read(address, read)
 | 
					            self.blocking_read(address, read)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -595,17 +595,41 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
    //  Async public API
 | 
					    //  Async public API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error>
 | 
					    pub async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        TXDMA: crate::i2c::TxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.write_timeout(address, write, || Ok(())).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn write_timeout(
 | 
				
			||||||
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        address: u8,
 | 
				
			||||||
 | 
					        write: &[u8],
 | 
				
			||||||
 | 
					        check_timeout: impl Fn() -> Result<(), Error>,
 | 
				
			||||||
 | 
					    ) -> Result<(), Error>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        TXDMA: crate::i2c::TxDma<T>,
 | 
					        TXDMA: crate::i2c::TxDma<T>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if write.is_empty() {
 | 
					        if write.is_empty() {
 | 
				
			||||||
            self.write_internal(address, write, true, || Ok(()))
 | 
					            self.write_internal(address, write, true, check_timeout)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            self.write_dma_internal(address, write, true, true, || Ok(())).await
 | 
					            self.write_dma_internal(address, write, true, true, check_timeout).await
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error>
 | 
					    pub async fn write_vectored(&mut self, address: u8, write: &[&[u8]]) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        TXDMA: crate::i2c::TxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.write_vectored_timeout(address, write, || Ok(())).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn write_vectored_timeout(
 | 
				
			||||||
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        address: u8,
 | 
				
			||||||
 | 
					        write: &[&[u8]],
 | 
				
			||||||
 | 
					        check_timeout: impl Fn() -> Result<(), Error>,
 | 
				
			||||||
 | 
					    ) -> Result<(), Error>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        TXDMA: crate::i2c::TxDma<T>,
 | 
					        TXDMA: crate::i2c::TxDma<T>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -620,7 +644,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
            let next = iter.next();
 | 
					            let next = iter.next();
 | 
				
			||||||
            let is_last = next.is_none();
 | 
					            let is_last = next.is_none();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.write_dma_internal(address, c, first, is_last, || Ok(())).await?;
 | 
					            self.write_dma_internal(address, c, first, is_last, || check_timeout())
 | 
				
			||||||
 | 
					                .await?;
 | 
				
			||||||
            first = false;
 | 
					            first = false;
 | 
				
			||||||
            current = next;
 | 
					            current = next;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -628,31 +653,58 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error>
 | 
					    pub async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        RXDMA: crate::i2c::RxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.read_timeout(address, buffer, || Ok(())).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn read_timeout(
 | 
				
			||||||
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        address: u8,
 | 
				
			||||||
 | 
					        buffer: &mut [u8],
 | 
				
			||||||
 | 
					        check_timeout: impl Fn() -> Result<(), Error>,
 | 
				
			||||||
 | 
					    ) -> Result<(), Error>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        RXDMA: crate::i2c::RxDma<T>,
 | 
					        RXDMA: crate::i2c::RxDma<T>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if buffer.is_empty() {
 | 
					        if buffer.is_empty() {
 | 
				
			||||||
            self.read_internal(address, buffer, false, || Ok(()))
 | 
					            self.read_internal(address, buffer, false, check_timeout)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            self.read_dma_internal(address, buffer, false, || Ok(())).await
 | 
					            self.read_dma_internal(address, buffer, false, check_timeout).await
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error>
 | 
					    pub async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        TXDMA: super::TxDma<T>,
 | 
				
			||||||
 | 
					        RXDMA: super::RxDma<T>,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self.write_read_timeout(address, write, read, || Ok(())).await
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn write_read_timeout(
 | 
				
			||||||
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        address: u8,
 | 
				
			||||||
 | 
					        write: &[u8],
 | 
				
			||||||
 | 
					        read: &mut [u8],
 | 
				
			||||||
 | 
					        check_timeout: impl Fn() -> Result<(), Error>,
 | 
				
			||||||
 | 
					    ) -> Result<(), Error>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        TXDMA: super::TxDma<T>,
 | 
					        TXDMA: super::TxDma<T>,
 | 
				
			||||||
        RXDMA: super::RxDma<T>,
 | 
					        RXDMA: super::RxDma<T>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if write.is_empty() {
 | 
					        if write.is_empty() {
 | 
				
			||||||
            self.write_internal(address, write, false, || Ok(()))?;
 | 
					            self.write_internal(address, write, false, || check_timeout())?;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            self.write_dma_internal(address, write, true, true, || Ok(())).await?;
 | 
					            self.write_dma_internal(address, write, true, true, || check_timeout())
 | 
				
			||||||
 | 
					                .await?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if read.is_empty() {
 | 
					        if read.is_empty() {
 | 
				
			||||||
            self.read_internal(address, read, true, || Ok(()))?;
 | 
					            self.read_internal(address, read, true, check_timeout)?;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            self.read_dma_internal(address, read, true, || Ok(())).await?;
 | 
					            self.read_dma_internal(address, read, true, check_timeout).await?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user